diff --git a/js/uhr.js b/js/uhr.js index 25bd705..8e9044c 100644 --- a/js/uhr.js +++ b/js/uhr.js @@ -18,34 +18,32 @@ along with this program. If not, see . "id": 0, "languages": [], "themes": [], - register: function register(code, language) { - this.languages.reduce(function(element) { + registerLanguage: function registerLanguage(code, language) { + var alreadyExists = this.languages.reduce(function (exists, element) { + if (exists) { + return true; + } if (code === element.code) { console.error("Error: Language code '" + code + "' cannot be registered for language '" + language.language + "' because it is already registered for language '" + element.language + "'!"); - return false; + return true; } - return true; - }, true); + return false; + }, false); + if (!alreadyExists) { + language.code = code; + this.languages.push(language); + } } }; - if (window.uhr !== undefined) { - return; - } + if (window.uhr !== undefined) { + return; + } window.uhr = { id: 0, languages: [], themes: [], - register: function (code, language) { - for (var i = 0; i < this.languages.length; i++) { - if (code === this.languages[i].code) { - console.error('Error: Language code ' + code + ' cannot be registered for language "' + language.language + '" because it is already registered for language "' + this.languages[i].language + '"!'); - return false; - } - } - language.code = code; - this.languages.push(language); - } + register: uhrGlobals.registerLanguage }; // auto-detect themes var styleSheets = $('link[rel=stylesheet]'); @@ -64,293 +62,316 @@ along with this program. If not, see . 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].styleClass, - 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(); - this._setCookie('uhr-status', 'on'); - } else { - } - }, - stop: function () { - if (this._isOn()) { - window.clearInterval(this._timer); - this._timer = null; - this._update(); - this._setCookie('uhr-status', 'off'); - } - }, - 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(); - }); - this._setCookie('uhr-language', languageKey); - 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; - this._setCookie('uhr-theme', theme); - } - }, - 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); - this._highlight('hour' + hour); - }, - _language: function () { - for (var i = 0; i < window.uhr.languages.length; i++) { - var language = window.uhr.languages[i]; - if (language.code == this.options.language) { - return language; - } - } - // fallback: return empty object - return {}; - }, - _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) % 24; - } - 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; - }, - _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); + // public interface methods (exported later) + var start = function start() { + if (!isOn(this)) { + var uhr = this; + this._timer = window.setInterval(function uhrTimer() { + uhr.options.time = new Date(); + update(uhr); + }, 1000); + update(this); + setCookie(this, 'uhr-status', 'on'); + } + }; + var stop = function stop() { + if (isOn(this)) { + window.clearInterval(this._timer); + this._timer = null; + update(this); + setCookie(this, 'uhr-status', 'off'); + } + }; + var toggle = function toggle() { + if (isOn(this)) { + this.stop(); + } else { + this.start(); + } + }; + var setLanguage = function setLanugage(languageKey) { + if (languageKey !== this.options.language) { + this.options.language = languageKey; + var renderer = new UhrRenderer(language(this), this.element.find('.letterarea')); + var uhr = this; + renderer.render(this, function () { + uhr._currentMinute = -1; + update(uhr); + }); + setCookie(this, 'uhr-language', languageKey); + update(this); + } + }; + var setTheme = function setTheme(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; + setCookie(this, 'uhr-theme', theme); + } + }; + var setTime = function setTime(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; + } + update(this); + }; - // language chooser - if (window.uhr.languages.length > 1) { - var languageChooser = $(''); - for (var i = 0; i < window.uhr.languages.length; i++) { - var language = window.uhr.languages[i]; - languageChooser.append(''); - } - e.after(languageChooser); - } + // private interface methods + var create = function create() { + this._id = window.uhr.id++; + var userTime = this.options.time; + if (this.options.time === undefined) { + this.options.time = new Date(); + } + setupHTML(this); + wireFunctionality(this); + if (userTime !== undefined) { + this.time(userTime); + } + }; + // private helper methods (not exported) + // set up + var setupHTML = function setupHTML(uhr) { + var e = uhr.element; + // Base clock area + e.addClass('uhr'); + e.empty(); + e.append(''); + e.append(''); + e.append(''); + e.append(''); + e.append('
'); + e.append('
'); + e.css('width', uhr.options.width); + var realWidth = e.width(); + e.width(realWidth); + e.height(realWidth); + e.css('font-size', (realWidth / 40) + 'px'); - // 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; + if (uhr.options.controls) { + // on/off switch + var toggleSwitch = $('
'); + toggleSwitch.append(''); + toggleSwitch.append(''); + e.after(toggleSwitch); - // 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 + if (window.uhr.languages.length > 1) { + var languageChooser = $(''); + for (var i = 0; i < window.uhr.languages.length; i++) { + var language = window.uhr.languages[i]; + languageChooser.append(''); + } + e.after(languageChooser); + } - // 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; - } - var found = false; - for (var i = 0; i < window.uhr.languages.length; i++) { - var code = window.uhr.languages[i].code; - if (selectedLanguage === code) { - found = true; - break; - } - } - if (!found) { - var fallback; - if (window.uhr.languages.length > 0) { - fallback = window.uhr.languages[0].code; - } else { - fallback = ''; - } - console.warn("Language " + selectedLanguage + " not found! Using fallback: " + fallback); - selectedLanguage = fallback; - } - languageChooser.val(selectedLanguage); - this.options.language = ""; - this.language(selectedLanguage); + // 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); + } + } + }; + var wireFunctionality = function wireFunctionality(uhr) { - // 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; - } - found = false; - for (var i = 0; i < window.uhr.themes.length; i++) { - var styleClass = window.uhr.themes[i].styleClass; - if (selectedTheme === styleClass) { - found = true; - break; - } - } - if (!found) { - var fallback = window.uhr.themes[0].styleClass; - console.warn("Theme " + selectedTheme + " not found! Using fallback: " + fallback); - selectedTheme = fallback; - } - themeChooser.val(selectedTheme); - this.options.theme = ""; - this.theme(selectedTheme); - }, - _setCookie: function (cookieName, cookieValue) { - var options = {}; - if (this.options.cookiePath !== undefined) { - options = {expires: 365, path: this.options.cookiePath}; - } else { - options = {expires: 365}; - } - $.cookie(cookieName + this._id, cookieValue, options); - } - }); + // on/off switch + var toggleSwitch = $('#uhr-onoffswitch-checkbox' + uhr._id); + toggleSwitch.on('click', function () { + uhr.toggle(); + }); + var status = $.cookie('uhr-status' + uhr._id); + if (status === undefined || uhr.options.force) { + status = uhr.options.status; + } + toggleSwitch.prop('checked', status === 'on'); + if (status === 'on') { + uhr.start(); + } else { + uhr.stop(); + } + + // language chooser + var languageChooser = $('#uhr-languagechooser' + uhr._id); + languageChooser.on('change', function () { + uhr.language(this.value); + }); + var selectedLanguage = $.cookie('uhr-language' + uhr._id); + if (selectedLanguage === undefined || uhr.options.force) { + selectedLanguage = uhr.options.language; + } + var found = false; + for (var i = 0; i < window.uhr.languages.length; i++) { + var code = window.uhr.languages[i].code; + if (selectedLanguage === code) { + found = true; + break; + } + } + if (!found) { + var fallback; + if (window.uhr.languages.length > 0) { + fallback = window.uhr.languages[0].code; + } else { + fallback = ''; + } + console.warn("Language " + selectedLanguage + " not found! Using fallback: " + fallback); + selectedLanguage = fallback; + } + languageChooser.val(selectedLanguage); + uhr.options.language = ""; + uhr.language(selectedLanguage); + + // theme chooser + var themeChooser = $('#uhr-themechooser' + uhr._id); + themeChooser.on('change', function () { + uhr.theme(this.value); + }); + var selectedTheme = $.cookie('uhr-theme' + uhr._id); + if (selectedTheme === undefined || uhr.options.force) { + selectedTheme = uhr.options.theme; + } + found = false; + for (var i = 0; i < window.uhr.themes.length; i++) { + var styleClass = window.uhr.themes[i].styleClass; + if (selectedTheme === styleClass) { + found = true; + break; + } + } + if (!found) { + var fallback = window.uhr.themes[0].styleClass; + console.warn("Theme " + selectedTheme + " not found! Using fallback: " + fallback); + selectedTheme = fallback; + } + themeChooser.val(selectedTheme); + uhr.options.theme = ""; + uhr.theme(selectedTheme); + }; + var setCookie = function setCookie(uhr, cookieName, cookieValue) { + var options = {}; + if (uhr.options.cookiePath !== undefined) { + options = {expires: 365, path: uhr.options.cookiePath}; + } else { + options = {expires: 365}; + } + $.cookie(cookieName + uhr._id, cookieValue, options); + }; + + // business logic + var isOn = function isOn(uhr) { + return uhr._timer !== null; + }; + var update = function update(uhr) { + if (isOn(uhr)) { + var time = uhr.options.time; + if (time.getMinutes() === uhr._currentMinute) { + return; + } + uhr._currentMinute = time.getMinutes(); + show(uhr, time); + } else { + clear(uhr); + uhr._currentMinute = -1; + } + }; + var show = function show(uhr, time) { + var dotMinute = getDotMinute(uhr, time); + var hour = getHour(uhr, time); + var coarseMinute = getCoarseMinute(uhr, time); + clear(uhr); + highlight(uhr, 'on'); + for (var i = 1; i <= dotMinute; i++) { + highlight(uhr, 'dot' + i); + } + highlight(uhr, 'minute' + coarseMinute); + highlight(uhr, 'hour' + hour); + }; + var highlight = function highlight(uhr, itemClass) { + uhr.element.find('.item.' + itemClass).addClass('active'); + }; + var clear = function clear(uhr) { + uhr.element.find('.item').removeClass('active'); + }; + var getDotMinute = function getDotMinute(uhr, date) { + if (typeof language(uhr).getDotMinute === 'function') { + return language(uhr).getDotMinute(date); + } + var minutes = date.getMinutes(); + return minutes % 5; + }; + var getCoarseMinute = function getCoarseMinute(uhr, date) { + if (typeof language(uhr).getCoarseMinute === 'function') { + return language(uhr).getCoarseMinute(date); + } + return date.getMinutes(); + }; + var getHour = function getHour(uhr, date) { + if (typeof language(uhr).getHour === 'function') { + return language(uhr).getHour(date); + } + var hour = date.getHours(); + if (date.getMinutes() >= 25) { + return (hour + 1) % 24; + } + return hour; + }; + + var language = function language(uhr) { + var matchingLanguages = window.uhr.languages.filter(function (element) { + return (element.code === this.options.language) + }, uhr); + if (matchingLanguages.length > 0) { + return matchingLanguages[0]; + } + // fallback: return empty object + return {}; +/* for (var i = 0; i < window.uhr.languages.length; i++) { + var language = window.uhr.languages[i]; + if (language.code == uhr.options.language) { + return language; + } + } + // fallback: return empty object + return {};*/ + }; + + $.widget("fritteli.uhr", { + "options": { + width: '100%', + status: 'on', + language: 'de_CH', + theme: window.uhr.themes[0].styleClass, + force: false, + controls: true + }, + "start": start, + "stop": stop, + "toggle": toggle, + "language": setLanguage, + "theme": setTheme, + "time": setTime, + // constructor method + "_create": create, + // private variables + "_id": -1, + "_timer": null, + "_currentMinute": -1 + }); /** * Hilfsklasse zum Rendern der Uhr. * @param layout Layout-Objekt, das gerendert werden soll.