-
Notifications
You must be signed in to change notification settings - Fork 1
/
converters_new.js
135 lines (135 loc) · 5.15 KB
/
converters_new.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
const commonOptions = { separator: " " };
var origin = document.getElementById("origin");
var target = document.getElementById("target");
function append(parent, content) {
if (typeof content === "string") parent.appendChild(document.createTextNode(content));
else if (Array.isArray(content)) for (var node of content) append(parent, node);
else parent.appendChild(content);
}
function element(className, content) {
const span = document.createElement("span");
span.className = className;
append(span, content);
return span;
}
function segment(converter, string) {
const nodes = [];
const regex = new RegExp(converter.regex);
let match, prevIndex = 0;
while (match = regex.exec(string)) {
if (regex.ignoreCase) for (var i = 0; i < match.length; i++) match[i] = match[i] && match[i].toLowerCase();
match.push(match.index, match.input);
if (match.groups) {
if (regex.ignoreCase) for (var key in match.groups) match.groups[key] = match.groups[key] && match.groups[key].toLowerCase();
match.push(match.groups);
}
let result = converter.transform.apply(converter, match);
const stringBefore = string.slice(prevIndex, match.index);
if (prevIndex && /^(\s*|['ʹʼˈ’′'])$/.test(stringBefore)) {
const pairwiseResult = converter.pairwise(nodes[nodes.length - 1][1], result);
nodes[nodes.length - 1][1] = pairwiseResult[0];
result = pairwiseResult[1];
if (commonOptions.separator) nodes.push(["separator", commonOptions.separator]);
}
else if (stringBefore) nodes.push(["raw", stringBefore]);
nodes.push(["substituted", result]);
prevIndex = regex.lastIndex;
}
const stringAfter = string.slice(prevIndex);
if (stringAfter) nodes.push(["raw", stringAfter]);
for (var args of nodes) if (args[0] === "substituted") args[1] = converter.construct.apply(converter, args[1]);
return nodes;
}
function update() {
history.replaceState(null, document.title, location.pathname + (origin.value && "#" + encodeURIComponent(origin.value)));
localStorage.setItem(Converter.name, JSON.stringify(Object.assign({ input: origin.value }, commonOptions, Converter)));
target.textContent = "";
const converter = new Converter();
for (var node of origin.value.split(/\r\n?|[\n\u2028\u2029]/).map(function(line) {
const div = document.createElement("div");
for (var args of segment(converter, line)) div.appendChild(element.apply(void 0, args));
return div;
})) target.appendChild(node);
}
[].forEach.call(document.querySelectorAll("input[type=checkbox]"), function(element) {
element.onclick = function() {
Converter[element.id] = element.checked;
update();
};
Converter[element.id] = element.checked;
});
[].forEach.call(document.querySelectorAll("input[type=radio]"), function(element) {
if (element.name in commonOptions) {
element.onclick = function() {
commonOptions[element.name] = document.forms.options[element.name].value;
update();
};
commonOptions[element.name] = document.forms.options[element.name].value;
} else {
element.onclick = function() {
Converter[element.name] = document.forms.options[element.name].value;
update();
};
Converter[element.name] = document.forms.options[element.name].value;
}
});
var separatorOther = document.getElementById("separator-other");
var separatorOther = document.getElementById("separator-other");
var separatorOtherInput = document.getElementById("separator-other-input");
if (separatorOther && separatorOtherInput) separatorOtherInput.oninput = function() {
separatorOther.checked = true;
commonOptions.separator = separatorOther.value = separatorOtherInput.value;
update();
};
origin.oninput = update;
origin.onscroll = function() {
if (target.isScrolling) target.isScrolling = false;
else {
target.scrollTop = this.scrollTop / (this.scrollHeight - this.clientHeight) * (target.scrollHeight - target.clientHeight);
origin.isScrolling = true;
}
};
target.onscroll = function() {
if (origin.isScrolling) origin.isScrolling = false;
else {
origin.scrollTop = this.scrollTop / (this.scrollHeight - this.clientHeight) * (origin.scrollHeight - origin.clientHeight);
target.isScrolling = true;
}
};
const prevOptions = localStorage.getItem(Converter.name);
if (prevOptions) {
const options = JSON.parse(prevOptions);
for (var key in options) {
if (typeof options[key] === "boolean") {
const input = document.getElementById(key);
if (input) input.checked = options[key];
}
}
if ("separator" in options) {
const input = [].find.call(document.querySelectorAll("input[name=separator]"), function(element) {
return element.value === options.separator;
});
if (input) input.checked = true;
else if (separatorOther && separatorOtherInput) {
separatorOther.checked = true;
separatorOther.value = separatorOtherInput.value = options.separator;
}
commonOptions.separator = options.separator;
delete options.separator;
}
if ("input" in options) {
origin.value = options.input;
delete options.input;
}
Object.assign(Converter, options);
}
function tryDecode(str) {
try {
return decodeURIComponent(str.replace(/%(?![\da-f]{2})/gi, "%25"));
} catch (e) {
return str;
}
}
const hash = location.hash.slice(location.hash[0] === "#");
if (hash) origin.value = tryDecode(hash);
if (origin.value) update();