Removed jQuery and replaced axios with fetch

This commit is contained in:
Dan Brown
2019-06-08 00:02:51 +01:00
parent b532ed0f86
commit 53ba5b7e33
13 changed files with 194 additions and 169 deletions

View File

@ -60,7 +60,7 @@ class BreadcrumbListing {
'entity_type': this.entityType,
};
window.$http.get('/search/entity/siblings', {params}).then(resp => {
window.$http.get('/search/entity/siblings', params).then(resp => {
this.entityListElem.innerHTML = resp.data;
}).catch(err => {
console.error(err);

View File

@ -1,4 +1,6 @@
import MarkdownIt from "markdown-it";
import {scrollAndHighlightElement} from "../services/util";
const md = new MarkdownIt({ html: false });
class PageComments {
@ -25,8 +27,8 @@ class PageComments {
handleAction(event) {
let actionElem = event.target.closest('[action]');
if (event.target.matches('a[href^="#"]')) {
let id = event.target.href.split('#')[1];
window.scrollAndHighlight(document.querySelector('#' + id));
const id = event.target.href.split('#')[1];
scrollAndHighlightElement(document.querySelector('#' + id));
}
if (actionElem === null) return;
event.preventDefault();
@ -132,7 +134,7 @@ class PageComments {
this.formContainer.parentNode.style.display = 'block';
this.elem.querySelector('[comment-add-button-container]').style.display = 'none';
this.formInput.focus();
window.scrollToElement(this.formInput);
this.formInput.scrollIntoView({behavior: "smooth"});
}
hideForm() {

View File

@ -1,6 +1,7 @@
import Clipboard from "clipboard/dist/clipboard.min";
import Code from "../services/code";
import * as DOM from "../services/dom";
import {scrollAndHighlightElement} from "../services/util";
class PageDisplay {
@ -20,10 +21,12 @@ class PageDisplay {
// Sidebar page nav click event
const sidebarPageNav = document.querySelector('.sidebar-page-nav');
DOM.onChildEvent(sidebarPageNav, 'a', 'click', (event, child) => {
window.components['tri-layout'][0].showContent();
this.goToText(child.getAttribute('href').substr(1));
});
if (sidebarPageNav) {
DOM.onChildEvent(sidebarPageNav, 'a', 'click', (event, child) => {
window.components['tri-layout'][0].showContent();
this.goToText(child.getAttribute('href').substr(1));
});
}
}
goToText(text) {
@ -35,11 +38,11 @@ class PageDisplay {
});
if (idElem !== null) {
window.scrollAndHighlight(idElem);
scrollAndHighlightElement(idElem);
} else {
const textElem = DOM.findText('.page-content > div > *', text);
if (textElem) {
window.scrollAndHighlight(textElem);
scrollAndHighlightElement(textElem);
}
}
}

View File

@ -1,6 +1,3 @@
// Global Polyfills
import "./services/dom-polyfills"
// Url retrieval function
window.baseUrl = function(path) {
let basePath = document.querySelector('meta[name="base-url"]').getAttribute('content');
@ -11,27 +8,24 @@ window.baseUrl = function(path) {
// Set events and http services on window
import Events from "./services/events"
import Http from "./services/http"
let httpInstance = Http();
import httpInstance from "./services/http"
const eventManager = new Events();
window.$http = httpInstance;
window.$events = new Events();
window.$events = eventManager;
// Translation setup
// Creates a global function with name 'trans' to be used in the same way as Laravel's translation system
import Translations from "./services/translations"
let translator = new Translations(window.translations);
const translator = new Translations(window.translations);
window.trans = translator.get.bind(translator);
window.trans_choice = translator.getPlural.bind(translator);
// Load in global UI helpers and libraries including jQuery
import "./services/global-ui"
// Set services on Vue
// Make services available to Vue instances
import Vue from "vue"
Vue.prototype.$http = httpInstance;
Vue.prototype.$events = window.$events;
Vue.prototype.$events = eventManager;
// Load vues and components
// Load Vues and components
import vues from "./vues/vues"
import components from "./components"
vues();

View File

@ -1,22 +0,0 @@
/**
* Polyfills for DOM API's
*/
// https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
if (!Element.prototype.matches) {
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
}
// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility
if (!Element.prototype.closest) {
Element.prototype.closest = function (s) {
var el = this;
var ancestor = this;
if (!document.documentElement.contains(el)) return null;
do {
if (ancestor.matches(s)) return ancestor;
ancestor = ancestor.parentElement;
} while (ancestor !== null);
return null;
};
}

View File

@ -1,58 +0,0 @@
// Global jQuery Config & Extensions
import jQuery from "jquery"
window.jQuery = window.$ = jQuery;
/**
* Scroll the view to a specific element.
* @param {HTMLElement} element
*/
window.scrollToElement = function(element) {
if (!element) return;
let offset = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
let top = element.getBoundingClientRect().top + offset;
$('html, body').animate({
scrollTop: top - 60 // Adjust to change final scroll position top margin
}, 300);
};
/**
* Scroll and highlight an element.
* @param {HTMLElement} element
*/
window.scrollAndHighlight = function(element) {
if (!element) return;
window.scrollToElement(element);
let color = document.getElementById('custom-styles').getAttribute('data-color-light');
let initColor = window.getComputedStyle(element).getPropertyValue('background-color');
element.style.backgroundColor = color;
setTimeout(() => {
element.classList.add('selectFade');
element.style.backgroundColor = initColor;
}, 10);
setTimeout(() => {
element.classList.remove('selectFade');
element.style.backgroundColor = '';
}, 3000);
};
// Smooth scrolling
jQuery.fn.smoothScrollTo = function () {
if (this.length === 0) return;
window.scrollToElement(this[0]);
return this;
};
// Making contains text expression not worry about casing
jQuery.expr[":"].contains = $.expr.createPseudo(function (arg) {
return function (elem) {
return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
};
});
// Detect IE for css
if(navigator.userAgent.indexOf('MSIE')!==-1
|| navigator.appVersion.indexOf('Trident/') > 0
|| navigator.userAgent.indexOf('Safari') !== -1){
document.body.classList.add('flexbox-support');
}

View File

@ -1,21 +1,146 @@
import axios from "axios"
function instance() {
let axiosInstance = axios.create({
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name=token]').getAttribute('content'),
'baseURL': window.baseUrl('')
}
/**
* Perform a HTTP GET request.
* Can easily pass query parameters as the second parameter.
* @param {String} url
* @param {Object} params
* @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
*/
async function get(url, params = {}) {
return request(url, {
method: 'GET',
params,
});
axiosInstance.interceptors.request.use(resp => {
return resp;
}, err => {
if (typeof err.response === "undefined" || typeof err.response.data === "undefined") return Promise.reject(err);
if (typeof err.response.data.error !== "undefined") window.$events.emit('error', err.response.data.error);
if (typeof err.response.data.message !== "undefined") window.$events.emit('error', err.response.data.message);
});
return axiosInstance;
}
/**
* Perform a HTTP POST request.
* @param {String} url
* @param {Object} data
* @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
*/
async function post(url, data = null) {
return dataRequest('POST', url, data);
}
export default instance;
/**
* Perform a HTTP PUT request.
* @param {String} url
* @param {Object} data
* @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
*/
async function put(url, data = null) {
return dataRequest('PUT', url, data);
}
/**
* Perform a HTTP PATCH request.
* @param {String} url
* @param {Object} data
* @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
*/
async function patch(url, data = null) {
return dataRequest('PATCH', url, data);
}
/**
* Perform a HTTP DELETE request.
* @param {String} url
* @param {Object} data
* @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
*/
async function performDelete(url, data = null) {
return dataRequest('DELETE', url, data);
}
/**
* Perform a HTTP request to the back-end that includes data in the body.
* Parses the body to JSON if an object, setting the correct headers.
* @param {String} method
* @param {String} url
* @param {Object} data
* @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
*/
async function dataRequest(method, url, data = null) {
const options = {
method: method,
body: data,
};
if (typeof data === 'object') {
options.headers = {'Content-Type': 'application/json'};
options.body = JSON.stringify(data);
}
return request(url, options)
}
/**
* Create a new HTTP request, setting the required CSRF information
* to communicate with the back-end. Parses & formats the response.
* @param {String} url
* @param {Object} options
* @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
*/
async function request(url, options = {}) {
if (!url.startsWith('http')) {
url = window.baseUrl(url);
}
if (options.params) {
const urlObj = new URL(url);
for (let paramName of Object.keys(options.params)) {
const value = options.params[paramName];
if (typeof value !== 'undefined' && value !== null) {
urlObj.searchParams.set(paramName, value);
}
}
url = urlObj.toString();
}
const csrfToken = document.querySelector('meta[name=token]').getAttribute('content');
options = Object.assign({}, options, {
'credentials': 'same-origin',
});
options.headers = Object.assign({}, options.headers || {}, {
'baseURL': window.baseUrl(''),
'X-CSRF-TOKEN': csrfToken,
});
const response = await fetch(url, options);
const content = await getResponseContent(response);
return {
data: content,
headers: response.headers,
redirected: response.redirected,
status: response.status,
statusText: response.statusText,
url: response.url,
original: response,
}
}
/**
* Get the content from a fetch response.
* Checks the content-type header to determine the format.
* @param response
* @returns {Promise<Object|String>}
*/
async function getResponseContent(response) {
const responseContentType = response.headers.get('Content-Type');
const subType = responseContentType.split('/').pop();
if (subType === 'javascript' || subType === 'json') {
return await response.json();
}
return await response.text();
}
export default {
get: get,
post: post,
put: put,
patch: patch,
delete: performDelete,
};

View File

@ -24,4 +24,25 @@ export function debounce(func, wait, immediate) {
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
};
/**
* Scroll and highlight an element.
* @param {HTMLElement} element
*/
export function scrollAndHighlightElement(element) {
if (!element) return;
element.scrollIntoView({behavior: 'smooth'});
const color = document.getElementById('custom-styles').getAttribute('data-color-light');
const initColor = window.getComputedStyle(element).getPropertyValue('background-color');
element.style.backgroundColor = color;
setTimeout(() => {
element.classList.add('selectFade');
element.style.backgroundColor = initColor;
}, 10);
setTimeout(() => {
element.classList.remove('selectFade');
element.style.backgroundColor = '';
}, 3000);
}

View File

@ -113,11 +113,13 @@ const methods = {
*/
getSuggestions(input, params) {
params.search = input;
let cacheKey = `${this.url}:${JSON.stringify(params)}`;
const cacheKey = `${this.url}:${JSON.stringify(params)}`;
if (typeof ajaxCache[cacheKey] !== "undefined") return Promise.resolve(ajaxCache[cacheKey]);
if (typeof ajaxCache[cacheKey] !== "undefined") {
return Promise.resolve(ajaxCache[cacheKey]);
}
return this.$http.get(this.url, {params}).then(resp => {
return this.$http.get(this.url, params).then(resp => {
ajaxCache[cacheKey] = resp.data;
return resp.data;
});

View File

@ -57,14 +57,14 @@ const methods = {
},
async fetchData() {
let query = {
const params = {
page,
search: this.searching ? this.searchTerm : null,
uploaded_to: this.uploadedTo || null,
filter_type: this.filter,
};
const {data} = await this.$http.get(baseUrl, {params: query});
const {data} = await this.$http.get(baseUrl, params);
this.images = this.images.concat(data.images);
this.hasMore = data.has_more;
page++;