Skip to content
Browse files

Fixes #2193: Implements workaround for https://code.google.com/p/chro…

…mium/issues/detail?id=516550 by adding Polymer.RenderStatus.whenReady and using it to defer `attached`
  • Loading branch information...
1 parent eafa3e5 commit 2bffc4c84e706043355eaf367100b60beb9cce60 @sorvell sorvell committed
View
10 src/lib/base.html
@@ -37,8 +37,14 @@
// reserved for canonical behavior
attachedCallback: function() {
- this.isAttached = true;
- this._doBehavior('attached'); // abstract
+ // NOTE: workaround for:
+ // https://code.google.com/p/chromium/issues/detail?id=516550
+ // To allow querying style/layout data in attached, we defer it
+ // until we are sure rendering is ready.
+ Polymer.RenderStatus.whenReady(function() {
+ this.isAttached = true;
+ this._doBehavior('attached'); // abstract
+ }.bind(this));
},
// reserved for canonical behavior
View
46 src/lib/imports-status.html
@@ -1,46 +0,0 @@
-<!--
-@license
-Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
-This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
-The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
-The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
-Code distributed by Google as part of the polymer project is also
-subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
--->
-
-<script>
-
- Polymer.ImportStatus = {
-
- _ready: false,
-
- _callbacks: [],
-
- whenLoaded: function(cb) {
- if (this._ready) {
- cb();
- } else {
- this._callbacks.push(cb);
- }
- },
-
- _importsLoaded: function() {
- this._ready = true;
- this._callbacks.forEach(function(cb) {
- cb();
- });
- this._callbacks = [];
- }
- };
-
- window.addEventListener('load', function() {
- Polymer.ImportStatus._importsLoaded();
- });
-
- if (window.HTMLImports) {
- HTMLImports.whenReady(function() {
- Polymer.ImportStatus._importsLoaded();
- });
- }
-
-</script>
View
65 src/lib/render-status.html
@@ -0,0 +1,65 @@
+<!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<script>
+ /*
+ * Helper for determining when first render occurs.
+ * Call `Polymer.RenderStatus.whenReady(callback)` to be notified when
+ * first render occurs or immediately if it has already occured.
+ * Note that since HTML Imports are designed to load before rendering,
+ * this call can also be used to guarantee that imports have loaded.
+ * This behavior is normalized to function correctly with the HTMLImports
+ * polyfill which does not otherwise maintain this rendering guarantee.
+ * Querying style and layout data before first render is currently
+ * problematic on some browsers (Blink/Webkit) so this helper can be used
+ * to prevent doing so until a safe time.
+ */
+ Polymer.RenderStatus = {
+
+ _ready: false,
+
+ _callbacks: [],
+
+ whenReady: function(cb) {
+ if (this._ready) {
+ cb();
+ } else {
+ this._callbacks.push(cb);
+ }
+ },
+
+ _makeReady: function() {
+ this._ready = true;
+ this._callbacks.forEach(function(cb) {
+ cb();
+ });
+ this._callbacks = [];
+ },
+
+ _catchFirstRender: function() {
+ requestAnimationFrame(function() {
+ Polymer.RenderStatus._makeReady();
+ });
+ }
+ };
+
+ if (window.HTMLImports) {
+ HTMLImports.whenReady(function() {
+ Polymer.RenderStatus._catchFirstRender();
+ });
+ } else {
+ Polymer.RenderStatus._catchFirstRender();
+ }
+
+ // NOTE: for bc.
+ Polymer.ImportStatus = Polymer.RenderStatus;
+ Polymer.ImportStatus.whenLoaded = Polymer.ImportStatus.whenReady;
+
+</script>
View
4 src/lib/template/dom-bind.html
@@ -48,8 +48,6 @@
-->
-<link rel="import" href="../imports-status.html">
-
<script>
Polymer({
@@ -68,7 +66,7 @@
created: function() {
// Ensure dom-bind doesn't stamp until all possible dependencies
// have resolved
- Polymer.ImportStatus.whenLoaded(this._markImportsReady.bind(this));
+ Polymer.RenderStatus.whenReady(this._markImportsReady.bind(this));
},
_ensureReady: function() {
View
1 src/polymer-lib.html
@@ -12,5 +12,6 @@
<link rel="import" href="lib/settings.html">
<link rel="import" href="lib/polymer-bootstrap.html">
<link rel="import" href="lib/lang.html">
+<link rel="import" href="lib/render-status.html">
<link rel="import" href="lib/base.html">
<link rel="import" href="lib/dom-module.html">
View
1 test/runner.html
@@ -26,6 +26,7 @@
'unit/template.html',
'unit/ready.html',
'unit/ready-shadow.html',
+ 'unit/attached-style.html',
'unit/configure.html',
'unit/shady.html',
'unit/polymer-dom.html',
View
36 test/smoke/offsetParent-polymer-import.html
@@ -0,0 +1,36 @@
+<!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../polymer.html">
+
+<dom-module id="some-thing">
+ <script>
+ Polymer({
+
+ is: 'some-thing',
+
+ created: function() {
+ console.warn(this.localName, 'created');
+ },
+
+ attached: function() {
+ this.report();
+ },
+
+ report: function() {
+ console.group(this.localName, 'report');
+ console.log('offsetParent is', this.offsetParent);
+ console.log('parentNode', this.parentNode, 'has position',
+ window.getComputedStyle(this.parentNode).position);
+ console.groupEnd(this.localName);
+ }
+
+ });
+</script>
+</dom-module>
View
12 test/smoke/offsetParent.html
@@ -10,15 +10,9 @@
-->
<html>
<head>
- <script>
- function importLoaded() {
- console.warn('import loaded');
- document.querySelector('some-thing').report();
- }
-
- </script>
- <link rel="import" href="offsetParent-import.html" onload="importLoaded()">
-
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+ <!-- <link rel="import" href="offsetParent-import.html" > -->
+ <link rel="import" href="offsetParent-polymer-import.html" >
</head>
<body style="position: relative;">
<some-thing></some-thing>
View
32 test/unit/attached-style-elements.html
@@ -0,0 +1,32 @@
+<!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<dom-module id="attached-style">
+ <style>
+ :host {
+ display: block;
+ box-sizing: border-box;
+ border: 1px solid black;
+ height: 100px;
+ }
+ </style>
+ <template>Hi</template>
+ <script>
+ Polymer({
+
+ is: 'attached-style',
+
+ attached: function() {
+ this.offsetParentAtAttachedTime = this.offsetParent;
+ this.offsetHeightAtAttachedTime = this.offsetHeight;
+ }
+
+ });
+ </script>
+</dom-module>
View
62 test/unit/attached-style.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script>
+ addEventListener('WebComponentsReady', function() {
+ window.elementsReady = true;
+ // Record layout data at WebComponentsReady time for later testing
+ var el = document.querySelector('attached-style');
+ el.offsetParentAtWebComponentsReadyTime = el.offsetParent;
+ el.offsetHeightAtWebComponentsReadyTime = el.offsetHeight;
+ });
+ </script>
+ <script src="../../../web-component-tester/browser.js"></script>
+
+ <link rel="import" href="../../polymer.html">
+ <link rel="import" href="attached-style-elements.html">
+</head>
+<body>
+
+ <attached-style></attached-style>
+
+ <script>
+
+ suite('Attached can get computed style data', function() {
+
+ var el = document.querySelector('attached-style');
+
+ test('style data available at attached time', function() {
+ assert.equal(el.offsetParentAtAttachedTime, document.body);
+ assert.equal(el.offsetHeightAtAttachedTime, 100);
+ });
+
+ test('style data available at WebComponentsReady time', function(done) {
+ function finish() {
+ assert.equal(el.offsetParentAtWebComponentsReadyTime, document.body);
+ assert.equal(el.offsetHeightAtWebComponentsReadyTime, 100);
+ done();
+ }
+ if (!window.elementsReady) {
+ addEventListener('WebComponentsReady', finish);
+ } else {
+ finish();
+ }
+ })
+
+ });
+ </script>
+
+</body>
+</html>

0 comments on commit 2bffc4c

Please sign in to comment.
Something went wrong with that request. Please try again.