1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-08-09 10:22:51 +03:00
This commit is contained in:
Abijeet
2017-04-19 01:23:27 +05:30
60 changed files with 2352 additions and 638 deletions

View File

@@ -1,12 +1,12 @@
"use strict";
import moment from 'moment';
import 'moment/locale/en-gb';
import editorOptions from "./pages/page-form";
const moment = require('moment');
require('moment/locale/en-gb');
const editorOptions = require("./pages/page-form");
moment.locale('en-gb');
export default function (ngApp, events) {
module.exports = function (ngApp, events) {
ngApp.controller('ImageManagerController', ['$scope', '$attrs', '$http', '$timeout', 'imageManagerService',
function ($scope, $attrs, $http, $timeout, imageManagerService) {
@@ -259,39 +259,6 @@ export default function (ngApp, events) {
}]);
ngApp.controller('BookShowController', ['$scope', '$http', '$attrs', '$sce', function ($scope, $http, $attrs, $sce) {
$scope.searching = false;
$scope.searchTerm = '';
$scope.searchResults = '';
$scope.searchBook = function (e) {
e.preventDefault();
let term = $scope.searchTerm;
if (term.length == 0) return;
$scope.searching = true;
$scope.searchResults = '';
let searchUrl = window.baseUrl('/search/book/' + $attrs.bookId);
searchUrl += '?term=' + encodeURIComponent(term);
$http.get(searchUrl).then((response) => {
$scope.searchResults = $sce.trustAsHtml(response.data);
});
};
$scope.checkSearchForm = function () {
if ($scope.searchTerm.length < 1) {
$scope.searching = false;
}
};
$scope.clearSearch = function () {
$scope.searching = false;
$scope.searchTerm = '';
};
}]);
ngApp.controller('PageEditController', ['$scope', '$http', '$attrs', '$interval', '$timeout', '$sce',
function ($scope, $http, $attrs, $interval, $timeout, $sce) {

View File

@@ -1,8 +1,9 @@
"use strict";
import DropZone from "dropzone";
import markdown from "marked";
const DropZone = require("dropzone");
const MarkdownIt = require("markdown-it");
const mdTasksLists = require('markdown-it-task-lists');
export default function (ngApp, events) {
module.exports = function (ngApp, events) {
/**
* Common tab controls using simple jQuery functions.
@@ -214,18 +215,8 @@ export default function (ngApp, events) {
}
}]);
let renderer = new markdown.Renderer();
// Custom markdown checkbox list item
// Attribution: https://github.com/chjj/marked/issues/107#issuecomment-44542001
renderer.listitem = function(text) {
if (/^\s*\[[x ]\]\s*/.test(text)) {
text = text
.replace(/^\s*\[ \]\s*/, '<input type="checkbox"/>')
.replace(/^\s*\[x\]\s*/, '<input type="checkbox" checked/>');
return `<li class="checkbox-item">${text}</li>`;
}
return `<li>${text}</li>`;
};
const md = new MarkdownIt();
md.use(mdTasksLists, {label: true});
/**
* Markdown input
@@ -244,20 +235,20 @@ export default function (ngApp, events) {
element = element.find('textarea').first();
let content = element.val();
scope.mdModel = content;
scope.mdChange(markdown(content, {renderer: renderer}));
scope.mdChange(md.render(content));
element.on('change input', (event) => {
content = element.val();
$timeout(() => {
scope.mdModel = content;
scope.mdChange(markdown(content, {renderer: renderer}));
scope.mdChange(md.render(content));
});
});
scope.$on('markdown-update', (event, value) => {
element.val(value);
scope.mdModel = value;
scope.mdChange(markdown(value));
scope.mdChange(md.render(value));
});
}

View File

@@ -1,12 +1,5 @@
"use strict";
// AngularJS - Create application and load components
import angular from "angular";
import "angular-resource";
import "angular-animate";
import "angular-sanitize";
import "angular-ui-sortable";
// Url retrieval function
window.baseUrl = function(path) {
let basePath = document.querySelector('meta[name="base-url"]').getAttribute('content');
@@ -15,11 +8,33 @@ window.baseUrl = function(path) {
return basePath + '/' + path;
};
const Vue = require("vue");
const axios = require("axios");
let axiosInstance = axios.create({
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name=token]').getAttribute('content'),
'baseURL': window.baseUrl('')
}
});
Vue.prototype.$http = axiosInstance;
require("./vues/vues");
// AngularJS - Create application and load components
const angular = require("angular");
require("angular-resource");
require("angular-animate");
require("angular-sanitize");
require("angular-ui-sortable");
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"
const Translations = require("./translations");
let translator = new Translations(window.translations);
window.trans = translator.get.bind(translator);
@@ -47,11 +62,12 @@ class EventManager {
}
window.Events = new EventManager();
Vue.prototype.$events = window.Events;
// Load in angular specific items
import Services from './services';
import Directives from './directives';
import Controllers from './controllers';
const Services = require('./services');
const Directives = require('./directives');
const Controllers = require('./controllers');
Services(ngApp, window.Events);
Directives(ngApp, window.Events);
Controllers(ngApp, window.Events);
@@ -154,4 +170,4 @@ if(navigator.userAgent.indexOf('MSIE')!==-1
}
// Page specific items
import "./pages/page-show";
require("./pages/page-show");

View File

@@ -60,7 +60,7 @@ function registerEditorShortcuts(editor) {
editor.addShortcut('meta+shift+E', '', ['FormatBlock', false, 'code']);
}
export default function() {
module.exports = function() {
let settings = {
selector: '#html-editor',
content_css: [
@@ -68,6 +68,7 @@ export default function() {
window.baseUrl('/libs/material-design-iconic-font/css/material-design-iconic-font.min.css')
],
body_class: 'page-content',
browser_spellcheck: true,
relative_urls: false,
remove_script_host: false,
document_base_url: window.baseUrl('/'),
@@ -213,4 +214,4 @@ export default function() {
}
};
return settings;
}
};

View File

@@ -1,8 +1,8 @@
"use strict";
// Configure ZeroClipboard
import Clipboard from "clipboard";
const Clipboard = require("clipboard");
export default window.setupPageShow = function (pageId) {
let setupPageShow = window.setupPageShow = function (pageId) {
// Set up pointer
let $pointer = $('#pointer').detach();
@@ -81,6 +81,12 @@ export default window.setupPageShow = function (pageId) {
let $idElem = $(idElem);
let color = $('#custom-styles').attr('data-color-light');
$idElem.css('background-color', color).attr('data-highlighted', 'true').smoothScrollTo();
setTimeout(() => {
$idElem.addClass('anim').addClass('selectFade').css('background-color', '');
setTimeout(() => {
$idElem.removeClass('selectFade');
}, 3000);
}, 100);
} else {
$('.page-content').find(':contains("' + text + '")').smoothScrollTo();
}
@@ -151,3 +157,5 @@ export default window.setupPageShow = function (pageId) {
});
};
module.exports = setupPageShow;

View File

@@ -44,4 +44,4 @@ class Translator {
}
export default Translator
module.exports = Translator;

View File

@@ -0,0 +1,44 @@
let data = {
id: null,
type: '',
searching: false,
searchTerm: '',
searchResults: '',
};
let computed = {
};
let methods = {
searchBook() {
if (this.searchTerm.trim().length === 0) return;
this.searching = true;
this.searchResults = '';
let url = window.baseUrl(`/search/${this.type}/${this.id}`);
url += `?term=${encodeURIComponent(this.searchTerm)}`;
this.$http.get(url).then(resp => {
this.searchResults = resp.data;
});
},
checkSearchForm() {
this.searching = this.searchTerm > 0;
},
clearSearch() {
this.searching = false;
this.searchTerm = '';
}
};
function mounted() {
this.id = Number(this.$el.getAttribute('entity-id'));
this.type = this.$el.getAttribute('entity-type');
}
module.exports = {
data, computed, methods, mounted
};

View File

@@ -0,0 +1,195 @@
const moment = require('moment');
let data = {
terms: '',
termString : '',
search: {
type: {
page: true,
chapter: true,
book: true
},
exactTerms: [],
tagTerms: [],
option: {},
dates: {
updated_after: false,
updated_before: false,
created_after: false,
created_before: false,
}
}
};
let computed = {
};
let methods = {
appendTerm(term) {
this.termString += ' ' + term;
this.termString = this.termString.replace(/\s{2,}/g, ' ');
this.termString = this.termString.replace(/^\s+/, '');
this.termString = this.termString.replace(/\s+$/, '');
},
exactParse(searchString) {
this.search.exactTerms = [];
let exactFilter = /"(.+?)"/g;
let matches;
while ((matches = exactFilter.exec(searchString)) !== null) {
this.search.exactTerms.push(matches[1]);
}
},
exactChange() {
let exactFilter = /"(.+?)"/g;
this.termString = this.termString.replace(exactFilter, '');
let matchesTerm = this.search.exactTerms.filter(term => {
return term.trim() !== '';
}).map(term => {
return `"${term}"`
}).join(' ');
this.appendTerm(matchesTerm);
},
addExact() {
this.search.exactTerms.push('');
setTimeout(() => {
let exactInputs = document.querySelectorAll('.exact-input');
exactInputs[exactInputs.length - 1].focus();
}, 100);
},
removeExact(index) {
this.search.exactTerms.splice(index, 1);
this.exactChange();
},
tagParse(searchString) {
this.search.tagTerms = [];
let tagFilter = /\[(.+?)\]/g;
let matches;
while ((matches = tagFilter.exec(searchString)) !== null) {
this.search.tagTerms.push(matches[1]);
}
},
tagChange() {
let tagFilter = /\[(.+?)\]/g;
this.termString = this.termString.replace(tagFilter, '');
let matchesTerm = this.search.tagTerms.filter(term => {
return term.trim() !== '';
}).map(term => {
return `[${term}]`
}).join(' ');
this.appendTerm(matchesTerm);
},
addTag() {
this.search.tagTerms.push('');
setTimeout(() => {
let tagInputs = document.querySelectorAll('.tag-input');
tagInputs[tagInputs.length - 1].focus();
}, 100);
},
removeTag(index) {
this.search.tagTerms.splice(index, 1);
this.tagChange();
},
typeParse(searchString) {
let typeFilter = /{\s?type:\s?(.*?)\s?}/;
let match = searchString.match(typeFilter);
let type = this.search.type;
if (!match) {
type.page = type.book = type.chapter = true;
return;
}
let splitTypes = match[1].replace(/ /g, '').split('|');
type.page = (splitTypes.indexOf('page') !== -1);
type.chapter = (splitTypes.indexOf('chapter') !== -1);
type.book = (splitTypes.indexOf('book') !== -1);
},
typeChange() {
let typeFilter = /{\s?type:\s?(.*?)\s?}/;
let type = this.search.type;
if (type.page === type.chapter && type.page === type.book) {
this.termString = this.termString.replace(typeFilter, '');
return;
}
let selectedTypes = Object.keys(type).filter(type => {return this.search.type[type];}).join('|');
let typeTerm = '{type:'+selectedTypes+'}';
if (this.termString.match(typeFilter)) {
this.termString = this.termString.replace(typeFilter, typeTerm);
return;
}
this.appendTerm(typeTerm);
},
optionParse(searchString) {
let optionFilter = /{([a-z_\-:]+?)}/gi;
let matches;
while ((matches = optionFilter.exec(searchString)) !== null) {
this.search.option[matches[1].toLowerCase()] = true;
}
},
optionChange(optionName) {
let isChecked = this.search.option[optionName];
if (isChecked) {
this.appendTerm(`{${optionName}}`);
} else {
this.termString = this.termString.replace(`{${optionName}}`, '');
}
},
updateSearch(e) {
e.preventDefault();
window.location = '/search?term=' + encodeURIComponent(this.termString);
},
enableDate(optionName) {
this.search.dates[optionName.toLowerCase()] = moment().format('YYYY-MM-DD');
this.dateChange(optionName);
},
dateParse(searchString) {
let dateFilter = /{([a-z_\-]+?):([a-z_\-0-9]+?)}/gi;
let dateTags = Object.keys(this.search.dates);
let matches;
while ((matches = dateFilter.exec(searchString)) !== null) {
if (dateTags.indexOf(matches[1]) === -1) continue;
this.search.dates[matches[1].toLowerCase()] = matches[2];
}
},
dateChange(optionName) {
let dateFilter = new RegExp('{\\s?'+optionName+'\\s?:([a-z_\\-0-9]+?)}', 'gi');
this.termString = this.termString.replace(dateFilter, '');
if (!this.search.dates[optionName]) return;
this.appendTerm(`{${optionName}:${this.search.dates[optionName]}}`);
},
dateRemove(optionName) {
this.search.dates[optionName] = false;
this.dateChange(optionName);
}
};
function created() {
this.termString = document.querySelector('[name=searchTerm]').value;
this.typeParse(this.termString);
this.exactParse(this.termString);
this.tagParse(this.termString);
this.optionParse(this.termString);
this.dateParse(this.termString);
}
module.exports = {
data, computed, methods, created
};

View File

@@ -0,0 +1,18 @@
const Vue = require("vue");
function exists(id) {
return document.getElementById(id) !== null;
}
let vueMapping = {
'search-system': require('./search'),
'entity-dashboard': require('./entity-search'),
};
Object.keys(vueMapping).forEach(id => {
if (exists(id)) {
let config = vueMapping[id];
config.el = '#' + id;
new Vue(config);
}
});