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.
Files changed (122) hide show
  1. package/.eslintrc +40 -0
  2. package/.travis.yml +5 -0
  3. package/CONTRIBUTING.md +98 -0
  4. package/LICENSE.md +13 -0
  5. package/OWNERS +2 -0
  6. package/README.md +63 -0
  7. package/catalog-info.yaml +30 -0
  8. package/karma.conf.js +130 -0
  9. package/lib/README.md +61 -0
  10. package/lib/api/.babelrc +3 -0
  11. package/lib/api/.eslintrc +9 -0
  12. package/lib/api/README.md +134 -0
  13. package/lib/api/index.js +15 -0
  14. package/lib/api/statistics.js +148 -0
  15. package/lib/application/README.md +96 -0
  16. package/lib/application/index.js +171 -0
  17. package/lib/body/README.md +13 -0
  18. package/lib/body/index.js +19 -0
  19. package/lib/bvFetch/README.md +101 -0
  20. package/lib/bvFetch/index.js +383 -0
  21. package/lib/checkHighContrast/README.md +26 -0
  22. package/lib/checkHighContrast/index.js +36 -0
  23. package/lib/cookie/README.md +29 -0
  24. package/lib/cookie/index.js +111 -0
  25. package/lib/cookieConsent/README.md +41 -0
  26. package/lib/cookieConsent/index.js +227 -0
  27. package/lib/cssLoadChecker/README.md +19 -0
  28. package/lib/cssLoadChecker/index.js +72 -0
  29. package/lib/date.now/README.md +11 -0
  30. package/lib/date.now/index.js +40 -0
  31. package/lib/domainPolice/README.md +66 -0
  32. package/lib/domainPolice/index.js +95 -0
  33. package/lib/evented/README.md +42 -0
  34. package/lib/evented/index.js +135 -0
  35. package/lib/getOriginalConstructor/README.md +16 -0
  36. package/lib/getOriginalConstructor/index.js +52 -0
  37. package/lib/global/README.md +10 -0
  38. package/lib/global/index.js +48 -0
  39. package/lib/ie/README.md +13 -0
  40. package/lib/ie/index.js +25 -0
  41. package/lib/loader/README.md +73 -0
  42. package/lib/loader/index.js +358 -0
  43. package/lib/logger/README.md +82 -0
  44. package/lib/logger/index.js +180 -0
  45. package/lib/messageFormat/README.md +10 -0
  46. package/lib/messageFormat/index.js +42 -0
  47. package/lib/namespacer/README.md +57 -0
  48. package/lib/namespacer/index.js +98 -0
  49. package/lib/performance/README.md +35 -0
  50. package/lib/performance/entries.js +5 -0
  51. package/lib/performance/getEntries.js +42 -0
  52. package/lib/performance/getEntriesByName.js +61 -0
  53. package/lib/performance/getEntriesByType.js +55 -0
  54. package/lib/performance/index.js +11 -0
  55. package/lib/performance/mark.js +97 -0
  56. package/lib/performance/measure.js +106 -0
  57. package/lib/performance/now.js +63 -0
  58. package/lib/pixelsDisplayed/README.md +19 -0
  59. package/lib/pixelsDisplayed/index.js +113 -0
  60. package/lib/polyfills/README.md +39 -0
  61. package/lib/polyfills/fetch/Headers.js +3 -0
  62. package/lib/polyfills/fetch/Request.js +3 -0
  63. package/lib/polyfills/fetch/Response.js +3 -0
  64. package/lib/polyfills/fetch/fetch.js +3 -0
  65. package/lib/polyfills/fetch/index.js +57 -0
  66. package/lib/polyfills/promise.js +265 -0
  67. package/lib/queryShadowDom/README.md +50 -0
  68. package/lib/queryShadowDom/index.js +93 -0
  69. package/lib/region/README.md +64 -0
  70. package/lib/region/europe/index.js +94 -0
  71. package/lib/region/europe/territories.js +40 -0
  72. package/lib/region/index.js +123 -0
  73. package/lib/staticAssetLoader/README.md +116 -0
  74. package/lib/staticAssetLoader/index.js +248 -0
  75. package/lib/waitForBody/README.md +21 -0
  76. package/lib/waitForBody/index.js +36 -0
  77. package/mkdocs.yaml +5 -0
  78. package/package.json +55 -0
  79. package/test/.eslintrc +5 -0
  80. package/test/fixtures/lib.loader.document-is-wrong-in-ie8.js +5 -0
  81. package/test/fixtures/lib.loader.loadscript-attribute.js +3 -0
  82. package/test/fixtures/lib.loader.loadscript.js +3 -0
  83. package/test/fixtures/lib.loader.loadstylesheet.css +3 -0
  84. package/test/unit/api/.eslintrc +6 -0
  85. package/test/unit/api/index.spec.js +37 -0
  86. package/test/unit/api/response.json +67 -0
  87. package/test/unit/api/statistics.spec.js +218 -0
  88. package/test/unit/application/index.spec.js +313 -0
  89. package/test/unit/body/index.spec.js +15 -0
  90. package/test/unit/bvFetch/index.spec.js +246 -0
  91. package/test/unit/checkHighContrast/index.spec.js +16 -0
  92. package/test/unit/cookie/index.spec.js +191 -0
  93. package/test/unit/cookieConsent/index.spec.js +119 -0
  94. package/test/unit/cssLoadChecker/index.spec.js +75 -0
  95. package/test/unit/date.now/index.spec.js +21 -0
  96. package/test/unit/domainPolice/index.spec.js +141 -0
  97. package/test/unit/evented/index.spec.js +59 -0
  98. package/test/unit/getOriginalConstructor/index.spec.js +60 -0
  99. package/test/unit/global/index.spec.js +84 -0
  100. package/test/unit/ie/index.spec.js +14 -0
  101. package/test/unit/loader/index.spec.js +644 -0
  102. package/test/unit/logger/index.spec.js +141 -0
  103. package/test/unit/messageFormat/index.spec.js +31 -0
  104. package/test/unit/mochaInit.js +8 -0
  105. package/test/unit/namespacer/index.spec.js +100 -0
  106. package/test/unit/performance/getEntries.spec.js +30 -0
  107. package/test/unit/performance/getEntriesByName.spec.js +88 -0
  108. package/test/unit/performance/getEntriesByType.spec.js +48 -0
  109. package/test/unit/performance/index.spec.js +35 -0
  110. package/test/unit/performance/mark.spec.js +40 -0
  111. package/test/unit/performance/measure.spec.js +50 -0
  112. package/test/unit/performance/now.spec.js +21 -0
  113. package/test/unit/pixelsDisplayed/index.spec.js +271 -0
  114. package/test/unit/polyfills/fetch/Headers.js +12 -0
  115. package/test/unit/polyfills/fetch/Request.js +12 -0
  116. package/test/unit/polyfills/fetch/Response.js +12 -0
  117. package/test/unit/polyfills/fetch/fetch.js +12 -0
  118. package/test/unit/polyfills/fetch/index.js +61 -0
  119. package/test/unit/polyfills/promise.spec.js +48 -0
  120. package/test/unit/region/europe/index.spec.js +70 -0
  121. package/test/unit/region/index.spec.js +113 -0
  122. package/test/unit/staticAssetLoader/index.spec.js +215 -0
@@ -0,0 +1,227 @@
1
+ var cookieConsent = (function () {
2
+ var init = false;
3
+ var consentDisabled = true;
4
+ var store = {};
5
+ var subscribers = {};
6
+ var events = ['add', 'enable', 'disable', 'change'];
7
+ var storeCallbacks = {};
8
+
9
+
10
+ /**
11
+ * _publish: Calls subscriber callbacks
12
+ * @param {String} consentKey Consent key
13
+ * @param {String} eventName Event name
14
+ * @param {Boolean} data Consent value
15
+ */
16
+ function _publish (consentKey, eventName, data) {
17
+ if (subscribers[consentKey] && subscribers[consentKey][eventName]) {
18
+ Object.values(subscribers[consentKey][eventName]).forEach(function (callback) {
19
+ callback(data);
20
+ })
21
+ }
22
+ }
23
+
24
+ /**
25
+ * _publishStore: calls Callbacks with the store object passed
26
+ */
27
+
28
+ function _publishStore () {
29
+ if (Object.values(storeCallbacks).length > 0) {
30
+ Object.values(storeCallbacks).forEach(function (callback) {
31
+ callback(Object.assign({}, store));
32
+ })
33
+ }
34
+ }
35
+ /**
36
+ * _set: Set store data
37
+ * @param {String} consentKey Consent key
38
+ * @param {String} consentValue Consent value
39
+ */
40
+ function _set (consentKey, consentValue) {
41
+ if (typeof consentValue !== 'boolean') {
42
+ throw new TypeError('cookieConsent (setConsent): consent values should be of type boolean. Check value for ' + consentKey + '.');
43
+ }
44
+
45
+ var oldValue = store[consentKey];
46
+
47
+ if (oldValue !== consentValue) {
48
+ store[consentKey] = consentValue;
49
+
50
+ if (oldValue === undefined) {
51
+ _publish(consentKey, 'add', consentValue);
52
+ }
53
+ if (oldValue === true) {
54
+ _publish(consentKey, 'disable', consentValue);
55
+ _publish(consentKey, 'change', consentValue);
56
+ }
57
+ else if (oldValue === false) {
58
+ _publish(consentKey, 'enable', consentValue);
59
+ _publish(consentKey, 'change', consentValue);
60
+ }
61
+ else {
62
+ _publish(consentKey, 'change', consentValue);
63
+ }
64
+ }
65
+ }
66
+ /**
67
+ * _unsubscribe: Unsubscribe subscribers
68
+ */
69
+ function _unsubscribe () {
70
+ if (subscribers[this.consentKey] && subscribers[this.consentKey][this.eventName]) {
71
+ delete subscribers[this.consentKey][this.eventName][this.key];
72
+ }
73
+ }
74
+
75
+ /**
76
+ * _unsubscribeStore: Unsubscribes subscribers from the consent store
77
+ */
78
+ function _unsubscribeStore () {
79
+ if (storeCallbacks[this.key]) {
80
+ delete storeCallbacks[this.key];
81
+ }
82
+ }
83
+ /**
84
+ * Get consent disabled
85
+ * @returns Boolean
86
+ */
87
+ function getConsentDisabled () {
88
+ return consentDisabled
89
+ }
90
+ /**
91
+ * initConsent: Initialize the consent store
92
+ * @param {Object} consent Consent object
93
+ * @param {Boolean} disable Disable consent
94
+ * @returns Boolean
95
+ */
96
+ function initConsent (consent, disable) {
97
+ if (!init) {
98
+ consentDisabled = !!disable;
99
+
100
+ if (consentDisabled) {
101
+ init = true;
102
+ return true;
103
+ }
104
+
105
+ if (!(consent && !Array.isArray(consent) && typeof consent === 'object')) {
106
+ throw new TypeError('cookieConsent (init): consent should be an object.');
107
+ }
108
+
109
+ var keys = Object.keys(consent);
110
+
111
+ for (var i = 0; i < keys.length; i++) {
112
+ if (typeof consent[keys[i]] !== 'boolean') {
113
+ throw new TypeError('cookieConsent (init): consent values for ' + keys[i] + ' should be of type boolean.');
114
+ }
115
+ }
116
+
117
+ store = Object.assign({}, consent);
118
+ init = true;
119
+ return true;
120
+ }
121
+
122
+ return false;
123
+ }
124
+ /**
125
+ * getConsent: Get consent value from store
126
+ * @param {String} consentKey Consent key
127
+ * @returns Boolean or Undefined
128
+ */
129
+ function getConsent (consentKey) {
130
+ if (consentDisabled) {
131
+ return true;
132
+ }
133
+
134
+ return store[consentKey];
135
+ }
136
+ /**
137
+ * setConsent: Set consent values in the store
138
+ * @param {Object} consent Consent object
139
+ * @returns Boolean
140
+ */
141
+ function setConsent (consent) {
142
+ if (init && !consentDisabled) {
143
+ if (!(consent && !Array.isArray(consent) && typeof consent === 'object')) {
144
+ throw new TypeError('cookieConsent (setConsent): consent should be an object.')
145
+ }
146
+ var store
147
+ var keys = Object.keys(consent);
148
+ for (var i = 0; i < keys.length; i++) {
149
+ _set(keys[i], consent[keys[i]]);
150
+ }
151
+ var storeCopy=Object.assign({},store)
152
+ if (JSON.stringify(storeCopy)!==JSON.stringify(store)) {
153
+ _publishStore()
154
+ }
155
+ return true;
156
+ }
157
+
158
+ return false;
159
+ }
160
+ /**
161
+ * subscribe: Subscribe to store events
162
+ * @param {String} consentKey Consent key
163
+ * @param {String} eventName Event name
164
+ * @param {Function} callback Event callback
165
+ * @returns Object: Contains unsubscribe method
166
+ */
167
+ function subscribe (consentKey, eventName, callback) {
168
+ if (typeof consentKey !== 'string') {
169
+ throw new TypeError('cookieConsent (subscribe): consent key should be of type string.');
170
+ }
171
+
172
+ if (typeof eventName !== 'string') {
173
+ throw new TypeError('cookieConsent (subscribe): event name should be of type string.');
174
+ }
175
+
176
+ if (!events.includes(eventName)) {
177
+ throw new TypeError('cookieConsent (subscribe): event name should be one of ' + events.join(', ') + '.');
178
+ }
179
+
180
+ if (typeof callback !== 'function') {
181
+ throw new TypeError('cookieConsent (subscribe): callback should be a function.');
182
+ }
183
+
184
+ if (!subscribers[consentKey]) {
185
+ subscribers[consentKey] = {};
186
+ }
187
+
188
+ if (!subscribers[consentKey][eventName]) {
189
+ subscribers[consentKey][eventName] = {};
190
+ }
191
+ var key = Math.random().toString(36).substr(2, 5);
192
+
193
+ subscribers[consentKey][eventName][key] = callback
194
+
195
+ return {
196
+ unsubscribe: _unsubscribe.bind({
197
+ consentKey: consentKey,
198
+ eventName: eventName,
199
+ key: key
200
+ })
201
+ };
202
+ }
203
+
204
+ function subscribeToConsentStore (callback) {
205
+ if (typeof callback !== 'function') {
206
+ throw new TypeError('cookieConsent (subscribeToConsentStore): callback should be a function.');
207
+ }
208
+
209
+ var key = Math.random().toString(36).substr(2, 5);
210
+ storeCallbacks[key] = callback;
211
+
212
+ return {
213
+ unsubscribe: _unsubscribeStore.bind({ key: key })
214
+ }
215
+ }
216
+
217
+ return {
218
+ initConsent: initConsent,
219
+ getConsent: getConsent,
220
+ getConsentDisabled: getConsentDisabled,
221
+ setConsent: setConsent,
222
+ subscribe: subscribe,
223
+ subscribeToConsentStore: subscribeToConsentStore
224
+ };
225
+ })();
226
+
227
+ module.exports = cookieConsent;
@@ -0,0 +1,19 @@
1
+ # CSS Load Checker
2
+
3
+ This module provides a means of checking if a CSS file has been loaded already or not. It does this by adding a test div to the page and checking the computed styles of it for the `display: none` style.
4
+
5
+ ```js
6
+ var cssLoadChecker = require('bv-ui-core/lib/cssLoadChecker');
7
+
8
+ if (cssLoadChecker.isCssLoaded('bv-verify-css-loaded')) {
9
+ // do stuff if loaded
10
+ }
11
+ else {
12
+ // do stuff if not loaded (like load it)
13
+ loader.loadStyleSheet(namespace.cssUrl, callback);
14
+ }
15
+ ```
16
+
17
+ The following methods are provided:
18
+
19
+ - `isCssLoaded(className)`: Loads a test div onto the page with the given class name and checks for the style `display: none`. If this is set, then the CSS file is assumed to be present so it returns true. Otherwise, it returns false. The test div is removed before this function finishes executing.
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @fileOverview
3
+ * Provides functions for checking if a stylesheet has been loaded previously
4
+ */
5
+
6
+ // Imports
7
+ var global = require('../global');
8
+ var body = require('../body');
9
+
10
+ /**
11
+ * Function to add the test div to the page
12
+ *
13
+ * @param {string} className - The class name used to check if the css file has loaded yet
14
+ * (does not include the '.' out front, just the name)
15
+ * @return {object} The element that was just created for the purposes of
16
+ * testing whether the CSS has loaded or not
17
+ */
18
+ var _loadTestDiv = function (className) {
19
+ var testDiv;
20
+
21
+ testDiv = global.document.createElement('div');
22
+ testDiv.style.height = '0px';
23
+ testDiv.style.width = '0px';
24
+ testDiv.style.border = '0px';
25
+ testDiv.className = className;
26
+ body().appendChild(testDiv);
27
+
28
+ return testDiv;
29
+ };
30
+
31
+ /**
32
+ * Function to remove the test div from the page
33
+ *
34
+ * @param {object} testDiv - The element that was created for the purposes of
35
+ * testing whether the CSS has loaded or not
36
+ */
37
+ var _cleanupTestDiv = function (testDiv) {
38
+ testDiv.parentNode.removeChild(testDiv);
39
+ };
40
+
41
+ module.exports = {
42
+
43
+ /**
44
+ * Check the test div to see if the styles have loaded
45
+ *
46
+ * @param {string} className - The class name used to check if the css file has loaded yet
47
+ * (does not include the '.' out front, just the name)
48
+ * @return {boolean} True or false as to whether the style sheet has been loaded.
49
+ */
50
+ isCssLoaded: function (className) {
51
+ var testDiv = _loadTestDiv(className);
52
+ var displayVal;
53
+ var result = false;
54
+
55
+ // add support for IE8
56
+ if (!global.getComputedStyle) {
57
+ displayVal = testDiv.currentStyle['display'];
58
+ }
59
+ else {
60
+ var computedStyles = global.getComputedStyle(testDiv);
61
+ displayVal = computedStyles.getPropertyValue('display');
62
+ }
63
+
64
+ if (displayVal === 'none') {
65
+ result = true;
66
+ }
67
+
68
+ _cleanupTestDiv(testDiv);
69
+ return result;
70
+ }
71
+
72
+ };
@@ -0,0 +1,11 @@
1
+ # Date.now
2
+
3
+ Uses `Date.now` when available and falls back to `new Date().getTime()` when
4
+ needed to get the number of milliseconds elapsed since 1 Jan 1970 00:00:00 UTC.
5
+
6
+ ## Usage
7
+ ```javascript
8
+ var date = require('date.now');
9
+
10
+ var now = date.now();
11
+ ```
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @fileOverview
3
+ * Provides a unified interface for getting the number of
4
+ * milliseconds elapsed since 1 Jan 1970
5
+ *
6
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now
7
+ */
8
+
9
+ // Imports
10
+ var global = require('../global');
11
+
12
+ // Cache references for speed and to guard against shenanigans
13
+ var nativeDate = global.Date;
14
+ var nativeNow = nativeDate && nativeDate.now;
15
+
16
+ // Is Date.now natively supported?
17
+ var isNativeSupported = (typeof nativeNow === 'function');
18
+
19
+ /**
20
+ * Native Implementation
21
+ * Uses the natively-supported Date.now
22
+ */
23
+ function nativeImplementation () {
24
+ return nativeNow.call(nativeDate);
25
+ }
26
+
27
+ /**
28
+ * Polyfill Implementation
29
+ * Provides similar functionality by using new Date().getTime()
30
+ */
31
+ function polyfillImplementation () {
32
+ return new nativeDate().getTime(); /*eslint new-cap:0*/
33
+ }
34
+
35
+ module.exports = {
36
+ now: function () {
37
+ var func = (isNativeSupported) ? nativeImplementation : polyfillImplementation;
38
+ return func();
39
+ }
40
+ };
@@ -0,0 +1,66 @@
1
+ # domainPolice
2
+
3
+ The `domainPolice` module provides a function that takes a hostname and an array of
4
+ objects representing a known whitelist of domains, and returns an object with a
5
+ simple API, representing the state of that URL in the whitelist.
6
+
7
+ ## Module arguments
8
+
9
+ - `hostname`: The particular hostname to be validated as a string. Ports and protocols are not validated and should not be supplied as part of this. Optimally, this should be provided from `window.location.hostname` in the browser.
10
+ - `allowedDomains`: An array of objects representing whitelisted arrays.
11
+
12
+ ## Usage
13
+
14
+ ```javascript
15
+ var domainPolice = require('bv-ui-core/lib/domainPolice');
16
+
17
+ var allowedDomains = [
18
+ {
19
+ domain: '.bazaarvoice.com',
20
+ thirdPartyCookieEnabled: true
21
+ },
22
+ {
23
+ domain: '.localhost',
24
+ thirdPartyCookieEnabled: false,
25
+ commentsEnabled: true,
26
+ },
27
+ {
28
+ domain: 'no-prefixing-dot.foo.com',
29
+ commentsEnabled: true
30
+ }
31
+ ];
32
+
33
+ var bvCop = domainPolice(allowedDomains, 'www.bazaarvoice.com');
34
+ bvCop.isValid; // => true
35
+ bvCop.get('domain'); // => '.bazaarvoice.com'
36
+ bvCop.get('thirdPartyCookieEnabled'); // => true
37
+ bvCop.get('commentsEnabled'); // => undefined
38
+
39
+ var nopeCop = domainPolice(allowedDomains, 'ww.w.foo.com');
40
+ nopeCop.isValid; // => false
41
+ nopeCop.get('anything'); // => undefined
42
+ ```
43
+
44
+ ### `allowedDomains` format
45
+
46
+ `allowedDomains` is an array of objects, and each object is expected to have a
47
+ `domain` property. It may also contain any other arbitrary properties as desired
48
+ for later lookup.
49
+
50
+ Prefixing `.` on the `domain` will allow it to match all subdomains as well.
51
+ URL hosts which include `www.` will be allowed with domain name match.
52
+
53
+ Given the above example, the following domains are all valid:
54
+
55
+ - `bazaarvoice.com`
56
+ - `subdomain.bazaarvoice.com`
57
+ - `localhost`
58
+ - `www-stg.localhost`
59
+ - `no-prefixing-dot.foo.com`
60
+ - `www.no-prefixing-dot.foo.com`
61
+
62
+ Domains that would not be allowed:
63
+
64
+ - `foo.com`
65
+ - `something.foo.com`
66
+ - `bazaarvoice.co.jp`
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @fileOverview
3
+ * The DomainPolice module is used to provide validation that content is only
4
+ * being loaded on authorized domains.
5
+ */
6
+
7
+ /**
8
+ * Returns true if the hostname is an exact match for a specific domain or a
9
+ * suffix match for a wildcard domain (domain starts with a '.').
10
+ *
11
+ * @param {String} domain Domain to check.
12
+ * @param {String} hostname Hostname to check against.
13
+ * @return {Boolean}
14
+ */
15
+ function domainMatches (domain, hostname) {
16
+ if (domain && (domain.charAt(0) === '.') && hostname) {
17
+ // domainMatches('.domain.com', 'sub.domain.com') and
18
+ // domainMatches('.sub.domain.com', 'sub.domain.com') are both true.
19
+ var index = ('.' + hostname).lastIndexOf(domain);
20
+ return index >= 0 && index === (1 + hostname.length - domain.length);
21
+ }
22
+
23
+ return hostname === domain || hostname === ('www.' + domain);
24
+ }
25
+
26
+ /**
27
+ * Returns the matching domain object if the hostname of the specified URL
28
+ * matches one of the specified domains.
29
+ *
30
+ * @param {Array} domains The set of domain objects to check the URL against
31
+ * @param {String} hostname The hostname to check
32
+ * @return {Object} The matching domain object from the array of provided domains
33
+ */
34
+ function allowedDomain (domains, hostname) {
35
+ var matchedDomain;
36
+
37
+ for (var i = 0; i < domains.length; i++) {
38
+ if (domainMatches(domains[i].domain, hostname)) {
39
+ matchedDomain = domains[i];
40
+
41
+ return matchedDomain;
42
+ }
43
+ }
44
+
45
+ // No match found, explicitly returning undefined
46
+ return undefined;
47
+ }
48
+
49
+ /**
50
+ * Returns an object that represents a found domain, including the ability to get various attributes off of the associated object from the domains array.
51
+ *
52
+ * @param {Array} domains The set of domain objects to check the URL against
53
+ * @param {String} hostname The hostname to be checked against. Preferably sourced by using window.location.hostname.
54
+ * @return {Object} An object representing the state of the matched domain
55
+ */
56
+ function domainPolice (domains, hostname) {
57
+ var domainState = {};
58
+ var domain = {
59
+ isValid: false,
60
+ get: function (key) {
61
+ return domainState[key];
62
+ }
63
+ };
64
+
65
+ var domainObject = allowedDomain(domains, hostname);
66
+
67
+ // If we have a matching domain
68
+ if (domainObject) {
69
+ domain.isValid = true;
70
+
71
+ // Manually copying keys, because I can't safely use Object.assign
72
+ // or the npm object-assign module, or even lodash.assign/lodash.extend,
73
+ // as they're assuming ES5 environments.
74
+ //
75
+ // TODO: Once we drop IE11, simplify.
76
+ for (var key in domainObject) {
77
+ if (domainObject.hasOwnProperty(key)) {
78
+ domainState[key] = domainObject[key];
79
+ }
80
+ }
81
+
82
+ // Special case: If the domain is a valid IPv4 address,
83
+ // remove the leading period.
84
+ // The return value here should be used when setting a cookie, and IPv4
85
+ // addresses with a prefixed period do not work for cookie setting like
86
+ // they do for domains.
87
+ if (domainState.domain.match(/^(\.\d+){4}$/)) {
88
+ domainState.domain = domainState.domain.substr(1);
89
+ }
90
+ }
91
+
92
+ return domain;
93
+ }
94
+
95
+ module.exports = domainPolice;
@@ -0,0 +1,42 @@
1
+ # evented
2
+
3
+ Based on [asEvented][1], the evented module provides a function that can be
4
+ called on a constructor in order to make instances act as event emitters.
5
+
6
+ ```js
7
+ var evented = require('bv-ui-core/lib/evented');
8
+
9
+ function Model(config) {
10
+ this.config = config;
11
+ };
12
+
13
+ evented.call(Model.prototype);
14
+ ```
15
+
16
+ An event emitter provides the following methods:
17
+
18
+ - `on(event, fn)`
19
+ - `off(event, fn)`
20
+ - `one(event, fn)`
21
+ - `once(event, fn)`
22
+ - `trigger(event, *data)`
23
+
24
+ By default, any errors thrown from an event listener are caught and simply logged to the console.
25
+ An alternate behavior can be specified by providing an event handler:
26
+
27
+ ```js
28
+ var model = new Model({});
29
+
30
+ model.setErrorHandler(function(error, trigger) {
31
+ // The following parameters are available to this function:
32
+ // - error : the value that was thrown, typically an instance of Error
33
+ // - trigger.event : the name of the event passed to trigger()
34
+ // - trigger.data : an array containing the additional arguments passed to trigger()
35
+ // - this : the instance on which trigger() was invoked
36
+ });
37
+
38
+ // If you prefer for errors to be thrown from trigger(), then use:
39
+ model.setErrorHandler(function(error) { throw error; });
40
+ ```
41
+
42
+ [1]: https://github.com/mkuklis/asEvented