+var Bindings = require("frb");
+require("frb/dom");
+var Properties = require("frb/properties");
var QS = require("qs");
var modes = require("tengwar/modes");
var fonts = require("tengwar/fonts");
-var body = document.body;
-var input = document.querySelector("#input");
-var generalUse = document.querySelector("#input-general-use");
-var classical = document.querySelector("#input-classical");
-var beleriand = document.querySelector("#input-beleriand");
-var annatar = document.querySelector("#input-tengwar-annatar");
-var parmaite = document.querySelector("#input-tengwar-parmaite");
-var output = document.querySelector("#output");
-var divider = document.querySelector("#divider");
-var inputBox = document.querySelector("#input-box");
-
-if (window.location.search) {
- query = QS.parse(window.location.search.slice(1));
- input.value = query.q || "";
- generalUse.checked = query.mode === "general-use";
- classical.checked = query.mode === "classical";
- beleriand.checked = query.mode === "beleriand";
- parmaite.checked = query.font === "parmaite";
- annatar.checked = query.font === "annatar";
-} else {
- query = {
+var controller = Bindings.create(null, {
+ state: {
q: "Mae govannen, Arda!",
mode: "general-use",
font: "annatar"
- };
-}
+ },
+ window: window,
+ bodyElement: document.body,
+ inputElement: document.querySelector("#input"),
+ generalUseElement: document.querySelector("#input-general-use"),
+ classicalElement: document.querySelector("#input-classical"),
+ beleriandElement: document.querySelector("#input-beleriand"),
+ annatarElement: document.querySelector("#input-tengwar-annatar"),
+ parmaiteElement: document.querySelector("#input-tengwar-parmaite"),
+ outputElement: document.querySelector("#output"),
+ dividerElement: document.querySelector("#divider"),
+ inputBoxElement: document.querySelector("#input-box")
+}, {
-body.classList.add("bootstrap");
-update();
-setTimeout(function () {
- body.classList.remove("bootstrap");
-}, 1000);
+ "inputElement.value": {"<->": "state.q"},
+
+ "bodyElement.classList.has('annatar')": {
+ "<-": "state.font == 'annatar'"
+ },
+ "bodyElement.classList.has('parmaite')": {
+ "<-": "state.font == 'parmaite'"
+ },
+
+ "outputElement.classList.has('annatar')": {
+ "<-": "state.font == 'annatar'"
+ },
+ "outputElement.classList.has('parmaite')": {
+ "<-": "state.font == 'parmaite'"
+ },
+
+ "annatarElement.checked": {
+ "<->": "state.font == 'annatar'"
+ },
+ "parmaiteElement.checked": {
+ "<->": "state.font == 'parmaite'"
+ },
+
+ "generalUseElement.checked": {
+ "<->": "state.mode == 'general-use'"
+ },
+ "beleriandElement.checked": {
+ "<->": "state.mode == 'beleriand'"
+ },
+ "classicalElement.checked": {
+ "<->": "state.mode == 'classical'"
+ },
+
+ "inputBoxElement.style.height": {
+ "<-": "heightPx"
+ },
+
+ "outputElement.innerHTML": {
+ "<-": "transcription"
+ },
+
+ "heightPx": {
+ dependencies: "state.height",
+ get: function () {
+ return this.state.height + "px";
+ },
+ set: function (height) {
+ this.state.height = parseInt(height, 10);
+ }
+ },
+
+ "mode": {
+ dependencies: "state.mode",
+ get: function () {
+ return modes[this.state.mode] || modes['general-use'];
+ }
+ },
-function update() {
- var value = query.q || "";
- if (value != input.value) {
- input.value = value;
+ "font": {
+ dependencies: "state.font",
+ get: function () {
+ return fonts[this.state.font] || modes['annatar'];
+ }
+ },
+
+ "transcription": {
+ dependencies: ["mode", "font", "state.q"],
+ get: function () {
+ return this.mode.transcribe(
+ this.state.q,
+ {font: this.font, block: true}
+ );
+ }
+ },
+
+ "searchString": {
+ dependencies: ["state.q", "state.mode", "state.font", "state.height"],
+ get: function () {
+ var string = "?" + QS.stringify(this.state);
+ window.history.replaceState(this.state, "", string);
+ return string;
+ }
}
- history.replaceState(query, value, "?" + QS.stringify(query));
- var mode = modes[query.mode] || TengwarParmaite;
- var font = fonts[query.font] || TengwarAnnatar;
- output.classList.remove(query.font !== "parmaite" ? "parmaite" : "annatar");
- body.classList.remove(query.font !== "parmaite" ? "parmaite" : "annatar");
- output.classList.add(query.font === "parmaite" ? "parmaite" : "annatar");
- body.classList.add(query.font === "parmaite" ? "parmaite" : "annatar");
- output.innerHTML = mode.transcribe(value, {font: font, block: true});
- inputBox.style.height = query.height + "px";
-}
-function onupdate(event) {
- var change;
- if (query.q !== input.value) change = true;
- query.q = input.value;
- var newMode = generalUse.checked ? "general-use" : classical.checked ? "classical" : "beleriand";
- if (query.mode !== newMode) change = true;
- query.mode = newMode;
- var newFont = annatar.checked ? "annatar" : "parmaite";
- if (query.font !== newFont) change = true;
- query.font = newFont;
- if (change) update();
-}
+});
-input.addEventListener("keyup", onupdate);
-input.addEventListener("keydown", onupdate);
+document.body.classList.add("bootstrap");
+setTimeout(function () {
+ document.body.classList.remove("bootstrap");
+}, 1000);
-input.select();
+if (window.location.search) {
+ var state = QS.parse(window.location.search.slice(1));
+ controller.state = {};
+ controller.state.font = state.font;
+ controller.state.mode = state.mode;
+ controller.state.q = state.q;
+ controller.state.height = state.height;
+} else {
+ controller.state = {
+ q: "Mae govannen, Arda!",
+ mode: "general-use",
+ font: "annatar",
+ height: null
+ }
+}
-generalUse.addEventListener("change", onupdate);
-classical.addEventListener("change", onupdate);
-beleriand.addEventListener("change", onupdate);
-parmaite.addEventListener("change", onupdate);
-annatar.addEventListener("change", onupdate);
+controller.inputElement.select();
divider.addEventListener("mousedown", function (event) {
event.preventDefault();
function mousemove(event) {
var end = event.y;
var delta = end - start;
- var height = parseInt(window.getComputedStyle(inputBox).height, 10);
+ var height = parseInt(window.getComputedStyle(controller.inputBoxElement).height, 10);
start = end;
- query.height = height - delta;
- update();
+ controller.state.height = height - delta;
}
function mouseup(event) {
window.removeEventListener("mouseup", mouseup);