Lots of linting.

This commit is contained in:
Manuel Friedli 2019-05-10 01:18:32 +02:00
parent 0d33434dbf
commit a57c97e1a1
20 changed files with 206 additions and 173 deletions

View file

@ -1,6 +1,7 @@
{ {
"parserOptions": { "parserOptions": {
"ecmaVersion": 6, "ecmaVersion": 6,
"project": "./tsconfig.json",
"sourceType": "module" "sourceType": "module"
}, },
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
@ -10,7 +11,10 @@
"env": { "env": {
"browser": true "browser": true
}, },
"extends": "eslint:recommended", "extends": [
"plugin:@typescript-eslint/recommended",
"eslint:recommended"
],
"rules": { "rules": {
"curly": "error", "curly": "error",
"deprecation": true, "deprecation": true,
@ -30,6 +34,15 @@
"alphabetize": true "alphabetize": true
} }
], ],
"no-console": [
"error",
{
"allow": [
"warn",
"error"
]
}
],
"no-unused-vars": "off", "no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [ "@typescript-eslint/no-unused-vars": [
"error", "error",
@ -39,6 +52,20 @@
"ignoreRestSiblings": false "ignoreRestSiblings": false
} }
], ],
"@typescript-eslint/no-namespace": [
"error",
{
"allowDeclarations": true
}
],
"@typescript-eslint/no-parameter-properties": [
"error",
{
"allows": [
"private readonly"
]
}
],
"prefer-for-of": true, "prefer-for-of": true,
"semi": [ "semi": [
"error", "error",

View file

@ -16,10 +16,10 @@
import * as Cookies from 'js-cookie'; import * as Cookies from 'js-cookie';
export class CookieHandler { export class CookieHandler {
constructor(private widgetId: string, private cookiePath?: string) { public constructor(private readonly widgetId: string, private readonly cookiePath?: string) {
} }
getLayout(): string { public getLayout(): string {
const oldCookie = this.getCookie('uhr-language'); const oldCookie = this.getCookie('uhr-language');
if (oldCookie) { if (oldCookie) {
// aha, old cookie is set. migrate to new one! // aha, old cookie is set. migrate to new one!
@ -29,32 +29,31 @@ export class CookieHandler {
return this.getCookie('uhr-layout'); return this.getCookie('uhr-layout');
} }
setLayout(layout: string): void { public setLayout(layout: string): void {
this.setCookie('uhr-layout', layout); this.setCookie('uhr-layout', layout);
} }
getMode(): string { public getMode(): string {
return this.getCookie('uhr-mode'); return this.getCookie('uhr-mode');
} }
setMode(mode: string): void { public setMode(mode: string): void {
this.setCookie('uhr-mode', mode); this.setCookie('uhr-mode', mode);
} }
public getStatus(): string {
getStatus(): string {
return this.getCookie('uhr-status'); return this.getCookie('uhr-status');
} }
setStatus(status: string): void { public setStatus(status: string): void {
this.setCookie('uhr-status', status); this.setCookie('uhr-status', status);
} }
getTheme(): string { public getTheme(): string {
return this.getCookie('uhr-theme'); return this.getCookie('uhr-theme');
} }
setTheme(theme: string): void { public setTheme(theme: string): void {
this.setCookie('uhr-theme', theme); this.setCookie('uhr-theme', theme);
} }

View file

@ -20,9 +20,9 @@ export class Globals {
private static layouts: Layout[] = []; private static layouts: Layout[] = [];
private static themes: Theme[] = []; private static themes: Theme[] = [];
static registerTheme(name: string, styleClass: string): void { public static registerTheme(name: string, styleClass: string): void {
if (Globals.themes.some(value => value.name === name)) { if (Globals.themes.some((value): boolean => value.name === name)) {
console.log(`Theme with name '${name}' already registered; ignoring register request for styleClass '${styleClass}'.`); console.warn(`Theme with name '${name}' already registered; ignoring register request for styleClass '${styleClass}'.`);
} else { } else {
Globals.themes.push({ Globals.themes.push({
name, name,
@ -31,28 +31,28 @@ export class Globals {
} }
} }
static hasThemes(): boolean { public static hasThemes(): boolean {
return Globals.themes.length > 0; return Globals.themes.length > 0;
} }
static hasMultipleThemes(): boolean { public static hasMultipleThemes(): boolean {
return Globals.themes.length > 1; return Globals.themes.length > 1;
} }
static getFirstTheme(): Theme { public static getFirstTheme(): Theme {
return Globals.getTheme(0); return Globals.getTheme(0);
} }
static getTheme(index: number): Theme { public static getTheme(index: number): Theme {
return Globals.themes[index]; return Globals.themes[index];
} }
static getThemes(): Theme[] { public static getThemes(): Theme[] {
return Globals.themes; return Globals.themes;
} }
static registerLayout(layout: Layout): void { public static registerLayout(layout: Layout): void {
const available = !Globals.layouts.some(element => { const available = !Globals.layouts.some((element): boolean => {
if (layout.code === element.code) { if (layout.code === element.code) {
if (layout.prettyName !== element.prettyName) { if (layout.prettyName !== element.prettyName) {
console.error( console.error(
@ -62,27 +62,26 @@ export class Globals {
return true; return true;
} }
return false; return false;
} });
);
if (available) { if (available) {
Globals.layouts.push(layout); Globals.layouts.push(layout);
Globals.layouts.sort((a, b) => a.prettyName.localeCompare(b.prettyName)); Globals.layouts.sort((a, b): number => a.prettyName.localeCompare(b.prettyName));
} }
} }
static hasLayouts(): boolean { public static hasLayouts(): boolean {
return Globals.layouts.length > 0; return Globals.layouts.length > 0;
} }
static hasMultipleLayouts(): boolean { public static hasMultipleLayouts(): boolean {
return Globals.layouts.length > 1; return Globals.layouts.length > 1;
} }
static getFirstLayout(): Layout { public static getFirstLayout(): Layout {
return Globals.layouts[0]; return Globals.layouts[0];
} }
static getLayouts(): Layout[] { public static getLayouts(): Layout[] {
return Globals.layouts; return Globals.layouts;
} }
} }

View file

@ -19,17 +19,18 @@
* @param style Die CSS-Styleklassen des Buchstabens. * @param style Die CSS-Styleklassen des Buchstabens.
*/ */
export class Letter { export class Letter {
private readonly value: string; // private readonly value: string;
private style: string = ''; private style: string;
constructor(value: string, style?: string) { public constructor(private readonly value: string, style: string = '') {
this.value = value; this.value = value;
if (style) {
this.style = style; this.style = style;
} // if (style) {
// this.style = style;
// }
} }
addStyle(style: string): void { public addStyle(style: string): void {
if (this.style === '') { if (this.style === '') {
this.style = style; this.style = style;
} else { } else {
@ -37,7 +38,7 @@ export class Letter {
} }
} }
toString(): string { public toString(): string {
return `<span class="item letter ${this.style}">${this.value}</span>`; return `<span class="item letter ${this.style}">${this.value}</span>`;
} }
} }

View file

@ -19,10 +19,24 @@ import {Uhr} from './uhr';
import {WidgetPrototype} from './widget/widget-prototype'; import {WidgetPrototype} from './widget/widget-prototype';
import {autodetectThemes} from './theme-autodetector'; import {autodetectThemes} from './theme-autodetector';
declare namespace Fritteli {
interface Fritteli {
uhr: Uhr;
}
interface Uhr {
register: (layout: Layout) => void;
}
}
declare namespace $ {
const fritteli: Fritteli.Fritteli;
const widget: JQueryUI.Widget;
}
// First things first: discover included themes and register them // First things first: discover included themes and register them
autodetectThemes(); autodetectThemes();
$.widget('fritteli.uhr', { const widgetPrototype: WidgetPrototype = {
options: { options: {
width: '100%', width: '100%',
status: 'on', status: 'on',
@ -34,53 +48,40 @@ $.widget('fritteli.uhr', {
autoresize: true, autoresize: true,
mode: 'normal' mode: 'normal'
}, },
start: function () { start: function (): void {
this.__fritteli_uhr_instance.start(); this.__fritteli_uhr_instance.start();
}, },
stop: function () { stop: function (): void {
this.__fritteli_uhr_instance.stop(); this.__fritteli_uhr_instance.stop();
}, },
toggle: function () { toggle: function (): void {
this.__fritteli_uhr_instance.toggle(); this.__fritteli_uhr_instance.toggle();
}, },
language: function (key: string) { language: function (key: string): void {
this.__fritteli_uhr_instance.setLayout(key); this.__fritteli_uhr_instance.setLayout(key);
}, },
theme: function (styleClass: string) { theme: function (styleClass: string): void {
this.__fritteli_uhr_instance.setTheme(styleClass); this.__fritteli_uhr_instance.setTheme(styleClass);
}, },
time: function (time: Date) { time: function (time: Date): void {
this.__fritteli_uhr_instance.setTime(time); this.__fritteli_uhr_instance.setTime(time);
}, },
mode: function (mode: string) { mode: function (mode: string): void {
this.__fritteli_uhr_instance.setMode(mode); this.__fritteli_uhr_instance.setMode(mode);
}, },
width: function (width: string) { width: function (width: string): void {
this.__fritteli_uhr_instance.setWidth(width); this.__fritteli_uhr_instance.setWidth(width);
}, },
// constructor method // constructor method
_create: function () { _create: function (): void {
this.__fritteli_uhr_instance = new Uhr(this); this.__fritteli_uhr_instance = new Uhr(this);
}, },
// destructor method // destructor method
_destroy: function () { _destroy: function (): void {
this.__fritteli_uhr_instance.destroy(); this.__fritteli_uhr_instance.destroy();
}, },
__fritteli_uhr_instance: null __fritteli_uhr_instance: null
} as WidgetPrototype); };
$.widget('fritteli.uhr', widgetPrototype);
$.fritteli.uhr.register = Globals.registerLayout; $.fritteli.uhr.register = Globals.registerLayout;
declare namespace $ {
const fritteli: Fritteli.Fritteli;
const widget: JQueryUI.Widget;
}
declare namespace Fritteli {
interface Fritteli {
uhr: Uhr;
}
interface Uhr {
register: (layout: Layout) => void;
}
}

View file

@ -224,12 +224,12 @@ class LayoutRendererV2Delegate {
'59': [LayoutRendererV2Delegate.vorne5, LayoutRendererV2Delegate.hinten9] '59': [LayoutRendererV2Delegate.vorne5, LayoutRendererV2Delegate.hinten9]
}; };
constructor(private layout: Layout) { public constructor(private readonly layout: Layout) {
} }
public parse(): Letter[][] { public parse(): Letter[][] {
const letters: Letter[][] = []; const letters: Letter[][] = [];
this.layout.letters.forEach(lineString => { this.layout.letters.forEach((lineString: string): void => {
const line: Letter[] = []; const line: Letter[] = [];
for (let c = 0; c < lineString.length; c++) { for (let c = 0; c < lineString.length; c++) {
line.push(new Letter(lineString[c])); line.push(new Letter(lineString[c]));
@ -250,10 +250,10 @@ class LayoutRendererV2Delegate {
private parseObject(letters: Letter[][], styleClass: string, object: WordDefinition): void { private parseObject(letters: Letter[][], styleClass: string, object: WordDefinition): void {
if (typeof object !== 'undefined' && object !== null) { if (typeof object !== 'undefined' && object !== null) {
Object.keys(object) Object.keys(object)
.map(key => Number(key)) .map((key: string): number => Number(key))
.forEach( .forEach(
y => object[y].forEach( (y: number): void => object[y].forEach(
x => letters[y - 1][x - 1].addStyle(styleClass) (x: number): void => letters[y - 1][x - 1].addStyle(styleClass)
) )
); );
} }
@ -262,7 +262,7 @@ class LayoutRendererV2Delegate {
private parseArrayOrObject(letters: Letter[][], styleClass: string, input: WordDefinition | WordDefinition[]): void { private parseArrayOrObject(letters: Letter[][], styleClass: string, input: WordDefinition | WordDefinition[]): void {
if (typeof input !== 'undefined' && input !== null) { if (typeof input !== 'undefined' && input !== null) {
if (Array.isArray(input)) { if (Array.isArray(input)) {
input.forEach(item => this.parseObject(letters, styleClass, item)); input.forEach((item: WordDefinition): void => this.parseObject(letters, styleClass, item));
} else { } else {
this.parseObject(letters, styleClass, input); this.parseObject(letters, styleClass, input);
} }
@ -271,10 +271,10 @@ class LayoutRendererV2Delegate {
private parseTimeDefinition(letters: Letter[][], styleClass: string, definition: TimeDefinition): void { private parseTimeDefinition(letters: Letter[][], styleClass: string, definition: TimeDefinition): void {
if (typeof definition !== 'undefined' && definition !== null) { if (typeof definition !== 'undefined' && definition !== null) {
Object.keys(definition).forEach(listString => { Object.keys(definition).forEach((listString: string): void => {
const timeValues: string[] = listString.split(','); const timeValues: string[] = listString.split(',');
const highlightLetters: WordDefinition | WordDefinition[] = definition[listString]; const highlightLetters: WordDefinition | WordDefinition[] = definition[listString];
timeValues.forEach(timeValue => this.parseArrayOrObject(letters, styleClass + timeValue, highlightLetters)); timeValues.forEach((timeValue: string): void => this.parseArrayOrObject(letters, styleClass + timeValue, highlightLetters));
}); });
} }
} }
@ -286,10 +286,10 @@ class LayoutRendererV2Delegate {
* @param renderarea Das jQuery-gewrappte HTML-Element, auf dem gerendert werden soll. * @param renderarea Das jQuery-gewrappte HTML-Element, auf dem gerendert werden soll.
*/ */
export class LayoutRenderer { export class LayoutRenderer {
constructor(private layout: Layout, private renderarea: JQuery<HTMLElement>) { public constructor(private readonly layout: Layout, private readonly renderarea: JQuery<HTMLElement>) {
} }
render(beforeshow?: () => void): void { public render(beforeshow?: () => void): void {
if (this.layout.parsed === undefined) { if (this.layout.parsed === undefined) {
if (this.layout.version === 2) { if (this.layout.version === 2) {
const delegate: LayoutRendererV2Delegate = new LayoutRendererV2Delegate(this.layout); const delegate: LayoutRendererV2Delegate = new LayoutRendererV2Delegate(this.layout);
@ -305,10 +305,10 @@ export class LayoutRenderer {
} }
} }
const letters: Letter[][] = this.layout.parsed; const letters: Letter[][] = this.layout.parsed;
this.renderarea.fadeOut('fast', () => { this.renderarea.fadeOut('fast', (): void => {
this.renderarea.empty(); this.renderarea.empty();
letters.forEach((line, index, array) => { letters.forEach((line, index, array): void => {
line.forEach(letter => this.renderarea.append(letter.toString())); line.forEach((letter): JQuery<HTMLElement> => this.renderarea.append(letter.toString()));
if (index < array.length - 1) { if (index < array.length - 1) {
this.renderarea.append('<br/>'); this.renderarea.append('<br/>');
} }

View file

@ -73,11 +73,6 @@ export const Layout_de: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_de);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -87,3 +82,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_de);

View file

@ -70,11 +70,6 @@ export const Layout_de_CH: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_de_CH);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -84,3 +79,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_de_CH);

View file

@ -72,11 +72,6 @@ export const Layout_de_CH_genau: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_de_CH_genau);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -86,3 +81,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_de_CH_genau);

View file

@ -71,11 +71,6 @@ export const Layout_dk: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_dk);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -85,3 +80,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_dk);

View file

@ -28,7 +28,7 @@ const twentyfive: WordDefinition = {3: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]};
export const Layout_en: Layout = { export const Layout_en: Layout = {
code: 'en', code: 'en',
getHour: (time: Date) => { getHour: (time: Date): number => {
const hour = time.getHours(); const hour = time.getHours();
if (time.getMinutes() >= 35) { if (time.getMinutes() >= 35) {
return (hour + 1) % 24; return (hour + 1) % 24;
@ -81,11 +81,6 @@ export const Layout_en: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_en);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -95,3 +90,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_en);

View file

@ -28,7 +28,7 @@ const veinticinco: WordDefinition = {9: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]};
export const Layout_es: Layout = { export const Layout_es: Layout = {
code: 'es', code: 'es',
getHour: (time: Date) => { getHour: (time: Date): number => {
const hour = time.getHours(); const hour = time.getHours();
if (time.getMinutes() >= 35) { if (time.getMinutes() >= 35) {
return (hour + 1) % 24; return (hour + 1) % 24;
@ -80,11 +80,6 @@ export const Layout_es: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_es);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -94,3 +89,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_es);

View file

@ -29,7 +29,7 @@ const vingtcinq: WordDefinition = {9: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]};
export const Layout_fr: Layout = { export const Layout_fr: Layout = {
code: 'fr', code: 'fr',
getHour: (time: Date) => { getHour: (time: Date): number => {
const hour = time.getHours(); const hour = time.getHours();
if (time.getMinutes() >= 35) { if (time.getMinutes() >= 35) {
return (hour + 1) % 24; return (hour + 1) % 24;
@ -114,11 +114,6 @@ export const Layout_fr: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_fr);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -128,3 +123,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_fr);

View file

@ -28,7 +28,7 @@ const venticinque: WordDefinition = {9: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]};
export const Layout_it: Layout = { export const Layout_it: Layout = {
code: 'it', code: 'it',
getHour: (time: Date) => { getHour: (time: Date): number => {
const hour = time.getHours(); const hour = time.getHours();
if (time.getMinutes() >= 35) { if (time.getMinutes() >= 35) {
return (hour + 1) % 24; return (hour + 1) % 24;
@ -79,11 +79,6 @@ export const Layout_it: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_it);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -93,3 +88,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_it);

View file

@ -28,7 +28,7 @@ const uur: WordDefinition = {10: [9, 10, 11]};
export const Layout_nl: Layout = { export const Layout_nl: Layout = {
code: 'nl', code: 'nl',
getHour: (time: Date) => { getHour: (time: Date): number => {
const hour = time.getHours(); const hour = time.getHours();
if (time.getMinutes() >= 20) { if (time.getMinutes() >= 20) {
return (hour + 1) % 24; return (hour + 1) % 24;
@ -80,11 +80,6 @@ export const Layout_nl: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_nl);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -94,3 +89,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_nl);

View file

@ -28,7 +28,7 @@ const vinte: WordDefinition = {8: [1, 2, 3, 4, 5]};
export const Layout_pt: Layout = { export const Layout_pt: Layout = {
code: 'pt', code: 'pt',
getHour: (time: Date) => { getHour: (time: Date): number => {
const hour = time.getHours(); const hour = time.getHours();
if (time.getMinutes() >= 35) { if (time.getMinutes() >= 35) {
return (hour + 1) % 24; return (hour + 1) % 24;
@ -80,11 +80,6 @@ export const Layout_pt: Layout = {
version: 2 version: 2
}; };
$.fritteli.uhr.register(Layout_pt);
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
declare namespace Fritteli { declare namespace Fritteli {
interface Fritteli { interface Fritteli {
uhr: Uhr; uhr: Uhr;
@ -94,3 +89,8 @@ declare namespace Fritteli {
register: (layout: Layout) => void; register: (layout: Layout) => void;
} }
} }
declare namespace $ {
const fritteli: Fritteli.Fritteli;
}
$.fritteli.uhr.register(Layout_pt);

View file

@ -16,8 +16,8 @@
import * as $ from 'jquery'; import * as $ from 'jquery';
import {Globals} from './domain/globals'; import {Globals} from './domain/globals';
export function autodetectThemes() { export function autodetectThemes(): void {
$('link[rel=stylesheet]').each((index, item) => { $('link[rel=stylesheet]').each((index, item): void => {
const styleSheet = $(item); const styleSheet = $(item);
const styleClass: string = styleSheet.attr('data-class'); const styleClass: string = styleSheet.attr('data-class');
if (styleClass !== undefined) { if (styleClass !== undefined) {

View file

@ -15,17 +15,21 @@
import {CookieHandler} from './cookie-handler'; import {CookieHandler} from './cookie-handler';
import {Globals} from './domain/globals'; import {Globals} from './domain/globals';
import {Layout} from './domain/layout';
import {Options} from './widget/options'; import {Options} from './widget/options';
import {Theme} from './domain/theme';
import {Uhr} from './uhr'; import {Uhr} from './uhr';
declare var $: JQueryStatic;
export class UhrRenderer { export class UhrRenderer {
private cookieHandler: CookieHandler; private cookieHandler: CookieHandler;
constructor( public constructor(
private uhr: Uhr, private readonly uhr: Uhr,
private $element: JQuery<HTMLElement>, private readonly $element: JQuery<HTMLElement>,
private options: Options, private readonly options: Options,
private id: string private readonly id: string
) { ) {
this.cookieHandler = new CookieHandler(id, options.cookiePath); this.cookieHandler = new CookieHandler(id, options.cookiePath);
} }
@ -74,7 +78,7 @@ export class UhrRenderer {
// language chooser // language chooser
if (Globals.hasMultipleLayouts()) { if (Globals.hasMultipleLayouts()) {
const languageChooser = $(`<select id="uhr-languagechooser${this.id}"></select>`); const languageChooser = $(`<select id="uhr-languagechooser${this.id}"></select>`);
Globals.getLayouts().forEach(layout => { Globals.getLayouts().forEach((layout: Layout): void => {
languageChooser.append(`<option value="${layout.code}">${layout.prettyName}</option>`); languageChooser.append(`<option value="${layout.code}">${layout.prettyName}</option>`);
}); });
content.append(languageChooser); content.append(languageChooser);
@ -83,18 +87,18 @@ export class UhrRenderer {
// theme chooser // theme chooser
if (Globals.hasMultipleThemes()) { if (Globals.hasMultipleThemes()) {
const themeChooser = $(`<select id="uhr-themechooser${this.id}"></select>`); const themeChooser = $(`<select id="uhr-themechooser${this.id}"></select>`);
Globals.getThemes().forEach(theme => { Globals.getThemes().forEach((theme: Theme): void => {
themeChooser.append(`<option value="${theme.styleClass}">${theme.name}</option>`); themeChooser.append(`<option value="${theme.styleClass}">${theme.name}</option>`);
}); });
content.append(themeChooser); content.append(themeChooser);
} }
const closebutton: JQuery<HTMLElement> = $(`<a class="uhr-closecontrolpanel" id="uhr-closecontrolpanel${this.id}"></a>`); const closebutton: JQuery<HTMLElement> = $(`<a class="uhr-closecontrolpanel" id="uhr-closecontrolpanel${this.id}"></a>`);
closebutton.on({click: () => $(`#uhr-controlpanel${this.id}`).hide('fast')}); closebutton.on({click: (): JQuery<HTMLElement> => $(`#uhr-controlpanel${this.id}`).hide('fast')});
content.append(closebutton); content.append(closebutton);
this.$element.after(controlpanel); this.$element.after(controlpanel);
controlpanel.hide(); controlpanel.hide();
const configlink: JQuery<HTMLElement> = $(`<a class="uhr-configlink" id="uhr-configlink${this.id}"></a>`); const configlink: JQuery<HTMLElement> = $(`<a class="uhr-configlink" id="uhr-configlink${this.id}"></a>`);
configlink.on({click: () => this.toggleConfigScreen()}); configlink.on({click: (): void => this.toggleConfigScreen()});
this.$element.after(configlink); this.$element.after(configlink);
} }
} }
@ -102,7 +106,7 @@ export class UhrRenderer {
private wireFunctionality(): void { private wireFunctionality(): void {
// on/off switch // on/off switch
const toggleSwitch: JQuery<HTMLElement> = $(`#uhr-onoffswitch-checkbox${this.id}`); const toggleSwitch: JQuery<HTMLElement> = $(`#uhr-onoffswitch-checkbox${this.id}`);
toggleSwitch.on({click: () => this.uhr.toggle()}); toggleSwitch.on({click: (): void => this.uhr.toggle()});
let status = this.cookieHandler.getStatus(); let status = this.cookieHandler.getStatus();
if (status === undefined || this.options.force) { if (status === undefined || this.options.force) {
status = this.options.status; status = this.options.status;
@ -117,7 +121,7 @@ export class UhrRenderer {
// time mode switch // time mode switch
const modeSwitch: JQuery<HTMLElement> = $(`#uhr-modeswitch-checkbox${this.id}`); const modeSwitch: JQuery<HTMLElement> = $(`#uhr-modeswitch-checkbox${this.id}`);
modeSwitch.on({ modeSwitch.on({
click: () => { click: (): void => {
if (this.options.mode === 'seconds') { if (this.options.mode === 'seconds') {
this.uhr.setMode('normal'); this.uhr.setMode('normal');
} else { } else {
@ -140,7 +144,7 @@ export class UhrRenderer {
// language chooser // language chooser
const languageChooser: JQuery<HTMLElement> = $(`#uhr-languagechooser${this.id}`); const languageChooser: JQuery<HTMLElement> = $(`#uhr-languagechooser${this.id}`);
languageChooser.on({ languageChooser.on({
change: () => { change: (): void => {
const languageKey = $(`#uhr-languagechooser${this.id}`).val() as string; const languageKey = $(`#uhr-languagechooser${this.id}`).val() as string;
this.uhr.setLayout(languageKey); this.uhr.setLayout(languageKey);
} }
@ -149,7 +153,7 @@ export class UhrRenderer {
if (selectedLayout === undefined || this.options.force) { if (selectedLayout === undefined || this.options.force) {
selectedLayout = this.options.language; selectedLayout = this.options.language;
} }
let found = Globals.getLayouts().some(item => selectedLayout === item.code); let found = Globals.getLayouts().some((item: Layout): boolean => selectedLayout === item.code);
if (!found) { if (!found) {
let fallbackLanguage; let fallbackLanguage;
if (Globals.hasLayouts()) { if (Globals.hasLayouts()) {
@ -167,7 +171,7 @@ export class UhrRenderer {
// theme chooser // theme chooser
const themeChooser: JQuery<HTMLElement> = $(`#uhr-themechooser${this.id}`); const themeChooser: JQuery<HTMLElement> = $(`#uhr-themechooser${this.id}`);
themeChooser.on({ themeChooser.on({
change: () => { change: (): void => {
const themeKey = $(`#uhr-themechooser${this.id}`).val() as string; const themeKey = $(`#uhr-themechooser${this.id}`).val() as string;
this.uhr.setTheme(themeKey); this.uhr.setTheme(themeKey);
} }
@ -176,7 +180,7 @@ export class UhrRenderer {
if (selectedTheme === undefined || this.options.force) { if (selectedTheme === undefined || this.options.force) {
selectedTheme = this.options.theme; selectedTheme = this.options.theme;
} }
found = Globals.getThemes().some(item => selectedTheme === item.styleClass); found = Globals.getThemes().some((item: Theme): boolean => selectedTheme === item.styleClass);
if (!found) { if (!found) {
const fallbackTheme = Globals.getFirstTheme().styleClass; const fallbackTheme = Globals.getFirstTheme().styleClass;
console.warn(`Theme '${selectedTheme}' not found! Using fallback '${fallbackTheme}'.`); console.warn(`Theme '${selectedTheme}' not found! Using fallback '${fallbackTheme}'.`);
@ -187,7 +191,7 @@ export class UhrRenderer {
this.uhr.setTheme(selectedTheme); this.uhr.setTheme(selectedTheme);
if (this.options.autoresize) { if (this.options.autoresize) {
$(window).on({ $(window).on({
resize: () => { resize: (): void => {
const $parent: JQuery<HTMLElement> = this.$element.parent(); const $parent: JQuery<HTMLElement> = this.$element.parent();
const $window: JQuery<Window> = $(window); const $window: JQuery<Window> = $(window);
const parentWidth: number = $parent.width(); const parentWidth: number = $parent.width();
@ -201,7 +205,7 @@ export class UhrRenderer {
} }
} }
private toggleConfigScreen() { private toggleConfigScreen(): void {
$(`#uhr-controlpanel${this.id}`).toggle('fast'); $(`#uhr-controlpanel${this.id}`).toggle('fast');
} }
} }

View file

@ -13,6 +13,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import WidgetCommonProperties = JQueryUI.WidgetCommonProperties;
import {EMPTY_LAYOUT, Layout} from './domain/layout'; import {EMPTY_LAYOUT, Layout} from './domain/layout';
import {CookieHandler} from './cookie-handler'; import {CookieHandler} from './cookie-handler';
import {Globals} from './domain/globals'; import {Globals} from './domain/globals';
@ -20,6 +21,8 @@ import {LayoutRenderer} from './layout-renderer';
import {UhrRenderer} from './uhr-renderer'; import {UhrRenderer} from './uhr-renderer';
import {WidgetPrototype} from './widget/widget-prototype'; import {WidgetPrototype} from './widget/widget-prototype';
declare var $: JQueryStatic;
export class Uhr { export class Uhr {
private timer: number = null; private timer: number = null;
@ -27,7 +30,7 @@ export class Uhr {
private renderer: UhrRenderer; private renderer: UhrRenderer;
private cookieHandler: CookieHandler; private cookieHandler: CookieHandler;
constructor(private widgetInstance: WidgetPrototype) { public constructor(private readonly widgetInstance: WidgetPrototype & WidgetCommonProperties) {
const userTime = this.widgetInstance.options.time; const userTime = this.widgetInstance.options.time;
if (this.widgetInstance.options.time === undefined) { if (this.widgetInstance.options.time === undefined) {
this.widgetInstance.options.time = new Date(); this.widgetInstance.options.time = new Date();
@ -41,7 +44,7 @@ export class Uhr {
} }
} }
destroy(): void { public destroy(): void {
if (this.timer) { if (this.timer) {
window.clearInterval(this.timer); window.clearInterval(this.timer);
this.timer = null; this.timer = null;
@ -54,9 +57,9 @@ export class Uhr {
$(`#uhr-controlpanel${this.widgetInstance.uuid}`).remove(); $(`#uhr-controlpanel${this.widgetInstance.uuid}`).remove();
} }
start(): void { public start(): void {
if (!this.isOn()) { if (!this.isOn()) {
this.timer = window.setInterval(() => { this.timer = window.setInterval((): void => {
this.widgetInstance.options.time = new Date(); this.widgetInstance.options.time = new Date();
this.update(); this.update();
}, 1000); }, 1000);
@ -65,7 +68,7 @@ export class Uhr {
} }
} }
stop(): void { public stop(): void {
if (this.isOn()) { if (this.isOn()) {
window.clearInterval(this.timer); window.clearInterval(this.timer);
this.timer = null; this.timer = null;
@ -74,7 +77,7 @@ export class Uhr {
} }
} }
toggle(): void { public toggle(): void {
if (this.isOn()) { if (this.isOn()) {
this.stop(); this.stop();
} else { } else {
@ -82,11 +85,11 @@ export class Uhr {
} }
} }
setLayout(key: string): void { public setLayout(key: string): void {
if (key !== this.widgetInstance.options.language) { if (key !== this.widgetInstance.options.language) {
this.widgetInstance.options.language = key; this.widgetInstance.options.language = key;
const renderer = new LayoutRenderer(this.getCurrentLayout(), this.widgetInstance.element.find('.letterarea')); const renderer = new LayoutRenderer(this.getCurrentLayout(), this.widgetInstance.element.find('.letterarea'));
renderer.render(() => { renderer.render((): void => {
this.currentMinute = -1; this.currentMinute = -1;
this.update(); this.update();
}); });
@ -95,7 +98,7 @@ export class Uhr {
} }
} }
setTheme(styleClass: string): void { public setTheme(styleClass: string): void {
if (styleClass !== this.widgetInstance.options.theme) { if (styleClass !== this.widgetInstance.options.theme) {
this.widgetInstance.element.removeClass(this.widgetInstance.options.theme).addClass(styleClass); this.widgetInstance.element.removeClass(this.widgetInstance.options.theme).addClass(styleClass);
$(`#uhr-onoffswitch${this.widgetInstance.uuid}`).removeClass(this.widgetInstance.options.theme).addClass(styleClass); $(`#uhr-onoffswitch${this.widgetInstance.uuid}`).removeClass(this.widgetInstance.options.theme).addClass(styleClass);
@ -104,7 +107,7 @@ export class Uhr {
} }
} }
setTime(time: Date): void { public setTime(time: Date): void {
this.currentMinute = null; this.currentMinute = null;
if (time === null) { if (time === null) {
this.widgetInstance.options.time = new Date(); this.widgetInstance.options.time = new Date();
@ -117,14 +120,14 @@ export class Uhr {
this.update(); this.update();
} }
setMode(mode: string): void { public setMode(mode: string): void {
this.widgetInstance.options.mode = mode; this.widgetInstance.options.mode = mode;
this.currentMinute = null; this.currentMinute = null;
this.update(); this.update();
this.cookieHandler.setMode(mode); this.cookieHandler.setMode(mode);
} }
setWidth(width: string): void { public setWidth(width: string): void {
this.renderer.setWidth(width); this.renderer.setWidth(width);
} }
@ -212,7 +215,7 @@ export class Uhr {
hash = hash.substring(1); hash = hash.substring(1);
hash = decodeURIComponent(hash); hash = decodeURIComponent(hash);
const params: string[] = hash.split('&'); const params: string[] = hash.split('&');
params.forEach(element => { params.forEach((element: string): void => {
const pair: string[] = element.split('='); const pair: string[] = element.split('=');
const key = pair[0]; const key = pair[0];
const value = pair[1]; const value = pair[1];
@ -243,7 +246,7 @@ export class Uhr {
} }
private getCurrentLayout(): Layout { private getCurrentLayout(): Layout {
const matchingLanguages: Layout[] = Globals.getLayouts().filter(element => element.code === this.widgetInstance.options.language, this); const matchingLanguages: Layout[] = Globals.getLayouts().filter((element: Layout): boolean => element.code === this.widgetInstance.options.language, this);
if (matchingLanguages.length > 0) { if (matchingLanguages.length > 0) {
return matchingLanguages[0]; return matchingLanguages[0];
} }

View file

@ -13,11 +13,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import WidgetCommonProperties = JQueryUI.WidgetCommonProperties;
import {Options} from './options'; import {Options} from './options';
import {Uhr} from '../uhr'; import {Uhr} from '../uhr';
export interface WidgetPrototype extends WidgetCommonProperties { export interface WidgetPrototype {
options: Options; options: Options;
start: () => void; start: () => void;
stop: () => void; stop: () => void;