Bug 1325922 - Add arrows svg file and style month-year button for date picker r=mconley
authorScott Wu <scottcwwu@gmail.com>
Thu, 24 Nov 2016 16:45:28 +0800
changeset 328602 daeecaee4447252f5e1259b523061353671b98b4
parent 328601 c57d40c4c50df860b1b25b2b3a013029eec5f7ca
child 328603 ff26bfb05b6cbf05f35e7430ddf1052fd2f9fb4a
push id85493
push userkwierso@gmail.com
push dateTue, 10 Jan 2017 00:45:12 +0000
treeherdermozilla-inbound@7822749b1b14 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs1325922
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1325922 - Add arrows svg file and style month-year button for date picker r=mconley MozReview-Commit-ID: KH0nTr7kN2m
toolkit/content/datepicker.xhtml
toolkit/content/widgets/datepicker.js
toolkit/content/widgets/spinner.js
toolkit/content/widgets/timepicker.js
toolkit/themes/shared/datetimeinputpickers.css
toolkit/themes/shared/icons/calendar-arrows.svg
toolkit/themes/shared/jar.inc.mn
--- a/toolkit/content/datepicker.xhtml
+++ b/toolkit/content/datepicker.xhtml
@@ -11,27 +11,26 @@
   <script type="application/javascript" src="chrome://global/content/bindings/spinner.js"></script>
   <script type="application/javascript" src="chrome://global/content/bindings/calendar.js"></script>
   <script type="application/javascript" src="chrome://global/content/bindings/datepicker.js"></script>
 </head>
 <body>
   <div id="date-picker">
     <div class="calendar-container">
       <div class="nav">
-        <button class="left">&lt;</button>
-        <button class="right">&gt;</button>
+        <button class="left"/>
+        <button class="right"/>
       </div>
       <div class="week-header"></div>
       <div class="days-viewport">
         <div class="days-view"></div>
       </div>
     </div>
-    <div class="month-year">
-      <div class="month-year-label"></div>
-      <div class="month-year-arrow"></div>
+    <div class="month-year-container">
+      <button class="month-year"/>
     </div>
     <div class="month-year-view"></div>
   </div>
   <template id="spinner-template">
     <div class="spinner-container">
       <button class="up"/>
       <div class="spinner"></div>
       <button class="down"/>
--- a/toolkit/content/widgets/datepicker.js
+++ b/toolkit/content/widgets/datepicker.js
@@ -169,40 +169,53 @@ function DatePicker(context) {
       }, "*");
     },
 
     /**
      * Attach event listeners
      */
     _attachEventListeners() {
       window.addEventListener("message", this);
-      document.addEventListener("click", this);
+      document.addEventListener("mouseup", this, { passive: true });
+      document.addEventListener("mousedown", this);
     },
 
     /**
      * Handle events.
      *
      * @param  {Event} event
      */
     handleEvent(event) {
       switch (event.type) {
         case "message": {
           this.handleMessage(event);
           break;
         }
-        case "click": {
+        case "mousedown": {
+          // Use preventDefault to keep focus on input boxes
+          event.preventDefault();
+          event.target.setCapture();
+
           if (event.target == this.context.buttonLeft) {
+            event.target.classList.add("active");
             this.state.dateKeeper.setMonthByOffset(-1);
             this._update();
           } else if (event.target == this.context.buttonRight) {
+            event.target.classList.add("active");
             this.state.dateKeeper.setMonthByOffset(1);
             this._update();
           }
           break;
         }
+        case "mouseup": {
+          if (event.target == this.context.buttonLeft || event.target == this.context.buttonRight) {
+            event.target.classList.remove("active");
+          }
+
+        }
       }
     },
 
     /**
      * Handle postMessage events.
      *
      * @param {Event} event
      */
@@ -302,32 +315,34 @@ function DatePicker(context) {
      *          {Array<Object>} years
      *          {Function} toggleMonthPicker
      *         }
      */
     setProps(props) {
       this.context.monthYear.textContent = this.state.dateFormat(props.dateObj);
 
       if (props.isVisible) {
+        this.context.monthYear.classList.add("active");
         this.components.month.setState({
           value: props.month,
           items: props.months,
           isInfiniteScroll: true,
           isValueSet: this.state.isMonthSet,
           smoothScroll: !this.state.firstOpened
         });
         this.components.year.setState({
           value: props.year,
           items: props.years,
           isInfiniteScroll: false,
           isValueSet: this.state.isYearSet,
           smoothScroll: !this.state.firstOpened
         });
         this.state.firstOpened = false;
       } else {
+        this.context.monthYear.classList.remove("active");
         this.state.isMonthSet = false;
         this.state.isYearSet = false;
         this.state.firstOpened = true;
       }
 
       this.props = Object.assign(this.props, props);
     },
 
--- a/toolkit/content/widgets/spinner.js
+++ b/toolkit/content/widgets/spinner.js
@@ -261,21 +261,21 @@ function Spinner(props, context) {
         elements[index].className = item.enabled ? "" : "disabled";
       });
     },
 
     /**
      * Attach event listeners to the spinner and buttons.
      */
     _attachEventListeners() {
-      const { spinner } = this.elements;
+      const { spinner, container } = this.elements;
 
       spinner.addEventListener("scroll", this, { passive: true });
-      document.addEventListener("mouseup", this, { passive: true });
-      document.addEventListener("mousedown", this);
+      container.addEventListener("mouseup", this, { passive: true });
+      container.addEventListener("mousedown", this, { passive: true });
     },
 
     /**
      * Handle events
      * @param  {DOMEvent} event
      */
     handleEvent(event) {
       const { mouseState = {}, index, itemsView } = this.state;
@@ -283,19 +283,16 @@ function Spinner(props, context) {
       const { spinner, up, down } = this.elements;
 
       switch (event.type) {
         case "scroll": {
           this._onScroll();
           break;
         }
         case "mousedown": {
-          // Use preventDefault to keep focus on input boxes
-          event.preventDefault();
-          event.target.setCapture();
           this.state.mouseState = {
             down: true,
             layerX: event.layerX,
             layerY: event.layerY
           };
           if (event.target == up) {
             // An "active" class is needed to simulate :active pseudo-class
             // because element is not focused.
--- a/toolkit/content/widgets/timepicker.js
+++ b/toolkit/content/widgets/timepicker.js
@@ -211,29 +211,36 @@ function TimePicker(context) {
           isHourSet,
           isMinuteSet,
           isDayPeriodSet
         }
       }, "*");
     },
     _attachEventListeners() {
       window.addEventListener("message", this);
+      document.addEventListener("mousedown", this);
     },
 
     /**
      * Handle events.
      *
      * @param  {Event} event
      */
     handleEvent(event) {
       switch (event.type) {
         case "message": {
           this.handleMessage(event);
           break;
         }
+        case "mousedown": {
+          // Use preventDefault to keep focus on input boxes
+          event.preventDefault();
+          event.target.setCapture();
+          break;
+        }
       }
     },
 
     /**
      * Handle postMessage events.
      *
      * @param {Event} event
      */
--- a/toolkit/themes/shared/datetimeinputpickers.css
+++ b/toolkit/themes/shared/datetimeinputpickers.css
@@ -11,26 +11,28 @@
   --spinner-button-height: 1.2rem;
   --colon-width: 2rem;
   --day-period-spacing-width: 1rem;
   --calendar-width: 23.1rem;
   --date-picker-item-height: 2.4rem;
 
   --border: 0.1rem solid #D6D6D6;
   --border-radius: 0.3rem;
+  --border-active-color: #B1B1B1;
 
   --font-color: #191919;
   --fill-color: #EBEBEB;
 
   --selected-font-color: #FFFFFF;
   --selected-fill-color: #0996F8;
 
   --button-font-color: #858585;
   --button-font-color-hover: #4D4D4D;
   --button-font-color-active: #191919;
+  --button-fill-color-active: #D4D4D4;
 
   --weekday-font-color: #6C6C6C;
   --weekday-outside-font-color: #6C6C6C;
   --weekend-font-color: #DA4E44;
   --weekend-outside-font-color: #FF988F;
 
   --disabled-opacity: 0.2;
 }
@@ -41,44 +43,95 @@ html {
 
 body {
   margin: 0;
   color: var(--font-color);
   font: message-box;
   font-size: var(--font-size-default);
 }
 
+button {
+  -moz-appearance: none;
+  background: none;
+  border: none;
+}
+
 .nav {
   display: flex;
   width: var(--calendar-width);
   height: 2.4rem;
   margin-bottom: 0.8rem;
   justify-content: space-between;
 }
 
-.nav button {
-  -moz-appearance: none;
-  background: none;
-  border: none;
+.nav > button {
   width: 3rem;
   height: var(--date-picker-item-height);
+  filter: url("chrome://global/skin/filters.svg#fill");
+  fill: var(--button-font-color);
+}
+
+.nav > button:hover {
+  fill: var(--button-font-color-hover);
 }
 
-.month-year {
+.nav > button.active {
+  fill: var(--button-font-color-active);
+}
+
+.nav > button.left {
+  background: url("chrome://global/skin/icons/calendar-arrows.svg#left") no-repeat 50% 50%;
+}
+
+.nav > button.right {
+  background: url("chrome://global/skin/icons/calendar-arrows.svg#right") no-repeat 50% 50%;
+}
+
+.month-year-container {
   position: absolute;
   display: flex;
   justify-content: center;
   align-items: center;
   top: 0;
   left: 3rem;
   width: 17.1rem;
   height: var(--date-picker-item-height);
   z-index: 10;
 }
 
+button.month-year {
+  font-size: 1.3rem;
+  border: var(--border);
+  border-radius: 0.3rem;
+  padding: 0.2rem 2.6rem 0.2rem 1.2rem;
+}
+
+button.month-year:hover {
+  background: var(--fill-color);
+}
+
+button.month-year.active {
+  border-color: var(--border-active-color);
+  background: var(--button-fill-color-active);
+}
+
+button.month-year::after {
+  position: absolute;
+  content: "";
+  width: 2.6rem;
+  height: 1.6rem;
+  background: url("chrome://global/skin/icons/spinner-arrows.svg#down") no-repeat 50% 50%;
+  filter: url("chrome://global/skin/filters.svg#fill");
+  fill: var(--button-font-color);
+}
+
+button.month-year.active::after {
+  background: url("chrome://global/skin/icons/spinner-arrows.svg#up") no-repeat 50% 50%;
+}
+
 .month-year-view {
   position: absolute;
   z-index: 5;
   padding-top: 3.2rem;
   top: 0;
   left: 0;
   bottom: 0;
   width: var(--calendar-width);
@@ -182,19 +235,16 @@ body {
 
 .spinner-container {
   display: flex;
   flex-direction: column;
   width: var(--spinner-width);
 }
 
 .spinner-container > button {
-  -moz-appearance: none;
-  border: none;
-  background: none;
   height: var(--spinner-button-height);
   filter: url("chrome://global/skin/filters.svg#fill");
   fill: var(--button-font-color);
 }
 
 .spinner-container > button:hover {
   fill: var(--button-font-color-hover);
 }
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/shared/icons/calendar-arrows.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
+  <style>
+    path:not(:target) {
+      display: none;
+    }
+  </style>
+  <path id="right" d="M4.8 14L3 12.3 8.5 7 3 1.7 4.8 0 12 7"/>
+  <path id="left" d="M9.2 0L11 1.7 5.5 7 11 12.3 9.2 14 2 7"/>
+</svg>
--- a/toolkit/themes/shared/jar.inc.mn
+++ b/toolkit/themes/shared/jar.inc.mn
@@ -19,16 +19,17 @@ toolkit.jar:
   skin/classic/global/aboutReaderContent.css               (../../shared/aboutReaderContent.css)
 * skin/classic/global/aboutReaderControls.css              (../../shared/aboutReaderControls.css)
   skin/classic/global/aboutSupport.css                     (../../shared/aboutSupport.css)
   skin/classic/global/appPicker.css                        (../../shared/appPicker.css)
   skin/classic/global/config.css                           (../../shared/config.css)
   skin/classic/global/datetimeinputpickers.css             (../../shared/datetimeinputpickers.css)
   skin/classic/global/datetimepopup.css                    (../../shared/datetimepopup.css)
   skin/classic/global/filters.svg                          (../../shared/filters.svg)
+  skin/classic/global/icons/calendar-arrows.svg            (../../shared/icons/calendar-arrows.svg)
   skin/classic/global/icons/find-arrows.svg                (../../shared/icons/find-arrows.svg)
   skin/classic/global/icons/info.svg                       (../../shared/incontent-icons/info.svg)
   skin/classic/global/icons/input-clear.svg                (../../shared/icons/input-clear.svg)
   skin/classic/global/icons/loading.png                    (../../shared/icons/loading.png)
   skin/classic/global/icons/loading@2x.png                 (../../shared/icons/loading@2x.png)
   skin/classic/global/icons/spinner-arrows.svg             (../../shared/icons/spinner-arrows.svg)
   skin/classic/global/icons/menubutton-dropmarker.svg      (../../shared/icons/menubutton-dropmarker.svg)
   skin/classic/global/icons/warning.svg                    (../../shared/incontent-icons/warning.svg)