Skip to content

Commit

Permalink
feat(webidl): support interface mixins (#1468)
Browse files Browse the repository at this point in the history
* feat: support interfaces mixins

* done() is not needed for synchronous tests

even for async tests we can use async functions as mocha supports it.

* remove dangling newline

* remove dangling newline 2
  • Loading branch information
saschanaz authored and Marcos Cáceres committed Feb 3, 2018
1 parent 5fd67f9 commit 42c7fb9
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 14 deletions.
2 changes: 1 addition & 1 deletion js/core/css/webidl.css
Expand Up @@ -228,7 +228,7 @@ a.idlEnumItem {
color: #c00;
}

.idlImplements a {
.idlImplements a, .idlIncludes a {
font-weight: bold;
}

Expand Down
2 changes: 2 additions & 0 deletions js/core/templates/webidl-contiguous/includes.html
@@ -0,0 +1,2 @@
<span class='idlIncludes'>{{extAttr obj indent
}}{{idn indent}}<a>{{obj.target}}</a> includes <a>{{obj.includes}}</a>;</span>
2 changes: 1 addition & 1 deletion js/core/templates/webidl-contiguous/interface.html
@@ -1,4 +1,4 @@
<span class='idlInterface' id='{{obj.idlId}}' data-idl data-title='{{obj.name}}'>{{extAttr obj indent
}}{{idn indent}}{{partial}}{{callback}}interface <span class='idlInterfaceID'>{{#tryLink obj}}{{obj.name}}{{/tryLink
}}{{idn indent}}{{partial}}{{callback}}interface {{mixin}}<span class='idlInterfaceID'>{{#tryLink obj}}{{obj.name}}{{/tryLink
}}</span>{{#if obj.inheritance}} : <span class='idlSuperclass'><a>{{obj.inheritance}}</a></span>{{/if}} &#123;
{{{children}}}{{idn indent}}&#125;;</span>
27 changes: 17 additions & 10 deletions src/core/webidl.js
Expand Up @@ -22,6 +22,7 @@ var idlEnumItemTmpl = tmpls["enum-item.html"];
var idlEnumTmpl = tmpls["enum.html"];
var idlExtAttributeTmpl = tmpls["extended-attribute.html"];
var idlFieldTmpl = tmpls["field.html"];
var idlIncludesTmpl = tmpls["includes.html"];
var idlImplementsTmpl = tmpls["implements.html"];
var idlInterfaceTmpl = tmpls["interface.html"];
var idlIterableTmpl = tmpls["iterable.html"];
Expand Down Expand Up @@ -514,12 +515,16 @@ function writeDefinition(obj, indent) {
switch (obj.type) {
case "typedef":
return idlTypedefTmpl(opt);
case "includes":
return idlIncludesTmpl(opt);
case "implements":
return idlImplementsTmpl(opt);
case "interface":
return writeInterfaceDefinition(opt);
case "interface mixin":
return writeInterfaceDefinition(opt, { mixin: true });
case "callback interface":
return writeInterfaceDefinition(opt, "callback ");
return writeInterfaceDefinition(opt, { callback: true });
case "dictionary":
var maxQualifiers = 0,
maxType = 0;
Expand Down Expand Up @@ -643,20 +648,20 @@ function writeDefinition(obj, indent) {
}
}

function writeInterfaceDefinition(opt, callback) {
function writeInterfaceDefinition(opt, fixes = {}) {
var obj = opt.obj,
indent = opt.indent;
var maxAttr = 0,
maxAttrQualifiers = 0,
maxMeth = 0,
maxConst = 0;
obj.members.forEach(function(it) {
for (const it of obj.members) {
if (
typeIsWhitespace(it.type) ||
it.type === "maplike" ||
it.type === "iterable"
) {
return;
continue;
}
var len = idlType2Text(it.idlType).length;
if (it.type === "attribute") {
Expand All @@ -666,7 +671,7 @@ function writeInterfaceDefinition(opt, callback) {
qualifiersLen > maxAttrQualifiers ? qualifiersLen : maxAttrQualifiers;
} else if (it.type === "operation") maxMeth = len > maxMeth ? len : maxMeth;
else if (it.type === "const") maxConst = len > maxConst ? len : maxConst;
});
}
var children = obj.members
.map(function(ch) {
switch (ch.type) {
Expand All @@ -692,11 +697,12 @@ function writeInterfaceDefinition(opt, callback) {
})
.join("");
return idlInterfaceTmpl({
obj: obj,
indent: indent,
obj,
indent,
partial: obj.partial ? "partial " : "",
callback: callback,
children: children,
callback: fixes.callback ? "callback " : "",
mixin: fixes.mixin ? "mixin ": "",
children,
});
}

Expand Down Expand Up @@ -867,6 +873,7 @@ function linkDefinitions(parse, definitionMap, parent, idlElem) {
.filter(
({ type }) =>
[
"includes",
"implements",
"ws",
"ws-pea",
Expand All @@ -881,8 +888,8 @@ function linkDefinitions(parse, definitionMap, parent, idlElem) {
// Top-level entities with linkable members.
case "callback interface":
case "dictionary":
case "exception":
case "interface":
case "interface mixin":
var partialIdx = "";
if (defn.partial) {
if (!idlPartials[defn.name]) {
Expand Down
22 changes: 20 additions & 2 deletions tests/spec/core/webidl-spec.js
Expand Up @@ -143,6 +143,14 @@ describe("Core - WebIDL", function() {
text = "callback interface SuperStar {\n};";
expect($target.text()).toEqual(text);

$target = $("#if-mixin", doc);
text = "interface mixin SuperStar {\n};";
expect($target.text()).toEqual(text);

$target = $("#if-partial-mixin", doc);
text = "partial interface mixin SuperStar {\n};";
expect($target.text()).toEqual(text);

$target = $("#if-doc", doc);
expect(
$target.find(":contains('DocInterface')").filter("a").attr("href")
Expand Down Expand Up @@ -579,7 +587,18 @@ describe("Core - WebIDL", function() {
done();
});

it("should handle implements", function(done) {
it("should handle includes", () => {
var $target = $("#incl-basic", doc);
var text = "Window includes Breakable;";
expect($target.text()).toEqual(text);
expect($target.find(".idlIncludes").length).toEqual(1);

$target = $("#incl-less-basic", doc);
text = "[Something]\n" + text;
expect($target.text()).toEqual(text);
});

it("should handle implements", () => {
var $target = $("#impl-basic", doc);
var text = "Window implements Breakable;";
expect($target.text()).toEqual(text);
Expand All @@ -588,7 +607,6 @@ describe("Core - WebIDL", function() {
$target = $("#impl-less-basic", doc);
text = "[Something]\n" + text;
expect($target.text()).toEqual(text);
done();
});

it("should link documentation", function() {
Expand Down
24 changes: 24 additions & 0 deletions tests/spec/core/webidl.html
Expand Up @@ -189,6 +189,15 @@ <h2>Interfaces</h2>
<pre id='if-callback' class='idl'>
callback interface SuperStar {};
</pre>
<p>
Interface mixin .
</p>
<pre id='if-mixin' class='idl'>
interface mixin SuperStar {};
</pre>
<pre id='if-partial-mixin' class='idl'>
partial interface mixin SuperStar {};
</pre>
<pre id='if-doc' class='idl'>
interface DocInterface {};
interface DocIsNotCaseSensitive {};
Expand Down Expand Up @@ -505,6 +514,21 @@ <h2>Implements</h2>
[Something]Window implements Breakable;
</pre>
</section>
<section>
<h2>Includes</h2>
<p>
Basic includes.
</p>
<pre id='incl-basic' class='idl'>
Window includes Breakable;
</pre>
<p>
Less basic includes.
</p>
<pre id='incl-less-basic' class='idl'>
[Something]Window includes Breakable;
</pre>
</section>
<section id="documentation">
<h2>Documentation</h2>
<pre id='doc-iface' class='idl'>
Expand Down

0 comments on commit 42c7fb9

Please sign in to comment.