Arlolra has uploaded a new change for review.

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

Change subject: Use async serializeDOM in jsapi
......................................................................

Use async serializeDOM in jsapi

 * Replace uses of `toString` with a `toWt` method.

 * Follow up to Id68d24007229dcfa0bf6fb16c6ed3ecdaad0c2e5 where these
   tests were skipped.

Change-Id: I33717f9261885bd121aef27360602fe8ebbc8ccb
---
M guides/jsapi/README.md
M lib/jsapi.js
M tests/mocha/jsapi.js
3 files changed, 151 insertions(+), 80 deletions(-)


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

diff --git a/guides/jsapi/README.md b/guides/jsapi/README.md
index 5ff6dcf..23f166a 100644
--- a/guides/jsapi/README.md
+++ b/guides/jsapi/README.md
@@ -46,29 +46,29 @@
 
        > var text = "I has a template! {{foo|bar|baz|eggs=spam}} See it?\n";
        > var pdoc = yield Parsoid.parse(text, { pdoc: true });
-       > console.log(String(pdoc));
+       > console.log(yield pdoc.toWt());
        I has a template! {{foo|bar|baz|eggs=spam}} See it?
        > var templates = pdoc.filterTemplates();
-       > console.log(templates.map(String));
+       > console.log(templates.map(t => yield t.toWt()));
        [ '{{foo|bar|baz|eggs=spam}}' ]
        > var template = templates[0];
        > console.log(template.name);
        foo
        > template.name = 'notfoo';
-       > console.log(String(template));
+       > console.log(yield template.toWt());
        {{notfoo|bar|baz|eggs=spam}}
-       > console.log(template.params.map(function(p) { return p.name; }));
+       > console.log(template.params.map(p => p.name));
        [ '1', '2', 'eggs' ]
-       > console.log(template.get(1).value);
+       > console.log(yield template.get(1).value.toWt());
        bar
-       > console.log(template.get("eggs").value);
+       > console.log(yield template.get("eggs").value.toWt());
        spam
 
 Getting nested templates is trivial:
 
        > var text = "{{foo|bar={{baz|{{spam}}}}}}";
        > var pdoc = yield Parsoid.parse(text, { pdoc: true });
-       > console.log(pdoc.filterTemplates().map(String));
+       > console.log(pdoc.filterTemplates().map(t => yield t.toWt()));
        [ '{{foo|bar={{baz|{{spam}}}}}}',
          '{{baz|{{spam}}}}',
          '{{spam}}' ]
@@ -108,13 +108,13 @@
        ...        template.name = 'bar-stub';
        ...    }
        ... });
-       > console.log(String(pdoc));
+       > console.log(yield pdoc.toWt());
        {{cleanup|date = July 2012}} '''Foo''' is a [[bar]]. {{bar-stub}}
 
 At any time you can convert the `pdoc` into HTML conforming to the
 [MediaWiki DOM spec] (by referencing the
 [`document`](#!/api/PDoc-property-document) property) or into wikitext (by
-invoking [`toString()`](#!/api/PNodeList-method-toString)).  This allows you
+invoking [`toWt()`](#!/api/PNodeList-method-toWt)).  This allows you
 to save the page using either standard API methods or the RESTBase API
 (once [T101501](https://phabricator.wikimedia.org/T101501) is resolved).
 
diff --git a/lib/jsapi.js b/lib/jsapi.js
index b802961..8bef1b7 100644
--- a/lib/jsapi.js
+++ b/lib/jsapi.js
@@ -19,11 +19,6 @@
 
 // WTS helper
 var wts = function(env, nodes) {
-       // XXX: Serializing to wikitext is very user-friendly, but it depends on
-       // WTS.serializeDOMSync which we might not want to keep around forever.
-       // An alternative would be:
-       //    return DU.normalizeOut(node, 'parsoidOnly');
-       // which might be almost as friendly.
        var body;
        if (nodes.length === 0) {
                return '';
@@ -35,8 +30,7 @@
                        body.appendChild(nodes[i].cloneNode(true));
                }
        }
-       // FXIME: serializeDOMSync is dead.
-       return (new WikitextSerializer({ env: env })).serializeDOMSync(body);
+       return (new WikitextSerializer({ env: env })).serializeDOM(body);
 };
 
 // noop helper
@@ -428,12 +422,12 @@
        }, },
 
        /**
-        * Return a string representing the contents of this object as wikitext.
-        * @return {String}
+        * Return a promise for a string representing the contents of this 
object as wikitext.
+        * @return {Promise}
         */
-       toString: { value: function() {
+       toWt: { value: Promise.method(function() {
                return wts(this.pdoc.env, this.nodes);
-       }, },
+       }), },
 });
 /**
  * Create a {@link PNodeList} from a string containing HTML.
@@ -475,7 +469,7 @@
  *   A function which will be invoked when {@link #update} is called.
  * @param {Function} [opts.wtsNodes]
  *   A function returning an array of {@link Node}s which can tweak the
- *   portion of the document serialized by {@link #toString}.
+ *   portion of the document serialized by {@link #toWt}.
  */
 PNode = function PNode(pdoc, parent, node, opts) {
        /** @property {PDoc} pdoc The parent document for this {@link PNode}. */
@@ -534,13 +528,13 @@
                return nodes.map(function(n) { return n.outerHTML; }).join('');
        }, },
        /**
-        * @inheritdoc PNodeList#toString
+        * @inheritdoc PNodeList#toWt
         * @method
         */
-       toString: { value: function() {
+       toWt: { value: Promise.method(function() {
                var nodes = this._wtsNodes ? this._wtsNodes() : [ this.node ];
                return wts(this.pdoc.env, nodes);
-       }, },
+       }), },
 });
 
 // Helper: getter and setter for the inner contents of a node.
@@ -1167,10 +1161,10 @@
                        this._value.update();
                },
        },
-       toString: { value: function() {
+       toWt: { value: Promise.method(function() {
                var k = this.key;
                return (k ? String(k) : this.name) + '=' + String(this.value);
-       }, },
+       }), },
 });
 
 /**
@@ -1272,7 +1266,7 @@
  * instance of {@link PNodeList}, you can filter it, mutate it, etc.
  * But it also provides means to serialize the document as either
  * HTML (via {@link #document} or {@link #toHtml}) or wikitext
- * (via {@link #toString}).
+ * (via {@link #toWt}).
  * @class
  * @extends PNodeList
  * @alternateClassName Parsoid.PDoc
diff --git a/tests/mocha/jsapi.js b/tests/mocha/jsapi.js
index 9243c24..f352c4f 100644
--- a/tests/mocha/jsapi.js
+++ b/tests/mocha/jsapi.js
@@ -22,7 +22,7 @@
        });
 });
 
-describe.skip('Examples from guides/jsapi', function() {
+describe('Examples from guides/jsapi', function() {
        it('converts empty wikitext to HTML', function() {
                return Parsoid.parse('', { pdoc: true}).then(function(pdoc) {
                        pdoc.should.have.property('document');
@@ -38,21 +38,33 @@
        });
        it('filters out templates', function() {
                var text = "I has a template! {{foo|bar|baz|eggs=spam}} See 
it?\n";
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       String(pdoc).should.equal(text);
-                       var templates = pdoc.filterTemplates();
+               var pdoc, templates, template;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal(text);
+                       templates = pdoc.filterTemplates();
                        templates.length.should.equal(1);
-                       
String(templates[0]).should.equal('{{foo|bar|baz|eggs=spam}}');
-                       var template = templates[0];
+                       return templates[0].toWt();
+               }).then(function(wt) {
+                       wt.should.equal('{{foo|bar|baz|eggs=spam}}');
+                       template = templates[0];
                        template.name.should.equal('foo');
                        template.name = 'notfoo';
-                       
String(template).should.equal('{{notfoo|bar|baz|eggs=spam}}');
+                       return template.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('{{notfoo|bar|baz|eggs=spam}}');
                        template.params.length.should.equal(3);
                        template.params[0].name.should.equal('1');
                        template.params[1].name.should.equal('2');
                        template.params[2].name.should.equal('eggs');
-                       String(template.get(1).value).should.equal('bar');
-                       String(template.get('eggs').value).should.equal('spam');
+                       return template.get(1).value.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('bar');
+                       return template.get('eggs').value.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('spam');
                });
        });
        it('filters templates, recursively', function() {
@@ -66,14 +78,19 @@
        });
        it('filters templates, non-recursively', function() {
                var text = "{{foo|this {{includes a|template}}}}";
+               var foo;
                return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
                        var templates = pdoc.filterTemplates({ recursive: false 
});
                        templates.length.should.equal(1);
-                       var foo = templates[0];
-                       String(foo.get(1).value).should.equal('this {{includes 
a|template}}');
+                       foo = templates[0];
+                       return foo.get(1).value.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('this {{includes a|template}}');
                        var more = foo.get(1).value.filterTemplates();
                        more.length.should.equal(1);
-                       String(more[0].get(1).value).should.equal('template');
+                       return more[0].get(1).value.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('template');
                });
        });
        it('is easy to mutate templates', function() {
@@ -87,12 +104,14 @@
                                        template.name = 'bar-stub';
                                }
                        });
-                       String(pdoc).should.equal("{{cleanup|date = July 2012}} 
'''Foo''' is a [[bar]]. {{bar-stub}}");
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal("{{cleanup|date = July 2012}} '''Foo''' 
is a [[bar]]. {{bar-stub}}");
                });
        });
 });
 
-describe.skip('Further examples of PDoc API', function() {
+describe('Further examples of PDoc API', function() {
        it('is easy to mutate templates (2)', function() {
                // Works even on nested templates!
                var text = "{{echo|{{cleanup}} '''Foo''' is a [[bar]].}} 
{{uncategorized}}";
@@ -105,7 +124,9 @@
                                        template.add('test2', 
Parsoid.PNodeList.fromHTML(pdoc, "I'm so <b>bold</b>!"));
                                }
                        });
-                       String(pdoc).should.equal("{{echo|{{cleanup|date = July 
2012|test1 = <nowiki>{{foo}}</nowiki>&bar{{!}}bat<nowiki><p></nowiki>|test2 = 
I'm so '''bold'''!}} '''Foo''' is a [[bar]].}} {{uncategorized}}");
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal("{{echo|{{cleanup|date = July 
2012|test1 = <nowiki>{{foo}}</nowiki>&bar{{!}}bat<nowiki><p></nowiki>|test2 = 
I'm so '''bold'''!}} '''Foo''' is a [[bar]].}} {{uncategorized}}");
                });
        });
        it('is safe to mutate template arguments', function() {
@@ -113,7 +134,9 @@
                return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
                        var t = pdoc.filterTemplates()[0];
                        t.remove(1);
-                       String(pdoc).should.equal('{{echo||bar}}');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo||bar}}');
                });
        });
        it('is safe to mutate template arguments (2)', function() {
@@ -124,7 +147,9 @@
                        var param2 = t.get(2);
                        param2.value = param1.value;
                        param1.value = '|';
-                       String(pdoc).should.equal('{{echo|{{!}}|foo}}');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo|{{!}}|foo}}');
                });
        });
        it('filters and mutates headings', function() {
@@ -143,47 +168,77 @@
                        headings[0].title = '=0=';
                        headings[1].title = headings[2].title;
                        headings[3].level = 3;
-                       String(pdoc).should.equal('=<nowiki>=0=</nowiki>=\n== 
three ==\n=== three ===\n\n=== four ===\nbody\n');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('=<nowiki>=0=</nowiki>=\n== three 
==\n=== three ===\n\n=== four ===\nbody\n');
                });
        });
        it('filters and mutates headings inside templates', function() {
                var text = "{{echo|1=\n= one =\n}}";
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var headings = pdoc.filterHeadings();
+               var pdoc, headings;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       headings = pdoc.filterHeadings();
                        headings.length.should.equal(1);
                        headings[0].level = 2;
-                       String(headings[0]).should.equal('== one ==\n');
-                       String(pdoc).should.equal('{{echo|1=\n== one ==\n}}');
+                       return headings[0].toWt();
+               }).then(function(wt) {
+                       wt.should.equal('== one ==\n');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo|1=\n== one ==\n}}');
                        headings[0].title = 'two';
-                       String(headings[0]).should.equal('== two ==\n');
-                       String(pdoc).should.equal('{{echo|1=\n== two ==\n}}');
+                       return headings[0].toWt();
+               }).then(function(wt) {
+                       wt.should.equal('== two ==\n');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo|1=\n== two ==\n}}');
                });
        });
        it('filters and mutates external links', function() {
                var text = "[http://example.com {{echo|link content}}]";
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var extlinks = pdoc.filterExtLinks();
+               var pdoc, extlinks;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       extlinks = pdoc.filterExtLinks();
                        extlinks.length.should.equal(1);
                        
String(extlinks[0].url).should.equal('http://example.com');
-                       String(extlinks[0].title).should.equal('{{echo|link 
content}}');
+                       return extlinks[0].title.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo|link content}}');
                        extlinks[0].title = ']';
-                       String(pdoc).should.equal('[http://example.com 
<nowiki>]</nowiki>]\n');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('[http://example.com 
<nowiki>]</nowiki>]\n');
                });
        });
        it('filters and mutates wiki links', function() {
                var text = "[[foo|1]] {{echo|[[bar|2]]}} [[{{echo|bat}}|3]]";
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var extlinks = pdoc.filterWikiLinks();
+               var pdoc, extlinks;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       extlinks = pdoc.filterWikiLinks();
                        extlinks.length.should.equal(3);
-                       String(extlinks[0].title).should.equal('Foo');
-                       String(extlinks[0].text).should.equal('1');
-                       String(extlinks[1].title).should.equal('Bar');
-                       String(extlinks[1].text).should.equal('2');
-                       String(extlinks[2].text).should.equal('3');
+                       return Promise.all([
+                               extlinks[0].title,
+                               extlinks[0].text.toWt(),
+                               extlinks[1].title,
+                               extlinks[1].text.toWt(),
+                               extlinks[2].text.toWt(),
+                       ]);
+               }).then(function(all) {
+                       all[0].should.equal('Foo');
+                       all[1].should.equal('1');
+                       all[2].should.equal('Bar');
+                       all[3].should.equal('2');
+                       all[4].should.equal('3');
                        extlinks[0].title = extlinks[0].text = 'foobar';
                        extlinks[1].text = 'A';
                        extlinks[2].text = 'B';
-                       String(pdoc).should.equal('[[foobar]] 
{{echo|[[bar|A]]}} [[{{echo|bat}}|B]]\n');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('[[foobar]] {{echo|[[bar|A]]}} 
[[{{echo|bat}}|B]]\n');
                });
        });
        it('filters and mutates html entities', function() {
@@ -195,7 +250,9 @@
                        entities[1].normalized.should.equal('"');
                        entities[0].normalized = '<';
                        entities[1].normalized = '>';
-                       String(pdoc).should.equal('&#x3C;{{echo|&#x3E;}}\n');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('&#x3C;{{echo|&#x3E;}}\n');
                });
        });
        it('filters and mutates comments', function() {
@@ -207,37 +264,53 @@
                        comments[1].contents.should.equal('bar');
                        comments[0].contents = '<!-- ha! -->';
                        comments[1].contents = '--';
-                       String(pdoc).should.equal('<!--<!-- ha! --&gt;--> 
{{echo|<!------>}}');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('<!--<!-- ha! --&gt;--> 
{{echo|<!------>}}');
                });
        });
        it('filters and mutates images', function() {
                var text = '[[File:SomeFile1.jpg]] 
[[File:SomeFile2.jpg|thumb|caption]]';
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var media = pdoc.filterMedia();
+               var pdoc, media;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       media = pdoc.filterMedia();
                        media.length.should.equal(2);
                        media[0].should.have.property('caption', null);
-                       String(media[1].caption).should.equal('caption');
+                       return media[1].caption.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('caption');
                        media[0].caption = '|';
                        media[1].caption = null;
-                       
String(pdoc).should.equal('[[File:SomeFile1.jpg|<nowiki>|</nowiki>]] 
[[File:SomeFile2.jpg|thumb]]');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       
wt.should.equal('[[File:SomeFile1.jpg|<nowiki>|</nowiki>]] 
[[File:SomeFile2.jpg|thumb]]');
                        media[0].caption = null;
                        media[1].caption = '|';
-                       String(pdoc).should.equal('[[File:SomeFile1.jpg]] 
[[File:SomeFile2.jpg|thumb|<nowiki>|</nowiki>]]');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('[[File:SomeFile1.jpg]] 
[[File:SomeFile2.jpg|thumb|<nowiki>|</nowiki>]]');
                });
        });
        it('filters and mutates text', function() {
                var text = 'foo {{echo|bar}}';
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var texts = pdoc.filterText({ recursive: false });
+               var pdoc, texts;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       texts = pdoc.filterText({ recursive: false });
                        texts.length.should.equal(1);
                        texts = pdoc.filterText({ recursive: true });
                        texts.length.should.equal(2);
                        texts[0].value.should.equal('foo ');
                        texts[1].value.should.equal('bar');
                        texts[0].value = 'FOO ';
-                       String(pdoc).should.equal('FOO {{echo|bar}}\n');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('FOO {{echo|bar}}\n');
                        texts[1].value = 'BAR';
-                       String(pdoc).should.equal('FOO {{echo|BAR}}\n');
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal('FOO {{echo|BAR}}\n');
                });
        });
        it.skip('filters and mutates text (2)', function() {
@@ -253,15 +326,19 @@
        });
        it('allows mutation using wikitext', function() {
                var text = '== heading ==';
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var headings = pdoc.filterHeadings();
+               var pdoc, headings;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       headings = pdoc.filterHeadings();
                        headings.length.should.equal(1);
                        // Note that even if the wikitext is unbalanced, the 
result
                        // will be balanced.  The bold face doesn't escape the 
heading!
-                       return Parsoid.PNodeList.fromWikitext(pdoc, 
"'''bold").then(function(pnl) {
-                               headings[0].title = pnl;
-                               String(pdoc).should.equal("== '''bold''' ==\n");
-                       });
+                       return Parsoid.PNodeList.fromWikitext(pdoc, "'''bold");
+               }).then(function(pnl) {
+                       headings[0].title = pnl;
+                       return pdoc.toWt();
+               }).then(function(wt) {
+                       wt.should.equal("== '''bold''' ==\n");
                });
        });
        it('allows iteration using length and get()', function() {

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I33717f9261885bd121aef27360602fe8ebbc8ccb
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