Image Node settings dialog fields

pull/10/head
Jens Pelzetter 2021-10-04 20:15:23 +02:00
parent 8da183514e
commit d4cb8bb5bb
4 changed files with 1018 additions and 729 deletions

View File

@ -678,7 +678,7 @@
id="librecms-image-node-view-settings-dialog-"
tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form action="#" class="modal-content">
<div class="modal-header">
<h3 class="modal-title"
id="librecms-image-node-view-settings-dialog-title-">
@ -692,7 +692,52 @@
</button>
</div>
<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 class="modal-footer">
<button class="btn btn-warning"
@ -700,13 +745,13 @@
type="button">
#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.close']}
</button>
<button class="btn btn-primary"
<button class="btn btn-primary image-settings-dialog-save"
data-dismiss="modal"
type="button">
#{CmsAdminMessages['cms_editor.image_node_view.settings.dialog.save']}
</button>
</div>
</div>
</form>
</div>
</div>
</div>

File diff suppressed because it is too large Load Diff

View File

@ -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"],
];
},
});

View File

@ -0,0 +1,5 @@
import { ImageNode } from "./image-node";
export * from "./image-node";
export default ImageNode;