Index: chrome/browser/resources/settings/controls/settings_idle_load.js |
diff --git a/chrome/browser/resources/settings/controls/settings_idle_load.js b/chrome/browser/resources/settings/controls/settings_idle_load.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3d741adb2cd4c08b167d265ef05baa903b7a8f6e |
--- /dev/null |
+++ b/chrome/browser/resources/settings/controls/settings_idle_load.js |
@@ -0,0 +1,88 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/** |
+ * @fileoverview |
+ * settings-idle-load is a simple variant of dom-if designed for lazy |
+ * loading and rendering of elements that are accessed imperatively. A URL is |
+ * given that holds the elements to be loaded lazily. |
+ */ |
+Polymer({ |
+ is: 'settings-idle-load', |
+ extends: 'template', |
+ |
+ behaviors: [Polymer.Templatizer], |
+ |
+ properties: { |
+ /** |
+ * If specified, it will be loaded via an HTML import before stamping the |
+ * template. |
+ */ |
+ url: String, |
+ }, |
+ |
+ /** @private {TemplatizerNode} */ |
+ child_: null, |
+ |
+ /** @private {number} */ |
+ idleCallback_: 0, |
+ |
+ /** @override */ |
+ attached: function() { |
+ this.idleCallback_ = requestIdleCallback(this.get.bind(this)); |
+ }, |
+ |
+ /** @override */ |
+ detached: function() { |
+ // No-op if callback already fired. |
+ cancelIdleCallback(this.idleCallback_); |
+ }, |
+ |
+ /** |
+ * @return {!Promise<Element>} Child element which has been stamped into the |
+ * DOM tree. |
+ */ |
+ get: function() { |
+ if (this.loading_) |
+ return this.loading_; |
+ |
+ this.loading_ = new Promise(function(resolve, reject) { |
+ this.importHref(this.url, function() { |
+ assert(!this.ctor); |
+ this.templatize(this); |
+ assert(this.ctor); |
+ |
+ var instance = this.stamp({}); |
+ |
+ assert(!this.child_); |
+ this.child_ = instance.root.firstElementChild; |
+ |
+ this.parentNode.insertBefore(instance.root, this); |
+ resolve(this.child_); |
+ |
+ this.fire('lazy-loaded'); |
+ }.bind(this), reject, true); |
+ }.bind(this)); |
+ |
+ return this.loading_; |
+ }, |
+ |
+ /** |
+ * @param {string} prop |
+ * @param {Object} value |
+ */ |
+ _forwardParentProp: function(prop, value) { |
+ if (this.child_) |
+ this.child_._templateInstance[prop] = value; |
+ }, |
+ |
+ /** |
+ * @param {string} path |
+ * @param {Object} value |
+ */ |
+ _forwardParentPath: function(path, value) { |
+ if (this.child_) |
+ this.child_._templateInstance.notifyPath(path, value, true); |
+ } |
+}); |