bv-ui-core 2.5.2 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- package/catalog-info.yaml +30 -0
- package/karma.conf.js +12 -3
- package/lib/README.md +61 -0
- package/lib/cookie/README.md +1 -1
- package/lib/cookie/index.js +8 -0
- package/lib/cookieConsent/README.md +3 -0
- package/lib/cookieConsent/index.js +44 -1
- package/lib/messageFormat/README.md +10 -0
- package/lib/messageFormat/index.js +42 -0
- package/lib/performance/getEntriesByName.js +1 -0
- package/mkdocs.yaml +5 -0
- package/package.json +3 -3
- package/test/unit/cookieConsent/index.spec.js +30 -1
- package/test/unit/messageFormat/index.spec.js +31 -0
- package/test/unit/performance/getEntriesByName.spec.js +6 -1
- package/test/unit/performance/getEntriesByType.spec.js +3 -2
- package/test/unit/performance/measure.spec.js +1 -1
@@ -0,0 +1,30 @@
|
|
1
|
+
apiVersion: backstage.io/v1alpha1
|
2
|
+
kind: Component
|
3
|
+
metadata:
|
4
|
+
name: bv-ui-core
|
5
|
+
github.com/project-slug: bazaarvoice/bv-ui-core
|
6
|
+
description: This project provides a central location for common Bazaarvoice UI code. It is intended to be installed into a project via NPM. Individual modules are authored as CommonJS modules, to be consumed by Webpack or another build tool that can ingest CommonJS.
|
7
|
+
annotations:
|
8
|
+
backstage.io/techdocs-ref: dir:.
|
9
|
+
github.com/project-slug: bazaarvoice/bv-ui-core
|
10
|
+
links:
|
11
|
+
- url: https://bazaarvoice.slack.com/app_redirect?channel=sme-swat
|
12
|
+
title: Slack channel
|
13
|
+
icon: send
|
14
|
+
- url: https://sonarqube.qa.bazaarvoice.com/dashboard?id=bazaarvoice_bv-ui-core
|
15
|
+
title: SonarQube
|
16
|
+
icon: dashboard
|
17
|
+
labels:
|
18
|
+
tech: javascript
|
19
|
+
tags:
|
20
|
+
- javascript
|
21
|
+
- nodejs
|
22
|
+
spec:
|
23
|
+
type: library
|
24
|
+
system: swat
|
25
|
+
lifecycle: production
|
26
|
+
owner: swat
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
package/karma.conf.js
CHANGED
@@ -20,12 +20,10 @@ module.exports = function (config) {
|
|
20
20
|
ui: 'bdd'
|
21
21
|
}
|
22
22
|
},
|
23
|
-
|
24
23
|
// list of files / patterns to load in the browser.
|
25
24
|
files: [
|
26
25
|
// We need the polyfill for testing es6 modules.
|
27
26
|
'node_modules/babel-polyfill/dist/polyfill.js',
|
28
|
-
|
29
27
|
// Loaded into the browser test page.
|
30
28
|
'test/unit/mochaInit.js',
|
31
29
|
'test/unit/**/*.spec.js',
|
@@ -109,10 +107,21 @@ module.exports = function (config) {
|
|
109
107
|
// Enable / disable watching file and executing tests whenever any file
|
110
108
|
// changes.
|
111
109
|
autoWatch: true,
|
110
|
+
customLaunchers: {
|
111
|
+
ChromeHeadless: {
|
112
|
+
base: 'Chrome',
|
113
|
+
flags: [
|
114
|
+
'--no-sandbox',
|
115
|
+
'--headless',
|
116
|
+
'--disable-gpu',
|
117
|
+
'--remote-debugging-port=9222'
|
118
|
+
]
|
119
|
+
}
|
120
|
+
},
|
112
121
|
|
113
122
|
// Start these browsers.
|
114
123
|
// See: https://npmjs.org/browse/keyword/karma-launcher
|
115
|
-
browsers: ['
|
124
|
+
browsers: ['ChromeHeadless'],
|
116
125
|
|
117
126
|
// Continuous Integration mode. If true, Karma captures browsers, runs the
|
118
127
|
// tests and exits.
|
package/lib/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
![](https://travis-ci.org/bazaarvoice/bv-ui-core.svg)
|
2
|
+
|
3
|
+
# bv-ui-core
|
4
|
+
|
5
|
+
This project provides a central location for common Bazaarvoice UI code. It is
|
6
|
+
intended to be installed into a project via NPM. Individual modules are authored
|
7
|
+
as CommonJS modules, to be consumed by Webpack or another build tool that can
|
8
|
+
ingest CommonJS.
|
9
|
+
|
10
|
+
**This is a public repository.** Please see the [contribution guidelines][1] for
|
11
|
+
details on contributing to this repo.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
You will need NPM to add this to your project; it is installed when you install
|
16
|
+
Node, so it is likely that you already have it. If not, you can install Node
|
17
|
+
using an [installer][2], or by using your favorite package manager (such as
|
18
|
+
Homebrew).
|
19
|
+
|
20
|
+
Once you have NPM, you can install bv-ui-core as follows:
|
21
|
+
|
22
|
+
```bash
|
23
|
+
npm install --save bv-ui-core
|
24
|
+
```
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
Require bv-ui-core modules into your code:
|
29
|
+
|
30
|
+
```javascript
|
31
|
+
var someModule = require('bv-ui-core/lib/someModule');
|
32
|
+
someModule.doThings();
|
33
|
+
```
|
34
|
+
|
35
|
+
For details on how to use a specific module, see the README document in the
|
36
|
+
module's directory.
|
37
|
+
|
38
|
+
## Modules
|
39
|
+
|
40
|
+
- [body](./lib/body)
|
41
|
+
- [checkHighContrast](./lib/checkHighContrast)
|
42
|
+
- [cookie](./lib/cookie)
|
43
|
+
- [cookieConsent](./lib/cookieConsent)
|
44
|
+
- [cssLoadChecker](./lib/cssLoadChecker)
|
45
|
+
- [date.now](./lib/date.now)
|
46
|
+
- [domainPolice](./lib/domainPolice)
|
47
|
+
- [evented](./lib/evented)
|
48
|
+
- [getOriginalConstructor](./lib/getOriginalConstructor)
|
49
|
+
- [global](./lib/global)
|
50
|
+
- [ie](./lib/ie)
|
51
|
+
- [loader](./lib/loader)
|
52
|
+
- [logger](./lib/logger)
|
53
|
+
- [namespacer](./lib/namespacer)
|
54
|
+
- [performance](./lib/performance)
|
55
|
+
- [polyfills](./lib/polyfills)
|
56
|
+
- [pixelsDisplayed](./lib/pixelsDisplayed)
|
57
|
+
- [staticAssetLoader](./lib/staticAssetLoader)
|
58
|
+
- [waitForBody](./lib/waitForBody)
|
59
|
+
|
60
|
+
[1]: ./CONTRIBUTING.md
|
61
|
+
[2]: https://nodejs.org/download/
|
package/lib/cookie/README.md
CHANGED
@@ -5,7 +5,7 @@ The cookie module provides methods for interacting with browser cookies.
|
|
5
5
|
```js
|
6
6
|
var cookie = require('bv-ui-core/lib/cookie');
|
7
7
|
|
8
|
-
cookie.
|
8
|
+
cookie.create('RememberMe', '1', 365);
|
9
9
|
console.log(cookie.read('RememberMe')); // '1'
|
10
10
|
cookie.remove('RememberMe');
|
11
11
|
```
|
package/lib/cookie/index.js
CHANGED
@@ -79,6 +79,14 @@ module.exports = {
|
|
79
79
|
if (consentPresent) {
|
80
80
|
createCookie(name, value, days, domain, secure);
|
81
81
|
}
|
82
|
+
cookieConsent.subscribe(name,'add',function (consent) {
|
83
|
+
if (consent) {
|
84
|
+
createCookie(name,value,days,domain,secure);
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
removeCookie(name,domain)
|
88
|
+
}
|
89
|
+
})
|
82
90
|
|
83
91
|
cookieConsent.subscribe(name, 'enable', function () {
|
84
92
|
createCookie(name, value, days, domain, secure);
|
@@ -30,6 +30,9 @@ cookieConsent.subscribe('cookie3', 'enable', function (data) {});
|
|
30
30
|
// Subscribe to consent 'disable' event. Triggers when a cookie consent is set to false
|
31
31
|
var event = cookieConsent.subscribe('cookie3', 'disable', function (data) {});
|
32
32
|
|
33
|
+
// Subscribe to the store change event. The latest consent store object is passed as parameter to the callback function
|
34
|
+
var event = subscribeToConsentStore(function (store){});
|
35
|
+
|
33
36
|
// Unsubscribe events
|
34
37
|
event.unsubscribe();
|
35
38
|
|
@@ -4,6 +4,9 @@ var cookieConsent = (function () {
|
|
4
4
|
var store = {};
|
5
5
|
var subscribers = {};
|
6
6
|
var events = ['add', 'enable', 'disable', 'change'];
|
7
|
+
var storeCallbacks = {};
|
8
|
+
|
9
|
+
|
7
10
|
/**
|
8
11
|
* _publish: Calls subscriber callbacks
|
9
12
|
* @param {String} consentKey Consent key
|
@@ -17,6 +20,18 @@ var cookieConsent = (function () {
|
|
17
20
|
})
|
18
21
|
}
|
19
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
|
+
}
|
20
35
|
/**
|
21
36
|
* _set: Set store data
|
22
37
|
* @param {String} consentKey Consent key
|
@@ -56,6 +71,15 @@ var cookieConsent = (function () {
|
|
56
71
|
delete subscribers[this.consentKey][this.eventName][this.key];
|
57
72
|
}
|
58
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
|
+
}
|
59
83
|
/**
|
60
84
|
* Get consent disabled
|
61
85
|
* @returns Boolean
|
@@ -119,10 +143,15 @@ var cookieConsent = (function () {
|
|
119
143
|
if (!(consent && !Array.isArray(consent) && typeof consent === 'object')) {
|
120
144
|
throw new TypeError('cookieConsent (setConsent): consent should be an object.')
|
121
145
|
}
|
146
|
+
var store
|
122
147
|
var keys = Object.keys(consent);
|
123
148
|
for (var i = 0; i < keys.length; i++) {
|
124
149
|
_set(keys[i], consent[keys[i]]);
|
125
150
|
}
|
151
|
+
var storeCopy=Object.assign({},store)
|
152
|
+
if (JSON.stringify(storeCopy)!==JSON.stringify(store)) {
|
153
|
+
_publishStore()
|
154
|
+
}
|
126
155
|
return true;
|
127
156
|
}
|
128
157
|
|
@@ -172,12 +201,26 @@ var cookieConsent = (function () {
|
|
172
201
|
};
|
173
202
|
}
|
174
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
|
+
|
175
217
|
return {
|
176
218
|
initConsent: initConsent,
|
177
219
|
getConsent: getConsent,
|
178
220
|
getConsentDisabled: getConsentDisabled,
|
179
221
|
setConsent: setConsent,
|
180
|
-
subscribe: subscribe
|
222
|
+
subscribe: subscribe,
|
223
|
+
subscribeToConsentStore: subscribeToConsentStore
|
181
224
|
};
|
182
225
|
})();
|
183
226
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# messageFormat
|
2
|
+
|
3
|
+
Uses `INTL.DisplayNames` and uses a polyfill from `https://cdn.polyfill.io/v3/polyfill.min.js?features=Intl.DisplayNames`
|
4
|
+
|
5
|
+
# Usage
|
6
|
+
|
7
|
+
```javascript
|
8
|
+
var messageFormat = require('bv-ui-core/lib/messageFormat');
|
9
|
+
messageFormat.generateCountryFromLocale('en_US') // United States
|
10
|
+
```
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/**
|
2
|
+
* @fileOverview
|
3
|
+
* messageFormat provides utility functions to which use the INTL API which provides
|
4
|
+
* language sensitive string comparison, number formatting, and date and time formatting.
|
5
|
+
*
|
6
|
+
* messageFormat can have functions which are used in multiple places
|
7
|
+
*
|
8
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
|
9
|
+
*/
|
10
|
+
|
11
|
+
|
12
|
+
var global = require('../global');
|
13
|
+
/**
|
14
|
+
* Generates the country name associated with the given locale
|
15
|
+
* @param {string} locale The locale code (e.g., 'en_US')
|
16
|
+
* @returns {string} The name of the country associated with the locale, or an empty string if the locale is not supported by Intl.DisplayNames
|
17
|
+
*/
|
18
|
+
function generateCountryFromLocale (locale) {
|
19
|
+
if (!locale || locale.length === 0) {
|
20
|
+
return '';
|
21
|
+
}
|
22
|
+
|
23
|
+
// Split the locale code into language and region components
|
24
|
+
try {
|
25
|
+
var localeArr = locale.split('_');
|
26
|
+
if (localeArr.length < 2) {
|
27
|
+
return '';
|
28
|
+
}
|
29
|
+
// Get the display name for the region (i.e., the country name)
|
30
|
+
var regionNames = new global.Intl.DisplayNames(localeArr[0], { type: 'region' });
|
31
|
+
var countryName = regionNames.of(localeArr[1]);
|
32
|
+
}
|
33
|
+
catch (error) {
|
34
|
+
return '';
|
35
|
+
}
|
36
|
+
// Return the country name, or an empty string if the region is not valid
|
37
|
+
return countryName
|
38
|
+
}
|
39
|
+
|
40
|
+
module.exports = {
|
41
|
+
generateCountryFromLocale: generateCountryFromLocale
|
42
|
+
}
|
@@ -53,6 +53,7 @@ module.exports = {
|
|
53
53
|
getEntriesByName: function (name, entryType) {
|
54
54
|
// Note: because the implementation functions explicitly check their number of arguments,
|
55
55
|
// we want to preserve the calls exactly as they came in
|
56
|
+
|
56
57
|
var hasArguments = (arguments.length > 0);
|
57
58
|
var func = (isNativeSupported ? nativeImplementation : polyfillImplementation);
|
58
59
|
return (hasArguments ? func(name, entryType) : func());
|
package/mkdocs.yaml
ADDED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "bv-ui-core",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.7.0",
|
4
4
|
"license": "Apache 2.0",
|
5
5
|
"description": "Bazaarvoice UI-related JavaScript",
|
6
6
|
"repository": {
|
@@ -12,7 +12,7 @@
|
|
12
12
|
},
|
13
13
|
"scripts": {
|
14
14
|
"lint": "eslint karma.conf.js lib test",
|
15
|
-
"test": "./node_modules/karma/bin/karma start --single-run --browsers
|
15
|
+
"test": "./node_modules/karma/bin/karma start --single-run --browsers ChromeHeadless",
|
16
16
|
"dev": "./node_modules/karma/bin/karma start --browsers Chrome"
|
17
17
|
},
|
18
18
|
"devDependencies": {
|
@@ -28,7 +28,7 @@
|
|
28
28
|
"json-loader": "^0.5.7",
|
29
29
|
"karma": "^3.0.0",
|
30
30
|
"karma-chai": "^0.1.0",
|
31
|
-
"karma-chrome-launcher": "2.0.0",
|
31
|
+
"karma-chrome-launcher": "^2.0.0",
|
32
32
|
"karma-coverage": "^1.1.2",
|
33
33
|
"karma-firefox-launcher": "^1.1.0",
|
34
34
|
"karma-htmlfile-reporter": "^0.3.6",
|
@@ -84,7 +84,36 @@ describe('lib/cookieConsent', function () {
|
|
84
84
|
function test5 () {
|
85
85
|
return cookieConsent.subscribe('key1', 'enable', function () {});
|
86
86
|
}
|
87
|
-
|
88
87
|
expect(test5()).to.be.an('object');
|
89
88
|
});
|
89
|
+
it('cookieConsent.subscribeToConsentStore', function () {
|
90
|
+
// Error checks - Correct errors are thrown
|
91
|
+
function test6 () {
|
92
|
+
cookieConsent.subscribeToConsentStore('Callback')
|
93
|
+
}
|
94
|
+
expect(test6).to.throw(TypeError,'cookieConsent (subscribeToConsentStore): callback should be a function.');
|
95
|
+
// Subscriber creation test - The subscription gets created correctly
|
96
|
+
function test7 () {
|
97
|
+
return cookieConsent.subscribeToConsentStore(function () {});
|
98
|
+
}
|
99
|
+
expect(test7()).to.be.an('object');
|
100
|
+
|
101
|
+
// Event listener test - The subscriber callback fires on store change
|
102
|
+
var fn = sinon.spy()
|
103
|
+
function test8 () {
|
104
|
+
cookieConsent.subscribeToConsentStore(fn)
|
105
|
+
cookieConsent.setConsent({ cookie4: true })
|
106
|
+
}
|
107
|
+
test8 ()
|
108
|
+
sinon.assert.calledOnce(fn)
|
109
|
+
// Unsubscribe test - Should be able to unsubscribe successfully (Should not fire the callback after unsubscription)
|
110
|
+
var fn2 = sinon.spy()
|
111
|
+
function test9 () {
|
112
|
+
var event = cookieConsent.subscribeToConsentStore(fn2)
|
113
|
+
event.unsubscribe()
|
114
|
+
cookieConsent.setConsent({ cookie5: true })
|
115
|
+
}
|
116
|
+
test9()
|
117
|
+
sinon.assert.notCalled(fn2)
|
118
|
+
});
|
90
119
|
});
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/**
|
2
|
+
* @fileOverview
|
3
|
+
* Unit tests for the messageFormat module
|
4
|
+
*/
|
5
|
+
var messageFormat = require('../../../lib/messageFormat');
|
6
|
+
|
7
|
+
describe('lib/messageFormat', function () {
|
8
|
+
it('messageFormat.generateCountryFromLocale', function () {
|
9
|
+
function test1 () {
|
10
|
+
return messageFormat.generateCountryFromLocale('en_US');
|
11
|
+
}
|
12
|
+
|
13
|
+
expect(test1()).to.be.equal('United States');
|
14
|
+
|
15
|
+
function test2 () {
|
16
|
+
return messageFormat.generateCountryFromLocale('en_DE');
|
17
|
+
}
|
18
|
+
|
19
|
+
expect(test2()).to.be.equal('Germany')
|
20
|
+
|
21
|
+
function test3 () {
|
22
|
+
return messageFormat.generateCountryFromLocale('de_DE');
|
23
|
+
}
|
24
|
+
expect(test3()).to.be.equal('Deutschland')
|
25
|
+
|
26
|
+
function test4 () {
|
27
|
+
return messageFormat.generateCountryFromLocale()
|
28
|
+
}
|
29
|
+
expect(test4()).to.be.empty
|
30
|
+
});
|
31
|
+
});
|
@@ -76,8 +76,13 @@ describe('lib/performance/getEntriesByName', function () {
|
|
76
76
|
expect(result.length).to.equal(0);
|
77
77
|
});
|
78
78
|
|
79
|
+
|
79
80
|
it('throws an error if no arguments are passed', function () {
|
80
|
-
|
81
|
+
//name is passed to the nativeImplementation which is undefined and returns an empty array
|
82
|
+
function test () {
|
83
|
+
return perfGetEntriesByName.getEntriesByName()
|
84
|
+
}
|
85
|
+
expect(test()).to.be.empty;
|
81
86
|
});
|
82
87
|
|
83
88
|
});
|
@@ -9,13 +9,14 @@ var perfMark = require('../../../lib/performance/mark.js');
|
|
9
9
|
|
10
10
|
describe('lib/performance/getEntriesByType', function () {
|
11
11
|
before(function () {
|
12
|
+
//Clearing all the marks as marks from other tests were being added
|
13
|
+
performance.clearMarks()
|
12
14
|
perfMark.mark('test-by-name1');
|
13
15
|
perfMark.mark('test-by-name2');
|
14
16
|
});
|
15
17
|
|
16
18
|
it('returns an array of all matching performance marks by type', function () {
|
17
19
|
var result = perfGetEntriesByType.getEntriesByType('mark');
|
18
|
-
|
19
20
|
// Test 1: it returns an array.
|
20
21
|
expect(result).to.be.an('array');
|
21
22
|
|
@@ -41,7 +42,7 @@ describe('lib/performance/getEntriesByType', function () {
|
|
41
42
|
});
|
42
43
|
|
43
44
|
it('throws an error if no arguments are passed', function () {
|
44
|
-
expect(
|
45
|
+
expect(perfGetEntriesByType.getEntriesByType()).to.be.empty;
|
45
46
|
});
|
46
47
|
|
47
48
|
});
|
@@ -32,7 +32,7 @@ describe('lib/performance/measure', function () {
|
|
32
32
|
});
|
33
33
|
|
34
34
|
it('throws an error if the measure name is omitted', function () {
|
35
|
-
expect(
|
35
|
+
expect(perfMeasure.measure()).to.be.empty;
|
36
36
|
});
|
37
37
|
|
38
38
|
it('throws an error if the startMark or endMark name is supplied, but is invalid', function () {
|