Flatten the closure, simplify its functions

This commit is contained in:
hideheader 2015-03-15 15:41:36 -04:00
parent d3f8e38936
commit b7483035d5
2 changed files with 53 additions and 78 deletions

View File

@ -229,7 +229,7 @@
<td><select data-option="keyMap" id="editor.keyMap"></select></td> <td><select data-option="keyMap" id="editor.keyMap"></select></td>
</tr> </tr>
</table> </table>
</div> </form>
</div> </div>
<section id="sections"> <section id="sections">
<h2><span id="sections-heading"></span> <img id="sections-help" src="help.png"></h2> <h2><span id="sections-heading"></span> <img id="sections-help" src="help.png"></h2>

99
edit.js
View File

@ -19,47 +19,37 @@ document.addEventListener("change", function(event) {
if (node.type && !node.form) { // INPUTs that aren't in a FORM are stylesheet if (node.type && !node.form) { // INPUTs that aren't in a FORM are stylesheet
switch (node.type) { switch (node.type) {
case "checkbox": case "checkbox":
clean(node, node.checked === node.defaultChecked); setCleanItem(node, node.checked === node.defaultChecked);
break; break;
case "text": case "text":
case "select-one": case "select-one":
case "select-multiple": case "select-multiple":
clean(node, node.value === node.defaultValue); setCleanItem(node, node.value === node.defaultValue);
break; break;
} }
} }
}); });
var clean = (function Clean() { // Set .dirty on stylesheet contributors that have changed
var items = {}, var items = {};
__clean = true; function isCleanItem(node) {
function isCleanGlobal(lastChange) { return items[node.id];
if (typeof lastChange === "boolean") { }
var wasClean = __clean; function setCleanItem(node, clean) {
__clean = !lastChange ? false : Object.keys(items).every(function(item) { var id = node.id;
return items[item] if (!id) id = node.id = Date.now().toString(32).substr(-6);
}); items[id] = clean;
if (wasClean !== __clean) initTitle();
} if (clean) node.classList.remove("dirty");
return __clean; else node.classList.add("dirty");
}
function isCleanItem(item, clean) { initTitle();
if (item instanceof HTMLElement) { }
var node = item; function isCleanGlobal() {
item = node.id; return Object.keys(items)
} .every(function(item) { return items[item] });
if (typeof clean === "boolean") { }
if (node) { function setCleanGlobal(form) {
if (!item) item = node.id = Date.now().toString(32).substr(-6);
node.classList[clean ? "remove" : "add"]("dirty");
}
var wasClean = items[item];
items[item] = clean;
if (wasClean !== clean) isCleanGlobal(clean);
}
return items[item];
}
function initialize(form) {
if (!form) form = null; if (!form) form = null;
Array.prototype.forEach.call(document.querySelectorAll("input, select"), function(node) { Array.prototype.forEach.call(document.querySelectorAll("input, select"), function(node) {
if (node.form === form) { if (node.form === form) {
@ -68,33 +58,19 @@ var clean = (function Clean() {
} else { } else {
node.defaultValue = node.value; node.defaultValue = node.value;
} }
node.classList.remove("dirty"); node.classList.remove("dirty");
delete items[node.id]; delete items[node.id];
} }
}); });
editors.forEach(function(cm) { editors.forEach(function(cm) {
cm.lastChange = cm.changeGeneration(); cm.lastChange = cm.changeGeneration();
indicateCodeChange(cm); indicateCodeChange(cm);
}); });
// NB: items set with isClean(string, bool) aren't touched
isCleanGlobal(true); initTitle();
} }
function isClean() {
// isClean() return global clean status
// isClean(bool) update global status
// isClean(element) get element clean status
// isClean(element, bool) update element status
switch (arguments.length) {
case 0: return isCleanGlobal();
case 1: return ("boolean" === typeof arguments[0] ? isCleanGlobal : isCleanItem)(arguments[0]);
default: return isCleanItem.apply(this, arguments);
}
}
isClean.initialize = initialize;
isClean.items = items;
return isClean;
})();
var editors = []; // array of all CodeMirror instances var editors = []; // array of all CodeMirror instances
function initCodeMirror() { function initCodeMirror() {
@ -244,11 +220,11 @@ window.onbeforeunload = function() {
height: outerHeight height: outerHeight
}); });
document.activeElement.blur(); document.activeElement.blur();
return !clean() ? t('styleChangesNotSaved') : null; return !isCleanGlobal() ? t('styleChangesNotSaved') : null;
} }
function indicateCodeChange(cm) { function indicateCodeChange(cm) {
clean(cm.getTextArea().parentNode, cm.isClean(cm.lastChange)); setCleanItem(cm.getTextArea().parentNode, cm.isClean(cm.lastChange));
} }
function addAppliesTo(list, name, value) { function addAppliesTo(list, name, value) {
@ -342,7 +318,7 @@ function removeAppliesTo(event) {
appliesToList.appendChild(e); appliesToList.appendChild(e);
} }
Array.prototype.forEach.call(appliesTo.querySelectorAll(".dirty"), function(node) { Array.prototype.forEach.call(appliesTo.querySelectorAll(".dirty"), function(node) {
clean(node, true); setCleanItem(node, true);
}); });
} }
@ -352,11 +328,11 @@ function removeSection(event) {
var idx = editors.indexOf(wrapper && wrapper.CodeMirror); var idx = editors.indexOf(wrapper && wrapper.CodeMirror);
if (idx >= 0) { if (idx >= 0) {
editors.splice(idx, 1); editors.splice(idx, 1);
clean(wrapper.parentNode, true); setCleanItem(wrapper.parentNode, true);
} }
section.parentNode.removeChild(section); section.parentNode.removeChild(section);
Array.prototype.forEach.call(section.querySelectorAll(".dirty"), function(node) { Array.prototype.forEach.call(section.querySelectorAll(".dirty"), function(node) {
clean(node, true); setCleanItem(node, true);
}); });
} }
@ -477,10 +453,9 @@ function init() {
addSection(null, section); addSection(null, section);
// default to enabled // default to enabled
document.getElementById("enabled").checked = true document.getElementById("enabled").checked = true
// document.title = t("addStyleTitle");
tE("heading", "addStyleTitle"); tE("heading", "addStyleTitle");
setupGlobalSearch(); setupGlobalSearch();
clean.initialize(null); setCleanGlobal(null);
initTitle(); initTitle();
return; return;
} }
@ -502,15 +477,15 @@ function initWithStyle(style) {
}); });
style.sections.forEach(function(section) { addSection(null, section) }); style.sections.forEach(function(section) { addSection(null, section) });
setupGlobalSearch(); setupGlobalSearch();
clean.initialize(null); setCleanGlobal(null);
initTitle(); initTitle();
} }
function initTitle(name, dirty) { function initTitle() {
const DIRTY_TITLE = "* $"; const DIRTY_TITLE = "* $";
if (typeof name !== "string") name = document.getElementById("name").defaultValue; var name = document.getElementById("name").defaultValue;
if (typeof dirty !== "boolean") dirty = !clean(); var dirty = !isCleanGlobal();
var title = styleId === null ? t("addStyleTitle") : t('editStyleTitle', [name]); var title = styleId === null ? t("addStyleTitle") : t('editStyleTitle', [name]);
document.title = !dirty ? title : DIRTY_TITLE.replace("$", title); document.title = !dirty ? title : DIRTY_TITLE.replace("$", title);
} }
@ -614,7 +589,7 @@ function getMeta(e) {
function saveComplete(style) { function saveComplete(style) {
styleId = style.id; styleId = style.id;
clean.initialize(null); setCleanGlobal(null);
// Go from new style URL to edit style URL // Go from new style URL to edit style URL
if (location.href.indexOf("id=") == -1) { if (location.href.indexOf("id=") == -1) {