blob: 4cbb765d8542f18bf52f4fb40916ea30be16dac9 [file] [log] [blame]
// 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.
*/
import {assert} from '//resources/js/assert.m.js';
import {html, Polymer, TemplateInstanceBase, templatize} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {ensureLazyLoaded} from '../ensure_lazy_loaded.js';
Polymer({
is: 'settings-idle-load',
_template: html`<slot></slot>`,
properties: {
/**
* If specified, it will be loaded via an HTML import before stamping the
* template.
*/
url: String,
},
/** @private {?Element} */
child_: null,
/** @private {?Element|?TemplateInstanceBase} */
instance_: null,
/** @private {number} */
idleCallback_: 0,
/** @override */
attached() {
this.idleCallback_ = requestIdleCallback(() => {
this.get();
});
},
/** @override */
detached() {
// No-op if callback already fired.
cancelIdleCallback(this.idleCallback_);
},
/**
* @return {!Promise<!Element>} Resolves with the stamped child element after
* the lazy module has been loaded.
*/
requestLazyModule_() {
return new Promise((resolve, reject) => {
ensureLazyLoaded().then(() => {
const template =
/** @type {!HTMLTemplateElement} */ (this.getContentChildren()[0]);
const TemplateClass = templatize(template, this, {
mutableData: false,
forwardHostProp: this._forwardHostPropV2,
});
this.instance_ = new TemplateClass();
assert(!this.child_);
this.child_ = this.instance_.root.firstElementChild;
this.parentNode.insertBefore(this.instance_.root, this);
resolve(this.child_);
this.fire('lazy-loaded');
}, reject);
});
},
/**
* @return {!Promise<Element>} Child element which has been stamped into the
* DOM tree.
*/
get() {
if (this.loading_) {
return this.loading_;
}
this.loading_ = this.requestLazyModule_();
return this.loading_;
},
/**
* @param {string} prop
* @param {Object} value
*/
_forwardHostPropV2(prop, value) {
if (this.instance_) {
this.instance_.forwardHostProp(prop, value);
}
},
});