| Index: src/object-observe.js
|
| diff --git a/src/object-observe.js b/src/object-observe.js
|
| index c4c6c14a3ada5c740bdd19623bc3f949dabf359b..77409b95748198194764d20322d954b559161bd6 100644
|
| --- a/src/object-observe.js
|
| +++ b/src/object-observe.js
|
| @@ -66,147 +66,18 @@ function CreateObjectInfo(object) {
|
| var info = {
|
| changeObservers: new InternalArray,
|
| notifier: null,
|
| - inactiveObservers: new InternalArray,
|
| - performing: { __proto__: null },
|
| - performingCount: 0,
|
| };
|
| objectInfoMap.set(object, info);
|
| return info;
|
| }
|
|
|
| -var defaultAcceptTypes = {
|
| - __proto__: null,
|
| - 'new': true,
|
| - 'updated': true,
|
| - 'deleted': true,
|
| - 'prototype': true,
|
| - 'reconfigured': true
|
| -};
|
| -
|
| -function CreateObserver(callback, accept) {
|
| - var observer = {
|
| - __proto__: null,
|
| - callback: callback,
|
| - accept: defaultAcceptTypes
|
| - };
|
| -
|
| - if (IS_UNDEFINED(accept))
|
| - return observer;
|
| -
|
| - var acceptMap = { __proto__: null };
|
| - for (var i = 0; i < accept.length; i++)
|
| - acceptMap[accept[i]] = true;
|
| -
|
| - observer.accept = acceptMap;
|
| - return observer;
|
| -}
|
| -
|
| -function ObserverIsActive(observer, objectInfo) {
|
| - if (objectInfo.performingCount === 0)
|
| - return true;
|
| -
|
| - var performing = objectInfo.performing;
|
| - for (var type in performing) {
|
| - if (performing[type] > 0 && observer.accept[type])
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -function ObserverIsInactive(observer, objectInfo) {
|
| - return !ObserverIsActive(observer, objectInfo);
|
| -}
|
| -
|
| -function RemoveNullElements(from) {
|
| - var i = 0;
|
| - var j = 0;
|
| - for (; i < from.length; i++) {
|
| - if (from[i] === null)
|
| - continue;
|
| - if (j < i)
|
| - from[j] = from[i];
|
| - j++;
|
| - }
|
| -
|
| - if (i !== j)
|
| - from.length = from.length - (i - j);
|
| -}
|
| -
|
| -function RepartitionObservers(conditionFn, from, to, objectInfo) {
|
| - var anyRemoved = false;
|
| - for (var i = 0; i < from.length; i++) {
|
| - var observer = from[i];
|
| - if (conditionFn(observer, objectInfo)) {
|
| - anyRemoved = true;
|
| - from[i] = null;
|
| - to.push(observer);
|
| - }
|
| - }
|
| -
|
| - if (anyRemoved)
|
| - RemoveNullElements(from);
|
| -}
|
| -
|
| -function BeginPerformChange(objectInfo, type) {
|
| - objectInfo.performing[type] = (objectInfo.performing[type] || 0) + 1;
|
| - objectInfo.performingCount++;
|
| - RepartitionObservers(ObserverIsInactive,
|
| - objectInfo.changeObservers,
|
| - objectInfo.inactiveObservers,
|
| - objectInfo);
|
| -}
|
| -
|
| -function EndPerformChange(objectInfo, type) {
|
| - objectInfo.performing[type]--;
|
| - objectInfo.performingCount--;
|
| - RepartitionObservers(ObserverIsActive,
|
| - objectInfo.inactiveObservers,
|
| - objectInfo.changeObservers,
|
| - objectInfo);
|
| -}
|
| -
|
| -function ensureObserverRemoved(objectInfo, callback) {
|
| - function remove(observerList) {
|
| - for (var i = 0; i < observerList.length; i++) {
|
| - if (observerList[i].callback === callback) {
|
| - observerList.splice(i, 1);
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - if (!remove(objectInfo.changeObservers))
|
| - remove(objectInfo.inactiveObservers);
|
| -}
|
| -
|
| -function AcceptArgIsValid(arg) {
|
| - if (IS_UNDEFINED(arg))
|
| - return true;
|
| -
|
| - if (!IS_SPEC_OBJECT(arg) ||
|
| - !IS_NUMBER(arg.length) ||
|
| - arg.length < 0)
|
| - return false;
|
| -
|
| - var length = arg.length;
|
| - for (var i = 0; i < length; i++) {
|
| - if (!IS_STRING(arg[i]))
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -function ObjectObserve(object, callback, accept) {
|
| +function ObjectObserve(object, callback) {
|
| if (!IS_SPEC_OBJECT(object))
|
| throw MakeTypeError("observe_non_object", ["observe"]);
|
| if (!IS_SPEC_FUNCTION(callback))
|
| throw MakeTypeError("observe_non_function", ["observe"]);
|
| if (ObjectIsFrozen(callback))
|
| throw MakeTypeError("observe_callback_frozen");
|
| - if (!AcceptArgIsValid(accept))
|
| - throw MakeTypeError("observe_accept_invalid");
|
|
|
| if (!observerInfoMap.has(callback)) {
|
| observerInfoMap.set(callback, {
|
| @@ -219,13 +90,8 @@ function ObjectObserve(object, callback, accept) {
|
| if (IS_UNDEFINED(objectInfo)) objectInfo = CreateObjectInfo(object);
|
| %SetIsObserved(object, true);
|
|
|
| - ensureObserverRemoved(objectInfo, callback);
|
| -
|
| - var observer = CreateObserver(callback, accept);
|
| - if (ObserverIsActive(observer, objectInfo))
|
| - objectInfo.changeObservers.push(observer);
|
| - else
|
| - objectInfo.inactiveObservers.push(observer);
|
| + var changeObservers = objectInfo.changeObservers;
|
| + if (changeObservers.indexOf(callback) < 0) changeObservers.push(callback);
|
|
|
| return object;
|
| }
|
| @@ -240,11 +106,11 @@ function ObjectUnobserve(object, callback) {
|
| if (IS_UNDEFINED(objectInfo))
|
| return object;
|
|
|
| - ensureObserverRemoved(objectInfo, callback);
|
| -
|
| - if (objectInfo.changeObservers.length === 0 &&
|
| - objectInfo.inactiveObservers.length === 0) {
|
| - %SetIsObserved(object, false);
|
| + var changeObservers = objectInfo.changeObservers;
|
| + var index = changeObservers.indexOf(callback);
|
| + if (index >= 0) {
|
| + changeObservers.splice(index, 1);
|
| + if (changeObservers.length === 0) %SetIsObserved(object, false);
|
| }
|
|
|
| return object;
|
| @@ -256,12 +122,8 @@ function EnqueueChangeRecord(changeRecord, observers) {
|
|
|
| for (var i = 0; i < observers.length; i++) {
|
| var observer = observers[i];
|
| - if (IS_UNDEFINED(observer.accept[changeRecord.type]))
|
| - continue;
|
| -
|
| - var callback = observer.callback;
|
| - var observerInfo = observerInfoMap.get(callback);
|
| - observationState.pendingObservers[observerInfo.priority] = callback;
|
| + var observerInfo = observerInfoMap.get(observer);
|
| + observationState.pendingObservers[observerInfo.priority] = observer;
|
| %SetObserverDeliveryPending();
|
| if (IS_NULL(observerInfo.pendingChangeRecords)) {
|
| observerInfo.pendingChangeRecords = new InternalArray(changeRecord);
|
| @@ -273,9 +135,6 @@ function EnqueueChangeRecord(changeRecord, observers) {
|
|
|
| function NotifyChange(type, object, name, oldValue) {
|
| var objectInfo = objectInfoMap.get(object);
|
| - if (objectInfo.changeObservers.length === 0)
|
| - return;
|
| -
|
| var changeRecord = (arguments.length < 4) ?
|
| { type: type, object: object, name: name } :
|
| { type: type, object: object, name: name, oldValue: oldValue };
|
| @@ -314,36 +173,6 @@ function ObjectNotifierNotify(changeRecord) {
|
| EnqueueChangeRecord(newRecord, objectInfo.changeObservers);
|
| }
|
|
|
| -function ObjectNotifierPerformChange(changeType, changeFn, receiver) {
|
| - if (!IS_SPEC_OBJECT(this))
|
| - throw MakeTypeError("called_on_non_object", ["performChange"]);
|
| -
|
| - var target = notifierTargetMap.get(this);
|
| - if (IS_UNDEFINED(target))
|
| - throw MakeTypeError("observe_notify_non_notifier");
|
| - if (!IS_STRING(changeType))
|
| - throw MakeTypeError("observe_perform_non_string");
|
| - if (!IS_SPEC_FUNCTION(changeFn))
|
| - throw MakeTypeError("observe_perform_non_function");
|
| -
|
| - if (IS_NULL_OR_UNDEFINED(receiver)) {
|
| - receiver = %GetDefaultReceiver(changeFn) || receiver;
|
| - } else if (!IS_SPEC_OBJECT(receiver) && %IsClassicModeFunction(changeFn)) {
|
| - receiver = ToObject(receiver);
|
| - }
|
| -
|
| - var objectInfo = objectInfoMap.get(target);
|
| - if (IS_UNDEFINED(objectInfo))
|
| - return;
|
| -
|
| - BeginPerformChange(objectInfo, changeType);
|
| - try {
|
| - %_CallFunction(receiver, changeFn);
|
| - } finally {
|
| - EndPerformChange(objectInfo, changeType);
|
| - }
|
| -}
|
| -
|
| function ObjectGetNotifier(object) {
|
| if (!IS_SPEC_OBJECT(object))
|
| throw MakeTypeError("observe_non_object", ["getNotifier"]);
|
| @@ -406,8 +235,7 @@ function SetupObjectObserve() {
|
| "unobserve", ObjectUnobserve
|
| ));
|
| InstallFunctions(notifierPrototype, DONT_ENUM, $Array(
|
| - "notify", ObjectNotifierNotify,
|
| - "performChange", ObjectNotifierPerformChange
|
| + "notify", ObjectNotifierNotify
|
| ));
|
| }
|
|
|
|
|