Merge lp:~bcsaller/juju-gui/hotkey-ext into lp:juju-gui/experimental

Proposed by Benjamin Saller
Status: Merged
Merged at revision: 688
Proposed branch: lp:~bcsaller/juju-gui/hotkey-ext
Merge into: lp:juju-gui/experimental
Diff against target: 260 lines (+94/-21)
5 files modified
app/app.js (+61/-15)
app/config-debug.js (+2/-1)
app/store/env/simulator.js (+17/-0)
app/views/topology/panzoom.js (+7/-5)
lib/views/stylesheet.less (+7/-0)
To merge this branch: bzr merge lp:~bcsaller/juju-gui/hotkey-ext
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+165428@code.launchpad.net

Description of the change

Hotkey extensions

Keybindings can declare more behavior
Toggle simulator

https://codereview.appspot.com/9694043/

To post a comment you must log in.
Revision history for this message
Benjamin Saller (bcsaller) wrote :

Reviewers: mp+165428_code.launchpad.net,

Message:
Please take a look.

Description:
Hotkey extensions

Keybindings can declare more behavior
Toggle simulator

https://code.launchpad.net/~bcsaller/juju-gui/hotkey-ext/+merge/165428

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/9694043/

Affected files:
   A [revision details]
   M app/app.js
   M app/config-debug.js
   M app/store/env/simulator.js
   M app/views/topology/panzoom.js
   M lib/views/stylesheet.less

Revision history for this message
Jeff Pihach (hatch) wrote :

LGTM - This hotkey stuff is getting to be a considerable number of lines
and looks pretty easy to be able to break out into an app extension to
clean up app.js. Possibly a follow-up?

https://codereview.appspot.com/9694043/

Revision history for this message
Gary Poster (gary) wrote :

LGTM. Maybe we should remove the feature flag simulator support? Oh,
and I think we should always instantiate the simulator in sandbox mode,
but only start it if simulateEvents is true in the config?

Thanks!

https://codereview.appspot.com/9694043/diff/1/app/app.js
File app/app.js (right):

https://codereview.appspot.com/9694043/diff/1/app/app.js#newcode173
app/app.js:173: '/': {
+1
...though on reflection it reminds me that we will need to change this
to work with the charm browser when it lands. Can cross the bridge when
we come to it.

https://codereview.appspot.com/9694043/diff/1/app/app.js#newcode207
app/app.js:207: '+': {
cool :-)

https://codereview.appspot.com/9694043/

Revision history for this message
Benjamin Saller (bcsaller) wrote :

*** Submitted:

Hotkey extensions

Keybindings can declare more behavior
Toggle simulator

R=jeff.pihach, gary.poster
CC=
https://codereview.appspot.com/9694043

https://codereview.appspot.com/9694043/

Revision history for this message
Benjamin Saller (bcsaller) wrote :

Thanks for the reviews, changed it to always create the simulator, to
start on config or hotkey and to clean up in the destructor.

https://codereview.appspot.com/9694043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'app/app.js'
--- app/app.js 2013-05-22 22:30:29 +0000
+++ app/app.js 2013-05-23 16:07:28 +0000
@@ -154,6 +154,9 @@
154 * target: {String} CSS selector of one element154 * target: {String} CSS selector of one element
155 * focus: {Boolean} Focus the element.155 * focus: {Boolean} Focus the element.
156 * toggle: {Boolean} Toggle element visibility.156 * toggle: {Boolean} Toggle element visibility.
157 * fire: {String} Event to fire when triggered. (XXX: Target is topology)
158 * condition: {Function} returns Boolean, should method be added to
159 * keybindings.
157 * callback: {Function} Taking (event, target).160 * callback: {Function} Taking (event, target).
158 * help: {String} Help text to display in popup.161 * help: {String} Help text to display in popup.
159 *162 *
@@ -167,17 +170,10 @@
167 focus: true,170 focus: true,
168 help: 'Select the charm Search'171 help: 'Select the charm Search'
169 },172 },
170 'S-d': {173 '/': {
171 callback: function(evt) {174 target: '#charm-search-field',
172 /* global saveAs: false */175 focus: true,
173 this.env.exportEnvironment(function(r) {176 help: 'Select the charm Search'
174 var exportData = JSON.stringify(r.result, undefined, 2);
175 var exportBlob = new Blob([exportData],
176 {type: 'application/json;charset=utf-8'});
177 saveAs(exportBlob, 'export.json');
178 });
179 },
180 help: 'Export the environment'
181 },177 },
182 'S-/': {178 'S-/': {
183 target: '#shortcut-help',179 target: '#shortcut-help',
@@ -187,10 +183,15 @@
187 if (target && !target.getHTML().length) {183 if (target && !target.getHTML().length) {
188 var bindings = [];184 var bindings = [];
189 Y.each(this.keybindings, function(v, k) {185 Y.each(this.keybindings, function(v, k) {
190 if (v.help) {186 if (v.help && (v.condition === undefined ||
187 v.condition.call(this) === true)) {
188 // TODO: translate keybindings to
189 // human <Alt> m
190 // <Control> <Shift> N (note caps)
191 // also 'g then i' style
191 bindings.push({key: k, help: v.help});192 bindings.push({key: k, help: v.help});
192 }193 }
193 });194 }, this);
194 target.setHTML(195 target.setHTML(
195 views.Templates.shortcuts({bindings: bindings}));196 views.Templates.shortcuts({bindings: bindings}));
196 }197 }
@@ -203,13 +204,46 @@
203 },204 },
204 help: 'Navigate to the Environment overview.'205 help: 'Navigate to the Environment overview.'
205 },206 },
207 '+': {
208 fire: 'zoom_in',
209 help: 'Zoom In'
210 },
211 '-': {
212 fire: 'zoom_out',
213 help: 'Zoom Out'
214 },
206 'esc': {215 'esc': {
216 fire: 'clearState',
207 callback: function() {217 callback: function() {
208 // Explicitly hide anything we might care about.218 // Explicitly hide anything we might care about.
209 Y.one('#shortcut-help').hide();219 Y.one('#shortcut-help').hide();
210 },220 },
211 help: 'Cancel current action'221 help: 'Cancel current action'
222 },
223
224 'C-s': {
225 'condition': function() {
226 return this._simulator !== undefined;
227 },
228 callback: function() {
229 this._simulator.toggle();
230 },
231 help: 'Toggle the simulator'
232 },
233
234 'S-d': {
235 callback: function(evt) {
236 /* global saveAs: false */
237 this.env.exportEnvironment(function(r) {
238 var exportData = JSON.stringify(r.result, undefined, 2);
239 var exportBlob = new Blob([exportData],
240 {type: 'application/json;charset=utf-8'});
241 saveAs(exportBlob, 'export.json');
242 });
243 },
244 help: 'Export the environment'
212 }245 }
246
213 },247 },
214248
215 /**249 /**
@@ -248,14 +282,14 @@
248 */282 */
249 activateHotkeys: function() {283 activateHotkeys: function() {
250 var key_map = {284 var key_map = {
251 '/': 191, '?': 63,285 '/': 191, '?': 63, '+': 187, '-': 189,
252 enter: 13, esc: 27, backspace: 8,286 enter: 13, esc: 27, backspace: 8,
253 tab: 9, pageup: 33, pagedown: 34};287 tab: 9, pageup: 33, pagedown: 34};
254 var code_map = {};288 var code_map = {};
255 Y.each(key_map, function(v, k) {289 Y.each(key_map, function(v, k) {
256 code_map[v] = k;290 code_map[v] = k;
257 });291 });
258 Y.one(window).on('keydown', function(evt) {292 this._keybindings = Y.one(window).on('keydown', function(evt) {
259 //Normalize key-code293 //Normalize key-code
260 var symbolic = [];294 var symbolic = [];
261 if (evt.ctrlKey) { symbolic.push('C');}295 if (evt.ctrlKey) { symbolic.push('C');}
@@ -266,12 +300,21 @@
266 var trigger = symbolic.join('-');300 var trigger = symbolic.join('-');
267 var spec = this.keybindings[trigger];301 var spec = this.keybindings[trigger];
268 if (spec) {302 if (spec) {
303 if (spec.condition && !spec.condition.call(this)) {
304 // Note that when a condition check fails
305 // the event still propagates.
306 return;
307 }
269 var target = Y.one(spec.target);308 var target = Y.one(spec.target);
270 if (target) {309 if (target) {
271 if (spec.toggle) { target.toggleView(); }310 if (spec.toggle) { target.toggleView(); }
272 if (spec.focus) { target.focus(); }311 if (spec.focus) { target.focus(); }
273 }312 }
274 if (spec.callback) { spec.callback.call(this, evt, target); }313 if (spec.callback) { spec.callback.call(this, evt, target); }
314 // HACK w/o context/view restriction but right direction
315 if (spec.fire) {
316 this.views.environment.instance.topo.fire(spec.fire);
317 }
275 // If we handled the event nothing else has to.318 // If we handled the event nothing else has to.
276 evt.stopPropagation();319 evt.stopPropagation();
277 evt.preventDefault();320 evt.preventDefault();
@@ -521,6 +564,9 @@
521 @method destructor564 @method destructor
522 */565 */
523 destructor: function() {566 destructor: function() {
567 if (this._keybindings) {
568 this._keybindings.detach();
569 }
524 Y.each(570 Y.each(
525 [this.env, this.db, this.charm_store, this.notifications,571 [this.env, this.db, this.charm_store, this.notifications,
526 this.landscape, this.endpointsController],572 this.landscape, this.endpointsController],
527573
=== modified file 'app/config-debug.js'
--- app/config-debug.js 2013-05-21 01:16:15 +0000
+++ app/config-debug.js 2013-05-23 16:07:28 +0000
@@ -45,7 +45,8 @@
45 sandbox: true,45 sandbox: true,
46 // When in sandbox mode should we create events to simulate a live env.46 // When in sandbox mode should we create events to simulate a live env.
47 // You can also use the :flags:/simulateEvents feature flag.47 // You can also use the :flags:/simulateEvents feature flag.
48 simulateEvents: false,48 // There is also a hotkey to toggle the simulator.
49 simulateEvents: true,
49 readOnly: false,50 readOnly: false,
50 login_help: 'For this demonstration, use the password "admin" to connect.'51 login_help: 'For this demonstration, use the password "admin" to connect.'
51};52};
5253
=== modified file 'app/store/env/simulator.js'
--- app/store/env/simulator.js 2013-05-21 12:52:33 +0000
+++ app/store/env/simulator.js 2013-05-23 16:07:28 +0000
@@ -484,6 +484,7 @@
484484
485 // Invoke on start as well.485 // Invoke on start as well.
486 tick();486 tick();
487 console.log('Simulator started');
487 return this;488 return this;
488489
489 },490 },
@@ -497,6 +498,22 @@
497 if (this._scheduler) {498 if (this._scheduler) {
498 this._scheduler.cancel();499 this._scheduler.cancel();
499 this._scheduler = null;500 this._scheduler = null;
501 console.log('Simulator stopped');
502 }
503 return this;
504 },
505
506 /**
507 Toggle the running state of the simulator.
508
509 @method toggle
510 @chainable
511 */
512 toggle: function() {
513 if (this._scheduler) {
514 this.stop();
515 } else {
516 this.start();
500 }517 }
501 return this;518 return this;
502 }519 }
503520
=== modified file 'app/views/topology/panzoom.js'
--- app/views/topology/panzoom.js 2013-05-17 14:51:05 +0000
+++ app/views/topology/panzoom.js 2013-05-23 16:07:28 +0000
@@ -59,7 +59,9 @@
5959
60 @event rendered60 @event rendered
61 */61 */
62 rendered: 'renderedHandler'62 rendered: 'renderedHandler',
63 zoom_in: 'zoom_in',
64 zoom_out: 'zoom_out'
63 }65 }
64 },66 },
6567
@@ -130,8 +132,8 @@
130 *132 *
131 * @method zoom_out133 * @method zoom_out
132 */134 */
133 zoom_out: function(data, context) {135 zoom_out: function(data, self) {
134 var slider = context.slider,136 var slider = this.slider || self.slider,
135 val = slider.get('value');137 val = slider.get('value');
136 slider.set('value', val - 25);138 slider.set('value', val - 25);
137 },139 },
@@ -141,8 +143,8 @@
141 *143 *
142 * @method zoom_in144 * @method zoom_in
143 */145 */
144 zoom_in: function(data, context) {146 zoom_in: function(data, self) {
145 var slider = context.slider,147 var slider = this.slider || self.slider,
146 val = slider.get('value');148 val = slider.get('value');
147 slider.set('value', val + 25);149 slider.set('value', val + 25);
148 },150 },
149151
=== modified file 'lib/views/stylesheet.less'
--- lib/views/stylesheet.less 2013-05-22 22:30:29 +0000
+++ lib/views/stylesheet.less 2013-05-23 16:07:28 +0000
@@ -117,6 +117,7 @@
117 background: url(/juju-ui/assets/images/top_bar.png) repeat-x;117 background: url(/juju-ui/assets/images/top_bar.png) repeat-x;
118 padding: 0;118 padding: 0;
119 position: relative;119 position: relative;
120 overflow: hidden;
120 color: @navbar-color;121 color: @navbar-color;
121 .brand {122 .brand {
122 margin: 12px 26px 6px 10px;123 margin: 12px 26px 6px 10px;
@@ -1725,6 +1726,12 @@
1725 letter-spacing: normal;1726 letter-spacing: normal;
1726}1727}
17271728
1729.yui3-slider-thumb {
1730 &:focus {
1731 outline: none;
1732 }
1733}
1734
1728/** Browser Setup **/1735/** Browser Setup **/
1729@import "browser/reset.less";1736@import "browser/reset.less";
1730@import "browser/vars.less";1737@import "browser/vars.less";

Subscribers

People subscribed via source and target branches