2014-08-12 11:55:34 +02:00
/ *
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 < http : //www.gnu.org/licenses/>.
* /
( function ( $ ) {
'use strict' ;
var uhrGlobals = {
"id" : 0 ,
"languages" : [ ] ,
"themes" : [ ] ,
registerLanguage : function registerLanguage ( code , language ) {
var alreadyExists = uhrGlobals . languages . some ( function ( element ) {
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 true ;
}
return false ;
} ) ;
if ( ! alreadyExists ) {
language . code = code ;
uhrGlobals . languages . push ( language ) ;
}
}
} ;
// auto-detect themes
$ ( 'link[rel=stylesheet]' ) . each ( function ( index , item ) {
var styleSheet = $ ( item ) ;
var styleClass = styleSheet . attr ( 'data-class' ) ;
if ( styleClass !== undefined ) {
var name = styleSheet . attr ( 'data-name' ) ;
if ( name === undefined ) {
name = styleClass ;
}
uhrGlobals . themes . push ( { 'styleClass' : styleClass , 'name' : name } ) ;
}
} ) ;
// fall-back if no theme was included
if ( uhrGlobals . themes . length === 0 ) {
uhrGlobals . themes . push ( { } ) ;
}
// public interface methods (exported later)
var start = function start ( ) {
if ( ! isOn . bind ( this ) ( ) ) {
this . timer = window . setInterval ( function ( ) {
this . options . time = new Date ( ) ;
update . bind ( this ) ( ) ;
} . bind ( this ) , 1000 ) ;
update . bind ( this ) ( ) ;
setCookie . bind ( this ) ( 'uhr-status' , 'on' ) ;
}
} ;
var stop = function stop ( ) {
if ( isOn . bind ( this ) ( ) ) {
window . clearInterval ( this . timer ) ;
this . timer = null ;
update . bind ( this ) ( ) ;
setCookie . bind ( this ) ( 'uhr-status' , 'off' ) ;
}
} ;
var toggle = function toggle ( ) {
if ( isOn . bind ( 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 . bind ( this ) ( ) , this . element . find ( '.letterarea' ) ) ;
renderer . render . bind ( this ) ( function ( ) {
this . currentMinute = - 1 ;
update . bind ( this ) ( ) ;
} . bind ( this ) ) ;
setCookie . bind ( this ) ( 'uhr-language' , languageKey ) ;
update . bind ( 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 . bind ( 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 . bind ( this ) ( ) ;
} ;
var setWidth = function setWidth ( width ) {
var e = this . element ;
e . css ( 'width' , width ) ;
var realWidth = e . width ( ) ;
e . width ( realWidth ) ;
e . height ( realWidth ) ;
e . css ( 'font-size' , ( realWidth / 40 ) + 'px' ) ;
} ;
// private interface methods
var create = function create ( ) {
this . id = uhrGlobals . id ++ ;
this . timer = null ;
this . currentMinute = - 1 ;
var userTime = this . options . time ;
if ( this . options . time === undefined ) {
this . options . time = new Date ( ) ;
}
setupHTML . bind ( this ) ( ) ;
wireFunctionality . bind ( this ) ( ) ;
if ( userTime !== undefined ) {
this . time ( userTime ) ;
}
} ;
// private helper methods (not exported)
var showConfigScreen = function showConfigScreen ( ) {
$ ( '#uhr-controlpanel' + this . id ) . fadeIn ( 'fast' ) ;
} ;
// set up
var setupHTML = function setupHTML ( ) {
var e = this . element ;
// Base clock area
e . addClass ( 'uhr' ) ;
e . empty ( ) ;
e . append ( '<span class="item dot dot1"></span>' ) ;
e . append ( '<span class="item dot dot2"></span>' ) ;
e . append ( '<span class="item dot dot3"></span>' ) ;
e . append ( '<span class="item dot dot4"></span>' ) ;
e . append ( '<div class="letterarea"></div>' ) ;
e . append ( '<div class="reflection"></div>' ) ;
setWidth . bind ( this ) ( this . options . width ) ;
if ( this . options . controls ) {
var configlink = $ ( '<a class="uhr-configlink" id="uhr-configlink' + this . id + '"></a>' ) ;
configlink . on ( 'click' , function ( ) {
showConfigScreen . bind ( this ) ( ) ;
} . bind ( this ) ) ;
e . after ( configlink ) ;
var controlpanel = $ ( '<div class="uhr-controlpanel" id="uhr-controlpanel' + this . id + '"></div>' ) ;
var content = $ ( '<div class="content"></div>' ) ;
controlpanel . append ( content ) ;
// on/off switch
var toggleSwitch = $ ( '<div class="onoffswitch" id="uhr-onoffswitch' + this . id + '"></div>' ) ;
toggleSwitch . append ( '<input type="checkbox" class="onoffswitch-checkbox" id="uhr-onoffswitch-checkbox' + this . id + '" checked="checked" />' ) ;
toggleSwitch . append ( '<label class="onoffswitch-label" for="uhr-onoffswitch-checkbox' + this . id + '">'
+ '<div class="onoffswitch-inner"></div>'
+ '<div class="onoffswitch-switch"></div>'
+ '</label>' ) ;
content . append ( toggleSwitch ) ;
// language chooser
if ( uhrGlobals . languages . length > 1 ) {
var languageChooser = $ ( '<select id="uhr-languagechooser' + this . id + '"></select>' ) ;
uhrGlobals . languages . forEach ( function ( item ) {
languageChooser . append ( '<option value="' + item . code + '">' + item . language + '</option>' ) ;
} ) ;
content . append ( languageChooser ) ;
}
// theme chooser
if ( uhrGlobals . themes . length > 1 ) {
var themeChooser = $ ( '<select id="uhr-themechooser' + this . id + '"></select>' ) ;
uhrGlobals . themes . forEach ( function ( item ) {
themeChooser . append ( '<option value="' + item . styleClass + '">' + item . name + '</option>' ) ;
} ) ;
content . append ( themeChooser ) ;
}
var closebutton = $ ( '<a class="uhr-closecontrolpanel" id="uhr-closecontrolpanel' + this . id + '"></a>' ) ;
closebutton . on ( 'click' , function ( ) {
$ ( '#uhr-controlpanel' + this . id ) . fadeOut ( 'fast' ) ;
} . bind ( this ) ) ;
content . append ( closebutton ) ;
e . after ( controlpanel ) ;
controlpanel . hide ( ) ;
}
} ;
var wireFunctionality = function wireFunctionality ( ) {
// on/off switch
var toggleSwitch = $ ( '#uhr-onoffswitch-checkbox' + this . id ) ;
toggleSwitch . on ( 'click' , function ( ) {
this . toggle ( ) ;
} . bind ( this ) ) ;
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 ( ) {
var languageKey = $ ( '#uhr-languagechooser' + this . id ) . val ( ) ;
this . language ( languageKey ) ;
} . bind ( this ) ) ;
var selectedLanguage = $ . cookie ( 'uhr-language' + this . id ) ;
if ( selectedLanguage === undefined || this . options . force ) {
selectedLanguage = this . options . language ;
}
var found = uhrGlobals . languages . some ( function ( item ) {
return selectedLanguage === item . code ;
} ) ;
if ( ! found ) {
var fallbackLanguage ;
if ( uhrGlobals . languages . length > 0 ) {
fallbackLanguage = uhrGlobals . languages [ 0 ] . code ;
} else {
fallbackLanguage = '' ;
}
console . warn ( "Language '" + selectedLanguage + "' not found! Using fallback '" + fallbackLanguage + "'" ) ;
selectedLanguage = fallbackLanguage ;
}
languageChooser . val ( selectedLanguage ) ;
this . options . language = "" ;
this . language ( selectedLanguage ) ;
// theme chooser
var themeChooser = $ ( '#uhr-themechooser' + this . id ) ;
themeChooser . on ( 'change' , function ( ) {
var themeKey = $ ( '#uhr-themechooser' + this . id ) . val ( ) ;
this . theme ( themeKey ) ;
} . bind ( this ) ) ;
var selectedTheme = $ . cookie ( 'uhr-theme' + this . id ) ;
if ( selectedTheme === undefined || this . options . force ) {
selectedTheme = this . options . theme ;
}
found = uhrGlobals . themes . some ( function ( item ) {
return selectedTheme === item . styleClass ;
} ) ;
if ( ! found ) {
var fallbackTheme = uhrGlobals . themes [ 0 ] . styleClass ;
console . warn ( "Theme '" + selectedTheme + "' not found! Using fallback '" + fallbackTheme + "'" ) ;
selectedTheme = fallbackTheme ;
}
themeChooser . val ( selectedTheme ) ;
this . options . theme = "" ;
this . theme ( selectedTheme ) ;
2014-08-12 19:19:37 +02:00
if ( this . options . autoresize ) {
$ ( window ) . on ( 'resize' , function ( ) {
var $e = this . element ;
var $parent = $e . parent ( ) ;
var $window = $ ( window ) ;
var parentWidth = $parent . width ( ) ;
var parentHeight = $parent . height ( ) ;
var windowWidth = $window . width ( ) ;
var windowHeight = $window . height ( ) ;
var size = Math . min ( parentWidth , parentHeight , windowWidth , windowHeight ) + 'px' ;
setWidth . bind ( this ) ( size ) ;
} . bind ( this ) ) ;
}
2014-08-12 11:55:34 +02:00
} ;
var setCookie = function setCookie ( 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 ) ;
} ;
// business logic
var isOn = function isOn ( ) {
return this . timer !== null ;
} ;
var update = function update ( ) {
if ( isOn . bind ( this ) ( ) ) {
var time = this . options . time ;
if ( ! language . bind ( this ) ( ) . hasOwnProperty ( 'seconds' ) ) {
if ( time . getMinutes ( ) === this . currentMinute ) {
return ;
}
this . currentMinute = time . getMinutes ( ) ;
}
show . bind ( this ) ( time ) ;
} else {
clear . bind ( this ) ( ) ;
this . currentMinute = - 1 ;
}
} ;
var show = function show ( time ) {
var second = getSecond . bind ( this ) ( time ) ;
var dotMinute = getDotMinute . bind ( this ) ( time ) ;
var hour = getHour . bind ( this ) ( time ) ;
var coarseMinute = getCoarseMinute . bind ( this ) ( time ) ;
clear . bind ( this ) ( ) ;
highlight . bind ( this ) ( 'on' ) ;
for ( var i = 1 ; i <= dotMinute ; i ++ ) {
highlight . bind ( this ) ( 'dot' + i ) ;
}
highlight . bind ( this ) ( 'second' + second ) ;
highlight . bind ( this ) ( 'minute' + coarseMinute ) ;
highlight . bind ( this ) ( 'hour' + hour ) ;
} ;
var highlight = function highlight ( itemClass ) {
this . element . find ( '.item.' + itemClass ) . addClass ( 'active' ) ;
} ;
var clear = function clear ( ) {
this . element . find ( '.item' ) . removeClass ( 'active' ) ;
} ;
var getSecond = function getSecond ( date ) {
if ( typeof language . bind ( this ) ( ) . getSeconds === 'function' ) {
return language . bind ( this ) ( ) . getSeconds ( date ) ;
}
return date . getSeconds ( ) ;
} ;
var getDotMinute = function getDotMinute ( date ) {
if ( typeof language . bind ( this ) ( ) . getDotMinute === 'function' ) {
return language . bind ( this ) ( ) . getDotMinute ( date ) ;
}
var minutes = date . getMinutes ( ) ;
return minutes % 5 ;
} ;
var getCoarseMinute = function getCoarseMinute ( date ) {
if ( typeof language . bind ( this ) ( ) . getCoarseMinute === 'function' ) {
return language . bind ( this ) ( ) . getCoarseMinute ( date ) ;
}
return date . getMinutes ( ) ;
} ;
var getHour = function getHour ( date ) {
if ( typeof language . bind ( this ) ( ) . getHour === 'function' ) {
return language . bind ( this ) ( ) . getHour ( date ) ;
}
var hour = date . getHours ( ) ;
if ( date . getMinutes ( ) >= 25 ) {
return ( hour + 1 ) % 24 ;
}
return hour ;
} ;
var language = function language ( ) {
var matchingLanguages = uhrGlobals . languages . filter ( function ( element ) {
return ( element . code === this . options . language ) ;
} , this ) ;
if ( matchingLanguages . length > 0 ) {
return matchingLanguages [ 0 ] ;
}
// fallback: return empty object
return { } ;
} ;
$ . widget ( "fritteli.uhr" , {
"options" : {
width : '100%' ,
status : 'on' ,
language : 'de_CH' ,
theme : uhrGlobals . themes [ 0 ] . styleClass ,
force : false ,
controls : true ,
2014-08-12 19:19:37 +02:00
cookiePath : undefined ,
autoresize : true
2014-08-12 11:55:34 +02:00
} ,
"start" : start ,
"stop" : stop ,
"toggle" : toggle ,
"language" : setLanguage ,
"theme" : setTheme ,
"time" : setTime ,
"width" : setWidth ,
// constructor method
"_create" : create
} ) ;
$ . fritteli . uhr . register = uhrGlobals . registerLanguage ;
/ * *
* 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 . render = function render ( beforeshow ) {
if ( layout . parsed === undefined ) {
switch ( layout . version ) {
case 2 :
var delegate = new UhrRendererV2Delegate ( layout ) ;
var parsedLayout = delegate . parse ( ) ;
Object . defineProperty ( layout , "parsed" , { "value" : parsedLayout , "writable" : false , "configurable" : false } ) ;
break ;
default :
console . warn ( "Unknown layout version: '" + layout . version + "'" ) ;
return ;
}
}
var letters = layout . parsed ;
renderarea . fadeOut ( 'fast' , function ( ) {
renderarea . empty ( ) ;
letters . forEach ( function ( line , index , array ) {
line . forEach ( function ( letter ) {
renderarea . append ( letter . toString ( ) ) ;
} ) ;
if ( index < array . length - 1 ) {
renderarea . append ( '<br/>' ) ;
}
} ) ;
if ( typeof beforeshow === 'function' ) {
beforeshow ( ) ;
}
renderarea . fadeIn ( 'fast' ) ;
} ) ;
} ;
}
function UhrRendererV2Delegate ( layout ) {
function parseArrayOrObject ( letters , styleClass , input ) {
if ( typeof input !== 'undefined' && input !== null ) {
if ( Array . isArray ( input ) ) {
input . forEach ( function ( item ) {
parseObject ( letters , styleClass , item ) ;
} ) ;
} else {
parseObject ( letters , styleClass , input ) ;
}
}
}
function parseObject ( letters , styleClass , object ) {
if ( typeof object !== 'undefined' && object !== null ) {
Object . keys ( object ) . forEach ( function ( y ) {
var highlightLetters = object [ y ] ;
highlightLetters . forEach ( function ( x ) {
letters [ y - 1 ] [ x - 1 ] . addStyle ( styleClass ) ;
} ) ;
} ) ;
}
}
function parseTimeDefinition ( letters , styleClass , definition ) {
if ( typeof definition !== 'undefined' && definition !== null ) {
Object . keys ( definition ) . forEach ( function ( listString ) {
var array = listString . split ( ',' ) ;
var highlightLetters = definition [ listString ] ;
array . forEach ( function ( item ) {
parseArrayOrObject ( letters , styleClass + item , highlightLetters ) ;
} ) ;
} ) ;
}
}
this . parse = function parse ( ) {
var letters = [ ] ;
layout . letters . forEach ( function ( string ) {
var line = [ ] ;
for ( var c = 0 ; c < string . length ; c ++ ) {
var character = new Letter ( string [ c ] ) ;
line . push ( character ) ;
}
letters . push ( line ) ;
} ) ;
parseArrayOrObject ( letters , 'on' , layout . permanent ) ;
parseTimeDefinition ( letters , 'second' , layout . seconds ) ;
parseTimeDefinition ( letters , 'minute' , layout . minutes ) ;
parseTimeDefinition ( letters , 'hour' , 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 ) {
var myValue = value ;
var myStyle = style || '' ;
this . addStyle = function ( style ) {
if ( myStyle === '' ) {
myStyle = style ;
} else {
myStyle += ' ' + style ;
}
} ;
this . toString = function ( ) {
return '<span class="item letter ' + myStyle + '">' + myValue + '</span>' ;
} ;
}
} ) ( jQuery ) ;