Improved NavBar, added LNVue().Start(), etc.
parent
51df83f9e7
commit
bcce34d170
|
@ -58,7 +58,13 @@ div.ln-tooltip {
|
||||||
border-radius: 0px 6px 6px 6px;
|
border-radius: 0px 6px 6px 6px;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
|
|
||||||
transition: opacity 500ms;
|
opacity: 0.0;
|
||||||
|
transition: opacity 300ms linear;
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
div.ln-tooltip[VISIBLE] {
|
||||||
|
opacity: 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@ -143,10 +149,14 @@ div.ln-select::after {
|
||||||
border-top: 1px solid black;
|
border-top: 1px solid black;
|
||||||
border-bottom: 1px solid black;
|
border-bottom: 1px solid black;
|
||||||
|
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ln-navitem {
|
.ln-navitem {
|
||||||
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
@ -160,8 +170,41 @@ div.ln-select::after {
|
||||||
.ln-navitem > a {
|
.ln-navitem > a {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.ln-navitem > div.ln-nav-children {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
white-space: pre;
|
||||||
|
left: 0px;
|
||||||
|
top: 100%;
|
||||||
|
opacity: 0.0;
|
||||||
|
|
||||||
|
transition: opacity 200ms;
|
||||||
|
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.ln-navitem:hover > div.ln-nav-children {
|
||||||
|
opacity: 1.0;
|
||||||
|
transition: opacity 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.ln-nav-children > .ln-navitem {
|
||||||
|
display: block;
|
||||||
|
margin-top: 4px;
|
||||||
|
padding-top: 4px;
|
||||||
|
border-top: 1px solid #C0C0C0;
|
||||||
|
}
|
||||||
|
div.ln-nav-children > .ln-navitem:first-of-type {
|
||||||
|
margin-top: 0px;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
div.ln-upload {
|
div.ln-upload {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
80
demo.html
80
demo.html
|
@ -8,7 +8,7 @@
|
||||||
<script type="text/javascript" src="js/vue.js"></script>
|
<script type="text/javascript" src="js/vue.js"></script>
|
||||||
<script type="text/javascript" src="js/vue-router.js"></script>
|
<script type="text/javascript" src="js/vue-router.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript" src="js/ln.vue.application.js"></script>
|
<script type="text/javascript" src="js/ln.vue.js"></script>
|
||||||
<script type="text/javascript" src="js/ln.vue.components.js"></script>
|
<script type="text/javascript" src="js/ln.vue.components.js"></script>
|
||||||
<script type="text/javascript" src="js/ln.vue.table.js"></script>
|
<script type="text/javascript" src="js/ln.vue.table.js"></script>
|
||||||
|
|
||||||
|
@ -23,22 +23,55 @@
|
||||||
<div id="frame">
|
<div id="frame">
|
||||||
<h1>ln.vue Demo Application</h1>
|
<h1>ln.vue Demo Application</h1>
|
||||||
|
|
||||||
<ln-navbar
|
<div v-if="false">
|
||||||
:navitems="[
|
<h2>Please wait for application to be loaded...</h2>
|
||||||
{ href: '/', label: 'HOME' },
|
</div>
|
||||||
{ href: '/controls', label: 'Simple Form Controls' },
|
|
||||||
{ href: '/table', label: 'Table View Control' },
|
<ln-navbar></ln-navbar>
|
||||||
{ href: '/state', label: 'Current State' },
|
|
||||||
]"></ln-navbar>
|
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
LNVue.addRouteTemplate(
|
let core = {
|
||||||
"/",
|
navigation: {
|
||||||
`<div>This is the ln.vue demo application. Feel free to test all the features, you can find.<br>Here should be a message:<br><i>{{ message.value }}</i></div>`
|
core: {
|
||||||
);
|
label: "HOME",
|
||||||
LNVue.addRouteTemplate(
|
path: '/',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
routes: {
|
||||||
|
'/': {
|
||||||
|
template: `<div>This is the ln.vue demo application. Feel free to test all the features, you can find.<br>Here should be a message:<br><i>{{ message.value }}</i></div>`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let controls = {
|
||||||
|
navigation: {
|
||||||
|
controls: {
|
||||||
|
label: "Controls",
|
||||||
|
navigation: {
|
||||||
|
simple: {
|
||||||
|
label: "Simple Form Controls",
|
||||||
|
path: '/controls',
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
label: "Table Contol",
|
||||||
|
path: '/table',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
routes: {
|
||||||
|
'/controls': {
|
||||||
|
url: '/controls.html',
|
||||||
|
},
|
||||||
|
'/table': {
|
||||||
|
url: '/table.html',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* LNVue.addRouteTemplate(
|
||||||
"/state",
|
"/state",
|
||||||
`<div>Current User Input object:<br><br>
|
`<div>Current User Input object:<br><br>
|
||||||
<span class="json">{{ JSON.stringify(controls,null,4) }}</span>
|
<span class="json">{{ JSON.stringify(controls,null,4) }}</span>
|
||||||
|
@ -47,7 +80,7 @@
|
||||||
|
|
||||||
LNVue.addRoute("/controls","/controls.html");
|
LNVue.addRoute("/controls","/controls.html");
|
||||||
LNVue.addRoute("/table","/table.html");
|
LNVue.addRoute("/table","/table.html");
|
||||||
|
*/
|
||||||
let message = { value: "" };
|
let message = { value: "" };
|
||||||
|
|
||||||
app = new LNVue("#frame",{
|
app = new LNVue("#frame",{
|
||||||
|
@ -127,6 +160,25 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.addModule(core);
|
||||||
|
app.addModule(controls);
|
||||||
|
|
||||||
|
app.addModule({
|
||||||
|
navigation: {
|
||||||
|
state: {
|
||||||
|
label: "State",
|
||||||
|
path: '/state',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
routes: {
|
||||||
|
'/state': `<div>Current User Input object:<br><br>
|
||||||
|
<span class="json">{{ JSON.stringify(controls,null,4) }}</span>
|
||||||
|
</div>`,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Start();
|
||||||
|
|
||||||
LNVue.onidle(()=>{
|
LNVue.onidle(()=>{
|
||||||
message.value = "idle time reached. Message written.";
|
message.value = "idle time reached. Message written.";
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
|
|
|
@ -18,24 +18,19 @@ function findTooltipData(el){
|
||||||
}
|
}
|
||||||
|
|
||||||
function tooltipShow(ev,tooltip){
|
function tooltipShow(ev,tooltip){
|
||||||
if (!tooltipEl.parentElement)
|
if (tooltipEl.parentElement)
|
||||||
{
|
document.body.appendChild(tooltipEl);
|
||||||
tooltipEl.style.visibility = "hidden";
|
|
||||||
tooltipEl.style.opacity = 0.0;
|
|
||||||
tooltipEl.style.visibility = "visible";
|
|
||||||
}
|
|
||||||
document.body.appendChild(tooltipEl);
|
|
||||||
|
|
||||||
tooltipEl.innerText = tooltip.value;
|
tooltipEl.innerText = tooltip.value;
|
||||||
tooltipEl.style.opacity = 1.0;
|
tooltipEl.setAttribute("VISIBLE","");
|
||||||
|
|
||||||
tootlipVisible = true;
|
tootlipVisible = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
function tooltipHide(ev,tooltip){
|
function tooltipHide(ev,tooltip){
|
||||||
tooltipEl.style.opacity = 0.0;
|
tooltipEl.removeAttribute("VISIBLE");
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
document.body.removeChild(tooltipEl);
|
//document.body.removeChild(tooltipEl);
|
||||||
}, 600);
|
}, 600);
|
||||||
|
|
||||||
tootlipVisible = false;
|
tootlipVisible = false;
|
||||||
|
@ -52,7 +47,7 @@ function tooltipMouseOver(ev){
|
||||||
else
|
else
|
||||||
tooltip.timeout = setTimeout(() => {
|
tooltip.timeout = setTimeout(() => {
|
||||||
tooltipShow(ev,tooltip);
|
tooltipShow(ev,tooltip);
|
||||||
}, 800);
|
}, tooltip.delay || 800);
|
||||||
|
|
||||||
if (tooltipEl){
|
if (tooltipEl){
|
||||||
tooltipEl.style.left = `${ev.x+3}px`;
|
tooltipEl.style.left = `${ev.x+3}px`;
|
||||||
|
@ -72,7 +67,7 @@ Vue.directive('tooltip',{
|
||||||
let tooltip = {
|
let tooltip = {
|
||||||
value: binding.value,
|
value: binding.value,
|
||||||
timeout: null,
|
timeout: null,
|
||||||
|
delay: null,
|
||||||
};
|
};
|
||||||
let tooltipKey = nextTooltipKey++;
|
let tooltipKey = nextTooltipKey++;
|
||||||
tooltipData[tooltipKey] = tooltip;
|
tooltipData[tooltipKey] = tooltip;
|
||||||
|
@ -81,15 +76,10 @@ Vue.directive('tooltip',{
|
||||||
el.addEventListener('mousemove',tooltipMouseOver);
|
el.addEventListener('mousemove',tooltipMouseOver);
|
||||||
el.addEventListener('mouseout',tooltipMouseOut);
|
el.addEventListener('mouseout',tooltipMouseOut);
|
||||||
|
|
||||||
},
|
|
||||||
inserted: function(el, binding, vnode){
|
|
||||||
|
|
||||||
},
|
},
|
||||||
update: function(el, binding, vnode, oldVnode){
|
update: function(el, binding, vnode, oldVnode){
|
||||||
|
let tooltip = findTooltipData(el);
|
||||||
},
|
tooltip.value = binding.value;
|
||||||
componentUpdated: function(el, binding, vnode, oldVnode){
|
|
||||||
|
|
||||||
},
|
},
|
||||||
unbind: function(el, binding, vnode){
|
unbind: function(el, binding, vnode){
|
||||||
el.removeEventListener('mouseover',tooltipMouseOver);
|
el.removeEventListener('mouseover',tooltipMouseOver);
|
||||||
|
@ -99,40 +89,66 @@ Vue.directive('tooltip',{
|
||||||
|
|
||||||
Vue.component('ln-navitem',{
|
Vue.component('ln-navitem',{
|
||||||
props: {
|
props: {
|
||||||
href: {
|
value: {
|
||||||
type: String,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
key: String,
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<router-link
|
<div
|
||||||
:to="href"
|
class="ln-navitem"
|
||||||
class="ln-navitem"unbind
|
:id="'nav-' + key"
|
||||||
v-slot="{ href, route, navigate, isActive, isExactActive }"
|
|
||||||
>
|
>
|
||||||
<div class="ln-navitem">
|
<router-link
|
||||||
<a :href="href" @click="navigate">
|
class="ln-navitem"
|
||||||
<slot></slot>
|
v-if="value.path"
|
||||||
</a>
|
:to="value.path"
|
||||||
<slot name="children"></slot>
|
v-slot="{ href, route, navigate, isActive, isExactActive }"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
:href="href"
|
||||||
|
@click="navigate"
|
||||||
|
>{{ value.label || value.path }}</a>
|
||||||
|
</router-link>
|
||||||
|
<span
|
||||||
|
v-if="!value.path"
|
||||||
|
class="ln-navitem"
|
||||||
|
>{{ value.label }}</span>
|
||||||
|
<div class="ln-nav-children"
|
||||||
|
v-if="value.navigation"
|
||||||
|
>
|
||||||
|
<ln-navitem
|
||||||
|
v-for="(item,key) in value.navigation"
|
||||||
|
v-bind:value="item"
|
||||||
|
v-bind:key="key"
|
||||||
|
></ln-navitem>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</div>
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
Vue.component('ln-navbar',{
|
Vue.component('ln-navbar',{
|
||||||
props: {
|
props: {
|
||||||
navitems: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
default: function(){
|
||||||
}
|
return LNVue.$_.navigation;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
component: {
|
||||||
|
type: [ Object, String ],
|
||||||
|
default: 'ln-navitem',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<div class="ln-navbar">
|
<div class="ln-navbar">
|
||||||
<ln-navitem
|
<div
|
||||||
v-for="navitem in navitems"
|
:is="component"
|
||||||
v-bind:href="navitem.href"
|
v-for="(item,key) in value"
|
||||||
>{{ navitem.label || navitem.href }}</ln-navitem>
|
v-bind:value="item"
|
||||||
|
v-bind:key="key"
|
||||||
|
>{{ item.label || item.path }}</div>
|
||||||
</div>`
|
</div>`
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,45 +8,93 @@
|
||||||
routes: [],
|
routes: [],
|
||||||
data: {},
|
data: {},
|
||||||
}, options );
|
}, options );
|
||||||
|
|
||||||
|
this._el = el;
|
||||||
this.data = Object.assign({}, options.data, { LNVue: this, msg: "Hello World" });
|
this.data = Object.assign({}, options.data, { LNVue: this, msg: "Hello World" });
|
||||||
|
this.promises = [];
|
||||||
|
|
||||||
Vue.prototype.$LNVue = this;
|
Vue.prototype.$LNVue = this;
|
||||||
|
LNVue.$_ = this;
|
||||||
|
|
||||||
console.log("LNVue: preparing");
|
console.log("LNVue: preparing");
|
||||||
|
|
||||||
|
this.navigation = {};
|
||||||
|
|
||||||
Promise
|
Promise
|
||||||
.all(LNVue.promises)
|
.all(LNVue.promises)
|
||||||
.then(()=>{
|
.then(()=>{
|
||||||
console.log("LNVue: starting");
|
console.log("LNVue: starting");
|
||||||
|
|
||||||
let routes = LNVue.routes
|
LNVue.vueRouter.addRoutes([{
|
||||||
.concat(this.options.routes)
|
|
||||||
.concat([{
|
|
||||||
path: "*",
|
path: "*",
|
||||||
component: {
|
component: {
|
||||||
template: `<h2>404 Not Found</h2>The URL you tried to reach is not existing.`,
|
template: `<h2>404 Not Found</h2>The URL you tried to reach is not existing.`,
|
||||||
},
|
},
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
let router = new VueRouter({
|
|
||||||
routes,
|
|
||||||
});
|
|
||||||
|
|
||||||
let vue = new Vue({
|
});
|
||||||
el,
|
|
||||||
data: this.data,
|
|
||||||
router: router,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.vue = function(){ return vue; }
|
|
||||||
|
|
||||||
|
this.vue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Start(){
|
||||||
|
Promise
|
||||||
|
.all(this.promises)
|
||||||
|
.then(()=>{
|
||||||
|
LNVue.onidle(()=>{
|
||||||
|
this.vue = new Vue({
|
||||||
|
el: this._el,
|
||||||
|
data: this.data,
|
||||||
|
router: LNVue.vueRouter,
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Version(){ return "0.1alpha"; };
|
Version(){ return "0.1alpha"; };
|
||||||
|
|
||||||
|
addModule(modSpec){
|
||||||
|
if (modSpec.navigation instanceof Object){
|
||||||
|
LNVue.deepAssign(modSpec.navigation,this.navigation);
|
||||||
|
}
|
||||||
|
|
||||||
|
LNVue.$each(modSpec.routes,(key,route)=>{
|
||||||
|
if ((route instanceof Object) && route.url)
|
||||||
|
{
|
||||||
|
let p = new Promise((resolve,reject)=>{
|
||||||
|
LNVue
|
||||||
|
.fetch(route.url)
|
||||||
|
.then((src)=>{
|
||||||
|
this.addRoute(key,{ template: src, data: ()=>{ return this.data; }, });
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.promises.push(p);
|
||||||
|
} else if (route instanceof Object){
|
||||||
|
this.addRoute(key,{ template: route.template, data: ()=>{ return this.data; }, } );
|
||||||
|
} else {
|
||||||
|
this.addRoute(key,{ template: route, data: ()=>{ return this.data; }, } );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addRoute(path,component){
|
||||||
|
let self = this;
|
||||||
|
LNVue.vueRouter.addRoutes([
|
||||||
|
{ path, component, },
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object.defineProperty( LNVue, '$LNVue', {
|
||||||
|
get: ()=>{ return LNVue.$_; },
|
||||||
|
});
|
||||||
|
|
||||||
|
LNVue.vueRouter = new VueRouter({
|
||||||
|
routes: [],
|
||||||
|
});
|
||||||
|
|
||||||
LNVue.$idles = [];
|
LNVue.$idles = [];
|
||||||
LNVue.onidle = function(cb,thisval = null){
|
LNVue.onidle = function(cb,thisval = null){
|
||||||
let scheduled = LNVue.$idles.length > 0;
|
let scheduled = LNVue.$idles.length > 0;
|
||||||
|
@ -69,6 +117,34 @@
|
||||||
},0);
|
},0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LNVue.$each = function(oa,cb){
|
||||||
|
if (oa instanceof Array){
|
||||||
|
let result = [];
|
||||||
|
oa.forEach((value,index)=>{
|
||||||
|
result.push(cb.call(value,index,value));
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
} else if (oa instanceof Object){
|
||||||
|
let result = {};
|
||||||
|
Object.keys(oa).forEach((key)=>{
|
||||||
|
if (oa.hasOwnProperty(key)){
|
||||||
|
result[key] = cb.call(oa[key],key,oa[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LNVue.deepAssign = function(source,target){
|
||||||
|
LNVue.$each(source,function(key){
|
||||||
|
if (target[key] instanceof Object){
|
||||||
|
LNVue.deepAssign(src[key],target[key]);
|
||||||
|
} else {
|
||||||
|
target[key] = source[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
LNVue.$ = function(src){
|
LNVue.$ = function(src){
|
||||||
let el = document.createElement("parse");
|
let el = document.createElement("parse");
|
||||||
el.innerHTML = src;
|
el.innerHTML = src;
|
||||||
|
@ -106,38 +182,5 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
LNVue.addRouteTemplate = function(path,template){
|
|
||||||
LNVue.routes.push({
|
|
||||||
path,
|
|
||||||
component: {
|
|
||||||
data: function(){
|
|
||||||
return this.$LNVue.data;
|
|
||||||
},
|
|
||||||
template,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
LNVue.addRoute = function(path,url){
|
|
||||||
let p = new Promise((resolve,reject) => {
|
|
||||||
LNVue
|
|
||||||
.fetch(url)
|
|
||||||
.then((src)=>{
|
|
||||||
LNVue.routes.push({
|
|
||||||
path,
|
|
||||||
component: {
|
|
||||||
data: function(){
|
|
||||||
return this.$LNVue.data;
|
|
||||||
},
|
|
||||||
template: src,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
LNVue.promises.push(p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LNVue;
|
return LNVue;
|
||||||
})();
|
})();
|
Loading…
Reference in New Issue