OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 Polymer('webui-view', (function() { | |
6 /** @const */ var CALLBACK_EVENT_FIRED = 'eventFired'; | |
7 /** @const */ var CALLBACK_CONTEXT_CHANGED = 'contextChanged'; | |
8 /** @const */ var CALLBACK_READY = 'ready'; | |
9 | |
10 return { | |
11 /** | |
12 * Dictionary of context observers that are methods of |this| bound to | |
13 * |this|. | |
14 */ | |
15 contextObservers_: null, | |
16 | |
17 /** | |
18 * Full path to the element in views hierarchy. | |
19 */ | |
20 path_: null, | |
21 | |
22 /** | |
23 * Whether DOM is ready. | |
24 */ | |
25 domReady_: false, | |
26 | |
27 /** | |
28 * Context used for sharing data with native backend. | |
29 */ | |
30 context: null, | |
31 | |
32 /** | |
33 * Internal storage of |this.context|. Short name has been choosen for | |
Nikita (slow)
2015/02/24 15:22:42
nit: You can make this comment shorter since you'r
dzhioev (left Google)
2015/02/26 14:01:37
What do you mean? this.C and this.context are diff
Nikita (slow)
2015/02/26 14:18:20
I suggested removing reasoning for using short nam
dzhioev (left Google)
2015/03/02 11:02:30
Done.
| |
34 * reason: such name doesn't take much space in HTML data bindings, which | |
35 * are used very often. | |
36 * C binded to the native part of the context, that means that all the | |
37 * changes in the native part appear in C automticaly. Reverse is not true, | |
Nikita (slow)
2015/02/26 14:18:20
nit: automatically
dzhioev (left Google)
2015/03/02 11:02:30
Done.
| |
38 * you should use: | |
39 * this.context.set(...); | |
40 * this.context.commitContextChanges(); | |
41 * to send updates to the native part. | |
42 * TODO(dzhioev): make binding two-way. | |
Nikita (slow)
2015/02/24 15:22:42
Since this is purely an optimization I suggest rem
dzhioev (left Google)
2015/02/26 14:01:37
Done. Removed comment.
| |
43 */ | |
44 C: null, | |
45 | |
46 ready: function() { | |
47 this.context = new wug.Context; | |
48 this.C = this.context.storage_; | |
49 this.contextObservers_ = {}; | |
50 }, | |
51 | |
52 /** | |
53 * One of element's lifecycle methods. | |
54 */ | |
55 domReady: function() { | |
56 var id = this.getAttribute('wugid'); | |
57 if (!id) | |
58 console.error('"wugid" attribute is missing.'); | |
Nikita (slow)
2015/02/24 15:22:42
nit: Should you return here and do not initialize
dzhioev (left Google)
2015/02/26 14:01:37
Done.
| |
59 if (id == 'WUG_ROOT') { | |
60 this.setPath_('WUG_ROOT'); | |
61 } | |
62 this.domReady_ = true; | |
63 if (this.path_) | |
64 this.init_(); | |
65 }, | |
66 | |
67 setPath_: function(path) { | |
68 this.path_ = path; | |
69 if (this.domReady_) | |
70 this.init_(); | |
71 }, | |
72 | |
73 init_: function() { | |
74 this.initContext_(); | |
75 this.initChildren_(); | |
76 window[this.path_ + '$contextChanged'] = | |
77 this.onContextChanged_.bind(this); | |
78 this.initialize(); | |
79 this.send(CALLBACK_READY); | |
80 }, | |
81 | |
82 fireEvent: function(_, _, source) { | |
83 this.send(CALLBACK_EVENT_FIRED, source.getAttribute('event')); | |
84 }, | |
85 | |
86 i18n: function(args) { | |
87 if (!(args instanceof Array)) | |
88 args = [args]; | |
89 args[0] = this.getType() + '$' + args[0]; | |
90 return loadTimeData.getStringF.apply(loadTimeData, args); | |
91 }, | |
92 | |
93 /** | |
94 * Sends message to Chrome, adding needed prefix to message name. All | |
95 * arguments after |messageName| are packed into message parameters list. | |
96 * | |
97 * @param {string} messageName Name of message without a prefix. | |
98 * @param {...*} varArgs parameters for message. | |
99 * @private | |
100 */ | |
101 send: function(messageName, varArgs) { | |
102 if (arguments.length == 0) | |
103 throw Error('Message name is not provided.'); | |
104 var fullMessageName = this.path_ + '$' + messageName; | |
105 var payload = Array.prototype.slice.call(arguments, 1); | |
106 chrome.send(fullMessageName, payload); | |
107 }, | |
108 | |
109 /** | |
110 * Starts observation of property with |key| of the context attached to | |
111 * current screen. This method differs from "login.ScreenContext" in that | |
112 * it automatically detects if observer is method of |this| and make | |
113 * all needed actions to make it work correctly. So it's no need for client | |
114 * to bind methods to |this| and keep resulting callback for | |
115 * |removeObserver| call: | |
116 * | |
117 * this.addContextObserver('key', this.onKeyChanged_); | |
Nikita (slow)
2015/02/24 15:22:42
Not clear whether this example on how caller shoul
dzhioev (left Google)
2015/02/26 14:01:37
Done.
| |
118 * ... | |
119 * this.removeContextObserver('key', this.onKeyChanged_); | |
120 * @private | |
121 */ | |
122 addContextObserver: function(key, observer) { | |
123 var realObserver = observer; | |
124 var propertyName = this.getPropertyNameOf_(observer); | |
125 if (propertyName) { | |
126 if (!this.contextObservers_.hasOwnProperty(propertyName)) | |
127 this.contextObservers_[propertyName] = observer.bind(this); | |
128 realObserver = this.contextObservers_[propertyName]; | |
129 } | |
130 this.context.addObserver(key, realObserver); | |
131 }, | |
132 | |
133 /** | |
134 * Removes |observer| from the list of context observers. Supports not only | |
135 * regular functions but also screen methods (see comment to | |
136 * |addContextObserver|). | |
137 * @private | |
138 */ | |
139 removeContextObserver: function(observer) { | |
140 var realObserver = observer; | |
141 var propertyName = this.getPropertyNameOf_(observer); | |
142 if (propertyName) { | |
143 if (!this.contextObservers_.hasOwnProperty(propertyName)) | |
144 return; | |
145 realObserver = this.contextObservers_[propertyName]; | |
146 delete this.contextObservers_[propertyName]; | |
147 } | |
148 this.context.removeObserver(realObserver); | |
149 }, | |
150 | |
151 /** | |
152 * Sends recent context changes to C++ handler. | |
153 * @private | |
154 */ | |
155 commitContextChanges: function() { | |
156 if (!this.context.hasChanges()) | |
157 return; | |
158 this.send(CALLBACK_CONTEXT_CHANGED, this.context.getChangesAndReset()); | |
159 }, | |
160 | |
161 /** | |
162 * Called when context changed on C++ side. | |
163 */ | |
164 onContextChanged_: function(diff) { | |
165 var changedKeys = this.context.applyChanges(diff); | |
166 this.contextChanged(changedKeys); | |
167 }, | |
168 | |
169 /** | |
170 * If |value| is the value of some property of |this| returns property's | |
171 * name. Otherwise returns empty string. | |
172 * @private | |
173 */ | |
174 getPropertyNameOf_: function(value) { | |
175 for (var key in this) | |
176 if (this[key] === value) | |
177 return key; | |
178 return ''; | |
179 } | |
180 }; | |
181 })()); | |
182 | |
OLD | NEW |