Arlolra has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/264026

Change subject: WIP: Native <gallery> extension
......................................................................

WIP: Native <gallery> extension

 * Based on https://github.com/Wikia/mediawiki-services-parsoid/pull/5

Change-Id: I2e19ddd50c437a01dda62ea46dcfb5d34e41f7b3
---
A lib/ext/Gallery.js
1 file changed, 145 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid 
refs/changes/26/264026/1

diff --git a/lib/ext/Gallery.js b/lib/ext/Gallery.js
new file mode 100644
index 0000000..f8e383f
--- /dev/null
+++ b/lib/ext/Gallery.js
@@ -0,0 +1,145 @@
+'use strict';
+require('../../core-upgrade.js');
+
+var async = require('async');
+var coreutil = require('util');
+
+var Util = require('../utils/Util.js').Util;
+var defines = require('../wt2html/parser.defines.js');
+var ExtensionHandler = 
require('../wt2html/tt/ExtensionHandler.js').ExtensionHandler;
+var Title = require('../mw/Title.js').Title;
+var PHPParseRequest = require('../mw/ApiRequest.js').PHPParseRequest;
+
+
+var Gallery = function() {};
+
+// Inherit functionality from ExtensionHandler
+coreutil.inherits(Gallery, ExtensionHandler);
+
+Gallery.prototype.handleGallery = function(manager, pipelineOpts, token, cb /* 
parsoid */) {
+       var tagWidths = token.dataAttribs.tagWidths;
+       var outerSource = token.getAttribute('source');
+       var innerSource = outerSource.substring(tagWidths[0], 
outerSource.length - tagWidths[1]);
+       var lines = innerSource.split('\n');
+       var offset = tagWidths[0] + token.dataAttribs.tsr[0];
+       var items = [];
+       var i;
+
+       // This async signalling has to happen before any further pipeline 
processing
+       cb({ 'async': true });
+
+       for (i = 0; i < lines.length; i++) {
+               items.push({ 'wt': lines[i], 'offset': offset });
+               offset += lines[i].length + 1;
+       }
+
+       async.mapLimit(
+               items,
+               100,
+               this._processLine.bind(this, manager),
+               this._processLinesHandler.bind(this, manager, token, cb)
+       );
+};
+
+Gallery.prototype._processLine = function(manager, item, callback /* async */) 
{
+       // Same regex as here: 
https://github.com/Wikia/app/blob/dev/includes/parser/Parser.php#L5256
+       var matches = item.wt.match(/^([^|]+)(\\|(.*))?$/);
+       var hasFileNamespace, wikitext;
+
+       if (!matches) {
+               callback(null, this._buildPlaceholderToken(item.wt));
+               return;
+       }
+
+       hasFileNamespace = Title.fromPrefixedText(manager.env, 
matches[1]).ns.isFile();
+       wikitext = '[[' + (hasFileNamespace ? '' : 'File:') + item.wt + 
'|thumb|none]]';
+
+       this._parse(
+               manager,
+               wikitext,
+               // Calculate source offset for Parsoid pipeline:
+               // subtract 2 for [[ prepended above and optionally 5 for File:
+               item.offset - 2 - (hasFileNamespace ? 0 : 5),
+               this._parseHandler.bind(this, callback, item.wt, 
hasFileNamespace)
+       );
+};
+
+Gallery.prototype._processLinesHandler = function(manager, token, finalcb /* 
parsoid */, error, results) {
+       var source = token.getAttribute('source');
+       var parserRequest = new PHPParseRequest(manager.env, 'gallery', source);
+       // TODO: Make a call to PHP Parser right in handleGallery method and 
later
+       // just combine results of both (this call) and async.map
+       parserRequest.once('src', function(innertoken, frame, innercb) {
+               var i, j;
+               var tokens = [];
+               var da = Util.clone(token.dataAttribs);
+               var dataMW = {
+                       alternativeRendering: frame,
+                       name: 'gallery',
+                       attrs: Util.KVtoHash(token.getAttribute('options'), 
true),
+                       body: {
+                               extsrc: Util.extractExtBody('gallery', source),
+                       },
+               };
+
+               da.stx = undefined;
+
+               tokens.push(new defines.TagTk('div', [
+                       new defines.KV('typeof', 'mw:Extension/nativeGallery'),
+                       new defines.KV('data-mw', JSON.stringify(dataMW)),
+               ], da));
+               for (i = 0; i < results.length; i++) {
+                       for (j = 0; j < results[i].length; j++) {
+                               tokens.push(results[i][j]);
+                       }
+                       if (i !== results.length - 1) {
+                               // Emit new line token between each token 
(either placeholder or image) to make up for
+                               // split('\n') and so does dsr not puke
+                               tokens.push('\n');
+                       }
+               }
+               tokens.push(new defines.EndTagTk('div'));
+               finalcb({'tokens': tokens, 'async': false});
+       });
+};
+
+Gallery.prototype._parse = function(manager, wt, offset, callback) {
+       var pipeline = manager.pipeFactory.getPipeline('text/x-mediawiki/full', 
{ isInclude: true, wrapTemplates: false, inBlockToken: true });
+       pipeline.setSourceOffsets(offset, offset + wt.length);
+       pipeline.addListener('document', callback);
+       pipeline.process(wt);
+};
+
+Gallery.prototype._parseHandler = function(callback /* async */, wt, 
hasFileNamespace, doc) {
+       if (doc.body.childNodes.length !== 1 ||
+               doc.body.firstChild.nodeType !== 
doc.body.firstChild.ELEMENT_NODE ||
+               doc.body.firstChild.getAttribute('typeof') !== 'mw:Image/Thumb'
+       ) {
+               callback(null, this._buildPlaceholderToken(wt));
+               return;
+       }
+       // Add information about file namespace presence to data-parsoid
+       // so on the way back we can correctly recreate wikitext if needed.
+       var dp = JSON.parse(doc.body.firstChild.getAttribute('data-parsoid'));
+       dp.hasFileNamespace = hasFileNamespace;
+       doc.body.firstChild.setAttribute('data-parsoid', JSON.stringify(dp));
+       callback(null, this._buildDOMFragment(doc.body.innerHTML));
+};
+
+Gallery.prototype._buildPlaceholderToken = function(src) {
+       return [
+               new defines.SelfclosingTagTk('meta', [new defines.KV('typeof', 
'mw:Placeholder')], { 'src': src }),
+       ];
+};
+
+Gallery.prototype._buildDOMFragment = function(src) {
+       return [
+               new defines.TagTk('div', [{ 'k': 'typeof', 'v': 
'mw:DOMFragment' }], { 'html': src }),
+               new defines.EndTagTk('div'),
+       ];
+};
+
+
+if (typeof module === "object") {
+       module.exports.Gallery = Gallery;
+}
\ No newline at end of file

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2e19ddd50c437a01dda62ea46dcfb5d34e41f7b3
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Arlolra <[email protected]>

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

Reply via email to