Builder refactor, various fixes
gitea/hedera-web/pipeline/head This commit looks good
Details
gitea/hedera-web/pipeline/head This commit looks good
Details
This commit is contained in:
parent
d1819118d8
commit
fd6f39371a
|
@ -1,4 +1,4 @@
|
||||||
hedera-web (1.407.79) stable; urgency=low
|
hedera-web (1.407.80) stable; urgency=low
|
||||||
|
|
||||||
* Initial Release.
|
* Initial Release.
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
<htk-button
|
<htk-button
|
||||||
icon="delete"
|
icon="delete"
|
||||||
tip="_RemoveAddress"
|
tip="_RemoveAddress"
|
||||||
on-click="this.onRemoveAddressClick($.address)"/>
|
on-click="this.onRemoveAddressClick($iter)"/>
|
||||||
<htk-button
|
<htk-button
|
||||||
icon="edit"
|
icon="edit"
|
||||||
tip="_EditAddress"
|
tip="_EditAddress"
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="check"
|
icon="check"
|
||||||
tip="_Accept"
|
tip="_Accept"
|
||||||
on-click="$.iter.performOperations()"/>
|
on-click="iter.performOperations()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="address">
|
<div id="form" class="address">
|
||||||
<div class="form box vn-w-sm vn-pa-lg">
|
<div class="form box vn-w-sm vn-pa-lg">
|
||||||
|
|
|
@ -1,22 +1,18 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<db-form id="password-form">
|
<db-form v-model="passwordForm">
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
<custom>
|
SELECT length, nAlpha, nUpper, nDigits, nPunct
|
||||||
SELECT length, nAlpha, nUpper, nDigits, nPunct
|
FROM account.userPassword
|
||||||
FROM account.userPassword
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
<db-form id="user-form">
|
<db-form id="user-form">
|
||||||
<db-model property="model" id="user-model" updatable="true">
|
<db-model property="model" id="user-model" updatable="true">
|
||||||
<custom>
|
SELECT u.id, u.name, u.email, u.nickname,
|
||||||
SELECT u.id, u.name, u.email, u.nickname,
|
u.lang, c.isToBeMailed, c.id clientFk
|
||||||
u.lang, c.isToBeMailed, c.id clientFk
|
FROM account.myUser u
|
||||||
FROM account.myUser u
|
LEFT JOIN myClient c
|
||||||
LEFT JOIN myClient c
|
ON u.id = c.id
|
||||||
ON u.id = c.id
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
</vn-group>
|
</vn-group>
|
||||||
|
@ -27,7 +23,7 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="place"
|
icon="place"
|
||||||
tip="_Addresses"
|
tip="_Addresses"
|
||||||
on-click="$.hash.setAll({form: 'account/address-list'})"/>
|
on-click="hash.setAll({form: 'account/address-list'})"/>
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="lock_reset"
|
icon="lock_reset"
|
||||||
tip="_Change password"
|
tip="_Change password"
|
||||||
|
@ -119,24 +115,19 @@
|
||||||
</h5>
|
</h5>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<htk-text form="password-form" column="length"/>
|
{{passwordForm.length}} <t>characters long</t>
|
||||||
<t>characters long</t>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<htk-text form="password-form" column="nAlpha"/>
|
{{passwordForm.nAlpha}} <t>alphabetic characters</t>
|
||||||
<t>alphabetic characters</t>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<htk-text form="password-form" column="nUpper"/>
|
{{passwordForm.nUpper}} <t>capital letters</t>
|
||||||
<t>capital letters</t>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<htk-text form="password-form" column="nDigits"/>
|
{{passwordForm.nDigits}} <t>digits</t>
|
||||||
<t>digits</t>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<htk-text form="password-form" column="nPunct"/>
|
{{passwordForm.nPunct}} <t>symbols</t>
|
||||||
<t>symbols</t>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<db-form id="user">
|
<db-form v-model="user">
|
||||||
<db-model property="model" lot="hash">
|
<db-model property="model" lot="hash">
|
||||||
SELECT u.id, u.name user, u.nickname, u.email, c.phone, r.name role
|
SELECT u.id, u.name user, u.nickname, u.email, c.phone, r.name role
|
||||||
FROM account.user u
|
FROM account.user u
|
||||||
|
@ -16,11 +16,11 @@
|
||||||
<div id="form" class="access-log">
|
<div id="form" class="access-log">
|
||||||
<div class="box vn-w-xs vn-pa-lg">
|
<div class="box vn-w-xs vn-pa-lg">
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<h4><htk-text form="user" column="nickname"/></h4>
|
<h4>{{user.nickname}}</h4>
|
||||||
<p>#<htk-text form="user" column="id"/> - <htk-text form="user" column="user"/></p>
|
<p>#{{user.id}} - {{user.user}}</p>
|
||||||
<p><htk-text form="user" column="role"/></p>
|
<p>{{user.role}}</p>
|
||||||
<p><htk-text form="user" column="email"/></p>
|
<p>{{user.email}}</p>
|
||||||
<p><htk-text form="user" column="phone"/></p>
|
<p>{{user.phone}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<htk-repeater form-id="iter" class="box vn-w-xs htk-list vn-mt-md">
|
<htk-repeater form-id="iter" class="box vn-w-xs htk-list vn-mt-md">
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="refresh"
|
icon="refresh"
|
||||||
tip="_Refresh"
|
tip="_Refresh"
|
||||||
on-click="$.sessions.refresh()"/>
|
on-click="sessions.refresh()"/>
|
||||||
<div class="connections-sum">
|
<div class="connections-sum">
|
||||||
<htk-text>
|
<htk-text>
|
||||||
<db-calc-sum
|
<db-calc-sum
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="side vn-mr-md">
|
<div class="side vn-mr-md">
|
||||||
<htk-image
|
<htk-image
|
||||||
form="iter"
|
form="$iter"
|
||||||
column="image"
|
column="image"
|
||||||
stamp-column="updated"
|
stamp-column="updated"
|
||||||
class="photo"
|
class="photo"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="refresh"
|
icon="refresh"
|
||||||
tip="_Refresh"
|
tip="_Refresh"
|
||||||
on-click="$.visits.refresh()"/>
|
on-click="visits.refresh()"/>
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="visibility"
|
icon="visibility"
|
||||||
tip="_Connections"
|
tip="_Connections"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
class="start-order"
|
class="start-order"
|
||||||
icon="add_shopping_cart"
|
icon="add_shopping_cart"
|
||||||
tip="_Start order"
|
tip="_Start order"
|
||||||
on-click="$.hash.setAll({form: 'ecomerce/catalog'})"/>
|
on-click="hash.setAll({form: 'ecomerce/catalog'})"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="home">
|
<div id="form" class="home">
|
||||||
<div class="column mansonry" id="news-column">
|
<div class="column mansonry" id="news-column">
|
||||||
|
|
|
@ -44,19 +44,16 @@
|
||||||
class="delete"
|
class="delete"
|
||||||
tip="_Remove"
|
tip="_Remove"
|
||||||
icon="delete"
|
icon="delete"
|
||||||
on-click="this.onDeleteClick($.iter)"/>
|
on-click="this.onDeleteClick($iter)"/>
|
||||||
<htk-image
|
<htk-image
|
||||||
form="iter"
|
value="{{iter.image}}"
|
||||||
column="image"
|
|
||||||
stamp-column="updated"
|
stamp-column="updated"
|
||||||
class="photo"
|
class="photo"
|
||||||
directory="catalog"
|
directory="catalog"
|
||||||
subdir="200x200"
|
subdir="200x200"
|
||||||
full-dir="1600x900"/>
|
full-dir="1600x900"/>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<h2>
|
<h2>{{iter.item}}</h2>
|
||||||
<htk-text form="iter" column="item"/>
|
|
||||||
</h2>
|
|
||||||
<p class="tags">
|
<p class="tags">
|
||||||
{{iter.value5}} {{iter.value6}} {{iter.value7}}
|
{{iter.value5}} {{iter.value6}} {{iter.value7}}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -169,13 +169,6 @@ Hedera.Catalog = new Class({
|
||||||
Hedera.Catalog.View.GRID : Hedera.Catalog.View.LIST);
|
Hedera.Catalog.View.GRID : Hedera.Catalog.View.LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
,onBasketReady: function(form) {
|
|
||||||
if (form.$.method != 'PICKUP')
|
|
||||||
Vn.Node.setText(this.$.method, _('Agency'));
|
|
||||||
else
|
|
||||||
Vn.Node.setText(this.$.method, _('Warehouse'));
|
|
||||||
}
|
|
||||||
|
|
||||||
,onItemsChange: function(model, status) {
|
,onItemsChange: function(model, status) {
|
||||||
if (status !== Db.Model.Status.CLEAN)
|
if (status !== Db.Model.Status.CLEAN)
|
||||||
this.$.order.style.display = 'block';
|
this.$.order.style.display = 'block';
|
||||||
|
@ -255,7 +248,7 @@ Hedera.Catalog = new Class({
|
||||||
if (this.isGuest()) return;
|
if (this.isGuest()) return;
|
||||||
|
|
||||||
this.onEraseClick();
|
this.onEraseClick();
|
||||||
this.$.card.row = form.row;
|
this.$.$card.row = form.row;
|
||||||
this.$.cardLot.assign({item: form.$.id});
|
this.$.cardLot.assign({item: form.$.id});
|
||||||
this.$.cardPopup.show(event.currentTarget);
|
this.$.cardPopup.show(event.currentTarget);
|
||||||
}
|
}
|
||||||
|
@ -303,7 +296,7 @@ Hedera.Catalog = new Class({
|
||||||
if (amountSum > 0) {
|
if (amountSum > 0) {
|
||||||
this.conn.execQuery(sql);
|
this.conn.execQuery(sql);
|
||||||
|
|
||||||
var itemName = this.$.card.get('item');
|
var itemName = this.$.$card.get('item');
|
||||||
Htk.Toast.showMessage(
|
Htk.Toast.showMessage(
|
||||||
Vn.Value.sprintf(_('Added%dOf%s'), amountSum, itemName));
|
Vn.Value.sprintf(_('Added%dOf%s'), amountSum, itemName));
|
||||||
}
|
}
|
||||||
|
@ -318,7 +311,7 @@ Hedera.Catalog = new Class({
|
||||||
|
|
||||||
,onPopupClose: function() {
|
,onPopupClose: function() {
|
||||||
this.onEraseClick();
|
this.onEraseClick();
|
||||||
this.$.card.row = -1;
|
this.$.$card.row = -1;
|
||||||
this.$.cardLot.value = undefined;
|
this.$.cardLot.value = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@
|
||||||
param="producer"/>
|
param="producer"/>
|
||||||
</vn-group>
|
</vn-group>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<db-form id="basket" on-ready="onBasketReady">
|
<db-form v-model="basket">
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
SELECT b.id, b.sent, a.description agency, m.code method
|
SELECT b.id, b.sent, a.description agency, m.code method
|
||||||
FROM myBasket b
|
FROM myBasket b
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
JOIN vn.itemType t ON t.id = i.typeFk
|
JOIN vn.itemType t ON t.id = i.typeFk
|
||||||
WHERE #filter;
|
WHERE #filter;
|
||||||
CALL myBasket_calcCatalogFull;
|
CALL myBasket_calcCatalogFull;
|
||||||
SELECT i.id, i.description, i.longName item, i.subName,
|
SELECT i.id, i.longName item, i.subName,
|
||||||
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
|
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
|
||||||
i.relevancy, i.size, i.category,
|
i.relevancy, i.size, i.category,
|
||||||
k.name ink, p.name producer, o.name origin,
|
k.name ink, p.name producer, o.name origin,
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
ORDER BY i.relevancy DESC, i.name, i.size
|
ORDER BY i.relevancy DESC, i.name, i.size
|
||||||
LIMIT 5000;
|
LIMIT 5000;
|
||||||
</db-model>
|
</db-model>
|
||||||
<db-form id="card" model="items"/>
|
<db-form id="$card" v-model="card" model="items"/>
|
||||||
<vn-lot id="card-lot"/>
|
<vn-lot id="card-lot"/>
|
||||||
</vn-group>
|
</vn-group>
|
||||||
<div id="form" class="catalog">
|
<div id="form" class="catalog">
|
||||||
|
@ -135,17 +135,17 @@
|
||||||
id="grid-view"
|
id="grid-view"
|
||||||
empty-message="_Choose filter from right menu"
|
empty-message="_Choose filter from right menu"
|
||||||
form-id="item"
|
form-id="item"
|
||||||
model="items" >
|
model="items">
|
||||||
<custom>
|
<custom>
|
||||||
<div
|
<div
|
||||||
id="item-box"
|
id="item-box"
|
||||||
class="item-box clickable"
|
class="item-box clickable"
|
||||||
title="{{_('AddToBasket')}}"
|
title="{{_('AddToBasket')}}"
|
||||||
on-click="this.onAddItemClick($event, $.item)">
|
on-click="this.onAddItemClick($event, $iter)">
|
||||||
<htk-image
|
<htk-image
|
||||||
directory="catalog"
|
directory="catalog"
|
||||||
subdir="200x200"
|
subdir="200x200"
|
||||||
form="item"
|
form="$iter"
|
||||||
column="image"
|
column="image"
|
||||||
stamp-column="updated"
|
stamp-column="updated"
|
||||||
full-dir="1600x900"
|
full-dir="1600x900"
|
||||||
|
@ -193,12 +193,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="right-panel" class="right-panel" on-click="onRightPanelClick">
|
<div id="right-panel" class="right-panel" on-click="onRightPanelClick">
|
||||||
<div class="basket-info">
|
<div class="basket-info">
|
||||||
|
<p>{{Vn.Value.format(basket.sent, '%D')}}</p>
|
||||||
<p>
|
<p>
|
||||||
<htk-text form="basket" column="sent" format="%D"/>
|
{{_(basket.method != 'PICKUP' ? 'Agency' : 'Warehouse')}}
|
||||||
</p>
|
{{basket.agency}}
|
||||||
<p>
|
|
||||||
<span id="method"/>
|
|
||||||
<htk-text form="basket" column="agency"/>
|
|
||||||
</p>
|
</p>
|
||||||
<button class="thin" on-click="this.onConfigureClick()">
|
<button class="thin" on-click="this.onConfigureClick()">
|
||||||
<t>Modify</t>
|
<t>Modify</t>
|
||||||
|
@ -266,7 +264,7 @@
|
||||||
placeholder="_Color"
|
placeholder="_Color"
|
||||||
form="params"
|
form="params"
|
||||||
column="color"
|
column="color"
|
||||||
on-mousedown="$.colors.lazyRefresh()">
|
on-mousedown="colors.lazyRefresh()">
|
||||||
<db-model
|
<db-model
|
||||||
id="colors"
|
id="colors"
|
||||||
property="model"
|
property="model"
|
||||||
|
@ -286,7 +284,7 @@
|
||||||
placeholder="_Producer"
|
placeholder="_Producer"
|
||||||
form="params"
|
form="params"
|
||||||
column="producer"
|
column="producer"
|
||||||
on-mousedown="$.producers.lazyRefresh()">
|
on-mousedown="producers.lazyRefresh()">
|
||||||
<db-model
|
<db-model
|
||||||
id="producers"
|
id="producers"
|
||||||
property="model"
|
property="model"
|
||||||
|
@ -306,7 +304,7 @@
|
||||||
placeholder="_Origin"
|
placeholder="_Origin"
|
||||||
form="params"
|
form="params"
|
||||||
column="origin"
|
column="origin"
|
||||||
on-mousedown="$.origins.lazyRefresh()">
|
on-mousedown="origins.lazyRefresh()">
|
||||||
<db-model
|
<db-model
|
||||||
id="origins"
|
id="origins"
|
||||||
property="model"
|
property="model"
|
||||||
|
@ -327,7 +325,7 @@
|
||||||
placeholder="_Category"
|
placeholder="_Category"
|
||||||
form="params"
|
form="params"
|
||||||
column="category"
|
column="category"
|
||||||
on-mousedown="$.categorys.lazyRefresh()">
|
on-mousedown="categorys.lazyRefresh()">
|
||||||
<db-model
|
<db-model
|
||||||
id="categorys"
|
id="categorys"
|
||||||
property="model"
|
property="model"
|
||||||
|
@ -395,7 +393,7 @@
|
||||||
modal="true"
|
modal="true"
|
||||||
on-closed="onPopupClose">
|
on-closed="onPopupClose">
|
||||||
<div property="child-node" class="item-card">
|
<div property="child-node" class="item-card">
|
||||||
<db-form id="card-extend">
|
<db-form vModel="extendedCard">
|
||||||
<db-model
|
<db-model
|
||||||
property="model"
|
property="model"
|
||||||
lot="card-lot"
|
lot="card-lot"
|
||||||
|
@ -410,29 +408,19 @@
|
||||||
<htk-image
|
<htk-image
|
||||||
directory="catalog"
|
directory="catalog"
|
||||||
subdir="200x200"
|
subdir="200x200"
|
||||||
form="card"
|
form="$card"
|
||||||
column="image"
|
column="image"
|
||||||
stamp-column="updated"
|
stamp-column="updated"
|
||||||
full-dir="1600x900"
|
full-dir="1600x900"
|
||||||
conn="conn"
|
conn="conn"
|
||||||
editable="true"/>
|
editable="true"/>
|
||||||
<div class="item-info">
|
<div class="item-info">
|
||||||
<h2>
|
<h2>{{card.item}}</h2>
|
||||||
<htk-text form="card" column="item"/>
|
<p class="sub-name">{{card.subname}}</p>
|
||||||
</h2>
|
<p>#{{card.id}}</p>
|
||||||
<p class="sub-name">
|
<p>{{Vn.Value.format(card.stems, _('%.0d Units'))}}</p>
|
||||||
<htk-text form="card" column="subName"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
#<htk-text form="card" column="id"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="card" column="stems" format="_%.0d Units"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="desc">
|
<p class="desc">{{extendedCard.description}}</p>
|
||||||
<htk-text form="card-extend" column="description" id="desc"/>
|
|
||||||
</p>
|
|
||||||
<htk-repeater show-status="false" form-id="tag" class="tags">
|
<htk-repeater show-status="false" form-id="tag" class="tags">
|
||||||
<db-model
|
<db-model
|
||||||
property="model"
|
property="model"
|
||||||
|
@ -448,8 +436,8 @@
|
||||||
</db-model>
|
</db-model>
|
||||||
<custom>
|
<custom>
|
||||||
<tr>
|
<tr>
|
||||||
<td><htk-text form="tag" column="name"/></td>
|
<td>{{tag.name}}</td>
|
||||||
<td><htk-text form="tag" column="value"/></td>
|
<td>{{tag.value}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</custom>
|
</custom>
|
||||||
</htk-repeater>
|
</htk-repeater>
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
column="debt">
|
column="debt">
|
||||||
<db-form property="form">
|
<db-form property="form">
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
<custom>
|
SELECT -myClient_getDebt(NULL) debt
|
||||||
SELECT -myClient_getDebt(NULL) debt
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
</htk-text>
|
</htk-text>
|
||||||
|
@ -42,9 +40,7 @@
|
||||||
form-id="iter"
|
form-id="iter"
|
||||||
renderer="repeaterFunc">
|
renderer="repeaterFunc">
|
||||||
<db-model property="model" id="tickets">
|
<db-model property="model" id="tickets">
|
||||||
<custom>
|
CALL myTicket_list(NULL, NULL);
|
||||||
CALL myTicket_list (NULL, NULL);
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
<custom>
|
<custom>
|
||||||
<a id="link" class="item" title="{{_('SeeOrder')}}">
|
<a id="link" class="item" title="{{_('SeeOrder')}}">
|
||||||
|
|
|
@ -10,13 +10,6 @@ Hedera.Ticket = new Class({
|
||||||
this.conn.execQuery('CALL myTicket_logAccess(#ticket)', null, params);
|
this.conn.execQuery('CALL myTicket_logAccess(#ticket)', null, params);
|
||||||
},
|
},
|
||||||
|
|
||||||
onTicketReady: function(form) {
|
|
||||||
if (form.$.method != 'PICKUP')
|
|
||||||
Vn.Node.setText(this.$.method, _('Agency'));
|
|
||||||
else
|
|
||||||
Vn.Node.setText(this.$.method, _('Warehouse'));
|
|
||||||
},
|
|
||||||
|
|
||||||
onPrintClick: function() {
|
onPrintClick: function() {
|
||||||
let params = Vn.Url.makeUri({
|
let params = Vn.Url.makeUri({
|
||||||
authorization: this.conn.token,
|
authorization: this.conn.token,
|
||||||
|
@ -27,24 +20,17 @@ Hedera.Ticket = new Class({
|
||||||
window.open(`/api/report/delivery-note?${params}`);
|
window.open(`/api/report/delivery-note?${params}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
repeaterFunc: function(res, form) {
|
repeaterFunc: function(scope, form) {
|
||||||
var discount = res.$.discount;
|
scope.$.discount.style.display = form.$.discount ? 'inline' : 'none';
|
||||||
discount.style.display = form.$.discount ? 'inline' : 'none';
|
|
||||||
res.$.discountSubtotal.value = this.discountSubtotal(form);
|
|
||||||
res.$.subtotal.value = this.subtotal(form);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
discountSubtotal: function(form) {
|
discountSubtotal: function(line) {
|
||||||
return form.$.quantity * form.$.price;
|
return line.quantity * line.price;
|
||||||
},
|
},
|
||||||
|
|
||||||
subtotal: function(form) {
|
subtotal: function(line) {
|
||||||
var discount = form.$.discount;
|
var discount = line.discount;
|
||||||
return this.discountSubtotal(form) * ((100 - discount) / 100);
|
return this.discountSubtotal(line) * ((100 - discount) / 100);
|
||||||
},
|
|
||||||
|
|
||||||
servicesFunc: function(res, form) {
|
|
||||||
res.$.subtotal.value = form.$.quantity * form.$.price;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onServicesChanged: function(model) {
|
onServicesChanged: function(model) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<vn-lot-query id="params">
|
<vn-lot-query id="params">
|
||||||
<vn-spec name="ticket" type="Number"/>
|
<vn-spec name="ticket" type="Number"/>
|
||||||
</vn-lot-query>
|
</vn-lot-query>
|
||||||
<db-lot id="ticket" lot="params" on-ready="onTicketReady">
|
<db-lot id="ticket-form" lot="params" v-model="ticket">
|
||||||
CALL myTicket_get(#ticket)
|
CALL myTicket_get(#ticket)
|
||||||
</db-lot>
|
</db-lot>
|
||||||
<div id="title">
|
<div id="title">
|
||||||
|
@ -16,42 +16,32 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="ticket">
|
<div id="form" class="ticket">
|
||||||
<div class="box vn-w-sm vn-pa-lg">
|
<div class="box vn-w-sm vn-pa-lg">
|
||||||
<htk-loader class="head" form="ticket">
|
<htk-loader class="head" form="ticket-form">
|
||||||
<h5>#<htk-text column="id" form="ticket"/></h5>
|
<h5>#{{ticket.id}}</h5>
|
||||||
<div>
|
<div>
|
||||||
<h6><t>ShippingInformation</t></h6>
|
<h6><t>ShippingInformation</t></h6>
|
||||||
<p>
|
<p>
|
||||||
<t>Preparation</t> <htk-text form="ticket" column="shipped" format="%D"/>
|
<t>Preparation</t> {{Vn.Value.format(ticket.shipped, '%D')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<t>Delivery</t> <htk-text form="ticket" column="landed" format="%D"/>
|
<t>Delivery</t> {{Vn.Value.format(ticket.landed, '%D')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span id="method"></span> <htk-text form="ticket" column="agency"/>
|
{{_(ticket.method != 'PICKUP' ? 'Agency' : 'Warehouse')}} {{ticket.agency}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="address">
|
<div class="address">
|
||||||
<h6><t>DeliveryAddress</t></h6>
|
<h6><t>DeliveryAddress</t></h6>
|
||||||
<p>
|
<p>{{ticket.nickname}}</p>
|
||||||
<htk-text form="ticket" column="nickname"/>
|
<p>{{ticket.street}}</p>
|
||||||
</p>
|
<p>{{ticket.postalCode}} {{ticket.city}} ({{ticket.province}})</p>
|
||||||
<p>
|
|
||||||
<htk-text form="ticket" column="street"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="ticket" column="postalCode"/>
|
|
||||||
<htk-text form="ticket" column="city"/>
|
|
||||||
(<htk-text form="ticket" column="province"/>)
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="total">
|
<div class="total">
|
||||||
<p class="important total">
|
<p class="important total">
|
||||||
<t>Total</t>
|
<t>Total</t> {{Vn.Value.format(ticket.taxBase, '%.2d€')}}
|
||||||
<htk-text format="%.2d€" form="ticket" column="taxBase"/>
|
|
||||||
</p>
|
</p>
|
||||||
<p class="important total">
|
<p class="important total">
|
||||||
<t>Total + tax</t>
|
<t>Total + tax</t> {{Vn.Value.format(ticket.total, '%.2d€')}}
|
||||||
<htk-text format="%.2d€" form="ticket" column="total"/>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</htk-loader>
|
</htk-loader>
|
||||||
|
@ -65,38 +55,32 @@
|
||||||
<custom>
|
<custom>
|
||||||
<div class="line">
|
<div class="line">
|
||||||
<htk-image
|
<htk-image
|
||||||
form="iter"
|
value="{{iter.image}}"
|
||||||
column="image"
|
|
||||||
stamp-column="updated"
|
stamp-column="updated"
|
||||||
class="photo"
|
class="photo"
|
||||||
directory="catalog"
|
directory="catalog"
|
||||||
subdir="200x200"
|
subdir="200x200"
|
||||||
full-dir="1600x900"/>
|
full-dir="1600x900"/>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<h2>
|
<h2>{{iter.concept}}</h2>
|
||||||
<htk-text form="iter" column="concept"/>
|
|
||||||
</h2>
|
|
||||||
<p class="tags">
|
<p class="tags">
|
||||||
<htk-text form="iter" column="value5"/>
|
{{iter.value5}} {{iter.value6}} {{iter.value7}}
|
||||||
<htk-text form="iter" column="value6"/>
|
|
||||||
<htk-text form="iter" column="value7"/>
|
|
||||||
</p>
|
</p>
|
||||||
<p class="amount">
|
<p class="amount">
|
||||||
<htk-text form="iter" column="quantity"/> x
|
{{iter.quantity}} x {{Vn.Value.format(iter.price, '%.2d€')}}
|
||||||
<htk-text form="iter" column="price" format="%.2d€"/>
|
|
||||||
</p>
|
</p>
|
||||||
<p class="subtotal">
|
<p class="subtotal">
|
||||||
<span class="discount" id="discount">
|
<span class="discount" id="discount">
|
||||||
<htk-text id="discount-subtotal" format="%.2d€"/> -
|
{{Vn.Value.format(this.discountSubtotal(iter), '%.2d€')}} -
|
||||||
<htk-text form="iter" column="discount" format="%.0d%"/> =
|
{{Vn.Value.format(iter.discount, '%.0d%')}} =
|
||||||
</span>
|
</span>
|
||||||
<htk-text id="subtotal" format="%.2d€"/>
|
{{Vn.Value.format(this.subtotal(iter), '%.2d€')}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</custom>
|
</custom>
|
||||||
</htk-repeater>
|
</htk-repeater>
|
||||||
<htk-repeater form-id="iter" id="services" class="packages" renderer="servicesFunc">
|
<htk-repeater form-id="iter" id="services" class="packages">
|
||||||
<db-model
|
<db-model
|
||||||
property="model"
|
property="model"
|
||||||
on-status-changed="onServicesChanged"
|
on-status-changed="onServicesChanged"
|
||||||
|
@ -106,15 +90,12 @@
|
||||||
<custom>
|
<custom>
|
||||||
<div class="line">
|
<div class="line">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<h2>
|
<h2>{{iter.description}}</h2>
|
||||||
<htk-text form="iter" column="description"/>
|
|
||||||
</h2>
|
|
||||||
<p class="amount">
|
<p class="amount">
|
||||||
<htk-text form="iter" column="quantity"/> x
|
{{iter.quantity}} x {{Vn.Value.format(iter.price, '%.2d€')}}
|
||||||
<htk-text form="iter" column="price" format="%.2d€"/>
|
|
||||||
</p>
|
</p>
|
||||||
<p class="subtotal">
|
<p class="subtotal">
|
||||||
<htk-text id="subtotal" format="%.2d€"/>
|
{{Vn.Value.format(iter.quantity * iter.price, '%.2d€')}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"/>
|
<div class="clear"/>
|
||||||
|
@ -131,22 +112,15 @@
|
||||||
<custom>
|
<custom>
|
||||||
<div class="line">
|
<div class="line">
|
||||||
<htk-image
|
<htk-image
|
||||||
form="iter"
|
value="{{iter.image}}"
|
||||||
column="image"
|
|
||||||
class="photo"
|
class="photo"
|
||||||
directory="catalog"
|
directory="catalog"
|
||||||
subdir="200x200"
|
subdir="200x200"
|
||||||
full-dir="1600x900"/>
|
full-dir="1600x900"/>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<h2>
|
<h2>{{iter.name}}</h2>
|
||||||
<htk-text form="iter" column="name"/>
|
<p>#{{iter.id}}</p>
|
||||||
</h2>
|
<p class="amount">{{iter.quantity}}</p>
|
||||||
<p>
|
|
||||||
#<htk-text form="iter" column="id"/>
|
|
||||||
</p>
|
|
||||||
<p class="amount">
|
|
||||||
<htk-text form="iter" column="quantity"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"/>
|
<div class="clear"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
title="_EditNew">
|
title="_EditNew">
|
||||||
<div class="side vn-mr-md">
|
<div class="side vn-mr-md">
|
||||||
<htk-image
|
<htk-image
|
||||||
form="iter"
|
form="$iter"
|
||||||
column="image"
|
column="image"
|
||||||
class="photo"
|
class="photo"
|
||||||
directory="news"
|
directory="news"
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
<htk-button
|
<htk-button
|
||||||
tip="_Remove"
|
tip="_Remove"
|
||||||
icon="delete"
|
icon="delete"
|
||||||
on-click="this.onDeleteClick($.iter)"/>
|
on-click="this.onDeleteClick($iter)"/>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</custom>
|
</custom>
|
||||||
|
|
|
@ -844,6 +844,7 @@ Model.implement({
|
||||||
|
|
||||||
if (!(op.type & Operation.DELETE
|
if (!(op.type & Operation.DELETE
|
||||||
&& op.type & Operation.INSERT))
|
&& op.type & Operation.INSERT))
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
isOperation = true;
|
isOperation = true;
|
||||||
|
|
||||||
if (op.type & Operation.DELETE) {
|
if (op.type & Operation.DELETE) {
|
||||||
|
|
|
@ -20,11 +20,11 @@ module.exports = new Class({
|
||||||
const hash = this.hash;
|
const hash = this.hash;
|
||||||
|
|
||||||
const builder = new Vn.Builder();
|
const builder = new Vn.Builder();
|
||||||
builder.compileFile('forms/'+ this.formInfo.path +'/ui.xml');
|
builder.compileFile(`forms/${this.formInfo.path}/ui.xml`);
|
||||||
|
|
||||||
const scope = this.builder = builder.load(null, this);
|
const scope = this.builder = builder.load(null, this);
|
||||||
this.$ = scope.$;
|
this.$ = scope.$;
|
||||||
scope.link(null, {conn, hash});
|
scope.link({conn, hash});
|
||||||
this.node = scope.$.form;
|
this.node = scope.$.form;
|
||||||
|
|
||||||
const paramsLot = this.$.params;
|
const paramsLot = this.$.params;
|
||||||
|
|
|
@ -69,7 +69,7 @@ module.exports = new Class({
|
||||||
builder.compileFile('reports/'+ this.info.path +'/ui.xml');
|
builder.compileFile('reports/'+ this.info.path +'/ui.xml');
|
||||||
|
|
||||||
var scope = this.scope = builder.load(this.doc, this);
|
var scope = this.scope = builder.load(this.doc, this);
|
||||||
scope.link(null, {
|
scope.link({
|
||||||
lot: this.lot,
|
lot: this.lot,
|
||||||
conn: this.conn
|
conn: this.conn
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,6 +12,8 @@ td.cell-button {
|
||||||
width: 44px;
|
width: 44px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
border: none;
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 10px;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,11 @@ module.exports = new Class({
|
||||||
Extends: Component
|
Extends: Component
|
||||||
,Tag: 'htk-repeater'
|
,Tag: 'htk-repeater'
|
||||||
,Child: 'model'
|
,Child: 'model'
|
||||||
,Properties:
|
,Properties: {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* The source data model.
|
* The source data model.
|
||||||
*/
|
*/
|
||||||
model:
|
model: {
|
||||||
{
|
|
||||||
type: Db.Model
|
type: Db.Model
|
||||||
,set: function(x) {
|
,set: function(x) {
|
||||||
this.link({_model: x}, {
|
this.link({_model: x}, {
|
||||||
|
@ -30,8 +28,7 @@ module.exports = new Class({
|
||||||
/**
|
/**
|
||||||
* The identifier for internal iterator.
|
* The identifier for internal iterator.
|
||||||
*/
|
*/
|
||||||
,formId:
|
,formId: {
|
||||||
{
|
|
||||||
type: String
|
type: String
|
||||||
,set: function(x) {
|
,set: function(x) {
|
||||||
this._formId = x;
|
this._formId = x;
|
||||||
|
@ -44,8 +41,7 @@ module.exports = new Class({
|
||||||
* {Function (Vn.BuilderResult, Db.Form)} Function to call after every
|
* {Function (Vn.BuilderResult, Db.Form)} Function to call after every
|
||||||
* box rendering.
|
* box rendering.
|
||||||
*/
|
*/
|
||||||
,renderer:
|
,renderer: {
|
||||||
{
|
|
||||||
type: Function
|
type: Function
|
||||||
,set: function(x) {
|
,set: function(x) {
|
||||||
this._renderer = x;
|
this._renderer = x;
|
||||||
|
@ -57,8 +53,7 @@ module.exports = new Class({
|
||||||
/**
|
/**
|
||||||
* Wether to show the model status.
|
* Wether to show the model status.
|
||||||
*/
|
*/
|
||||||
,showStatus:
|
,showStatus: {
|
||||||
{
|
|
||||||
type: Boolean
|
type: Boolean
|
||||||
,set: function(x) {
|
,set: function(x) {
|
||||||
this._showStatus = x;
|
this._showStatus = x;
|
||||||
|
@ -71,8 +66,7 @@ module.exports = new Class({
|
||||||
/**
|
/**
|
||||||
* Message that should be displayed when source model is not ready.
|
* Message that should be displayed when source model is not ready.
|
||||||
*/
|
*/
|
||||||
,emptyMessage:
|
,emptyMessage: {
|
||||||
{
|
|
||||||
type: String
|
type: String
|
||||||
,value: null
|
,value: null
|
||||||
}
|
}
|
||||||
|
@ -105,7 +99,7 @@ module.exports = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
,getBuilder: function(index) {
|
,getBuilder: function(index) {
|
||||||
return this._childsData[index].builder;
|
return this._childsData[index].scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
,getForm: function(index) {
|
,getForm: function(index) {
|
||||||
|
@ -119,14 +113,12 @@ module.exports = new Class({
|
||||||
});
|
});
|
||||||
|
|
||||||
var scope = this._builder.load(this.doc, null, this._parentScope);
|
var scope = this._builder.load(this.doc, null, this._parentScope);
|
||||||
scope.link([set.getObject()], {
|
scope.link({
|
||||||
[this._formId]: set
|
$iter: set,
|
||||||
|
[this._formId]: set.getObject()
|
||||||
});
|
});
|
||||||
|
|
||||||
this._childsData.push({
|
this._childsData.push({scope, set});
|
||||||
builder: scope,
|
|
||||||
set: set
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this._renderer)
|
if (this._renderer)
|
||||||
this._renderer(scope, set);
|
this._renderer(scope, set);
|
||||||
|
@ -228,7 +220,7 @@ module.exports = new Class({
|
||||||
,_unrefChildData: function(index) {
|
,_unrefChildData: function(index) {
|
||||||
var childData = this._childsData[index];
|
var childData = this._childsData[index];
|
||||||
childData.set.unref();
|
childData.set.unref();
|
||||||
childData.builder.unref();
|
childData.scope.unref();
|
||||||
}
|
}
|
||||||
|
|
||||||
,destroy: function() {
|
,destroy: function() {
|
||||||
|
|
597
js/vn/builder.js
597
js/vn/builder.js
|
@ -1,16 +1,22 @@
|
||||||
const VnObject = require('./object');
|
const VnObject = require('./object');
|
||||||
const Component = require('./component');
|
|
||||||
const VnNode = require('./node');
|
|
||||||
const Scope = require('./scope');
|
const Scope = require('./scope');
|
||||||
const Type = require('./type');
|
|
||||||
const kebabToCamel = require('./string-util').kebabToCamel;
|
const kebabToCamel = require('./string-util').kebabToCamel;
|
||||||
|
|
||||||
|
const CompilerObject = require('./compiler-object');
|
||||||
|
const CompilerElement = require('./compiler-element');
|
||||||
|
const CompilerText = require('./compiler-text');
|
||||||
|
|
||||||
|
const regCompilers = [
|
||||||
|
CompilerText,
|
||||||
|
CompilerObject,
|
||||||
|
CompilerElement
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a object from a XML specification.
|
* Creates a object from a XML specification.
|
||||||
*/
|
*/
|
||||||
module.exports = new Class({
|
module.exports = new Class({
|
||||||
Extends: VnObject
|
Extends: VnObject
|
||||||
,_contexts: null
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles an XML file.
|
* Compiles an XML file.
|
||||||
|
@ -30,8 +36,8 @@ module.exports = new Class({
|
||||||
* @return {Boolean} %true on success, %false othersise
|
* @return {Boolean} %true on success, %false othersise
|
||||||
*/
|
*/
|
||||||
,compileString: function(xmlString) {
|
,compileString: function(xmlString) {
|
||||||
var parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
var doc = parser.parseFromString(xmlString, 'text/xml');
|
const doc = parser.parseFromString(xmlString, 'text/xml');
|
||||||
return this.compileDocument(doc);
|
return this.compileDocument(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +47,12 @@ module.exports = new Class({
|
||||||
* @param {Document} doc The DOM document
|
* @param {Document} doc The DOM document
|
||||||
* @return {Boolean} %true on success, %false othersise
|
* @return {Boolean} %true on success, %false othersise
|
||||||
*/
|
*/
|
||||||
,compileDocument: function(doc, exprArgs) {
|
,compileDocument: function(doc) {
|
||||||
if (!doc)
|
if (!doc)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this._preCompile(exprArgs);
|
this._preCompile();
|
||||||
var docElement = doc.documentElement;
|
const docElement = doc.documentElement;
|
||||||
|
|
||||||
if (docElement.tagName !== 'vn') {
|
if (docElement.tagName !== 'vn') {
|
||||||
this.showError('The toplevel tag should be named \'vn\'');
|
this.showError('The toplevel tag should be named \'vn\'');
|
||||||
|
@ -54,9 +60,9 @@ module.exports = new Class({
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var childs = docElement.childNodes;
|
const childs = docElement.childNodes;
|
||||||
if (childs)
|
if (childs)
|
||||||
for (var i = 0; i < childs.length; i++)
|
for (let i = 0; i < childs.length; i++)
|
||||||
this._compile(childs[i]);
|
this._compile(childs[i]);
|
||||||
|
|
||||||
this._postCompile();
|
this._postCompile();
|
||||||
|
@ -69,8 +75,8 @@ module.exports = new Class({
|
||||||
* @path Node The DOM node
|
* @path Node The DOM node
|
||||||
* @return %true on success, %false othersise
|
* @return %true on success, %false othersise
|
||||||
*/
|
*/
|
||||||
,compileNode: function(node, exprArgs) {
|
,compileNode: function(node) {
|
||||||
this._preCompile(exprArgs);
|
this._preCompile();
|
||||||
this._mainContext = this._compile(node).id;
|
this._mainContext = this._compile(node).id;
|
||||||
this._postCompile();
|
this._postCompile();
|
||||||
return true;
|
return true;
|
||||||
|
@ -79,28 +85,27 @@ module.exports = new Class({
|
||||||
/**
|
/**
|
||||||
* Called before starting to compile nodes.
|
* Called before starting to compile nodes.
|
||||||
*/
|
*/
|
||||||
,_preCompile: function(exprArgs) {
|
,_preCompile: function() {
|
||||||
this._path = null;
|
this._path = null;
|
||||||
this._tags = {};
|
this._tags = {};
|
||||||
this._contexts = [];
|
this._contexts = [];
|
||||||
|
this._exprContexts = [];
|
||||||
this._contextMap = {};
|
this._contextMap = {};
|
||||||
this._links = [];
|
this._links = [];
|
||||||
this._mainContext = null;
|
this._mainContext = null;
|
||||||
|
|
||||||
this._baseExprArgs = ['_', '$'];
|
this._compilers = [];
|
||||||
if (exprArgs)
|
for (regCompiler of regCompilers)
|
||||||
this._baseExprArgs = this._baseExprArgs.concat(exprArgs);
|
this._compilers.push(new regCompiler(this));
|
||||||
|
|
||||||
this._baseEventArgs = this._baseExprArgs.concat(['$event']);
|
|
||||||
|
|
||||||
this._exprArgs = this._baseExprArgs.join(',');
|
|
||||||
this._eventArgs = this._baseEventArgs.join(',');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after all nodes have been compiled.
|
* Called after all nodes have been compiled.
|
||||||
*/
|
*/
|
||||||
,_postCompile: function() {}
|
,_postCompile: function() {
|
||||||
|
for (const compiler of this._compilers)
|
||||||
|
compiler.postCompile(this._contextMap);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles a node.
|
* Compiles a node.
|
||||||
|
@ -115,24 +120,24 @@ module.exports = new Class({
|
||||||
else if (node.nodeType !== Node.TEXT_NODE
|
else if (node.nodeType !== Node.TEXT_NODE
|
||||||
|| /^[\n\r\t]*$/.test(node.textContent))
|
|| /^[\n\r\t]*$/.test(node.textContent))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
context =
|
let i;
|
||||||
this.textCompile(node, tagName)
|
const compilers = this._compilers;
|
||||||
|| this.objectCompile(node, tagName)
|
for (i = 0; i < compilers.length && context === null; i++)
|
||||||
|| this.elementCompile(node, tagName);
|
context = compilers[i].compile(this, node, tagName);
|
||||||
|
|
||||||
context.id = this._contexts.length;
|
context.id = this._contexts.length;
|
||||||
|
context.compiler = compilers[i - 1];
|
||||||
|
|
||||||
if (isElement) {
|
if (isElement) {
|
||||||
var nodeId = node.getAttribute('id');
|
const nodeId = node.getAttribute('id');
|
||||||
|
|
||||||
if (nodeId) {
|
if (nodeId) {
|
||||||
this._contextMap[kebabToCamel(nodeId)] = context.id;
|
this._contextMap[kebabToCamel(nodeId)] = context.id;
|
||||||
context.nodeId = nodeId;
|
context.nodeId = nodeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tags = this._tags[tagName];
|
let tags = this._tags[tagName];
|
||||||
|
|
||||||
if (!tags)
|
if (!tags)
|
||||||
this._tags[tagName] = tags = [];
|
this._tags[tagName] = tags = [];
|
||||||
|
|
||||||
|
@ -143,537 +148,21 @@ module.exports = new Class({
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
,getMain: function(scope) {
|
|
||||||
return scope.objects[this._mainContext];
|
|
||||||
}
|
|
||||||
|
|
||||||
,getByTagName: function(scope, tagName) {
|
|
||||||
var tags = this._tags[tagName];
|
|
||||||
|
|
||||||
if (tags) {
|
|
||||||
var arr = new Array(tags.length);
|
|
||||||
|
|
||||||
for (var i = 0; i < tags.length; i++)
|
|
||||||
arr[i] = scope.objects[tags[i]];
|
|
||||||
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
,load: function(dstDocument, thisArg, parentScope) {
|
,load: function(dstDocument, thisArg, parentScope) {
|
||||||
if (this._contexts === null)
|
if (!this._contexts) return null;
|
||||||
return null;
|
|
||||||
|
|
||||||
const doc = dstDocument ? dstDocument : document;
|
const doc = dstDocument ? dstDocument : document;
|
||||||
const contexts = this._contexts;
|
const objects = new Array(this._contexts.length);
|
||||||
const len = contexts.length;
|
const exprValues = new Array(this._exprContexts.length);
|
||||||
const objects = new Array(len);
|
return new Scope(this, doc, objects, exprValues, thisArg, parentScope);
|
||||||
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, scope);
|
|
||||||
else if (context.klass)
|
|
||||||
objects[i] = this.objectInstantiate(doc, context, scope);
|
|
||||||
else
|
|
||||||
objects[i] = this.textInstantiate(doc, context, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
return scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
,link: function(scope) {
|
|
||||||
const objects = scope.objects;
|
|
||||||
const links = this._links;
|
|
||||||
|
|
||||||
// Pre-link
|
|
||||||
|
|
||||||
for (var i = links.length - 1; i >= 0; i--) {
|
|
||||||
const link = links[i];
|
|
||||||
const object = objects[link.context.id];
|
|
||||||
const objectRef = scope.$[link.objectId];
|
|
||||||
|
|
||||||
if (objectRef === undefined) {
|
|
||||||
this.showError('Referenced unexistent object with id \'%s\'',
|
|
||||||
link.objectId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (link.prop)
|
|
||||||
object[link.prop] = objectRef;
|
|
||||||
else
|
|
||||||
object.appendChild(objectRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post-link
|
|
||||||
|
|
||||||
const contexts = this._contexts;
|
|
||||||
for (var i = 0; i < contexts.length; i++) {
|
|
||||||
const context = contexts[i];
|
|
||||||
const object = objects[i];
|
|
||||||
|
|
||||||
if (context.tagName)
|
|
||||||
this.elementLink(context, object, objects, scope);
|
|
||||||
else if (context.klass)
|
|
||||||
this.objectLink(context, object, objects, scope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,digest(scope) {
|
|
||||||
const contexts = this._contexts;
|
|
||||||
const objects = scope.objects;
|
|
||||||
const exprScope = scope.exprScope;
|
|
||||||
|
|
||||||
for (let i = 0; i < contexts.length; i++) {
|
|
||||||
const context = contexts[i];
|
|
||||||
const object = objects[i];
|
|
||||||
|
|
||||||
if (context.exprs) {
|
|
||||||
const values = [];
|
|
||||||
let isEmpty = false;
|
|
||||||
|
|
||||||
for (expr of context.exprs) {
|
|
||||||
let value = undefined;
|
|
||||||
try {
|
|
||||||
value = expr.apply(scope.thisArg, exprScope);
|
|
||||||
if (value == null) {
|
|
||||||
isEmpty = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('Expression error:', e.message);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
values.push(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
let text;
|
|
||||||
|
|
||||||
if (!isEmpty) {
|
|
||||||
let k = 0;
|
|
||||||
text = context.text.replace(/{{\d+}}/g, function() {
|
|
||||||
return values[k++];
|
|
||||||
});
|
|
||||||
} else
|
|
||||||
text = '';
|
|
||||||
|
|
||||||
object.textContent = text;
|
|
||||||
} else {
|
|
||||||
const dynProps = context.dynProps;
|
|
||||||
|
|
||||||
for (const prop in dynProps) {
|
|
||||||
let value = undefined;
|
|
||||||
try {
|
|
||||||
value = dynProps[prop].apply(scope.thisArg, exprScope);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('Expression error:', e.message);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.tagName)
|
|
||||||
object.setAttribute(prop, value);
|
|
||||||
else
|
|
||||||
object[prop] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,showError: function(error) {
|
,showError: function(error) {
|
||||||
var path = this._path ? this._path : 'Node';
|
const path = this._path ? this._path : 'Node';
|
||||||
var logArgs = ['Vn.Builder: %s: '+ error, path];
|
const logArgs = ['Vn.Builder: %s: '+ error, path];
|
||||||
|
|
||||||
for (var i = 1; i < arguments.length; i++)
|
for (let i = 1; i < arguments.length; i++)
|
||||||
logArgs.push(arguments[i]);
|
logArgs.push(arguments[i]);
|
||||||
|
|
||||||
console.warn.apply(null, logArgs);
|
console.warn.apply(null, logArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
,_addLink: function(context, prop, objectId) {
|
|
||||||
this._links.push({
|
|
||||||
context
|
|
||||||
,prop
|
|
||||||
,objectId: kebabToCamel(objectId)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
,fnExpr(expr) {
|
|
||||||
return new Function(this._exprArgs,
|
|
||||||
'"use strict"; return ' + expr + ';'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
,matchExpr(value) {
|
|
||||||
const match = /^{{(.*)}}$/.exec(value);
|
|
||||||
if (!match) return null;
|
|
||||||
return this.fnExpr(match[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
,_translateValue: function(value) {
|
|
||||||
var chr = value.charAt(0);
|
|
||||||
|
|
||||||
if (chr === '_')
|
|
||||||
return _(value.substr(1));
|
|
||||||
else if (chr === '\\' && value.charAt(1) === '_')
|
|
||||||
return value.substr(1);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
,_getMethod: function(value) {
|
|
||||||
let method;
|
|
||||||
|
|
||||||
if (this.isIdentifier(value)) {
|
|
||||||
// XXX: Compatibility with old events
|
|
||||||
method = value;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
method = new Function(this._eventArgs,
|
|
||||||
'"use strict"; return ' + value + ';'
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
this.showError(`Method: ${err.message}: ${value}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
,_isEvent: function(attribute) {
|
|
||||||
return /^on-\w+/.test(attribute);
|
|
||||||
}
|
|
||||||
|
|
||||||
,isIdentifier: function(value) {
|
|
||||||
return /^[a-zA-Z_$][\w$]*$/.test(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
,_replaceFunc: function(token) {
|
|
||||||
return token.charAt(1).toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TextNode
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a text node context.
|
|
||||||
*/
|
|
||||||
,textCompile: function(node, tagName) {
|
|
||||||
if (!tagName) {
|
|
||||||
let text = node.textContent;
|
|
||||||
|
|
||||||
if (/{{.*}}/.test(text)) {
|
|
||||||
let i = 0;
|
|
||||||
const self = this;
|
|
||||||
const exprs = [];
|
|
||||||
text = text.replace(/{{((?:(?!}}).)*)}}/g, function(match, capture) {
|
|
||||||
exprs.push(self.fnExpr(capture));
|
|
||||||
return `{{${i++}}}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {text, exprs};
|
|
||||||
} else
|
|
||||||
return {text};
|
|
||||||
} else if (tagName === 't')
|
|
||||||
return {text: _(node.firstChild.textContent)};
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
,textInstantiate: function(doc, context) {
|
|
||||||
return doc.createTextNode(context.exprs ? '' : context.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vn.Object
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a object context.
|
|
||||||
*/
|
|
||||||
,objectCompile: function(node, tagName) {
|
|
||||||
var klass = vnCustomTags[tagName];
|
|
||||||
|
|
||||||
if (!klass)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var props = {};
|
|
||||||
var objectProps = {};
|
|
||||||
var childs = [];
|
|
||||||
var events = {};
|
|
||||||
|
|
||||||
var context = {
|
|
||||||
klass: klass,
|
|
||||||
props: props,
|
|
||||||
dynProps: {},
|
|
||||||
funcProps: {},
|
|
||||||
objectProps: objectProps,
|
|
||||||
childs: childs,
|
|
||||||
events: events,
|
|
||||||
custom: null
|
|
||||||
};
|
|
||||||
|
|
||||||
var a = node.attributes;
|
|
||||||
|
|
||||||
for (var i = 0; i < a.length; i++) {
|
|
||||||
var attribute = a[i].nodeName;
|
|
||||||
var value = a[i].nodeValue;
|
|
||||||
|
|
||||||
if (this._isEvent(attribute)) {
|
|
||||||
var handler = this._getMethod(value)
|
|
||||||
|
|
||||||
if (handler)
|
|
||||||
events[attribute.substr(3)] = handler;
|
|
||||||
} else if (!/^(id|property)$/.test(attribute)) {
|
|
||||||
this.propCompile(context, klass, props,
|
|
||||||
node, attribute, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var childNodes = node.childNodes;
|
|
||||||
|
|
||||||
if (childNodes)
|
|
||||||
for (var i = 0; i < childNodes.length; i++) {
|
|
||||||
var child = childNodes[i];
|
|
||||||
var isElement = child.nodeType === Node.ELEMENT_NODE;
|
|
||||||
var childTagName = isElement ? child.tagName.toLowerCase() : null;
|
|
||||||
var childContext;
|
|
||||||
|
|
||||||
if (childTagName === 'pointer') {
|
|
||||||
this._addLink(context, null, child.getAttribute('object'));
|
|
||||||
} else if (childTagName === 'custom') {
|
|
||||||
context.custom = child;
|
|
||||||
} else if (childContext = this._compile(child)) {
|
|
||||||
var prop = isElement ? child.getAttribute('property') : null;
|
|
||||||
|
|
||||||
if (prop) {
|
|
||||||
prop = prop.replace(/-./g, this._replaceFunc);
|
|
||||||
objectProps[prop] = childContext.id;
|
|
||||||
} else
|
|
||||||
childs.push(childContext.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
,propCompile: function(context, klass, props, node, attribute, value) {
|
|
||||||
let isLink = false;
|
|
||||||
let propError = false;
|
|
||||||
let newValue = null;
|
|
||||||
const propName = attribute.replace(/-./g, this._replaceFunc);
|
|
||||||
const propInfo = klass.Properties[propName];
|
|
||||||
|
|
||||||
if (!propInfo) {
|
|
||||||
this.showError('Attribute \'%s\' not valid for tag \'%s\'',
|
|
||||||
attribute, node.tagName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!value) {
|
|
||||||
this.showError('Attribute \'%s\' empty on tag \'%s\'',
|
|
||||||
attribute, node.tagName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const expr = this.matchExpr(value);
|
|
||||||
|
|
||||||
if (expr) {
|
|
||||||
context.dynProps[propName] = expr;
|
|
||||||
} else {
|
|
||||||
switch (propInfo.type) {
|
|
||||||
case Boolean:
|
|
||||||
newValue = (/^(true|1)$/i).test(value);
|
|
||||||
break;
|
|
||||||
case Number:
|
|
||||||
newValue = 0 + new Number(value);
|
|
||||||
break;
|
|
||||||
case String:
|
|
||||||
newValue = this._translateValue(value);
|
|
||||||
break;
|
|
||||||
case Function:
|
|
||||||
context.funcProps[propName] = this._getMethod(value);
|
|
||||||
break;
|
|
||||||
case Type:
|
|
||||||
newValue = window[value];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (propInfo.enumType)
|
|
||||||
newValue = propInfo.enumType[value];
|
|
||||||
else if (propInfo.type instanceof Function)
|
|
||||||
isLink = true;
|
|
||||||
else
|
|
||||||
propError = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLink)
|
|
||||||
this._addLink(context, propName, value);
|
|
||||||
else if (newValue !== null && newValue !== undefined)
|
|
||||||
props[propName] = newValue;
|
|
||||||
else if (propError)
|
|
||||||
this.showError('Attribute \'%s\' invalid for tag \'%s\'',
|
|
||||||
attribute, node.tagName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,objectInstantiate: function(doc, context, scope) {
|
|
||||||
const object = new context.klass();
|
|
||||||
object.setProperties(context.props);
|
|
||||||
|
|
||||||
if (context.nodeId && object instanceof Component) {
|
|
||||||
var id = context.nodeId;
|
|
||||||
object.htmlId = scope.getHtmlId(id);
|
|
||||||
object.className = '_'+ id +' '+ (object.className || '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
,objectLink: function(context, object, objects, scope) {
|
|
||||||
const objectProps = context.objectProps;
|
|
||||||
for (const prop in objectProps)
|
|
||||||
object[prop] = objects[objectProps[prop]];
|
|
||||||
|
|
||||||
const childs = context.childs;
|
|
||||||
for (let i = 0; i < childs.length; i++)
|
|
||||||
object.appendChild(objects[childs[i]]);
|
|
||||||
|
|
||||||
const funcProps = context.funcProps;
|
|
||||||
for (const prop in funcProps) {
|
|
||||||
let method;
|
|
||||||
const handler = funcProps[prop];
|
|
||||||
|
|
||||||
if (typeof handler === 'string') {
|
|
||||||
// XXX: Compatibility with old expressions
|
|
||||||
method = scope.thisArg[handler];
|
|
||||||
if (!method)
|
|
||||||
this.showError(`Function '${handler}' not found`);
|
|
||||||
method = method.bind(scope.thisArg);
|
|
||||||
} else {
|
|
||||||
method = function() {
|
|
||||||
handler.apply(scope.thisArg, scope.exprScope);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method)
|
|
||||||
object[prop] = method;
|
|
||||||
}
|
|
||||||
|
|
||||||
const events = context.events;
|
|
||||||
for (const event in events) {
|
|
||||||
let listener;
|
|
||||||
const handler = events[event];
|
|
||||||
|
|
||||||
if (typeof handler === 'string') {
|
|
||||||
// XXX: Compatibility with old expressions
|
|
||||||
listener = scope.thisArg[handler];
|
|
||||||
if (!listener)
|
|
||||||
this.showError(`Function '${handler}' not found`);
|
|
||||||
} else {
|
|
||||||
listener = function() {
|
|
||||||
handler.apply(scope.thisArg, scope.exprScope.concat(arguments));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener)
|
|
||||||
object.on(event, listener, scope.thisArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.custom)
|
|
||||||
object.loadXml(scope, context.custom);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Element
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a HTML node context.
|
|
||||||
*/
|
|
||||||
,elementCompile: function(node, tagName) {
|
|
||||||
var attributes = {};
|
|
||||||
var dynProps = {};
|
|
||||||
var childs = [];
|
|
||||||
var events = {};
|
|
||||||
var handler;
|
|
||||||
|
|
||||||
var a = node.attributes;
|
|
||||||
|
|
||||||
for (var i = 0; i < a.length; i++) {
|
|
||||||
var attribute = a[i].nodeName;
|
|
||||||
var value = a[i].nodeValue;
|
|
||||||
|
|
||||||
if (this._isEvent(attribute)) {
|
|
||||||
var handler = this._getMethod(value);
|
|
||||||
if (handler) events[attribute.substr(3)] = handler;
|
|
||||||
} else if (attribute !== 'id') {
|
|
||||||
const expr = this.matchExpr(value);
|
|
||||||
if (expr)
|
|
||||||
dynProps[attribute] = expr;
|
|
||||||
else
|
|
||||||
attributes[attribute] = this._translateValue(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var childContext;
|
|
||||||
var childNodes = node.childNodes;
|
|
||||||
|
|
||||||
if (childNodes)
|
|
||||||
for (var i = 0; i < childNodes.length; i++)
|
|
||||||
if (childContext = this._compile(childNodes[i]))
|
|
||||||
childs.push(childContext.id);
|
|
||||||
|
|
||||||
return {
|
|
||||||
tagName,
|
|
||||||
attributes,
|
|
||||||
dynProps,
|
|
||||||
childs,
|
|
||||||
events
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
,elementInstantiate: function(doc, context, scope) {
|
|
||||||
var object = doc.createElement(context.tagName);
|
|
||||||
|
|
||||||
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) {
|
|
||||||
const childs = context.childs;
|
|
||||||
for (var i = 0; i < childs.length; i++) {
|
|
||||||
let child = objects[childs[i]];
|
|
||||||
|
|
||||||
if (child instanceof Component)
|
|
||||||
child = child.node;
|
|
||||||
if (child instanceof Node)
|
|
||||||
object.appendChild(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
const events = context.events;
|
|
||||||
for (const event in events) {
|
|
||||||
let listener;
|
|
||||||
const handler = events[event];
|
|
||||||
if (typeof handler === 'string') {
|
|
||||||
// XXX: Compatibility with old expressions
|
|
||||||
listener = scope.thisArg[handler];
|
|
||||||
if (!listener)
|
|
||||||
this.showError(`Function '${handler}' not found`);
|
|
||||||
listener = listener.bind(scope.thisArg);
|
|
||||||
} else {
|
|
||||||
listener = function(e) {
|
|
||||||
handler.apply(scope.thisArg, scope.exprScope.concat(e));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener)
|
|
||||||
object.addEventListener(event, listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
const Compiler = require('./compiler');
|
||||||
|
const Component = require('./component');
|
||||||
|
const VnNode = require('./node');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles a @HTMLElement from element tag.
|
||||||
|
*/
|
||||||
|
module.exports = new Class({
|
||||||
|
Extends: Compiler
|
||||||
|
|
||||||
|
,compile: function(builder, node, tagName) {
|
||||||
|
const context = {
|
||||||
|
tagName,
|
||||||
|
attributes: {},
|
||||||
|
childs: [],
|
||||||
|
events: {}
|
||||||
|
};
|
||||||
|
const {attributes} = context;
|
||||||
|
|
||||||
|
const a = node.attributes;
|
||||||
|
for (let i = 0; i < a.length; i++) {
|
||||||
|
const attribute = a[i].nodeName;
|
||||||
|
const value = a[i].nodeValue;
|
||||||
|
|
||||||
|
if (this.isEvent(attribute)) {
|
||||||
|
const handler = this._getMethod(value);
|
||||||
|
if (handler) context.events[attribute.substr(3)] = handler;
|
||||||
|
} else if (!/^(id|property)$/.test(attribute)) {
|
||||||
|
if (this.isExpr(value))
|
||||||
|
this.compileExpr(context, attribute, value);
|
||||||
|
else
|
||||||
|
attributes[attribute] = this._translateValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let childContext;
|
||||||
|
const childNodes = node.childNodes;
|
||||||
|
|
||||||
|
if (childNodes)
|
||||||
|
for (let i = 0; i < childNodes.length; i++)
|
||||||
|
if (childContext = builder._compile(childNodes[i]))
|
||||||
|
context.childs.push(childContext.id);
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
,instantiate: function(doc, context, scope) {
|
||||||
|
const object = doc.createElement(context.tagName);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
,setProperty(object, property, value) {
|
||||||
|
object.setAttribute(property, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
,link: function(context, object, objects, scope) {
|
||||||
|
const childs = context.childs;
|
||||||
|
for (let i = 0; i < childs.length; i++) {
|
||||||
|
let child = objects[childs[i]];
|
||||||
|
|
||||||
|
if (child instanceof Component)
|
||||||
|
child = child.node;
|
||||||
|
if (child instanceof Node)
|
||||||
|
object.appendChild(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
const events = context.events;
|
||||||
|
for (const event in events) {
|
||||||
|
const listener = this.bindMethod(events[event], scope, true);
|
||||||
|
if (listener)
|
||||||
|
object.addEventListener(event, listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,216 @@
|
||||||
|
const Compiler = require('./compiler');
|
||||||
|
const Component = require('./component');
|
||||||
|
const Type = require('./type');
|
||||||
|
const kebabToCamel = require('./string-util').kebabToCamel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles a @Vn.Object from element tag.
|
||||||
|
*/
|
||||||
|
module.exports = new Class({
|
||||||
|
Extends: Compiler
|
||||||
|
|
||||||
|
,_links: []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a object context.
|
||||||
|
*/
|
||||||
|
,compile: function(builder, node, tagName) {
|
||||||
|
const klass = vnCustomTags[tagName];
|
||||||
|
if (!klass) return null;
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
klass,
|
||||||
|
props: {},
|
||||||
|
funcProps: {},
|
||||||
|
objectProps: {},
|
||||||
|
childs: [],
|
||||||
|
events: {},
|
||||||
|
custom: null
|
||||||
|
};
|
||||||
|
|
||||||
|
const a = node.attributes;
|
||||||
|
for (let i = 0; i < a.length; i++) {
|
||||||
|
const attribute = a[i].nodeName;
|
||||||
|
const value = a[i].nodeValue;
|
||||||
|
|
||||||
|
if (this.isEvent(attribute)) {
|
||||||
|
const handler = this._getMethod(value)
|
||||||
|
if (handler) context.events[attribute.substr(3)] = handler;
|
||||||
|
} else if (!/^(id|property)$/.test(attribute)) {
|
||||||
|
this.propCompile(context, node, attribute, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const childNodes = node.childNodes;
|
||||||
|
|
||||||
|
if (childNodes)
|
||||||
|
for (let i = 0; i < childNodes.length; i++) {
|
||||||
|
const child = childNodes[i];
|
||||||
|
const isElement = child.nodeType === Node.ELEMENT_NODE;
|
||||||
|
const childTagName = isElement ? child.tagName.toLowerCase() : null;
|
||||||
|
let childContext;
|
||||||
|
|
||||||
|
if (childTagName === 'pointer') {
|
||||||
|
this._addLink(context, null, child.getAttribute('object'));
|
||||||
|
} else if (childTagName === 'custom') {
|
||||||
|
context.custom = child;
|
||||||
|
} else if (childContext = builder._compile(child)) {
|
||||||
|
let prop = isElement ? child.getAttribute('property') : null;
|
||||||
|
|
||||||
|
if (prop) {
|
||||||
|
prop = kebabToCamel(prop);
|
||||||
|
context.objectProps[prop] = childContext.id;
|
||||||
|
} else
|
||||||
|
context.childs.push(childContext.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
,propCompile: function(context, node, attribute, value) {
|
||||||
|
const tagName = node.tagName;
|
||||||
|
const propName = kebabToCamel(attribute);
|
||||||
|
const propInfo = context.klass.Properties[propName];
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
this.showError('Attribute \'%s\' empty on tag \'%s\'',
|
||||||
|
attribute, tagName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propName == 'vModel') {
|
||||||
|
context.vModel = this.modelExpr(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!propInfo) {
|
||||||
|
this.showError('Attribute \'%s\' not valid for tag \'%s\'',
|
||||||
|
attribute, tagName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isExpr(value)) {
|
||||||
|
this.compileExpr(context, propName, value);
|
||||||
|
} else {
|
||||||
|
let isLink = false;
|
||||||
|
let propError = false;
|
||||||
|
let newValue = null;
|
||||||
|
|
||||||
|
switch (propInfo.type) {
|
||||||
|
case Boolean:
|
||||||
|
newValue = (/^(true|1)$/i).test(value);
|
||||||
|
break;
|
||||||
|
case Number:
|
||||||
|
newValue = 0 + new Number(value);
|
||||||
|
break;
|
||||||
|
case String:
|
||||||
|
newValue = this._translateValue(value);
|
||||||
|
break;
|
||||||
|
case Function:
|
||||||
|
context.funcProps[propName] = this._getMethod(value);
|
||||||
|
break;
|
||||||
|
case Type:
|
||||||
|
newValue = window[value];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (propInfo.enumType)
|
||||||
|
newValue = propInfo.enumType[value];
|
||||||
|
else if (propInfo.type instanceof Function)
|
||||||
|
isLink = true;
|
||||||
|
else
|
||||||
|
propError = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLink)
|
||||||
|
this._addLink(context, propName, value);
|
||||||
|
else if (newValue !== null && newValue !== undefined)
|
||||||
|
context.props[propName] = newValue;
|
||||||
|
else if (propError)
|
||||||
|
this.showError('Attribute \'%s\' invalid for tag \'%s\'',
|
||||||
|
attribute, tagName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
,instantiate: function(doc, context, scope) {
|
||||||
|
const object = new context.klass();
|
||||||
|
object.setProperties(context.props);
|
||||||
|
|
||||||
|
if (context.nodeId && object instanceof Component) {
|
||||||
|
const id = context.nodeId;
|
||||||
|
object.htmlId = scope.getHtmlId(id);
|
||||||
|
object.className = '_'+ id +' '+ (object.className || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
,setProperty(object, property, value) {
|
||||||
|
object[property] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
,preLink(scope) {
|
||||||
|
const objects = scope.objects;
|
||||||
|
const links = this._links;
|
||||||
|
|
||||||
|
for (let i = links.length - 1; i >= 0; i--) {
|
||||||
|
const link = links[i];
|
||||||
|
const object = objects[link.context.id];
|
||||||
|
const objectRef = scope.$[link.objectId];
|
||||||
|
|
||||||
|
if (objectRef === undefined) {
|
||||||
|
this.showError('Referenced unexistent object with id \'%s\'',
|
||||||
|
link.objectId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link.prop)
|
||||||
|
object[link.prop] = objectRef;
|
||||||
|
else
|
||||||
|
object.appendChild(objectRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
,link: function(context, object, objects, scope) {
|
||||||
|
const objectProps = context.objectProps;
|
||||||
|
for (const prop in objectProps)
|
||||||
|
object[prop] = objects[objectProps[prop]];
|
||||||
|
|
||||||
|
const childs = context.childs;
|
||||||
|
for (let i = 0; i < childs.length; i++)
|
||||||
|
object.appendChild(objects[childs[i]]);
|
||||||
|
|
||||||
|
const funcProps = context.funcProps;
|
||||||
|
for (const prop in funcProps)
|
||||||
|
object[prop] = this.bindMethod(funcProps[prop], scope);
|
||||||
|
|
||||||
|
const events = context.events;
|
||||||
|
for (const event in events) {
|
||||||
|
const listener = this.bindMethod(events[event], scope);
|
||||||
|
if (listener)
|
||||||
|
object.on(event, listener, scope.thisArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.vModel) {
|
||||||
|
object.on('change', function(lot) {
|
||||||
|
context.vModel.call(scope.thisArg, scope.$, lot.$);
|
||||||
|
scope.digest();
|
||||||
|
}, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.custom)
|
||||||
|
object.loadXml(scope, context.custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
,_addLink: function(context, prop, objectId) {
|
||||||
|
this._links.push({
|
||||||
|
context
|
||||||
|
,prop
|
||||||
|
,objectId: kebabToCamel(objectId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
,_replaceFunc: function(token) {
|
||||||
|
return token.charAt(1).toUpperCase();
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,33 @@
|
||||||
|
const Compiler = require('./compiler');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles a @Text from text node.
|
||||||
|
*/
|
||||||
|
module.exports = new Class({
|
||||||
|
Extends: Compiler
|
||||||
|
|
||||||
|
,compile: function(builder, node, tagName) {
|
||||||
|
if (tagName && tagName != 't')
|
||||||
|
return null;
|
||||||
|
|
||||||
|
const text = node.textContent;
|
||||||
|
const context = {text};
|
||||||
|
|
||||||
|
if (tagName === 't') {
|
||||||
|
context.text = _(node.firstChild.textContent);
|
||||||
|
} else if (this.isExpr(text, true)) {
|
||||||
|
context.text = '';
|
||||||
|
this.compileExpr(context, null, text, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
,instantiate: function(doc, context) {
|
||||||
|
return doc.createTextNode(context.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
,setProperty(object, property, value) {
|
||||||
|
object.textContent = value;
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,150 @@
|
||||||
|
|
||||||
|
var VnObject = require('./object');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for compilers.
|
||||||
|
*/
|
||||||
|
module.exports = new Class({
|
||||||
|
Extends: VnObject
|
||||||
|
|
||||||
|
,compile: function() {}
|
||||||
|
,postCompile: function() {}
|
||||||
|
,instantiate: function() {}
|
||||||
|
,preLink: function() {}
|
||||||
|
,link: function() {}
|
||||||
|
,connect: function() {}
|
||||||
|
,postLink: function() {}
|
||||||
|
,setProperty: function() {}
|
||||||
|
,free: function() {}
|
||||||
|
|
||||||
|
,initialize: function(builder) {
|
||||||
|
this._builder = builder;
|
||||||
|
this._interpoler = builder._interpoler;
|
||||||
|
this.parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the passed attribute name it's an event.
|
||||||
|
*
|
||||||
|
* @param {String} attribute The attribute name
|
||||||
|
* @return {Boolean} %true if it's an event, otherwise %false
|
||||||
|
*/
|
||||||
|
,isEvent: function(attribute) {
|
||||||
|
return /^on-\w+/.test(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
,isIdentifier: function(value) {
|
||||||
|
return /^[a-zA-Z_$][\w$]*$/.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an error parsing the node.
|
||||||
|
*
|
||||||
|
* @param {String} error The error message template
|
||||||
|
* @param {...} varArgs The message template arguments
|
||||||
|
*/
|
||||||
|
,showError: function() {
|
||||||
|
this._builder.showError.apply(this._builder, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
,_getMethod: function(value) {
|
||||||
|
// XXX: Compatibility with old methods
|
||||||
|
return this.isIdentifier(value)
|
||||||
|
? value
|
||||||
|
: this.fnExpr(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
,bindMethod(handler, scope, isEvent) {
|
||||||
|
// XXX: Compatibility with old methods
|
||||||
|
if (typeof handler === 'string') {
|
||||||
|
const method = scope.thisArg[handler];
|
||||||
|
if (!method) {
|
||||||
|
this.showError(`Function '${handler}' not found`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return method.bind(scope.thisArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function($event) {
|
||||||
|
let handlerScope;
|
||||||
|
if (isEvent) {
|
||||||
|
handlerScope = Object.create(scope.$);
|
||||||
|
Object.assign(handlerScope, {$event});
|
||||||
|
} else
|
||||||
|
handlerScope = scope.$;
|
||||||
|
|
||||||
|
handler.call(this, handlerScope);
|
||||||
|
}.bind(scope.thisArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
,matchExpr(value) {
|
||||||
|
const match = /^{{(.*)}}$/.exec(value);
|
||||||
|
if (!match) return null;
|
||||||
|
return this.fnExpr(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
,modelExpr(expr) {
|
||||||
|
try {
|
||||||
|
return new Function('$scope', '$value',
|
||||||
|
`"use strict"; $scope.${expr} = $value;`
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
this.showError(`${err.message}:`, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
,exprRegex: /^{{((?:(?!}}).)*)}}$/
|
||||||
|
,exprRegexMulti: /{{((?:(?!}}).)*)}}/g
|
||||||
|
|
||||||
|
,isExpr(expr, isMulti) {
|
||||||
|
return isMulti
|
||||||
|
? this.exprRegexMulti.test(expr)
|
||||||
|
: this.exprRegex.test(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
,compileExpr(context, property, value, isMulti) {
|
||||||
|
const exprContext = {
|
||||||
|
context,
|
||||||
|
property,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isMulti) {
|
||||||
|
let i = 0;
|
||||||
|
const self = this;
|
||||||
|
exprContext.exprs = [];
|
||||||
|
exprContext.template = value.replace(this.exprRegexMulti,
|
||||||
|
function(match, capture) {
|
||||||
|
exprContext.exprs.push(self.fnExpr(capture));
|
||||||
|
return `{{${i++}}}`;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const match = this.exprRegex.exec(value);
|
||||||
|
exprContext.expr = this.fnExpr(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._builder._exprContexts.push(exprContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
,fnExpr(expr) {
|
||||||
|
try {
|
||||||
|
return new Function('$scope',
|
||||||
|
`with($scope) { return ${expr}; }`
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
this.showError(`${err.message}:`, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
,_translateValue: function(value) {
|
||||||
|
var chr = value.charAt(0);
|
||||||
|
|
||||||
|
if (chr === '_')
|
||||||
|
return _(value.substr(1));
|
||||||
|
else if (chr === '\\' && value.charAt(1) === '_')
|
||||||
|
return value.substr(1);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
});
|
|
@ -29,7 +29,11 @@ module.exports = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
,initialize: function(props) {
|
,initialize: function(props) {
|
||||||
this._params = {};
|
this._params = new Proxy({}, {
|
||||||
|
set(obj, prop, value) {
|
||||||
|
return Reflect.set(obj, prop, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
VnObject.prototype.initialize.call(this, props);
|
VnObject.prototype.initialize.call(this, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
112
js/vn/scope.js
112
js/vn/scope.js
|
@ -6,21 +6,30 @@ let scopeUid = 0;
|
||||||
module.exports = new Class({
|
module.exports = new Class({
|
||||||
Extends: VnObject
|
Extends: VnObject
|
||||||
|
|
||||||
,initialize: function(builder, objects, thisArg, parent) {
|
,initialize: function(builder, doc, objects, exprValues, thisArg, parent) {
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
this.objects = objects;
|
this.objects = objects;
|
||||||
|
this.exprValues = exprValues;
|
||||||
this.thisArg = thisArg;
|
this.thisArg = thisArg;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.uid = ++scopeUid;
|
this.uid = ++scopeUid;
|
||||||
this.$ = parent ? Object.create(parent.$) : {};
|
this.$ = parent ? Object.create(parent.$) : {};
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent.on('lot-change', this.onLotChange, this);
|
parent.ref();
|
||||||
|
// XXX: Keep commented until optimized
|
||||||
|
//parent.on('change', this.onChange, this);
|
||||||
if (!thisArg) this.thisArg = parent.thisArg;
|
if (!thisArg) this.thisArg = parent.thisArg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contexts = builder._contexts;
|
||||||
|
for (let i = 0; i < contexts.length; i++) {
|
||||||
|
const context = contexts[i];
|
||||||
|
objects[i] = context.compiler.instantiate(doc, context, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
,link: function(exprScope, extraObjects) {
|
,link: function(extraObjects) {
|
||||||
var contextMap = this.builder._contextMap;
|
var contextMap = this.builder._contextMap;
|
||||||
|
|
||||||
for (var id in extraObjects)
|
for (var id in extraObjects)
|
||||||
|
@ -28,26 +37,88 @@ module.exports = new Class({
|
||||||
for (var id in contextMap)
|
for (var id in contextMap)
|
||||||
this.$[id] = this.objects[contextMap[id]];
|
this.$[id] = this.objects[contextMap[id]];
|
||||||
|
|
||||||
this.exprScope = [
|
const builder = this.builder;
|
||||||
_,
|
const contexts = builder._contexts;
|
||||||
this.$
|
const objects = this.objects;
|
||||||
].concat(exprScope);
|
|
||||||
|
|
||||||
this.builder.link(this);
|
for (const compiler of builder._compilers)
|
||||||
this.builder.digest(this);
|
compiler.preLink(this);
|
||||||
|
|
||||||
|
for (let i = 0; i < contexts.length; i++) {
|
||||||
|
const context = contexts[i];
|
||||||
|
context.compiler.link(context, objects[i], objects, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < contexts.length; i++) {
|
||||||
|
const context = contexts[i];
|
||||||
|
context.compiler.connect(context, objects[i], objects, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const compiler of builder._compilers)
|
||||||
|
compiler.postLink(this);
|
||||||
|
|
||||||
|
this.digest();
|
||||||
|
|
||||||
for (const object of this.objects)
|
for (const object of this.objects)
|
||||||
if (object.assignLot)
|
if (object.assignLot)
|
||||||
object.on('change', this.onLotChange, this);
|
object.on('change', this.onChange, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
,onLotChange() {
|
,digest() {
|
||||||
this.emit('lot-change');
|
const exprContexts = this.builder._exprContexts;
|
||||||
this.builder.digest(this);
|
const exprValues = this.exprValues;
|
||||||
|
const objects = this.objects;
|
||||||
|
|
||||||
|
for (let i = 0; i < exprContexts.length; i++) {
|
||||||
|
const exprContext = exprContexts[i];
|
||||||
|
let newValue;
|
||||||
|
|
||||||
|
if (exprContext.template) {
|
||||||
|
const values = [];
|
||||||
|
let isEmpty = false;
|
||||||
|
|
||||||
|
for (expr of exprContext.exprs) {
|
||||||
|
const value = this.execExpr(expr);
|
||||||
|
if (value == null) {
|
||||||
|
isEmpty = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isEmpty) {
|
||||||
|
let k = 0;
|
||||||
|
newValue = exprContext.template.replace(/{{\d+}}/g, function() {
|
||||||
|
return values[k++];
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
newValue = '';
|
||||||
|
} else
|
||||||
|
newValue = this.execExpr(exprContext.expr);
|
||||||
|
|
||||||
|
if (newValue !== exprValues[i]) {
|
||||||
|
const context = exprContext.context;
|
||||||
|
context.compiler.setProperty(objects[context.id],
|
||||||
|
exprContext.property, newValue);
|
||||||
|
exprValues[i] = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
,execExpr(expr) {
|
||||||
|
try {
|
||||||
|
return expr.call(this.thisArg, this.$);
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
,onChange() {
|
||||||
|
this.emit('change');
|
||||||
|
this.digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
,getMain: function() {
|
,getMain: function() {
|
||||||
return this.builder.getMain(this);
|
return this.objects[this.builder._mainContext];
|
||||||
}
|
}
|
||||||
|
|
||||||
,getById: function(objectId) {
|
,getById: function(objectId) {
|
||||||
|
@ -56,7 +127,18 @@ module.exports = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
,getByTagName: function(tagName) {
|
,getByTagName: function(tagName) {
|
||||||
return this.builder.getByTagName(this, tagName);
|
const tags = this.builder._tags[tagName];
|
||||||
|
|
||||||
|
if (tags) {
|
||||||
|
const arr = new Array(tags.length);
|
||||||
|
|
||||||
|
for (let i = 0; i < tags.length; i++)
|
||||||
|
arr[i] = this.objects[tags[i]];
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
,getHtmlId: function(nodeId) {
|
,getHtmlId: function(nodeId) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "hedera-web",
|
"name": "hedera-web",
|
||||||
"version": "1.407.79",
|
"version": "1.407.80",
|
||||||
"description": "Verdnatura web page",
|
"description": "Verdnatura web page",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -66,7 +66,7 @@ class HtmlService extends Service {
|
||||||
|
|
||||||
// Setting the version
|
// Setting the version
|
||||||
|
|
||||||
setcookie('vnVersion', $this->getVersion());
|
setcookie('vnVersion', $this->getVersion(), ['samesite' => 'Lax']);
|
||||||
|
|
||||||
// Loading the requested page
|
// Loading the requested page
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,10 @@ abstract class Service {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isset($row['access'])) {
|
if (isset($row['access'])) {
|
||||||
setcookie('vnVisit', $row['visit'], time() + 31536000); // 1 Year
|
setcookie('vnVisit', $row['visit'], [
|
||||||
|
'expires' => time() + 31536000, // 1 Year
|
||||||
|
'samesite' => 'Lax'
|
||||||
|
]);
|
||||||
$_SESSION['access'] = $row['access'];
|
$_SESSION['access'] = $row['access'];
|
||||||
} else
|
} else
|
||||||
$_SESSION['skipVisit'] = TRUE;
|
$_SESSION['skipVisit'] = TRUE;
|
||||||
|
|
Loading…
Reference in New Issue