summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/markup/views/text-editor.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/inspector/markup/views/text-editor.js')
-rw-r--r--devtools/client/inspector/markup/views/text-editor.js143
1 files changed, 143 insertions, 0 deletions
diff --git a/devtools/client/inspector/markup/views/text-editor.js b/devtools/client/inspector/markup/views/text-editor.js
new file mode 100644
index 0000000000..62b59c74cd
--- /dev/null
+++ b/devtools/client/inspector/markup/views/text-editor.js
@@ -0,0 +1,143 @@
+/* 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/. */
+
+"use strict";
+
+const {
+ createFactory,
+} = require("resource://devtools/client/shared/vendor/react.js");
+
+const TextNode = createFactory(
+ require("resource://devtools/client/inspector/markup/components/TextNode.js")
+);
+
+loader.lazyRequireGetter(
+ this,
+ "getAutocompleteMaxWidth",
+ "resource://devtools/client/inspector/markup/utils.js",
+ true
+);
+loader.lazyRequireGetter(
+ this,
+ "getLongString",
+ "resource://devtools/client/inspector/shared/utils.js",
+ true
+);
+loader.lazyRequireGetter(
+ this,
+ "InplaceEditor",
+ "resource://devtools/client/shared/inplace-editor.js",
+ true
+);
+
+/**
+ * Creates a simple text editor node, used for TEXT and COMMENT
+ * nodes.
+ *
+ * @param {MarkupContainer} container
+ * The container owning this editor.
+ * @param {DOMNode} node
+ * The node being edited.
+ * @param {String} type
+ * The type of editor to build. This can be either 'text' or 'comment'.
+ */
+function TextEditor(container, node, type) {
+ this.container = container;
+ this.markup = this.container.markup;
+ this.node = node;
+ this._selected = false;
+
+ this.showTextEditor = this.showTextEditor.bind(this);
+
+ this.buildMarkup(type);
+}
+
+TextEditor.prototype = {
+ buildMarkup(type) {
+ const doc = this.markup.doc;
+
+ this.elt = doc.createElement("span");
+ this.elt.classList.add("editor", type);
+
+ getLongString(this.node.getNodeValue()).then(value => {
+ this.textNode = this.ReactDOM.render(
+ TextNode({
+ showTextEditor: this.showTextEditor,
+ type,
+ value,
+ }),
+ this.elt
+ );
+ });
+ },
+
+ get ReactDOM() {
+ // Reuse the toolbox's ReactDOM to avoid loading react-dom.js again in the
+ // Inspector's BrowserLoader.
+ return this.container.markup.inspector.ReactDOM;
+ },
+
+ get selected() {
+ return this._selected;
+ },
+
+ set selected(value) {
+ if (value === this._selected) {
+ return;
+ }
+ this._selected = value;
+ this.update();
+ },
+
+ showTextEditor(element) {
+ new InplaceEditor({
+ cssProperties: this.markup.inspector.cssProperties,
+ done: (val, commit) => {
+ if (!commit) {
+ return;
+ }
+ getLongString(this.node.getNodeValue()).then(oldValue => {
+ this.container.undo.do(
+ () => {
+ this.node.setNodeValue(val);
+ },
+ () => {
+ this.node.setNodeValue(oldValue);
+ }
+ );
+ });
+ },
+ element,
+ maxWidth: () => getAutocompleteMaxWidth(element, this.container.elt),
+ multiline: true,
+ stopOnReturn: true,
+ trimOutput: false,
+ });
+ },
+
+ async update() {
+ try {
+ const value = await getLongString(this.node.getNodeValue());
+
+ if (this.textNode.state.value !== value) {
+ this.textNode.setState({ value });
+ }
+ } catch (e) {
+ console.error(e);
+ }
+ },
+
+ destroy() {
+ this.ReactDOM.unmountComponentAtNode(this.elt);
+ },
+
+ /**
+ * Stub method for consistency with ElementEditor.
+ */
+ getInfoAtNode() {
+ return null;
+ },
+};
+
+module.exports = TextEditor;