jenkins-bot has submitted this change and it was merged. Change subject: Bug 46027, bug 49484: Drop mw:ExtLink/URL ......................................................................
Bug 46027, bug 49484: Drop mw:ExtLink/URL * Changes to the content of URL links in VE were not properly handled, as the VE never changed the type to mw:ExtLink on such change. * Instead of requiring clients to implement such a type change, abstract syntactical detail about URL link vs. bracketed external link in Parsoid. Automatically switch between formats as required, but preserve non-minimal links of the form [http://example.com http://example.com]. * Serializer support for mw:ExtLink/URL remains, so cached HTML will continue to work for now. This can be dropped after cache clearing. * The VE handles mw:ExtLink content well, and will also do so for links that were formerly marked as mw:ExtLink/URL. Once cached HTML is cleared the VE can also drop mw:ExtLink/URL handling. Change-Id: Ibb4c27b799016c7a41efb23c03978794c1d2f012 --- M js/lib/ext.core.LinkHandler.js M js/lib/mediawiki.DOMPostProcessor.js M js/lib/mediawiki.Util.js M js/lib/mediawiki.WikitextSerializer.js M js/lib/pegTokenizer.pegjs.txt 5 files changed, 55 insertions(+), 30 deletions(-) Approvals: Subramanya Sastry: Looks good to me, approved jenkins-bot: Verified diff --git a/js/lib/ext.core.LinkHandler.js b/js/lib/ext.core.LinkHandler.js index 86dff08..71db862 100644 --- a/js/lib/ext.core.LinkHandler.js +++ b/js/lib/ext.core.LinkHandler.js @@ -789,7 +789,8 @@ // Reset the optInfo since we're changing the nature of it optInfo = undefined; // Figure out the proper string to put here and break. - if ( tokenType === 'mw:ExtLink/URL' ) { + if ( tokenType === 'mw:ExtLink' && + currentToken.dataAttribs.stx === 'url' ) { // Add the URL resultStr += tkHref; // Tell our loop to skip to the end of this tag @@ -1261,13 +1262,14 @@ cb( { tokens: [ new SelfclosingTagTk('img', tagAttrs, dataAttribs) ] } ); } else { tagAttrs = [ - new KV( 'rel', 'mw:ExtLink/URL' ) + new KV( 'rel', 'mw:ExtLink' ) // href is set explicitly below ]; // combine with existing rdfa attrs tagAttrs = buildLinkAttrs(token.attribs, false, null, tagAttrs).attribs; builtTag = new TagTk( 'a', tagAttrs, dataAttribs ); + dataAttribs.stx = 'url'; if (origTxt) { // origTxt will be null for content from templates @@ -1283,7 +1285,7 @@ tokens: [ builtTag, txt, - new EndTagTk( 'a' ) + new EndTagTk( 'a', [], {tsr: [dataAttribs.tsr[1], dataAttribs.tsr[1]]} ) ] } ); } diff --git a/js/lib/mediawiki.DOMPostProcessor.js b/js/lib/mediawiki.DOMPostProcessor.js index dd534f3..1a66490 100644 --- a/js/lib/mediawiki.DOMPostProcessor.js +++ b/js/lib/mediawiki.DOMPostProcessor.js @@ -1995,7 +1995,7 @@ } else { return [2, 2]; } - } else if (aType === "mw:ExtLink" && dp.tsr) { + } else if (aType === "mw:ExtLink" && dp.tsr && dp.stx !== 'url') { return [dp.targetOff - dp.tsr[0], 1]; } else { return null; diff --git a/js/lib/mediawiki.Util.js b/js/lib/mediawiki.Util.js index 8c22ce6..0e4fe18 100644 --- a/js/lib/mediawiki.Util.js +++ b/js/lib/mediawiki.Util.js @@ -1539,6 +1539,20 @@ html_old_names[name] === true; }; +/** + * Determine whether the protocol of a link is potentially valid. Use the + * environment's per-wiki config to do so. + */ +Util.isProtocolValid = function ( linkTarget, env ) { + var wikiConf = env.conf.wiki; + if ( typeof linkTarget === 'string' ) { + return wikiConf.hasValidProtocol( linkTarget ); + } else { + return true; + } +}; + + if (typeof module === "object") { module.exports.Util = Util; } diff --git a/js/lib/mediawiki.WikitextSerializer.js b/js/lib/mediawiki.WikitextSerializer.js index 168fb18..1d3c760 100644 --- a/js/lib/mediawiki.WikitextSerializer.js +++ b/js/lib/mediawiki.WikitextSerializer.js @@ -809,7 +809,7 @@ console.warn("Toks: " + JSON.stringify(tokens)); } var tkSrc = arg.substring(da.tsr[0], da.tsr[1]); - // Replace pipe by an entity + // Replace pipe by an entity. This is not completely safe. if (t.name === 'extlink' || t.name === 'urllink') { tkSrc = tkSrc.replace(/\|/g, '|'); } @@ -1643,7 +1643,7 @@ // Protect empty link content from PST pipe trick contentSrc = '<nowiki/>'; } - linkTarget = linkData.target.value; + linkTarget = target.value; linkTarget = this._addColonEscape(linkTarget, linkData); cb( escapes.prefix + linkData.prefix + @@ -1652,20 +1652,37 @@ return; } } else if ( rel === 'mw:ExtLink' ) { - // 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 + ' ' + - state.serializeChildrenToString(node, this.wteHandlers.aHandler, false) + - ']', node ); + // Get plain text content, if any + var contentStr = node.childNodes.length === 1 && + node.firstChild.nodeType === node.TEXT_NODE && + node.firstChild.nodeValue; + if ( contentStr && + // Can we minimize this? + ( target.value === contentStr || + node.getAttribute('href') === contentStr) && + // But preserve non-minimal encoding + (target.modified || linkData.contentModified || dp.stx === 'url')) + { + // Serialize as URL link + cb(target.value, node); + } else { + // 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 ); + } + } else if ( rel === 'mw:ExtLink/URL' ) { + cb( target.value, node ); } else if ( rel.match( /mw:ExtLink\/(?:ISBN|RFC|PMID)/ ) ) { cb( node.firstChild.nodeValue, node ); - } else if ( rel === 'mw:ExtLink/URL' ) { - cb( linkData.target.value, node ); } else if ( rel === 'mw:ExtLink/Numbered' ) { // XXX: Use shadowed href? Storing serialized tokens in // data-parsoid seems to be... wrong. - cb( '[' + Util.tokensToString(linkData.target.value) + ']', node); + cb( '[' + Util.tokensToString(target.value) + ']', node); } else if ( rel.match( /\bmw:Image/ ) ) { this.handleImage( node, state, cb ); } else { diff --git a/js/lib/pegTokenizer.pegjs.txt b/js/lib/pegTokenizer.pegjs.txt index 105087f..7a1f6c3 100644 --- a/js/lib/pegTokenizer.pegjs.txt +++ b/js/lib/pegTokenizer.pegjs.txt @@ -162,19 +162,6 @@ return false; }; - /** - * Determine whether the protocol of a link is potentially valid. Use the environment's per-wiki config to do so. - */ - function isProtocolValid( linkTarget ) { - var env = pegArgs.env, - wikiConf = env.conf.wiki; - - if ( typeof linkTarget === 'string' ) { - return wikiConf.hasValidProtocol( linkTarget ); - } else { - return true; - } - } /** * Get an attribute value and source, given a start and end position. Returned object will have a 'value' property @@ -806,7 +793,7 @@ & { return stops.push('extlink', true); } //target:urllink target:extlink_preprocessor_text - & { return isProtocolValid( target ); } + & { return Util.isProtocolValid( target, pegArgs.env ); } sp:( space / [\u00A0\u1680\u180E\u2000-\u200A\u202F\u205F\u3000] )* targetOff:({ return pos; }) content:( @@ -895,7 +882,12 @@ /* Default URL protocols in MediaWiki (see DefaultSettings). Normally * these can be configured dynamically. */ -url_protocol = & { return isProtocolValid( input.substr( pos ) ); } h:[a-zA-Z\/]+ c:':'? s:'//'? { return h.join( '' ) + c + s; } +url_protocol = + & { return Util.isProtocolValid( input.substr( pos ), pegArgs.env ); } + h:[a-zA-Z\/]+ c:':'? s:'//'? +{ + return h.join( '' ) + c + s; +} // javascript does not support unicode features.. unicode_separator_space = [ \u00A0\u1680\u180E\u2000-\u200A\u202F\u205F\u3000] -- To view, visit https://gerrit.wikimedia.org/r/71162 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ibb4c27b799016c7a41efb23c03978794c1d2f012 Gerrit-PatchSet: 7 Gerrit-Project: mediawiki/extensions/Parsoid Gerrit-Branch: master Gerrit-Owner: 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
