jenkins-bot has submitted this change and it was merged.

Change subject: Bug 53727: Don't use \b to match (^|$|\s)
......................................................................


Bug 53727: Don't use \b to match (^|$|\s)

We use \b often to match (?:^|$|\s), but it does in fact match "the position
where a word character is not followed or preceeded by another
word-character.", where \w is equivalent to [A-Za-z0-9_]. (See
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#special-word-boundary)

Example:

    /\bfoo\b/.test('aaa:foo:bbb');
    true

* Replace \b with (?:^|\s) or (?=$|\s) and adjust uses of match() results
  accordingly to account for the consuming match in (?:^|s). If JS supported
  look-behind assertions we could use those instead.

* Convert some uses of .match() where the return value was not used into
  .test()

* Remove some tests for truishness which are not needed when using .test()

* Strip data-parsoid and data-mw early before comments are stripped, so that
  the simplistic comment stripping does not violate attribute boundaries. This
  fixes a few formerly blacklisted tests. The blacklist is updated
  accordingly.

Change-Id: I596623b5a96c41b9b1411db2a70630f08251ffe4
---
M js/lib/dom.cleanup.js
M js/lib/dom.computeDSR.js
M js/lib/dom.generateRefs.js
M js/lib/dom.migrateTrailingNLs.js
M js/lib/dom.t.unpackDOMFragments.js
M js/lib/dom.wrapTemplates.js
M js/lib/ext.core.LinkHandler.js
M js/lib/ext.core.Sanitizer.js
M js/lib/mediawiki.DOMUtils.js
M js/lib/mediawiki.Util.js
M js/lib/mediawiki.WikitextSerializer.js
M js/lib/mediawiki.parser.defines.js
M js/tests/parserTests-blacklist.js
13 files changed, 61 insertions(+), 62 deletions(-)

Approvals:
  Subramanya Sastry: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/js/lib/dom.cleanup.js b/js/lib/dom.cleanup.js
index f9a026d..71e4d87 100644
--- a/js/lib/dom.cleanup.js
+++ b/js/lib/dom.cleanup.js
@@ -13,7 +13,7 @@
        var metaType = node.getAttribute("typeof");
        if (metaType &&
                // TODO: Use /Start for all Transclusion / Param markers!
-               
(metaType.match(/\bmw:(StartTag|EndTag|Extension\/ref\/Marker|TSRMarker)\/?[^\s]*\b/)
 &&
+               
(/(?:^|\s)mw:(StartTag|EndTag|Extension\/ref\/Marker|TSRMarker)\/?[^\s]*/.test(metaType)
 &&
                !node.getAttribute("property")) ||
                (editMode && metaType === "mw:Placeholder/StrippedTag")
        ) {
@@ -53,7 +53,7 @@
                        // valid data-mw and dsr.  This should reduce 
data-parsoid bloat.
                        //
                        // Transcluded nodes will not have dp.tsr set and dont 
need dp.src either
-                       if 
(/\bmw:(Transclusion|Extension)\b/.test(node.getAttribute("typeof")) &&
+                       if 
(/(?:^|\s)mw:(Transclusion|Extension)(?=$|\s)/.test(node.getAttribute("typeof"))
 &&
                                (!dp.tsr ||
                                node.getAttribute("data-mw") && dp.dsr && 
dp.dsr[0] && dp.dsr[1]))
                        {
diff --git a/js/lib/dom.computeDSR.js b/js/lib/dom.computeDSR.js
index b799c57..22550da 100644
--- a/js/lib/dom.computeDSR.js
+++ b/js/lib/dom.computeDSR.js
@@ -193,7 +193,7 @@
                        var next = child.nextSibling;
                        if (next) {
                                if (DU.isElt(next) && next.data.parsoid.src &&
-                                       
/\bmw:Placeholder\/StrippedTag\b/.test(next.getAttribute("typeof")))
+                                       
/(?:^|\s)mw:Placeholder\/StrippedTag(?=$|\s)/.test(next.getAttribute("typeof")))
                                {
                                        if (next.data.parsoid.name in 
Consts.WTQuoteTags &&
                                                child.nodeName in 
Consts.WTQuoteTags)
diff --git a/js/lib/dom.generateRefs.js b/js/lib/dom.generateRefs.js
index caefc81..a551a80 100644
--- a/js/lib/dom.generateRefs.js
+++ b/js/lib/dom.generateRefs.js
@@ -9,9 +9,9 @@
                DU.loadDataParsoid(child);
                if (DU.isElt(child)) {
                        var typeOf = child.getAttribute('typeof');
-                       if ((/\bmw:Extension\/ref\/Marker\b/).test(typeOf)) {
+                       if 
((/(?:^|\s)mw:Extension\/ref\/Marker(?=$|\s)/).test(typeOf)) {
                                refsExt.extractRefFromNode(child);
-                       } else if 
((/\bmw:Extension\/references\b/).test(typeOf)) {
+                       } else if 
((/(?:^|\s)mw:Extension\/references(?=$|\s)/).test(typeOf)) {
                                refsExt.insertReferencesIntoDOM(child);
                        } else if (child.childNodes.length > 0) {
                                generateRefs(refsExt, child);
diff --git a/js/lib/dom.migrateTrailingNLs.js b/js/lib/dom.migrateTrailingNLs.js
index 564c523..cfec188 100644
--- a/js/lib/dom.migrateTrailingNLs.js
+++ b/js/lib/dom.migrateTrailingNLs.js
@@ -80,7 +80,7 @@
                                break;
                        }
 
-                       if (type && (DU.isTplMetaType(type) || 
type.match(/\b(mw:Includes|mw:Extension\/)/))) {
+                       if (type && (DU.isTplMetaType(type) || 
type.match(/(?:^|\s)(mw:Includes|mw:Extension\/)/))) {
                                break;
                        }
 
diff --git a/js/lib/dom.t.unpackDOMFragments.js 
b/js/lib/dom.t.unpackDOMFragments.js
index 71e92a5..2c3332b 100644
--- a/js/lib/dom.t.unpackDOMFragments.js
+++ b/js/lib/dom.t.unpackDOMFragments.js
@@ -41,7 +41,7 @@
                var typeOf = node.getAttribute('typeof'),
                        about = node.getAttribute('about'),
                        lastNode = node;
-               if (/\bmw:DOMFragment\b/.test(typeOf)) {
+               if (/(?:^|\s)mw:DOMFragment(?=$|\s)/.test(typeOf)) {
                        // Replace this node and possibly a sibling with 
node.dp.html
                        var parentNode = node.parentNode,
                                // Use a div rather than a p, as the p might be 
stripped out
@@ -66,7 +66,7 @@
 
                        var html = node.data.parsoid.html,
                                tsrDelta = node.data.parsoid.tsrDelta;
-                       if (!html || /\bmw:Transclusion\b/.test(typeOf)) {
+                       if (!html || 
/(?:^|\s)mw:Transclusion(?=$|\s)/.test(typeOf)) {
                                // Ex: A multi-part template with an extension 
in its
                                // output (possibly passed in as a parameter).
                                //
@@ -108,7 +108,7 @@
                        // here.
                        if (dsr) {
                                var type = firstChild.getAttribute("typeof");
-                               if 
(/\bmw:(Transclusion|Extension)\b/.test(type)) {
+                               if 
(/(?:^|\s)mw:(Transclusion|Extension)(?=$|\s)/.test(type)) {
                                        firstChild.data.parsoid.dsr = [dsr[0], 
dsr[1]];
                                } else { // non-transcluded images
                                        firstChild.data.parsoid.dsr = [dsr[0], 
dsr[1], 2, 2];
diff --git a/js/lib/dom.wrapTemplates.js b/js/lib/dom.wrapTemplates.js
index a0f9893..a282f23 100644
--- a/js/lib/dom.wrapTemplates.js
+++ b/js/lib/dom.wrapTemplates.js
@@ -170,7 +170,7 @@
                } else {
                        // Remove mw:* from the typeof
                        var type = meta.getAttribute("typeof");
-                       type = type.replace(/\bmw:[^\/]*(\/[^\s]+|\b)/, '');
+                       type = 
type.replace(/(?:^|\s)mw:[^\/]*(\/[^\s]+|(?=$|\s))/g, '');
                        meta.setAttribute("typeof", type);
                }
        }
@@ -605,7 +605,7 @@
                // However, tcStart (= range.start), even if a meta, need not be
                // a marker meta added for the template.
                if (DU.hasNodeName(startElem, "meta") &&
-                               
/\bmw:(:?Transclusion|Param)\b/.test(startElem.getAttribute('typeof'))) {
+                               
/(?:^|\s)mw:(:?Transclusion|Param)(?=$|\s)/.test(startElem.getAttribute('typeof')))
 {
                        DU.deleteNode(startElem);
                }
 
@@ -642,7 +642,7 @@
                if ( DU.isElt(elem) ) {
                        var type = elem.getAttribute( 'typeof' ),
                                // SSS FIXME: This regexp differs from that in 
isTplMetaType
-                               metaMatch = type ? type.match( 
/\b(mw:(?:Transclusion|Param)(\/[^\s]+)?)\b/ ) : null;
+                               metaMatch = type ? type.match( 
/(?:^|\s)(mw:(?:Transclusion|Param)(\/[^\s]+)?)(?=$|\s)/ ) : null;
 
                        // Ignore templates without tsr.
                        //
@@ -655,13 +655,13 @@
                        // on end-meta-tags.
                        //
                        // Ex: "<ref>{{echo|bar}}<!--bad-></ref>"
-                       if (metaMatch && ( DU.getDataParsoid( elem ).tsr || 
type.match(/\/End\b/))) {
+                       if (metaMatch && ( DU.getDataParsoid( elem ).tsr || 
/\/End(?=$|\s)/.test(type))) {
                                var metaType = metaMatch[1];
 
                                about = elem.getAttribute('about');
                                aboutRef = tpls[about];
                                // Is this a start marker?
-                               if (!metaType.match(/\/End\b/)) {
+                               if (!/\/End(?=$|\s)/.test(metaType)) {
                                        if ( aboutRef ) {
                                                aboutRef.start = elem;
                                                // content or end marker 
existed already
diff --git a/js/lib/ext.core.LinkHandler.js b/js/lib/ext.core.LinkHandler.js
index 9f52707..3343c3d 100644
--- a/js/lib/ext.core.LinkHandler.js
+++ b/js/lib/ext.core.LinkHandler.js
@@ -1347,18 +1347,19 @@
        //console.warn( 'mw:content: ' + JSON.stringify( content, null, 2 ) );
 
        var dataAttribs = Util.clone(token.dataAttribs);
-       var rdfaType = token.getAttribute('typeof'), magLinkRe = 
/\bmw:ExtLink\/(?:ISBN|RFC|PMID)\b/;
-       if ( rdfaType && rdfaType.match( magLinkRe ) ) {
-               if ( rdfaType.match( /\bmw:ExtLink\/ISBN/ ) ) {
+       var rdfaType = token.getAttribute('typeof'),
+               magLinkRe = /(?:^|\s)(mw:ExtLink\/(?:ISBN|RFC|PMID))(?=$|\s)/;
+       if ( rdfaType && magLinkRe.test(rdfaType) ) {
+               if ( /(?:^|\s)mw:ExtLink\/ISBN/.test(rdfaType) ) {
                        title = Title.fromPrefixedText( env, href );
                        newAttrs = [
                                new KV('href', title.makeLink()),
-                               new KV('rel', rdfaType.match( magLinkRe )[0] )
+                               new KV('rel', rdfaType.match( magLinkRe )[1] )
                        ];
                } else {
                        newAttrs = [
                                new KV('href', href),
-                               new KV('rel', rdfaType.match( magLinkRe )[0] )
+                               new KV('rel', rdfaType.match( magLinkRe )[1] )
                        ];
                }
 
diff --git a/js/lib/ext.core.Sanitizer.js b/js/lib/ext.core.Sanitizer.js
index fad9f47..0df0941 100644
--- a/js/lib/ext.core.Sanitizer.js
+++ b/js/lib/ext.core.Sanitizer.js
@@ -918,7 +918,7 @@
        //    unconditionally discard the entire attribute or process it 
further.
        //    That further processing will catch and discard any dangerous
        //    strings in the rest of the attribute
-       return k === "typeof" && /\bmw:.+?\b/.test(v) ||
+       return k === "typeof" && /(?:^|\s)mw:.+?(?=$|\s)/.test(v) ||
                k === "about" && /^#mwt\d+$/.test(v);
 };
 
diff --git a/js/lib/mediawiki.DOMUtils.js b/js/lib/mediawiki.DOMUtils.js
index ad56eaa..ba4917e 100644
--- a/js/lib/mediawiki.DOMUtils.js
+++ b/js/lib/mediawiki.DOMUtils.js
@@ -287,7 +287,7 @@
                        var type = node.getAttribute('typeof'),
                                about = node.getAttribute('about') || '',
                                tplAttrState = tplAttrs[about];
-                       if (type && type.match(/\bmw:ExpandedAttrs\/[^\s]+/) &&
+                       if (type && 
/(?:^|\s)mw:ExpandedAttrs\/[^\s]+/.test(type) &&
                                        tplAttrState &&
                                        tplAttrState.vs[name] )
                        {
@@ -455,7 +455,7 @@
         * @param {string} nType
         */
        isTplMetaType: function(nType)  {
-               return nType && nType.match(/\bmw:Transclusion(\/[^\s]+)*\b/);
+               return 
(/(?:^|\s)mw:Transclusion(\/[^\s]+)*(?=$|\s)/).test(nType);
        },
 
        /**
@@ -465,7 +465,7 @@
         * @param {string} nType
         */
        isExpandedAttrsMetaType: function(nType) {
-               return nType && nType.match(/\bmw:ExpandedAttrs(\/[^\s]+)*\b/);
+               return 
(/(?:^|\s)mw:ExpandedAttrs(\/[^\s]+)*(?=$|\s)/).test(nType);
        },
 
        /**
@@ -484,8 +484,8 @@
        isTplStartMarkerMeta: function(node)  {
                if (this.hasNodeName(node, "meta")) {
                        var t = node.getAttribute("typeof");
-                       var tMatch = t && 
t.match(/\bmw:Transclusion(\/[^\s]+)*\b/);
-                       return tMatch && !t.match(/\/End\b/);
+                       var tMatch = 
/(?:^|\s)mw:Transclusion(\/[^\s]+)*(?=$|\s)/.test(t);
+                       return tMatch && !/\/End(?=$|\s)/.test(t);
                } else {
                        return false;
                }
@@ -500,7 +500,7 @@
        isTplEndMarkerMeta: function(n)  {
                if (this.hasNodeName(n, "meta")) {
                        var t = n.getAttribute("typeof");
-                       return t && 
t.match(/\bmw:Transclusion(\/[^\s]+)*\/End\b/);
+                       return 
(/(?:^|\s)mw:Transclusion(\/[^\s]+)*\/End(?=$|\s)/).test(t);
                } else {
                        return false;
                }
@@ -631,7 +631,7 @@
        },
 
        isEncapsulatedElt: function(node) {
-               return this.isElt(node) && 
(/\bmw:(?:Transclusion\b|Param\b|Extension\/[^\s]+)/).test(node.getAttribute('typeof'));
+               return this.isElt(node) && 
(/(?:^|\s)mw:(?:Transclusion(?=$|\s)|Param(?=$|\s)|Extension\/[^\s]+)/).test(node.getAttribute('typeof'));
        },
 
        /**
@@ -906,11 +906,7 @@
 
                var classes = ele.getAttribute( 'class' );
 
-               if ( classes && classes.match( new RegExp( '\\b' + someClass + 
'\\b' ) ) ) {
-                       return true;
-               } else {
-                       return false;
-               }
+               return new RegExp( '(?:^|\\s)' + someClass + '(?=$|\\s)' 
).test(classes);
        },
 
        hasBlockContent: function(node) {
@@ -1032,17 +1028,17 @@
                                if (node.nodeType === node.ELEMENT_NODE) {
                                        var typeOf = 
node.getAttribute('typeof'),
                                                about = 
node.getAttribute('about');
-                                       if 
((/\b(?:mw:(?:Transclusion\b|Extension\/))/
+                                       if 
((/(?:^|\s)(?:mw:(?:Transclusion(?=$|\s)|Extension\/))/
                                                                .test(typeOf) 
&& about) ||
-                                                       
/\b(?:mw:Image(?:\b|\/))/.test(typeOf))
+                                                       
/(?:^|\s)(?:mw:Image(?:(?=$|\s)|\/))/.test(typeOf))
                                        {
                                                DU.loadDataParsoid(node);
                                                nodes = 
DU.getAboutSiblings(node, about);
                                                var key;
-                                               if 
(/\bmw:Transclusion\b/.test(typeOf)) {
+                                               if 
(/(?:^|\s)mw:Transclusion(?=$|\s)/.test(typeOf)) {
                                                        expAccum = 
expansions.transclusions;
                                                        key = 
node.data.parsoid.src;
-                                               } else if 
(/\bmw:Extension\//.test(typeOf)) {
+                                               } else if 
(/(?:^|\s)mw:Extension\//.test(typeOf)) {
                                                        expAccum = 
expansions.extensions;
                                                        key = 
node.data.parsoid.src;
                                                } else {
diff --git a/js/lib/mediawiki.Util.js b/js/lib/mediawiki.Util.js
index 8a12386..192a5c7 100644
--- a/js/lib/mediawiki.Util.js
+++ b/js/lib/mediawiki.Util.js
@@ -192,7 +192,7 @@
                }
 
                // BUG 47854: Treat all mw:Extension/* tokens as non-SOL.
-               if (token.name === 'meta' && 
/\bmw:Extension\//.test(token.getAttribute('typeof'))) {
+               if (token.name === 'meta' && 
/(?:^|\s)mw:Extension\//.test(token.getAttribute('typeof'))) {
                        return false;
                } else {
                        return token.dataAttribs.stx !== 'html';
@@ -906,18 +906,23 @@
        if ( !parsoidOnly ) {
                // Strip comment-and-ws-only lines that PHP parser strips out
                out = out.replace(/\n[ \t]*<!--([^-]|-(?!->))*-->([ 
\t]|<!--([^-]|-(?!->))*-->)*\n/g, '\n');
-               // ignore troublesome attributes
+               // Ignore troublesome attributes.
+               // Strip JSON attributes like data-mw and data-parsoid early so 
that
+               // comment stripping in normalizeNewlines does not match 
unbalanced
+               // comments in wikitext source.
+               out = out.replace(/ 
(data-mw|data-parsoid|resource|rel|prefix|about|rev|datatype|inlist|property|vocab|content|title|class)="[^\"]*"/g,
 '');
                out = normalizeNewlines( out ).
                        // remove <span typeof="....">....</span>
                        replace(/<span(?:[^>]*) 
typeof="mw:(?:Placeholder|Nowiki|Transclusion|Entity)"(?: 
[^\0-\cZ\s\"\'>\/=]+(?:="[^"]*")?)*>((?:[^<]+|(?!<\/span).)*)<\/span>/g, '$1').
-                       replace(/ 
(data-mw|data-parsoid|typeof|resource|rel|prefix|about|rev|datatype|inlist|property|vocab|content|title|class)="[^\"]*"/g,
 '');
+                       // strip typeof last
+                       replace(/ typeof="[^\"]*"/g, '');
        } else {
+               // unnecessary attributes, we don't need to check these
+               // style is in there because we should only check classes.
+               out = out.replace(/ 
(data-parsoid|prefix|about|rev|datatype|inlist|vocab|content|style)="[^\"]*"/g, 
'');
                out = normalizeNewlines( out ).
                        // remove <span typeof="mw:Placeholder">....</span>
                        replace(/<span(?: [^>]+)* typeof="mw:Placeholder"(?: 
[^\0-\cZ\s\"\'>\/=]+(?:="[^"]*")?)*>((?:[^<]+|(?!<\/span).)*)<\/span>/g, '$1').
-                       // unnecessary attributes, we don't need to check these
-                       // style is in there because we should only check 
classes.
-                       replace(/ 
(data-parsoid|prefix|about|rev|datatype|inlist|vocab|content|style)="[^\"]*"/g, 
'').
                        replace(/<\/?(?:meta|link)(?: 
[^\0-\cZ\s"'>\/=]+(?:="[^"]*")?)*\/?>/g, '');
        }
        return out.
diff --git a/js/lib/mediawiki.WikitextSerializer.js 
b/js/lib/mediawiki.WikitextSerializer.js
index 24d1953..2812612 100644
--- a/js/lib/mediawiki.WikitextSerializer.js
+++ b/js/lib/mediawiki.WikitextSerializer.js
@@ -204,7 +204,7 @@
 
                // Ignore non-whitelisted html tags
                if (t.isHTMLTag()) {
-                       if (/\bmw:Extension\b/.test(t.getAttribute("typeof")) &&
+                       if 
(/(?:^|\s)mw:Extension(?=$|\s)/.test(t.getAttribute("typeof")) &&
                                options.extName !== t.getAttribute("name"))
                        {
                                return true;
@@ -696,13 +696,13 @@
         * ----------------------------------------------------------------- */
 
        // SSS FIXME: Move this somewhere else
-       var urlTriggers = /\b(RFC|ISBN|PMID)\b/;
-       var fullCheckNeeded = text.match(urlTriggers);
+       var urlTriggers = /(?:^|\s)(RFC|ISBN|PMID)(?=$|\s)/;
+       var fullCheckNeeded = urlTriggers.test(text);
 
        // Quick check for the common case (useful to kill a majority of 
requests)
        //
        // Pure white-space or text without wt-special chars need not be 
analyzed
-       if (!fullCheckNeeded && !text.match(/(^|\n)[ 
\t]+[^\s]+|[<>\[\]\-\+\|'!=#\*:;~{}]/)) {
+       if (!fullCheckNeeded && !/(^|\n)[ 
\t]+[^\s]+|[<>\[\]\-\+\|'!=#\*:;~{}]/.test(text)) {
                // console.warn("---EWT:F1---");
                return text;
        }
@@ -1138,9 +1138,9 @@
        // Figure out the type of the link
        var rel = node.getAttribute('rel');
        if ( rel ) {
-               var typeMatch = rel.match( /\bmw:[^\b]+/ );
+               var typeMatch = rel.match( /(?:^|\s)(mw:[^\s]+)/ );
                if ( typeMatch ) {
-                       rtData.type = typeMatch[0];
+                       rtData.type = typeMatch[1];
                }
        }
 
@@ -1293,7 +1293,7 @@
                                val = val.value;
                        }
 
-                       if ( rel.match( /\bmw:Image\/Frame\b/ ) && val > 1 ) {
+                       if ( /(?:^|\s)mw:Image\/Frame(?=$|\s)/.test(rel) && val 
> 1 ) {
                                val = 1;
                        }
 
@@ -1879,7 +1879,7 @@
                        // XXX: Use shadowed href? Storing serialized tokens in
                        // data-parsoid seems to be... wrong.
                        cb( '[' + Util.tokensToString(target.value) + ']', 
node);
-               } else if ( rel.match( /\bmw:Image/ ) ) {
+               } else if ( /(?:^|\s)mw:Image/.test(rel) ) {
                        this.handleImage( node, state, cb );
                } else {
                        // Unknown rel was set
@@ -2622,7 +2622,7 @@
                                                }
                                        }
                                        emitEndTag('</nowiki>', node, state, 
cb);
-                               } else if ( type.match( 
/\bmw\:Image(\/(Frame|Frameless|Thumb))?/ ) ) {
+                               } else if ( 
/(?:^|\s)mw\:Image(\/(Frame|Frameless|Thumb))?/.test(type) ) {
                                        state.serializer.handleImage( node, 
state, cb );
                                }
                        } else {
@@ -2771,7 +2771,7 @@
                sepnls: {
                        before: function (node, otherNode) {
                                var type = node.getAttribute('rel');
-                               if (/\bmw:WikiLink\/Category\b/.test(type) &&
+                               if 
(/(?:^|\s)mw:WikiLink\/Category(?=$|\s)/.test(type) &&
                                                
!node.getAttribute('data-parsoid')) {
                                        // Fresh category link: Serialize on 
its own line
                                        return {min: 1};
@@ -2781,7 +2781,7 @@
                        },
                        after: function (node, otherNode) {
                                var type = node.getAttribute('rel');
-                               if (/\bmw:WikiLink\/Category\b/.test(type) &&
+                               if 
(/(?:^|\s)mw:WikiLink\/Category(?=$|\s)/.test(type) &&
                                                
!node.getAttribute('data-parsoid') &&
                                                otherNode.nodeName !== 'BODY')
                                {
@@ -2816,7 +2816,7 @@
 
 WSP._serializeAttributes = function (state, token) {
        function hasExpandedAttrs(tokType) {
-               return tokType && tokType.match(/\bmw:ExpandedAttrs\/[^\s]+/);
+               return (/(?:^|\s)mw:ExpandedAttrs\/[^\s]+/).test(tokType);
        }
 
        var tplAttrState = { kvs: {}, ks: {}, vs: {} },
@@ -3165,11 +3165,11 @@
                typeOf = node.getAttribute( 'typeof' ) || '';
 
        // XXX: Convert into separate handlers?
-       if (/\bmw:(?:Transclusion\b|Param\b|Extension\/[^\s]+)/.test(typeOf)) {
+       if 
(/(?:^|\s)mw:(?:Transclusion(?=$|\s)|Param(?=$|\s)|Extension\/[^\s]+)/.test(typeOf))
 {
                return {
                        handle: function () {
                                var src, dataMW;
-                               if 
(/\bmw:(Transclusion\b|Param\b)/.test(typeOf)) {
+                               if 
(/(?:^|\s)mw:(Transclusion(?=$|\s)|Param(?=$|\s))/.test(typeOf)) {
                                        dataMW = 
JSON.parse(node.getAttribute("data-mw"));
                                        if (dataMW) {
                                                src = 
state.serializer._buildTemplateWT(node,
@@ -3178,7 +3178,7 @@
                                                console.error("ERROR: No 
data-mw for: " + node.outerHTML);
                                                src = dp.src;
                                        }
-                               } else if (/\bmw:Extension\//.test(typeOf)) {
+                               } else if 
(/(?:^|\s)mw:Extension\//.test(typeOf)) {
                                        dataMW = 
JSON.parse(node.getAttribute("data-mw"));
                                        src = !dataMW ? dp.src : 
state.serializer._buildExtensionWT(state, node, dataMW);
                                } else {
@@ -3964,7 +3964,7 @@
 
                                        // Skip over encapsulated content since 
it has already been serialized
                                        var typeOf = node.getAttribute( 
'typeof' ) || '';
-                                       if 
(/\bmw:(?:Transclusion\b|Param\b|Extension\/[^\s]+)/.test(typeOf)) {
+                                       if 
(/(?:^|\s)mw:(?:Transclusion(?=$|\s)|Param(?=$|\s)|Extension\/[^\s]+)/.test(typeOf))
 {
                                                nextNode = 
DU.skipOverEncapsulatedContent(node);
                                        }
                                } else if (DU.onlySubtreeChanged(node, 
this.env) &&
diff --git a/js/lib/mediawiki.parser.defines.js 
b/js/lib/mediawiki.parser.defines.js
index 85ab460..3bbaa9a 100644
--- a/js/lib/mediawiki.parser.defines.js
+++ b/js/lib/mediawiki.parser.defines.js
@@ -160,7 +160,7 @@
                        var type = Util.lookup(this.attribs, 'typeof'),
                                about = Util.lookup(this.attribs, 'about'),
                                tplAttrState = tplAttrs[about];
-                       if (type && type.match(/\bmw:ExpandedAttrs\/[^\s]+/) &&
+                       if (/(?:^|\s)mw:ExpandedAttrs\/[^\s]+/.test(type) &&
                                        tplAttrState &&
                                        tplAttrState.vs[name] )
                        {
diff --git a/js/tests/parserTests-blacklist.js 
b/js/tests/parserTests-blacklist.js
index 6bd2c5a..7d4d3b8 100644
--- a/js/tests/parserTests-blacklist.js
+++ b/js/tests/parserTests-blacklist.js
@@ -147,8 +147,6 @@
 add("wt2html", "1. includeonly in html attr key");
 add("wt2html", "2. includeonly in html attr value");
 add("wt2html", "3. includeonly in part of an attr value");
-add("wt2html", "Templates: P-wrapping: 1a. Templates on consecutive lines");
-add("wt2html", "Templates: P-wrapping: 1b. Templates on consecutive lines");
 add("wt2html", "Templates: Links: 2. Generation of link href");
 add("wt2html", "Templates: Links: 3. Generation of part of a link href");
 add("wt2html", "Templates: Links: 4. Multiple templates generating link href");
@@ -398,7 +396,6 @@
 add("wt2html", "Non-transclusion because of too many up levels");
 add("wt2html", "MSGNW magic word");
 add("wt2html", "RAW magic word");
-add("wt2html", "Template caching");
 add("wt2html", "anchorencode");
 add("wt2html", "anchorencode trims spaces");
 add("wt2html", "anchorencode deals with links");

-- 
To view, visit https://gerrit.wikimedia.org/r/82562
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I596623b5a96c41b9b1411db2a70630f08251ffe4
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/Parsoid
Gerrit-Branch: master
Gerrit-Owner: GWicke <[email protected]>
Gerrit-Reviewer: GWicke <[email protected]>
Gerrit-Reviewer: Subramanya Sastry <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to