internationalise settings and controls

This commit is contained in:
Kuldeep M 2022-01-21 10:12:49 +00:00 committed by GitHub
parent 487d0a788e
commit c18430f486
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
69 changed files with 48772 additions and 1029 deletions

View File

@ -1,99 +1,113 @@
const accentPreset = {}; import { message } from '../message';
export const accentPreset = {};
accentPreset.get = () => { accentPreset.get = () => {
return [
{ name: 'Grey', prefix: 'Super extra light', type: 'grey', hsl: { h: 0, s: 0, l: 90 } },
{ name: 'Grey', prefix: 'Extra light', type: 'grey', hsl: { h: 0, s: 0, l: 77 } },
{ name: 'Grey', prefix: 'Light', type: 'grey', hsl: { h: 0, s: 0, l: 63 } },
{ name: 'Grey', prefix: false, type: 'grey', hsl: { h: 0, s: 0, l: 50 } },
{ name: 'Grey', prefix: 'Dark', type: 'grey', hsl: { h: 0, s: 0, l: 37 } },
{ name: 'Grey', prefix: 'Extra dark', type: 'grey', hsl: { h: 0, s: 0, l: 23 } },
{ name: 'Grey', prefix: 'Super extra dark', type: 'grey', hsl: { h: 0, s: 0, l: 10 } },
{ name: 'Red', prefix: 'Super extra light', type: 'primary', hsl: { h: 0, s: 40, l: 90 } },
{ name: 'Red', prefix: 'Extra light', type: 'primary', hsl: { h: 0, s: 60, l: 77 } },
{ name: 'Red', prefix: 'Light', type: 'primary', hsl: { h: 0, s: 80, l: 63 } },
{ name: 'Red', prefix: false, type: 'primary', hsl: { h: 0, s: 100, l: 50 } },
{ name: 'Red', prefix: 'Dark', type: 'primary', hsl: { h: 0, s: 80, l: 37 } },
{ name: 'Red', prefix: 'Extra dark', type: 'primary', hsl: { h: 0, s: 60, l: 23 } },
{ name: 'Red', prefix: 'Super extra dark', type: 'primary', hsl: { h: 0, s: 40, l: 10 } },
{ name: 'Orange', prefix: 'Super extra light', type: 'secondary', hsl: { h: 30, s: 40, l: 90 } },
{ name: 'Orange', prefix: 'Extra light', type: 'secondary', hsl: { h: 30, s: 60, l: 77 } },
{ name: 'Orange', prefix: 'Light', type: 'secondary', hsl: { h: 30, s: 80, l: 63 } },
{ name: 'Orange', prefix: false, type: 'secondary', hsl: { h: 30, s: 100, l: 50 } },
{ name: 'Orange', prefix: 'Dark', type: 'secondary', hsl: { h: 30, s: 80, l: 37 } },
{ name: 'Orange', prefix: 'Extra dark', type: 'secondary', hsl: { h: 30, s: 60, l: 23 } },
{ name: 'Orange', prefix: 'Super extra dark', type: 'secondary', hsl: { h: 30, s: 40, l: 10 } },
{ name: 'Yellow', prefix: 'Super extra light', type: 'primary', hsl: { h: 60, s: 40, l: 90 } },
{ name: 'Yellow', prefix: 'Extra light', type: 'primary', hsl: { h: 60, s: 60, l: 77 } },
{ name: 'Yellow', prefix: 'Light', type: 'primary', hsl: { h: 60, s: 80, l: 63 } },
{ name: 'Yellow', prefix: false, type: 'primary', hsl: { h: 60, s: 100, l: 50 } },
{ name: 'Yellow', prefix: 'Dark', type: 'primary', hsl: { h: 60, s: 80, l: 37 } },
{ name: 'Yellow', prefix: 'Extra dark', type: 'primary', hsl: { h: 60, s: 60, l: 23 } },
{ name: 'Yellow', prefix: 'Super extra dark', type: 'primary', hsl: { h: 60, s: 40, l: 10 } },
{ name: 'Lime', prefix: 'Super extra light', type: 'secondary', hsl: { h: 90, s: 40, l: 90 } },
{ name: 'Lime', prefix: 'Extra light', type: 'secondary', hsl: { h: 90, s: 60, l: 77 } },
{ name: 'Lime', prefix: 'Light', type: 'secondary', hsl: { h: 90, s: 80, l: 63 } },
{ name: 'Lime', prefix: false, type: 'secondary', hsl: { h: 90, s: 100, l: 50 } },
{ name: 'Lime', prefix: 'Dark', type: 'secondary', hsl: { h: 90, s: 80, l: 37 } },
{ name: 'Lime', prefix: 'Extra dark', type: 'secondary', hsl: { h: 90, s: 60, l: 23 } },
{ name: 'Lime', prefix: 'Super extra dark', type: 'secondary', hsl: { h: 90, s: 40, l: 10 } },
{ name: 'Green', prefix: 'Super extra light', type: 'primary', hsl: { h: 120, s: 40, l: 90 } },
{ name: 'Green', prefix: 'Extra light', type: 'primary', hsl: { h: 120, s: 60, l: 77 } },
{ name: 'Green', prefix: 'Light', type: 'primary', hsl: { h: 120, s: 80, l: 63 } },
{ name: 'Green', prefix: false, type: 'primary', hsl: { h: 120, s: 100, l: 50 } },
{ name: 'Green', prefix: 'Dark', type: 'primary', hsl: { h: 120, s: 80, l: 37 } },
{ name: 'Green', prefix: 'Extra dark', type: 'primary', hsl: { h: 120, s: 60, l: 23 } },
{ name: 'Green', prefix: 'Super extra dark', type: 'primary', hsl: { h: 120, s: 40, l: 10 } },
{ name: 'Aqua', prefix: 'Super extra light', type: 'secondary', hsl: { h: 150, s: 40, l: 90 } },
{ name: 'Aqua', prefix: 'Extra light', type: 'secondary', hsl: { h: 150, s: 60, l: 77 } },
{ name: 'Aqua', prefix: 'Light', type: 'secondary', hsl: { h: 150, s: 80, l: 63 } },
{ name: 'Aqua', prefix: false, type: 'secondary', hsl: { h: 150, s: 100, l: 50 } },
{ name: 'Aqua', prefix: 'Dark', type: 'secondary', hsl: { h: 150, s: 80, l: 37 } },
{ name: 'Aqua', prefix: 'Extra dark', type: 'secondary', hsl: { h: 150, s: 60, l: 23 } },
{ name: 'Aqua', prefix: 'Super extra dark', type: 'secondary', hsl: { h: 150, s: 40, l: 10 } },
{ name: 'Cyan', prefix: 'Super extra light', type: 'primary', hsl: { h: 180, s: 40, l: 90 } },
{ name: 'Cyan', prefix: 'Extra light', type: 'primary', hsl: { h: 180, s: 60, l: 77 } },
{ name: 'Cyan', prefix: 'Light', type: 'primary', hsl: { h: 180, s: 80, l: 63 } },
{ name: 'Cyan', prefix: false, type: 'primary', hsl: { h: 180, s: 100, l: 50 } },
{ name: 'Cyan', prefix: 'Dark', type: 'primary', hsl: { h: 180, s: 80, l: 37 } },
{ name: 'Cyan', prefix: 'Extra dark', type: 'primary', hsl: { h: 180, s: 60, l: 23 } },
{ name: 'Cyan', prefix: 'Super extra dark', type: 'primary', hsl: { h: 180, s: 40, l: 10 } },
{ name: 'Teal', prefix: 'Super extra light', type: 'secondary', hsl: { h: 210, s: 40, l: 90 } },
{ name: 'Teal', prefix: 'Extra light', type: 'secondary', hsl: { h: 210, s: 60, l: 77 } },
{ name: 'Teal', prefix: 'Light', type: 'secondary', hsl: { h: 210, s: 80, l: 63 } },
{ name: 'Teal', prefix: false, type: 'secondary', hsl: { h: 210, s: 100, l: 50 } },
{ name: 'Teal', prefix: 'Dark', type: 'secondary', hsl: { h: 210, s: 80, l: 37 } },
{ name: 'Teal', prefix: 'Extra dark', type: 'secondary', hsl: { h: 210, s: 60, l: 23 } },
{ name: 'Teal', prefix: 'Super extra dark', type: 'secondary', hsl: { h: 210, s: 40, l: 10 } },
{ name: 'Blue', prefix: 'Super extra light', type: 'primary', hsl: { h: 240, s: 40, l: 90 } },
{ name: 'Blue', prefix: 'Extra light', type: 'primary', hsl: { h: 240, s: 60, l: 77 } },
{ name: 'Blue', prefix: 'Light', type: 'primary', hsl: { h: 240, s: 80, l: 63 } },
{ name: 'Blue', prefix: false, type: 'primary', hsl: { h: 240, s: 100, l: 50 } },
{ name: 'Blue', prefix: 'Dark', type: 'primary', hsl: { h: 240, s: 80, l: 37 } },
{ name: 'Blue', prefix: 'Extra dark', type: 'primary', hsl: { h: 240, s: 60, l: 23 } },
{ name: 'Blue', prefix: 'Super extra dark', type: 'primary', hsl: { h: 240, s: 40, l: 10 } },
{ name: 'Purple', prefix: 'Super extra light', type: 'secondary', hsl: { h: 270, s: 40, l: 90 } },
{ name: 'Purple', prefix: 'Extra light', type: 'secondary', hsl: { h: 270, s: 60, l: 77 } },
{ name: 'Purple', prefix: 'Light', type: 'secondary', hsl: { h: 270, s: 80, l: 63 } },
{ name: 'Purple', prefix: false, type: 'secondary', hsl: { h: 270, s: 100, l: 50 } },
{ name: 'Purple', prefix: 'Dark', type: 'secondary', hsl: { h: 270, s: 80, l: 37 } },
{ name: 'Purple', prefix: 'Extra dark', type: 'secondary', hsl: { h: 270, s: 60, l: 23 } },
{ name: 'Purple', prefix: 'Super extra dark', type: 'secondary', hsl: { h: 270, s: 40, l: 10 } },
{ name: 'Magenta', prefix: 'Super extra light', type: 'primary', hsl: { h: 300, s: 40, l: 90 } },
{ name: 'Magenta', prefix: 'Extra light', type: 'primary', hsl: { h: 300, s: 60, l: 77 } },
{ name: 'Magenta', prefix: 'Light', type: 'primary', hsl: { h: 300, s: 80, l: 63 } },
{ name: 'Magenta', prefix: false, type: 'primary', hsl: { h: 300, s: 100, l: 50 } },
{ name: 'Magenta', prefix: 'Dark', type: 'primary', hsl: { h: 300, s: 80, l: 37 } },
{ name: 'Magenta', prefix: 'Extra dark', type: 'primary', hsl: { h: 300, s: 60, l: 23 } },
{ name: 'Magenta', prefix: 'Super extra dark', type: 'primary', hsl: { h: 300, s: 40, l: 10 } },
{ name: 'Fuchsia', prefix: 'Super extra light', type: 'secondary', hsl: { h: 330, s: 40, l: 90 } },
{ name: 'Fuchsia', prefix: 'Extra light', type: 'secondary', hsl: { h: 330, s: 60, l: 77 } },
{ name: 'Fuchsia', prefix: 'Light', type: 'secondary', hsl: { h: 330, s: 80, l: 63 } },
{ name: 'Fuchsia', prefix: false, type: 'secondary', hsl: { h: 330, s: 100, l: 50 } },
{ name: 'Fuchsia', prefix: 'Dark', type: 'secondary', hsl: { h: 330, s: 80, l: 37 } },
{ name: 'Fuchsia', prefix: 'Extra dark', type: 'secondary', hsl: { h: 330, s: 60, l: 23 } },
{ name: 'Fuchsia', prefix: 'Super extra dark', type: 'secondary', hsl: { h: 330, s: 40, l: 10 } },
];
};
export { accentPreset }; return [
{ name: message.get('menuContentThemeAccentPresetColorGrey'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'grey', hsl: { h: 0, s: 0, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorGrey'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'grey', hsl: { h: 0, s: 0, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorGrey'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'grey', hsl: { h: 0, s: 0, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorGrey'), prefix: false, type: 'grey', hsl: { h: 0, s: 0, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorGrey'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'grey', hsl: { h: 0, s: 0, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorGrey'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'grey', hsl: { h: 0, s: 0, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorGrey'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'grey', hsl: { h: 0, s: 0, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorRed'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'primary', hsl: { h: 0, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorRed'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'primary', hsl: { h: 0, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorRed'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'primary', hsl: { h: 0, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorRed'), prefix: false, type: 'primary', hsl: { h: 0, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorRed'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'primary', hsl: { h: 0, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorRed'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'primary', hsl: { h: 0, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorRed'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'primary', hsl: { h: 0, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorOrange'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'secondary', hsl: { h: 30, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorOrange'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'secondary', hsl: { h: 30, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorOrange'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'secondary', hsl: { h: 30, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorOrange'), prefix: false, type: 'secondary', hsl: { h: 30, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorOrange'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'secondary', hsl: { h: 30, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorOrange'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'secondary', hsl: { h: 30, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorOrange'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'secondary', hsl: { h: 30, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorYellow'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'primary', hsl: { h: 60, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorYellow'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'primary', hsl: { h: 60, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorYellow'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'primary', hsl: { h: 60, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorYellow'), prefix: false, type: 'primary', hsl: { h: 60, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorYellow'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'primary', hsl: { h: 60, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorYellow'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'primary', hsl: { h: 60, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorYellow'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'primary', hsl: { h: 60, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorLime'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'secondary', hsl: { h: 90, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorLime'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'secondary', hsl: { h: 90, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorLime'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'secondary', hsl: { h: 90, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorLime'), prefix: false, type: 'secondary', hsl: { h: 90, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorLime'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'secondary', hsl: { h: 90, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorLime'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'secondary', hsl: { h: 90, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorLime'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'secondary', hsl: { h: 90, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorGreen'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'primary', hsl: { h: 120, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorGreen'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'primary', hsl: { h: 120, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorGreen'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'primary', hsl: { h: 120, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorGreen'), prefix: false, type: 'primary', hsl: { h: 120, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorGreen'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'primary', hsl: { h: 120, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorGreen'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'primary', hsl: { h: 120, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorGreen'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'primary', hsl: { h: 120, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorAqua'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'secondary', hsl: { h: 150, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorAqua'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'secondary', hsl: { h: 150, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorAqua'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'secondary', hsl: { h: 150, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorAqua'), prefix: false, type: 'secondary', hsl: { h: 150, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorAqua'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'secondary', hsl: { h: 150, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorAqua'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'secondary', hsl: { h: 150, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorAqua'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'secondary', hsl: { h: 150, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorCyan'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'primary', hsl: { h: 180, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorCyan'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'primary', hsl: { h: 180, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorCyan'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'primary', hsl: { h: 180, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorCyan'), prefix: false, type: 'primary', hsl: { h: 180, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorCyan'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'primary', hsl: { h: 180, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorCyan'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'primary', hsl: { h: 180, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorCyan'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'primary', hsl: { h: 180, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorTeal'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'secondary', hsl: { h: 210, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorTeal'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'secondary', hsl: { h: 210, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorTeal'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'secondary', hsl: { h: 210, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorTeal'), prefix: false, type: 'secondary', hsl: { h: 210, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorTeal'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'secondary', hsl: { h: 210, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorTeal'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'secondary', hsl: { h: 210, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorTeal'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'secondary', hsl: { h: 210, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorBlue'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'primary', hsl: { h: 240, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorBlue'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'primary', hsl: { h: 240, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorBlue'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'primary', hsl: { h: 240, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorBlue'), prefix: false, type: 'primary', hsl: { h: 240, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorBlue'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'primary', hsl: { h: 240, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorBlue'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'primary', hsl: { h: 240, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorBlue'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'primary', hsl: { h: 240, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorPurple'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'secondary', hsl: { h: 270, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorPurple'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'secondary', hsl: { h: 270, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorPurple'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'secondary', hsl: { h: 270, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorPurple'), prefix: false, type: 'secondary', hsl: { h: 270, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorPurple'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'secondary', hsl: { h: 270, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorPurple'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'secondary', hsl: { h: 270, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorPurple'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'secondary', hsl: { h: 270, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorMagenta'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'primary', hsl: { h: 300, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorMagenta'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'primary', hsl: { h: 300, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorMagenta'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'primary', hsl: { h: 300, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorMagenta'), prefix: false, type: 'primary', hsl: { h: 300, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorMagenta'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'primary', hsl: { h: 300, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorMagenta'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'primary', hsl: { h: 300, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorMagenta'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'primary', hsl: { h: 300, s: 40, l: 10 } },
{ name: message.get('menuContentThemeAccentPresetColorFuchsia'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel3'), type: 'secondary', hsl: { h: 330, s: 40, l: 90 } },
{ name: message.get('menuContentThemeAccentPresetColorFuchsia'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel2'), type: 'secondary', hsl: { h: 330, s: 60, l: 77 } },
{ name: message.get('menuContentThemeAccentPresetColorFuchsia'), prefix: message.get('menuContentThemeAccentPresetModifierLightLevel1'), type: 'secondary', hsl: { h: 330, s: 80, l: 63 } },
{ name: message.get('menuContentThemeAccentPresetColorFuchsia'), prefix: false, type: 'secondary', hsl: { h: 330, s: 100, l: 50 } },
{ name: message.get('menuContentThemeAccentPresetColorFuchsia'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel1'), type: 'secondary', hsl: { h: 330, s: 80, l: 37 } },
{ name: message.get('menuContentThemeAccentPresetColorFuchsia'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel2'), type: 'secondary', hsl: { h: 330, s: 60, l: 23 } },
{ name: message.get('menuContentThemeAccentPresetColorFuchsia'), prefix: message.get('menuContentThemeAccentPresetModifierDarkLevel3'), type: 'secondary', hsl: { h: 330, s: 40, l: 10 } },
];
};

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { state } from '../state'; import { state } from '../state';
import { data } from '../data'; import { data } from '../data';
import { layout } from '../layout'; import { layout } from '../layout';
@ -359,9 +361,10 @@ bookmark.add = {
const bookmarkForm = new BookmarkForm({ bookmarkData: newBookmarkData }); const bookmarkForm = new BookmarkForm({ bookmarkData: newBookmarkData });
const addModal = new Modal({ const addModal = new Modal({
heading: 'Add a new Bookmark', heading: message.get('bookmarkAddHeading'),
content: bookmarkForm.form(), content: bookmarkForm.form(),
successText: 'Add', successText: message.get('bookmarkAddSuccessText'),
cancelText: message.get('bookmarkAddCancelText'),
width: (state.get.current().bookmark.style === 'block') ? 60 : 70, width: (state.get.current().bookmark.style === 'block') ? 60 : 70,
maxHeight: true, maxHeight: true,
openAction: () => { openAction: () => {

View File

@ -1,5 +1,5 @@
:root { :root {
--bookmark-form-space: calc((var(--form-space) / 4) * 1em); --bookmark-form-space: calc((var(--form-space) / 4) * 1.25em);
} }
.bookmark-form { .bookmark-form {
@ -17,12 +17,10 @@
} }
.bookmark-form-description { .bookmark-form-description {
margin-bottom: 3em; margin-bottom: var(--bookmark-form-space);
} }
.bookmark-form-main { .bookmark-form-main {}
padding-bottom: var(--bookmark-form-space);
}
.bookmark-form-aside { .bookmark-form-aside {
display: none; display: none;

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { bookmark } from '../bookmark'; import { bookmark } from '../bookmark';
import { bookmarkDefault } from '../bookmarkDefault'; import { bookmarkDefault } from '../bookmarkDefault';
import { bookmarkMinMax } from '../bookmarkMinMax'; import { bookmarkMinMax } from '../bookmarkMinMax';
@ -96,8 +98,8 @@ export const BookmarkForm = function({
path: 'url', path: 'url',
id: 'url', id: 'url',
value: bookmarkData.link.url, value: bookmarkData.link.url,
placeholder: 'https://www.example.com/', placeholder: message.get('bookmarkFormUrlPlaceholder'),
labelText: 'URL', labelText: message.get('bookmarkFormUrlLabel'),
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
} }
@ -106,17 +108,17 @@ export const BookmarkForm = function({
alignment: new Control_radioGrid({ alignment: new Control_radioGrid({
object: bookmarkData.link, object: bookmarkData.link,
radioGroup: [ radioGroup: [
{ id: 'toolbar-position-top-left', labelText: 'Top Left', value: 'top-left', position: 1 }, { id: 'toolbar-position-top-left', labelText: message.get('bookmarkFormDisplayAlignmentTopLeft'), value: 'top-left', position: 1 },
{ id: 'toolbar-position-top-center', labelText: 'Top Center', value: 'top-center', position: 2 }, { id: 'toolbar-position-top-center', labelText: message.get('bookmarkFormDisplayAlignmentTopCenter'), value: 'top-center', position: 2 },
{ id: 'toolbar-position-top-right', labelText: 'Top Right', value: 'top-right', position: 3 }, { id: 'toolbar-position-top-right', labelText: message.get('bookmarkFormDisplayAlignmentTopRight'), value: 'top-right', position: 3 },
{ id: 'toolbar-position-center-left', labelText: 'Center Left', value: 'center-left', position: 4 }, { id: 'toolbar-position-center-left', labelText: message.get('bookmarkFormDisplayAlignmentCenterLeft'), value: 'center-left', position: 4 },
{ id: 'toolbar-position-center-center', labelText: 'Center Center', value: 'center-center', position: 5 }, { id: 'toolbar-position-center-center', labelText: message.get('bookmarkFormDisplayAlignmentCenterCenter'), value: 'center-center', position: 5 },
{ id: 'toolbar-position-center-right', labelText: 'Center Right', value: 'center-right', position: 6 }, { id: 'toolbar-position-center-right', labelText: message.get('bookmarkFormDisplayAlignmentCenterRight'), value: 'center-right', position: 6 },
{ id: 'toolbar-position-bottom-left', labelText: 'Bottom Left', value: 'bottom-left', position: 7 }, { id: 'toolbar-position-bottom-left', labelText: message.get('bookmarkFormDisplayAlignmentBottomLeft'), value: 'bottom-left', position: 7 },
{ id: 'toolbar-position-bottom-center', labelText: 'Bottom Center', value: 'bottom-center', position: 8 }, { id: 'toolbar-position-bottom-center', labelText: message.get('bookmarkFormDisplayAlignmentBottomCenter'), value: 'bottom-center', position: 8 },
{ id: 'toolbar-position-bottom-right', labelText: 'Bottom Right', value: 'bottom-right', position: 9 } { id: 'toolbar-position-bottom-right', labelText: message.get('bookmarkFormDisplayAlignmentBottomRight'), value: 'bottom-right', position: 9 }
], ],
label: 'Visual Element and Name alignment', label: message.get('bookmarkFormDisplayAlignmentLabel'),
groupName: 'display-alignment', groupName: 'display-alignment',
path: 'display.alignment', path: 'display.alignment',
gridSize: '3x3', gridSize: '3x3',
@ -127,8 +129,8 @@ export const BookmarkForm = function({
direction: new Control_radio({ direction: new Control_radio({
object: bookmarkData.link, object: bookmarkData.link,
radioGroup: [ radioGroup: [
{ id: 'display-direction-vertical', labelText: 'Vertical', description: 'Stack the Visual Element and Name one above the other.', value: 'vertical' }, { id: 'display-direction-vertical', labelText: message.get('bookmarkFormDisplayDirectionVerticalLabel'), description: message.get('bookmarkFormDisplayDirectionVerticalDescription'), value: 'vertical' },
{ id: 'display-direction-horizontal', labelText: 'Horizontal', description: 'Arrange the Visual Element and Name side by side.', value: 'horizontal' } { id: 'display-direction-horizontal', labelText: message.get('bookmarkFormDisplayDirectionHorizontalLabel'), description: message.get('bookmarkFormDisplayDirectionHorizontalDescription'), value: 'horizontal' }
], ],
groupName: 'display-direction', groupName: 'display-direction',
path: 'display.direction', path: 'display.direction',
@ -140,8 +142,8 @@ export const BookmarkForm = function({
order: new Control_radio({ order: new Control_radio({
object: bookmarkData.link, object: bookmarkData.link,
radioGroup: [ radioGroup: [
{ id: 'display-order-visual-name', labelText: 'Visual element then name', description: 'Place the Visual Element before the Name.', value: 'visual-name' }, { id: 'display-order-visual-name', labelText: message.get('bookmarkFormDisplayOrderVisualNameLabel'), description: message.get('bookmarkFormDisplayOrderVisualNameDescription'), value: 'visual-name' },
{ id: 'display-order-name-visual', labelText: 'Name then visual element', description: 'Place the Name before the Visual Element.', value: 'name-visual' } { id: 'display-order-name-visual', labelText: message.get('bookmarkFormDisplayOrderNameVisualLabel'), description: message.get('bookmarkFormDisplayOrderNameVisualDescription'), value: 'name-visual' }
], ],
groupName: 'display-order', groupName: 'display-order',
path: 'display.order', path: 'display.order',
@ -154,7 +156,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.rotate', path: 'display.rotate',
id: 'display-rotate', id: 'display-rotate',
labelText: 'Rotate', labelText: message.get('bookmarkFormDisplayRotate'),
value: bookmarkData.link.display.rotate, value: bookmarkData.link.display.rotate,
defaultValue: bookmarkDefault.display.rotate, defaultValue: bookmarkDefault.display.rotate,
min: bookmarkMinMax.display.rotate.min, min: bookmarkMinMax.display.rotate.min,
@ -165,14 +167,14 @@ export const BookmarkForm = function({
}), }),
translate: { translate: {
label: form.label({ label: form.label({
text: 'Adjust Visual Element position', text: message.get('bookmarkFormDisplayTranslateLabel'),
noPadding: true noPadding: true
}), }),
x: new Control_sliderSlim({ x: new Control_sliderSlim({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.translate.x', path: 'display.translate.x',
id: 'display-translate-x', id: 'display-translate-x',
labelText: 'Horizontal', labelText: message.get('bookmarkFormDisplayTranslateX'),
value: bookmarkData.link.display.translate.x, value: bookmarkData.link.display.translate.x,
defaultValue: bookmarkDefault.display.translate.x, defaultValue: bookmarkDefault.display.translate.x,
min: bookmarkMinMax.display.translate.x.min, min: bookmarkMinMax.display.translate.x.min,
@ -185,7 +187,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.translate.y', path: 'display.translate.y',
id: 'display-translate-y', id: 'display-translate-y',
labelText: 'Vertical', labelText: message.get('bookmarkFormDisplayTranslateY'),
value: bookmarkData.link.display.translate.y, value: bookmarkData.link.display.translate.y,
defaultValue: bookmarkDefault.display.translate.y, defaultValue: bookmarkDefault.display.translate.y,
min: bookmarkMinMax.display.translate.y.min, min: bookmarkMinMax.display.translate.y.min,
@ -199,7 +201,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.gutter', path: 'display.gutter',
id: 'display-gutter', id: 'display-gutter',
labelText: 'Gutter', labelText: message.get('bookmarkFormDisplayGutter'),
value: bookmarkData.link.display.gutter, value: bookmarkData.link.display.gutter,
defaultValue: bookmarkDefault.display.gutter, defaultValue: bookmarkDefault.display.gutter,
min: bookmarkMinMax.display.gutter.min, min: bookmarkMinMax.display.gutter.min,
@ -213,8 +215,8 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.visual.show', path: 'display.visual.show',
id: 'display-visual-show', id: 'display-visual-show',
labelText: 'Show Visual Element', labelText: message.get('bookmarkFormDisplayVisualShowLabel'),
description: 'Display Letters, Icon or an Image on this Bookmark hexagon.', description: message.get('bookmarkFormDisplayVisualShowDescription'),
action: () => { action: () => {
this.disable(); this.disable();
this.collapse.display.visual.update(); this.collapse.display.visual.update();
@ -224,9 +226,9 @@ export const BookmarkForm = function({
type: new Control_radio({ type: new Control_radio({
object: bookmarkData.link, object: bookmarkData.link,
radioGroup: [ radioGroup: [
{ id: 'display-visual-type-letter', labelText: 'Letter', value: 'letter' }, { id: 'display-visual-type-letter', labelText: message.get('bookmarkFormDisplayVisualTypeLetter'), value: 'letter' },
{ id: 'display-visual-type-icon', labelText: 'Icon', value: 'icon' }, { id: 'display-visual-type-icon', labelText: message.get('bookmarkFormDisplayVisualTypeIcon'), value: 'icon' },
{ id: 'display-visual-type-image', labelText: 'Image', value: 'image' } { id: 'display-visual-type-image', labelText: message.get('bookmarkFormDisplayVisualTypeImage'), value: 'image' }
], ],
groupName: 'display-visual-type', groupName: 'display-visual-type',
path: 'display.visual.type', path: 'display.visual.type',
@ -239,7 +241,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.visual.size', path: 'display.visual.size',
id: 'display-visual-size', id: 'display-visual-size',
labelText: 'Visual size', labelText: message.get('bookmarkFormDisplayVisualSize'),
value: bookmarkData.link.display.visual.size, value: bookmarkData.link.display.visual.size,
defaultValue: bookmarkDefault.display.visual.size, defaultValue: bookmarkDefault.display.visual.size,
min: bookmarkMinMax.display.visual.size.min, min: bookmarkMinMax.display.visual.size.min,
@ -254,8 +256,8 @@ export const BookmarkForm = function({
path: 'display.visual.letter.text', path: 'display.visual.letter.text',
id: 'display-visual-letter-text', id: 'display-visual-letter-text',
value: bookmarkData.link.display.visual.letter.text, value: bookmarkData.link.display.visual.letter.text,
placeholder: 'E', placeholder: message.get('bookmarkFormDisplayVisualLetterTextPlaceholder'),
labelText: 'Bookmark letter', labelText: message.get('bookmarkFormDisplayVisualLetterTextLabel'),
srOnly: true, srOnly: true,
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
@ -268,8 +270,8 @@ export const BookmarkForm = function({
path: 'display.visual.icon.label', path: 'display.visual.icon.label',
id: 'display-visual-icon-label', id: 'display-visual-icon-label',
value: bookmarkData.link.display.visual.icon.label, value: bookmarkData.link.display.visual.icon.label,
placeholder: 'FontAwesome Brands or Icons', placeholder: message.get('bookmarkFormDisplayVisualIconTextPlaceholder'),
labelText: 'Bookmark icon', labelText: message.get('bookmarkFormDisplayVisualIconTextLabel'),
srOnly: true, srOnly: true,
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
@ -279,7 +281,7 @@ export const BookmarkForm = function({
classList: ['bookmark-form-text-icon', 'form-group-item-small'] classList: ['bookmark-form-text-icon', 'form-group-item-small']
}), }),
remove: new Button({ remove: new Button({
text: 'Remove icon', text: message.get('bookmarkFormDisplayVisualIconRemove'),
srOnly: true, srOnly: true,
style: ['line'], style: ['line'],
iconName: 'cross', iconName: 'cross',
@ -299,8 +301,8 @@ export const BookmarkForm = function({
path: 'display.visual.image.url', path: 'display.visual.image.url',
id: 'display-visual-image-url', id: 'display-visual-image-url',
value: bookmarkData.link.display.visual.image.url, value: bookmarkData.link.display.visual.image.url,
placeholder: 'https://www.example.com/image.jpg', placeholder: message.get('bookmarkFormDisplayVisualImageUrlPlaceholder'),
labelText: 'Bookmark image', labelText: message.get('bookmarkFormDisplayVisualImageUrlLabel'),
srOnly: true, srOnly: true,
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
@ -312,7 +314,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.visual.shadow.size', path: 'display.visual.shadow.size',
id: 'display-visual-shadow-size', id: 'display-visual-shadow-size',
labelText: 'Visual shadow', labelText: message.get('bookmarkFormDisplayVisualShadowSize'),
value: bookmarkData.link.display.visual.shadow.size, value: bookmarkData.link.display.visual.shadow.size,
defaultValue: bookmarkDefault.display.visual.shadow.size, defaultValue: bookmarkDefault.display.visual.shadow.size,
min: bookmarkMinMax.display.visual.shadow.size.min, min: bookmarkMinMax.display.visual.shadow.size.min,
@ -328,7 +330,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.name.show', path: 'display.name.show',
id: 'display-name-show', id: 'display-name-show',
labelText: 'Show Name', labelText: message.get('bookmarkFormDisplayNameShow'),
action: () => { action: () => {
this.disable(); this.disable();
this.collapse.display.name.update(); this.collapse.display.name.update();
@ -340,8 +342,8 @@ export const BookmarkForm = function({
path: 'display.name.text', path: 'display.name.text',
id: 'display-name-text', id: 'display-name-text',
value: bookmarkData.link.display.name.text, value: bookmarkData.link.display.name.text,
placeholder: 'Example', placeholder: message.get('bookmarkFormDisplayNameTextPlaceholder'),
labelText: 'Bookmark name', labelText: message.get('bookmarkFormDisplayNameTextLabel'),
srOnly: true, srOnly: true,
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
@ -351,7 +353,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'display.name.size', path: 'display.name.size',
id: 'display-name-size', id: 'display-name-size',
labelText: 'Name size', labelText: message.get('bookmarkFormDisplayNameSize'),
value: bookmarkData.link.display.name.size, value: bookmarkData.link.display.name.size,
defaultValue: bookmarkDefault.display.name.size, defaultValue: bookmarkDefault.display.name.size,
min: bookmarkMinMax.display.name.size.min, min: bookmarkMinMax.display.name.size.min,
@ -366,8 +368,8 @@ export const BookmarkForm = function({
by: new Control_radio({ by: new Control_radio({
object: bookmarkData.link, object: bookmarkData.link,
radioGroup: [ radioGroup: [
{ id: 'accent-by-theme', labelText: 'Theme Accent', description: 'Use the Accent defined by the Theme.', value: 'theme' }, { id: 'accent-by-theme', labelText: message.get('bookmarkFormAccentByThemeLabel'), description: message.get('bookmarkFormAccentByThemeDescription'), value: 'theme' },
{ id: 'accent-by-custom', labelText: 'Custom Accent', description: 'Override the Theme Accent.', value: 'custom' } { id: 'accent-by-custom', labelText: message.get('bookmarkFormAccentByCustomLabel'), description: message.get('bookmarkFormAccentByCustomDescription'), value: 'custom' }
], ],
groupName: 'accent-by', groupName: 'accent-by',
path: 'accent.by', path: 'accent.by',
@ -381,7 +383,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'accent', path: 'accent',
id: 'accent', id: 'accent',
labelText: 'Accent', labelText: message.get('bookmarkFormAccentColor'),
srOnly: true, srOnly: true,
defaultValue: bookmarkDefault.accent.rgb, defaultValue: bookmarkDefault.accent.rgb,
minMaxObject: bookmarkMinMax, minMaxObject: bookmarkMinMax,
@ -395,8 +397,8 @@ export const BookmarkForm = function({
by: new Control_radio({ by: new Control_radio({
object: bookmarkData.link, object: bookmarkData.link,
radioGroup: [ radioGroup: [
{ id: 'color-by-theme', labelText: 'Theme colour', description: 'Use the Colour defined by the Theme.', value: 'theme' }, { id: 'color-by-theme', labelText: message.get('bookmarkFormColorByThemeLabel'), description: message.get('bookmarkFormColorByThemeDescription'), value: 'theme' },
{ id: 'color-by-custom', labelText: 'Custom colour', description: 'Override the Theme colour.', value: 'custom' } { id: 'color-by-custom', labelText: message.get('bookmarkFormColorByCustomLabel'), description: message.get('bookmarkFormColorByCustomDescription'), value: 'custom' }
], ],
groupName: 'color-by', groupName: 'color-by',
path: 'color.by', path: 'color.by',
@ -410,7 +412,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'color', path: 'color',
id: 'color', id: 'color',
labelText: 'Colour', labelText: message.get('bookmarkFormColorColor'),
srOnly: true, srOnly: true,
defaultValue: bookmarkDefault.color.rgb, defaultValue: bookmarkDefault.color.rgb,
minMaxObject: bookmarkMinMax, minMaxObject: bookmarkMinMax,
@ -423,7 +425,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'color.opacity', path: 'color.opacity',
id: 'color-opacity', id: 'color-opacity',
labelText: 'Opacity', labelText: message.get('bookmarkFormColorOpacity'),
value: bookmarkData.link.color.opacity, value: bookmarkData.link.color.opacity,
defaultValue: bookmarkDefault.color.opacity, defaultValue: bookmarkDefault.color.opacity,
min: bookmarkMinMax.color.opacity.min, min: bookmarkMinMax.color.opacity.min,
@ -438,8 +440,8 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'background.show', path: 'background.show',
id: 'background-show', id: 'background-show',
labelText: 'Show background', labelText: message.get('bookmarkFormBackgroundShowLabel'),
description: 'Display an Image or video Background on this Bookmark tile.', description: message.get('bookmarkFormBackgroundShowDescription'),
action: () => { action: () => {
this.collapse.background.update(); this.collapse.background.update();
this.disable(); this.disable();
@ -449,8 +451,8 @@ export const BookmarkForm = function({
type: new Control_radio({ type: new Control_radio({
object: bookmarkData.link, object: bookmarkData.link,
radioGroup: [ radioGroup: [
{ id: 'background-type-image', labelText: 'Image', value: 'image' }, { id: 'background-type-image', labelText: message.get('bookmarkFormBackgroundTypeImage'), value: 'image' },
{ id: 'background-type-video', labelText: 'Video', value: 'video' } { id: 'background-type-video', labelText: message.get('bookmarkFormBackgroundTypeVideo'), value: 'video' }
], ],
groupName: 'background-type', groupName: 'background-type',
path: 'background.type', path: 'background.type',
@ -463,7 +465,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'background.opacity', path: 'background.opacity',
id: 'background-opacity', id: 'background-opacity',
labelText: 'Opacity', labelText: message.get('bookmarkFormBackgroundOpacity'),
value: bookmarkData.link.background.opacity, value: bookmarkData.link.background.opacity,
defaultValue: bookmarkDefault.background.opacity, defaultValue: bookmarkDefault.background.opacity,
min: bookmarkMinMax.background.opacity.min, min: bookmarkMinMax.background.opacity.min,
@ -478,8 +480,8 @@ export const BookmarkForm = function({
path: 'background.image.url', path: 'background.image.url',
id: 'background-image-url', id: 'background-image-url',
value: bookmarkData.link.background.image.url, value: bookmarkData.link.background.image.url,
placeholder: 'https://www.example.com/image.jpg', placeholder: message.get('bookmarkFormBackgroundImagePlaceholder'),
labelText: 'Background image URL', labelText: message.get('bookmarkFormBackgroundImageLabel'),
srOnly: true, srOnly: true,
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
@ -492,8 +494,8 @@ export const BookmarkForm = function({
path: 'background.video.url', path: 'background.video.url',
id: 'background-video-url', id: 'background-video-url',
value: bookmarkData.link.background.video.url, value: bookmarkData.link.background.video.url,
placeholder: 'https://www.example.com/video.mp4', placeholder: message.get('bookmarkFormBackgroundVideoPlaceholder'),
labelText: 'Background video URL', labelText: message.get('bookmarkFormBackgroundVideoLabel'),
srOnly: true, srOnly: true,
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
@ -505,7 +507,7 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'border', path: 'border',
id: 'border', id: 'border',
labelText: 'Border', labelText: message.get('bookmarkFormBorder'),
value: bookmarkData.link.border, value: bookmarkData.link.border,
defaultValue: bookmarkDefault.border, defaultValue: bookmarkDefault.border,
min: bookmarkMinMax.border.min, min: bookmarkMinMax.border.min,
@ -519,8 +521,8 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'shape.wide', path: 'shape.wide',
id: 'shape-wide', id: 'shape-wide',
labelText: 'Wide tile', labelText: message.get('bookmarkFormShapeWideLabel'),
description: 'Bookmark tile to span across two columns.', description: message.get('bookmarkFormShapeWideDescription'),
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
} }
@ -529,8 +531,8 @@ export const BookmarkForm = function({
object: bookmarkData.link, object: bookmarkData.link,
path: 'shape.tall', path: 'shape.tall',
id: 'shape-tall', id: 'shape-tall',
labelText: 'Tall tile', labelText: message.get('bookmarkFormShapeTallLabel'),
description: 'Bookmark tile to span across two columns.', description: message.get('bookmarkFormShapeTallDescription'),
action: () => { action: () => {
this.preview.update.assemble(bookmarkData); this.preview.update.assemble(bookmarkData);
} }
@ -542,8 +544,8 @@ export const BookmarkForm = function({
destination: new Control_radio({ destination: new Control_radio({
object: bookmarkData, object: bookmarkData,
radioGroup: [ radioGroup: [
{ id: 'group-destination-existing', labelText: 'Existing Group', value: 'existing' }, { id: 'group-destination-existing', labelText: message.get('bookmarkFormGroupDestinationExisting'), value: 'existing' },
{ id: 'group-destination-new', labelText: 'New Group', value: 'new' } { id: 'group-destination-new', labelText: message.get('bookmarkFormGroupDestinationNew'), value: 'new' }
], ],
groupName: 'group.destination', groupName: 'group.destination',
path: 'group.destination', path: 'group.destination',
@ -556,12 +558,12 @@ export const BookmarkForm = function({
path: 'group.name', path: 'group.name',
id: 'group-name', id: 'group-name',
value: bookmarkData.group.name, value: bookmarkData.group.name,
placeholder: 'Example group', placeholder: message.get('bookmarkFormGroupNamePlaceholder'),
labelText: 'URL', labelText: message.get('bookmarkFormGroupNameLabel'),
srOnly: true srOnly: true
}), }),
random: new Button({ random: new Button({
text: 'Random Group name', text: message.get('bookmarkFormGroupRandom'),
style: ['line'], style: ['line'],
func: () => { func: () => {
bookmarkData.group.name = randomString({ adjectivesCount: randomNumber(1, 3) }); bookmarkData.group.name = randomString({ adjectivesCount: randomNumber(1, 3) });
@ -573,7 +575,7 @@ export const BookmarkForm = function({
object: bookmarkData, object: bookmarkData,
path: 'position.destination.group', path: 'position.destination.group',
id: 'position-destination-group', id: 'position-destination-group',
labelText: 'Group', labelText: message.get('bookmarkFormGroupPositionGroup'),
srOnly: true, srOnly: true,
option: (bookmark.all.length > 0) ? this.selectOption.group() : [], option: (bookmark.all.length > 0) ? this.selectOption.group() : [],
selected: bookmarkData.position.destination.group, selected: bookmarkData.position.destination.group,
@ -599,7 +601,7 @@ export const BookmarkForm = function({
object: bookmarkData, object: bookmarkData,
path: 'position.destination.item', path: 'position.destination.item',
id: 'position-destination-item', id: 'position-destination-item',
labelText: 'Position', labelText: message.get('bookmarkFormGroupPositionItem'),
option: (bookmark.all.length > 0) ? this.selectOption.item() : [], option: (bookmark.all.length > 0) ? this.selectOption.item() : [],
selected: bookmarkData.position.destination.item selected: bookmarkData.position.destination.item
}) })
@ -612,10 +614,10 @@ export const BookmarkForm = function({
object: bookmarkData.propagate, object: bookmarkData.propagate,
path: 'display', path: 'display',
id: 'apply-to-all-display', id: 'apply-to-all-display',
labelText: 'Apply "Show Visual Element" and "Show Name" to other Bookmarks', labelText: message.get('bookmarkFormPropagateVisualLabel'),
description: [ description: [
'The Letter, Icon, Image and Name text will not be shared.', message.get('bookmarkFormPropagateVisualDescriptionPara1'),
'Useful for hiding the Visual Elements or Names on all Bookmarks.' message.get('bookmarkFormPropagateVisualDescriptionPara2')
] ]
}); });
@ -628,10 +630,10 @@ export const BookmarkForm = function({
object: bookmarkData.propagate, object: bookmarkData.propagate,
path: 'layout', path: 'layout',
id: 'apply-to-all-layout', id: 'apply-to-all-layout',
labelText: 'Apply Layout to other Bookmarks', labelText: message.get('bookmarkFormPropagateLayoutLabel'),
description: [ description: [
'When saved, apply the above Layout to all other Bookmarks.', message.get('bookmarkFormPropagateLayoutDescriptionPara1'),
'Only the Visual and Name size, Alignment, Order, Position and Gutter will be will be applied to all.' message.get('bookmarkFormPropagateLayoutDescriptionPara2')
] ]
}); });
@ -644,10 +646,10 @@ export const BookmarkForm = function({
object: bookmarkData.propagate, object: bookmarkData.propagate,
path: 'theme', path: 'theme',
id: 'apply-to-all-theme', id: 'apply-to-all-theme',
labelText: 'Apply Theme to other Bookmarks', labelText: message.get('bookmarkFormPropagateThemeLabel'),
description: [ description: [
'When saved, apply the above Theme to all other Bookmarks.', message.get('bookmarkFormPropagateThemeDescriptionPara1'),
'Only the Colour, Accent, Opacity, Border and Visual shadow will be applied to all.' message.get('bookmarkFormPropagateThemeDescriptionPara2')
] ]
}); });
@ -662,17 +664,17 @@ export const BookmarkForm = function({
visual: { visual: {
shadow: { shadow: {
size: new Control_helperText({ size: new Control_helperText({
text: ['Visual shadow only applies to a Letter or Icon.'] text: [message.get('bookmarkFormDisplayVisualShadowHelperPara1')]
}) })
} }
} }
}, },
background: { background: {
image: new Control_helperText({ image: new Control_helperText({
text: ['Background image only supports a direct URL to an image file.'] text: [message.get('bookmarkFormBackgroundImageHelperPara1')]
}), }),
video: new Control_helperText({ video: new Control_helperText({
text: ['Background video only supports a direct URL to a video file. Supports MP4 and WebM format.', 'YouTube page URLs can not be used.'] text: [message.get('bookmarkFormBackgroundVideoHelperPara1')]
}) })
} }
} }
@ -769,8 +771,8 @@ export const BookmarkForm = function({
form.wrap({ form.wrap({
children: [ children: [
node('div|class:bookmark-form-description', [ node('div|class:bookmark-form-description', [
node('h2:Visual & Name'), node(`h2:${message.get('bookmarkFormSectionVisualHeading')}`),
node('p:Display Letters, Icon, Image and a Name on this Bookmark tile.') node(`p:${message.get('bookmarkFormSectionVisualDescription')}`)
]) ])
] ]
}), }),
@ -799,8 +801,8 @@ export const BookmarkForm = function({
form.wrap({ form.wrap({
children: [ children: [
node('div|class:bookmark-form-description', [ node('div|class:bookmark-form-description', [
node('h2:Address'), node(`h2:${message.get('bookmarkFormSectionAddressHeading')}`),
complexNode({ tag: 'p', text: 'Be sure to use the full URL and include <strong>"https://..."</strong>', complexText: true }) complexNode({ tag: 'p', text: message.get('bookmarkFormSectionAddressDescription'), complexText: true })
]) ])
] ]
}), }),
@ -823,8 +825,8 @@ export const BookmarkForm = function({
form.wrap({ form.wrap({
children: [ children: [
node('div|class:bookmark-form-description', [ node('div|class:bookmark-form-description', [
node('h2:Position'), node(`h2:${message.get('bookmarkFormSectionPositionHeading')}`),
node('p:The Group to place this Bookmark in.') node(`p:${message.get('bookmarkFormSectionPositionDescription')}`)
]) ])
] ]
}), }),
@ -868,8 +870,8 @@ export const BookmarkForm = function({
form.wrap({ form.wrap({
children: [ children: [
node('div|class:bookmark-form-description', [ node('div|class:bookmark-form-description', [
node('h2:Layout'), node(`h2:${message.get('bookmarkFormSectionLayoutHeading')}`),
node('p:Change the Visual Element and Name position, scale and orientation.') node(`p:${message.get('bookmarkFormSectionLayoutDescription')}`)
]) ])
] ]
}), }),
@ -915,8 +917,8 @@ export const BookmarkForm = function({
form.wrap({ form.wrap({
children: [ children: [
node('div|class:bookmark-form-description', [ node('div|class:bookmark-form-description', [
node('h2:Theme'), node(`h2:${message.get('bookmarkFormSectionThemeHeading')}`),
node('p:Override the Theme and Accent colour.') node(`p:${message.get('bookmarkFormSectionThemeDescription')}`)
]) ])
] ]
}), }),
@ -1053,23 +1055,23 @@ export const BookmarkForm = function({
this.tab = new Tab({ this.tab = new Tab({
group: [{ group: [{
tabText: 'Visual & Name', tabText: message.get('bookmarkFormTabVisual'),
area: this.area.visual(), area: this.area.visual(),
active: true active: true
}, { }, {
tabText: 'Address', tabText: message.get('bookmarkFormTabAddress'),
area: this.area.address(), area: this.area.address(),
active: false active: false
}, { }, {
tabText: 'Position', tabText: message.get('bookmarkFormTabPosition'),
area: this.area.position(), area: this.area.position(),
active: false active: false
}, { }, {
tabText: 'Layout', tabText: message.get('bookmarkFormTabLayout'),
area: this.area.layout(), area: this.area.layout(),
active: false active: false
}, { }, {
tabText: 'Theme', tabText: message.get('bookmarkFormTabTheme'),
area: this.area.theme(), area: this.area.theme(),
active: false active: false
}] }]

View File

@ -1,10 +1,12 @@
import { message } from '../message';
import { BookmarkTile } from '../bookmarkTile'; import { BookmarkTile } from '../bookmarkTile';
import { node } from '../../utility/node'; import { node } from '../../utility/node';
import './index.css'; import './index.css';
export const BookmarkPreview = function ({ export const BookmarkPreview = function({
bookmarkData = false bookmarkData = false
} = {}) { } = {}) {
@ -29,9 +31,9 @@ export const BookmarkPreview = function ({
} }
if (bookmarkData.link.shape.tall || bookmarkData.link.shape.wide) { if (bookmarkData.link.shape.tall || bookmarkData.link.shape.wide) {
this.title.textContent = 'Preview (50% scale)'; this.title.textContent = message.get('bookmarkPreviewHalf');
} else { } else {
this.title.textContent = 'Preview'; this.title.textContent = message.get('bookmarkPreviewFull');
} }
}; };

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { state } from '../state'; import { state } from '../state';
import { data } from '../data'; import { data } from '../data';
import { bookmark } from '../bookmark'; import { bookmark } from '../bookmark';
@ -16,7 +18,7 @@ import { complexNode } from '../../utility/complexNode';
import { isValidString } from '../../utility/isValidString'; import { isValidString } from '../../utility/isValidString';
import { trimString } from '../../utility/trimString'; import { trimString } from '../../utility/trimString';
const BookmarkTile = function ({ const BookmarkTile = function({
bookmarkData = {}, bookmarkData = {},
preview = false preview = false
} = {}) { } = {}) {
@ -63,11 +65,11 @@ const BookmarkTile = function ({
this.control.button = { this.control.button = {
left: new Button({ left: new Button({
text: 'Move this bookmark left', text: message.get('bookmarkTileControlLeft'),
srOnly: true, srOnly: true,
iconName: 'arrowKeyboardLeft', iconName: 'arrowKeyboardLeft',
style: ['link'], style: ['link'],
title: 'Move this bookmark left', title: message.get('bookmarkTileControlLeft'),
classList: ['bookmark-control-button', 'bookmark-control-left'], classList: ['bookmark-control-button', 'bookmark-control-left'],
func: () => { func: () => {
@ -86,19 +88,19 @@ const BookmarkTile = function ({
} }
}), }),
sort: new Button({ sort: new Button({
text: 'Drag bookmark to reorder', text: message.get('bookmarkTileControlSort'),
srOnly: true, srOnly: true,
iconName: 'drag', iconName: 'drag',
style: ['link'], style: ['link'],
title: 'Drag bookmark to reorder', title: message.get('bookmarkTileControlSort'),
classList: ['bookmark-control-button', 'bookmark-control-sort'] classList: ['bookmark-control-button', 'bookmark-control-sort']
}), }),
right: new Button({ right: new Button({
text: 'Move this bookmark right', text: message.get('bookmarkTileControlRight'),
srOnly: true, srOnly: true,
iconName: 'arrowKeyboardRight', iconName: 'arrowKeyboardRight',
style: ['link'], style: ['link'],
title: 'Move this bookmark right', title: message.get('bookmarkTileControlRight'),
classList: ['bookmark-control-button', 'bookmark-control-right'], classList: ['bookmark-control-button', 'bookmark-control-right'],
func: () => { func: () => {
@ -117,11 +119,11 @@ const BookmarkTile = function ({
} }
}), }),
edit: new Button({ edit: new Button({
text: 'Edit this bookmark', text: message.get('bookmarkTileControlEdit'),
srOnly: true, srOnly: true,
iconName: 'edit', iconName: 'edit',
style: ['link'], style: ['link'],
title: 'Edit this bookmark', title: message.get('bookmarkTileControlEdit'),
classList: ['bookmark-control-button', 'bookmark-control-edit'], classList: ['bookmark-control-button', 'bookmark-control-edit'],
func: () => { func: () => {
@ -136,9 +138,10 @@ const BookmarkTile = function ({
const bookmarkForm = new BookmarkForm({ bookmarkData: newBookmarkData }); const bookmarkForm = new BookmarkForm({ bookmarkData: newBookmarkData });
const editModal = new Modal({ const editModal = new Modal({
heading: isValidString(newBookmarkData.link.display.name.text) ? 'Edit ' + newBookmarkData.link.display.name.text : 'Edit unnamed bookmark', heading: isValidString(newBookmarkData.link.display.name.text) ? `${message.get('bookmarkEditHeadingName')} ${newBookmarkData.link.display.name.text}` : message.get('bookmarkEditHeadingUnnamed'),
content: bookmarkForm.form(), content: bookmarkForm.form(),
successText: 'Save', successText: message.get('bookmarkEditSuccessText'),
cancelText: message.get('bookmarkEditCancelText'),
width: (state.get.current().bookmark.style === 'block') ? 60 : 70, width: (state.get.current().bookmark.style === 'block') ? 60 : 70,
maxHeight: true, maxHeight: true,
successAction: () => { successAction: () => {
@ -177,18 +180,19 @@ const BookmarkTile = function ({
} }
}), }),
remove: new Button({ remove: new Button({
text: 'Remove this bookmark', text: message.get('bookmarkTileControlRemove'),
srOnly: true, srOnly: true,
iconName: 'cross', iconName: 'cross',
style: ['link'], style: ['link'],
title: 'Remove this bookmark', title: message.get('bookmarkTileControlRemove'),
classList: ['bookmark-control-button', 'bookmark-control-remove'], classList: ['bookmark-control-button', 'bookmark-control-remove'],
func: () => { func: () => {
const removeModal = new Modal({ const removeModal = new Modal({
heading: isValidString(bookmarkData.link.display.name.text) ? 'Remove ' + bookmarkData.link.display.name.text : 'Remove unnamed bookmark', heading: isValidString(bookmarkData.link.display.name.text) ? `${message.get('bookmarkRemoveHeadingName')} ${bookmarkData.link.display.name.text}` : message.get('bookmarkRemoveHeadingUnnamed'),
content: 'Are you sure you want to remove this Bookmark? This can not be undone.', content: message.get('bookmarkRemoveContent'),
successText: 'Remove', successText: message.get('bookmarkRemoveSuccessText'),
cancelText: message.get('bookmarkRemoveCancelText'),
width: 'small', width: 'small',
successAction: () => { successAction: () => {

View File

@ -0,0 +1,21 @@
export const browserDetect = () => {
const userAgent = navigator.userAgent;
let browserName = {
chrome: false,
firefox: false,
none: false
};
if (userAgent.match(/chrome|chromium|crios/i)) {
browserName.chrome = true;
} else if (userAgent.match(/firefox|fxios/i)) {
browserName.firefox = true;
} else {
browserName.none = true;
}
return browserName;
};

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import * as form from '../../form'; import * as form from '../../form';
import { Button } from '../../button'; import { Button } from '../../button';
@ -65,7 +67,7 @@ export const Control_color = function ({
})), })),
max: 7, max: 7,
classList: ['form-group-item-half'], classList: ['form-group-item-half'],
placeholder: 'Hex code', placeholder: message.get('controlColorTextPlaceholder'),
func: () => { func: () => {
if (path) { if (path) {
@ -82,11 +84,12 @@ export const Control_color = function ({
}); });
this.reset = new Button({ this.reset = new Button({
text: false, text: message.get('controlGeneralReset'),
iconName: 'replay', iconName: 'replay',
style: ['line'], style: ['line'],
classList: ['form-group-item-small'], classList: ['form-group-item-small'],
title: 'Reset to default', title: message.get('controlGeneralReset'),
srOnly: true,
func: () => { func: () => {
set({ object: object, path: path + '.rgb', value: JSON.parse(JSON.stringify(defaultValue)) }); set({ object: object, path: path + '.rgb', value: JSON.parse(JSON.stringify(defaultValue)) });
@ -99,11 +102,12 @@ export const Control_color = function ({
}); });
this.random = new Button({ this.random = new Button({
text: false, text: message.get('controlColorRandom'),
iconName: 'random', iconName: 'random',
style: ['line'], style: ['line'],
classList: ['form-group-item-small'], classList: ['form-group-item-small'],
title: 'Random colour', title: message.get('controlColorRandom'),
srOnly: true,
func: () => { func: () => {
set({ object: object, path: path + '.hsl', value: { h: randomNumber(0, 360), s: randomNumber(0, 100), l: randomNumber(0, 100) } }); set({ object: object, path: path + '.hsl', value: { h: randomNumber(0, 360), s: randomNumber(0, 100), l: randomNumber(0, 100) } });

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import * as form from '../../form'; import * as form from '../../form';
import { Button } from '../../button'; import { Button } from '../../button';
@ -24,11 +26,12 @@ export const Control_colorMixer = function ({
} = {}) { } = {}) {
this.moreControlsToggle = new Button({ this.moreControlsToggle = new Button({
text: false, text: message.get('controlColorMixerMoreControls'),
iconName: 'arrowKeyboardDown', iconName: 'arrowKeyboardDown',
style: ['line'], style: ['line'],
classList: ['collapse-toggle', 'form-group-item-small'], classList: ['collapse-toggle', 'form-group-item-small'],
title: 'More controls', title: message.get('controlColorMixerMoreControls'),
srOnly: true,
func: () => { func: () => {
this.moreControlsCollapse.toggle(); this.moreControlsCollapse.toggle();
this.moreControlsUpdate(); this.moreControlsUpdate();
@ -67,7 +70,7 @@ export const Control_colorMixer = function ({
object: object, object: object,
path: path + '.hsl.h', path: path + '.hsl.h',
id: id + '-hsl-h', id: id + '-hsl-h',
labelText: 'Hue', labelText: message.get('controlColorMixerSliderH'),
value: get({ object: object, path: path + '.hsl.h' }), value: get({ object: object, path: path + '.hsl.h' }),
min: get({ object: minMaxObject, path: path + '.hsl.h.min' }), min: get({ object: minMaxObject, path: path + '.hsl.h.min' }),
max: get({ object: minMaxObject, path: path + '.hsl.h.max' }), max: get({ object: minMaxObject, path: path + '.hsl.h.max' }),
@ -93,7 +96,7 @@ export const Control_colorMixer = function ({
object: object, object: object,
path: path + '.hsl.s', path: path + '.hsl.s',
id: id + '-hsl-s', id: id + '-hsl-s',
labelText: 'Saturation', labelText: message.get('controlColorMixerSliderS'),
value: get({ object: object, path: path + '.hsl.s' }), value: get({ object: object, path: path + '.hsl.s' }),
min: get({ object: minMaxObject, path: path + '.hsl.s.min' }), min: get({ object: minMaxObject, path: path + '.hsl.s.min' }),
max: get({ object: minMaxObject, path: path + '.hsl.s.max' }), max: get({ object: minMaxObject, path: path + '.hsl.s.max' }),
@ -119,7 +122,7 @@ export const Control_colorMixer = function ({
object: object, object: object,
path: path + '.hsl.l', path: path + '.hsl.l',
id: id + '-hsl-l', id: id + '-hsl-l',
labelText: 'Lightness', labelText: message.get('controlColorMixerSliderL'),
value: get({ object: object, path: path + '.hsl.l' }), value: get({ object: object, path: path + '.hsl.l' }),
min: get({ object: minMaxObject, path: path + '.hsl.l.min' }), min: get({ object: minMaxObject, path: path + '.hsl.l.min' }),
max: get({ object: minMaxObject, path: path + '.hsl.l.max' }), max: get({ object: minMaxObject, path: path + '.hsl.l.max' }),
@ -145,7 +148,7 @@ export const Control_colorMixer = function ({
object: object, object: object,
path: path + '.rgb.r', path: path + '.rgb.r',
id: id + '-rgb-r', id: id + '-rgb-r',
labelText: 'Red', labelText: message.get('controlColorMixerSliderR'),
value: get({ object: object, path: path + '.rgb.r' }), value: get({ object: object, path: path + '.rgb.r' }),
min: get({ object: minMaxObject, path: path + '.rgb.r.min' }), min: get({ object: minMaxObject, path: path + '.rgb.r.min' }),
max: get({ object: minMaxObject, path: path + '.rgb.r.max' }), max: get({ object: minMaxObject, path: path + '.rgb.r.max' }),
@ -171,7 +174,7 @@ export const Control_colorMixer = function ({
object: object, object: object,
path: path + '.rgb.g', path: path + '.rgb.g',
id: id + '-rgb-g', id: id + '-rgb-g',
labelText: 'Green', labelText: message.get('controlColorMixerSliderG'),
value: get({ object: object, path: path + '.rgb.g' }), value: get({ object: object, path: path + '.rgb.g' }),
min: get({ object: minMaxObject, path: path + '.rgb.g.min' }), min: get({ object: minMaxObject, path: path + '.rgb.g.min' }),
max: get({ object: minMaxObject, path: path + '.rgb.g.max' }), max: get({ object: minMaxObject, path: path + '.rgb.g.max' }),
@ -197,7 +200,7 @@ export const Control_colorMixer = function ({
object: object, object: object,
path: path + '.rgb.b', path: path + '.rgb.b',
id: id + '-rgb-b', id: id + '-rgb-b',
labelText: 'Blue', labelText: message.get('controlColorMixerSliderB'),
value: get({ object: object, path: path + '.rgb.b' }), value: get({ object: object, path: path + '.rgb.b' }),
min: get({ object: minMaxObject, path: path + '.rgb.b.min' }), min: get({ object: minMaxObject, path: path + '.rgb.b.min' }),
max: get({ object: minMaxObject, path: path + '.rgb.b.max' }), max: get({ object: minMaxObject, path: path + '.rgb.b.max' }),

View File

@ -6,7 +6,7 @@ import { set } from '../../../utility/set';
import { trimString } from '../../../utility/trimString'; import { trimString } from '../../../utility/trimString';
import { clearChildNode } from '../../../utility/clearChildNode'; import { clearChildNode } from '../../../utility/clearChildNode';
export const Control_select = function ({ export const Control_select = function({
option = [], option = [],
selected = 0, selected = 0,
object = {}, object = {},
@ -24,7 +24,9 @@ export const Control_select = function ({
selected: selected, selected: selected,
func: () => { func: () => {
if (object) {
set({ object: object, path: path, value: this.select.selectedIndex }); set({ object: object, path: path, value: this.select.selectedIndex });
}
if (action) { action(); } if (action) { action(); }

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import * as form from '../../form'; import * as form from '../../form';
import { Button } from '../../button'; import { Button } from '../../button';
@ -6,7 +8,7 @@ import { get } from '../../../utility/get';
import { set } from '../../../utility/set'; import { set } from '../../../utility/set';
import { minMax } from '../../../utility/minMax'; import { minMax } from '../../../utility/minMax';
export const Control_slider = function ({ export const Control_slider = function({
object = {}, object = {},
path = false, path = false,
id = 'name', id = 'name',
@ -115,11 +117,12 @@ export const Control_slider = function ({
}); });
this.reset = new Button({ this.reset = new Button({
text: false, text: message.get('controlGeneralReset'),
iconName: 'replay', iconName: 'replay',
style: ['line'], style: ['line'],
classList: ['form-group-item-small'], classList: ['form-group-item-small'],
title: 'Reset to default', title: message.get('controlGeneralReset'),
srOnly: true,
func: () => { func: () => {
set({ set({

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import * as form from '../../form'; import * as form from '../../form';
import { Button } from '../../button'; import { Button } from '../../button';
@ -6,7 +8,7 @@ import { get } from '../../../utility/get';
import { set } from '../../../utility/set'; import { set } from '../../../utility/set';
import { minMax } from '../../../utility/minMax'; import { minMax } from '../../../utility/minMax';
export const Control_sliderSlim = function ({ export const Control_sliderSlim = function({
object = {}, object = {},
path = false, path = false,
id = 'name', id = 'name',
@ -99,11 +101,12 @@ export const Control_sliderSlim = function ({
}); });
this.reset = new Button({ this.reset = new Button({
text: false, text: message.get('controlGeneralReset'),
iconName: 'replay', iconName: 'replay',
style: ['line'], style: ['line'],
classList: ['form-group-item-small'], classList: ['form-group-item-small'],
title: 'Reset to default', title: message.get('controlGeneralReset'),
srOnly: true,
func: () => { func: () => {
set({ set({

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import * as form from '../../form'; import * as form from '../../form';
import { Button } from '../../button'; import { Button } from '../../button';
@ -5,7 +7,7 @@ import { Button } from '../../button';
import { get } from '../../../utility/get'; import { get } from '../../../utility/get';
import { set } from '../../../utility/set'; import { set } from '../../../utility/set';
export const Control_textReset = function ({ export const Control_textReset = function({
object = {}, object = {},
path = false, path = false,
id = 'name', id = 'name',
@ -63,11 +65,12 @@ export const Control_textReset = function ({
} }
this.reset = new Button({ this.reset = new Button({
text: false, text: message.get('controlGeneralReset'),
iconName: 'replay', iconName: 'replay',
style: ['line'], style: ['line'],
classList: ['form-group-item-small'], classList: ['form-group-item-small'],
title: 'Reset to default', title: message.get('controlGeneralReset'),
srOnly: true,
func: () => { func: () => {
set({ set({
object: object, object: object,

View File

@ -1,7 +1,8 @@
import { message } from '../message';
import { state } from '../state'; import { state } from '../state';
import { data } from '../data'; import { data } from '../data';
import { Modal } from '../modal'; import { Modal } from '../modal';
import { CustomThemeTile } from '../customThemeTile'; import { CustomThemeTile } from '../customThemeTile';
import { CustomThemeForm } from '../customThemeForm'; import { CustomThemeForm } from '../customThemeForm';
@ -78,9 +79,10 @@ customTheme.add = {
const bookmarkForm = new CustomThemeForm({ customThemeData: newCustomThemeData }); const bookmarkForm = new CustomThemeForm({ customThemeData: newCustomThemeData });
const addModal = new Modal({ const addModal = new Modal({
heading: 'Save current theme', heading: message.get('themeCustomAddHeading'),
content: bookmarkForm.form(), content: bookmarkForm.form(),
successText: 'Save', successText: message.get('themeCustomAddSuccessText'),
cancelText: message.get('themeCustomAddCancelText'),
width: 'small', width: 'small',
successAction: () => { successAction: () => {
customTheme.item.mod.add(newCustomThemeData); customTheme.item.mod.add(newCustomThemeData);

View File

@ -1,3 +1,4 @@
import { message } from '../message';
import { Button } from '../button'; import { Button } from '../button';
@ -7,7 +8,7 @@ import { node } from '../../utility/node';
import { randomString } from '../../utility/randomString'; import { randomString } from '../../utility/randomString';
import { randomNumber } from '../../utility/randomNumber'; import { randomNumber } from '../../utility/randomNumber';
export const CustomThemeForm = function ({ export const CustomThemeForm = function({
customThemeData = false customThemeData = false
} = {}) { } = {}) {
@ -19,11 +20,11 @@ export const CustomThemeForm = function ({
path: 'name', path: 'name',
id: 'name', id: 'name',
value: customThemeData.theme.name, value: customThemeData.theme.name,
placeholder: 'Example theme', placeholder: message.get('themeCustomFormNamePlaceholder'),
labelText: 'Name' labelText: message.get('themeCustomFormNameLabel')
}), }),
randomName: new Button({ randomName: new Button({
text: 'Random theme name', text: message.get('themeCustomFormRandom'),
style: ['line'], style: ['line'],
func: () => { func: () => {
customThemeData.theme.name = randomString({ adjectivesCount: randomNumber(1, 3) }); customThemeData.theme.name = randomString({ adjectivesCount: randomNumber(1, 3) });

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { state } from '../state'; import { state } from '../state';
import { data } from '../data'; import { data } from '../data';
import { theme } from '../theme'; import { theme } from '../theme';
@ -324,12 +326,12 @@ export const CustomThemeTile = function({
this.control.button = { this.control.button = {
edit: new Button({ edit: new Button({
text: 'Edit this saved theme', text: message.get('themeCustomTileControlEdit'),
srOnly: true, srOnly: true,
iconName: 'edit', iconName: 'edit',
style: ['link'], style: ['link'],
size: 'small', size: 'small',
title: 'Edit this saved theme', title: message.get('themeCustomTileControlEdit'),
classList: ['theme-custom-control-button', 'theme-custom-control-edit'], classList: ['theme-custom-control-button', 'theme-custom-control-edit'],
func: () => { func: () => {
@ -342,9 +344,10 @@ export const CustomThemeTile = function({
const bookmarkForm = new CustomThemeForm({ customThemeData: newCustomThemeData }); const bookmarkForm = new CustomThemeForm({ customThemeData: newCustomThemeData });
const editModal = new Modal({ const editModal = new Modal({
heading: isValidString(customThemeData.theme.name) ? 'Edit ' + customThemeData.theme.name : 'Edit unnamed custom theme', heading: isValidString(customThemeData.theme.name) ? `${message.get('themeCustomEditHeadingName')} ${customThemeData.theme.name}` : message.get('themeCustomEditHeadingUnnamed'),
content: bookmarkForm.form(), content: bookmarkForm.form(),
successText: 'Save', successText: message.get('themeCustomEditSuccessText'),
cancelText: message.get('themeCustomEditCancelText'),
width: 'small', width: 'small',
successAction: () => { successAction: () => {
@ -360,21 +363,22 @@ export const CustomThemeTile = function({
} }
}), }),
remove: new Button({ remove: new Button({
text: 'Remove this saved theme', text: message.get('themeCustomTileControlRemove'),
srOnly: true, srOnly: true,
iconName: 'cross', iconName: 'cross',
style: ['link'], style: ['link'],
size: 'small', size: 'small',
title: 'Remove this saved theme', title: message.get('themeCustomTileControlRemove'),
classList: ['theme-custom-control-button', 'theme-custom-control-remove'], classList: ['theme-custom-control-button', 'theme-custom-control-remove'],
func: () => { func: () => {
menu.close(); menu.close();
const removeModal = new Modal({ const removeModal = new Modal({
heading: isValidString(customThemeData.theme.name) ? 'Remove ' + customThemeData.theme.name : 'Remove unnamed custom theme', heading: isValidString(customThemeData.theme.name) ? `${message.get('themeCustomRemoveHeadingName')} ${customThemeData.theme.name}` : message.get('themeCustomRemoveHeadingUnnamed'),
content: 'Are you sure you want to remove this saved theme? This can not be undone.', content: message.get('themeCustomRemoveContent'),
successText: 'Remove', successText: message.get('themeCustomRemoveSuccessText'),
cancelText: message.get('themeCustomRemoveCancelText'),
width: 'small', width: 'small',
successAction: () => { successAction: () => {
customTheme.item.mod.remove(customThemeData); customTheme.item.mod.remove(customThemeData);

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { state } from '../state'; import { state } from '../state';
import { bookmark } from '../bookmark'; import { bookmark } from '../bookmark';
import { menu } from '../menu'; import { menu } from '../menu';
@ -85,9 +87,10 @@ data.import = {
}); });
const importModal = new Modal({ const importModal = new Modal({
heading: 'Restoring from a ' + APP_NAME + ' backup', heading: message.get('dataRestoreHeading'),
content: importForm.form(), content: importForm.form(),
successText: 'Import', successText: message.get('dataRestoreSuccessText'),
cancelText: message.get('dataRestoreCancelText'),
width: 'small', width: 'small',
successAction: () => { successAction: () => {
if (data.import.state.setup.include || data.import.state.theme.include || data.import.state.bookmark.include) { if (data.import.state.setup.include || data.import.state.theme.include || data.import.state.bookmark.include) {
@ -216,7 +219,7 @@ data.export = () => {
timestamp.year = leadingZero(timestamp.year); timestamp.year = leadingZero(timestamp.year);
timestamp = timestamp.year + '.' + timestamp.month + '.' + timestamp.date + ' - ' + timestamp.hours + ' ' + timestamp.minutes + ' ' + timestamp.seconds; timestamp = timestamp.year + '.' + timestamp.month + '.' + timestamp.date + ' - ' + timestamp.hours + ' ' + timestamp.minutes + ' ' + timestamp.seconds;
const fileName = APP_NAME + ' backup - ' + timestamp + '.json'; const fileName = APP_NAME + ' ' + message.get('dataExportBackup') + ' - ' + timestamp + '.json';
const dataToExport = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data.load())); const dataToExport = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data.load()));
@ -340,12 +343,13 @@ data.clear = {
all: { all: {
render: () => { render: () => {
const clearModal = new Modal({ const clearModal = new Modal({
heading: 'Clear all ' + APP_NAME + ' data?', heading: message.get('dataClearAllHeading'),
content: node('div', [ content: node('div', [
node('p:Are you sure you want to clear all ' + APP_NAME + ' Bookmarks and Settings? ' + APP_NAME + ' will be restore to the default state.'), node(`p:${message.get('dataClearAllContentPara1')}`),
node('p:This can not be undone.') node(`p:${message.get('dataClearAllContentPara2')}`)
]), ]),
successText: 'Clear all data', successText: message.get('dataClearAllSuccessText'),
cancelText: message.get('dataClearAllCancelText'),
width: 'small', width: 'small',
successAction: () => { successAction: () => {
data.wipe.all(); data.wipe.all();
@ -358,12 +362,13 @@ data.clear = {
partial: { partial: {
render: () => { render: () => {
const clearModal = new Modal({ const clearModal = new Modal({
heading: 'Clear ' + APP_NAME + ' data except bookmarks?', heading: message.get('dataClearPartialHeading'),
content: node('div', [ content: node('div', [
node('p:Are you sure you want to clear all ' + APP_NAME + ' Settings? ' + APP_NAME + ' will be restore to the default state but your Bookmarks and Groups will remain.'), node(`p:${message.get('dataClearPartialContentPara1')}`),
node('p:This can not be undone.') node(`p:${message.get('dataClearPartialContentPara2')}`)
]), ]),
successText: 'Clear all except bookmarks', successText: message.get('dataClearPartialSuccessText'),
cancelText: message.get('dataClearPartialCancelText'),
width: 35, width: 35,
successAction: () => { successAction: () => {
data.wipe.partial(); data.wipe.partial();
@ -379,7 +384,7 @@ data.feedback = {};
data.feedback.empty = { data.feedback.empty = {
render: (feedback) => { render: (feedback) => {
feedback.appendChild(node('p:Nothing selected to import.|class:muted small')); feedback.appendChild(node(`p:${message.get('dataFeedbackEmpty')}|class:muted small`));
} }
}; };
@ -391,7 +396,7 @@ data.feedback.clear = {
data.feedback.success = { data.feedback.success = {
render: (feedback, filename, action) => { render: (feedback, filename, action) => {
feedback.appendChild(node('p:Success! Restoring ' + APP_NAME + ' Bookmarks and Settings.|class:muted small')); feedback.appendChild(node(`p:${message.get('dataFeedbackSuccess')}|class:muted small`));
feedback.appendChild(node('p:' + filename)); feedback.appendChild(node('p:' + filename));
@ -404,21 +409,21 @@ data.feedback.success = {
data.feedback.fail = { data.feedback.fail = {
notJson: { notJson: {
render: (feedback, filename) => { render: (feedback, filename) => {
feedback.appendChild(node('p:Not a JSON file. Make sure the selected file came from ' + APP_NAME + '.|class:small muted')); feedback.appendChild(node(`p:${message.get('dataFeedbackFailNotJson')}|class:small muted`));
feedback.appendChild(complexNode({ tag: 'p', text: filename })); feedback.appendChild(complexNode({ tag: 'p', text: filename }));
data.feedback.animation.set.render(feedback, 'is-shake'); data.feedback.animation.set.render(feedback, 'is-shake');
} }
}, },
notAppJson: { notAppJson: {
render: (feedback, filename) => { render: (feedback, filename) => {
feedback.appendChild(node('p:Not the right kind of JSON file. Make sure the selected file came from ' + APP_NAME + '.|class:small muted')); feedback.appendChild(node(`p:${message.get('dataFeedbackFailNotAppJson')}|class:small muted`));
feedback.appendChild(complexNode({ tag: 'p', text: filename })); feedback.appendChild(complexNode({ tag: 'p', text: filename }));
data.feedback.animation.set.render(feedback, 'is-shake'); data.feedback.animation.set.render(feedback, 'is-shake');
} }
}, },
notClipboardJson: { notClipboardJson: {
render: (feedback, name) => { render: (feedback, name) => {
feedback.appendChild(node('p:Not the right kind of data. Make sure the clipboard holds data from ' + APP_NAME + ' or a ' + APP_NAME + ' backup JSON file.|class:small muted')); feedback.appendChild(node(`p:${message.get('dataFeedbackFailNotClipboardJson')}|class:small muted`));
feedback.appendChild(node('p:' + name)); feedback.appendChild(node('p:' + name));
data.feedback.animation.set.render(feedback, 'is-shake'); data.feedback.animation.set.render(feedback, 'is-shake');
} }

View File

@ -1,4 +1,3 @@
import { Button } from '../button'; import { Button } from '../button';
import { KeyboardShortcut } from '../keyboardShortcut'; import { KeyboardShortcut } from '../keyboardShortcut';
@ -6,7 +5,8 @@ import { node } from '../../utility/node';
import './index.css'; import './index.css';
export const Dropdown = function ({ export const Dropdown = function({
title = false,
text = 'Dropdown', text = 'Dropdown',
menuItem = [], menuItem = [],
buttonStyle = [], buttonStyle = [],
@ -23,6 +23,7 @@ export const Dropdown = function ({
menu: node('div|class:dropdown-menu'), menu: node('div|class:dropdown-menu'),
content: node('div|class:dropdown-content'), content: node('div|class:dropdown-content'),
toggle: new Button({ toggle: new Button({
title: title,
text: text, text: text,
srOnly: srOnly, srOnly: srOnly,
iconName: iconName, iconName: iconName,

View File

@ -4,7 +4,7 @@ import { trimString } from '../../../../utility/trimString';
import './index.css'; import './index.css';
export const select = function ({ export const select = function({
id = false, id = false,
classList = [], classList = [],
option = [], option = [],
@ -35,9 +35,10 @@ export const select = function ({
} }
if (option.length > 0) { if (option.length > 0) {
option.forEach((item) => { option.forEach((item) => {
if (typeof item == 'string') {
select.appendChild( select.appendChild(
complexNode({ complexNode({
tag: 'option', tag: 'option',
@ -49,12 +50,31 @@ export const select = function ({
}) })
); );
}); } else {
select.selectedIndex = selected; const option = complexNode({ tag: 'option' });
if (item.name) {
option.textContent = item.name;
}
if (item.id) {
option.value = item.id;
}
if (item.disabled) {
option.disabled = true;
}
select.appendChild(option);
} }
});
}
select.selectedIndex = selected;
return select; return select;
}; };

View File

@ -8,7 +8,7 @@ import moment from 'moment';
import './index.css'; import './index.css';
export const Greeting = function () { export const Greeting = function() {
this.now; this.now;
@ -25,10 +25,10 @@ export const Greeting = function () {
}; };
this.message = ['Good night', 'Good morning', 'Good afternoon', 'Good evening'];
this.update = () => { this.update = () => {
const goodMessage = ['Good night', 'Good morning', 'Good afternoon', 'Good evening'];
this.now = moment(); this.now = moment();
let value; let value;
@ -43,7 +43,7 @@ export const Greeting = function () {
case 'good': case 'good':
value = this.message[Math.floor(this.now.hours() / 6)]; value = goodMessage[Math.floor(this.now.hours() / 6)];
break; break;
@ -55,7 +55,7 @@ export const Greeting = function () {
case 'hi': case 'hi':
value = 'Hi'; value = 'hi';
break; break;
@ -67,7 +67,7 @@ export const Greeting = function () {
} else { } else {
value = this.message[Math.floor(this.now.hours() / 6)]; value = goodMessage[Math.floor(this.now.hours() / 6)];
} }

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { state } from '../state'; import { state } from '../state';
import { data } from '../data'; import { data } from '../data';
import { layout } from '../layout'; import { layout } from '../layout';
@ -213,9 +215,10 @@ group.add = {
const groupForm = new GroupForm({ groupData: newGroupData }); const groupForm = new GroupForm({ groupData: newGroupData });
const addModal = new Modal({ const addModal = new Modal({
heading: 'Add a new Group', heading: message.get('groupAddHeading'),
content: groupForm.form(), content: groupForm.form(),
successText: 'Add', successText: message.get('groupAddSuccessText'),
cancelText: message.get('groupAddCancelText'),
width: 40, width: 40,
openAction: () => { openAction: () => {

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { state } from '../state'; import { state } from '../state';
import { data } from '../data'; import { data } from '../data';
import { group } from '../group'; import { group } from '../group';
@ -14,7 +16,7 @@ import { node } from '../../utility/node';
import { isValidString } from '../../utility/isValidString'; import { isValidString } from '../../utility/isValidString';
import { clearChildNode } from '../../utility/clearChildNode'; import { clearChildNode } from '../../utility/clearChildNode';
export const GroupArea = function ({ export const GroupArea = function({
groupData = {} groupData = {}
} = {}) { } = {}) {
@ -42,11 +44,11 @@ export const GroupArea = function ({
this.control.button = { this.control.button = {
up: new Button({ up: new Button({
text: 'Move this group up', text: message.get('groupAreaControlUp'),
srOnly: true, srOnly: true,
iconName: 'arrowKeyboardUp', iconName: 'arrowKeyboardUp',
style: ['line'], style: ['line'],
title: 'Move this group up', title: message.get('groupAreaControlUp'),
classList: ['group-control-button', 'group-control-up'], classList: ['group-control-button', 'group-control-up'],
func: () => { func: () => {
@ -65,19 +67,19 @@ export const GroupArea = function ({
} }
}), }),
sort: new Button({ sort: new Button({
text: 'Drag group to reorder', text: message.get('groupAreaControlSort'),
srOnly: true, srOnly: true,
iconName: 'drag', iconName: 'drag',
style: ['line'], style: ['line'],
title: 'Drag group to reorder', title: message.get('groupAreaControlSort'),
classList: ['group-control-button', 'group-control-sort'], classList: ['group-control-button', 'group-control-sort'],
}), }),
down: new Button({ down: new Button({
text: 'Move this group down', text: message.get('groupAreaControlDown'),
srOnly: true, srOnly: true,
iconName: 'arrowKeyboardDown', iconName: 'arrowKeyboardDown',
style: ['line'], style: ['line'],
title: 'Move this group right', title: message.get('groupAreaControlDown'),
classList: ['group-control-button', 'group-control-up'], classList: ['group-control-button', 'group-control-up'],
func: () => { func: () => {
@ -96,11 +98,11 @@ export const GroupArea = function ({
} }
}), }),
edit: new Button({ edit: new Button({
text: 'Edit this group', text: message.get('groupAreaControlEdit'),
srOnly: true, srOnly: true,
iconName: 'edit', iconName: 'edit',
style: ['line'], style: ['line'],
title: 'Edit this group', title: message.get('groupAreaControlEdit'),
classList: ['group-control-button', 'group-control-edit'], classList: ['group-control-button', 'group-control-edit'],
func: () => { func: () => {
@ -115,9 +117,10 @@ export const GroupArea = function ({
const groupForm = new GroupForm({ groupData: newGroupData }); const groupForm = new GroupForm({ groupData: newGroupData });
const editModal = new Modal({ const editModal = new Modal({
heading: isValidString(newGroupData.group.name.text) ? 'Edit ' + newGroupData.group.name.text : 'Edit unnamed group', heading: isValidString(newGroupData.group.name.text) ? `${message.get('groupEditHeadingName')} ${newGroupData.group.name.text}` : message.get('groupEditHeadingUnnamed'),
content: groupForm.form(), content: groupForm.form(),
successText: 'Save', successText: message.get('groupEditSuccessText'),
cancelText: message.get('groupEditCancelText'),
width: 40, width: 40,
successAction: () => { successAction: () => {
@ -135,18 +138,19 @@ export const GroupArea = function ({
} }
}), }),
remove: new Button({ remove: new Button({
text: 'Remove this group', text: message.get('groupAreaControlRemove'),
srOnly: true, srOnly: true,
iconName: 'cross', iconName: 'cross',
style: ['line'], style: ['line'],
title: 'Remove this group', title: message.get('groupAreaControlRemove'),
classList: ['group-control-button', 'group-control-remove'], classList: ['group-control-button', 'group-control-remove'],
func: () => { func: () => {
const removeModal = new Modal({ const removeModal = new Modal({
heading: isValidString(groupData.group.name.text) ? 'Remove ' + groupData.group.name.text : 'Remove unnamed bookmark', heading: isValidString(groupData.group.name.text) ? `${message.get('groupRemoveHeadingName')} ${groupData.group.name.text}` : message.get('groupRemoveHeadingUnnamed'),
content: 'Are you sure you want to remove this Group and all the Bookmarks within? This can not be undone.', content: message.get('groupRemoveContent'),
successText: 'Remove', successText: message.get('groupRemoveSuccessText'),
cancelText: message.get('groupRemoveCancelText'),
width: 'small', width: 'small',
successAction: () => { successAction: () => {
@ -169,9 +173,9 @@ export const GroupArea = function ({
this.openAll = { this.openAll = {
button: new Button({ button: new Button({
text: 'Open all Bookmarks in this Group', text: message.get('groupAreaControlOpenAll'),
style: ['line'], style: ['line'],
title: 'Open all Bookmarks in this Group', title: message.get('groupAreaControlOpenAll'),
srOnly: true, srOnly: true,
iconName: 'openAll', iconName: 'openAll',
classList: ['group-toolbar-button', 'group-toolbar-open-all'], classList: ['group-toolbar-button', 'group-toolbar-open-all'],
@ -208,9 +212,9 @@ export const GroupArea = function ({
this.collapse = { this.collapse = {
button: new Button({ button: new Button({
text: 'Collapse this Group', text: message.get('groupAreaControlCollapse'),
style: ['line'], style: ['line'],
title: 'Collapse this Group', title: message.get('groupAreaControlCollapse'),
srOnly: true, srOnly: true,
iconName: 'arrowKeyboardUp', iconName: 'arrowKeyboardUp',
classList: ['group-toolbar-button', 'group-toolbar-collapse'], classList: ['group-toolbar-button', 'group-toolbar-collapse'],

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { bookmark } from '../bookmark'; import { bookmark } from '../bookmark';
import * as form from '../form'; import * as form from '../form';
@ -58,26 +60,26 @@ export const GroupForm = function({
this.control.group = { this.control.group = {
name: { name: {
show: new Control_checkbox({
object: groupData.group,
path: 'name.show',
id: 'name-show',
labelText: message.get('groupFormNameShow'),
action: () => {
this.disable();
}
}),
text: new Control_text({ text: new Control_text({
object: groupData.group, object: groupData.group,
path: 'name.text', path: 'name.text',
id: 'name-text', id: 'name-text',
value: groupData.group.name.text, value: groupData.group.name.text,
placeholder: 'Example group', placeholder: message.get('groupFormNameTextPlaceholder'),
labelText: 'Group name', labelText: message.get('groupFormNameTextLabel'),
srOnly: true srOnly: true
}), }),
show: new Control_checkbox({
object: groupData.group,
path: 'name.show',
id: 'name-show',
labelText: 'Show Group name',
action: () => {
this.disable();
}
}),
random: new Button({ random: new Button({
text: 'Random Group name', text: message.get('groupFormNameRandom'),
style: ['line'], style: ['line'],
func: () => { func: () => {
groupData.group.name.text = randomString({ adjectivesCount: randomNumber(1, 3) }); groupData.group.name.text = randomString({ adjectivesCount: randomNumber(1, 3) });
@ -90,8 +92,8 @@ export const GroupForm = function({
object: groupData.group, object: groupData.group,
path: 'toolbar.collapse.show', path: 'toolbar.collapse.show',
id: 'toolbar-collapse-show', id: 'toolbar-collapse-show',
labelText: 'Show Collapse', labelText: message.get('groupFormCollapseShowLabel'),
description: 'The Collapse button will show or hide the Bookmaks in this Group.' description: message.get('groupFormCollapseShowDescription')
}) })
}, },
openAll: { openAll: {
@ -99,8 +101,8 @@ export const GroupForm = function({
object: groupData.group, object: groupData.group,
path: 'toolbar.openAll.show', path: 'toolbar.openAll.show',
id: 'toolbar-openAll-show', id: 'toolbar-openAll-show',
labelText: 'Show Open all', labelText: message.get('groupFormOpenAllShowLabel'),
description: 'Open all button will appear if there is at least one Bookmark in this Group.' description: message.get('groupFormOpenAllShowDescription')
}) })
} }
}; };
@ -109,7 +111,7 @@ export const GroupForm = function({
object: groupData, object: groupData,
path: 'position.destination', path: 'position.destination',
id: 'position-destination', id: 'position-destination',
labelText: 'Position', labelText: message.get('groupFormDestination'),
option: this.selectOption.group(), option: this.selectOption.group(),
selected: groupData.position.destination selected: groupData.position.destination
}); });
@ -139,8 +141,8 @@ export const GroupForm = function({
form.wrap({ form.wrap({
children: [ children: [
node('div|class:group-form-description', [ node('div|class:group-form-description', [
node('h2:Name'), node(`h2:${message.get('groupFormSectionNameHeading')}`),
node('p:Display a Name above this Group.') node(`p:${message.get('groupFormSectionNameDescription')}`)
]) ])
] ]
}), }),
@ -177,8 +179,8 @@ export const GroupForm = function({
form.wrap({ form.wrap({
children: [ children: [
node('div|class:group-form-description', [ node('div|class:group-form-description', [
node('h2:Toolbar'), node(`h2:${message.get('groupFormSectionToolbarHeading')}`),
node('p:Display controls to open all or show/hide the Bookmarks in this Group.') node(`p:${message.get('groupFormSectionToolbarDescription')}`)
]) ])
] ]
}), }),
@ -206,8 +208,8 @@ export const GroupForm = function({
form.wrap({ form.wrap({
children: [ children: [
node('div|class:group-form-description', [ node('div|class:group-form-description', [
node('h2:Ordering'), node(`h2:${message.get('groupFormSectionOrderingHeading')}`),
node('p:The position of this Group.') node(`p:${message.get('groupFormSectionOrderingDescription')}`)
]) ])
] ]
}), }),

View File

@ -105,6 +105,9 @@ icon.all = {
}, },
openAll: { openAll: {
path: 'M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z' path: 'M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z'
},
globe: {
path: 'M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2s.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2s.07-1.35.16-2h4.68c.09.65.16 1.32.16 2s-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2s-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z'
} }
}; };

View File

@ -0,0 +1,7 @@
:root {
--import-form-space: calc((var(--form-space) / 4) * 1em);
}
.import-form-description {
margin-bottom: var(--import-form-space);
}

View File

@ -1,25 +1,28 @@
import { message } from '../message';
import * as form from '../form'; import * as form from '../form';
import { Control_radio } from '../control/radio'; import { Control_radio } from '../control/radio';
import { Control_checkbox } from '../control/checkbox'; import { Control_checkbox } from '../control/checkbox';
import { node } from '../../utility/node'; import { node } from '../../utility/node';
import { complexNode } from '../../utility/complexNode'; import { complexNode } from '../../utility/complexNode';
export const ImportForm = function ({ import './index.css';
export const ImportForm = function({
dataToImport = false, dataToImport = false,
state = false state = false
} = {}) { } = {}) {
this.element = { this.element = {
form: node('form|class:import-form'), form: node('form|class:import-form'),
description: complexNode({ description: node('div|class:import-form-description', [
complexNode({
tag: 'p', tag: 'p',
text: 'You can restore all or parts of a backup file. The following data will be restored:', text: message.get('dataFormDescription')
attr: [{ key: 'class', value: 'mb-5' }]
}) })
])
}; };
this.count = { this.count = {
@ -41,8 +44,11 @@ export const ImportForm = function ({
object: state, object: state,
path: 'bookmark.include', path: 'bookmark.include',
id: 'bookmark-include', id: 'bookmark-include',
labelText: 'Bookmarks', labelText: message.get('dataFormBookmarkIncludeLabel'),
description: [`This includes <strong>${this.count.bookmark()} ${this.count.bookmark() > 1 ? 'Bookmarks' : 'Bookmark'}</strong> in <strong>${dataToImport.bookmark.length} ${dataToImport.bookmark.length > 1 ? 'Groups' : 'Group'}.<strong>`, 'Bookmarks will keep any custom Colours, Accents and Borders when imported.'], description: [
message.get('dataFormBookmarkIncludeDescriptionPara1'),
message.get('dataFormBookmarkIncludeDescriptionPara2')
],
action: () => { action: () => {
this.disable(); this.disable();
} }
@ -50,8 +56,8 @@ export const ImportForm = function ({
type: new Control_radio({ type: new Control_radio({
object: state, object: state,
radioGroup: [ radioGroup: [
{ id: 'bookmark-type-restore', labelText: 'Replace existing bookmarks', value: 'restore' }, { id: 'bookmark-type-restore', labelText: message.get('dataFormBookmarkTypeRestore'), value: 'restore' },
{ id: 'bookmark-type-append', labelText: 'Add to existing bookmarks', value: 'append' } { id: 'bookmark-type-append', labelText: message.get('dataFormBookmarkTypeAppend'), value: 'append' }
], ],
groupName: 'bookmark-type', groupName: 'bookmark-type',
path: 'bookmark.type' path: 'bookmark.type'
@ -62,8 +68,8 @@ export const ImportForm = function ({
object: state, object: state,
path: 'theme.include', path: 'theme.include',
id: 'theme-include', id: 'theme-include',
labelText: 'Theme', labelText: message.get('dataFormThemeIncludeLabel'),
description: 'This includes the Colour, Accent, Fonts, Background and any saved Custom Themes.' description: message.get('dataFormThemeIncludeDescription')
}) })
}, },
setup: { setup: {
@ -71,8 +77,8 @@ export const ImportForm = function ({
object: state, object: state,
path: 'setup.include', path: 'setup.include',
id: 'setup-include', id: 'setup-include',
labelText: 'Settings', labelText: message.get('dataFormSetupIncludeLabel'),
description: 'This includes Layout size and position, Header area size, Bookmark area size and other user settings.' description: message.get('dataFormSetupIncludeDescription')
}) })
} }
} }

View File

@ -16,6 +16,7 @@ import { header } from './header';
import { group } from './group'; import { group } from './group';
import { toolbar } from './toolbar'; import { toolbar } from './toolbar';
import { groupAndBookmark } from './groupAndBookmark'; import { groupAndBookmark } from './groupAndBookmark';
import { message } from './message';
import * as form from './form'; import * as form from './form';
@ -38,5 +39,6 @@ export const component = {
group, group,
form, form,
toolbar, toolbar,
groupAndBookmark groupAndBookmark,
message
}; };

View File

@ -1,23 +1,22 @@
import { state } from '../state'; import { state } from '../state';
import { APP_NAME } from '../../constant';
import { MenuFrame } from '../menuFrame'; import { MenuFrame } from '../menuFrame';
const menu = {}; const menu = {};
menu.navData = [ menu.navData = [
// { name: 'Debug', active: true, overscroll: true, sub: ['Input', 'Button', 'Bookmark', 'Icon'] }, // { name: 'debug', active: true, overscroll: true, sub: ['input', 'button', 'bookmark', 'icon'] },
{ name: 'Theme', active: true, overscroll: true, sub: ['Preset', 'Saved', 'Style', 'Colour', 'Accent', 'Font', 'Radius', 'Shadow', 'Shade', 'Opacity', 'Background', 'Layout', 'Header', 'Bookmark'] }, { name: 'theme', active: true, overscroll: true, sub: ['preset', 'saved', 'style', 'color', 'accent', 'font', 'radius', 'shadow', 'shade', 'opacity', 'background', 'layout', 'header', 'bookmark'] },
{ name: 'Layout', active: false, overscroll: true, sub: ['Scaling', 'Area', 'Padding', 'Gutter', 'Alignment', 'Page'] }, { name: 'layout', active: false, overscroll: true, sub: ['scaling', 'area', 'padding', 'gutter', 'alignment', 'page'] },
{ name: 'Header', active: false, overscroll: true, sub: ['Alignment', 'Greeting', 'Transitional words', 'Clock', 'Date', 'Search'] }, { name: 'header', active: false, overscroll: true, sub: ['alignment', 'greeting', 'transitional', 'clock', 'date', 'search'] },
{ name: 'Bookmark', active: false, overscroll: true, sub: ['General', 'Style', 'Orientation', 'Sort'] }, { name: 'bookmark', active: false, overscroll: true, sub: ['general', 'style', 'orientation', 'sort'] },
{ name: 'Group', active: false, overscroll: true, sub: ['Alignment', 'Name', 'Collapse', 'Toolbar'] }, { name: 'group', active: false, overscroll: true, sub: ['alignment', 'name', 'collapse', 'toolbar'] },
{ name: 'Toolbar', active: false, overscroll: true, sub: ['Size', 'Location', 'Position', 'Controls'] }, { name: 'toolbar', active: false, overscroll: true, sub: ['size', 'location', 'position', 'controls'] },
{ name: 'Data', active: false, overscroll: true, sub: ['Restore', 'Backup', 'Clear'] }, { name: 'data', active: false, overscroll: true, sub: ['restore', 'backup', 'clear'] },
{ name: 'Support', active: false, overscroll: false }, { name: 'language', active: false, overscroll: false },
{ name: 'Coffee', active: false, overscroll: false }, { name: 'support', active: false, overscroll: false },
{ name: APP_NAME, active: false, overscroll: false } { name: 'coffee', active: false, overscroll: false },
{ name: 'app', active: false, overscroll: false }
]; ];
menu.mod = {}; menu.mod = {};

View File

@ -1,3 +1,7 @@
import { message } from '../../message';
import * as form from '../../form';
import { node } from '../../../utility/node'; import { node } from '../../../utility/node';
import { APP_NAME } from '../../../constant'; import { APP_NAME } from '../../../constant';
@ -7,25 +11,29 @@ import { Splash } from '../../splash';
const appSetting = {}; const appSetting = {};
appSetting[APP_NAME.toLowerCase()] = (parent) => { appSetting.app = (parent) => {
const githubLink = new Link({ text: 'GitHub.', href: `https://github.com/zombieFox/${APP_NAME}`, openNew: true }); appSetting.app.para1 = node(`p:${message.get('menuContentAppPara1')}`);
const redditLink = new Link({ text: `Reddit ${APP_NAME} community.`, href: `https://www.reddit.com/r/${APP_NAME}`, openNew: true }); appSetting.app.link1 = new Link({
text: message.get('menuContentAppLink1'),
href: `https://www.reddit.com/r/${APP_NAME}`,
openNew: true
});
const licenseLink = new Link({ text: 'GNU General Public License v3.0', href: `https://github.com/zombieFox/${APP_NAME}/blob/master/license`, openNew: true }); appSetting.app.para2 = node(`p:${message.get('menuContentAppPara2')}`);
const para1 = node('p'); appSetting.app.link2 = new Link({
text: message.get('menuContentAppLink2'),
href: `https://github.com/zombieFox/${APP_NAME}`,
openNew: true
});
para1.innerHTML = `This project can be found on ${githubLink.link().outerHTML}`; appSetting.app.link3 = new Link({
text: message.get('menuContentAppLink3'),
const para2 = node('p'); href: `https://github.com/zombieFox/${APP_NAME}/blob/master/license`,
openNew: true
para2.innerHTML = `Share your setup with the ${redditLink.link().outerHTML}`; });
const para3 = node('p');
para3.innerHTML = `${APP_NAME} uses the ${licenseLink.link().outerHTML}`;
const splash = new Splash(); const splash = new Splash();
@ -33,9 +41,33 @@ appSetting[APP_NAME.toLowerCase()] = (parent) => {
node('div', [ node('div', [
splash.splash(), splash.splash(),
node('hr'), node('hr'),
para1, form.wrap({
para2, children: [
para3 appSetting.app.para1,
form.indent({
children: [
node('p', [
appSetting.app.link1.link()
])
]
})
]
}),
form.wrap({
children: [
appSetting.app.para2,
form.indent({
children: [
node('p', [
appSetting.app.link2.link()
]),
node('p', [
appSetting.app.link3.link()
])
]
})
]
})
]) ])
); );

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import { state } from '../../state'; import { state } from '../../state';
import { data } from '../../data'; import { data } from '../../data';
import { bookmark } from '../../bookmark'; import { bookmark } from '../../bookmark';
@ -77,7 +79,7 @@ bookmarkSetting.general = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'bookmark-show', id: 'bookmark-show',
path: 'bookmark.show', path: 'bookmark.show',
labelText: 'Show Bookmarks', labelText: message.get('menuContentBookmarkGeneralShow'),
action: () => { action: () => {
layout.area.assemble(); layout.area.assemble();
@ -111,7 +113,7 @@ bookmarkSetting.general = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'bookmark-url-show', id: 'bookmark-url-show',
path: 'bookmark.url.show', path: 'bookmark.url.show',
labelText: 'Show URL on Bookmark hover', labelText: message.get('menuContentBookmarkGeneralUrlShow'),
action: () => { action: () => {
applyCSSState('bookmark.url.show'); applyCSSState('bookmark.url.show');
data.save(); data.save();
@ -122,7 +124,7 @@ bookmarkSetting.general = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'bookmark-line-show', id: 'bookmark-line-show',
path: 'bookmark.line.show', path: 'bookmark.line.show',
labelText: 'Show Bookmark line', labelText: message.get('menuContentBookmarkGeneralLineShow'),
action: () => { action: () => {
applyCSSState('bookmark.line.show'); applyCSSState('bookmark.line.show');
data.save(); data.save();
@ -133,8 +135,8 @@ bookmarkSetting.general = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'bookmark-shadow-show', id: 'bookmark-shadow-show',
path: 'bookmark.shadow.show', path: 'bookmark.shadow.show',
labelText: 'Show shadow on Bookmark hover', labelText: message.get('menuContentBookmarkGeneralShadowShowLabel'),
description: 'Effects may not be visible if Theme Shadow is set to 0.', description: message.get('menuContentBookmarkGeneralShadowShowDescription'),
action: () => { action: () => {
applyCSSState('bookmark.shadow.show'); applyCSSState('bookmark.shadow.show');
data.save(); data.save();
@ -145,7 +147,7 @@ bookmarkSetting.general = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'bookmark-hoverScale-show', id: 'bookmark-hoverScale-show',
path: 'bookmark.hoverScale.show', path: 'bookmark.hoverScale.show',
labelText: 'Grow on Bookmark hover', labelText: message.get('menuContentBookmarkGeneralHoverScaleShow'),
action: () => { action: () => {
applyCSSState('bookmark.hoverScale.show'); applyCSSState('bookmark.hoverScale.show');
data.save(); data.save();
@ -156,7 +158,7 @@ bookmarkSetting.general = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'bookmark-newTab', id: 'bookmark-newTab',
path: 'bookmark.newTab', path: 'bookmark.newTab',
labelText: 'Open Bookmarks in a new tab', labelText: message.get('menuContentBookmarkGeneralNewTab'),
action: () => { action: () => {
groupAndBookmark.render(); groupAndBookmark.render();
@ -184,7 +186,7 @@ bookmarkSetting.general = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'bookmark.size', path: 'bookmark.size',
id: 'bookmark-size', id: 'bookmark-size',
labelText: 'Bookmark size', labelText: message.get('menuContentBookmarkGeneralSize'),
value: state.get.current().bookmark.size, value: state.get.current().bookmark.size,
defaultValue: state.get.default().bookmark.size, defaultValue: state.get.default().bookmark.size,
min: state.get.minMax().bookmark.size.min, min: state.get.minMax().bookmark.size.min,
@ -241,8 +243,8 @@ bookmarkSetting.style = (parent) => {
bookmarkSetting.control.style = new Control_radio({ bookmarkSetting.control.style = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'bookmark-style-block', labelText: 'Block', description: 'Square shaped Bookmark tiles.', value: 'block' }, { id: 'bookmark-style-block', labelText: message.get('menuContentBookmarkStyleBlockLabel'), description: message.get('menuContentBookmarkStyleBlockDescription'), value: 'block' },
{ id: 'bookmark-style-list', labelText: 'List', description: 'Short and wide Bookmark tiles.', value: 'list' } { id: 'bookmark-style-list', labelText: message.get('menuContentBookmarkStyleListLabel'), description: message.get('menuContentBookmarkStyleListDescription'), value: 'list' }
], ],
groupName: 'bookmark-style', groupName: 'bookmark-style',
path: 'bookmark.style', path: 'bookmark.style',
@ -296,8 +298,8 @@ bookmarkSetting.orientation = (parent) => {
bookmarkSetting.control.orientation.orientationElement = new Control_radio({ bookmarkSetting.control.orientation.orientationElement = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'bookmark-orientation-top', labelText: 'Top', value: 'top' }, { id: 'bookmark-orientation-top', labelText: message.get('menuContentBookmarkOrientationTop'), value: 'top' },
{ id: 'bookmark-orientation-bottom', labelText: 'Bottom', value: 'bottom' } { id: 'bookmark-orientation-bottom', labelText: message.get('menuContentBookmarkOrientationBottom'), value: 'bottom' }
], ],
groupName: 'bookmark-orientation', groupName: 'bookmark-orientation',
path: 'bookmark.orientation', path: 'bookmark.orientation',
@ -325,7 +327,7 @@ bookmarkSetting.orientation = (parent) => {
}); });
bookmarkSetting.control.orientation.orientationHelper = new Control_helperText({ bookmarkSetting.control.orientation.orientationHelper = new Control_helperText({
text: ['Display the URL and Controls either at the top or bottom of a Bookmark Tile.'] text: [message.get('menuContentBookmarkOrientationHelperPara1')]
}); });
parent.appendChild( parent.appendChild(
@ -340,7 +342,7 @@ bookmarkSetting.orientation = (parent) => {
bookmarkSetting.sort = (parent) => { bookmarkSetting.sort = (parent) => {
bookmarkSetting.control.sort.letter = new Button({ bookmarkSetting.control.sort.letter = new Button({
text: 'By letter', text: message.get('menuContentBookmarkSortLetter'),
style: ['line'], style: ['line'],
func: () => { func: () => {
@ -368,7 +370,7 @@ bookmarkSetting.sort = (parent) => {
}); });
bookmarkSetting.control.sort.icon = new Button({ bookmarkSetting.control.sort.icon = new Button({
text: 'By icon', text: message.get('menuContentBookmarkSortIcon'),
style: ['line'], style: ['line'],
func: () => { func: () => {
@ -396,7 +398,7 @@ bookmarkSetting.sort = (parent) => {
}); });
bookmarkSetting.control.sort.name = new Button({ bookmarkSetting.control.sort.name = new Button({
text: 'By name', text: message.get('menuContentBookmarkSortName'),
style: ['line'], style: ['line'],
func: () => { func: () => {

View File

@ -1,10 +1,9 @@
import { APP_NAME } from '../../../constant'; import { message } from '../../message';
import * as form from '../../form'; import * as form from '../../form';
import { Link } from '../../link'; import { Link } from '../../link';
import { node } from '../../../utility/node'; import { node } from '../../../utility/node';
import { complexNode } from '../../../utility/complexNode'; import { complexNode } from '../../../utility/complexNode';
@ -16,11 +15,11 @@ coffeeSetting.coffee = (parent) => {
node('div', [ node('div', [
complexNode({ complexNode({
tag: 'p', tag: 'p',
text: APP_NAME + ' is free, appreciation is welcome in the form of coffee!' text: message.get('menuContentCoffeePara')
}), }),
form.wrap({ form.wrap({
children: [(new Link({ children: [(new Link({
text: 'Buy me a coffee', text: message.get('menuContentCoffeeButton'),
href: 'https://www.buymeacoffee.com/zombieFox', href: 'https://www.buymeacoffee.com/zombieFox',
iconName: 'coffee', iconName: 'coffee',
iconPosition: 'left', iconPosition: 'left',

View File

@ -1,6 +1,7 @@
import { message } from '../../message';
import { data } from '../../data'; import { data } from '../../data';
import { menu } from '../../menu'; import { menu } from '../../menu';
import { APP_NAME } from '../../../constant';
import * as form from '../../form'; import * as form from '../../form';
@ -28,7 +29,7 @@ dataSetting.restore = (parent) => {
id: 'restore-data', id: 'restore-data',
type: 'file', type: 'file',
inputHide: true, inputHide: true,
labelText: 'Import from file', labelText: message.get('menuContentDataRestoreFile'),
inputButtonStyle: ['line'], inputButtonStyle: ['line'],
action: () => { action: () => {
data.import.file({ data.import.file({
@ -40,7 +41,7 @@ dataSetting.restore = (parent) => {
}); });
dataSetting.control.restore.paste = new Button({ dataSetting.control.restore.paste = new Button({
text: 'Import from clipboard', text: message.get('menuContentDataRestoreClipboard'),
style: ['line'], style: ['line'],
func: () => { func: () => {
data.import.paste({ data.import.paste({
@ -50,7 +51,7 @@ dataSetting.restore = (parent) => {
}); });
dataSetting.control.restore.restoreHelper = new Control_helperText({ dataSetting.control.restore.restoreHelper = new Control_helperText({
text: ['Restore a previously exported ' + APP_NAME + ' backup.'] text: [message.get('menuContentDataRestoreHelperPara1')]
}); });
dataSetting.control.restore.feedback = form.feedback(); dataSetting.control.restore.feedback = form.feedback();
@ -58,7 +59,7 @@ dataSetting.restore = (parent) => {
data.feedback.empty.render(dataSetting.control.restore.feedback); data.feedback.empty.render(dataSetting.control.restore.feedback);
dataSetting.control.restore.drop = new DropFile({ dataSetting.control.restore.drop = new DropFile({
heading: 'Or drop a ' + APP_NAME + ' backup file here.', heading: message.get('menuContentDataRestoreDrop'),
dropAaction: () => { dropAaction: () => {
data.import.drop({ data.import.drop({
fileList: dataSetting.control.restore.drop.files, fileList: dataSetting.control.restore.drop.files,
@ -88,7 +89,7 @@ dataSetting.restore = (parent) => {
dataSetting.backup = (parent) => { dataSetting.backup = (parent) => {
dataSetting.control.backup.export = new Button({ dataSetting.control.backup.export = new Button({
text: 'Export data', text: message.get('menuContentDataBackupFile'),
style: ['line'], style: ['line'],
func: () => { func: () => {
data.export(); data.export();
@ -96,7 +97,7 @@ dataSetting.backup = (parent) => {
}); });
dataSetting.control.backup.copy = new Button({ dataSetting.control.backup.copy = new Button({
text: 'Copy to clipboard', text: message.get('menuContentDataBackupClipboard'),
style: ['line'], style: ['line'],
func: () => { func: () => {
navigator.clipboard.writeText(JSON.stringify(data.load())); navigator.clipboard.writeText(JSON.stringify(data.load()));
@ -104,7 +105,10 @@ dataSetting.backup = (parent) => {
}); });
dataSetting.control.backup.exportHelper = new Control_helperText({ dataSetting.control.backup.exportHelper = new Control_helperText({
text: ['Download a backup of your ' + APP_NAME + ' Bookmarks and Settings.', 'This file can later be imported on this or another deivce.'] text: [
message.get('menuContentDataBackupHelperPara1'),
message.get('menuContentDataBackupHelperPara2')
]
}); });
parent.appendChild( parent.appendChild(
@ -131,7 +135,7 @@ dataSetting.backup = (parent) => {
dataSetting.clear = (parent) => { dataSetting.clear = (parent) => {
dataSetting.control.clear.all = new Button({ dataSetting.control.clear.all = new Button({
text: 'Clear all data', text: message.get('menuContentDataClearAll'),
style: ['line'], style: ['line'],
func: () => { func: () => {
menu.close(); menu.close();
@ -140,7 +144,7 @@ dataSetting.clear = (parent) => {
}); });
dataSetting.control.clear.partial = new Button({ dataSetting.control.clear.partial = new Button({
text: 'Clear all except bookmarks', text: message.get('menuContentDataClearPartial'),
style: ['line'], style: ['line'],
func: () => { func: () => {
menu.close(); menu.close();
@ -148,16 +152,24 @@ dataSetting.clear = (parent) => {
} }
}); });
dataSetting.control.clear.link = new Link({
text: message.get('menuContentDataClearAlertLink'),
href: '#menu-content-item-backup'
});
dataSetting.control.clear.alert = new Alert({ dataSetting.control.clear.alert = new Alert({
iconName: 'warning', iconName: 'warning',
children: [ children: [
node('p:You will lose Bookmarks by clearing all data.|class:small'), node(`p:${message.get('menuContentDataClearAlertPara')}|class:small`),
node(`p:Have you ${(new Link({ text: 'backed up your data?', href: '#menu-content-item-backup' })).link().outerHTML}|class:small`) node('p|class:small', dataSetting.control.clear.link.link())
] ]
}); });
dataSetting.control.clear.helper = new Control_helperText({ dataSetting.control.clear.helper = new Control_helperText({
text: ['Clear all data to reset ' + APP_NAME + ' to the default state.', 'Alternatively, it is possible to wipe all settings but keep the current Bookmarks and Groups.'] text: [
message.get('menuContentDataClearHelperPara1'),
message.get('menuContentDataClearHelperPara2')
]
}); });
parent.appendChild( parent.appendChild(

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import { state } from '../../state'; import { state } from '../../state';
import { data } from '../../data'; import { data } from '../../data';
import { bookmark } from '../../bookmark'; import { bookmark } from '../../bookmark';
@ -124,11 +126,11 @@ groupSetting.alignment = (parent) => {
groupSetting.control.alignment.justify = new Control_radioGrid({ groupSetting.control.alignment.justify = new Control_radioGrid({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'group-area-justify-left', labelText: 'Left', value: 'left', position: 1 }, { id: 'group-area-justify-left', labelText: message.get('menuContentGroupAlignmentJustifyLeft'), value: 'left', position: 1 },
{ id: 'group-area-justify-center', labelText: 'Center', value: 'center', position: 2 }, { id: 'group-area-justify-center', labelText: message.get('menuContentGroupAlignmentJustifyCenter'), value: 'center', position: 2 },
{ id: 'group-area-justify-right', labelText: 'Right', value: 'right', position: 3 } { id: 'group-area-justify-right', labelText: message.get('menuContentGroupAlignmentJustifyRight'), value: 'right', position: 3 }
], ],
label: 'Group details area alignment', label: message.get('menuContentGroupAlignmentJustifyLabel'),
groupName: 'group-area-justify', groupName: 'group-area-justify',
path: 'group.area.justify', path: 'group.area.justify',
gridSize: '3x1', gridSize: '3x1',
@ -140,9 +142,10 @@ groupSetting.alignment = (parent) => {
groupSetting.control.alignment.order = new Control_radio({ groupSetting.control.alignment.order = new Control_radio({
object: state.get.current(), object: state.get.current(),
label: message.get('menuContentGroupAlignmentOrderLabel'),
radioGroup: [ radioGroup: [
{ id: 'group-order-header-body', labelText: 'Group details then Bookmarks', description: 'Order the Group details area to appear before the Bookmarks area.', value: 'header-body' }, { id: 'group-order-header-body', labelText: message.get('menuContentGroupAlignmentOrderHeaderBodyLabel'), description: message.get('menuContentGroupAlignmentOrderHeaderBodyDescription'), value: 'header-body' },
{ id: 'group-order-body-header', labelText: 'Bookmarks then Group details', description: 'Order the Bookmarks area to appear before the Group details area.', value: 'body-header' } { id: 'group-order-body-header', labelText: message.get('menuContentGroupAlignmentOrderBodyHeaderLabel'), description: message.get('menuContentGroupAlignmentOrderBodyHeaderDescription'), value: 'body-header' }
], ],
groupName: 'group-order', groupName: 'group-order',
path: 'group.order', path: 'group.order',
@ -226,7 +229,7 @@ groupSetting.name = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'group.name.size', path: 'group.name.size',
id: 'group-name-size', id: 'group-name-size',
labelText: 'Name size', labelText: message.get('menuContentGroupNameSize'),
value: state.get.current().group.name.size, value: state.get.current().group.name.size,
defaultValue: state.get.default().group.name.size, defaultValue: state.get.default().group.name.size,
min: state.get.minMax().group.name.size.min, min: state.get.minMax().group.name.size.min,
@ -270,7 +273,7 @@ groupSetting.name = (parent) => {
}); });
groupSetting.control.name.show = new Button({ groupSetting.control.name.show = new Button({
text: 'Show all', text: message.get('menuContentGroupNameShow'),
style: ['line'], style: ['line'],
func: () => { func: () => {
@ -288,7 +291,7 @@ groupSetting.name = (parent) => {
}); });
groupSetting.control.name.hide = new Button({ groupSetting.control.name.hide = new Button({
text: 'Hide all', text: message.get('menuContentGroupNameHide'),
style: ['line'], style: ['line'],
func: () => { func: () => {
@ -306,7 +309,7 @@ groupSetting.name = (parent) => {
}); });
groupSetting.control.name.helper = new Control_helperText({ groupSetting.control.name.helper = new Control_helperText({
text: ['Group Names can also be changed by editing individual Groups.'] text: [message.get('menuContentGroupNameHelperPara1')]
}); });
parent.appendChild( parent.appendChild(
@ -331,11 +334,11 @@ groupSetting.collapse = (parent) => {
groupSetting.control.collapse = { groupSetting.control.collapse = {
show: new Button({ show: new Button({
text: 'Collapse all groups', text: message.get('menuContentGroupCollapseShow'),
style: ['line'], style: ['line'],
func: () => { func: () => {
bookmark.all.forEach(item => { item.collapse = true; }); bookmark.all.forEach(item => { item.collapse = false; });
groupAndBookmark.render(); groupAndBookmark.render();
@ -348,11 +351,11 @@ groupSetting.collapse = (parent) => {
} }
}), }),
hide: new Button({ hide: new Button({
text: 'Open all groups', text: message.get('menuContentGroupCollapseHide'),
style: ['line'], style: ['line'],
func: () => { func: () => {
bookmark.all.forEach(item => { item.collapse = false; }); bookmark.all.forEach(item => { item.collapse = true; });
groupAndBookmark.render(); groupAndBookmark.render();
@ -390,7 +393,7 @@ groupSetting.toolbar = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'group.toolbar.size', path: 'group.toolbar.size',
id: 'group-toolbar-size', id: 'group-toolbar-size',
labelText: 'Group toolbar size', labelText: message.get('menuContentGroupToolbarSize'),
value: state.get.current().group.toolbar.size, value: state.get.current().group.toolbar.size,
defaultValue: state.get.default().group.toolbar.size, defaultValue: state.get.default().group.toolbar.size,
min: state.get.minMax().group.toolbar.size.min, min: state.get.minMax().group.toolbar.size.min,
@ -448,9 +451,11 @@ groupSetting.toolbar = (parent) => {
}); });
groupSetting.control.toolbar.collapse = { groupSetting.control.toolbar.collapse = {
label: new Control_label({ text: 'Group Collapse control' }), label: new Control_label({
text: message.get('menuContentGroupToolbarCollapseLabel')
}),
show: new Button({ show: new Button({
text: 'Show all', text: message.get('menuContentGroupToolbarCollapseShow'),
style: ['line'], style: ['line'],
func: () => { func: () => {
@ -467,7 +472,7 @@ groupSetting.toolbar = (parent) => {
} }
}), }),
hide: new Button({ hide: new Button({
text: 'Hide all', text: message.get('menuContentGroupToolbarCollapseHide'),
style: ['line'], style: ['line'],
func: () => { func: () => {
@ -484,14 +489,16 @@ groupSetting.toolbar = (parent) => {
} }
}), }),
helper: new Control_helperText({ helper: new Control_helperText({
text: ['Group toolbar collapse button can also be changed by editing individual Groups.'] text: [message.get('menuContentGroupToolbarCollapseHelperPara1')]
}) })
}; };
groupSetting.control.toolbar.openAll = { groupSetting.control.toolbar.openAll = {
label: new Control_label({ text: 'Group Open all control' }), label: new Control_label({
text: message.get('menuContentGroupToolbarOpenAllLabel')
}),
show: new Button({ show: new Button({
text: 'Show all', text: message.get('menuContentGroupToolbarOpenAllShow'),
style: ['line'], style: ['line'],
func: () => { func: () => {
@ -508,7 +515,7 @@ groupSetting.toolbar = (parent) => {
} }
}), }),
hide: new Button({ hide: new Button({
text: 'Hide all', text: message.get('menuContentGroupToolbarOpenAllHide'),
style: ['line'], style: ['line'],
func: () => { func: () => {
@ -525,7 +532,7 @@ groupSetting.toolbar = (parent) => {
} }
}), }),
helper: new Control_helperText({ helper: new Control_helperText({
text: ['Group toolbar open all button can also be changed by editing individual Groups.'] text: [message.get('menuContentGroupToolbarOpenAllHelperPara1')]
}) })
}; };

View File

@ -1,15 +1,15 @@
import { message } from '../../message';
import { state } from '../../state'; import { state } from '../../state';
import { data } from '../../data'; import { data } from '../../data';
import { header } from '../../header'; import { header } from '../../header';
import { layout } from '../../layout'; import { layout } from '../../layout';
import { searchEnginePreset } from '../../searchEnginePreset'; import { searchEnginePreset } from '../../searchEnginePreset';
import { APP_NAME } from '../../../constant';
import * as form from '../../form'; import * as form from '../../form';
import { Collapse } from '../../collapse'; import { Collapse } from '../../collapse';
import { Edge } from '../../edge'; import { Edge } from '../../edge';
import { Link } from '../../link';
import { Control_helperText } from '../../control/helperText'; import { Control_helperText } from '../../control/helperText';
import { Control_radio } from '../../control/radio'; import { Control_radio } from '../../control/radio';
@ -402,11 +402,11 @@ headerSetting.alignment = (parent) => {
headerSetting.alignment.alignment = new Control_radioGrid({ headerSetting.alignment.alignment = new Control_radioGrid({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'header-item-justify-left', labelText: 'Left', value: 'left', position: 1 }, { id: 'header-item-justify-left', labelText: message.get('menuContentHeaderAlignmentJustifyLeft'), value: 'left', position: 1 },
{ id: 'header-item-justify-center', labelText: 'Center', value: 'center', position: 2 }, { id: 'header-item-justify-center', labelText: message.get('menuContentHeaderAlignmentJustifyCenter'), value: 'center', position: 2 },
{ id: 'header-item-justify-right', labelText: 'Right', value: 'right', position: 3 } { id: 'header-item-justify-right', labelText: message.get('menuContentHeaderAlignmentJustifyRight'), value: 'right', position: 3 }
], ],
label: 'Header item alignment', label: message.get('menuContentHeaderAlignmentJustifyLabel'),
groupName: 'header-item-justify', groupName: 'header-item-justify',
path: 'header.item.justify', path: 'header.item.justify',
gridSize: '3x1', gridSize: '3x1',
@ -418,7 +418,7 @@ headerSetting.alignment = (parent) => {
headerSetting.alignment.alignmentHelper = new Control_helperText({ headerSetting.alignment.alignmentHelper = new Control_helperText({
complexText: true, complexText: true,
text: [`Effects may not be visible if the ${(new Link({ text: 'Search box size', href: '#menu-content-item-search' })).link().outerHTML} size is set to Auto and grows to fill available space.`] text: [message.get('menuContentHeaderAlignmentHelperPara1')]
}); });
parent.appendChild( parent.appendChild(
@ -438,8 +438,8 @@ headerSetting.greeting = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.greeting.show', path: 'header.greeting.show',
id: 'header-greeting-show', id: 'header-greeting-show',
labelText: 'Show Greeting', labelText: message.get('menuContentHeaderGreetingShow'),
action: function () { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
header.item.render(); header.item.render();
@ -459,7 +459,7 @@ headerSetting.greeting = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.greeting.size', path: 'header.greeting.size',
id: 'header-greeting-size', id: 'header-greeting-size',
labelText: 'Size', labelText: message.get('menuContentHeaderGreetingSize'),
value: state.get.current().header.greeting.size, value: state.get.current().header.greeting.size,
defaultValue: state.get.default().header.greeting.size, defaultValue: state.get.default().header.greeting.size,
min: state.get.minMax().header.greeting.size.min, min: state.get.minMax().header.greeting.size.min,
@ -481,9 +481,9 @@ headerSetting.greeting = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.greeting.newLine', path: 'header.greeting.newLine',
id: 'header-greeting-newLine', id: 'header-greeting-newLine',
labelText: 'New line', labelText: message.get('menuContentHeaderGreetingNewLineLabel'),
description: 'Force on to a new line and seperate from other Header items.', description: message.get('menuContentHeaderGreetingNewLineDescription'),
action: function () { action: () => {
applyCSSState('header.greeting.newLine'); applyCSSState('header.greeting.newLine');
data.save(); data.save();
} }
@ -491,13 +491,13 @@ headerSetting.greeting = (parent) => {
headerSetting.control.greeting.type = new Control_radio({ headerSetting.control.greeting.type = new Control_radio({
object: state.get.current(), object: state.get.current(),
label: 'Wording', label: message.get('menuContentHeaderGreetingTypeLabel'),
radioGroup: [ radioGroup: [
{ id: 'header-greeting-type-good', labelText: '"Good morning..."', value: 'good' }, { id: 'header-greeting-type-good', labelText: message.get('menuContentHeaderGreetingTypeGood'), value: 'good' },
{ id: 'header-greeting-type-hello', labelText: '"Hello..."', value: 'hello' }, { id: 'header-greeting-type-hello', labelText: message.get('menuContentHeaderGreetingTypeHello'), value: 'hello' },
{ id: 'header-greeting-type-hi', labelText: '"Hi..."', value: 'hi' }, { id: 'header-greeting-type-hi', labelText: message.get('menuContentHeaderGreetingTypeHi'), value: 'hi' },
{ id: 'header-greeting-type-none', labelText: 'None', description: 'Useful for just displaying your name.', value: 'none' }, { id: 'header-greeting-type-none', labelText: message.get('menuContentHeaderGreetingTypeNoneLabel'), description: message.get('menuContentHeaderGreetingTypeNoneDescription'), value: 'none' },
{ id: 'header-greeting-type-custom', labelText: 'Custom', description: ['Use your own greeting.', 'Defaults to "Good morning..." if left blank.'], value: 'custom' } { id: 'header-greeting-type-custom', labelText: message.get('menuContentHeaderGreetingTypeCustomLabel'), description: [message.get('menuContentHeaderGreetingTypeCustomDescriptionPara1'), message.get('menuContentHeaderGreetingTypeCustomDescriptionPara2')], value: 'custom' }
], ],
groupName: 'header-greeting-type', groupName: 'header-greeting-type',
path: 'header.greeting.type', path: 'header.greeting.type',
@ -516,8 +516,8 @@ headerSetting.greeting = (parent) => {
path: 'header.greeting.custom', path: 'header.greeting.custom',
id: 'header-greeting-custom', id: 'header-greeting-custom',
value: state.get.current().header.greeting.custom, value: state.get.current().header.greeting.custom,
placeholder: 'Howdy', placeholder: message.get('menuContentHeaderGreetingCustomPlaceholder'),
labelText: 'Custom greeting text', labelText: message.get('menuContentHeaderGreetingCustomLabel'),
srOnly: true, srOnly: true,
action: () => { action: () => {
header.element.greeting.update(); header.element.greeting.update();
@ -543,8 +543,8 @@ headerSetting.greeting = (parent) => {
path: 'header.greeting.name', path: 'header.greeting.name',
id: 'header-greeting-name', id: 'header-greeting-name',
value: state.get.current().header.greeting.name, value: state.get.current().header.greeting.name,
placeholder: 'Nickname, alias or superhero name', placeholder: message.get('menuContentHeaderGreetingNamePlaceholder'),
labelText: 'Name', labelText: message.get('menuContentHeaderGreetingNameLabel'),
action: () => { action: () => {
header.element.greeting.update(); header.element.greeting.update();
data.save(); data.save();
@ -603,7 +603,7 @@ headerSetting.transitional = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.transitional.show', path: 'header.transitional.show',
id: 'header-transitional-show', id: 'header-transitional-show',
labelText: 'Show Transitional words', labelText: message.get('menuContentHeaderTransitionalShowLabel'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -621,14 +621,30 @@ headerSetting.transitional = (parent) => {
}); });
headerSetting.control.transitional.showHelper = new Control_helperText({ headerSetting.control.transitional.showHelper = new Control_helperText({
text: ['Only available when Date or Time is shown.'] text: [message.get('menuContentHeaderTransitionalShowHelperPara1')]
});
headerSetting.control.transitional.type = new Control_radio({
object: state.get.current(),
label: message.get('menuContentHeaderTransitionalTypeLabel'),
radioGroup: [
{ id: 'header-transitional-type-time-and-date', labelText: message.get('menuContentHeaderTransitionalTypeTimeAndDate'), value: 'time-and-date' },
{ id: 'header-transitional-type-its', labelText: message.get('menuContentHeaderTransitionalTypeIts'), value: 'its' }
],
groupName: 'header-transitional-type',
path: 'header.transitional.type',
action: () => {
header.element.transitional.update();
headerSetting.disable();
data.save();
}
}); });
headerSetting.control.transitional.size = new Control_sliderSlim({ headerSetting.control.transitional.size = new Control_sliderSlim({
object: state.get.current(), object: state.get.current(),
path: 'header.transitional.size', path: 'header.transitional.size',
id: 'header-transitional-size', id: 'header-transitional-size',
labelText: 'Size', labelText: message.get('menuContentHeaderTransitionalSize'),
value: state.get.current().header.transitional.size, value: state.get.current().header.transitional.size,
defaultValue: state.get.default().header.transitional.size, defaultValue: state.get.default().header.transitional.size,
min: state.get.minMax().header.transitional.size.min, min: state.get.minMax().header.transitional.size.min,
@ -650,26 +666,10 @@ headerSetting.transitional = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.transitional.newLine', path: 'header.transitional.newLine',
id: 'header-transitional-newLine', id: 'header-transitional-newLine',
labelText: 'New line', labelText: message.get('menuContentHeaderTransitionalNewLineLabel'),
description: 'Force on to a new line and seperate from other Header items.', description: message.get('menuContentHeaderTransitionalNewLineDescription'),
action: function () {
applyCSSState('header.transitional.newLine');
data.save();
}
});
headerSetting.control.transitional.type = new Control_radio({
object: state.get.current(),
label: 'Wording',
radioGroup: [
{ id: 'header-transitional-type-time-and-date', labelText: '"The time and date is"', value: 'time-and-date' },
{ id: 'header-transitional-type-its', labelText: '"It\'s"', value: 'its' }
],
groupName: 'header-transitional-type',
path: 'header.transitional.type',
action: () => { action: () => {
header.element.transitional.update(); applyCSSState('header.transitional.newLine');
headerSetting.disable();
data.save(); data.save();
} }
}); });
@ -718,7 +718,7 @@ headerSetting.clock = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.clock.hour.show', path: 'header.clock.hour.show',
id: 'header-clock-hour-show', id: 'header-clock-hour-show',
labelText: 'Show hours', labelText: message.get('menuContentHeaderClockHourShow'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -739,8 +739,8 @@ headerSetting.clock = (parent) => {
headerSetting.control.clock.hour.display = new Control_radio({ headerSetting.control.clock.hour.display = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'header-clock-hour-display-number', labelText: 'As number', value: 'number' }, { id: 'header-clock-hour-display-number', labelText: message.get('menuContentHeaderClockHourDisplayNumber'), value: 'number' },
{ id: 'header-clock-hour-display-word', labelText: 'As word', value: 'word' } { id: 'header-clock-hour-display-word', labelText: message.get('menuContentHeaderClockHourDisplayWord'), value: 'word' }
], ],
groupName: 'header-clock-hour-display', groupName: 'header-clock-hour-display',
path: 'header.clock.hour.display', path: 'header.clock.hour.display',
@ -768,7 +768,7 @@ headerSetting.clock = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.clock.minute.show', path: 'header.clock.minute.show',
id: 'header-clock-minute-show', id: 'header-clock-minute-show',
labelText: 'Show minutes', labelText: message.get('menuContentHeaderClockMinuteShow'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -789,8 +789,8 @@ headerSetting.clock = (parent) => {
headerSetting.control.clock.minute.display = new Control_radio({ headerSetting.control.clock.minute.display = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'header-clock-minute-display-number', labelText: 'As number', value: 'number' }, { id: 'header-clock-minute-display-number', labelText: message.get('menuContentHeaderClockMinuteDisplayNumber'), value: 'number' },
{ id: 'header-clock-minute-display-word', labelText: 'As word', value: 'word' } { id: 'header-clock-minute-display-word', labelText: message.get('menuContentHeaderClockMinuteDisplayWord'), value: 'word' }
], ],
groupName: 'header-clock-minute-display', groupName: 'header-clock-minute-display',
path: 'header.clock.minute.display', path: 'header.clock.minute.display',
@ -818,7 +818,7 @@ headerSetting.clock = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.clock.second.show', path: 'header.clock.second.show',
id: 'header-clock-second-show', id: 'header-clock-second-show',
labelText: 'Show seconds', labelText: message.get('menuContentHeaderClockSecondShow'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -839,8 +839,8 @@ headerSetting.clock = (parent) => {
headerSetting.control.clock.second.display = new Control_radio({ headerSetting.control.clock.second.display = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'header-clock-second-display-number', labelText: 'As number', value: 'number' }, { id: 'header-clock-second-display-number', labelText: message.get('menuContentHeaderClockSecondDisplayNumber'), value: 'number' },
{ id: 'header-clock-second-display-word', labelText: 'As word', value: 'word' } { id: 'header-clock-second-display-word', labelText: message.get('menuContentHeaderClockSecondDisplayWord'), value: 'word' }
], ],
groupName: 'header-clock-second-display', groupName: 'header-clock-second-display',
path: 'header.clock.second.display', path: 'header.clock.second.display',
@ -862,13 +862,55 @@ headerSetting.clock = (parent) => {
}] }]
}); });
headerSetting.control.clock.separator = {};
headerSetting.control.clock.separator.show = new Control_checkbox({
object: state.get.current(),
path: 'header.clock.separator.show',
id: 'header-clock-separator-show',
labelText: message.get('menuContentHeaderClockSeparatorShow'),
action: () => {
header.element.clock.update();
headerSetting.control.clock.separator.collapse.update();
headerSetting.disable();
data.save();
}
});
headerSetting.control.clock.separator.text = new Control_textReset({
object: state.get.current(),
path: 'header.clock.separator.text',
id: 'header-clock-separator-text',
value: state.get.current().header.clock.separator.text,
defaultValue: state.get.default().header.clock.separator.text,
placeholder: message.get('menuContentHeaderClockSeparatorPlaceholder'),
labelText: message.get('menuContentHeaderClockSeparatorLabel'),
srOnly: true,
action: () => {
header.element.clock.update();
data.save();
}
});
headerSetting.control.clock.separator.area = node('div', [
headerSetting.control.clock.separator.text.wrap()
]);
headerSetting.control.clock.separator.collapse = new Collapse({
type: 'checkbox',
checkbox: headerSetting.control.clock.separator.show,
target: [{
content: headerSetting.control.clock.separator.area
}]
});
headerSetting.control.clock.hour24 = { headerSetting.control.clock.hour24 = {
show: new Control_checkbox({ show: new Control_checkbox({
object: state.get.current(), object: state.get.current(),
path: 'header.clock.hour24.show', path: 'header.clock.hour24.show',
id: 'header-clock-hour24-show', id: 'header-clock-hour24-show',
labelText: '24 hours', labelText: message.get('menuContentHeaderClockHour24'),
action: function () { action: () => {
header.element.clock.update(); header.element.clock.update();
headerSetting.disable(); headerSetting.disable();
data.save(); data.save();
@ -881,8 +923,8 @@ headerSetting.clock = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.clock.meridiem.show', path: 'header.clock.meridiem.show',
id: 'header-clock-meridiem-show', id: 'header-clock-meridiem-show',
labelText: 'AM / PM', labelText: message.get('menuContentHeaderClockMeridiem'),
action: function () { action: () => {
header.element.clock.update(); header.element.clock.update();
data.save(); data.save();
} }
@ -893,7 +935,7 @@ headerSetting.clock = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.clock.size', path: 'header.clock.size',
id: 'header-clock-size', id: 'header-clock-size',
labelText: 'Size', labelText: message.get('menuContentHeaderClockSize'),
value: state.get.current().header.clock.size, value: state.get.current().header.clock.size,
defaultValue: state.get.default().header.clock.size, defaultValue: state.get.default().header.clock.size,
min: state.get.minMax().header.clock.size.min, min: state.get.minMax().header.clock.size.min,
@ -915,56 +957,14 @@ headerSetting.clock = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.clock.newLine', path: 'header.clock.newLine',
id: 'header-clock-newLine', id: 'header-clock-newLine',
labelText: 'New line', labelText: message.get('menuContentHeaderClockNewLineLabel'),
description: 'Force on to a new line and seperate from other Header items.', description: message.get('menuContentHeaderClockNewLineDescription'),
action: function () { action: () => {
applyCSSState('header.clock.newLine'); applyCSSState('header.clock.newLine');
data.save(); data.save();
} }
}); });
headerSetting.control.clock.separator = {};
headerSetting.control.clock.separator.show = new Control_checkbox({
object: state.get.current(),
path: 'header.clock.separator.show',
id: 'header-clock-separator-show',
labelText: 'Show separator',
action: () => {
header.element.clock.update();
headerSetting.control.clock.separator.collapse.update();
headerSetting.disable();
data.save();
}
});
headerSetting.control.clock.separator.text = new Control_textReset({
object: state.get.current(),
path: 'header.clock.separator.text',
id: 'header-clock-separator-text',
value: state.get.current().header.clock.separator.text,
defaultValue: state.get.default().header.clock.separator.text,
placeholder: ':',
labelText: 'Separator character',
srOnly: true,
action: () => {
header.element.clock.update();
data.save();
}
});
headerSetting.control.clock.separator.area = node('div', [
headerSetting.control.clock.separator.text.wrap()
]);
headerSetting.control.clock.separator.collapse = new Collapse({
type: 'checkbox',
checkbox: headerSetting.control.clock.separator.show,
target: [{
content: headerSetting.control.clock.separator.area
}]
});
headerSetting.control.clock.area = node('div', [ headerSetting.control.clock.area = node('div', [
node('hr'), node('hr'),
headerSetting.control.clock.separator.show.wrap(), headerSetting.control.clock.separator.show.wrap(),
@ -1050,7 +1050,7 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.day.show', path: 'header.date.day.show',
id: 'header-date-day-show', id: 'header-date-day-show',
labelText: 'Show Day', labelText: message.get('menuContentHeaderDateDayShow'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -1071,8 +1071,8 @@ headerSetting.date = (parent) => {
headerSetting.control.date.day.display = new Control_radio({ headerSetting.control.date.day.display = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'header-date-day-display-number', labelText: 'As number', value: 'number' }, { id: 'header-date-day-display-number', labelText: message.get('menuContentHeaderDateDayDisplayNumber'), value: 'number' },
{ id: 'header-date-day-display-word', labelText: 'As word', value: 'word' } { id: 'header-date-day-display-word', labelText: message.get('menuContentHeaderDateDayDisplayWord'), value: 'word' }
], ],
groupName: 'header-date-day-display', groupName: 'header-date-day-display',
path: 'header.date.day.display', path: 'header.date.day.display',
@ -1093,10 +1093,10 @@ headerSetting.date = (parent) => {
headerSetting.control.date.day.weekStart = new Control_radio({ headerSetting.control.date.day.weekStart = new Control_radio({
object: state.get.current(), object: state.get.current(),
label: 'Start of the week', label: message.get('menuContentHeaderDateDayDisplayWeekStartLabel'),
radioGroup: [ radioGroup: [
{ id: 'header-date-day-week-start-monday', labelText: 'Monday', value: 'monday' }, { id: 'header-date-day-week-start-monday', labelText: message.get('menuContentHeaderDateDayDisplayWeekStartMonday'), value: 'monday' },
{ id: 'header-date-day-week-start-sunday', labelText: 'Sunday', value: 'sunday' } { id: 'header-date-day-week-start-sunday', labelText: message.get('menuContentHeaderDateDayDisplayWeekStartSunday'), value: 'sunday' }
], ],
groupName: 'header-date-day-week-start', groupName: 'header-date-day-week-start',
path: 'header.date.day.weekStart', path: 'header.date.day.weekStart',
@ -1116,10 +1116,10 @@ headerSetting.date = (parent) => {
headerSetting.control.date.day.length = new Control_radio({ headerSetting.control.date.day.length = new Control_radio({
object: state.get.current(), object: state.get.current(),
label: 'Word length', label: message.get('menuContentHeaderDateDayDisplayLengthLabel'),
radioGroup: [ radioGroup: [
{ id: 'header-date-day-length-long', labelText: 'Long', value: 'long' }, { id: 'header-date-day-length-long', labelText: message.get('menuContentHeaderDateDayDisplayLengthLong'), value: 'long' },
{ id: 'header-date-day-length-short', labelText: 'Short', value: 'short' } { id: 'header-date-day-length-short', labelText: message.get('menuContentHeaderDateDayDisplayLengthShort'), value: 'short' }
], ],
groupName: 'header-date-day-length', groupName: 'header-date-day-length',
path: 'header.date.day.length', path: 'header.date.day.length',
@ -1158,7 +1158,7 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.date.show', path: 'header.date.date.show',
id: 'header-date-date-show', id: 'header-date-date-show',
labelText: 'Show Date', labelText: message.get('menuContentHeaderDateDateShow'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -1179,8 +1179,8 @@ headerSetting.date = (parent) => {
headerSetting.control.date.date.display = new Control_radio({ headerSetting.control.date.date.display = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'header-date-date-display-number', labelText: 'As number', value: 'number' }, { id: 'header-date-date-display-number', labelText: message.get('menuContentHeaderDateDateDisplayNumber'), value: 'number' },
{ id: 'header-date-date-display-word', labelText: 'As word', value: 'word' } { id: 'header-date-date-display-word', labelText: message.get('menuContentHeaderDateDateDisplayWord'), value: 'word' }
], ],
groupName: 'header-date-date-display', groupName: 'header-date-date-display',
path: 'header.date.date.display', path: 'header.date.date.display',
@ -1202,7 +1202,7 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.date.ordinal', path: 'header.date.date.ordinal',
id: 'header-date-date-ordinal', id: 'header-date-date-ordinal',
labelText: 'Ordinal numbers', labelText: message.get('menuContentHeaderDateDateDisplayOrdinal'),
action: () => { action: () => {
header.element.date.update(); header.element.date.update();
data.save(); data.save();
@ -1228,7 +1228,7 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.month.show', path: 'header.date.month.show',
id: 'header-date-month-show', id: 'header-date-month-show',
labelText: 'Show Month', labelText: message.get('menuContentHeaderDateMonthShow'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -1249,8 +1249,8 @@ headerSetting.date = (parent) => {
headerSetting.control.date.month.display = new Control_radio({ headerSetting.control.date.month.display = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'header-date-month-display-number', labelText: 'As number', value: 'number' }, { id: 'header-date-month-display-number', labelText: message.get('menuContentHeaderDateMonthDisplayNumber'), value: 'number' },
{ id: 'header-date-month-display-word', labelText: 'As word', value: 'word' } { id: 'header-date-month-display-word', labelText: message.get('menuContentHeaderDateMonthDisplayWord'), value: 'word' }
], ],
groupName: 'header-date-month-display', groupName: 'header-date-month-display',
path: 'header.date.month.display', path: 'header.date.month.display',
@ -1271,10 +1271,10 @@ headerSetting.date = (parent) => {
headerSetting.control.date.month.length = new Control_radio({ headerSetting.control.date.month.length = new Control_radio({
object: state.get.current(), object: state.get.current(),
label: 'Word length', label: message.get('menuContentHeaderDateMonthDisplayLengthLabel'),
radioGroup: [ radioGroup: [
{ id: 'header-date-month-length-long', labelText: 'Long', value: 'long' }, { id: 'header-date-month-length-long', labelText: message.get('menuContentHeaderDateMonthDisplayLengthLong'), value: 'long' },
{ id: 'header-date-month-length-short', labelText: 'Short', value: 'short' } { id: 'header-date-month-length-short', labelText: message.get('menuContentHeaderDateMonthDisplayLengthShort'), value: 'short' }
], ],
groupName: 'header-date-month-length', groupName: 'header-date-month-length',
path: 'header.date.month.length', path: 'header.date.month.length',
@ -1296,7 +1296,7 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.month.ordinal', path: 'header.date.month.ordinal',
id: 'header-date-month-ordinal', id: 'header-date-month-ordinal',
labelText: 'Ordinal numbers', labelText: message.get('menuContentHeaderDateMonthDisplayOrdinal'),
action: () => { action: () => {
header.element.date.update(); header.element.date.update();
data.save(); data.save();
@ -1324,7 +1324,7 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.year.show', path: 'header.date.year.show',
id: 'header-date-year-show', id: 'header-date-year-show',
labelText: 'Show Year', labelText: message.get('menuContentHeaderDateYearShow'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -1345,8 +1345,8 @@ headerSetting.date = (parent) => {
headerSetting.control.date.year.display = new Control_radio({ headerSetting.control.date.year.display = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'header-date-year-display-number', labelText: 'As number', value: 'number' }, { id: 'header-date-year-display-number', labelText: message.get('menuContentHeaderDateYearDisplayNumber'), value: 'number' },
{ id: 'header-date-year-display-word', labelText: 'As word', value: 'word' } { id: 'header-date-year-display-word', labelText: message.get('menuContentHeaderDateYearDisplayWord'), value: 'word' }
], ],
groupName: 'header-date-year-display', groupName: 'header-date-year-display',
path: 'header.date.year.display', path: 'header.date.year.display',
@ -1382,7 +1382,7 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.separator.show', path: 'header.date.separator.show',
id: 'header-date-separator-show', id: 'header-date-separator-show',
labelText: 'Show separator', labelText: message.get('menuContentHeaderDateSeparatorShow'),
action: () => { action: () => {
header.element.date.update(); header.element.date.update();
headerSetting.control.date.separator.collapse.update(); headerSetting.control.date.separator.collapse.update();
@ -1402,8 +1402,8 @@ headerSetting.date = (parent) => {
id: 'header-date-separator-text', id: 'header-date-separator-text',
value: state.get.current().header.date.separator.text, value: state.get.current().header.date.separator.text,
defaultValue: state.get.default().header.date.separator.text, defaultValue: state.get.default().header.date.separator.text,
placeholder: ':', placeholder: message.get('menuContentHeaderDateSeparatorPlaceholder'),
labelText: 'Separator character', labelText: message.get('menuContentHeaderDateSeparatorLabel'),
srOnly: true, srOnly: true,
action: () => { action: () => {
header.element.date.update(); header.element.date.update();
@ -1425,10 +1425,10 @@ headerSetting.date = (parent) => {
headerSetting.control.date.format = new Control_radio({ headerSetting.control.date.format = new Control_radio({
object: state.get.current(), object: state.get.current(),
label: 'Format', label: message.get('menuContentHeaderDateFormatLabel'),
radioGroup: [ radioGroup: [
{ id: 'header-date-format-date-month', labelText: 'Date / Month', value: 'date-month' }, { id: 'header-date-format-date-month', labelText: message.get('menuContentHeaderDateFormatDateMonth'), value: 'date-month' },
{ id: 'header-date-format-month-date', labelText: 'Month / Date', value: 'month-date' } { id: 'header-date-format-month-date', labelText: message.get('menuContentHeaderDateFormatMonthDate'), value: 'month-date' }
], ],
groupName: 'header-date-format', groupName: 'header-date-format',
path: 'header.date.format', path: 'header.date.format',
@ -1442,7 +1442,7 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.size', path: 'header.date.size',
id: 'header-date-size', id: 'header-date-size',
labelText: 'Size', labelText: message.get('menuContentHeaderDateSize'),
value: state.get.current().header.date.size, value: state.get.current().header.date.size,
defaultValue: state.get.default().header.date.size, defaultValue: state.get.default().header.date.size,
min: state.get.minMax().header.date.size.min, min: state.get.minMax().header.date.size.min,
@ -1464,9 +1464,9 @@ headerSetting.date = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.date.newLine', path: 'header.date.newLine',
id: 'header-date-newLine', id: 'header-date-newLine',
labelText: 'New line', labelText: message.get('menuContentHeaderDateNewLineLabel'),
description: 'Force on to a new line and seperate from other Header items.', description: message.get('menuContentHeaderDateNewLineDescription'),
action: function () { action: () => {
applyCSSState('header.date.newLine'); applyCSSState('header.date.newLine');
data.save(); data.save();
} }
@ -1532,7 +1532,7 @@ headerSetting.search = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.search.show', path: 'header.search.show',
id: 'header-search-show', id: 'header-search-show',
labelText: 'Show Search', labelText: message.get('menuContentHeaderSearchShow'),
action: () => { action: () => {
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
@ -1549,204 +1549,13 @@ headerSetting.search = (parent) => {
} }
}); });
headerSetting.control.search.size = new Control_sliderSlim({
object: state.get.current(),
path: 'header.search.size',
id: 'header-search-size',
labelText: 'Size',
value: state.get.current().header.search.size,
defaultValue: state.get.default().header.search.size,
min: state.get.minMax().header.search.size.min,
max: state.get.minMax().header.search.size.max,
action: () => {
applyCSSVar('header.search.size');
headerSetting.edge.search.size.track();
data.save();
},
mouseDownAction: () => {
headerSetting.edge.search.size.show();
},
mouseUpAction: () => {
headerSetting.edge.search.size.hide();
}
});
headerSetting.control.search.newTab = new Control_checkbox({
object: state.get.current(),
path: 'header.search.newTab',
id: 'header-search-newTab',
labelText: 'Open Search results in a new tab',
action: function () {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
data.save();
}
});
headerSetting.control.search.newLine = new Control_checkbox({
object: state.get.current(),
path: 'header.search.newLine',
id: 'header-search-newLine',
labelText: 'New line',
description: 'Force on to a new line and seperate from other Header items.',
action: function () {
applyCSSState('header.search.newLine');
data.save();
}
});
const searchEngineList = [];
for (let key in searchEnginePreset) {
searchEngineList.push({ id: `header-search-engine-selected-${key}`, labelText: searchEnginePreset[key].name, value: key });
}
searchEngineList.push({ id: 'header-search-engine-selected-custom', labelText: 'Custom', value: 'custom' });
headerSetting.control.search.engine = {
selected: new Control_radio({
object: state.get.current(),
label: 'Search engine',
radioGroup: searchEngineList,
groupName: 'header-search-engine-selected',
path: 'header.search.engine.selected',
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.disable();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
headerSetting.control.search.engine.custom.collapse.update();
data.save();
}
}),
custom: {
name: new Control_text({
object: state.get.current(),
path: 'header.search.engine.custom.name',
id: 'header-search-engine-custom-name',
value: state.get.current().header.search.engine.custom.name,
placeholder: 'Search engine name',
labelText: 'Name',
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
data.save();
}
}),
url: new Control_text({
object: state.get.current(),
path: 'header.search.engine.custom.url',
id: 'header-search-engine-custom-url',
value: state.get.current().header.search.engine.custom.url,
placeholder: 'HTTPS://',
labelText: 'URL',
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
data.save();
}
}),
urlHelper: new Control_helperText({
text: ['Enter a web address with the search parameters, eg: "https://vimeo.com/search?q="', APP_NAME + ' will add the search term entered into the Search box at the end of the above URL.']
}),
queryName: new Control_text({
object: state.get.current(),
path: 'header.search.engine.custom.queryName',
id: 'header-search-engine-custom-queryName',
value: state.get.current().header.search.engine.custom.queryName,
placeholder: 'q',
labelText: 'Name attribute',
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
data.save();
}
}),
queryNameHelper: new Control_helperText({
text: ['Sets the name attribute on the Search input field.', 'This defines the name passed to the search engine when submitting. If not sure leave blank.']
})
}
};
headerSetting.control.search.engine.custom.area = node('div', [
headerSetting.control.search.engine.custom.name.wrap(),
headerSetting.control.search.engine.custom.url.wrap(),
headerSetting.control.search.engine.custom.urlHelper.wrap(),
headerSetting.control.search.engine.custom.queryName.wrap(),
headerSetting.control.search.engine.custom.queryNameHelper.wrap()
]);
headerSetting.control.search.engine.custom.collapse = new Collapse({
type: 'radio',
radioGroup: headerSetting.control.search.engine.selected,
target: [{
id: headerSetting.control.search.engine.selected.radioSet[headerSetting.control.search.engine.selected.radioSet.length - 1].radio.value,
content: headerSetting.control.search.engine.custom.area
}]
});
headerSetting.control.search.text = {
justify: new Control_radioGrid({
object: state.get.current(),
radioGroup: [
{ id: 'header-search-text-justify-left', labelText: 'Left', value: 'left', position: 1 },
{ id: 'header-search-text-justify-center', labelText: 'Center', value: 'center', position: 2 },
{ id: 'header-search-text-justify-right', labelText: 'Right', value: 'right', position: 3 }
],
label: 'Search text alignment',
groupName: 'header-search-text-justify',
path: 'header.search.text.justify',
gridSize: '3x1',
action: () => {
applyCSSClass('header.search.text.justify');
data.save();
}
})
};
headerSetting.control.search.width = { headerSetting.control.search.width = {
by: new Control_radio({ by: new Control_radio({
object: state.get.current(), object: state.get.current(),
label: 'Search box width', label: message.get('menuContentHeaderSearchWidthLabel'),
radioGroup: [ radioGroup: [
{ id: 'header-search-width-by-auto', labelText: 'Auto width', description: 'Search box will grow to best fit available space.', value: 'auto' }, { id: 'header-search-width-by-auto', labelText: message.get('menuContentHeaderSearchWidthAutoLabel'), description: message.get('menuContentHeaderSearchWidthAutoDescription'), value: 'auto' },
{ id: 'header-search-width-by-custom', labelText: 'Custom width', description: 'Define how wide the Search box should be inside the Header Area.', value: 'custom' } { id: 'header-search-width-by-custom', labelText: message.get('menuContentHeaderSearchWidthCustomLabel'), description: message.get('menuContentHeaderSearchWidthCustomDescription'), value: 'custom' }
], ],
groupName: 'header-search-width-by', groupName: 'header-search-width-by',
path: 'header.search.width.by', path: 'header.search.width.by',
@ -1761,7 +1570,7 @@ headerSetting.search = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'header.search.width.size', path: 'header.search.width.size',
id: 'header-search-size', id: 'header-search-size',
labelText: 'Width', labelText: message.get('menuContentHeaderSearchWidthSize'),
value: state.get.current().header.search.width.size, value: state.get.current().header.search.width.size,
defaultValue: state.get.default().header.search.width.size, defaultValue: state.get.default().header.search.width.size,
min: state.get.minMax().header.search.width.size.min, min: state.get.minMax().header.search.width.size.min,
@ -1793,6 +1602,203 @@ headerSetting.search = (parent) => {
}] }]
}); });
headerSetting.control.search.size = new Control_sliderSlim({
object: state.get.current(),
path: 'header.search.size',
id: 'header-search-size',
labelText: message.get('menuContentHeaderSearchSize'),
value: state.get.current().header.search.size,
defaultValue: state.get.default().header.search.size,
min: state.get.minMax().header.search.size.min,
max: state.get.minMax().header.search.size.max,
action: () => {
applyCSSVar('header.search.size');
headerSetting.edge.search.size.track();
data.save();
},
mouseDownAction: () => {
headerSetting.edge.search.size.show();
},
mouseUpAction: () => {
headerSetting.edge.search.size.hide();
}
});
headerSetting.control.search.newLine = new Control_checkbox({
object: state.get.current(),
path: 'header.search.newLine',
id: 'header-search-newLine',
labelText: message.get('menuContentHeaderSearchNewLineLabel'),
description: message.get('menuContentHeaderSearchNewLineDescription'),
action: () => {
applyCSSState('header.search.newLine');
data.save();
}
});
const searchEngineList = [];
for (let key in searchEnginePreset) {
searchEngineList.push({ id: `header-search-engine-selected-${key}`, labelText: searchEnginePreset[key].name, value: key });
}
searchEngineList.push({ id: 'header-search-engine-selected-custom', labelText: message.get('menuContentHeaderSearchEngineSelectedCustom'), value: 'custom' });
headerSetting.control.search.engine = {
selected: new Control_radio({
object: state.get.current(),
label: message.get('menuContentHeaderSearchEngineSelectedLabel'),
radioGroup: searchEngineList,
groupName: 'header-search-engine-selected',
path: 'header.search.engine.selected',
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.disable();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
headerSetting.control.search.engine.custom.collapse.update();
data.save();
}
}),
custom: {
name: new Control_text({
object: state.get.current(),
path: 'header.search.engine.custom.name',
id: 'header-search-engine-custom-name',
value: state.get.current().header.search.engine.custom.name,
placeholder: message.get('menuContentHeaderSearchEngineCustomNamePlaceholder'),
labelText: message.get('menuContentHeaderSearchEngineCustomNameLabel'),
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
data.save();
}
}),
url: new Control_text({
object: state.get.current(),
path: 'header.search.engine.custom.url',
id: 'header-search-engine-custom-url',
value: state.get.current().header.search.engine.custom.url,
placeholder: message.get('menuContentHeaderSearchEngineCustomUrlPlaceholder'),
labelText: message.get('menuContentHeaderSearchEngineCustomUrlLabel'),
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
data.save();
}
}),
urlHelper: new Control_helperText({
text: [
message.get('menuContentHeaderSearchEngineCustomUrlHelperPara1'),
message.get('menuContentHeaderSearchEngineCustomUrlHelperPara2')
]
}),
queryName: new Control_text({
object: state.get.current(),
path: 'header.search.engine.custom.queryName',
id: 'header-search-engine-custom-queryName',
value: state.get.current().header.search.engine.custom.queryName,
placeholder: message.get('menuContentHeaderSearchEngineCustomQueryNamePlaceholder'),
labelText: message.get('menuContentHeaderSearchEngineCustomQueryNameLabel'),
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
data.save();
}
}),
queryNameHelper: new Control_helperText({
text: [
message.get('menuContentHeaderSearchEngineCustomQueryNameHelperPara1'),
message.get('menuContentHeaderSearchEngineCustomQueryNameHelperPara2')
]
})
}
};
headerSetting.control.search.engine.custom.area = node('div', [
headerSetting.control.search.engine.custom.name.wrap(),
headerSetting.control.search.engine.custom.url.wrap(),
headerSetting.control.search.engine.custom.urlHelper.wrap(),
headerSetting.control.search.engine.custom.queryName.wrap(),
headerSetting.control.search.engine.custom.queryNameHelper.wrap()
]);
headerSetting.control.search.engine.custom.collapse = new Collapse({
type: 'radio',
radioGroup: headerSetting.control.search.engine.selected,
target: [{
id: headerSetting.control.search.engine.selected.radioSet[headerSetting.control.search.engine.selected.radioSet.length - 1].radio.value,
content: headerSetting.control.search.engine.custom.area
}]
});
headerSetting.control.search.text = {
justify: new Control_radioGrid({
object: state.get.current(),
radioGroup: [
{ id: 'header-search-text-justify-left', labelText: message.get('menuContentHeaderSearchEngineTextJustifyLeft'), value: 'left', position: 1 },
{ id: 'header-search-text-justify-center', labelText: message.get('menuContentHeaderSearchEngineTextJustifyCenter'), value: 'center', position: 2 },
{ id: 'header-search-text-justify-right', labelText: message.get('menuContentHeaderSearchEngineTextJustifyRight'), value: 'right', position: 3 }
],
label: message.get('menuContentHeaderSearchEngineTextJustifyLabel'),
groupName: 'header-search-text-justify',
path: 'header.search.text.justify',
gridSize: '3x1',
action: () => {
applyCSSClass('header.search.text.justify');
data.save();
}
})
};
headerSetting.control.search.newTab = new Control_checkbox({
object: state.get.current(),
path: 'header.search.newTab',
id: 'header-search-newTab',
labelText: message.get('menuContentHeaderSearchNewTab'),
action: () => {
header.item.mod.order();
header.item.clear();
header.item.render();
layout.area.assemble();
headerSetting.edge.greeting.size.update.primary(header.element.greeting.greeting());
headerSetting.edge.transitional.size.update.primary(header.element.transitional.transitional());
headerSetting.edge.clock.size.update.primary(header.element.clock.clock());
headerSetting.edge.date.size.update.primary(header.element.date.date());
headerSetting.edge.search.size.update.primary(header.element.search.search());
data.save();
}
});
headerSetting.control.search.area = node('div', [ headerSetting.control.search.area = node('div', [
headerSetting.control.search.width.by.wrap(), headerSetting.control.search.width.by.wrap(),
form.wrap({ form.wrap({

View File

@ -1,21 +1,24 @@
import { message } from '../message';
import { debugSetting } from './debugSetting'; import { debugSetting } from './debugSetting';
import { APP_NAME } from '../../constant';
import { layoutSetting } from './layoutSetting'; import { layoutSetting } from './layoutSetting';
import { groupSetting } from './groupSetting'; import { groupSetting } from './groupSetting';
import { bookmarkSetting } from './bookmarkSetting'; import { bookmarkSetting } from './bookmarkSetting';
import { headerSetting } from './headerSetting'; import { headerSetting } from './headerSetting';
import { toolbarSetting } from './toolbarSetting'; import { toolbarSetting } from './toolbarSetting';
import { themeSetting } from './themeSetting'; import { themeSetting } from './themeSetting';
import { languageSetting } from './languageSetting';
import { dataSetting } from './dataSetting'; import { dataSetting } from './dataSetting';
import { supportSetting } from './supportSetting'; import { supportSetting } from './supportSetting';
import { coffeeSetting } from './coffeeSetting'; import { coffeeSetting } from './coffeeSetting';
import { appSetting } from './appSetting'; import { appSetting } from './appSetting';
import { node } from '../../utility/node'; import { node } from '../../utility/node';
import { uppercaseFirstLetter } from '../../utility/uppercaseFirstLetter';
import './index.css'; import './index.css';
export const MenuContent = function ({ export const MenuContent = function({
activeNavData = {}, activeNavData = {},
container = false container = false
} = {}) { } = {}) {
@ -49,7 +52,9 @@ export const MenuContent = function ({
const menuContentItem = this.element.content(item); const menuContentItem = this.element.content(item);
menuContentItem.appendChild(this.element.header(item)); menuContentItem.appendChild(this.element.header(
message.get(`menuNav${uppercaseFirstLetter(activeNavData.name)}SubNav${uppercaseFirstLetter(item)}`)
));
const formElement = this.element.form({ indent: true }); const formElement = this.element.form({ indent: true });
@ -131,9 +136,19 @@ export const MenuContent = function ({
switch (this.makeId(activeNavData.name)) { switch (this.makeId(activeNavData.name)) {
case 'language':
menuContentItem.appendChild(this.element.header(message.get(`menuNav${uppercaseFirstLetter(activeNavData.name)}Label`)));
formElement = this.element.form({ indent: true });
languageSetting[this.makeId(activeNavData.name)](formElement);
break;
case 'support': case 'support':
menuContentItem.appendChild(this.element.header(activeNavData.name)); menuContentItem.appendChild(this.element.header(message.get(`menuNav${uppercaseFirstLetter(activeNavData.name)}Label`)));
formElement = this.element.form({ indent: true }); formElement = this.element.form({ indent: true });
@ -143,7 +158,7 @@ export const MenuContent = function ({
case 'coffee': case 'coffee':
menuContentItem.appendChild(this.element.header(activeNavData.name)); menuContentItem.appendChild(this.element.header(message.get(`menuNav${uppercaseFirstLetter(activeNavData.name)}Label`)));
formElement = this.element.form({ indent: true }); formElement = this.element.form({ indent: true });
@ -151,7 +166,7 @@ export const MenuContent = function ({
break; break;
case this.makeId(APP_NAME): case 'app':
formElement = this.element.form(); formElement = this.element.form();

View File

@ -0,0 +1,81 @@
import { message } from '../../message';
import { state } from '../../state';
import { data } from '../../data';
import { header } from '../../header';
import { groupAndBookmark } from '../../groupAndBookmark';
import { menu } from '../../menu';
import { toolbar } from '../../toolbar';
import { APP_NAME } from '../../../constant';
import { Alert } from '../../alert';
import { Link } from '../../link';
import { Control_select } from '../../control/select';
import { node } from '../../../utility/node';
const languageSetting = {};
languageSetting.control = {
language: {}
};
languageSetting.language = (parent) => {
const selectedLanguageIndex = () => {
let index = 0;
index = message.language.code().indexOf(state.get.current().language);
return index;
};
languageSetting.control.language.selected = new Control_select({
path: 'language.selected',
id: 'language-selected',
labelText: message.get('menuContentLanguageSelect'),
srOnly: true,
option: message.language.list(),
selected: selectedLanguageIndex(),
action: () => {
state.get.current().language = message.language.code()[languageSetting.control.language.selected.selected()];
data.save();
toolbar.bar.render();
header.item.clear();
header.item.render();
groupAndBookmark.render();
menu.close();
menu.open();
}
});
languageSetting.control.link = new Link({
text: message.get('menuContentLanguageAlertLink'),
href: `https://github.com/zombieFox/${APP_NAME}`,
openNew: true
});
languageSetting.control.alert = new Alert({
iconName: 'globe',
children: [
node(`p:${message.get('menuContentLanguageAlertPara')}`),
node('p', languageSetting.control.link.link())
]
});
parent.appendChild(
node('div', [
languageSetting.control.language.selected.wrap(),
languageSetting.control.alert.wrap()
])
);
};
export { languageSetting };

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import { state } from '../../state'; import { state } from '../../state';
import { data } from '../../data'; import { data } from '../../data';
import { header } from '../../header'; import { header } from '../../header';
@ -8,7 +10,6 @@ import { theme } from '../../theme';
import * as form from '../../form'; import * as form from '../../form';
import { Edge } from '../../edge'; import { Edge } from '../../edge';
import { Link } from '../../link';
import { Control_helperText } from '../../control/helperText'; import { Control_helperText } from '../../control/helperText';
import { Control_radio } from '../../control/radio'; import { Control_radio } from '../../control/radio';
@ -109,7 +110,7 @@ layoutSetting.scaling = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'layout.size', path: 'layout.size',
id: 'layout-size', id: 'layout-size',
labelText: 'Global size', labelText: message.get('menuContentLayoutScalingSize'),
value: state.get.current().layout.size, value: state.get.current().layout.size,
defaultValue: state.get.default().layout.size, defaultValue: state.get.default().layout.size,
min: state.get.minMax().layout.size.min, min: state.get.minMax().layout.size.min,
@ -147,7 +148,7 @@ layoutSetting.area = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'layout.width', path: 'layout.width',
id: 'layout-width', id: 'layout-width',
labelText: 'Layout area width', labelText: message.get('menuContentLayoutAreaWidth'),
value: state.get.current().layout.width, value: state.get.current().layout.width,
defaultValue: state.get.default().layout.width, defaultValue: state.get.default().layout.width,
min: state.get.minMax().layout.width.min, min: state.get.minMax().layout.width.min,
@ -170,7 +171,7 @@ layoutSetting.area = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'layout.area.header.width', path: 'layout.area.header.width',
id: 'layout-area-header-width', id: 'layout-area-header-width',
labelText: 'Header area width', labelText: message.get('menuContentLayoutAreaHeaderWidth'),
value: state.get.current().layout.area.header.width, value: state.get.current().layout.area.header.width,
defaultValue: state.get.default().layout.area.header.width, defaultValue: state.get.default().layout.area.header.width,
min: state.get.minMax().layout.area.header.width.min, min: state.get.minMax().layout.area.header.width.min,
@ -190,11 +191,11 @@ layoutSetting.area = (parent) => {
justify: new Control_radioGrid({ justify: new Control_radioGrid({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'layout-area-header-justify-left', labelText: 'Left', value: 'left', position: 1 }, { id: 'layout-area-header-justify-left', labelText: message.get('menuContentLayoutAreaHeaderJustifyLeft'), value: 'left', position: 1 },
{ id: 'layout-area-header-justify-center', labelText: 'Center', value: 'center', position: 2 }, { id: 'layout-area-header-justify-center', labelText: message.get('menuContentLayoutAreaHeaderJustifyCenter'), value: 'center', position: 2 },
{ id: 'layout-area-header-justify-right', labelText: 'Right', value: 'right', position: 3 } { id: 'layout-area-header-justify-right', labelText: message.get('menuContentLayoutAreaHeaderJustifyRight'), value: 'right', position: 3 }
], ],
label: 'Header area alignment', label: message.get('menuContentLayoutAreaHeaderJustifyLabel'),
groupName: 'layout-area-header-justify', groupName: 'layout-area-header-justify',
path: 'layout.area.header.justify', path: 'layout.area.header.justify',
gridSize: '3x1', gridSize: '3x1',
@ -204,11 +205,11 @@ layoutSetting.area = (parent) => {
} }
}), }),
justifyHelper1: new Control_helperText({ justifyHelper1: new Control_helperText({
text: ['Effects may not be visible if the Header Area is full width.'] text: [message.get('menuContentLayoutAreaHeaderJustifyHelper1Para1')]
}), }),
justifyHelper2: new Control_helperText({ justifyHelper2: new Control_helperText({
complexText: true, complexText: true,
text: [`Only available when ${(new Link({ text: 'Layout Direction', href: '#menu-content-item-alignment' })).link().outerHTML} is Vertical and Header items are shown.`] text: [message.get('menuContentLayoutAreaHeaderJustifyHelper2Para1')]
}) })
}; };
@ -217,7 +218,7 @@ layoutSetting.area = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'layout.area.bookmark.width', path: 'layout.area.bookmark.width',
id: 'layout-area-bookmark-width', id: 'layout-area-bookmark-width',
labelText: 'Bookmark area width', labelText: message.get('menuContentLayoutAreaBookmarkWidth'),
value: state.get.current().layout.area.bookmark.width, value: state.get.current().layout.area.bookmark.width,
defaultValue: state.get.default().layout.area.bookmark.width, defaultValue: state.get.default().layout.area.bookmark.width,
min: state.get.minMax().layout.area.bookmark.width.min, min: state.get.minMax().layout.area.bookmark.width.min,
@ -237,11 +238,11 @@ layoutSetting.area = (parent) => {
justify: new Control_radioGrid({ justify: new Control_radioGrid({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'layout-area-bookmark-justify-left', labelText: 'Left', value: 'left', position: 1 }, { id: 'layout-area-bookmark-justify-left', labelText: message.get('menuContentLayoutAreaBookmarkJustifyLeft'), value: 'left', position: 1 },
{ id: 'layout-area-bookmark-justify-center', labelText: 'Center', value: 'center', position: 2 }, { id: 'layout-area-bookmark-justify-center', labelText: message.get('menuContentLayoutAreaBookmarkJustifyCenter'), value: 'center', position: 2 },
{ id: 'layout-area-bookmark-justify-right', labelText: 'Right', value: 'right', position: 3 } { id: 'layout-area-bookmark-justify-right', labelText: message.get('menuContentLayoutAreaBookmarkJustifyRight'), value: 'right', position: 3 }
], ],
label: 'Bookmark area alignment', label: message.get('menuContentLayoutAreaBookmarkJustifyLabel'),
groupName: 'layout-area-bookmark-justify', groupName: 'layout-area-bookmark-justify',
path: 'layout.area.bookmark.justify', path: 'layout.area.bookmark.justify',
gridSize: '3x1', gridSize: '3x1',
@ -251,11 +252,11 @@ layoutSetting.area = (parent) => {
} }
}), }),
justifyHelper1: new Control_helperText({ justifyHelper1: new Control_helperText({
text: ['Effects may not be visible if the Bookmark Area is full width.'] text: [message.get('menuContentLayoutAreaBookmarkJustifyHelper1Para1')]
}), }),
justifyHelper2: new Control_helperText({ justifyHelper2: new Control_helperText({
complexText: true, complexText: true,
text: [`Only available when ${(new Link({ text: 'Layout Direction', href: '#menu-content-item-alignment' })).link().outerHTML} is Vertical and Header items are shown.`] text: [message.get('menuContentLayoutAreaBookmarkJustifyHelper2Para1')]
}) })
}; };
@ -293,7 +294,7 @@ layoutSetting.padding = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'layout.padding', path: 'layout.padding',
id: 'layout-padding', id: 'layout-padding',
labelText: 'Space around Header and Bookmark Area', labelText: message.get('menuContentLayoutPadding'),
value: state.get.current().layout.padding, value: state.get.current().layout.padding,
defaultValue: state.get.default().layout.padding, defaultValue: state.get.default().layout.padding,
min: state.get.minMax().layout.padding.min, min: state.get.minMax().layout.padding.min,
@ -327,7 +328,7 @@ layoutSetting.gutter = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'layout.gutter', path: 'layout.gutter',
id: 'layout-gutter', id: 'layout-gutter',
labelText: 'Space between Header and Bookmark items', labelText: message.get('menuContentLayoutGutter'),
value: state.get.current().layout.gutter, value: state.get.current().layout.gutter,
defaultValue: state.get.default().layout.gutter, defaultValue: state.get.default().layout.gutter,
min: state.get.minMax().layout.gutter.min, min: state.get.minMax().layout.gutter.min,
@ -358,17 +359,17 @@ layoutSetting.alignment = (parent) => {
layoutSetting.control.alignment.alignment = new Control_radioGrid({ layoutSetting.control.alignment.alignment = new Control_radioGrid({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'layout-alignment-top-left', labelText: 'Top Left', value: 'top-left', position: 1 }, { id: 'layout-alignment-top-left', labelText: message.get('menuContentLayoutAlignmentTopLeft'), value: 'top-left', position: 1 },
{ id: 'layout-alignment-top-center', labelText: 'Top Center', value: 'top-center', position: 2 }, { id: 'layout-alignment-top-center', labelText: message.get('menuContentLayoutAlignmentTopCenter'), value: 'top-center', position: 2 },
{ id: 'layout-alignment-top-right', labelText: 'Top Right', value: 'top-right', position: 3 }, { id: 'layout-alignment-top-right', labelText: message.get('menuContentLayoutAlignmentTopRight'), value: 'top-right', position: 3 },
{ id: 'layout-alignment-center-left', labelText: 'Center Left', value: 'center-left', position: 4 }, { id: 'layout-alignment-center-left', labelText: message.get('menuContentLayoutAlignmentCenterLeft'), value: 'center-left', position: 4 },
{ id: 'layout-alignment-center-center', labelText: 'Center Center', value: 'center-center', position: 5 }, { id: 'layout-alignment-center-center', labelText: message.get('menuContentLayoutAlignmentCenterCenter'), value: 'center-center', position: 5 },
{ id: 'layout-alignment-center-right', labelText: 'Center Right', value: 'center-right', position: 6 }, { id: 'layout-alignment-center-right', labelText: message.get('menuContentLayoutAlignmentCenterRight'), value: 'center-right', position: 6 },
{ id: 'layout-alignment-bottom-left', labelText: 'Bottom Left', value: 'bottom-left', position: 7 }, { id: 'layout-alignment-bottom-left', labelText: message.get('menuContentLayoutAlignmentBottomLeft'), value: 'bottom-left', position: 7 },
{ id: 'layout-alignment-bottom-center', labelText: 'Bottom Center', value: 'bottom-center', position: 8 }, { id: 'layout-alignment-bottom-center', labelText: message.get('menuContentLayoutAlignmentBottomCenter'), value: 'bottom-center', position: 8 },
{ id: 'layout-alignment-bottom-right', labelText: 'Bottom Right', value: 'bottom-right', position: 9 } { id: 'layout-alignment-bottom-right', labelText: message.get('menuContentLayoutAlignmentBottomRight'), value: 'bottom-right', position: 9 }
], ],
label: 'Area alignment', label: message.get('menuContentLayoutAlignmentLabel'),
groupName: 'layout-alignment', groupName: 'layout-alignment',
path: 'layout.alignment', path: 'layout.alignment',
gridSize: '3x3', gridSize: '3x3',
@ -381,8 +382,8 @@ layoutSetting.alignment = (parent) => {
layoutSetting.control.alignment.direction = new Control_radio({ layoutSetting.control.alignment.direction = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'layout-direction-horizontal', labelText: 'Align horizontal', description: 'Stack the Header and Bookmarks in a row side by side.', value: 'horizontal' }, { id: 'layout-direction-horizontal', labelText: message.get('menuContentLayoutDirectionHorizontalLabel'), description: message.get('menuContentLayoutDirectionHorizontalDescription'), value: 'horizontal' },
{ id: 'layout-direction-vertical', labelText: 'Align vertical', description: 'Stack the Header and Bookmarks in a column one above the other.', value: 'vertical' } { id: 'layout-direction-vertical', labelText: message.get('menuContentLayoutDirectionVerticalLabel'), description: message.get('menuContentLayoutDirectionVerticalDescription'), value: 'vertical' }
], ],
groupName: 'layout-direction', groupName: 'layout-direction',
path: 'layout.direction', path: 'layout.direction',
@ -396,8 +397,8 @@ layoutSetting.alignment = (parent) => {
layoutSetting.control.alignment.order = new Control_radio({ layoutSetting.control.alignment.order = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'layout-order-header-bookmark', labelText: 'Header then Bookmarks', description: 'Order the Header area to appear before the Bookmarks area.', value: 'header-bookmark' }, { id: 'layout-order-header-bookmark', labelText: message.get('menuContentLayoutOrderHeaderBookmarkLabel'), description: message.get('menuContentLayoutOrderHeaderBookmarkDescription'), value: 'header-bookmark' },
{ id: 'layout-order-bookmark-header', labelText: 'Bookmarks then Header', description: 'Order the Bookmarks area to appear before the Header area.', value: 'bookmark-header' } { id: 'layout-order-bookmark-header', labelText: message.get('menuContentLayoutOrderBookmarkHeaderLabel'), description: message.get('menuContentLayoutOrderBookmarkHeaderDescription'), value: 'bookmark-header' }
], ],
groupName: 'layout-order', groupName: 'layout-order',
path: 'layout.order', path: 'layout.order',
@ -428,8 +429,8 @@ layoutSetting.page = (parent) => {
id: 'layout-title', id: 'layout-title',
value: state.get.current().layout.title, value: state.get.current().layout.title,
defaultValue: state.get.default().layout.title, defaultValue: state.get.default().layout.title,
placeholder: 'New Tab', placeholder: message.get('menuContentLayoutPageTitlePlaceholder'),
labelText: 'Title', labelText: message.get('menuContentLayoutPageTitleLabel'),
action: () => { action: () => {
layout.title.render(); layout.title.render();
data.save(); data.save();
@ -442,8 +443,8 @@ layoutSetting.page = (parent) => {
id: 'layout-favicon', id: 'layout-favicon',
value: state.get.current().layout.favicon, value: state.get.current().layout.favicon,
defaultValue: state.get.default().layout.favicon, defaultValue: state.get.default().layout.favicon,
placeholder: 'https://www.example.com/favicon.svg', placeholder: message.get('menuContentLayoutPageFaviconPlaceholder'),
labelText: 'Favicon URL', labelText: message.get('menuContentLayoutPageFaviconLabel'),
action: () => { action: () => {
layout.favicon.render(); layout.favicon.render();
data.save(); data.save();
@ -451,16 +452,16 @@ layoutSetting.page = (parent) => {
}); });
layoutSetting.control.page.faviconHelper = new Control_helperText({ layoutSetting.control.page.faviconHelper = new Control_helperText({
text: ['Not supported by all browsers.'] text: [message.get('menuContentLayoutPageFaviconHelperPara1')]
}); });
layoutSetting.control.page.scrollbar = new Control_radio({ layoutSetting.control.page.scrollbar = new Control_radio({
object: state.get.current(), object: state.get.current(),
label: 'Scrollbar', label: message.get('menuContentLayoutPageScrollbarLabel'),
radioGroup: [ radioGroup: [
{ id: 'layout-scrollbar-auto', labelText: 'Auto', value: 'auto' }, { id: 'layout-scrollbar-auto', labelText: message.get('menuContentLayoutPageScrollbarAuto'), value: 'auto' },
{ id: 'layout-scrollbar-thin', labelText: 'Thin', value: 'thin' }, { id: 'layout-scrollbar-thin', labelText: message.get('menuContentLayoutPageScrollbarThin'), value: 'thin' },
{ id: 'layout-scrollbar-none', labelText: 'Hidden', value: 'none' } { id: 'layout-scrollbar-none', labelText: message.get('menuContentLayoutPageScrollbarNone'), value: 'none' }
], ],
groupName: 'layout-scrollbar', groupName: 'layout-scrollbar',
path: 'layout.scrollbar', path: 'layout.scrollbar',
@ -471,7 +472,7 @@ layoutSetting.page = (parent) => {
}); });
layoutSetting.control.page.scrollbarHelper = new Control_helperText({ layoutSetting.control.page.scrollbarHelper = new Control_helperText({
text: ['Not supported by all browsers.'] text: [message.get('menuContentLayoutPageScrollbarHelperPara1')]
}); });
layoutSetting.control.page.overscroll = { layoutSetting.control.page.overscroll = {
@ -479,7 +480,7 @@ layoutSetting.page = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'layout.overscroll.active', path: 'layout.overscroll.active',
id: 'layout-overscroll-active', id: 'layout-overscroll-active',
labelText: 'Scroll past end', labelText: message.get('menuContentLayoutPageOverscrollActive'),
action: () => { action: () => {
applyCSSState('layout.overscroll.active'); applyCSSState('layout.overscroll.active');
layoutSetting.disable(); layoutSetting.disable();
@ -490,10 +491,10 @@ layoutSetting.page = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'layout.overscroll.unblur', path: 'layout.overscroll.unblur',
id: 'layout-overscroll-unblur-background', id: 'layout-overscroll-unblur-background',
labelText: 'Unblur background image or video', labelText: message.get('menuContentLayoutPageOverscrollUnblurLabel'),
description: [ description: [
'Background image or video will unblur when scrolled to the bottom of the page.', message.get('menuContentLayoutPageOverscrollUnblurDescriptionPara1'),
'Image or video blur can be found under Theme Background.' message.get('menuContentLayoutPageOverscrollUnblurDescriptionPara2')
], ],
action: () => { action: () => {
theme.background.image.render(); theme.background.image.render();

View File

@ -1,28 +1,71 @@
import { message } from '../../message';
import { APP_NAME } from '../../../constant'; import { APP_NAME } from '../../../constant';
import * as form from '../../form'; import * as form from '../../form';
import { Link } from '../../link'; import { Link } from '../../link';
import { node } from '../../../utility/node'; import { node } from '../../../utility/node';
const supportSetting = {}; const supportSetting = {};
supportSetting.link = { supportSetting.supportPage = {
url: 'https://github.com/zombieFox/' + APP_NAME + '/wiki/', get: () => {
page: {
applyToAll: 'Applying-bookmark-settings-to-all', const supportLink = {};
browser: 'Browser-support',
cookies: 'Cookies-and-cache', supportLink.baseUrl = 'https://github.com/zombieFox/' + APP_NAME + '/wiki/';
data: 'Data-backup-and-restore',
localBackgroundImage: 'Local-background-image', supportLink.page = {
protectedUrl: 'Protected-URLs', applyToAll: {
recovering: 'Recovering-settings-and-bookmarks', label: message.get('menuContentSupportPageApplyToAll'),
resetting: 'Resetting-when-opening-the-browser', url: 'Applying-bookmark-settings-to-all'
privacy: 'Respecting-your-privacy', },
backgroundImageVideo: 'Setting-a-background-video-or-image', browser: {
firefox: 'Setting-' + APP_NAME + '-as-your-Firefox-homepage' label: message.get('menuContentSupportPageBrowser'),
url: 'Browser-support'
},
cookies: {
label: message.get('menuContentSupportPageCookies'),
url: 'Cookies-and-cache'
},
data: {
label: message.get('menuContentSupportPageData'),
url: 'Data-backup-and-restore'
},
localBackgroundImage: {
label: message.get('menuContentSupportPageLocalBackgroundImage'),
url: 'Local-background-image'
},
protectedUrl: {
label: message.get('menuContentSupportPageProtectedUrl'),
url: 'Protected-URLs'
},
recovering: {
label: message.get('menuContentSupportPageRecovering'),
url: 'Recovering-settings-and-bookmarks'
},
resetting: {
label: message.get('menuContentSupportPageResetting'),
url: 'Resetting-when-opening-the-browser'
},
privacy: {
label: message.get('menuContentSupportPagePrivacy'),
url: 'Respecting-your-privacy'
},
backgroundImageVideo: {
label: message.get('menuContentSupportPageBackgroundImageVideo'),
url: 'Setting-a-background-video-or-image'
},
firefox: {
label: message.get('menuContentSupportPageFirefox'),
url: 'Setting-' + APP_NAME + '-as-your-Firefox-homepage'
},
};
return supportLink;
} }
}; };
@ -34,15 +77,17 @@ supportSetting.support = (parent) => {
const list = node('ul|class:list-feature'); const list = node('ul|class:list-feature');
for (var key in supportSetting.link.page) { const supportLink = supportSetting.supportPage.get();
const supportLink = new Link({ for (var key in supportLink.page) {
text: supportSetting.link.page[key].replace(/-/g, ' '),
href: supportSetting.link.url + supportSetting.link.page[key], const linkItem = new Link({
text: supportLink.page[key].label,
href: supportLink.baseUrl + supportLink.page[key].url,
openNew: true openNew: true
}); });
list.appendChild(node('li', [supportLink.link()])); list.appendChild(node('li', [linkItem.link()]));
} }
@ -52,15 +97,33 @@ supportSetting.support = (parent) => {
}; };
const para = node('p'); supportSetting.support.para = node('p');
para.innerHTML = `For more support or feedback, submit an ${(new Link({ text: 'Issue', href: `https://github.com/zombieFox/${APP_NAME}/issues`, openNew: true })).link().outerHTML} or check the ${(new Link({ text: 'Wiki', href: `https://github.com/zombieFox/${APP_NAME}/wiki`, openNew: true })).link().outerHTML}.`; supportSetting.support.para.innerHTML = message.get('menuContentSupportPara');
supportSetting.support.linkIssue = new Link({
text: message.get('menuContentSupportLink1'),
href: `https://github.com/zombieFox/${APP_NAME}/issues`,
openNew: true
});
supportSetting.support.linkWiki = new Link({
text: message.get('menuContentSupportLink2'),
href: `https://github.com/zombieFox/${APP_NAME}/wiki`,
openNew: true
});
parent.appendChild( parent.appendChild(
node('div', [ node('div', [
makeLinks(), makeLinks(),
node('hr'), node('hr'),
para supportSetting.support.para,
form.indent({
children: [
node('p', supportSetting.support.linkIssue.link()),
node('p', supportSetting.support.linkWiki.link())
]
})
]) ])
); );

View File

@ -1,3 +1,5 @@
import { message } from '../../message';
import { state } from '../../state'; import { state } from '../../state';
import { data } from '../../data'; import { data } from '../../data';
import { header } from '../../header'; import { header } from '../../header';
@ -273,7 +275,7 @@ themeSetting.disable = () => {
themeSetting.preset = (parent) => { themeSetting.preset = (parent) => {
themeSetting.control.preset.presetHelper = new Control_helperText({ themeSetting.control.preset.presetHelper = new Control_helperText({
text: ['Applying a Preset will replace the current Colour, Accent, Font, Style, Opacity, Radius, Shadow, Shade and Background.'] text: [message.get('menuContentThemePresetHelperPara1')]
}); });
const preset = () => { const preset = () => {
@ -310,10 +312,10 @@ themeSetting.saved = (parent) => {
themeSetting.control.saved = { themeSetting.control.saved = {
savedElement: node('div|class:theme-custom'), savedElement: node('div|class:theme-custom'),
customHelper: new Control_helperText({ customHelper: new Control_helperText({
text: ['Saving a Theme will record the current Colour, Accent, Font, Style, Opacity, Radius, Shadow, Shade and Background.'] text: [message.get('menuContentThemeSavedHelperPara1')]
}), }),
saveButton: new Button({ saveButton: new Button({
text: 'Save current theme', text: message.get('menuContentThemeSavedSave'),
style: ['line'], style: ['line'],
func: () => { func: () => {
menu.close(); menu.close();
@ -321,7 +323,7 @@ themeSetting.saved = (parent) => {
} }
}), }),
edit: new Button({ edit: new Button({
text: 'Edit saved themes', text: message.get('menuContentThemeSavedEdit'),
iconName: 'edit', iconName: 'edit',
style: ['line'], style: ['line'],
srOnly: true, srOnly: true,
@ -384,9 +386,9 @@ themeSetting.style = (parent) => {
themeSetting.control.style = new Control_radio({ themeSetting.control.style = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'theme-style-dark', labelText: 'Dark mode', description: false, value: 'dark' }, { id: 'theme-style-dark', labelText: message.get('menuContentThemeStyleDarkLabel'), description: false, value: 'dark' },
{ id: 'theme-style-light', labelText: 'Light mode', description: false, value: 'light' }, { id: 'theme-style-light', labelText: message.get('menuContentThemeStyleLightLabel'), description: false, value: 'light' },
{ id: 'theme-style-system', labelText: 'Automatic', description: 'Follow the system Light or Dark mode.', value: 'system' } { id: 'theme-style-system', labelText: message.get('menuContentThemeStyleAutomaticLabel'), description: message.get('menuContentThemeStyleAutomaticDescription'), value: 'system' }
], ],
groupName: 'theme-style', groupName: 'theme-style',
path: 'theme.style', path: 'theme.style',
@ -405,7 +407,7 @@ themeSetting.style = (parent) => {
}; };
themeSetting.colour = (parent) => { themeSetting.color = (parent) => {
const shade = () => { const shade = () => {
@ -444,7 +446,7 @@ themeSetting.colour = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.color.range.primary.h', path: 'theme.color.range.primary.h',
id: 'theme-color-range-primary-h', id: 'theme-color-range-primary-h',
labelText: 'Primary colour', labelText: message.get('menuContentThemeColorRangePrimaryH'),
value: state.get.current().theme.color.range.primary.h, value: state.get.current().theme.color.range.primary.h,
defaultValue: state.get.default().theme.color.range.primary.h, defaultValue: state.get.default().theme.color.range.primary.h,
min: state.get.minMax().theme.color.range.primary.h.min, min: state.get.minMax().theme.color.range.primary.h.min,
@ -459,7 +461,7 @@ themeSetting.colour = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.color.range.primary.s', path: 'theme.color.range.primary.s',
id: 'theme-color-range-primary-s', id: 'theme-color-range-primary-s',
labelText: 'Saturation', labelText: message.get('menuContentThemeColorRangePrimaryS'),
value: state.get.current().theme.color.range.primary.s, value: state.get.current().theme.color.range.primary.s,
defaultValue: state.get.default().theme.color.range.primary.s, defaultValue: state.get.default().theme.color.range.primary.s,
min: state.get.minMax().theme.color.range.primary.s.min, min: state.get.minMax().theme.color.range.primary.s.min,
@ -474,12 +476,12 @@ themeSetting.colour = (parent) => {
}, },
contrast: new Control_sliderDouble({ contrast: new Control_sliderDouble({
object: state.get.current(), object: state.get.current(),
labelText: 'Contrast range', labelText: message.get('menuContentThemeColorContrastLabel'),
style: 'contrast', style: 'contrast',
left: { left: {
path: 'theme.color.contrast.start', path: 'theme.color.contrast.start',
id: 'theme-color-contrast-start', id: 'theme-color-contrast-start',
labelText: 'Contrast start', labelText: message.get('menuContentThemeColorContrastLeft'),
value: state.get.current().theme.color.contrast.start, value: state.get.current().theme.color.contrast.start,
defaultValue: state.get.default().theme.color.contrast.start, defaultValue: state.get.default().theme.color.contrast.start,
min: state.get.minMax().theme.color.contrast.start.min, min: state.get.minMax().theme.color.contrast.start.min,
@ -492,7 +494,7 @@ themeSetting.colour = (parent) => {
right: { right: {
path: 'theme.color.contrast.end', path: 'theme.color.contrast.end',
id: 'theme-color-contrast-end', id: 'theme-color-contrast-end',
labelText: 'Contrast end', labelText: message.get('menuContentThemeColorContrastRight'),
value: state.get.current().theme.color.contrast.end, value: state.get.current().theme.color.contrast.end,
defaultValue: state.get.default().theme.color.contrast.end, defaultValue: state.get.default().theme.color.contrast.end,
min: state.get.minMax().theme.color.contrast.end.min, min: state.get.minMax().theme.color.contrast.end.min,
@ -505,16 +507,16 @@ themeSetting.colour = (parent) => {
}), }),
contrastHelper: new Control_helperText({ contrastHelper: new Control_helperText({
text: [ text: [
'Move the Contrast range controls close together for a muted look.', message.get('menuContentThemeColorContrastHelperPara1'),
'Move the Contrast range controls far apart from each other for a sharp vivid look.' message.get('menuContentThemeColorContrastHelperPara2')
] ]
}), }),
shade: { shade: {
helper: new Control_helperText({ helper: new Control_helperText({
text: [ text: [
'Backgrounds, Bookmarks and Modals use shades from the left.', message.get('menuContentThemeColorShadeHelperPara1'),
'Text and form elements use shades from the right.', message.get('menuContentThemeColorShadeHelperPara2'),
'For a light look switch to the Light Style and then select a Primary colour. And vice versa for a dark look.' message.get('menuContentThemeColorShadeHelperPara3')
] ]
}) })
} }
@ -564,7 +566,7 @@ themeSetting.accent = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.accent', path: 'theme.accent',
id: 'theme-accent', id: 'theme-accent',
labelText: 'Accent colour', labelText: message.get('menuContentThemeAccentColor'),
defaultValue: state.get.default().theme.accent.rgb, defaultValue: state.get.default().theme.accent.rgb,
minMaxObject: state.get.minMax(), minMaxObject: state.get.minMax(),
randomColor: true, randomColor: true,
@ -589,7 +591,7 @@ themeSetting.accent = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.accent.random.active', path: 'theme.accent.random.active',
id: 'theme-accent-random-active', id: 'theme-accent-random-active',
labelText: 'Random Accent colour on load/refresh', labelText: message.get('menuContentThemeAccentRandomActive'),
action: () => { action: () => {
themeSetting.disable(); themeSetting.disable();
themeSetting.control.accent.random.collapse.update(); themeSetting.control.accent.random.collapse.update();
@ -600,11 +602,11 @@ themeSetting.accent = (parent) => {
themeSetting.control.accent.random.style = new Control_radio({ themeSetting.control.accent.random.style = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'theme-accent-random-style-any', labelText: 'Any', value: 'any' }, { id: 'theme-accent-random-style-any', labelText: message.get('menuContentThemeAccentRandomStyleAny'), value: 'any' },
{ id: 'theme-accent-random-style-light', labelText: 'Light', value: 'light' }, { id: 'theme-accent-random-style-light', labelText: message.get('menuContentThemeAccentRandomStyleLight'), value: 'light' },
{ id: 'theme-accent-random-style-dark', labelText: 'Dark', value: 'dark' }, { id: 'theme-accent-random-style-dark', labelText: message.get('menuContentThemeAccentRandomStyleDark'), value: 'dark' },
{ id: 'theme-accent-random-style-pastel', labelText: 'Pastel', value: 'pastel' }, { id: 'theme-accent-random-style-pastel', labelText: message.get('menuContentThemeAccentRandomStylePastel'), value: 'pastel' },
{ id: 'theme-accent-random-style-saturated', labelText: 'Saturated', value: 'saturated' }, { id: 'theme-accent-random-style-saturated', labelText: message.get('menuContentThemeAccentRandomStyleSaturated'), value: 'saturated' },
], ],
groupName: 'theme-accent-random-style', groupName: 'theme-accent-random-style',
path: 'theme.accent.random.style', path: 'theme.accent.random.style',
@ -614,7 +616,7 @@ themeSetting.accent = (parent) => {
}); });
themeSetting.control.accent.randomiseNow = new Button({ themeSetting.control.accent.randomiseNow = new Button({
text: 'Randomise now', text: message.get('menuContentThemeAccentRandomRandomise'),
style: ['line'], style: ['line'],
func: () => { func: () => {
theme.accent.random.render(); theme.accent.random.render();
@ -651,7 +653,7 @@ themeSetting.accent = (parent) => {
themeSetting.control.accent.cycle.alert = new Alert({ themeSetting.control.accent.cycle.alert = new Alert({
iconName: 'info', iconName: 'info',
children: [ children: [
node('p:Take care as a fast changing Accent hue may cause performance issues.|class:small') node(`p:${message.get('menuContentThemeAccentCycleAlert')}|class:small`)
] ]
}); });
@ -659,7 +661,7 @@ themeSetting.accent = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.accent.cycle.active', path: 'theme.accent.cycle.active',
id: 'theme-accent-random-cycle-active', id: 'theme-accent-random-cycle-active',
labelText: 'Auto change Accent hue', labelText: message.get('menuContentThemeAccentCycleActive'),
action: () => { action: () => {
themeSetting.control.accent.cycle.collapse.update(); themeSetting.control.accent.cycle.collapse.update();
theme.accent.cycle.bind(); theme.accent.cycle.bind();
@ -673,7 +675,7 @@ themeSetting.accent = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.accent.cycle.speed', path: 'theme.accent.cycle.speed',
id: 'theme-accent-random-cycle-speed', id: 'theme-accent-random-cycle-speed',
labelText: 'Change delay', labelText: message.get('menuContentThemeAccentCycleSpeed'),
value: state.get.current().theme.accent.cycle.speed, value: state.get.current().theme.accent.cycle.speed,
defaultValue: state.get.default().theme.accent.cycle.speed, defaultValue: state.get.default().theme.accent.cycle.speed,
min: state.get.minMax().theme.accent.cycle.speed.min, min: state.get.minMax().theme.accent.cycle.speed.min,
@ -688,7 +690,7 @@ themeSetting.accent = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.accent.cycle.step', path: 'theme.accent.cycle.step',
id: 'theme-accent-random-cycle-step', id: 'theme-accent-random-cycle-step',
labelText: 'Change steps', labelText: message.get('menuContentThemeAccentCycleStep'),
value: state.get.current().theme.accent.cycle.step, value: state.get.current().theme.accent.cycle.step,
defaultValue: state.get.default().theme.accent.cycle.step, defaultValue: state.get.default().theme.accent.cycle.step,
min: state.get.minMax().theme.accent.cycle.step.min, min: state.get.minMax().theme.accent.cycle.step.min,
@ -700,7 +702,7 @@ themeSetting.accent = (parent) => {
}); });
themeSetting.control.accent.cycle.stepHelper = new Control_helperText({ themeSetting.control.accent.cycle.stepHelper = new Control_helperText({
text: ['Auto change Accent hue will not work when the Accent colour is a grey or black.'] text: [message.get('menuContentThemeAccentCycleHelperPara1')]
}); });
themeSetting.control.accent.cycle.area = node('div', [ themeSetting.control.accent.cycle.area = node('div', [
@ -761,8 +763,8 @@ themeSetting.font = (parent) => {
id: 'theme-font-display-name', id: 'theme-font-display-name',
value: state.get.current().theme.font.display.name, value: state.get.current().theme.font.display.name,
defaultValue: state.get.default().theme.font.display.name, defaultValue: state.get.default().theme.font.display.name,
placeholder: 'Google font name', placeholder: message.get('menuContentThemeFontDisplayNamePlaceholder'),
labelText: 'Display font', labelText: message.get('menuContentThemeFontDisplayNameLabel'),
action: () => { action: () => {
theme.font.display.delay(); theme.font.display.delay();
data.save(); data.save();
@ -771,16 +773,17 @@ themeSetting.font = (parent) => {
nameHelper: new Control_helperText({ nameHelper: new Control_helperText({
complexText: true, complexText: true,
text: [ text: [
`Use a ${(new Link({ text: 'Google Font', href: 'https://fonts.google.com/', openNew: true })).link().outerHTML} to customise the Clock, Date, Group names and Bookmark Letters.`, message.get('menuContentThemeFontDisplayNameHelperPara1'),
'Add a font name as it appears on Google Fonts, including capital letters and spaces, eg: enter "Fredoka One" or "Kanit"', (new Link({ text: message.get('menuContentThemeFontDisplayNameHelperLink'), href: 'https://fonts.google.com/', openNew: true })).link().outerHTML,
'Clear the field to use the default font "Fjalla One".' message.get('menuContentThemeFontDisplayNameHelperPara2'),
message.get('menuContentThemeFontDisplayNameHelperPara3')
] ]
}), }),
weight: new Control_slider({ weight: new Control_slider({
object: state.get.current(), object: state.get.current(),
path: 'theme.font.display.weight', path: 'theme.font.display.weight',
id: 'theme-font-display-weight', id: 'theme-font-display-weight',
labelText: 'Font weight', labelText: message.get('menuContentThemeFontDisplayWeightLabel'),
value: state.get.current().theme.font.display.weight, value: state.get.current().theme.font.display.weight,
defaultValue: state.get.default().theme.font.display.weight, defaultValue: state.get.default().theme.font.display.weight,
step: state.get.step().theme.font.display.weight, step: state.get.step().theme.font.display.weight,
@ -792,7 +795,7 @@ themeSetting.font = (parent) => {
} }
}), }),
weightLight: new Button({ weightLight: new Button({
text: 'Light', text: message.get('menuContentThemeFontDisplayWeightLight'),
style: ['line'], style: ['line'],
func: () => { func: () => {
state.get.current().theme.font.display.weight = fontWeight.light; state.get.current().theme.font.display.weight = fontWeight.light;
@ -802,7 +805,7 @@ themeSetting.font = (parent) => {
} }
}), }),
weightRegular: new Button({ weightRegular: new Button({
text: 'Regular', text: message.get('menuContentThemeFontDisplayWeightRegular'),
style: ['line'], style: ['line'],
func: () => { func: () => {
state.get.current().theme.font.display.weight = fontWeight.regular; state.get.current().theme.font.display.weight = fontWeight.regular;
@ -812,7 +815,7 @@ themeSetting.font = (parent) => {
} }
}), }),
weightBold: new Button({ weightBold: new Button({
text: 'Bold', text: message.get('menuContentThemeFontDisplayWeightBold'),
style: ['line'], style: ['line'],
func: () => { func: () => {
state.get.current().theme.font.display.weight = fontWeight.bold; state.get.current().theme.font.display.weight = fontWeight.bold;
@ -822,13 +825,13 @@ themeSetting.font = (parent) => {
} }
}), }),
weightHelper: new Control_helperText({ weightHelper: new Control_helperText({
text: ['Not all fonts support all weights. Refer to the Google Font page to see which are available.'] text: [message.get('menuContentThemeFontDisplayWeightHelperPara1')]
}), }),
style: new Control_radio({ style: new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'theme-font-display-style-normal', labelText: 'Normal', value: 'normal' }, { id: 'theme-font-display-style-normal', labelText: message.get('menuContentThemeFontDisplayStyleNormal'), value: 'normal' },
{ id: 'theme-font-display-style-italic', labelText: 'Italic', value: 'italic' } { id: 'theme-font-display-style-italic', labelText: message.get('menuContentThemeFontDisplayStyleItalic'), value: 'italic' }
], ],
groupName: 'theme-font-display-style', groupName: 'theme-font-display-style',
path: 'theme.font.display.style', path: 'theme.font.display.style',
@ -849,8 +852,8 @@ themeSetting.font = (parent) => {
id: 'theme-font-ui-name', id: 'theme-font-ui-name',
value: state.get.current().theme.font.ui.name, value: state.get.current().theme.font.ui.name,
defaultValue: state.get.default().theme.font.ui.name, defaultValue: state.get.default().theme.font.ui.name,
placeholder: 'Google font name', placeholder: message.get('menuContentThemeFontUiNamePlaceholder'),
labelText: 'User interface font', labelText: message.get('menuContentThemeFontUiNameLabel'),
action: () => { action: () => {
theme.font.ui.delay(); theme.font.ui.delay();
data.save(); data.save();
@ -859,16 +862,17 @@ themeSetting.font = (parent) => {
nameHelper: new Control_helperText({ nameHelper: new Control_helperText({
complexText: true, complexText: true,
text: [ text: [
`Use a ${(new Link({ text: 'Google Font', href: 'https://fonts.google.com/', openNew: true })).link().outerHTML} to customise the Bookmark name, URL and form elements.`, message.get('menuContentThemeFontUiNameHelperPara1'),
'Add a font name as it appears on Google Fonts, including capital letters and spaces, eg: enter "Roboto", "Source Sans Pro" or "Noto Sans"', (new Link({ text: message.get('menuContentThemeFontUiNameHelperLink'), href: 'https://fonts.google.com/', openNew: true })).link().outerHTML,
'Clear the field to use the default font "Open Sans".' message.get('menuContentThemeFontUiNameHelperPara2'),
message.get('menuContentThemeFontUiNameHelperPara3')
] ]
}), }),
weight: new Control_slider({ weight: new Control_slider({
object: state.get.current(), object: state.get.current(),
path: 'theme.font.ui.weight', path: 'theme.font.ui.weight',
id: 'theme-font-ui-weight', id: 'theme-font-ui-weight',
labelText: 'Font weight', labelText: message.get('menuContentThemeFontUiWeightLabel'),
value: state.get.current().theme.font.ui.weight, value: state.get.current().theme.font.ui.weight,
defaultValue: state.get.default().theme.font.ui.weight, defaultValue: state.get.default().theme.font.ui.weight,
step: state.get.step().theme.font.ui.weight, step: state.get.step().theme.font.ui.weight,
@ -880,7 +884,7 @@ themeSetting.font = (parent) => {
} }
}), }),
weightLight: new Button({ weightLight: new Button({
text: 'Light', text: message.get('menuContentThemeFontUiWeightLight'),
style: ['line'], style: ['line'],
func: () => { func: () => {
state.get.current().theme.font.ui.weight = fontWeight.light; state.get.current().theme.font.ui.weight = fontWeight.light;
@ -890,7 +894,7 @@ themeSetting.font = (parent) => {
} }
}), }),
weightRegular: new Button({ weightRegular: new Button({
text: 'Regular', text: message.get('menuContentThemeFontUiWeightRegular'),
style: ['line'], style: ['line'],
func: () => { func: () => {
state.get.current().theme.font.ui.weight = fontWeight.regular; state.get.current().theme.font.ui.weight = fontWeight.regular;
@ -900,7 +904,7 @@ themeSetting.font = (parent) => {
} }
}), }),
weightBold: new Button({ weightBold: new Button({
text: 'Bold', text: message.get('menuContentThemeFontUiWeightBold'),
style: ['line'], style: ['line'],
func: () => { func: () => {
state.get.current().theme.font.ui.weight = fontWeight.bold; state.get.current().theme.font.ui.weight = fontWeight.bold;
@ -910,13 +914,13 @@ themeSetting.font = (parent) => {
} }
}), }),
weightHelper: new Control_helperText({ weightHelper: new Control_helperText({
text: ['Not all fonts support all weights. Refer to the Google Font page to see which are available.'] text: [message.get('menuContentThemeFontUiWeightHelperPara1')]
}), }),
style: new Control_radio({ style: new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'theme-font-ui-style-normal', labelText: 'Normal', value: 'normal' }, { id: 'theme-font-ui-style-normal', labelText: message.get('menuContentThemeFontUiStyleNormal'), value: 'normal' },
{ id: 'theme-font-ui-style-italic', labelText: 'Italic', value: 'italic' } { id: 'theme-font-ui-style-italic', labelText: message.get('menuContentThemeFontUiStyleItalic'), value: 'italic' }
], ],
groupName: 'theme-font-ui-style', groupName: 'theme-font-ui-style',
path: 'theme.font.ui.style', path: 'theme.font.ui.style',
@ -992,7 +996,7 @@ themeSetting.radius = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.radius', path: 'theme.radius',
id: 'theme-radius', id: 'theme-radius',
labelText: 'Corners radius', labelText: message.get('menuContentThemeRadius'),
value: state.get.current().theme.radius, value: state.get.current().theme.radius,
defaultValue: state.get.default().theme.radius, defaultValue: state.get.default().theme.radius,
min: state.get.minMax().theme.radius.min, min: state.get.minMax().theme.radius.min,
@ -1017,7 +1021,7 @@ themeSetting.shadow = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.shadow', path: 'theme.shadow',
id: 'theme-shadow', id: 'theme-shadow',
labelText: 'Shadow size', labelText: message.get('menuContentThemeShadow'),
value: state.get.current().theme.shadow, value: state.get.current().theme.shadow,
defaultValue: state.get.default().theme.shadow, defaultValue: state.get.default().theme.shadow,
min: state.get.minMax().theme.shadow.min, min: state.get.minMax().theme.shadow.min,
@ -1043,7 +1047,7 @@ themeSetting.shade = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.shade.opacity', path: 'theme.shade.opacity',
id: 'theme.shade.opacity', id: 'theme.shade.opacity',
labelText: 'Shade opacity', labelText: message.get('menuContentThemeShadeOpacity'),
value: state.get.current().theme.shade.opacity, value: state.get.current().theme.shade.opacity,
defaultValue: state.get.default().theme.shade.opacity, defaultValue: state.get.default().theme.shade.opacity,
min: state.get.minMax().theme.shade.opacity.min, min: state.get.minMax().theme.shade.opacity.min,
@ -1057,7 +1061,7 @@ themeSetting.shade = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.shade.blur', path: 'theme.shade.blur',
id: 'theme.shade.blur', id: 'theme.shade.blur',
labelText: 'Shade blur', labelText: message.get('menuContentThemeShadeBlurLabel'),
value: state.get.current().theme.shade.blur, value: state.get.current().theme.shade.blur,
defaultValue: state.get.default().theme.shade.blur, defaultValue: state.get.default().theme.shade.blur,
min: state.get.minMax().theme.shade.blur.min, min: state.get.minMax().theme.shade.blur.min,
@ -1068,7 +1072,7 @@ themeSetting.shade = (parent) => {
} }
}), }),
blurHelper: new Control_helperText({ blurHelper: new Control_helperText({
text: ['Not supported by all browsers.'] text: [message.get('menuContentThemeShadeBlurHelperPara1')]
}) })
}; };
@ -1088,7 +1092,7 @@ themeSetting.opacity = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.opacity.general', path: 'theme.opacity.general',
id: 'theme-opacity-general', id: 'theme-opacity-general',
labelText: 'All opacity', labelText: message.get('menuContentThemeOpacityGeneralLabel'),
value: state.get.current().theme.opacity.general, value: state.get.current().theme.opacity.general,
defaultValue: state.get.default().theme.opacity.general, defaultValue: state.get.default().theme.opacity.general,
min: state.get.minMax().theme.opacity.general.min, min: state.get.minMax().theme.opacity.general.min,
@ -1133,14 +1137,17 @@ themeSetting.opacity = (parent) => {
}); });
themeSetting.control.opacity.generalHelper = new Control_helperText({ themeSetting.control.opacity.generalHelper = new Control_helperText({
text: ['Change the opacity of Search bar, Bookmarks, Group controls and the Toolbar.', 'Opacity can also be changed when editing individual Bookmarks.'] text: [
message.get('menuContentThemeOpacityGeneralHelperPara1'),
message.get('menuContentThemeOpacityGeneralHelperPara2')
]
}); });
themeSetting.control.opacity.toolbar = new Control_sliderSlim({ themeSetting.control.opacity.toolbar = new Control_sliderSlim({
object: state.get.current(), object: state.get.current(),
path: 'theme.toolbar.opacity', path: 'theme.toolbar.opacity',
id: 'theme-toolbar-opacity', id: 'theme-toolbar-opacity',
labelText: 'Toolbar', labelText: message.get('menuContentThemeOpacityToolbar'),
value: state.get.current().theme.toolbar.opacity, value: state.get.current().theme.toolbar.opacity,
defaultValue: state.get.default().theme.toolbar.opacity, defaultValue: state.get.default().theme.toolbar.opacity,
min: state.get.minMax().theme.toolbar.opacity.min, min: state.get.minMax().theme.toolbar.opacity.min,
@ -1160,7 +1167,7 @@ themeSetting.opacity = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.bookmark.item.opacity', path: 'theme.bookmark.item.opacity',
id: 'theme-bookmark-item-opacity', id: 'theme-bookmark-item-opacity',
labelText: 'Bookmark', labelText: message.get('menuContentThemeOpacityBookmark'),
value: state.get.current().theme.bookmark.item.opacity, value: state.get.current().theme.bookmark.item.opacity,
defaultValue: state.get.default().theme.bookmark.item.opacity, defaultValue: state.get.default().theme.bookmark.item.opacity,
min: state.get.minMax().theme.bookmark.item.opacity.min, min: state.get.minMax().theme.bookmark.item.opacity.min,
@ -1182,7 +1189,7 @@ themeSetting.opacity = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.header.search.opacity', path: 'theme.header.search.opacity',
id: 'theme-header-search-opacity', id: 'theme-header-search-opacity',
labelText: 'Search box', labelText: message.get('menuContentThemeOpacitySearch'),
value: state.get.current().theme.header.search.opacity, value: state.get.current().theme.header.search.opacity,
defaultValue: state.get.default().theme.header.search.opacity, defaultValue: state.get.default().theme.header.search.opacity,
min: state.get.minMax().theme.header.search.opacity.min, min: state.get.minMax().theme.header.search.opacity.min,
@ -1203,7 +1210,7 @@ themeSetting.opacity = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.group.toolbar.opacity', path: 'theme.group.toolbar.opacity',
id: 'theme-group-toolbar-opacity', id: 'theme-group-toolbar-opacity',
labelText: 'Group toolbar', labelText: message.get('menuContentThemeOpacityGroupToolbar'),
value: state.get.current().theme.group.toolbar.opacity, value: state.get.current().theme.group.toolbar.opacity,
defaultValue: state.get.default().theme.group.toolbar.opacity, defaultValue: state.get.default().theme.group.toolbar.opacity,
min: state.get.minMax().theme.group.toolbar.opacity.min, min: state.get.minMax().theme.group.toolbar.opacity.min,
@ -1249,6 +1256,8 @@ themeSetting.opacity = (parent) => {
themeSetting.background = (parent) => { themeSetting.background = (parent) => {
const supportLink = supportSetting.supportPage.get();
const updateVideoPlayState = () => { const updateVideoPlayState = () => {
if (theme.background.element.video) { if (theme.background.element.video) {
@ -1265,12 +1274,12 @@ themeSetting.background = (parent) => {
type: new Control_radio({ type: new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'theme-background-type-theme', labelText: 'Background by Theme', description: 'Use the Background colour defined by the Theme.', value: 'theme' }, { id: 'theme-background-type-theme', labelText: message.get('menuContentThemeBackgroundTypeThemeLabel'), description: message.get('menuContentThemeBackgroundTypeThemeDescription'), value: 'theme' },
{ id: 'theme-background-type-accent', labelText: 'Background by Accent', description: 'Use the Accent colour for the Background.', value: 'accent' }, { id: 'theme-background-type-accent', labelText: message.get('menuContentThemeBackgroundTypeAccentLabel'), description: message.get('menuContentThemeBackgroundTypeAccentDescription'), value: 'accent' },
{ id: 'theme-background-type-color', labelText: 'Custom colour', value: 'color' }, { id: 'theme-background-type-color', labelText: message.get('menuContentThemeBackgroundTypeColor'), value: 'color' },
{ id: 'theme-background-type-gradient', labelText: 'Gradient', value: 'gradient' }, { id: 'theme-background-type-gradient', labelText: message.get('menuContentThemeBackgroundTypeGradient'), value: 'gradient' },
{ id: 'theme-background-type-image', labelText: 'Image', value: 'image' }, { id: 'theme-background-type-image', labelText: message.get('menuContentThemeBackgroundTypeImage'), value: 'image' },
{ id: 'theme-background-type-video', labelText: 'Video', value: 'video' } { id: 'theme-background-type-video', labelText: message.get('menuContentThemeBackgroundTypeVideo'), value: 'video' }
], ],
groupName: 'theme-background-type', groupName: 'theme-background-type',
path: 'theme.background.type', path: 'theme.background.type',
@ -1287,7 +1296,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.color', path: 'theme.background.color',
id: 'theme-background-color', id: 'theme-background-color',
labelText: 'Background colour', labelText: message.get('menuContentThemeBackgroundColor'),
defaultValue: state.get.default().theme.background.color.rgb, defaultValue: state.get.default().theme.background.color.rgb,
minMaxObject: state.get.minMax(), minMaxObject: state.get.minMax(),
randomColor: true, randomColor: true,
@ -1309,7 +1318,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.gradient.angle', path: 'theme.background.gradient.angle',
id: 'theme-background-gradient-angle', id: 'theme-background-gradient-angle',
labelText: 'Background gradient angle', labelText: message.get('menuContentThemeBackgroundGradientAngle'),
value: state.get.current().theme.background.gradient.angle, value: state.get.current().theme.background.gradient.angle,
defaultValue: state.get.default().theme.background.gradient.angle, defaultValue: state.get.default().theme.background.gradient.angle,
min: state.get.minMax().theme.background.gradient.angle.min, min: state.get.minMax().theme.background.gradient.angle.min,
@ -1324,7 +1333,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.gradient.start', path: 'theme.background.gradient.start',
id: 'theme-background-gradient-start', id: 'theme-background-gradient-start',
labelText: 'Background gradient start', labelText: message.get('menuContentThemeBackgroundGradientLeft'),
defaultValue: state.get.default().theme.background.gradient.start.rgb, defaultValue: state.get.default().theme.background.gradient.start.rgb,
minMaxObject: state.get.minMax(), minMaxObject: state.get.minMax(),
randomColor: true, randomColor: true,
@ -1345,7 +1354,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.gradient.end', path: 'theme.background.gradient.end',
id: 'theme-background-gradient-end', id: 'theme-background-gradient-end',
labelText: 'Background gradient end', labelText: message.get('menuContentThemeBackgroundGradientRight'),
defaultValue: state.get.default().theme.background.gradient.end.rgb, defaultValue: state.get.default().theme.background.gradient.end.rgb,
minMaxObject: state.get.minMax(), minMaxObject: state.get.minMax(),
randomColor: true, randomColor: true,
@ -1367,8 +1376,8 @@ themeSetting.background = (parent) => {
alert: new Alert({ alert: new Alert({
iconName: 'info', iconName: 'info',
children: [ children: [
node('p:Local images can no longer be used. Images must be hosted somewhere online.|class:small'), node(`p:${message.get('menuContentThemeBackgroundImageAlertPara1')}|class:small`),
complexNode({ tag: 'p', attr: [{ key: 'class', value: 'small' }], node: [(new Link({ text: 'Why has this changed?', href: supportSetting.link.url + supportSetting.link.page.localBackgroundImage, openNew: true })).link()] }) complexNode({ tag: 'p', attr: [{ key: 'class', value: 'small' }], node: [(new Link({ text: message.get('menuContentThemeBackgroundImageAlertPara2'), href: supportLink.baseUrl + supportLink.page.localBackgroundImage.url, openNew: true })).link()] })
] ]
}), }),
url: new Control_textarea({ url: new Control_textarea({
@ -1376,8 +1385,8 @@ themeSetting.background = (parent) => {
path: 'theme.background.image.url', path: 'theme.background.image.url',
id: 'theme-background-image-url', id: 'theme-background-image-url',
value: state.get.current().theme.background.image.url, value: state.get.current().theme.background.image.url,
placeholder: 'https://www.example.com/image.jpg', placeholder: message.get('menuContentThemeBackgroundImageUrlPlaceholder'),
labelText: 'URL', labelText: message.get('menuContentThemeBackgroundImageUrlLabel'),
action: () => { action: () => {
theme.background.image.render(); theme.background.image.render();
data.save(); data.save();
@ -1385,17 +1394,17 @@ themeSetting.background = (parent) => {
}), }),
urlHelper: new Control_helperText({ urlHelper: new Control_helperText({
text: [ text: [
'Add more than one URL separated by spaces or on new lines for a random background image on load.', message.get('menuContentThemeBackgroundImageUrlHelperPara1'),
'Unsplash can be used for random images, eg:', message.get('menuContentThemeBackgroundImageUrlHelperPara2'),
'https://source.unsplash.com/random/1920x1080/?night,day,sky', message.get('menuContentThemeBackgroundImageUrlHelperPara3'),
'Change parameters after .../random/ for more options. Loading times may vary.' message.get('menuContentThemeBackgroundImageUrlHelperPara4')
] ]
}), }),
blur: new Control_sliderSlim({ blur: new Control_sliderSlim({
object: state.get.current(), object: state.get.current(),
path: 'theme.background.image.blur', path: 'theme.background.image.blur',
id: 'theme-background-image-blur', id: 'theme-background-image-blur',
labelText: 'Blur', labelText: message.get('menuContentThemeBackgroundImageBlur'),
value: state.get.current().theme.background.image.blur, value: state.get.current().theme.background.image.blur,
defaultValue: state.get.default().theme.background.image.blur, defaultValue: state.get.default().theme.background.image.blur,
min: state.get.minMax().theme.background.image.blur.min, min: state.get.minMax().theme.background.image.blur.min,
@ -1409,7 +1418,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.image.grayscale', path: 'theme.background.image.grayscale',
id: 'theme-background-image-grayscale', id: 'theme-background-image-grayscale',
labelText: 'Grayscale', labelText: message.get('menuContentThemeBackgroundImageGrayscale'),
value: state.get.current().theme.background.image.grayscale, value: state.get.current().theme.background.image.grayscale,
defaultValue: state.get.default().theme.background.image.grayscale, defaultValue: state.get.default().theme.background.image.grayscale,
min: state.get.minMax().theme.background.image.grayscale.min, min: state.get.minMax().theme.background.image.grayscale.min,
@ -1423,7 +1432,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.image.scale', path: 'theme.background.image.scale',
id: 'theme-background-image-scale', id: 'theme-background-image-scale',
labelText: 'Scale', labelText: message.get('menuContentThemeBackgroundImageScale'),
value: state.get.current().theme.background.image.scale, value: state.get.current().theme.background.image.scale,
defaultValue: state.get.default().theme.background.image.scale, defaultValue: state.get.default().theme.background.image.scale,
min: state.get.minMax().theme.background.image.scale.min, min: state.get.minMax().theme.background.image.scale.min,
@ -1437,7 +1446,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.image.accent', path: 'theme.background.image.accent',
id: 'theme-background-image-accent', id: 'theme-background-image-accent',
labelText: 'Accent', labelText: message.get('menuContentThemeBackgroundImageAccent'),
value: state.get.current().theme.background.image.accent, value: state.get.current().theme.background.image.accent,
defaultValue: state.get.default().theme.background.image.accent, defaultValue: state.get.default().theme.background.image.accent,
min: state.get.minMax().theme.background.image.accent.min, min: state.get.minMax().theme.background.image.accent.min,
@ -1451,7 +1460,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.image.opacity', path: 'theme.background.image.opacity',
id: 'theme-background-image-opacity', id: 'theme-background-image-opacity',
labelText: 'Opacity', labelText: message.get('menuContentThemeBackgroundImageOpacity'),
value: state.get.current().theme.background.image.opacity, value: state.get.current().theme.background.image.opacity,
defaultValue: state.get.default().theme.background.image.opacity, defaultValue: state.get.default().theme.background.image.opacity,
min: state.get.minMax().theme.background.image.opacity.min, min: state.get.minMax().theme.background.image.opacity.min,
@ -1466,7 +1475,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.image.vignette.opacity', path: 'theme.background.image.vignette.opacity',
id: 'theme-background-image-vignette-opacity', id: 'theme-background-image-vignette-opacity',
labelText: 'Vignette', labelText: message.get('menuContentThemeBackgroundImageVignetteOpacity'),
value: state.get.current().theme.background.image.vignette.opacity, value: state.get.current().theme.background.image.vignette.opacity,
defaultValue: state.get.default().theme.background.image.vignette.opacity, defaultValue: state.get.default().theme.background.image.vignette.opacity,
min: state.get.minMax().theme.background.image.vignette.opacity.min, min: state.get.minMax().theme.background.image.vignette.opacity.min,
@ -1478,11 +1487,11 @@ themeSetting.background = (parent) => {
}), }),
range: new Control_sliderDouble({ range: new Control_sliderDouble({
object: state.get.current(), object: state.get.current(),
labelText: 'Shade start and end', labelText: message.get('menuContentThemeBackgroundImageVignetteRangeLabel'),
left: { left: {
path: 'theme.background.image.vignette.end', path: 'theme.background.image.vignette.end',
id: 'theme-background-image-vignette-end', id: 'theme-background-image-vignette-end',
labelText: 'Shade end', labelText: message.get('menuContentThemeBackgroundImageVignetteRangeLeft'),
value: state.get.current().theme.background.image.vignette.end, value: state.get.current().theme.background.image.vignette.end,
defaultValue: state.get.default().theme.background.image.vignette.end, defaultValue: state.get.default().theme.background.image.vignette.end,
min: state.get.minMax().theme.background.image.vignette.end.min, min: state.get.minMax().theme.background.image.vignette.end.min,
@ -1496,7 +1505,7 @@ themeSetting.background = (parent) => {
right: { right: {
path: 'theme.background.image.vignette.start', path: 'theme.background.image.vignette.start',
id: 'theme-background-image-vignette-start', id: 'theme-background-image-vignette-start',
labelText: 'Shade start', labelText: message.get('menuContentThemeBackgroundImageVignetteRangeRight'),
value: state.get.current().theme.background.image.vignette.start, value: state.get.current().theme.background.image.vignette.start,
defaultValue: state.get.default().theme.background.image.vignette.start, defaultValue: state.get.default().theme.background.image.vignette.start,
min: state.get.minMax().theme.background.image.vignette.start.min, min: state.get.minMax().theme.background.image.vignette.start.min,
@ -1514,8 +1523,8 @@ themeSetting.background = (parent) => {
alert: new Alert({ alert: new Alert({
iconName: 'info', iconName: 'info',
children: [ children: [
node('p:YouTube page URLs <strong>can not</strong> be used.|class:small'), node(`p:${message.get('menuContentThemeBackgroundVideoAlertPara1')}.|class:small`),
complexNode({ tag: 'p', attr: [{ key: 'class', value: 'small' }], node: [(new Link({ text: 'How to link to a video file.', href: supportSetting.link.url + supportSetting.link.page.backgroundImageVideo, openNew: true })).link()] }) complexNode({ tag: 'p', attr: [{ key: 'class', value: 'small' }], node: [(new Link({ text: message.get('menuContentThemeBackgroundVideoAlertPara2'), href: supportLink.baseUrl + supportLink.page.backgroundImageVideo.url, openNew: true })).link()] })
] ]
}), }),
url: new Control_textarea({ url: new Control_textarea({
@ -1523,8 +1532,8 @@ themeSetting.background = (parent) => {
path: 'theme.background.video.url', path: 'theme.background.video.url',
id: 'theme-background-video-url', id: 'theme-background-video-url',
value: state.get.current().theme.background.video.url, value: state.get.current().theme.background.video.url,
placeholder: 'https://www.example.com/video.mp4', placeholder: message.get('menuContentThemeBackgroundVideoUrlPlaceholder'),
labelText: 'URL', labelText: message.get('menuContentThemeBackgroundVideoUrlLabel'),
action: () => { action: () => {
theme.background.video.clear(); theme.background.video.clear();
theme.background.video.render(); theme.background.video.render();
@ -1533,15 +1542,15 @@ themeSetting.background = (parent) => {
}), }),
urlHelper: new Control_helperText({ urlHelper: new Control_helperText({
text: [ text: [
'Background video only supports a direct URL to a video file. Supports MP4 and WebM format.', message.get('menuContentThemeBackgroundVideoUrlHelperPara1'),
'Add more than one URL separated by spaces or on new lines for a random background video on load.' message.get('menuContentThemeBackgroundVideoUrlHelperPara2')
] ]
}), }),
blur: new Control_sliderSlim({ blur: new Control_sliderSlim({
object: state.get.current(), object: state.get.current(),
path: 'theme.background.video.blur', path: 'theme.background.video.blur',
id: 'theme-background-video-blur', id: 'theme-background-video-blur',
labelText: 'Blur', labelText: message.get('menuContentThemeBackgroundVideoBlur'),
value: state.get.current().theme.background.video.blur, value: state.get.current().theme.background.video.blur,
defaultValue: state.get.default().theme.background.video.blur, defaultValue: state.get.default().theme.background.video.blur,
min: state.get.minMax().theme.background.video.blur.min, min: state.get.minMax().theme.background.video.blur.min,
@ -1555,7 +1564,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.video.grayscale', path: 'theme.background.video.grayscale',
id: 'theme-background-video-grayscale', id: 'theme-background-video-grayscale',
labelText: 'Grayscale', labelText: message.get('menuContentThemeBackgroundVideoGrayscale'),
value: state.get.current().theme.background.video.grayscale, value: state.get.current().theme.background.video.grayscale,
defaultValue: state.get.default().theme.background.video.grayscale, defaultValue: state.get.default().theme.background.video.grayscale,
min: state.get.minMax().theme.background.video.grayscale.min, min: state.get.minMax().theme.background.video.grayscale.min,
@ -1569,7 +1578,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.video.scale', path: 'theme.background.video.scale',
id: 'theme-background-video-scale', id: 'theme-background-video-scale',
labelText: 'Scale', labelText: message.get('menuContentThemeBackgroundVideoScale'),
value: state.get.current().theme.background.video.scale, value: state.get.current().theme.background.video.scale,
defaultValue: state.get.default().theme.background.video.scale, defaultValue: state.get.default().theme.background.video.scale,
min: state.get.minMax().theme.background.video.scale.min, min: state.get.minMax().theme.background.video.scale.min,
@ -1583,7 +1592,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.video.accent', path: 'theme.background.video.accent',
id: 'theme-background-video-accent', id: 'theme-background-video-accent',
labelText: 'Accent', labelText: message.get('menuContentThemeBackgroundVideoAccent'),
value: state.get.current().theme.background.video.accent, value: state.get.current().theme.background.video.accent,
defaultValue: state.get.default().theme.background.video.accent, defaultValue: state.get.default().theme.background.video.accent,
min: state.get.minMax().theme.background.video.accent.min, min: state.get.minMax().theme.background.video.accent.min,
@ -1597,7 +1606,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.video.opacity', path: 'theme.background.video.opacity',
id: 'theme-background-video-opacity', id: 'theme-background-video-opacity',
labelText: 'Opacity', labelText: message.get('menuContentThemeBackgroundVideoOpacity'),
value: state.get.current().theme.background.video.opacity, value: state.get.current().theme.background.video.opacity,
defaultValue: state.get.default().theme.background.video.opacity, defaultValue: state.get.default().theme.background.video.opacity,
min: state.get.minMax().theme.background.video.opacity.min, min: state.get.minMax().theme.background.video.opacity.min,
@ -1612,7 +1621,7 @@ themeSetting.background = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.background.video.vignette.opacity', path: 'theme.background.video.vignette.opacity',
id: 'theme-background-video-vignette-opacity', id: 'theme-background-video-vignette-opacity',
labelText: 'Vignette', labelText: message.get('menuContentThemeBackgroundVideoVignetteOpacity'),
value: state.get.current().theme.background.video.vignette.opacity, value: state.get.current().theme.background.video.vignette.opacity,
defaultValue: state.get.default().theme.background.video.vignette.opacity, defaultValue: state.get.default().theme.background.video.vignette.opacity,
min: state.get.minMax().theme.background.video.vignette.opacity.min, min: state.get.minMax().theme.background.video.vignette.opacity.min,
@ -1624,11 +1633,11 @@ themeSetting.background = (parent) => {
}), }),
range: new Control_sliderDouble({ range: new Control_sliderDouble({
object: state.get.current(), object: state.get.current(),
labelText: 'Shade start and end', labelText: message.get('menuContentThemeBackgroundVideoVignetteRangeLabel'),
left: { left: {
path: 'theme.background.video.vignette.end', path: 'theme.background.video.vignette.end',
id: 'theme-background-video-vignette-end', id: 'theme-background-video-vignette-end',
labelText: 'Shade end', labelText: message.get('menuContentThemeBackgroundVideoVignetteRangeLeft'),
value: state.get.current().theme.background.video.vignette.end, value: state.get.current().theme.background.video.vignette.end,
defaultValue: state.get.default().theme.background.video.vignette.end, defaultValue: state.get.default().theme.background.video.vignette.end,
min: state.get.minMax().theme.background.video.vignette.end.min, min: state.get.minMax().theme.background.video.vignette.end.min,
@ -1642,7 +1651,7 @@ themeSetting.background = (parent) => {
right: { right: {
path: 'theme.background.video.vignette.start', path: 'theme.background.video.vignette.start',
id: 'theme-background-video-vignette-start', id: 'theme-background-video-vignette-start',
labelText: 'Shade start', labelText: message.get('menuContentThemeBackgroundVideoVignetteRangeRight'),
value: state.get.current().theme.background.video.vignette.start, value: state.get.current().theme.background.video.vignette.start,
defaultValue: state.get.default().theme.background.video.vignette.start, defaultValue: state.get.default().theme.background.video.vignette.start,
min: state.get.minMax().theme.background.video.vignette.start.min, min: state.get.minMax().theme.background.video.vignette.start.min,
@ -1752,10 +1761,10 @@ themeSetting.layout = (parent) => {
themeSetting.control.layout.color.by = new Control_radio({ themeSetting.control.layout.color.by = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'theme-layout-by-theme', labelText: 'Transparent', description: 'No background colour behind the Layout.', value: 'theme' }, { id: 'theme-layout-by-theme', labelText: message.get('menuContentThemeLayoutColorByTransparentLabel'), description: message.get('menuContentThemeLayoutColorByTransparentDescription'), value: 'theme' },
{ id: 'theme-layout-by-custom', labelText: 'Custom colour', description: 'Use a custom colour behind the Layout.', value: 'custom' } { id: 'theme-layout-by-custom', labelText: message.get('menuContentThemeLayoutColorByCustomLabel'), description: message.get('menuContentThemeLayoutColorByCustomDescription'), value: 'custom' }
], ],
label: 'Layout background colour', label: message.get('menuContentThemeLayoutColorLabel'),
groupName: 'theme-layout-by', groupName: 'theme-layout-by',
path: 'theme.layout.color.by', path: 'theme.layout.color.by',
action: () => { action: () => {
@ -1770,7 +1779,7 @@ themeSetting.layout = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.layout.color', path: 'theme.layout.color',
id: 'theme-layout-color', id: 'theme-layout-color',
labelText: 'Layout background colour', labelText: message.get('menuContentThemeLayoutColorColor'),
defaultValue: state.get.default().theme.layout.color.rgb, defaultValue: state.get.default().theme.layout.color.rgb,
minMaxObject: state.get.minMax(), minMaxObject: state.get.minMax(),
action: () => { action: () => {
@ -1790,7 +1799,7 @@ themeSetting.layout = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.layout.color.opacity', path: 'theme.layout.color.opacity',
id: 'theme-layout-color-opacity', id: 'theme-layout-color-opacity',
labelText: 'Background opacity', labelText: message.get('menuContentThemeLayoutColorOpacity'),
value: state.get.current().theme.layout.color.opacity, value: state.get.current().theme.layout.color.opacity,
defaultValue: state.get.default().theme.layout.color.opacity, defaultValue: state.get.default().theme.layout.color.opacity,
min: state.get.minMax().theme.layout.color.opacity.min, min: state.get.minMax().theme.layout.color.opacity.min,
@ -1807,7 +1816,7 @@ themeSetting.layout = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.layout.color.blur', path: 'theme.layout.color.blur',
id: 'theme.layout-blur', id: 'theme.layout-blur',
labelText: 'Background blur', labelText: message.get('menuContentThemeLayoutColorBlurLabel'),
value: state.get.current().theme.layout.color.blur, value: state.get.current().theme.layout.color.blur,
defaultValue: state.get.default().theme.layout.color.blur, defaultValue: state.get.default().theme.layout.color.blur,
min: state.get.minMax().theme.layout.color.blur.min, min: state.get.minMax().theme.layout.color.blur.min,
@ -1821,7 +1830,7 @@ themeSetting.layout = (parent) => {
}); });
themeSetting.control.layout.color.blurHelper = new Control_helperText({ themeSetting.control.layout.color.blurHelper = new Control_helperText({
text: ['Not supported by all browsers.'] text: [message.get('menuContentThemeLayoutColorBlurHelperPara1')]
}); });
themeSetting.control.layout.color.area = node('div', [ themeSetting.control.layout.color.area = node('div', [
@ -1845,7 +1854,7 @@ themeSetting.layout = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.layout.divider.size', path: 'theme.layout.divider.size',
id: 'theme.layout-divider-size', id: 'theme.layout-divider-size',
labelText: 'Divider between Header and Bookmark area', labelText: message.get('menuContentThemeLayoutDivider'),
value: state.get.current().theme.layout.divider.size, value: state.get.current().theme.layout.divider.size,
defaultValue: state.get.default().theme.layout.divider.size, defaultValue: state.get.default().theme.layout.divider.size,
min: state.get.minMax().theme.layout.divider.size.min, min: state.get.minMax().theme.layout.divider.size.min,
@ -1889,10 +1898,10 @@ themeSetting.header = (parent) => {
themeSetting.control.header.color.by = new Control_radio({ themeSetting.control.header.color.by = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'theme-header-by-theme', labelText: 'Transparent', description: 'No background colour behind the Header area.', value: 'theme' }, { id: 'theme-header-by-theme', labelText: message.get('menuContentThemeHeaderColorByTransparentLabel'), description: message.get('menuContentThemeHeaderColorByTransparentDescription'), value: 'theme' },
{ id: 'theme-header-by-custom', labelText: 'Custom colour', description: 'Use a custom colour behind the Header area.', value: 'custom' } { id: 'theme-header-by-custom', labelText: message.get('menuContentThemeHeaderColorByCustomLabel'), description: message.get('menuContentThemeHeaderColorByCustomDescription'), value: 'custom' }
], ],
label: 'Header background colour', label: message.get('menuContentThemeHeaderColorLabel'),
groupName: 'theme-header-by', groupName: 'theme-header-by',
path: 'theme.header.color.by', path: 'theme.header.color.by',
action: () => { action: () => {
@ -1907,7 +1916,7 @@ themeSetting.header = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.header.color', path: 'theme.header.color',
id: 'theme-header-color', id: 'theme-header-color',
labelText: 'Header area background colour', labelText: message.get('menuContentThemeHeaderColorColor'),
defaultValue: state.get.default().theme.header.color.rgb, defaultValue: state.get.default().theme.header.color.rgb,
minMaxObject: state.get.minMax(), minMaxObject: state.get.minMax(),
action: () => { action: () => {
@ -1927,7 +1936,7 @@ themeSetting.header = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.header.color.opacity', path: 'theme.header.color.opacity',
id: 'theme-header-color-opacity', id: 'theme-header-color-opacity',
labelText: 'Background opacity', labelText: message.get('menuContentThemeHeaderColorOpacity'),
value: state.get.current().theme.header.color.opacity, value: state.get.current().theme.header.color.opacity,
defaultValue: state.get.default().theme.header.color.opacity, defaultValue: state.get.default().theme.header.color.opacity,
min: state.get.minMax().theme.header.color.opacity.min, min: state.get.minMax().theme.header.color.opacity.min,
@ -1978,10 +1987,10 @@ themeSetting.bookmark = (parent) => {
themeSetting.control.bookmark.color.by = new Control_radio({ themeSetting.control.bookmark.color.by = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'theme-bookmark-by-theme', labelText: 'Transparent', description: 'No background colour behind the Bookmark area.', value: 'theme' }, { id: 'theme-bookmark-by-theme', labelText: message.get('menuContentThemeBookmarkColorByTransparentLabel'), description: message.get('menuContentThemeBookmarkColorByTransparentDescription'), value: 'theme' },
{ id: 'theme-bookmark-by-custom', labelText: 'Custom colour', description: 'Use a custom colour behind the Bookmark area.', value: 'custom' } { id: 'theme-bookmark-by-custom', labelText: message.get('menuContentThemeBookmarkColorByCustomLabel'), description: message.get('menuContentThemeBookmarkColorByCustomDescription'), value: 'custom' }
], ],
label: 'Bookmark area background colour', label: message.get('menuContentThemeBookmarkColorLabel'),
groupName: 'theme-bookmark-by', groupName: 'theme-bookmark-by',
path: 'theme.bookmark.color.by', path: 'theme.bookmark.color.by',
action: () => { action: () => {
@ -1996,7 +2005,7 @@ themeSetting.bookmark = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.bookmark.color', path: 'theme.bookmark.color',
id: 'theme-bookmark-color', id: 'theme-bookmark-color',
labelText: 'Header area background colour', labelText: message.get('menuContentThemeBookmarkColorColor'),
defaultValue: state.get.default().theme.bookmark.color.rgb, defaultValue: state.get.default().theme.bookmark.color.rgb,
minMaxObject: state.get.minMax(), minMaxObject: state.get.minMax(),
action: () => { action: () => {
@ -2016,7 +2025,7 @@ themeSetting.bookmark = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.bookmark.color.opacity', path: 'theme.bookmark.color.opacity',
id: 'theme-bookmark-color-opacity', id: 'theme-bookmark-color-opacity',
labelText: 'Background opacity', labelText: message.get('menuContentThemeBookmarkColorOpacity'),
value: state.get.current().theme.bookmark.color.opacity, value: state.get.current().theme.bookmark.color.opacity,
defaultValue: state.get.default().theme.bookmark.color.opacity, defaultValue: state.get.default().theme.bookmark.color.opacity,
min: state.get.minMax().theme.bookmark.color.opacity.min, min: state.get.minMax().theme.bookmark.color.opacity.min,
@ -2049,7 +2058,7 @@ themeSetting.bookmark = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'theme.bookmark.item.border', path: 'theme.bookmark.item.border',
id: 'theme-bookmark-item-border', id: 'theme-bookmark-item-border',
labelText: 'Bookmark border', labelText: message.get('menuContentThemeBookmarkItemBorderLabel'),
value: state.get.current().theme.bookmark.item.border, value: state.get.current().theme.bookmark.item.border,
defaultValue: state.get.default().theme.bookmark.item.border, defaultValue: state.get.default().theme.bookmark.item.border,
min: state.get.minMax().theme.bookmark.item.border.min, min: state.get.minMax().theme.bookmark.item.border.min,
@ -2062,12 +2071,15 @@ themeSetting.bookmark = (parent) => {
}); });
themeSetting.control.bookmark.item.borderHelper = new Control_helperText({ themeSetting.control.bookmark.item.borderHelper = new Control_helperText({
text: ['Bookmark border can also be changed when editing individual Bookmarks.', 'The colour of the Border is defined by the Accent which can also be changed when editing individual Bookmarks.'] text: [
message.get('menuContentThemeBookmarkItemBorderHelperPara1'),
message.get('menuContentThemeBookmarkItemBorderHelperPara2')
]
}); });
themeSetting.control.bookmark.item.rainbow = { themeSetting.control.bookmark.item.rainbow = {
add: new Button({ add: new Button({
text: 'Add unique accent to each Bookmark', text: message.get('menuContentThemeBookmarkItemRainbowAdd'),
style: ['line'], style: ['line'],
func: () => { func: () => {
theme.accent.rainbow.render(); theme.accent.rainbow.render();
@ -2075,7 +2087,7 @@ themeSetting.bookmark = (parent) => {
} }
}), }),
remove: new Button({ remove: new Button({
text: 'Remove all accent overrides', text: message.get('menuContentThemeBookmarkItemRainbowRemove'),
style: ['line'], style: ['line'],
func: () => { func: () => {
theme.accent.rainbow.clear(); theme.accent.rainbow.clear();
@ -2083,7 +2095,7 @@ themeSetting.bookmark = (parent) => {
} }
}), }),
helper: new Control_helperText({ helper: new Control_helperText({
text: ['Bookmark custom Accent can also be changed when editing individual Bookmarks.'] text: [message.get('menuContentThemeBookmarkItemRainbowHelperPara1')]
}) })
}; };

View File

@ -1,10 +1,11 @@
import { message } from '../../message';
import { state } from '../../state'; import { state } from '../../state';
import { data } from '../../data'; import { data } from '../../data';
import { header } from '../../header'; import { header } from '../../header';
import { layout } from '../../layout'; import { layout } from '../../layout';
import { toolbar } from '../../toolbar'; import { toolbar } from '../../toolbar';
import { Edge } from '../../edge'; import { Edge } from '../../edge';
import { Control_helperText } from '../../control/helperText'; import { Control_helperText } from '../../control/helperText';
@ -69,7 +70,7 @@ toolbarSetting.size = (parent) => {
object: state.get.current(), object: state.get.current(),
path: 'toolbar.size', path: 'toolbar.size',
id: 'toolbar-size', id: 'toolbar-size',
labelText: 'Toolbar size', labelText: message.get('menuContentToolbarSize'),
value: state.get.current().toolbar.size, value: state.get.current().toolbar.size,
defaultValue: state.get.default().toolbar.size, defaultValue: state.get.default().toolbar.size,
min: state.get.minMax().toolbar.size.min, min: state.get.minMax().toolbar.size.min,
@ -99,8 +100,8 @@ toolbarSetting.location = (parent) => {
toolbarSetting.control.location.locationElement = new Control_radio({ toolbarSetting.control.location.locationElement = new Control_radio({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'toolbar-location-corner', labelText: 'In a corner', value: 'corner' }, { id: 'toolbar-location-corner', labelText: message.get('menuContentToolbarLocationCorner'), value: 'corner' },
{ id: 'toolbar-location-header', labelText: 'In the Header', value: 'header' } { id: 'toolbar-location-header', labelText: message.get('menuContentToolbarLocationHeader'), value: 'header' }
], ],
groupName: 'toolbar-location', groupName: 'toolbar-location',
path: 'toolbar.location', path: 'toolbar.location',
@ -110,7 +111,6 @@ toolbarSetting.location = (parent) => {
toolbar.current.update.style(); toolbar.current.update.style();
header.item.mod.order(); header.item.mod.order();
header.item.clear(); header.item.clear();
header.item.clear();
header.item.render(); header.item.render();
toolbar.bar.render(); toolbar.bar.render();
layout.area.assemble(); layout.area.assemble();
@ -133,23 +133,23 @@ toolbarSetting.location = (parent) => {
}); });
toolbarSetting.control.location.locationHelper = new Control_helperText({ toolbarSetting.control.location.locationHelper = new Control_helperText({
text: ['Position the Toolbar inside the Header or in a corner of the window.'] text: [message.get('menuContentToolbarLocationHelperPara1')]
}); });
toolbarSetting.control.location.newLine = new Control_checkbox({ toolbarSetting.control.location.newLine = new Control_checkbox({
object: state.get.current(), object: state.get.current(),
path: 'toolbar.newLine', path: 'toolbar.newLine',
id: 'header-newLine', id: 'header-newLine',
labelText: 'New line', labelText: message.get('menuContentToolbarLocationNewLineLabel'),
description: 'Force on to a new line and seperate from other Header items.', description: message.get('menuContentToolbarLocationNewLineDescription'),
action: function () { action: function() {
applyCSSState('toolbar.newLine'); applyCSSState('toolbar.newLine');
data.save(); data.save();
} }
}); });
toolbarSetting.control.location.newLineHelper = new Control_helperText({ toolbarSetting.control.location.newLineHelper = new Control_helperText({
text: ['Only available when the Toolbar is positioned inside the Header.'] text: [message.get('menuContentToolbarLocationNewLineHelperPara1')]
}); });
parent.appendChild( parent.appendChild(
@ -169,12 +169,12 @@ toolbarSetting.position = (parent) => {
toolbarSetting.control.positionElement = new Control_radioGrid({ toolbarSetting.control.positionElement = new Control_radioGrid({
object: state.get.current(), object: state.get.current(),
radioGroup: [ radioGroup: [
{ id: 'toolbar-position-top-left', labelText: 'Top left', value: 'top-left', position: 1 }, { id: 'toolbar-position-top-left', labelText: message.get('menuContentToolbarPositionTopLeft'), value: 'top-left', position: 1 },
{ id: 'toolbar-position-top-right', labelText: 'Top right', value: 'top-right', position: 2 }, { id: 'toolbar-position-top-right', labelText: message.get('menuContentToolbarPositionTopRight'), value: 'top-right', position: 2 },
{ id: 'toolbar-position-bottom-left', labelText: 'Bottom left', value: 'bottom-left', position: 3 }, { id: 'toolbar-position-bottom-left', labelText: message.get('menuContentToolbarPositionBottomLeft'), value: 'bottom-left', position: 3 },
{ id: 'toolbar-position-bottom-right', labelText: 'Bottom right', value: 'bottom-right', position: 4 } { id: 'toolbar-position-bottom-right', labelText: message.get('menuContentToolbarPositionBottomRight'), value: 'bottom-right', position: 4 }
], ],
label: 'Toolbar position', label: message.get('menuContentToolbarPositionLabel'),
groupName: 'toolbar-position', groupName: 'toolbar-position',
path: 'toolbar.position', path: 'toolbar.position',
gridSize: '2x2', gridSize: '2x2',
@ -187,11 +187,11 @@ toolbarSetting.position = (parent) => {
}); });
toolbarSetting.control.positionElementHelper1 = new Control_helperText({ toolbarSetting.control.positionElementHelper1 = new Control_helperText({
text: ['Position the Toolbar in one of the four corners of the window.'] text: [message.get('menuContentToolbarPositionHelper1Para1')]
}); });
toolbarSetting.control.positionElementHelper2 = new Control_helperText({ toolbarSetting.control.positionElementHelper2 = new Control_helperText({
text: ['Only available when the Toolbar is positioned in a corner.'] text: [message.get('menuContentToolbarPositionHelper2Para1')]
}); });
parent.appendChild( parent.appendChild(
@ -210,7 +210,7 @@ toolbarSetting.controls = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'toolbar-accent-show', id: 'toolbar-accent-show',
path: 'toolbar.accent.show', path: 'toolbar.accent.show',
labelText: 'Show Accent control', labelText: message.get('menuContentToolbarControlsAccent'),
action: () => { action: () => {
toolbar.current.update.control(); toolbar.current.update.control();
data.save(); data.save();
@ -221,7 +221,7 @@ toolbarSetting.controls = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'toolbar-add-show', id: 'toolbar-add-show',
path: 'toolbar.add.show', path: 'toolbar.add.show',
labelText: 'Show Add control', labelText: message.get('menuContentToolbarControlsAdd'),
action: () => { action: () => {
toolbar.current.update.control(); toolbar.current.update.control();
data.save(); data.save();
@ -232,7 +232,7 @@ toolbarSetting.controls = (parent) => {
object: state.get.current(), object: state.get.current(),
id: 'toolbar-edit-show', id: 'toolbar-edit-show',
path: 'toolbar.edit.show', path: 'toolbar.edit.show',
labelText: 'Show Edit control', labelText: message.get('menuContentToolbarControlsEdit'),
action: () => { action: () => {
toolbar.current.update.control(); toolbar.current.update.control();
data.save(); data.save();

View File

@ -1,10 +1,13 @@
import { message } from '../message';
import { Button } from '../button'; import { Button } from '../button';
import { node } from '../../utility/node'; import { node } from '../../utility/node';
import { uppercaseFirstLetter } from '../../utility/uppercaseFirstLetter';
import './index.css'; import './index.css';
export const MenuNav = function ({ export const MenuNav = function({
navData = {}, navData = {},
action = false action = false
} = {}) { } = {}) {
@ -116,6 +119,8 @@ export const MenuNav = function ({
navData.forEach((item) => { navData.forEach((item) => {
const navTop = item.name;
const navItem = { const navItem = {
topLevel: false, topLevel: false,
subLevel: false, subLevel: false,
@ -123,7 +128,7 @@ export const MenuNav = function ({
}; };
const navButton = new Button({ const navButton = new Button({
text: item.name, text: message.get(`menuNav${uppercaseFirstLetter(navTop)}Label`),
style: ['link'], style: ['link'],
block: true, block: true,
classList: ['menu-nav-tab'], classList: ['menu-nav-tab'],
@ -148,7 +153,7 @@ export const MenuNav = function ({
item.sub.forEach((item) => { item.sub.forEach((item) => {
const subLevelLink = node('a:' + item + '|href:#menu-content-item-' + this.makeId(item) + ',class:menu-nav-sub button button-link button-small,tabindex:1'); const subLevelLink = node('a:' + message.get(`menuNav${uppercaseFirstLetter(navTop)}SubNav${uppercaseFirstLetter(item)}`) + '|href:#menu-content-item-' + this.makeId(item) + ',class:menu-nav-sub button button-link button-small,tabindex:1');
subNav.appendChild(subLevelLink); subNav.appendChild(subLevelLink);

View File

@ -0,0 +1,134 @@
import { APP_NAME } from '../../constant';
import { state } from '../state';
import { browserDetect } from '../browserDetect';
import { default as bn } from '../../locale/bn/messages.json';
import { default as de } from '../../locale/de/messages.json';
import { default as en_GB } from '../../locale/en_GB/messages.json';
import { default as en_US } from '../../locale/en_US/messages.json';
import { default as es } from '../../locale/es/messages.json';
import { default as fil } from '../../locale/fil/messages.json';
import { default as fr } from '../../locale/fr/messages.json';
import { default as gu } from '../../locale/gu/messages.json';
import { default as hi } from '../../locale/hi/messages.json';
import { default as id } from '../../locale/id/messages.json';
import { default as it } from '../../locale/it/messages.json';
import { default as ja } from '../../locale/ja/messages.json';
import { default as ms } from '../../locale/ms/messages.json';
import { default as pt } from '../../locale/pt/messages.json';
import { default as ru } from '../../locale/ru/messages.json';
import { default as uk } from '../../locale/uk/messages.json';
import { default as vi } from '../../locale/vi/messages.json';
const message = {};
message.language = {
pack: { bn, de, en_GB, en_US, es, fil, fr, gu, hi, id, it, ja, ms, pt, ru, uk, vi }
};
message.language.list = () => {
return [
{ code: 'system', name: message.get('menuContentLanguageSystem') }, // system
{ name: '', disabled: true },
{ code: 'bn', name: 'বাংলা [bn]' }, // Bengali
{ code: 'de', name: 'Deutsch [de]' }, // German
{ code: 'en_GB', name: 'English [en] (GB)' }, // English GB
{ code: 'en_US', name: 'English [en] (US)' }, // English USA
{ code: 'es', name: 'Español [es]' }, // Spanish
{ code: 'fil', name: 'Filipino [fi]' }, // Filipino
{ code: 'fr', name: 'Français [fr]' }, // French
{ code: 'gu', name: 'ગુજરાતી [gu]' }, // Gujarati
{ code: 'hi', name: 'हिंदी [hi]' }, // Hindi
{ code: 'id', name: 'Indonesia [id]' }, // Indonesian
{ code: 'it', name: 'Italiano [it]' }, // Italian
{ code: 'ja', name: '日本語 [ja]' }, // Japanese
{ code: 'ms', name: 'Melayu [ms]' }, // Malay
{ code: 'pt', name: 'Português [pt]' }, // Portuguese
{ code: 'ru', name: 'Pусский [ru]' }, // Russian
{ code: 'uk', name: 'український [uk]' }, // Ukrainian
{ code: 'vi', name: 'англійська [vi]' } // Vietnamese
];
};
message.language.name = () => message.language.list().map(item => item.name);
message.language.code = () => message.language.list().map(item => item.code);
message.get = (stringId) => {
let string;
switch (state.get.current().language) {
// use system language
case 'system':
if (browserDetect().chrome && typeof chrome != 'undefined') {
// if browser is chrome
if ('i18n' in chrome) {
// if installed as extension
string = chrome.i18n.getMessage(stringId);
} else {
string = message.language.pack.en_GB[stringId].message;
}
} else if (browserDetect().firefox && typeof browser != 'undefined') {
// if browser is firefox
if ('i18n' in browser) {
// if installed as addon
string = browser.i18n.getMessage(stringId);
} else {
string = message.language.pack.en_GB[stringId].message;
}
} else {
string = message.language.pack.en_GB[stringId].message;
}
break;
// use manually selected language
default:
if (stringId in message.language.pack[state.get.current().language]) {
// string found in chosen language
string = message.language.pack[state.get.current().language][stringId].message;
} else {
// or use default language
string = message.language.pack.en_GB[stringId].message;
}
break;
}
if (string.indexOf('{appName}') > -1) {
string = string.replaceAll('{appName}', APP_NAME);
}
return string;
};
export { message };

View File

@ -3,6 +3,7 @@ const state = {};
state.current = {}; state.current = {};
state.default = { state.default = {
language: 'system',
layout: { layout: {
area: { area: {
header: { width: 100, justify: 'center' }, header: { width: 100, justify: 'center' },
@ -269,6 +270,7 @@ state.set = {
restore: { restore: {
setup: (dataToRestore) => { setup: (dataToRestore) => {
state.current.language = dataToRestore.state.language;
state.current.layout = dataToRestore.state.layout; state.current.layout = dataToRestore.state.layout;
state.current.header = dataToRestore.state.header; state.current.header = dataToRestore.state.header;
state.current.bookmark = dataToRestore.state.bookmark; state.current.bookmark = dataToRestore.state.bookmark;

View File

@ -1,4 +1,3 @@
import { acrid } from './acrid'; import { acrid } from './acrid';
import { aerial } from './aerial'; import { aerial } from './aerial';
import { app } from './app'; import { app } from './app';

View File

@ -1,3 +1,5 @@
import { message } from '../message';
import { state } from '../state'; import { state } from '../state';
import { menu } from '../menu'; import { menu } from '../menu';
import { data } from '../data'; import { data } from '../data';
@ -19,7 +21,7 @@ import { applyCSSState } from '../../utility/applyCSSState';
import './index.css'; import './index.css';
export const ToolbarControl = function () { export const ToolbarControl = function() {
this.element = { this.element = {
toolbar: node('div|class:toolbar'), toolbar: node('div|class:toolbar'),
@ -35,7 +37,7 @@ export const ToolbarControl = function () {
path: 'theme.accent', path: 'theme.accent',
id: 'theme-accent-quick', id: 'theme-accent-quick',
type: 'color', type: 'color',
labelText: 'Accent colour', labelText: message.get('toolbarAccent'),
srOnly: true, srOnly: true,
inputButtonStyle: ['dot', 'line'], inputButtonStyle: ['dot', 'line'],
inputButtonClassList: ['toolbar-item'], inputButtonClassList: ['toolbar-item'],
@ -53,18 +55,20 @@ export const ToolbarControl = function () {
} }
}), }),
add: new Dropdown({ add: new Dropdown({
text: 'Add', title: message.get('toolbarAddLabel'),
text: message.get('toolbarAddLabel'),
buttonStyle: ['line'], buttonStyle: ['line'],
buttonClassList: ['toolbar-item'], buttonClassList: ['toolbar-item'],
srOnly: true, srOnly: true,
iconName: 'add', iconName: 'add',
menuItem: [ menuItem: [
{ text: 'New Group', iconName: 'addGroup', action: () => { group.add.render(); } }, { text: message.get('toolbarAddGroup'), iconName: 'addGroup', action: () => { group.add.render(); } },
{ text: 'New Bookmark', iconName: 'addBookmark', action: () => { bookmark.add.render(); } } { text: message.get('toolbarAddBookmark'), iconName: 'addBookmark', action: () => { bookmark.add.render(); } }
] ]
}), }),
edit: new Button({ edit: new Button({
text: 'Enter edit bookmark mode', title: message.get('toolbarEdit'),
text: message.get('toolbarEdit'),
srOnly: true, srOnly: true,
iconName: 'edit', iconName: 'edit',
classList: ['toolbar-item'], classList: ['toolbar-item'],
@ -78,7 +82,8 @@ export const ToolbarControl = function () {
} }
}), }),
setting: new Button({ setting: new Button({
text: 'Open settings menu', title: message.get('toolbarSetting'),
text: message.get('toolbarSetting'),
srOnly: true, srOnly: true,
iconName: 'settings', iconName: 'settings',
classList: ['toolbar-item'], classList: ['toolbar-item'],

View File

@ -570,6 +570,7 @@ update.mod['7.0.0'] = function(data) {
delete data.state.dropdown; delete data.state.dropdown;
return data; return data;
}; };
update.mod['7.1.0'] = function(data) { update.mod['7.1.0'] = function(data) {
@ -604,6 +605,7 @@ update.mod['7.1.0'] = function(data) {
}); });
return data; return data;
}; };
update.mod['7.4.0'] = function(data) { update.mod['7.4.0'] = function(data) {
@ -614,6 +616,15 @@ update.mod['7.4.0'] = function(data) {
}; };
return data; return data;
};
update.mod['7.5.0'] = function(data) {
data.state.language = { system: true, selected: 'en_GB' };
return data;
}; };
update.run = (data) => { update.run = (data) => {

View File

@ -1,6 +1,6 @@
export const version = {}; export const version = {};
version.number = '7.4.0'; version.number = '7.5.0';
version.name = 'Delightful Komodo Dragon'; version.name = 'Delightful Komodo Dragon';

View File

@ -1,4 +1,5 @@
import { component } from './component'; import { component } from './component';
import { APP_NAME } from './constant'; import { APP_NAME } from './constant';
console.log(APP_NAME + ' version:', component.version.number, component.version.name); console.log(APP_NAME + ' version:', component.version.number, component.version.name);

2778
src/locale/bn/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/de/messages.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2778
src/locale/es/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/fil/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/fr/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/gu/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/hi/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/id/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/it/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/ja/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/ms/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/pt/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/ru/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/uk/messages.json Normal file

File diff suppressed because it is too large Load Diff

2778
src/locale/vi/messages.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,10 @@
{ {
"name": "nightTab", "name": "__MSG_appName__",
"short_name": "nightTab", "short_name": "__MSG_appShortName__",
"description": "A neutral new tab page accented with a chosen colour. Customise the layout, style, background and bookmarks in nightTab.", "description": "__MSG_appDescription__",
"version": "7.4.0", "version": "7.5.0",
"manifest_version": 2, "manifest_version": 2,
"default_locale": "en_GB",
"chrome_url_overrides": { "chrome_url_overrides": {
"newtab": "index.html" "newtab": "index.html"
}, },

View File

@ -0,0 +1,5 @@
export const uppercaseFirstLetter = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
};

View File

@ -52,6 +52,9 @@ module.exports = {
}, { }, {
from: './src/icon/', from: './src/icon/',
to: './icon/' to: './icon/'
}, {
from: './src/locale',
to: './_locales'
}, { }, {
from: './src/initialBackground.js', from: './src/initialBackground.js',
to: './initialBackground.js' to: './initialBackground.js'

View File

@ -7,7 +7,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin');
const version = require('./src/manifest.json').version; const version = require('./src/manifest.json').version;
const name = require('./src/manifest.json').name; const name = require('./src/locale/en_GB/messages.json').appName.message;
module.exports = merge(common, { module.exports = merge(common, {
mode: 'production', mode: 'production',