diff --git a/.eslintignore b/.eslintignore index e294b7775..b757f3546 100644 --- a/.eslintignore +++ b/.eslintignore @@ -64,7 +64,9 @@ CliClient/build/ # AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD CliClient/app/LinkSelector.js CliClient/app/services/plugins/PluginRunner.js +CliClient/tests/fsDriver.js CliClient/tests/InMemoryCache.js +CliClient/tests/MdToHtml.js CliClient/tests/models_Setting.js CliClient/tests/services_CommandService.js CliClient/tests/services_InteropService.js @@ -216,22 +218,36 @@ ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js ReactNativeClient/lib/components/SelectDateTimeDialog.js ReactNativeClient/lib/errorUtils.js ReactNativeClient/lib/eventManager.js +ReactNativeClient/lib/fs-driver-node.js ReactNativeClient/lib/hooks/useEffectDebugger.js ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js ReactNativeClient/lib/hooks/usePrevious.js ReactNativeClient/lib/hooks/usePropsDebugger.js ReactNativeClient/lib/InMemoryCache.js +ReactNativeClient/lib/joplin-renderer/MarkupToHtml.js +ReactNativeClient/lib/joplin-renderer/MdToHtml.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/code_inline.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fountain.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/highlight_keywords.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/html_image.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/image.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/katex.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/link_open.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js +ReactNativeClient/lib/joplin-renderer/noteStyle.js +ReactNativeClient/lib/joplin-renderer/pathUtils.js ReactNativeClient/lib/JoplinServerApi.js ReactNativeClient/lib/locale.js ReactNativeClient/lib/Logger.js ReactNativeClient/lib/markdownUtils.js +ReactNativeClient/lib/markupLanguageUtils.js ReactNativeClient/lib/models/Alarm.js ReactNativeClient/lib/models/Setting.js ReactNativeClient/lib/ntpDate.js +ReactNativeClient/lib/path-utils.js ReactNativeClient/lib/PoorManIntervals.js ReactNativeClient/lib/reducer.js ReactNativeClient/lib/services/AlarmService.js @@ -292,6 +308,7 @@ ReactNativeClient/lib/services/plugins/PluginService.js ReactNativeClient/lib/services/plugins/reducer.js ReactNativeClient/lib/services/plugins/sandboxProxy.js ReactNativeClient/lib/services/plugins/ToolbarButtonController.js +ReactNativeClient/lib/services/plugins/utils/contentScriptsToRendererRules.js ReactNativeClient/lib/services/plugins/utils/createViewHandle.js ReactNativeClient/lib/services/plugins/utils/executeSandboxCall.js ReactNativeClient/lib/services/plugins/utils/manifestFromObject.js diff --git a/.gitignore b/.gitignore index 50b1318f0..6f485a0d2 100644 --- a/.gitignore +++ b/.gitignore @@ -58,7 +58,9 @@ plugin_types/ # AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD CliClient/app/LinkSelector.js CliClient/app/services/plugins/PluginRunner.js +CliClient/tests/fsDriver.js CliClient/tests/InMemoryCache.js +CliClient/tests/MdToHtml.js CliClient/tests/models_Setting.js CliClient/tests/services_CommandService.js CliClient/tests/services_InteropService.js @@ -210,22 +212,36 @@ ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js ReactNativeClient/lib/components/SelectDateTimeDialog.js ReactNativeClient/lib/errorUtils.js ReactNativeClient/lib/eventManager.js +ReactNativeClient/lib/fs-driver-node.js ReactNativeClient/lib/hooks/useEffectDebugger.js ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js ReactNativeClient/lib/hooks/usePrevious.js ReactNativeClient/lib/hooks/usePropsDebugger.js ReactNativeClient/lib/InMemoryCache.js +ReactNativeClient/lib/joplin-renderer/MarkupToHtml.js +ReactNativeClient/lib/joplin-renderer/MdToHtml.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/code_inline.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fountain.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/highlight_keywords.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/html_image.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/image.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/katex.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/link_open.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js +ReactNativeClient/lib/joplin-renderer/noteStyle.js +ReactNativeClient/lib/joplin-renderer/pathUtils.js ReactNativeClient/lib/JoplinServerApi.js ReactNativeClient/lib/locale.js ReactNativeClient/lib/Logger.js ReactNativeClient/lib/markdownUtils.js +ReactNativeClient/lib/markupLanguageUtils.js ReactNativeClient/lib/models/Alarm.js ReactNativeClient/lib/models/Setting.js ReactNativeClient/lib/ntpDate.js +ReactNativeClient/lib/path-utils.js ReactNativeClient/lib/PoorManIntervals.js ReactNativeClient/lib/reducer.js ReactNativeClient/lib/services/AlarmService.js @@ -286,6 +302,7 @@ ReactNativeClient/lib/services/plugins/PluginService.js ReactNativeClient/lib/services/plugins/reducer.js ReactNativeClient/lib/services/plugins/sandboxProxy.js ReactNativeClient/lib/services/plugins/ToolbarButtonController.js +ReactNativeClient/lib/services/plugins/utils/contentScriptsToRendererRules.js ReactNativeClient/lib/services/plugins/utils/createViewHandle.js ReactNativeClient/lib/services/plugins/utils/executeSandboxCall.js ReactNativeClient/lib/services/plugins/utils/manifestFromObject.js diff --git a/.ignore b/.ignore index ce5272e9b..798db5ac2 100644 --- a/.ignore +++ b/.ignore @@ -7,7 +7,9 @@ # AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD CliClient/app/LinkSelector.js CliClient/app/services/plugins/PluginRunner.js +CliClient/tests/fsDriver.js CliClient/tests/InMemoryCache.js +CliClient/tests/MdToHtml.js CliClient/tests/models_Setting.js CliClient/tests/services_CommandService.js CliClient/tests/services_InteropService.js @@ -159,22 +161,36 @@ ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js ReactNativeClient/lib/components/SelectDateTimeDialog.js ReactNativeClient/lib/errorUtils.js ReactNativeClient/lib/eventManager.js +ReactNativeClient/lib/fs-driver-node.js ReactNativeClient/lib/hooks/useEffectDebugger.js ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js ReactNativeClient/lib/hooks/usePrevious.js ReactNativeClient/lib/hooks/usePropsDebugger.js ReactNativeClient/lib/InMemoryCache.js +ReactNativeClient/lib/joplin-renderer/MarkupToHtml.js +ReactNativeClient/lib/joplin-renderer/MdToHtml.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/code_inline.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fountain.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/highlight_keywords.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/html_image.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/image.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/katex.js +ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/link_open.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js +ReactNativeClient/lib/joplin-renderer/noteStyle.js +ReactNativeClient/lib/joplin-renderer/pathUtils.js ReactNativeClient/lib/JoplinServerApi.js ReactNativeClient/lib/locale.js ReactNativeClient/lib/Logger.js ReactNativeClient/lib/markdownUtils.js +ReactNativeClient/lib/markupLanguageUtils.js ReactNativeClient/lib/models/Alarm.js ReactNativeClient/lib/models/Setting.js ReactNativeClient/lib/ntpDate.js +ReactNativeClient/lib/path-utils.js ReactNativeClient/lib/PoorManIntervals.js ReactNativeClient/lib/reducer.js ReactNativeClient/lib/services/AlarmService.js @@ -235,6 +251,7 @@ ReactNativeClient/lib/services/plugins/PluginService.js ReactNativeClient/lib/services/plugins/reducer.js ReactNativeClient/lib/services/plugins/sandboxProxy.js ReactNativeClient/lib/services/plugins/ToolbarButtonController.js +ReactNativeClient/lib/services/plugins/utils/contentScriptsToRendererRules.js ReactNativeClient/lib/services/plugins/utils/createViewHandle.js ReactNativeClient/lib/services/plugins/utils/executeSandboxCall.js ReactNativeClient/lib/services/plugins/utils/manifestFromObject.js diff --git a/CliClient/app/app.js b/CliClient/app/app.js index caaa2c395..396e08baf 100644 --- a/CliClient/app/app.js +++ b/CliClient/app/app.js @@ -8,7 +8,7 @@ const Note = require('lib/models/Note.js'); const Tag = require('lib/models/Tag.js'); const Setting = require('lib/models/Setting').default; const { reg } = require('lib/registry.js'); -const { fileExtension } = require('lib/path-utils.js'); +const { fileExtension } = require('lib/path-utils'); const { _ } = require('lib/locale'); const fs = require('fs-extra'); const { cliUtils } = require('./cli-utils.js'); diff --git a/CliClient/app/build-doc.js b/CliClient/app/build-doc.js index a96dcb8ca..2a7651d15 100644 --- a/CliClient/app/build-doc.js +++ b/CliClient/app/build-doc.js @@ -1,5 +1,5 @@ const fs = require('fs-extra'); -const { fileExtension, dirname } = require('lib/path-utils.js'); +const { fileExtension, dirname } = require('lib/path-utils'); const wrap_ = require('word-wrap'); const { languageCode } = require('lib/locale'); diff --git a/CliClient/app/cli-integration-tests.js b/CliClient/app/cli-integration-tests.js index e07b858e4..6b35f0ea3 100644 --- a/CliClient/app/cli-integration-tests.js +++ b/CliClient/app/cli-integration-tests.js @@ -2,7 +2,7 @@ const fs = require('fs-extra'); const Logger = require('lib/Logger').default; -const { dirname } = require('lib/path-utils.js'); +const { dirname } = require('lib/path-utils'); const { DatabaseDriverNode } = require('lib/database-driver-node.js'); const { JoplinDatabase } = require('lib/joplin-database.js'); const BaseModel = require('lib/BaseModel.js'); diff --git a/CliClient/app/command-e2ee.js b/CliClient/app/command-e2ee.js index 97d11fb1f..6c26150ff 100644 --- a/CliClient/app/command-e2ee.js +++ b/CliClient/app/command-e2ee.js @@ -5,7 +5,7 @@ const DecryptionWorker = require('lib/services/DecryptionWorker'); const BaseItem = require('lib/models/BaseItem'); const Setting = require('lib/models/Setting').default; const shim = require('lib/shim').default; -const pathUtils = require('lib/path-utils.js'); +const pathUtils = require('lib/path-utils'); const imageType = require('image-type'); const readChunk = require('read-chunk'); diff --git a/CliClient/app/fuzzing.js b/CliClient/app/fuzzing.js index 534a0830b..35feb904f 100644 --- a/CliClient/app/fuzzing.js +++ b/CliClient/app/fuzzing.js @@ -3,8 +3,8 @@ const { time } = require('lib/time-utils.js'); const Logger = require('lib/Logger').default; const Resource = require('lib/models/Resource.js'); -const { dirname } = require('lib/path-utils.js'); -const { FsDriverNode } = require('./fs-driver-node.js'); +const { dirname } = require('lib/path-utils'); +const FsDriverNode = require('lib/fs-driver-node').default; const lodash = require('lodash'); const exec = require('child_process').exec; const fs = require('fs-extra'); diff --git a/CliClient/app/main.js b/CliClient/app/main.js index 79d2758fb..51df82bb5 100644 --- a/CliClient/app/main.js +++ b/CliClient/app/main.js @@ -24,7 +24,7 @@ const MasterKey = require('lib/models/MasterKey'); const Setting = require('lib/models/Setting').default; const Revision = require('lib/models/Revision.js'); const Logger = require('lib/Logger').default; -const { FsDriverNode } = require('lib/fs-driver-node.js'); +const FsDriverNode = require('lib/fs-driver-node').default; const { shimInit } = require('lib/shim-init-node.js'); const { _ } = require('lib/locale'); const { FileApiDriverLocal } = require('lib/file-api-driver-local.js'); diff --git a/CliClient/tests/EnexToMd.js b/CliClient/tests/EnexToMd.js index 947584711..1dba69834 100644 --- a/CliClient/tests/EnexToMd.js +++ b/CliClient/tests/EnexToMd.js @@ -4,7 +4,7 @@ require('app-module-path').addPath(__dirname); const os = require('os'); const { time } = require('lib/time-utils.js'); -const { filename } = require('lib/path-utils.js'); +const { filename } = require('lib/path-utils'); const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js'); const Folder = require('lib/models/Folder.js'); const Note = require('lib/models/Note.js'); diff --git a/CliClient/tests/HtmlToHtml.js b/CliClient/tests/HtmlToHtml.js index 220b4eaec..c06ea0883 100644 --- a/CliClient/tests/HtmlToHtml.js +++ b/CliClient/tests/HtmlToHtml.js @@ -4,7 +4,7 @@ require('app-module-path').addPath(__dirname); const os = require('os'); const { time } = require('lib/time-utils.js'); -const { filename } = require('lib/path-utils.js'); +const { filename } = require('lib/path-utils'); const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js'); const Folder = require('lib/models/Folder.js'); const Note = require('lib/models/Note.js'); diff --git a/CliClient/tests/HtmlToMd.js b/CliClient/tests/HtmlToMd.js index c67e91e29..7d8fd7c21 100644 --- a/CliClient/tests/HtmlToMd.js +++ b/CliClient/tests/HtmlToMd.js @@ -4,7 +4,7 @@ require('app-module-path').addPath(__dirname); const os = require('os'); const { time } = require('lib/time-utils.js'); -const { filename } = require('lib/path-utils.js'); +const { filename } = require('lib/path-utils'); const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js'); const Folder = require('lib/models/Folder.js'); const Note = require('lib/models/Note.js'); diff --git a/CliClient/tests/MarkupToHtml.js b/CliClient/tests/MarkupToHtml.js index 6bbeef67c..01d1d02b8 100644 --- a/CliClient/tests/MarkupToHtml.js +++ b/CliClient/tests/MarkupToHtml.js @@ -1,7 +1,7 @@ require('app-module-path').addPath(__dirname); const { asyncTest } = require('test-utils.js'); -const MarkupToHtml = require('lib/joplin-renderer/MarkupToHtml'); +const MarkupToHtml = require('lib/joplin-renderer/MarkupToHtml').default; describe('MarkupToHtml', function() { diff --git a/CliClient/tests/MdToHtml.js b/CliClient/tests/MdToHtml.ts similarity index 78% rename from CliClient/tests/MdToHtml.js rename to CliClient/tests/MdToHtml.ts index eec6cedaa..9f2be04e6 100644 --- a/CliClient/tests/MdToHtml.js +++ b/CliClient/tests/MdToHtml.ts @@ -1,24 +1,11 @@ -/* eslint-disable no-unused-vars */ - -require('app-module-path').addPath(__dirname); - const os = require('os'); -const { time } = require('lib/time-utils.js'); -const { filename } = require('lib/path-utils.js'); -const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js'); -const Folder = require('lib/models/Folder.js'); -const Note = require('lib/models/Note.js'); -const BaseModel = require('lib/BaseModel.js'); +const { filename } = require('lib/path-utils'); +const { asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js'); const shim = require('lib/shim').default; -const MdToHtml = require('lib/joplin-renderer/MdToHtml'); -const { enexXmlToMd } = require('lib/import-enex-md-gen.js'); +const MdToHtml = require('lib/joplin-renderer/MdToHtml').default; const { themeStyle } = require('lib/theme'); -process.on('unhandledRejection', (reason, p) => { - console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); -}); - -function newTestMdToHtml(options = null) { +function newTestMdToHtml(options:any = null) { options = { ResourceModel: { isResourceUrl: () => false, @@ -32,7 +19,7 @@ function newTestMdToHtml(options = null) { describe('MdToHtml', function() { - beforeEach(async (done) => { + beforeEach(async (done:Function) => { await setupDatabaseAndSynchronizer(1); await switchClient(1); done(); @@ -52,14 +39,14 @@ describe('MdToHtml', function() { // if (mdFilename !== 'sanitize_9.md') continue; - const mdToHtmlOptions = { + const mdToHtmlOptions:any = { bodyOnly: true, }; if (mdFilename === 'checkbox_alternative.md') { mdToHtmlOptions.plugins = { checkbox: { - renderingType: 2, + checkboxRenderingType: 2, }, }; } @@ -96,7 +83,7 @@ describe('MdToHtml', function() { })); it('should return enabled plugin assets', asyncTest(async () => { - const pluginOptions = {}; + const pluginOptions:any = {}; const pluginNames = MdToHtml.pluginNames(); for (const n of pluginNames) pluginOptions[n] = { enabled: false }; @@ -126,7 +113,7 @@ describe('MdToHtml', function() { // In this case, the HTML contains both the style and // the rendered markdown wrapped in a DIV. const result = await mdToHtml.render('just **testing**'); - expect(result.cssStrings.length).toBe(0); + expect(result.cssStrings.length).toBeGreaterThan(0); expect(result.html.indexOf('rendered-md') >= 0).toBe(true); })); @@ -137,7 +124,7 @@ describe('MdToHtml', function() { // with no wrapper and no style. // The style is instead in the cssStrings property. const result = await mdToHtml.render('just **testing**', null, { bodyOnly: true }); - expect(result.cssStrings.length).toBe(1); + expect(result.cssStrings.length).toBeGreaterThan(0); expect(result.html.trim()).toBe('just testing'); })); @@ -147,7 +134,7 @@ describe('MdToHtml', function() { // It is similar to the bodyOnly option, excepts that // the rendered Markdown is wrapped in a DIV const result = await mdToHtml.render('just **testing**', null, { splitted: true }); - expect(result.cssStrings.length).toBe(1); + expect(result.cssStrings.length).toBeGreaterThan(0); expect(result.html.trim()).toBe('
just testing
\n') return html;
@@ -178,12 +326,12 @@ class MdToHtml {
return html.substring(3, html.length - 5);
}
- clearCache() {
+ public clearCache() {
this.cachedOutputs_ = {};
}
// "theme" is the theme as returned by themeStyle()
- async render(body, theme = null, options = null) {
+ public async render(body:string, theme:any = null, options:any = null):Promise >1)+f+t+w+C.slice(T);break;default:t=C+f+t+w}return s(t)}return y=void 0===y?6:/[gprs]/.test(m)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y)),w.toString=function(){return t+""},w}return{format:h,formatPrefix:function(t,e){var n=h(((t=Vs(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor($s(e)/3))),i=Math.pow(10,-r),a=ec[8+r/3];return function(t){return n(i*t)+a}}}};function rc(t){return qs=nc(t),Xs=qs.format,Zs=qs.formatPrefix,qs}rc({decimal:".",thousands:",",grouping:[3],currency:["$",""],minus:"-"});var ic=function(t){return Math.max(0,-$s(Math.abs(t)))},ac=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor($s(e)/3)))-$s(Math.abs(t)))},oc=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,$s(e)-$s(t))+1},sc=function(){return new cc};function cc(){this.reset()}cc.prototype={constructor:cc,reset:function(){this.s=this.t=0},add:function(t){lc(uc,t,this.t),lc(this,uc.s,this.s),this.s?this.t+=uc.t:this.s=uc.t},valueOf:function(){return this.s}};var uc=new cc;function lc(t,e,n){var r=t.s=e+n,i=r-e,a=r-i;t.t=e-a+(n-i)}var hc=Math.PI,fc=hc/2,dc=hc/4,pc=2*hc,gc=180/hc,yc=hc/180,vc=Math.abs,mc=Math.atan,bc=Math.atan2,xc=Math.cos,_c=Math.ceil,kc=Math.exp,wc=(Math.floor,Math.log),Ec=Math.pow,Tc=Math.sin,Cc=Math.sign||function(t){return t>0?1:t<0?-1:0},Sc=Math.sqrt,Ac=Math.tan;function Mc(t){return t>1?0:t<-1?hc:Math.acos(t)}function Oc(t){return t>1?fc:t<-1?-fc:Math.asin(t)}function Dc(t){return(t=Tc(t/2))*t}function Nc(){}function Bc(t,e){t&&Fc.hasOwnProperty(t.type)&&Fc[t.type](t,e)}var Lc={Feature:function(t,e){Bc(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=xc(e=(e*=yc)/2+dc),o=Tc(e),s=Uc*o,c=zc*a+s*xc(i),u=s*r*Tc(i);Wc.add(bc(u,c)),Yc=t,zc=a,Uc=o}var Jc=function(t){return Vc.reset(),$c(t,Hc),2*Vc};function Qc(t){return[bc(t[1],t[0]),Oc(t[2])]}function Kc(t){var e=t[0],n=t[1],r=xc(n);return[r*xc(e),r*Tc(e),Tc(n)]}function tu(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function eu(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function nu(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function ru(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function iu(t){var e=Sc(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var au,ou,su,cu,uu,lu,hu,fu,du,pu,gu=sc(),yu={point:vu,lineStart:bu,lineEnd:xu,polygonStart:function(){yu.point=_u,yu.lineStart=ku,yu.lineEnd=wu,gu.reset(),Hc.polygonStart()},polygonEnd:function(){Hc.polygonEnd(),yu.point=vu,yu.lineStart=bu,yu.lineEnd=xu,Wc<0?(au=-(su=180),ou=-(cu=90)):gu>1e-6?cu=90:gu<-1e-6&&(ou=-90),pu[0]=au,pu[1]=su},sphere:function(){au=-(su=180),ou=-(cu=90)}};function vu(t,e){du.push(pu=[au=t,su=t]),e >>1;u[g]${md.utils.escapeHtml(latex)}
${renderToStringWithCache(latex, options)}${markdownIt.utils.escapeHtml(latex)}
${renderToStringWithCache(latex, katexOptions)}${contentHtml}
- ${contentHtml}
+ Mermaid
+ //
+ // And that's going to make the lib set the `mermaid` object to the H1 element.
+ // So below, we double-check that what we have really is an instance of the library.
+ return typeof mermaid !== 'undefined' && mermaid !== null && typeof mermaid === 'object' && !!mermaid.init;
}
function mermaidInit() {
diff --git a/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.ts b/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.ts
index b00c7392d..4a1151632 100644
--- a/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.ts
+++ b/ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.ts
@@ -1,53 +1,50 @@
+import { RuleOptions } from 'lib/joplin-renderer/MdToHtml';
+
const md5 = require('md5');
const htmlUtils = require('../../htmlUtils');
-// @ts-ignore: Keep the function signature as-is despite unusued arguments
-function installRule(markdownIt:any, mdOptions:any, ruleOptions:any, context:any) {
- markdownIt.core.ruler.push('sanitize_html', (state:any) => {
- const tokens = state.tokens;
+export default {
+ plugin: function(markdownIt:any, ruleOptions:RuleOptions) {
+ markdownIt.core.ruler.push('sanitize_html', (state:any) => {
+ const tokens = state.tokens;
- const walkHtmlTokens = (tokens:any[]) => {
- if (!tokens || !tokens.length) return;
+ const walkHtmlTokens = (tokens:any[]) => {
+ if (!tokens || !tokens.length) return;
- for (const token of tokens) {
- if (!['html_block', 'html_inline'].includes(token.type)) {
+ for (const token of tokens) {
+ if (!['html_block', 'html_inline'].includes(token.type)) {
+ walkHtmlTokens(token.children);
+ continue;
+ }
+
+ const cacheKey = md5(escape(token.content));
+ let sanitizedContent = ruleOptions.context.cache.value(cacheKey);
+
+ // For html_inline, the content is only a fragment of HTML, as it will be rendered, but
+ // it's not necessarily valid HTML. For example this HTML:
+ //
+ // Testing
+ //
+ // will be rendered as three tokens:
+ //
+ // html_inline:
+ // text: Testing
+ // html_inline:
+ //
+ // So the sanitizeHtml function must handle this kind of non-valid HTML.
+
+ if (!sanitizedContent) {
+ sanitizedContent = htmlUtils.sanitizeHtml(token.content, { addNoMdConvClass: true });
+ }
+
+ token.content = sanitizedContent;
+
+ ruleOptions.context.cache.setValue(cacheKey, sanitizedContent, 1000 * 60 * 60);
walkHtmlTokens(token.children);
- continue;
}
+ };
- const cacheKey = md5(escape(token.content));
- let sanitizedContent = context.cache.value(cacheKey);
-
- // For html_inline, the content is only a fragment of HTML, as it will be rendered, but
- // it's not necessarily valid HTML. For example this HTML:
- //
- // Testing
- //
- // will be rendered as three tokens:
- //
- // html_inline:
- // text: Testing
- // html_inline:
- //
- // So the sanitizeHtml function must handle this kind of non-valid HTML.
-
- if (!sanitizedContent) {
- sanitizedContent = htmlUtils.sanitizeHtml(token.content, { addNoMdConvClass: true });
- }
-
- token.content = sanitizedContent;
-
- context.cache.setValue(cacheKey, sanitizedContent, 1000 * 60 * 60);
- walkHtmlTokens(token.children);
- }
- };
-
- walkHtmlTokens(tokens);
- });
-}
-
-export default function(context:any, ruleOptions:any) {
- return function(md:any, mdOptions:any) {
- installRule(md, mdOptions, ruleOptions, context);
- };
-}
+ walkHtmlTokens(tokens);
+ });
+ },
+};
diff --git a/ReactNativeClient/lib/joplin-renderer/assets/mermaid/mermaid.min.js b/ReactNativeClient/lib/joplin-renderer/assets/mermaid/mermaid.min.js
index c6706e924..7c0fbb995 100644
--- a/ReactNativeClient/lib/joplin-renderer/assets/mermaid/mermaid.min.js
+++ b/ReactNativeClient/lib/joplin-renderer/assets/mermaid/mermaid.min.js
@@ -1,4 +1,11 @@
-!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.mermaid=e():t.mermaid=e()}("undefined"!=typeof self?self:this,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=383)}([function(t,e,n){"use strict";n.r(e);var r=function(t,e){return tcu&&(cu=e)),u?t0?r=S(s=Math.floor(s/r)*r,c=Math.ceil(c/r)*r,n):r<0&&(r=S(s=Math.ceil(s*r)/r,c=Math.floor(c*r)/r,n)),r>0?(i[a]=Math.floor(s/r)*r,i[o]=Math.ceil(c/r)*r,e(i)):r<0&&(i[a]=Math.ceil(s*r)/r,i[o]=Math.floor(c*r)/r,e(i)),t},t}function sg(){var t=ig(Jp,Jp);return t.copy=function(){return ng(t,sg())},Rp.apply(t,arguments),og(t)}function cg(t){var e;function n(t){return isNaN(t=+t)?e:t}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=Up.call(e,Xp),n):t.slice()},n.unknown=function(t){return arguments.length?(e=t,n):e},n.copy=function(){return cg(t).unknown(e)},t=arguments.length?Up.call(t,Xp):[0,1],og(n)}var ug=function(t,e){var n,r=0,i=(t=t.slice()).length-1,a=t[r],o=t[i];return o0){for(;fc)break;g.push(h)}}else g=C(f,d,Math.min(d-f,p)).map(n);return r?g.reverse():g},r.tickFormat=function(t,i){if(null==i&&(i=10===a?".0e":","),"function"!=typeof i&&(i=Xs(i)),t===1/0)return i;null==t&&(t=10);var o=Math.max(1,a*t/r.ticks().length);return function(t){var r=t/n(Math.round(e(t)));return r*a=c)return-1;if(37===(i=e.charCodeAt(o++))){if(i=e.charAt(o++),!(a=_[i in Hy?e.charAt(o++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return(b.x=k(n,b),b.X=k(r,b),b.c=k(e,b),x.x=k(n,x),x.X=k(r,x),x.c=k(e,x),{format:function(t){var e=k(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=w(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=k(t+="",x);return e.toString=function(){return t},e},utcParse:function(t){var e=w(t+="",!0);return e.toString=function(){return t},e}})}var zy,Uy,$y,Wy,Vy,Hy={"-":"",_:" ",0:"0"},Gy=/^\s*\d+/,qy=/^%/,Xy=/[\\^$*+?|[\]().{}]/g;function Zy(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(ah&&A.push("'"+this.terminals_[T]+"'");O=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(c+1)+": Unexpected "+(x==f?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(O,{text:p.match,token:this.terminals_[x]||x,line:p.yylineno,loc:v,expected:A})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+x);switch(w[0]){case 1:n.push(x),i.push(p.yytext),a.push(p.yylloc),n.push(w[1]),x=null,_?(x=_,_=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,v=p.yylloc,l>0&&l--);break;case 2:if(C=this.productions_[w[1]][1],M.$=i[i.length-C],M._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(M._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(E=this.performAction.apply(M,[s,u,c,g.yy,w[1],i,a].concat(d))))return E;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[w[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},M={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;a