mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-29 20:06:18 +08:00
Created solution for JS translations
Also tidied up existing components and JS
This commit is contained in:
@ -64,7 +64,7 @@ export default function (ngApp, events) {
|
||||
$scope.$apply(() => {
|
||||
$scope.images.unshift(data);
|
||||
});
|
||||
events.emit('success', 'Image uploaded');
|
||||
events.emit('success', trans('components.image_upload_success'));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -151,10 +151,9 @@ export default function (ngApp, events) {
|
||||
if ($scope.searching) components['term'] = $scope.searchTerm;
|
||||
|
||||
|
||||
let urlQueryString = Object.keys(components).map((key) => {
|
||||
url += Object.keys(components).map((key) => {
|
||||
return key + '=' + encodeURIComponent(components[key]);
|
||||
}).join('&');
|
||||
url += urlQueryString;
|
||||
|
||||
$http.get(url).then((response) => {
|
||||
$scope.images = $scope.images.concat(response.data.images);
|
||||
@ -209,7 +208,7 @@ export default function (ngApp, events) {
|
||||
event.preventDefault();
|
||||
let url = window.baseUrl('/images/update/' + $scope.selectedImage.id);
|
||||
$http.put(url, this.selectedImage).then(response => {
|
||||
events.emit('success', 'Image details updated');
|
||||
events.emit('success', trans('components.image_update_success'));
|
||||
}, (response) => {
|
||||
if (response.status === 422) {
|
||||
let errors = response.data;
|
||||
@ -238,7 +237,7 @@ export default function (ngApp, events) {
|
||||
$http.delete(url).then((response) => {
|
||||
$scope.images.splice($scope.images.indexOf($scope.selectedImage), 1);
|
||||
$scope.selectedImage = false;
|
||||
events.emit('success', 'Image successfully deleted');
|
||||
events.emit('success', trans('components.image_delete_success'));
|
||||
}, (response) => {
|
||||
// Pages failure
|
||||
if (response.status === 400) {
|
||||
@ -309,9 +308,9 @@ export default function (ngApp, events) {
|
||||
|
||||
// Set initial header draft text
|
||||
if ($scope.isUpdateDraft || $scope.isNewPageDraft) {
|
||||
$scope.draftText = 'Editing Draft'
|
||||
$scope.draftText = trans('entities.pages_editing_draft');
|
||||
} else {
|
||||
$scope.draftText = 'Editing Page'
|
||||
$scope.draftText = trans('entities.pages_editing_page');
|
||||
}
|
||||
|
||||
let autoSave = false;
|
||||
@ -388,7 +387,7 @@ export default function (ngApp, events) {
|
||||
lastSave = Date.now();
|
||||
}, errorRes => {
|
||||
if (draftErroring) return;
|
||||
events.emit('error', 'Failed to save draft. Ensure you have internet connection before saving this page.')
|
||||
events.emit('error', trans('errors.page_draft_autosave_fail'));
|
||||
draftErroring = true;
|
||||
});
|
||||
}
|
||||
@ -421,7 +420,7 @@ export default function (ngApp, events) {
|
||||
let url = window.baseUrl('/ajax/page/' + pageId);
|
||||
$http.get(url).then((responseData) => {
|
||||
if (autoSave) $interval.cancel(autoSave);
|
||||
$scope.draftText = 'Editing Page';
|
||||
$scope.draftText = trans('entities.pages_editing_page');
|
||||
$scope.isUpdateDraft = false;
|
||||
$scope.$broadcast('html-update', responseData.data.html);
|
||||
$scope.$broadcast('markdown-update', responseData.data.markdown || responseData.data.html);
|
||||
@ -429,7 +428,7 @@ export default function (ngApp, events) {
|
||||
$timeout(() => {
|
||||
startAutoSave();
|
||||
}, 1000);
|
||||
events.emit('success', 'Draft discarded, The editor has been updated with the current page content');
|
||||
events.emit('success', trans('entities.pages_draft_discarded'));
|
||||
});
|
||||
};
|
||||
|
||||
@ -594,7 +593,7 @@ export default function (ngApp, events) {
|
||||
$scope.$apply(() => {
|
||||
$scope.files.push(data);
|
||||
});
|
||||
events.emit('success', 'File uploaded');
|
||||
events.emit('success', trans('entities.attachments_file_uploaded'));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -612,7 +611,7 @@ export default function (ngApp, events) {
|
||||
data.link = '';
|
||||
}
|
||||
});
|
||||
events.emit('success', 'File updated');
|
||||
events.emit('success', trans('entities.attachments_file_updated'));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -638,7 +637,7 @@ export default function (ngApp, events) {
|
||||
file.uploaded_to = pageId;
|
||||
$http.post(window.baseUrl('/attachments/link'), file).then(resp => {
|
||||
$scope.files.push(resp.data);
|
||||
events.emit('success', 'Link attached');
|
||||
events.emit('success', trans('entities.attachments_link_attached'));
|
||||
$scope.file = getCleanFile();
|
||||
}, checkError('link'));
|
||||
};
|
||||
@ -672,7 +671,7 @@ export default function (ngApp, events) {
|
||||
$scope.editFile.link = '';
|
||||
}
|
||||
$scope.editFile = false;
|
||||
events.emit('success', resp.headers('message-success'));
|
||||
events.emit('success', trans('entities.attachments_updated_success'));
|
||||
}, checkError('edit'));
|
||||
};
|
||||
|
||||
|
@ -102,7 +102,7 @@ export default function (ngApp, events) {
|
||||
$(file.previewElement).find('[data-dz-errormessage]').text(message);
|
||||
}
|
||||
|
||||
if (xhr.status === 413) setMessage('The server does not allow uploads of this size. Please try a smaller file.');
|
||||
if (xhr.status === 413) setMessage(trans('errors.server_upload_limit'));
|
||||
if (errorMessage.file) setMessage(errorMessage.file[0]);
|
||||
|
||||
});
|
||||
@ -261,15 +261,21 @@ export default function (ngApp, events) {
|
||||
link: function (scope, element, attrs) {
|
||||
|
||||
// Elements
|
||||
const input = element.find('[markdown-input] textarea').first();
|
||||
const display = element.find('.markdown-display').first();
|
||||
const insertImage = element.find('button[data-action="insertImage"]');
|
||||
const insertEntityLink = element.find('button[data-action="insertEntityLink"]')
|
||||
const $input = element.find('[markdown-input] textarea').first();
|
||||
const $display = element.find('.markdown-display').first();
|
||||
const $insertImage = element.find('button[data-action="insertImage"]');
|
||||
const $insertEntityLink = element.find('button[data-action="insertEntityLink"]');
|
||||
|
||||
// Prevent markdown display link click redirect
|
||||
$display.on('click', 'a', function(event) {
|
||||
event.preventDefault();
|
||||
window.open(this.getAttribute('href'));
|
||||
});
|
||||
|
||||
let currentCaretPos = 0;
|
||||
|
||||
input.blur(event => {
|
||||
currentCaretPos = input[0].selectionStart;
|
||||
$input.blur(event => {
|
||||
currentCaretPos = $input[0].selectionStart;
|
||||
});
|
||||
|
||||
// Scroll sync
|
||||
@ -279,10 +285,10 @@ export default function (ngApp, events) {
|
||||
displayHeight;
|
||||
|
||||
function setScrollHeights() {
|
||||
inputScrollHeight = input[0].scrollHeight;
|
||||
inputHeight = input.height();
|
||||
displayScrollHeight = display[0].scrollHeight;
|
||||
displayHeight = display.height();
|
||||
inputScrollHeight = $input[0].scrollHeight;
|
||||
inputHeight = $input.height();
|
||||
displayScrollHeight = $display[0].scrollHeight;
|
||||
displayHeight = $display.height();
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
@ -291,29 +297,29 @@ export default function (ngApp, events) {
|
||||
window.addEventListener('resize', setScrollHeights);
|
||||
let scrollDebounceTime = 800;
|
||||
let lastScroll = 0;
|
||||
input.on('scroll', event => {
|
||||
$input.on('scroll', event => {
|
||||
let now = Date.now();
|
||||
if (now - lastScroll > scrollDebounceTime) {
|
||||
setScrollHeights()
|
||||
}
|
||||
let scrollPercent = (input.scrollTop() / (inputScrollHeight - inputHeight));
|
||||
let scrollPercent = ($input.scrollTop() / (inputScrollHeight - inputHeight));
|
||||
let displayScrollY = (displayScrollHeight - displayHeight) * scrollPercent;
|
||||
display.scrollTop(displayScrollY);
|
||||
$display.scrollTop(displayScrollY);
|
||||
lastScroll = now;
|
||||
});
|
||||
|
||||
// Editor key-presses
|
||||
input.keydown(event => {
|
||||
$input.keydown(event => {
|
||||
// Insert image shortcut
|
||||
if (event.which === 73 && event.ctrlKey && event.shiftKey) {
|
||||
event.preventDefault();
|
||||
let caretPos = input[0].selectionStart;
|
||||
let currentContent = input.val();
|
||||
let caretPos = $input[0].selectionStart;
|
||||
let currentContent = $input.val();
|
||||
const mdImageText = "";
|
||||
input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos));
|
||||
input.focus();
|
||||
input[0].selectionStart = caretPos + (";
|
||||
input[0].selectionEnd = caretPos + (';
|
||||
$input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos));
|
||||
$input.focus();
|
||||
$input[0].selectionStart = caretPos + (";
|
||||
$input[0].selectionEnd = caretPos + (';
|
||||
return;
|
||||
}
|
||||
|
||||
@ -328,35 +334,35 @@ export default function (ngApp, events) {
|
||||
});
|
||||
|
||||
// Insert image from image manager
|
||||
insertImage.click(event => {
|
||||
$insertImage.click(event => {
|
||||
window.ImageManager.showExternal(image => {
|
||||
let caretPos = currentCaretPos;
|
||||
let currentContent = input.val();
|
||||
let currentContent = $input.val();
|
||||
let mdImageText = "";
|
||||
input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos));
|
||||
input.change();
|
||||
$input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos));
|
||||
$input.change();
|
||||
});
|
||||
});
|
||||
|
||||
function showLinkSelector() {
|
||||
window.showEntityLinkSelector((entity) => {
|
||||
let selectionStart = currentCaretPos;
|
||||
let selectionEnd = input[0].selectionEnd;
|
||||
let selectionEnd = $input[0].selectionEnd;
|
||||
let textSelected = (selectionEnd !== selectionStart);
|
||||
let currentContent = input.val();
|
||||
let currentContent = $input.val();
|
||||
|
||||
if (textSelected) {
|
||||
let selectedText = currentContent.substring(selectionStart, selectionEnd);
|
||||
let linkText = `[${selectedText}](${entity.link})`;
|
||||
input.val(currentContent.substring(0, selectionStart) + linkText + currentContent.substring(selectionEnd));
|
||||
$input.val(currentContent.substring(0, selectionStart) + linkText + currentContent.substring(selectionEnd));
|
||||
} else {
|
||||
let linkText = ` [${entity.name}](${entity.link}) `;
|
||||
input.val(currentContent.substring(0, selectionStart) + linkText + currentContent.substring(selectionStart))
|
||||
$input.val(currentContent.substring(0, selectionStart) + linkText + currentContent.substring(selectionStart))
|
||||
}
|
||||
input.change();
|
||||
$input.change();
|
||||
});
|
||||
}
|
||||
insertEntityLink.click(showLinkSelector);
|
||||
$insertEntityLink.click(showLinkSelector);
|
||||
|
||||
// Upload and insert image on paste
|
||||
function editorPaste(e) {
|
||||
@ -369,7 +375,7 @@ export default function (ngApp, events) {
|
||||
}
|
||||
}
|
||||
|
||||
input.on('paste', editorPaste);
|
||||
$input.on('paste', editorPaste);
|
||||
|
||||
// Handle image drop, Uploads images to BookStack.
|
||||
function handleImageDrop(event) {
|
||||
@ -381,7 +387,7 @@ export default function (ngApp, events) {
|
||||
}
|
||||
}
|
||||
|
||||
input.on('drop', handleImageDrop);
|
||||
$input.on('drop', handleImageDrop);
|
||||
|
||||
// Handle image upload and add image into markdown content
|
||||
function uploadImage(file) {
|
||||
@ -399,17 +405,17 @@ export default function (ngApp, events) {
|
||||
|
||||
// Insert image into markdown
|
||||
let id = "image-" + Math.random().toString(16).slice(2);
|
||||
let selectStart = input[0].selectionStart;
|
||||
let selectEnd = input[0].selectionEnd;
|
||||
let content = input[0].value;
|
||||
let selectStart = $input[0].selectionStart;
|
||||
let selectEnd = $input[0].selectionEnd;
|
||||
let content = $input[0].value;
|
||||
let selectText = content.substring(selectStart, selectEnd);
|
||||
let placeholderImage = window.baseUrl(`/loading.gif#upload${id}`);
|
||||
let innerContent = ((selectEnd > selectStart) ? `![${selectText}]` : '![]') + `(${placeholderImage})`;
|
||||
input[0].value = content.substring(0, selectStart) + innerContent + content.substring(selectEnd);
|
||||
$input[0].value = content.substring(0, selectStart) + innerContent + content.substring(selectEnd);
|
||||
|
||||
input.focus();
|
||||
input[0].selectionStart = selectStart;
|
||||
input[0].selectionEnd = selectStart;
|
||||
$input.focus();
|
||||
$input[0].selectionStart = selectStart;
|
||||
$input[0].selectionEnd = selectStart;
|
||||
|
||||
let remoteFilename = "image-" + Date.now() + "." + ext;
|
||||
formData.append('file', file, remoteFilename);
|
||||
@ -417,20 +423,20 @@ export default function (ngApp, events) {
|
||||
|
||||
xhr.open('POST', window.baseUrl('/images/gallery/upload'));
|
||||
xhr.onload = function () {
|
||||
let selectStart = input[0].selectionStart;
|
||||
let selectStart = $input[0].selectionStart;
|
||||
if (xhr.status === 200 || xhr.status === 201) {
|
||||
let result = JSON.parse(xhr.responseText);
|
||||
input[0].value = input[0].value.replace(placeholderImage, result.thumbs.display);
|
||||
input.change();
|
||||
$input[0].value = $input[0].value.replace(placeholderImage, result.thumbs.display);
|
||||
$input.change();
|
||||
} else {
|
||||
console.log('An error occurred uploading the image');
|
||||
console.log(trans('errors.image_upload_error'));
|
||||
console.log(xhr.responseText);
|
||||
input[0].value = input[0].value.replace(innerContent, '');
|
||||
input.change();
|
||||
$input[0].value = $input[0].value.replace(innerContent, '');
|
||||
$input.change();
|
||||
}
|
||||
input.focus();
|
||||
input[0].selectionStart = selectStart;
|
||||
input[0].selectionEnd = selectStart;
|
||||
$input.focus();
|
||||
$input[0].selectionStart = selectStart;
|
||||
$input[0].selectionEnd = selectStart;
|
||||
};
|
||||
xhr.send(formData);
|
||||
}
|
||||
@ -568,8 +574,7 @@ export default function (ngApp, events) {
|
||||
}
|
||||
// Enter or tab key
|
||||
else if ((event.keyCode === 13 || event.keyCode === 9) && !event.shiftKey) {
|
||||
let text = suggestionElems[active].textContent;
|
||||
currentInput[0].value = text;
|
||||
currentInput[0].value = suggestionElems[active].textContent;
|
||||
currentInput.focus();
|
||||
$suggestionBox.hide();
|
||||
isShowing = false;
|
||||
@ -665,7 +670,7 @@ export default function (ngApp, events) {
|
||||
|
||||
ngApp.directive('entityLinkSelector', [function($http) {
|
||||
return {
|
||||
restict: 'A',
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
|
||||
const selectButton = element.find('.entity-link-selector-confirm');
|
||||
|
@ -17,6 +17,12 @@ window.baseUrl = function(path) {
|
||||
|
||||
let ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']);
|
||||
|
||||
// Translation setup
|
||||
// Creates a global function with name 'trans' to be used in the same way as Laravel's translation system
|
||||
import Translations from "./translations"
|
||||
let translator = new Translations(window.translations);
|
||||
window.trans = translator.get.bind(translator);
|
||||
|
||||
// Global Event System
|
||||
class EventManager {
|
||||
constructor() {
|
||||
@ -70,150 +76,83 @@ jQuery.expr[":"].contains = $.expr.createPseudo(function (arg) {
|
||||
});
|
||||
|
||||
// Global jQuery Elements
|
||||
$(function () {
|
||||
|
||||
let notifications = $('.notification');
|
||||
let successNotification = notifications.filter('.pos');
|
||||
let errorNotification = notifications.filter('.neg');
|
||||
let warningNotification = notifications.filter('.warning');
|
||||
// Notification Events
|
||||
window.Events.listen('success', function (text) {
|
||||
successNotification.hide();
|
||||
successNotification.find('span').text(text);
|
||||
setTimeout(() => {
|
||||
successNotification.show();
|
||||
}, 1);
|
||||
});
|
||||
window.Events.listen('warning', function (text) {
|
||||
warningNotification.find('span').text(text);
|
||||
warningNotification.show();
|
||||
});
|
||||
window.Events.listen('error', function (text) {
|
||||
errorNotification.find('span').text(text);
|
||||
errorNotification.show();
|
||||
});
|
||||
|
||||
// Notification hiding
|
||||
notifications.click(function () {
|
||||
$(this).fadeOut(100);
|
||||
});
|
||||
|
||||
// Chapter page list toggles
|
||||
$('.chapter-toggle').click(function (e) {
|
||||
e.preventDefault();
|
||||
$(this).toggleClass('open');
|
||||
$(this).closest('.chapter').find('.inset-list').slideToggle(180);
|
||||
});
|
||||
|
||||
// Back to top button
|
||||
$('#back-to-top').click(function() {
|
||||
$('#header').smoothScrollTo();
|
||||
});
|
||||
let scrollTopShowing = false;
|
||||
let scrollTop = document.getElementById('back-to-top');
|
||||
let scrollTopBreakpoint = 1200;
|
||||
window.addEventListener('scroll', function() {
|
||||
let scrollTopPos = document.documentElement.scrollTop || document.body.scrollTop || 0;
|
||||
if (!scrollTopShowing && scrollTopPos > scrollTopBreakpoint) {
|
||||
scrollTop.style.display = 'block';
|
||||
scrollTopShowing = true;
|
||||
setTimeout(() => {
|
||||
scrollTop.style.opacity = 0.4;
|
||||
}, 1);
|
||||
} else if (scrollTopShowing && scrollTopPos < scrollTopBreakpoint) {
|
||||
scrollTop.style.opacity = 0;
|
||||
scrollTopShowing = false;
|
||||
setTimeout(() => {
|
||||
scrollTop.style.display = 'none';
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// Common jQuery actions
|
||||
$('[data-action="expand-entity-list-details"]').click(function() {
|
||||
$('.entity-list.compact').find('p').not('.empty-text').slideToggle(240);
|
||||
});
|
||||
|
||||
// Popup close
|
||||
$('.popup-close').click(function() {
|
||||
$(this).closest('.overlay').fadeOut(240);
|
||||
});
|
||||
$('.overlay').click(function(event) {
|
||||
if (!$(event.target).hasClass('overlay')) return;
|
||||
$(this).fadeOut(240);
|
||||
});
|
||||
|
||||
// Prevent markdown display link click redirect
|
||||
$('.markdown-display').on('click', 'a', function(event) {
|
||||
event.preventDefault();
|
||||
window.open($(this).attr('href'));
|
||||
});
|
||||
|
||||
// Toggle Switches
|
||||
let $switches = $('[toggle-switch]');
|
||||
if ($switches.length > 0) {
|
||||
$switches.click(event => {
|
||||
let $switch = $(event.target);
|
||||
let input = $switch.find('input').first()[0];
|
||||
let checked = input.value !== 'true';
|
||||
input.value = checked ? 'true' : 'false';
|
||||
$switch.toggleClass('active', checked);
|
||||
});
|
||||
}
|
||||
|
||||
// Image pickers
|
||||
$('.image-picker').on('click', 'button', event => {
|
||||
let button = event.target;
|
||||
let picker = $(button).closest('.image-picker')[0];
|
||||
let action = button.getAttribute('data-action');
|
||||
let resize = picker.getAttribute('data-resize-height') && picker.getAttribute('data-resize-width');
|
||||
let usingIds = picker.getAttribute('data-current-id') !== '';
|
||||
let resizeCrop = picker.getAttribute('data-resize-crop') !== '';
|
||||
let imageElem = picker.querySelector('img');
|
||||
let input = picker.querySelector('input');
|
||||
|
||||
function setImage(image) {
|
||||
|
||||
if (image === 'none') {
|
||||
imageElem.src = picker.getAttribute('data-default-image');
|
||||
imageElem.classList.add('none');
|
||||
input.value = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
imageElem.src = image.url;
|
||||
input.value = usingIds ? image.id : image.url;
|
||||
imageElem.classList.remove('none');
|
||||
}
|
||||
|
||||
if (action === 'show-image-manager') {
|
||||
window.ImageManager.showExternal((image) => {
|
||||
if (!resize) {
|
||||
setImage(image);
|
||||
return;
|
||||
}
|
||||
let requestString = '/images/thumb/' + image.id + '/' + picker.getAttribute('data-resize-width') + '/' + picker.getAttribute('data-resize-height') + '/' + (resizeCrop ? 'true' : 'false');
|
||||
$.get(window.baseUrl(requestString), resp => {
|
||||
image.url = resp.url;
|
||||
setImage(image);
|
||||
});
|
||||
});
|
||||
} else if (action === 'reset-image') {
|
||||
setImage({id: 0, url: picker.getAttribute('data-default-image')});
|
||||
} else if (action === 'remove-image') {
|
||||
setImage('none');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Detect IE for css
|
||||
if(navigator.userAgent.indexOf('MSIE')!==-1
|
||||
|| navigator.appVersion.indexOf('Trident/') > 0
|
||||
|| navigator.userAgent.indexOf('Safari') !== -1){
|
||||
$('body').addClass('flexbox-support');
|
||||
}
|
||||
|
||||
let notifications = $('.notification');
|
||||
let successNotification = notifications.filter('.pos');
|
||||
let errorNotification = notifications.filter('.neg');
|
||||
let warningNotification = notifications.filter('.warning');
|
||||
// Notification Events
|
||||
window.Events.listen('success', function (text) {
|
||||
successNotification.hide();
|
||||
successNotification.find('span').text(text);
|
||||
setTimeout(() => {
|
||||
successNotification.show();
|
||||
}, 1);
|
||||
});
|
||||
window.Events.listen('warning', function (text) {
|
||||
warningNotification.find('span').text(text);
|
||||
warningNotification.show();
|
||||
});
|
||||
window.Events.listen('error', function (text) {
|
||||
errorNotification.find('span').text(text);
|
||||
errorNotification.show();
|
||||
});
|
||||
|
||||
// Notification hiding
|
||||
notifications.click(function () {
|
||||
$(this).fadeOut(100);
|
||||
});
|
||||
|
||||
// Chapter page list toggles
|
||||
$('.chapter-toggle').click(function (e) {
|
||||
e.preventDefault();
|
||||
$(this).toggleClass('open');
|
||||
$(this).closest('.chapter').find('.inset-list').slideToggle(180);
|
||||
});
|
||||
|
||||
// Back to top button
|
||||
$('#back-to-top').click(function() {
|
||||
$('#header').smoothScrollTo();
|
||||
});
|
||||
let scrollTopShowing = false;
|
||||
let scrollTop = document.getElementById('back-to-top');
|
||||
let scrollTopBreakpoint = 1200;
|
||||
window.addEventListener('scroll', function() {
|
||||
let scrollTopPos = document.documentElement.scrollTop || document.body.scrollTop || 0;
|
||||
if (!scrollTopShowing && scrollTopPos > scrollTopBreakpoint) {
|
||||
scrollTop.style.display = 'block';
|
||||
scrollTopShowing = true;
|
||||
setTimeout(() => {
|
||||
scrollTop.style.opacity = 0.4;
|
||||
}, 1);
|
||||
} else if (scrollTopShowing && scrollTopPos < scrollTopBreakpoint) {
|
||||
scrollTop.style.opacity = 0;
|
||||
scrollTopShowing = false;
|
||||
setTimeout(() => {
|
||||
scrollTop.style.display = 'none';
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// Common jQuery actions
|
||||
$('[data-action="expand-entity-list-details"]').click(function() {
|
||||
$('.entity-list.compact').find('p').not('.empty-text').slideToggle(240);
|
||||
});
|
||||
|
||||
// Popup close
|
||||
$('.popup-close').click(function() {
|
||||
$(this).closest('.overlay').fadeOut(240);
|
||||
});
|
||||
$('.overlay').click(function(event) {
|
||||
if (!$(event.target).hasClass('overlay')) return;
|
||||
$(this).fadeOut(240);
|
||||
});
|
||||
|
||||
// Detect IE for css
|
||||
if(navigator.userAgent.indexOf('MSIE')!==-1
|
||||
|| navigator.appVersion.indexOf('Trident/') > 0
|
||||
|| navigator.userAgent.indexOf('Safari') !== -1){
|
||||
$('body').addClass('flexbox-support');
|
||||
}
|
||||
|
||||
// Page specific items
|
||||
import "./pages/page-show";
|
||||
|
47
resources/assets/js/translations.js
Normal file
47
resources/assets/js/translations.js
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Translation Manager
|
||||
* Handles the JavaScript side of translating strings
|
||||
* in a way which fits with Laravel.
|
||||
*/
|
||||
class Translator {
|
||||
|
||||
/**
|
||||
* Create an instance, Passing in the required translations
|
||||
* @param translations
|
||||
*/
|
||||
constructor(translations) {
|
||||
this.store = translations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a translation, Same format as laravel's 'trans' helper
|
||||
* @param key
|
||||
* @param replacements
|
||||
* @returns {*}
|
||||
*/
|
||||
get(key, replacements) {
|
||||
let splitKey = key.split('.');
|
||||
let value = splitKey.reduce((a, b) => {
|
||||
return a != undefined ? a[b] : a;
|
||||
}, this.store);
|
||||
|
||||
if (value === undefined) {
|
||||
console.log(`Translation with key "${key}" does not exist`);
|
||||
value = key;
|
||||
}
|
||||
|
||||
if (replacements === undefined) return value;
|
||||
|
||||
let replaceMatches = value.match(/:([\S]+)/g);
|
||||
if (replaceMatches === null) return value;
|
||||
replaceMatches.forEach(match => {
|
||||
let key = match.substring(1);
|
||||
if (typeof replacements[key] === 'undefined') return;
|
||||
value = value.replace(match, replacements[key]);
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Translator
|
Reference in New Issue
Block a user