From 1e43aead46da9b0fe354c6b6ea35e8c71ac7c176 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 24 Apr 2017 09:47:56 +0200 Subject: [PATCH] backup --- js/db/form.js | 70 ++++------------ js/db/iterator-iface.js | 10 --- js/db/iterator.js | 53 ++++++------ js/hedera/gui.js | 2 +- js/htk/repeater.js | 4 +- js/vn/hash.js | 181 ++++++++++++++++++---------------------- js/vn/lot-iface.js | 41 ++++++--- js/vn/lot.js | 69 +++++++++------ js/vn/value.js | 56 ++++++++++--- 9 files changed, 241 insertions(+), 245 deletions(-) diff --git a/js/db/form.js b/js/db/form.js index 55ecbd34..93694232 100644 --- a/js/db/form.js +++ b/js/db/form.js @@ -4,14 +4,10 @@ var Model = require ('./model'); module.exports = new Class ({ - Extends: Vn.Object - ,Implements: Iterator + Extends: Iterator ,Tag: 'db-form' ,Properties: { - /** - * The model associated to this form. - */ model: { type: Model @@ -42,78 +38,42 @@ module.exports = new Class return; this._row = x; + this._rowChanged (); this.changed (); } ,get: function () { return this._row; } - }, - /** - * The number of rows in the form. - */ - numRows: - { - type: Number - ,get: function () - { - return this._model ? - this._model.numRows : 0; - } - }, - /** - * Checks if the form data is ready. - */ - ready: - { - type: Boolean - ,get: function () - { - return this._model ? - this._model.ready : false; - } - }, - /** - * The current row parameters. - */ - params: - { - type: Object - ,set: function (x) - { - this.assign (x); - } - ,get: function () - { - return this.getParams (); - } } } - - ,lastRow: 0 - ,_model: null - ,_row: -1 - ,_ready: false + + ,initialize: function (props) + { + Object.assign (this, { + _lastRow: 0 + ,_lastReady: false + }); + this.parent (props); + } ,onModelChange: function () { var ready = this._model && this._model.ready; - if (ready != this._ready) + if (ready != this._lastReady) { if (this._row != -1) - this.lastRow = this._row; + this._lastRow = this._row; - this._ready = ready; + this._lastReady = ready; this.emit ('status-changed'); if (this._row == -1) - this.row = this.lastRow; + this.row = this._lastRow; if (ready) this.emit ('ready'); - - this.changed (); } } diff --git a/js/db/iterator-iface.js b/js/db/iterator-iface.js index c04e678d..bc0dc0f1 100644 --- a/js/db/iterator-iface.js +++ b/js/db/iterator-iface.js @@ -27,13 +27,6 @@ module.exports = new Class { type: Number }, - /** - * The current row parameters. - */ - params: - { - type: Object - }, /** * Checks if the form data is ready. */ @@ -42,9 +35,6 @@ module.exports = new Class type: Boolean } } - - ,_model: null - ,_row: -1 ,refresh: function () { diff --git a/js/db/iterator.js b/js/db/iterator.js index a9228b3d..ee33cfee 100644 --- a/js/db/iterator.js +++ b/js/db/iterator.js @@ -3,17 +3,15 @@ var IteratorIface = require ('./iterator-iface'); var Model = require ('./model'); /** - * A light iterator for models. + * A light iterator for models. It assumes that its row and model properties + * are always valid. */ module.exports = new Class ({ - Extends: Vn.Object + Extends: Vn.Lot ,Implements: IteratorIface ,Properties: { - /** - * The model associated to this form. - */ model: { type: Model @@ -26,24 +24,19 @@ module.exports = new Class return this._model; } }, - /** - * The row where the form positioned, has -1 if the row is unselected. - */ row: { type: Number ,set: function (x) { this._row = x; + this.updateParams (); } ,get: function () { return this._row; } }, - /** - * The number of rows in the form. - */ numRows: { type: Number @@ -53,9 +46,6 @@ module.exports = new Class this._model.numRows : 0; } }, - /** - * Checks if the form data is ready. - */ ready: { type: Boolean @@ -64,21 +54,26 @@ module.exports = new Class return this._model ? this._model.ready : false; } - }, - /** - * The current row parameters. - */ - params: - { - type: Object - ,set: function (x) - { - this.assign (x); - } - ,get: function () - { - return this.getParams (); - } } } + + ,initialize: function (props) + { + Object.assign (this, { + _model: null + ,_row: -1 + }); + this.parent (props); + } + + ,_paramsChanged: function (diff) + { + for (var key in diff) + this._model.set (this._row, key, diff[key]); + } + + ,updateParams: function () + { + this.params = this._model.getObject (this._row); + } }); diff --git a/js/hedera/gui.js b/js/hedera/gui.js index fb0c423f..4c355e11 100644 --- a/js/hedera/gui.js +++ b/js/hedera/gui.js @@ -7,7 +7,7 @@ require ('./gui.css'); /** * The main screen component. It has a left menu, a navbar with configurable - * action buttons and the body where @Db.Form childs can be displayed. + * action buttons and the body where @Form childs can be displayed. */ module.exports = new Class ({ diff --git a/js/htk/repeater.js b/js/htk/repeater.js index ca86d9c4..52260371 100644 --- a/js/htk/repeater.js +++ b/js/htk/repeater.js @@ -47,8 +47,8 @@ module.exports = new Class } } /** - * {Function (Vn.BuilderResult, Db.Form)} Function to call after every - * box rendering. + * {Function (Vn.BuilderResult, Db.Iterator)} Function to call after + * every box rendering. */ ,renderer: { diff --git a/js/vn/hash.js b/js/vn/hash.js index c1b406b6..4b0053b6 100644 --- a/js/vn/hash.js +++ b/js/vn/hash.js @@ -1,19 +1,18 @@ -var VnObject = require ('./object'); var VnDate = require ('./date'); -var LotIface = require ('./lot-iface'); -var Value = require ('./value'); +var Lot = require ('./lot'); /** - * Class to handle the hash part of the URL as a key-value - * javascript object. It also handles dates and objects as - * a value. + * Class to handle the hash part of the URL as a key-value javascript object. + * It also handles dates and objects as a value. */ module.exports = new Class ({ - Extends: VnObject - ,Implements: LotIface + Extends: Lot ,Properties: { + /** + * The main window object. + */ window: { type: Window @@ -27,120 +26,110 @@ module.exports = new Class { return this._window; } - }, - params: - { - type: Object - ,set: function (x) - { - this.setAll (x); - } - ,get: function () - { - return this._hashMap; - } } } ,initialize: function (props) { - this._hash = null; - this._hashMap = null; - this._window = null; - this._hashChangedHandler = this._hashChanged.bind (this); + Object.assign (this, { + _hash: null + ,_hashLock: false + ,_window: null + ,_hashChangedHandler: this._hashChanged.bind (this) + }); this.parent (props); } - ,get: function (key) + ,_paramsChanged: function () { - return this._hashMap[key]; - } - - ,set: function (key, value) - { - var object = {}; - object[key] = value; - this.assign (object); - } - - ,assign: function (object) - { - var newObject = {}; - - for (var key in this._hashMap) - newObject[key] = this._hashMap[key]; - for (var key in object) - newObject[key] = object[key]; - - this.setAll (newObject); - } - - /** - * Sets the hash part of the URL. - * - * @param {Object} object A key-value object - */ - ,setAll: function (object) - { - if (object) - for (var key in object) - if (object[key] === null || object[key] === undefined) - delete object[key]; - - var newHash = this.make (object); - - if (!object) - object = {}; - - if (!Value.equals (this._hashMap, object)) - { - this._hashMap = object; - this._hash = newHash; - - this._blockChanged = true; - location.hash = newHash; - this._blockChanged = false; - - this.changed (); - } + this._updateHash (); } /** * Creates a URL with the given hash data. * - * @param {Object} object A key-value object + * @param {Object} params A key-value object * @param {boolean} add %true to combine with the current params, %false otherwise * @return {string} The URL */ - ,make: function (object, add) + ,make: function (params, add) + { + if (add) + { + params = Object.assign ({}, params); + + for (var key in this._params) + if (!params[key]) + params[key] = this._params[key]; + } + + return this.renderHash (object); + } + + /** + * Updates the window hash with current params. + */ + ,updateHash: function () + { + if (this._hashLock) + return; + + this._hash = this.renderHash (this._params); + + this._hashLock = true; + location.hash = this._hash; + this._hashLock = false; + } + + /* + * Called when window hash changes. + */ + ,_hashChanged: function () + { + var newHash = location.hash; + + if (this._hashLock || this._hash === newHash) + return; + + this._hash = newHash; + + this._hashLock = true; + this.params = this.parseHash (newHash); + this._hashLock = false; + } + + /** + * Creates a URL with the given hash data. + * + * @param {Object} params The key-value object + * @return {string} The URL + */ + ,renderHash: function (params) { var hash = '#!'; - - if (add && object) - for (var key in this._hashMap) - if (!object[key]) - object[key] = this._hashMap[key]; - for (var key in object) + for (var key in params) + if (params[key] !== undefined) { if (hash.length > 2) hash += '&'; - hash += encodeURIComponent (key) +'='+ this.renderValue (object[key]); + hash += encodeURIComponent (key) +'='+ this.renderValue (params[key]); } return hash; } - ,_hashChanged: function () + /** + * Parses a hash string to a key-value object. + * + * @param {string} hashString The hash string + * @return {Object} The key-value object + */ + ,parseHash: function (hashString) { - var newHash = location.hash; - - if (this._blockChanged || this._hash == newHash) - return; - var newMap = hashMap = {}; - var kvPairs = newHash.substr(2).split ('&'); + var kvPairs = hashString.substr(2).split ('&'); for (var i = 0; i < kvPairs.length; i++) { @@ -149,17 +138,13 @@ module.exports = new Class if (kvPair[0]) newMap[decodeURIComponent (kvPair[0])] = this.parseValue (kvPair[1]); } - - if (!Value.equals (this._hashMap, newMap)) - { - this._hashMap = newMap; - this._hash = newHash; - this.changed (); - } } ,renderValue: function (v) { + if (v == null) + return ''; + switch (typeof v) { case 'number': diff --git a/js/vn/lot-iface.js b/js/vn/lot-iface.js index 161fa413..f28be673 100644 --- a/js/vn/lot-iface.js +++ b/js/vn/lot-iface.js @@ -1,19 +1,26 @@ /** - * Holds a plain key-value javascript object and monitorizes - * changes over it. + * Holds a plain key-value javascript object and monitorizes changes over it. */ module.exports = new Class ({ Properties: { /** - * The internal object with the params. + * The internal object with the params, this is the lot internal object + * and should be used for read-only purposes. */ params: { type: Object } + /** + * Shortcut for params property. + */ + ,$: + { + type: Object + } } /** @@ -22,7 +29,10 @@ module.exports = new Class * @param {string} field The field name * @return {*} The field value */ - ,get: function () {} + ,get: function (field) + { + return this.params[field]; + } /** * Sets a value on the set. @@ -30,7 +40,12 @@ module.exports = new Class * @param {string} field The field name * @param {*} value The new field value */ - ,set: function () {} + ,set: function (field, value) + { + var params = {}; + params[field] = value; + this.assign (param); + } /** * Returns an array with the set keys. @@ -54,13 +69,7 @@ module.exports = new Class * * @param {Object} object The source object */ - ,assign: function (object) - { - for (var key in object) - this.set (key, object[key]); - - this.changed (); - } + ,assign: function () {} /** * Copies all values from another lot. @@ -71,4 +80,12 @@ module.exports = new Class { this.assign (lot.params); } + + /** + * Resets all values. + */ + ,reset: function () + { + this.params = {}; + } }); diff --git a/js/vn/lot.js b/js/vn/lot.js index cec8a694..190d91a4 100644 --- a/js/vn/lot.js +++ b/js/vn/lot.js @@ -1,6 +1,7 @@ var VnObject = require ('./object'); var LotIface = require ('./lot-iface'); +var Value = require ('./value'); module.exports = new Class ({ @@ -14,8 +15,19 @@ module.exports = new Class type: Object ,set: function (x) { - this._params = x; - this.changed (); + this._setAll (x); + } + ,get: function () + { + return this._params; + } + } + ,$: + { + type: Object + ,set: function (x) + { + this._setAll (x); } ,get: function () { @@ -24,32 +36,15 @@ module.exports = new Class } } - ,_attachments: null - ,initialize: function (props) { this._params = {}; this.parent (props); } - ,get: function (paramName) + ,get: function (field) { - return this._params[paramName]; - } - - ,set: function (paramName, value) - { - this._params[paramName] = value; - this.changed (); - } - - /** - * Resets all values. - */ - ,reset: function () - { - this._params = {}; - this.changed (); + return this._params[field]; } ,keys: function () @@ -57,11 +52,35 @@ module.exports = new Class return Object.keys (this._params); } - ,assign: function (object) + ,assign: function (params) { - for (var key in object) - this._params[key] = object[key]; + var diff = Value.partialDiff (this._params, params); - this.changed (); + if (diff) + { + Object.assign (this._params, diff); + this._paramsChanged (diff); + this.changed (diff); + } } + + ,setAll: function (params) + { + var diff = Value.diff (this._params, params); + + if (diff) + { + this._params = Value.kvClone (params); + this._paramsChanged (diff); + this.changed (diff); + } + } + + /** + * Called when lot params changes, can be implemented by child classes to + * be notified about changes. + * + * @param {Object} diff Changed parameters and its new values + */ + ,_paramsChanged: function () {} }); diff --git a/js/vn/value.js b/js/vn/value.js index 1f5cd639..a37a5b2e 100644 --- a/js/vn/value.js +++ b/js/vn/value.js @@ -2,8 +2,8 @@ var VnDate = require ('./date'); /** - * Checks if two values are equal, it also checks objects. Basic - * values are compared using the strict equality operator. + * Checks if two values are equal, it also checks objects. Basic values are + * compared using the strict equality operator. * * @param {*} a Value to compare to * @param {*} b Value to compare with @@ -32,7 +32,7 @@ function equals (a, b) } /** - * Calculates differences of two key-value objects. + * Calculates differences between two key-value objects. * * @param {Object} orgObject Value to compare to * @param {Object} newObject Value to compare with @@ -40,18 +40,13 @@ function equals (a, b) */ function diff (orgObject, newObject) { - var key; var diff = {}; - var keys = Object.keys (orgObject); - - for (var i = keys.length; --i; key = keys[i]) + for (var key in orgObject) if (!simpleEquals (orgObject[key], newObject[key])) diff[key] = simpleClone (newObject[key]); - var keys = Object.keys (newObject); - - for (var i = keys.length; --i; key = keys[i]) + for (var key in newObject) if (orgObject[key] === undefined && newObject[key] !== undefined) diff[key] = simpleClone (newObject[key]); @@ -61,6 +56,39 @@ function diff (orgObject, newObject) return null; } +/** + * Calculates new differences between two key-value objects. + * + * @param {Object} orgObject Value to compare to + * @param {Object} newObject Value to compare with + * @return {Object} The differences or %null if there are no differences + */ +function partialDiff (orgObject, newObject) +{ + var diff = {}; + + for (var key in newObject) + if (!simpleEquals (orgObject[key], newObject[key])) + diff[key] = simpleClone (newObject[key]); + + if (Object.keys (diff).length > 0) + return diff; + + return null; +} + +function kvClone (object) +{ + var key; + var copy = {}; + var keys = Object.keys (object); + + for (var i = keys.length; --i; key = keys[i]) + copy[key] = simpleClone (object[key]); + + return copy; +} + /** * Copies a simple value. * @@ -120,6 +148,8 @@ module.exports = ,equals: equals ,diff: diff + ,partialDiff: partialDiff + ,kvClone: kvClone ,simpleClone: simpleClone ,simpleEquals: simpleEquals ,sprintf: sprintf @@ -133,7 +163,7 @@ module.exports = return false; } - + ,format: function (value, format) { if (value === null || value === undefined) @@ -155,12 +185,12 @@ module.exports = return value; } - + ,replaceNumber: function (value, token, digits) { return new Number (value).toFixed (parseInt (digits)); } - + ,replaceString: function (value) { return value;