2021-01-30 07:33:04 +08:00
|
|
|
import { getAttributeOrThrow } from "../lib/attribute";
|
|
|
|
|
2021-01-18 05:03:03 +08:00
|
|
|
/**
|
|
|
|
* A hook used on [contenteditable] elements to update the specified
|
|
|
|
* attribute with the element text.
|
|
|
|
*
|
|
|
|
* Configuration:
|
|
|
|
*
|
|
|
|
* * `data-update-attribute` - the name of the attribute to update when content changes
|
|
|
|
*/
|
|
|
|
const ContentEditable = {
|
|
|
|
mounted() {
|
2021-01-30 07:33:04 +08:00
|
|
|
this.props = getProps(this);
|
2021-01-18 05:03:03 +08:00
|
|
|
|
|
|
|
this.__updateAttribute();
|
|
|
|
|
|
|
|
// Set the specified attribute on every content change
|
|
|
|
this.el.addEventListener("input", (event) => {
|
|
|
|
this.__updateAttribute();
|
|
|
|
});
|
|
|
|
|
|
|
|
// Make sure only plain text is pasted
|
|
|
|
this.el.addEventListener("paste", (event) => {
|
|
|
|
event.preventDefault();
|
|
|
|
const text = event.clipboardData.getData("text/plain");
|
|
|
|
document.execCommand("insertText", false, text);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
updated() {
|
2021-01-30 07:33:04 +08:00
|
|
|
this.props = getProps(this);
|
|
|
|
|
2021-01-18 05:03:03 +08:00
|
|
|
// The element has been re-rendered so we have to add the attribute back
|
|
|
|
this.__updateAttribute();
|
|
|
|
},
|
|
|
|
|
|
|
|
__updateAttribute() {
|
|
|
|
const value = this.el.innerText.trim();
|
2021-01-30 07:33:04 +08:00
|
|
|
this.el.setAttribute(this.props.attribute, value);
|
2021-01-18 05:03:03 +08:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-01-30 07:33:04 +08:00
|
|
|
function getProps(hook) {
|
|
|
|
return {
|
|
|
|
attribute: getAttributeOrThrow(hook.el, "data-update-attribute"),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-01-18 05:03:03 +08:00
|
|
|
export default ContentEditable;
|