Skip to content

Commit e7a0ade

Browse files
feature: support ie browser (#1887)
* feature: support ie browser into separate es5 folder (larger target, polyfill)
1 parent 16feded commit e7a0ade

File tree

7 files changed

+215
-8
lines changed

7 files changed

+215
-8
lines changed

demo/web1.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
<script type="module" src="https://unpkg.com/ionicons@4.5.10-0/dist/ionicons/ionicons.esm.js"></script>
1414
<script nomodule="" src="https://unpkg.com/ionicons@4.5.10-0/dist/ionicons/ionicons.js"></script>
1515

16-
<script src="../dist/gridstack-jq.js"></script>
16+
<!-- support for ie -->
17+
<script src="../dist/es5/gridstack-poly.js"></script>
18+
<script src="../dist/es5/gridstack-jq.js"></script>
1719
</head>
1820

1921
<body>

es5/tsconfig.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"compilerOptions": {
3+
/*
4+
"allowJs": true,
5+
"esModuleInterop": true,
6+
"allowSyntheticDefaultImports": true
7+
*/
8+
"declaration": true,
9+
"emitDecoratorMetadata": true,
10+
"experimentalDecorators": true,
11+
"inlineSources": true,
12+
"lib": [ "es6", "es2015", "dom" ],
13+
"module": "CommonJS",
14+
"noImplicitAny": false,
15+
"outDir": "../dist/es5",
16+
"sourceMap": true,
17+
"strict": false,
18+
"target": "ES5"
19+
},
20+
"exclude": [
21+
"../src/**/*.spec.ts",
22+
// used for webpack h5/jq/static .js
23+
"../src/gridstack-h5.ts",
24+
"../src/gridstack-jq.ts",
25+
"../src/gridstack-static.ts",
26+
],
27+
"include": [
28+
"../src/**/*.ts"
29+
],
30+
"typeroots": [
31+
"../node_modules/@types"
32+
]
33+
}

es5/webpack.config.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const path = require('path');
2+
const webpackConfig = require('../webpack.config.js');
3+
4+
const config = {...webpackConfig,
5+
target: ['web', 'es5'],
6+
module: {
7+
rules: [
8+
{
9+
test: /\.ts$/,
10+
use: {
11+
loader: 'ts-loader',
12+
options: {
13+
configFile: 'es5/tsconfig.json'
14+
}
15+
},
16+
exclude: ['/node_modules/', '/src/h5/', '/src/index-*.ts'],
17+
},
18+
],
19+
},
20+
};
21+
config.output.path = path.resolve(__dirname, '../dist/es5')
22+
module.exports = config

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
}
2020
],
2121
"scripts": {
22-
"build": "yarn --no-progress && rm -rf dist/* && grunt && webpack && tsc --stripInternal && yarn doc",
22+
"build": "yarn --no-progress && rm -rf dist/* && grunt && webpack && tsc --stripInternal && webpack --config es5/webpack.config.js && tsc --stripInternal --project es5/tsconfig.json && yarn doc",
2323
"w": "rm -rf dist/* && grunt && webpack",
2424
"t": "rm -rf dist/* && grunt && tsc --stripInternal",
2525
"doc": "doctoc ./README.md && doctoc ./doc/README.md && doctoc ./doc/CHANGES.md",
@@ -91,4 +91,4 @@
9191
"webpack": "^5.3.2",
9292
"webpack-cli": "^4.6.0"
9393
}
94-
}
94+
}

src/gridstack-poly.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,23 @@ if (!Array.prototype.findIndex) {
146146
});
147147
})([Element.prototype, Document.prototype, DocumentFragment.prototype]);
148148

149+
// from: https://github.com/jserz/js_piece/blob/master/DOM/Element/prepend()/prepend().md
150+
(function (arr) {
151+
arr.forEach(function (item) {
152+
item.prepend = item.prepend || function () {
153+
var argArr = Array.prototype.slice.call(arguments),
154+
docFrag = document.createDocumentFragment();
155+
156+
argArr.forEach(function (argItem) {
157+
var isNode = argItem instanceof Node;
158+
docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem)));
159+
});
160+
161+
this.insertBefore(docFrag, this.firstChild);
162+
};
163+
});
164+
})([Element.prototype, Document.prototype, DocumentFragment.prototype]);
165+
149166
// Production steps of ECMA-262, Edition 5, 15.4.4.18
150167
// Reference: http://es5.github.io/#x15.4.4.18
151168

@@ -202,4 +219,138 @@ if (!Array.prototype['forEach']) {
202219
}
203220
// 8. return undefined
204221
};
222+
}
223+
224+
// https://developer.mozilla.org/zh-CN/docs/Web/API/CustomEvent/CustomEvent
225+
(function(){
226+
try{
227+
new window.CustomEvent('T');
228+
}catch(e){
229+
var CustomEvent = function(event, params){
230+
params = params || { bubbles: false, cancelable: false, detail: undefined };
231+
232+
var evt = document.createEvent('CustomEvent');
233+
234+
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
235+
236+
return evt;
237+
};
238+
239+
CustomEvent.prototype = window.Event.prototype;
240+
241+
window.CustomEvent = CustomEvent;
242+
}
243+
})();
244+
245+
// https://github.com/jserz/js_piece/blob/master/DOM/ChildNode/remove()/remove().md
246+
(function (arr) {
247+
arr.forEach(function (item) {
248+
if (item.hasOwnProperty('remove')) {
249+
return;
250+
}
251+
Object.defineProperty(item, 'remove', {
252+
configurable: true,
253+
enumerable: true,
254+
writable: true,
255+
value: function remove() {
256+
this.parentNode.removeChild(this);
257+
}
258+
});
259+
});
260+
})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
261+
262+
// https://developer.mozilla.org/zh-CN/docs/Web/API/Element/matches
263+
if (!Element.prototype.matches) {
264+
Element.prototype.matches =
265+
Element.prototype.matchesSelector ||
266+
Element.prototype.mozMatchesSelector ||
267+
Element.prototype.msMatchesSelector ||
268+
Element.prototype.oMatchesSelector ||
269+
Element.prototype.webkitMatchesSelector ||
270+
function(s) {
271+
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
272+
i = matches.length;
273+
while (--i >= 0 && matches.item(i) !== this) {}
274+
return i > -1;
275+
};
276+
}
277+
278+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
279+
// Production steps of ECMA-262, Edition 6, 22.1.2.1
280+
if (!Array.from) {
281+
Array.from = (function () {
282+
var toStr = Object.prototype.toString;
283+
var isCallable = function (fn) {
284+
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
285+
};
286+
var toInteger = function (value) {
287+
var number = Number(value);
288+
if (isNaN(number)) { return 0; }
289+
if (number === 0 || !isFinite(number)) { return number; }
290+
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
291+
};
292+
var maxSafeInteger = Math.pow(2, 53) - 1;
293+
var toLength = function (value) {
294+
var len = toInteger(value);
295+
return Math.min(Math.max(len, 0), maxSafeInteger);
296+
};
297+
298+
// The length property of the from method is 1.
299+
return function from(arrayLike/*, mapFn, thisArg */) {
300+
// 1. Let C be the this value.
301+
var C = this;
302+
303+
// 2. Let items be ToObject(arrayLike).
304+
var items = Object(arrayLike);
305+
306+
// 3. ReturnIfAbrupt(items).
307+
if (arrayLike == null) {
308+
throw new TypeError("Array.from requires an array-like object - not null or undefined");
309+
}
310+
311+
// 4. If mapfn is undefined, then let mapping be false.
312+
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
313+
var T;
314+
if (typeof mapFn !== 'undefined') {
315+
// 5. else
316+
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
317+
if (!isCallable(mapFn)) {
318+
throw new TypeError('Array.from: when provided, the second argument must be a function');
319+
}
320+
321+
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
322+
if (arguments.length > 2) {
323+
T = arguments[2];
324+
}
325+
}
326+
327+
// 10. Let lenValue be Get(items, "length").
328+
// 11. Let len be ToLength(lenValue).
329+
var len = toLength(items.length);
330+
331+
// 13. If IsConstructor(C) is true, then
332+
// 13. a. Let A be the result of calling the [[Construct]] internal method
333+
// of C with an argument list containing the single item len.
334+
// 14. a. Else, Let A be ArrayCreate(len).
335+
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
336+
337+
// 16. Let k be 0.
338+
var k = 0;
339+
// 17. Repeat, while k < len… (also steps a - h)
340+
var kValue;
341+
while (k < len) {
342+
kValue = items[k];
343+
if (mapFn) {
344+
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
345+
} else {
346+
A[k] = kValue;
347+
}
348+
k += 1;
349+
}
350+
// 18. Let putStatus be Put(A, "length", len, true).
351+
A.length = len;
352+
// 20. Return A.
353+
return A;
354+
};
355+
}());
205356
}

src/gridstack.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* Copyright (c) 2021 Alain Dumesny
66
* see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE
77
*/
8-
98
import { GridStackEngine } from './gridstack-engine';
109
import { Utils, HeightData } from './utils';
1110
import { ColumnOptions, GridItemHTMLElement, GridStackElement, GridStackEventHandlerCallback,
@@ -164,7 +163,7 @@ export class GridStack {
164163
// create the grid element, but check if the passed 'parent' already has grid styling and should be used instead
165164
let el = parent;
166165
if (!parent.classList.contains('grid-stack')) {
167-
let doc = document.implementation.createHTMLDocument();
166+
let doc = document.implementation.createHTMLDocument("");
168167
doc.body.innerHTML = `<div class="grid-stack ${opt.class || ''}"></div>`;
169168
el = doc.body.children[0] as HTMLElement;
170169
parent.appendChild(el);
@@ -400,13 +399,13 @@ export class GridStack {
400399

401400
let el: HTMLElement;
402401
if (typeof els === 'string') {
403-
let doc = document.implementation.createHTMLDocument();
402+
let doc = document.implementation.createHTMLDocument("");
404403
doc.body.innerHTML = els;
405404
el = doc.body.children[0] as HTMLElement;
406405
} else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {
407406
let content = els ? (els as GridStackWidget).content || '' : '';
408407
options = els;
409-
let doc = document.implementation.createHTMLDocument();
408+
let doc = document.implementation.createHTMLDocument("");
410409
doc.body.innerHTML = `<div class="grid-stack-item ${this.opts.itemClass || ''}"><div class="grid-stack-item-content">${content}</div></div>`;
411410
el = doc.body.children[0] as HTMLElement;
412411
} else {

src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ export class Utils {
295295

296296
/** @internal returns the passed element if scrollable, else the closest parent that will, up to the entire document scrolling element */
297297
static getScrollElement(el?: HTMLElement): HTMLElement {
298-
if (!el) return document.scrollingElement as HTMLElement;
298+
if (!el) return document.scrollingElement as HTMLElement || document.documentElement;
299299
const style = getComputedStyle(el);
300300
const overflowRegex = /(auto|scroll)/;
301301

0 commit comments

Comments
 (0)