UNPKG

ajsfw

Version:
1,035 lines 50.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var logger = require("ajsfw/dbg/logger"); var utils = require("ajsfw/utils"); var exceptions = require("./exceptions"); var ViewComponent = (function () { function ViewComponent(navigator, router, documentManager, templateManager, viewManager, viewComponentManager, id, componentViewId, parentComponent, visualComponent, state, parentComponentInitStateNotify) { if (visualComponent === null) { throw new exceptions.VisualComponentNotRegisteredException(null); } logger.log(logger.LogType.Constructor, 0, "ajs.mvvm.viewmodel", this); this._componentViewId = componentViewId; this.ajs = { stylesheetsApplied: false, initialized: false, id: id, navigator: navigator, router: router, documentManager: documentManager, templateManager: templateManager, viewComponentManager: viewComponentManager, viewManager: viewManager, parentComponent: parentComponent, visualComponent: visualComponent, templateElement: visualComponent.component, stateToApply: state, parentComponentInitStateNotify: parentComponentInitStateNotify, key: null, stateChanged: false, stateKeys: [], stateChangePrevented: false, stateQueue: [], processingStateQueue: false, hasVisualStateTransition: false, visualStateTransitionRunning: false, visualStateTransitionBeginHandler: null, transitionNewElement: null, transitionOldElement: null, attributeProcessors: { __default: this.__attrDefault, component: this.__attrComponent, if: this.__attrIf, onclick: this.__attrEventHandler, onmousedown: this.__attrEventHandler, onmouseup: this.__attrEventHandler, onkeydown: this.__attrEventHandler, onkeyup: this.__attrEventHandler, onkeypress: this.__attrEventHandler, onchange: this.__attrEventHandler, oninput: this.__attrEventHandler, ontouchmove_ajs: this.__attrEventHandler, onanimationend: this.__attrEventHandler, onstatetransitionbegin: this.__attrTransitionBeginHanler } }; logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); } Object.defineProperty(ViewComponent.prototype, "componentViewId", { get: function () { return this._componentViewId; }, enumerable: true, configurable: true }); ; ViewComponent.prototype.configure = function () { var services = []; for (var _i = 0; _i < arguments.length; _i++) { services[_i] = arguments[_i]; } return this._onConfigure.apply(this, services); }; ViewComponent.prototype.initialize = function () { return __awaiter(this, void 0, void 0, function () { var newState; return __generator(this, function (_a) { switch (_a.label) { case 0: logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); if (!(this.ajs.stateToApply && this.ajs.stateToApply !== null)) return [3, 2]; newState = utils.DeepMerge.merge(this._onDefaultState(), this.ajs.stateToApply); utils.Obj.assign(this.ajs.stateToApply, newState); return [4, this.__applyState({ component: this, stateChangeRoot: this.ajs.parentComponentInitStateNotify, state: this.ajs.stateToApply })]; case 1: _a.sent(); return [3, 4]; case 2: return [4, this.__applyState({ component: this, stateChangeRoot: this.ajs.parentComponentInitStateNotify || null, state: this._onDefaultState() })]; case 3: _a.sent(); _a.label = 4; case 4: this.ajs.parentComponentInitStateNotify = undefined; this.ajs.stateToApply = undefined; logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2, this.__initialize()]; } }); }); }; ViewComponent.prototype.destroy = function () { return this.__destroy(); }; ; ViewComponent.prototype.setState = function (state, stateChangeRootComponent) { if (stateChangeRootComponent === void 0) { stateChangeRootComponent = null; } return this.__setState(state, stateChangeRootComponent); }; ViewComponent.prototype.clearState = function (render) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); this.__clearState(render); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); }; ViewComponent.prototype.render = function (parentElement, clearStateChangeOnly, attributes) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); var element = this.__render(parentElement, clearStateChangeOnly, attributes); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return element; }; ViewComponent.prototype.ajsVisualStateTransitionBegin = function (newElement) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); this._ajsVisualStateTransitionBegin(newElement); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); }; ViewComponent.prototype.insertChildComponent = function (viewComponentName, id, state, placeholder, index) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); this.__insertChildComponent(viewComponentName, id, state, placeholder, index); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); }; ViewComponent.prototype.removeChildComponent = function (placeholder, id) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); this.__removeChildComponent(placeholder, id); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); }; Object.defineProperty(ViewComponent.prototype, "preventStateChange", { set: function (value) { this._setPreventStateChange(value); }, enumerable: true, configurable: true }); ViewComponent.prototype._onDefaultState = function () { return {}; }; ViewComponent.prototype._onConfigure = function () { var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } return Promise.resolve(); }; ViewComponent.prototype._onInitialize = function () { return Promise.resolve(); }; ViewComponent.prototype._onFinalize = function () { return; }; ViewComponent.prototype._filterState = function (state) { return state; }; ViewComponent.prototype._filterStateKey = function (key, value) { return { filterApplied: false, key: null, state: null }; }; ViewComponent.prototype._filterStateArrayItem = function (key, index, length, state) { return { filterApplied: false, key: null, state: null }; }; ViewComponent.prototype._setPreventStateChange = function (value) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); logger.log(logger.LogType.Info, 0, "ajs.mvvm.viewmodel", this, "Setting prevent state change to " + value + " (" + utils.getClassName(this) + ", id: " + this.ajs.id, ", viewId: " + this.componentViewId + ")"); this.ajs.stateChangePrevented = value; var children = this.ajs.viewComponentManager.getChildrenComponentInstances(this); for (var i = 0; i < children.length; i++) { children[i].preventStateChange = value; } if (!value) { this.__processStateQueue(); } logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); }; ViewComponent.prototype._ajsVisualStateTransitionBegin = function (newElement) { return __awaiter(this, void 0, void 0, function () { var transitionType; return __generator(this, function (_a) { switch (_a.label) { case 0: logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); if (this.ajs.visualStateTransitionRunning) { this._ajsVisualStateTransitionCancel(); } this.ajs.visualStateTransitionRunning = true; this.ajs.transitionNewElement = newElement; if (!(typeof this.ajs.visualStateTransitionBeginHandler === "function")) return [3, 2]; return [4, this.ajs.visualStateTransitionBeginHandler.call(this)]; case 1: transitionType = _a.sent(); if (transitionType !== null) { this.__ajsVisualStateTransitionStart(transitionType); } else { this._ajsVisualStateTransitionEnd(); } return [3, 3]; case 2: this._ajsVisualStateTransitionEnd(); _a.label = 3; case 3: logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } }); }); }; ViewComponent.prototype._ajsVisualStateTransitionCancel = function () { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); if (this.ajs.transitionNewElement) { this._ajsVisualStateTransitionEnd(); } logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); }; ViewComponent.prototype._ajsVisualStateTransitionEnd = function () { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); if (this.ajs.visualStateTransitionRunning && this.ajs.transitionOldElement instanceof HTMLElement && this.__childElementExists(this.ajs.transitionOldElement.parentElement, this.ajs.transitionOldElement)) { this.ajs.transitionOldElement.removeAttribute("statetransitiontypeold"); this.ajs.transitionNewElement.removeAttribute("statetransitiontypenew"); } this.ajs.documentManager.removeNode(this.ajs.transitionOldElement); this.ajs.transitionOldElement = null; this.ajs.transitionNewElement = null; this.ajs.visualStateTransitionRunning = false; logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); }; ViewComponent.prototype.__initialize = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); return [4, this.__applyTemplateStylesheets()]; case 1: _a.sent(); return [4, this._onInitialize()]; case 2: _a.sent(); this.ajs.stateChanged = true; logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } }); }); }; ViewComponent.prototype.__destroy = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); this.clearState(false); return [4, this._onFinalize()]; case 1: _a.sent(); this.ajs.documentManager.removeNodeByUniqueId(this.componentViewId); this.ajs.viewComponentManager.removeComponentInstance(this); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } }); }); }; ViewComponent.prototype.__applyTemplateStylesheets = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); return [4, this.ajs.documentManager.applyStyleSheetsFromTemplate(this.ajs.visualComponent.template)]; case 1: _a.sent(); this.ajs.stylesheetsApplied = true; logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } }); }); }; ViewComponent.prototype.__setState = function (state, stateChangeRootComponent) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); logger.log(logger.LogType.Info, 0, "ajs.mvvm.viewmodel", this, "Setting component state: " + utils.getClassName(this) + ", id: " + this.ajs.id, ", viewId: " + this.componentViewId, state); if (this.ajs.visualStateTransitionRunning) { this._ajsVisualStateTransitionCancel(); } this.ajs.stateQueue.push({ component: this, stateChangeRoot: stateChangeRootComponent, state: state }); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2, this.__processStateQueue()]; }); }); }; ViewComponent.prototype.__processStateQueue = function () { return __awaiter(this, void 0, void 0, function () { var stateInfo, node; return __generator(this, function (_a) { switch (_a.label) { case 0: logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); if (this.ajs.stateQueue.length === 0) { logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } if (this.ajs.processingStateQueue) { logger.log(logger.LogType.Warning, 0, "ajs.mvvm.viewmodel", this, "Processing state already running!"); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } if (this.ajs.stateChangePrevented) { logger.log(logger.LogType.Warning, 0, "ajs.mvvm.viewmodel", this, "State change is prevented: " + utils.getClassName(this) + ", id: " + this.ajs.id, ", viewId: " + this.componentViewId); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } this.ajs.processingStateQueue = true; logger.log(logger.LogType.Info, 0, "ajs.mvvm.viewmodel", this, "Processing state queue: " + utils.getClassName(this) + ", id: " + this.ajs.id, ", viewId: " + this.componentViewId + ", " + this.ajs.stateQueue.length + " state changes queued"); _a.label = 1; case 1: if (!(this.ajs.stateQueue.length > 0)) return [3, 3]; if (this.ajs.stateChangePrevented) { logger.log(logger.LogType.Warning, 0, "ajs.mvvm.viewmodel", this, "State change is prevented: " + utils.getClassName(this) + ", id: " + this.ajs.id, ", viewId: " + this.componentViewId); logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } stateInfo = this.ajs.stateQueue.shift(); logger.log(logger.LogType.Info, 0, "ajs.mvvm.viewmodel", this, "Setting component state: " + utils.getClassName(this) + ", id: " + this.ajs.id, ", viewId: " + this.componentViewId + ", " + this.ajs.stateQueue.length + " state changes queued", stateInfo.state); if (this.ajs.hasVisualStateTransition) { node = this.ajs.documentManager.getTargetNodeByUniqueId(this.componentViewId); this.ajs.transitionOldElement = node.cloneNode(true); } this.ajs.viewManager.stateChangeBegin(stateInfo); return [4, this.__applyState(stateInfo)]; case 2: _a.sent(); this.ajs.viewManager.stateChangeEnd(stateInfo); return [3, 1]; case 3: this.ajs.processingStateQueue = false; logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } }); }); }; ViewComponent.prototype.__clearState = function (render) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); var schi = { component: this, stateChangeRoot: null, state: null }; if (render) { this.ajs.viewManager.stateChangeBegin(schi); } while (this.ajs.stateKeys.length > 0) { if (this[this.ajs.stateKeys[0]] instanceof ViewComponent) { this[this.ajs.stateKeys[0]].destroy(); } if (this[this.ajs.stateKeys[0]] instanceof Array) { for (var i = 0; i < this[this.ajs.stateKeys[0]].length; i++) { if (this[this.ajs.stateKeys[0]][i] instanceof ViewComponent) { this[this.ajs.stateKeys[0]][i].destroy(); } } } delete (this[this.ajs.stateKeys[0]]); this.ajs.stateKeys.splice(0, 1); } if (render) { this.ajs.stateChanged = true; this.ajs.viewManager.stateChangeEnd(schi); } logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); }; ViewComponent.prototype.__applyState = function (stateChangeInfo) { return __awaiter(this, void 0, void 0, function () { var state, _a, _b, _i, key, filteredKey, filteredState; return __generator(this, function (_c) { switch (_c.label) { case 0: logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); state = stateChangeInfo.state; if (state === undefined || state === null) { return [2]; } state = this._filterState(state); if (state === undefined || state === null) { return [2]; } _a = []; for (_b in state) _a.push(_b); _i = 0; _c.label = 1; case 1: if (!(_i < _a.length)) return [3, 6]; key = _a[_i]; if (!state.hasOwnProperty(key)) { return [3, 5]; } filteredKey = key; filteredState = this._filterStateKey(filteredKey, state[filteredKey]); if (filteredState.filterApplied) { if (filteredState.key !== key) { filteredKey = filteredState.key; delete state[key]; } state[filteredKey] = filteredState.state; } if (!this.hasOwnProperty(filteredKey)) return [3, 3]; return [4, this.__updateExistingStateKey(filteredKey, { component: stateChangeInfo.component, stateChangeRoot: stateChangeInfo.stateChangeRoot, state: state })]; case 2: _c.sent(); return [3, 5]; case 3: return [4, this.__createNewStateKey(filteredKey, { component: stateChangeInfo.component, stateChangeRoot: stateChangeInfo.stateChangeRoot, state: state })]; case 4: _c.sent(); _c.label = 5; case 5: _i++; return [3, 1]; case 6: logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return [2]; } }); }); }; ViewComponent.prototype.__createNewStateKey = function (key, stateChangeInfo) { return __awaiter(this, void 0, void 0, function () { var state, _a, _b, filteredStates, i, filteredState, filteredState, i, j, c; return __generator(this, function (_c) { switch (_c.label) { case 0: state = stateChangeInfo.state; if (!this.ajs.visualComponent.children.hasOwnProperty(key)) return [3, 5]; if (!(state[key] instanceof Array)) return [3, 2]; return [4, this.__createComponentsArray(key, stateChangeInfo)]; case 1: _c.sent(); return [3, 4]; case 2: _a = this; _b = key; return [4, this.__createViewComponent(key, this.ajs.visualComponent.children[key], state[key])]; case 3: _a[_b] = _c.sent(); this.ajs.stateKeys.push(key); _c.label = 4; case 4: return [2]; case 5: filteredStates = []; if (state[key] instanceof Array) { for (i = 0; i < state[key].length; i++) { filteredState = this._filterStateArrayItem(key, i, state[key].length, state[key][i]); if (filteredState.filterApplied) { if (filteredState.key !== key) { filteredStates.push(filteredState); } } } } if (!(filteredStates.length > 0)) return [3, 7]; filteredState = {}; for (i = 0; i < filteredStates.length; i++) { if (filteredState[filteredStates[i].key] === undefined) { filteredState[filteredStates[i].key] = []; } if (filteredStates[i].state instanceof Array) { for (j = 0; j < filteredStates[i].state.length; j++) { filteredState[filteredStates[i].key].push(filteredStates[i].state[j]); } } else { filteredState[filteredStates[i].key].push(filteredStates[i].state); } } return [4, this.__applyState(filteredState)]; case 6: _c.sent(); return [2]; case 7: this[key] = state[key]; this.ajs.stateKeys.push(key); this.ajs.stateChanged = true; if (stateChangeInfo.stateChangeRoot !== null) { c = this; while (c !== stateChangeInfo.stateChangeRoot) { c = c.ajs.parentComponent; c.ajs.stateChanged = true; } } return [2]; } }); }); }; ViewComponent.prototype.__createComponentsArray = function (key, stateChangeInfo) { return __awaiter(this, void 0, void 0, function () { var state, i, filteredState, newViewComponent, j, newViewComponent; return __generator(this, function (_a) { switch (_a.label) { case 0: state = stateChangeInfo.state; this.ajs.stateKeys.push(key); this[key] = []; i = 0; _a.label = 1; case 1: if (!(i < state[key].length)) return [3, 7]; filteredState = this._filterStateArrayItem(key, i, state[key].length, state[key][i]); if (!(!filteredState.filterApplied || !(filteredState.state instanceof Array))) return [3, 3]; newViewComponent = void 0; return [4, this.__createViewComponent(key, this.ajs.visualComponent.children[key], filteredState.filterApplied && filteredState.key === key ? filteredState.state : state[key][i])]; case 2: newViewComponent = _a.sent(); this[key][i] = newViewComponent; return [3, 6]; case 3: j = 0; _a.label = 4; case 4: if (!(j < filteredState.state.length)) return [3, 6]; newViewComponent = void 0; return [4, this.__createViewComponent(key, this.ajs.visualComponent.children[key], filteredState.state[j])]; case 5: newViewComponent = _a.sent(); if (j === 0) { this[key][i] = newViewComponent; return [3, 4]; } if (i < state[key].length - 1) { this[key].splice(i + 1, 0, newViewComponent); } else { this[key].push(newViewComponent); } i++; j++; return [3, 4]; case 6: i++; return [3, 1]; case 7: return [2]; } }); }); }; ViewComponent.prototype.__updateExistingStateKey = function (key, stateChangeInfo) { return __awaiter(this, void 0, void 0, function () { var state, c; return __generator(this, function (_a) { switch (_a.label) { case 0: state = stateChangeInfo.state; if (!(this[key] instanceof ViewComponent)) return [3, 2]; return [4, this[key].setState(state[key], stateChangeInfo.stateChangeRoot !== null ? stateChangeInfo.stateChangeRoot : this)]; case 1: _a.sent(); return [2]; case 2: if (!(state[key] instanceof Array && this.ajs.visualComponent.children.hasOwnProperty(key) && this[key] instanceof Array)) return [3, 4]; return [4, this.__updateArrayState(key, stateChangeInfo)]; case 3: _a.sent(); return [2]; case 4: if (this.ajs.stateKeys.indexOf(key) === -1) { this.ajs.stateKeys.push(key); } if (this[key] !== state[key]) { this[key] = state[key]; this.ajs.stateChanged = true; if (stateChangeInfo.stateChangeRoot !== null) { c = this; while (c !== stateChangeInfo.stateChangeRoot) { c = c.ajs.parentComponent; c.ajs.stateChanged = true; } } } return [2]; } }); }); }; ViewComponent.prototype.__updateArrayState = function (key, stateChangeInfo) { return __awaiter(this, void 0, void 0, function () { var state, i, del, j, c, newViewComponent; return __generator(this, function (_a) { switch (_a.label) { case 0: state = stateChangeInfo.state; i = 0; while (i < this[key].length) { del = true; for (j = 0; j < state[key].length; j++) { if (this[key][i].key === state[key][j].key) { del = false; break; } } if (!del) { i++; continue; } this[key][i].destroy(); if (stateChangeInfo.stateChangeRoot !== null) { c = this; while (c !== stateChangeInfo.stateChangeRoot) { c = c.ajs.parentComponent; c.ajs.stateChanged = true; } } this[key].splice(i, 1); if (this[key].length === 0) { this.ajs.stateKeys.splice(this.ajs.stateKeys.indexOf(key), 1); } } if (this.ajs.stateKeys.indexOf(key) === -1) { this.ajs.stateKeys.push(key); } i = 0; _a.label = 1; case 1: if (!(i < state[key].length)) return [3, 6]; if (!(this[key].length > i && this[key][i].key === state[key][i].key)) return [3, 3]; return [4, this[key][i].setState(state[key][i], stateChangeInfo.stateChangeRoot !== null ? stateChangeInfo.stateChangeRoot : this)]; case 2: _a.sent(); return [3, 5]; case 3: return [4, this.__createViewComponent(key, this.ajs.visualComponent.children[key], state[key][i])]; case 4: newViewComponent = _a.sent(); this[key].splice(i, 0, newViewComponent); _a.label = 5; case 5: i++; return [3, 1]; case 6: return [2]; } }); }); }; ViewComponent.prototype.__createViewComponent = function (id, viewComponentInfo, state) { var name = viewComponentInfo.tagName; if (name === "COMPONENT" && viewComponentInfo.nameAttribute) { name = viewComponentInfo.nameAttribute; } return this.ajs.viewComponentManager.createViewComponent(name, id, this, state, this); }; ViewComponent.prototype.__render = function (parentElement, clearStateChangeOnly, attributes) { logger.log(logger.LogType.Enter, 0, "ajs.mvvm.viewmodel", this); var node; node = this.__renderTree(this.ajs.visualComponent.component, parentElement, clearStateChangeOnly, attributes); this.ajs.stateChanged = false; if (clearStateChangeOnly) { logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return null; } if (!(node instanceof HTMLElement)) { logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return null; } var componentNode = node; componentNode.ajsData = componentNode.ajsData || {}; componentNode.ajsData.component = this; componentNode.ajsData.ownerComponent = this; logger.log(logger.LogType.Exit, 0, "ajs.mvvm.viewmodel", this); return node; }; ViewComponent.prototype.__renderTree = function (sourceNode, targetNode, clearStateChangeOnly, attributes) { var id = null; if (sourceNode.nodeType === Node.ELEMENT_NODE) { id = sourceNode.getAttribute("id"); } if (id !== null && this[id] !== undefined && (this[id] instanceof ViewComponent || this[id] instanceof Array)) { if (this[id] instanceof ViewComponent) { this[id].render(targetNode, clearStateChangeOnly, sourceNode.attributes); } else { if (this[id] instanceof Array) { for (var i = 0; i < this[id].length; i++) { if (this[id][i] instanceof ViewComponent) { this[id][i].render(targetNode, clearStateChangeOnly, sourceNode.attributes); } } } } } else { var addedNode = void 0; if (clearStateChangeOnly) { addedNode = null; } else { addedNode = this.__renderNode(sourceNode, targetNode, attributes); } var skip = sourceNode === this.ajs.visualComponent.component && !this.ajs.stateChanged; if (addedNode !== null && skip) { addedNode.ajsData = addedNode.ajsData || {}; addedNode.ajsData.skipUpdate = true; } if (addedNode !== null && !skip) { for (var i = 0; i < sourceNode.childNodes.length; i++) { this.__renderTree(sourceNode.childNodes.item(i), addedNode, false); } } else { for (var i = 0; i < sourceNode.childNodes.length; i++) { this.__renderTree(sourceNode.childNodes.item(i), null, true); } } return addedNode; } }; ViewComponent.prototype.__renderNode = function (sourceNode, targetNode, attributes) { var clonedNode = sourceNode.cloneNode(false); var adoptedNode = targetNode.ownerDocument.adoptNode(clonedNode); if (attributes) { this.__mergeAttributes(adoptedNode, attributes); } var processedNode = this.__processNode(adoptedNode); if (processedNode && processedNode !== null) { if (processedNode instanceof HTMLElement) { processedNode.ajsData = processedNode.ajsData || {}; processedNode.ajsData.ownerComponent = this; } targetNode.appendChild(processedNode); } return processedNode; }; ViewComponent.prototype.__mergeAttributes = function (targetNode, attributes) { if (!(targetNode instanceof Element)) { return; } for (var i = 0; i < attributes.length; i++) { switch (attributes[i].nodeName.toLowerCase()) { case "class": if (targetNode.hasAttribute("class")) { if (targetNode.getAttribute("class").indexOf(attributes[i].nodeValue) === -1) { targetNode.setAttribute(attributes[i].nodeName, targetNode.getAttribute("class") + " " + attributes[i].nodeValue); } } else { targetNode.setAttribute(attributes[i].nodeName, attributes[i].nodeValue); } break; case "id": break; default: targetNode.setAttribute(attributes[i].nodeName, attributes[i].nodeValue); break; } } }; ViewComponent.prototype.__processNode = function (node) { switch (node.nodeType) { case Node.ELEMENT_NODE: return this.__processElement(node); case Node.TEXT_NODE: return this.__processText(node); default: return null; } }; ViewComponent.prototype.__processText = function (node) { var props = node.nodeValue.match(/{(.*?)}/g); if (props !== null) { for (var i = 0; i < props.length; i++) { var propName = props[i].substring(1, props[i].length - 1); if (this[propName] !== undefined && this[propName] !== null) { node.nodeValue = node.nodeValue.replace(props[i], this[propName]); } else { node.nodeValue = node.nodeValue.replace(props[i], ""); } } } if (node.nodeValue.substr(0, 8) === "#ASHTML:") { var asHtml = document.createElement("ashtml"); asHtml.innerHTML = node.nodeValue.substr(8); node = asHtml; var ahrefs = asHtml.getElementsByTagName("a"); for (var i = 0; i < ahrefs.length; i++) { this.__processElement(ahrefs.item(i)); } } return node; }; ViewComponent.prototype.__linkMouseDown = function (e) { e.returnValue = this.ajs.navigator.linkClicked(e); if (!e.returnValue) { e.cancelBubble = true; e.preventDefault(); e.stopPropagation(); } }; ViewComponent.prototype.__processElement = function (element) { var _this = this; element = this.__processAttributes(element); if (element instanceof HTMLAnchorElement) { if (element.hasAttribute("href")) { var href = element.getAttribute("href"); if (href.substr(0, 4) !== "http") { var domEventListenerInfo = { source: this.ajs.templateElement, eventType: "mousedown", eventListener: function (e) { _this.__linkMouseDown(e); } }; var node = element; node.ajsData = node.ajsData || {}; if (!(node.ajsData.eventListeners instanceof Array)) { node.ajsData.eventListeners = []; } node.ajsData.eventListeners.push(domEventListenerInfo); domEventListenerInfo = { source: this.ajs.templateElement, eventType: "click", eventListener: function (e) { e.returnValue = false; e.cancelBubble = true; e.preventDefault(); e.stopPropagation(); } }; node.ajsData.eventListeners.push(domEventListenerInfo); } } } return element; }; ViewComponent.prototype.__processAttributes = function (element) { var toRemove = []; for (var i = 0; i < element.attributes.length; i++) { if (this.ajs.attributeProcessors[element.attributes[i].nodeName] !== undefined) { if (!this.ajs.attributeProcessors[element.attributes[i].nodeName].call(this, toRemove, element.attributes[i])) { return null; } } else { if (!this.ajs.attributeProcessors.__default.call(this, toRemove, element.attributes[i])) { return null; } } } for (var i = 0; i < toRemove.length; i++) { element.removeAttribute(toRemove[i]); if (element.hasOwnProperty(toRemove[i])) { element[toRemove[i]] = null; } } return element; }; ViewComponent.prototype.__attrComponent = function (toRemove, attr) { toRemove.push(attr.nodeName); return true; }; ViewComponent.prototype.__attrIf = function (toRemove, attr) { var condition = attr.nodeValue; try { if (!eval(condition)) { return false; } } catch (e) { throw new exceptions.InvalidAttributeIfValueException(e); } toRemove.push(attr.nodeName); return true; }; ViewComponent.prototype.__attrDefault = function (toRemove, attr) { var props = attr.nodeValue.match(/{(.*?)}/); if (props !== null) { var propName = props[1]; if (this[propName] !== undefined && this[propName] !== null) { attr.nodeValue = attr.nodeValue.replace(props[0], this[propName]); } else { toRemove.push(attr.nodeName); } } return true; }; ViewComponent.prototype.__attrEventHandler = function (toRemove, attr) { var _this = this; toRemove.push(attr.nodeName); if ((this[attr.nodeValue] !== undefined && typeof this[attr.nodeValue] === "function") || (this["_" + attr.nodeValue] !== undefined && typeof this["_" + attr.nodeValue] === "function") || (this["__" + attr.nodeValue] !== undefined && typeof this["__" + attr.nodeValue] === "function")) { var eventType = attr.nodeName.substring(2); if (eventType.indexOf("_ajs") !== -1) { eventType = eventType.substr(0, eventType.indexOf("_ajs")); } var eventHandlerName_1 = attr.nodeValue; if (!(this[attr.nodeValue] !== undefined && typeof this[attr.nodeValue] === "function")) { if ((this["_" + attr.nodeValue] !== undefined && typeof this["_" + attr.nodeValue] === "function")) { eventHandlerName_1 = "_" + eventHandlerName_1; } else { eventHandlerName_1 = "__" + eventHandlerName_1; } } var listener = function (e) { _this[eventHandlerName_1](e); }; var domEventListenerInfo = { source: this.ajs.templateElement, eventType: eventType, eventListener: listener }; var node = attr.ownerElement; node.ajsData = node.ajsData || {}; if (!(node.ajsData.eventListeners instanceof Array)) { node.ajsData.eventListeners = []; } node.ajsData.eventListeners.push(domEventListenerInfo); } return true; }; ViewComponent.prototype.__attrTransitionBeginHanler = function (toRemove, attr) { if (this[attr.nodeValue] !== undefined && typeof this[attr.nodeValue] === "function") { this.ajs.hasVisualStateTransition = true; this.ajs.visualStateTransitionBeginHandler = this[attr.nodeValue]; } toRemove.push(attr.nodeName); return true; }; ViewComponent.prototype.__insertChildComponent = function (viewComponentName, id, state, placeholder, index) { if (state === null) { state = {}; } var visualComponent; visualComponent = this.ajs.templateManager.getVisualComponent(viewComponentName); if (visualComponent === null) { throw new exceptions.VisualComponentNotRegisteredException(viewComponentName); } this.__visualComponentInsertChild(placeholder, viewComponentName, id, index); var thisState = {}; thisState[id] = state; this.setState(thisState, this); }; ViewComponent.prototype.__removeChildComponent = function (placeholder, id) { if (this.hasOwnProperty(id) && this[id] instanceof ViewComponent) { this.__visualComponentRemoveChild(placeholder, id); this[id]._destroy(); delete this[id]; var i = this.ajs.stateKeys.indexOf(id); if (i !== -1) { this.ajs.stateKeys.splice(i, 1); } } }; ViewComponent.prototype.__visualComponentInsertChild = function (placeholder, componentName, id, index) { if (this.ajs.visualComponent.placeholders.hasOwnProperty(placeholder)) { var ph = this.ajs.visualComponent.placeholders[placeholder].placeholder; var vc = ph.ownerDocument.createElement(componentName); vc.setAttribute("id", id); if (index !== undefined) { } else { ph.appendChild(vc); } this.ajs.visualComponent.children[id] = { tagName: componentName, nameAttribute: null }; } }; ViewComponent.prototype.__visualComponentRemoveChild = function (placeholder, id) { if (this.ajs.visualComponent.placeholders.hasOwnProperty(placeholder)) { var ph = this.ajs.visualComponent.placeholders[placeholder].placeholder; var vc = null; for (var i = 0; i < ph.childElementCount; i++) { if (ph.children.item(i).hasAttribute("id") && ph.children.item(i).getAttribute("id") === id) { vc = ph.children.item(i); break; } } if (vc !== null) { ph.removeChild(vc); delete this.ajs.visualComponent.children[id]; } } }; ViewComponent.prototype.__ajsVisualStateTransitionStart = function (transitionType) { if (this.ajs.transitionOldElement instanceof HTMLElement && this.ajs.transitionNewElement instanceof HTMLElement) { this.ajs.transitionNewElement.parentElement.insertBefore(this.ajs.transitionOldElement, this.ajs.transitionNewElement); this.ajs.transitionOldElement.setAttribute("statetransitiontypeold", transitionType.oldComponent); this.ajs.transitionNewElement.setAttribute("statetransitiontypenew", transitionType.newComponent); } }; ViewComponent.prototype.__childElementExists = function (