Skip to content

Commit

Permalink
feat: #947 urlProcessor支持第三个参数,第三个参数为回调函数
Browse files Browse the repository at this point in the history
  • Loading branch information
sunsonliu committed Jan 3, 2025
1 parent fd13e45 commit 05c6cab
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 13 deletions.
46 changes: 46 additions & 0 deletions src/Engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,52 @@ export default class Engine {
this.currentStrMd5 = [];
this.globalConfig = markdownParams.engine.global;
this.htmlWhiteListAppend = this.globalConfig.htmlWhiteList;
this.urlProcessorMap = {};
}

/**
* 重新生成html
* 这是为urlProcessor支持异步回调函数而实现的重新生成html的方法
* 该方法会清空所有缓存,所以降低了该方法的执行频率,1s内最多执行一次
*/
reMakeHtml() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
this.timer = setTimeout(() => {
this.$cherry.lastMarkdownText = '';
this.hashCache = {};
const markdownText = this.$cherry.editor.editor.getValue();
const html = this.makeHtml(markdownText);
this.$cherry.previewer.refresh(html);
this.$cherry.$event.emit('afterChange', {
markdownText,
html,
});
}, 1000);
}

urlProcessor(url, srcType) {
const key = `${srcType}_${url}`;
if (this.urlProcessorMap[key]) {
return this.urlProcessorMap[key];
}
const ret = this.$cherry.options.callback.urlProcessor(url, srcType, (/** @type {string} */ newUrl) => {
if (newUrl) {
if (!this.urlProcessorMap[key]) {
this.urlProcessorMap[key] = newUrl;
this.reMakeHtml();
}
} else {
delete this.urlProcessorMap[key];
}
return;
});
if (ret) {
return ret;
}
return url;
}

initMath(opts) {
Expand Down
6 changes: 3 additions & 3 deletions src/UrlCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ let urlCache = {};
const cherryInnerLinkRegex = /^cherry-inner:\/\/([0-9a-f]+)$/i;

export function urlProcessorProxy(urlProcessor) {
return function (url, srcType) {
return function (url, srcType, callback) {
if (UrlCache.isInnerLink(url)) {
const newUrl = urlProcessor(UrlCache.get(url), srcType);
const newUrl = urlProcessor(UrlCache.get(url), srcType, callback);
return UrlCache.replace(url, newUrl);
}
return urlProcessor(url, srcType);
return urlProcessor(url, srcType, callback);
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/hooks/AutoLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ export default class AutoLink extends SyntaxBase {
linkText = url;
}
}
const processedURL = this.$engine.$cherry.options.callback.urlProcessor(url, 'autolink');
const processedURL = this.$engine.urlProcessor(url, 'autolink');
const safeUri = encodeURIOnce(processedURL);
const displayUri = $e(linkText);
const additionalAttrs = [this.target, this.rel].filter(Boolean).join(' ');
Expand Down
8 changes: 4 additions & 4 deletions src/core/hooks/HtmlBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,19 @@ export default class HtmlBlock extends ParagraphBase {
let wholeStr = whole;
// 识别<a>和<img>标签的href和src属性,并触发urlProcessor回调
m1.replace(/^a .*? href="([^"]+)"/, (all, href) => {
const processedURL = this.$engine.$cherry.options.callback.urlProcessor(href, 'link');
const processedURL = this.$engine.urlProcessor(href, 'link');
wholeStr = wholeStr.replace(/ href="[^"]+"/, ` href="${processedURL}"`);
});
m1.replace(/^a href="([^"]+)"/, (all, href) => {
const processedURL = this.$engine.$cherry.options.callback.urlProcessor(href, 'link');
const processedURL = this.$engine.urlProcessor(href, 'link');
wholeStr = wholeStr.replace(/ href="[^"]+"/, ` href="${processedURL}"`);
});
m1.replace(/^img .*? src="([^"]+)"/, (all, src) => {
const processedURL = this.$engine.$cherry.options.callback.urlProcessor(src, 'image');
const processedURL = this.$engine.urlProcessor(src, 'image');
wholeStr = wholeStr.replace(/ src="[^"]+"/, ` src="${processedURL}"`);
});
m1.replace(/^img src="([^"]+)"/, (all, src) => {
const processedURL = this.$engine.$cherry.options.callback.urlProcessor(src, 'image');
const processedURL = this.$engine.urlProcessor(src, 'image');
wholeStr = wholeStr.replace(/ src="[^"]+"/, ` src="${processedURL}"`);
});

Expand Down
4 changes: 2 additions & 2 deletions src/core/hooks/Image.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class Image extends SyntaxBase {
attrs += ` poster="${encodeURIOnce(poster)}"`;
}

const processedURL = this.$engine.$cherry.options.callback.urlProcessor(link, type);
const processedURL = this.$engine.urlProcessor(link, type);
const defaultWrapper = `<${type} src="${UrlCache.set(
encodeURIOnce(processedURL),
)}"${attrs} ${extent} ${style} ${classes} controls="controls">${$e(alt || '')}</${type}>`;
Expand Down Expand Up @@ -98,7 +98,7 @@ export default class Image extends SyntaxBase {
.replace(/&/g, '&amp;') // 对&多做一次转义,cherry现有的机制会自动把&amp;转成&,只有多做一次转义才能抵消cherry的机制
: '';
return `${leadingChar}<img ${srcProp}="${UrlCache.set(
encodeURIOnce(this.$engine.$cherry.options.callback.urlProcessor(srcValue, 'image')),
encodeURIOnce(this.$engine.urlProcessor(srcValue, 'image')),
)}" ${extent} ${style} ${classes} alt="${$e(alt || '')}"${attrs} ${extendAttrStr}/>`;
}
// should never happen
Expand Down
2 changes: 1 addition & 1 deletion src/core/hooks/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export default class Link extends SyntaxBase {
const processedText = coreText.replace(/~1D/g, '~D'); // 还原替换的$符号
// text可能是html标签,依赖htmlBlock进行处理
if (isValidScheme(processedURL)) {
processedURL = this.$engine.$cherry.options.callback.urlProcessor(processedURL, 'link');
processedURL = this.$engine.urlProcessor(processedURL, 'link');
processedURL = encodeURIOnce(processedURL);
return `${leadingChar + extraLeadingChar}<a href="${UrlCache.set(processedURL)}" ${
this.rel
Expand Down
4 changes: 2 additions & 2 deletions types/cherry.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export interface _CherryOptions<T extends CherryCustomOptions = CherryCustomOpti
* @param url 来源url
* @param srcType 来源类型
*/
urlProcessor?: (url: string, srcType: 'image' | 'audio' | 'video' | 'autolink' | 'link') => string;
urlProcessor?: (url: string, srcType: 'image' | 'audio' | 'video' | 'autolink' | 'link', callback?: any) => string;
/** 文件上传回调 */
fileUpload?: CherryFileUploadHandler;
/** 多文件上传回调 */
Expand Down Expand Up @@ -219,7 +219,7 @@ export interface CherryEngineOptions {
* @param url 来源url
* @param srcType 来源类型
*/
urlProcessor?: (url: string, srcType: 'image' | 'audio' | 'video' | 'autolink' | 'link') => string;
urlProcessor?: (url: string, srcType: 'image' | 'audio' | 'video' | 'autolink' | 'link', callback?: any) => string;
/**
* 额外允许渲染的html标签
* 标签以英文竖线分隔,如:htmlWhiteList: 'iframe|script|style'
Expand Down

0 comments on commit 05c6cab

Please sign in to comment.