@dwightbcoder/action-ui
Advanced tools
Comparing version 1.0.0 to 1.0.1
{ | ||
"name": "@dwightbcoder/action-ui", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "Action UI is a Javascript framework for building event-base user interfaces", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
# Action UI | ||
Action UI is a ES6 Javascript framework for building event-base user interfaces | ||
The goal of this package is to make decoupled event-driven API-powered websites and applications simpler to produce with minimal learning curve. | ||
Please review the documentation via the [Wiki](https://github.com/dwightbcoder/action-ui/wiki) | ||
## Core Modules | ||
@@ -5,0 +10,0 @@ |
@@ -0,1 +1,2 @@ | ||
import * as Util from './modules/util.js' | ||
export { Action } from './modules/action.js' | ||
@@ -6,4 +7,4 @@ export { Controller } from './modules/controller.js' | ||
export { Router } from './modules/router.js' | ||
export { Util } from './modules/util.js' | ||
export { Util } | ||
export { View } from './modules/view.js' | ||
export { ViewHandlebars } from './modules/view.handlebars.js' |
@@ -1,3 +0,2 @@ | ||
'use strict' | ||
import { Util } from './util.js' | ||
import * as Util from './util.js' | ||
import { Model } from './model.js' | ||
@@ -286,4 +285,4 @@ | ||
verbose: false, | ||
autoCreate: false, | ||
autoCache: false, | ||
autoCreate: true, | ||
autoCache: true, | ||
cssClass: { 'loading': 'loading', 'success': 'success', 'fail': 'fail' }, | ||
@@ -290,0 +289,0 @@ eventBefore: new CustomEvent('action.before', { bubbles: true, detail: { type: 'before', name: null, data: null, model: null } }), |
@@ -1,3 +0,1 @@ | ||
'use strict' | ||
/** | ||
@@ -14,11 +12,5 @@ * Controller | ||
index() | ||
{ | ||
//this.view.render() | ||
} | ||
__autoload() { return this.view.render() } | ||
_404(path) | ||
{ | ||
//this.view.render() | ||
} | ||
__error(e) { return this.view.render() } | ||
@@ -25,0 +17,0 @@ get view() { return this._view } |
@@ -1,3 +0,2 @@ | ||
'use strict' | ||
import { Util } from './util.js' | ||
import * as Util from './util.js' | ||
import { Model } from './model.js' | ||
@@ -4,0 +3,0 @@ |
@@ -1,3 +0,2 @@ | ||
'use strict' | ||
import { Util } from "./util.js"; | ||
import * as Util from "./util.js"; | ||
@@ -69,2 +68,3 @@ /** | ||
_watchers.get(this).push(callback) | ||
return this | ||
} | ||
@@ -76,2 +76,3 @@ | ||
_changes.set(this, {}) | ||
return this | ||
} | ||
@@ -78,0 +79,0 @@ |
@@ -1,14 +0,14 @@ | ||
'use strict' | ||
import { Util } from './util.js' | ||
import * as Util from './util.js' | ||
import { Controller } from './controller.js' | ||
import { View } from './view.js' | ||
import { ViewHandlebars } from './view.handlebars.js' | ||
//import { View } from './view.js' | ||
class Router | ||
{ | ||
constructor(controllers, view, state = {}) | ||
constructor(controllers = {}, view = 'controller', state = {}) | ||
{ | ||
this.controllers = controllers | ||
this._instance = {} | ||
this._view = view | ||
this._state = state | ||
this.view = (view instanceof View) ? view : new View(view) | ||
this.state = state | ||
window.addEventListener('popstate', this.changeState.bind(this)) | ||
@@ -27,3 +27,3 @@ } | ||
if (!this.controllers[controller]) | ||
if (! this.controllers[controller]) | ||
{ | ||
@@ -37,5 +37,11 @@ pathController = _options.defaultController | ||
{ | ||
this._instance[controller] = new this.controllers[controller](this._view) | ||
if ( this.controllers[controller] ) | ||
{ | ||
this._instance[controller] = new this.controllers[controller](this.view) | ||
} | ||
else | ||
{ | ||
this._instance[controller] = new Controller(this.view) | ||
} | ||
} | ||
@@ -50,3 +56,9 @@ pathMethod = pathMethod || _options.defaultMethod | ||
} | ||
if (_options.autoload && ! (this._instance[controller][method] instanceof Function)) | ||
{ | ||
method = _options.autoloadMethod | ||
} | ||
model.dev = location.host == _options.devHost | ||
model.view = template | ||
@@ -72,3 +84,7 @@ model.controller = pathController | ||
this._instance[controller].view.model.clear().sync(model) | ||
this._instance[controller].view.model | ||
.clear() | ||
.sync(model) | ||
.clearChanges() | ||
result = this._instance[controller][method] | ||
@@ -79,12 +95,3 @@ .apply(this._instance[controller], args) | ||
{ | ||
if ( this._instance[controller].view instanceof ViewHandlebars) | ||
{ | ||
this._instance[controller].view.html = _options.errorView | ||
} | ||
model.view = _options.errorView | ||
model.path = path.join('/') | ||
this._instance[controller].view.model.clear().sync(model) | ||
result = this._instance[controller][_options.errorMethod]() | ||
result = this.handleError(controller, model, path) | ||
} | ||
@@ -94,3 +101,3 @@ | ||
{ | ||
Util.deepAssign(this._state, | ||
Util.deepAssign(this.state, | ||
{ | ||
@@ -104,3 +111,3 @@ route: route, | ||
history.pushState(this._state, null, route) | ||
history.pushState(this.state, null, route) | ||
} | ||
@@ -110,7 +117,14 @@ | ||
{ | ||
let viewContainer = document.querySelectorAll('[ui-view="' + this._view.name + '"]') | ||
let viewContainer = document.querySelectorAll('[ui-view="' + this.view.name + '"]') | ||
viewContainer.forEach(el => el.classList.add(_options.cssClass.loading)) | ||
this.handleLoading(viewContainer, true) | ||
result.then(() => viewContainer.forEach(el => el.classList.remove(_options.cssClass.loading))) | ||
result | ||
.then(() => this.handleLoading(viewContainer, false)) | ||
.catch(e => | ||
{ | ||
this.handleLoading(viewContainer, false) | ||
this.handleError(controller, model, path, e) | ||
throw e | ||
}) | ||
} | ||
@@ -121,2 +135,31 @@ | ||
handleLoading(elements, loading) | ||
{ | ||
if ( loading ) | ||
{ | ||
elements.forEach(el => el.classList.add(_options.cssClass.loading)) | ||
} | ||
else | ||
{ | ||
elements.forEach(el => el.classList.remove(_options.cssClass.loading)) | ||
} | ||
return this | ||
} | ||
handleError(controller, model, path, error) | ||
{ | ||
if ( this._instance[controller].view instanceof ViewHandlebars) | ||
{ | ||
this._instance[controller].view.html = _options.errorView | ||
} | ||
model.error = error | ||
model.view = _options.errorView | ||
model.path = path.join('/') | ||
this._instance[controller].view.model.clear().sync(model).clearChanges() | ||
return this._instance[controller][_options.errorMethod]() | ||
} | ||
sanitizePath(path) | ||
@@ -178,10 +221,13 @@ { | ||
let _options = { | ||
autoload: true, | ||
verbose: false, | ||
cssClass: { 'loading': 'loading', 'success': 'success', 'fail': 'fail' }, | ||
defaultController: 'default', | ||
autoloadMethod: '__autoload', | ||
defaultMethod: 'index', | ||
errorMethod: '_404', | ||
errorView: '404' | ||
errorMethod: '__error', | ||
errorView: 'error', | ||
devHost: 'localhost' | ||
} | ||
export { Router } |
@@ -1,26 +0,17 @@ | ||
'use strict' | ||
/** | ||
* Utilities | ||
*/ | ||
class Util | ||
function deepAssign(target, source) | ||
{ | ||
static deepAssign(target, source) | ||
for (let i in source) | ||
{ | ||
for (let i in source) | ||
if (source.hasOwnProperty(i)) | ||
{ | ||
if (source.hasOwnProperty(i)) | ||
if (target.hasOwnProperty(i)) | ||
{ | ||
if (target.hasOwnProperty(i)) | ||
if (source[i] instanceof Object) | ||
{ | ||
if (source[i] instanceof Object) | ||
{ | ||
Util.deepAssign(target[i], source[i]) | ||
} | ||
else if (target[i] != source[i]) | ||
{ | ||
target[i] = source[i] | ||
} | ||
deepAssign(target[i], source[i]) | ||
} | ||
else | ||
else if (target[i] != source[i]) | ||
{ | ||
@@ -30,31 +21,35 @@ target[i] = source[i] | ||
} | ||
} | ||
} | ||
static requestFromElement(element) | ||
{ | ||
return new Request( | ||
element.action || options.href || null, | ||
else | ||
{ | ||
method: element.method || null | ||
target[i] = source[i] | ||
} | ||
) | ||
} | ||
} | ||
} | ||
static form(element) | ||
{ | ||
return element.tagName == 'FORM' ? element : element.form | ||
} | ||
function requestFromElement(element) | ||
{ | ||
return new Request( | ||
element.action || options.href || null, | ||
{ | ||
method: element.method || null | ||
} | ||
) | ||
} | ||
static capitalize(str) | ||
{ | ||
return str[0].toUpperCase() + str.substr(1).toLowerCase() | ||
} | ||
function form(element) | ||
{ | ||
return element.tagName == 'FORM' ? element : element.form | ||
} | ||
static camelCase(str) | ||
{ | ||
return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (match, chr) => chr.toUpperCase()) | ||
} | ||
function capitalize(str) | ||
{ | ||
return str[0].toUpperCase() + str.substr(1).toLowerCase() | ||
} | ||
export { Util } | ||
function camelCase(str) | ||
{ | ||
return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_match, chr) => chr.toUpperCase()) | ||
} | ||
export { deepAssign, requestFromElement, form, capitalize, camelCase } |
@@ -1,2 +0,1 @@ | ||
'user strict' | ||
import { View } from './view.js' | ||
@@ -44,5 +43,5 @@ | ||
_promise = fetch(ViewHandlebars.options.basePath + template) | ||
.then((response) => { if (response.ok) return response.text() }) | ||
.then((html) => this._html = Handlebars.compile(html)) | ||
.catch((e) => console.error('Template not found: ' + template)) | ||
.then(response => { if (response.ok) return response.text() }) | ||
.then(html => this._html = Handlebars.compile(html)) | ||
.catch(e => { throw new Error('Template not found: ' + template) }) | ||
} | ||
@@ -49,0 +48,0 @@ } |
@@ -1,3 +0,2 @@ | ||
'use strict' | ||
import { Util } from './util.js' | ||
import * as Util from './util.js' | ||
import { Model } from './model.js' | ||
@@ -4,0 +3,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
30489
13
882
37