mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-23 15:19:58 +08:00
Added vanilla JS component system
This commit is contained in:
@ -31,6 +31,7 @@
|
|||||||
"angular-sanitize": "^1.5.5",
|
"angular-sanitize": "^1.5.5",
|
||||||
"angular-ui-sortable": "^0.17.0",
|
"angular-ui-sortable": "^0.17.0",
|
||||||
"axios": "^0.16.1",
|
"axios": "^0.16.1",
|
||||||
|
"babel-polyfill": "^6.23.0",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"clipboard": "^1.5.16",
|
"clipboard": "^1.5.16",
|
||||||
"codemirror": "^5.26.0",
|
"codemirror": "^5.26.0",
|
||||||
|
48
resources/assets/js/components/dropdown.js
Normal file
48
resources/assets/js/components/dropdown.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Dropdown
|
||||||
|
* Provides some simple logic to create simple dropdown menus.
|
||||||
|
*/
|
||||||
|
class DropDown {
|
||||||
|
|
||||||
|
constructor(elem) {
|
||||||
|
this.container = elem;
|
||||||
|
this.menu = elem.querySelector('ul');
|
||||||
|
this.toggle = elem.querySelector('[dropdown-toggle]');
|
||||||
|
this.setupListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
this.menu.style.display = 'block';
|
||||||
|
this.menu.classList.add('anim', 'menuIn');
|
||||||
|
this.container.addEventListener('mouseleave', this.hide.bind(this));
|
||||||
|
|
||||||
|
// Focus on first input if existing
|
||||||
|
let input = this.menu.querySelector('input');
|
||||||
|
if (input !== null) input.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.menu.style.display = 'none';
|
||||||
|
this.menu.classList.remove('anim', 'menuIn');
|
||||||
|
}
|
||||||
|
|
||||||
|
setupListeners() {
|
||||||
|
// Hide menu on option click
|
||||||
|
this.container.addEventListener('click', event => {
|
||||||
|
let possibleChildren = Array.from(this.menu.querySelectorAll('a'));
|
||||||
|
if (possibleChildren.indexOf(event.target) !== -1) this.hide();
|
||||||
|
});
|
||||||
|
// Show dropdown on toggle click
|
||||||
|
this.toggle.addEventListener('click', this.show.bind(this));
|
||||||
|
// Hide menu on enter press
|
||||||
|
this.container.addEventListener('keypress', event => {
|
||||||
|
if (event.keyCode !== 13) return true;
|
||||||
|
event.preventDefault();
|
||||||
|
this.hide();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DropDown;
|
21
resources/assets/js/components/index.js
Normal file
21
resources/assets/js/components/index.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
let componentMapping = {
|
||||||
|
'dropdown': require('./dropdown'),
|
||||||
|
};
|
||||||
|
|
||||||
|
window.components = {};
|
||||||
|
|
||||||
|
let componentNames = Object.keys(componentMapping);
|
||||||
|
|
||||||
|
for (let i = 0, len = componentNames.length; i < len; i++) {
|
||||||
|
let name = componentNames[i];
|
||||||
|
let elems = document.querySelectorAll(`[${name}]`);
|
||||||
|
if (elems.length === 0) continue;
|
||||||
|
|
||||||
|
let component = componentMapping[name];
|
||||||
|
if (typeof window.components[name] === "undefined") window.components[name] = [];
|
||||||
|
for (let j = 0, jLen = elems.length; j < jLen; j++) {
|
||||||
|
let instance = new component(elems[j]);
|
||||||
|
window.components[name].push(instance);
|
||||||
|
}
|
||||||
|
}
|
@ -114,45 +114,6 @@ module.exports = function (ngApp, events) {
|
|||||||
};
|
};
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
/**
|
|
||||||
* Dropdown
|
|
||||||
* Provides some simple logic to create small dropdown menus
|
|
||||||
*/
|
|
||||||
ngApp.directive('dropdown', [function () {
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
link: function (scope, element, attrs) {
|
|
||||||
const menu = element.find('ul');
|
|
||||||
|
|
||||||
function hide() {
|
|
||||||
menu.hide();
|
|
||||||
menu.removeClass('anim menuIn');
|
|
||||||
}
|
|
||||||
|
|
||||||
function show() {
|
|
||||||
menu.show().addClass('anim menuIn');
|
|
||||||
element.mouseleave(hide);
|
|
||||||
|
|
||||||
// Focus on input if exist in dropdown and hide on enter press
|
|
||||||
let inputs = menu.find('input');
|
|
||||||
if (inputs.length > 0) inputs.first().focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide menu on option click
|
|
||||||
element.on('click', '> ul a', hide);
|
|
||||||
// Show dropdown on toggle click.
|
|
||||||
element.find('[dropdown-toggle]').on('click', show);
|
|
||||||
// Hide menu on enter press in inputs
|
|
||||||
element.on('keypress', 'input', event => {
|
|
||||||
if (event.keyCode !== 13) return true;
|
|
||||||
event.preventDefault();
|
|
||||||
hide();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TinyMCE
|
* TinyMCE
|
||||||
* An angular wrapper around the tinyMCE editor.
|
* An angular wrapper around the tinyMCE editor.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
require("babel-polyfill");
|
||||||
|
|
||||||
// Url retrieval function
|
// Url retrieval function
|
||||||
window.baseUrl = function(path) {
|
window.baseUrl = function(path) {
|
||||||
@ -22,6 +23,7 @@ window.$http = axiosInstance;
|
|||||||
Vue.prototype.$http = axiosInstance;
|
Vue.prototype.$http = axiosInstance;
|
||||||
|
|
||||||
require("./vues/vues");
|
require("./vues/vues");
|
||||||
|
require("./components");
|
||||||
|
|
||||||
|
|
||||||
// AngularJS - Create application and load components
|
// AngularJS - Create application and load components
|
||||||
|
Reference in New Issue
Block a user