OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview Base class for all login WebUI screens. | 6 * @fileoverview Base class for all login WebUI screens. |
7 */ | 7 */ |
8 cr.define('login', function() { | 8 cr.define('login', function() { |
9 var Screen = cr.ui.define('div'); | 9 var Screen = cr.ui.define('div'); |
10 | 10 |
11 /** @const */ var CALLBACK_BUTTON_CLICKED = 'buttonClicked'; | |
12 /** @const */ var CALLBACK_CONTEXT_CHANGED = 'contextChanged'; | |
13 | |
11 function doNothing() {}; | 14 function doNothing() {}; |
12 | 15 |
16 var querySelectorAll = HTMLDivElement.prototype.querySelectorAll; | |
17 | |
13 Screen.prototype = { | 18 Screen.prototype = { |
14 __proto__: HTMLDivElement.prototype, | 19 __proto__: HTMLDivElement.prototype, |
15 | 20 |
21 /** | |
22 * Prefix added to sent to Chrome messages' names. | |
23 */ | |
24 sendPrefix_: '', | |
25 | |
26 /** | |
27 * Context used by this screen. | |
28 */ | |
29 context_: null, | |
30 | |
31 /** | |
32 * Dictionary of context observers that are methods of |this| binded to | |
Denis Kuznetsov (DE-MUC)
2014/06/11 14:29:17
s/binded/bound/
dzhioev (left Google)
2014/06/20 07:24:16
Done.
| |
33 * |this|. | |
34 */ | |
35 contextObservers_: {}, | |
36 | |
37 get context() { | |
38 return this.context_; | |
39 }, | |
40 | |
41 /** | |
42 * Sends recent context changes to C++ handler. | |
43 */ | |
44 commitContextChanges: function() { | |
45 this.send(CALLBACK_CONTEXT_CHANGED, this.context_.getChangesAndReset()); | |
46 }, | |
47 | |
48 /** | |
49 * Sends message to Chrome, adding needed prefix to message name. All | |
50 * arguments after |messageName| are packed into message parameters list. | |
51 * | |
52 * @param {string} messageName Name of message without a prefix. | |
53 * @param {...*} varArgs parameters for message. | |
54 */ | |
55 send: function(messageName, varArgs) { | |
56 if (arguments.length == 0) | |
57 throw Error('Message name is not provided.'); | |
58 var fullMessageName = this.sendPrefix_ + messageName; | |
59 var payload = Array.prototype.slice.call(arguments, 1); | |
60 chrome.send(fullMessageName, payload); | |
61 }, | |
62 | |
16 decorate: doNothing, | 63 decorate: doNothing, |
17 | 64 |
18 /** | 65 /** |
19 * Returns minimal size that screen prefers to have. Default implementation | 66 * Returns minimal size that screen prefers to have. Default implementation |
20 * returns current screen size. | 67 * returns current screen size. |
21 * @return {{width: number, height: number}} | 68 * @return {{width: number, height: number}} |
22 */ | 69 */ |
23 getPreferredSize: function() { | 70 getPreferredSize: function() { |
24 return {width: this.offsetWidth, height: this.offsetHeight}; | 71 return {width: this.offsetWidth, height: this.offsetHeight}; |
25 }, | 72 }, |
26 | 73 |
27 /** | 74 /** |
28 * Called for currently active screen when screen size changed. | 75 * Called for currently active screen when screen size changed. |
29 */ | 76 */ |
30 onWindowResize: doNothing, | 77 onWindowResize: doNothing, |
78 | |
79 /** | |
80 * Does the following things: | |
81 * * Creates screen context. | |
82 * * Looks for elements having "is" property and adds them as the proprties | |
83 * of the screen with name equal to value of "is", i.e. HTML element | |
84 * <div is="myDiv"></div> will be stored in this.myDiv. | |
85 * * Looks for buttons having "action" properties and adds click handlers | |
86 * to them. These handlers send |CALLBACK_BUTTON_CLICKED| messages to | |
87 * C++ with "action" property's value as payload. | |
88 */ | |
89 makeMagic: function() { | |
ygorshenin1
2014/06/11 10:44:00
Don't see how this method is used in https://coder
Denis Kuznetsov (DE-MUC)
2014/06/11 14:29:17
I agree about naming.
I'm also concerned about usi
dzhioev (left Google)
2014/06/18 14:43:39
It is called in |decorate| method of new screen.
I
dzhioev (left Google)
2014/06/18 14:43:39
* The main reason why I don't want use "id"s is th
Denis Kuznetsov (DE-MUC)
2014/06/19 19:16:36
First, attribute names are usually nouns. "Is" is
dzhioev (left Google)
2014/06/20 07:24:16
Renamed to "alias"
| |
90 this.context_ = new login.ScreenContext(this); | |
91 var elements = this.querySelectorAll('[is]'); | |
92 for (var i = 0; i < elements.length; ++i) | |
93 this[elements[i].getAttribute('is')] = elements[i]; | |
94 var buttons = this.querySelectorAll('button[action]'); | |
95 var self = this; | |
96 for (var i = 0; i < buttons.length; ++i) { | |
97 buttons[i].addEventListener('click', function(e) { | |
98 var action = this.getAttribute('action'); | |
99 self.send(CALLBACK_BUTTON_CLICKED, action); | |
100 e.stopPropagation(); | |
101 }); | |
102 } | |
103 }, | |
104 | |
105 /** | |
106 * Starts observation of property with |key| of the context attached to | |
107 * current screen. This method differs from "login.ScreenContext" in that | |
108 * it automatically detects if observer is method of |this| and make | |
109 * all needed actions to make it work correctly. So it's no need for client | |
110 * to bind methods to |this| and keep resulting callback for unobserve: | |
111 * | |
112 * this.observeContext('key', this.onKeyChanged_); | |
113 * ... | |
114 * this.unobserveContext('key', this.onKeyChanged_); | |
115 */ | |
116 observeContext: function(key, observer) { | |
Denis Kuznetsov (DE-MUC)
2014/06/11 14:29:17
subscribeForKeyChange / watchKeyChange?
dzhioev (left Google)
2014/06/18 14:43:39
See comment to ScreenContext.observe
| |
117 var realObserver = observer; | |
118 var propertyName = this.getPropertyNameOf_(observer); | |
119 if (propertyName) { | |
120 if (!this.contextObservers_.hasOwnProperty(propertyName)) | |
121 this.contextObservers_[propertyName] = observer.bind(this); | |
122 realObserver = this.contextObservers_[propertyName]; | |
123 } | |
124 this.context.observe(key, realObserver); | |
125 }, | |
126 | |
127 /** | |
128 * Removes |observer| from the list of context observers. Supports not only | |
129 * regular functions but also screen methods (see comment to | |
130 * |observeContext|). | |
131 */ | |
132 unobserveContext: function(observer) { | |
133 var realObserver = observer; | |
134 var propertyName = this.getPropertyNameOf_(observer); | |
135 if (propertyName) { | |
136 if (!this.contextObservers_.hasOwnProperty(propertyName)) | |
137 return; | |
138 realObserver = this.contextObservers_[propertyName]; | |
139 delete this.contextObservers_[propertyName]; | |
140 } | |
141 this.context.unobserve(realObserver); | |
142 }, | |
143 | |
144 /** | |
145 * Calls standart |querySelectorAll| method and returns its result converted | |
146 * to Array. | |
147 */ | |
148 querySelectorAll: function(selector) { | |
149 var list = querySelectorAll.call(this, selector); | |
150 return Array.prototype.slice.call(list); | |
151 }, | |
152 | |
153 /** | |
154 * Called when context changes are recieved from C++. | |
155 */ | |
156 contextChanged_: function(diff) { | |
ygorshenin1
2014/06/11 10:44:00
nit: add @private annotation.
dzhioev (left Google)
2014/06/18 14:43:39
Done.
| |
157 this.context.applyChanges(diff); | |
158 }, | |
159 | |
160 getPropertyNameOf_: function(value) { | |
ygorshenin1
2014/06/11 10:44:00
nit: add comment to this function + @private annot
dzhioev (left Google)
2014/06/18 14:43:39
Done.
| |
161 for (var key in this) | |
162 if (this[key] === value) | |
163 return key; | |
164 return ''; | |
165 } | |
31 }; | 166 }; |
32 | 167 |
33 return { | 168 return { |
34 Screen: Screen | 169 Screen: Screen |
35 }; | 170 }; |
36 }); | 171 }); |
37 | 172 |
38 cr.define('login', function() { | 173 cr.define('login', function() { |
39 return { | 174 return { |
40 /** | 175 /** |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 propertyName, descriptor); | 215 propertyName, descriptor); |
81 if (api.indexOf(propertyName) >= 0) { | 216 if (api.indexOf(propertyName) >= 0) { |
82 constructor[propertyName] = (function(x) { | 217 constructor[propertyName] = (function(x) { |
83 return function() { | 218 return function() { |
84 var screen = $(id); | 219 var screen = $(id); |
85 return screen[x].apply(screen, arguments); | 220 return screen[x].apply(screen, arguments); |
86 }; | 221 }; |
87 })(propertyName); | 222 })(propertyName); |
88 } | 223 } |
89 }); | 224 }); |
225 constructor.contextChanged = function() { | |
226 var screen = $(id); | |
227 screen.contextChanged_.apply(screen, arguments); | |
228 } | |
90 constructor.prototype.name = function() { return id; }; | 229 constructor.prototype.name = function() { return id; }; |
91 | 230 |
92 constructor.register = function() { | 231 constructor.register = function() { |
93 var screen = $(id); | 232 var screen = $(id); |
94 constructor.decorate(screen); | 233 constructor.decorate(screen); |
95 Oobe.getInstance().registerScreen(screen); | 234 Oobe.getInstance().registerScreen(screen); |
96 }; | 235 }; |
97 | 236 |
98 var result = {}; | 237 var result = {}; |
99 result[name] = constructor; | 238 result[name] = constructor; |
100 return result; | 239 return result; |
101 }); | 240 }); |
102 } | 241 } |
103 }; | 242 }; |
104 }); | 243 }); |
105 | 244 |
OLD | NEW |