Source code
Revision control
Copy as Markdown
Other Tools
/* 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
"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;