143 lines
3.2 KiB
JavaScript
143 lines
3.2 KiB
JavaScript
/* 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.mjs");
|
|
|
|
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;
|