/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ (function($) { "use strict"; if (window._uhr !== undefined) { return; } window._uhr = { id: 0, languages: [], themes: [] }; // auto-detect themes var styleSheets = $('head link[rel=stylesheet]'); for (var i = 0; i < styleSheets.length; i++) { var styleSheet = $(styleSheets[i]); var styleClass = styleSheet.attr('data-class'); if (styleClass !== undefined) { var name = styleSheet.attr('data-name'); if (name === undefined) { name = styleClass; } window._uhr.themes.push({'class': styleClass, 'name': name}); } } // fall-back if no theme was included if (window._uhr.themes.length == 0) { window._uhr.themes.push({}); } $.widget("fritteli.uhr", { options: { width: '100%', status: 'on', language: 'de_CH', theme: window._uhr.themes[0].class, force: false, controls: true }, start: function() { if (!this._isOn()) { var uhr = this; this._timer = window.setInterval(function() { uhr._update(); }, 1000); this._update(); $.cookie('uhr-status' + this._id, 'on', {expires: 365}); } else { } }, stop: function() { if(this._isOn()) { window.clearInterval(this._timer); this._timer = null; this._update(); $.cookie('uhr-status' + this._id, 'off', {expires: 365}); } }, toggle: function() { if(this._isOn()) { this.stop(); } else { this.start(); } }, language: function(languageKey) { if (languageKey !== this.options.language) { this.options.language = languageKey; var renderer = new UhrRenderer(this._language(), this.element.find('.letterarea')); var uhr = this; renderer.render(this, function() { uhr._currentMinute = -1; uhr._update(); }); $.cookie('uhr-language' + this._id, languageKey, {expires: 365}); this._update(); } }, theme: function(theme) { if (theme != this.options.theme) { this.element.removeClass(this.options.theme).addClass(theme); $('#uhr-onoffswitch' + this._id).removeClass(this.options.theme).addClass(theme); this.options.theme = theme; $.cookie('uhr-theme' + this._id, theme, {expires: 365}); } }, time: function(time) { this.options.time = time; if (time == null) { this._currentMinute = -1; this._update(); } else { if (this._timer != null) { window.clearInterval(this._timer); } var renderer = new UhrRenderer(this._language(), this.element.find('.letterarea')); var uhr = this; renderer.render(this, function() { uhr._show(time); }); } }, // private variables _id: -1, _timer: null, _currentMinute: -1, // private methods _isOn: function() { return this._timer !== null; }, _update: function() { if (this._isOn()) { var time = new Date(); if (time.getMinutes() == this._currentMinute) { return; } this._currentMinute = time.getMinutes(); this._show(time); } else { this._clear(); this._currentMinute = -1; } }, _show: function(time) { var dotMinute = this._getDotMinute(time); var hour = this._getHour(time); var coarseMinute = this._getCoarseMinute(time); this._clear(); this._highlight('on'); for (var i = 1; i <= dotMinute; i++) { this._highlight('dot' + i); } this._highlight('minute' + coarseMinute); hour = this._normalizeHour(hour); this._highlight('hour' + hour); if (coarseMinute == 0) { this._highlight('sharphour'); } }, _language: function() { return window._uhr.languages[this.options.language]; }, _highlight: function(itemClass) { this.element.find('.item.' + itemClass).addClass('active'); }, _clear: function() { this.element.find('.item').removeClass('active'); }, _getHour: function(date) { if (typeof this._language().getHour === 'function') { return this._language().getHour(date); } var hour = date.getHours(); if (date.getMinutes() >= 25) { return hour + 1; } return hour; }, _getCoarseMinute: function(date) { if (typeof this._language().getCoarseMinute === 'function') { return this._language().getCoarseMinute(date); } var minutes = date.getMinutes(); return minutes - this._getDotMinute(date); }, _getDotMinute: function(date) { if (typeof this._language().getDotMinute === 'function') { return this._language().getDotMinute(date); } var minutes = date.getMinutes(); return minutes % 5; }, _normalizeHour: function(hour) { if (hour > 12) { hour %= 12; } if (hour == 0) { return 12; } return hour; }, _create: function() { this._id = window._uhr.id++; this._setupHTML(); this._wireFunctionality(); if (this.options.time !== undefined) { this.time(this.options.time); } }, _setupHTML: function() { var e = this.element; // Base clock area e.addClass('uhr'); e.empty(); e.append(''); e.append(''); e.append(''); e.append(''); e.append('
'); e.append('
'); e.css('width', this.options.width); var realWidth = e.width(); e.width(realWidth); e.height(realWidth); e.css('font-size', (realWidth / 40) + 'px'); if (this.options.controls) { // on/off switch var toggleSwitch = $('
'); toggleSwitch.append(''); toggleSwitch.append(''); e.after(toggleSwitch); // language chooser var options = []; for (var code in window._uhr.languages) { if (window._uhr.languages.hasOwnProperty(code)) { var language = window._uhr.languages[code]; options.push(''); } } if (options.length > 1) { var languageChooser = $(''); for (var i = 0; i < options.length; i++) { languageChooser.append(options[i]); } e.after(languageChooser); } // theme chooser if (window._uhr.themes.length > 1) { var themeChooser = $(''); for (var i = 0; i < window._uhr.themes.length; i++) { var theme = window._uhr.themes[i]; themeChooser.append(''); } e.after(themeChooser); } } }, _wireFunctionality: function() { var uhr = this; // on/off switch var toggleSwitch = $('#uhr-onoffswitch-checkbox' + this._id); toggleSwitch.on('click', function() { uhr.toggle(); }); var status = $.cookie('uhr-status' + this._id); if (status == undefined || this.options.force) { status = this.options.status; } toggleSwitch.prop('checked', status == 'on'); if (status == 'on') { this.start(); } else { this.stop(); } // language chooser var languageChooser = $('#uhr-languagechooser' + this._id); languageChooser.on('change', function() { uhr.language(this.value); }); var selectedLanguage = $.cookie('uhr-language' + this._id); if (selectedLanguage == undefined || this.options.force) { selectedLanguage = this.options.language; } languageChooser.val(selectedLanguage); this.options.language = ""; this.language(selectedLanguage); // theme chooser var themeChooser = $('#uhr-themechooser' + this._id); themeChooser.on('change', function() { uhr.theme(this.value); }); var selectedTheme = $.cookie('uhr-theme' + this._id); if (selectedTheme == undefined || this.options.force) { selectedTheme = this.options.theme; } var found = false; for (var i = 0; i < window._uhr.themes.length; i++) { var styleClass = window._uhr.themes[i].class; if (selectedTheme == styleClass) { found = true; break; } } if (!found) { var fallback = window._uhr.themes[0].class; console.warn("Theme " + selectedTheme + " not found! Using fallback: " + fallback); selectedTheme = fallback; } themeChooser.val(selectedTheme); this.options.theme = ""; this.theme(selectedTheme); } }); })(jQuery); /** * Hilfsklasse zum Rendern der Uhr. * @param layout Layout-Objekt, das gerendert werden soll. * @param renderarea Das jQuery-gewrappte HTML-Element, auf dem gerendert werden soll. */ function UhrRenderer(layout, renderarea) { this.layout = layout; this.renderarea = renderarea; } UhrRenderer.prototype.render = function(uhr, beforeshow) { var renderer = this; this.renderarea.fadeOut('fast', function() { renderer.renderarea.empty(); for (var y = 0; y < renderer.layout.values.length; y++) { for (var x = 0; x < renderer.layout.values[y].length; x++) { var letter = renderer.layout.values[y][x]; renderer.renderarea.append(letter.toString()); } if (y < renderer.layout.values.length - 1) { renderer.renderarea.append('
'); } } if (typeof beforeshow === 'function') { beforeshow(); } renderer.renderarea.fadeIn('fast'); }); }; /** * Ein Buchstabe. Hilfsklasse für den Renderer und Inhalt der Layout-Arrays. * @param value Der Buchstabe, der Dargestellt werden soll. * @param style Die CSS-Styleklassen des Buchstabens. */ function Letter(value, style) { this.value = value; this.style = style || ''; this.getStyle = function() { return 'item letter ' + style; }; this.getValue = function() { return value; } } Letter.prototype.toString = function letterToString() { return '' + this.getValue() + ''; }; /** * Hilfsfunktion, um einen Buchstaben zu erzeugen. * * @param letter string: Der Buchstabe, der angezeigt werden soll * @param style string: CSS-Klasse(n) als String * @example l('I', 'is') erzeugt den Buchstaben 'I' mit der CSS-Styleklasse 'is' */ function l(letter, style) { return new Letter(letter, style); } /** * Hilfsfunktion, um einen Buchstaben zu erzeugen, der zu einem Stunden-Wort gehört. * * @param letter string: Der Buchstabe, der angezeigt werden soll * @param hours... integer: Eine Aufzählung von Stundenwerten, zu welchen der Buchstabe als aktiv angezeigt werden soll * @example h('Z', 2, 11) erzeugt den Buchstaben 'Z', der um 2:xx, 11:xx, 14:xx und 23:xx aktiv angezeigt wird */ function h(letter) { var style = ''; for (var i = 1; i < arguments.length; i++) { style += ' hour' + arguments[i]; } return l(letter, style); } /** * Hilfsfunktion, um einen Buchstaben zu erzeugen, der zu einem Minuten-Wort gehört. * * @param letter string: Der Buchstabe, der angezeigt werden soll * @param minutes... integer: Eine Aufzählung von Minutenwerten, zu welchen der Buchstabe als aktiv angezeigt werden soll * @example m('A', 5, 10, 15, 20, 35) erzeugt den Buchstaben 'A' der um :05, :10, :15, :20 und :35 aktiv angezeigt wird */ function m(letter) { var style = ''; for (var i = 1; i < arguments.length; i++) { style += ' minute' + arguments[i]; } return l(letter, style); }