C. Scott Ananian has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/385474 )
Change subject: Remove unnecessary calls to Node#childNodes.length ...................................................................... Remove unnecessary calls to Node#childNodes.length These calls force us to allocate a backing array for childNodes, deoptimizing a linked list representation. Use the standard Node#hasChildNodes() method instead, which can be efficiently implemented without allocating a backing array. Change-Id: I1706bfa15263564bc981d689947835a3d0d4a68f --- M lib/ext/Cite/index.js M lib/ext/Nowiki/index.js M lib/html2wt/DOMDiff.js M lib/html2wt/DOMHandlers.js M lib/html2wt/LinkHandler.js M lib/html2wt/WikitextSerializer.js M lib/html2wt/escapeWikitext.js M lib/utils/DOMTraverser.js M lib/utils/DOMUtils.js M lib/wt2html/pp/handlers/cleanup.js M lib/wt2html/pp/processors/markFosteredContent.js M lib/wt2html/pp/processors/migrateTemplateMarkerMetas.js 12 files changed, 25 insertions(+), 25 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid refs/changes/74/385474/1 diff --git a/lib/ext/Cite/index.js b/lib/ext/Cite/index.js index bf704b2..6ad779e 100644 --- a/lib/ext/Cite/index.js +++ b/lib/ext/Cite/index.js @@ -643,7 +643,7 @@ cite.references.extractRefFromNode(child, refsData, _processRefs.bind(null, cite, refsData), referencesId, referencesGroup, nestedRefsHTML); - } else if (child.childNodes.length > 0) { + } else if (child.hasChildNodes()) { _processRefsInReferences(cite, refsData, child, referencesId, referencesGroup, nestedRefsHTML); } @@ -705,7 +705,7 @@ dmw.caption = DU.ppToXML(captionDOM, { innerXML: true }); } } - if (child.childNodes.length > 0) { + if (child.hasChildNodes()) { _processRefs(cite, refsData, child); } } diff --git a/lib/ext/Nowiki/index.js b/lib/ext/Nowiki/index.js index 3af8836..dad56cf 100644 --- a/lib/ext/Nowiki/index.js +++ b/lib/ext/Nowiki/index.js @@ -45,7 +45,7 @@ var serialHandler = { handle: Promise.method(function(node, state, wrapperUnmodified) { - if (!node.childNodes.length) { + if (!node.hasChildNodes()) { state.hasSelfClosingNowikis = true; state.emitChunk('<nowiki/>', node); return; diff --git a/lib/html2wt/DOMDiff.js b/lib/html2wt/DOMDiff.js index 153c39d..b607a34 100644 --- a/lib/html2wt/DOMDiff.js +++ b/lib/html2wt/DOMDiff.js @@ -180,17 +180,17 @@ // Passed all tests, element node itself is equal. if (deep) { // Compare children too - if (nodeA.childNodes.length !== nodeB.childNodes.length) { - return false; - } var childA = nodeA.firstChild; var childB = nodeB.firstChild; - while (childA) { + while (childA && childB) { if (!this.treeEquals(childA, childB, deep)) { return false; } childA = childA.nextSibling; childB = childB.nextSibling; + } + if (childA || childB) { + return false; } } @@ -374,7 +374,7 @@ // SSS FIXME: WTS checks for zero children in a few places // That code would have to be upgraded if we emit mw:DiffMarker // in this scenario. So, bailing out in this one case for now. - if (newParentNode.childNodes.length > 0) { + if (newParentNode.hasChildNodes()) { var meta = newParentNode.ownerDocument.createElement('meta'); meta.setAttribute('typeof', 'mw:DiffMarker'); if (DU.isBlockNodeWithVisibleWT(baseNode)) { diff --git a/lib/html2wt/DOMHandlers.js b/lib/html2wt/DOMHandlers.js index dd3a77d..9ac2547 100644 --- a/lib/html2wt/DOMHandlers.js +++ b/lib/html2wt/DOMHandlers.js @@ -75,7 +75,7 @@ state.singleLineContext.enforce(); var p; - if (node.childNodes.length) { + if (node.hasChildNodes()) { p = state.serializeChildren(node); } else { // Deal with empty headings @@ -461,7 +461,7 @@ } WTSUtils.emitStartTag(quotes, node, state); - if (node.childNodes.length === 0) { + if (!node.hasChildNodes()) { // Empty nodes like <i></i> or <b></b> need // a <nowiki/> in place of the empty content so that // they parse back identically. @@ -1550,7 +1550,7 @@ WTSUtils.emitStartTag(tag, node, state); var p; - if (node.childNodes.length) { + if (node.hasChildNodes()) { var inPHPBlock = state.inPHPBlock; if (Util.tagOpensBlockScope(node.nodeName.toLowerCase())) { state.inPHPBlock = true; diff --git a/lib/html2wt/LinkHandler.js b/lib/html2wt/LinkHandler.js index eff758c..6b52024 100644 --- a/lib/html2wt/LinkHandler.js +++ b/lib/html2wt/LinkHandler.js @@ -138,7 +138,7 @@ // Get the content string or tokens var contentParts; - if (node.childNodes.length >= 1 && DU.allChildrenAreText(node)) { + if (node.hasChildNodes() && DU.allChildrenAreText(node)) { var contentString = node.textContent; if (rtData.target.value && rtData.target.value !== contentString) { // Try to identify a new potential tail @@ -151,7 +151,7 @@ rtData.prefix = ''; rtData.content.string = contentString; } - } else if (node.childNodes.length) { + } else if (node.hasChildNodes()) { rtData.contentNode = node; } else if (/^mw:PageProp\/redirect$/.test(rtData.type)) { rtData.isRedirect = true; @@ -316,7 +316,7 @@ var target = linkData.target; // Get plain text content, if any - var contentStr = node.childNodes.length >= 1 && + var contentStr = node.hasChildNodes() && DU.allChildrenAreText(node) ? node.textContent : null; // First check if we can serialize as an URL link return contentStr && @@ -641,7 +641,7 @@ var wiki = state.env.conf.wiki; // Get plain text content, if any - var contentStr = node.childNodes.length >= 1 && + var contentStr = node.hasChildNodes() && DU.allChildrenAreText(node) ? node.textContent : null; // TODO: match vs. interwikis too diff --git a/lib/html2wt/WikitextSerializer.js b/lib/html2wt/WikitextSerializer.js index 95ad30d..27dd478 100644 --- a/lib/html2wt/WikitextSerializer.js +++ b/lib/html2wt/WikitextSerializer.js @@ -1005,7 +1005,7 @@ state.currNodeUnmodified = true; if (DU.isZeroWidthWikitextElt(node) && - node.childNodes.length > 0 && + node.hasChildNodes() && state.sep.constraints.constraintInfo.sepType === 'sibling') { state.sep.constraints.constraintInfo.onSOL = state.onSOL; state.sep.constraints.constraintInfo.sepType = 'parent-child'; diff --git a/lib/html2wt/escapeWikitext.js b/lib/html2wt/escapeWikitext.js index 17584e3..9968005 100644 --- a/lib/html2wt/escapeWikitext.js +++ b/lib/html2wt/escapeWikitext.js @@ -628,7 +628,7 @@ if (DU.isBlockNode(node)) { return !startsOnANewLine(node); } - if (node.childNodes.length > 0) { + if (node.hasChildNodes()) { if (hasBlocksOnLine(node.firstChild, false)) { return true; } diff --git a/lib/utils/DOMTraverser.js b/lib/utils/DOMTraverser.js index c135c09..a57d502 100644 --- a/lib/utils/DOMTraverser.js +++ b/lib/utils/DOMTraverser.js @@ -112,7 +112,7 @@ if (possibleNext === true) { // the 'continue processing' case - if (DU.isElt(workNode) && workNode.childNodes.length > 0) { + if (DU.isElt(workNode) && workNode.hasChildNodes()) { this.traverse(workNode.firstChild, env, options, atTopLevel, tplInfo); } possibleNext = workNode.nextSibling; diff --git a/lib/utils/DOMUtils.js b/lib/utils/DOMUtils.js index d6ff3ef..c9cd9fb 100644 --- a/lib/utils/DOMUtils.js +++ b/lib/utils/DOMUtils.js @@ -975,7 +975,7 @@ return true; } else if (this.isFirstEncapsulationWrapperNode(node)) { // Dont try any harder than this - return node.childNodes.length === 0 || node.innerHTML.match(/^\n/); + return (!node.hasChildNodes()) || node.innerHTML.match(/^\n/); } else { return this.isBlockNodeWithVisibleWT(node); } @@ -1743,7 +1743,7 @@ } var workNode; - if (DU.isElt(node) && node.childNodes.length || wrapperName !== node.nodeName) { + if (DU.isElt(node) && node.hasChildNodes() || wrapperName !== node.nodeName) { // Create a copy of the node without children workNode = node.ownerDocument.createElement(wrapperName); // copy over attributes diff --git a/lib/wt2html/pp/handlers/cleanup.js b/lib/wt2html/pp/handlers/cleanup.js index 581929e..d761aba 100644 --- a/lib/wt2html/pp/handlers/cleanup.js +++ b/lib/wt2html/pp/handlers/cleanup.js @@ -86,7 +86,7 @@ if (dp.autoInsertedStart && dp.autoInsertedEnd && // template/extension content OR nodes with templated-attributes !DU.hasParsoidAboutId(node) && ( - node.childNodes.length === 0 || ( + (!node.hasChildNodes()) || ( node.childNodes.length === 1 && !DU.isElt(node.firstChild) && /^\s*$/.test(node.textContent) ) diff --git a/lib/wt2html/pp/processors/markFosteredContent.js b/lib/wt2html/pp/processors/markFosteredContent.js index 1b31fda..556572b 100644 --- a/lib/wt2html/pp/processors/markFosteredContent.js +++ b/lib/wt2html/pp/processors/markFosteredContent.js @@ -120,7 +120,7 @@ // If the foster content holder is not empty, // close it and get a new content holder. - if (fosterContentHolder.childNodes.length > 0) { + if (fosterContentHolder.hasChildNodes()) { sibling.parentNode.insertBefore(fosterContentHolder, sibling); fosterContentHolder = getFosterContentHolder(sibling.ownerDocument, inPTag); } @@ -143,7 +143,7 @@ console.assert(table && DU.isElt(table) && DU.hasNodeName(table, "table"), "Table isn't a sibling. Something's amiss!"); - if (fosterContentHolder.childNodes.length > 0) { + if (fosterContentHolder.hasChildNodes()) { table.parentNode.insertBefore(fosterContentHolder, table); } @@ -159,7 +159,7 @@ } else if (DU.isMarkerMeta(c, "mw:TransclusionShadow")) { DU.deleteNode(c); } else if (DU.isElt(c)) { - if (c.childNodes.length > 0) { + if (c.hasChildNodes()) { markFosteredContent(c, env); } } diff --git a/lib/wt2html/pp/processors/migrateTemplateMarkerMetas.js b/lib/wt2html/pp/processors/migrateTemplateMarkerMetas.js index 6d2928f..23ffee5 100644 --- a/lib/wt2html/pp/processors/migrateTemplateMarkerMetas.js +++ b/lib/wt2html/pp/processors/migrateTemplateMarkerMetas.js @@ -21,7 +21,7 @@ var c = node.firstChild; while (c) { var sibling = c.nextSibling; - if (c.childNodes.length > 0) { + if (c.hasChildNodes()) { migrateTemplateMarkerMetas(c, env); } c = sibling; -- To view, visit https://gerrit.wikimedia.org/r/385474 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1706bfa15263564bc981d689947835a3d0d4a68f Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/services/parsoid Gerrit-Branch: master Gerrit-Owner: C. Scott Ananian <canan...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits