/**
* {@link XMLEditor} part used to display the clipboard content.
*/
class ClipboardTool extends HTMLElement {
constructor() {
super();
this._xmlEditor = null;
this._source = null;
this._sourcePopup = null;
this._onSourcePopupClosed = this.onSourcePopupClosed.bind(this);
this._plainTextTimeout = null;
}
// -----------------------------------------------------------------------
// Custom element
// -----------------------------------------------------------------------
connectedCallback() {
if (this.firstChild === null) {
this._button = document.createElement("span");
this._button.className = "xxe-tool-button xxe-clpbrd-tool-button";
this._button.setAttribute("title", "Show Clipboard Content");
this._button.textContent = XUI.StockIcon["clipboard"];
this.appendChild(this._button);
this._label = document.createElement("span");
this._label.className = "xxe-clpbrd-tool-label";
this.appendChild(this._label);
let handler = this.onClick.bind(this);
this._button.addEventListener("click", handler);
this._button.addEventListener("contextmenu", handler);
this._label.addEventListener("contextmenu", handler);
}
// Otherwise, already connected.
}
// -----------------------------------------------------------------------
// Event handlers
// -----------------------------------------------------------------------
onClick(event) {
XUI.Util.consumeEvent(event);
if (this._sourcePopup === null) {
this._sourcePopup = XUI.Dialogs.open({
form: this.createSourcePopup(this._source), type: "popup",
classes:
"xui-control xui-dialog xxe-tool-popup xxe-clpbrd-tool-src",
position: "stopmenu", reference: this
});
this._sourcePopup.addEventListener("dialogclosed",
this._onSourcePopupClosed);
} else {
XUI.Dialogs.close(this._sourcePopup);
}
}
createSourcePopup(source) {
let pane = document.createElement("pre");
pane.className =
"xui-control xxe-tool-popup-list xxe-clpbrd-tool-src-pane";
pane.style.width =
String(this.parentElement.getBoundingClientRect().width / 2) + "px";
pane.textContent = (source === null)? "" : source;
return pane;
}
onSourcePopupClosed(event) {
this._sourcePopup = null;
if (this._xmlEditor !== null) {
this._xmlEditor.documentView.requestFocus();
}
}
onPaste(event) {
XUI.Util.consumeEvent(event);
if (this._xmlEditor !== null && this._xmlEditor.documentIsOpened) {
const pasted = event.clipboardData.getData('text/plain');
if (pasted !== null && pasted.length > 0) {
// pasted.startsWith("<?xml") is OK here.
this._xmlEditor.documentView.sendSetClipboard(pasted);
}
}
}
// -----------------------------------------------------------------------
// Used by XMLEditor
// -----------------------------------------------------------------------
set xmlEditor(editor) {
assertOrError(editor !== null);
this._xmlEditor = editor;
editor.clipboardIntegration.getLevel()
.then((level) => {
if (level < ClipboardIntegration.CAN_READ_WRITE) {
this._button.style.color =
(level < ClipboardIntegration.CAN_WRITE)?
"orange" : "#F4C430"; /*Saffron*/
let toolTip = this._button.getAttribute("title");
toolTip += `\n\n\
SYSTEM CLIPBOARD INTEGRATION NOT AVAILABLE\n\
in this browser, therefore this is just a clipboard\n\
which is private to this XML editor.\n\n\
You'll have to paste text (Ctrl-V; \u2318-V on the Mac)\n\
copied from outside this XML editor into the text field\n\
at right to update the content of this private clipboard.`;
this._button.setAttribute("title", toolTip);
// Focusable but without tab navigation.
this._label.setAttribute("tabindex", "-1");
this._label.addEventListener("paste",
this.onPaste.bind(this));
}
});
}
clipboardUpdated(update) {
if (update !== null) {
if (!update.label) {
this.updateLabel("", false, null);
} else {
this.updateLabel(update.label, update.inclusion, update.source);
}
} else {
// Otherwise, editing context changed but clipboard not updated
// OR the document being edited has just been opened or closed.
if (!this._xmlEditor.documentIsOpened) {
this.updateLabel("", false, null);
}
}
}
updateLabel(label, readOnly, source) {
if (this._plainTextTimeout !== null) {
clearTimeout(this._plainTextTimeout);
this._plainTextTimeout = null;
}
let plainText = null;
if (label === "#text" && (plainText = source.trim()).length > 0) {
plainText = plainText.replaceAll(/\s+/g, ' ');
plainText = XUI.Util.shortenText(plainText, 40);
this._label.textContent = plainText;
this._plainTextTimeout = setTimeout(() => {
this._label.textContent = "#text";
}, 1000 /*ms*/);
} else {
this._label.textContent = label;
}
if (readOnly) {
this._label.classList.add("xxe-clpbrd-tool-label-ro");
} else {
this._label.classList.remove("xxe-clpbrd-tool-label-ro");
}
this._source = source;
}
}
window.customElements.define("xxe-clipboard-tool", ClipboardTool);