1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-30 04:23:11 +03:00

Updated some comment elements and standardised more JS

- Updated comment routes to be simpler.
- Updated comments JS to align better with updated component system.
- Documented available global JS functions/services.
- Removed redundant controller method.
- Added window.$events helpers for validation messages and
success/error.
- Updated JS events system to not be class based for simplicity.
- Added window.trans_plural method to handle pluralisation/replacements
where you already have the translation string itself.

Fixes #1836
This commit is contained in:
Dan Brown
2020-07-28 18:19:18 +01:00
parent 2c0fdf83c1
commit 7590ecd37c
11 changed files with 192 additions and 124 deletions

View File

@ -1,55 +1,66 @@
const listeners = {};
const stack = [];
/**
* Simple global events manager
* Emit a custom event for any handlers to pick-up.
* @param {String} eventName
* @param {*} eventData
*/
class Events {
constructor() {
this.listeners = {};
this.stack = [];
}
/**
* Emit a custom event for any handlers to pick-up.
* @param {String} eventName
* @param {*} eventData
* @returns {Events}
*/
emit(eventName, eventData) {
this.stack.push({name: eventName, data: eventData});
if (typeof this.listeners[eventName] === 'undefined') return this;
let eventsToStart = this.listeners[eventName];
for (let i = 0; i < eventsToStart.length; i++) {
let event = eventsToStart[i];
event(eventData);
}
return this;
}
/**
* Listen to a custom event and run the given callback when that event occurs.
* @param {String} eventName
* @param {Function} callback
* @returns {Events}
*/
listen(eventName, callback) {
if (typeof this.listeners[eventName] === 'undefined') this.listeners[eventName] = [];
this.listeners[eventName].push(callback);
return this;
}
/**
* Emit an event for public use.
* Sends the event via the native DOM event handling system.
* @param {Element} targetElement
* @param {String} eventName
* @param {Object} eventData
*/
emitPublic(targetElement, eventName, eventData) {
const event = new CustomEvent(eventName, {
detail: eventData,
bubbles: true
});
targetElement.dispatchEvent(event);
function emit(eventName, eventData) {
stack.push({name: eventName, data: eventData});
if (typeof listeners[eventName] === 'undefined') return this;
let eventsToStart = listeners[eventName];
for (let i = 0; i < eventsToStart.length; i++) {
let event = eventsToStart[i];
event(eventData);
}
}
export default Events;
/**
* Listen to a custom event and run the given callback when that event occurs.
* @param {String} eventName
* @param {Function} callback
* @returns {Events}
*/
function listen(eventName, callback) {
if (typeof listeners[eventName] === 'undefined') listeners[eventName] = [];
listeners[eventName].push(callback);
}
/**
* Emit an event for public use.
* Sends the event via the native DOM event handling system.
* @param {Element} targetElement
* @param {String} eventName
* @param {Object} eventData
*/
function emitPublic(targetElement, eventName, eventData) {
const event = new CustomEvent(eventName, {
detail: eventData,
bubbles: true
});
targetElement.dispatchEvent(event);
}
/**
* Notify of a http error.
* Check for standard scenarios such as validation errors and
* formats an error notification accordingly.
* @param {Error} error
*/
function showValidationErrors(error) {
if (!error.status) return;
if (error.status === 422 && error.data) {
const message = Object.values(error.data).flat().join('\n');
emit('error', message);
}
}
export default {
emit,
emitPublic,
listen,
success: (msg) => emit('success', msg),
error: (msg) => emit('error', msg),
showValidationErrors,
}

View File

@ -69,7 +69,10 @@ async function dataRequest(method, url, data = null) {
// Send data as JSON if a plain object
if (typeof data === 'object' && !(data instanceof FormData)) {
options.headers = {'Content-Type': 'application/json'};
options.headers = {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
};
options.body = JSON.stringify(data);
}

View File

@ -47,7 +47,19 @@ class Translator {
*/
getPlural(key, count, replacements) {
const text = this.getTransText(key);
const splitText = text.split('|');
return this.parsePlural(text, count, replacements);
}
/**
* Parse the given translation and find the correct plural option
* to use. Similar format at laravel's 'trans_choice' helper.
* @param {String} translation
* @param {Number} count
* @param {Object} replacements
* @returns {String}
*/
parsePlural(translation, count, replacements) {
const splitText = translation.split('|');
const exactCountRegex = /^{([0-9]+)}/;
const rangeRegex = /^\[([0-9]+),([0-9*]+)]/;
let result = null;