Catalog filter, builder ids
gitea/hedera-web/pipeline/head This commit looks good Details

This commit is contained in:
Juan Ferrer 2022-05-28 21:27:36 +02:00
parent 0141eea534
commit 3de2c2f9fe
22 changed files with 475 additions and 484 deletions

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
hedera-web (1.407.74) stable; urgency=low
hedera-web (1.407.75) stable; urgency=low
* Initial Release.

View File

@ -25,7 +25,7 @@ Hedera.Catalog = new Class({
,activate: function() {
document.body.appendChild(this.$.rightPanel);
this.$.itemsModel.setInfo('i', 'item', 'vn', ['id']);
this.$.items.setInfo('i', 'item', 'vn', ['id']);
if (localStorage.getItem('hederaView'))
this.setView(parseInt(localStorage.getItem('hederaView')));
@ -39,6 +39,103 @@ Hedera.Catalog = new Class({
Vn.Node.remove(this.$.rightPanel);
}
,onFilterChange: function() {
const $ = this.$;
const params = [
'search',
'realm',
'type',
'color',
'origin',
'category',
'producer'
];
const lot = {};
for (const param of params)
lot[param] = this.$[param].value;
if (lot.search != null || lot.type != null) {
const filter = new Sql.Operation({
type: Sql.Operation.Type.AND
});
const exprs = filter.exprs;
let idSearch = false;
if (lot.search != null) {
idSearch = /^\d+$/.test(lot.search);
exprs.add(idSearch ? $.idOp : $.nameOp);
}
if (!idSearch) {
if (lot.realm != null)
exprs.add($.realmOp);
if (lot.type != null)
exprs.add($.typeOp);
const tags = [
'color',
'origin',
'category',
'producer'
];
for (const tag of tags)
if (lot[tag] != null)
exprs.add($[`${tag}Op`]);
}
const batch = new Sql.Batch();
batch.addObject('filter', filter);
batch.block();
$.items.batch = batch;
} else
$.items.batch = null;
}
,onRealmChange: function() {
const hasRealm = this.$.realm.value != null;
this.$.filters.style.display = hasRealm ? 'block' : 'none';
this.$.realmMsg.style.display = hasRealm ? 'none' : 'block';
this.onFilterChange();
this.refreshTitle();
}
,onTypeChange: function() {
this.onFilterChange();
this.refreshTitle();
}
,refreshTitle: function() {
const types = this.$.types;
const realms = this.$.realms;
const type = this.$.type.value;
const realm = this.$.realm.value;
let typeName;
let realmName;
if (type && types.ready) {
var row = types.search('id', type);
if (row != -1) typeName = types.get(row, 'name');
}
if (realm && realms.ready) {
var row = realms.search('id', realm);
if (row != -1) realmName = realms.get(row, 'name');
}
let title = _('Catalog');
let subtitle = '';
if (typeName) {
title = typeName;
subtitle = realmName;
} else if (realmName) {
title = realmName;
}
Vn.Node.setText(this.$.titleText, title);
Vn.Node.setText(this.$.subtitle, subtitle);
}
,setView: function(view) {
if (view === Hedera.Catalog.View.GRID) {
this.$.viewButton.setProperties({
@ -87,16 +184,11 @@ Hedera.Catalog = new Class({
Db.Model.SortWay.ASC : Db.Model.SortWay.DESC;
if (sortField)
this.$.itemsModel.sortByName(sortField, sortWay);
this.$.items.sortByName(sortField, sortWay);
this.hideMenu();
}
,onFilterChange: function(param, newValue) {
if (newValue)
this.hideMenu();
}
,realmRenderer: function(builder, form) {
var link = builder.$.link;
link.href = this.hash.make({
@ -105,57 +197,6 @@ Hedera.Catalog = new Class({
});
}
,onRealmChange: function(param, newValue) {
if (newValue) {
this.$.filters.style.display = 'block';
this.$.realmMsg.style.display = 'none';
} else {
this.$.filters.style.display = 'none';
this.$.realmMsg.style.display = 'block';
}
this.refreshFilter(newValue, undefined);
}
,onTypeChange: function(param, newValue) {
this.onFilterChange(param, newValue);
this.refreshTitle();
this.refreshFilter(undefined, newValue);
}
,refreshFilter: function(realm, type) {
var batch = this.$.filterBatch;
batch.block();
this.$.realmValue.value = realm;
this.$.typeValue.value = type;
this.$.search.value = undefined;
this.$.color.value = undefined;
this.$.origin.value = undefined;
this.$.category.value = undefined;
this.$.producer.value = undefined;
batch.unblock();
batch.changed();
}
,refreshTitle: function() {
var types = this.$.typesModel;
if (!types.ready)
return;
var title = _('Catalog');
var type = this.$.type.value;
if (type) {
var row = types.search('id', type);
if (row != -1)
title = types.get(row, 'name');
}
Vn.Node.setText(this.$.titleText, title);
}
,onRightPanelClick: function(event) {
event.stopPropagation();
}

View File

@ -1,6 +1,10 @@
.catalog {
margin-right: 18em;
}
.title ._subtitle {
font-size: .7rem;
color: #bbb;
}
/* Right panel */
@ -177,7 +181,16 @@
.item-info > .htk-button > img {
vertical-align: middle;
}
.item-info .item-id {
float: right;
font-size: .8rem;
line-height: 1.8em;
color: #777;
}
.item-info .available-price {
position: absolute;
bottom: 0;
right: 0;
white-space: nowrap;
font-size: .95em;
text-align: right;
@ -251,11 +264,6 @@
flex: auto;
overflow: hidden;
}
.grid-view .item-info .available-price {
position: absolute;
bottom: 0;
right: 0;
}
.grid-view .item-info .tags td {
overflow: hidden;
white-space: nowrap;
@ -305,13 +313,6 @@
.list-view .item-info > .htk-button {
float: right;
}
.list-view .item-info .available-price {
clear: both;
float: right;
position:absolute;
bottom: 0;
right: 0;
}
.list-view .item-info .tags {
display: block;
text-overflow: ellipsis;

View File

@ -1,45 +1,91 @@
<vn>
<div id="title">
<h1 id="title-text"><t>Catalog</t></h1>
<div id="subtitle"></div>
</div>
<div id="actions" class="catalog-actions">
<htk-search-entry
param="search"/>
<htk-bar-button
id="view-button"
tip="_Switch view"
icon="view_list"
on-click="this.onSwitchViewClick()"/>
<htk-bar-button
icon="shopping_cart_checkout"
tip="_ShoppingBasket"
on-click="this.onBasketClick()"/>
<button
class="menu"
on-click="onShowMenuClick">
<htk-icon name="menu" alt="_Menu"/>
</button>
</div>
<vn-group>
<vn-param id="card-item"/>
<vn-param id="realm" on-changed="onRealmChange"/>
<vn-param id="type" on-changed="onTypeChange"/>
<vn-param id="search" on-changed="onFilterChange"/>
<vn-param id="color" on-changed="onFilterChange"/>
<vn-param id="origin" on-changed="onFilterChange"/>
<vn-param id="category" on-changed="onFilterChange"/>
<vn-param id="producer" on-changed="onFilterChange"/>
<vn-hash-param key="realm" param="realm"/>
<vn-hash-param key="type" param="type"/>
<sql-filter type="AND" id="filter">
<sql-filter-item type="EQUAL" primary="false" id="op-realm">
<sql-field target="t" name="categoryFk"/>
<sql-value id="realm-value"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-type">
<sql-field target="i" name="typeFk"/>
<sql-value id="type-value"/>
</sql-filter-item>
<sql-filter-item type="LIKE" id="op-name">
<sql-field target="i" name="longName"/>
<sql-search-tags param="search"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-color">
<sql-field target="i" name="inkFk"/>
<sql-value param="color"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-origin">
<sql-field target="i" name="originFk"/>
<sql-value param="origin"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-category">
<sql-field target="i" name="category"/>
<sql-value param="category"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-producer">
<sql-field target="i" name="producerFk"/>
<sql-value param="producer"/>
</sql-filter-item>
</sql-filter>
</vn-group>
<vn-group>
<vn-param id="card-item"/>
<vn-param id="search" on-changed="this.onFilterChange()"/>
<vn-param id="realm" on-changed="this.onRealmChange()"/>
<vn-param id="type" on-changed="this.onTypeChange()"/>
<vn-param id="color" on-changed="this.onFilterChange()"/>
<vn-param id="origin" on-changed="this.onFilterChange()"/>
<vn-param id="category" on-changed="this.onFilterChange()"/>
<vn-param id="producer" on-changed="this.onFilterChange()"/>
</vn-group>
<vn-group>
<sql-operation
id="id-op"
type="EQUAL">
<sql-field target="i" name="id"/>
<sql-value param="search"/>
</sql-operation>
<sql-operation
id="name-op"
type="LIKE">
<sql-field target="i" name="longName"/>
<sql-search-tags param="search"/>
</sql-operation>
<sql-operation
id="realm-op"
type="EQUAL">
<sql-field target="t" name="categoryFk"/>
<sql-value param="realm"/>
</sql-operation>
<sql-operation
id="type-op"
type="EQUAL">
<sql-field target="i" name="typeFk"/>
<sql-value param="type"/>
</sql-operation>
<sql-operation
id="color-op"
type="EQUAL">
<sql-field target="i" name="inkFk"/>
<sql-value param="color"/>
</sql-operation>
<sql-operation
type="EQUAL"
id="origin-op">
<sql-field target="i" name="originFk"/>
<sql-value param="origin"/>
</sql-operation>
<sql-operation
type="EQUAL"
id="category-op">
<sql-field target="i" name="category"/>
<sql-value param="category"/>
</sql-operation>
<sql-operation
id="producer-op"
type="EQUAL">
<sql-field target="i" name="producerFk"/>
<sql-value param="producer"/>
</sql-operation>
</vn-group>
<vn-group>
<db-form id="basket" on-ready="onBasketReady">
<db-model property="model">
SELECT b.id, b.sent, a.description agency, m.code method
@ -49,7 +95,7 @@
</db-model>
</db-form>
<db-model
id="items-model"
id="items"
result-index="2"
on-status-changed="onItemsChange">
CREATE TEMPORARY TABLE tmp.item
@ -77,47 +123,21 @@
WHERE b.available > 0
ORDER BY i.relevancy DESC, i.name, i.size
LIMIT 5000;
<sql-batch property="batch" id="filter-batch">
<custom>
<item name="filter" object="filter"/>
</custom>
</sql-batch>
</db-model>
<db-form id="card" model="items-model"/>
<db-form id="card" model="items"/>
<sql-batch id="card-batch">
<custom>
<item name="item" param="card-item"/>
</custom>
</sql-batch>
</vn-group>
<div id="title">
<h1 id="title-text"><t>Catalog</t></h1>
</div>
<div id="actions" class="catalog-actions">
<htk-search-entry
param="search"/>
<htk-bar-button
id="view-button"
tip="_Switch view"
icon="view_list"
on-click="this.onSwitchViewClick()"/>
<htk-bar-button
icon="shopping_cart_checkout"
tip="_ShoppingBasket"
on-click="this.onBasketClick()"/>
<button
class="menu"
on-click="onShowMenuClick">
<htk-icon name="menu" alt="_Menu"/>
</button>
</div>
<div id="form" class="catalog">
<div id="main" class="main">
<htk-repeater
id="grid-view"
empty-message="_Choose filter from right menu"
form-id="item"
model="items-model" >
model="items" >
<custom>
<div
id="item-box"
@ -134,6 +154,9 @@
title="_Zoom image"/>
<div class="item-info">
<h2>
<span class="item-id">
#{{item.id}}
</span>
{{item.item}}
</h2>
<p class="sub-name">
@ -187,13 +210,13 @@
<div class="categories">
<div class="realms">
<htk-repeater
model="realms-model"
form-id="form"
renderer="realmRenderer"
class="realms-box">
<db-model
id="realms-model"
property="model">
id="realms"
property="model"
on-status-changed="refreshTitle">
SELECT c.id, l.name, c.color, c.code
FROM vn.itemCategory c
JOIN vn.itemCategoryL10n l ON l.id = c.id
@ -220,9 +243,10 @@
<h2><t>Filter by</t></h2>
<vn-filter
placeholder="_Family"
param="type">
param="type"
id="type-filter">
<db-model
id="types-model"
id="types"
property="model"
conn="conn"
result-index="1"
@ -245,7 +269,8 @@
</vn-filter>
<vn-filter
placeholder="_Color"
param="color">
param="color"
id="color-filter">
<db-model property="model" auto-load="false" result-index="1">
CALL myBasket_getAvailable;
SELECT DISTINCT l.id, l.name
@ -256,18 +281,11 @@
WHERE #filter
ORDER BY name
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-origin"/>
<pointer object="op-category"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Producer"
param="producer">
param="producer"
id="producer-filter">
<db-model property="model" auto-load="false" result-index="1">
CALL myBasket_getAvailable;
SELECT DISTINCT p.id, p.name
@ -278,18 +296,11 @@
WHERE #filter
ORDER BY name
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-origin"/>
<pointer object="op-color"/>
<pointer object="op-category"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Origin"
param="origin">
param="origin"
id="origin-filter">
<db-model property="model" auto-load="false" result-index="1">
CALL myBasket_getAvailable;
SELECT DISTINCT o.id, l.name, o.code
@ -301,18 +312,11 @@
WHERE #filter
ORDER BY name
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-color"/>
<pointer object="op-category"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Category"
param="category">
param="category"
id="category-filter">
<db-model property="model" auto-load="false" result-index="1">
CALL myBasket_getAvailable;
SELECT DISTINCT i.category, i.category
@ -322,14 +326,6 @@
WHERE #filter
ORDER BY category
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-color"/>
<pointer object="op-origin"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
</div>
<div id="order" class="order">

View File

@ -1,5 +1,5 @@
var NodeBuilder = require('./node-builder');
var NodeBuilder = require('../vn/node-builder');
/**
* Represents a grid column. This is an abstract class and should not be

View File

@ -59,7 +59,6 @@ module.exports = new Class({
}
,_onChange: function() {
console.log(this._val);
if (this.node.checked && this._radioGroup)
this._radioGroup.value = this._val || this.value;
}

View File

@ -3,8 +3,7 @@ require('db/db');
require('./style/index.scss');
Htk = module.exports = {
NodeBuilder : require('./node-builder')
,Widget : require('./widget')
Widget : require('./widget')
,Component : require('./component')
,Popup : require('./popup')
,Dialog : require('./dialog')

View File

@ -1,10 +1,9 @@
const NodeBuilder = require('./node-builder');
const NodeBuilder = require('../vn/node-builder');
const Widget = new Class({
Extends: NodeBuilder
,Properties:
{
,Properties: {
/**
* Main HTML node that represents the widget
*/
@ -24,7 +23,7 @@ const Widget = new Class({
this.node.style = x;
}
,get: function() {
return this.node.style;
return this._node.style;
}
},
/**
@ -46,7 +45,7 @@ const Widget = new Class({
classList: {
type: Object
,get: function() {
return this.node.classList;
return this._node.classList;
}
},
/**
@ -55,12 +54,26 @@ const Widget = new Class({
title: {
type: String
,set: function(x) {
this.node.title = x;
this._node.title = x;
}
,get: function() {
return this.node.title;
return this._node.title;
}
}
},
/**
* The HTML id of the element.
*/
htmlId:
{
type: String
,set: function(x) {
this._htmlId = x;
this._node.id = x;
}
,get: function() {
return this._htmlId;
}
},
}
,_node: null

View File

@ -8,10 +8,8 @@ var Value = require('./value');
module.exports = new Class({
Extends: Object
,Tag: 'sql-batch'
,Properties:
{
blocked:
{
,Properties: {
blocked: {
type: Boolean
,set: function(x) {
this._blocked = x;

View File

@ -1,33 +1,29 @@
var Stmt = require ('./stmt');
var Value = require ('./value');
var Field = require ('./field');
var Stmt = require('./stmt');
var Value = require('./value');
var Field = require('./field');
/**
* The equivalent of a SQL DML.
*/
module.exports = new Class
({
module.exports = new Class({
Extends: Stmt
,field: []
,expr: []
,addSet: function (fieldName, value)
{
this.expr.push (new Value ({value: value}));
this.field.push (new Field ({name: fieldName}));
,addSet: function(fieldName, value) {
this.expr.push(new Value({value: value}));
this.field.push(new Field({name: fieldName}));
}
,addExpr: function (fieldName, expr)
{
this.expr.push (expr);
this.field.push (new Field ({name: fieldName}));
,addExpr: function(fieldName, expr) {
this.expr.push(expr);
this.field.push(new Field({name: fieldName}));
}
,delSet: function ()
{
this.field.splice (0, this.field.length);
this.expr.splice (0, this.expr.length);
,delSet: function() {
this.field.splice(0, this.field.length);
this.expr.splice(0, this.expr.length);
}
});

View File

@ -4,8 +4,7 @@ var Object = require('./object');
/**
* The equivalent of a SQL expression.
*/
module.exports = new Class
({
module.exports = new Class({
Extends: Object
,Tag: 'sql-expr'
});

View File

@ -4,14 +4,11 @@ var Operation = require('./operation');
/**
* The equivalent of a SQL operation.
*/
module.exports = new Class
({
module.exports = new Class({
Extends: Operation
,Tag: 'sql-filter-item'
,Properties:
{
primary:
{
,Properties: {
primary: {
type: Boolean
}
}

View File

@ -1,50 +1,44 @@
var Operation = require ('./operation');
var Operation = require('./operation');
/**
* The equivalent of a SQL operation.
*/
module.exports = new Class
({
module.exports = new Class({
Extends: Operation
,Tag: 'sql-filter'
,Properties:
{
alwaysReady:
{
,Properties: {
alwaysReady: {
type: Boolean
}
}
,isReady: function ()
{
,isReady: function() {
if (this.alwaysReady)
return true;
var e = this.exprs.getArray ();
var e = this.exprs.getArray();
for (var i = 0; i < e.length; i++)
if (e[i].isReady () && e[i].primary)
if (e[i].isReady() && e[i].primary)
return true;
return false;
}
,render: function (batch)
{
,render: function(batch) {
var isReady = false;
var newOp = new Operation ({type: this.type});
var newOp = new Operation({type: this.type});
var e = this.exprs.getArray ();
var e = this.exprs.getArray();
for (var i = 0; i < e.length; i++)
if (e[i].isReady ())
{
newOp.exprs.add (e[i]);
if (e[i].isReady()) {
newOp.exprs.add(e[i]);
isReady = true;
}
if (!isReady)
return 'TRUE';
return newOp.render (batch);
return newOp.render(batch);
}
});

View File

@ -1,69 +1,60 @@
var Object = require ('./object');
var Object = require('./object');
/**
* List of Sql.Object
*/
module.exports = new Class
({
module.exports = new Class({
Extends: Object
,objects: []
,add: function (object)
{
this.objects.push (object.ref ());
object.on ('changed', this._onObjectChange, this);
this._onObjectChange ();
,add: function(object) {
this.objects.push(object.ref());
object.on('changed', this._onObjectChange, this);
this._onObjectChange();
}
,get: function (i)
{
,get: function(i) {
return objects[i];
}
,getArray: function ()
{
,getArray: function() {
return this.objects;
}
,remove: function (i)
{
this._unrefObject (this.objects.splice (i, 1));
this._onObjectChange ();
,remove: function(i) {
this._unrefObject(this.objects.splice(i, 1));
this._onObjectChange();
}
,_onObjectChange: function ()
{
this.signalEmit ('changed');
,_onObjectChange: function() {
this.signalEmit('changed');
}
,isReady: function ()
{
,isReady: function() {
var o = this.objects;
if (o.length == 0)
return false;
for (var i = 0; i < o.length; i++)
if (!o[i].isReady ())
if (!o[i].isReady())
return false;
return true;
}
,_unrefObject: function (object)
{
object.disconnect ('changed', this._onObjectChange, this);
object.unref ();
,_unrefObject: function(object) {
object.disconnect('changed', this._onObjectChange, this);
object.unref();
}
,_destroy: function ()
{
,_destroy: function() {
for (var i = 0; i < this.objects.length; i++)
this._unrefObject (this.objects[i]);
this._unrefObject(this.objects[i]);
this.parent ();
this.parent();
}
});

View File

@ -1,8 +1,7 @@
/**
* Base class for all objects on this library.
*/
module.exports = new Class
({
module.exports = new Class({
Extends: Vn.Object
/**
@ -11,15 +10,14 @@ module.exports = new Class
* @param {Sql.Batch} batch The batch used to render the object
* @return {String} The SQL string
*/
,render: function (batch) {}
,render: function(batch) {}
/**
* Gets if the object is ready to be rendered.
*
* @return {boolean} %true if the object is ready, %false otherwise
*/
,isReady: function ()
{
,isReady: function() {
return true;
}
@ -28,5 +26,5 @@ module.exports = new Class
*
* @return {Sql.Batch} batch The batch
*/
,findHolders: function (batch) {}
,findHolders: function(batch) {}
});

View File

@ -1,5 +1,5 @@
var Expr = require ('./expr');
var Expr = require('./expr');
/**
* The equivalent of a SQL operation between exprs.
@ -7,11 +7,10 @@ var Expr = require ('./expr');
* @param {Array#Sql.Expr} expr Array with the exprs
* @param {Sql..Operation.Type} type The type of the operation
*/
var Operation = new Class ();
var Operation = new Class();
module.exports = Operation;
var Type =
{
var Type = {
EQUAL : 0
,LIKE : 1
,AND : 2
@ -19,8 +18,7 @@ var Type =
,REGEXP : 4
};
var Operators =
[
var Operators = [
'='
,'LIKE'
,'AND'
@ -28,58 +26,48 @@ var Operators =
,'REGEXP'
];
Operation.extend
({
Operation.extend({
Type: Type
,Operators: Operators
});
Operation.implement
({
Operation.implement({
Extends: Expr
,Tag: 'sql-operation'
,Properties:
{
type:
{
,Properties: {
type: {
enumType: Type
,value: -1
}
}
,initialize: function (props)
{
this.parent (props);
this.link ({exprs: new Sql.List ()}, {'changed': this.onListChange});
,initialize: function(props) {
this.parent(props);
this.link({exprs: new Sql.List()}, {'changed': this.onListChange});
}
,appendChild: function (child)
{
this.exprs.add (child);
,appendChild: function(child) {
this.exprs.add(child);
}
,onListChange: function ()
{
this.signalEmit ('changed');
,onListChange: function() {
this.signalEmit('changed');
}
,isReady: function ()
{
return this.exprs.isReady ();
,isReady: function() {
return this.exprs.isReady();
}
,render: function (batch)
{
,render: function(batch) {
var sql = '(';
var operator = ' '+ Operators[this.type] +' ';
var e = this.exprs.getArray ();
var e = this.exprs.getArray();
for (var i = 0; i < e.length; i++)
{
for (var i = 0; i < e.length; i++) {
if (i > 0)
sql += operator;
sql += e[i].render (batch);
sql += e[i].render(batch);
}
sql += ')';

View File

@ -8,13 +8,11 @@ module.exports = new Class({
Extends: Expr
,Tag: 'sql-value'
,Properties:
{
,Properties: {
/**
* The master param.
*/
param:
{
param: {
type: Vn.Param
,set: function(x) {
this.link({_param: x}, {'changed': this.onParamChange});
@ -27,8 +25,7 @@ module.exports = new Class({
/**
* The value.
*/
value:
{
value: {
type: String
,set: function(x) {
if (Vn.Value.compare(x, this._value))

View File

@ -1,4 +1,6 @@
const VnObject = require('./object');
const Widget = require('../htk/widget');
const VnNode = require('./node');
const Scope = require('./scope');
const kebabToCamel = require('./string-util').kebabToCamel;
@ -123,8 +125,10 @@ module.exports = new Class({
if (isElement) {
var nodeId = node.getAttribute('id');
if (nodeId)
if (nodeId) {
this._contextMap[kebabToCamel(nodeId)] = context.id;
context.nodeId = nodeId;
}
var tags = this._tags[tagName];
@ -161,23 +165,24 @@ module.exports = new Class({
if (this._contexts === null)
return null;
const doc = dstDocument ? dstDocument : document;
const contexts = this._contexts;
const len = contexts.length;
const objects = new Array(len);
const doc = dstDocument ? dstDocument : document;
const scope = new Scope(this, objects, thisArg, parentScope);
for (var i = 0; i < len; i++) {
var context = contexts[i];
if (context.tagName)
objects[i] = this.elementInstantiate(doc, context);
objects[i] = this.elementInstantiate(doc, context, scope);
else if (context.klass)
objects[i] = this.objectInstantiate(doc, context);
objects[i] = this.objectInstantiate(doc, context, scope);
else
objects[i] = this.textInstantiate(doc, context);
objects[i] = this.textInstantiate(doc, context, scope);
}
return new Scope(this, objects, thisArg, parentScope);
return scope;
}
,link: function(scope, exprScope) {
@ -502,13 +507,20 @@ module.exports = new Class({
}
}
,objectInstantiate: function(doc, context) {
return new context.klass();
,objectInstantiate: function(doc, context, scope) {
const object = new context.klass();
object.setProperties(context.props);
if (context.nodeId && object instanceof Widget) {
var id = context.nodeId;
object.htmlId = scope.getHtmlId(id);
object.className = '_'+ id +' '+ object.className;
}
return object;
}
,objectLink: function(context, object, objects, scope, exprScope) {
object.setProperties(context.props);
const objectProps = context.objectProps;
for (const prop in objectProps)
object[prop] = objects[objectProps[prop]];
@ -609,20 +621,28 @@ module.exports = new Class({
};
}
,elementInstantiate: function(doc, context) {
return doc.createElement(context.tagName);
}
,elementInstantiate: function(doc, context, scope) {
var object = doc.createElement(context.tagName);
,elementLink: function(context, object, objects, scope, exprScope) {
const attributes = context.attributes;
for (const attribute in attributes)
object.setAttribute(attribute, attributes[attribute]);
if (context.nodeId) {
const id = context.nodeId;
object.setAttribute('id', scope.getHtmlId(id));
VnNode.addClass(object, '_'+ id);
}
return object;
}
,elementLink: function(context, object, objects, scope, exprScope) {
const childs = context.childs;
for (var i = 0; i < childs.length; i++) {
let child = objects[childs[i]];
if (child instanceof Htk.Widget)
if (child instanceof Widget)
child = child.node;
if (child instanceof Node)
object.appendChild(child);

View File

@ -1,6 +1,7 @@
const VnObject = require('./object');
module.exports = new Class({
Extends: Vn.Object
Extends: VnObject
,doc: null

View File

@ -1,6 +1,8 @@
const VnObject = require('./object');
const kebabToCamel = require('./string-util').kebabToCamel;
let scopeUid = 0;
module.exports = new Class({
Extends: VnObject
@ -9,6 +11,7 @@ module.exports = new Class({
this.objects = objects;
this.thisArg = thisArg;
this.parentScope = parent;
this.uid = ++scopeUid;
this.$ = parent ? Object.create(parent.$) : {};
if (!thisArg && parent)

View File

@ -1,40 +1,39 @@
require ('mootools');
require('mootools');
Vn = module.exports = {
Locale : require ('./locale')
,Enum : function () {}
,Object : require ('./object')
,Browser : require ('./browser')
,Cookie : require ('./cookie')
,Date : require ('./date')
,Value : require ('./value')
,Url : require ('./url')
,Mutators : require ('./mutators')
,Param : require ('./param')
,HashListener : require ('./hash-listener')
,Hash : require ('./hash')
,HashParam : require ('./hash-param')
,Node : require ('./node')
,Builder : require ('./builder')
,JsonException : require ('./json-exception')
,JsonConnection : require ('./json-connection')
Locale : require('./locale')
,Enum : function() {}
,Object : require('./object')
,Browser : require('./browser')
,Cookie : require('./cookie')
,Date : require('./date')
,Value : require('./value')
,Url : require('./url')
,Mutators : require('./mutators')
,Param : require('./param')
,HashListener : require('./hash-listener')
,Hash : require('./hash')
,HashParam : require('./hash-param')
,Node : require('./node')
,NodeBuilder : require('./node-builder')
,Builder : require('./builder')
,JsonException : require('./json-exception')
,JsonConnection : require('./json-connection')
,Config: {}
,includes: {}
,cssIncludes: {}
,currentDeps: []
,currentCallback: null
,head: document.getElementsByTagName ('head')[0]
,head: document.getElementsByTagName('head')[0]
,isMobileCached: null
,getVersion: function ()
{
if (this._version === undefined)
{
,getVersion: function() {
if (this._version === undefined) {
var re = /[; ]vnVersion=([^\\s;]*)/;
var sMatch = (' '+ document.cookie).match (re);
this._version = (sMatch) ? '?'+ unescape (sMatch[1]) : '';
var sMatch = (' '+ document.cookie).match(re);
this._version = (sMatch) ? '?'+ unescape(sMatch[1]) : '';
}
return this._version;
@ -46,26 +45,22 @@ Vn = module.exports = {
*
* @param {string} fileName The stylesheet file name
*/
,includeCss: function (fileName)
{
,includeCss: function(fileName) {
var cssData = this.cssIncludes[fileName];
if (!cssData)
{
var link = document.createElement ('link');
if (!cssData) {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = fileName + this.getVersion ();
this.head.appendChild (link);
link.href = fileName + this.getVersion();
this.head.appendChild(link);
this.cssIncludes[fileName] =
{
included: true
,link: link
};
}
else if (!cssData.included)
{
} else if (!cssData.included) {
cssData.link.disabled = false;
cssData.included = true;
}
@ -76,19 +71,16 @@ Vn = module.exports = {
*
* @param {string} fileName The stylesheet file name
*/
,excludeCss: function (fileName)
{
,excludeCss: function(fileName) {
var cssData = this.cssIncludes[fileName];
if (cssData && cssData.included)
{
if (cssData && cssData.included) {
cssData.link.disabled = true;
cssData.included = false;
}
}
,_createIncludeData: function (path)
{
,_createIncludeData: function(path) {
var includeData = {
depCount: 0
,success: false
@ -101,37 +93,34 @@ Vn = module.exports = {
return includeData;
}
,_handleCallback: function (includeData, callback)
{
,_handleCallback: function(includeData, callback) {
if (!callback)
return;
if (includeData.success)
callback (includeData.loaded);
callback(includeData.loaded);
else
includeData.callbacks.push (callback);
includeData.callbacks.push(callback);
}
,_resolveDeps: function (includeData)
{
,_resolveDeps: function(includeData) {
includeData.success = true;
var callbacks = includeData.callbacks;
if (callbacks)
for (var i = 0; i < callbacks.length; i++)
callbacks[i] (includeData.loaded);
callbacks[i](includeData.loaded);
var dependants = includeData.dependants;
if (dependants)
for (var i = 0; i < dependants.length; i++)
{
for (var i = 0; i < dependants.length; i++) {
var dependant = dependants[i];
dependant.depCount--;
if (dependant.depCount == 0)
this._resolveDeps (dependant);
this._resolveDeps(dependant);
}
delete includeData.callbacks;
@ -146,11 +135,9 @@ Vn = module.exports = {
*
* @param {Function} callback The main function
*/
,main: function (callback)
{
if (this.mainCalled)
{
Vn.warning ("Vn: main method should be called only once");
,main: function(callback) {
if (this.mainCalled) {
Vn.warning("Vn: main method should be called only once");
return;
}
@ -161,44 +148,39 @@ Vn = module.exports = {
basePath += location.port ? ':'+ location.port : '';
basePath += location.pathname;
var scripts = this.head.getElementsByTagName ('script');
var scripts = this.head.getElementsByTagName('script');
var includes = this.currentDeps;
for (var i = 0; i < scripts.length; i++)
{
var path = scripts[i].src.substr (basePath.length);
path = path.substr (0, path.indexOf ('.js')) +'.js';
for (var i = 0; i < scripts.length; i++) {
var path = scripts[i].src.substr(basePath.length);
path = path.substr(0, path.indexOf('.js')) +'.js';
var includeData = this.includes[path];
if (includeData === undefined)
{
if (includeData === undefined) {
this.currentDeps = includes;
var includeData = this._createIncludeData (path);
this._onScriptLoad (includeData, true);
var includeData = this._createIncludeData(path);
this._onScriptLoad(includeData, true);
}
}
includeData.callbacks.push (this._onMainDepsLoad.bind (this));
window.addEventListener ('load', this._onWindowLoad.bind (this));
includeData.callbacks.push(this._onMainDepsLoad.bind(this));
window.addEventListener('load', this._onWindowLoad.bind(this));
}
,_onMainDepsLoad: function ()
{
,_onMainDepsLoad: function() {
this.mainDepsLoaded = true;
this._callMain ();
this._callMain();
}
,_onWindowLoad: function ()
{
,_onWindowLoad: function() {
this.windowReady = true;
this._callMain ();
this._callMain();
}
,_callMain: function ()
{
,_callMain: function() {
if (this.mainCallback && this.windowReady && this.mainDepsLoaded)
this.mainCallback ();
this.mainCallback();
}
/**
@ -207,14 +189,12 @@ Vn = module.exports = {
*
* @param {...} The list of files as function arguments
*/
,include: function ()
{
for (var i = 0; i < arguments.length; i++)
{
var includeData = this._realIncludeJs (arguments[i] +'.js');
,include: function() {
for (var i = 0; i < arguments.length; i++) {
var includeData = this._realIncludeJs(arguments[i] +'.js');
if (!includeData.success)
this.currentDeps.push (includeData);
this.currentDeps.push(includeData);
}
}
@ -224,14 +204,12 @@ Vn = module.exports = {
*
* @param {...} The list of files as function arguments
*/
,resource: function ()
{
for (var i = 0; i < arguments.length; i++)
{
var includeData = this._realLoadXml (arguments[i]);
,resource: function() {
for (var i = 0; i < arguments.length; i++) {
var includeData = this._realLoadXml(arguments[i]);
if (!includeData.success)
this.currentDeps.push (includeData);
this.currentDeps.push(includeData);
}
}
@ -241,8 +219,7 @@ Vn = module.exports = {
*
* @param {Function} callback The callback function
*/
,define: function (callback)
{
,define: function(callback) {
this.currentCallback = callback;
}
@ -252,12 +229,11 @@ Vn = module.exports = {
* @param {string} libName The folder of the library
* @param {Array<string>} files Array with every library file name
*/
,includeLib: function (libName, files)
{
Vn.Locale.loadScript ('js/'+ libName +'.js');
,includeLib: function(libName, files) {
Vn.Locale.loadScript('js/'+ libName +'.js');
for (var i = 0; i < files.length; i++)
this.include ('js/'+ libName +'/'+ files[i]);
this.include('js/'+ libName +'/'+ files[i]);
}
/**
@ -268,72 +244,63 @@ Vn = module.exports = {
* @param {Function} callback The function to call when script is
* downloaded and included
*/
,includeJs: function (fileName, callback, skipVersion)
{
var includeData = this._realIncludeJs (fileName, skipVersion);
this._handleCallback (includeData, callback);
,includeJs: function(fileName, callback, skipVersion) {
var includeData = this._realIncludeJs(fileName, skipVersion);
this._handleCallback(includeData, callback);
}
,_realIncludeJs: function (fileName, skipVersion)
{
,_realIncludeJs: function(fileName, skipVersion) {
var includeData = this.includes[fileName];
if (includeData === undefined)
{
includeData = this._createIncludeData (fileName);
if (includeData === undefined) {
includeData = this._createIncludeData(fileName);
var src = fileName;
if (!skipVersion)
src = src + this.getVersion ();
src = src + this.getVersion();
var script = document.createElement ('script');
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = false;
script.src = src;
script.onload =
this._onScriptLoad.bind (this, includeData, true);
this._onScriptLoad.bind(this, includeData, true);
script.onerror =
this._onScriptLoad.bind (this, includeData, false);
this._onScriptLoad.bind(this, includeData, false);
script.onreadystatechange =
this._onScriptStateChange.bind (this, includeData, script);
this._onScriptStateChange.bind(this, includeData, script);
this.head.appendChild (script);
this.head.appendChild(script);
}
return includeData;
}
,_onScriptStateChange: function (includeData, script)
{
,_onScriptStateChange: function(includeData, script) {
if (script.readyState == 'complete')
this._onScriptLoad (includeData, true);
this._onScriptLoad(includeData, true);
}
,_onScriptLoad: function (includeData, loaded)
{
,_onScriptLoad: function(includeData, loaded) {
includeData.loaded = loaded;
if (loaded)
{
if (loaded) {
if (this.currentCallback)
includeData.callbacks.unshift (this.currentCallback);
includeData.callbacks.unshift(this.currentCallback);
var includes = this.currentDeps;
if (includes && includes.length > 0)
{
if (includes && includes.length > 0) {
includeData.depCount = includes.length;
for (var i = 0; i < includes.length; i++)
includes[i].dependants.push (includeData);
}
else
this._resolveDeps (includeData);
}
else
this._resolveDeps (includeData);
includes[i].dependants.push(includeData);
} else
this._resolveDeps(includeData);
} else
this._resolveDeps(includeData);
this.currentDeps = [];
this.currentCallback = null;
@ -345,32 +312,28 @@ Vn = module.exports = {
* @param {string} path The file path
* @param {Function} callback The function to call when file is downloaded
*/
,loadXml: function (path, callback)
{
var includeData = this._realLoadXml (path);
this._handleCallback (includeData, callback);
,loadXml: function(path, callback) {
var includeData = this._realLoadXml(path);
this._handleCallback(includeData, callback);
}
,_realLoadXml: function (path)
{
,_realLoadXml: function(path) {
var includeData = this.includes[path];
if (includeData === undefined)
{
includeData = this._createIncludeData (path);
if (includeData === undefined) {
includeData = this._createIncludeData(path);
var request = new XMLHttpRequest ();
var request = new XMLHttpRequest();
request.onreadystatechange =
this._onXmlReady.bind (this, includeData, request);
request.open ('get', path + this.getVersion (), true);
request.send ();
this._onXmlReady.bind(this, includeData, request);
request.open('get', path + this.getVersion(), true);
request.send();
}
return includeData;
}
,_onXmlReady: function (includeData, request)
{
,_onXmlReady: function(includeData, request) {
if (request.readyState != 4)
return;
@ -379,7 +342,7 @@ Vn = module.exports = {
if (includeData.loaded)
includeData.xml = request.responseXML;
this._resolveDeps (includeData);
this._resolveDeps(includeData);
}
/**
@ -388,8 +351,7 @@ Vn = module.exports = {
* @param {string} path The file path
* @return {Object} The DOM object
*/
,getXml: function (path)
{
,getXml: function(path) {
var includeData = this.includes[path];
if (!(includeData && includeData.success))
@ -403,12 +365,10 @@ Vn = module.exports = {
*
* return {boolean} %true if is mobile, %false otherwise.
*/
,isMobile: function ()
{
if (this.isMobileCached === null)
{
,isMobile: function() {
if (this.isMobileCached === null) {
var regExp = /(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i;
this.isMobileCached = navigator.userAgent.match (regExp);
this.isMobileCached = navigator.userAgent.match(regExp);
}
return this.isMobileCached;

View File

@ -1,6 +1,6 @@
{
"name": "hedera-web",
"version": "1.407.74",
"version": "1.407.75",
"description": "Verdnatura web page",
"license": "GPL-3.0",
"repository": {