From 9ea65c52298cc33c6bc229226004dc31e83d042f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20C=C3=A1ceres?= Date: Tue, 10 Jan 2017 16:34:32 +1100 Subject: [PATCH] feat(webidl-contiguous): link method() and enum "" (#1023) * link simple method() names (closes #1000) * fix(webidl-contiguous): Link enum when empty string (closes #981) * test(webidl-contiguous-spec): link simple method() names --- js/core/jquery-enhanced.js | 2 +- .../templates/webidl-contiguous/compiled.js | 6 +- .../webidl-contiguous/enum-item.html | 2 +- js/core/webidl-contiguous.js | 68 ++++++++++++++++--- tests/spec/core/webidl-contiguous-spec.js | 52 +++++++++++++- tests/spec/core/webidl-contiguous.html | 50 ++++++++++++++ 6 files changed, 163 insertions(+), 17 deletions(-) diff --git a/js/core/jquery-enhanced.js b/js/core/jquery-enhanced.js index 0e57043773..0538494afd 100644 --- a/js/core/jquery-enhanced.js +++ b/js/core/jquery-enhanced.js @@ -77,7 +77,7 @@ define([ } else if (this.contents().length == 1 && this.children("abbr, acronym").length == 1 && this.find(":first-child").attr("title")) { titleString = this.find(":first-child").attr("title"); } else { - titleString = this.text(); + titleString = this.text() === "\"\"" ? "the-empty-string" : this.text(); } // now we have a string of one or more titles titleString = utils.norm(titleString).toLowerCase(); diff --git a/js/core/templates/webidl-contiguous/compiled.js b/js/core/templates/webidl-contiguous/compiled.js index a79801b4a3..50de73623a 100644 --- a/js/core/templates/webidl-contiguous/compiled.js +++ b/js/core/templates/webidl-contiguous/compiled.js @@ -137,13 +137,13 @@ templates['enum-item.html'] = template({"1":function(container,depth0,helpers,pa var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3=container.escapeExpression, alias4="function"; return alias3((helpers.idn || (depth0 && depth0.idn) || alias2).call(alias1,(depth0 != null ? depth0.indent : depth0),{"name":"idn","hash":{},"data":data})) - + "\"" + + "\" class=\"idlEnumItem\">\"" + alias3(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias4 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper))) - + "\"" + + "\"" + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.needsComma : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "\n"; },"useData":true}); diff --git a/js/core/templates/webidl-contiguous/enum-item.html b/js/core/templates/webidl-contiguous/enum-item.html index 55dc0accfd..7d42389fed 100644 --- a/js/core/templates/webidl-contiguous/enum-item.html +++ b/js/core/templates/webidl-contiguous/enum-item.html @@ -1 +1 @@ -{{idn indent}}"{{name}}"{{#if needsComma}},{{/if}} +{{idn indent}}"{{name}}"{{#if needsComma}},{{/if}} diff --git a/js/core/webidl-contiguous.js b/js/core/webidl-contiguous.js index 5d2c2765b1..7d2d841da5 100644 --- a/js/core/webidl-contiguous.js +++ b/js/core/webidl-contiguous.js @@ -130,8 +130,11 @@ define( var content = options.fn(this); if (obj.dfn) { var result = ""; return result; @@ -472,7 +475,7 @@ define( } } children += idlEnumItemTmpl({ - lname: item.toString().toLowerCase(), + lname: item.toString() ? item.toString() : "the-empty-string", name: item.toString(), parentID: obj.name.toLowerCase(), indent: indent + 1, @@ -745,13 +748,14 @@ define( case "enum": name = defn.name; + defn.values.forEach(function(v, i) { if (v.type === undefined) { defn.values[i] = { toString: function() { return v; }, - dfn: findDfn(name, v, definitionMap) + dfn: findDfn(name, v, definitionMap, defn.type) }; } }); @@ -826,7 +830,7 @@ define( if (parent) { defn.linkFor = parent; } - defn.dfn = findDfn(parent, name, definitionMap); + defn.dfn = findDfn(parent, name, definitionMap, defn.type); }); } @@ -837,14 +841,54 @@ define( // counted as matching. // // When a matching is found, it's given formatting, - // marked as an IDL definition, and returned. If no is found, + // marked as an IDL definition, and returned. If no is found, // the function returns 'undefined'. - function findDfn(parent, name, definitionMap) { + function findDfn(parent, name, definitionMap, type) { var originalParent = parent; var originalName = name; parent = parent.toLowerCase(); - name = name.toLowerCase(); - if (unlinkable.has(name)){ + switch (type) { + case "operation": + // ignore overloads + if (name.search("!overload") !== -1) { + break; + } + // Allow linking to both "method()" and "method" name. + const asMethodName = name.toLowerCase() + "()"; + + if (definitionMap[asMethodName]) { + const dfn = findDfn(parent, asMethodName, definitionMap); + if (!dfn) { + break; // try finding dfn using name, using normal search path... + } + const lt = (dfn[0].dataset.lt) ? dfn[0].dataset.lt.split("|") : []; + lt.push(asMethodName, name); + dfn[0].dataset.lt = lt.join("|"); + if (!definitionMap[name]) { + definitionMap[name] = []; + } + definitionMap[name].push(dfn); + return dfn; + }; + // no method alias, so let's find the dfn and add it + const dfn = findDfn(parent, name, definitionMap); + if (!dfn) { + break; + } + const lt = (dfn[0].dataset.lt) ? dfn[0].dataset.lt.split("|") : []; + lt.push(asMethodName, name); + dfn[0].dataset.lt = lt.join("|"); + definitionMap[asMethodName] = [dfn]; + return dfn; + case "enum": + if (name === "") { + name = "the-empty-string"; + break; + } + default: + name = name.toLowerCase(); + } + if (unlinkable.has(name)) { return; } var dfnForArray = definitionMap[name]; @@ -882,9 +926,11 @@ define( pubsubhub.pub("error", "Multiple s for " + originalName + (originalParent ? " in " + originalParent : "")); } if (dfns.length === 0) { - const msg = "No for " + originalName + (originalParent ? " in " + originalParent : "") + "."; - pubsubhub.pub("warn", msg); - return undefined; + if (type) { + const msg = "No for " + originalName + (originalParent ? " in " + originalParent : "") + "."; + pubsubhub.pub("warn", msg); + } + return; } var dfn = dfns[0]; // Mark the definition as code. diff --git a/tests/spec/core/webidl-contiguous-spec.js b/tests/spec/core/webidl-contiguous-spec.js index 8c002ba4e3..78374c9b77 100644 --- a/tests/spec/core/webidl-contiguous-spec.js +++ b/tests/spec/core/webidl-contiguous-spec.js @@ -11,6 +11,46 @@ describe("Core - Contiguous WebIDL", function() { doc = idlDoc; }, "spec/core/webidl-contiguous.html").then(done); }); + + it("links simple method names and types", done => { + const section = doc.querySelector("#sec-parenthesis-method"); + [ + "basic", + "ext", + "ull", + "paramed", + "withName", + "named", + ] + .map( + methodName => [methodName, methodName.toLowerCase()] + ) + .map( + ([methodName, id]) => [id, methodName, doc.getElementById(`dom-parenthesistest-${id}()`)] + ) + .forEach(([id, methodName, elem]) => { + expect(elem).toBeTruthy(); + expect(elem.firstElementChild.localName).toEqual("code"); + expect(elem.textContent).toEqual(`${methodName}()`); + expect(elem.id).toEqual(`dom-parenthesistest-${id}()`); + expect(elem.dataset.dfnType).toEqual("dfn"); + expect(elem.dataset.dfnFor).toEqual("parenthesistest"); + expect(elem.dataset.idl).toEqual(""); + // corresponding link + const aElem = section.querySelector(`pre a[href="#dom-parenthesistest-${id}()"]`); + expect(aElem).toBeTruthy(); + expect(aElem.textContent).toEqual(methodName); + }); + const smokeTest = doc.getElementById("dom-parenthesistest-noparens"); + expect(smokeTest).toBeTruthy(); + expect(smokeTest.firstElementChild.localName).toEqual("code"); + expect(smokeTest.textContent).toEqual("noParens"); + // corresponding link + const aElem = section.querySelector(`pre a[href="#dom-parenthesistest-noparens"]`); + expect(aElem).toBeTruthy(); + expect(aElem.textContent).toEqual("noParens"); + done(); + }); it("should handle interfaces", function(done) { var $target = $("#if-basic", doc); var text = "interface SuperStar {\n};"; @@ -530,7 +570,7 @@ describe("Core - Contiguous WebIDL", function() { expect($target.find(".idlEnumItem").length) .toEqual(4); expect($target.find(".idlEnumItem").first().text()) - .toEqual("one"); + .toEqual("\"one\""); // Links and IDs. expect($target.find(":contains('EnumBasic')").filter("a").attr("href")) @@ -551,6 +591,16 @@ describe("Core - Contiguous WebIDL", function() { done(); }); + it("links empty-string enumeration value", done => { + const links = doc.querySelector(`#enum-empty-sec a[href="#dom-emptyenum-the-empty-string"]`); + const dfn = doc.querySelector("#dom-emptyenum-the-empty-string"); + const smokeDfn = doc.querySelector(`#enum-empty-sec a[href="#dom-emptyenum-not empty"]`); + expect(links).toBeTruthy(); + expect(dfn).toBeTruthy(); + expect(smokeDfn).toBeTruthy(); + done(); + }); + it("should handle callbacks", function(done) { var $target = $("#cb-basic", doc); var text = "callback SuperStar = void ();"; diff --git a/tests/spec/core/webidl-contiguous.html b/tests/spec/core/webidl-contiguous.html index abeb618e49..ca740e9a70 100644 --- a/tests/spec/core/webidl-contiguous.html +++ b/tests/spec/core/webidl-contiguous.html @@ -37,6 +37,45 @@ CUSTOM PARAGRAPH

+
+

test qualified

Unsupported

@@ -410,6 +449,17 @@

Enumerations

one is first.

one is referenced with a [link-for] attribute.

+
+
+        enum EmptyEnum {
+          "",
+          "not empty"
+        };
+        
+

EmptyEnum

+

""

... +

not empty...

+

Callbacks

+
+      interface ParenthesisTest {
+          void basic();
+          void noParens();
+          [Something] void ext();
+          unsigned long long ull(short s);
+          unsigned long long ull(long s);
+          SuperStar[][][][] paramed(SuperStar[][]?[] one, [ExtAttrs] ByteString? ext, optional short maybe, short[] shorts, short[][][][] hypercubes, optional short defaulted = 3.5, optional DOMString defaulted2 = "one", short... variable);
+          getter float withName ();
+          setter void named ();
+          void dataLtOverride();
+      };
+      
+

+ ull is a method. Its overloaded form returns a SuperStar/ +

+

dataLtOverride()

+

ParenthesisTest

+

basic()...

+

ext()...

+

ull()...

+

paramed()...

+

withName()...

+

named()...

+

dfnDoesNotLinkToAnything()...

+

noParens...

+

1 basic

+

2 basic()

+

3 basic

+

4 basic

+

noParens

+

noParens()

+

noParens

+

noParens

+

noParens()

+

this also links

+