Skip to content

Commit

Permalink
wip #1500 Get image content for Richtext processing
Browse files Browse the repository at this point in the history
  • Loading branch information
ComLock committed Nov 25, 2024
1 parent cc4cf1b commit 7f04530
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 69 deletions.
8 changes: 4 additions & 4 deletions src/main/resources/lib/enonic/react4xp/DataFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
import { getCachedPageComponentFromContentType } from '/lib/enonic/react4xp/pageTemplate/getCachedPageComponentFromContentType';
import { getCachedPageComponentFromPageTemplateContentId } from '/lib/enonic/react4xp/pageTemplate/getCachedPageComponentFromPageTemplateContentId';

import {replaceMacroComments} from './replaceMacroComments';
import { dataFromProcessedHtml } from '/lib/enonic/react4xp/dataFromProcessedHtml';


export type FragmentContent<
Expand Down Expand Up @@ -515,7 +515,7 @@ export class DataFetcher {
const processedHtml = processHtml({
value: html
});
const data = replaceMacroComments(processedHtml);
const data = dataFromProcessedHtml(processedHtml);
setIn(processedComponent, path, data);
}
} // for
Expand Down Expand Up @@ -545,7 +545,7 @@ export class DataFetcher {
});
const renderableTextComponent: RenderableTextComponent = JSON.parse(JSON.stringify(component));
renderableTextComponent.props = {
data: replaceMacroComments(processedHtml),
data: dataFromProcessedHtml(processedHtml),
mode
};
return renderableTextComponent;
Expand Down Expand Up @@ -586,7 +586,7 @@ export class DataFetcher {
const processedHtml = processHtml({
value: html
});
const data = replaceMacroComments(processedHtml);
const data = dataFromProcessedHtml(processedHtml);
setIn(processedLayoutOrPageComponent, path, data);
}
} // for
Expand Down
115 changes: 115 additions & 0 deletions src/main/resources/lib/enonic/react4xp/dataFromProcessedHtml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import type {
ImageContent,
ImageData,
MacroData,
RichTextData
} from '@enonic/react-components';
import {get as getContentByKey} from '/lib/xp/content';


export function dataFromProcessedHtml(processedHtml: string): RichTextData {
const rv: RichTextData = {
processedHtml,
macros: [],
images: [],
links: [],
};
let index = 0;
rv.processedHtml = processedHtml
.replace(
/<p>(<!--#MACRO (?:.*?\n?)*?-->)<\/p>/gm,
'$1'
)
.replace(
/<pre>(<!--#MACRO (?:.*?\n?)*?-->)<\/pre>/gm,
'$1'
)
.replace(
/<!--#MACRO ((?:.*?\n?)*?)-->/gm,
(_origHtmlMacroComment, attributesString) => {
// Replacer is executed once per match (macro comment)
index++;
const ref = index.toString();
let name: string = '';
const macro: Partial<MacroData> = {
config: {},
ref,
};
const replacedAttributes = attributesString.replace(
/([^=]+)="([^"]*)"\s*/g,
(_kv, key, value) => {
// Replacer is executed once per match (attribute key/value)
if (key === '_name') {
name = value;
macro.name = name;
macro.descriptor = `whatever:${name}`;
return `data-macro-name="${value}" data-macro-ref="${ref}"`;
}
if (key === '_document') {
return '';
}
if (key === '_body') {
key = 'body';
}
if (macro.config && name) {
if (!macro.config[name]) {
macro.config[name] = {};
}
macro.config[name][key] = value;
}
return '';
}
)
const replacedMacro = `<editor-macro ${replacedAttributes}></editor-macro>`;
if (rv.macros) {
rv.macros.push(macro as MacroData);
}
return replacedMacro;
} // single macro replacer
);

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match
// If the g flag is used, all results matching the complete regular expression will be returned, but capturing groups are not included.
rv.processedHtml = rv.processedHtml.replace(/<img((?:.*?\n?)*?)\/?>/gm,
(_origImgString, imgAttributesString) => {
// Replacer is executed once per match (img element)
index++;
const ref = index.toString();

const srcMatches = imgAttributesString.match(/src="((?:.*?\n?)*?)"/m);
if (!srcMatches) {
throw new Error(`No src attribute found in imgAttributesString:${imgAttributesString}!`);
}
const [_fullSrc, src] = srcMatches;
// (log||console).debug('src:%s', src);

const idMatches = src.match(/_\/image\/([0-9a-f-]+)/);
// (log||console).debug('idMatches:%s', idMatches);

if (!idMatches) {
throw new Error(`No image id found in src:${src}!`);
}
const [_fullId, imageContentId] = idMatches;
// (log||console).debug('imageContentId:%s', imageContentId);

const imageContent: ImageContent = getContentByKey({ key: imageContentId });
if (!imageContent) {
throw new Error(`No image content found for id:${imageContentId}!`);
}
// (log||console).debug('imageContent:%s', imageContent);

const image = {
image: imageContent,
ref,
// style: null // TODO
};
rv.images.push(image as ImageData);
const replacedImage = `<img${imgAttributesString} data-image-ref="${ref}">`;
// (log||console).debug('replacedImage:%s', replacedImage);
return replacedImage;
});

// NOTE content-links seems to work fine without any special handling

return rv;
}
65 changes: 0 additions & 65 deletions src/main/resources/lib/enonic/react4xp/replaceMacroComments.ts

This file was deleted.

0 comments on commit 7f04530

Please sign in to comment.