import { BasicInterceptor } from 'growi-pluginkit'; class DetachCodeBlockUtil { static createReplaceStr(replaceId) { return `
${replaceId}`;
}
}
/**
* The interceptor that detach code blocks
*/
export class DetachCodeBlockInterceptor extends BasicInterceptor {
constructor(crowi) {
super();
this.logger = require('@alias/logger')('growi:DetachCodeBlockInterceptor');
this.crowi = crowi;
this.crowiForJquery = crowi.getCrowiForJquery();
}
/**
* @inheritdoc
*/
isInterceptWhen(contextName) {
return /^prePreProcess|prePostProcess$/.test(contextName);
}
getTargetKey(contextName) {
if (contextName === 'prePreProcess') {
return 'markdown';
}
else if (contextName === 'prePostProcess') {
return 'parsedHTML';
}
}
/**
* @inheritdoc
*/
process(contextName, ...args) {
this.logger.debug(`processing: 'contextName'=${contextName}`);
const context = Object.assign(args[0]); // clone
const targetKey = this.getTargetKey(contextName);
/* eslint-disable no-unused-vars */
const currentPagePath = context.currentPagePath;
/* eslint-enable */
context.dcbContextMap = {};
// see: https://regex101.com/r/8PAEcC/4
context[targetKey] = context[targetKey].replace(/((```|~~~)(.|[\r\n])*?(```|~~~))|(`[^\r\n]*?`)|((.|[\r\n])*?<\/pre>)|(]*>(.|[\r\n])*?<\/pre>)/gm, (all) => {
// create ID
const replaceId = 'dcb-' + this.createRandomStr(8);
this.logger.debug(`'replaceId'=${replaceId} : `, all);
// register to context
let dcbContext = {};
dcbContext.content = all;
dcbContext.substituteContent = DetachCodeBlockUtil.createReplaceStr(replaceId);
context.dcbContextMap[replaceId] = dcbContext;
// return substituteContent
return dcbContext.substituteContent;
});
// resolve
return Promise.resolve(context);
}
/**
* @see http://qiita.com/ryounagaoka/items/4736c225bdd86a74d59c
*
* @param {number} length
* @return random strings
*/
createRandomStr(length) {
const bag = 'abcdefghijklmnopqrstuvwxyz0123456789';
let generated = '';
for (var i = 0; i < length; i++) {
generated += bag[Math.floor(Math.random() * bag.length)];
}
return generated;
}
}
/**
* The interceptor that restore detached code blocks
*/
export class RestoreCodeBlockInterceptor extends BasicInterceptor {
constructor(crowi) {
super();
this.logger = require('@alias/logger')('growi:DetachCodeBlockInterceptor');
this.crowi = crowi;
this.crowiForJquery = crowi.getCrowiForJquery();
}
/**
* @inheritdoc
*/
isInterceptWhen(contextName) {
return /^postPreProcess|preRenderHtml|preRenderPreviewHtml|preRenderCommentHtml|preRenderCommentPreviewHtml$/.test(contextName);
}
getTargetKey(contextName) {
if (contextName === 'postPreProcess') {
return 'markdown';
}
else if (contextName === 'preRenderHtml' || contextName === 'preRenderPreviewHtml'
|| contextName === 'preRenderCommentHtml' || contextName === 'preRenderCommentPreviewHtml') {
return 'parsedHTML';
}
}
/**
* @inheritdoc
*/
process(contextName, ...args) {
this.logger.debug(`processing: 'contextName'=${contextName}`);
const context = Object.assign(args[0]); // clone
const targetKey = this.getTargetKey(contextName);
// forEach keys of dcbContextMap
Object.keys(context.dcbContextMap).forEach((replaceId) => {
// get context object from context
let dcbContext = context.dcbContextMap[replaceId];
// replace it with content by using getter function so that the doller sign does not work
// see: https://github.com/weseek/growi/issues/285
context[targetKey] = context[targetKey].replace(dcbContext.substituteContent, () => { return dcbContext.content });
});
// resolve
return Promise.resolve(context);
}
}