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_CONTEXT_CHANGED = 'contextChanged'; | |
7 /** @const */ var CALLBACK_READY = 'ready'; | |
8 | |
9 return { | |
10 /** @const */ | |
11 CALLBACK_EVENT_FIRED: 'eventFired', | |
12 | |
13 /** | |
14 * Dictionary of context observers that are methods of |this| bound to | |
15 * |this|. | |
16 */ | |
17 contextObservers_: null, | |
18 | |
19 /** | |
20 * Full path to the element in views hierarchy. | |
21 */ | |
22 path_: null, | |
23 | |
24 /** | |
25 * Whether DOM is ready. | |
26 */ | |
27 domReady_: false, | |
28 | |
29 /** | |
30 * Context used for sharing data with native backend. | |
31 */ | |
32 context: null, | |
33 | |
34 /** | |
35 * Internal storage of |this.context|. | |
36 * |C| bound to the native part of the context, that means that all the | |
37 * changes in the native part appear in |C| automatically. Reverse is not | |
38 * true, you should use: | |
39 * this.context.set(...); | |
40 * this.context.commitContextChanges(); | |
41 * to send updates to the native part. | |
42 */ | |
43 C: null, | |
44 | |
45 ready: function() { | |
46 this.context = new wug.Context; | |
47 this.C = this.context.storage_; | |
48 this.contextObservers_ = {}; | |
49 }, | |
50 | |
51 /** | |
52 * One of element's lifecycle methods. | |
53 */ | |
54 domReady: function() { | |
55 var id = this.getAttribute('wugid'); | |
56 if (!id) { | |
57 console.error('"wugid" attribute is missing.'); | |
58 return; | |
59 } | |
60 if (id == 'WUG_ROOT') | |
61 this.setPath_('WUG_ROOT'); | |
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(this.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. In contrast with "wug.Context.addObserver" this method | |
112 * can automatically detect if observer is method of |this| and make | |
113 * all needed actions to make it work correctly. So there is no need in | |
114 * binding method to |this| before adding it. For example, if |this| has | |
115 * a method |onKeyChanged_|, you can do: | |
116 * | |
117 * this.addContextObserver('key', this.onKeyChanged_); | |
118 * ... | |
119 * this.removeContextObserver('key', this.onKeyChanged_); | |
120 * | |
121 * instead of: | |
122 * | |
123 * this.keyObserver_ = this.onKeyChanged_.bind(this); | |
124 * this.addContextObserver('key', this.keyObserver_); | |
125 * ... | |
126 * this.removeContextObserver('key', this.keyObserver_); | |
127 * | |
128 * @private | |
129 */ | |
130 addContextObserver: function(key, observer) { | |
131 var realObserver = observer; | |
132 var propertyName = this.getPropertyNameOf_(observer); | |
133 if (propertyName) { | |
134 if (!this.contextObservers_.hasOwnProperty(propertyName)) | |
135 this.contextObservers_[propertyName] = observer.bind(this); | |
136 realObserver = this.contextObservers_[propertyName]; | |
137 } | |
138 this.context.addObserver(key, realObserver); | |
139 }, | |
140 | |
141 /** | |
142 * Removes |observer| from the list of context observers. Observer could be | |
143 * a method of |this| (see comment to |addContextObserver|). | |
144 * @private | |
145 */ | |
146 removeContextObserver: function(observer) { | |
147 var realObserver = observer; | |
148 var propertyName = this.getPropertyNameOf_(observer); | |
149 if (propertyName) { | |
150 if (!this.contextObservers_.hasOwnProperty(propertyName)) | |
151 return; | |
152 realObserver = this.contextObservers_[propertyName]; | |
153 delete this.contextObservers_[propertyName]; | |
154 } | |
155 this.context.removeObserver(realObserver); | |
156 }, | |
157 | |
158 /** | |
159 * Sends recent context changes to C++ handler. | |
160 * @private | |
161 */ | |
162 commitContextChanges: function() { | |
163 if (!this.context.hasChanges()) | |
164 return; | |
165 this.send(CALLBACK_CONTEXT_CHANGED, this.context.getChangesAndReset()); | |
166 }, | |
167 | |
168 /** | |
169 * Called when context changed on C++ side. | |
170 */ | |
171 onContextChanged_: function(diff) { | |
172 var changedKeys = this.context.applyChanges(diff); | |
173 this.contextChanged(changedKeys); | |
174 }, | |
175 | |
176 /** | |
177 * If |value| is the value of some property of |this| returns property's | |
178 * name. Otherwise returns empty string. | |
179 * @private | |
180 */ | |
181 getPropertyNameOf_: function(value) { | |
182 for (var key in this) | |
183 if (this[key] === value) | |
184 return key; | |
185 return ''; | |
186 } | |
187 }; | |
188 })()); | |
189 | |
OLD | NEW |