marko
Version:
UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.
105 lines (89 loc) • 2.37 kB
JavaScript
"use strict";var extend = require("raptor-util/extend");
function ensure(state, propertyName) {
var proto = state.constructor.prototype;
if (!(propertyName in proto)) {
Object.defineProperty(proto, propertyName, {
get: function () {
return this.A_[propertyName];
},
set: function (value) {
this.aq_(propertyName, value, false /* ensure:false */);
}
});
}
}
function State(component) {
this.s_ = component;
this.A_ = {};
this.ak_ = false;
this.av_ = null;
this.au_ = null;
this.aP_ = null; // An object that we use to keep tracking of state properties that were forced to be dirty
Object.seal(this);
}
State.prototype = {
_s_: function () {
var self = this;
self.ak_ = false;
self.av_ = null;
self.au_ = null;
self.aP_ = null;
},
ao_: function (newState) {
var state = this;
var key;
var rawState = this.A_;
for (key in rawState) {
if (!(key in newState)) {
state.aq_(
key,
undefined,
false /* ensure:false */,
false /* forceDirty:false */
);
}
}
for (key in newState) {
state.aq_(
key,
newState[key],
true /* ensure:true */,
false /* forceDirty:false */
);
}
},
aq_: function (name, value, shouldEnsure, forceDirty) {
var rawState = this.A_;
if (shouldEnsure) {
ensure(this, name);
}
if (forceDirty) {
var forcedDirtyState = this.aP_ || (this.aP_ = {});
forcedDirtyState[name] = true;
} else if (rawState[name] === value) {
return;
}
if (!this.ak_) {
// This is the first time we are modifying the component state
// so introduce some properties to do some tracking of
// changes to the state
this.ak_ = true; // Mark the component state as dirty (i.e. modified)
this.av_ = rawState;
this.A_ = rawState = extend({}, rawState);
this.au_ = {};
this.s_.ap_();
}
this.au_[name] = value;
if (value === undefined) {
// Don't store state properties with an undefined or null value
delete rawState[name];
} else {
// Otherwise, store the new value in the component state
rawState[name] = value;
}
},
toJSON: function () {
return this.A_;
}
};
module.exports = State;