Skip to content

Commit 3f22cb0

Browse files
committed
pre-release
1 parent d57f54d commit 3f22cb0

File tree

10 files changed

+192
-69
lines changed

10 files changed

+192
-69
lines changed

pages/index.pug

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
mixin section(id, content_id, active="")
2+
section.mdl-layout__tab-panel(id=id class=active)
3+
.tab-content.mdl-grid(id=content_id)
4+
block
5+
6+
7+
18
doctype html
29
html(lang='en')
310
head
@@ -22,16 +29,12 @@ html(lang='en')
2229

2330
main.mdl-layout__content
2431
#tabs
25-
section#GENERAL.mdl-layout__tab-panel
26-
#file-content.tab-content.mdl-grid
27-
include general_tab
28-
section#STYLE.mdl-layout__tab-panel.is-active
29-
#style-content.tab-content.mdl-grid
30-
include style_tab
31-
section#PREVIEW.mdl-layout__tab-panel
32-
#preview-content.tab-content
33-
section#CODE.mdl-layout__tab-panel
34-
#code-content.tab-content
32+
+section("GENERAL", "file-content")
33+
include general_tab
34+
+section("STYLE", "style-content", "is-active")
35+
include style_tab
36+
+section("PREVIEW", "preview-content")
37+
+section("CODE", "code-content")
3538

3639
#terminal.mdl-shadow--2dp
3740
include terminal

pages/style_tab.pug

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ mixin presets(names)
22
each cls, name in names
33
span.mdl-chip
44
.preset
5-
span.preset-label.mdl-chip__text(class=cls)=name
5+
span.preset-label.mdl-chip__text(id=name class=cls)=name
66
.mdl-layout-spacer
77
button.preset-button.mdl-chip__action(type="button")
8-
i.material-icons cancel
8+
i.material-icons mode_edit
99

1010
mixin checkboxes(...simple)
1111
each check in simple

scripts/cutter.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { DEFAULTS, getPrefix, multiplePrefix, SEPARATOR, VAR_NAMES } from "../core/constants";
1+
import { CLASS_CODES, DEFAULTS, getPrefix, multiplePrefix, SEPARATOR, VAR_NAMES } from "../core/constants";
22
import { areArraysEqual, getSameElements } from "../core/utils";
33
import { find_span_for_place, get_chosen_line_content, terminal } from "./terminal";
4-
import { restorePresets } from "./style_tab";
4+
import { restore_presets } from "./style_tab";
55

66

77

@@ -184,7 +184,7 @@ interface Formatting {
184184
* It applies given style to a node (preset example) or to a range of nodes (styled spans),
185185
* cutting and merging them if necessary.
186186
* @see terminal styled spans
187-
* @see restorePresets preset example
187+
* @see restore_presets preset example
188188
* @param acceptor node or acceptor to apply style to.
189189
* @param format style that will be applied.
190190
*/
@@ -234,8 +234,9 @@ function cut (range: Range, format?: Formatting) {
234234
* @param format style to apply.
235235
*/
236236
function apply_formatting (elem: HTMLElement, format?: Formatting) {
237-
if (format == null) elem.className = "";
238-
else {
237+
if (format == null) elem.className = [...elem.classList].filter((value: string): boolean => {
238+
return !Object.keys(CLASS_CODES).includes(value);
239+
}).join(" "); else {
239240
if (multiplePrefix(format.type)) {
240241
const new_name = format.type + SEPARATOR + format.value;
241242
const same_class = [...elem.classList].find((value: string): boolean => {
@@ -259,7 +260,7 @@ function apply_formatting (elem: HTMLElement, format?: Formatting) {
259260
* @param single - node to identify classes.
260261
* @return list of common classes or null if none.
261262
*/
262-
export function get_common_classes (range?: Range, single?: HTMLDivElement): string[] | null {
263+
export function get_common_classes (range?: Range, single?: HTMLSpanElement): string[] | null {
263264
if (!range == !single) return null;
264265
let base: HTMLElement[];
265266
if (!!single) base = [single];

scripts/main.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import "./imports"
22

33
import { choose_line, getClearText, mode, reflect_nodes, selection_in_place, switch_mode, terminal, TERMINAL_STATE } from "./terminal";
4-
import { reflect_term_changers, reflectVariable, restorePresets } from "./style_tab";
4+
import { reflect_term_changers, reflect_variable, restore_presets } from "./style_tab";
55
import { check } from "./storer";
66

77

@@ -16,7 +16,7 @@ window.onload = () => {
1616
switch_mode(TERMINAL_STATE.STYLE);
1717
choose_line(terminal.firstElementChild as HTMLDivElement);
1818
check();
19-
restorePresets();
19+
restore_presets();
2020
}
2121

2222

@@ -50,15 +50,15 @@ document.ondrop = (event) => {
5050
* @see STYLE STYLE mode
5151
* @see reflect_nodes selecting nodes
5252
* @see reflect_term_changers term changers
53-
* @see reflectVariable reflect variable
53+
* @see reflect_variable reflect variable
5454
*/
5555
document.onselectionchange = () => {
5656
const selection = document.getSelection();
5757
if ((mode != TERMINAL_STATE.STYLE) || !selection_in_place(selection)) return;
5858
const range = selection.getRangeAt(0);
5959
reflect_nodes(range);
6060
reflect_term_changers(range);
61-
reflectVariable(range);
61+
reflect_variable(range);
6262
}
6363

6464

scripts/storer.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
/**
2+
* Flag, symbolizing whether user allowed saving cookies or not. If not set, no cookies will be saved.
3+
*/
14
let allowed = Boolean(get('allowed'));
25

6+
/**
7+
* Function, asking user to allow cookies. It is called once, after window loaded.
8+
*/
39
export function check () {
410
if (!allowed) {
511
alert("For storing user preferences and presets this site uses cookies.");
@@ -8,11 +14,21 @@ export function check () {
814
}
915
}
1016

11-
export function get (key: string): string | boolean | null {
12-
return window.localStorage.getItem(key);
17+
18+
19+
/**
20+
* Function to get parameter from storage.
21+
* @param key string key
22+
*/
23+
export function get (key: string): any | null {
24+
return JSON.parse(window.localStorage.getItem(key));
1325
}
1426

15-
export function set (key: string, value: string | boolean): void {
16-
check();
17-
window.localStorage.setItem(key, String(value));
27+
/**
28+
* Function to set parameter to storage.
29+
* @param key string key.
30+
* @param value any value, will be saved as JSON.
31+
*/
32+
export function set (key: string, value: any): void {
33+
if (allowed) window.localStorage.setItem(key, JSON.stringify(value));
1834
}

scripts/style_tab.ts

Lines changed: 99 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,54 @@ import { get, set } from "./storer";
55

66

77

8+
/**
9+
* Style tab onclick handler. Recognizes 2 types of click:
10+
* 1. Click on 'term changer' or 'preset', applies given style (or styles) connected to currently selected element.
11+
* 2. Click on 'preset button' to alter preset value.
12+
* @see term_changers term changers
13+
* @see focused_preset presets
14+
* @see save_preset preset button
15+
* @param event click event.
16+
*/
817
document.getElementById('style-content').onclick = (event: MouseEvent) => {
918
const target = event.target as HTMLElement;
10-
const selection = window.getSelection();
11-
if (selection.rangeCount == 0) return;
1219

1320
if (target.classList.contains('term-changer') || target.classList.contains('preset-label')) {
14-
const acceptor = focusedPreset ?? get_focus();
21+
const acceptor = focused_preset ?? get_focus();
1522
if (target.classList.contains('term-changer')) apply_style(acceptor, target);
1623
else apply_styles(acceptor, target as HTMLSpanElement);
1724

1825
} else if (target.classList.contains('preset-button')) {
19-
if (!!focusedPreset && (target.id == focusedPreset.id)) {
20-
savePreset(focusedPreset);
21-
focusedPreset = null;
22-
} else focusedPreset = target as HTMLDivElement;
23-
switch_mode(focusedPreset == null ? TERMINAL_STATE.STYLE : TERMINAL_STATE.GENERAL);
24-
reflect_term_changers(null, focusedPreset);
26+
const preset_target = target.parentElement.getElementsByClassName('preset-label')[0] as HTMLSpanElement;
27+
if (!!focused_preset && (preset_target.id != focused_preset.id)) return;
28+
target.parentElement.classList.toggle("focused", !focused_preset);
29+
switch_mode(!!focused_preset ? TERMINAL_STATE.STYLE : TERMINAL_STATE.GENERAL);
30+
if (!!focused_preset) {
31+
save_preset(focused_preset);
32+
focused_preset = null;
33+
} else {
34+
focused_preset = preset_target;
35+
reflect_term_changers(null, focused_preset);
36+
}
2537
}
2638
}
2739

2840

2941

3042
// Left section: styles controls.
3143

44+
/**
45+
* Array of 'term changers' - interface elements, representing all styles that can be handled.
46+
* Interacting with term changer leads to changing of style of selected text part.
47+
*/
3248
const term_changers = [...document.getElementsByClassName('term-changer')] as HTMLElement[];
3349

50+
/**
51+
* Function, called after 'term changer' was clicked. It applies term changer style to given element or range.
52+
* @see term_changers term changer
53+
* @param acceptor element or range, to which style will be applied.
54+
* @param elem term changer, representing style, that will be applied.
55+
*/
3456
function apply_style (acceptor: Range | HTMLSpanElement, elem: HTMLElement): void {
3557
const name = elem.getAttribute('name');
3658
if (elem.nodeName == "INPUT") {
@@ -43,7 +65,14 @@ function apply_style (acceptor: Range | HTMLSpanElement, elem: HTMLElement): voi
4365
}
4466
}
4567

46-
export function reflect_term_changers (range?: Range, single?: HTMLDivElement) {
68+
/**
69+
* Function to set term changers to represent selected text or preset styles.
70+
* @see term_changers term changers
71+
* @see focused_preset preset
72+
* @param range selected text, that should be represented.
73+
* @param single preset, that should be represented.
74+
*/
75+
export function reflect_term_changers (range?: Range, single?: HTMLSpanElement) {
4776
drop_term_changers();
4877
if (!range == !single) return;
4978

@@ -63,6 +92,10 @@ export function reflect_term_changers (range?: Range, single?: HTMLDivElement) {
6392
}
6493
}
6594

95+
/**
96+
* Function to reset 'term changers' to their default values.
97+
* @see term_changers term changers
98+
*/
6699
export function drop_term_changers (): void {
67100
(document.getElementById('colors-tab') as HTMLFormElement).reset();
68101
[...term_changers].forEach((value: HTMLElement) => {
@@ -74,24 +107,46 @@ export function drop_term_changers (): void {
74107

75108
// Middle section: presets controls.
76109

77-
let focusedPreset: HTMLDivElement = null;
78-
110+
/**
111+
* Preset, that is currently focused to change.
112+
* Preset is a stylable span outside of terminal, may be considered as a combination of term changers.
113+
* @see term_changers term changers
114+
*/
115+
let focused_preset: HTMLSpanElement = null;
116+
117+
/**
118+
* Function, called after 'preset' was clicked. It applies preset styles to given element or range.
119+
* @see focused_preset preset
120+
* @param acceptor element or range, to which style will be applied.
121+
* @param elem term changer, representing style, that will be applied.
122+
*/
79123
function apply_styles (acceptor: Range | HTMLSpanElement, elem: HTMLElement): void {
80124
style(acceptor, null);
81125
[...elem.classList].forEach((value: string): void => {
82-
if ((value == "preset-label") || (value == 'mdl-chip__text')) return;
126+
if (!Object.keys(CLASS_CODES).includes(value)) return;
83127
const type = getPrefix(value);
84128
if (multiplePrefix(type)) style(acceptor, { type: type, value: getPostfix(value) });
85129
else style(acceptor, { type: type, value: true });
86130
});
87131
}
88132

89-
function savePreset (preset: HTMLDivElement): void {
133+
/**
134+
* Function to save preset styles to cookies. Presets may be altered after 'preset button' is clicked.
135+
* During alteration terminal goes into 'GENERAL' mode.
136+
* Their value is saved after button is clicked for the second time.
137+
* @see TERMINAL_STATE terminal mode
138+
* @param preset preset to save value.
139+
*/
140+
function save_preset (preset: HTMLSpanElement): void {
90141
set(preset.id, preset.className);
91142
}
92143

93-
export function restorePresets () {
94-
[...document.getElementsByClassName('preset-example')].forEach((value: HTMLDivElement): void => {
144+
/**
145+
* Function, loading preset values from cookies. Called once on window loaded.
146+
* @see focused_preset presets
147+
*/
148+
export function restore_presets () {
149+
[...document.getElementsByClassName('preset-label')].forEach((value: HTMLDivElement): void => {
95150
const savedValue = get(value.id) as string;
96151
if (!!savedValue) value.className = savedValue;
97152
});
@@ -101,25 +156,43 @@ export function restorePresets () {
101156

102157
// Right section: variable controls.
103158

159+
/**
160+
* Input element, representing variable name, and function called on input to this element.
161+
* Variable name may be set to every 'styled span' and is contained in special 'data-var-name' attribute.
162+
* @see terminal styled span
163+
*/
104164
const var_name = document.getElementById("var-name-input") as HTMLInputElement;
105165
var_name.oninput = () => {
106166
const collapse = get_collapse(get_focus());
107167
if (!!collapse) {
108168
collapse.setAttribute(VAR_NAMES[var_name.id], var_name.value);
109169
if (var_name.value.length == 0) collapse.setAttribute(VAR_NAMES["var-type-input"], "");
110170
}
111-
reflectVariable(get_focus());
171+
reflect_variable(get_focus());
112172
};
173+
174+
/**
175+
* Input element, representing variable type, and function called on input to this element.
176+
* Variable type may be set to 'styled span' with 'var name' and is contained in special 'data-var-type' attribute.
177+
* If span has no 'var name', this element is automatically cleared and disabled.
178+
* @see var_name var name
179+
* @see terminal styled span
180+
*/
113181
const var_type = document.getElementById("var-type-input") as HTMLSelectElement;
114182
var_type.oninput = () => {
115183
const collapse = get_collapse(get_focus());
116184
if (!!collapse && var_type.selectedIndex != 0) collapse.setAttribute(VAR_NAMES[var_type.id], var_type.value);
117-
reflectVariable(get_focus());
185+
reflect_variable(get_focus());
118186
};
119187

120-
export function reflectVariable (range: Range): void {
188+
/**
189+
* Function to set 'var name' and 'var type' to represent selected span.
190+
* @see var_name var name
191+
* @see var_type var type
192+
*/
193+
export function reflect_variable (range: Range): void {
121194
const collapse = get_collapse(range);
122-
dropVariables();
195+
drop_variables();
123196

124197
if (!!collapse) {
125198
const variable = collapse.getAttribute(VAR_NAMES[var_name.id]) ?? "";
@@ -133,7 +206,12 @@ export function reflectVariable (range: Range): void {
133206
} else var_name._enable(false);
134207
}
135208

136-
function dropVariables (): void {
209+
/**
210+
* Function to reset 'var name' and 'var type' to none.
211+
* @see var_name var name
212+
* @see var_type var type
213+
*/
214+
function drop_variables (): void {
137215
(document.getElementById('variables-tab') as HTMLFormElement).reset();
138216
var_name._set("");
139217
var_name._enable(true);

0 commit comments

Comments
 (0)