/* 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.options.time = new Date(); uhr._update(); }, 1000); this._update(); $.cookie('uhr-status' + this._id, 'on', {expires: 365, path: '/'}); } else { } }, stop: function() { if(this._isOn()) { window.clearInterval(this._timer); this._timer = null; this._update(); $.cookie('uhr-status' + this._id, 'off', {expires: 365, path: '/'}); } }, 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, path: '/'}); 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, path: '/'}); } }, time: function(time) { this._currentMinute = -1; if (time == null) { this.options.time = new Date(); } else { if (this._timer != null) { window.clearInterval(this._timer); } this.options.time = time; } this._update(); }, // private variables _id: -1, _timer: null, _currentMinute: -1, // private methods _isOn: function() { return this._timer !== null; }, _update: function() { if (this._isOn()) { var time = this.options.time; 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); } return date.getMinutes(); }, _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++; var userTime = this.options.time; if (this.options.time === undefined) { this.options.time = new Date(); } this._setupHTML(); this._wireFunctionality(); if (userTime !== undefined) { this.time(userTime); } }, _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; if (this.layout._parsed === undefined) { switch (this.layout.version) { case 2: var delegate = new _UhrRendererV2Delegate(this.layout); this.layout._parsed = delegate.parse(); break; default: console.warn("Unknown layout version: '" + this.layout.version + "'"); return; } } var letters = this.layout._parsed; this.renderarea.fadeOut('fast', function() { renderer.renderarea.empty(); for (var y = 0; y < letters.length; y++) { for (var x = 0; x < letters[y].length; x++) { var letter = letters[y][x]; renderer.renderarea.append(letter.toString()); } if (y < letters.length - 1) { renderer.renderarea.append('
'); } } if (typeof beforeshow === 'function') { beforeshow(); } renderer.renderarea.fadeIn('fast'); }); }; function _UhrRendererV2Delegate(layout) { this.layout = layout; this._parseArrayOrObject = function(letters, styleClass, input) { if (Array.isArray(input)) { for (var i = 0; i < input.length; i++) { this._parseObject(letters, styleClass, input[i]); } } else { this._parseObject(letters, styleClass, input); } } this._parseObject = function(letters, styleClass, object) { for (line in object) { if (object.hasOwnProperty(line)) { var highlightLetters = object[line]; for (var i = 0; i < highlightLetters.length; i++) { var x = highlightLetters[i] - 1; letters[line - 1][x].addStyle(styleClass); } } } } this._parseTimeDefinition = function(letters, styleClass, definition) { for (listString in definition) { if (definition.hasOwnProperty(listString)) { var array = listString.split(','); var highlightLetters = definition[listString]; for (var index = 0; index < array.length; index++) { this._parseArrayOrObject(letters, styleClass + array[index], highlightLetters); } } } } } _UhrRendererV2Delegate.prototype.parse = function() { var letters = []; for (var i = 0; i < this.layout.letters.length; i++) { var line = []; var string = this.layout.letters[i]; for (var c = 0; c < string.length; c++) { var character = new Letter(string[c]); line.push(character); } letters.push(line); } this._parseArrayOrObject(letters, 'on', this.layout.permanent); this._parseTimeDefinition(letters, 'minute', this.layout.minutes); this._parseTimeDefinition(letters, 'hour', this.layout.hours); return letters; }; /** * 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 ' + this.style; }; this.getValue = function() { return value; } this.addStyle = function(style) { if (this.style == '') { this.style = style; } else { this.style += ' ' + style; } } } Letter.prototype.toString = function letterToString() { return '' + this.getValue() + ''; };