UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

401 lines 19.9 kB
'use strict';var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var lang_1 = require('angular2/src/facade/lang'); var exceptions_1 = require('angular2/src/facade/exceptions'); var collection_1 = require('angular2/src/facade/collection'); var abstract_change_detector_1 = require('./abstract_change_detector'); var change_detection_util_1 = require('./change_detection_util'); var constants_1 = require('./constants'); var proto_record_1 = require('./proto_record'); var DynamicChangeDetector = (function (_super) { __extends(DynamicChangeDetector, _super); function DynamicChangeDetector(id, dispatcher, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices, strategy, _records, _eventBindings, _directiveRecords, _genConfig) { _super.call(this, id, dispatcher, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices, strategy); this._records = _records; this._eventBindings = _eventBindings; this._directiveRecords = _directiveRecords; this._genConfig = _genConfig; this.directives = null; var len = _records.length + 1; this.values = collection_1.ListWrapper.createFixedSize(len); this.localPipes = collection_1.ListWrapper.createFixedSize(len); this.prevContexts = collection_1.ListWrapper.createFixedSize(len); this.changes = collection_1.ListWrapper.createFixedSize(len); this.dehydrateDirectives(false); } DynamicChangeDetector.prototype.handleEventInternal = function (eventName, elIndex, locals) { var _this = this; var preventDefault = false; this._matchingEventBindings(eventName, elIndex) .forEach(function (rec) { var res = _this._processEventBinding(rec, locals); if (res === false) { preventDefault = true; } }); return preventDefault; }; /** @internal */ DynamicChangeDetector.prototype._processEventBinding = function (eb, locals) { var values = collection_1.ListWrapper.createFixedSize(eb.records.length); values[0] = this.values[0]; for (var protoIdx = 0; protoIdx < eb.records.length; ++protoIdx) { var proto = eb.records[protoIdx]; if (proto.isSkipRecord()) { protoIdx += this._computeSkipLength(protoIdx, proto, values); } else { var res = this._calculateCurrValue(proto, values, locals); if (proto.lastInBinding) { this._markPathAsCheckOnce(proto); return res; } else { this._writeSelf(proto, res, values); } } } throw new exceptions_1.BaseException("Cannot be reached"); }; DynamicChangeDetector.prototype._computeSkipLength = function (protoIndex, proto, values) { if (proto.mode === proto_record_1.RecordType.SkipRecords) { return proto.fixedArgs[0] - protoIndex - 1; } if (proto.mode === proto_record_1.RecordType.SkipRecordsIf) { var condition = this._readContext(proto, values); return condition ? proto.fixedArgs[0] - protoIndex - 1 : 0; } if (proto.mode === proto_record_1.RecordType.SkipRecordsIfNot) { var condition = this._readContext(proto, values); return condition ? 0 : proto.fixedArgs[0] - protoIndex - 1; } throw new exceptions_1.BaseException("Cannot be reached"); }; /** @internal */ DynamicChangeDetector.prototype._markPathAsCheckOnce = function (proto) { if (!proto.bindingRecord.isDefaultChangeDetection()) { var dir = proto.bindingRecord.directiveRecord; this._getDetectorFor(dir.directiveIndex).markPathToRootAsCheckOnce(); } }; /** @internal */ DynamicChangeDetector.prototype._matchingEventBindings = function (eventName, elIndex) { return this._eventBindings.filter(function (eb) { return eb.eventName == eventName && eb.elIndex === elIndex; }); }; DynamicChangeDetector.prototype.hydrateDirectives = function (directives) { this.values[0] = this.context; this.directives = directives; if (this.strategy === constants_1.ChangeDetectionStrategy.OnPushObserve) { for (var i = 0; i < this.directiveIndices.length; ++i) { var index = this.directiveIndices[i]; _super.prototype.observeDirective.call(this, directives.getDirectiveFor(index), i); } } }; DynamicChangeDetector.prototype.dehydrateDirectives = function (destroyPipes) { if (destroyPipes) { this._destroyPipes(); } this.values[0] = null; this.directives = null; collection_1.ListWrapper.fill(this.values, change_detection_util_1.ChangeDetectionUtil.uninitialized, 1); collection_1.ListWrapper.fill(this.changes, false); collection_1.ListWrapper.fill(this.localPipes, null); collection_1.ListWrapper.fill(this.prevContexts, change_detection_util_1.ChangeDetectionUtil.uninitialized); }; /** @internal */ DynamicChangeDetector.prototype._destroyPipes = function () { for (var i = 0; i < this.localPipes.length; ++i) { if (lang_1.isPresent(this.localPipes[i])) { change_detection_util_1.ChangeDetectionUtil.callPipeOnDestroy(this.localPipes[i]); } } }; DynamicChangeDetector.prototype.checkNoChanges = function () { this.runDetectChanges(true); }; DynamicChangeDetector.prototype.detectChangesInRecordsInternal = function (throwOnChange) { var protos = this._records; var changes = null; var isChanged = false; for (var protoIdx = 0; protoIdx < protos.length; ++protoIdx) { var proto = protos[protoIdx]; var bindingRecord = proto.bindingRecord; var directiveRecord = bindingRecord.directiveRecord; if (this._firstInBinding(proto)) { this.propertyBindingIndex = proto.propertyBindingIndex; } if (proto.isLifeCycleRecord()) { if (proto.name === "DoCheck" && !throwOnChange) { this._getDirectiveFor(directiveRecord.directiveIndex).doCheck(); } else if (proto.name === "OnInit" && !throwOnChange && this.state == constants_1.ChangeDetectorState.NeverChecked) { this._getDirectiveFor(directiveRecord.directiveIndex).onInit(); } else if (proto.name === "OnChanges" && lang_1.isPresent(changes) && !throwOnChange) { this._getDirectiveFor(directiveRecord.directiveIndex).onChanges(changes); } } else if (proto.isSkipRecord()) { protoIdx += this._computeSkipLength(protoIdx, proto, this.values); } else { var change = this._check(proto, throwOnChange, this.values, this.locals); if (lang_1.isPresent(change)) { this._updateDirectiveOrElement(change, bindingRecord); isChanged = true; changes = this._addChange(bindingRecord, change, changes); } } if (proto.lastInDirective) { changes = null; if (isChanged && !bindingRecord.isDefaultChangeDetection()) { this._getDetectorFor(directiveRecord.directiveIndex).markAsCheckOnce(); } isChanged = false; } } }; /** @internal */ DynamicChangeDetector.prototype._firstInBinding = function (r) { var prev = change_detection_util_1.ChangeDetectionUtil.protoByIndex(this._records, r.selfIndex - 1); return lang_1.isBlank(prev) || prev.bindingRecord !== r.bindingRecord; }; DynamicChangeDetector.prototype.afterContentLifecycleCallbacksInternal = function () { var dirs = this._directiveRecords; for (var i = dirs.length - 1; i >= 0; --i) { var dir = dirs[i]; if (dir.callAfterContentInit && this.state == constants_1.ChangeDetectorState.NeverChecked) { this._getDirectiveFor(dir.directiveIndex).afterContentInit(); } if (dir.callAfterContentChecked) { this._getDirectiveFor(dir.directiveIndex).afterContentChecked(); } } }; DynamicChangeDetector.prototype.afterViewLifecycleCallbacksInternal = function () { var dirs = this._directiveRecords; for (var i = dirs.length - 1; i >= 0; --i) { var dir = dirs[i]; if (dir.callAfterViewInit && this.state == constants_1.ChangeDetectorState.NeverChecked) { this._getDirectiveFor(dir.directiveIndex).afterViewInit(); } if (dir.callAfterViewChecked) { this._getDirectiveFor(dir.directiveIndex).afterViewChecked(); } } }; /** @internal */ DynamicChangeDetector.prototype._updateDirectiveOrElement = function (change, bindingRecord) { if (lang_1.isBlank(bindingRecord.directiveRecord)) { _super.prototype.notifyDispatcher.call(this, change.currentValue); } else { var directiveIndex = bindingRecord.directiveRecord.directiveIndex; bindingRecord.setter(this._getDirectiveFor(directiveIndex), change.currentValue); } if (this._genConfig.logBindingUpdate) { _super.prototype.logBindingUpdate.call(this, change.currentValue); } }; /** @internal */ DynamicChangeDetector.prototype._addChange = function (bindingRecord, change, changes) { if (bindingRecord.callOnChanges()) { return _super.prototype.addChange.call(this, changes, change.previousValue, change.currentValue); } else { return changes; } }; /** @internal */ DynamicChangeDetector.prototype._getDirectiveFor = function (directiveIndex) { return this.directives.getDirectiveFor(directiveIndex); }; /** @internal */ DynamicChangeDetector.prototype._getDetectorFor = function (directiveIndex) { return this.directives.getDetectorFor(directiveIndex); }; /** @internal */ DynamicChangeDetector.prototype._check = function (proto, throwOnChange, values, locals) { if (proto.isPipeRecord()) { return this._pipeCheck(proto, throwOnChange, values); } else { return this._referenceCheck(proto, throwOnChange, values, locals); } }; /** @internal */ DynamicChangeDetector.prototype._referenceCheck = function (proto, throwOnChange, values, locals) { if (this._pureFuncAndArgsDidNotChange(proto)) { this._setChanged(proto, false); return null; } var currValue = this._calculateCurrValue(proto, values, locals); if (this.strategy === constants_1.ChangeDetectionStrategy.OnPushObserve) { _super.prototype.observeValue.call(this, currValue, proto.selfIndex); } if (proto.shouldBeChecked()) { var prevValue = this._readSelf(proto, values); if (change_detection_util_1.ChangeDetectionUtil.looseNotIdentical(prevValue, currValue)) { if (proto.lastInBinding) { var change = change_detection_util_1.ChangeDetectionUtil.simpleChange(prevValue, currValue); if (throwOnChange) this.throwOnChangeError(prevValue, currValue); this._writeSelf(proto, currValue, values); this._setChanged(proto, true); return change; } else { this._writeSelf(proto, currValue, values); this._setChanged(proto, true); return null; } } else { this._setChanged(proto, false); return null; } } else { this._writeSelf(proto, currValue, values); this._setChanged(proto, true); return null; } }; DynamicChangeDetector.prototype._calculateCurrValue = function (proto, values, locals) { switch (proto.mode) { case proto_record_1.RecordType.Self: return this._readContext(proto, values); case proto_record_1.RecordType.Const: return proto.funcOrValue; case proto_record_1.RecordType.PropertyRead: var context = this._readContext(proto, values); return proto.funcOrValue(context); case proto_record_1.RecordType.SafeProperty: var context = this._readContext(proto, values); return lang_1.isBlank(context) ? null : proto.funcOrValue(context); case proto_record_1.RecordType.PropertyWrite: var context = this._readContext(proto, values); var value = this._readArgs(proto, values)[0]; proto.funcOrValue(context, value); return value; case proto_record_1.RecordType.KeyedWrite: var context = this._readContext(proto, values); var key = this._readArgs(proto, values)[0]; var value = this._readArgs(proto, values)[1]; context[key] = value; return value; case proto_record_1.RecordType.Local: return locals.get(proto.name); case proto_record_1.RecordType.InvokeMethod: var context = this._readContext(proto, values); var args = this._readArgs(proto, values); return proto.funcOrValue(context, args); case proto_record_1.RecordType.SafeMethodInvoke: var context = this._readContext(proto, values); if (lang_1.isBlank(context)) { return null; } var args = this._readArgs(proto, values); return proto.funcOrValue(context, args); case proto_record_1.RecordType.KeyedRead: var arg = this._readArgs(proto, values)[0]; return this._readContext(proto, values)[arg]; case proto_record_1.RecordType.Chain: var args = this._readArgs(proto, values); return args[args.length - 1]; case proto_record_1.RecordType.InvokeClosure: return lang_1.FunctionWrapper.apply(this._readContext(proto, values), this._readArgs(proto, values)); case proto_record_1.RecordType.Interpolate: case proto_record_1.RecordType.PrimitiveOp: case proto_record_1.RecordType.CollectionLiteral: return lang_1.FunctionWrapper.apply(proto.funcOrValue, this._readArgs(proto, values)); default: throw new exceptions_1.BaseException("Unknown operation " + proto.mode); } }; DynamicChangeDetector.prototype._pipeCheck = function (proto, throwOnChange, values) { var context = this._readContext(proto, values); var selectedPipe = this._pipeFor(proto, context); if (!selectedPipe.pure || this._argsOrContextChanged(proto)) { var args = this._readArgs(proto, values); var currValue = selectedPipe.pipe.transform(context, args); if (proto.shouldBeChecked()) { var prevValue = this._readSelf(proto, values); if (change_detection_util_1.ChangeDetectionUtil.looseNotIdentical(prevValue, currValue)) { currValue = change_detection_util_1.ChangeDetectionUtil.unwrapValue(currValue); if (proto.lastInBinding) { var change = change_detection_util_1.ChangeDetectionUtil.simpleChange(prevValue, currValue); if (throwOnChange) this.throwOnChangeError(prevValue, currValue); this._writeSelf(proto, currValue, values); this._setChanged(proto, true); return change; } else { this._writeSelf(proto, currValue, values); this._setChanged(proto, true); return null; } } else { this._setChanged(proto, false); return null; } } else { this._writeSelf(proto, currValue, values); this._setChanged(proto, true); return null; } } }; DynamicChangeDetector.prototype._pipeFor = function (proto, context) { var storedPipe = this._readPipe(proto); if (lang_1.isPresent(storedPipe)) return storedPipe; var pipe = this.pipes.get(proto.name); this._writePipe(proto, pipe); return pipe; }; DynamicChangeDetector.prototype._readContext = function (proto, values) { if (proto.contextIndex == -1) { return this._getDirectiveFor(proto.directiveIndex); } return values[proto.contextIndex]; }; DynamicChangeDetector.prototype._readSelf = function (proto, values) { return values[proto.selfIndex]; }; DynamicChangeDetector.prototype._writeSelf = function (proto, value, values) { values[proto.selfIndex] = value; }; DynamicChangeDetector.prototype._readPipe = function (proto) { return this.localPipes[proto.selfIndex]; }; DynamicChangeDetector.prototype._writePipe = function (proto, value) { this.localPipes[proto.selfIndex] = value; }; DynamicChangeDetector.prototype._setChanged = function (proto, value) { if (proto.argumentToPureFunction) this.changes[proto.selfIndex] = value; }; DynamicChangeDetector.prototype._pureFuncAndArgsDidNotChange = function (proto) { return proto.isPureFunction() && !this._argsChanged(proto); }; DynamicChangeDetector.prototype._argsChanged = function (proto) { var args = proto.args; for (var i = 0; i < args.length; ++i) { if (this.changes[args[i]]) { return true; } } return false; }; DynamicChangeDetector.prototype._argsOrContextChanged = function (proto) { return this._argsChanged(proto) || this.changes[proto.contextIndex]; }; DynamicChangeDetector.prototype._readArgs = function (proto, values) { var res = collection_1.ListWrapper.createFixedSize(proto.args.length); var args = proto.args; for (var i = 0; i < args.length; ++i) { res[i] = values[args[i]]; } return res; }; return DynamicChangeDetector; })(abstract_change_detector_1.AbstractChangeDetector); exports.DynamicChangeDetector = DynamicChangeDetector; //# sourceMappingURL=dynamic_change_detector.js.map