Image Node settings dialog fields
parent
8da183514e
commit
d4cb8bb5bb
|
|
@ -678,7 +678,7 @@
|
||||||
id="librecms-image-node-view-settings-dialog-"
|
id="librecms-image-node-view-settings-dialog-"
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<form action="#" class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3 class="modal-title"
|
<h3 class="modal-title"
|
||||||
id="librecms-image-node-view-settings-dialog-title-">
|
id="librecms-image-node-view-settings-dialog-title-">
|
||||||
|
|
@ -692,7 +692,52 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
Image Node View Settings Dialog
|
<div class="form-group">
|
||||||
|
<label for="alttext">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.alttext.label']}</label>
|
||||||
|
<input aria-describedby="alttext-help"
|
||||||
|
class="form-control"
|
||||||
|
id="alttext"
|
||||||
|
required="true"
|
||||||
|
type="text" />
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
id="alttext-help">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.alttext.help']}</small>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="size">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.size.label']}</label>
|
||||||
|
<select aria-describedby="size-help"
|
||||||
|
class="custom-select"
|
||||||
|
id="size">
|
||||||
|
<option value="25">25%</option>
|
||||||
|
<option value="33">33%</option>
|
||||||
|
<option value="50">50%</option>
|
||||||
|
<option value="66">66%</option>
|
||||||
|
<option value="75">75%</option>
|
||||||
|
<option value="100">100%</option>
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
id="size-help">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.size.help']}</small>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="align">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.align.label']}</label>
|
||||||
|
<select aria-describedby="align-help"
|
||||||
|
class="custom-select"
|
||||||
|
id="align">
|
||||||
|
<option value="floatleft">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.align.floatleft']}</option>
|
||||||
|
<option value="center">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.align.center']}</option>
|
||||||
|
<option value="floatright">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.align.floatright']}</option>
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
id="align-help">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.align.help']}</small>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input aria-describedby="fullsizeoverlay-help"
|
||||||
|
class="form-check-input"
|
||||||
|
id="fullsizeoverlay"
|
||||||
|
type="checkbox" />
|
||||||
|
<label for="fullsizeoverlay">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.fullsizeoverlay.label']}</label>
|
||||||
|
<small class="form-text text-muted"
|
||||||
|
id="fullsizeoverlay-help">#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.fullsizeoverlay.help']}</small>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn btn-warning"
|
<button class="btn btn-warning"
|
||||||
|
|
@ -700,13 +745,13 @@
|
||||||
type="button">
|
type="button">
|
||||||
#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.close']}
|
#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.close']}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary"
|
<button class="btn btn-primary image-settings-dialog-save"
|
||||||
data-dismiss="modal"
|
data-dismiss="modal"
|
||||||
type="button">
|
type="button">
|
||||||
#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.save']}
|
#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.save']}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,235 @@
|
||||||
|
import { Node, nodeInputRule, mergeAttributes } from "@tiptap/core";
|
||||||
|
|
||||||
|
declare module "@tiptap/core" {
|
||||||
|
interface Commands<ReturnType> {
|
||||||
|
libreCmsImageNode: {
|
||||||
|
setLibreCmsImage: (attributes?: { language: string }) => ReturnType;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ImageNode = Node.create({
|
||||||
|
name: "libreCmsImageNode",
|
||||||
|
|
||||||
|
content: "inline*",
|
||||||
|
|
||||||
|
marks: "",
|
||||||
|
|
||||||
|
group: "block",
|
||||||
|
|
||||||
|
code: false,
|
||||||
|
|
||||||
|
defining: true,
|
||||||
|
|
||||||
|
addAttributes() {
|
||||||
|
return {
|
||||||
|
align: {
|
||||||
|
parseHTML: (element) => {
|
||||||
|
if (element.hasAttribute("data-align")) {
|
||||||
|
return element.getAttribute("data-align");
|
||||||
|
} else {
|
||||||
|
return "center";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
altText: {
|
||||||
|
parseHTML: (element) => {
|
||||||
|
const imgElem = element.querySelector("img");
|
||||||
|
if (imgElem) {
|
||||||
|
return imgElem.alt;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
figCaption: {
|
||||||
|
parseHTML: (element) => {
|
||||||
|
const figCaptionElem = element.querySelector("figcaption");
|
||||||
|
if (figCaptionElem) {
|
||||||
|
return figCaptionElem.innerHTML;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fullSizeOverlay: {
|
||||||
|
parseHTML: (element) => {
|
||||||
|
if (element.hasAttribute("data-fullsizeoverlay")) {
|
||||||
|
return (
|
||||||
|
element.getAttribute("data-fullsizeoverlay") ===
|
||||||
|
"true"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
parseHTML: (element) => {
|
||||||
|
if (element.hasAttribute("data-size")) {
|
||||||
|
return element.getAttribute("data-size");
|
||||||
|
} else {
|
||||||
|
return "50";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
addCommands() {
|
||||||
|
return {
|
||||||
|
setLibreCmsImage:
|
||||||
|
(attributes) =>
|
||||||
|
({ commands }) => {
|
||||||
|
return commands.setNode("libreCmsImageNode", attributes);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
addNodeView() {
|
||||||
|
return ({
|
||||||
|
editor,
|
||||||
|
node,
|
||||||
|
getPos,
|
||||||
|
HTMLAttributes,
|
||||||
|
decorations,
|
||||||
|
extension,
|
||||||
|
}) => {
|
||||||
|
const templateNode = document.querySelector(
|
||||||
|
"#librecms-image-node-view"
|
||||||
|
);
|
||||||
|
if (!templateNode) {
|
||||||
|
const errorMsg = document.createElement("div");
|
||||||
|
errorMsg.classList.add("alert");
|
||||||
|
errorMsg.classList.add("alert-danger");
|
||||||
|
errorMsg.textContent = "Failed to create image node view.";
|
||||||
|
|
||||||
|
return errorMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("Node: ");
|
||||||
|
// console.dir(node);
|
||||||
|
|
||||||
|
// console.log(`getPos =`);
|
||||||
|
// console.dir(getPos);
|
||||||
|
|
||||||
|
// console.log(`HTMLAttributes =`);
|
||||||
|
// console.dir(HTMLAttributes);
|
||||||
|
|
||||||
|
// console.log(`decorations = ${decorations}`);
|
||||||
|
// console.dir(decorations);
|
||||||
|
|
||||||
|
// console.log(`extension = ${extension}`);
|
||||||
|
// console.dir(extension);
|
||||||
|
|
||||||
|
const template = templateNode as HTMLTemplateElement;
|
||||||
|
const nodeView = template.content.cloneNode(true) as HTMLElement;
|
||||||
|
const dialogIdNr = Math.floor(Math.random() * 1000000000);
|
||||||
|
const dialogId = `librecms-image-node-view-settings-dialog-${dialogIdNr}`;
|
||||||
|
const dialogTitleId = `${dialogId}-title`;
|
||||||
|
const settingsButtonElem = nodeView.querySelector(
|
||||||
|
".image-settings-button"
|
||||||
|
);
|
||||||
|
if (settingsButtonElem) {
|
||||||
|
settingsButtonElem.setAttribute("data-target", `#${dialogId}`);
|
||||||
|
}
|
||||||
|
const settingsDialogElem = nodeView.querySelector(
|
||||||
|
".modal.image-settings-dialog"
|
||||||
|
);
|
||||||
|
if (settingsDialogElem) {
|
||||||
|
settingsDialogElem.id = dialogId;
|
||||||
|
settingsDialogElem.setAttribute(
|
||||||
|
"aria-labelledby",
|
||||||
|
dialogTitleId
|
||||||
|
);
|
||||||
|
|
||||||
|
const settingsDialogTitleElem =
|
||||||
|
settingsDialogElem.querySelector(".modal-title");
|
||||||
|
if (settingsDialogTitleElem) {
|
||||||
|
settingsDialogTitleElem.id = dialogTitleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const settingDialogIds =
|
||||||
|
settingsDialogElem.querySelectorAll("*[id]");
|
||||||
|
for (let i = 0; i < settingDialogIds.length; i++) {
|
||||||
|
const elemWithId = settingDialogIds.item(i);
|
||||||
|
elemWithId.id = `${elemWithId.id}-${dialogIdNr}`;
|
||||||
|
}
|
||||||
|
const settingDialogLabels =
|
||||||
|
settingsDialogElem.querySelectorAll("*[for]");
|
||||||
|
for (let i = 0; i < settingDialogLabels.length; i++) {
|
||||||
|
const label = settingDialogLabels.item(i);
|
||||||
|
label.id = `${label.id}-${dialogIdNr}`;
|
||||||
|
}
|
||||||
|
const describedElems = settingsDialogElem.querySelectorAll(
|
||||||
|
"*[aria-describedby]"
|
||||||
|
);
|
||||||
|
for (let i = 0; i < describedElems.length; i++) {
|
||||||
|
const describedElem = describedElems.item(i);
|
||||||
|
describedElem.id = `${describedElem.id}-${dialogIdNr}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitButton = settingsDialogElem.querySelector(
|
||||||
|
"button.image-settings-dialog-save"
|
||||||
|
);
|
||||||
|
|
||||||
|
const altTextInput = settingsDialogElem.querySelector(
|
||||||
|
`input#alttext-${dialogIdNr}`
|
||||||
|
);
|
||||||
|
const alignSelect = settingsDialogElem.querySelector(
|
||||||
|
`input#align-${dialogIdNr}`
|
||||||
|
);
|
||||||
|
|
||||||
|
// ToDo: Init inputs
|
||||||
|
|
||||||
|
if (submitButton) {
|
||||||
|
submitButton.addEventListener("click", (event) => {
|
||||||
|
// ToDo: Read values from inputs and update node.attrs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const figCaptionElem = nodeView.querySelector("figcaption");
|
||||||
|
if (node.attrs.figCaption !== "" && figCaptionElem) {
|
||||||
|
figCaptionElem.innerHTML = node.attrs.figCaption;
|
||||||
|
}
|
||||||
|
const dom = document.createElement("div");
|
||||||
|
dom.classList.add("librecms-image-node-view", "p-2");
|
||||||
|
dom.appendChild(nodeView);
|
||||||
|
|
||||||
|
return {
|
||||||
|
dom,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
parseHTML() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
tag: "figure[data-type=librecms-image-node]",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
renderHTML({ node, HTMLAttributes }) {
|
||||||
|
console.log("node = ");
|
||||||
|
console.dir(node);
|
||||||
|
return [
|
||||||
|
"figure",
|
||||||
|
mergeAttributes(HTMLAttributes, {
|
||||||
|
"data-align": node.attrs.align,
|
||||||
|
"data-fullsizeoverlay": node.attrs.fullSizeOverlay,
|
||||||
|
"data-size": node.attrs.size,
|
||||||
|
"data-type": "librecms-image-node",
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
"img",
|
||||||
|
{
|
||||||
|
alt: node.attrs.altText,
|
||||||
|
src: "/assets/remixicon/image-line.svg",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
["figcaption"],
|
||||||
|
];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { ImageNode } from "./image-node";
|
||||||
|
|
||||||
|
export * from "./image-node";
|
||||||
|
|
||||||
|
export default ImageNode;
|
||||||
Loading…
Reference in New Issue