Skip to content

Commit

Permalink
Remove forceUpgraded check in dom-module.import
Browse files Browse the repository at this point in the history
Multiple elements depend on dom-module.import and may register before dom-module
is registered.

With the forceUpgraded check, only the first module to call .import will be
upgraded, typically custom-style.

This will break the subsiquent elements, such as dom-template.

Fixes Polymer/vulcanize#234
  • Loading branch information
dfreedm committed Aug 24, 2015
1 parent 5605634 commit b85b641
Showing 1 changed file with 110 additions and 111 deletions.
221 changes: 110 additions & 111 deletions src/lib/dom-module.html
Original file line number Diff line number Diff line change
@@ -1,111 +1,110 @@
<script>

(function() {

var modules = {};
var lcModules = {};
var findModule = function(id) {
return modules[id] || lcModules[id.toLowerCase()];
}

/**
* The `dom-module` element registers the dom it contains to the name given
* by the module's id attribute. It provides a unified database of dom
* accessible via any dom-module element. Use the `import(id, selector)`
* method to locate dom within this database. For example,
*
* <dom-module id="foo">
* <img src="stuff.png">
* </dom-module>
*
* Then in code in some other location that cannot access the dom-module above
*
* var img = document.createElement('dom-module').import('foo', 'img');
*
*/
var DomModule = function() {
return document.createElement('dom-module');
};

DomModule.prototype = Object.create(HTMLElement.prototype);

Polymer.Base.extend(DomModule.prototype, {

constructor: DomModule,

createdCallback: function() {
this.register();
},

/**
* Registers the dom-module at a given id. This method should only be called
* when a dom-module is imperatively created. For
* example, `document.createElement('dom-module').register('foo')`.
* @method register
* @param {String} id The id at which to register the dom-module.
*/
register: function(id) {
var id = id || this.id ||
this.getAttribute('name') || this.getAttribute('is');
if (id) {
this.id = id;
// store id separate from lowercased id so that
// in all cases mixedCase id will stored distinctly
// and lowercase version is a fallback
modules[id] = this;
lcModules[id.toLowerCase()] = this;
}
},

/**
* Retrieves the dom specified by `selector` in the module specified by
* `id`. For example, this.import('foo', 'img');
* @method register
* @param {String} id
* @param {String} selector
* @return {Object} Returns the dom which matches `selector` in the module
* at the specified `id`.
*/
import: function(id, selector) {
var m = findModule(id);
if (!m) {
// If polyfilling, a script can run before a dom-module element
// is upgraded. We force the containing document to upgrade
// and try again to workaround this polyfill limitation.
forceDocumentUpgrade();
m = findModule(id);
}
if (m && selector) {
m = m.querySelector(selector);
}
return m;
}

});

// NOTE: HTMLImports polyfill does not
// block scripts on upgrading elements. However, we want to ensure that
// any dom-module in the tree is available prior to a subsequent script
// processing.
// Therefore, we force any dom-modules in the tree to upgrade when dom-module
// is registered by temporarily setting CE polyfill to crawl the entire
// imports tree. (Note: this should only upgrade any imports that have been
// loaded by this point. In addition the HTMLImports polyfill should be
// changed to upgrade elements prior to running any scripts.)
var cePolyfill = window.CustomElements && !CustomElements.useNative;
document.registerElement('dom-module', DomModule);

function forceDocumentUpgrade() {
if (cePolyfill) {
var script = document._currentScript || document.currentScript;
var doc = script && script.ownerDocument;
if (doc && !doc.__customElementsForceUpgraded) {
doc.__customElementsForceUpgraded = true;
CustomElements.upgradeAll(doc);
}
}
}

})();

</script>
<script>

(function() {

var modules = {};
var lcModules = {};
var findModule = function(id) {
return modules[id] || lcModules[id.toLowerCase()];
}

/**
* The `dom-module` element registers the dom it contains to the name given
* by the module's id attribute. It provides a unified database of dom
* accessible via any dom-module element. Use the `import(id, selector)`
* method to locate dom within this database. For example,
*
* <dom-module id="foo">
* <img src="stuff.png">
* </dom-module>
*
* Then in code in some other location that cannot access the dom-module above
*
* var img = document.createElement('dom-module').import('foo', 'img');
*
*/
var DomModule = function() {
return document.createElement('dom-module');
};

DomModule.prototype = Object.create(HTMLElement.prototype);

Polymer.Base.extend(DomModule.prototype, {

constructor: DomModule,

createdCallback: function() {
this.register();
},

/**
* Registers the dom-module at a given id. This method should only be called
* when a dom-module is imperatively created. For
* example, `document.createElement('dom-module').register('foo')`.
* @method register
* @param {String} id The id at which to register the dom-module.
*/
register: function(id) {
var id = id || this.id ||
this.getAttribute('name') || this.getAttribute('is');
if (id) {
this.id = id;
// store id separate from lowercased id so that
// in all cases mixedCase id will stored distinctly
// and lowercase version is a fallback
modules[id] = this;
lcModules[id.toLowerCase()] = this;
}
},

/**
* Retrieves the dom specified by `selector` in the module specified by
* `id`. For example, this.import('foo', 'img');
* @method register
* @param {String} id
* @param {String} selector
* @return {Object} Returns the dom which matches `selector` in the module
* at the specified `id`.
*/
import: function(id, selector) {
var m = findModule(id);
if (!m) {
// If polyfilling, a script can run before a dom-module element
// is upgraded. We force the containing document to upgrade
// and try again to workaround this polyfill limitation.
forceDocumentUpgrade();
m = findModule(id);
}
if (m && selector) {
m = m.querySelector(selector);
}
return m;
}

});

// NOTE: HTMLImports polyfill does not
// block scripts on upgrading elements. However, we want to ensure that
// any dom-module in the tree is available prior to a subsequent script
// processing.
// Therefore, we force any dom-modules in the tree to upgrade when dom-module
// is registered by temporarily setting CE polyfill to crawl the entire
// imports tree. (Note: this should only upgrade any imports that have been
// loaded by this point. In addition the HTMLImports polyfill should be
// changed to upgrade elements prior to running any scripts.)
var cePolyfill = window.CustomElements && !CustomElements.useNative;
document.registerElement('dom-module', DomModule);

function forceDocumentUpgrade() {
if (cePolyfill) {
var script = document._currentScript || document.currentScript;
var doc = script && script.ownerDocument;
if (doc) {
CustomElements.upgradeAll(doc);
}
}
}

})();

</script>

0 comments on commit b85b641

Please sign in to comment.