mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
All: Fixes #2667: Fixed sanitize function so that it does not break HTML
This commit is contained in:
parent
120aa066c2
commit
71d1e6eb82
20
BUILD.md
20
BUILD.md
@ -20,25 +20,25 @@ Then you can test the various applications:
|
||||
## Testing the desktop application
|
||||
|
||||
cd ElectronClient
|
||||
npm run start
|
||||
npm start
|
||||
|
||||
If you'd like to auto-reload the app on changes rather than having to quit and restart it manually each time, you can use [watchman-make](https://facebook.github.io/watchman/docs/watchman-make.html):
|
||||
|
||||
```sh
|
||||
cd ElectronClient
|
||||
watchman-make -p '**/*.js' '**/*.jsx' --run "npm run start"
|
||||
watchman-make -p '**/*.js' '**/*.jsx' --run "npm start"
|
||||
```
|
||||
|
||||
It still requires you to quit the application each time you want it to rebuild, but at least you don't have to re-run `"npm run start"` each time. Here's what the workflow loop looks like in practice:
|
||||
It still requires you to quit the application each time you want it to rebuild, but at least you don't have to re-run `"npm start"` each time. Here's what the workflow loop looks like in practice:
|
||||
|
||||
1. Edit and save files in your text editor.
|
||||
2. Switch to the Electron app and <kbd>cmd</kbd>+<kbd>Q</kbd> to quit it.
|
||||
3. `watchman` immediately restarts the app for you (whereas usually you'd have to switch back to the terminal, type `"npm run start"`, and hit enter).
|
||||
3. `watchman` immediately restarts the app for you (whereas usually you'd have to switch back to the terminal, type `"npm start"`, and hit enter).
|
||||
|
||||
## Testing the Terminal application
|
||||
|
||||
cd CliClient
|
||||
npm run start
|
||||
npm start
|
||||
|
||||
## Testing the Mobile application
|
||||
|
||||
@ -47,12 +47,12 @@ First you need to setup React Native to build projects with native code. For thi
|
||||
Then:
|
||||
|
||||
cd ReactNativeClient
|
||||
npm run start-android
|
||||
# Or: npm run start-ios
|
||||
npm start-android
|
||||
# Or: npm start-ios
|
||||
|
||||
To run the iOS application, it might be easier to open the file `ios/Joplin.xcworkspace` on XCode and run the app from there.
|
||||
|
||||
Normally the bundler should start automatically with the application. If it doesn't run `npm run start`.
|
||||
Normally the bundler should start automatically with the application. If it doesn't run `npm start`.
|
||||
|
||||
## Building the clipper
|
||||
|
||||
@ -72,9 +72,9 @@ Running `npm run build` would have the same effect, but without watching.
|
||||
|
||||
## Running an application with additional parameters
|
||||
|
||||
You can specify additional parameters when running the desktop or CLI application. To do so, add `--` to the `npm run start` command, followed by your flags. For example:
|
||||
You can specify additional parameters when running the desktop or CLI application. To do so, add `--` to the `npm start` command, followed by your flags. For example:
|
||||
|
||||
npm run start -- --profile ~/MyTestProfile
|
||||
npm start -- --profile ~/MyTestProfile
|
||||
|
||||
## TypeScript
|
||||
|
||||
|
144
CliClient/package-lock.json
generated
144
CliClient/package-lock.json
generated
@ -726,10 +726,68 @@
|
||||
"minimist": "^1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
|
||||
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
|
||||
"requires": {
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
||||
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
|
||||
"requires": {
|
||||
"dom-serializer": "0",
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||
"requires": {
|
||||
"domelementtype": "^1.3.1",
|
||||
"domhandler": "^2.3.0",
|
||||
"domutils": "^1.5.1",
|
||||
"entities": "^1.1.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1311,19 +1369,14 @@
|
||||
"integrity": "sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg=="
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz",
|
||||
"integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==",
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
|
||||
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
|
||||
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
|
||||
},
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
@ -1332,9 +1385,9 @@
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
|
||||
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
|
||||
},
|
||||
"domexception": {
|
||||
"version": "1.0.1",
|
||||
@ -1345,20 +1398,21 @@
|
||||
}
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
|
||||
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.0.0.tgz",
|
||||
"integrity": "sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==",
|
||||
"requires": {
|
||||
"domelementtype": "1"
|
||||
"domelementtype": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
||||
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.0.0.tgz",
|
||||
"integrity": "sha512-n5SelJ1axbO636c2yUtOGia/IcJtVtlhQbFiVDBZHKV5ReJO1ViX7sFEemtuyoAnBxk5meNSYgA8V4s0271efg==",
|
||||
"requires": {
|
||||
"dom-serializer": "0",
|
||||
"domelementtype": "1"
|
||||
"dom-serializer": "^0.2.1",
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"dot-prop": {
|
||||
@ -3042,40 +3096,20 @@
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz",
|
||||
"integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==",
|
||||
"requires": {
|
||||
"domelementtype": "^1.3.1",
|
||||
"domhandler": "^2.3.0",
|
||||
"domutils": "^1.5.1",
|
||||
"entities": "^1.1.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^3.1.1"
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0",
|
||||
"domutils": "^2.0.0",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
|
||||
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4538,14 +4572,6 @@
|
||||
"is-stream": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node-html-parser": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.2.4.tgz",
|
||||
"integrity": "sha512-qHwPdGyGr9pOZBoSgUOuNPG20QYZVN00lFcxKQgjPUODSxVH7obQeLVVawa3B4cfSNtLIeczSzoy/xYA8XG5WQ==",
|
||||
"requires": {
|
||||
"he": "1.1.1"
|
||||
}
|
||||
},
|
||||
"node-persist": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-persist/-/node-persist-2.1.0.tgz",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"author": "Laurent Cozic",
|
||||
"scripts": {
|
||||
"test": "gulp buildTests -L && jasmine --config=tests/support/jasmine.json",
|
||||
"postinstall": "patch-package && npm run build",
|
||||
"postinstall": "patch-package --patch-dir ../patches && npm run build",
|
||||
"build": "gulp build",
|
||||
"start": "gulp build -L && node 'build/main.js' --profile ~/Temp/TestNotes2 --stack-trace-enabled --log-level debug --env dev"
|
||||
},
|
||||
@ -52,6 +52,7 @@
|
||||
"highlight.js": "^9.17.1",
|
||||
"html-entities": "^1.2.1",
|
||||
"html-minifier": "^3.5.15",
|
||||
"htmlparser2": "^4.1.0",
|
||||
"image-data-uri": "^2.0.0",
|
||||
"image-type": "^3.0.0",
|
||||
"joplin-turndown": "^4.0.19",
|
||||
@ -108,8 +109,7 @@
|
||||
"valid-url": "^1.0.9",
|
||||
"word-wrap": "^1.2.3",
|
||||
"xml2js": "^0.4.19",
|
||||
"yargs-parser": "^7.0.0",
|
||||
"node-html-parser": "^1.2.4"
|
||||
"yargs-parser": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^4.0.2",
|
||||
|
@ -30,7 +30,11 @@ describe('MdToHtml', function() {
|
||||
it('should convert from Markdown to Html', asyncTest(async () => {
|
||||
const basePath = `${__dirname}/md_to_html`;
|
||||
const files = await shim.fsDriver().readDirStats(basePath);
|
||||
const mdToHtml = new MdToHtml();
|
||||
const mdToHtml = new MdToHtml({
|
||||
ResourceModel: {
|
||||
isResourceUrl: () => false,
|
||||
},
|
||||
});
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const mdFilename = files[i].path;
|
||||
@ -39,7 +43,7 @@ describe('MdToHtml', function() {
|
||||
const mdFilePath = `${basePath}/${mdFilename}`;
|
||||
const htmlPath = `${basePath}/${filename(mdFilePath)}.html`;
|
||||
|
||||
// if (mdFilename !== 'table_with_header.html') continue;
|
||||
// if (mdFilename !== 'sanitize_9.md') continue;
|
||||
|
||||
const mdToHtmlOptions = {
|
||||
bodyOnly: true,
|
||||
|
@ -1,2 +1,2 @@
|
||||
<img src onerror="" />
|
||||
<img src onerror="" />
|
||||
<img src=""/>
|
||||
<img src=""/>
|
@ -1,2 +1,2 @@
|
||||
<img src onerror="" />
|
||||
<img src onerror="" />
|
||||
<img src=""/>
|
||||
<img src=""/>
|
@ -1 +1 @@
|
||||
<p><a href="#" onclick="">Testing <strong>inline</strong> text</a></p>
|
||||
<p><a href="#">Testing <strong>inline</strong> text</a></p>
|
||||
|
1
CliClient/tests/md_to_html/sanitize_3.html
Normal file
1
CliClient/tests/md_to_html/sanitize_3.html
Normal file
@ -0,0 +1 @@
|
||||
<p>Should be <span style="color: red;">red</span>.</p>
|
1
CliClient/tests/md_to_html/sanitize_3.md
Normal file
1
CliClient/tests/md_to_html/sanitize_3.md
Normal file
@ -0,0 +1 @@
|
||||
Should be <span style="color: red;">red</span>.
|
4
CliClient/tests/md_to_html/sanitize_4.html
Normal file
4
CliClient/tests/md_to_html/sanitize_4.html
Normal file
@ -0,0 +1,4 @@
|
||||
<div class="different">
|
||||
<h5 id="h5">H5</h5>
|
||||
<h6 id="h6">H6</h6>
|
||||
</div>
|
6
CliClient/tests/md_to_html/sanitize_4.md
Normal file
6
CliClient/tests/md_to_html/sanitize_4.md
Normal file
@ -0,0 +1,6 @@
|
||||
<div class="different">
|
||||
|
||||
##### H5
|
||||
###### H6
|
||||
|
||||
</div>
|
6
CliClient/tests/md_to_html/sanitize_5.html
Normal file
6
CliClient/tests/md_to_html/sanitize_5.html
Normal file
@ -0,0 +1,6 @@
|
||||
<style>
|
||||
.different h5 { color: lightgreen; }
|
||||
h5 { color: orange; }
|
||||
h6 { color: orange; }
|
||||
.different h6 { color: lightgreen; }
|
||||
</style>
|
6
CliClient/tests/md_to_html/sanitize_5.md
Normal file
6
CliClient/tests/md_to_html/sanitize_5.md
Normal file
@ -0,0 +1,6 @@
|
||||
<style>
|
||||
.different h5 { color: lightgreen; }
|
||||
h5 { color: orange; }
|
||||
h6 { color: orange; }
|
||||
.different h6 { color: lightgreen; }
|
||||
</style>
|
1
CliClient/tests/md_to_html/sanitize_6.html
Normal file
1
CliClient/tests/md_to_html/sanitize_6.html
Normal file
@ -0,0 +1 @@
|
||||
<p><mark>bla</mark></p>
|
1
CliClient/tests/md_to_html/sanitize_6.md
Normal file
1
CliClient/tests/md_to_html/sanitize_6.md
Normal file
@ -0,0 +1 @@
|
||||
<mark>bla</mark>
|
0
CliClient/tests/md_to_html/sanitize_7.html
Normal file
0
CliClient/tests/md_to_html/sanitize_7.html
Normal file
1
CliClient/tests/md_to_html/sanitize_7.md
Normal file
1
CliClient/tests/md_to_html/sanitize_7.md
Normal file
@ -0,0 +1 @@
|
||||
<script>alert('xss')</script><script>alert('xss')</script>
|
2
CliClient/tests/md_to_html/sanitize_8.html
Normal file
2
CliClient/tests/md_to_html/sanitize_8.html
Normal file
@ -0,0 +1,2 @@
|
||||
<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"leavethisalone"</span>></span>testing fence<span class="hljs-tag"></<span class="hljs-name">a</span>></span>
|
||||
</code></pre>
|
3
CliClient/tests/md_to_html/sanitize_8.md
Normal file
3
CliClient/tests/md_to_html/sanitize_8.md
Normal file
@ -0,0 +1,3 @@
|
||||
```html
|
||||
<a href="#" onclick="leavethisalone">testing fence</a>
|
||||
```
|
1
CliClient/tests/md_to_html/sanitize_9.html
Normal file
1
CliClient/tests/md_to_html/sanitize_9.html
Normal file
@ -0,0 +1 @@
|
||||
<div>M&Ms</div>
|
1
CliClient/tests/md_to_html/sanitize_9.md
Normal file
1
CliClient/tests/md_to_html/sanitize_9.md
Normal file
@ -0,0 +1 @@
|
||||
<div>M&Ms</div>
|
51
ElectronClient/package-lock.json
generated
51
ElectronClient/package-lock.json
generated
@ -3629,6 +3629,24 @@
|
||||
"webidl-conversions": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.0.0.tgz",
|
||||
"integrity": "sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.0.0.tgz",
|
||||
"integrity": "sha512-n5SelJ1axbO636c2yUtOGia/IcJtVtlhQbFiVDBZHKV5ReJO1ViX7sFEemtuyoAnBxk5meNSYgA8V4s0271efg==",
|
||||
"requires": {
|
||||
"dom-serializer": "^0.2.1",
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"dot-prop": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz",
|
||||
@ -6257,6 +6275,24 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz",
|
||||
"integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0",
|
||||
"domutils": "^2.0.0",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz",
|
||||
@ -7967,21 +8003,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-html-parser": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.2.4.tgz",
|
||||
"integrity": "sha512-qHwPdGyGr9pOZBoSgUOuNPG20QYZVN00lFcxKQgjPUODSxVH7obQeLVVawa3B4cfSNtLIeczSzoy/xYA8XG5WQ==",
|
||||
"requires": {
|
||||
"he": "1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"he": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-notifier": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dist": "node_modules/.bin/electron-builder",
|
||||
"build": "patch-package && gulp build",
|
||||
"build": "patch-package --patch-dir ../patches && gulp build",
|
||||
"postinstall": "npm run build && gulp electronRebuild",
|
||||
"start": "gulp build -L && electron . --env dev --log-level debug --no-welcome --open-dev-tools"
|
||||
},
|
||||
@ -107,6 +107,7 @@
|
||||
"highlight.js": "^9.17.1",
|
||||
"html-entities": "^1.2.1",
|
||||
"html-minifier": "^4.0.0",
|
||||
"htmlparser2": "^4.1.0",
|
||||
"image-type": "^3.0.0",
|
||||
"joplin-turndown": "^4.0.19",
|
||||
"joplin-turndown-plugin-gfm": "^1.0.12",
|
||||
@ -137,7 +138,6 @@
|
||||
"multiparty": "^4.2.1",
|
||||
"mustache": "^3.0.1",
|
||||
"node-fetch": "^1.7.3",
|
||||
"node-html-parser": "^1.2.4",
|
||||
"node-notifier": "^6.0.0",
|
||||
"pretty-bytes": "^5.3.0",
|
||||
"promise": "^8.0.1",
|
||||
|
@ -1,18 +0,0 @@
|
||||
diff --git a/node_modules/sax/lib/sax.js b/node_modules/sax/lib/sax.js
|
||||
index 795d607..ccad5d8 100644
|
||||
--- a/node_modules/sax/lib/sax.js
|
||||
+++ b/node_modules/sax/lib/sax.js
|
||||
@@ -1040,6 +1040,13 @@
|
||||
parser.textNode += c
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Sax is kind of buggy when handling large text node. It has a function to check that
|
||||
+ // the buffer doesn't run out of space but it doesn't seem to call it for text node.
|
||||
+ // The result is that parser.textNode reaches 1GB and then the app crashes. So here
|
||||
+ // we call checkBufferLength to make sure the buffer is cleared and the "text" event
|
||||
+ // emitted so that the caller can handle memory properly.
|
||||
+ checkBufferLength(parser);
|
||||
continue
|
||||
|
||||
case S.SCRIPT:
|
@ -201,6 +201,7 @@ class MdToHtml {
|
||||
// Using the `context` object, a plugin can define what additional assets they need (css, fonts, etc.) using context.pluginAssets.
|
||||
// The calling application will need to handle loading these assets.
|
||||
|
||||
markdownIt.use(rules.sanitize_html(context, ruleOptions));
|
||||
markdownIt.use(rules.image(context, ruleOptions));
|
||||
markdownIt.use(rules.checkbox(context, ruleOptions));
|
||||
markdownIt.use(rules.link_open(context, ruleOptions));
|
||||
@ -208,7 +209,6 @@ class MdToHtml {
|
||||
if (this.pluginEnabled('katex')) markdownIt.use(rules.katex(context, ruleOptions));
|
||||
if (this.pluginEnabled('fountain')) markdownIt.use(rules.fountain(context, ruleOptions));
|
||||
if (this.pluginEnabled('mermaid')) markdownIt.use(rules.mermaid(context, ruleOptions));
|
||||
markdownIt.use(rules.sanitize_html(context, ruleOptions));
|
||||
markdownIt.use(rules.highlight_keywords(context, ruleOptions));
|
||||
markdownIt.use(rules.code_inline(context, ruleOptions));
|
||||
markdownIt.use(markdownItAnchor, { slugify: uslugify });
|
||||
|
@ -34,7 +34,7 @@ function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
if (!content.match(imageRegex)) return defaultRender(tokens, idx, options, env, self);
|
||||
|
||||
return content.replace(imageRegex, (v, before, src, after) => {
|
||||
if (!Resource.isResourceUrl(src)) return defaultRender(tokens, idx, options, env, self);
|
||||
if (!Resource.isResourceUrl(src)) return `<img${before}src="${src}"${after}>`;
|
||||
return renderImageHtml(before, src, after, ruleOptions);
|
||||
});
|
||||
};
|
||||
|
@ -1,20 +1,6 @@
|
||||
const md5 = require('md5');
|
||||
const htmlUtils = require('../../htmlUtils');
|
||||
|
||||
function getOpenTagName(html:string):string {
|
||||
const m = html.toLowerCase().match(/<([a-z]+)(\s|>)/);
|
||||
if (!m || m.length < 2) return null;
|
||||
return m[1];
|
||||
}
|
||||
|
||||
function isSelfClosedTag(html:string):boolean {
|
||||
return html.substr(-2) === '/>';
|
||||
}
|
||||
|
||||
function stripOffClosingTag(html:string, tagName:string):string {
|
||||
return html.substr(0, html.length - tagName.length - 3);
|
||||
}
|
||||
|
||||
// @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) => {
|
||||
@ -43,40 +29,10 @@ function installRule(markdownIt:any, mdOptions:any, ruleOptions:any, context:any
|
||||
// text: Testing
|
||||
// html_inline: </a>
|
||||
//
|
||||
// The problem for us is that when we pass this HTML fragment to the sanitize function
|
||||
// it is going to turn it into valid HTML. Thus:
|
||||
//
|
||||
// "<a href="#">" becomes "<a href="#"></a>"
|
||||
// "</a>" becomes ""
|
||||
//
|
||||
// So the result would be "<a href="#"></a>Testing"
|
||||
//
|
||||
// Because of this, we need to be careful with html_inline:
|
||||
//
|
||||
// 0. Check if it's an opening or closing tag - only opening ones need to be processed
|
||||
// 1. Sanitize the fragment
|
||||
// 2. Strip off the closing tag that was added
|
||||
//
|
||||
// Also self-closing tags need to be handled.
|
||||
//
|
||||
// html_block is not a problem as the whole content is valid HTML.
|
||||
// So the sanitizeHtml function must handle this kind of non-valid HTML.
|
||||
|
||||
if (!sanitizedContent) {
|
||||
if (token.type === 'html_inline') {
|
||||
const openTagName = getOpenTagName(token.content);
|
||||
const isSelfClosed = isSelfClosedTag(token.content);
|
||||
|
||||
if (!openTagName) {
|
||||
sanitizedContent = token.content;
|
||||
} else {
|
||||
sanitizedContent = htmlUtils.sanitizeHtml(token.content);
|
||||
if (!isSelfClosed) {
|
||||
sanitizedContent = stripOffClosingTag(sanitizedContent, openTagName);
|
||||
}
|
||||
}
|
||||
} else { // html_block
|
||||
sanitizedContent = htmlUtils.sanitizeHtml(token.content);
|
||||
}
|
||||
}
|
||||
|
||||
token.content = sanitizedContent;
|
||||
|
@ -2,12 +2,32 @@ const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = new Entities().encode;
|
||||
|
||||
// [\s\S] instead of . for multiline matching
|
||||
const NodeHtmlParser = require('node-html-parser');
|
||||
|
||||
// https://stackoverflow.com/a/16119722/561309
|
||||
const imageRegex = /<img([\s\S]*?)src=["']([\s\S]*?)["']([\s\S]*?)>/gi;
|
||||
const JS_EVENT_NAMES = ['onabort', 'onafterprint', 'onbeforeprint', 'onbeforeunload', 'onblur', 'oncanplay', 'oncanplaythrough', 'onchange', 'onclick', 'oncontextmenu', 'oncopy', 'oncuechange', 'oncut', 'ondblclick', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onfocus', 'onhashchange', 'oninput', 'oninvalid', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onmessage', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onoffline', 'ononline', 'onpagehide', 'onpageshow', 'onpaste', 'onpause', 'onplay', 'onplaying', 'onpopstate', 'onprogress', 'onratechange', 'onreset', 'onresize', 'onscroll', 'onsearch', 'onseeked', 'onseeking', 'onselect', 'onstalled', 'onstorage', 'onsubmit', 'onsuspend', 'ontimeupdate', 'ontoggle', 'onunload', 'onvolumechange', 'onwaiting', 'onwheel'];
|
||||
|
||||
const selfClosingElements = [
|
||||
'area',
|
||||
'base',
|
||||
'basefont',
|
||||
'br',
|
||||
'col',
|
||||
'command',
|
||||
'embed',
|
||||
'frame',
|
||||
'hr',
|
||||
'img',
|
||||
'input',
|
||||
'isindex',
|
||||
'keygen',
|
||||
'link',
|
||||
'meta',
|
||||
'param',
|
||||
'source',
|
||||
'track',
|
||||
'wbr',
|
||||
];
|
||||
|
||||
class HtmlUtils {
|
||||
|
||||
attributesHtml(attr) {
|
||||
@ -46,31 +66,64 @@ class HtmlUtils {
|
||||
});
|
||||
}
|
||||
|
||||
sanitizeHtml(html) {
|
||||
const walkHtmlNodes = (nodes) => {
|
||||
if (!nodes || !nodes.length) return;
|
||||
isSelfClosingTag(tagName) {
|
||||
return selfClosingElements.includes(tagName.toLowerCase());
|
||||
}
|
||||
|
||||
for (const node of nodes) {
|
||||
for (const attr in node.attributes) {
|
||||
if (!node.attributes.hasOwnProperty(attr)) continue;
|
||||
if (JS_EVENT_NAMES.includes(attr)) node.setAttribute(attr, '');
|
||||
}
|
||||
walkHtmlNodes(node.childNodes);
|
||||
}
|
||||
sanitizeHtml(html) {
|
||||
const htmlparser2 = require('htmlparser2');
|
||||
|
||||
const output = [];
|
||||
|
||||
const tagStack = [];
|
||||
|
||||
const currentTag = () => {
|
||||
if (!tagStack.length) return '';
|
||||
return tagStack[tagStack.length - 1];
|
||||
};
|
||||
|
||||
// Need to wrap in div, otherwise elements at the root will be skipped
|
||||
// The DIV tags are removed below
|
||||
const dom = NodeHtmlParser.parse(`<div>${html}</div>`, {
|
||||
script: false,
|
||||
style: true,
|
||||
pre: true,
|
||||
comment: false,
|
||||
});
|
||||
const disallowedTags = ['script', 'iframe', 'frameset', 'frame', 'object'];
|
||||
|
||||
walkHtmlNodes([dom]);
|
||||
const output = dom.toString();
|
||||
return output.substr(5, output.length - 11);
|
||||
const parser = new htmlparser2.Parser({
|
||||
|
||||
onopentag: (name, attrs) => {
|
||||
tagStack.push(name.toLowerCase());
|
||||
|
||||
if (disallowedTags.includes(currentTag())) return;
|
||||
|
||||
attrs = Object.assign({}, attrs);
|
||||
for (const eventName of JS_EVENT_NAMES) {
|
||||
delete attrs[eventName];
|
||||
}
|
||||
let attrHtml = this.attributesHtml(attrs);
|
||||
if (attrHtml) attrHtml = ` ${attrHtml}`;
|
||||
const closingSign = this.isSelfClosingTag(name) ? '/>' : '>';
|
||||
output.push(`<${name}${attrHtml}${closingSign}`);
|
||||
},
|
||||
|
||||
ontext: (decodedText) => {
|
||||
if (disallowedTags.includes(currentTag())) return;
|
||||
|
||||
output.push(htmlentities(decodedText));
|
||||
},
|
||||
|
||||
onclosetag: (name) => {
|
||||
const current = currentTag();
|
||||
|
||||
if (current === name.toLowerCase()) tagStack.pop();
|
||||
|
||||
if (disallowedTags.includes(current)) return;
|
||||
|
||||
if (this.isSelfClosingTag(name)) return;
|
||||
output.push(`</${name}>`);
|
||||
},
|
||||
|
||||
}, { decodeEntities: true });
|
||||
|
||||
parser.write(html);
|
||||
parser.end();
|
||||
|
||||
return output.join('');
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
"md5": "^2.2.1",
|
||||
"mermaid": "^8.4.6",
|
||||
"memory-cache": "^0.2.0",
|
||||
"node-html-parser": "^1.2.4",
|
||||
"uslug": "^1.0.4"
|
||||
}
|
||||
}
|
||||
|
183
ReactNativeClient/package-lock.json
generated
183
ReactNativeClient/package-lock.json
generated
@ -2171,6 +2171,12 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
|
||||
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
|
||||
},
|
||||
"@yarnpkg/lockfile": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
|
||||
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
|
||||
"dev": true
|
||||
},
|
||||
"abort-controller": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
@ -3853,12 +3859,44 @@
|
||||
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.4.tgz",
|
||||
"integrity": "sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg=="
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
|
||||
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"entities": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"dom-walk": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
|
||||
"integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=",
|
||||
"dev": true
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
|
||||
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.0.0.tgz",
|
||||
"integrity": "sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.0.0.tgz",
|
||||
"integrity": "sha512-n5SelJ1axbO636c2yUtOGia/IcJtVtlhQbFiVDBZHKV5ReJO1ViX7sFEemtuyoAnBxk5meNSYgA8V4s0271efg==",
|
||||
"requires": {
|
||||
"dom-serializer": "^0.2.1",
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"duplexify": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
|
||||
@ -4417,6 +4455,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"find-yarn-workspace-root": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz",
|
||||
"integrity": "sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs-extra": "^4.0.3",
|
||||
"micromatch": "^3.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
|
||||
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"findup-sync": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
|
||||
@ -5520,6 +5581,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz",
|
||||
"integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0",
|
||||
"domutils": "^2.0.0",
|
||||
"entities": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
|
||||
@ -6254,6 +6326,15 @@
|
||||
"graceful-fs": "^4.1.9"
|
||||
}
|
||||
},
|
||||
"klaw-sync": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
|
||||
"integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.11"
|
||||
}
|
||||
},
|
||||
"last-run": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
|
||||
@ -7485,21 +7566,6 @@
|
||||
"is-stream": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node-html-parser": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.2.4.tgz",
|
||||
"integrity": "sha512-qHwPdGyGr9pOZBoSgUOuNPG20QYZVN00lFcxKQgjPUODSxVH7obQeLVVawa3B4cfSNtLIeczSzoy/xYA8XG5WQ==",
|
||||
"requires": {
|
||||
"he": "1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"he": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-int64": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
||||
@ -7928,6 +7994,93 @@
|
||||
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
|
||||
},
|
||||
"patch-package": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.2.1.tgz",
|
||||
"integrity": "sha512-dfCtQor63PPij6DDYtCzBRoO5nNAcMSg7Cmh+DLhR+s3t0OLQBdvFxJksZHBe1J2MjsSWDjTF4+oQKFbdkssIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@yarnpkg/lockfile": "^1.1.0",
|
||||
"chalk": "^2.4.2",
|
||||
"cross-spawn": "^6.0.5",
|
||||
"find-yarn-workspace-root": "^1.2.1",
|
||||
"fs-extra": "^7.0.1",
|
||||
"is-ci": "^2.0.0",
|
||||
"klaw-sync": "^6.0.0",
|
||||
"minimist": "^1.2.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"semver": "^5.6.0",
|
||||
"slash": "^2.0.0",
|
||||
"tmp": "^0.0.33"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"nice-try": "^1.0.4",
|
||||
"path-key": "^2.0.1",
|
||||
"semver": "^5.5.0",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"slash": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
|
||||
"integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"path-dirname": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
|
||||
|
@ -8,7 +8,7 @@
|
||||
"start": "node node_modules/react-native/local-cli/cli.js start --reset-cache",
|
||||
"start-ios": "react-native run-ios",
|
||||
"start-android": "react-native run-android",
|
||||
"postinstall": "jetify && npm run build",
|
||||
"postinstall": "patch-package --patch-dir ../patches && jetify && npm run build",
|
||||
"build": "gulp build",
|
||||
"log-ios": "react-native-log-ios \"Joplin\"",
|
||||
"log-android": "adb logcat *:S ReactNative:V ReactNativeJS:V"
|
||||
@ -26,6 +26,7 @@
|
||||
"form-data": "^2.1.4",
|
||||
"highlight.js": "^9.17.1",
|
||||
"html-entities": "^1.2.1",
|
||||
"htmlparser2": "^4.1.0",
|
||||
"jsc-android": "241213.1.0",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"katex": "^0.11.1",
|
||||
@ -46,7 +47,6 @@
|
||||
"memory-cache": "^0.2.0",
|
||||
"mermaid": "^8.4.6",
|
||||
"moment": "^2.24.0",
|
||||
"node-html-parser": "^1.2.4",
|
||||
"prop-types": "^15.6.0",
|
||||
"punycode": "^2.1.1",
|
||||
"query-string": "4.3.4",
|
||||
@ -101,6 +101,7 @@
|
||||
"gulp": "^4.0.2",
|
||||
"jetifier": "^1.6.5",
|
||||
"metro-react-native-babel-preset": "^0.54.1",
|
||||
"patch-package": "^6.2.1",
|
||||
"react-test-renderer": "^16.8.3"
|
||||
}
|
||||
}
|
||||
|
47
patches/htmlparser2+4.1.0.patch
Normal file
47
patches/htmlparser2+4.1.0.patch
Normal file
@ -0,0 +1,47 @@
|
||||
diff --git a/node_modules/htmlparser2/lib/Parser.js b/node_modules/htmlparser2/lib/Parser.js
|
||||
index 44b4371..bcd7cc2 100644
|
||||
--- a/node_modules/htmlparser2/lib/Parser.js
|
||||
+++ b/node_modules/htmlparser2/lib/Parser.js
|
||||
@@ -212,6 +212,13 @@ var Parser = /** @class */ (function (_super) {
|
||||
this._tagname = "";
|
||||
};
|
||||
Parser.prototype.onclosetag = function (name) {
|
||||
+ // When this is true, the onclosetag event will always be emitted
|
||||
+ // for closing tags (eg </div>) even if that tag was not previously
|
||||
+ // open. This is needed because we reconstruct the HTML based on
|
||||
+ // fragments that don't necessarily contain the opening tag.
|
||||
+ // Without this patch, onopentagname would not be emitted, and
|
||||
+ // so the closing tag would disappear from the output.
|
||||
+ var alwaysClose = true;
|
||||
this._updatePosition(1);
|
||||
if (this._lowerCaseTagNames) {
|
||||
name = name.toLowerCase();
|
||||
@@ -236,11 +243,15 @@ var Parser = /** @class */ (function (_super) {
|
||||
else if (name === "p" && !this._options.xmlMode) {
|
||||
this.onopentagname(name);
|
||||
this._closeCurrentTag();
|
||||
+ } else if (!this._stack.length && alwaysClose) {
|
||||
+ this._cbs.onclosetag(name);
|
||||
}
|
||||
}
|
||||
else if (!this._options.xmlMode && (name === "br" || name === "p")) {
|
||||
this.onopentagname(name);
|
||||
this._closeCurrentTag();
|
||||
+ } else if (!this._stack.length && alwaysClose) {
|
||||
+ this._cbs.onclosetag(name);
|
||||
}
|
||||
};
|
||||
Parser.prototype.onselfclosingtag = function () {
|
||||
@@ -331,7 +342,11 @@ var Parser = /** @class */ (function (_super) {
|
||||
};
|
||||
Parser.prototype.onend = function () {
|
||||
if (this._cbs.onclosetag) {
|
||||
- for (var i = this._stack.length; i > 0; this._cbs.onclosetag(this._stack[--i]))
|
||||
+ // Prevent the parser from auto-closing tags. Since we deal with fragments that
|
||||
+ // maybe contain the opening tag but not the closing one, we don't want that
|
||||
+ // closing tag to be auto-added.
|
||||
+ //
|
||||
+ // for (var i = this._stack.length; i > 0; this._cbs.onclosetag(this._stack[--i]))
|
||||
;
|
||||
}
|
||||
if (this._cbs.onend)
|
Loading…
Reference in New Issue
Block a user