1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/**
@license
Copyright (c) 2017 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
*/
import './boot.js';
let scheduled = false;
let beforeRenderQueue = [];
let afterRenderQueue = [];
function schedule() {
scheduled = true;
// before next render
requestAnimationFrame(function() {
scheduled = false;
flushQueue(beforeRenderQueue);
// after the render
setTimeout(function() {
runQueue(afterRenderQueue);
});
});
}
function flushQueue(queue) {
while (queue.length) {
callMethod(queue.shift());
}
}
function runQueue(queue) {
for (let i=0, l=queue.length; i < l; i++) {
callMethod(queue.shift());
}
}
function callMethod(info) {
const context = info[0];
const callback = info[1];
const args = info[2];
try {
callback.apply(context, args);
} catch(e) {
setTimeout(() => {
throw e;
});
}
}
function flush() {
while (beforeRenderQueue.length || afterRenderQueue.length) {
flushQueue(beforeRenderQueue);
flushQueue(afterRenderQueue);
}
scheduled = false;
}
/**
* Module for scheduling flushable pre-render and post-render tasks.
*
* @summary Module for scheduling flushable pre-render and post-render tasks.
*/
`TODO(modulizer): A namespace named Polymer.RenderStatus was
declared here. The surrounding comments should be reviewed,
and this string can then be deleted`;
/**
* Enqueues a callback which will be run before the next render, at
* `requestAnimationFrame` timing.
*
* This method is useful for enqueuing work that requires DOM measurement,
* since measurement may not be reliable in custom element callbacks before
* the first render, as well as for batching measurement tasks in general.
*
* Tasks in this queue may be flushed by calling `flush()`.
*
* @param {*} context Context object the callback function will be bound to
* @param {function(...*):void} callback Callback function
* @param {!Array=} args An array of arguments to call the callback function with
* @return {void}
*/
export function beforeNextRender(context, callback, args) {
if (!scheduled) {
schedule();
}
beforeRenderQueue.push([context, callback, args]);
}
/**
* Enqueues a callback which will be run after the next render, equivalent
* to one task (`setTimeout`) after the next `requestAnimationFrame`.
*
* This method is useful for tuning the first-render performance of an
* element or application by deferring non-critical work until after the
* first paint. Typical non-render-critical work may include adding UI
* event listeners and aria attributes.
*
* @param {*} context Context object the callback function will be bound to
* @param {function(...*):void} callback Callback function
* @param {!Array=} args An array of arguments to call the callback function with
* @return {void}
*/
export function afterNextRender(context, callback, args) {
if (!scheduled) {
schedule();
}
afterRenderQueue.push([context, callback, args]);
}
/**
* Flushes all `beforeNextRender` tasks, followed by all `afterNextRender`
* tasks.
*
* @return {void}
*/
export { flush };
|