123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- (function(global) {
- /**
- * Polyfill URLSearchParams
- *
- * Inspired from : https://github.com/WebReflection/url-search-params/blob/master/src/url-search-params.js
- */
- var checkIfIteratorIsSupported = function() {
- try {
- return !!Symbol.iterator;
- } catch (error) {
- return false;
- }
- };
- var iteratorSupported = checkIfIteratorIsSupported();
- var createIterator = function(items) {
- var iterator = {
- next: function() {
- var value = items.shift();
- return { done: value === void 0, value: value };
- }
- };
- if (iteratorSupported) {
- iterator[Symbol.iterator] = function() {
- return iterator;
- };
- }
- return iterator;
- };
- /**
- * Search param name and values should be encoded according to https://url.spec.whatwg.org/#urlencoded-serializing
- * encodeURIComponent() produces the same result except encoding spaces as `%20` instead of `+`.
- */
- var serializeParam = function(value) {
- return encodeURIComponent(value).replace(/%20/g, '+');
- };
- var deserializeParam = function(value) {
- return decodeURIComponent(String(value).replace(/\+/g, ' '));
- };
- var polyfillURLSearchParams = function() {
- var URLSearchParams = function(searchString) {
- Object.defineProperty(this, '_entries', { writable: true, value: {} });
- var typeofSearchString = typeof searchString;
- if (typeofSearchString === 'undefined') {
- // do nothing
- } else if (typeofSearchString === 'string') {
- if (searchString !== '') {
- this._fromString(searchString);
- }
- } else if (searchString instanceof URLSearchParams) {
- var _this = this;
- searchString.forEach(function(value, name) {
- _this.append(name, value);
- });
- } else if ((searchString !== null) && (typeofSearchString === 'object')) {
- if (Object.prototype.toString.call(searchString) === '[object Array]') {
- for (var i = 0; i < searchString.length; i++) {
- var entry = searchString[i];
- if ((Object.prototype.toString.call(entry) === '[object Array]') || (entry.length !== 2)) {
- this.append(entry[0], entry[1]);
- } else {
- throw new TypeError('Expected [string, any] as entry at index ' + i + ' of URLSearchParams\'s input');
- }
- }
- } else {
- for (var key in searchString) {
- if (searchString.hasOwnProperty(key)) {
- this.append(key, searchString[key]);
- }
- }
- }
- } else {
- throw new TypeError('Unsupported input\'s type for URLSearchParams');
- }
- };
- var proto = URLSearchParams.prototype;
- proto.append = function(name, value) {
- if (name in this._entries) {
- this._entries[name].push(String(value));
- } else {
- this._entries[name] = [String(value)];
- }
- };
- proto.delete = function(name) {
- delete this._entries[name];
- };
- proto.get = function(name) {
- return (name in this._entries) ? this._entries[name][0] : null;
- };
- proto.getAll = function(name) {
- return (name in this._entries) ? this._entries[name].slice(0) : [];
- };
- proto.has = function(name) {
- return (name in this._entries);
- };
- proto.set = function(name, value) {
- this._entries[name] = [String(value)];
- };
- proto.forEach = function(callback, thisArg) {
- var entries;
- for (var name in this._entries) {
- if (this._entries.hasOwnProperty(name)) {
- entries = this._entries[name];
- for (var i = 0; i < entries.length; i++) {
- callback.call(thisArg, entries[i], name, this);
- }
- }
- }
- };
- proto.keys = function() {
- var items = [];
- this.forEach(function(value, name) {
- items.push(name);
- });
- return createIterator(items);
- };
- proto.values = function() {
- var items = [];
- this.forEach(function(value) {
- items.push(value);
- });
- return createIterator(items);
- };
- proto.entries = function() {
- var items = [];
- this.forEach(function(value, name) {
- items.push([name, value]);
- });
- return createIterator(items);
- };
- if (iteratorSupported) {
- proto[Symbol.iterator] = proto.entries;
- }
- proto.toString = function() {
- var searchArray = [];
- this.forEach(function(value, name) {
- searchArray.push(serializeParam(name) + '=' + serializeParam(value));
- });
- return searchArray.join('&');
- };
- global.URLSearchParams = URLSearchParams;
- };
- var checkIfURLSearchParamsSupported = function() {
- try {
- var URLSearchParams = global.URLSearchParams;
- return (
- (new URLSearchParams('?a=1').toString() === 'a=1') &&
- (typeof URLSearchParams.prototype.set === 'function') &&
- (typeof URLSearchParams.prototype.entries === 'function')
- );
- } catch (e) {
- return false;
- }
- };
- if (!checkIfURLSearchParamsSupported()) {
- polyfillURLSearchParams();
- }
- var proto = global.URLSearchParams.prototype;
- if (typeof proto.sort !== 'function') {
- proto.sort = function() {
- var _this = this;
- var items = [];
- this.forEach(function(value, name) {
- items.push([name, value]);
- if (!_this._entries) {
- _this.delete(name);
- }
- });
- items.sort(function(a, b) {
- if (a[0] < b[0]) {
- return -1;
- } else if (a[0] > b[0]) {
- return +1;
- } else {
- return 0;
- }
- });
- if (_this._entries) { // force reset because IE keeps keys index
- _this._entries = {};
- }
- for (var i = 0; i < items.length; i++) {
- this.append(items[i][0], items[i][1]);
- }
- };
- }
- if (typeof proto._fromString !== 'function') {
- Object.defineProperty(proto, '_fromString', {
- enumerable: false,
- configurable: false,
- writable: false,
- value: function(searchString) {
- if (this._entries) {
- this._entries = {};
- } else {
- var keys = [];
- this.forEach(function(value, name) {
- keys.push(name);
- });
- for (var i = 0; i < keys.length; i++) {
- this.delete(keys[i]);
- }
- }
- searchString = searchString.replace(/^\?/, '');
- var attributes = searchString.split('&');
- var attribute;
- for (var i = 0; i < attributes.length; i++) {
- attribute = attributes[i].split('=');
- this.append(
- deserializeParam(attribute[0]),
- (attribute.length > 1) ? deserializeParam(attribute[1]) : ''
- );
- }
- }
- });
- }
- // HTMLAnchorElement
- })(
- (typeof global !== 'undefined') ? global
- : ((typeof window !== 'undefined') ? window
- : ((typeof self !== 'undefined') ? self : this))
- );
- (function(global) {
- /**
- * Polyfill URL
- *
- * Inspired from : https://github.com/arv/DOM-URL-Polyfill/blob/master/src/url.js
- */
- var checkIfURLIsSupported = function() {
- try {
- var u = new global.URL('b', 'http://a');
- u.pathname = 'c d';
- return (u.href === 'http://a/c%20d') && u.searchParams;
- } catch (e) {
- return false;
- }
- };
- var polyfillURL = function() {
- var _URL = global.URL;
- var URL = function(url, base) {
- if (typeof url !== 'string') url = String(url);
- if (base && typeof base !== 'string') base = String(base);
- // Only create another document if the base is different from current location.
- var doc = document, baseElement;
- if (base && (global.location === void 0 || base !== global.location.href)) {
- base = base.toLowerCase();
- doc = document.implementation.createHTMLDocument('');
- baseElement = doc.createElement('base');
- baseElement.href = base;
- doc.head.appendChild(baseElement);
- try {
- if (baseElement.href.indexOf(base) !== 0) throw new Error(baseElement.href);
- } catch (err) {
- throw new Error('URL unable to set base ' + base + ' due to ' + err);
- }
- }
- var anchorElement = doc.createElement('a');
- anchorElement.href = url;
- if (baseElement) {
- doc.body.appendChild(anchorElement);
- anchorElement.href = anchorElement.href; // force href to refresh
- }
- var inputElement = doc.createElement('input');
- inputElement.type = 'url';
- inputElement.value = url;
- if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || (!inputElement.checkValidity() && !base)) {
- throw new TypeError('Invalid URL');
- }
- Object.defineProperty(this, '_anchorElement', {
- value: anchorElement
- });
- // create a linked searchParams which reflect its changes on URL
- var searchParams = new global.URLSearchParams(this.search);
- var enableSearchUpdate = true;
- var enableSearchParamsUpdate = true;
- var _this = this;
- ['append', 'delete', 'set'].forEach(function(methodName) {
- var method = searchParams[methodName];
- searchParams[methodName] = function() {
- method.apply(searchParams, arguments);
- if (enableSearchUpdate) {
- enableSearchParamsUpdate = false;
- _this.search = searchParams.toString();
- enableSearchParamsUpdate = true;
- }
- };
- });
- Object.defineProperty(this, 'searchParams', {
- value: searchParams,
- enumerable: true
- });
- var search = void 0;
- Object.defineProperty(this, '_updateSearchParams', {
- enumerable: false,
- configurable: false,
- writable: false,
- value: function() {
- if (this.search !== search) {
- search = this.search;
- if (enableSearchParamsUpdate) {
- enableSearchUpdate = false;
- this.searchParams._fromString(this.search);
- enableSearchUpdate = true;
- }
- }
- }
- });
- };
- var proto = URL.prototype;
- var linkURLWithAnchorAttribute = function(attributeName) {
- Object.defineProperty(proto, attributeName, {
- get: function() {
- return this._anchorElement[attributeName];
- },
- set: function(value) {
- this._anchorElement[attributeName] = value;
- },
- enumerable: true
- });
- };
- ['hash', 'host', 'hostname', 'port', 'protocol']
- .forEach(function(attributeName) {
- linkURLWithAnchorAttribute(attributeName);
- });
- Object.defineProperty(proto, 'search', {
- get: function() {
- return this._anchorElement['search'];
- },
- set: function(value) {
- this._anchorElement['search'] = value;
- this._updateSearchParams();
- },
- enumerable: true
- });
- Object.defineProperties(proto, {
- 'toString': {
- get: function() {
- var _this = this;
- return function() {
- return _this.href;
- };
- }
- },
- 'href': {
- get: function() {
- return this._anchorElement.href.replace(/\?$/, '');
- },
- set: function(value) {
- this._anchorElement.href = value;
- this._updateSearchParams();
- },
- enumerable: true
- },
- 'pathname': {
- get: function() {
- return this._anchorElement.pathname.replace(/(^\/?)/, '/');
- },
- set: function(value) {
- this._anchorElement.pathname = value;
- },
- enumerable: true
- },
- 'origin': {
- get: function() {
- // get expected port from protocol
- var expectedPort = { 'http:': 80, 'https:': 443, 'ftp:': 21 }[this._anchorElement.protocol];
- // add port to origin if, expected port is different than actual port
- // and it is not empty f.e http://foo:8080
- // 8080 != 80 && 8080 != ''
- var addPortToOrigin = this._anchorElement.port != expectedPort &&
- this._anchorElement.port !== '';
- return this._anchorElement.protocol +
- '//' +
- this._anchorElement.hostname +
- (addPortToOrigin ? (':' + this._anchorElement.port) : '');
- },
- enumerable: true
- },
- 'password': { // TODO
- get: function() {
- return '';
- },
- set: function(value) {
- },
- enumerable: true
- },
- 'username': { // TODO
- get: function() {
- return '';
- },
- set: function(value) {
- },
- enumerable: true
- },
- });
- URL.createObjectURL = function(blob) {
- return _URL.createObjectURL.apply(_URL, arguments);
- };
- URL.revokeObjectURL = function(url) {
- return _URL.revokeObjectURL.apply(_URL, arguments);
- };
- global.URL = URL;
- };
- if (!checkIfURLIsSupported()) {
- polyfillURL();
- }
- if ((global.location !== void 0) && !('origin' in global.location)) {
- var getOrigin = function() {
- return global.location.protocol + '//' + global.location.hostname + (global.location.port ? (':' + global.location.port) : '');
- };
- try {
- Object.defineProperty(global.location, 'origin', {
- get: getOrigin,
- enumerable: true
- });
- } catch (e) {
- setInterval(function() {
- global.location.origin = getOrigin();
- }, 100);
- }
- }
- })(
- (typeof global !== 'undefined') ? global
- : ((typeof window !== 'undefined') ? window
- : ((typeof self !== 'undefined') ? self : this))
- );
|