OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 }); |
OLD | NEW |