| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| cr.define('settime', function() { |
| /** |
| * TimeSetter handles a dialog to check and set system time. It can also |
| * include a timezone dropdown if timezoneId is provided. |
| * |
| * TimeSetter uses the system time to populate the controls initially and |
| * update them as the system time or timezone changes, and notifies Chrome |
| * when the user changes the time or timezone. |
| * @constructor |
| */ |
| function TimeSetter() {} |
| |
| cr.addSingletonGetter(TimeSetter); |
| |
| /** @const */ var BODY_PADDING_PX = 20; |
| /** @const */ var LABEL_PADDING_PX = 5; |
| |
| TimeSetter.prototype = { |
| /** |
| * Performs initial setup. |
| */ |
| initialize: function() { |
| // Store values for reverting inputs when the user's date/time is invalid. |
| this.prevValues_ = {}; |
| |
| // The build time doesn't include a timezone, so subtract 1 day to get a |
| // safe minimum date. |
| this.minDate_ = new Date(loadTimeData.getValue('buildTime')); |
| this.minDate_.setDate(this.minDate_.getDate() - 1); |
| |
| // Set the max date to the min date plus 20 years. |
| this.maxDate_ = new Date(this.minDate_); |
| this.maxDate_.setYear(this.minDate_.getFullYear() + 20); |
| |
| // Make sure the ostensible date is within this range. |
| var now = new Date(); |
| if (now > this.maxDate_) |
| this.maxDate_ = now; |
| else if (now < this.minDate_) |
| this.minDate_ = now; |
| |
| $('date').setAttribute('min', this.toHtmlValues_(this.minDate_).date); |
| $('date').setAttribute('max', this.toHtmlValues_(this.maxDate_).date); |
| |
| this.updateTime_(); |
| |
| // Show the timezone select if we have a timezone ID. |
| var currentTimezoneId = loadTimeData.getValue('currentTimezoneId'); |
| if (currentTimezoneId) { |
| this.setTimezone_(currentTimezoneId); |
| $('timezone-select').addEventListener( |
| 'change', this.onTimezoneChange_.bind(this), false); |
| $('timezone').hidden = false; |
| } |
| |
| this.sizeToFit_(); |
| |
| $('time').addEventListener('blur', this.onTimeBlur_.bind(this), false); |
| $('date').addEventListener('blur', this.onTimeBlur_.bind(this), false); |
| |
| $('set-time').addEventListener( |
| 'submit', this.onSubmit_.bind(this), false); |
| }, |
| |
| /** |
| * Sets the current timezone. |
| * @param {string} timezoneId The timezone ID to select. |
| * @private |
| */ |
| setTimezone_: function(timezoneId) { |
| $('timezone-select').value = timezoneId; |
| this.updateTime_(); |
| }, |
| |
| /** |
| * Updates the date/time controls to the current local time. |
| * Called initially, then called again once a minute. |
| * @private |
| */ |
| updateTime_: function() { |
| var now = new Date(); |
| |
| // Only update time controls if neither is focused. |
| if (document.activeElement.id != 'date' && |
| document.activeElement.id != 'time') { |
| var htmlValues = this.toHtmlValues_(now); |
| this.prevValues_.date = $('date').value = htmlValues.date; |
| this.prevValues_.time = $('time').value = htmlValues.time; |
| } |
| |
| window.clearTimeout(this.timeTimeout_); |
| |
| // Start timer to update these inputs every minute. |
| var secondsRemaining = 60 - now.getSeconds(); |
| this.timeTimeout_ = window.setTimeout(this.updateTime_.bind(this), |
| secondsRemaining * 1000); |
| }, |
| |
| /** |
| * Sets the system time from the UI. |
| * @private |
| */ |
| applyTime_: function() { |
| var date = $('date').valueAsDate; |
| date.setMilliseconds(date.getMilliseconds() + $('time').valueAsNumber); |
| |
| // Add timezone offset to get real time. |
| date.setMinutes(date.getMinutes() + date.getTimezoneOffset()); |
| |
| var seconds = Math.floor(date / 1000); |
| chrome.send('setTimeInSeconds', [seconds]); |
| }, |
| |
| /** |
| * Called when focus is lost on date/time controls. |
| * @param {Event} e The blur event. |
| * @private |
| */ |
| onTimeBlur_: function(e) { |
| if (e.target.validity.valid && e.target.value) { |
| // Make this the new fallback time in case of future invalid input. |
| this.prevValues_[e.target.id] = e.target.value; |
| this.applyTime_(); |
| } else { |
| // Restore previous value. |
| e.target.value = this.prevValues_[e.target.id]; |
| } |
| }, |
| |
| /** |
| * @param {Event} e The change event. |
| * @private |
| */ |
| onTimezoneChange_: function(e) { |
| chrome.send('setTimezone', [e.currentTarget.value]); |
| }, |
| |
| /** |
| * Closes the dialog window. |
| * @param {Event} e The submit event. |
| * @private |
| */ |
| onSubmit_: function(e) { |
| e.preventDefault(); |
| chrome.send('dialogClose'); |
| }, |
| |
| /** |
| * Resizes the window if necessary to show the entire contents. |
| * @private |
| */ |
| sizeToFit_: function() { |
| // Because of l10n, we should check that the vertical content can fit |
| // within the window. |
| if (window.innerHeight < document.body.scrollHeight) { |
| // Resize window to fit scrollHeight and the title bar. |
| var newHeight = document.body.scrollHeight + |
| window.outerHeight - window.innerHeight; |
| window.resizeTo(window.outerWidth, newHeight); |
| } |
| }, |
| |
| /** |
| * Builds date and time strings suitable for the values of HTML date and |
| * time elements. |
| * @param {Date} date The date object to represent. |
| * @return {{date: string, time: string}} Date is an RFC 3339 formatted date |
| * and time is an HH:MM formatted time. |
| * @private |
| */ |
| toHtmlValues_: function(date) { |
| // Get the current time and subtract the timezone offset, so the |
| // JSON string is in local time. |
| var localDate = new Date(date); |
| localDate.setMinutes(date.getMinutes() - date.getTimezoneOffset()); |
| return {date: localDate.toISOString().slice(0, 10), |
| time: localDate.toISOString().slice(11, 16)}; |
| }, |
| }; |
| |
| TimeSetter.setTimezone = function(timezoneId) { |
| TimeSetter.getInstance().setTimezone_(timezoneId); |
| }; |
| |
| TimeSetter.updateTime = function() { |
| TimeSetter.getInstance().updateTime_(); |
| }; |
| |
| return { |
| TimeSetter: TimeSetter |
| }; |
| }); |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| settime.TimeSetter.getInstance().initialize(); |
| }); |