Commit 96e6fc70 authored by Filipa Lacerda's avatar Filipa Lacerda

Import modules instead of using the ones in global namespace

Removes set favicon related methods from global scope
Improves test related with favicon

Removes convertPermissionToBoolean from global scope.
Adds tests for convertPermissionToBoolean - were non existant

Removes setParamInURL from gl.utils

Removes parseIntPagination from gl.utils namespace

Remove normalizeCRLFHeaders from gl.utils namespace

Removes normalizeHeaders from gl.utils namespace

Use gl.utils for filtered search

Fix bad import

Fix broken test by cleaning window.history namespace

Adds changelog
parent 6a1b84c7
/* global Flash */ /* global Flash */
import { handleLocationHash } from '../../lib/utils/common_utils';
export default class BlobViewer { export default class BlobViewer {
constructor() { constructor() {
BlobViewer.initAuxiliaryViewer(); BlobViewer.initAuxiliaryViewer();
...@@ -114,7 +116,7 @@ export default class BlobViewer { ...@@ -114,7 +116,7 @@ export default class BlobViewer {
$(viewer).renderGFM(); $(viewer).renderGFM();
this.$fileHolder.trigger('highlight:line'); this.$fileHolder.trigger('highlight:line');
gl.utils.handleLocationHash(); handleLocationHash();
this.toggleCopyButtonState(); this.toggleCopyButtonState();
}) })
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* global List */ /* global List */
import _ from 'underscore'; import _ from 'underscore';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { getUrlParamsArray } from '../../lib/utils/common_utils';
window.gl = window.gl || {}; window.gl = window.gl || {};
window.gl.issueBoards = window.gl.issueBoards || {}; window.gl.issueBoards = window.gl.issueBoards || {};
...@@ -21,7 +22,7 @@ gl.issueBoards.BoardsStore = { ...@@ -21,7 +22,7 @@ gl.issueBoards.BoardsStore = {
}, },
create () { create () {
this.state.lists = []; this.state.lists = [];
this.filter.path = gl.utils.getUrlParamsArray().join('&'); this.filter.path = getUrlParamsArray().join('&');
this.detail = { issue: {} }; this.detail = { issue: {} };
}, },
addList (listObj, defaultAvatar) { addList (listObj, defaultAvatar) {
......
...@@ -3,6 +3,7 @@ consistent-return, prefer-rest-params */ ...@@ -3,6 +3,7 @@ consistent-return, prefer-rest-params */
import _ from 'underscore'; import _ from 'underscore';
import bp from './breakpoints'; import bp from './breakpoints';
import { bytesToKiB } from './lib/utils/number_utils'; import { bytesToKiB } from './lib/utils/number_utils';
import { setCiStatusFavicon } from './lib/utils/common_utils';
window.Build = (function () { window.Build = (function () {
Build.timeout = null; Build.timeout = null;
...@@ -169,7 +170,7 @@ window.Build = (function () { ...@@ -169,7 +170,7 @@ window.Build = (function () {
data: this.state, data: this.state,
}) })
.done((log) => { .done((log) => {
gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`); setCiStatusFavicon(`${this.pageUrl}/status.json`);
if (log.state) { if (log.state) {
this.state = log.state; this.state = log.state;
......
/* eslint-disable class-methods-use-this, object-shorthand, no-unused-vars, no-use-before-define, no-new, max-len, no-restricted-syntax, guard-for-in, no-continue */ /* eslint-disable class-methods-use-this, object-shorthand, no-unused-vars, no-use-before-define, no-new, max-len, no-restricted-syntax, guard-for-in, no-continue */
import _ from 'underscore'; import _ from 'underscore';
import './lib/utils/common_utils'; import { insertText, getSelectedFragment, nodeMatchesSelector } from './lib/utils/common_utils';
import { placeholderImage } from './lazy_loader'; import { placeholderImage } from './lazy_loader';
const gfmRules = { const gfmRules = {
...@@ -295,7 +295,7 @@ class CopyAsGFM { ...@@ -295,7 +295,7 @@ class CopyAsGFM {
const clipboardData = e.originalEvent.clipboardData; const clipboardData = e.originalEvent.clipboardData;
if (!clipboardData) return; if (!clipboardData) return;
const documentFragment = window.gl.utils.getSelectedFragment(); const documentFragment = getSelectedFragment();
if (!documentFragment) return; if (!documentFragment) return;
const el = transformer(documentFragment.cloneNode(true)); const el = transformer(documentFragment.cloneNode(true));
...@@ -412,7 +412,7 @@ class CopyAsGFM { ...@@ -412,7 +412,7 @@ class CopyAsGFM {
for (const selector in rules) { for (const selector in rules) {
const func = rules[selector]; const func = rules[selector];
if (!window.gl.utils.nodeMatchesSelector(node, selector)) continue; if (!nodeMatchesSelector(node, selector)) continue;
let result; let result;
if (func.length === 2) { if (func.length === 2) {
......
...@@ -77,7 +77,7 @@ import initProjectVisibilitySelector from './project_visibility'; ...@@ -77,7 +77,7 @@ import initProjectVisibilitySelector from './project_visibility';
import GpgBadges from './gpg_badges'; import GpgBadges from './gpg_badges';
import UserFeatureHelper from './helpers/user_feature_helper'; import UserFeatureHelper from './helpers/user_feature_helper';
import initChangesDropdown from './init_changes_dropdown'; import initChangesDropdown from './init_changes_dropdown';
import { ajaxGet } from './lib/utils/common_utils'; import { ajaxGet, convertPermissionToBoolean } from './lib/utils/common_utils';
(function() { (function() {
var Dispatcher; var Dispatcher;
...@@ -101,7 +101,7 @@ import { ajaxGet } from './lib/utils/common_utils'; ...@@ -101,7 +101,7 @@ import { ajaxGet } from './lib/utils/common_utils';
$('.js-gfm-input:not(.js-vue-textarea)').each((i, el) => { $('.js-gfm-input:not(.js-vue-textarea)').each((i, el) => {
const gfm = new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources); const gfm = new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources);
const enableGFM = gl.utils.convertPermissionToBoolean(el.dataset.supportsAutocomplete); const enableGFM = convertPermissionToBoolean(el.dataset.supportsAutocomplete);
gfm.setup($(el), { gfm.setup($(el), {
emojis: true, emojis: true,
members: enableGFM, members: enableGFM,
......
...@@ -6,7 +6,7 @@ import environmentTable from './environments_table.vue'; ...@@ -6,7 +6,7 @@ import environmentTable from './environments_table.vue';
import EnvironmentsStore from '../stores/environments_store'; import EnvironmentsStore from '../stores/environments_store';
import loadingIcon from '../../vue_shared/components/loading_icon.vue'; import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import tablePagination from '../../vue_shared/components/table_pagination.vue'; import tablePagination from '../../vue_shared/components/table_pagination.vue';
import '../../lib/utils/common_utils'; import { convertPermissionToBoolean, getParameterByName, setParamInURL } from '../../lib/utils/common_utils';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import Poll from '../../lib/utils/poll'; import Poll from '../../lib/utils/poll';
import environmentsMixin from '../mixins/environments_mixin'; import environmentsMixin from '../mixins/environments_mixin';
...@@ -51,19 +51,19 @@ export default { ...@@ -51,19 +51,19 @@ export default {
computed: { computed: {
scope() { scope() {
return gl.utils.getParameterByName('scope'); return getParameterByName('scope');
}, },
canReadEnvironmentParsed() { canReadEnvironmentParsed() {
return gl.utils.convertPermissionToBoolean(this.canReadEnvironment); return convertPermissionToBoolean(this.canReadEnvironment);
}, },
canCreateDeploymentParsed() { canCreateDeploymentParsed() {
return gl.utils.convertPermissionToBoolean(this.canCreateDeployment); return convertPermissionToBoolean(this.canCreateDeployment);
}, },
canCreateEnvironmentParsed() { canCreateEnvironmentParsed() {
return gl.utils.convertPermissionToBoolean(this.canCreateEnvironment); return convertPermissionToBoolean(this.canCreateEnvironment);
}, },
}, },
...@@ -72,8 +72,8 @@ export default { ...@@ -72,8 +72,8 @@ export default {
* Toggles loading property. * Toggles loading property.
*/ */
created() { created() {
const scope = gl.utils.getParameterByName('scope') || this.visibility; const scope = getParameterByName('scope') || this.visibility;
const page = gl.utils.getParameterByName('page') || this.pageNumber; const page = getParameterByName('page') || this.pageNumber;
this.service = new EnvironmentsService(this.endpoint); this.service = new EnvironmentsService(this.endpoint);
...@@ -126,15 +126,15 @@ export default { ...@@ -126,15 +126,15 @@ export default {
* @return {String} * @return {String}
*/ */
changePage(pageNumber) { changePage(pageNumber) {
const param = gl.utils.setParamInURL('page', pageNumber); const param = setParamInURL('page', pageNumber);
gl.utils.visitUrl(param); gl.utils.visitUrl(param);
return param; return param;
}, },
fetchEnvironments() { fetchEnvironments() {
const scope = gl.utils.getParameterByName('scope') || this.visibility; const scope = getParameterByName('scope') || this.visibility;
const page = gl.utils.getParameterByName('page') || this.pageNumber; const page = getParameterByName('page') || this.pageNumber;
this.isLoading = true; this.isLoading = true;
......
...@@ -9,7 +9,7 @@ import tablePagination from '../../vue_shared/components/table_pagination.vue'; ...@@ -9,7 +9,7 @@ import tablePagination from '../../vue_shared/components/table_pagination.vue';
import Poll from '../../lib/utils/poll'; import Poll from '../../lib/utils/poll';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import environmentsMixin from '../mixins/environments_mixin'; import environmentsMixin from '../mixins/environments_mixin';
import '../../lib/utils/common_utils'; import { convertPermissionToBoolean, getParameterByName, setParamInURL } from '../../lib/utils/common_utils';
export default { export default {
components: { components: {
...@@ -47,15 +47,15 @@ export default { ...@@ -47,15 +47,15 @@ export default {
computed: { computed: {
scope() { scope() {
return gl.utils.getParameterByName('scope'); return getParameterByName('scope');
}, },
canReadEnvironmentParsed() { canReadEnvironmentParsed() {
return gl.utils.convertPermissionToBoolean(this.canReadEnvironment); return convertPermissionToBoolean(this.canReadEnvironment);
}, },
canCreateDeploymentParsed() { canCreateDeploymentParsed() {
return gl.utils.convertPermissionToBoolean(this.canCreateDeployment); return convertPermissionToBoolean(this.canCreateDeployment);
}, },
/** /**
...@@ -82,8 +82,8 @@ export default { ...@@ -82,8 +82,8 @@ export default {
* Toggles loading property. * Toggles loading property.
*/ */
created() { created() {
const scope = gl.utils.getParameterByName('scope') || this.visibility; const scope = getParameterByName('scope') || this.visibility;
const page = gl.utils.getParameterByName('page') || this.pageNumber; const page = getParameterByName('page') || this.pageNumber;
this.service = new EnvironmentsService(this.endpoint); this.service = new EnvironmentsService(this.endpoint);
...@@ -125,15 +125,15 @@ export default { ...@@ -125,15 +125,15 @@ export default {
* @param {Number} pageNumber desired page to go to. * @param {Number} pageNumber desired page to go to.
*/ */
changePage(pageNumber) { changePage(pageNumber) {
const param = gl.utils.setParamInURL('page', pageNumber); const param = setParamInURL('page', pageNumber);
gl.utils.visitUrl(param); gl.utils.visitUrl(param);
return param; return param;
}, },
fetchEnvironments() { fetchEnvironments() {
const scope = gl.utils.getParameterByName('scope') || this.visibility; const scope = getParameterByName('scope') || this.visibility;
const page = gl.utils.getParameterByName('page') || this.pageNumber; const page = getParameterByName('page') || this.pageNumber;
this.isLoading = true; this.isLoading = true;
......
import '~/lib/utils/common_utils'; import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
/** /**
* Environments Store. * Environments Store.
* *
...@@ -66,8 +66,8 @@ export default class EnvironmentsStore { ...@@ -66,8 +66,8 @@ export default class EnvironmentsStore {
} }
setPagination(pagination = {}) { setPagination(pagination = {}) {
const normalizedHeaders = gl.utils.normalizeHeaders(pagination); const normalizedHeaders = normalizeHeaders(pagination);
const paginationInformation = gl.utils.parseIntPagination(normalizedHeaders); const paginationInformation = parseIntPagination(normalizedHeaders);
this.state.paginationInformation = paginationInformation; this.state.paginationInformation = paginationInformation;
return paginationInformation; return paginationInformation;
......
<script> <script>
import tablePagination from '~/vue_shared/components/table_pagination.vue'; import tablePagination from '~/vue_shared/components/table_pagination.vue';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import { getParameterByName } from '../../lib/utils/common_utils';
export default { export default {
props: { props: {
...@@ -18,8 +19,8 @@ export default { ...@@ -18,8 +19,8 @@ export default {
}, },
methods: { methods: {
change(page) { change(page) {
const filterGroupsParam = gl.utils.getParameterByName('filter_groups'); const filterGroupsParam = getParameterByName('filter_groups');
const sortParam = gl.utils.getParameterByName('sort'); const sortParam = getParameterByName('sort');
eventHub.$emit('fetchPage', page, filterGroupsParam, sortParam); eventHub.$emit('fetchPage', page, filterGroupsParam, sortParam);
}, },
}, },
......
import FilterableList from '~/filterable_list'; import FilterableList from '~/filterable_list';
import eventHub from './event_hub'; import eventHub from './event_hub';
import { getParameterByName } from '../lib/utils/common_utils';
export default class GroupFilterableList extends FilterableList { export default class GroupFilterableList extends FilterableList {
constructor({ form, filter, holder, filterEndpoint, pagePath }) { constructor({ form, filter, holder, filterEndpoint, pagePath }) {
...@@ -54,7 +55,7 @@ export default class GroupFilterableList extends FilterableList { ...@@ -54,7 +55,7 @@ export default class GroupFilterableList extends FilterableList {
e.preventDefault(); e.preventDefault();
const queryData = {}; const queryData = {};
const sortParam = gl.utils.getParameterByName('sort', e.currentTarget.href); const sortParam = getParameterByName('sort', e.currentTarget.href);
if (sortParam) { if (sortParam) {
queryData.sort = sortParam; queryData.sort = sortParam;
......
...@@ -8,6 +8,7 @@ import GroupItem from './components/group_item.vue'; ...@@ -8,6 +8,7 @@ import GroupItem from './components/group_item.vue';
import GroupsStore from './stores/groups_store'; import GroupsStore from './stores/groups_store';
import GroupsService from './services/groups_service'; import GroupsService from './services/groups_service';
import eventHub from './event_hub'; import eventHub from './event_hub';
import { getParameterByName } from '../lib/utils/common_utils';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('dashboard-group-app'); const el = document.getElementById('dashboard-group-app');
...@@ -58,17 +59,17 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -58,17 +59,17 @@ document.addEventListener('DOMContentLoaded', () => {
this.isLoading = true; this.isLoading = true;
} }
pageParam = gl.utils.getParameterByName('page'); pageParam = getParameterByName('page');
if (pageParam) { if (pageParam) {
page = pageParam; page = pageParam;
} }
filterGroupsParam = gl.utils.getParameterByName('filter_groups'); filterGroupsParam = getParameterByName('filter_groups');
if (filterGroupsParam) { if (filterGroupsParam) {
filterGroups = filterGroupsParam; filterGroups = filterGroupsParam;
} }
sortParam = gl.utils.getParameterByName('sort'); sortParam = getParameterByName('sort');
if (sortParam) { if (sortParam) {
sort = sortParam; sort = sortParam;
} }
......
import Vue from 'vue'; import Vue from 'vue';
import { parseIntPagination, normalizeHeaders } from '../../lib/utils/common_utils';
export default class GroupsStore { export default class GroupsStore {
constructor() { constructor() {
...@@ -30,8 +31,8 @@ export default class GroupsStore { ...@@ -30,8 +31,8 @@ export default class GroupsStore {
let paginationInfo; let paginationInfo;
if (Object.keys(pagination).length) { if (Object.keys(pagination).length) {
const normalizedHeaders = gl.utils.normalizeHeaders(pagination); const normalizedHeaders = normalizeHeaders(pagination);
paginationInfo = gl.utils.parseIntPagination(normalizedHeaders); paginationInfo = parseIntPagination(normalizedHeaders);
} else { } else {
paginationInfo = pagination; paginationInfo = pagination;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
prefer-rest-params, prefer-spread, no-unused-vars, prefer-template, prefer-rest-params, prefer-spread, no-unused-vars, prefer-template,
promise/catch-or-return */ promise/catch-or-return */
import Api from './api'; import Api from './api';
import { normalizeCRLFHeaders } from './lib/utils/common_utils';
var slice = [].slice; var slice = [].slice;
...@@ -30,7 +31,7 @@ window.GroupsSelect = (function() { ...@@ -30,7 +31,7 @@ window.GroupsSelect = (function() {
$.ajax(params).then((data, status, xhr) => { $.ajax(params).then((data, status, xhr) => {
const results = data || []; const results = data || [];
const headers = gl.utils.normalizeCRLFHeaders(xhr.getAllResponseHeaders()); const headers = normalizeCRLFHeaders(xhr.getAllResponseHeaders());
const currentPage = parseInt(headers['X-PAGE'], 10) || 0; const currentPage = parseInt(headers['X-PAGE'], 10) || 0;
const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0; const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0;
const more = currentPage < totalPages; const more = currentPage < totalPages;
......
/* eslint-disable no-param-reassing */ window.gl = window.gl || {};
window.gl.utils = window.gl.utils || {};
export const getPagePath = (index = 0) => $('body').data('page').split(':')[index]; export const getPagePath = (index = 0) => $('body').data('page').split(':')[index];
window.gl.utils.getPagePath = getPagePath; window.gl.utils.getPagePath = getPagePath;
...@@ -48,7 +49,7 @@ export const ajaxPost = (url, data) => $.ajax({ ...@@ -48,7 +49,7 @@ export const ajaxPost = (url, data) => $.ajax({
window.gl.utils.ajaxPost = ajaxPost; window.gl.utils.ajaxPost = ajaxPost;
// TODO: This function seems not to be used anywhere // TODO: This function seems not to be used anywhere
window.gl.utils.extractLast = term => this.split(term).pop(); // window.gl.utils.extractLast = term => this.split(term).pop();
export const rstrip = function rstrip(val) { export const rstrip = function rstrip(val) {
if (val) { if (val) {
...@@ -145,10 +146,11 @@ window.gl.utils.parseUrlPathname = parseUrlPathname; ...@@ -145,10 +146,11 @@ window.gl.utils.parseUrlPathname = parseUrlPathname;
// We can trust that each param has one & since values containing & will be encoded // We can trust that each param has one & since values containing & will be encoded
// Remove the first character of search as it is always ? // Remove the first character of search as it is always ?
window.gl.utils.getUrlParamsArray = () => window.location.search.slice(1).split('&').map((param) => { export const getUrlParamsArray = () => window.location.search.slice(1).split('&').map((param) => {
const split = param.split('='); const split = param.split('=');
return [decodeURI(split[0]), split[1]].join('='); return [decodeURI(split[0]), split[1]].join('=');
}); });
window.gl.utils.getUrlParamsArray = getUrlParamsArray;
export const isMetaKey = e => e.metaKey || e.ctrlKey || e.altKey || e.shiftKey; export const isMetaKey = e => e.metaKey || e.ctrlKey || e.altKey || e.shiftKey;
window.gl.utils.isMetaKey = isMetaKey; window.gl.utils.isMetaKey = isMetaKey;
...@@ -178,8 +180,8 @@ window.gl.utils.scrollToElement = scrollToElement; ...@@ -178,8 +180,8 @@ window.gl.utils.scrollToElement = scrollToElement;
*/ */
export const getParameterByName = (name, urlToParse) => { export const getParameterByName = (name, urlToParse) => {
const url = urlToParse || window.location.href; const url = urlToParse || window.location.href;
name = name.replace(/[[\]]/g, '\\$&'); const parsedName = name.replace(/[[\]]/g, '\\$&');
const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`); const regex = new RegExp(`[?&]${parsedName}(=([^&#]*)|&|#|$)`);
const results = regex.exec(url); const results = regex.exec(url);
if (!results) return null; if (!results) return null;
if (!results[2]) return ''; if (!results[2]) return '';
...@@ -200,6 +202,7 @@ export const getSelectedFragment = () => { ...@@ -200,6 +202,7 @@ export const getSelectedFragment = () => {
}; };
window.gl.utils.getSelectedFragment = getSelectedFragment; window.gl.utils.getSelectedFragment = getSelectedFragment;
// TODO: Update this name, there is a gl.text.insertText function.
export const insertText = (target, text) => { export const insertText = (target, text) => {
// Firefox doesn't support `document.execCommand('insertText', false, text)` on textareas // Firefox doesn't support `document.execCommand('insertText', false, text)` on textareas
const selectionStart = target.selectionStart; const selectionStart = target.selectionStart;
...@@ -212,7 +215,9 @@ export const insertText = (target, text) => { ...@@ -212,7 +215,9 @@ export const insertText = (target, text) => {
const insertedText = text instanceof Function ? text(textBefore, textAfter) : text; const insertedText = text instanceof Function ? text(textBefore, textAfter) : text;
const newText = textBefore + insertedText + textAfter; const newText = textBefore + insertedText + textAfter;
// eslint-disable-next-line no-param-reassign
target.value = newText; target.value = newText;
// eslint-disable-next-line no-param-reassign
target.selectionStart = target.selectionEnd = selectionStart + insertedText.length; target.selectionStart = target.selectionEnd = selectionStart + insertedText.length;
// Trigger autosave // Trigger autosave
...@@ -242,6 +247,7 @@ export const nodeMatchesSelector = (node, selector) => { ...@@ -242,6 +247,7 @@ export const nodeMatchesSelector = (node, selector) => {
let parentNode = node.parentNode; let parentNode = node.parentNode;
if (!parentNode) { if (!parentNode) {
parentNode = document.createElement('div'); parentNode = document.createElement('div');
// eslint-disable-next-line no-param-reassign
node = node.cloneNode(true); node = node.cloneNode(true);
parentNode.appendChild(node); parentNode.appendChild(node);
} }
...@@ -264,7 +270,6 @@ export const normalizeHeaders = (headers) => { ...@@ -264,7 +270,6 @@ export const normalizeHeaders = (headers) => {
return upperCaseHeaders; return upperCaseHeaders;
}; };
window.gl.utils.normalizeHeaders = normalizeHeaders;
/** /**
this will take in the getAllResponseHeaders result and normalize them this will take in the getAllResponseHeaders result and normalize them
...@@ -281,7 +286,6 @@ export const normalizeCRLFHeaders = (headers) => { ...@@ -281,7 +286,6 @@ export const normalizeCRLFHeaders = (headers) => {
return normalizeHeaders(headersObject); return normalizeHeaders(headersObject);
}; };
window.gl.utils.normalizeCRLFHeaders = normalizeCRLFHeaders;
/** /**
* Parses pagination object string values into numbers. * Parses pagination object string values into numbers.
...@@ -297,7 +301,6 @@ export const parseIntPagination = paginationInformation => ({ ...@@ -297,7 +301,6 @@ export const parseIntPagination = paginationInformation => ({
nextPage: parseInt(paginationInformation['X-NEXT-PAGE'], 10), nextPage: parseInt(paginationInformation['X-NEXT-PAGE'], 10),
previousPage: parseInt(paginationInformation['X-PREV-PAGE'], 10), previousPage: parseInt(paginationInformation['X-PREV-PAGE'], 10),
}); });
window.gl.utils.parseIntPagination = parseIntPagination;
/** /**
* Updates the search parameter of a URL given the parameter and value provided. * Updates the search parameter of a URL given the parameter and value provided.
...@@ -320,6 +323,7 @@ export const setParamInURL = (param, value) => { ...@@ -320,6 +323,7 @@ export const setParamInURL = (param, value) => {
.split('&') .split('&')
.reduce((acc, element) => { .reduce((acc, element) => {
const val = element.split('='); const val = element.split('=');
// eslint-disable-next-line no-param-reassign
acc[val[0]] = decodeURIComponent(val[1]); acc[val[0]] = decodeURIComponent(val[1]);
return acc; return acc;
}, {}); }, {});
...@@ -337,7 +341,6 @@ export const setParamInURL = (param, value) => { ...@@ -337,7 +341,6 @@ export const setParamInURL = (param, value) => {
return search; return search;
}; };
window.gl.utils.setParamInURL = setParamInURL;
/** /**
* Converts permission provided as strings to booleans. * Converts permission provided as strings to booleans.
...@@ -346,7 +349,6 @@ window.gl.utils.setParamInURL = setParamInURL; ...@@ -346,7 +349,6 @@ window.gl.utils.setParamInURL = setParamInURL;
* @returns {Boolean} * @returns {Boolean}
*/ */
export const convertPermissionToBoolean = permission => permission === 'true'; export const convertPermissionToBoolean = permission => permission === 'true';
window.gl.utils.convertPermissionToBoolean = convertPermissionToBoolean;
/** /**
* Back Off exponential algorithm * Back Off exponential algorithm
...@@ -400,7 +402,6 @@ export const backOff = (fn, timeout = 60000) => { ...@@ -400,7 +402,6 @@ export const backOff = (fn, timeout = 60000) => {
fn(next, stop); fn(next, stop);
}); });
}; };
window.gl.utils.backOff = backOff;
export const setFavicon = (faviconPath) => { export const setFavicon = (faviconPath) => {
const faviconEl = document.getElementById('favicon'); const faviconEl = document.getElementById('favicon');
...@@ -408,7 +409,6 @@ export const setFavicon = (faviconPath) => { ...@@ -408,7 +409,6 @@ export const setFavicon = (faviconPath) => {
faviconEl.setAttribute('href', faviconPath); faviconEl.setAttribute('href', faviconPath);
} }
}; };
window.gl.utils.setFavicon = setFavicon;
export const resetFavicon = () => { export const resetFavicon = () => {
const faviconEl = document.getElementById('favicon'); const faviconEl = document.getElementById('favicon');
...@@ -417,7 +417,6 @@ export const resetFavicon = () => { ...@@ -417,7 +417,6 @@ export const resetFavicon = () => {
faviconEl.setAttribute('href', originalFavicon); faviconEl.setAttribute('href', originalFavicon);
} }
}; };
window.gl.utils.resetFavicon = resetFavicon;
export const setCiStatusFavicon = (pageUrl) => { export const setCiStatusFavicon = (pageUrl) => {
$.ajax({ $.ajax({
...@@ -425,14 +424,13 @@ export const setCiStatusFavicon = (pageUrl) => { ...@@ -425,14 +424,13 @@ export const setCiStatusFavicon = (pageUrl) => {
dataType: 'json', dataType: 'json',
success: (data) => { success: (data) => {
if (data && data.favicon) { if (data && data.favicon) {
gl.utils.setFavicon(data.favicon); setFavicon(data.favicon);
} else { } else {
gl.utils.resetFavicon(); resetFavicon();
} }
}, },
error: () => { error: () => {
gl.utils.resetFavicon(); resetFavicon();
}, },
}); });
}; };
window.gl.utils.setCiStatusFavicon = setCiStatusFavicon;
import httpStatusCodes from './http_status'; import httpStatusCodes from './http_status';
import { normalizeHeaders } from './common_utils';
/** /**
* Polling utility for handling realtime updates. * Polling utility for handling realtime updates.
...@@ -57,7 +58,7 @@ export default class Poll { ...@@ -57,7 +58,7 @@ export default class Poll {
} }
checkConditions(response) { checkConditions(response) {
const headers = gl.utils.normalizeHeaders(response.headers); const headers = normalizeHeaders(response.headers);
const pollInterval = parseInt(headers[this.intervalHeader], 10); const pollInterval = parseInt(headers[this.intervalHeader], 10);
if (pollInterval > 0 && response.status === httpStatusCodes.OK && this.canPoll) { if (pollInterval > 0 && response.status === httpStatusCodes.OK && this.canPoll) {
......
...@@ -41,7 +41,7 @@ import './commit/image_file'; ...@@ -41,7 +41,7 @@ import './commit/image_file';
// lib/utils // lib/utils
import './lib/utils/animate'; import './lib/utils/animate';
import './lib/utils/bootstrap_linked_tabs'; import './lib/utils/bootstrap_linked_tabs';
import './lib/utils/common_utils'; import { handleLocationHash } from './lib/utils/common_utils';
import './lib/utils/datetime_utility'; import './lib/utils/datetime_utility';
import './lib/utils/pretty_time'; import './lib/utils/pretty_time';
import './lib/utils/text_utility'; import './lib/utils/text_utility';
...@@ -162,10 +162,10 @@ document.addEventListener('beforeunload', function () { ...@@ -162,10 +162,10 @@ document.addEventListener('beforeunload', function () {
$('[data-toggle="popover"]').popover('destroy'); $('[data-toggle="popover"]').popover('destroy');
}); });
window.addEventListener('hashchange', gl.utils.handleLocationHash); window.addEventListener('hashchange', handleLocationHash);
window.addEventListener('load', function onLoad() { window.addEventListener('load', function onLoad() {
window.removeEventListener('load', onLoad, false); window.removeEventListener('load', onLoad, false);
gl.utils.handleLocationHash(); handleLocationHash();
}, false); }, false);
gl.lazyLoader = new LazyLoader({ gl.lazyLoader = new LazyLoader({
...@@ -191,7 +191,7 @@ $(function () { ...@@ -191,7 +191,7 @@ $(function () {
$body.on('click', 'a[href^="#"]', function() { $body.on('click', 'a[href^="#"]', function() {
var href = this.getAttribute('href'); var href = this.getAttribute('href');
if (href.substr(1) === gl.utils.getLocationHash()) { if (href.substr(1) === gl.utils.getLocationHash()) {
setTimeout(gl.utils.handleLocationHash, 1); setTimeout(handleLocationHash, 1);
} }
}); });
......
...@@ -7,7 +7,11 @@ import './flash'; ...@@ -7,7 +7,11 @@ import './flash';
import BlobForkSuggestion from './blob/blob_fork_suggestion'; import BlobForkSuggestion from './blob/blob_fork_suggestion';
import initChangesDropdown from './init_changes_dropdown'; import initChangesDropdown from './init_changes_dropdown';
import bp from './breakpoints'; import bp from './breakpoints';
import parseUrlPathname from './lib/utils/common_utils'; import {
parseUrlPathname,
handleLocationHash,
isMetaClick,
} from './lib/utils/common_utils';
/* eslint-disable max-len */ /* eslint-disable max-len */
// MergeRequestTabs // MergeRequestTabs
...@@ -115,7 +119,7 @@ import parseUrlPathname from './lib/utils/common_utils'; ...@@ -115,7 +119,7 @@ import parseUrlPathname from './lib/utils/common_utils';
} }
clickTab(e) { clickTab(e) {
if (e.currentTarget && gl.utils.isMetaClick(e)) { if (e.currentTarget && isMetaClick(e)) {
const targetLink = e.currentTarget.getAttribute('href'); const targetLink = e.currentTarget.getAttribute('href');
e.stopImmediatePropagation(); e.stopImmediatePropagation();
e.preventDefault(); e.preventDefault();
...@@ -310,7 +314,7 @@ import parseUrlPathname from './lib/utils/common_utils'; ...@@ -310,7 +314,7 @@ import parseUrlPathname from './lib/utils/common_utils';
forceShow: true, forceShow: true,
}); });
anchor[0].scrollIntoView(); anchor[0].scrollIntoView();
window.gl.utils.handleLocationHash(); handleLocationHash();
// We have multiple elements on the page with `#note_xxx` // We have multiple elements on the page with `#note_xxx`
// (discussion and diff tabs) and `:target` only applies to the first // (discussion and diff tabs) and `:target` only applies to the first
anchor.addClass('target'); anchor.addClass('target');
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import EmptyState from './empty_state.vue'; import EmptyState from './empty_state.vue';
import MonitoringStore from '../stores/monitoring_store'; import MonitoringStore from '../stores/monitoring_store';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import { backOff } from '../../lib/utils/common_utils'; import { backOff, convertPermissionToBoolean } from '../../lib/utils/common_utils';
export default { export default {
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
return { return {
store, store,
state: 'gettingStarted', state: 'gettingStarted',
hasMetrics: gl.utils.convertPermissionToBoolean(metricsData.hasMetrics), hasMetrics: convertPermissionToBoolean(metricsData.hasMetrics),
documentationPath: metricsData.documentationPath, documentationPath: metricsData.documentationPath,
settingsPath: metricsData.settingsPath, settingsPath: metricsData.settingsPath,
endpoint: metricsData.additionalMetrics, endpoint: metricsData.additionalMetrics,
......
...@@ -23,7 +23,7 @@ import loadAwardsHandler from './awards_handler'; ...@@ -23,7 +23,7 @@ import loadAwardsHandler from './awards_handler';
import './autosave'; import './autosave';
import './dropzone_input'; import './dropzone_input';
import TaskList from './task_list'; import TaskList from './task_list';
import { ajaxPost, isInViewport, getPagePath } from './lib/utils/common_utils'; import { ajaxPost, isInViewport, getPagePath, scrollToElement, isMetaKey } from './lib/utils/common_utils';
window.autosize = autosize; window.autosize = autosize;
window.Dropzone = Dropzone; window.Dropzone = Dropzone;
...@@ -176,7 +176,7 @@ export default class Notes { ...@@ -176,7 +176,7 @@ export default class Notes {
keydownNoteText(e) { keydownNoteText(e) {
var $textarea, discussionNoteForm, editNote, myLastNote, myLastNoteEditBtn, newText, originalText; var $textarea, discussionNoteForm, editNote, myLastNote, myLastNoteEditBtn, newText, originalText;
if (gl.utils.isMetaKey(e)) { if (isMetaKey(e)) {
return; return;
} }
...@@ -1482,7 +1482,7 @@ export default class Notes { ...@@ -1482,7 +1482,7 @@ export default class Notes {
* *
* 1) Get Form metadata * 1) Get Form metadata
* 2) Update note element with new content * 2) Update note element with new content
* 3) Perform network request to submit the updated note using `gl.utils.ajaxPost` * 3) Perform network request to submit the updated note using `ajaxPost`
* a) If request is successfully completed * a) If request is successfully completed
* 1. Show submitted Note element * 1. Show submitted Note element
* b) If request failed * b) If request failed
......
import '~/lib/utils/common_utils'; import { getParameterByName } from '~/lib/utils/common_utils';
import '~/lib/utils/url_utility'; import '~/lib/utils/url_utility';
(() => { (() => {
...@@ -9,7 +9,7 @@ import '~/lib/utils/url_utility'; ...@@ -9,7 +9,7 @@ import '~/lib/utils/url_utility';
init(limit = 0, preload = false, disable = false, prepareData = $.noop, callback = $.noop) { init(limit = 0, preload = false, disable = false, prepareData = $.noop, callback = $.noop) {
this.url = $('.content_list').data('href') || gl.utils.removeParams(['limit', 'offset']); this.url = $('.content_list').data('href') || gl.utils.removeParams(['limit', 'offset']);
this.limit = limit; this.limit = limit;
this.offset = parseInt(gl.utils.getParameterByName('offset'), 10) || this.limit; this.offset = parseInt(getParameterByName('offset'), 10) || this.limit;
this.disable = disable; this.disable = disable;
this.prepareData = prepareData; this.prepareData = prepareData;
this.callback = callback; this.callback = callback;
......
import { convertPermissionToBoolean } from '../lib/utils/common_utils';
function insertRow($row) { function insertRow($row) {
const $rowClone = $row.clone(); const $rowClone = $row.clone();
$rowClone.removeAttr('data-is-persisted'); $rowClone.removeAttr('data-is-persisted');
...@@ -6,7 +8,7 @@ function insertRow($row) { ...@@ -6,7 +8,7 @@ function insertRow($row) {
} }
function removeRow($row) { function removeRow($row) {
const isPersisted = gl.utils.convertPermissionToBoolean($row.attr('data-is-persisted')); const isPersisted = convertPermissionToBoolean($row.attr('data-is-persisted'));
if (isPersisted) { if (isPersisted) {
$row.hide(); $row.hide();
......
import LinkedTabs from './lib/utils/bootstrap_linked_tabs'; import LinkedTabs from './lib/utils/bootstrap_linked_tabs';
import { setCiStatusFavicon } from './lib/utils/common_utils';
export default class Pipelines { export default class Pipelines {
constructor(options = {}) { constructor(options = {}) {
...@@ -8,7 +9,7 @@ export default class Pipelines { ...@@ -8,7 +9,7 @@ export default class Pipelines {
} }
if (options.pipelineStatusUrl) { if (options.pipelineStatusUrl) {
gl.utils.setCiStatusFavicon(options.pipelineStatusUrl); setCiStatusFavicon(options.pipelineStatusUrl);
} }
} }
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import tablePagination from '../../vue_shared/components/table_pagination.vue'; import tablePagination from '../../vue_shared/components/table_pagination.vue';
import navigationTabs from './navigation_tabs.vue'; import navigationTabs from './navigation_tabs.vue';
import navigationControls from './nav_controls.vue'; import navigationControls from './nav_controls.vue';
import { convertPermissionToBoolean, getParameterByName, setParamInURL } from '../../lib/utils/common_utils';
export default { export default {
props: { props: {
...@@ -44,10 +45,10 @@ ...@@ -44,10 +45,10 @@
}, },
computed: { computed: {
canCreatePipelineParsed() { canCreatePipelineParsed() {
return gl.utils.convertPermissionToBoolean(this.canCreatePipeline); return convertPermissionToBoolean(this.canCreatePipeline);
}, },
scope() { scope() {
const scope = gl.utils.getParameterByName('scope'); const scope = getParameterByName('scope');
return scope === null ? 'all' : scope; return scope === null ? 'all' : scope;
}, },
...@@ -105,10 +106,10 @@ ...@@ -105,10 +106,10 @@
}; };
}, },
pageParameter() { pageParameter() {
return gl.utils.getParameterByName('page') || this.pagenum; return getParameterByName('page') || this.pagenum;
}, },
scopeParameter() { scopeParameter() {
return gl.utils.getParameterByName('scope') || this.apiScope; return getParameterByName('scope') || this.apiScope;
}, },
}, },
created() { created() {
...@@ -122,7 +123,7 @@ ...@@ -122,7 +123,7 @@
* @param {Number} pageNumber desired page to go to. * @param {Number} pageNumber desired page to go to.
*/ */
change(pageNumber) { change(pageNumber) {
const param = gl.utils.setParamInURL('page', pageNumber); const param = setParamInURL('page', pageNumber);
gl.utils.visitUrl(param); gl.utils.visitUrl(param);
return param; return param;
......
import { parseIntPagination, normalizeHeaders } from '../../lib/utils/common_utils';
export default class PipelinesStore { export default class PipelinesStore {
constructor() { constructor() {
this.state = {}; this.state = {};
...@@ -19,8 +21,8 @@ export default class PipelinesStore { ...@@ -19,8 +21,8 @@ export default class PipelinesStore {
let paginationInfo; let paginationInfo;
if (Object.keys(pagination).length) { if (Object.keys(pagination).length) {
const normalizedHeaders = gl.utils.normalizeHeaders(pagination); const normalizedHeaders = normalizeHeaders(pagination);
paginationInfo = gl.utils.parseIntPagination(normalizedHeaders); paginationInfo = parseIntPagination(normalizedHeaders);
} else { } else {
paginationInfo = pagination; paginationInfo = pagination;
} }
......
/* eslint-disable class-methods-use-this, no-unneeded-ternary, quote-props */ /* eslint-disable class-methods-use-this, no-unneeded-ternary, quote-props */
import UsersSelect from './users_select'; import UsersSelect from './users_select';
import { isMetaClick } from './lib/utils/common_utils';
export default class Todos { export default class Todos {
constructor() { constructor() {
...@@ -141,7 +142,7 @@ export default class Todos { ...@@ -141,7 +142,7 @@ export default class Todos {
return; return;
} }
if (gl.utils.isMetaClick(e)) { if (isMetaClick(e)) {
const windowTarget = '_blank'; const windowTarget = '_blank';
const selected = e.target; const selected = e.target;
e.stopPropagation(); e.stopPropagation();
......
...@@ -31,6 +31,7 @@ import { ...@@ -31,6 +31,7 @@ import {
SquashBeforeMerge, SquashBeforeMerge,
notify, notify,
} from './dependencies'; } from './dependencies';
import { setFavicon } from '../lib/utils/common_utils';
export default { export default {
el: '#js-vue-mr-widget', el: '#js-vue-mr-widget',
...@@ -86,7 +87,7 @@ export default { ...@@ -86,7 +87,7 @@ export default {
.then((res) => { .then((res) => {
this.handleNotification(res); this.handleNotification(res);
this.mr.setData(res); this.mr.setData(res);
this.setFavicon(); this.setFaviconHelper();
if (cb) { if (cb) {
cb.call(null, res); cb.call(null, res);
...@@ -115,9 +116,9 @@ export default { ...@@ -115,9 +116,9 @@ export default {
immediateExecution: true, immediateExecution: true,
}); });
}, },
setFavicon() { setFaviconHelper() {
if (this.mr.ciStatusFaviconPath) { if (this.mr.ciStatusFaviconPath) {
gl.utils.setFavicon(this.mr.ciStatusFaviconPath); setFavicon(this.mr.ciStatusFaviconPath);
} }
}, },
fetchDeployments() { fetchDeployments() {
...@@ -193,7 +194,7 @@ export default { ...@@ -193,7 +194,7 @@ export default {
}); });
}, },
handleMounted() { handleMounted() {
this.setFavicon(); this.setFaviconHelper();
this.initDeploymentsPolling(); this.initDeploymentsPolling();
}, },
}, },
......
---
title: Exports common_utils utility functions as modules
merge_request:
author:
type: other
...@@ -14,6 +14,10 @@ describe('Environments Folder View', () => { ...@@ -14,6 +14,10 @@ describe('Environments Folder View', () => {
window.history.pushState({}, null, 'environments/folders/build'); window.history.pushState({}, null, 'environments/folders/build');
}); });
afterEach(() => {
window.history.pushState({}, null, '');
});
let component; let component;
describe('successfull request', () => { describe('successfull request', () => {
......
...@@ -78,8 +78,9 @@ import 'vendor/jquery.scrollTo'; ...@@ -78,8 +78,9 @@ import 'vendor/jquery.scrollTo';
}); });
describe('meta click', () => { describe('meta click', () => {
let metakeyEvent;
beforeEach(function () { beforeEach(function () {
spyOn(gl.utils, 'isMetaClick').and.returnValue(true); metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
}); });
it('opens page when commits link is clicked', function () { it('opens page when commits link is clicked', function () {
...@@ -89,7 +90,7 @@ import 'vendor/jquery.scrollTo'; ...@@ -89,7 +90,7 @@ import 'vendor/jquery.scrollTo';
}); });
this.class.bindEvents(); this.class.bindEvents();
document.querySelector('.merge-request-tabs .commits-tab a').click(); $('.merge-request-tabs .commits-tab a').trigger(metakeyEvent);
}); });
it('opens page when commits badge is clicked', function () { it('opens page when commits badge is clicked', function () {
...@@ -99,7 +100,7 @@ import 'vendor/jquery.scrollTo'; ...@@ -99,7 +100,7 @@ import 'vendor/jquery.scrollTo';
}); });
this.class.bindEvents(); this.class.bindEvents();
document.querySelector('.merge-request-tabs .commits-tab a .badge').click(); $('.merge-request-tabs .commits-tab a .badge').trigger(metakeyEvent);
}); });
}); });
......
...@@ -26,9 +26,10 @@ describe('Todos', () => { ...@@ -26,9 +26,10 @@ describe('Todos', () => {
describe('meta click', () => { describe('meta click', () => {
let visitUrlSpy; let visitUrlSpy;
let metakeyEvent;
beforeEach(() => { beforeEach(() => {
spyOn(gl.utils, 'isMetaClick').and.returnValue(true); metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
visitUrlSpy = spyOn(gl.utils, 'visitUrl').and.callFake(() => {}); visitUrlSpy = spyOn(gl.utils, 'visitUrl').and.callFake(() => {});
}); });
...@@ -41,7 +42,7 @@ describe('Todos', () => { ...@@ -41,7 +42,7 @@ describe('Todos', () => {
done(); done();
}); });
todoItem.click(); $('.todos-list .todo').trigger(metakeyEvent);
expect(visitUrlSpy).not.toHaveBeenCalled(); expect(visitUrlSpy).not.toHaveBeenCalled();
}); });
......
...@@ -232,29 +232,42 @@ describe('mrWidgetOptions', () => { ...@@ -232,29 +232,42 @@ describe('mrWidgetOptions', () => {
describe('handleMounted', () => { describe('handleMounted', () => {
it('should call required methods to do the initial kick-off', () => { it('should call required methods to do the initial kick-off', () => {
spyOn(vm, 'initDeploymentsPolling'); spyOn(vm, 'initDeploymentsPolling');
spyOn(vm, 'setFavicon'); spyOn(vm, 'setFaviconHelper');
vm.handleMounted(); vm.handleMounted();
expect(vm.setFavicon).toHaveBeenCalled(); expect(vm.setFaviconHelper).toHaveBeenCalled();
expect(vm.initDeploymentsPolling).toHaveBeenCalled(); expect(vm.initDeploymentsPolling).toHaveBeenCalled();
}); });
}); });
describe('setFavicon', () => { describe('setFavicon', () => {
let faviconElement;
beforeEach(() => {
const favicon = document.createElement('link');
favicon.setAttribute('id', 'favicon');
favicon.setAttribute('href', 'default/favicon');
document.body.appendChild(favicon);
faviconElement = document.body.getElementById('favicon');
});
afterEach(() => {
document.body.removeChild(document.getElementById('favicon'));
});
it('should call setFavicon method', () => { it('should call setFavicon method', () => {
spyOn(gl.utils, 'setFavicon');
vm.setFavicon(); vm.setFavicon();
expect(gl.utils.setFavicon).toHaveBeenCalledWith(vm.mr.ciStatusFaviconPath); expect(faviconElement.getAttribute('href')).toEqual(vm.mr.ciStatusFaviconPath);
}); });
it('should not call setFavicon when there is no ciStatusFaviconPath', () => { it('should not call setFavicon when there is no ciStatusFaviconPath', () => {
spyOn(gl.utils, 'setFavicon');
vm.mr.ciStatusFaviconPath = null; vm.mr.ciStatusFaviconPath = null;
vm.setFavicon(); vm.setFaviconHelper();
expect(gl.utils.setFavicon).not.toHaveBeenCalled(); expect(faviconElement.getAttribute('href')).toEqual(null);
}); });
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment