Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview Deferred resource loader for OOBE/Login screens. | 6 * @fileoverview Deferred resource loader for OOBE/Login screens. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 cr.define('cr.ui.login.ResourceLoader', function() { | 9 cr.define('cr.ui.login.ResourceLoader', function() { |
| 10 'use strict'; | 10 'use strict'; |
| 11 | 11 |
| 12 // Deferred assets. | 12 // Deferred assets. |
| 13 var ASSETS = {}; | 13 var ASSETS = {}; |
| 14 | 14 |
| 15 /** | 15 /** |
| 16 * Register assets for deferred loading. When the bundle is loaded | 16 * Register assets for deferred loading. When the bundle is loaded |
| 17 * assets will be added to the current page's DOM: <link> and <script> | 17 * assets will be added to the current page's DOM: <link> and <script> |
| 18 * tags pointing to the CSS and JavaScript will be added to the | 18 * tags pointing to the CSS and JavaScript will be added to the |
| 19 * <head>, and HTML will be appended to a specified element. | 19 * <head>, and HTML will be appended to a specified element. |
| 20 * | 20 * |
| 21 * @param {Object} desc Descriptor for the asset bundle | 21 * @param {Object} desc Descriptor for the asset bundle |
| 22 * @param {string} desc.id Unique identifier for the asset bundle. | 22 * @param {string} desc.id Unique identifier for the asset bundle. |
| 23 * @param {Array=} desc.js URLs containing JavaScript sources. | 23 * @param {Array=} desc.js URLs containing JavaScript sources. |
| 24 * @param {Array=} desc.css URLs containing CSS rules. | 24 * @param {Array=} desc.css URLs containing CSS rules. |
| 25 * @param {Array<Object>=} desc.html Descriptors for HTML fragments, | 25 * @param {Array<Object>=} desc.html Descriptors for HTML fragments, |
| 26 * each of which has a 'url' property and a 'targetID' property that | 26 * each of which has a 'url' property and a 'targetID' property that |
| 27 * specifies the node under which the HTML should be appended. | 27 * specifies the node under which the HTML should be appended. If 'targetID' |
| 28 * is null, then the fetched body will be appended to document.body. | |
| 28 * | 29 * |
| 29 * Example: | 30 * Example: |
| 30 * ResourceLoader.registerAssets({ | 31 * ResourceLoader.registerAssets({ |
| 31 * id: 'bundle123', | 32 * id: 'bundle123', |
| 32 * js: ['//foo.com/src.js', '//bar.com/lib.js'], | 33 * js: ['//foo.com/src.js', '//bar.com/lib.js'], |
| 33 * css: ['//foo.com/style.css'], | 34 * css: ['//foo.com/style.css'], |
| 34 * html: [{ url: '//foo.com/tmpls.html' targetID: 'tmpls'}] | 35 * html: [{ url: '//foo.com/tmpls.html' targetID: 'tmpls'}] |
| 35 * }); | 36 * }); |
| 36 * | 37 * |
| 37 * Note: to avoid cross-site requests, all HTML assets must be served | 38 * Note: to avoid cross-site requests, all HTML assets must be served |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 var fileURL = /^file:\/\//; | 112 var fileURL = /^file:\/\//; |
| 112 return xhr.readyState == 4 && | 113 return xhr.readyState == 4 && |
| 113 (xhr.status == 200 || fileURL.test(url) && xhr.status == 0); | 114 (xhr.status == 200 || fileURL.test(url) && xhr.status == 0); |
| 114 } | 115 } |
| 115 | 116 |
| 116 /* | 117 /* |
| 117 * Load a chunk of HTML into the current document. | 118 * Load a chunk of HTML into the current document. |
| 118 * @param {string} id Identifier of the page's asset bundle. | 119 * @param {string} id Identifier of the page's asset bundle. |
| 119 * @param {Object} html Descriptor of the HTML to fetch. | 120 * @param {Object} html Descriptor of the HTML to fetch. |
| 120 * @param {string} html.url The URL resolving to some HTML. | 121 * @param {string} html.url The URL resolving to some HTML. |
| 121 * @param {string} html.targetID The element ID to which the retrieved | 122 * @param {string?} html.targetID The element ID to which the retrieved |
| 122 * HTML nodes should be appended. | 123 * HTML nodes should be appended. If null, then the elements will be appended |
| 124 * to document.body instead. | |
| 123 */ | 125 */ |
| 124 function loadHTML(id, html) { | 126 function loadHTML(id, html) { |
| 125 var xhr = new XMLHttpRequest(); | 127 var xhr = new XMLHttpRequest(); |
| 126 xhr.open('GET', html.url); | 128 xhr.open('GET', html.url); |
| 127 xhr.onreadystatechange = function() { | 129 xhr.onreadystatechange = function() { |
| 128 if (isSuccessful(html.url, xhr)) { | 130 if (isSuccessful(html.url, xhr)) { |
| 129 moveNodes(this.responseXML.body, $(html.targetID)); | 131 moveNodes(this.responseXML.head, document.head); |
| 132 moveNodes(this.responseXML.body, $(html.targetID) || document.body); | |
| 133 | |
| 130 resourceLoaded(id); | 134 resourceLoaded(id); |
| 131 } | 135 } |
| 132 }; | 136 }; |
| 133 xhr.responseType = 'document'; | 137 xhr.responseType = 'document'; |
| 134 xhr.send(); | 138 xhr.send(); |
| 135 } | 139 } |
| 136 | 140 |
| 137 /** | 141 /** |
| 138 * Record that a resource has been loaded for an asset bundle. When | 142 * Record that a resource has been loaded for an asset bundle. When |
| 139 * all the resources have been loaded the callback that was specified | 143 * all the resources have been loaded the callback that was specified |
| 140 * in the loadAssets call is invoked. | 144 * in the loadAssets call is invoked. |
| 141 * @param {string} id Identifier of the asset bundle. | 145 * @param {string} id Identifier of the asset bundle. |
| 142 */ | 146 */ |
| 143 function resourceLoaded(id) { | 147 function resourceLoaded(id) { |
| 144 var assets = ASSETS[id]; | 148 var assets = ASSETS[id]; |
| 145 assets.count--; | 149 assets.count--; |
| 146 if (assets.count == 0) | 150 if (assets.count == 0) |
| 147 finishedLoading(id); | 151 finishedLoading(id); |
| 148 } | 152 } |
| 149 | 153 |
| 150 /** | 154 /** |
| 151 * Finishes loading an asset bundle. | 155 * Finishes loading an asset bundle. |
| 152 * @param {string} id Identifier of the asset bundle. | 156 * @param {string} id Identifier of the asset bundle. |
| 153 */ | 157 */ |
| 154 function finishedLoading(id) { | 158 function finishedLoading(id) { |
| 155 var assets = ASSETS[id]; | 159 var assets = ASSETS[id]; |
| 156 console.log('Finished loading asset bundle', id); | 160 console.log('Finished loading asset bundle ' + id); |
| 157 assets.loaded = true; | 161 assets.loaded = true; |
| 158 window.setTimeout(function() { | 162 window.setTimeout(function() { |
| 159 assets.callback(); | 163 assets.callback(); |
| 160 chrome.send('screenAssetsLoaded', [id]); | 164 chrome.send('screenAssetsLoaded', [id]); |
| 161 }, 0); | 165 }, 0); |
| 162 } | 166 } |
| 163 | 167 |
| 164 /** | 168 /** |
| 165 * Load an asset bundle, invoking the callback when finished. | 169 * Load an asset bundle, invoking the callback when finished. |
| 166 * @param {string} id Identifier for the asset bundle to load. | 170 * @param {string} id Identifier for the asset bundle to load. |
| 167 * @param {function()=} callback Function to invoke when done loading. | 171 * @param {function()=} callback Function to invoke when done loading. |
| 168 */ | 172 */ |
| 169 function loadAssets(id, callback) { | 173 function loadAssets(id, callback) { |
| 170 var assets = ASSETS[id]; | 174 var assets = ASSETS[id]; |
| 171 assets.callback = callback || function() {}; | 175 assets.callback = callback || function() {}; |
| 172 console.log('Loading asset bundle', id); | 176 console.log('Loading asset bundle ' + id); |
| 173 if (alreadyLoadedAssets(id)) | 177 if (alreadyLoadedAssets(id)) |
| 174 console.warn('asset bundle', id, 'already loaded!'); | 178 console.warn('asset bundle', id, 'already loaded!'); |
| 175 if (assets.count == 0) { | 179 if (assets.count == 0) { |
| 176 finishedLoading(id); | 180 finishedLoading(id); |
| 177 } else { | 181 } else { |
| 178 assets.css.forEach(loadCSS.bind(null, id)); | 182 assets.css.forEach(loadCSS.bind(null, id)); |
| 179 assets.js.forEach(loadJS.bind(null, id)); | 183 assets.js.forEach(loadJS.bind(null, id)); |
| 180 assets.html.forEach(loadHTML.bind(null, id)); | 184 assets.html.forEach(loadHTML.bind(null, id)); |
| 181 } | 185 } |
| 182 } | 186 } |
| 183 | 187 |
| 188 /** | |
| 189 * Load an asset bundle after the document has been loaded and Chrome is idle. | |
| 190 * @param {string} id Identifier for the asset bundle to load. | |
| 191 * @param {function()=} callback Function to invoke when done loading. | |
| 192 * @param {number=} idleTimeoutMs The maximum amount of time to wait for an | |
| 193 * idle notification. | |
| 194 */ | |
| 195 function loadAssetsOnIdle(id, callback, idleTimeoutMs = 250) { | |
|
xiyuan
2016/05/09 18:27:38
idleTimeoutMs -> opt_IdleTimeoutMs since it is an
stevenjb
2016/05/09 19:10:26
We have been using ES6 is settings UI since it wil
jdufault
2016/05/10 18:45:23
Done.
| |
| 196 let loadOnIdle = function() { | |
| 197 window.requestIdleCallback(function() { | |
| 198 loadAssets(id, callback); | |
| 199 }, { timeout: idleTimeoutMs }); | |
| 200 }; | |
| 201 | |
| 202 if (document.readyState == 'complete') { | |
| 203 loadOnIdle(); | |
| 204 } | |
| 205 else { | |
|
xiyuan
2016/05/09 18:27:38
nit: move this to line 204, i.e. } else {
jdufault
2016/05/10 18:45:23
Done.
| |
| 206 window.addEventListener('DOMContentLoaded', loadOnIdle); | |
| 207 } | |
| 208 } | |
| 209 | |
| 184 return { | 210 return { |
| 185 alreadyLoadedAssets: alreadyLoadedAssets, | 211 alreadyLoadedAssets: alreadyLoadedAssets, |
| 186 hasDeferredAssets: hasDeferredAssets, | 212 hasDeferredAssets: hasDeferredAssets, |
| 187 loadAssets: loadAssets, | 213 loadAssets: loadAssets, |
| 214 loadAssetsOnIdle: loadAssetsOnIdle, | |
| 188 registerAssets: registerAssets | 215 registerAssets: registerAssets |
| 189 }; | 216 }; |
| 190 }); | 217 }); |
| OLD | NEW |