summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/lib
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/lib')
-rw-r--r--app/assets/javascripts/lib/utils/accessor.js47
-rw-r--r--app/assets/javascripts/lib/utils/ajax_cache.js54
-rw-r--r--app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js116
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js80
-rw-r--r--app/assets/javascripts/lib/utils/constants.js2
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js12
-rw-r--r--app/assets/javascripts/lib/utils/http_status.js4
-rw-r--r--app/assets/javascripts/lib/utils/number_utils.js44
-rw-r--r--app/assets/javascripts/lib/utils/poll.js11
-rw-r--r--app/assets/javascripts/lib/utils/regexp.js10
-rw-r--r--app/assets/javascripts/lib/utils/simple_poll.js15
-rw-r--r--app/assets/javascripts/lib/utils/text_utility.js347
-rw-r--r--app/assets/javascripts/lib/utils/type_utility.js17
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js171
14 files changed, 569 insertions, 361 deletions
diff --git a/app/assets/javascripts/lib/utils/accessor.js b/app/assets/javascripts/lib/utils/accessor.js
new file mode 100644
index 00000000000..1d18992af63
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/accessor.js
@@ -0,0 +1,47 @@
+function isPropertyAccessSafe(base, property) {
+ let safe;
+
+ try {
+ safe = !!base[property];
+ } catch (error) {
+ safe = false;
+ }
+
+ return safe;
+}
+
+function isFunctionCallSafe(base, functionName, ...args) {
+ let safe = true;
+
+ try {
+ base[functionName](...args);
+ } catch (error) {
+ safe = false;
+ }
+
+ return safe;
+}
+
+function isLocalStorageAccessSafe() {
+ let safe;
+
+ const TEST_KEY = 'isLocalStorageAccessSafe';
+ const TEST_VALUE = 'true';
+
+ safe = isPropertyAccessSafe(window, 'localStorage');
+ if (!safe) return safe;
+
+ safe = isFunctionCallSafe(window.localStorage, 'setItem', TEST_KEY, TEST_VALUE);
+
+ if (safe) window.localStorage.removeItem(TEST_KEY);
+
+ return safe;
+}
+
+const AccessorUtilities = {
+ isPropertyAccessSafe,
+ isFunctionCallSafe,
+ isLocalStorageAccessSafe,
+};
+
+export default AccessorUtilities;
diff --git a/app/assets/javascripts/lib/utils/ajax_cache.js b/app/assets/javascripts/lib/utils/ajax_cache.js
new file mode 100644
index 00000000000..cf030d613df
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/ajax_cache.js
@@ -0,0 +1,54 @@
+class AjaxCache {
+ constructor() {
+ this.internalStorage = { };
+ this.pendingRequests = { };
+ }
+
+ get(endpoint) {
+ return this.internalStorage[endpoint];
+ }
+
+ hasData(endpoint) {
+ return Object.prototype.hasOwnProperty.call(this.internalStorage, endpoint);
+ }
+
+ remove(endpoint) {
+ delete this.internalStorage[endpoint];
+ }
+
+ retrieve(endpoint) {
+ if (this.hasData(endpoint)) {
+ return Promise.resolve(this.get(endpoint));
+ }
+
+ let pendingRequest = this.pendingRequests[endpoint];
+
+ if (!pendingRequest) {
+ pendingRequest = new Promise((resolve, reject) => {
+ // jQuery 2 is not Promises/A+ compatible (missing catch)
+ $.ajax(endpoint) // eslint-disable-line promise/catch-or-return
+ .then(data => resolve(data),
+ (jqXHR, textStatus, errorThrown) => {
+ const error = new Error(`${endpoint}: ${errorThrown}`);
+ error.textStatus = textStatus;
+ reject(error);
+ },
+ );
+ })
+ .then((data) => {
+ this.internalStorage[endpoint] = data;
+ delete this.pendingRequests[endpoint];
+ })
+ .catch((error) => {
+ delete this.pendingRequests[endpoint];
+ throw error;
+ });
+
+ this.pendingRequests[endpoint] = pendingRequest;
+ }
+
+ return pendingRequest.then(() => this.get(endpoint));
+ }
+}
+
+export default new AjaxCache();
diff --git a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js
index 2955bda1a36..0bf2ba6acc2 100644
--- a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js
+++ b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js
@@ -31,82 +31,78 @@
*
* ### How to use
*
- * new window.gl.LinkedTabs({
+ * new LinkedTabs({
* action: "#{controller.action_name}",
* defaultAction: 'tab1',
* parentEl: '.tab-links'
* });
*/
-(() => {
- window.gl = window.gl || {};
+export default class LinkedTabs {
+ /**
+ * Binds the events and activates de default tab.
+ *
+ * @param {Object} options
+ */
+ constructor(options = {}) {
+ this.options = options;
- window.gl.LinkedTabs = class LinkedTabs {
- /**
- * Binds the events and activates de default tab.
- *
- * @param {Object} options
- */
- constructor(options) {
- this.options = options || {};
+ this.defaultAction = this.options.defaultAction;
+ this.action = this.options.action || this.defaultAction;
- this.defaultAction = this.options.defaultAction;
- this.action = this.options.action || this.defaultAction;
-
- if (this.action === 'show') {
- this.action = this.defaultAction;
- }
+ if (this.action === 'show') {
+ this.action = this.defaultAction;
+ }
- this.currentLocation = window.location;
+ this.currentLocation = window.location;
- const tabSelector = `${this.options.parentEl} a[data-toggle="tab"]`;
+ const tabSelector = `${this.options.parentEl} a[data-toggle="tab"]`;
- // since this is a custom event we need jQuery :(
- $(document)
- .off('shown.bs.tab', tabSelector)
- .on('shown.bs.tab', tabSelector, e => this.tabShown(e));
+ // since this is a custom event we need jQuery :(
+ $(document)
+ .off('shown.bs.tab', tabSelector)
+ .on('shown.bs.tab', tabSelector, e => this.tabShown(e));
- this.activateTab(this.action);
- }
+ this.activateTab(this.action);
+ }
- /**
- * Handles the `shown.bs.tab` event to set the currect url action.
- *
- * @param {type} evt
- * @return {Function}
- */
- tabShown(evt) {
- const source = evt.target.getAttribute('href');
+ /**
+ * Handles the `shown.bs.tab` event to set the currect url action.
+ *
+ * @param {type} evt
+ * @return {Function}
+ */
+ tabShown(evt) {
+ const source = evt.target.getAttribute('href');
- return this.setCurrentAction(source);
- }
+ return this.setCurrentAction(source);
+ }
- /**
- * Updates the URL with the path that matched the given action.
- *
- * @param {String} source
- * @return {String}
- */
- setCurrentAction(source) {
- const copySource = source;
+ /**
+ * Updates the URL with the path that matched the given action.
+ *
+ * @param {String} source
+ * @return {String}
+ */
+ setCurrentAction(source) {
+ const copySource = source;
- copySource.replace(/\/+$/, '');
+ copySource.replace(/\/+$/, '');
- const newState = `${copySource}${this.currentLocation.search}${this.currentLocation.hash}`;
+ const newState = `${copySource}${this.currentLocation.search}${this.currentLocation.hash}`;
- history.replaceState({
- url: newState,
- }, document.title, newState);
- return newState;
- }
+ history.replaceState({
+ url: newState,
+ }, document.title, newState);
+ return newState;
+ }
- /**
- * Given the current action activates the correct tab.
- * http://getbootstrap.com/javascript/#tab-show
- * Note: Will trigger `shown.bs.tab`
- */
- activateTab() {
- return $(`${this.options.parentEl} a[data-action='${this.action}']`).tab('show');
- }
- };
-})();
+ /**
+ * Given the current action activates the correct tab.
+ * http://getbootstrap.com/javascript/#tab-show
+ * Note: Will trigger `shown.bs.tab`
+ */
+ activateTab() {
+ return $(`${this.options.parentEl} a[data-action='${this.action}']`).tab('show');
+ }
+}
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 4aad0128aef..7e62773ae6c 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -2,6 +2,8 @@
(function() {
(function(w) {
var base;
+ const faviconEl = document.getElementById('favicon');
+ const originalFavicon = faviconEl ? faviconEl.getAttribute('href') : null;
w.gl || (w.gl = {});
(base = w.gl).utils || (base.utils = {});
w.gl.utils.isInGroupsPage = function() {
@@ -33,6 +35,14 @@
});
};
+ w.gl.utils.ajaxPost = function(url, data) {
+ return $.ajax({
+ type: 'POST',
+ url: url,
+ data: data,
+ });
+ };
+
w.gl.utils.extractLast = function(term) {
return this.split(term).pop();
};
@@ -45,6 +55,10 @@
}
};
+ gl.utils.updateTooltipTitle = function($tooltipEl, newTitle) {
+ return $tooltipEl.attr('title', newTitle).tooltip('fixTitle');
+ };
+
w.gl.utils.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
event_name = event_name || 'input';
var closest_submit, field, that;
@@ -121,7 +135,10 @@
gl.utils.getUrlParamsArray = function () {
// We can trust that each param has one & since values containing & will be encoded
// Remove the first character of search as it is always ?
- return window.location.search.slice(1).split('&');
+ return window.location.search.slice(1).split('&').map((param) => {
+ const split = param.split('=');
+ return [decodeURI(split[0]), split[1]].join('=');
+ });
};
gl.utils.isMetaKey = function(e) {
@@ -163,7 +180,10 @@
w.gl.utils.getSelectedFragment = () => {
const selection = window.getSelection();
if (selection.rangeCount === 0) return null;
- const documentFragment = selection.getRangeAt(0).cloneContents();
+ const documentFragment = document.createDocumentFragment();
+ for (let i = 0; i < selection.rangeCount; i += 1) {
+ documentFragment.appendChild(selection.getRangeAt(i).cloneContents());
+ }
if (documentFragment.textContent.length === 0) return null;
return documentFragment;
@@ -263,7 +283,7 @@
});
/**
- * Updates the search parameter of a URL given the parameter and values provided.
+ * Updates the search parameter of a URL given the parameter and value provided.
*
* If no search params are present we'll add it.
* If param for page is already present, we'll update it
@@ -278,17 +298,24 @@
let search;
const locationSearch = window.location.search;
- if (locationSearch.length === 0) {
- search = `?${param}=${value}`;
- }
+ if (locationSearch.length) {
+ const parameters = locationSearch.substring(1, locationSearch.length)
+ .split('&')
+ .reduce((acc, element) => {
+ const val = element.split('=');
+ acc[val[0]] = decodeURIComponent(val[1]);
+ return acc;
+ }, {});
- if (locationSearch.indexOf(param) !== -1) {
- const regex = new RegExp(param + '=\\d');
- search = locationSearch.replace(regex, `${param}=${value}`);
- }
+ parameters[param] = value;
+
+ const toString = Object.keys(parameters)
+ .map(val => `${val}=${encodeURIComponent(parameters[val])}`)
+ .join('&');
- if (locationSearch.length && locationSearch.indexOf(param) === -1) {
- search = `${locationSearch}&${param}=${value}`;
+ search = `?${toString}`;
+ } else {
+ search = `?${param}=${value}`;
}
return search;
@@ -354,5 +381,34 @@
fn(next, stop);
});
};
+
+ w.gl.utils.setFavicon = (faviconPath) => {
+ if (faviconEl && faviconPath) {
+ faviconEl.setAttribute('href', faviconPath);
+ }
+ };
+
+ w.gl.utils.resetFavicon = () => {
+ if (faviconEl) {
+ faviconEl.setAttribute('href', originalFavicon);
+ }
+ };
+
+ w.gl.utils.setCiStatusFavicon = (pageUrl) => {
+ $.ajax({
+ url: pageUrl,
+ dataType: 'json',
+ success: function(data) {
+ if (data && data.favicon) {
+ gl.utils.setFavicon(data.favicon);
+ } else {
+ gl.utils.resetFavicon();
+ }
+ },
+ error: function() {
+ gl.utils.resetFavicon();
+ }
+ });
+ };
})(window);
}).call(window);
diff --git a/app/assets/javascripts/lib/utils/constants.js b/app/assets/javascripts/lib/utils/constants.js
new file mode 100644
index 00000000000..1e96c7ab5cd
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/constants.js
@@ -0,0 +1,2 @@
+/* eslint-disable import/prefer-default-export */
+export const BYTES_IN_KIB = 1024;
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index 82dcbdc26c8..b2f48049bb4 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -1,9 +1,10 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, max-len */
-/* global timeago */
-/* global dateFormat */
-window.timeago = require('timeago.js');
-window.dateFormat = require('vendor/date.format');
+import timeago from 'timeago.js';
+import dateFormat from 'vendor/date.format';
+
+window.timeago = timeago;
+window.dateFormat = dateFormat;
(function() {
(function(w) {
@@ -101,8 +102,7 @@ window.dateFormat = require('vendor/date.format');
};
w.gl.utils.updateTimeagoText = function(el) {
- const timeago = gl.utils.getTimeago();
- const formattedDate = timeago.format(el.getAttribute('datetime'), 'gl_en');
+ const formattedDate = gl.utils.getTimeago().format(el.getAttribute('datetime'), 'gl_en');
if (el.textContent !== formattedDate) {
el.textContent = formattedDate;
diff --git a/app/assets/javascripts/lib/utils/http_status.js b/app/assets/javascripts/lib/utils/http_status.js
index bc109a69c20..415e50f32ae 100644
--- a/app/assets/javascripts/lib/utils/http_status.js
+++ b/app/assets/javascripts/lib/utils/http_status.js
@@ -2,9 +2,7 @@
* exports HTTP status codes
*/
-const statusCodes = {
+export default {
NO_CONTENT: 204,
OK: 200,
};
-
-module.exports = statusCodes;
diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js
new file mode 100644
index 00000000000..f1b07408671
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/number_utils.js
@@ -0,0 +1,44 @@
+import { BYTES_IN_KIB } from './constants';
+
+/**
+ * Function that allows a number with an X amount of decimals
+ * to be formatted in the following fashion:
+ * * For 1 digit to the left of the decimal point and X digits to the right of it
+ * * * Show 3 digits to the right
+ * * For 2 digits to the left of the decimal point and X digits to the right of it
+ * * * Show 2 digits to the right
+*/
+export function formatRelevantDigits(number) {
+ let digitsLeft = '';
+ let relevantDigits = 0;
+ let formattedNumber = '';
+ if (!isNaN(Number(number))) {
+ digitsLeft = number.split('.')[0];
+ switch (digitsLeft.length) {
+ case 1:
+ relevantDigits = 3;
+ break;
+ case 2:
+ relevantDigits = 2;
+ break;
+ case 3:
+ relevantDigits = 1;
+ break;
+ default:
+ relevantDigits = 4;
+ break;
+ }
+ formattedNumber = Number(number).toFixed(relevantDigits);
+ }
+ return formattedNumber;
+}
+
+/**
+ * Utility function that calculates KiB of the given bytes.
+ *
+ * @param {Number} number bytes
+ * @return {Number} KiB
+ */
+export function bytesToKiB(number) {
+ return number / BYTES_IN_KIB;
+}
diff --git a/app/assets/javascripts/lib/utils/poll.js b/app/assets/javascripts/lib/utils/poll.js
index 5c22aea51cd..e31cc5fbabe 100644
--- a/app/assets/javascripts/lib/utils/poll.js
+++ b/app/assets/javascripts/lib/utils/poll.js
@@ -65,7 +65,6 @@ export default class Poll {
this.makeRequest();
}, pollInterval);
}
-
this.options.successCallback(response);
}
@@ -76,8 +75,14 @@ export default class Poll {
notificationCallback(true);
return resource[method](data)
- .then(response => this.checkConditions(response))
- .catch(error => errorCallback(error));
+ .then((response) => {
+ this.checkConditions(response);
+ notificationCallback(false);
+ })
+ .catch((error) => {
+ notificationCallback(false);
+ errorCallback(error);
+ });
}
/**
diff --git a/app/assets/javascripts/lib/utils/regexp.js b/app/assets/javascripts/lib/utils/regexp.js
new file mode 100644
index 00000000000..baa0b51d59b
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/regexp.js
@@ -0,0 +1,10 @@
+/**
+ * Regexp utility for the convenience of working with regular expressions.
+ *
+ */
+
+// Inspired by https://github.com/mishoo/UglifyJS/blob/2bc1d02363db3798d5df41fb5059a19edca9b7eb/lib/parse-js.js#L203
+// Unicode 6.1
+const unicodeLetters = '\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0\\u08A2-\\u08AC\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F0\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA697\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7F8-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC';
+
+export default { unicodeLetters };
diff --git a/app/assets/javascripts/lib/utils/simple_poll.js b/app/assets/javascripts/lib/utils/simple_poll.js
new file mode 100644
index 00000000000..25ca98afbe7
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/simple_poll.js
@@ -0,0 +1,15 @@
+export default (fn, interval = 2000, timeout = 60000) => {
+ const startTime = Date.now();
+
+ return new Promise((resolve, reject) => {
+ const stop = arg => ((arg instanceof Error) ? reject(arg) : resolve(arg));
+ const next = () => {
+ if (Date.now() - startTime < timeout) {
+ setTimeout(fn.bind(null, next, stop), interval);
+ } else {
+ reject(new Error('SIMPLE_POLL_TIMEOUT'));
+ }
+ };
+ fn(next, stop);
+ });
+};
diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js
index 2e5f8a09fc1..b43c1c3aac6 100644
--- a/app/assets/javascripts/lib/utils/text_utility.js
+++ b/app/assets/javascripts/lib/utils/text_utility.js
@@ -1,192 +1,189 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, quotes, one-var, one-var-declaration-per-line, operator-assignment, no-else-return, prefer-template, prefer-arrow-callback, no-empty, max-len, consistent-return, no-unused-vars, no-return-assign, max-len */
+/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, quotes, one-var, one-var-declaration-per-line, operator-assignment, no-else-return, prefer-template, prefer-arrow-callback, no-empty, max-len, consistent-return, no-unused-vars, no-return-assign, max-len, vars-on-top */
-require('vendor/latinise');
+import 'vendor/latinise';
-(function() {
- (function(w) {
- var base;
- if (w.gl == null) {
- w.gl = {};
+var base;
+var w = window;
+if (w.gl == null) {
+ w.gl = {};
+}
+if ((base = w.gl).text == null) {
+ base.text = {};
+}
+gl.text.addDelimiter = function(text) {
+ return text ? text.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : text;
+};
+gl.text.highCountTrim = function(count) {
+ return count > 99 ? '99+' : count;
+};
+gl.text.randomString = function() {
+ return Math.random().toString(36).substring(7);
+};
+gl.text.replaceRange = function(s, start, end, substitute) {
+ return s.substring(0, start) + substitute + s.substring(end);
+};
+gl.text.getTextWidth = function(text, font) {
+ /**
+ * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
+ *
+ * @param {String} text The text to be rendered.
+ * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
+ *
+ * @see http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
+ */
+ // re-use canvas object for better performance
+ var canvas = gl.text.getTextWidth.canvas || (gl.text.getTextWidth.canvas = document.createElement('canvas'));
+ var context = canvas.getContext('2d');
+ context.font = font;
+ return context.measureText(text).width;
+};
+gl.text.selectedText = function(text, textarea) {
+ return text.substring(textarea.selectionStart, textarea.selectionEnd);
+};
+gl.text.lineBefore = function(text, textarea) {
+ var split;
+ split = text.substring(0, textarea.selectionStart).trim().split('\n');
+ return split[split.length - 1];
+};
+gl.text.lineAfter = function(text, textarea) {
+ return text.substring(textarea.selectionEnd).trim().split('\n')[0];
+};
+gl.text.blockTagText = function(text, textArea, blockTag, selected) {
+ var lineAfter, lineBefore;
+ lineBefore = this.lineBefore(text, textArea);
+ lineAfter = this.lineAfter(text, textArea);
+ if (lineBefore === blockTag && lineAfter === blockTag) {
+ // To remove the block tag we have to select the line before & after
+ if (blockTag != null) {
+ textArea.selectionStart = textArea.selectionStart - (blockTag.length + 1);
+ textArea.selectionEnd = textArea.selectionEnd + (blockTag.length + 1);
}
- if ((base = w.gl).text == null) {
- base.text = {};
- }
- gl.text.addDelimiter = function(text) {
- return text ? text.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : text;
- };
- gl.text.highCountTrim = function(count) {
- return count > 99 ? '99+' : count;
- };
- gl.text.randomString = function() {
- return Math.random().toString(36).substring(7);
- };
- gl.text.replaceRange = function(s, start, end, substitute) {
- return s.substring(0, start) + substitute + s.substring(end);
- };
- gl.text.getTextWidth = function(text, font) {
- /**
- * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
- *
- * @param {String} text The text to be rendered.
- * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
- *
- * @see http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
- */
- // re-use canvas object for better performance
- var canvas = gl.text.getTextWidth.canvas || (gl.text.getTextWidth.canvas = document.createElement('canvas'));
- var context = canvas.getContext('2d');
- context.font = font;
- return context.measureText(text).width;
- };
- gl.text.selectedText = function(text, textarea) {
- return text.substring(textarea.selectionStart, textarea.selectionEnd);
- };
- gl.text.lineBefore = function(text, textarea) {
- var split;
- split = text.substring(0, textarea.selectionStart).trim().split('\n');
- return split[split.length - 1];
- };
- gl.text.lineAfter = function(text, textarea) {
- return text.substring(textarea.selectionEnd).trim().split('\n')[0];
- };
- gl.text.blockTagText = function(text, textArea, blockTag, selected) {
- var lineAfter, lineBefore;
- lineBefore = this.lineBefore(text, textArea);
- lineAfter = this.lineAfter(text, textArea);
- if (lineBefore === blockTag && lineAfter === blockTag) {
- // To remove the block tag we have to select the line before & after
- if (blockTag != null) {
- textArea.selectionStart = textArea.selectionStart - (blockTag.length + 1);
- textArea.selectionEnd = textArea.selectionEnd + (blockTag.length + 1);
- }
- return selected;
- } else {
- return blockTag + "\n" + selected + "\n" + blockTag;
- }
- };
- gl.text.insertText = function(textArea, text, tag, blockTag, selected, wrap) {
- var insertText, inserted, selectedSplit, startChar, removedLastNewLine, removedFirstNewLine, currentLineEmpty, lastNewLine;
- removedLastNewLine = false;
- removedFirstNewLine = false;
- currentLineEmpty = false;
+ return selected;
+ } else {
+ return blockTag + "\n" + selected + "\n" + blockTag;
+ }
+};
+gl.text.insertText = function(textArea, text, tag, blockTag, selected, wrap) {
+ var insertText, inserted, selectedSplit, startChar, removedLastNewLine, removedFirstNewLine, currentLineEmpty, lastNewLine;
+ removedLastNewLine = false;
+ removedFirstNewLine = false;
+ currentLineEmpty = false;
- // Remove the first newline
- if (selected.indexOf('\n') === 0) {
- removedFirstNewLine = true;
- selected = selected.replace(/\n+/, '');
- }
+ // Remove the first newline
+ if (selected.indexOf('\n') === 0) {
+ removedFirstNewLine = true;
+ selected = selected.replace(/\n+/, '');
+ }
- // Remove the last newline
- if (textArea.selectionEnd - textArea.selectionStart > selected.replace(/\n$/, '').length) {
- removedLastNewLine = true;
- selected = selected.replace(/\n$/, '');
- }
+ // Remove the last newline
+ if (textArea.selectionEnd - textArea.selectionStart > selected.replace(/\n$/, '').length) {
+ removedLastNewLine = true;
+ selected = selected.replace(/\n$/, '');
+ }
- selectedSplit = selected.split('\n');
+ selectedSplit = selected.split('\n');
- if (!wrap) {
- lastNewLine = textArea.value.substr(0, textArea.selectionStart).lastIndexOf('\n');
+ if (!wrap) {
+ lastNewLine = textArea.value.substr(0, textArea.selectionStart).lastIndexOf('\n');
- // Check whether the current line is empty or consists only of spaces(=handle as empty)
- if (/^\s*$/.test(textArea.value.substring(lastNewLine, textArea.selectionStart))) {
- currentLineEmpty = true;
- }
- }
+ // Check whether the current line is empty or consists only of spaces(=handle as empty)
+ if (/^\s*$/.test(textArea.value.substring(lastNewLine, textArea.selectionStart))) {
+ currentLineEmpty = true;
+ }
+ }
- startChar = !wrap && !currentLineEmpty && textArea.selectionStart > 0 ? '\n' : '';
+ startChar = !wrap && !currentLineEmpty && textArea.selectionStart > 0 ? '\n' : '';
- if (selectedSplit.length > 1 && (!wrap || (blockTag != null))) {
- if (blockTag != null) {
- insertText = this.blockTagText(text, textArea, blockTag, selected);
+ if (selectedSplit.length > 1 && (!wrap || (blockTag != null))) {
+ if (blockTag != null) {
+ insertText = this.blockTagText(text, textArea, blockTag, selected);
+ } else {
+ insertText = selectedSplit.map(function(val) {
+ if (val.indexOf(tag) === 0) {
+ return "" + (val.replace(tag, ''));
} else {
- insertText = selectedSplit.map(function(val) {
- if (val.indexOf(tag) === 0) {
- return "" + (val.replace(tag, ''));
- } else {
- return "" + tag + val;
- }
- }).join('\n');
+ return "" + tag + val;
}
- } else {
- insertText = "" + startChar + tag + selected + (wrap ? tag : ' ');
- }
+ }).join('\n');
+ }
+ } else {
+ insertText = "" + startChar + tag + selected + (wrap ? tag : ' ');
+ }
- if (removedFirstNewLine) {
- insertText = '\n' + insertText;
- }
+ if (removedFirstNewLine) {
+ insertText = '\n' + insertText;
+ }
- if (removedLastNewLine) {
- insertText += '\n';
- }
+ if (removedLastNewLine) {
+ insertText += '\n';
+ }
- if (document.queryCommandSupported('insertText')) {
- inserted = document.execCommand('insertText', false, insertText);
- }
- if (!inserted) {
- try {
- document.execCommand("ms-beginUndoUnit");
- } catch (error) {}
- textArea.value = this.replaceRange(text, textArea.selectionStart, textArea.selectionEnd, insertText);
- try {
- document.execCommand("ms-endUndoUnit");
- } catch (error) {}
- }
- return this.moveCursor(textArea, tag, wrap, removedLastNewLine);
- };
- gl.text.moveCursor = function(textArea, tag, wrapped, removedLastNewLine) {
- var pos;
- if (!textArea.setSelectionRange) {
- return;
- }
- if (textArea.selectionStart === textArea.selectionEnd) {
- if (wrapped) {
- pos = textArea.selectionStart - tag.length;
- } else {
- pos = textArea.selectionStart;
- }
+ if (document.queryCommandSupported('insertText')) {
+ inserted = document.execCommand('insertText', false, insertText);
+ }
+ if (!inserted) {
+ try {
+ document.execCommand("ms-beginUndoUnit");
+ } catch (error) {}
+ textArea.value = this.replaceRange(text, textArea.selectionStart, textArea.selectionEnd, insertText);
+ try {
+ document.execCommand("ms-endUndoUnit");
+ } catch (error) {}
+ }
+ return this.moveCursor(textArea, tag, wrap, removedLastNewLine);
+};
+gl.text.moveCursor = function(textArea, tag, wrapped, removedLastNewLine) {
+ var pos;
+ if (!textArea.setSelectionRange) {
+ return;
+ }
+ if (textArea.selectionStart === textArea.selectionEnd) {
+ if (wrapped) {
+ pos = textArea.selectionStart - tag.length;
+ } else {
+ pos = textArea.selectionStart;
+ }
- if (removedLastNewLine) {
- pos -= 1;
- }
+ if (removedLastNewLine) {
+ pos -= 1;
+ }
- return textArea.setSelectionRange(pos, pos);
- }
- };
- gl.text.updateText = function(textArea, tag, blockTag, wrap) {
- var $textArea, selected, text;
- $textArea = $(textArea);
- textArea = $textArea.get(0);
- text = $textArea.val();
- selected = this.selectedText(text, textArea);
- $textArea.focus();
- return this.insertText(textArea, text, tag, blockTag, selected, wrap);
- };
- gl.text.init = function(form) {
- var self;
- self = this;
- return $('.js-md', form).off('click').on('click', function() {
- var $this;
- $this = $(this);
- return self.updateText($this.closest('.md-area').find('textarea'), $this.data('md-tag'), $this.data('md-block'), !$this.data('md-prepend'));
- });
- };
- gl.text.removeListeners = function(form) {
- return $('.js-md', form).off();
- };
- gl.text.humanize = function(string) {
- return string.charAt(0).toUpperCase() + string.replace(/_/g, ' ').slice(1);
- };
- gl.text.pluralize = function(str, count) {
- return str + (count > 1 || count === 0 ? 's' : '');
- };
- gl.text.truncate = function(string, maxLength) {
- return string.substr(0, (maxLength - 3)) + '...';
- };
- gl.text.dasherize = function(str) {
- return str.replace(/[_\s]+/g, '-');
- };
- gl.text.slugify = function(str) {
- return str.trim().toLowerCase().latinise();
- };
- })(window);
-}).call(window);
+ return textArea.setSelectionRange(pos, pos);
+ }
+};
+gl.text.updateText = function(textArea, tag, blockTag, wrap) {
+ var $textArea, selected, text;
+ $textArea = $(textArea);
+ textArea = $textArea.get(0);
+ text = $textArea.val();
+ selected = this.selectedText(text, textArea);
+ $textArea.focus();
+ return this.insertText(textArea, text, tag, blockTag, selected, wrap);
+};
+gl.text.init = function(form) {
+ var self;
+ self = this;
+ return $('.js-md', form).off('click').on('click', function() {
+ var $this;
+ $this = $(this);
+ return self.updateText($this.closest('.md-area').find('textarea'), $this.data('md-tag'), $this.data('md-block'), !$this.data('md-prepend'));
+ });
+};
+gl.text.removeListeners = function(form) {
+ return $('.js-md', form).off();
+};
+gl.text.humanize = function(string) {
+ return string.charAt(0).toUpperCase() + string.replace(/_/g, ' ').slice(1);
+};
+gl.text.pluralize = function(str, count) {
+ return str + (count > 1 || count === 0 ? 's' : '');
+};
+gl.text.truncate = function(string, maxLength) {
+ return string.substr(0, (maxLength - 3)) + '...';
+};
+gl.text.dasherize = function(str) {
+ return str.replace(/[_\s]+/g, '-');
+};
+gl.text.slugify = function(str) {
+ return str.trim().toLowerCase().latinise();
+};
diff --git a/app/assets/javascripts/lib/utils/type_utility.js b/app/assets/javascripts/lib/utils/type_utility.js
index db62e0be324..be86f336bcd 100644
--- a/app/assets/javascripts/lib/utils/type_utility.js
+++ b/app/assets/javascripts/lib/utils/type_utility.js
@@ -1,15 +1,2 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, no-return-assign, max-len */
-(function() {
- (function(w) {
- var base;
- if (w.gl == null) {
- w.gl = {};
- }
- if ((base = w.gl).utils == null) {
- base.utils = {};
- }
- return w.gl.utils.isObject = function(obj) {
- return (obj != null) && (obj.constructor === Object);
- };
- })(window);
-}).call(window);
+// eslint-disable-next-line import/prefer-default-export
+export const isObject = obj => obj && obj.constructor === Object;
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index 09c4261b318..b9d2fc25c39 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -1,93 +1,90 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, one-var, one-var-declaration-per-line, no-void, guard-for-in, no-restricted-syntax, prefer-template, quotes, max-len */
-(function() {
- (function(w) {
- var base;
- if (w.gl == null) {
- w.gl = {};
+var base;
+var w = window;
+if (w.gl == null) {
+ w.gl = {};
+}
+if ((base = w.gl).utils == null) {
+ base.utils = {};
+}
+// Returns an array containing the value(s) of the
+// of the key passed as an argument
+w.gl.utils.getParameterValues = function(sParam) {
+ var i, sPageURL, sParameterName, sURLVariables, values;
+ sPageURL = decodeURIComponent(window.location.search.substring(1));
+ sURLVariables = sPageURL.split('&');
+ sParameterName = void 0;
+ values = [];
+ i = 0;
+ while (i < sURLVariables.length) {
+ sParameterName = sURLVariables[i].split('=');
+ if (sParameterName[0] === sParam) {
+ values.push(sParameterName[1].replace(/\+/g, ' '));
}
- if ((base = w.gl).utils == null) {
- base.utils = {};
+ i += 1;
+ }
+ return values;
+};
+// @param {Object} params - url keys and value to merge
+// @param {String} url
+w.gl.utils.mergeUrlParams = function(params, url) {
+ var lastChar, newUrl, paramName, paramValue, pattern;
+ newUrl = decodeURIComponent(url);
+ for (paramName in params) {
+ paramValue = params[paramName];
+ pattern = new RegExp("\\b(" + paramName + "=).*?(&|$)");
+ if (paramValue == null) {
+ newUrl = newUrl.replace(pattern, '');
+ } else if (url.search(pattern) !== -1) {
+ newUrl = newUrl.replace(pattern, "$1" + paramValue + "$2");
+ } else {
+ newUrl = "" + newUrl + (newUrl.indexOf('?') > 0 ? '&' : '?') + paramName + "=" + paramValue;
}
- // Returns an array containing the value(s) of the
- // of the key passed as an argument
- w.gl.utils.getParameterValues = function(sParam) {
- var i, sPageURL, sParameterName, sURLVariables, values;
- sPageURL = decodeURIComponent(window.location.search.substring(1));
- sURLVariables = sPageURL.split('&');
- sParameterName = void 0;
- values = [];
- i = 0;
- while (i < sURLVariables.length) {
- sParameterName = sURLVariables[i].split('=');
- if (sParameterName[0] === sParam) {
- values.push(sParameterName[1].replace(/\+/g, ' '));
- }
- i += 1;
+ }
+ // Remove a trailing ampersand
+ lastChar = newUrl[newUrl.length - 1];
+ if (lastChar === '&') {
+ newUrl = newUrl.slice(0, -1);
+ }
+ return newUrl;
+};
+// removes parameter query string from url. returns the modified url
+w.gl.utils.removeParamQueryString = function(url, param) {
+ var urlVariables, variables;
+ url = decodeURIComponent(url);
+ urlVariables = url.split('&');
+ return ((function() {
+ var j, len, results;
+ results = [];
+ for (j = 0, len = urlVariables.length; j < len; j += 1) {
+ variables = urlVariables[j];
+ if (variables.indexOf(param) === -1) {
+ results.push(variables);
}
- return values;
- };
- // @param {Object} params - url keys and value to merge
- // @param {String} url
- w.gl.utils.mergeUrlParams = function(params, url) {
- var lastChar, newUrl, paramName, paramValue, pattern;
- newUrl = decodeURIComponent(url);
- for (paramName in params) {
- paramValue = params[paramName];
- pattern = new RegExp("\\b(" + paramName + "=).*?(&|$)");
- if (paramValue == null) {
- newUrl = newUrl.replace(pattern, '');
- } else if (url.search(pattern) !== -1) {
- newUrl = newUrl.replace(pattern, "$1" + paramValue + "$2");
- } else {
- newUrl = "" + newUrl + (newUrl.indexOf('?') > 0 ? '&' : '?') + paramName + "=" + paramValue;
- }
- }
- // Remove a trailing ampersand
- lastChar = newUrl[newUrl.length - 1];
- if (lastChar === '&') {
- newUrl = newUrl.slice(0, -1);
- }
- return newUrl;
- };
- // removes parameter query string from url. returns the modified url
- w.gl.utils.removeParamQueryString = function(url, param) {
- var urlVariables, variables;
- url = decodeURIComponent(url);
- urlVariables = url.split('&');
- return ((function() {
- var j, len, results;
- results = [];
- for (j = 0, len = urlVariables.length; j < len; j += 1) {
- variables = urlVariables[j];
- if (variables.indexOf(param) === -1) {
- results.push(variables);
- }
- }
- return results;
- })()).join('&');
- };
- w.gl.utils.removeParams = (params) => {
- const url = new URL(window.location.href);
- params.forEach((param) => {
- url.search = w.gl.utils.removeParamQueryString(url.search, param);
- });
- return url.href;
- };
- w.gl.utils.getLocationHash = function(url) {
- var hashIndex;
- if (typeof url === 'undefined') {
- // Note: We can't use window.location.hash here because it's
- // not consistent across browsers - Firefox will pre-decode it
- url = window.location.href;
- }
- hashIndex = url.indexOf('#');
- return hashIndex === -1 ? null : url.substring(hashIndex + 1);
- };
+ }
+ return results;
+ })()).join('&');
+};
+w.gl.utils.removeParams = (params) => {
+ const url = new URL(window.location.href);
+ params.forEach((param) => {
+ url.search = w.gl.utils.removeParamQueryString(url.search, param);
+ });
+ return url.href;
+};
+w.gl.utils.getLocationHash = function(url) {
+ var hashIndex;
+ if (typeof url === 'undefined') {
+ // Note: We can't use window.location.hash here because it's
+ // not consistent across browsers - Firefox will pre-decode it
+ url = window.location.href;
+ }
+ hashIndex = url.indexOf('#');
+ return hashIndex === -1 ? null : url.substring(hashIndex + 1);
+};
- w.gl.utils.refreshCurrentPage = () => gl.utils.visitUrl(document.location.href);
+w.gl.utils.refreshCurrentPage = () => gl.utils.visitUrl(document.location.href);
- w.gl.utils.visitUrl = (url) => {
- document.location.href = url;
- };
- })(window);
-}).call(window);
+w.gl.utils.visitUrl = (url) => {
+ document.location.href = url;
+};