mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-30 06:30:03 +00:00
Converted jQuery bits into raw JS components
This commit is contained in:
parent
5e5928a8a6
commit
2a069880cd
23 changed files with 387 additions and 209 deletions
resources
53
resources/assets/js/components/back-top-top.js
Normal file
53
resources/assets/js/components/back-top-top.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
class BackToTop {
|
||||||
|
|
||||||
|
constructor(elem) {
|
||||||
|
this.elem = elem;
|
||||||
|
this.targetElem = document.getElementById('header');
|
||||||
|
this.showing = false;
|
||||||
|
this.breakPoint = 1200;
|
||||||
|
this.elem.addEventListener('click', this.scrollToTop.bind(this));
|
||||||
|
window.addEventListener('scroll', this.onPageScroll.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
onPageScroll() {
|
||||||
|
let scrollTopPos = document.documentElement.scrollTop || document.body.scrollTop || 0;
|
||||||
|
if (!this.showing && scrollTopPos > this.breakPoint) {
|
||||||
|
this.elem.style.display = 'block';
|
||||||
|
this.showing = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.elem.style.opacity = 0.4;
|
||||||
|
}, 1);
|
||||||
|
} else if (this.showing && scrollTopPos < this.breakPoint) {
|
||||||
|
this.elem.style.opacity = 0;
|
||||||
|
this.showing = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.elem.style.display = 'none';
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToTop() {
|
||||||
|
let targetTop = this.targetElem.getBoundingClientRect().top;
|
||||||
|
let scrollElem = document.documentElement.scrollTop ? document.documentElement : document.body;
|
||||||
|
let duration = 300;
|
||||||
|
let start = Date.now();
|
||||||
|
let scrollStart = this.targetElem.getBoundingClientRect().top;
|
||||||
|
|
||||||
|
function setPos() {
|
||||||
|
let percentComplete = (1-((Date.now() - start) / duration));
|
||||||
|
let target = Math.abs(percentComplete * scrollStart);
|
||||||
|
if (percentComplete > 0) {
|
||||||
|
scrollElem.scrollTop = target;
|
||||||
|
requestAnimationFrame(setPos.bind(this));
|
||||||
|
} else {
|
||||||
|
scrollElem.scrollTop = targetTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(setPos.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BackToTop;
|
67
resources/assets/js/components/chapter-toggle.js
Normal file
67
resources/assets/js/components/chapter-toggle.js
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
class ChapterToggle {
|
||||||
|
|
||||||
|
constructor(elem) {
|
||||||
|
this.elem = elem;
|
||||||
|
this.isOpen = elem.classList.contains('open');
|
||||||
|
elem.addEventListener('click', this.click.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
let list = this.elem.parentNode.querySelector('.inset-list');
|
||||||
|
|
||||||
|
this.elem.classList.add('open');
|
||||||
|
list.style.display = 'block';
|
||||||
|
list.style.height = '';
|
||||||
|
let height = list.getBoundingClientRect().height;
|
||||||
|
list.style.height = '0px';
|
||||||
|
list.style.overflow = 'hidden';
|
||||||
|
list.style.transition = 'height ease-in-out 240ms';
|
||||||
|
|
||||||
|
let transitionEndBound = onTransitionEnd.bind(this);
|
||||||
|
function onTransitionEnd() {
|
||||||
|
list.style.overflow = '';
|
||||||
|
list.style.height = '';
|
||||||
|
list.style.transition = '';
|
||||||
|
list.removeEventListener('transitionend', transitionEndBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
list.style.height = `${height}px`;
|
||||||
|
list.addEventListener('transitionend', transitionEndBound)
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
let list = this.elem.parentNode.querySelector('.inset-list');
|
||||||
|
|
||||||
|
this.elem.classList.remove('open');
|
||||||
|
list.style.display = 'block';
|
||||||
|
list.style.height = list.getBoundingClientRect().height + 'px';
|
||||||
|
list.style.overflow = 'hidden';
|
||||||
|
list.style.transition = 'height ease-in-out 240ms';
|
||||||
|
|
||||||
|
let transitionEndBound = onTransitionEnd.bind(this);
|
||||||
|
function onTransitionEnd() {
|
||||||
|
list.style.overflow = '';
|
||||||
|
list.style.height = '';
|
||||||
|
list.style.transition = '';
|
||||||
|
list.style.display = 'none';
|
||||||
|
list.removeEventListener('transitionend', transitionEndBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
list.style.height = `0px`;
|
||||||
|
list.addEventListener('transitionend', transitionEndBound)
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
click(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.isOpen ? this.close() : this.open();
|
||||||
|
this.isOpen = !this.isOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ChapterToggle;
|
65
resources/assets/js/components/expand-toggle.js
Normal file
65
resources/assets/js/components/expand-toggle.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
class ExpandToggle {
|
||||||
|
|
||||||
|
constructor(elem) {
|
||||||
|
this.elem = elem;
|
||||||
|
this.isOpen = false;
|
||||||
|
this.selector = elem.getAttribute('expand-toggle');
|
||||||
|
elem.addEventListener('click', this.click.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
open(elemToToggle) {
|
||||||
|
elemToToggle.style.display = 'block';
|
||||||
|
elemToToggle.style.height = '';
|
||||||
|
let height = elemToToggle.getBoundingClientRect().height;
|
||||||
|
elemToToggle.style.height = '0px';
|
||||||
|
elemToToggle.style.overflow = 'hidden';
|
||||||
|
elemToToggle.style.transition = 'height ease-in-out 240ms';
|
||||||
|
|
||||||
|
let transitionEndBound = onTransitionEnd.bind(this);
|
||||||
|
function onTransitionEnd() {
|
||||||
|
elemToToggle.style.overflow = '';
|
||||||
|
elemToToggle.style.height = '';
|
||||||
|
elemToToggle.style.transition = '';
|
||||||
|
elemToToggle.removeEventListener('transitionend', transitionEndBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
elemToToggle.style.height = `${height}px`;
|
||||||
|
elemToToggle.addEventListener('transitionend', transitionEndBound)
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(elemToToggle) {
|
||||||
|
elemToToggle.style.display = 'block';
|
||||||
|
elemToToggle.style.height = elemToToggle.getBoundingClientRect().height + 'px';
|
||||||
|
elemToToggle.style.overflow = 'hidden';
|
||||||
|
elemToToggle.style.transition = 'all ease-in-out 240ms';
|
||||||
|
|
||||||
|
let transitionEndBound = onTransitionEnd.bind(this);
|
||||||
|
function onTransitionEnd() {
|
||||||
|
elemToToggle.style.overflow = '';
|
||||||
|
elemToToggle.style.height = '';
|
||||||
|
elemToToggle.style.transition = '';
|
||||||
|
elemToToggle.style.display = 'none';
|
||||||
|
elemToToggle.removeEventListener('transitionend', transitionEndBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
elemToToggle.style.height = `0px`;
|
||||||
|
elemToToggle.addEventListener('transitionend', transitionEndBound)
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
click(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
let matchingElems = document.querySelectorAll(this.selector);
|
||||||
|
for (let i = 0, len = matchingElems.length; i < len; i++) {
|
||||||
|
this.isOpen ? this.close(matchingElems[i]) : this.open(matchingElems[i]);
|
||||||
|
}
|
||||||
|
this.isOpen = !this.isOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ExpandToggle;
|
|
@ -1,6 +1,11 @@
|
||||||
|
|
||||||
let componentMapping = {
|
let componentMapping = {
|
||||||
'dropdown': require('./dropdown'),
|
'dropdown': require('./dropdown'),
|
||||||
|
'overlay': require('./overlay'),
|
||||||
|
'back-to-top': require('./back-top-top'),
|
||||||
|
'notification': require('./notification'),
|
||||||
|
'chapter-toggle': require('./chapter-toggle'),
|
||||||
|
'expand-toggle': require('./expand-toggle'),
|
||||||
};
|
};
|
||||||
|
|
||||||
window.components = {};
|
window.components = {};
|
||||||
|
|
40
resources/assets/js/components/notification.js
Normal file
40
resources/assets/js/components/notification.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
class Notification {
|
||||||
|
|
||||||
|
constructor(elem) {
|
||||||
|
this.elem = elem;
|
||||||
|
this.type = elem.getAttribute('notification');
|
||||||
|
this.textElem = elem.querySelector('span');
|
||||||
|
this.autohide = this.elem.hasAttribute('data-autohide');
|
||||||
|
window.Events.listen(this.type, text => {
|
||||||
|
console.log('show', text);
|
||||||
|
this.show(text);
|
||||||
|
});
|
||||||
|
elem.addEventListener('click', this.hide.bind(this));
|
||||||
|
if (elem.hasAttribute('data-show')) this.show(this.textElem.textContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
show(textToShow = '') {
|
||||||
|
this.textElem.textContent = textToShow;
|
||||||
|
this.elem.style.display = 'block';
|
||||||
|
setTimeout(() => {
|
||||||
|
this.elem.classList.add('showing');
|
||||||
|
}, 1);
|
||||||
|
|
||||||
|
if (this.autohide) setTimeout(this.hide.bind(this), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.elem.classList.remove('showing');
|
||||||
|
|
||||||
|
function transitionEnd() {
|
||||||
|
this.elem.style.display = 'none';
|
||||||
|
this.elem.removeEventListener('transitionend', transitionEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.elem.addEventListener('transitionend', transitionEnd.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Notification;
|
39
resources/assets/js/components/overlay.js
Normal file
39
resources/assets/js/components/overlay.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
class Overlay {
|
||||||
|
|
||||||
|
constructor(elem) {
|
||||||
|
this.container = elem;
|
||||||
|
elem.addEventListener('click', event => {
|
||||||
|
if (event.target === elem) return this.hide();
|
||||||
|
});
|
||||||
|
let closeButtons = elem.querySelectorAll('.overlay-close');
|
||||||
|
for (let i=0; i < closeButtons.length; i++) {
|
||||||
|
closeButtons[i].addEventListener('click', this.hide.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle(show = true) {
|
||||||
|
let start = Date.now();
|
||||||
|
let duration = 240;
|
||||||
|
|
||||||
|
function setOpacity() {
|
||||||
|
let elapsedTime = (Date.now() - start);
|
||||||
|
let targetOpacity = show ? (elapsedTime / duration) : 1-(elapsedTime / duration);
|
||||||
|
this.container.style.opacity = targetOpacity;
|
||||||
|
if (elapsedTime > duration) {
|
||||||
|
this.container.style.display = show ? 'display' : 'none';
|
||||||
|
this.container.style.opacity = '';
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(setOpacity.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(setOpacity.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() { this.toggle(false); }
|
||||||
|
show() { this.toggle(true); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Overlay;
|
|
@ -713,6 +713,7 @@ module.exports = function (ngApp, events) {
|
||||||
function hide() {
|
function hide() {
|
||||||
element.fadeOut(240);
|
element.fadeOut(240);
|
||||||
}
|
}
|
||||||
|
scope.hide = hide;
|
||||||
|
|
||||||
// Listen to confirmation of entity selections (doubleclick)
|
// Listen to confirmation of entity selections (doubleclick)
|
||||||
events.listen('entity-select-confirm', entity => {
|
events.listen('entity-select-confirm', entity => {
|
||||||
|
|
|
@ -19,12 +19,8 @@ let axiosInstance = axios.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
window.$http = axiosInstance;
|
window.$http = axiosInstance;
|
||||||
|
|
||||||
Vue.prototype.$http = axiosInstance;
|
Vue.prototype.$http = axiosInstance;
|
||||||
|
|
||||||
require("./vues/vues");
|
|
||||||
require("./components");
|
|
||||||
|
|
||||||
|
|
||||||
// AngularJS - Create application and load components
|
// AngularJS - Create application and load components
|
||||||
const angular = require("angular");
|
const angular = require("angular");
|
||||||
|
@ -67,6 +63,9 @@ class EventManager {
|
||||||
window.Events = new EventManager();
|
window.Events = new EventManager();
|
||||||
Vue.prototype.$events = window.Events;
|
Vue.prototype.$events = window.Events;
|
||||||
|
|
||||||
|
require("./vues/vues");
|
||||||
|
require("./components");
|
||||||
|
|
||||||
// Load in angular specific items
|
// Load in angular specific items
|
||||||
const Services = require('./services');
|
const Services = require('./services');
|
||||||
const Directives = require('./directives');
|
const Directives = require('./directives');
|
||||||
|
@ -93,83 +92,11 @@ jQuery.expr[":"].contains = $.expr.createPseudo(function (arg) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Global jQuery Elements
|
|
||||||
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
|
// Detect IE for css
|
||||||
if(navigator.userAgent.indexOf('MSIE')!==-1
|
if(navigator.userAgent.indexOf('MSIE')!==-1
|
||||||
|| navigator.appVersion.indexOf('Trident/') > 0
|
|| navigator.appVersion.indexOf('Trident/') > 0
|
||||||
|| navigator.userAgent.indexOf('Safari') !== -1){
|
|| navigator.userAgent.indexOf('Safari') !== -1){
|
||||||
$('body').addClass('flexbox-support');
|
document.body.classList.add('flexbox-support');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Page specific items
|
// Page specific items
|
||||||
|
|
|
@ -36,41 +36,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.anim.notification {
|
.anim.menuIn {
|
||||||
transform: translate3d(580px, 0, 0);
|
transform-origin: 100% 0%;
|
||||||
animation-name: notification;
|
animation-name: menuIn;
|
||||||
animation-duration: 3s;
|
animation-duration: 120ms;
|
||||||
animation-timing-function: ease-in-out;
|
animation-delay: 0s;
|
||||||
animation-fill-mode: forwards;
|
animation-timing-function: cubic-bezier(.62, .28, .23, .99);
|
||||||
&.stopped {
|
|
||||||
animation-name: notificationStopped;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes notification {
|
|
||||||
0% {
|
|
||||||
transform: translate3d(580px, 0, 0);
|
|
||||||
}
|
|
||||||
10% {
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
90% {
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate3d(580px, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes notificationStopped {
|
|
||||||
0% {
|
|
||||||
transform: translate3d(580px, 0, 0);
|
|
||||||
}
|
|
||||||
10% {
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes menuIn {
|
@keyframes menuIn {
|
||||||
|
@ -85,14 +56,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.anim.menuIn {
|
|
||||||
transform-origin: 100% 0%;
|
|
||||||
animation-name: menuIn;
|
|
||||||
animation-duration: 120ms;
|
|
||||||
animation-delay: 0s;
|
|
||||||
animation-timing-function: cubic-bezier(.62, .28, .23, .99);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes loadingBob {
|
@keyframes loadingBob {
|
||||||
0% {
|
0% {
|
||||||
transform: translate3d(0, 0, 0);
|
transform: translate3d(0, 0, 0);
|
||||||
|
|
|
@ -1,4 +1,65 @@
|
||||||
.overlay {
|
// System wide notifications
|
||||||
|
[notification] {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: $-xl*2 $-xl;
|
||||||
|
padding: $-l $-xl;
|
||||||
|
background-color: #EEE;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: $bs-med;
|
||||||
|
z-index: 999999;
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
max-width: 480px;
|
||||||
|
transition: transform ease-in-out 360ms;
|
||||||
|
transform: translate3d(580px, 0, 0);
|
||||||
|
i, span {
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
font-size: 2em;
|
||||||
|
padding-right: $-l;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
&.pos {
|
||||||
|
background-color: $positive;
|
||||||
|
color: #EEE;
|
||||||
|
}
|
||||||
|
&.neg {
|
||||||
|
background-color: $negative;
|
||||||
|
color: #EEE;
|
||||||
|
}
|
||||||
|
&.warning {
|
||||||
|
background-color: $secondary;
|
||||||
|
color: #EEE;
|
||||||
|
}
|
||||||
|
&.showing {
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[chapter-toggle] {
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 0;
|
||||||
|
transition: all ease-in-out 180ms;
|
||||||
|
user-select: none;
|
||||||
|
i.zmdi-caret-right {
|
||||||
|
transition: all ease-in-out 180ms;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
transform-origin: 25% 50%;
|
||||||
|
}
|
||||||
|
&.open {
|
||||||
|
//margin-bottom: 0;
|
||||||
|
}
|
||||||
|
&.open i.zmdi-caret-right {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[overlay] {
|
||||||
background-color: rgba(0, 0, 0, 0.333);
|
background-color: rgba(0, 0, 0, 0.333);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 95536;
|
z-index: 95536;
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
.inset-list {
|
.inset-list {
|
||||||
display: none;
|
display: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-bottom: $-l;
|
|
||||||
}
|
}
|
||||||
h5 {
|
h5 {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -22,6 +21,9 @@
|
||||||
border-left-color: $color-page-draft;
|
border-left-color: $color-page-draft;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.entity-list-item {
|
||||||
|
margin-bottom: $-m;
|
||||||
|
}
|
||||||
hr {
|
hr {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
@ -51,23 +53,6 @@
|
||||||
margin-right: $-s;
|
margin-right: $-s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.chapter-toggle {
|
|
||||||
cursor: pointer;
|
|
||||||
margin: 0 0 $-l 0;
|
|
||||||
transition: all ease-in-out 180ms;
|
|
||||||
user-select: none;
|
|
||||||
i.zmdi-caret-right {
|
|
||||||
transition: all ease-in-out 180ms;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
transform-origin: 25% 50%;
|
|
||||||
}
|
|
||||||
&.open {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
&.open i.zmdi-caret-right {
|
|
||||||
transform: rotate(90deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-page-nav {
|
.sidebar-page-nav {
|
||||||
$nav-indent: $-s;
|
$nav-indent: $-s;
|
||||||
|
@ -171,7 +156,7 @@
|
||||||
background-color: rgba($color-chapter, 0.12);
|
background-color: rgba($color-chapter, 0.12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.chapter-toggle {
|
[chapter-toggle] {
|
||||||
padding-left: $-s;
|
padding-left: $-s;
|
||||||
}
|
}
|
||||||
.list-item-chapter {
|
.list-item-chapter {
|
||||||
|
@ -336,8 +321,10 @@ ul.pagination {
|
||||||
h4, a {
|
h4, a {
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
p {
|
.entity-item-snippet {
|
||||||
display: none;
|
display: none;
|
||||||
|
}
|
||||||
|
p {
|
||||||
font-size: $fs-m * 0.8;
|
font-size: $fs-m * 0.8;
|
||||||
padding-top: $-xs;
|
padding-top: $-xs;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
|
@ -66,44 +66,6 @@ body.dragging, body.dragging * {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// System wide notifications
|
|
||||||
.notification {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: $-xl*2 $-xl;
|
|
||||||
padding: $-l $-xl;
|
|
||||||
background-color: #EEE;
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: $bs-med;
|
|
||||||
z-index: 999999;
|
|
||||||
display: block;
|
|
||||||
cursor: pointer;
|
|
||||||
max-width: 480px;
|
|
||||||
i, span {
|
|
||||||
display: table-cell;
|
|
||||||
}
|
|
||||||
i {
|
|
||||||
font-size: 2em;
|
|
||||||
padding-right: $-l;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
&.pos {
|
|
||||||
background-color: $positive;
|
|
||||||
color: #EEE;
|
|
||||||
}
|
|
||||||
&.neg {
|
|
||||||
background-color: $negative;
|
|
||||||
color: #EEE;
|
|
||||||
}
|
|
||||||
&.warning {
|
|
||||||
background-color: $secondary;
|
|
||||||
color: #EEE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loading icon
|
// Loading icon
|
||||||
$loadingSize: 10px;
|
$loadingSize: 10px;
|
||||||
.loading-container {
|
.loading-container {
|
||||||
|
@ -151,7 +113,7 @@ $loadingSize: 10px;
|
||||||
|
|
||||||
// Back to top link
|
// Back to top link
|
||||||
$btt-size: 40px;
|
$btt-size: 40px;
|
||||||
#back-to-top {
|
[back-to-top] {
|
||||||
background-color: $primary;
|
background-color: $primary;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: $-m;
|
bottom: $-m;
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div id="back-to-top">
|
<div back-to-top>
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<i class="zmdi zmdi-chevron-up"></i> <span>{{ trans('common.back_to_top') }}</span>
|
<i class="zmdi zmdi-chevron-up"></i> <span>{{ trans('common.back_to_top') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
<div class="book entity-list-item" data-entity-type="book" data-entity-id="{{$book->id}}">
|
<div class="book entity-list-item" data-entity-type="book" data-entity-id="{{$book->id}}">
|
||||||
<h4 class="text-book"><a class="text-book entity-list-item-link" href="{{$book->getUrl()}}"><i class="zmdi zmdi-book"></i><span class="entity-list-item-name">{{$book->name}}</span></a></h4>
|
<h4 class="text-book"><a class="text-book entity-list-item-link" href="{{$book->getUrl()}}"><i class="zmdi zmdi-book"></i><span class="entity-list-item-name">{{$book->name}}</span></a></h4>
|
||||||
@if(isset($book->searchSnippet))
|
<div class="entity-item-snippet">
|
||||||
<p class="text-muted">{!! $book->searchSnippet !!}</p>
|
@if(isset($book->searchSnippet))
|
||||||
@else
|
<p class="text-muted">{!! $book->searchSnippet !!}</p>
|
||||||
<p class="text-muted">{{ $book->getExcerpt() }}</p>
|
@else
|
||||||
@endif
|
<p class="text-muted">{{ $book->getExcerpt() }}</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -10,14 +10,18 @@
|
||||||
<i class="zmdi zmdi-collection-bookmark"></i><span class="entity-list-item-name">{{ $chapter->name }}</span>
|
<i class="zmdi zmdi-collection-bookmark"></i><span class="entity-list-item-name">{{ $chapter->name }}</span>
|
||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
@if(isset($chapter->searchSnippet))
|
|
||||||
<p class="text-muted">{!! $chapter->searchSnippet !!}</p>
|
<div class="entity-item-snippet">
|
||||||
@else
|
@if(isset($chapter->searchSnippet))
|
||||||
<p class="text-muted">{{ $chapter->getExcerpt() }}</p>
|
<p class="text-muted">{!! $chapter->searchSnippet !!}</p>
|
||||||
@endif
|
@else
|
||||||
|
<p class="text-muted">{{ $chapter->getExcerpt() }}</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@if(!isset($hidePages) && count($chapter->pages) > 0)
|
@if(!isset($hidePages) && count($chapter->pages) > 0)
|
||||||
<p class="text-muted chapter-toggle"><i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ trans('entities.x_pages', ['count' => $chapter->pages->count()]) }}</span></p>
|
<p chapter-toggle class="text-muted"><i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ trans('entities.x_pages', ['count' => $chapter->pages->count()]) }}</span></p>
|
||||||
<div class="inset-list">
|
<div class="inset-list">
|
||||||
@foreach($chapter->pages as $page)
|
@foreach($chapter->pages as $page)
|
||||||
<h5 class="@if($page->draft) draft @endif"><a href="{{ $page->getUrl() }}" class="text-page @if($page->draft) draft @endif"><i class="zmdi zmdi-file-text"></i>{{$page->name}}</a></h5>
|
<h5 class="@if($page->draft) draft @endif"><a href="{{ $page->getUrl() }}" class="text-page @if($page->draft) draft @endif"><i class="zmdi zmdi-file-text"></i>{{$page->name}}</a></h5>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<div id="code-editor">
|
<div id="code-editor">
|
||||||
<div class="overlay" ref="overlay" v-cloak @click="hide()">
|
<div overlay ref="overlay" v-cloak @click="hide()">
|
||||||
<div class="popup-body" @click.stop>
|
<div class="popup-body" @click.stop>
|
||||||
|
|
||||||
<div class="popup-header primary-background">
|
<div class="popup-header primary-background">
|
||||||
<div class="popup-title">{{ trans('components.code_editor') }}</div>
|
<div class="popup-title">{{ trans('components.code_editor') }}</div>
|
||||||
<button class="popup-close neg corner-button button" @click="hide()">x</button>
|
<button class="overlay-close neg corner-button button" @click="hide()">x</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="padded">
|
<div class="padded">
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<div id="entity-selector-wrap">
|
<div id="entity-selector-wrap">
|
||||||
<div class="overlay" entity-link-selector>
|
<div overlay entity-link-selector>
|
||||||
<div class="popup-body small flex-child">
|
<div class="popup-body small flex-child">
|
||||||
<div class="popup-header primary-background">
|
<div class="popup-header primary-background">
|
||||||
<div class="popup-title">{{ trans('entities.entity_select') }}</div>
|
<div class="popup-title">{{ trans('entities.entity_select') }}</div>
|
||||||
<button type="button" class="corner-button neg button popup-close">x</button>
|
<button type="button" class="corner-button neg button overlay-close">x</button>
|
||||||
</div>
|
</div>
|
||||||
@include('components.entity-selector', ['name' => 'entity-selector'])
|
@include('components.entity-selector', ['name' => 'entity-selector'])
|
||||||
<div class="popup-footer">
|
<div class="popup-footer">
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<div id="image-manager" image-type="{{ $imageType }}" ng-controller="ImageManagerController" uploaded-to="{{ $uploaded_to or 0 }}">
|
<div id="image-manager" image-type="{{ $imageType }}" ng-controller="ImageManagerController" uploaded-to="{{ $uploaded_to or 0 }}">
|
||||||
<div class="overlay" ng-cloak ng-click="hide()">
|
<div overlay ng-cloak ng-click="hide()">
|
||||||
<div class="popup-body" ng-click="$event.stopPropagation()">
|
<div class="popup-body" ng-click="$event.stopPropagation()">
|
||||||
|
|
||||||
<div class="popup-header primary-background">
|
<div class="popup-header primary-background">
|
||||||
<div class="popup-title">{{ trans('components.image_select') }}</div>
|
<div class="popup-title">{{ trans('components.image_select') }}</div>
|
||||||
<button class="popup-close neg corner-button button">x</button>
|
<button class="overlay-close neg corner-button button">x</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-fill image-manager-body">
|
<div class="flex-fill image-manager-body">
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 faded">
|
<div class="col-sm-6 faded">
|
||||||
<div class="action-buttons text-left">
|
<div class="action-buttons text-left">
|
||||||
<a data-action="expand-entity-list-details" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>{{ trans('common.toggle_details') }}</a>
|
<a expand-toggle=".entity-list.compact .entity-item-snippet" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>{{ trans('common.toggle_details') }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,11 +15,13 @@
|
||||||
<a href="{{ $page->getUrl() }}" class="text-page entity-list-item-link"><i class="zmdi zmdi-file-text"></i><span class="entity-list-item-name">{{ $page->name }}</span></a>
|
<a href="{{ $page->getUrl() }}" class="text-page entity-list-item-link"><i class="zmdi zmdi-file-text"></i><span class="entity-list-item-name">{{ $page->name }}</span></a>
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
@if(isset($page->searchSnippet))
|
<div class="entity-item-snippet">
|
||||||
<p class="text-muted">{!! $page->searchSnippet !!}</p>
|
@if(isset($page->searchSnippet))
|
||||||
@else
|
<p class="text-muted">{!! $page->searchSnippet !!}</p>
|
||||||
<p class="text-muted">{{ $page->getExcerpt() }}</p>
|
@else
|
||||||
@endif
|
<p class="text-muted">{{ $page->getExcerpt() }}</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
@if(isset($style) && $style === 'detailed')
|
@if(isset($style) && $style === 'detailed')
|
||||||
<div class="row meta text-muted text-small">
|
<div class="row meta text-muted text-small">
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@if($bookChild->isA('chapter') && count($bookChild->pages) > 0)
|
@if($bookChild->isA('chapter') && count($bookChild->pages) > 0)
|
||||||
<p class="text-muted chapter-toggle @if($bookChild->matchesOrContains($current)) open @endif">
|
<p chapter-toggle class="text-muted @if($bookChild->matchesOrContains($current)) open @endif">
|
||||||
<i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ trans('entities.x_pages', ['count' => $bookChild->pages->count()]) }}</span>
|
<i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ trans('entities.x_pages', ['count' => $bookChild->pages->count()]) }}</span>
|
||||||
</p>
|
</p>
|
||||||
<ul class="menu sub-menu inset-list @if($bookChild->matchesOrContains($current)) open @endif">
|
<ul class="menu sub-menu inset-list @if($bookChild->matchesOrContains($current)) open @endif">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<style id="custom-styles" data-color="{{ setting('app-color') }}" data-color-light="{{ setting('app-color-light') }}">
|
<style id="custom-styles" data-color="{{ setting('app-color') }}" data-color-light="{{ setting('app-color-light') }}">
|
||||||
header, #back-to-top, .primary-background {
|
header, [back-to-top], .primary-background {
|
||||||
background-color: {{ setting('app-color') }} !important;
|
background-color: {{ setting('app-color') }} !important;
|
||||||
}
|
}
|
||||||
.faded-small, .primary-background-light {
|
.faded-small, .primary-background-light {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
|
||||||
<div class="notification anim pos" @if(!session()->has('success')) style="display:none;" @endif>
|
<div notification="success" data-autohide class="pos" @if(session()->has('success')) data-show @endif>
|
||||||
<i class="zmdi zmdi-check-circle"></i> <span>{!! nl2br(htmlentities(session()->get('success'))) !!}</span>
|
<i class="zmdi zmdi-check-circle"></i> <span>{!! nl2br(htmlentities(session()->get('success'))) !!}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notification anim warning stopped" @if(!session()->has('warning')) style="display:none;" @endif>
|
<div notification="warning" class="warning" @if(session()->has('warning')) data-show @endif>
|
||||||
<i class="zmdi zmdi-info"></i> <span>{!! nl2br(htmlentities(session()->get('warning'))) !!}</span>
|
<i class="zmdi zmdi-info"></i> <span>{!! nl2br(htmlentities(session()->get('warning'))) !!}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notification anim neg stopped" @if(!session()->has('error')) style="display:none;" @endif>
|
<div notification="error" class="neg" @if(session()->has('error')) data-show @endif>
|
||||||
<i class="zmdi zmdi-alert-circle"></i> <span>{!! nl2br(htmlentities(session()->get('error'))) !!}</span>
|
<i class="zmdi zmdi-alert-circle"></i> <span>{!! nl2br(htmlentities(session()->get('error'))) !!}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue