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
import { MultilineEditor } from "chrome://browser/content/multilineeditor/multiline-editor.mjs";
/**
* Creates a Smartbar editor element.
*
* @param {HTMLInputElement | MultilineEditor} inputElement
* The input element to replace.
* @returns {{
* input: MultilineEditor,
* editor: object
* } | null}
* An object with the new editor element and the adapter.
*/
export function createEditor(inputElement) {
if (!inputElement) {
return null;
}
if (inputElement instanceof MultilineEditor) {
return {
input: inputElement,
editor: createEditorAdapter(inputElement),
};
}
const doc = inputElement.ownerDocument;
const editorElement = /** @type {MultilineEditor} */ (
doc.createElement("moz-multiline-editor")
);
// Copy attributes except those that don’t apply.
for (const attr of inputElement.attributes) {
if (attr.name == "type" || attr.name == "value") {
continue;
}
editorElement.setAttribute(attr.name, attr.value);
}
editorElement.className = inputElement.className;
editorElement.id = inputElement.id;
editorElement.value = inputElement.value ?? "";
inputElement.replaceWith(editorElement);
return {
input: editorElement,
editor: createEditorAdapter(editorElement),
};
}
/**
* Creates an adapter for the Smartbar editor element.
*
* @param {MultilineEditor} editorElement
* The editor element.
*/
export function createEditorAdapter(editorElement) {
const getSelectionBounds = () => {
let start = editorElement.selectionStart ?? 0;
let end = editorElement.selectionEnd ?? start;
if (start > end) {
[start, end] = [end, start];
}
return { start, end };
};
return {
get composing() {
return !!editorElement.composing;
},
selection: {
get rangeCount() {
const { start, end } = getSelectionBounds();
return start === end && editorElement.value === "" ? 0 : 1;
},
toStringWithFormat() {
const { start, end } = getSelectionBounds();
if (start == null || end == null) {
return "";
}
return editorElement.value?.substring(start, end);
},
},
};
}