diff --git a/packages/app-cli/tests/services_PluginService.ts b/packages/app-cli/tests/services_PluginService.ts
index 4f0a21ed1..33d210fec 100644
--- a/packages/app-cli/tests/services_PluginService.ts
+++ b/packages/app-cli/tests/services_PluginService.ts
@@ -170,7 +170,9 @@ describe('services_PluginService', function() {
const tempDir = await createTempDir();
const contentScriptPath = `${tempDir}/markdownItTestPlugin.js`;
+ const contentScriptCssPath = `${tempDir}/markdownItTestPlugin.css`;
await shim.fsDriver().copy(`${testPluginDir}/content_script/src/markdownItTestPlugin.js`, contentScriptPath);
+ await shim.fsDriver().copy(`${testPluginDir}/content_script/src/markdownItTestPlugin.css`, contentScriptCssPath);
const service = newPluginService();
@@ -205,7 +207,7 @@ describe('services_PluginService', function() {
const mdToHtml = new MdToHtml();
const module = require(contentScript.path).default;
- mdToHtml.loadExtraRendererRule(contentScript.id, module({}));
+ mdToHtml.loadExtraRendererRule(contentScript.id, tempDir, module({}));
const result = await mdToHtml.render([
'```justtesting',
@@ -213,6 +215,11 @@ describe('services_PluginService', function() {
'```',
].join('\n'));
+ const asset = result.pluginAssets.find(a => a.name === 'justtesting/markdownItTestPlugin.css');
+ const assetContent: string = await shim.fsDriver().readFile(asset.path, 'utf8');
+
+ expect(assetContent.includes('.just-testing')).toBe(true);
+ expect(assetContent.includes('background-color: red;')).toBe(true);
expect(result.html.includes('JUST TESTING: something')).toBe(true);
await shim.fsDriver().remove(tempDir);
diff --git a/packages/app-cli/tests/support/plugins/content_script/package.json b/packages/app-cli/tests/support/plugins/content_script/package.json
index a7ad2623f..761cec9f9 100644
--- a/packages/app-cli/tests/support/plugins/content_script/package.json
+++ b/packages/app-cli/tests/support/plugins/content_script/package.json
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
-}
\ No newline at end of file
+}
diff --git a/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.css b/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.css
new file mode 100644
index 000000000..a168fce07
--- /dev/null
+++ b/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.css
@@ -0,0 +1,4 @@
+.just-testing {
+ background-color: red;
+ color: yellow;
+}
\ No newline at end of file
diff --git a/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.js b/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.js
index bc6bc2aac..a294bfb25 100644
--- a/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.js
+++ b/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.js
@@ -6,7 +6,7 @@ function plugin(markdownIt, _options) {
markdownIt.renderer.rules.fence = function(tokens, idx, options, env, self) {
const token = tokens[idx];
if (token.info !== 'justtesting') return defaultRender(tokens, idx, options, env, self);
- return `JUST TESTING: ${token.content}`;
+ return `
JUST TESTING: ${token.content}
`;
};
}
@@ -14,6 +14,11 @@ module.exports = {
default: function(_context) {
return {
plugin: plugin,
+ assets: function() {
+ return [
+ { name: 'markdownItTestPlugin.css' }
+ ];
+ },
}
},
}
diff --git a/packages/renderer/MdToHtml.ts b/packages/renderer/MdToHtml.ts
index 1b71b3577..f257105f6 100644
--- a/packages/renderer/MdToHtml.ts
+++ b/packages/renderer/MdToHtml.ts
@@ -9,6 +9,7 @@ interface RendererRule {
install(context: any, ruleOptions: any): any;
assets?(theme: any): any;
plugin?: any;
+ assetPath?: string;
}
interface RendererRules {
@@ -197,7 +198,7 @@ export default class MdToHtml {
if (options.extraRendererRules) {
for (const rule of options.extraRendererRules) {
- this.loadExtraRendererRule(rule.id, rule.module);
+ this.loadExtraRendererRule(rule.id, rule.assetPath, rule.module);
}
}
}
@@ -232,15 +233,28 @@ export default class MdToHtml {
}
// `module` is a file that has already been `required()`
- public loadExtraRendererRule(id: string, module: any) {
+ public loadExtraRendererRule(id: string, assetPath: string, module: any) {
if (this.extraRendererRules_[id]) throw new Error(`A renderer rule with this ID has already been loaded: ${id}`);
- this.extraRendererRules_[id] = module;
+ this.extraRendererRules_[id] = {
+ ...module,
+ assetPath,
+ };
+ }
+
+ private ruleByKey(key: string): RendererRule {
+ if (rules[key]) return rules[key];
+ if (this.extraRendererRules_[key]) return this.extraRendererRules_[key];
+ if (key === 'highlight.js') return null;
+ throw new Error(`No such rule: ${key}`);
}
private processPluginAssets(pluginAssets: PluginAssets): RenderResult {
const files: RenderResultPluginAsset[] = [];
const cssStrings = [];
for (const pluginName in pluginAssets) {
+
+ const rule = this.ruleByKey(pluginName);
+
for (const asset of pluginAssets[pluginName]) {
let mime = asset.mime;
@@ -263,10 +277,18 @@ export default class MdToHtml {
throw new Error(`Unsupported inline mime type: ${mime}`);
}
} else {
+ // TODO: we should resolve the path using
+ // resolveRelativePathWithinDir() for increased
+ // security, but the shim is not accessible from the
+ // renderer, and React Native doesn't have this
+ // function, so for now use the provided path as-is.
+
const name = `${pluginName}/${asset.name}`;
+ const assetPath = rule?.assetPath ? `${rule.assetPath}/${asset.name}` : `pluginAssets/${name}`;
+
files.push(Object.assign({}, asset, {
name: name,
- path: `pluginAssets/${name}`,
+ path: assetPath,
mime: mime,
}));
}
@@ -282,7 +304,7 @@ export default class MdToHtml {
// This return all the assets for all the plugins. Since it is called
// on each render, the result is cached.
- private allProcessedAssets(theme: any, codeTheme: string) {
+ private allProcessedAssets(rules: RendererRules, theme: any, codeTheme: string) {
const cacheKey: string = theme.cacheKey + codeTheme;
if (this.allProcessedAssets_[cacheKey]) return this.allProcessedAssets_[cacheKey];
@@ -501,7 +523,7 @@ export default class MdToHtml {
let cssStrings = noteStyle(options.theme);
- let output = { ...this.allProcessedAssets(options.theme, options.codeTheme) };
+ let output = { ...this.allProcessedAssets(allRules, options.theme, options.codeTheme) };
cssStrings = cssStrings.concat(output.cssStrings);
if (options.userCss) cssStrings.push(options.userCss);