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

Side by Side Diff: chrome/browser/resources/settings/device_page/night_light_slider.js

Issue 2950673002: [MD Settings][Night Light] CL8: Add the ripple focus effect to the slider knobs (Closed)
Patch Set: Created 3 years, 6 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
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 6 * @fileoverview
7 * night-light-slider is used to set the custom automatic schedule of the 7 * night-light-slider is used to set the custom automatic schedule of the
8 * Night Light feature, so that users can set their desired start and end 8 * Night Light feature, so that users can set their desired start and end
9 * times. 9 * times.
10 */ 10 */
11 11
12 /** @const */ var HOURS_PER_DAY = 24; 12 /** @const */ var HOURS_PER_DAY = 24;
dpapad 2017/06/20 17:35:19 These are on global scope. Can you wrap the conten
afakhry 2017/06/20 19:59:54 Done.
13 /** @const */ var MIN_KNOBS_DISTANCE_MINUTES = 30; 13 /** @const */ var MIN_KNOBS_DISTANCE_MINUTES = 30;
14 /** @const */ var OFFSET_MINUTES_6PM = 18 * 60; 14 /** @const */ var OFFSET_MINUTES_6PM = 18 * 60;
15 /** @const */ var TOTAL_MINUTES_PER_DAY = 24 * 60; 15 /** @const */ var TOTAL_MINUTES_PER_DAY = 24 * 60;
16 16
17 Polymer({ 17 Polymer({
18 is: 'night-light-slider', 18 is: 'night-light-slider',
19 19
20 behaviors: [ 20 behaviors: [
21 I18nBehavior, 21 I18nBehavior,
dpapad 2017/06/20 17:35:20 Is this used anywhere?
afakhry 2017/06/20 19:59:54 It's used in the HTML $i18n{...}. Isn't that what
stevenjb 2017/06/20 20:19:02 No, $i18n is a pre-processing macro. I18nBehavior
afakhry 2017/06/20 20:25:16 Oh, I see. In that case, removed.
22 PrefsBehavior, 22 PrefsBehavior,
23 Polymer.IronA11yKeysBehavior, 23 Polymer.IronA11yKeysBehavior,
24 Polymer.PaperInkyFocusBehavior,
24 ], 25 ],
25 26
26 properties: { 27 properties: {
27 /** 28 /**
28 * The object currently being dragged. Either the start or end knobs. 29 * The object currently being dragged. Either the start or end knobs.
29 * @type {?Object} 30 * @type {?Object}
30 * @private 31 * @private
31 */ 32 */
32 dragObject_: { 33 dragObject_: {
33 type: Object, 34 type: Object,
34 value: null, 35 value: null,
35 }, 36 },
36 37
37 /** 38 /**
38 * The start knob time as a string to be shown on the start label bubble. 39 * The start knob time as a string to be shown on the start label bubble.
39 * @private 40 * @private
40 */ 41 */
41 startTime_: { 42 startTime_: {
dpapad 2017/06/20 17:35:19 Nit: Use shorthand (here and elsewhere, where appl
afakhry 2017/06/20 19:59:54 Done.
42 type: String, 43 type: String,
43 }, 44 },
44 45
45 /** 46 /**
46 * The end knob time as a string to be shown on the end label bubble. 47 * The end knob time as a string to be shown on the end label bubble.
47 * @private 48 * @private
48 */ 49 */
49 endTime_: { 50 endTime_: {
50 type: String, 51 type: String,
51 }, 52 },
52 }, 53 },
53 54
54 observers: [ 55 observers: [
55 'customTimesChanged_(prefs.ash.night_light.custom_start_time.*, ' + 56 'customTimesChanged_(prefs.ash.night_light.custom_start_time.*, ' +
56 'prefs.ash.night_light.custom_end_time.*)', 57 'prefs.ash.night_light.custom_end_time.*)',
57 ], 58 ],
58 59
59 keyBindings: { 60 keyBindings: {
60 'left': 'onLeftKey_', 61 'left': 'onLeftKey_',
61 'right': 'onRightKey_', 62 'right': 'onRightKey_',
62 }, 63 },
63 64
64 ready: function() { 65 ready: function() {
dpapad 2017/06/20 17:35:19 Missing annotation: @override
afakhry 2017/06/20 19:59:54 Done.
65 // Build the legend markers. 66 // Build the legend markers.
66 var markersContainer = this.$.markersContainer; 67 var markersContainer = this.$.markersContainer;
67 var width = markersContainer.offsetWidth; 68 var width = markersContainer.offsetWidth;
68 for (var i = 0; i <= HOURS_PER_DAY; ++i) { 69 for (var i = 0; i <= HOURS_PER_DAY; ++i) {
69 var marker = document.createElement('div'); 70 var marker = document.createElement('div');
70 marker.className = 'markers'; 71 marker.className = 'markers';
71 markersContainer.appendChild(marker); 72 markersContainer.appendChild(marker);
72 marker.style.left = (i * 100 / HOURS_PER_DAY) + '%'; 73 marker.style.left = (i * 100 / HOURS_PER_DAY) + '%';
73 } 74 }
75
76 this.$.startKnob.addEventListener('focus', this.onFocus_.bind(this));
dpapad 2017/06/20 01:24:47 Why are those listeners added programmatically ins
afakhry 2017/06/20 19:59:54 I have no idea. I tried that at first, but Chrome
dpapad 2017/06/20 20:39:09 That means that the declarative syntax was most li
afakhry 2017/06/20 20:50:09 Oh, I was using onfocus="onFocus_" instead of on-f
77 this.$.startKnob.addEventListener('blur', this.onBlur_.bind(this));
78 this.$.endKnob.addEventListener('focus', this.onFocus_.bind(this));
79 this.$.endKnob.addEventListener('blur', this.onBlur_.bind(this));
80
74 this.async(function() { 81 this.async(function() {
75 // Read the initial prefs values and refresh the slider. 82 // Read the initial prefs values and refresh the slider.
76 this.customTimesChanged_(); 83 this.customTimesChanged_();
77 }); 84 });
78 }, 85 },
79 86
80 /** 87 /**
81 * Expands or un-expands the knob being dragged along with its corresponding 88 * Expands or un-expands the knob being dragged along with its corresponding
82 * label bubble. 89 * label bubble.
83 * @param {boolean} expand True to expand, and false to un-expand. 90 * @param {boolean} expand True to expand, and false to un-expand.
(...skipping 20 matching lines...) Expand all
104 if (activeElement == this.$.startKnob || activeElement == this.$.endKnob) 111 if (activeElement == this.$.startKnob || activeElement == this.$.endKnob)
105 activeElement.blur(); 112 activeElement.blur();
106 }, 113 },
107 114
108 /** 115 /**
109 * Start dragging the target knob. 116 * Start dragging the target knob.
110 * @private 117 * @private
111 */ 118 */
112 startDrag_: function(event) { 119 startDrag_: function(event) {
113 event.preventDefault(); 120 event.preventDefault();
114 this.dragObject_ = event.target; 121
122 // Only handle start or end knobs. Use the "knob-inner" divs just to display
123 // the knobs.
124 if (event.target == this.$.startKnob ||
125 event.target == this.$.startKnob.firstElementChild) {
126 this.dragObject_ = this.$.startKnob;
dpapad 2017/06/20 01:24:47 Is dragObject_ used in the HTML? If not, there is
afakhry 2017/06/20 19:59:54 Sorry, I'm not very familiar with javascript. What
dpapad 2017/06/20 20:39:09 See example https://cs.chromium.org/chromium/src/c
afakhry 2017/06/20 20:50:09 Thanks for the pointer and the explanation. Done.
127 } else if (event.target == this.$.endKnob ||
128 event.target == this.$.endKnob.firstElementChild) {
129 this.dragObject_ = this.$.endKnob;
130 } else {
131 return;
132 }
133
115 this.setExpanded_(true); 134 this.setExpanded_(true);
116 135
117 // Focus is only given to the knobs by means of keyboard tab navigations. 136 // Focus is only given to the knobs by means of keyboard tab navigations.
118 // When we start dragging, we don't want to see any focus halos around any 137 // When we start dragging, we don't want to see any focus halos around any
119 // knob. 138 // knob.
120 this.blurAnyFocusedKnob_(); 139 this.blurAnyFocusedKnob_();
121 140
122 // However, our night-light-slider element must get the focus. 141 // However, our night-light-slider element must get the focus.
123 this.focus(); 142 this.focus();
124 }, 143 },
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 * @private 458 * @private
440 */ 459 */
441 onRightKey_: function(e) { 460 onRightKey_: function(e) {
442 e.preventDefault(); 461 e.preventDefault();
443 var knobPref = this.getFocusedKnobPrefPathIfAny_(); 462 var knobPref = this.getFocusedKnobPrefPathIfAny_();
444 if (!knobPref) 463 if (!knobPref)
445 return; 464 return;
446 465
447 this.incrementPref_(knobPref, 1); 466 this.incrementPref_(knobPref, 1);
448 }, 467 },
468
469 /**
470 * Checks if any of the two knobs is focused.
stevenjb 2017/06/20 00:31:44 s/any/either/ (Also, redundant comment not needed)
afakhry 2017/06/20 19:59:54 Done.
471 *
472 * @return {boolean} true if either of the two knobs is focused, false
473 * otherwise.
stevenjb 2017/06/20 00:31:44 s/false otherwise//
dpapad 2017/06/20 01:24:47 Or even shorter as follows: "Whether either of th
afakhry 2017/06/20 19:59:54 Done.
afakhry 2017/06/20 19:59:54 Done.
474 * @private
475 */
476 isEitherKnobFocused_: function() {
477 var activeElement = this.shadowRoot.activeElement;
478 return activeElement == this.$.startKnob || activeElement == this.$.endKnob;
479 },
480
481 /**
482 * Overrides _createRipple() from PaperInkyFocusBehavior to create the ripple
483 * only on a knob if it's focused, or on a dummy hidden element so that it
484 * doesn't show.
485 * @private
stevenjb 2017/06/20 00:31:44 @override
afakhry 2017/06/20 19:59:54 It doesn't actually override, but rather shadows t
dpapad 2017/06/20 20:39:09 I don't think @override works for inherited behavi
486 */
487 _createRipple: function() {
488 if (this.isEitherKnobFocused_()) {
489 this._rippleContainer = this.shadowRoot.activeElement;
490 } else {
491 // We can't just skip the ripple creation and return early with null here.
492 // The code inherited from PaperInkyFocusBehavior expects that this
493 // function return a ripple element. So to avoid crashes, we'll setup the
stevenjb 2017/06/20 00:31:44 returns
afakhry 2017/06/20 19:59:54 Done.
494 // ripple to be created under a hidden element.
495 this._rippleContainer = this.$.hidden;
stevenjb 2017/06/20 00:31:44 Ugh, this is kind of awkward. Can we just create a
dpapad 2017/06/20 17:35:19 Don't have a good suggestion.
afakhry 2017/06/20 19:59:54 If the ripple container is null, the behavior will
496 }
497
498 return Polymer.PaperInkyFocusBehaviorImpl._createRipple.call(this);
499 },
500
501 /**
502 * Handles focus events on the start and end knobs.
503 * @private
504 */
505 onFocus_: function() {
506 this.ensureRipple();
507
508 if (this.hasRipple()) {
509 this._ripple.style.display = '';
510 this._ripple.holdDown = true;
511 }
512 },
513
514 /**
515 * Handles blur events on the start and end knobs.
516 * @private
517 */
518 onBlur_: function() {
519 if (this.hasRipple()) {
520 this._ripple.remove();
521 this._ripple = null;
522 }
523 },
524
525 /** @private */
stevenjb 2017/06/20 00:31:44 @override; also, group the overrides together.
afakhry 2017/06/20 19:59:54 This is also not an override, but shadowing of the
526 _focusedChanged: function(receivedFocusFromKeyboard) {
527 // Overrides the _focusedChanged() from the PaperInkyFocusBehavior so that
528 // it does nothing. This function is called only once for the entire
529 // night-light-slider element even when focus is moved between the two
530 // knobs. This doesn't allow us to decide on which knob the ripple will be
531 // created. Hence we handle focus and blur explicitly above.
532 }
449 }); 533 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698