diff options
Diffstat (limited to 'app/assets/javascripts/lib')
-rw-r--r-- | app/assets/javascripts/lib/graphql.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/datetime_utility.js | 13 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/downloader.js | 20 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/keycodes.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/keys.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/text_markdown.js | 7 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/url_utility.js | 66 |
7 files changed, 100 insertions, 14 deletions
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js index 8d3b87d5cc0..b6c41ffa7ab 100644 --- a/app/assets/javascripts/lib/graphql.js +++ b/app/assets/javascripts/lib/graphql.js @@ -33,6 +33,7 @@ export default (resolvers = {}, config = {}) => { }; return new ApolloClient({ + typeDefs: config.typeDefs, link: ApolloLink.split( operation => operation.getContext().hasUpload || operation.getContext().isSingleRequest, createUploadLink(httpOptions), diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index f6077673ad5..6b69d2febe0 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -57,6 +57,19 @@ export const getMonthNames = abbreviated => { export const pad = (val, len = 2) => `0${val}`.slice(-len); /** + * Returns i18n weekday names array. + */ +export const getWeekdayNames = () => [ + __('Sunday'), + __('Monday'), + __('Tuesday'), + __('Wednesday'), + __('Thursday'), + __('Friday'), + __('Saturday'), +]; + +/** * Given a date object returns the day of the week in English * @param {date} date * @returns {String} diff --git a/app/assets/javascripts/lib/utils/downloader.js b/app/assets/javascripts/lib/utils/downloader.js new file mode 100644 index 00000000000..2297f5f90ce --- /dev/null +++ b/app/assets/javascripts/lib/utils/downloader.js @@ -0,0 +1,20 @@ +/** + * Helper function to trigger a download. + * + * - If the `fileName` is `_blank` it will open the file in a new tab. + * - If `fileData` is provided, it will inline the content and use data URLs to + * download the file. In this case the `url` property will be ignored. Please + * note that `fileData` needs to be Base64 encoded. + */ +export default ({ fileName, url, fileData }) => { + let href = url; + + if (fileData) { + href = `data:text/plain;base64,${fileData}`; + } + + const anchor = document.createElement('a'); + anchor.download = fileName; + anchor.href = href; + anchor.click(); +}; diff --git a/app/assets/javascripts/lib/utils/keycodes.js b/app/assets/javascripts/lib/utils/keycodes.js index 16bffc5c2cf..618266f7a09 100644 --- a/app/assets/javascripts/lib/utils/keycodes.js +++ b/app/assets/javascripts/lib/utils/keycodes.js @@ -1,3 +1,6 @@ +// `e.keyCode` is deprecated, these values should be migrated +// See: https://gitlab.com/gitlab-org/gitlab/-/issues/216102 + export const BACKSPACE_KEY_CODE = 8; export const ENTER_KEY_CODE = 13; export const ESC_KEY_CODE = 27; diff --git a/app/assets/javascripts/lib/utils/keys.js b/app/assets/javascripts/lib/utils/keys.js new file mode 100644 index 00000000000..8e5420e87ea --- /dev/null +++ b/app/assets/javascripts/lib/utils/keys.js @@ -0,0 +1,4 @@ +/* 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 diff --git a/app/assets/javascripts/lib/utils/text_markdown.js b/app/assets/javascripts/lib/utils/text_markdown.js index cccf9ad311c..0dfc144c363 100644 --- a/app/assets/javascripts/lib/utils/text_markdown.js +++ b/app/assets/javascripts/lib/utils/text_markdown.js @@ -1,4 +1,4 @@ -/* eslint-disable func-names, no-param-reassign, operator-assignment, no-else-return, consistent-return */ +/* eslint-disable func-names, no-param-reassign, operator-assignment, consistent-return */ import $ from 'jquery'; import { insertText } from '~/lib/utils/common_utils'; @@ -217,16 +217,15 @@ export function insertMarkdownText({ } if (val.indexOf(tag) === 0) { return String(val.replace(tag, '')); - } else { - return String(tag) + val; } + return String(tag) + val; }) .join('\n'); } } else if (tag.indexOf(textPlaceholder) > -1) { textToInsert = tag.replace(textPlaceholder, selected); } else { - textToInsert = String(startChar) + tag + selected + (wrap ? tag : ' '); + textToInsert = String(startChar) + tag + selected + (wrap ? tag : ''); } if (removedFirstNewLine) { diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index a495d2040d3..966e6d42b80 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -63,15 +63,22 @@ export function getParameterValues(sParam, url = window.location) { }, []); } -// @param {Object} params - url keys and value to merge -// @param {String} url +/** + * Merges a URL to a set of params replacing value for + * those already present. + * + * Also removes `null` param values from the resulting URL. + * + * @param {Object} params - url keys and value to merge + * @param {String} url + */ export function mergeUrlParams(params, url) { const re = /^([^?#]*)(\?[^#]*)?(.*)/; const merged = {}; - const urlparts = url.match(re); + const [, fullpath, query, fragment] = url.match(re); - if (urlparts[2]) { - urlparts[2] + if (query) { + query .substr(1) .split('&') .forEach(part => { @@ -84,11 +91,15 @@ export function mergeUrlParams(params, url) { Object.assign(merged, params); - const query = Object.keys(merged) + const newQuery = Object.keys(merged) + .filter(key => merged[key] !== null) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(merged[key])}`) .join('&'); - return `${urlparts[1]}?${query}${urlparts[3]}`; + if (newQuery) { + return `${fullpath}?${newQuery}${fragment}`; + } + return `${fullpath}${fragment}`; } /** @@ -213,12 +224,45 @@ export function getBaseURL() { } /** + * Returns true if url is an absolute URL + * + * @param {String} url + */ +export function isAbsolute(url) { + return /^https?:\/\//.test(url); +} + +/** + * Returns true if url is a root-relative URL + * + * @param {String} url + */ +export function isRootRelative(url) { + return /^\//.test(url); +} + +/** * Returns true if url is an absolute or root-relative URL * * @param {String} url */ export function isAbsoluteOrRootRelative(url) { - return /^(https?:)?\//.test(url); + return isAbsolute(url) || isRootRelative(url); +} + +/** + * Converts a relative path to an absolute or a root relative path depending + * on what is passed as a basePath. + * + * @param {String} path Relative path, eg. ../img/img.png + * @param {String} basePath Absolute or root relative path, eg. /user/project or + * https://gitlab.com/user/project + */ +export function relativePathToAbsolute(path, basePath) { + const absolute = isAbsolute(basePath); + const base = absolute ? basePath : `file:///${basePath}`; + const url = new URL(path, base); + return absolute ? url.href : decodeURIComponent(url.pathname); } /** @@ -259,8 +303,10 @@ export function getWebSocketUrl(path) { export function queryToObject(query) { const removeQuestionMarkFromQuery = String(query).startsWith('?') ? query.slice(1) : query; return removeQuestionMarkFromQuery.split('&').reduce((accumulator, curr) => { - const p = curr.split('='); - accumulator[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); + const [key, value] = curr.split('='); + if (value !== undefined) { + accumulator[decodeURIComponent(key)] = decodeURIComponent(value); + } return accumulator; }, {}); } |