Skip to content

Commit

Permalink
Initial work for Custom Elements support
Browse files Browse the repository at this point in the history
Changes here paired with jsdom/webidl2js#44 will
enable `./test-web-components.js` to work. You will need to `npm
install` before running `node ./test-web-components.js`.
  • Loading branch information
tbranyen committed May 29, 2017
1 parent 0f4128d commit f9b90d2
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 1 deletion.
13 changes: 13 additions & 0 deletions lib/jsdom/browser/Window.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,19 @@ function Window(options) {
};

///// PUBLIC DATA PROPERTIES (TODO: should be getters)
this.customElements = new class CustomElementsRegistry {
get(tagName) {
return this[idlUtils.registry].get(tagName);
}

define(tagName, constructor) {
this[idlUtils.registry].set(tagName, constructor);
}

constructor() {
this[idlUtils.registry] = new Map();
}
};

this.console = {
assert: wrapConsoleMethod("assert"),
Expand Down
5 changes: 5 additions & 0 deletions lib/jsdom/living/nodes/Document-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,11 @@ class DocumentImpl extends NodeImpl {
}

_createElementWithCorrectElementInterface(name, namespace) {
let Constructor = null;

if (Constructor = this._global.window.customElements.get(name)) {
return new Constructor();
}
// https://dom.spec.whatwg.org/#concept-element-interface
// TODO: eventually we should re-write the element-builder system to be namespace aware, but for now it is not.
const builder = this._elementBuilders[name.toLowerCase()] || this._defaultElementBuilder.bind(this);
Expand Down
1 change: 1 addition & 0 deletions lib/jsdom/living/nodes/HTMLElement-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class HTMLElementImpl extends ElementImpl {
constructor(args, privateData) {
super(args, privateData);
this._initGlobalEvents();
this._core = this._core || global.window;

this._tabIndex = 0;

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"st": "^1.2.0",
"watchify": "^3.9.0",
"wd": "^1.1.3",
"webidl2js": "^7.0.1"
"webidl2js": "jsdom/webidl2js#1868f38611e7d9b6e598036de129100bf5e98b6c"
},
"browser": {
"canvas": false,
Expand Down
46 changes: 46 additions & 0 deletions test-web-components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Modified JSDOM to allow `super` on `HTMLElement`.
const { JSDOM } = require('./');
const { window } = new JSDOM('<!doctype html>')

// FIXME Necessary for now to get MyShinyComponent in the shared JSDOM window.
global.window = window;

// Web Components on the way...!
const { HTMLElement, document, customElements } = window;

// Plain ole Custom Element...
class MyShinyComponent extends HTMLElement {
constructor(props = { someMessage: 'Set via innerHTML' }) {
super();

this.innerHTML = `<span>${props.someMessage}</span>`;
}
}

// Define into the internal JSDOM CustomElementsRegistry
customElements.define('my-shiny-component', MyShinyComponent);

// Helper function to create a regular DOM Node or upgraded Custom Element.
function makeElement(tagName, props) {
const Constructor = customElements.get(tagName);

if (Constructor) {
return new Constructor(props);
}
else {
document.createElement(tagName);
}
}

//console.log(
// makeElement('my-shiny-component', { someMessage: 'Hello World' }).outerHTML
//);

document.body.innerHTML = '<my-shiny-component></my-shiny-component>';

/**
*
*
* @return
*/
console.log(document.body.outerHTML);

0 comments on commit f9b90d2

Please sign in to comment.