summaryrefslogtreecommitdiffstats
path: root/devtools/client/webide/modules/config-view.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/webide/modules/config-view.js')
-rw-r--r--devtools/client/webide/modules/config-view.js373
1 files changed, 373 insertions, 0 deletions
diff --git a/devtools/client/webide/modules/config-view.js b/devtools/client/webide/modules/config-view.js
new file mode 100644
index 000000000..5fb07e235
--- /dev/null
+++ b/devtools/client/webide/modules/config-view.js
@@ -0,0 +1,373 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const {Cu} = require("chrome");
+
+const EventEmitter = require("devtools/shared/event-emitter");
+const Services = require("Services");
+const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties");
+
+var ConfigView;
+
+module.exports = ConfigView = function (window) {
+ EventEmitter.decorate(this);
+ this._doc = window.document;
+ this._keys = [];
+ return this;
+};
+
+ConfigView.prototype = {
+ _renderByType: function (input, name, value, customType) {
+ value = customType || typeof value;
+
+ switch (value) {
+ case "boolean":
+ input.setAttribute("data-type", "boolean");
+ input.setAttribute("type", "checkbox");
+ break;
+ case "number":
+ input.setAttribute("data-type", "number");
+ input.setAttribute("type", "number");
+ break;
+ case "object":
+ input.setAttribute("data-type", "object");
+ input.setAttribute("type", "text");
+ break;
+ default:
+ input.setAttribute("data-type", "string");
+ input.setAttribute("type", "text");
+ break;
+ }
+ return input;
+ },
+
+ set front(front) {
+ this._front = front;
+ },
+
+ set keys(keys) {
+ this._keys = keys;
+ },
+
+ get keys() {
+ return this._keys;
+ },
+
+ set kind(kind) {
+ this._kind = kind;
+ },
+
+ set includeTypeName(include) {
+ this._includeTypeName = include;
+ },
+
+ search: function (event) {
+ if (event.target.value.length) {
+ let stringMatch = new RegExp(event.target.value, "i");
+
+ for (let i = 0; i < this._keys.length; i++) {
+ let key = this._keys[i];
+ let row = this._doc.getElementById("row-" + key);
+ if (key.match(stringMatch)) {
+ row.classList.remove("hide");
+ } else if (row) {
+ row.classList.add("hide");
+ }
+ }
+ } else {
+ var trs = this._doc.getElementById("device-fields").querySelectorAll("tr");
+
+ for (let i = 0; i < trs.length; i++) {
+ trs[i].classList.remove("hide");
+ }
+ }
+ },
+
+ generateDisplay: function (json) {
+ let deviceItems = Object.keys(json);
+ deviceItems.sort();
+ this.keys = deviceItems;
+ for (let i = 0; i < this.keys.length; i++) {
+ let key = this.keys[i];
+ this.generateField(key, json[key].value, json[key].hasUserValue);
+ }
+ },
+
+ generateField: function (name, value, hasUserValue, customType, newRow) {
+ let table = this._doc.querySelector("table");
+ let sResetDefault = Strings.GetStringFromName("device_reset_default");
+
+ if (this._keys.indexOf(name) === -1) {
+ this._keys.push(name);
+ }
+
+ let input = this._doc.createElement("input");
+ let tr = this._doc.createElement("tr");
+ tr.setAttribute("id", "row-" + name);
+ tr.classList.add("edit-row");
+ let td = this._doc.createElement("td");
+ td.classList.add("field-name");
+ td.textContent = name;
+ tr.appendChild(td);
+ td = this._doc.createElement("td");
+ input.classList.add("editable");
+ input.setAttribute("id", name);
+ input = this._renderByType(input, name, value, customType);
+
+ if (customType === "boolean" || input.type === "checkbox") {
+ input.checked = value;
+ } else {
+ if (typeof value === "object") {
+ value = JSON.stringify(value);
+ }
+ input.value = value;
+ }
+
+ if (!(this._includeTypeName || isNaN(parseInt(value, 10)))) {
+ input.type = "number";
+ }
+
+ td.appendChild(input);
+ tr.appendChild(td);
+ td = this._doc.createElement("td");
+ td.setAttribute("id", "td-" + name);
+
+ let button = this._doc.createElement("button");
+ button.setAttribute("data-id", name);
+ button.setAttribute("id", "btn-" + name);
+ button.classList.add("reset");
+ button.textContent = sResetDefault;
+ td.appendChild(button);
+
+ if (!hasUserValue) {
+ button.classList.add("hide");
+ }
+
+ tr.appendChild(td);
+
+ // If this is a new field, add it to the top of the table.
+ if (newRow) {
+ let existing = table.querySelector("#" + name);
+
+ if (!existing) {
+ table.insertBefore(tr, newRow);
+ } else {
+ existing.value = value;
+ }
+ } else {
+ table.appendChild(tr);
+ }
+ },
+
+ resetTable: function () {
+ let table = this._doc.querySelector("table");
+ let trs = table.querySelectorAll("tr:not(#add-custom-field)");
+
+ for (var i = 0; i < trs.length; i++) {
+ table.removeChild(trs[i]);
+ }
+
+ return table;
+ },
+
+ _getCallType: function (type, name) {
+ let frontName = "get";
+
+ if (this._includeTypeName) {
+ frontName += type;
+ }
+
+ return this._front[frontName + this._kind](name);
+ },
+
+ _setCallType: function (type, name, value) {
+ let frontName = "set";
+
+ if (this._includeTypeName) {
+ frontName += type;
+ }
+
+ return this._front[frontName + this._kind](name, value);
+ },
+
+ _saveByType: function (options) {
+ let fieldName = options.id;
+ let inputType = options.type;
+ let value = options.value;
+ let input = this._doc.getElementById(fieldName);
+
+ switch (inputType) {
+ case "boolean":
+ this._setCallType("Bool", fieldName, input.checked);
+ break;
+ case "number":
+ this._setCallType("Int", fieldName, value);
+ break;
+ case "object":
+ try {
+ value = JSON.parse(value);
+ } catch (e) {}
+ this._setCallType("Object", fieldName, value);
+ break;
+ default:
+ this._setCallType("Char", fieldName, value);
+ break;
+ }
+ },
+
+ updateField: function (event) {
+ if (event.target) {
+ let inputType = event.target.getAttribute("data-type");
+ let inputValue = event.target.checked || event.target.value;
+
+ if (event.target.nodeName == "input" &&
+ event.target.validity.valid &&
+ event.target.classList.contains("editable")) {
+ let id = event.target.id;
+ if (inputType === "boolean") {
+ if (event.target.checked) {
+ inputValue = true;
+ } else {
+ inputValue = false;
+ }
+ }
+
+ this._saveByType({
+ id: id,
+ type: inputType,
+ value: inputValue
+ });
+ this._doc.getElementById("btn-" + id).classList.remove("hide");
+ }
+ }
+ },
+
+ _resetToDefault: function (name, input, button) {
+ this._front["clearUser" + this._kind](name);
+ let dataType = input.getAttribute("data-type");
+ let tr = this._doc.getElementById("row-" + name);
+
+ switch (dataType) {
+ case "boolean":
+ this._defaultField = this._getCallType("Bool", name);
+ this._defaultField.then(boolean => {
+ input.checked = boolean;
+ }, () => {
+ input.checked = false;
+ tr.parentNode.removeChild(tr);
+ });
+ break;
+ case "number":
+ this._defaultField = this._getCallType("Int", name);
+ this._defaultField.then(number => {
+ input.value = number;
+ }, () => {
+ tr.parentNode.removeChild(tr);
+ });
+ break;
+ case "object":
+ this._defaultField = this._getCallType("Object", name);
+ this._defaultField.then(object => {
+ input.value = JSON.stringify(object);
+ }, () => {
+ tr.parentNode.removeChild(tr);
+ });
+ break;
+ default:
+ this._defaultField = this._getCallType("Char", name);
+ this._defaultField.then(string => {
+ input.value = string;
+ }, () => {
+ tr.parentNode.removeChild(tr);
+ });
+ break;
+ }
+
+ button.classList.add("hide");
+ },
+
+ checkReset: function (event) {
+ if (event.target.classList.contains("reset")) {
+ let btnId = event.target.getAttribute("data-id");
+ let input = this._doc.getElementById(btnId);
+ this._resetToDefault(btnId, input, event.target);
+ }
+ },
+
+ updateFieldType: function () {
+ let table = this._doc.querySelector("table");
+ let customValueType = table.querySelector("#custom-value-type").value;
+ let customTextEl = table.querySelector("#custom-value-text");
+ let customText = customTextEl.value;
+
+ if (customValueType.length === 0) {
+ return false;
+ }
+
+ switch (customValueType) {
+ case "boolean":
+ customTextEl.type = "checkbox";
+ customText = customTextEl.checked;
+ break;
+ case "number":
+ customText = parseInt(customText, 10) || 0;
+ customTextEl.type = "number";
+ break;
+ default:
+ customTextEl.type = "text";
+ break;
+ }
+
+ return customValueType;
+ },
+
+ clearNewFields: function () {
+ let table = this._doc.querySelector("table");
+ let customTextEl = table.querySelector("#custom-value-text");
+ if (customTextEl.checked) {
+ customTextEl.checked = false;
+ } else {
+ customTextEl.value = "";
+ }
+
+ this.updateFieldType();
+ },
+
+ updateNewField: function () {
+ let table = this._doc.querySelector("table");
+ let customValueType = this.updateFieldType();
+
+ if (!customValueType) {
+ return;
+ }
+
+ let customRow = table.querySelector("tr:nth-of-type(2)");
+ let customTextEl = table.querySelector("#custom-value-text");
+ let customTextNameEl = table.querySelector("#custom-value-name");
+
+ if (customTextEl.validity.valid) {
+ let customText = customTextEl.value;
+
+ if (customValueType === "boolean") {
+ customText = customTextEl.checked;
+ }
+
+ let customTextName = customTextNameEl.value.replace(/[^A-Za-z0-9\.\-_]/gi, "");
+ this.generateField(customTextName, customText, true, customValueType, customRow);
+ this._saveByType({
+ id: customTextName,
+ type: customValueType,
+ value: customText
+ });
+ customTextNameEl.value = "";
+ this.clearNewFields();
+ }
+ },
+
+ checkNewFieldSubmit: function (event) {
+ if (event.keyCode === 13) {
+ this._doc.getElementById("custom-value").click();
+ }
+ }
+};