From 8f583a23bec297f531e09da8a19653a3cb0a4491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Dziewo=C5=84ski?= Date: Fri, 22 May 2020 19:09:21 +0200 Subject: [PATCH] Use the faster childIndexOf() approach in JS too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I was wondering if the different approach to childIndexOf() implemented in PHP in b8d7a75c34de97ba3a2e9cda2df5409de21fa729 would be faster in JS as well, and yes, it is. Our test suite now takes (on my machine): * Chrome: 8337 ms → 7355 ms (average over 5 tries) * Firefox: 5321 ms → 5044 ms (average over 5 tries) Change-Id: I71963eeb92dcea9bfd59cbf01a7aa0b7de5d9cf1 --- modules/parser.js | 4 ++-- modules/utils.js | 15 +++++++++++++++ tests/qunit/testUtils.js | 17 ++++------------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/modules/parser.js b/modules/parser.js index f73496153..42b1131cd 100644 --- a/modules/parser.js +++ b/modules/parser.js @@ -754,13 +754,13 @@ function getComments( rootNode ) { match = timestamps[ nextTimestamp ][ 1 ]; range = { startContainer: startNode.parentNode, - startOffset: Array.prototype.indexOf.call( startNode.parentNode.childNodes, startNode ), + startOffset: utils.childIndexOf( startNode ), endContainer: node, endOffset: match.index + match[ 0 ].length }; sigRange = { startContainer: firstSigNode.parentNode, - startOffset: Array.prototype.indexOf.call( firstSigNode.parentNode.childNodes, firstSigNode ), + startOffset: utils.childIndexOf( firstSigNode ), endContainer: node, endOffset: match.index + match[ 0 ].length }; diff --git a/modules/utils.js b/modules/utils.js index 31135b943..2963886a4 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -15,6 +15,20 @@ function getNativeRange( comment ) { return nativeRange; } +/** + * Get the index of a node in its parentNode's childNode list + * + * @param {Node} child + * @return {number} Index in parentNode's childNode list + */ +function childIndexOf( child ) { + var i = 0; + while ( ( child = child.previousSibling ) ) { + i++; + } + return i; +} + /** * Find closest ancestor element using one of the given tag names. * @@ -48,6 +62,7 @@ function htmlTrim( str ) { module.exports = { getNativeRange: getNativeRange, + childIndexOf: childIndexOf, closestElement: closestElement, htmlTrim: htmlTrim }; diff --git a/tests/qunit/testUtils.js b/tests/qunit/testUtils.js index 31d496005..ea1147418 100644 --- a/tests/qunit/testUtils.js +++ b/tests/qunit/testUtils.js @@ -1,3 +1,6 @@ +var + utils = require( 'ext.discussionTools.init' ).utils; + module.exports = {}; /* eslint-disable qunit/no-commented-tests */ @@ -46,18 +49,6 @@ module.exports.overrideMwConfig = function ( config ) { ); }; -/** - * Get the index of a node in its parentNode's childNode list - * - * @copyright 2011-2019 VisualEditor Team and others; see http://ve.mit-license.org - * - * @param {Node} node The node - * @return {number} Index in parentNode's childNode list - */ -function parentIndex( node ) { - return Array.prototype.indexOf.call( node.parentNode.childNodes, node ); -} - /** * Get the offset path from ancestor to offset in descendant * @@ -76,7 +67,7 @@ function getOffsetPath( ancestor, node, nodeOffset ) { console.log( node, 'is not a descendant of', ancestor ); throw new Error( 'Not a descendant' ); } - path.unshift( parentIndex( node ) ); + path.unshift( utils.childIndexOf( node ) ); node = node.parentNode; } return path;