Skip to content

Commit 98b5174

Browse files
authored
feat: load Web Components polyfill on demand (#96)
BREAKING CHANGE: any applications that want to support Edge and/or IE11 should now import the respective browser support module. For details, see the README.md
1 parent 4de71ce commit 98b5174

30 files changed

+1843
-1560
lines changed

README.md

+28
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,34 @@ Then, you can use the custom element in an HTML page:
5757
<ui5-button>Hello world!</ui5-button>
5858
```
5959

60+
## Browser support
61+
62+
Currently only Chrome, Safari and Firefox support Web Components natively.
63+
64+
If your application should run on browsers without native Web Components support (Edge and/or IE11), import one the following modules before your first Web Component import:
65+
66+
### Edge only
67+
68+
```js
69+
import "@ui5/webcomponents-base/src/sap/ui/webcomponents/base/browsersupport/Edge";
70+
```
71+
72+
### Edge and IE11
73+
74+
```js
75+
import "@ui5/webcomponents-base/src/sap/ui/webcomponents/base/browsersupport/IE11";
76+
```
77+
78+
*Note:* Importing the module for IE11 support automatically enables Edge support as well, so there is no need to import them both explicitly.
79+
80+
Example:
81+
82+
```js
83+
import "@ui5/webcomponents-base/src/sap/ui/webcomponents/base/browsersupport/IE11"; // This will enable Edge and IE11 support for all Web Components below
84+
import "@ui5/webcomponents/dist/Button"; // loads ui5-button
85+
import "@ui5/webcomponents/dist/Label"; // loads ui5-label
86+
```
87+
6088
## Configure
6189
UI5 Web Components have built-in internalization and globalization support. Language, compact/cozy switch, date/time settings and theme can be changed with parameters.
6290

packages/base/.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# Note: Changes to this file also must be applied to the top level .eslintignore file.
22
test
3+
src/sap/ui/webcomponents/base/thirdparty

packages/base/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"@polymer/polymer": "^3.1.0",
2323
"@ui5/webcomponents-core": "0.7.0",
2424
"lit-html": "^1.0.0",
25+
"regenerator-runtime": "0.12.1",
2526
"url-search-params-polyfill": "^5.0.0"
2627
},
2728
"devDependencies": {

packages/base/src/sap/ui/webcomponents/base/Bootstrap.js

-5
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,9 @@ import "./shims/jquery-shim";
33

44
import whenDOMReady from "./util/whenDOMReady";
55
import EventEnrichment from "./events/EventEnrichment";
6-
import patchNodeValue from "./compatibility/patchNodeValue";
76
import IconFonts from "./IconFonts";
87
import DOMEventHandler from "./DOMEventHandler";
98

10-
11-
// This will only have effect if the polyfill is loaded
12-
patchNodeValue();
13-
149
EventEnrichment.run();
1510

1611
let bootPromise;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// URLSearchParams
2+
import "url-search-params-polyfill";
3+
4+
// Edge only needs the Web Components polyfill and the pseudo mutation observer fix
5+
import "../thirdparty/webcomponents-polyfill";
6+
import "../compatibility/patchNodeValue";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// String
2+
import "@ui5/webcomponents-core/dist/sap/ui/thirdparty/es6-string-methods";
3+
4+
// Object
5+
import "../thirdparty/Object.assign";
6+
import "../thirdparty/Object.entries";
7+
8+
// Array
9+
import "../thirdparty/Array.from";
10+
import "../thirdparty/Array.prototype.fill";
11+
import "../thirdparty/Array.prototype.includes";
12+
13+
// Number
14+
import "../thirdparty/Number.isInteger";
15+
import "../thirdparty/Number.isNaN";
16+
import "../thirdparty/Number.parseInt";
17+
18+
// Symbol
19+
import "../thirdparty/Symbol";
20+
21+
// Element
22+
import "../thirdparty/Element.prototype.matches";
23+
import "../thirdparty/Element.prototype.closest";
24+
25+
// Promise
26+
import "@ui5/webcomponents-core/dist/sap/ui/thirdparty/es6-promise";
27+
28+
// WeakSet
29+
import "../thirdparty/WeakSet";
30+
31+
// fetch
32+
import "../thirdparty/fetch";
33+
34+
// template
35+
import "../thirdparty/template";
36+
37+
// Various event polyfills - preventDefault, window.Event, window.CustomEvent, window.MouseEvent
38+
import "../thirdparty/events-polyfills";
39+
40+
// async - await
41+
import "regenerator-runtime/runtime";
42+
43+
// Plus all polyfills needed for Edge are also needed for IE11
44+
import "./Edge";

packages/base/src/sap/ui/webcomponents/base/compatibility/ShadowDOM.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import "../thirdparty/webcomponents-polyfill";
21
import { getTheme, getRTL, getCompactSize } from "../Configuration";
32

43
import StyleInjection from "../theming/StyleInjection";

packages/base/src/sap/ui/webcomponents/base/compatibility/patchNodeValue.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import "../thirdparty/webcomponents-polyfill";
2-
31
const patchNodeValue = () => {
42
if (!window.ShadyDOM) {
53
return;
@@ -21,4 +19,6 @@ const patchNodeValue = () => {
2119
});
2220
};
2321

24-
export default patchNodeValue;
22+
patchNodeValue();
23+
24+
export default {};

packages/base/src/sap/ui/webcomponents/base/events/PolymerGestures.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import "../thirdparty/webcomponents-polyfill";
21
import * as PolymerGestures from "@polymer/polymer/lib/utils/gestures";
32
import { injectGesturesProvider } from "./DefaultGestures";
43

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// https://raw.githubusercontent.com/webcomponents/webcomponents-platform/master/webcomponents-platform.js
2+
/**
3+
* @license
4+
* Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
5+
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
6+
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
7+
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
8+
* Code distributed by Google as part of the polymer project is also
9+
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
10+
*/
11+
12+
if (!Array.from) {
13+
Array.from = function (object) {
14+
return [].slice.call(object);
15+
};
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
if (!Array.prototype.fill) {
2+
Object.defineProperty(Array.prototype, 'fill', {
3+
value: function(value) {
4+
5+
// Steps 1-2.
6+
if (this == null) {
7+
throw new TypeError('this is null or not defined');
8+
}
9+
10+
var O = Object(this);
11+
12+
// Steps 3-5.
13+
var len = O.length >>> 0;
14+
15+
// Steps 6-7.
16+
var start = arguments[1];
17+
var relativeStart = start >> 0;
18+
19+
// Step 8.
20+
var k = relativeStart < 0 ?
21+
Math.max(len + relativeStart, 0) :
22+
Math.min(relativeStart, len);
23+
24+
// Steps 9-10.
25+
var end = arguments[2];
26+
var relativeEnd = end === undefined ?
27+
len : end >> 0;
28+
29+
// Step 11.
30+
var final = relativeEnd < 0 ?
31+
Math.max(len + relativeEnd, 0) :
32+
Math.min(relativeEnd, len);
33+
34+
// Step 12.
35+
while (k < final) {
36+
O[k] = value;
37+
k++;
38+
}
39+
40+
// Step 13.
41+
return O;
42+
}
43+
});
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
2+
if (!Array.prototype.includes) {
3+
Object.defineProperty(Array.prototype, 'includes', {
4+
value: function(searchElement, fromIndex) {
5+
6+
if (this == null) {
7+
throw new TypeError('"this" is null or not defined');
8+
}
9+
10+
// 1. Let O be ? ToObject(this value).
11+
var o = Object(this);
12+
13+
// 2. Let len be ? ToLength(? Get(O, "length")).
14+
var len = o.length >>> 0;
15+
16+
// 3. If len is 0, return false.
17+
if (len === 0) {
18+
return false;
19+
}
20+
21+
// 4. Let n be ? ToInteger(fromIndex).
22+
// (If fromIndex is undefined, this step produces the value 0.)
23+
var n = fromIndex | 0;
24+
25+
// 5. If n ≥ 0, then
26+
// a. Let k be n.
27+
// 6. Else n < 0,
28+
// a. Let k be len + n.
29+
// b. If k < 0, let k be 0.
30+
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
31+
32+
function sameValueZero(x, y) {
33+
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
34+
}
35+
36+
// 7. Repeat, while k < len
37+
while (k < len) {
38+
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
39+
// b. If SameValueZero(searchElement, elementK) is true, return true.
40+
if (sameValueZero(o[k], searchElement)) {
41+
return true;
42+
}
43+
// c. Increase k by 1.
44+
k++;
45+
}
46+
47+
// 8. Return false
48+
return false;
49+
}
50+
});
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
if (!Element.prototype.closest) {
2+
Element.prototype.closest = function(s) {
3+
var el = this;
4+
if (!document.documentElement.contains(el)) return null;
5+
do {
6+
if (el.matches(s)) return el;
7+
el = el.parentElement || el.parentNode;
8+
} while (el !== null && el.nodeType === 1);
9+
return null;
10+
};
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
if (Element && !Element.prototype.matches) {
2+
var proto = Element.prototype;
3+
proto.matches = proto.matchesSelector ||
4+
proto.mozMatchesSelector || proto.msMatchesSelector ||
5+
proto.oMatchesSelector || proto.webkitMatchesSelector;
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Number.isInteger = Number.isInteger || function(value) {
2+
return typeof value === 'number' &&
3+
isFinite(value) &&
4+
Math.floor(value) === value;
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Number.isNaN = Number.isNaN || window.isNaN;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Number.parseInt = Number.parseInt || window.parseInt;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// https://raw.githubusercontent.com/webcomponents/webcomponents-platform/master/webcomponents-platform.js
2+
/**
3+
* @license
4+
* Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
5+
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
6+
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
7+
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
8+
* Code distributed by Google as part of the polymer project is also
9+
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
10+
*/
11+
12+
if (!Object.assign) {
13+
var assign = function(target, source) {
14+
var n$ = Object.getOwnPropertyNames(source);
15+
for (var i=0, p; i < n$.length; i++) {
16+
p = n$[i];
17+
target[p] = source[p];
18+
}
19+
}
20+
21+
Object.assign = function(target, sources) {
22+
var args = [].slice.call(arguments, 1);
23+
for (var i=0, s; i < args.length; i++) {
24+
s = args[i];
25+
if (s) {
26+
assign(target, s);
27+
}
28+
}
29+
return target;
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
if (!Object.entries) {
2+
Object.entries = function( obj ){
3+
var ownProps = Object.keys( obj ),
4+
i = ownProps.length,
5+
resArray = new Array(i); // preallocate the Array
6+
while (i--)
7+
resArray[i] = [ownProps[i], obj[ownProps[i]]];
8+
9+
return resArray;
10+
};
11+
}

0 commit comments

Comments
 (0)