/
index.js
309 lines (294 loc) · 9.92 KB
/
index.js
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/**
* Creates an instance of Error that aggregates and preserves an innerError.
* @param message The error message.
* @param innerError The inner error message to aggregate.
* @param skipIfAlreadyAggregate Indicates to not wrap the inner error if it itself already has an innerError.
* @return The Error instance.
*/
export function AggregateError(message: string, innerError?: Error, skipIfAlreadyAggregate?: boolean): Error {
if (innerError) {
if (innerError.innerError && skipIfAlreadyAggregate) {
return innerError;
}
if (innerError.stack) {
message += `\n------------------------------------------------\ninner error: ${innerError.stack}`;
}
}
let e = new Error(message);
if (innerError) {
e.innerError = innerError;
}
return e;
}
/**
* Enables discovery of what features the runtime environment supports.
*/
interface Feature {
/**
* Does the runtime environment support ShadowDOM?
*/
shadowDOM: boolean;
/**
* Does the runtime environment support the css scoped attribute?
*/
scopedCSS: boolean;
/**
* Does the runtime environment support native HTMLTemplateElement?
*/
htmlTemplateElement: boolean;
/**
* Does the runtime environment support Object.observe?
*/
objectObserve: boolean;
/**
* Does the runtime environment support Array.observe?
*/
arrayObserve: boolean;
}
/**
* The singleton instance of the Feature discovery API.
*/
export const FEATURE: Feature = {};
/**
* The runtime's performance API.
*/
interface Performance {
now(): number;
}
/**
* Represents the core APIs of the runtime environment.
*/
interface Platform {
/**
* The runtime environment's global.
*/
global: Object,
/**
* A function wich does nothing.
*/
noop: Function;
/**
* The runtime's location API.
*/
location: Object;
/**
* The runtime's history API.
*/
history: Object;
/**
* The runtime's performance API
*/
performance: Performance;
/**
* Registers a function to call when the system is ready to update (repaint) the display.
* @param callback The function to call.
*/
requestAnimationFrame(callback: (animationFrameStart: number) => void): number;
/**
* The runtime's XMLHttpRequest API.
*/
XMLHttpRequest: XMLHttpRequest;
/**
* Iterate all modules loaded by the script loader.
* @param callback A callback that will receive each module id along with the module object. Return true to end enumeration.
*/
eachModule(callback: (key: string, value: Object) => boolean): void;
/**
* Add a global event listener.
* @param eventName A string representing the event type to listen for.
* @param callback The function that receives a notification when an event of the specified type occurs.
* @param capture If true, useCapture indicates that the user wishes to initiate capture.
*/
addEventListener(eventName: string, callback: Function, capture?: boolean): void;
/**
* Remove a global event listener.
* @param eventName A string representing the event type to listen for.
* @param callback The function to remove from the event.
* @param capture Specifies whether the listener to be removed was registered as a capturing listener or not.
*/
removeEventListener(eventName: string, callback: Function, capture?: boolean): void;
}
/**
* The singleton instance of the Platform API.
*/
export const PLATFORM: Platform = {
noop: function() {},
eachModule() {}
};
PLATFORM.global = (function() {
// Workers don’t have `window`, only `self`
if (typeof self !== 'undefined') {
return self;
}
if (typeof global !== 'undefined') {
return global;
}
// Not all environments allow eval and Function
// Use only as a last resort:
return new Function('return this')();
})();
/**
* Represents the core APIs of the DOM.
*/
interface Dom {
/**
* The global DOM Element type.
*/
Element: Element;
/**
* The global DOM SVGElement type.
*/
SVGElement: SVGElement;
/**
* A key representing a DOM boundary.
*/
boundary: string;
/**
* The document title.
*/
title: string;
/**
* The document's active/focused element.
*/
activeElement: Element;
/**
* Add an event listener to the document.
* @param eventName A string representing the event type to listen for.
* @param callback The function that receives a notification when an event of the specified type occurs.
* @param capture If true, useCapture indicates that the user wishes to initiate capture.
*/
addEventListener(eventName: string, callback: Function, capture: boolean): void;
/**
* Remove an event listener from the document.
* @param eventName A string representing the event type to listen for.
* @param callback The function to remove from the event.
* @param capture Specifies whether the listener to be removed was registered as a capturing listener or not.
*/
removeEventListener(eventName: string, callback: Function, capture: boolean): void;
/**
* Adopts a node from an external document.
* @param node The node to be adopted.
* @return The adopted node able to be used in the document.
*/
adoptNode(node: Node): Node;
/**
* Creates the specified HTML element or an HTMLUnknownElement if the given element name isn't a known one.
* @param tagName A string that specifies the type of element to be created.
* @return The created element.
*/
createElement(tagName: string): Element;
/**
* Creates a new Text node.
* @param text A string to populate the new Text node.
* @return A Text node.
*/
createTextNode(text: string): Text;
/**
* Creates a new Comment node.
* @param text A string to populate the new Comment node.
* @return A Comment node.
*/
createComment(text: string): Comment;
/**
* Creates a new DocumentFragment.
* @return A DocumentFragment.
*/
createDocumentFragment(): DocumentFragment;
/**
* Creates a new MutationObserver.
* @param callback A callback that will recieve the change records with the mutations.
* @return A MutationObservere.
*/
createMutationObserver(callback: Function): MutationObserver;
/**
* Creates a new CustomEvent.
* @param eventType A string representing the event type.
* @param options An options object specifying bubbles:boolean, cancelable:boolean and/or detail:Object information.
* @return A CustomEvent.
*/
createCustomEvent(eventType: string, options: Object): CustomEvent;
/**
* Dispatches an event on the document.
* @param evt The event to dispatch.
*/
dispatchEvent(evt: Event): void;
/**
* Gives the values of all the CSS properties of an element after applying the active stylesheets and resolving any basic computation those values may contain.
* @param element The Element for which to get the computed style.
* @return The computed styles.
*/
getComputedStyle(element: Element): CSSStyleDeclaration;
/**
* Locates an element in the document according to its id.
* @param id The id to search the document for.
* @return The found element.
*/
getElementById(id: string): Element;
/**
* Performs a query selector on the document and returns all located matches.
* @param query The query to use in searching the document.
* @return A list of all matched elements in the document.
*/
querySelectorAll(query: string): NodeList;
/**
* Gets the element that is the next sibling of the provided element.
* @param element The element whose next sibling is being located.
* @return The next sibling Element of the provided Element.
*/
nextElementSibling(element: Node): Element;
/**
* Creates an HTMLTemplateElement using the markup provided.
* @param markup A string containing the markup to turn into a template. Note: This string must contain the template element as well.
* @return The instance of HTMLTemplateElement that was created from the provided markup.
*/
createTemplateFromMarkup(markup: string): Element;
/**
* Appends a node to the parent, if provided, or the document.body otherwise.
* @param newNode The node to append.
* @param parentNode The node to append to, otherwise the document.body.
*/
appendNode(newNode: Node, parentNode?:Node): void;
/**
* Replaces a node in the parent with a new node.
* @param newNode The node to replace the old node with.
* @param node The node that is being replaced.
* @param parentNode The node that the current node is parented to.
*/
replaceNode(newNode: Node, node: Node, parentNode: Node): void;
/**
* Removes the specified node from the parent node.
* @param node The node to remove.
* @param parentNode The parent node from which the node will be removed.
*/
removeNode(node: Node, parentNode: Node): void;
/**
* Injects styles into the destination element, or the document.head if no destination is provided.
* @param styles The css text to injext.
* @param destination The destination element to inject the css text into. If not specified it will default to the document.head.
* @param prepend Indicates whether or not the styles should be prepended to the destination. By default they are appended.
* @return The Style node that was created.
*/
injectStyles(styles: string, destination?: Element, prepend?:boolean): Node;
}
/**
* The singleton instance of the Dom API.
*/
export const DOM: Dom = {};
/**
* Enables initializing a specific implementation of the Platform Abstraction Layer (PAL).
* @param callback Allows providing a callback which configures the three PAL singletons with their platform-specific implementations.
*/
export function initializePAL(callback: (platform: Platform, feature: Feature, dom: Dom) => void): void {
if (typeof Object.getPropertyDescriptor !== 'function') {
Object.getPropertyDescriptor = function(subject, name) {
let pd = Object.getOwnPropertyDescriptor(subject, name);
let proto = Object.getPrototypeOf(subject);
while (typeof pd === 'undefined' && proto !== null) {
pd = Object.getOwnPropertyDescriptor(proto, name);
proto = Object.getPrototypeOf(proto);
}
return pd;
};
}
callback(PLATFORM, FEATURE, DOM);
}