bv-ui-core 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +40 -0
- package/.travis.yml +5 -0
- package/CONTRIBUTING.md +98 -0
- package/LICENSE.md +13 -0
- package/OWNERS +2 -0
- package/README.md +63 -0
- package/catalog-info.yaml +30 -0
- package/karma.conf.js +130 -0
- package/lib/README.md +61 -0
- package/lib/api/.babelrc +3 -0
- package/lib/api/.eslintrc +9 -0
- package/lib/api/README.md +134 -0
- package/lib/api/index.js +15 -0
- package/lib/api/statistics.js +148 -0
- package/lib/application/README.md +96 -0
- package/lib/application/index.js +171 -0
- package/lib/body/README.md +13 -0
- package/lib/body/index.js +19 -0
- package/lib/bvFetch/README.md +101 -0
- package/lib/bvFetch/index.js +383 -0
- package/lib/checkHighContrast/README.md +26 -0
- package/lib/checkHighContrast/index.js +36 -0
- package/lib/cookie/README.md +29 -0
- package/lib/cookie/index.js +111 -0
- package/lib/cookieConsent/README.md +41 -0
- package/lib/cookieConsent/index.js +227 -0
- package/lib/cssLoadChecker/README.md +19 -0
- package/lib/cssLoadChecker/index.js +72 -0
- package/lib/date.now/README.md +11 -0
- package/lib/date.now/index.js +40 -0
- package/lib/domainPolice/README.md +66 -0
- package/lib/domainPolice/index.js +95 -0
- package/lib/evented/README.md +42 -0
- package/lib/evented/index.js +135 -0
- package/lib/getOriginalConstructor/README.md +16 -0
- package/lib/getOriginalConstructor/index.js +52 -0
- package/lib/global/README.md +10 -0
- package/lib/global/index.js +48 -0
- package/lib/ie/README.md +13 -0
- package/lib/ie/index.js +25 -0
- package/lib/loader/README.md +73 -0
- package/lib/loader/index.js +358 -0
- package/lib/logger/README.md +82 -0
- package/lib/logger/index.js +180 -0
- package/lib/messageFormat/README.md +10 -0
- package/lib/messageFormat/index.js +42 -0
- package/lib/namespacer/README.md +57 -0
- package/lib/namespacer/index.js +98 -0
- package/lib/performance/README.md +35 -0
- package/lib/performance/entries.js +5 -0
- package/lib/performance/getEntries.js +42 -0
- package/lib/performance/getEntriesByName.js +61 -0
- package/lib/performance/getEntriesByType.js +55 -0
- package/lib/performance/index.js +11 -0
- package/lib/performance/mark.js +97 -0
- package/lib/performance/measure.js +106 -0
- package/lib/performance/now.js +63 -0
- package/lib/pixelsDisplayed/README.md +19 -0
- package/lib/pixelsDisplayed/index.js +113 -0
- package/lib/polyfills/README.md +39 -0
- package/lib/polyfills/fetch/Headers.js +3 -0
- package/lib/polyfills/fetch/Request.js +3 -0
- package/lib/polyfills/fetch/Response.js +3 -0
- package/lib/polyfills/fetch/fetch.js +3 -0
- package/lib/polyfills/fetch/index.js +57 -0
- package/lib/polyfills/promise.js +265 -0
- package/lib/queryShadowDom/README.md +50 -0
- package/lib/queryShadowDom/index.js +93 -0
- package/lib/region/README.md +64 -0
- package/lib/region/europe/index.js +94 -0
- package/lib/region/europe/territories.js +40 -0
- package/lib/region/index.js +123 -0
- package/lib/staticAssetLoader/README.md +116 -0
- package/lib/staticAssetLoader/index.js +248 -0
- package/lib/waitForBody/README.md +21 -0
- package/lib/waitForBody/index.js +36 -0
- package/mkdocs.yaml +5 -0
- package/package.json +55 -0
- package/test/.eslintrc +5 -0
- package/test/fixtures/lib.loader.document-is-wrong-in-ie8.js +5 -0
- package/test/fixtures/lib.loader.loadscript-attribute.js +3 -0
- package/test/fixtures/lib.loader.loadscript.js +3 -0
- package/test/fixtures/lib.loader.loadstylesheet.css +3 -0
- package/test/unit/api/.eslintrc +6 -0
- package/test/unit/api/index.spec.js +37 -0
- package/test/unit/api/response.json +67 -0
- package/test/unit/api/statistics.spec.js +218 -0
- package/test/unit/application/index.spec.js +313 -0
- package/test/unit/body/index.spec.js +15 -0
- package/test/unit/bvFetch/index.spec.js +246 -0
- package/test/unit/checkHighContrast/index.spec.js +16 -0
- package/test/unit/cookie/index.spec.js +191 -0
- package/test/unit/cookieConsent/index.spec.js +119 -0
- package/test/unit/cssLoadChecker/index.spec.js +75 -0
- package/test/unit/date.now/index.spec.js +21 -0
- package/test/unit/domainPolice/index.spec.js +141 -0
- package/test/unit/evented/index.spec.js +59 -0
- package/test/unit/getOriginalConstructor/index.spec.js +60 -0
- package/test/unit/global/index.spec.js +84 -0
- package/test/unit/ie/index.spec.js +14 -0
- package/test/unit/loader/index.spec.js +644 -0
- package/test/unit/logger/index.spec.js +141 -0
- package/test/unit/messageFormat/index.spec.js +31 -0
- package/test/unit/mochaInit.js +8 -0
- package/test/unit/namespacer/index.spec.js +100 -0
- package/test/unit/performance/getEntries.spec.js +30 -0
- package/test/unit/performance/getEntriesByName.spec.js +88 -0
- package/test/unit/performance/getEntriesByType.spec.js +48 -0
- package/test/unit/performance/index.spec.js +35 -0
- package/test/unit/performance/mark.spec.js +40 -0
- package/test/unit/performance/measure.spec.js +50 -0
- package/test/unit/performance/now.spec.js +21 -0
- package/test/unit/pixelsDisplayed/index.spec.js +271 -0
- package/test/unit/polyfills/fetch/Headers.js +12 -0
- package/test/unit/polyfills/fetch/Request.js +12 -0
- package/test/unit/polyfills/fetch/Response.js +12 -0
- package/test/unit/polyfills/fetch/fetch.js +12 -0
- package/test/unit/polyfills/fetch/index.js +61 -0
- package/test/unit/polyfills/promise.spec.js +48 -0
- package/test/unit/region/europe/index.spec.js +70 -0
- package/test/unit/region/index.spec.js +113 -0
- package/test/unit/staticAssetLoader/index.spec.js +215 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileOverview Checks visibility of an element by calculating the
|
|
3
|
+
* visible pixels for vertical and horizontal viewport.
|
|
4
|
+
* This is a migration of repository bv-ui-pixels-displayed
|
|
5
|
+
*/
|
|
6
|
+
var global = require('../global');
|
|
7
|
+
|
|
8
|
+
function getDimensions () {
|
|
9
|
+
var window = global;
|
|
10
|
+
var docEl = window.document && window.document.documentElement;
|
|
11
|
+
return {
|
|
12
|
+
height: window.innerHeight || docEl.clientHeight,
|
|
13
|
+
width: window.innerWidth || docEl.clientWidth
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function pixelsDisplayedVertical (el) {
|
|
18
|
+
var rect = el.getBoundingClientRect();
|
|
19
|
+
var displayed;
|
|
20
|
+
var windowHeight = module.exports.getDimensions().height;
|
|
21
|
+
|
|
22
|
+
// There are five potential DOM node positions relative to the viewport:
|
|
23
|
+
// * Completely above the viewport, not visible
|
|
24
|
+
// * Completely below the viewport, not visible
|
|
25
|
+
// * A top portion (or all) of the DOM node is visible
|
|
26
|
+
// * A middle portion of the DOM node is visible
|
|
27
|
+
// * A bottom portion of the DOM node is visible
|
|
28
|
+
|
|
29
|
+
if (rect.top <= 0) {
|
|
30
|
+
// The top of the node is at or above the top of the viewport,
|
|
31
|
+
// so the top plus its height would be how much is shown.
|
|
32
|
+
// However, we never want to provide a negative number for amount displayed.
|
|
33
|
+
displayed = Math.max(rect.top + rect.height, 0);
|
|
34
|
+
|
|
35
|
+
// Once we know how much is potentially showing, we want to ensure that we don't over-report.
|
|
36
|
+
// If the window height is less than our calculated display, use that.
|
|
37
|
+
displayed = Math.min(displayed, windowHeight);
|
|
38
|
+
|
|
39
|
+
// Cases handled:
|
|
40
|
+
// * Completely above the viewport, not visible
|
|
41
|
+
// * First displayed value would be 0, as the sum would be negative and so Math.max would return 0
|
|
42
|
+
// * Second displayed will remain 0, as that is (hopefully) less than viewport height
|
|
43
|
+
// * A middle portion of the DOM node is visible, or a bottom portion of the DOM node is visible
|
|
44
|
+
// * First displayed value will be the height of the DOM node below the top of the viewport
|
|
45
|
+
// * Second displayed value will be either that height, or the height of the viewport itself
|
|
46
|
+
|
|
47
|
+
return displayed;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// If the top of our rectangle is greater than the viewport's height,
|
|
51
|
+
// we're not visible, as the node is completely below the viewport.
|
|
52
|
+
if (rect.top >= windowHeight) { return 0; }
|
|
53
|
+
|
|
54
|
+
// At this point, the only remaining case is that the top of the DOM node is
|
|
55
|
+
// somewhere in the viewport. We can determine the maximum possible amount
|
|
56
|
+
// displayed rather easily, by determining how much distance there is between
|
|
57
|
+
// the top of the bounding rectangle and the viewport's height.
|
|
58
|
+
// However, if this is larger than our DOM node, we don't want to report more
|
|
59
|
+
// displayed than the node's full height;
|
|
60
|
+
return Math.min(windowHeight - rect.top, rect.height);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function pixelsDisplayedHorizontal (el) {
|
|
64
|
+
var rect = el.getBoundingClientRect();
|
|
65
|
+
var displayed;
|
|
66
|
+
|
|
67
|
+
var windowWidth = module.exports.getDimensions().width;
|
|
68
|
+
|
|
69
|
+
// There are five potential DOM node positions relative to the viewport:
|
|
70
|
+
// * Completely to the left of the viewport, not visible
|
|
71
|
+
// * Completely to the right of the viewport, not visible
|
|
72
|
+
// * A left portion (or all) of the DOM node is visible
|
|
73
|
+
// * A middle portion of the DOM node is visible
|
|
74
|
+
// * A right portion of the DOM node is visible
|
|
75
|
+
|
|
76
|
+
if (rect.left <= 0) {
|
|
77
|
+
// The left of the node is at or to the left of the viewport,
|
|
78
|
+
// so the left plus its width would be how much is shown.
|
|
79
|
+
// However, we never want to provide a negative number for amount displayed.
|
|
80
|
+
displayed = Math.max(rect.left + rect.width, 0);
|
|
81
|
+
|
|
82
|
+
// Once we know how much is potentially showing, we want to ensure that we don't over-report.
|
|
83
|
+
// If the window weight is less than our calculated display, use that.
|
|
84
|
+
displayed = Math.min(displayed, windowWidth);
|
|
85
|
+
|
|
86
|
+
// Cases handled:
|
|
87
|
+
// * Completely to the left of the viewport, not visible
|
|
88
|
+
// * First displayed value would be 0, as the sum would be negative and so Math.max would return 0
|
|
89
|
+
// * Second displayed will remain 0, as that is (hopefully) less than viewport width
|
|
90
|
+
// * A middle portion of the DOM node is visible, or a right portion of the DOM node is visible
|
|
91
|
+
// * First displayed value will be the width of the DOM node to the right of the left border of the viewport
|
|
92
|
+
// * Second displayed value will be either that width, or the width of the viewport itself
|
|
93
|
+
|
|
94
|
+
return displayed;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// If the left of our rectangle is greater than the viewport's width,
|
|
98
|
+
// we're not visible, as the node is completely to the right of the viewport.
|
|
99
|
+
if (rect.left >= windowWidth) { return 0; }
|
|
100
|
+
|
|
101
|
+
// At this point, the only remaining case is that the left of the DOM node is
|
|
102
|
+
// somewhere in the viewport. We can determine the maximum possible amount
|
|
103
|
+
// displayed rather easily, by determining how much distance there is between
|
|
104
|
+
// the left of the bounding rectangle and the viewport's width.
|
|
105
|
+
// However, if this is larger than our DOM node, we don't want to report more
|
|
106
|
+
// displayed than the node's full width;
|
|
107
|
+
return Math.min(windowWidth - rect.left, rect.width);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = { getDimensions: getDimensions,
|
|
111
|
+
pixelsDisplayedHorizontal: pixelsDisplayedHorizontal,
|
|
112
|
+
pixelsDisplayedVertical: pixelsDisplayedVertical
|
|
113
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Polyfills!
|
|
2
|
+
|
|
3
|
+
The polyfills contained in this folder can be imported as necessary. They should
|
|
4
|
+
export either the builtin native function(s), if found on the global, or the
|
|
5
|
+
polyfill itself.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
**In code**
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
const Promise = require('bv-ui-core/lib/polyfills/promise')
|
|
13
|
+
// Do things with the Promise polyfill!
|
|
14
|
+
const myPromise = new Promise((resolve, reject) => {/*...*/})
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
const { fetch, Headers } = require('bv-ui-core/lib/polyfills/fetch')
|
|
19
|
+
// Do things with the fetch polyfill!
|
|
20
|
+
fetch(url, {
|
|
21
|
+
headers: new Headers({
|
|
22
|
+
'Accept': 'application/json',
|
|
23
|
+
}),
|
|
24
|
+
}).then(myCallback)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**In webpack**
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
plugins: [
|
|
31
|
+
// Any references to these items in the bundle will be wrapped in
|
|
32
|
+
// references to their respective polyfill module exports.
|
|
33
|
+
new webpack.ProvidePlugin({
|
|
34
|
+
Promise: 'bv-ui-core/lib/polyfills/promise',
|
|
35
|
+
fetch: ['bv-ui-core/lib/polyfills/fetch', 'fetch'],
|
|
36
|
+
Headers: ['bv-ui-core/lib/polyfills/fetch', 'Headers'],
|
|
37
|
+
})
|
|
38
|
+
]
|
|
39
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for the existence of a builtin fetch function, and return it if it
|
|
3
|
+
* exists. Otherwise, load whatwg-fetch in a non-globally-polluting way. It
|
|
4
|
+
* checks for the existence of a 'self' variable to attach itself to, and
|
|
5
|
+
* otherwise, will attach itself to the global object. Because of that, create
|
|
6
|
+
* a global.self reference for it to attach to, caching any preexisting value,
|
|
7
|
+
* and restoring the preexisting value after load, exporting the polyfill (and
|
|
8
|
+
* its supporting data types) from this module.
|
|
9
|
+
*
|
|
10
|
+
* In the case of an existing builtin fetch, return it and its supporting data
|
|
11
|
+
* types from this module, so that any module that needs fetch or its supporting
|
|
12
|
+
* data types can import all of them from here, whether they're preexisting or
|
|
13
|
+
* not.
|
|
14
|
+
*/
|
|
15
|
+
var global = require('../../global')
|
|
16
|
+
|
|
17
|
+
// If fetch is unsupported, or is currently polyfilled, supply our own, just in case
|
|
18
|
+
if (typeof global.fetch === 'undefined' || !global.fetch.toString().match(/\[native code]/)) {
|
|
19
|
+
// Cache any preexisting value
|
|
20
|
+
var self = global.self;
|
|
21
|
+
|
|
22
|
+
// Create a new version of 'self', complete with things
|
|
23
|
+
// whatwg-fetch does some internal support checks for.
|
|
24
|
+
global.self = {};
|
|
25
|
+
|
|
26
|
+
// whatwg-fetch uses 'in' checks which breaks on undefined properties, so we
|
|
27
|
+
// should check for existence and only add the ones that we know we have.
|
|
28
|
+
var names = ['URLSearchParams', 'FileReader', 'Blob', 'FormData', 'ArrayBuffer'];
|
|
29
|
+
names.forEach(function (name) {
|
|
30
|
+
if (global[name]) {
|
|
31
|
+
global.self[name] = global[name];
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Require whatwg-fetch, which will search for 'self' and attach to it.
|
|
36
|
+
require('whatwg-fetch');
|
|
37
|
+
|
|
38
|
+
// Export the polyfilled items that were housed in the global.self namespace.
|
|
39
|
+
module.exports = {
|
|
40
|
+
fetch: global.self.fetch,
|
|
41
|
+
Headers: global.self.Headers,
|
|
42
|
+
Request: global.self.Request,
|
|
43
|
+
Response: global.self.Response
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Restore the original value of 'self' to the version we cached at the top.
|
|
47
|
+
global.self = self;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// fetch is natively supported, export it and its support constructors.
|
|
51
|
+
module.exports = {
|
|
52
|
+
fetch: global.fetch,
|
|
53
|
+
Headers: global.Headers,
|
|
54
|
+
Request: global.Request,
|
|
55
|
+
Response: global.Response
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The majority of this polyfill is lovingly lifted from Taylor Hakes and
|
|
3
|
+
* modified to meet our needs. Where his polyfill was contained in an IIFE, we
|
|
4
|
+
* instead check for the existence of the builtin Promise and return it if it
|
|
5
|
+
* exists. If it doesn't exist, we create a polyfill and return that.
|
|
6
|
+
*
|
|
7
|
+
* We are intentially avoiding polluting the global namespace here by not
|
|
8
|
+
* attaching the polyfill to the global.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Copyright (c) 2014 Taylor Hakes
|
|
12
|
+
// Copyright (c) 2014 Forbes Lindesay
|
|
13
|
+
// https://github.com/taylorhakes/promise-polyfill
|
|
14
|
+
//
|
|
15
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
// in the Software without restriction, including without limitation the rights
|
|
18
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
// furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
// The above copyright notice and this permission notice shall be included in
|
|
23
|
+
// all copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
31
|
+
// THE SOFTWARE.
|
|
32
|
+
var global = require('../global')
|
|
33
|
+
|
|
34
|
+
// If Promise is unsupported, or is currently polyfilled, supply our own, just in case
|
|
35
|
+
if (typeof global.Promise === 'undefined' || !global.Promise.toString().match(/\[native code]/)) {
|
|
36
|
+
// Store setTimeout reference so promise-polyfill will be unaffected by
|
|
37
|
+
// other code modifying setTimeout (like sinon.useFakeTimers())
|
|
38
|
+
var setTimeoutFunc = setTimeout;
|
|
39
|
+
|
|
40
|
+
function noop () {}
|
|
41
|
+
|
|
42
|
+
// Polyfill for Function.prototype.bind
|
|
43
|
+
function bind (fn, thisArg) {
|
|
44
|
+
return function () {
|
|
45
|
+
fn.apply(thisArg, arguments);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function Promise (fn) {
|
|
50
|
+
if (typeof this !== 'object') {
|
|
51
|
+
throw new TypeError('Promises must be constructed via new');
|
|
52
|
+
}
|
|
53
|
+
if (typeof fn !== 'function') {
|
|
54
|
+
throw new TypeError('not a function');
|
|
55
|
+
}
|
|
56
|
+
this._state = 0;
|
|
57
|
+
this._handled = false;
|
|
58
|
+
this._value = undefined;
|
|
59
|
+
this._deferreds = [];
|
|
60
|
+
|
|
61
|
+
doResolve(fn, this);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function handle (self, deferred) {
|
|
65
|
+
while (self._state === 3) {
|
|
66
|
+
self = self._value;
|
|
67
|
+
}
|
|
68
|
+
if (self._state === 0) {
|
|
69
|
+
self._deferreds.push(deferred);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
self._handled = true;
|
|
73
|
+
Promise._immediateFn(function () {
|
|
74
|
+
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
|
|
75
|
+
if (cb === null) {
|
|
76
|
+
(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
var ret;
|
|
80
|
+
try {
|
|
81
|
+
ret = cb(self._value);
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
reject(deferred.promise, e);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
resolve(deferred.promise, ret);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function resolve (self, newValue) {
|
|
92
|
+
try {
|
|
93
|
+
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
|
|
94
|
+
if (newValue === self) {
|
|
95
|
+
throw new TypeError('A promise cannot be resolved with itself.');
|
|
96
|
+
}
|
|
97
|
+
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
|
|
98
|
+
var then = newValue.then;
|
|
99
|
+
if (newValue instanceof Promise) {
|
|
100
|
+
self._state = 3;
|
|
101
|
+
self._value = newValue;
|
|
102
|
+
finale(self);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
else if (typeof then === 'function') {
|
|
106
|
+
doResolve(bind(then, newValue), self);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
self._state = 1;
|
|
111
|
+
self._value = newValue;
|
|
112
|
+
finale(self);
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
reject(self, e);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function reject (self, newValue) {
|
|
120
|
+
self._state = 2;
|
|
121
|
+
self._value = newValue;
|
|
122
|
+
finale(self);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function finale (self) {
|
|
126
|
+
if (self._state === 2 && self._deferreds.length === 0) {
|
|
127
|
+
Promise._immediateFn(function () {
|
|
128
|
+
if (!self._handled) {
|
|
129
|
+
Promise._unhandledRejectionFn(self._value);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
for (var i = 0, len = self._deferreds.length; i < len; i++) {
|
|
135
|
+
handle(self, self._deferreds[i]);
|
|
136
|
+
}
|
|
137
|
+
self._deferreds = null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function Handler (onFulfilled, onRejected, promise) {
|
|
141
|
+
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
|
|
142
|
+
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
|
|
143
|
+
this.promise = promise;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Take a potentially misbehaving resolver function and make sure
|
|
148
|
+
* onFulfilled and onRejected are only called once.
|
|
149
|
+
*
|
|
150
|
+
* Makes no guarantees about asynchrony.
|
|
151
|
+
*/
|
|
152
|
+
function doResolve (fn, self) {
|
|
153
|
+
var done = false;
|
|
154
|
+
try {
|
|
155
|
+
fn(function (value) {
|
|
156
|
+
if (done) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
done = true;
|
|
160
|
+
resolve(self, value);
|
|
161
|
+
}, function (reason) {
|
|
162
|
+
if (done) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
done = true;
|
|
166
|
+
reject(self, reason);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
catch (ex) {
|
|
170
|
+
if (done) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
done = true;
|
|
174
|
+
reject(self, ex);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
Promise.prototype['catch'] = function (onRejected) {
|
|
179
|
+
return this.then(null, onRejected);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
Promise.prototype.then = function (onFulfilled, onRejected) {
|
|
183
|
+
var prom = new (this.constructor)(noop);
|
|
184
|
+
|
|
185
|
+
handle(this, new Handler(onFulfilled, onRejected, prom));
|
|
186
|
+
return prom;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
Promise.all = function (arr) {
|
|
190
|
+
var args = Array.prototype.slice.call(arr);
|
|
191
|
+
|
|
192
|
+
return new Promise(function (resolve, reject) {
|
|
193
|
+
if (args.length === 0) {
|
|
194
|
+
return resolve([]);
|
|
195
|
+
}
|
|
196
|
+
var remaining = args.length;
|
|
197
|
+
|
|
198
|
+
function res (i, val) {
|
|
199
|
+
try {
|
|
200
|
+
if (val && (typeof val === 'object' || typeof val === 'function')) {
|
|
201
|
+
var then = val.then;
|
|
202
|
+
if (typeof then === 'function') {
|
|
203
|
+
then.call(val, function (val) {
|
|
204
|
+
res(i, val);
|
|
205
|
+
}, reject);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
args[i] = val;
|
|
210
|
+
if (--remaining === 0) {
|
|
211
|
+
resolve(args);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch (ex) {
|
|
215
|
+
reject(ex);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
for (var i = 0; i < args.length; i++) {
|
|
220
|
+
res(i, args[i]);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
Promise.resolve = function (value) {
|
|
226
|
+
if (value && typeof value === 'object' && value.constructor === Promise) {
|
|
227
|
+
return value;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return new Promise(function (resolve) {
|
|
231
|
+
resolve(value);
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
Promise.reject = function (value) {
|
|
236
|
+
return new Promise(function (resolve, reject) {
|
|
237
|
+
reject(value);
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
Promise.race = function (values) {
|
|
242
|
+
return new Promise(function (resolve, reject) {
|
|
243
|
+
for (var i = 0, len = values.length; i < len; i++) {
|
|
244
|
+
values[i].then(resolve, reject);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// Use polyfill for setImmediate for performance gains
|
|
250
|
+
Promise._immediateFn = (typeof setImmediate === 'function' && function (fn) { setImmediate(fn); }) ||
|
|
251
|
+
function (fn) {
|
|
252
|
+
setTimeoutFunc(fn, 0);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
Promise._unhandledRejectionFn = function _unhandledRejectionFn (err) {
|
|
256
|
+
if (typeof console !== 'undefined' && console) {
|
|
257
|
+
console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
module.exports = Promise
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
module.exports = global.Promise
|
|
265
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Query Shadow DOM Element
|
|
2
|
+
|
|
3
|
+
This file exposes multiple functions that can be used to query elements within the ShadowDOM.
|
|
4
|
+
|
|
5
|
+
```javascript
|
|
6
|
+
shadowQuerySelectorAll
|
|
7
|
+
// Returns Nodes matching with match selector.
|
|
8
|
+
```
|
|
9
|
+
| Parameter | Type | Description |
|
|
10
|
+
| :-------- | :------- | :------------------------- |
|
|
11
|
+
| `node` | `DOM Element` | **Required**. Root node to query for particular elements. |
|
|
12
|
+
| `matchSelector` | `string` | **Required**. Criteria to select the elements in the dom starting with node as root element. |
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
findShadowRoots
|
|
17
|
+
// Returns a list of all the shadow roots found in the given root element and its descendants.
|
|
18
|
+
```
|
|
19
|
+
| Parameter | Type | Description |
|
|
20
|
+
| :-------- | :------- | :------------------------- |
|
|
21
|
+
| `node` | `DOM Element` | **Required**. The root node from which to start searching for shadow roots. |
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
filterShadowHosts
|
|
25
|
+
// Returns NodeFilter.
|
|
26
|
+
```
|
|
27
|
+
| Parameter | Type | Description |
|
|
28
|
+
| :-------- | :------- | :------------------------- |
|
|
29
|
+
| `node` | `DOM Element` | **Required**. Document node. |
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
findElementsInShadowDomByMatchSector
|
|
33
|
+
// returns a NodeList of all elements within the shadow DOM of the shadowElement parameter that match the matchSelector parameter.
|
|
34
|
+
```
|
|
35
|
+
| Parameter | Type | Description |
|
|
36
|
+
| :-------- | :------- | :------------------------- |
|
|
37
|
+
| `node` | `DOM Element` | **Required**. A DOM node that has a shadow root. |
|
|
38
|
+
| `matchSelector` | `string` | **Required**. Criteria to select the elements in the dom starting with node as root element. |
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
const { shadowQuerySelectorAll } = require('bv-ui-core/lib/queryShadowDomElement');
|
|
46
|
+
|
|
47
|
+
const nodeList = shadowQuerySelectorAll(document, '[data-bv-show='reviews']')
|
|
48
|
+
|
|
49
|
+
// ['div', 'div']
|
|
50
|
+
```
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function to deterimine whether given node is shadow host.
|
|
3
|
+
* @param {*} node Document node.
|
|
4
|
+
* @returns NodeFilter
|
|
5
|
+
*/
|
|
6
|
+
function filterShadowHosts (node) {
|
|
7
|
+
if (node && node.shadowRoot) {
|
|
8
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
9
|
+
}
|
|
10
|
+
return NodeFilter.FILTER_SKIP;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The function finds all the shadow roots in a given root element and returns a list of them.
|
|
15
|
+
* @param node - The root element from which to start searching for shadow roots.
|
|
16
|
+
* @returns a list of all the shadow roots found in the given root element and its descendants.
|
|
17
|
+
*/
|
|
18
|
+
function findShadowRoots (node) {
|
|
19
|
+
|
|
20
|
+
if (!node) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT, filterShadowHosts);
|
|
25
|
+
let listOfShadowRoots = [];
|
|
26
|
+
|
|
27
|
+
// Tree walker will not determine the node.
|
|
28
|
+
if (node.shadowRoot) {
|
|
29
|
+
listOfShadowRoots.push(node);
|
|
30
|
+
listOfShadowRoots = listOfShadowRoots.concat(findShadowRoots(node.shadowRoot));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Traverse all the nodes.
|
|
34
|
+
while (walker.nextNode()) {
|
|
35
|
+
listOfShadowRoots.push(walker.currentNode);
|
|
36
|
+
|
|
37
|
+
if (walker.currentNode.shadowRoot) {
|
|
38
|
+
listOfShadowRoots = listOfShadowRoots.concat(findShadowRoots(walker.currentNode.shadowRoot));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
return listOfShadowRoots;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* This function finds elements within a shadow DOM that match a given selector.
|
|
47
|
+
* @param node - A DOM element that has a shadow root.
|
|
48
|
+
* @param matchSelector - Criteria to select the elements in the dom starting with element as root element.
|
|
49
|
+
* @returns The function `findElementsInShadowDomByMatchSector` returns a NodeList of all elements
|
|
50
|
+
* within the shadow DOM of the `shadowElement` parameter that match the `matchSelector` parameter.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
function findElementsInShadowDomByMatchSector (node, matchSelector) {
|
|
54
|
+
if (node && node.shadowRoot && matchSelector) {
|
|
55
|
+
return node.shadowRoot.querySelectorAll(matchSelector)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Finds elements in the DOM including open shadowDOM.
|
|
61
|
+
* @param {*} node Root element to query for particular elements
|
|
62
|
+
* @param {*} matchSelector Criteria to select the elements in the dom starting with element as root element.
|
|
63
|
+
* @returns Nodes matching with match selector.
|
|
64
|
+
*/
|
|
65
|
+
function shadowQuerySelectorAll (node, matchSelector) {
|
|
66
|
+
|
|
67
|
+
/* Checks if both `element` and `matchSelector` are truthy values. If either of
|
|
68
|
+
them is falsy, it throws an error. */
|
|
69
|
+
if (!(node && matchSelector)) {
|
|
70
|
+
throw new Error(`Unable to find ${node} or ${matchSelector}`)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Get the elements by query selector all.
|
|
74
|
+
const nodeList = node.querySelectorAll(matchSelector);
|
|
75
|
+
const shadowRoots = findShadowRoots(node);
|
|
76
|
+
let elements = [];
|
|
77
|
+
|
|
78
|
+
for (const rootElement of shadowRoots) {
|
|
79
|
+
const filteredElements = findElementsInShadowDomByMatchSector(rootElement, matchSelector);
|
|
80
|
+
if (filteredElements.length > 0) {
|
|
81
|
+
elements.push(...filteredElements);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return [...nodeList, ...elements];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
findShadowRoots,
|
|
90
|
+
filterShadowHosts,
|
|
91
|
+
shadowQuerySelectorAll,
|
|
92
|
+
findElementsInShadowDomByMatchSector
|
|
93
|
+
}
|