diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-08-20 21:42:06 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-08-20 21:42:06 +0300 |
commit | 6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch) | |
tree | 78be5963ec075d80116a932011d695dd33910b4e /app/assets/javascripts/lib/utils | |
parent | 1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff) |
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'app/assets/javascripts/lib/utils')
-rw-r--r-- | app/assets/javascripts/lib/utils/axios_startup_calls.js | 19 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/common_utils.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/datetime_utility.js | 34 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/highlight.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/http_status.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/keys.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/poll.js | 17 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/text_markdown.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/url_utility.js | 41 |
9 files changed, 105 insertions, 23 deletions
diff --git a/app/assets/javascripts/lib/utils/axios_startup_calls.js b/app/assets/javascripts/lib/utils/axios_startup_calls.js index cb2e8a76c08..a047cebc8ab 100644 --- a/app/assets/javascripts/lib/utils/axios_startup_calls.js +++ b/app/assets/javascripts/lib/utils/axios_startup_calls.js @@ -34,14 +34,17 @@ const setupAxiosStartupCalls = axios => { }); // eslint-disable-next-line promise/no-nesting - return res.json().then(data => ({ - data, - status: res.status, - statusText: res.statusText, - headers: fetchHeaders, - config: req, - request: req, - })); + return res + .clone() + .json() + .then(data => ({ + data, + status: res.status, + statusText: res.statusText, + headers: fetchHeaders, + config: req, + request: req, + })); }); } diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index 8bf9a281151..bcf302cc262 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -4,12 +4,12 @@ import { GlBreakpointInstance as breakpointInstance } from '@gitlab/ui/dist/utils'; import $ from 'jquery'; +import { isFunction } from 'lodash'; +import Cookies from 'js-cookie'; import axios from './axios_utils'; import { getLocationHash } from './url_utility'; import { convertToCamelCase, convertToSnakeCase } from './text_utility'; import { isObject } from './type_utility'; -import { isFunction } from 'lodash'; -import Cookies from 'js-cookie'; export const getPagePath = (index = 0) => { const page = $('body').attr('data-page') || ''; diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index 6e02fc1eb91..e26b63fbb85 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -689,3 +689,37 @@ export const approximateDuration = (seconds = 0) => { } return n__('1 day', '%d days', seconds < ONE_DAY_LIMIT ? 1 : days); }; + +/** + * A utility function which helps creating a date object + * for a specific date. Accepts the year, month and day + * returning a date object for the given params. + * + * @param {Int} year the full year as a number i.e. 2020 + * @param {Int} month the month index i.e. January => 0 + * @param {Int} day the day as a number i.e. 23 + * + * @return {Date} the date object from the params + */ +export const dateFromParams = (year, month, day) => { + const date = new Date(); + + date.setFullYear(year); + date.setMonth(month); + date.setDate(day); + + return date; +}; + +/** + * A utility function which computes the difference in seconds + * between 2 dates. + * + * @param {Date} startDate the start sate + * @param {Date} endDate the end date + * + * @return {Int} the difference in seconds + */ +export const differenceInSeconds = (startDate, endDate) => { + return (endDate.getTime() - startDate.getTime()) / 1000; +}; diff --git a/app/assets/javascripts/lib/utils/highlight.js b/app/assets/javascripts/lib/utils/highlight.js index b1dd562f63a..32553af9af3 100644 --- a/app/assets/javascripts/lib/utils/highlight.js +++ b/app/assets/javascripts/lib/utils/highlight.js @@ -1,5 +1,5 @@ import fuzzaldrinPlus from 'fuzzaldrin-plus'; -import sanitize from 'sanitize-html'; +import { sanitize } from 'dompurify'; /** * Wraps substring matches with HTML `<span>` elements. @@ -24,7 +24,7 @@ export default function highlight(string, match = '', matchPrefix = '<b>', match return string; } - const sanitizedValue = sanitize(string.toString(), { allowedTags: [] }); + const sanitizedValue = sanitize(string.toString(), { ALLOWED_TAGS: [] }); // occurrences is an array of character indices that should be // highlighted in the original string, i.e. [3, 4, 5, 7] diff --git a/app/assets/javascripts/lib/utils/http_status.js b/app/assets/javascripts/lib/utils/http_status.js index 08a77966bbd..7132986a7e6 100644 --- a/app/assets/javascripts/lib/utils/http_status.js +++ b/app/assets/javascripts/lib/utils/http_status.js @@ -22,6 +22,7 @@ const httpStatusCodes = { CONFLICT: 409, GONE: 410, UNPROCESSABLE_ENTITY: 422, + INTERNAL_SERVER_ERROR: 500, SERVICE_UNAVAILABLE: 503, }; diff --git a/app/assets/javascripts/lib/utils/keys.js b/app/assets/javascripts/lib/utils/keys.js index 8e5420e87ea..2a8b1759e54 100644 --- a/app/assets/javascripts/lib/utils/keys.js +++ b/app/assets/javascripts/lib/utils/keys.js @@ -1,4 +1,2 @@ -/* eslint-disable @gitlab/require-i18n-strings */ - export const ESC_KEY = 'Escape'; -export const ESC_KEY_IE11 = 'Esc'; // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key +export const ENTER_KEY = 'Enter'; diff --git a/app/assets/javascripts/lib/utils/poll.js b/app/assets/javascripts/lib/utils/poll.js index a900ff34bf5..7f0c65868c2 100644 --- a/app/assets/javascripts/lib/utils/poll.js +++ b/app/assets/javascripts/lib/utils/poll.js @@ -46,6 +46,19 @@ import { normalizeHeaders } from './common_utils'; * 4. If HTTP response is 200, we poll. * 5. If HTTP response is different from 200, we stop polling. * + * @example + * // With initial delay (for, for example, reducing unnecessary requests) + * + * const poll = new Poll({ + * resource: this.service, + * method: 'fetchNotes', + * successCallback: () => {}, + * errorCallback: () => {}, + * }); + * + * // Performs the first request in 2.5s and then uses the `Poll-Interval` header. + * poll.makeDelayedRequest(2500); + * */ export default class Poll { constructor(options = {}) { @@ -74,6 +87,10 @@ export default class Poll { this.options.successCallback(response); } + makeDelayedRequest(delay = 0) { + this.timeoutID = setTimeout(() => this.makeRequest(), delay); + } + makeRequest() { const { resource, method, data, errorCallback, notificationCallback } = this.options; diff --git a/app/assets/javascripts/lib/utils/text_markdown.js b/app/assets/javascripts/lib/utils/text_markdown.js index 4d25ee9e4bd..8d23d177410 100644 --- a/app/assets/javascripts/lib/utils/text_markdown.js +++ b/app/assets/javascripts/lib/utils/text_markdown.js @@ -308,9 +308,11 @@ export function addMarkdownListeners(form) { .off('click') .on('click', function() { const $this = $(this); + const tag = this.dataset.mdTag; + return updateText({ textArea: $this.closest('.md-area').find('textarea'), - tag: $this.data('mdTag'), + tag, cursorOffset: $this.data('mdCursorOffset'), blockTag: $this.data('mdBlock'), wrap: !$this.data('mdPrepend'), diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index c6c34b831ee..8077570158a 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -71,29 +71,56 @@ export function getParameterValues(sParam, url = window.location) { * * @param {Object} params - url keys and value to merge * @param {String} url + * @param {Object} options + * @param {Boolean} options.spreadArrays - split array values into separate key/value-pairs */ -export function mergeUrlParams(params, url) { +export function mergeUrlParams(params, url, options = {}) { + const { spreadArrays = false } = options; const re = /^([^?#]*)(\?[^#]*)?(.*)/; - const merged = {}; + let merged = {}; const [, fullpath, query, fragment] = url.match(re); if (query) { - query + merged = query .substr(1) .split('&') - .forEach(part => { + .reduce((memo, part) => { if (part.length) { const kv = part.split('='); - merged[decodeUrlParameter(kv[0])] = decodeUrlParameter(kv.slice(1).join('=')); + let key = decodeUrlParameter(kv[0]); + const value = decodeUrlParameter(kv.slice(1).join('=')); + if (spreadArrays && key.endsWith('[]')) { + key = key.slice(0, -2); + if (!Array.isArray(memo[key])) { + return { ...memo, [key]: [value] }; + } + memo[key].push(value); + + return memo; + } + + return { ...memo, [key]: value }; } - }); + + return memo; + }, {}); } Object.assign(merged, params); const newQuery = Object.keys(merged) .filter(key => merged[key] !== null) - .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(merged[key])}`) + .map(key => { + let value = merged[key]; + const encodedKey = encodeURIComponent(key); + if (spreadArrays && Array.isArray(value)) { + value = merged[key] + .map(arrayValue => encodeURIComponent(arrayValue)) + .join(`&${encodedKey}[]=`); + return `${encodedKey}[]=${value}`; + } + return `${encodedKey}=${encodeURIComponent(value)}`; + }) .join('&'); if (newQuery) { |