ace settings

This commit is contained in:
Andy Bunce 2017-09-03 23:26:00 +01:00
parent a9b2bff043
commit f2d20c204f
13 changed files with 623 additions and 300 deletions

View file

@ -85,14 +85,16 @@ function debounce(func, wait, immediate) {
}; };
// https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript // https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
function fullscreen() { const Fullscreen={
var isInFullScreen = (document.fullscreenElement && document.fullscreenElement !== null) || isInFullScreen(){
return (document.fullscreenElement && document.fullscreenElement !== null) ||
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
(document.mozFullScreenElement && document.mozFullScreenElement !== null) || (document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
(document.msFullscreenElement && document.msFullscreenElement !== null); (document.msFullscreenElement && document.msFullscreenElement !== null);
},
toggle(){
var docElm = document.documentElement; var docElm = document.documentElement;
if (!isInFullScreen) { if (!this.isInFullScreen()) {
if (docElm.requestFullscreen) { if (docElm.requestFullscreen) {
docElm.requestFullscreen(); docElm.requestFullscreen();
} else if (docElm.mozRequestFullScreen) { } else if (docElm.mozRequestFullScreen) {
@ -113,7 +115,14 @@ function fullscreen() {
document.msExitFullscreen(); document.msExitFullscreen();
} }
} }
},
install: function(Vue){
Object.defineProperty(Vue.prototype, '$fullscreen', {
get () { return Fullscreen }
}) }
}; };
Vue.use(Fullscreen);
const router = new VueRouter({ const router = new VueRouter({
base:"/vue-poc/ui/", base:"/vue-poc/ui/",
@ -133,7 +142,8 @@ const router = new VueRouter({
{ path: '/tabs', component: Tabs,meta:{title:"tab test",requiresAuth: true} }, { path: '/tabs', component: Tabs,meta:{title:"tab test",requiresAuth: true} },
{ path: '/login', component: Login,meta:{title:"login"} }, { path: '/login', component: Login,meta:{title:"login"} },
{ path: '/edit', component: Edit,meta:{title:"Ace editor"} }, { path: '/edit', component: Edit,meta:{title:"Ace editor"} },
{ path: '/server/users', component: Users,meta:{title:"Users"} },
{ path: '/server/repo', component: Repo,meta:{title:"Repository"} },
{ path: '/files', component: Files,meta:{title:"File system"},props:{protocol:"webfile"} }, { path: '/files', component: Files,meta:{title:"File system"},props:{protocol:"webfile"} },
{ path: '/database', component: Files,meta:{title:"Databases"},props:{protocol:"basexdb"} }, { path: '/database', component: Files,meta:{title:"Databases"},props:{protocol:"basexdb"} },
{ path: '/ping', component: Ping,meta:{title:"Ping"} }, { path: '/ping', component: Ping,meta:{title:"Ping"} },
@ -212,6 +222,8 @@ const app = new Vue({
children: [ children: [
{href: '/jobs',text: 'Running jobs',icon: 'dashboard'}, {href: '/jobs',text: 'Running jobs',icon: 'dashboard'},
{href: '/logs',text: 'Server logs',icon: 'dns'}, {href: '/logs',text: 'Server logs',icon: 'dns'},
{href: '/server/users',text: 'Users',icon: 'supervisor_account'},
{href: '/server/repo',text: 'Server code repository',icon: 'local_library'},
{href: '/ping',text: 'Ping',icon: 'update'} {href: '/ping',text: 'Ping',icon: 'update'}
]}, ]},
{ {
@ -257,46 +269,7 @@ const app = new Vue({
showAlert(msg){ showAlert(msg){
this.alert.msg=moment().format()+" "+ msg this.alert.msg=moment().format()+" "+ msg
this.alert.show=true this.alert.show=true
},
fullscreenEnabled(){
return document.fullscreenEnabled
},
isInFullScreen(){
return (document.fullscreenElement && document.fullscreenElement !== null) ||
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
(document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
(document.msFullscreenElement && document.msFullscreenElement !== null)
},
fullscreen(){
// https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
var isInFullScreen = this.isInFullScreen();
alert(isInFullScreen);
var docElm = document.documentElement;
if (!isInFullScreen) {
if (docElm.requestFullscreen) {
docElm.requestFullscreen();
} else if (docElm.mozRequestFullScreen) {
docElm.mozRequestFullScreen();
} else if (docElm.webkitRequestFullScreen) {
docElm.webkitRequestFullScreen();
} else if (docElm.msRequestFullscreen) {
docElm.msRequestFullscreen();
} }
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
}
},
computed:{
fullscreenIcon(){ return this.isInFullScreen()?'fullscreen_exit':'fullscreen'}
}, },
created(){ created(){

View file

@ -1,14 +1,26 @@
<!DOCTYPE html> <!DOCTYPE html>
<!-- <!--
simple full screen simple full screen toggle icon
--> -->
<template id="qd-fullscreen"> <template id="qd-fullscreen">
<a onclick="fullscreen()" href="javascript:void(0);">fS</a> <a @click="toggle()" href="javascript:void(0);" title="Fullscreen toggle">
<v-icon>{{ fullscreenIcon }}</v-icon>
</a>
</template> </template>
<script>{ <script>{
created:function(){ data(){
console.log("qd-fullscreen"); return {fullscreenIcon:"fullscreen"}
},
methods:{
toggle(){
this.$fullscreen.toggle()
setTimeout(()=>{
var state=this.$fullscreen.isInFullScreen()
//console.log("FS",state);
this.fullscreenIcon=state?"fullscreen_exit":"fullscreen"
}, 1000);
}
} }
} }
</script> </script>

View file

@ -1,22 +1,31 @@
// ace editor for vue.js <!DOCTYPE html>
<!--
ace editor for vue.js
//https://jsfiddle.net/bc_rikko/gbpw2q9x/3/ //https://jsfiddle.net/bc_rikko/gbpw2q9x/3/
Vue.component('vue-ace', { -->
template: '<div style="width: 100%; height: 100%;"></div>', <template id="vue-ace">
<div style="width: 100%; height: 100%;"></div>
</template>
<script>{
props: [ 'content', props: [ 'content',
'mode', 'mode',
'theme',
'wrap', 'wrap',
'readOnly', 'readOnly',
'events' 'events',
'settings'
], ],
data () { data () {
return { return {
editor: Object, editor: Object,
beforeContent: '', beforeContent: '',
aceSettings:{ aceSettings:{
theme: "github",
keybinding: "ace",
fontsize: 16,
enableSnippets:true, enableSnippets:true,
enableBasicAutocompletion:true, enableBasicAutocompletion:true,
enableLiveAutocompletion:true}, enableLiveAutocompletion:true
},
annots:{ annots:{
error:0,warning:0,info:0 error:0,warning:0,info:0
} }
@ -35,6 +44,10 @@ Vue.component('vue-ace', {
'wrap' (value) { 'wrap' (value) {
var session=this.editor.getSession() var session=this.editor.getSession()
session.setUseWrapMode(value) session.setUseWrapMode(value)
},
'settings' (value) {
//console.log("--settings--",value)
this.applySettings()
} }
}, },
methods:{ methods:{
@ -53,35 +66,40 @@ Vue.component('vue-ace', {
text: "Strange error", text: "Strange error",
type: "error" // also warning and information type: "error" // also warning and information
}]); }]);
}
}, },
mounted () { applySettings(){
const mode = this.mode || 'text' const aceSettings=this.settings
const theme = this.theme || 'github' //console.log("font: ",aceSettings.fontsize)
const wrap = this.wrap || false this.editor.setTheme(`ace/theme/${aceSettings.theme}`)
//this.editor.setKeyboardHandler(`ace/keyboard//${aceSettings.keybinding}`)
const aceSettings=this.aceSettings this.editor.setFontSize(parseInt(aceSettings.fontsize,10))
this.editor.setOptions({
const readOnly = this.readOnly || false
ace.config.set("workerPath", "/vue-poc/ui/ace-workers")
this.editor = window.ace.edit(this.$el)
this.editor.$blockScrolling = Infinity
this.editor.setValue(this.content, 1)
// mode-xxx.js or theme-xxx.js
var session=this.editor.getSession()
session.setMode(`ace/mode/${mode}`)
session.setUseWrapMode(wrap)
this.editor.setTheme(`ace/theme/${theme}`)
this.editor.setOptions({ readOnly:this.readOnly,
enableSnippets : aceSettings.enableSnippets, enableSnippets : aceSettings.enableSnippets,
enableBasicAutocompletion : aceSettings.enableBasicAutocompletion, enableBasicAutocompletion : aceSettings.enableBasicAutocompletion,
enableLiveAutocompletion : aceSettings.enableLiveAutocompletion, enableLiveAutocompletion : aceSettings.enableLiveAutocompletion,
tabSize: 2, tabSize: 2,
useSoftTabs: true useSoftTabs: true
}); });
}
},
mounted () {
const mode = this.mode || 'text'
const wrap = this.wrap || false
const aceSettings=this.settings
console.log("QA: ",this.settings.theme)
const readOnly = this.readOnly || false
ace.config.set("workerPath", "/vue-poc/ui/ace-workers")
this.editor = window.ace.edit(this.$el)
this.editor.$blockScrolling = Infinity
this.editor.setValue(this.content, 1)
this.editor.setOptions({ readOnly:this.readOnly })
var session=this.editor.getSession()
session.setMode(`ace/mode/${mode}`)
session.setUseWrapMode(wrap)
this.editor.commands.addCommand({ this.editor.commands.addCommand({
name: "showKeyboardShortcuts", name: "showKeyboardShortcuts",
bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"}, bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"},
@ -121,4 +139,4 @@ Vue.component('vue-ace', {
}); });
} }
} }
}) }</script>

View file

@ -0,0 +1,45 @@
<!-- common namespaces -->
<namespaces>
<namespace uri="http://www.w3.org/XML/1998/namespace" prefix="xml">
<description>XML core features</description>
</namespace>
<namespace uri="http://www.w3.org/1999/xlink" prefix="xlink">
<description>XML Linking Language (XLink) namespace</description>
</namespace>
<namespace uri="http://www.w3.org/2001/XInclude" prefix="xi">
<description>XML Inclusions (XInclude) </description>
</namespace>
<namespace uri="http://www.w3.org/1999/XSL/Format" prefix="fo">
<description>XSL Formatting Objects namespace </description>
</namespace>
<namespace uri="http://www.w3.org/1999/XSL/Transform" prefix="xsl">
<description>XSL Transformations namespace from the XSLT 1.0
Recommendation
</description>
</namespace>
<namespace uri="http://www.w3.org/2001/XMLSchema" prefix="xsd">
<description>XML Schema Part 1: Structures namespace. </description>
</namespace>
<namespace uri="http://www.w3.org/2001/XMLSchema-datatypes"
prefix="xs">
<description>XML Schema Part 2: Datatypes namespace. </description>
</namespace>
<namespace uri="http://www.w3.org/2001/XMLSchema-instance"
prefix="xsi">
<description>Namespace for XML Schema attributes used in XML instances
(documents), such as xsi:type, xsi:schemaLocation, and xsi:nil.
</description>
</namespace>
<namespace uri="http://www.w3.org/2000/svg" prefix="svg">
<description>Scalable Vector Graphics namespace
</description>
</namespace>
</namespaces>

View file

@ -110,7 +110,8 @@
<v-card-text v-if="!busy"> <v-card-text v-if="!busy">
<v-flex xs12 style="height:70vh" fill-height> <v-flex xs12 style="height:70vh" fill-height>
<vue-ace :content="contentA" :mode="mode" :wrap="wrap" :events="events" <vue-ace :content="contentA" :mode="mode" :wrap="wrap" :settings="aceSettings"
:events="events" v-resize="onResize"
v-on:change-content="changeContentA" v-on:change-content="changeContentA"
v-on:annotation="annotation"></vue-ace> v-on:annotation="annotation"></vue-ace>
</v-flex> </v-flex>
@ -151,7 +152,8 @@ v-on:annotation="annotation"></vue-ace>
"text/turtle":"turtle", "text/turtle":"turtle",
"text/css":"css", "text/css":"css",
"image/svg+xml":"svg" "image/svg+xml":"svg"
} },
aceSettings: { }
} }
}, },
methods: { methods: {
@ -252,6 +254,10 @@ v-on:annotation="annotation"></vue-ace>
var r=this.mimemap[mime] var r=this.mimemap[mime]
return r?r:"text" return r?r:"text"
}, },
onResize(){
var h=window.innerHeight
console.log("height:",h)
},
leaving(event) { leaving(event) {
event.returnValue = "event seems to need to be set"; event.returnValue = "event seems to need to be set";
//debugger; //debugger;
@ -271,6 +277,12 @@ v-on:annotation="annotation"></vue-ace>
var url=this.$route.query.url var url=this.$route.query.url
if(url) this.fetch(url) if(url) this.fetch(url)
}, },
beforeRouteEnter (to, from, next) {
settings.getItem('settings/ace')
.then( v =>{
next(vm => {vm.aceSettings = v;})
})
},
beforeRouteLeave (to, from, next) { beforeRouteLeave (to, from, next) {
// called when the route that renders this component is about to // called when the route that renders this component is about to
// be navigated away from. // be navigated away from.

View file

@ -30,7 +30,7 @@
<v-card-text > <v-card-text >
<v-flex xs12 style="height:200px" fill-height> <v-flex xs12 style="height:200px" fill-height>
<vue-ace :content="xq" mode="xquery" wrap="true" <vue-ace :content="xq" mode="xquery" wrap="true"
v-on:change-content="onChange" v-on:change-content="onChange" :settings="aceSettings"
></vue-ace> ></vue-ace>
</v-flex> </v-flex>
</v-card-text> </v-card-text>
@ -82,7 +82,8 @@
jobId: null, jobId: null,
waiting: false, waiting: false,
start: null, start: null,
jobState: {} jobState: {},
aceSettings:{}
} }
}, },
methods:{ methods:{
@ -181,7 +182,14 @@
this.showResult=true this.showResult=true
} }
}, },
beforeRouteEnter (to, from, next) {
settings.getItem('settings/ace')
.then( v =>{
next(vm => {
console.log('eval settings: ',v);
vm.aceSettings = v;
})})
},
created:function(){ created:function(){
localforage.getItem('eval/xq').then((value) => { this.xq=value || this.xq}); localforage.getItem('eval/xq').then((value) => { this.xq=value || this.xq});
} }

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<template id="repo">
<v-container fluid>
repository todo
</v-container>
</template>
<script>{
data: function(){
return {
message: 'bad route!'
}
},
created:function(){
console.log("notfound",this.$route.query.q)
}
}
</script>

View file

@ -1,9 +1,52 @@
<!DOCTYPE html> <!DOCTYPE html>
<template id="acesettings"> <template id="acesettings">
<v-container>
<v-layout row> <v-layout row>
<v-flex xs12 sm6 offset-sm3> <v-flex xs12 sm8 offset-sm2>
<v-card> <v-card>
<v-alert warning value="true">Not fully implemented</v-alert> <v-alert warning value="true">Not fully implemented</v-alert>
<v-container fluid>
<v-layout row>
<v-flex xs4>
<v-subheader>Theme</v-subheader>
</v-flex>
<v-flex xs8>
<v-select
v-bind:items="themes"
v-model="ace.theme"
label="Theme"
></v-select>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs4>
<v-subheader>Key binding</v-subheader>
</v-flex>
<v-flex xs8>
<v-select
v-bind:items="keybindings"
v-model="ace.keybinding"
label="Key binding"
></v-select>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs4>
<v-subheader>Font size</v-subheader>
</v-flex>
<v-flex xs8>
<v-text-field
label="Font size (px)"
v-model="ace.fontsize"
></v-text-field>
</v-flex>
</v-layout>
<v-divider ></v-divider>
</v-container>
<v-list two-line subheader> <v-list two-line subheader>
<v-subheader>Ace editor settings</v-subheader> <v-subheader>Ace editor settings</v-subheader>
@ -40,75 +83,47 @@
</v-list> </v-list>
<v-card-text> <v-card-text>
<v-divider ></v-divider>
<v-container fluid>
<v-layout row>
<v-flex xs4>
<v-subheader>Theme</v-subheader>
</v-flex>
<v-flex xs8>
<v-text-field
label="Theme"
v-model="ace.theme"
></v-text-field>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs4>
<v-subheader>Key binding</v-subheader>
</v-flex>
<v-flex xs8>
<v-select
v-bind:items="keybindings"
v-model="ace.keybinding"
label="Key binding"
></v-select>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs4>
<v-subheader>Font size</v-subheader>
</v-flex>
<v-flex xs8>
<v-text-field
label="Font size (px)"
v-model="ace.fontsize"
></v-text-field>
</v-flex>
</v-layout>
<v-divider ></v-divider>
</v-container>
</v-card-text> </v-card-text>
</v-card> </v-card>
</v-flex> </v-flex>
</v-layout> </v-layout>
</v-container>
</template> </template>
<script>{ <script>{
data () { data () {
return { return {
ace: { xace: {
enableSnippets: true, enableSnippets: true,
enableBasicAutocompletion: true, enableBasicAutocompletion: true,
enableLiveAutocompletion: true, enableLiveAutocompletion: true,
theme: "github", theme: "github",
keybinding: "Ace", keybinding: "ace",
fontsize: "14px" fontsize: "14"
}, },
keybindings:[ 'ace', 'vim', 'emacs', 'textarea', 'sublime' ] ace: {},
keybindings:[ 'ace', 'vim', 'emacs', 'textarea', 'sublime' ],
themes: [ "github", "chaos","tomorrow"]
}
},
methods:{
extend(obj, src) {
Object.keys(src).forEach(function(key) { if(!obj[key]) obj[key] = src[key]; });
return obj;
} }
}, },
beforeRouteEnter (to, from, next) { beforeRouteEnter (to, from, next) {
settings.getItem('settings/ace') settings.getItem('settings/ace')
.then((v)=>{ .then( v =>{
next(vm => vm.ace=v) next(vm => { vm.ace = v; })
}) })
}, },
created: function () {
mounted: function () {
// console.log(this.ace,this.xace)
// this.extend(this.storeace,this.storeace);
// console.log("$$$",this.ace)
}, },
watch: {"ace":{ watch: {"ace":{
handler:function(v){ handler:function(v){

View file

@ -1,14 +1,17 @@
<!DOCTYPE html> <!DOCTYPE html>
<template id="settings"> <template id="settings">
<v-container fluid> <v-container fluid>
<p>Settings are currently only stored locally in the browser, using <code>localstorage</code></p>
<v-card> <v-card>
<v-card-title class="lime darken-1">Available settings</v-card-title>
<v-card-text> <v-card-text>
<router-link to="/acesettings">Editor settings</router-link> <router-link to="/acesettings">Editor</router-link>
</v-card-text> </v-card-text>
</v-card> </v-card>
<div>.</div>
<v-card > <v-card >
<v-card-title>System information</v-card-title> <v-card-title class="lime darken-1">System information</v-card-title>
<v-card-text></v-card-text> <v-card-text>keys?</v-card-text>
<v-card-actions> <v-card-actions>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn @click="wipe" error>Wipe</v-btn></v-card-actions> <v-btn @click="wipe" error>Wipe</v-btn></v-card-actions>
@ -18,7 +21,8 @@
<script>{ <script>{
data:function(){return { data:function(){return {
keys:[] keys: [],
showDev: false
} }
}, },
methods:{ methods:{

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<template id="tabs"> <template id="tabs">
<v-tabs id="mobile-tabs-6" scroll-bars light> <v-tabs scroll-bars >
<v-card class="primary white--text"> <v-card >
<v-card-actions> <v-card-actions>
<v-btn icon light> <v-btn icon light>
<v-icon>menu</v-icon> <v-icon>menu</v-icon>
@ -16,28 +16,32 @@
</v-btn> </v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
<v-tabs-bar slot="activators" class="green">
<v-tabs-slider></v-tabs-slider> <v-tabs-bar class="grey lighten-3">
<v-tabs-item <v-tabs-item
v-for="i in 13" v-for="i in 13"
:key="i" :key="i"
:href="'#mobile-tabs-6-' + i" :href="'#mobile-tabs-6-' + i"
> >
Item {{ i }} <v-chip close>
<v-btn icon class="pink--text"> <v-avatar class="pink">
<v-icon>favorite</v-icon> <v-icon>favorite</v-icon>
</v-btn> </v-avatar>
Item {{ i }} more
</v-chip>
</v-tabs-item> </v-tabs-item>
<v-tabs-slider class="primary"></v-tabs-slider>
</v-tabs-bar> </v-tabs-bar>
<v-tabs-content
v-for="i in 13" <v-tabs-items>
<v-tabs-content v-for="i in 13"
:key="i" :key="i"
:id="'mobile-tabs-6-' + i" :id="'mobile-tabs-6-' + i">
>
<v-card flat > <v-card flat >
<v-card-text>{{ text }}</v-card-text> <v-card-text>{{i}} - {{ text }}</v-card-text>
</v-card> </v-card>
</v-tabs-content> </v-tabs-content>
</v-tabs-items>
</v-tabs> </v-tabs>
</template> </template>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<template id="users">
<v-container fluid>
users todo
</v-container>
</template>
<script>{
data: function(){
return {
message: 'bad route!'
}
},
created:function(){
console.log("notfound",this.$route.query.q)
}
}
</script>

View file

@ -1,10 +1,22 @@
// generated 2017-09-02T22:16:55.583+01:00 // generated 2017-09-03T23:24:46.005+01:00
Vue.component('qd-fullscreen',{template:` Vue.component('qd-fullscreen',{template:`
<a onclick="fullscreen()" href="javascript:void(0);">fS</a> <a @click="toggle()" href="javascript:void(0);" title="Fullscreen toggle">
<v-icon>{{ fullscreenIcon }}</v-icon>
</a>
`, `,
created:function(){ data(){
console.log("qd-fullscreen"); return {fullscreenIcon:"fullscreen"}
},
methods:{
toggle(){
this.$fullscreen.toggle()
setTimeout(()=>{
var state=this.$fullscreen.isInFullScreen()
//console.log("FS",state);
this.fullscreenIcon=state?"fullscreen_exit":"fullscreen"
}, 1000);
}
} }
} }
@ -125,6 +137,144 @@
}) })
} }
} }
}
);
Vue.component('vue-ace',{template:`
<div style="width: 100%; height: 100%;"></div>
`,
props: [ 'content',
'mode',
'wrap',
'readOnly',
'events',
'settings'
],
data () {
return {
editor: Object,
beforeContent: '',
aceSettings:{
theme: "github",
keybinding: "ace",
fontsize: 16,
enableSnippets:true,
enableBasicAutocompletion:true,
enableLiveAutocompletion:true
},
annots:{
error:0,warning:0,info:0
}
}
},
watch: {
'content' (value) {
if (this.beforeContent !== value) {
this.editor.setValue(value, 1)
}
},
'mode' (value) {
var session=this.editor.getSession()
session.setMode(`ace/mode/${value}`)
},
'wrap' (value) {
var session=this.editor.getSession()
session.setUseWrapMode(value)
},
'settings' (value) {
//console.log("--settings--",value)
this.applySettings()
}
},
methods:{
command(cmd){
//alert("fold")
var cm = this.editor.commands
//console.log(cm.commands)
cm.exec(cmd, this.editor)
},
testAnnotations(){
this.editor.getSession().setAnnotations([{
row: 1,
column: 0,
text: "Strange error",
type: "error" // also warning and information
}]);
},
applySettings(){
const aceSettings=this.settings
//console.log("font: ",aceSettings.fontsize)
this.editor.setTheme(`ace/theme/${aceSettings.theme}`)
//this.editor.setKeyboardHandler(`ace/keyboard//${aceSettings.keybinding}`)
this.editor.setFontSize(parseInt(aceSettings.fontsize,10))
this.editor.setOptions({
enableSnippets : aceSettings.enableSnippets,
enableBasicAutocompletion : aceSettings.enableBasicAutocompletion,
enableLiveAutocompletion : aceSettings.enableLiveAutocompletion,
tabSize: 2,
useSoftTabs: true
});
}
},
mounted () {
const mode = this.mode || 'text'
const wrap = this.wrap || false
const aceSettings=this.settings
console.log("QA: ",this.settings.theme)
const readOnly = this.readOnly || false
ace.config.set("workerPath", "/vue-poc/ui/ace-workers")
this.editor = window.ace.edit(this.$el)
this.editor.$blockScrolling = Infinity
this.editor.setValue(this.content, 1)
this.editor.setOptions({ readOnly:this.readOnly })
var session=this.editor.getSession()
session.setMode(`ace/mode/${mode}`)
session.setUseWrapMode(wrap)
this.editor.commands.addCommand({
name: "showKeyboardShortcuts",
bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"},
exec: function(editor) {
ace.config.loadModule("ace/ext/keybinding_menu", function(module) {
module.init(editor);
editor.showKeyboardShortcuts()
})
}
})
this.editor.on('change', () => {
this.beforeContent = this.editor.getValue()
this.$emit('change-content', this.editor.getValue())
});
this.editor.getSession().on("changeAnnotation", ()=>{
var annot = this.editor.getSession().getAnnotations();
this.annots={error:0,warning:0,info:0};
for (var key in annot){
if (annot.hasOwnProperty(key)){
this.annots[annot[key].type]+=1;
//console.log("[" + annot[key].row + " , " + annot[key].column + "] - \t" + annot[key].type+ "# " +annot[key].text);
}
}
//console.log(this.annots)
this.$emit('annotation',this.annots)
});
if(this.events){
this.events.$on('eventFired', (cmd) => {
if(cmd=="outline"){
var row = this.editor.selection.getCursor().row
var toks=this.editor.session.getTokens(row).filter(function(t) {
return true
})
console.log(toks);
}else this.command(cmd);
});
}
}
} }
); );
/** /**
@ -606,7 +756,7 @@ Vue.filter('round', function(value, decimals) {
<v-card-text v-if="!busy"> <v-card-text v-if="!busy">
<v-flex xs12="" style="height:70vh" fill-height=""> <v-flex xs12="" style="height:70vh" fill-height="">
<vue-ace :content="contentA" :mode="mode" :wrap="wrap" :events="events" v-on:change-content="changeContentA" v-on:annotation="annotation"></vue-ace> <vue-ace :content="contentA" :mode="mode" :wrap="wrap" :settings="aceSettings" :events="events" v-resize="onResize" v-on:change-content="changeContentA" v-on:annotation="annotation"></vue-ace>
</v-flex> </v-flex>
</v-card-text> </v-card-text>
</v-card> </v-card>
@ -644,7 +794,8 @@ Vue.filter('round', function(value, decimals) {
"text/turtle":"turtle", "text/turtle":"turtle",
"text/css":"css", "text/css":"css",
"image/svg+xml":"svg" "image/svg+xml":"svg"
} },
aceSettings: { }
} }
}, },
methods: { methods: {
@ -745,6 +896,10 @@ Vue.filter('round', function(value, decimals) {
var r=this.mimemap[mime] var r=this.mimemap[mime]
return r?r:"text" return r?r:"text"
}, },
onResize(){
var h=window.innerHeight
console.log("height:",h)
},
leaving(event) { leaving(event) {
event.returnValue = "event seems to need to be set"; event.returnValue = "event seems to need to be set";
//debugger; //debugger;
@ -764,6 +919,12 @@ Vue.filter('round', function(value, decimals) {
var url=this.$route.query.url var url=this.$route.query.url
if(url) this.fetch(url) if(url) this.fetch(url)
}, },
beforeRouteEnter (to, from, next) {
settings.getItem('settings/ace')
.then( v =>{
next(vm => {vm.aceSettings = v;})
})
},
beforeRouteLeave (to, from, next) { beforeRouteLeave (to, from, next) {
// called when the route that renders this component is about to // called when the route that renders this component is about to
// be navigated away from. // be navigated away from.
@ -804,7 +965,7 @@ Vue.filter('round', function(value, decimals) {
<v-card-text> <v-card-text>
<v-flex xs12="" style="height:200px" fill-height=""> <v-flex xs12="" style="height:200px" fill-height="">
<vue-ace :content="xq" mode="xquery" wrap="true" v-on:change-content="onChange"></vue-ace> <vue-ace :content="xq" mode="xquery" wrap="true" v-on:change-content="onChange" :settings="aceSettings"></vue-ace>
</v-flex> </v-flex>
</v-card-text> </v-card-text>
@ -853,7 +1014,8 @@ Vue.filter('round', function(value, decimals) {
jobId: null, jobId: null,
waiting: false, waiting: false,
start: null, start: null,
jobState: {} jobState: {},
aceSettings:{}
} }
}, },
methods:{ methods:{
@ -952,7 +1114,14 @@ Vue.filter('round', function(value, decimals) {
this.showResult=true this.showResult=true
} }
}, },
beforeRouteEnter (to, from, next) {
settings.getItem('settings/ace')
.then( v =>{
next(vm => {
console.log('eval settings: ',v);
vm.aceSettings = v;
})})
},
created:function(){ created:function(){
localforage.getItem('eval/xq').then((value) => { this.xq=value || this.xq}); localforage.getItem('eval/xq').then((value) => { this.xq=value || this.xq});
} }
@ -1885,6 +2054,23 @@ body
} }
);
const Repo=Vue.extend({template:`
<v-container fluid="">
repository todo
</v-container>
`,
data: function(){
return {
message: 'bad route!'
}
},
created:function(){
console.log("notfound",this.$route.query.q)
}
}
); );
const Search=Vue.extend({template:` const Search=Vue.extend({template:`
<v-container fluid=""> <v-container fluid="">
@ -2051,10 +2237,42 @@ body
); );
const Acesettings=Vue.extend({template:` const Acesettings=Vue.extend({template:`
<v-container>
<v-layout row=""> <v-layout row="">
<v-flex xs12="" sm6="" offset-sm3=""> <v-flex xs12="" sm8="" offset-sm2="">
<v-card> <v-card>
<v-alert warning="" value="true">Not fully implemented</v-alert> <v-alert warning="" value="true">Not fully implemented</v-alert>
<v-container fluid="">
<v-layout row="">
<v-flex xs4="">
<v-subheader>Theme</v-subheader>
</v-flex>
<v-flex xs8="">
<v-select v-bind:items="themes" v-model="ace.theme" label="Theme"></v-select>
</v-flex>
</v-layout>
<v-layout row="">
<v-flex xs4="">
<v-subheader>Key binding</v-subheader>
</v-flex>
<v-flex xs8="">
<v-select v-bind:items="keybindings" v-model="ace.keybinding" label="Key binding"></v-select>
</v-flex>
</v-layout>
<v-layout row="">
<v-flex xs4="">
<v-subheader>Font size</v-subheader>
</v-flex>
<v-flex xs8="">
<v-text-field label="Font size (px)" v-model="ace.fontsize"></v-text-field>
</v-flex>
</v-layout>
<v-divider></v-divider>
</v-container>
<v-list two-line="" subheader=""> <v-list two-line="" subheader="">
<v-subheader>Ace editor settings</v-subheader> <v-subheader>Ace editor settings</v-subheader>
@ -2091,64 +2309,46 @@ body
</v-list> </v-list>
<v-card-text> <v-card-text>
<v-divider></v-divider>
<v-container fluid="">
<v-layout row="">
<v-flex xs4="">
<v-subheader>Theme</v-subheader>
</v-flex>
<v-flex xs8="">
<v-text-field label="Theme" v-model="ace.theme"></v-text-field>
</v-flex>
</v-layout>
<v-layout row="">
<v-flex xs4="">
<v-subheader>Key binding</v-subheader>
</v-flex>
<v-flex xs8="">
<v-select v-bind:items="keybindings" v-model="ace.keybinding" label="Key binding"></v-select>
</v-flex>
</v-layout>
<v-layout row="">
<v-flex xs4="">
<v-subheader>Font size</v-subheader>
</v-flex>
<v-flex xs8="">
<v-text-field label="Font size (px)" v-model="ace.fontsize"></v-text-field>
</v-flex>
</v-layout>
<v-divider></v-divider>
</v-container>
</v-card-text> </v-card-text>
</v-card> </v-card>
</v-flex> </v-flex>
</v-layout> </v-layout>
</v-container>
`, `,
data () { data () {
return { return {
ace: { xace: {
enableSnippets: true, enableSnippets: true,
enableBasicAutocompletion: true, enableBasicAutocompletion: true,
enableLiveAutocompletion: true, enableLiveAutocompletion: true,
theme: "github", theme: "github",
keybinding: "Ace", keybinding: "ace",
fontsize: "14px" fontsize: "14"
}, },
keybindings:[ 'ace', 'vim', 'emacs', 'textarea', 'sublime' ] ace: {},
keybindings:[ 'ace', 'vim', 'emacs', 'textarea', 'sublime' ],
themes: [ "github", "chaos","tomorrow"]
}
},
methods:{
extend(obj, src) {
Object.keys(src).forEach(function(key) { if(!obj[key]) obj[key] = src[key]; });
return obj;
} }
}, },
beforeRouteEnter (to, from, next) { beforeRouteEnter (to, from, next) {
settings.getItem('settings/ace') settings.getItem('settings/ace')
.then((v)=>{ .then( v =>{
next(vm => vm.ace=v) next(vm => { vm.ace = v; })
}) })
}, },
created: function () {
mounted: function () {
// console.log(this.ace,this.xace)
// this.extend(this.storeace,this.storeace);
// console.log("$$$",this.ace)
}, },
watch: {"ace":{ watch: {"ace":{
handler:function(v){ handler:function(v){
@ -2163,14 +2363,17 @@ body
); );
const Settings=Vue.extend({template:` const Settings=Vue.extend({template:`
<v-container fluid=""> <v-container fluid="">
<p>Settings are currently only stored locally in the browser, using <code>localstorage</code></p>
<v-card> <v-card>
<v-card-title class="lime darken-1">Available settings</v-card-title>
<v-card-text> <v-card-text>
<router-link to="/acesettings">Editor settings</router-link> <router-link to="/acesettings">Editor</router-link>
</v-card-text> </v-card-text>
</v-card> </v-card>
<div>.</div>
<v-card> <v-card>
<v-card-title>System information</v-card-title> <v-card-title class="lime darken-1">System information</v-card-title>
<v-card-text></v-card-text> <v-card-text>keys?</v-card-text>
<v-card-actions> <v-card-actions>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn @click="wipe" error="">Wipe</v-btn></v-card-actions> <v-btn @click="wipe" error="">Wipe</v-btn></v-card-actions>
@ -2179,7 +2382,8 @@ body
`, `,
data:function(){return { data:function(){return {
keys:[] keys: [],
showDev: false
} }
}, },
methods:{ methods:{
@ -2199,8 +2403,8 @@ body
); );
const Tabs=Vue.extend({template:` const Tabs=Vue.extend({template:`
<v-tabs id="mobile-tabs-6" scroll-bars="" light=""> <v-tabs scroll-bars="">
<v-card class="primary white--text"> <v-card>
<v-card-actions> <v-card-actions>
<v-btn icon="" light=""> <v-btn icon="" light="">
<v-icon>menu</v-icon> <v-icon>menu</v-icon>
@ -2215,20 +2419,26 @@ body
</v-btn> </v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
<v-tabs-bar slot="activators" class="green">
<v-tabs-slider></v-tabs-slider> <v-tabs-bar class="grey lighten-3">
<v-tabs-item v-for="i in 13" :key="i" :href="'#mobile-tabs-6-' + i"> <v-tabs-item v-for="i in 13" :key="i" :href="'#mobile-tabs-6-' + i">
Item {{ i }} <v-chip close="">
<v-btn icon="" class="pink--text"> <v-avatar class="pink">
<v-icon>favorite</v-icon> <v-icon>favorite</v-icon>
</v-btn> </v-avatar>
Item {{ i }} more
</v-chip>
</v-tabs-item> </v-tabs-item>
<v-tabs-slider class="primary"></v-tabs-slider>
</v-tabs-bar> </v-tabs-bar>
<v-tabs-items>
<v-tabs-content v-for="i in 13" :key="i" :id="'mobile-tabs-6-' + i"> <v-tabs-content v-for="i in 13" :key="i" :id="'mobile-tabs-6-' + i">
<v-card flat=""> <v-card flat="">
<v-card-text>{{ text }}</v-card-text> <v-card-text>{{i}} - {{ text }}</v-card-text>
</v-card> </v-card>
</v-tabs-content> </v-tabs-content>
</v-tabs-items>
</v-tabs> </v-tabs>
`, `,
@ -2607,6 +2817,23 @@ created(){
console.log("timeline") console.log("timeline")
} }
} }
);
const Users=Vue.extend({template:`
<v-container fluid="">
users todo
</v-container>
`,
data: function(){
return {
message: 'bad route!'
}
},
created:function(){
console.log("notfound",this.$route.query.q)
}
}
); );
const Vuepoc=Vue.extend({template:` const Vuepoc=Vue.extend({template:`
<v-app> <v-app>
@ -2916,14 +3143,16 @@ function debounce(func, wait, immediate) {
}; };
// https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript // https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
function fullscreen() { const Fullscreen={
var isInFullScreen = (document.fullscreenElement && document.fullscreenElement !== null) || isInFullScreen(){
return (document.fullscreenElement && document.fullscreenElement !== null) ||
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
(document.mozFullScreenElement && document.mozFullScreenElement !== null) || (document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
(document.msFullscreenElement && document.msFullscreenElement !== null); (document.msFullscreenElement && document.msFullscreenElement !== null);
},
toggle(){
var docElm = document.documentElement; var docElm = document.documentElement;
if (!isInFullScreen) { if (!this.isInFullScreen()) {
if (docElm.requestFullscreen) { if (docElm.requestFullscreen) {
docElm.requestFullscreen(); docElm.requestFullscreen();
} else if (docElm.mozRequestFullScreen) { } else if (docElm.mozRequestFullScreen) {
@ -2944,7 +3173,14 @@ function fullscreen() {
document.msExitFullscreen(); document.msExitFullscreen();
} }
} }
},
install: function(Vue){
Object.defineProperty(Vue.prototype, '$fullscreen', {
get () { return Fullscreen }
}) }
}; };
Vue.use(Fullscreen);
const router = new VueRouter({ const router = new VueRouter({
base:"/vue-poc/ui/", base:"/vue-poc/ui/",
@ -2964,7 +3200,8 @@ const router = new VueRouter({
{ path: '/tabs', component: Tabs,meta:{title:"tab test",requiresAuth: true} }, { path: '/tabs', component: Tabs,meta:{title:"tab test",requiresAuth: true} },
{ path: '/login', component: Login,meta:{title:"login"} }, { path: '/login', component: Login,meta:{title:"login"} },
{ path: '/edit', component: Edit,meta:{title:"Ace editor"} }, { path: '/edit', component: Edit,meta:{title:"Ace editor"} },
{ path: '/server/users', component: Users,meta:{title:"Users"} },
{ path: '/server/repo', component: Repo,meta:{title:"Repository"} },
{ path: '/files', component: Files,meta:{title:"File system"},props:{protocol:"webfile"} }, { path: '/files', component: Files,meta:{title:"File system"},props:{protocol:"webfile"} },
{ path: '/database', component: Files,meta:{title:"Databases"},props:{protocol:"basexdb"} }, { path: '/database', component: Files,meta:{title:"Databases"},props:{protocol:"basexdb"} },
{ path: '/ping', component: Ping,meta:{title:"Ping"} }, { path: '/ping', component: Ping,meta:{title:"Ping"} },
@ -3043,6 +3280,8 @@ const app = new Vue({
children: [ children: [
{href: '/jobs',text: 'Running jobs',icon: 'dashboard'}, {href: '/jobs',text: 'Running jobs',icon: 'dashboard'},
{href: '/logs',text: 'Server logs',icon: 'dns'}, {href: '/logs',text: 'Server logs',icon: 'dns'},
{href: '/server/users',text: 'Users',icon: 'supervisor_account'},
{href: '/server/repo',text: 'Server code repository',icon: 'local_library'},
{href: '/ping',text: 'Ping',icon: 'update'} {href: '/ping',text: 'Ping',icon: 'update'}
]}, ]},
{ {
@ -3088,46 +3327,7 @@ const app = new Vue({
showAlert(msg){ showAlert(msg){
this.alert.msg=moment().format()+" "+ msg this.alert.msg=moment().format()+" "+ msg
this.alert.show=true this.alert.show=true
},
fullscreenEnabled(){
return document.fullscreenEnabled
},
isInFullScreen(){
return (document.fullscreenElement && document.fullscreenElement !== null) ||
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null) ||
(document.mozFullScreenElement && document.mozFullScreenElement !== null) ||
(document.msFullscreenElement && document.msFullscreenElement !== null)
},
fullscreen(){
// https://stackoverflow.com/questions/36672561/how-to-exit-fullscreen-onclick-using-javascript
var isInFullScreen = this.isInFullScreen();
alert(isInFullScreen);
var docElm = document.documentElement;
if (!isInFullScreen) {
if (docElm.requestFullscreen) {
docElm.requestFullscreen();
} else if (docElm.mozRequestFullScreen) {
docElm.mozRequestFullScreen();
} else if (docElm.webkitRequestFullScreen) {
docElm.webkitRequestFullScreen();
} else if (docElm.msRequestFullscreen) {
docElm.msRequestFullscreen();
} }
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
}
},
computed:{
fullscreenIcon(){ return this.isInFullScreen()?'fullscreen_exit':'fullscreen'}
}, },
created(){ created(){

View file

@ -9,7 +9,7 @@
<title>Vue Router Test</title> <title>Vue Router Test</title>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic"> <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons"> <link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
<link href="https://unpkg.com/vuetify@0.14.11/dist/vuetify.min.css" rel="stylesheet" type="text/css"> <link href="https://unpkg.com/vuetify@0.15.1/dist/vuetify.min.css" rel="stylesheet" type="text/css">
<link href="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.css" rel="stylesheet" type="text/css"> <link href="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.css" rel="stylesheet" type="text/css">
<link href="/vue-poc/ui/app.css" rel="stylesheet" type="text/css"> <link href="/vue-poc/ui/app.css" rel="stylesheet" type="text/css">
@ -19,7 +19,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.5.3/vue-router.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.5.3/vue-router.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.4.0/qs.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.4.0/qs.js"></script>
<script src="https://unpkg.com/vuetify@0.14.11/dist/vuetify.min.js"></script> <script src="https://unpkg.com/vuetify@0.15.1/dist/vuetify.min.js"></script>
<script src="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.js"></script> <script src="https://unpkg.com/vue-multiselect@2.0.0-beta.15/dist/vue-multiselect.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.7/ace.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.7/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.7/ext-language_tools.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.7/ext-language_tools.js"></script>
@ -33,7 +33,6 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.css" />
<script src="/vue-poc/ui/perf-stat.js"></script> <script src="/vue-poc/ui/perf-stat.js"></script>
<script src="/vue-poc/ui/vue-ace.js"></script>
</head> </head>
<body> <body>
<v-app id="app" > <v-app id="app" >
@ -83,9 +82,6 @@
</v-list> </v-list>
</v-menu> </v-menu>
<v-btn icon @click="fullscreen" :disabled="!fullscreenEnabled">
<v-icon>{{ fullscreenIcon }}</v-icon>
</v-btn>
<qd-fullscreen></qd-fullscreen> <qd-fullscreen></qd-fullscreen>
</v-toolbar> </v-toolbar>
<main> <main>