diff --git a/build.bat b/build.bat new file mode 100644 index 0000000000..066f9965a5 --- /dev/null +++ b/build.bat @@ -0,0 +1,5 @@ +@ECHO NPM INSTALL +@call npm install +@ECHO . +@ECHO GRUNT +@call grunt \ No newline at end of file diff --git a/build.log b/build.log deleted file mode 100644 index f0ae67d66b..0000000000 --- a/build.log +++ /dev/null @@ -1,41 +0,0 @@ -BUILD LOG ---------- -Build Time: 2013-06-17T12:21:13 - -NODEJS INFORMATION -================== -nodejs: v0.10.4 -chai: 1.6.1 -grunt: 0.4.1 -grunt-audit: 0.0.0 -grunt-contrib-uglify: 0.2.2 -grunt-contrib-yuidoc: 0.4.0 -grunt-karma-0.9.1: 0.4.3 -karma: 0.9.2 -karma-chrome-launcher: 0.0.1 -karma-coffee-preprocessor: 0.0.1 -karma-crbot-reporter: 0.0.3 -karma-firefox-launcher: 0.0.2 -karma-jasmine: 0.0.1 -karma-mocha: 0.0.1 -karma-phantomjs-launcher: 0.0.2 -karma-requirejs: 0.0.1 -karma-script-launcher: 0.0.1 -mocha: 1.10.0 - -REPO REVISIONS -============== -polymer: 24689e70b7ebb122909d4ed17b53a2b2a455a2e5 -platform: 569a80ae565a0ecbe01d3a79128021fdf1caaff7 -ShadowDOM: 7a50b20542a559a0ffccb9e3a9330246a1f9fb5f -HTMLImports: 7960a892cd4461333809605c3806ba4da699b1f0 -CustomElements: 76bfa07e8bfd5ed75c0c14682a66c40600e6baa0 -PointerEvents: 9bab6b80e74fcbbdb4145286aae264ae54175419 -PointerGestures: d6328b1e65daf111720f76b70f6d469a91a96335 -mdv: aaa18dc0069764ec9f25654c949e4a1071f551f2 - -BUILD HASHES -============ -polymer.min.js: 434cd0b3e8d81699760c75043ab6f7c5676db006 -polymer.native.min.js: 4f966c0f59a909dd3ac28068f1164016551ec179 -polymer.sandbox.min.js: 7444aba9341f62aeb0d89538ee033c77c16cd0e0 \ No newline at end of file diff --git a/gruntfile.js b/gruntfile.js index 128482886e..1b102435b3 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -19,17 +19,16 @@ module.exports = function(grunt) { Polymer = [ "polymer.js", "boot.js", - "shimStyling.js", "lib/lang.js", - "lib/dom.js", - "lib/deserialize.js", "lib/job.js", + "lib/dom.js", "lib/super.js", + "lib/deserialize.js", "api.js", "instance/utils.js", "instance/events.js", - "instance/properties.js", "instance/attributes.js", + "instance/properties.js", "instance/mdv.js", "instance/base.js", "instance/styles.js", @@ -38,7 +37,8 @@ module.exports = function(grunt) { "declaration/events.js", "declaration/properties.js", "declaration/attributes.js", - "declaration/polymer-element.js" + "declaration/polymer-element.js", + "deprecated.js" ].map(function(n) { return "src/" + n; }); diff --git a/polymer.js b/polymer.js index 1e77e26c95..3f8574ff47 100644 --- a/polymer.js +++ b/polymer.js @@ -21,8 +21,8 @@ var modules = [ "api.js", "instance/utils.js", "instance/events.js", - "instance/properties.js", "instance/attributes.js", + "instance/properties.js", "instance/mdv.js", "instance/base.js", "instance/styles.js", @@ -31,7 +31,8 @@ var modules = [ "declaration/events.js", "declaration/properties.js", "declaration/attributes.js", - "declaration/polymer-element.js" + "declaration/polymer-element.js", + "deprecated.js" ].map(function(n) { return "src/" + n; })); diff --git a/src/declaration/attributes.js b/src/declaration/attributes.js index 667d95cef7..1c8e66d5a0 100644 --- a/src/declaration/attributes.js +++ b/src/declaration/attributes.js @@ -89,7 +89,8 @@ isInstanceAttribute: function(name) { return !this.blackList[name] && name.slice(0,3) !== 'on-'; }, - blackList: {name: 1, 'extends': 1, constructor: 1} + // do not clone these attributes onto instances + blackList: {name: 1, 'extends': 1, constructor: 1, noscript: 1} }; // add ATTRIBUTES symbol to blacklist diff --git a/src/declaration/polymer-element.js b/src/declaration/polymer-element.js index ddb0da9b7f..5c827c082e 100644 --- a/src/declaration/polymer-element.js +++ b/src/declaration/polymer-element.js @@ -10,6 +10,8 @@ var extend = Polymer.extend; var apis = scope.api.declaration; + var deferred = {}; + // imperative implementation: Polymer() // maps tag names to prototypes @@ -17,20 +19,53 @@ // register an 'own' prototype for tag `name` function element(name, prototype) { - registry[name] = prototype; + registry[name] = prototype || {}; + if (deferred[name]) { + deferred[name].define(); + } } // returns a prototype that chains to or HTMLElement function generatePrototype(tag) { return Object.create(HTMLElement.getPrototypeForTag(tag)); } + + // On platforms that do not support __proto__ (IE10), the prototype chain + // of a custom element is simulated via installation of __proto__. + // Although custom elements manages this, we install it here so it's + // available during desuaring. + function ensurePrototypeTraversal(prototype) { + if (!Object.__proto__) { + var ancestor = Object.getPrototypeOf(prototype); + prototype.__proto__ = ancestor; + if (scope.isBase(ancestor)) { + ancestor.__proto__ = Object.getPrototypeOf(ancestor); + } + } + } // declarative implementation: var prototype = generatePrototype(); extend(prototype, { - // custom element processing + // TODO(sjmiles): temporary BC readyCallback: function() { + this._createdCallback(); + }, + createdCallback: function() { + this._createdCallback(); + }, + // custom element processing + _createdCallback: function() { + // fetch our element name + var name = this.getAttribute('name'); + if (registry[name]) { + this.define(); + } else { + deferred[name] = this; + } + }, + define: function() { // fetch our element name var name = this.getAttribute('name'); // fetch our extendee name @@ -45,6 +80,7 @@ // Potentially remove when spec bug is addressed. // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407 this.addResolvePathApi(); + ensurePrototypeTraversal(this.prototype); // declarative features this.desugar(); // under ShadowDOMPolyfill, transforms to approximate missing CSS features @@ -111,7 +147,7 @@ // make a fresh object that inherits from a prototype object inheritObject: function(prototype, name) { // copy inherited properties onto a new object - prototype[name] = extend({}, prototype.__proto__[name]); + prototype[name] = extend({}, Object.getPrototypeOf(prototype)[name]); }, // register 'prototype' to custom element 'name', store constructor register: function(name) { diff --git a/src/deprecated.js b/src/deprecated.js new file mode 100644 index 0000000000..e543b2b475 --- /dev/null +++ b/src/deprecated.js @@ -0,0 +1,14 @@ +/* + * Copyright 2013 The Polymer Authors. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +// NOTE: put deprecated methods here that throw a useful error +Polymer.register = function(context) { + if (context != window) { + // context is the here, with a name attribute + var name = context.getAttribute('name'); + throw new Error('Polymer.register is deprecated in declaration of ' + name + '. Please see http://www.polymer-project.org/getting-started.html'); + } +}; diff --git a/src/instance/attributes.js b/src/instance/attributes.js index 47519df37b..57bee66eda 100644 --- a/src/instance/attributes.js +++ b/src/instance/attributes.js @@ -61,6 +61,19 @@ // convert representation of 'stringValue' based on type of 'defaultValue' deserializeValue: function(stringValue, defaultValue) { return scope.deserializeValue(stringValue, defaultValue); + }, + serializeValue: function(value) { + if (typeof value != 'object' && value !== undefined) { + return value; + } + }, + propertyToAttribute: function(name) { + if (Object.keys(this[PUBLISHED]).indexOf(name) >= 0) { + var serializedValue = this.serializeValue(this[name]); + if (serializedValue !== undefined) { + this.setAttribute(name, serializedValue); + } + } } }; diff --git a/src/instance/base.js b/src/instance/base.js index 1d35ab11fc..09289253f7 100644 --- a/src/instance/base.js +++ b/src/instance/base.js @@ -12,8 +12,15 @@ // user entry point for constructor-like initialization ready: function() { }, - // system entry point, do not override + // TODO(sjmiles): temporary BC readyCallback: function() { + this._createdCallback(); + }, + createdCallback: function() { + this._createdCallback(); + }, + // system entry point, do not override + _createdCallback: function() { //this.style.display = 'inline-block'; // install property observers // do this first so we can observe changes during initialization @@ -31,10 +38,44 @@ // bindings will self destruct after a short time; this is // necessary to make elements collectable as garbage // when polyfilling Object.observe - this.asyncUnbindAll(); + //this.asyncUnbindAll(); // user initialization this.ready(); }, + insertedCallback: function() { + this._enteredDocumentCallback(); + }, + enteredDocumentCallback: function() { + this._enteredDocumentCallback(); + }, + _enteredDocumentCallback: function() { + this.cancelUnbindAll(true); + // TODO(sorvell): bc + if (this.inserted) { + this.inserted(); + } + // invoke user action + if (this.enteredDocument) { + this.enteredDocument(); + } + }, + removedCallback: function() { + this._leftDocumentCallback(); + }, + leftDocumentCallback: function() { + this._leftDocumentCallback(); + }, + _leftDocumentCallback: function() { + this.asyncUnbindAll(); + // TODO(sorvell): bc + if (this.removed) { + this.removed(); + } + // invoke user action + if (this.leftDocument) { + this.leftDocument(); + } + }, // recursive ancestral initialization, oldest first parseElements: function(p) { if (p && p.element) { @@ -57,14 +98,9 @@ var elderRoot = this.shadowRoot; // make a shadow root var root = this.createShadowRoot(); - // memoize the elder root - root.olderShadowRoot = elderRoot; // migrate flag(s) root.applyAuthorStyles = this.applyAuthorStyles; root.resetStyleInheritance = this.resetStyleInheritance; - // TODO(sorvell): host not set per spec; we set it for convenience - // so we can traverse from root to host. - root.host = this; // stamp template // which includes parsing and applying MDV bindings before being // inserted (to avoid {{}} in attribute values) @@ -74,8 +110,6 @@ root.appendChild(dom); // perform post-construction initialization tasks on shadow root this.shadowRootReady(root, template); - // watch future changes to shadow root - CustomElements.watchShadow(this); // return the created shadow root return root; } @@ -100,7 +134,8 @@ }; } }, - attributeChangedCallback: function() { + attributeChangedCallback: function(name, oldValue) { + this.attributeToProperty(name, this.getAttribute(name)); if (this.attributeChanged) { this.attributeChanged.apply(this, arguments); } diff --git a/src/instance/mdv.js b/src/instance/mdv.js index 62b01f502f..f206e32f46 100644 --- a/src/instance/mdv.js +++ b/src/instance/mdv.js @@ -66,20 +66,6 @@ } }); } - }, - insertedCallback: function() { - this.cancelUnbindAll(true); - // invoke user 'inserted' - if (this.inserted) { - this.inserted(); - } - }, - removedCallback: function() { - this.asyncUnbindAll(); - // invoke user 'removed' - if (this.removed) { - this.removed(); - } } }; diff --git a/src/instance/properties.js b/src/instance/properties.js index 244cf26203..7c2c7d59c8 100644 --- a/src/instance/properties.js +++ b/src/instance/properties.js @@ -12,6 +12,8 @@ // magic words var OBSERVE_SUFFIX = 'Changed'; + + var PUBLISHED = scope.api.instance.attributes.PUBLISHED; // element api @@ -53,10 +55,13 @@ unregisterObservers(this); }, // property should be observed if it has an observation callback + // or if it is published shouldObserveProperty: function(name) { - return Boolean(this[name + OBSERVE_SUFFIX]); + return Boolean(this[name + OBSERVE_SUFFIX] || + Object.keys(this[PUBLISHED]).indexOf(name) >= 0); }, dispatchPropertyChange: function(name, oldValue) { + this.propertyToAttribute(name); invoke.call(this, name + OBSERVE_SUFFIX, [oldValue]); } }; diff --git a/src/instance/styles.js b/src/instance/styles.js index df26d593d8..cd54407cc8 100644 --- a/src/instance/styles.js +++ b/src/instance/styles.js @@ -39,10 +39,10 @@ var scope = this.findStyleController(); if (scope && !this.scopeHasElementStyle(scope, STYLE_CONTROLLER_SCOPE)) { // allow inherited controller styles - var proto = Object.getPrototypeOf(this), cssText = ''; + var proto = getPrototypeOf(this), cssText = ''; while (proto && proto.element) { cssText += proto.element.cssTextForScope(STYLE_CONTROLLER_SCOPE); - proto = Object.getPrototypeOf(proto); + proto = getPrototypeOf(proto); } if (cssText) { var style = this.element.cssTextToScopeStyle(cssText, @@ -73,6 +73,12 @@ } } }; + + // NOTE: use raw prototype traversal so that we ensure correct traversal + // on platforms where the protoype chain is simulated via __proto__ (IE10) + function getPrototypeOf(prototype) { + return prototype.__proto__; + } // exports diff --git a/src/lib/deserialize.js b/src/lib/deserialize.js index db03c1577a..e1f434920b 100644 --- a/src/lib/deserialize.js +++ b/src/lib/deserialize.js @@ -24,7 +24,7 @@ return (String(floatVal) === value) ? floatVal : value; }, 'object': function(value, defaultValue) { - if (!defaultValue) { + if (defaultValue === null) { return value; } try { diff --git a/src/lib/styles.js b/src/lib/styles.js deleted file mode 100644 index 91ca7ba15d..0000000000 --- a/src/lib/styles.js +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2013 The Polymer Authors. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ -(function(scope) { - - var STYLE_SELECTOR = 'style'; - var SHEET_SELECTOR = '[rel=stylesheet]'; - var STYLE_SCOPE_ATTRIBUTE = 'element'; - var STYLE_GLOBAL_SCOPE = 'global'; - var STYLE_CONTROLLER_SCOPE = 'controller'; - var SCOPE_ATTR = 'polymer-scope'; - - // imports - - var log = window.logFlags || {}; - - var styles = { - /** - * Install external stylesheets loaded in elements into the - * element's template. - * @param elementElement The element to style. - */ - installSheets: function(elementElement) { - installLocalSheets(elementElement); - installGlobalStyles(elementElement); - }, - /** - * Takes external stylesheets loaded in an element and moves - * their content into a - - - could become: - - -
- -
- - Note the use of @polyfill in the comment above a ShadowDOM specific style - declaration. This is a directive to the styling shim to use the selector - in comments in lieu of the next selector when running under polyfill. -*/ -(function(scope) { - -var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); -var concat = Array.prototype.concat.call.bind(Array.prototype.concat); -var slice = Array.prototype.slice.call.bind(Array.prototype.slice); - -var stylizer = { - hostRuleRe: /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim, - selectorRe: /([^{]*)({[\s\S]*?})/gim, - hostElementRe: /(.*)((?:\*)|(?:\:scope))(.*)/, - hostFixableRe: /^[.\[:]/, - cssCommentRe: /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim, - cssPolyfillCommentRe: /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim, - cssPseudoRe: /::(x-[^\s{,(]*)/gim, - selectorReSuffix: '([>\\s~+\[.,{:][\\s\\S]*)?$', - hostRe: /@host/gim, - cache: {}, - shimStyling: function(element) { - if (window.ShadowDOMPolyfill && element) { - // use caching to make working with styles nodes easier and to facilitate - // lookup of extendee - var name = element.getAttribute('name'); - stylizer.cacheDefinition(element); - stylizer.shimPolyfillDirectives(element.styles, name); - // find styles and apply shimming... - if (Polymer.strictPolyfillStyling) { - stylizer.applyScopeToContent(element.templateContent(), name); - } - stylizer.applyShimming(stylizer.stylesForElement(element), name); - } - }, - // Shim styles to be placed inside a shadowRoot. - // 1. shim @host rules and inherited @host rules - // 2. shim scoping: apply .scoped when available or pseudo-scoping when not - // (e.g. a selector 'div' becomes 'x-foo div') - shimShadowDOMStyling: function(styles, name) { - if (window.ShadowDOMPolyfill) { - stylizer.shimPolyfillDirectives(styles, name); - stylizer.applyShimming(styles, name); - } - }, - applyShimming: function(styles, name) { - var cssText = this.shimAtHost(styles, name); - cssText += this.shimScoping(styles, name); - this.addCssToDocument(cssText); - }, - cacheDefinition: function(element) { - var name = element.getAttribute('name'); - var content = element.templateContent(); - var styles = content && content.querySelectorAll('style'); - element.styles = styles ? slice(styles) : []; - stylizer.cache[name] = element; - }, - applyScopeToContent: function(root, name) { - if (root) { - forEach(root.querySelectorAll('*'), function(node) { - node.setAttribute(name, ''); - }); - forEach(root.querySelectorAll('template'), function(template) { - this.applyScopeToContent(templateContent(template), name); - }, this); - } - }, - stylesForElement: function(element) { - var styles = element.styles; - var content = element.templateContent(); - var shadow = content && content.querySelector('shadow'); - if (shadow || (content === null)) { - var extendee = this.findExtendee(element.getAttribute('name')); - if (extendee) { - var extendeeStyles = this.stylesForElement(extendee); - styles = concat(slice(extendeeStyles), slice(styles)); - } - } - return styles; - }, - findExtendee: function(name) { - var element = this.cache[name]; - return element && this.cache[element.getAttribute('extends')]; - }, - /* - * Process styles to convert native ShadowDOM rules that will trip - * up the css parser; we rely on decorating the stylesheet with comments. - * - * For example, we convert this rule: - * - * (comment start) @polyfill @host g-menu-item (comment end) - * shadow::-webkit-distributed(g-menu-item) { - * - * to this: - * - * scopeName g-menu-item { - * - **/ - shimPolyfillDirectives: function(styles, name) { - if (window.ShadowDOMPolyfill) { - if (styles) { - forEach(styles, function(s) { - s.textContent = this.convertPolyfillDirectives(s.textContent, name); - }, this); - } - } - }, - // form: @host { .foo { declarations } } - // becomes: scopeName.foo { declarations } - shimAtHost: function(styles, name) { - if (styles) { - return this.convertAtHostStyles(styles, name); - } - }, - /* Ensure styles are scoped. Pseudo-scoping takes a rule like: - * - * .foo {... } - * - * and converts this to - * - * scopeName .foo { ... } - */ - shimScoping: function(styles, name) { - if (styles) { - return this.convertScopedStyles(styles, name); - } - }, - convertPolyfillDirectives: function(cssText, name) { - var r = '', l = 0, matches, selector; - while (matches=this.cssPolyfillCommentRe.exec(cssText)) { - r += cssText.substring(l, matches.index); - // remove end comment delimiter (*/) - selector = matches[1].slice(0, -2).replace(this.hostRe, name); - r += this.scopeSelector(selector, name) + '{'; - l = this.cssPolyfillCommentRe.lastIndex; - } - r += cssText.substring(l, cssText.length); - return r; - }, - // consider styles that do not include component name in the selector to be - // unscoped and in need of promotion; - // for convenience, also consider keyframe rules this way. - findAtHostRules: function(cssRules, matcher) { - return Array.prototype.filter.call(cssRules, - this.isHostRule.bind(this, matcher)); - }, - isHostRule: function(matcher, cssRule) { - return (cssRule.selectorText && cssRule.selectorText.match(matcher)) || - (cssRule.cssRules && this.findAtHostRules(cssRule.cssRules, matcher).length) || - (cssRule.type == CSSRule.WEBKIT_KEYFRAMES_RULE); - }, - convertAtHostStyles: function(styles, name) { - var cssText = this.stylesToCssText(styles); - var r = '', l=0, matches; - while (matches=this.hostRuleRe.exec(cssText)) { - r += cssText.substring(l, matches.index); - r += this.scopeHostCss(matches[1], name); - l = this.hostRuleRe.lastIndex; - } - r += cssText.substring(l, cssText.length); - var selectorRe = new RegExp('^' + name + this.selectorReSuffix, 'm'); - var cssText = this.rulesToCss(this.findAtHostRules(this.cssToRules(r), - selectorRe)); - return cssText; - }, - scopeHostCss: function(cssText, name) { - var r = '', matches; - while (matches = this.selectorRe.exec(cssText)) { - r += this.scopeHostSelector(matches[1], name) +' ' + matches[2] + '\n\t'; - } - return r; - }, - // supports scopig by name and [is=name] syntax - scopeHostSelector: function(selector, name) { - var r = [], parts = selector.split(','), is = '[is=' + name + ']'; - parts.forEach(function(p) { - p = p.trim(); - // selector: *|:scope -> name - if (p.match(this.hostElementRe)) { - p = p.replace(this.hostElementRe, name + '$1$3, ' + is + '$1$3'); - // selector: .foo -> name.foo, [bar] -> name[bar] - } else if (p.match(this.hostFixableRe)) { - p = name + p + ', ' + is + p; - } - r.push(p); - }, this); - return r.join(', '); - }, - convertScopedStyles: function(styles, name) { - forEach(styles, function(s) { - if (s.parentNode) { - s.parentNode.removeChild(s); - } - }); - var cssText = this.stylesToCssText(styles).replace(this.hostRuleRe, ''); - cssText = this.convertPseudos(cssText); - var rules = this.cssToRules(cssText); - cssText = this.scopeRules(rules, name); - return cssText; - }, - convertPseudos: function(cssText) { - return cssText.replace(this.cssPseudoRe, ' [pseudo=$1]'); - }, - // change a selector like 'div' to 'name div' - scopeRules: function(cssRules, name) { - var cssText = ''; - forEach(cssRules, function(rule) { - if (rule.selectorText && (rule.style && rule.style.cssText)) { - cssText += this.scopeSelector(rule.selectorText, name, - Polymer.strictPolyfillStyling) + ' {\n\t'; - cssText += this.propertiesFromRule(rule) + '\n}\n\n'; - } else if (rule.media) { - cssText += '@media ' + rule.media.mediaText + ' {\n'; - cssText += this.scopeRules(rule.cssRules, name); - cssText += '\n}\n\n'; - } else if (rule.cssText) { - cssText += rule.cssText + '\n\n'; - } - }, this); - return cssText; - }, - propertiesFromRule: function(rule) { - var properties = rule.style.cssText; - // TODO(sorvell): Chrome cssom incorrectly removes quotes from the content - // property. (https://code.google.com/p/chromium/issues/detail?id=247231) - if (rule.style.content && !rule.style.content.match(/['"]+/)) { - properties = 'content: \'' + rule.style.content + '\';\n' + - rule.style.cssText.replace(/content:[^;]*;/g, ''); - } - return properties; - }, - selectorNeedsScoping: function(selector, name) { - var matchScope = '(' + name + '|\\[is=' + name + '\\])'; - var selectorRe = new RegExp('^' + matchScope + this.selectorReSuffix, 'm'); - return !selector.match(selectorRe); - }, - scopeSelector: function(selector, name, strict) { - var r = [], parts = selector.split(','); - parts.forEach(function(p) { - p = p.trim(); - if (this.selectorNeedsScoping(p, name)) { - p = strict ? this.applyStrictSelectorScope(p, name) : - this.applySimpleSelectorScope(p, name); - } - r.push(p); - }, this); - return r.join(', '); - }, - // scope via name and [is=name] - applySimpleSelectorScope: function(selector, name) { - return name + ' ' + selector + ', ' + '[is=' + name + '] ' + selector; - }, - // return a selector with [name] suffix on each simple selector - // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name] - applyStrictSelectorScope: function(selector, name) { - var splits = [' ', '>', '+', '~'], - scoped = selector, - attrName = '[' + name + ']'; - splits.forEach(function(sep) { - var parts = scoped.split(sep); - scoped = parts.map(function(p) { - var t = p.trim(); - if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) { - p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3') - } - return p; - }).join(sep); - }); - return scoped; - }, - stylesToCssText: function(styles, preserveComments) { - var cssText = ''; - forEach(styles, function(s) { - cssText += s.textContent + '\n\n'; - }); - // strip comments for easier processing - if (!preserveComments) { - cssText = this.stripCssComments(cssText); - } - return cssText; - }, - stripCssComments: function(cssText) { - return cssText.replace(this.cssCommentRe, ''); - }, - cssToRules: function(cssText) { - var style = document.createElement('style'); - style.textContent = cssText; - document.head.appendChild(style); - var rules = style.sheet.cssRules; - style.parentNode.removeChild(style); - return rules; - }, - rulesToCss: function(cssRules) { - for (var i=0, css=[]; i < cssRules.length; i++) { - css.push(cssRules[i].cssText); - } - return css.join('\n\n'); - }, - addCssToDocument: function(cssText) { - if (cssText) { - this.getSheet().appendChild(document.createTextNode(cssText)); - } - }, - // support for creating @host rules - getSheet: function() { - if (!this.sheet) { - this.sheet = document.createElement("style"); - this.sheet.setAttribute('polymer-polyfill', ''); - } - return this.sheet; - }, - addSheetToDocument: function() { - this.addCssToDocument('style { display: none !important; }\n'); - var head = document.querySelector('head'); - head.insertBefore(this.getSheet(), head.childNodes[0]); - } -}; - -// add polyfill stylesheet to document -if (window.ShadowDOMPolyfill) { - stylizer.addSheetToDocument(); -} - -// exports - -scope.shimStyling = stylizer.shimStyling; -scope.shimShadowDOMStyling = stylizer.shimShadowDOMStyling; -scope.shimPolyfillDirectives = stylizer.shimPolyfillDirectives.bind(stylizer); -scope.strictPolyfillStyling = false; - -})(Polymer); \ No newline at end of file diff --git a/test/html/callbacks.html b/test/html/callbacks.html index 47c8447683..e4bcba05be 100644 --- a/test/html/callbacks.html +++ b/test/html/callbacks.html @@ -73,7 +73,8 @@ xBase.parentNode.removeChild(xBase); xExtendor.parentNode.removeChild(xExtendor); - + // Ensure IE goes... + CustomElements.takeRecords(); setTimeout(function() { chai.assert.equal(xBase.isRemoved, true); chai.assert.equal(xExtendor.isRemoved, true); diff --git a/test/html/element-script.html b/test/html/element-script.html index 86742a8f0d..48cb7e24d9 100644 --- a/test/html/element-script.html +++ b/test/html/element-script.html @@ -24,7 +24,7 @@
-
@@ -45,6 +45,9 @@ + @@ -70,7 +73,8 @@ } }); - + + diff --git a/test/html/event-path.html b/test/html/event-path.html index c28456b04b..8ab12e9786 100644 --- a/test/html/event-path.html +++ b/test/html/event-path.html @@ -71,19 +71,18 @@ menuButton.$.menuButtonContent, menu.$.selectorContent, menu.$.selectorDiv, - menu.$.menuShadow.olderShadowRoot, + menu.shadowRoot.olderShadowRoot, menu.$.menuShadow, menu.$.menuDiv, - menu.webkitShadowRoot, + menu.shadowRoot, menu, menuButton.$.menuButtonDiv, menuButton.$.overlay.$.overlayContent, - menuButton.$.overlay.webkitShadowRoot, + menuButton.$.overlay.shadowRoot, menuButton.$.overlay, - menuButton.webkitShadowRoot, + menuButton.shadowRoot, menuButton ]; -console.log(path) var x = 0; path.forEach(function(n, i) { n.addEventListener('x', function(e) { diff --git a/test/html/prop-attr-reflection.html b/test/html/prop-attr-reflection.html new file mode 100644 index 0000000000..b404c6ad84 --- /dev/null +++ b/test/html/prop-attr-reflection.html @@ -0,0 +1,74 @@ + + + + publish attributes + + + + + + + + + + + + + + + + + + + diff --git a/test/html/styling/apply-reset-styles.html b/test/html/styling/apply-reset-styles.html index 1e60a5d07e..aea8ce69f3 100644 --- a/test/html/styling/apply-reset-styles.html +++ b/test/html/styling/apply-reset-styles.html @@ -39,6 +39,11 @@ + - +
red
- - - - +
diff --git a/test/html/unbind.html b/test/html/unbind.html index c5a019d8d0..265857ccfd 100644 --- a/test/html/unbind.html +++ b/test/html/unbind.html @@ -33,6 +33,8 @@ diff --git a/test/js/attrs.js b/test/js/attrs.js index 06191d0174..e0271f8bc2 100644 --- a/test/js/attrs.js +++ b/test/js/attrs.js @@ -8,4 +8,5 @@ htmlSuite('attributes-declarative', function() { htmlTest('html/publish-attributes.html'); htmlTest('html/take-attributes.html'); htmlTest('html/attr-mustache.html'); + htmlTest('html/prop-attr-reflection.html'); }); \ No newline at end of file diff --git a/test/js/events.js b/test/js/events.js index 5c2d66895e..b92bfaf696 100644 --- a/test/js/events.js +++ b/test/js/events.js @@ -32,12 +32,14 @@ suite('events', function() { } test('host event', function(done) { - createTestElement('x-foo'); + createTestElement('x-events-foo'); + // Ensure IE goes... + CustomElements.takeRecords(); setTimeout(function() { - var foo = document.createElement('x-foo'); + var foo = document.createElement('x-events-foo'); work.appendChild(foo); foo.click(); - assert.equal(results.textContent, 'x-foo'); + assert.equal(results.textContent, 'x-events-foo'); done(); }, 0); }); diff --git a/test/js/mdv-syntax.js b/test/js/mdv-syntax.js index daf6c72c52..03c6a56b8b 100644 --- a/test/js/mdv-syntax.js +++ b/test/js/mdv-syntax.js @@ -5,6 +5,11 @@ */ htmlSuite('MDV syntax', function() { - htmlTest('html/mdv-syntax.html'); - htmlTest('html/mdv-syntax.html?shadow'); + // TODO(sorvell): only test under native until the following + // ShadowDOMPolyfill issue is addressed: + // https://github.com/Polymer/ShadowDOM/issues/189 + if (!window.ShadowDOMPolyfill) { + htmlTest('html/mdv-syntax.html'); + } + //htmlTest('html/mdv-syntax.html?shadow'); }); diff --git a/test/js/oop.js b/test/js/oop.js index 745728c4b3..2e8a2df61f 100644 --- a/test/js/oop.js +++ b/test/js/oop.js @@ -4,6 +4,16 @@ * license that can be found in the LICENSE file. */ +function createObjectWithProto(prototype) { + var obj = Object.create(prototype); + // NOTE: On some platforms (IE10) __proto__ does not exist. + // In this case, we install it. + if (!Object.__proto__) { + obj.__proto__ = prototype; + } + return obj; + } + suite('oop', function() { var assert = chai.assert; @@ -21,7 +31,7 @@ suite('oop', function() { }; // var Sub = function() {}; - Sub.prototype = Object.create(Base.prototype); + Sub.prototype = createObjectWithProto(Base.prototype); Sub.prototype.say = function() { this.super(); this.log(' sub'); @@ -29,7 +39,7 @@ suite('oop', function() { Sub.prototype.say.nom = 'say'; // var SubSub = function() {}; - SubSub.prototype = Object.create(Sub.prototype); + SubSub.prototype = createObjectWithProto(Sub.prototype); SubSub.prototype.say = function() { this.super(); this.log(' subsub'); diff --git a/test/js/register.js b/test/js/register.js index 8c03b487ff..4ff02de121 100644 --- a/test/js/register.js +++ b/test/js/register.js @@ -19,7 +19,7 @@ suite('register', function() { }); test('register', function(done) { - Polymer('x-foo', { + Polymer('x-register-foo', { ready: function() { this.message = 'foo'; }, @@ -27,9 +27,11 @@ suite('register', function() { this.message = 'hello'; } }); - work.innerHTML = ''; + work.innerHTML = ''; + // Ensure IE goes... + CustomElements.takeRecords(); setTimeout(function() { - var foo = document.createElement('x-foo'); + var foo = document.createElement('x-register-foo'); // test ready assert.equal(foo.message, 'foo'); // test sayHello @@ -46,4 +48,4 @@ htmlSuite('element callbacks', function() { htmlSuite('element script', function() { htmlTest('html/element-script.html'); -}); \ No newline at end of file +});