GWicke has uploaded a new change for review. https://gerrit.wikimedia.org/r/84871
Change subject: WIP: Major DOM spec cleanup ...................................................................... WIP: Major DOM spec cleanup * mw:WikiLink/Interwiki becomes mw:ExtLink. We automatically serialize links matching an interwiki URL as wiki links. * mw:ExtLink/* all become just mw:ExtLink. We transparently handle the serialization to special ISBN/RFC/PMID and auto-numbered forms. Auto-numbered external links now have an empty content, which will be auto-numbered with CSS as documented in bug 53505. * mw:WikiLink/Category becomes mw:PageProp/Category * mw:WikiLink/Language becomes mw:PageProp/Language Change-Id: I0f0a826c6a56e9d74d92fefdc29dc2503e7908e3 --- M js/lib/ext.core.LinkHandler.js M js/lib/mediawiki.Util.js M js/lib/mediawiki.WikiConfig.js M js/lib/mediawiki.WikitextSerializer.js M js/lib/mediawiki.wikitext.constants.js M js/lib/pegTokenizer.pegjs.txt M js/tests/parserTests.txt 7 files changed, 218 insertions(+), 67 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Parsoid refs/changes/71/84871/1 diff --git a/js/lib/ext.core.LinkHandler.js b/js/lib/ext.core.LinkHandler.js index 3343c3d..627e4bc 100644 --- a/js/lib/ext.core.LinkHandler.js +++ b/js/lib/ext.core.LinkHandler.js @@ -359,8 +359,8 @@ newTk = new SelfclosingTagTk('link'), content = this.addLinkAttributesAndGetContent(newTk, token, target); - // Change the rel to be mw:WikiLink / Category - Util.lookupKV( newTk.attribs, 'rel' ).v += '/Category'; + // Change the rel to be mw:PageProp/Category + Util.lookupKV( newTk.attribs, 'rel' ).v = 'mw:PageProp/Category'; var strContent = Util.tokensToString( content ), saniContent = Util.sanitizeTitleURI( strContent ).replace( /#/g, '%23' ); @@ -414,8 +414,8 @@ var absHref = target.language.url.replace( "$1", target.href ); newTk.addNormalizedAttribute('href', absHref, target.hrefSrc); - // Change the rel to be mw:WikiLink/Language - Util.lookupKV( newTk.attribs, 'rel' ).v = 'mw:WikiLink/Language'; + // Change the rel to be mw:PageProp/Language + Util.lookupKV( newTk.attribs, 'rel' ).v = 'mw:PageProp/Language'; cb({tokens: [newTk]}); }; @@ -434,8 +434,8 @@ var absHref = target.interwiki.url.replace( "$1", target.href ); newTk.addNormalizedAttribute('href', absHref, target.hrefSrc); - // Change the rel to be mw:WikiLink/Interwiki - Util.lookupKV( newTk.attribs, 'rel' ).v = 'mw:WikiLink/Interwiki'; + // Change the rel to be mw:ExtLink + Util.lookupKV( newTk.attribs, 'rel' ).v = 'mw:ExtLink'; tokens.push( newTk ); @@ -1348,9 +1348,9 @@ var dataAttribs = Util.clone(token.dataAttribs); var rdfaType = token.getAttribute('typeof'), - magLinkRe = /(?:^|\s)(mw:ExtLink\/(?:ISBN|RFC|PMID))(?=$|\s)/; + magLinkRe = /(?:^|\s)(mw:(?:Ext|Wiki)Link\/(?:ISBN|RFC|PMID))(?=$|\s)/; if ( rdfaType && magLinkRe.test(rdfaType) ) { - if ( /(?:^|\s)mw:ExtLink\/ISBN/.test(rdfaType) ) { + if ( /(?:^|\s)mw:WikiLink\/ISBN/.test(rdfaType) ) { title = Title.fromPrefixedText( env, href ); newAttrs = [ new KV('href', title.makeLink()), @@ -1359,9 +1359,10 @@ } else { newAttrs = [ new KV('href', href), - new KV('rel', rdfaType.match( magLinkRe )[1] ) + new KV('rel', 'mw:ExtLink' ) ]; } + token.removeAttribute('typeof'); // SSS FIXME: Right now, Parsoid does not support templating // of ISBN attributes. So, "ISBN {{echo|1234567890}}" will not @@ -1379,9 +1380,8 @@ } else if ( this.urlParser.tokenizeURL( href )) { rdfaType = 'mw:ExtLink'; if ( ! content.length ) { - content = ['[' + this.linkCount + ']']; - this.linkCount++; - rdfaType = 'mw:ExtLink/Numbered'; + //content = ['[' + this.linkCount + ']']; + //this.linkCount++; } else if ( content.length === 1 && content[0].constructor === String && this.urlParser.tokenizeURL( content[0] ) && diff --git a/js/lib/mediawiki.Util.js b/js/lib/mediawiki.Util.js index 192a5c7..4a49086 100644 --- a/js/lib/mediawiki.Util.js +++ b/js/lib/mediawiki.Util.js @@ -177,7 +177,7 @@ var tc = token.constructor; return (tc === pd.SelfclosingTagTk || tc === pd.TagTk || tc === pd.EndTagTk) && token.name === 'link' && - /mw:(WikiLink\/Category|PageProp\/redirect)/.test(token.getAttribute('rel')); + /mw:PageProp\/(?:Category|redirect)/.test(token.getAttribute('rel')); }, isSolTransparent: function(token) { @@ -911,19 +911,21 @@ // 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 ). + out = normalizeNewlines( out ) // remove <span typeof="....">....</span> - replace(/<span(?:[^>]*) typeof="mw:(?:Placeholder|Nowiki|Transclusion|Entity)"(?: [^\0-\cZ\s\"\'>\/=]+(?:="[^"]*")?)*>((?:[^<]+|(?!<\/span).)*)<\/span>/g, '$1'). + .replace(/<span(?:[^>]*) typeof="mw:(?:Placeholder|Nowiki|Transclusion|Entity)"(?: [^\0-\cZ\s\"\'>\/=]+(?:="[^"]*")?)*>((?:[^<]+|(?!<\/span).)*)<\/span>/g, '$1') + // Remove auto-numbered links as we are emitting empty links instead + .replace(/(<a [^>]+>)\[\d+\](<\/a>)/g, '$1$2') // strip typeof last - replace(/ typeof="[^\"]*"/g, ''); + .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 ). + out = normalizeNewlines( out ) // remove <span typeof="mw:Placeholder">....</span> - replace(/<span(?: [^>]+)* typeof="mw:Placeholder"(?: [^\0-\cZ\s\"\'>\/=]+(?:="[^"]*")?)*>((?:[^<]+|(?!<\/span).)*)<\/span>/g, '$1'). - replace(/<\/?(?:meta|link)(?: [^\0-\cZ\s"'>\/=]+(?:="[^"]*")?)*\/?>/g, ''); + .replace(/<span(?: [^>]+)* typeof="mw:Placeholder"(?: [^\0-\cZ\s\"\'>\/=]+(?:="[^"]*")?)*>((?:[^<]+|(?!<\/span).)*)<\/span>/g, '$1') + .replace(/<\/?(?:meta|link)(?: [^\0-\cZ\s"'>\/=]+(?:="[^"]*")?)*\/?>/g, ''); } return out. // replace mwt ids @@ -976,6 +978,8 @@ .replace(/href="#/g, 'href="Main Page#') // replace unnecessary URL escaping .replace(/ href="[^"]*"/g, Util.decodeURI) + // Remove auto-numbered links as we are emitting empty links instead + .replace(/(<a [^>]+>)\[\d+\](<\/a>)/g, '$1$2') // strip empty spans .replace(/<span><\/span>/g, '') .replace(/(<(table|tbody|tr|th|td|\/th|\/td)[^<>]*>)\s+/g, '$1'); @@ -1401,6 +1405,14 @@ } }; +/** + * Escape special regexp characters in a string used to build a regexp + */ +Util.escapeRegExp = function(s) { + return s.replace(/[\^\\$*+?.()|{}\[\]\/]/g, '\\$&'); +}; + + if (typeof module === "object") { module.exports.Util = Util; } diff --git a/js/lib/mediawiki.WikiConfig.js b/js/lib/mediawiki.WikiConfig.js index e8cf480..f4768a8 100644 --- a/js/lib/mediawiki.WikiConfig.js +++ b/js/lib/mediawiki.WikiConfig.js @@ -10,11 +10,6 @@ // Make sure our base config is never modified JSUtils.deepFreeze(baseConfig); -// escape 'special' characters in a regexp, returning a regexp which matches -// the string exactly -var re_escape = function(s) { - return s.replace(/[\^\\$*+?.()|{}\[\]]/g, '\\$&'); -}; /** * @class @@ -28,7 +23,8 @@ */ function WikiConfig( resultConf, prefix, uri ) { var nsid, - name; + name, + conf = this; // Mapping from canonical namespace name to id @@ -132,7 +128,7 @@ if (!this.interwikiMap[entry.code]) { this.interwikiMap[entry.code] = { prefix: entry.code, - url: 'http://' + entry.code + '.wikipedia.org/wiki/$1', + url: '//' + entry.code + '.wikipedia.org/wiki/$1', language: entry['*'] }; } else if (!this.interwikiMap[entry.code].language) { @@ -141,6 +137,48 @@ this.interwikiMap[entry.code].language = entry['*']; } } + + this.InterWikiMatcher = (function () { + var keys = Object.keys(conf.interwikiMap), + patterns = []; + keys.forEach(function(key) { + patterns.push( + // Avoid regexp escaping on placeholder + Util.escapeRegExp( + conf.interwikiMap[key].url.replace('$1', '%1') + ) + // Now convert placeholder to group match + .replace('%1', '(.*?)') + ); + }); + var reString = '^(?:' + patterns.join('|') + ')$', + regExp = new RegExp(reString); + var match = function (s) { + var matches = s.match(regExp); + if (matches) { + var groups = matches.slice(1); + for (var i=0; i<groups.length; i++) { + if (groups[i] !== undefined) { + // The prefix: 'en', 'de' etc + var key = keys[i]; + if (conf.interwikiMap[key].language) { + // Escape language interwikis with a colon + key = ':' + key; + } + return [ + key, + groups[i] + ]; + } + } + } + return false; + }; + return { + match: match + }; + })(); + // "mw" here refers to "magicwords", not "mediawiki" var mws = resultConf.magicwords; @@ -186,7 +224,7 @@ } this._mwRegexps[mw.name] = new RegExp( '^(' + - this.mwAliases[mw.name].map(re_escape).join('|') + + this.mwAliases[mw.name].map(Util.escapeRegExp).join('|') + ')$', mw['case-sensitive'] === '' ? '' : 'i' ); } @@ -422,6 +460,55 @@ return alias.replace( /\$1/, value ); }; + + +// Default RFC/PMID resource URL patterns +WikiConfig.prototype.ExtResourceURLPatterns = { + 'RFC' : '//tools.ietf.org/html/rfc%s', + 'PMID' : '//www.ncbi.nlm.nih.gov/pubmed/%s?dopt=Abstract' +}; + +/** + * Matcher for RFC/PMID URL patterns, returning the type and number. The match + * method takes a string and returns false on no match or a tuple like this on match: + * ['RFC', '12345'] + */ +WikiConfig.prototype.ExtResourceURLPatternMatcher = (function () { + var keys = Object.keys(WikiConfig.prototype.ExtResourceURLPatterns), + patterns = []; + keys.forEach(function(key) { + patterns.push( + Util.escapeRegExp(WikiConfig.prototype.ExtResourceURLPatterns[key]) + .replace('%s', '(\\w+)') + ); + }); + var reString = '^(?:' + patterns.join('|') + ')$', + regExp = new RegExp(reString); + var match = function (s) { + var matches = s.match(regExp); + if (matches) { + var groups = matches.slice(1); + for (var i=0; i<groups.length; i++) { + if (groups[i] !== undefined) { + return [ + // The key: 'PMID', 'RFC' etc + keys[i], + groups[i] + ]; + } + } + } + return false; + }; + return { + match: match + }; +})(); + +/** + * Matcher for interwiki prefixes. + */ + /** * @param {string} potentialLink */ @@ -452,6 +539,7 @@ this.extensionTags[newTag] = true; }; + /** * @param {string} tagName */ diff --git a/js/lib/mediawiki.WikitextSerializer.js b/js/lib/mediawiki.WikitextSerializer.js index 83bdd04..e3601ad 100644 --- a/js/lib/mediawiki.WikitextSerializer.js +++ b/js/lib/mediawiki.WikitextSerializer.js @@ -1215,7 +1215,7 @@ }; // Categories dont need prefix/suffix nowiki-escaping - if (linkData.type === 'mw:WikiLink/Category' ) { + if (linkData.type === 'mw:PageProp/Category' ) { return escapes; } @@ -1666,17 +1666,49 @@ if ( linkData.type !== null && linkData.target.value !== null ) { // We have a type and target info - var target = linkData.target; + // Temporary backwards-compatibility for types + if (linkData.type === 'mw:WikiLink/Category') { + linkData.type = 'mw:PageProp/Category'; + } else if (linkData.type === 'mw:WikiLink/Language') { + linkData.type = 'mw:PageProp/Language'; + } else if (/^mw:ExtLink\//.test(linkData.type)) { + linkData.type = 'mw:ExtLink'; + } - if (/^mw:WikiLink(\/(Category|Language|Interwiki))?$/.test( linkData.type ) || - /^mw:PageProp\/redirect$/.test( linkData.type ) ) { + var target = linkData.target; + if (/mw.ExtLink/.test(linkData.type)) { + var targetVal = target.fromsrc || true ? target.value : Util.decodeURI(target.value); + // Check if the href matches any of our interwiki URL patterns + var href = node.getAttribute('href') || '', + interWikiMatch = env.conf.wiki.InterWikiMatcher.match(href); + if (interWikiMatch) { + console.log(interWikiMatch); + // External link that is really an interwiki link. Convert it. + linkData.type = 'mw:WikiLink'; + linkData.isInterwiki = true; + var oldPrefix = target.value.match(/^(:?[^:]+):/); + if (oldPrefix && + oldPrefix[1].toLowerCase() === interWikiMatch[0].toLowerCase()) + { + // Reuse old prefix capitalization + console.log(oldPrefix[1], interWikiMatch); + target.value = oldPrefix[1] + ':' + interWikiMatch[1]; + } else { + target.value = interWikiMatch.join(':'); + } + } + } + + if (/^mw:WikiLink$/.test( linkData.type ) || + /^mw:PageProp\/(?:redirect|Category|Language)$/.test( linkData.type ) ) { // Decode any link that did not come from the source if (! target.fromsrc) { target.value = Util.decodeURI(target.value); } // Special-case handling for category links - if ( linkData.type === 'mw:WikiLink/Category' ) { + if ( linkData.type === 'mw:WikiLink/Category' || + linkData.type === 'mw:PageProp/Category' ) { // Split target and sort key var targetParts = target.value.match( /^([^#]*)#(.*)/ ); if ( targetParts ) { @@ -1718,7 +1750,7 @@ linkData.content.fromsrc = true; } //} - } else if ( linkData.type === 'mw:WikiLink/Language' ) { + } else if ( linkData.type === 'mw:PageProp/Language' ) { // Fix up the the content string // TODO: see if linkData can be cleaner! if (linkData.content.string === undefined) { @@ -1768,9 +1800,9 @@ ( dp.stx !== 'piped' && !dp.pipetrick ) ), canUsePipeTrick = - linkData.type === 'mw:WikiLink/Language' || + linkData.type === 'mw:PageProp/Language' || contentString !== undefined && - linkData.type !== 'mw:WikiLink/Category' && + linkData.type !== 'mw:PageProp/Category' && ( Util.stripPipeTrickChars(strippedTargetValue) === contentString || @@ -1784,7 +1816,7 @@ env.normalizeTitle(contentString) || // Interwiki links with pipetrick have their prefix // stripped, so compare against a stripped version - ( linkData.type === 'mw:WikiLink/Interwiki' && + ( linkData.isInterwiki && dp.pipetrick && env.normalizeTitle( contentString ) === target.value.replace(/^:?[a-zA-Z]+:/, '') ) @@ -1835,7 +1867,7 @@ } if ( contentSrc === '' && ! willUsePipeTrick && - linkData.type !== 'mw:WikiLink/Category' ) { + linkData.type !== 'mw:PageProp/Category' ) { // Protect empty link content from PST pipe trick contentSrc = '<nowiki/>'; } @@ -1847,11 +1879,12 @@ linkData.tail + escapes.tail, node ); return; } - } else if ( rel === 'mw:ExtLink' ) { + } else if ( rel === 'mw:ExtLink' || rel === 'mw:ExtLink/Numbered' ) { // Get plain text content, if any var contentStr = node.childNodes.length === 1 && node.firstChild.nodeType === node.TEXT_NODE && node.firstChild.nodeValue; + // First check if we can serialize as an URL link if ( contentStr && // Can we minimize this? ( target.value === contentStr || @@ -1862,23 +1895,40 @@ // Serialize as URL link cb(target.value, node); } else { + // TODO: match vs. interwikis too + var href = node.getAttribute('href') || '', + extLinkResourceMatch = env.conf.wiki.ExtResourceURLPatternMatcher + .match(href); // Fully serialize the content contentStr = state.serializeChildrenToString(node, this.wteHandlers.aHandler, false); - // We expect modified hrefs to be percent-encoded already, so - // don't need to encode them here any more. Unmodified hrefs are - // just using the original encoding anyway. - cb( '[' + target.value + ' ' + contentStr + ']', node ); + // First check for RFC/PMID links. We rely on selser to + // preserve non-minimal forms. + if (extLinkResourceMatch && contentStr === extLinkResourceMatch.join(' ')) { + // link target matches and link text is RFC 1234 or + // PMID 1234: Serialize to that + cb( extLinkResourceMatch.join(' '), node ); + // There is an interwiki for RFCs, but strangely none for + // PMIDs. + } else if (!contentStr) { + // serialize as auto-numbered external link + // [http://example.com] + cb( '[' + target.value + ']', node); + } else { + + // We expect modified hrefs to be percent-encoded already, so + // don't need to encode them here any more. Unmodified hrefs are + // just using the original encoding anyway. + cb( '[' + target.value + ' ' + contentStr + ']', node ); + } } - } else if ( rel === 'mw:ExtLink/URL' ) { - cb( target.value, node ); - } else if ( rel.match( /mw:ExtLink\/(?:ISBN|RFC|PMID)/ ) ) { + } else if ( rel.match( /mw:ExtLink\/(?:RFC|PMID)/ ) || + /mw:(?:Wiki|Ext)Link\/ISBN/.test(rel) ) { + // FIXME: Handle RFC/PMID in generic ExtLink handler by matching prefixes! + // FIXME: Handle ISBN in generic WikiLink handler by looking for + // Special:BookSources! cb( node.firstChild.nodeValue, node ); - } else if ( rel === 'mw:ExtLink/Numbered' ) { - // XXX: Use shadowed href? Storing serialized tokens in - // data-parsoid seems to be... wrong. - cb( '[' + Util.tokensToString(target.value) + ']', node); } else if ( /(?:^|\s)mw:Image/.test(rel) ) { this.handleImage( node, state, cb ); } else { @@ -1914,8 +1964,8 @@ this._htmlElementHandler(node, state, cb); } else { // encodeURI only encodes spaces and the like - var href = encodeURI(node.getAttribute('href')); - cb( '[' + href + ' ' + + var hrefStr = encodeURI(node.getAttribute('href')); + cb( '[' + hrefStr + ' ' + state.serializeChildrenToString(node, this.wteHandlers.aHandler, false) + ']', node ); } @@ -2784,7 +2834,7 @@ sepnls: { before: function (node, otherNode) { var type = node.getAttribute('rel'); - if (/(?:^|\s)mw:WikiLink\/Category(?=$|\s)/.test(type) && + if (/(?:^|\s)mw:PageProp\/Category(?=$|\s)/.test(type) && !node.getAttribute('data-parsoid')) { // Fresh category link: Serialize on its own line return {min: 1}; @@ -2794,7 +2844,7 @@ }, after: function (node, otherNode) { var type = node.getAttribute('rel'); - if (/(?:^|\s)mw:WikiLink\/Category(?=$|\s)/.test(type) && + if (/(?:^|\s)mw:PageProp\/Category(?=$|\s)/.test(type) && !node.getAttribute('data-parsoid') && otherNode.nodeName !== 'BODY') { diff --git a/js/lib/mediawiki.wikitext.constants.js b/js/lib/mediawiki.wikitext.constants.js index d96c659..be21a34 100644 --- a/js/lib/mediawiki.wikitext.constants.js +++ b/js/lib/mediawiki.wikitext.constants.js @@ -216,6 +216,7 @@ } }; + // Fill in reverse map of prefix options. Object.keys(WikitextConstants.Image.PrefixOptions).forEach(function(k) { var v = WikitextConstants.Image.PrefixOptions[k]; diff --git a/js/lib/pegTokenizer.pegjs.txt b/js/lib/pegTokenizer.pegjs.txt index 7899994..25813ab 100644 --- a/js/lib/pegTokenizer.pegjs.txt +++ b/js/lib/pegTokenizer.pegjs.txt @@ -877,7 +877,7 @@ new SelfclosingTagTk( 'extlink', [ new KV('href', 'Special:BookSources/' + isbncode), new KV('mw:content', 'ISBN ' + isbn), - new KV('typeof', 'mw:ExtLink/ISBN') + new KV('typeof', 'mw:WikiLink/ISBN') ], {tsr: [pos0, pos]}) ]; diff --git a/js/tests/parserTests.txt b/js/tests/parserTests.txt index 61c5ed4..0316622 100644 --- a/js/tests/parserTests.txt +++ b/js/tests/parserTests.txt @@ -2139,9 +2139,9 @@ [[Category:foo]] <!-- No pre-wrapping --> {{echo| [[Category:foo]]}} <!-- No pre-wrapping --> !! result - <link rel="mw:WikiLink/Category" href="./Category:Foo"> <!-- No pre-wrapping --> + <link rel="mw:PageProp/Category" href="./Category:Foo"> <!-- No pre-wrapping --> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" [[Category:foo]]"}},"i":0}}]}'> </span> -<link rel="mw:WikiLink/Category" href="./Category:Foo" about="#mwt1"> <!-- No pre-wrapping --> +<link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1"> <!-- No pre-wrapping --> !! end !! test @@ -2153,9 +2153,9 @@ [[Category:foo]] {{echo|b}} !! result <pre> -<link rel="mw:WikiLink/Category" href="./Category:Foo"> a +<link rel="mw:PageProp/Category" href="./Category:Foo"> a -<link rel="mw:WikiLink/Category" href="./Category:Foo"> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b"}},"i":0}}]}'>b</span></pre> +<link rel="mw:PageProp/Category" href="./Category:Foo"> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b"}},"i":0}}]}'>b</span></pre> !! end ### @@ -5209,7 +5209,7 @@ [[ko:]] !! result <p> -<link rel="mw:WikiLink/Language" href="http://ko.wikipedia.org/wiki/"></p> +<link rel="mw:PageProp/Language" href="http://ko.wikipedia.org/wiki/"></p> !! end !! test @@ -5219,7 +5219,7 @@ !! input [[:ko:]] !! result -<p><a rel="mw:WikiLink/Interwiki" href="http://ko.wikipedia.org/wiki/">ko:</a></p> +<p><a rel="mw:ExtLink" href="//ko.wikipedia.org/wiki/">ko:</a></p> !! end ### @@ -5282,7 +5282,7 @@ !! input #REDIRECT [[Category:Foo]] !! result -<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:WikiLink/Category" href="./Category:Foo"> +<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:PageProp/Category" href="./Category:Foo"> !! end !! test @@ -5292,7 +5292,7 @@ !! input #REDIRECT [[Category%3AFoo]] !! result -<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:WikiLink/Category" href="./Category:Foo"> +<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:PageProp/Category" href="./Category:Foo"> !! end !! test @@ -7847,9 +7847,9 @@ <!--Two categories (Bug 50330)--> <table>[[Category:bar1]][[Category:bar2]]<tr><td>foo</td></tr></table> !!result -<link rel="mw:WikiLink/Category" href="./Category:Foo1"><table><tbody><tr><td>foo</td></tr></tbody></table> +<link rel="mw:PageProp/Category" href="./Category:Foo1"><table><tbody><tr><td>foo</td></tr></tbody></table> <!--Two categories (Bug 50330)--> -<link rel="mw:WikiLink/Category" href="./Category:Bar1"><link rel="mw:WikiLink/Category" href="./Category:Bar2"><table><tbody><tr><td>foo</td></tr></tbody></table> +<link rel="mw:PageProp/Category" href="./Category:Bar1"><link rel="mw:PageProp/Category" href="./Category:Bar2"><table><tbody><tr><td>foo</td></tr></tbody></table> !!end !!test @@ -9970,7 +9970,7 @@ !! input x[[Category:Foo]]y !! result -<p>x<link rel="mw:WikiLink/Category" href="Category:Foo">y</p> +<p>x<link rel="mw:PageProp/Category" href="Category:Foo">y</p> !! end !! test @@ -9996,8 +9996,8 @@ [[Category:Foo]] [[Category:Foo|Bar]] !! result -<link rel="mw:WikiLink/Category" href="Category:Foo"> -<link rel="mw:WikiLink/Category" href="Category:Foo#Bar"> +<link rel="mw:PageProp/Category" href="Category:Foo"> +<link rel="mw:PageProp/Category" href="Category:Foo#Bar"> !! end ### -- To view, visit https://gerrit.wikimedia.org/r/84871 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0f0a826c6a56e9d74d92fefdc29dc2503e7908e3 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Parsoid Gerrit-Branch: master Gerrit-Owner: GWicke <gwi...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits