Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: src/object-observe.js

Issue 11225058: Initial JS stub implementation of Object.observe. Adds support for .object/.unobserve/.notify/.deli… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: cr changes Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 "use strict";
29
30 var observerInfoMap = new $WeakMap;
31 var objectInfoMap = new $WeakMap;
32
33 $Object.observe = function(object, callback) {
34 if (!IS_SPEC_OBJECT(object))
35 throw MakeTypeError("observe_non_object", ["observe"]);
36 if (!IS_SPEC_FUNCTION(callback))
37 throw MakeTypeError("observe_non_function", ["observe"]);
38 if ($Object.isFrozen(callback))
39 throw MakeTypeError("observe_callback_frozen");
rossberg 2012/10/24 09:57:24 I wonder, is this actually necessary? Why does the
rafaelw 2012/10/24 11:18:04 Sadly, yes. This was necessary to prevent a side-c
40
41 var observerInfo = observerInfoMap.get(callback);
42 if (IS_UNDEFINED(observerInfo)) {
43 observerInfo = new $Object();
rossberg 2012/10/24 09:57:24 Nit: {} is clearer and potentially more efficient
rafaelw 2012/10/24 11:18:04 Done.
44 observerInfo.pendingChangeRecords = null;
45 // TODO: setup observerInfo.priority.
46 observerInfoMap.set(callback, observerInfo);
47 }
48
49 var objectInfo = objectInfoMap.get(object);
50 if (IS_UNDEFINED(objectInfo)) {
51 objectInfo = new $Object();
52 objectInfo.changeObservers = new $Array(callback);
rossberg 2012/10/24 09:57:24 Nit: [callback] instead of invoking Array construc
rafaelw 2012/10/24 11:18:04 Done.
53 // TODO: setup objectInfo.notifier
54 objectInfoMap.set(object, objectInfo);
55 return;
56 }
57
58 var changeObservers = objectInfo.changeObservers;
59 if (changeObservers.indexOf(callback) >= 0)
rossberg 2012/10/24 09:57:24 Why not use a Set for this?
rafaelw 2012/10/24 11:18:04 AFAIC, The V8 implementation for Map & Set isn't c
rossberg 2012/10/24 12:03:13 Ah, you are right of course. Maybe put in a TODO t
rafaelw 2012/10/24 14:56:05 Done.
60 return;
61
62 changeObservers.push(callback);
63 }
64
65 $Object.unobserve = function(object, callback) {
66 if (!IS_SPEC_OBJECT(object))
67 throw MakeTypeError("observe_non_object", ["unobserve"]);
68
69 var objectInfo = objectInfoMap.get(object);
70 if (IS_UNDEFINED(objectInfo))
rossberg 2012/10/24 09:57:24 OT: Is there a reason why the spec does not make t
rafaelw 2012/10/24 11:18:04 You mean: unobserving something that isn't observe
71 return;
72
73 var observerInfo = observerInfoMap.get(callback);
74
75 var changeObservers = objectInfo.changeObservers;
76 var index = changeObservers.indexOf(callback);
77 if (index < 0)
78 return;
79
80 changeObservers.splice(index, 1);
81 }
82
83 function EnqueueChangeRecord(changeRecord, observers) {
84 for (var i = 0; i < observers.length; i++) {
85 var observer = observers[i];
86 var observerInfo = observerInfoMap.get(observer);
87
88 // TODO: "activate" the observer
89
90 var pendingChangeRecords = observerInfo.pendingChangeRecords;
91 if (IS_NULL(pendingChangeRecords)) {
92 pendingChangeRecords = observerInfo.pendingChangeRecords = new $Array(chan geRecord);
rossberg 2012/10/24 09:57:24 Line too long.
rafaelw 2012/10/24 11:18:04 Done.
93 } else {
94 pendingChangeRecords.push(changeRecord);
95 }
96 }
97 }
98
99 $Object.notify = function(object, changeRecord) {
100 // TODO: notifier needs to be [[THIS]]
rossberg 2012/10/24 09:57:24 Check that this is an object.
rafaelw 2012/10/24 11:18:04 I asked Arv about this in the spec. He pointed out
101 if (!IS_STRING(changeRecord['type']))
rossberg 2012/10/24 09:57:24 Preferable: changeRecord.type
rafaelw 2012/10/24 11:18:04 Done.
102 throw MakeTypeError("observe_type_non_string");
103
104 var objectInfo = objectInfoMap.get(object);
105 if (IS_UNDEFINED(objectInfo))
106 return;
107
108 var newRecord = new $Object();
rossberg 2012/10/24 09:57:24 {}
rafaelw 2012/10/24 11:18:04 Done.
109 newRecord['object'] = object; // TODO: Needs to be 'object' retreived from not ifier
rossberg 2012/10/24 09:57:24 newRecord.object
rossberg 2012/10/24 09:57:24 Line too long
rafaelw 2012/10/24 11:18:04 Done.
110 for (var prop in changeRecord) {
111 if (prop === 'object')
112 continue;
113 newRecord[prop] = changeRecord[prop];
114 }
115 $Object.freeze(newRecord);
116
117 EnqueueChangeRecord(newRecord, objectInfo.changeObservers);
118 }
119
120 $Object.deliverChangeRecords = function(callback) {
121 if (!IS_SPEC_FUNCTION(callback))
122 throw MakeTypeError("observe_non_function", ["deliverChangeRecords"]);
123
124 var observerInfo = observerInfoMap.get(callback);
125 if (IS_UNDEFINED(observerInfo))
126 return;
127
128 var pendingChangeRecords = observerInfo.pendingChangeRecords;
129 if (IS_NULL(pendingChangeRecords))
130 return;
131
132 observerInfo.pendingChangeRecords = null;
133
134 callback(pendingChangeRecords);
135 return;
136 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698