Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
186 lines
4.7 KiB
JavaScript
Executable file
186 lines
4.7 KiB
JavaScript
Executable file
define(function(require, exports, module) {
|
|
'use strict';
|
|
|
|
var IntlHelper = require('shared/intl_helper');
|
|
var View = require('view');
|
|
var createDay = require('common/calc').createDay;
|
|
var timeObserver = require('time_observer');
|
|
|
|
var activeClass = View.ACTIVE;
|
|
|
|
IntlHelper.define('current-time', 'mozdatetime', {
|
|
hour: 'numeric',
|
|
minute: 'numeric',
|
|
dayperiod: false,
|
|
});
|
|
|
|
function CurrentTime(options) {
|
|
this._container = options.container;
|
|
// timespan can be injected later! this is just a convenience
|
|
this.timespan = options.timespan;
|
|
this._sticky = options.sticky;
|
|
this.activate = this.activate.bind(this);
|
|
this._tick = this._tick.bind(this);
|
|
}
|
|
module.exports = CurrentTime;
|
|
|
|
CurrentTime.prototype = {
|
|
_create: function() {
|
|
if (this.element) {
|
|
return;
|
|
}
|
|
|
|
this.element = document.createElement('div');
|
|
this.element.setAttribute('aria-hidden', true);
|
|
this.element.classList.add('md__current-time');
|
|
this._container.appendChild(this.element);
|
|
},
|
|
|
|
refresh: function() {
|
|
this._clearInterval();
|
|
|
|
if (this._previousOverlap) {
|
|
this._previousOverlap.classList.remove('is-hidden');
|
|
}
|
|
|
|
this._unmarkCurrentDay();
|
|
this._hide();
|
|
this.activate();
|
|
},
|
|
|
|
activate: function() {
|
|
if (!this.timespan.containsNumeric(Date.now())) {
|
|
this._maybeActivateInTheFuture();
|
|
return;
|
|
}
|
|
|
|
this._create();
|
|
this.element.classList.add(activeClass);
|
|
this._tick();
|
|
},
|
|
|
|
_maybeActivateInTheFuture: function() {
|
|
var now = Date.now();
|
|
var diff = this.timespan.start - now;
|
|
if (diff >= 0) {
|
|
// if timespan is in the "future" we make sure it will start rendering
|
|
// the current time as soon as it reaches 00:00:00 of the first day
|
|
// inside timespan (eg. current time is 2014-05-22T23:59:50 and user is
|
|
// viewing 2014-05-23 until past midnight)
|
|
this._clearInterval();
|
|
timeObserver.once('day', this.activate);
|
|
}
|
|
},
|
|
|
|
deactivate: function() {
|
|
this._clearInterval();
|
|
this._hide();
|
|
},
|
|
|
|
_hide: function() {
|
|
if (this.element) {
|
|
this.element.classList.remove(activeClass);
|
|
}
|
|
},
|
|
|
|
destroy: function() {
|
|
this.deactivate();
|
|
if (this.element) {
|
|
this._container.removeChild(this.element);
|
|
}
|
|
},
|
|
|
|
_clearInterval: function() {
|
|
timeObserver.off('day', this.activate);
|
|
timeObserver.off('minute', this._tick);
|
|
},
|
|
|
|
_tick: function() {
|
|
this._clearInterval();
|
|
if (!this.timespan.contains(new Date())) {
|
|
this.deactivate();
|
|
this._unmarkCurrentDay();
|
|
return;
|
|
}
|
|
this._render();
|
|
timeObserver.once('minute', this._tick);
|
|
},
|
|
|
|
_render: function() {
|
|
var now = new Date();
|
|
|
|
var formatter = IntlHelper.get('current-time');
|
|
this.element.textContent = formatter.format(now);
|
|
|
|
this.element.dataset.date = now;
|
|
this.element.dataset.l10nDateFormat = 'current-time';
|
|
this.element.id = 'current-time-indicator';
|
|
|
|
var hour = now.getHours();
|
|
var elapsedMinutes = (hour * 60) + now.getMinutes();
|
|
var totalMinutes = 24 * 60;
|
|
var percentage = ((elapsedMinutes / totalMinutes) * 100);
|
|
// we limit the position between 0.5-99.5% to avoid cropping the text
|
|
this.element.style.top = Math.max(Math.min(percentage, 99.5), 0.5) + '%';
|
|
|
|
this._checkOverlap(hour);
|
|
this._markCurrentDay(now);
|
|
},
|
|
|
|
_checkOverlap: function(hour) {
|
|
// we only need to check the current hour (with current design there is
|
|
// no way to overlap previous/next hours)
|
|
var displayHour = this._container.querySelector(
|
|
`.md__hour-${hour} .md__display-hour`
|
|
);
|
|
|
|
displayHour.classList.toggle('is-hidden', this._intersect(displayHour));
|
|
|
|
// just in case last time it checked was against a different hour
|
|
if (this._previousOverlap && this._previousOverlap !== displayHour) {
|
|
this._previousOverlap.classList.remove('is-hidden');
|
|
}
|
|
|
|
this._previousOverlap = displayHour;
|
|
},
|
|
|
|
_intersect: function(displayHour) {
|
|
var b1 = this.element.getBoundingClientRect();
|
|
var b2 = displayHour.getBoundingClientRect();
|
|
|
|
return (
|
|
b1.left <= b2.right &&
|
|
b2.left <= b1.right &&
|
|
b1.top <= b2.bottom &&
|
|
b2.top <= b1.bottom
|
|
);
|
|
},
|
|
|
|
_markCurrentDay: function(date) {
|
|
if (!this._sticky) {
|
|
return;
|
|
}
|
|
|
|
var day = createDay(date);
|
|
var selector = `.md__allday[data-date="${day}"] .md__day-name`;
|
|
var header = this._sticky.querySelector(selector);
|
|
|
|
if (header) {
|
|
header.classList.add('is-today');
|
|
}
|
|
|
|
if (this._previousHeader !== header) {
|
|
this._unmarkCurrentDay();
|
|
}
|
|
|
|
this._previousHeader = header;
|
|
},
|
|
|
|
_unmarkCurrentDay: function() {
|
|
if (this._previousHeader) {
|
|
this._previousHeader.classList.remove('is-today');
|
|
}
|
|
}
|
|
};
|
|
|
|
});
|