Compare commits
4 Commits
release-2.
...
server_tas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d71ac2e218 | ||
|
|
c35c5a5821 | ||
|
|
bcb08ac8a2 | ||
|
|
6ff8d775c2 |
@@ -856,9 +856,6 @@ packages/generator-joplin/generators/app/templates/api_index.js.map
|
||||
packages/generator-joplin/generators/app/templates/src/index.d.ts
|
||||
packages/generator-joplin/generators/app/templates/src/index.js
|
||||
packages/generator-joplin/generators/app/templates/src/index.js.map
|
||||
packages/htmlpack/src/index.d.ts
|
||||
packages/htmlpack/src/index.js
|
||||
packages/htmlpack/src/index.js.map
|
||||
packages/lib/AsyncActionQueue.d.ts
|
||||
packages/lib/AsyncActionQueue.js
|
||||
packages/lib/AsyncActionQueue.js.map
|
||||
@@ -1003,9 +1000,6 @@ packages/lib/import-enex-md-gen.js.map
|
||||
packages/lib/import-enex-md-gen.test.d.ts
|
||||
packages/lib/import-enex-md-gen.test.js
|
||||
packages/lib/import-enex-md-gen.test.js.map
|
||||
packages/lib/import-enex.d.ts
|
||||
packages/lib/import-enex.js
|
||||
packages/lib/import-enex.js.map
|
||||
packages/lib/locale.d.ts
|
||||
packages/lib/locale.js
|
||||
packages/lib/locale.js.map
|
||||
@@ -1819,9 +1813,6 @@ packages/renderer/utils.js.map
|
||||
packages/tools/buildServerDocker.d.ts
|
||||
packages/tools/buildServerDocker.js
|
||||
packages/tools/buildServerDocker.js.map
|
||||
packages/tools/buildServerDocker.test.d.ts
|
||||
packages/tools/buildServerDocker.test.js
|
||||
packages/tools/buildServerDocker.test.js.map
|
||||
packages/tools/convertThemesToCss.d.ts
|
||||
packages/tools/convertThemesToCss.js
|
||||
packages/tools/convertThemesToCss.js.map
|
||||
@@ -1855,9 +1846,6 @@ packages/tools/release-server.js.map
|
||||
packages/tools/setupNewRelease.d.ts
|
||||
packages/tools/setupNewRelease.js
|
||||
packages/tools/setupNewRelease.js.map
|
||||
packages/tools/tagServerLatest.d.ts
|
||||
packages/tools/tagServerLatest.js
|
||||
packages/tools/tagServerLatest.js.map
|
||||
packages/tools/tool-utils.d.ts
|
||||
packages/tools/tool-utils.js
|
||||
packages/tools/tool-utils.js.map
|
||||
|
||||
12
.gitignore
vendored
@@ -841,9 +841,6 @@ packages/generator-joplin/generators/app/templates/api_index.js.map
|
||||
packages/generator-joplin/generators/app/templates/src/index.d.ts
|
||||
packages/generator-joplin/generators/app/templates/src/index.js
|
||||
packages/generator-joplin/generators/app/templates/src/index.js.map
|
||||
packages/htmlpack/src/index.d.ts
|
||||
packages/htmlpack/src/index.js
|
||||
packages/htmlpack/src/index.js.map
|
||||
packages/lib/AsyncActionQueue.d.ts
|
||||
packages/lib/AsyncActionQueue.js
|
||||
packages/lib/AsyncActionQueue.js.map
|
||||
@@ -988,9 +985,6 @@ packages/lib/import-enex-md-gen.js.map
|
||||
packages/lib/import-enex-md-gen.test.d.ts
|
||||
packages/lib/import-enex-md-gen.test.js
|
||||
packages/lib/import-enex-md-gen.test.js.map
|
||||
packages/lib/import-enex.d.ts
|
||||
packages/lib/import-enex.js
|
||||
packages/lib/import-enex.js.map
|
||||
packages/lib/locale.d.ts
|
||||
packages/lib/locale.js
|
||||
packages/lib/locale.js.map
|
||||
@@ -1804,9 +1798,6 @@ packages/renderer/utils.js.map
|
||||
packages/tools/buildServerDocker.d.ts
|
||||
packages/tools/buildServerDocker.js
|
||||
packages/tools/buildServerDocker.js.map
|
||||
packages/tools/buildServerDocker.test.d.ts
|
||||
packages/tools/buildServerDocker.test.js
|
||||
packages/tools/buildServerDocker.test.js.map
|
||||
packages/tools/convertThemesToCss.d.ts
|
||||
packages/tools/convertThemesToCss.js
|
||||
packages/tools/convertThemesToCss.js.map
|
||||
@@ -1840,9 +1831,6 @@ packages/tools/release-server.js.map
|
||||
packages/tools/setupNewRelease.d.ts
|
||||
packages/tools/setupNewRelease.js
|
||||
packages/tools/setupNewRelease.js.map
|
||||
packages/tools/tagServerLatest.d.ts
|
||||
packages/tools/tagServerLatest.js
|
||||
packages/tools/tagServerLatest.js.map
|
||||
packages/tools/tool-utils.d.ts
|
||||
packages/tools/tool-utils.js
|
||||
packages/tools/tool-utils.js.map
|
||||
|
||||
|
Before Width: | Height: | Size: 297 B |
@@ -137,8 +137,8 @@ fi
|
||||
#-----------------------------------------------------
|
||||
print 'Downloading Joplin...'
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
wget -O "${TEMP_DIR}/Joplin.AppImage" "https://github.com/laurent22/joplin/releases/download/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage"
|
||||
wget -O "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png
|
||||
wget -O ${TEMP_DIR}/Joplin.AppImage https://github.com/laurent22/joplin/releases/download/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage
|
||||
wget -O ${TEMP_DIR}/joplin.png https://joplinapp.org/images/Icon512.png
|
||||
|
||||
#-----------------------------------------------------
|
||||
print 'Installing Joplin...'
|
||||
@@ -149,7 +149,7 @@ rm -f ~/.joplin/*.AppImage ~/.local/share/applications/joplin.desktop ~/.joplin/
|
||||
mkdir -p ~/.joplin/
|
||||
|
||||
# Download the latest version
|
||||
mv "${TEMP_DIR}/Joplin.AppImage" ~/.joplin/Joplin.AppImage
|
||||
mv ${TEMP_DIR}/Joplin.AppImage ~/.joplin/Joplin.AppImage
|
||||
|
||||
# Gives execution privileges
|
||||
chmod +x ~/.joplin/Joplin.AppImage
|
||||
@@ -159,7 +159,7 @@ print "${COLOR_GREEN}OK${COLOR_RESET}"
|
||||
#-----------------------------------------------------
|
||||
print 'Installing icon...'
|
||||
mkdir -p ~/.local/share/icons/hicolor/512x512/apps
|
||||
mv "${TEMP_DIR}/joplin.png" ~/.local/share/icons/hicolor/512x512/apps/joplin.png
|
||||
mv ${TEMP_DIR}/joplin.png ~/.local/share/icons/hicolor/512x512/apps/joplin.png
|
||||
print "${COLOR_GREEN}OK${COLOR_RESET}"
|
||||
|
||||
# Detect desktop environment
|
||||
@@ -222,7 +222,7 @@ fi
|
||||
print "${COLOR_GREEN}Joplin version${COLOR_RESET} ${RELEASE_VERSION} ${COLOR_GREEN}installed.${COLOR_RESET}"
|
||||
|
||||
# Record version
|
||||
echo "$RELEASE_VERSION" > ~/.joplin/VERSION
|
||||
echo $RELEASE_VERSION > ~/.joplin/VERSION
|
||||
|
||||
#-----------------------------------------------------
|
||||
if [[ "$SHOW_CHANGELOG" == true ]]; then
|
||||
@@ -232,5 +232,5 @@ fi
|
||||
|
||||
#-----------------------------------------------------
|
||||
print "Cleaning up..."
|
||||
rm -rf "$TEMP_DIR"
|
||||
rm -rf $TEMP_DIR
|
||||
print "${COLOR_GREEN}OK${COLOR_RESET}"
|
||||
|
||||
38
README.md
@@ -504,47 +504,47 @@ Current translations:
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
| Language | Po File | Last translator | Percent done
|
||||
---|---|---|---|---
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 91%
|
||||
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 28%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 71%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 55%
|
||||
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 94%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 56%
|
||||
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | jmontane, 2019 | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | Mustafa Al-Dailemi (dailemi@hotmail.com)Language-Team: | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [marph91](mailto:martin.d@andix.de) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [Atalanttore](mailto:atalanttore@googlemail.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 54%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Mora](mailto:francisco.m.collao@gmail.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 31%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 96%
|
||||
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 36%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [eresytter](mailto:42007357+eresytter@users.noreply.github.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Albano Battistella](mailto:albano_battistella@hotmail.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 83%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 86%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [eresytter](mailto:42007357+eresytter@users.noreply.github.com) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Albano Battistella](mailto:albano_battistella@hotmail.com) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 84%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 87%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MetBril](mailto:metbril@users.noreply.github.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | Alexander Dawson | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 67%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [konhi](mailto:hello.konhi@gmail.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [konhi](mailto:hello.konhi@gmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Nicolas Suzuki](mailto:nicolas.suzuki@pm.me) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 62%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 63%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 91%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 42%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/vi.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 80%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 81%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [南宫小骏](mailto:jackytsu@vip.qq.com) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [SiderealArt](mailto:nelson22768384@gmail.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Po-Chiang Chao](mailto:BobChao%29%20%28bobchao@gmail.com) | 94%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 95%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 94%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 95%
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
|
||||
# Contributors
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
"releaseIOS": "node packages/tools/release-ios.js",
|
||||
"releasePluginGenerator": "node packages/tools/release-plugin-generator.js",
|
||||
"releaseServer": "node packages/tools/release-server.js",
|
||||
"tagServerLatest": "node packages/tools/tagServerLatest.js",
|
||||
"buildServerDocker": "node packages/tools/buildServerDocker.js",
|
||||
"setupNewRelease": "node ./packages/tools/setupNewRelease",
|
||||
"test-ci": "lerna run test-ci --stream",
|
||||
|
||||
4
packages/app-cli/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "joplin",
|
||||
"version": "2.4.1",
|
||||
"version": "2.3.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "joplin",
|
||||
"version": "2.4.1",
|
||||
"version": "2.3.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"aws-sdk": "^2.588.0",
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
],
|
||||
"owner": "Laurent Cozic"
|
||||
},
|
||||
"version": "2.4.1",
|
||||
"version": "2.4.0",
|
||||
"bin": {
|
||||
"joplin": "./main.js"
|
||||
},
|
||||
|
||||
@@ -84,10 +84,4 @@ describe('HtmlToMd', function() {
|
||||
}
|
||||
}));
|
||||
|
||||
it('should allow disabling escape', async () => {
|
||||
const htmlToMd = new HtmlToMd();
|
||||
expect(htmlToMd.parse('https://test.com/1_2_3.pdf', { disableEscapeContent: true })).toBe('https://test.com/1_2_3.pdf');
|
||||
expect(htmlToMd.parse('https://test.com/1_2_3.pdf', { disableEscapeContent: false })).toBe('https://test.com/1\\_2\\_3.pdf');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1 +1 @@
|
||||
X<sub>1</sub> X<sup>1</sup> <ins>Insert</ins> <span style="text-decoration: underline;">Insert alt</span> <s>Strike</s>
|
||||
X<sub>1</sub> X<sup>1</sup> <ins>Insert</ins> <s>Strike</s>
|
||||
@@ -1 +1 @@
|
||||
X<sub>1</sub> X<sup>1</sup> <ins>Insert</ins> <ins>Insert alt</ins> ~~Strike~~
|
||||
X<sub>1</sub> X<sup>1</sup> <ins>Insert</ins> ~~Strike~~
|
||||
|
Before Width: | Height: | Size: 441 B After Width: | Height: | Size: 441 B |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -42,6 +42,9 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
|
||||
this.sidebar_selectionChange = this.sidebar_selectionChange.bind(this);
|
||||
this.checkSyncConfig_ = this.checkSyncConfig_.bind(this);
|
||||
// this.checkNextcloudAppButton_click = this.checkNextcloudAppButton_click.bind(this);
|
||||
this.showLogButton_click = this.showLogButton_click.bind(this);
|
||||
this.nextcloudAppHelpLink_click = this.nextcloudAppHelpLink_click.bind(this);
|
||||
this.onCancelClick = this.onCancelClick.bind(this);
|
||||
this.onSaveClick = this.onSaveClick.bind(this);
|
||||
this.onApplyClick = this.onApplyClick.bind(this);
|
||||
@@ -55,6 +58,19 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
await shared.checkSyncConfig(this, this.state.settings);
|
||||
}
|
||||
|
||||
// async checkNextcloudAppButton_click() {
|
||||
// this.setState({ showNextcloudAppLog: true });
|
||||
// await shared.checkNextcloudApp(this, this.state.settings);
|
||||
// }
|
||||
|
||||
showLogButton_click() {
|
||||
this.setState({ showNextcloudAppLog: true });
|
||||
}
|
||||
|
||||
nextcloudAppHelpLink_click() {
|
||||
bridge().openExternal('https://joplinapp.org/nextcloud_app');
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
this.setState({ settings: this.props.settings });
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import PluginBox, { InstallState } from './PluginBox';
|
||||
import PluginService, { PluginSettings } from '@joplin/lib/services/plugins/PluginService';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import useOnInstallHandler from './useOnInstallHandler';
|
||||
import { themeStyle } from '@joplin/lib/theme';
|
||||
|
||||
const Root = styled.div`
|
||||
`;
|
||||
@@ -101,13 +100,6 @@ export default function(props: Props) {
|
||||
}
|
||||
}
|
||||
|
||||
const renderContentSourceInfo = () => {
|
||||
if (props.repoApi().isUsingDefaultContentUrl) return null;
|
||||
const theme = themeStyle(props.themeId);
|
||||
const url = new URL(props.repoApi().contentBaseUrl);
|
||||
return <div style={{ ...theme.textStyleMinor, marginTop: 5, fontSize: theme.fontSize }}>{_('Content provided by %s', url.hostname)}</div>;
|
||||
};
|
||||
|
||||
return (
|
||||
<Root>
|
||||
<div style={{ marginBottom: 10, width: props.maxWidth }}>
|
||||
@@ -120,7 +112,6 @@ export default function(props: Props) {
|
||||
placeholder={props.disabled ? _('Please wait...') : _('Search for plugins...')}
|
||||
disabled={props.disabled}
|
||||
/>
|
||||
{renderContentSourceInfo()}
|
||||
</div>
|
||||
|
||||
<ResultsRoot>
|
||||
|
||||
@@ -4,7 +4,7 @@ const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const { themeStyle } = require('@joplin/lib/theme');
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { filename, basename } = require('@joplin/lib/path-utils');
|
||||
const importEnex = require('@joplin/lib/import-enex').default;
|
||||
const { importEnex } = require('@joplin/lib/import-enex');
|
||||
|
||||
class ImportScreenComponent extends React.Component {
|
||||
UNSAFE_componentWillMount() {
|
||||
|
||||
@@ -75,7 +75,6 @@ interface Props {
|
||||
shareInvitations: ShareInvitation[];
|
||||
isSafeMode: boolean;
|
||||
needApiAuth: boolean;
|
||||
processingShareInvitationResponse: boolean;
|
||||
}
|
||||
|
||||
interface ShareFolderDialogOptions {
|
||||
@@ -198,7 +197,6 @@ class MainScreenComponent extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
private showShareInvitationNotification(props: Props): boolean {
|
||||
if (props.processingShareInvitationResponse) return false;
|
||||
return !!props.shareInvitations.find(i => i.status === 0);
|
||||
}
|
||||
|
||||
@@ -548,16 +546,8 @@ class MainScreenComponent extends React.Component<Props, State> {
|
||||
};
|
||||
|
||||
const onInvitationRespond = async (shareUserId: string, accept: boolean) => {
|
||||
// The below functions can take a bit of time to complete so in the
|
||||
// meantime we hide the notification so that the user doesn't click
|
||||
// multiple times on the Accept link.
|
||||
ShareService.instance().setProcessingShareInvitationResponse(true);
|
||||
try {
|
||||
await ShareService.instance().respondInvitation(shareUserId, accept);
|
||||
await ShareService.instance().refreshShareInvitations();
|
||||
} finally {
|
||||
ShareService.instance().setProcessingShareInvitationResponse(false);
|
||||
}
|
||||
await ShareService.instance().respondInvitation(shareUserId, accept);
|
||||
await ShareService.instance().refreshShareInvitations();
|
||||
void reg.scheduleSync(1000);
|
||||
};
|
||||
|
||||
@@ -863,7 +853,6 @@ const mapStateToProps = (state: AppState) => {
|
||||
mainLayout: state.mainLayout,
|
||||
startupPluginsLoaded: state.startupPluginsLoaded,
|
||||
shareInvitations: state.shareService.shareInvitations,
|
||||
processingShareInvitationResponse: state.shareService.processingShareInvitationResponse,
|
||||
isSafeMode: state.settings.isSafeMode,
|
||||
needApiAuth: state.needApiAuth,
|
||||
showInstallTemplatesPlugin: state.hasLegacyTemplates && !state.pluginService.plugins['joplin.plugin.templates'],
|
||||
|
||||
@@ -19,11 +19,6 @@ export const runtime = (): CommandRuntime => {
|
||||
visible: !layoutItemProp(layout, 'noteList', 'visible'),
|
||||
});
|
||||
|
||||
// Toggling the sidebar will affect the size of most other on-screen components.
|
||||
// Dispatching a window resize event is a bit of a hack, but it ensures that any
|
||||
// component that watches for resizes will be accurately notified
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
|
||||
context.dispatch({
|
||||
type: 'MAIN_LAYOUT_SET',
|
||||
value: newLayout,
|
||||
|
||||
@@ -19,11 +19,6 @@ export const runtime = (): CommandRuntime => {
|
||||
visible: !layoutItemProp(layout, 'sideBar', 'visible'),
|
||||
});
|
||||
|
||||
// Toggling the sidebar will affect the size of most other on-screen components.
|
||||
// Dispatching a window resize event is a bit of a hack, but it ensures that any
|
||||
// component that watches for resizes will be accurately notified
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
|
||||
context.dispatch({
|
||||
type: 'MAIN_LAYOUT_SET',
|
||||
value: newLayout,
|
||||
|
||||
@@ -6,8 +6,7 @@ import { EditorCommand, NoteBodyEditorProps } from '../../utils/types';
|
||||
import { commandAttachFileToBody, handlePasteEvent } from '../../utils/resourceHandling';
|
||||
import { ScrollOptions, ScrollOptionTypes } from '../../utils/types';
|
||||
import { CommandValue } from '../../utils/types';
|
||||
import { useScrollHandler, usePrevious, cursorPositionToTextOffset } from './utils';
|
||||
import useElementSize from '@joplin/lib/hooks/useElementSize';
|
||||
import { useScrollHandler, usePrevious, cursorPositionToTextOffset, useRootSize } from './utils';
|
||||
import Toolbar from './Toolbar';
|
||||
import styles_ from './styles';
|
||||
import { RenderedBody, defaultRenderedBody } from './utils/types';
|
||||
@@ -60,7 +59,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
const props_onChangeRef = useRef<Function>(null);
|
||||
props_onChangeRef.current = props.onChange;
|
||||
|
||||
const rootSize = useElementSize(rootRef);
|
||||
const rootSize = useRootSize({ rootRef });
|
||||
|
||||
usePluginServiceRegistration(ref);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useCallback, useRef } from 'react';
|
||||
import { useEffect, useCallback, useRef, useState } from 'react';
|
||||
import shim from '@joplin/lib/shim';
|
||||
|
||||
export function cursorPositionToTextOffset(cursorPos: any, body: string) {
|
||||
@@ -89,3 +89,21 @@ export function useScrollHandler(editorRef: any, webviewRef: any, onScroll: Func
|
||||
return { resetScroll, setEditorPercentScroll, setViewerPercentScroll, editor_scroll };
|
||||
}
|
||||
|
||||
|
||||
export function useRootSize(dependencies: any) {
|
||||
const { rootRef } = dependencies;
|
||||
|
||||
const [rootSize, setRootSize] = useState({ width: 0, height: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
if (!rootRef.current) return;
|
||||
|
||||
const { width, height } = rootRef.current.getBoundingClientRect();
|
||||
|
||||
if (rootSize.width !== width || rootSize.height !== height) {
|
||||
setRootSize({ width: width, height: height });
|
||||
}
|
||||
});
|
||||
|
||||
return rootSize;
|
||||
}
|
||||
|
||||
@@ -171,7 +171,6 @@ export default function useKeymap(CodeMirror: any) {
|
||||
'Cmd-Right': 'goLineRightSmart',
|
||||
'Alt-Backspace': 'delGroupBefore',
|
||||
'Alt-Delete': 'delGroupAfter',
|
||||
'Cmd-Backspace': 'delWrappedLineLeft',
|
||||
|
||||
'fallthrough': 'basic',
|
||||
};
|
||||
|
||||
@@ -793,7 +793,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
|
||||
};
|
||||
}
|
||||
|
||||
await loadDocumentAssets(editor, await props.allAssets(props.contentMarkupLanguage, { contentMaxWidthTarget: '.mce-content-body' }));
|
||||
await loadDocumentAssets(editor, await props.allAssets(props.contentMarkupLanguage));
|
||||
|
||||
dispatchDidUpdate(editor);
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ import useMarkupToHtml from './utils/useMarkupToHtml';
|
||||
import useFormNote, { OnLoadEvent } from './utils/useFormNote';
|
||||
import useFolder from './utils/useFolder';
|
||||
import styles_ from './styles';
|
||||
import { NoteEditorProps, FormNote, ScrollOptions, ScrollOptionTypes, OnChangeEvent, NoteBodyEditorProps, AllAssetsOptions } from './utils/types';
|
||||
import { NoteEditorProps, FormNote, ScrollOptions, ScrollOptionTypes, OnChangeEvent, NoteBodyEditorProps } from './utils/types';
|
||||
import ResourceEditWatcher from '@joplin/lib/services/ResourceEditWatcher/index';
|
||||
import CommandService from '@joplin/lib/services/CommandService';
|
||||
import ToolbarButton from '../ToolbarButton/ToolbarButton';
|
||||
@@ -151,12 +151,7 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
plugins: props.plugins,
|
||||
});
|
||||
|
||||
const allAssets = useCallback(async (markupLanguage: number, options: AllAssetsOptions = null): Promise<any[]> => {
|
||||
options = {
|
||||
contentMaxWidthTarget: '',
|
||||
...options,
|
||||
};
|
||||
|
||||
const allAssets = useCallback(async (markupLanguage: number): Promise<any[]> => {
|
||||
const theme = themeStyle(props.themeId);
|
||||
|
||||
const markupToHtml = markupLanguageUtils.newMarkupToHtml({}, {
|
||||
@@ -164,10 +159,7 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
customCss: props.customCss,
|
||||
});
|
||||
|
||||
return markupToHtml.allAssets(markupLanguage, theme, {
|
||||
contentMaxWidth: props.contentMaxWidth,
|
||||
contentMaxWidthTarget: options.contentMaxWidthTarget,
|
||||
});
|
||||
return markupToHtml.allAssets(markupLanguage, theme, { contentMaxWidth: props.contentMaxWidth });
|
||||
}, [props.themeId, props.customCss, props.contentMaxWidth]);
|
||||
|
||||
const handleProvisionalFlag = useCallback(() => {
|
||||
|
||||
@@ -69,17 +69,8 @@ export function htmlToClipboardData(html: string): ClipboardData {
|
||||
// In that case we need to set both HTML and Text context, otherwise it
|
||||
// won't be possible to paste the text in, for example, a text editor.
|
||||
// https://github.com/laurent22/joplin/issues/4788
|
||||
//
|
||||
// Also we don't escape the content produced in HTML to MD conversion
|
||||
// because it's not what would be expected. For example, if the content is
|
||||
// `* something`, strictly speaking it would be correct to escape to `\*
|
||||
// something`, however this is not what the user would expect when copying
|
||||
// text. Likewise for URLs that contain "_". So the resulting Markdown might
|
||||
// not be perfectly valid but would be closer to what a user would expect.
|
||||
// If they want accurate MArkdown they can switch to the MD editor.
|
||||
// https://github.com/laurent22/joplin/issues/5440
|
||||
return {
|
||||
text: htmlToMd().parse(copyableContent, { disableEscapeContent: true }),
|
||||
text: htmlToMd().parse(copyableContent),
|
||||
html: cleanUpCodeBlocks(copyableContent),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,10 +6,6 @@ import { MarkupLanguage } from '@joplin/renderer';
|
||||
import { RenderResult, RenderResultPluginAsset } from '@joplin/renderer/MarkupToHtml';
|
||||
import { MarkupToHtmlOptions } from './useMarkupToHtml';
|
||||
|
||||
export interface AllAssetsOptions {
|
||||
contentMaxWidthTarget?: string;
|
||||
}
|
||||
|
||||
export interface ToolbarButtonInfos {
|
||||
[key: string]: ToolbarButtonInfo;
|
||||
}
|
||||
@@ -59,7 +55,7 @@ export interface NoteBodyEditorProps {
|
||||
onScroll(event: any): void;
|
||||
markupToHtml: (markupLanguage: MarkupLanguage, markup: string, options: MarkupToHtmlOptions)=> Promise<RenderResult>;
|
||||
htmlToMarkdown: Function;
|
||||
allAssets: (markupLanguage: MarkupLanguage, options: AllAssetsOptions)=> Promise<RenderResultPluginAsset[]>;
|
||||
allAssets: (markupLanguage: MarkupLanguage)=> Promise<RenderResultPluginAsset[]>;
|
||||
disabled: boolean;
|
||||
dispatch: Function;
|
||||
noteToolbar: any;
|
||||
|
||||
@@ -139,10 +139,9 @@ class NoteSearchBarComponent extends React.Component {
|
||||
color: theme.colorFaded,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
});
|
||||
|
||||
const matchesFoundString = (query.length > 0) ? (
|
||||
const matchesFoundString = (query.length > 0 && this.props.resultCount > 0) ? (
|
||||
<div style={textStyle}>
|
||||
{`${this.props.resultCount === 0 ? 0 : this.props.selectedIndex + 1} / ${this.props.resultCount}`}
|
||||
{`${this.props.selectedIndex + 1} / ${this.props.resultCount}`}
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
|
||||
@@ -138,9 +138,9 @@ const syncTargetNames: string[] = [
|
||||
|
||||
|
||||
const logosImageNames: Record<string, string> = {
|
||||
'dropbox': 'SyncTarget_Dropbox.svg',
|
||||
'joplinCloud': 'SyncTarget_JoplinCloud.svg',
|
||||
'onedrive': 'SyncTarget_OneDrive.svg',
|
||||
'dropbox': 'Dropbox.svg',
|
||||
'joplinCloud': 'JoplinCloud.svg',
|
||||
'onedrive': 'OneDrive.svg',
|
||||
};
|
||||
|
||||
export default function(props: Props) {
|
||||
@@ -274,7 +274,7 @@ export default function(props: Props) {
|
||||
const height = info.name !== 'joplinCloud' ? descriptionHeight : null;
|
||||
|
||||
const logoImageName = logosImageNames[info.name];
|
||||
const logoImageSrc = logoImageName ? `${bridge().buildDir()}/images/${logoImageName}` : '';
|
||||
const logoImageSrc = logoImageName ? `${bridge().buildDir()}/images/syncTargetLogos/${logoImageName}` : '';
|
||||
const logo = logoImageSrc ? <SyncTargetLogo src={logoImageSrc}/> : null;
|
||||
const descriptionComp = <SyncTargetDescription height={height} ref={info.name === 'joplinCloud' ? joplinCloudDescriptionRef : null}>{info.description}</SyncTargetDescription>;
|
||||
const featuresComp = showJoplinCloudForm && info.name === 'joplinCloud' ? null : renderFeatures(info.name);
|
||||
|
||||
4
packages/app-desktop/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.4.12",
|
||||
"version": "2.4.6",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.4.12",
|
||||
"version": "2.4.6",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.13.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.4.12",
|
||||
"version": "2.4.6",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
@@ -37,7 +37,7 @@
|
||||
"asar": true,
|
||||
"asarUnpack": "./node_modules/node-notifier/vendor/**",
|
||||
"win": {
|
||||
"rfc3161TimeStampServer": "http://sha256timestamp.ws.symantec.com/sha256/timestamp",
|
||||
"rfc3161TimeStampServer": "http://timestamp.comodoca.com/rfc3161",
|
||||
"icon": "../../Assets/ImageSources/Joplin.ico",
|
||||
"target": [
|
||||
{
|
||||
|
||||
@@ -141,8 +141,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097651
|
||||
versionName "2.4.3"
|
||||
versionCode 2097649
|
||||
versionName "2.4.1"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
|
||||
@@ -486,13 +486,13 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 76;
|
||||
CURRENT_PROJECT_VERSION = 72;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 12.5.2;
|
||||
MARKETING_VERSION = 12.4.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -514,12 +514,12 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 76;
|
||||
CURRENT_PROJECT_VERSION = 72;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 12.5.2;
|
||||
MARKETING_VERSION = 12.4.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -659,14 +659,14 @@
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 76;
|
||||
CURRENT_PROJECT_VERSION = 72;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 12.5.2;
|
||||
MARKETING_VERSION = 12.4.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
@@ -690,14 +690,14 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 76;
|
||||
CURRENT_PROJECT_VERSION = 72;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 12.5.2;
|
||||
MARKETING_VERSION = 12.4.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
@@ -488,7 +488,7 @@ SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de
|
||||
FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b
|
||||
FBReactNativeSpec: 6da2c8ff1ebe6b6cf4510fcca58c24c4d02b16fc
|
||||
FBReactNativeSpec: d2f54de51f69366bd1f5c1fb9270698dce678f8d
|
||||
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
|
||||
JoplinCommonShareExtension: 270b4f8eb4e22828eeda433a04ed689fc1fd09b5
|
||||
JoplinRNShareExtension: 7137e9787374e1b0797ecbef9103d1588d90e403
|
||||
|
||||
@@ -498,7 +498,6 @@ async function initialize(dispatch: Function) {
|
||||
let locale = NativeModules.I18nManager.localeIdentifier;
|
||||
if (!locale) locale = defaultLocale();
|
||||
Setting.setValue('locale', closestSupportedLocale(locale));
|
||||
Setting.setValue('sync.target', 0);
|
||||
Setting.setValue('firstStart', 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ dialogs.confirm = (parentComponent, message) => {
|
||||
if (!parentComponent) throw new Error('parentComponent is required');
|
||||
if (!('dialogbox' in parentComponent)) throw new Error('A "dialogbox" component must be defined on the parent component!');
|
||||
|
||||
return dialogs.confirmRef(parentComponent.dialogbox, message);
|
||||
return dialogs.confirmRef(parentComponent.dialogBox, message);
|
||||
};
|
||||
|
||||
dialogs.pop = (parentComponent, message, buttons, options = null) => {
|
||||
|
||||
2
packages/fork-htmlparser2/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/fork-htmlparser2",
|
||||
"version": "4.1.36",
|
||||
"version": "4.1.34",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@joplin/fork-htmlparser2",
|
||||
"description": "Fast & forgiving HTML/XML/RSS parser",
|
||||
"version": "4.1.36",
|
||||
"version": "4.1.34",
|
||||
"author": "Felix Boehm <me@feedic.com>",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -65,5 +65,5 @@
|
||||
"prettier": {
|
||||
"tabWidth": 4
|
||||
},
|
||||
"gitHead": "eb4b0e64eab40a51b0895d3a40a9d8c3cb7b1b14"
|
||||
"gitHead": "80c0089d2c52aff608b2bea74389de5a7f12f2e2"
|
||||
}
|
||||
|
||||
2
packages/fork-sax/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/fork-sax",
|
||||
"version": "1.2.40",
|
||||
"version": "1.2.38",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@joplin/fork-sax",
|
||||
"description": "An evented streaming XML parser in JavaScript",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
||||
"version": "1.2.40",
|
||||
"version": "1.2.38",
|
||||
"main": "lib/sax.js",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -18,5 +18,5 @@
|
||||
"standard": "^8.6.0",
|
||||
"tap": "^10.5.1"
|
||||
},
|
||||
"gitHead": "eb4b0e64eab40a51b0895d3a40a9d8c3cb7b1b14"
|
||||
"gitHead": "80c0089d2c52aff608b2bea74389de5a7f12f2e2"
|
||||
}
|
||||
|
||||
1
packages/htmlpack/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
dist/*
|
||||
@@ -1,19 +0,0 @@
|
||||
# HTMLPACK
|
||||
|
||||
Pack an HTML and all its JavaScript, CSS, image, fonts, and external files into a single HTML file. JavaScript and CSS is embedded in STYLE and SCRIPT tags, while all other files and images are converted to dataUri format and embedded in the document.
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
import htmlpack from '@joplin/htmlpack';
|
||||
htmlpack('/path/to/input.html', '/path/to/output.html');
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The script works in synchronous way so it will block the calling process while running.
|
||||
- No security check on what's included.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
489
packages/htmlpack/package-lock.json
generated
@@ -1,489 +0,0 @@
|
||||
{
|
||||
"name": "@joplin/htmlpack",
|
||||
"version": "1.0.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@joplin/htmlpack",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@joplin/fork-htmlparser2": "^4.1.34",
|
||||
"css": "^3.0.0",
|
||||
"datauri": "^4.1.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"html-entities": "^1.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^9.0.6"
|
||||
}
|
||||
},
|
||||
"../fork-htmlparser2": {
|
||||
"name": "@joplin/fork-htmlparser2",
|
||||
"version": "4.1.34",
|
||||
"extraneous": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0",
|
||||
"domutils": "^2.0.0",
|
||||
"entities": "^2.0.0",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^25.1.3",
|
||||
"@types/node": "^13.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^1.13.0",
|
||||
"@typescript-eslint/parser": "^1.13.0",
|
||||
"coveralls": "^3.0.1",
|
||||
"eslint": "^6.0.0",
|
||||
"eslint-config-prettier": "^6.0.0",
|
||||
"jest": "^26.6.3",
|
||||
"prettier": "^1.18.2",
|
||||
"ts-jest": "^24.0.2",
|
||||
"typescript": "^3.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@joplin/fork-htmlparser2": {
|
||||
"version": "4.1.34",
|
||||
"resolved": "https://registry.npmjs.org/@joplin/fork-htmlparser2/-/fork-htmlparser2-4.1.34.tgz",
|
||||
"integrity": "sha512-1/tQZEDnI36RaEJte0eumw1/c8OhmJOpgFyW+Nxsk2u/vvcgnEvjFjauiH2ZxtO5FTJB3BMQ4M23+Y5dw2cnnw==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0",
|
||||
"domutils": "^2.0.0",
|
||||
"entities": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/fs-extra": {
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
||||
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.1.tgz",
|
||||
"integrity": "sha512-4/Z9DMPKFexZj/Gn3LylFgamNKHm4K3QDi0gz9B26Uk0c8izYf97B5fxfpspMNkWlFupblKM/nV8+NA9Ffvr+w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/atob": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||
"bin": {
|
||||
"atob": "bin/atob.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/css": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
|
||||
"integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.4",
|
||||
"source-map": "^0.6.1",
|
||||
"source-map-resolve": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/datauri": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/datauri/-/datauri-4.1.0.tgz",
|
||||
"integrity": "sha512-y17kh32+I82G+ED9MNWFkZiP/Cq/vO1hN9+tSZsT9C9qn3NrvcBnh7crSepg0AQPge1hXx2Ca44s1FRdv0gFWA==",
|
||||
"dependencies": {
|
||||
"image-size": "1.0.0",
|
||||
"mimer": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
||||
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.2.0",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer/node_modules/domhandler": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz",
|
||||
"integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domelementtype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
|
||||
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/domhandler": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz",
|
||||
"integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
|
||||
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
|
||||
"dependencies": {
|
||||
"dom-serializer": "^1.0.1",
|
||||
"domelementtype": "^2.2.0",
|
||||
"domhandler": "^4.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domutils/node_modules/domhandler": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz",
|
||||
"integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
|
||||
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
|
||||
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
|
||||
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
|
||||
},
|
||||
"node_modules/html-entities": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz",
|
||||
"integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA=="
|
||||
},
|
||||
"node_modules/image-size": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz",
|
||||
"integrity": "sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw==",
|
||||
"dependencies": {
|
||||
"queue": "6.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"image-size": "bin/image-size.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimer": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mimer/-/mimer-2.0.2.tgz",
|
||||
"integrity": "sha512-izxvjsB7Ur5HrTbPu6VKTrzxSMBFBqyZQc6dWlZNQ4/wAvf886fD4lrjtFd8IQ8/WmZKdxKjUtqFFNaj3hQ52g==",
|
||||
"bin": {
|
||||
"mimer": "bin/mimer"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/queue": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
||||
"integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
|
||||
"dependencies": {
|
||||
"inherits": "~2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-resolve": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
|
||||
"integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
|
||||
"dependencies": {
|
||||
"atob": "^2.1.2",
|
||||
"decode-uri-component": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@joplin/fork-htmlparser2": {
|
||||
"version": "4.1.34",
|
||||
"resolved": "https://registry.npmjs.org/@joplin/fork-htmlparser2/-/fork-htmlparser2-4.1.34.tgz",
|
||||
"integrity": "sha512-1/tQZEDnI36RaEJte0eumw1/c8OhmJOpgFyW+Nxsk2u/vvcgnEvjFjauiH2ZxtO5FTJB3BMQ4M23+Y5dw2cnnw==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0",
|
||||
"domutils": "^2.0.0",
|
||||
"entities": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@types/fs-extra": {
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
||||
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.1.tgz",
|
||||
"integrity": "sha512-4/Z9DMPKFexZj/Gn3LylFgamNKHm4K3QDi0gz9B26Uk0c8izYf97B5fxfpspMNkWlFupblKM/nV8+NA9Ffvr+w==",
|
||||
"dev": true
|
||||
},
|
||||
"atob": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
||||
},
|
||||
"css": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
|
||||
"integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.4",
|
||||
"source-map": "^0.6.1",
|
||||
"source-map-resolve": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"datauri": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/datauri/-/datauri-4.1.0.tgz",
|
||||
"integrity": "sha512-y17kh32+I82G+ED9MNWFkZiP/Cq/vO1hN9+tSZsT9C9qn3NrvcBnh7crSepg0AQPge1hXx2Ca44s1FRdv0gFWA==",
|
||||
"requires": {
|
||||
"image-size": "1.0.0",
|
||||
"mimer": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
|
||||
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.2.0",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domhandler": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz",
|
||||
"integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
|
||||
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz",
|
||||
"integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
|
||||
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
|
||||
"requires": {
|
||||
"dom-serializer": "^1.0.1",
|
||||
"domelementtype": "^2.2.0",
|
||||
"domhandler": "^4.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domhandler": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz",
|
||||
"integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
|
||||
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
|
||||
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
|
||||
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
|
||||
},
|
||||
"html-entities": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz",
|
||||
"integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA=="
|
||||
},
|
||||
"image-size": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz",
|
||||
"integrity": "sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw==",
|
||||
"requires": {
|
||||
"queue": "6.0.2"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"mimer": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mimer/-/mimer-2.0.2.tgz",
|
||||
"integrity": "sha512-izxvjsB7Ur5HrTbPu6VKTrzxSMBFBqyZQc6dWlZNQ4/wAvf886fD4lrjtFd8IQ8/WmZKdxKjUtqFFNaj3hQ52g=="
|
||||
},
|
||||
"queue": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
||||
"integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
|
||||
"requires": {
|
||||
"inherits": "~2.0.3"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"source-map-resolve": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
|
||||
"integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
|
||||
"requires": {
|
||||
"atob": "^2.1.2",
|
||||
"decode-uri-component": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "@joplin/htmlpack",
|
||||
"version": "1.0.1",
|
||||
"description": "Pack an HTML file and all its linked resources into a single HTML file",
|
||||
"main": "dist/index.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"tsc": "tsc --project tsconfig.json",
|
||||
"watch": "tsc --watch --project tsconfig.json"
|
||||
},
|
||||
"author": "Laurent Czoic",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@joplin/fork-htmlparser2": "^4.1.35",
|
||||
"css": "^3.0.0",
|
||||
"datauri": "^4.1.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"html-entities": "^1.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^9.0.6"
|
||||
},
|
||||
"gitHead": "eb4b0e64eab40a51b0895d3a40a9d8c3cb7b1b14"
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
import * as fs from 'fs-extra';
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlparser2 = require('@joplin/fork-htmlparser2');
|
||||
const Datauri = require('datauri/sync');
|
||||
const cssParse = require('css/lib/parse');
|
||||
const cssStringify = require('css/lib/stringify');
|
||||
|
||||
const selfClosingElements = [
|
||||
'area',
|
||||
'base',
|
||||
'basefont',
|
||||
'br',
|
||||
'col',
|
||||
'command',
|
||||
'embed',
|
||||
'frame',
|
||||
'hr',
|
||||
'img',
|
||||
'input',
|
||||
'isindex',
|
||||
'keygen',
|
||||
'link',
|
||||
'meta',
|
||||
'param',
|
||||
'source',
|
||||
'track',
|
||||
'wbr',
|
||||
];
|
||||
|
||||
const htmlentities = (s: string): string => {
|
||||
const output = (new Entities()).encode(s);
|
||||
return output.replace(/	/ig, '\t');
|
||||
};
|
||||
|
||||
const dataUriEncode = (filePath: string): string => {
|
||||
const result = Datauri(filePath);
|
||||
return result.content;
|
||||
};
|
||||
|
||||
const attributesHtml = (attr: any) => {
|
||||
const output = [];
|
||||
|
||||
for (const n in attr) {
|
||||
if (!attr.hasOwnProperty(n)) continue;
|
||||
output.push(`${n}="${htmlentities(attr[n])}"`);
|
||||
}
|
||||
|
||||
return output.join(' ');
|
||||
};
|
||||
|
||||
const attrValue = (attrs: any, name: string): string => {
|
||||
if (!attrs[name]) return '';
|
||||
return attrs[name].toLowerCase();
|
||||
};
|
||||
|
||||
const isSelfClosingTag = (tagName: string) => {
|
||||
return selfClosingElements.includes(tagName.toLowerCase());
|
||||
};
|
||||
|
||||
const processCssContent = (cssBaseDir: string, content: string): string => {
|
||||
const o = cssParse(content, {
|
||||
silent: false,
|
||||
});
|
||||
|
||||
for (const rule of o.stylesheet.rules) {
|
||||
if (rule.type === 'font-face') {
|
||||
for (const declaration of rule.declarations) {
|
||||
if (declaration.property === 'src') {
|
||||
declaration.value = declaration.value.replace(/url\((.*?)\)/g, (_v: any, url: string) => {
|
||||
const cssFilePath = `${cssBaseDir}/${url}`;
|
||||
if (fs.existsSync(cssFilePath)) {
|
||||
return `url(${dataUriEncode(cssFilePath)})`;
|
||||
} else {
|
||||
return `url(${url})`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cssStringify(o);
|
||||
};
|
||||
|
||||
const processLinkTag = (baseDir: string, _name: string, attrs: any): string => {
|
||||
const href = attrValue(attrs, 'href');
|
||||
if (!href) return null;
|
||||
|
||||
const filePath = `${baseDir}/${href}`;
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
return `<style>${processCssContent(dirname(filePath), content)}</style>`;
|
||||
};
|
||||
|
||||
const processScriptTag = (baseDir: string, _name: string, attrs: any): string => {
|
||||
const src = attrValue(attrs, 'src');
|
||||
if (!src) return null;
|
||||
|
||||
const content = fs.readFileSync(`${baseDir}/${src}`, 'utf8');
|
||||
return `<script>${htmlentities(content)}</script>`;
|
||||
};
|
||||
|
||||
const processImgTag = (baseDir: string, _name: string, attrs: any): string => {
|
||||
const src = attrValue(attrs, 'src');
|
||||
if (!src) return null;
|
||||
|
||||
const filePath = `${baseDir}/${src}`;
|
||||
if (!fs.existsSync(filePath)) return null;
|
||||
|
||||
const modAttrs = { ...attrs };
|
||||
delete modAttrs.src;
|
||||
return `<img src="${dataUriEncode(filePath)}" ${attributesHtml(modAttrs)}/>`;
|
||||
};
|
||||
|
||||
const processAnchorTag = (baseDir: string, _name: string, attrs: any): string => {
|
||||
const href = attrValue(attrs, 'href');
|
||||
if (!href) return null;
|
||||
|
||||
const filePath = `${baseDir}/${href}`;
|
||||
if (!fs.existsSync(filePath)) return null;
|
||||
|
||||
const modAttrs = { ...attrs };
|
||||
modAttrs.href = dataUriEncode(filePath);
|
||||
modAttrs.download = basename(filePath);
|
||||
return `<a ${attributesHtml(modAttrs)}>`;
|
||||
};
|
||||
|
||||
function basename(path: string) {
|
||||
if (!path) throw new Error('Path is empty');
|
||||
const s = path.split(/\/|\\/);
|
||||
return s[s.length - 1];
|
||||
}
|
||||
|
||||
function dirname(path: string) {
|
||||
if (!path) throw new Error('Path is empty');
|
||||
const s = path.split(/\/|\\/);
|
||||
s.pop();
|
||||
return s.join('/');
|
||||
}
|
||||
|
||||
export default async function htmlpack(inputFile: string, outputFile: string) {
|
||||
const inputHtml = await fs.readFile(inputFile, 'utf8');
|
||||
const baseDir = dirname(inputFile);
|
||||
|
||||
const output: string[] = [];
|
||||
|
||||
interface Tag {
|
||||
name: string;
|
||||
}
|
||||
|
||||
const tagStack: Tag[] = [];
|
||||
|
||||
const currentTag = () => {
|
||||
if (!tagStack.length) return { name: '', processed: false };
|
||||
return tagStack[tagStack.length - 1];
|
||||
};
|
||||
|
||||
const parser = new htmlparser2.Parser({
|
||||
|
||||
onopentag: (name: string, attrs: any) => {
|
||||
name = name.toLowerCase();
|
||||
|
||||
let processedResult = '';
|
||||
|
||||
if (name === 'link') {
|
||||
processedResult = processLinkTag(baseDir, name, attrs);
|
||||
}
|
||||
|
||||
if (name === 'script') {
|
||||
processedResult = processScriptTag(baseDir, name, attrs);
|
||||
}
|
||||
|
||||
if (name === 'img') {
|
||||
processedResult = processImgTag(baseDir, name, attrs);
|
||||
}
|
||||
|
||||
if (name === 'a') {
|
||||
processedResult = processAnchorTag(baseDir, name, attrs);
|
||||
}
|
||||
|
||||
tagStack.push({ name });
|
||||
|
||||
if (processedResult) {
|
||||
output.push(processedResult);
|
||||
} else {
|
||||
let attrHtml = attributesHtml(attrs);
|
||||
if (attrHtml) attrHtml = ` ${attrHtml}`;
|
||||
const closingSign = isSelfClosingTag(name) ? '/>' : '>';
|
||||
output.push(`<${name}${attrHtml}${closingSign}`);
|
||||
}
|
||||
},
|
||||
|
||||
ontext: (decodedText: string) => {
|
||||
if (currentTag().name === 'style') {
|
||||
// For CSS, we have to put the style as-is inside the tag because if we html-entities encode
|
||||
// it, it's not going to work. But it's ok because JavaScript won't run within the style tag.
|
||||
// Ideally CSS should be loaded from an external file.
|
||||
output.push(decodedText);
|
||||
} else {
|
||||
output.push(htmlentities(decodedText));
|
||||
}
|
||||
},
|
||||
|
||||
onclosetag: (name: string) => {
|
||||
const current = currentTag();
|
||||
|
||||
if (current.name === name.toLowerCase()) tagStack.pop();
|
||||
|
||||
if (isSelfClosingTag(name)) return;
|
||||
output.push(`</${name}>`);
|
||||
},
|
||||
|
||||
}, { decodeEntities: true });
|
||||
|
||||
parser.write(inputHtml);
|
||||
parser.end();
|
||||
|
||||
await fs.writeFile(outputFile, output.join(''), 'utf8');
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist"
|
||||
},
|
||||
"rootDir": ".",
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules",
|
||||
],
|
||||
}
|
||||
@@ -251,12 +251,6 @@ export default class BaseApplication {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--user-data-dir=') === 0) {
|
||||
// Electron-specific flag. Allows users to run the app with chromedriver.
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.length && arg[0] == '-') {
|
||||
throw new JoplinError(_('Unknown flag: %s', arg), 'flagError');
|
||||
} else {
|
||||
@@ -790,7 +784,6 @@ export default class BaseApplication {
|
||||
Setting.setValue('sync.interval', 3600);
|
||||
}
|
||||
|
||||
Setting.setValue('sync.target', 0);
|
||||
Setting.setValue('firstStart', 0);
|
||||
} else {
|
||||
setLocale(Setting.value('locale'));
|
||||
|
||||
@@ -6,7 +6,6 @@ export interface ParseOptions {
|
||||
anchorNames?: string[];
|
||||
preserveImageTagsWithSize?: boolean;
|
||||
baseUrl?: string;
|
||||
disableEscapeContent?: boolean;
|
||||
}
|
||||
|
||||
export default class HtmlToMd {
|
||||
@@ -21,7 +20,6 @@ export default class HtmlToMd {
|
||||
emDelimiter: '*',
|
||||
strongDelimiter: '**',
|
||||
br: '',
|
||||
disableEscapeContent: 'disableEscapeContent' in options ? options.disableEscapeContent : false,
|
||||
});
|
||||
turndown.use(turndownPluginGfm);
|
||||
turndown.remove('script');
|
||||
|
||||
@@ -479,31 +479,6 @@ export default class Synchronizer {
|
||||
void this.cancel();
|
||||
});
|
||||
|
||||
// ========================================================================
|
||||
// 2. DELETE_REMOTE
|
||||
// ------------------------------------------------------------------------
|
||||
// Delete the remote items that have been deleted locally.
|
||||
// ========================================================================
|
||||
|
||||
if (syncSteps.indexOf('delete_remote') >= 0) {
|
||||
const deletedItems = await BaseItem.deletedItems(syncTargetId);
|
||||
for (let i = 0; i < deletedItems.length; i++) {
|
||||
if (this.cancelling()) break;
|
||||
|
||||
const item = deletedItems[i];
|
||||
const path = BaseItem.systemPath(item.item_id);
|
||||
this.logSyncOperation('deleteRemote', null, { id: item.item_id }, 'local has been deleted');
|
||||
await this.apiCall('delete', path);
|
||||
|
||||
if (item.item_type === BaseModel.TYPE_RESOURCE) {
|
||||
const remoteContentPath = resourceRemotePath(item.item_id);
|
||||
await this.apiCall('delete', remoteContentPath);
|
||||
}
|
||||
|
||||
await BaseItem.remoteDeletedItem(syncTargetId, item.item_id);
|
||||
}
|
||||
} // DELETE_REMOTE STEP
|
||||
|
||||
// ========================================================================
|
||||
// 1. UPLOAD
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -788,6 +763,31 @@ export default class Synchronizer {
|
||||
}
|
||||
} // UPLOAD STEP
|
||||
|
||||
// ========================================================================
|
||||
// 2. DELETE_REMOTE
|
||||
// ------------------------------------------------------------------------
|
||||
// Delete the remote items that have been deleted locally.
|
||||
// ========================================================================
|
||||
|
||||
if (syncSteps.indexOf('delete_remote') >= 0) {
|
||||
const deletedItems = await BaseItem.deletedItems(syncTargetId);
|
||||
for (let i = 0; i < deletedItems.length; i++) {
|
||||
if (this.cancelling()) break;
|
||||
|
||||
const item = deletedItems[i];
|
||||
const path = BaseItem.systemPath(item.item_id);
|
||||
this.logSyncOperation('deleteRemote', null, { id: item.item_id }, 'local has been deleted');
|
||||
await this.apiCall('delete', path);
|
||||
|
||||
if (item.item_type === BaseModel.TYPE_RESOURCE) {
|
||||
const remoteContentPath = resourceRemotePath(item.item_id);
|
||||
await this.apiCall('delete', remoteContentPath);
|
||||
}
|
||||
|
||||
await BaseItem.remoteDeletedItem(syncTargetId, item.item_id);
|
||||
}
|
||||
} // DELETE_REMOTE STEP
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 3. DELTA
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -9,8 +9,10 @@ const shared = {};
|
||||
shared.init = function(comp) {
|
||||
if (!comp.state) comp.state = {};
|
||||
comp.state.checkSyncConfigResult = null;
|
||||
comp.state.checkNextcloudAppResult = null;
|
||||
comp.state.settings = {};
|
||||
comp.state.changedSettingKeys = [];
|
||||
comp.state.showNextcloudAppLog = false;
|
||||
comp.state.showAdvancedSettings = false;
|
||||
};
|
||||
|
||||
@@ -33,6 +35,7 @@ shared.checkSyncConfig = async function(comp, settings) {
|
||||
comp.setState({ checkSyncConfigResult: result });
|
||||
|
||||
if (result.ok) {
|
||||
// await shared.checkNextcloudApp(comp, settings);
|
||||
// Users often expect config to be auto-saved at this point, if the config check was successful
|
||||
shared.saveSettings(comp);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ const os = require('os');
|
||||
const { filename } = require('./path-utils');
|
||||
import { setupDatabaseAndSynchronizer, switchClient, expectNotThrow, supportDir } from './testing/test-utils';
|
||||
const { enexXmlToMd } = require('./import-enex-md-gen.js');
|
||||
import importEnex from './import-enex';
|
||||
const { importEnex } = require('./import-enex');
|
||||
import Note from './models/Note';
|
||||
import Tag from './models/Tag';
|
||||
import Resource from './models/Resource';
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
import uuid from './uuid';
|
||||
import BaseModel from './BaseModel';
|
||||
import Note from './models/Note';
|
||||
import Tag from './models/Tag';
|
||||
import Resource from './models/Resource';
|
||||
import Setting from './models/Setting';
|
||||
import time from './time';
|
||||
import shim from './shim';
|
||||
import { NoteEntity } from './services/database/types';
|
||||
import { enexXmlToMd } from './import-enex-md-gen';
|
||||
import { MarkupToHtml } from '@joplin/renderer';
|
||||
const uuid = require('./uuid').default;
|
||||
const moment = require('moment');
|
||||
const BaseModel = require('./BaseModel').default;
|
||||
const Note = require('./models/Note').default;
|
||||
const Tag = require('./models/Tag').default;
|
||||
const Resource = require('./models/Resource').default;
|
||||
const Setting = require('./models/Setting').default;
|
||||
const { MarkupToHtml } = require('@joplin/renderer');
|
||||
const { wrapError } = require('./errorUtils');
|
||||
const { enexXmlToMd } = require('./import-enex-md-gen.js');
|
||||
const { enexXmlToHtml } = require('./import-enex-html-gen.js');
|
||||
const time = require('./time').default;
|
||||
const Levenshtein = require('levenshtein');
|
||||
const md5 = require('md5');
|
||||
const { Base64Decode } = require('base64-stream');
|
||||
const md5File = require('md5-file');
|
||||
const shim = require('./shim').default;
|
||||
const { mime } = require('./mime-utils');
|
||||
|
||||
// const Promise = require('promise');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
function dateToTimestamp(s: string, defaultValue: number = null): number {
|
||||
function dateToTimestamp(s, defaultValue = null) {
|
||||
// Most dates seem to be in this format
|
||||
let m = moment(s, 'YYYYMMDDTHHmmssZ');
|
||||
|
||||
@@ -37,12 +36,12 @@ function dateToTimestamp(s: string, defaultValue: number = null): number {
|
||||
return m.toDate().getTime();
|
||||
}
|
||||
|
||||
function extractRecognitionObjId(recognitionXml: string) {
|
||||
function extractRecognitionObjId(recognitionXml) {
|
||||
const r = recognitionXml.match(/objID="(.*?)"/);
|
||||
return r && r.length >= 2 ? r[1] : null;
|
||||
}
|
||||
|
||||
async function decodeBase64File(sourceFilePath: string, destFilePath: string) {
|
||||
async function decodeBase64File(sourceFilePath, destFilePath) {
|
||||
// When something goes wrong with streams you can get an error "EBADF, Bad file descriptor"
|
||||
// with no strack trace to tell where the error happened.
|
||||
|
||||
@@ -74,17 +73,17 @@ async function decodeBase64File(sourceFilePath: string, destFilePath: string) {
|
||||
destStream.on('finish', () => {
|
||||
fs.fdatasyncSync(destFile);
|
||||
fs.closeSync(destFile);
|
||||
resolve(null);
|
||||
resolve();
|
||||
});
|
||||
|
||||
sourceStream.on('error', (error: any) => reject(error));
|
||||
destStream.on('error', (error: any) => reject(error));
|
||||
sourceStream.on('error', (error) => reject(error));
|
||||
destStream.on('error', (error) => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
async function md5FileAsync(filePath: string): Promise<string> {
|
||||
async function md5FileAsync(filePath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
md5File(filePath, (error: any, hash: string) => {
|
||||
md5File(filePath, (error, hash) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
@@ -95,24 +94,24 @@ async function md5FileAsync(filePath: string): Promise<string> {
|
||||
});
|
||||
}
|
||||
|
||||
function removeUndefinedProperties(note: NoteEntity) {
|
||||
const output: any = {};
|
||||
function removeUndefinedProperties(note) {
|
||||
const output = {};
|
||||
for (const n in note) {
|
||||
if (!note.hasOwnProperty(n)) continue;
|
||||
const v = (note as any)[n];
|
||||
const v = note[n];
|
||||
if (v === undefined || v === null) continue;
|
||||
output[n] = v;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
function levenshteinPercent(s1: string, s2: string) {
|
||||
function levenshteinPercent(s1, s2) {
|
||||
const l = new Levenshtein(s1, s2);
|
||||
if (!s1.length || !s2.length) return 1;
|
||||
return Math.abs(l.distance / s1.length);
|
||||
}
|
||||
|
||||
async function fuzzyMatch(note: ExtractedNote) {
|
||||
async function fuzzyMatch(note) {
|
||||
if (note.created_time < time.unixMs() - 1000 * 60 * 60 * 24 * 360) {
|
||||
const notes = await Note.modelSelectAll('SELECT * FROM notes WHERE is_conflict = 0 AND created_time = ? AND title = ?', [note.created_time, note.title]);
|
||||
return notes.length !== 1 ? null : notes[0];
|
||||
@@ -138,30 +137,9 @@ async function fuzzyMatch(note: ExtractedNote) {
|
||||
return null;
|
||||
}
|
||||
|
||||
interface ExtractedResource {
|
||||
hasData?: boolean;
|
||||
id?: string;
|
||||
size?: number;
|
||||
dataFilePath?: string;
|
||||
dataEncoding?: string;
|
||||
data?: string;
|
||||
filename?: string;
|
||||
sourceUrl?: string;
|
||||
mime?: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
interface ExtractedNote extends NoteEntity {
|
||||
resources?: ExtractedResource[];
|
||||
tags?: string[];
|
||||
title?: string;
|
||||
bodyXml?: string;
|
||||
// is_todo?: boolean;
|
||||
}
|
||||
|
||||
// At this point we have the resource has it's been parsed from the XML, but additional
|
||||
// processing needs to be done to get the final resource file, its size, MD5, etc.
|
||||
async function processNoteResource(resource: ExtractedResource) {
|
||||
async function processNoteResource(resource) {
|
||||
if (!resource.hasData) {
|
||||
// Some resources have no data, go figure, so we need a special case for this.
|
||||
resource.id = md5(Date.now() + Math.random());
|
||||
@@ -197,7 +175,7 @@ async function processNoteResource(resource: ExtractedResource) {
|
||||
return resource;
|
||||
}
|
||||
|
||||
async function saveNoteResources(note: ExtractedNote) {
|
||||
async function saveNoteResources(note) {
|
||||
let resourcesCreated = 0;
|
||||
for (let i = 0; i < note.resources.length; i++) {
|
||||
const resource = note.resources[i];
|
||||
@@ -220,7 +198,7 @@ async function saveNoteResources(note: ExtractedNote) {
|
||||
return resourcesCreated;
|
||||
}
|
||||
|
||||
async function saveNoteTags(note: ExtractedNote) {
|
||||
async function saveNoteTags(note) {
|
||||
let notesTagged = 0;
|
||||
for (let i = 0; i < note.tags.length; i++) {
|
||||
const tagTitle = note.tags[i];
|
||||
@@ -235,19 +213,12 @@ async function saveNoteTags(note: ExtractedNote) {
|
||||
return notesTagged;
|
||||
}
|
||||
|
||||
interface ImportOptions {
|
||||
fuzzyMatching?: boolean;
|
||||
onProgress?: Function;
|
||||
onError?: Function;
|
||||
outputFormat?: string;
|
||||
}
|
||||
|
||||
async function saveNoteToStorage(note: ExtractedNote, importOptions: ImportOptions) {
|
||||
async function saveNoteToStorage(note, importOptions) {
|
||||
importOptions = Object.assign({}, {
|
||||
fuzzyMatching: false,
|
||||
}, importOptions);
|
||||
|
||||
note = Note.filter(note as any);
|
||||
note = Note.filter(note);
|
||||
|
||||
const existingNote = importOptions.fuzzyMatching ? await fuzzyMatch(note) : null;
|
||||
|
||||
@@ -259,7 +230,7 @@ async function saveNoteToStorage(note: ExtractedNote, importOptions: ImportOptio
|
||||
notesTagged: 0,
|
||||
};
|
||||
|
||||
const resourcesCreated = await saveNoteResources(note);
|
||||
const resourcesCreated = await saveNoteResources(note, importOptions);
|
||||
result.resourcesCreated += resourcesCreated;
|
||||
|
||||
const notesTagged = await saveNoteTags(note);
|
||||
@@ -291,60 +262,16 @@ async function saveNoteToStorage(note: ExtractedNote, importOptions: ImportOptio
|
||||
return result;
|
||||
}
|
||||
|
||||
interface Node {
|
||||
name: string;
|
||||
attributes: Record<string, any>;
|
||||
}
|
||||
|
||||
interface NoteResourceRecognition {
|
||||
objID?: string;
|
||||
}
|
||||
|
||||
const preProcessFile = async (filePath: string): Promise<string> => {
|
||||
// Disabled pre-processing for now because it runs out of memory:
|
||||
// https://github.com/laurent22/joplin/issues/5543
|
||||
//
|
||||
// It could be fixed by not loading the whole file in memory, but there are
|
||||
// other issues because people import 1GB+ files so pre-processing
|
||||
// everything means creating a new copy of that file, and that has its own
|
||||
// problems.
|
||||
|
||||
return filePath;
|
||||
|
||||
// const content: string = await shim.fsDriver().readFile(filePath, 'utf8');
|
||||
|
||||
// // The note content in an ENEX file is wrapped in a CDATA block so it means
|
||||
// // that any "]]>" inside the note must be somehow escaped, or else the CDATA
|
||||
// // block would be closed at the wrong point.
|
||||
// //
|
||||
// // The problem is that Evernote appears to encode "]]>" as "]]<![CDATA[>]]>"
|
||||
// // instead of the more sensible "]]>", or perhaps they have nothing in
|
||||
// // place to properly escape data imported from their web clipper. In any
|
||||
// // case it results in invalid XML that Evernote cannot even import back.
|
||||
// //
|
||||
// // Handling that invalid XML with SAX would also be very tricky, so instead
|
||||
// // we add a pre-processing step that converts this tags to just ">". It
|
||||
// // should be safe to do so because such content can only be within the body
|
||||
// // of a note - and ">" or ">" is equivalent.
|
||||
// //
|
||||
// // Ref: https://discourse.joplinapp.org/t/20470/4
|
||||
// const newContent = content.replace(/<!\[CDATA\[>\]\]>/g, '>');
|
||||
// if (content === newContent) return filePath;
|
||||
// const newFilePath = `${Setting.value('tempDir')}/${md5(Date.now() + Math.random())}.enex`;
|
||||
// await shim.fsDriver().writeFile(newFilePath, newContent, 'utf8');
|
||||
// return newFilePath;
|
||||
};
|
||||
|
||||
export default async function importEnex(parentFolderId: string, filePath: string, importOptions: ImportOptions = null) {
|
||||
function importEnex(parentFolderId, filePath, importOptions = null) {
|
||||
if (!importOptions) importOptions = {};
|
||||
if (!('fuzzyMatching' in importOptions)) importOptions.fuzzyMatching = false;
|
||||
if (!('onProgress' in importOptions)) importOptions.onProgress = function() {};
|
||||
if (!('onError' in importOptions)) importOptions.onError = function() {};
|
||||
|
||||
function handleSaxStreamEvent(fn: Function) {
|
||||
return function(...args: any[]) {
|
||||
function handleSaxStreamEvent(fn) {
|
||||
return function(...args) {
|
||||
// Pass the parser to the wrapped function for debugging purposes
|
||||
if (this._parser) (fn as any)._parser = this._parser;
|
||||
if (this._parser) fn._parser = this._parser;
|
||||
|
||||
try {
|
||||
fn.call(this, ...args);
|
||||
@@ -358,9 +285,6 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
};
|
||||
}
|
||||
|
||||
const fileToProcess = await preProcessFile(filePath);
|
||||
const needToDeleteFileToProcess = fileToProcess !== filePath;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const progressState = {
|
||||
loaded: 0,
|
||||
@@ -371,22 +295,22 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
notesTagged: 0,
|
||||
};
|
||||
|
||||
const stream = fs.createReadStream(fileToProcess);
|
||||
const stream = fs.createReadStream(filePath);
|
||||
|
||||
const options = {};
|
||||
const strict = true;
|
||||
const saxStream = require('@joplin/fork-sax').createStream(strict, options);
|
||||
|
||||
const nodes: Node[] = []; // LIFO list of nodes so that we know in which node we are in the onText event
|
||||
let note: ExtractedNote = null;
|
||||
let noteAttributes: Record<string, any> = null;
|
||||
let noteResource: ExtractedResource = null;
|
||||
let noteResourceAttributes: Record<string, any> = null;
|
||||
let noteResourceRecognition: NoteResourceRecognition = null;
|
||||
const notes: ExtractedNote[] = [];
|
||||
const nodes = []; // LIFO list of nodes so that we know in which node we are in the onText event
|
||||
let note = null;
|
||||
let noteAttributes = null;
|
||||
let noteResource = null;
|
||||
let noteResourceAttributes = null;
|
||||
let noteResourceRecognition = null;
|
||||
const notes = [];
|
||||
let processingNotes = false;
|
||||
|
||||
const createErrorWithNoteTitle = (fnThis: any, error: any) => {
|
||||
const createErrorWithNoteTitle = (fnThis, error) => {
|
||||
const line = [];
|
||||
|
||||
const parser = fnThis ? fnThis._parser : null;
|
||||
@@ -405,7 +329,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
return error;
|
||||
};
|
||||
|
||||
stream.on('error', function(error: any) {
|
||||
stream.on('error', function(error) {
|
||||
importOptions.onError(createErrorWithNoteTitle(this, error));
|
||||
});
|
||||
|
||||
@@ -493,11 +417,11 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
return true;
|
||||
}
|
||||
|
||||
saxStream.on('error', function(error: any) {
|
||||
saxStream.on('error', function(error) {
|
||||
importOptions.onError(createErrorWithNoteTitle(this, error));
|
||||
});
|
||||
|
||||
saxStream.on('text', handleSaxStreamEvent(function(text: string) {
|
||||
saxStream.on('text', handleSaxStreamEvent(function(text) {
|
||||
const n = currentNodeName();
|
||||
|
||||
if (noteAttributes) {
|
||||
@@ -519,8 +443,8 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
|
||||
fs.appendFileSync(noteResource.dataFilePath, text);
|
||||
} else {
|
||||
if (!(n in noteResource)) (noteResource as any)[n] = '';
|
||||
(noteResource as any)[n] += text;
|
||||
if (!(n in noteResource)) noteResource[n] = '';
|
||||
noteResource[n] += text;
|
||||
}
|
||||
} else if (note) {
|
||||
if (n == 'title') {
|
||||
@@ -541,7 +465,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
}
|
||||
}));
|
||||
|
||||
saxStream.on('opentag', handleSaxStreamEvent(function(node: Node) {
|
||||
saxStream.on('opentag', handleSaxStreamEvent(function(node) {
|
||||
const n = node.name.toLowerCase();
|
||||
nodes.push(node);
|
||||
|
||||
@@ -564,7 +488,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
}
|
||||
}));
|
||||
|
||||
saxStream.on('cdata', handleSaxStreamEvent(function(data: any) {
|
||||
saxStream.on('cdata', handleSaxStreamEvent(function(data) {
|
||||
const n = currentNodeName();
|
||||
|
||||
if (noteResourceRecognition) {
|
||||
@@ -576,7 +500,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
}
|
||||
}));
|
||||
|
||||
saxStream.on('closetag', handleSaxStreamEvent(function(n: string) {
|
||||
saxStream.on('closetag', handleSaxStreamEvent(function(n) {
|
||||
nodes.pop();
|
||||
|
||||
if (n == 'note') {
|
||||
@@ -605,7 +529,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
note.longitude = noteAttributes.longitude;
|
||||
note.altitude = noteAttributes.altitude;
|
||||
note.author = noteAttributes.author ? noteAttributes.author.trim() : '';
|
||||
note.is_todo = noteAttributes['reminder-order'] !== '0' && !!noteAttributes['reminder-order'] as any;
|
||||
note.is_todo = noteAttributes['reminder-order'] !== '0' && !!noteAttributes['reminder-order'];
|
||||
note.todo_due = dateToTimestamp(noteAttributes['reminder-time'], 0);
|
||||
note.todo_completed = dateToTimestamp(noteAttributes['reminder-done-time'], 0);
|
||||
note.order = dateToTimestamp(noteAttributes['reminder-order'], 0);
|
||||
@@ -648,11 +572,10 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
saxStream.on('end', handleSaxStreamEvent(function() {
|
||||
// Wait till there is no more notes to process.
|
||||
const iid = shim.setInterval(() => {
|
||||
void processNotes().then(allDone => {
|
||||
processNotes().then(allDone => {
|
||||
if (allDone) {
|
||||
shim.clearTimeout(iid);
|
||||
if (needToDeleteFileToProcess) void shim.fsDriver().remove(fileToProcess);
|
||||
resolve(null);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
@@ -661,3 +584,5 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
stream.pipe(saxStream);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { importEnex };
|
||||
@@ -41,45 +41,45 @@ locales['uk_UA'] = require('./uk_UA.json');
|
||||
locales['vi'] = require('./vi.json');
|
||||
locales['zh_CN'] = require('./zh_CN.json');
|
||||
locales['zh_TW'] = require('./zh_TW.json');
|
||||
stats['ar'] = {"percentDone":99};
|
||||
stats['ar'] = {"percentDone":91};
|
||||
stats['eu'] = {"percentDone":28};
|
||||
stats['bs_BA'] = {"percentDone":71};
|
||||
stats['bg_BG'] = {"percentDone":55};
|
||||
stats['ca'] = {"percentDone":99};
|
||||
stats['hr_HR'] = {"percentDone":95};
|
||||
stats['cs_CZ'] = {"percentDone":94};
|
||||
stats['bg_BG'] = {"percentDone":56};
|
||||
stats['ca'] = {"percentDone":95};
|
||||
stats['hr_HR'] = {"percentDone":96};
|
||||
stats['cs_CZ'] = {"percentDone":95};
|
||||
stats['da_DK'] = {"percentDone":99};
|
||||
stats['de_DE'] = {"percentDone":99};
|
||||
stats['de_DE'] = {"percentDone":95};
|
||||
stats['et_EE'] = {"percentDone":54};
|
||||
stats['en_GB'] = {"percentDone":100};
|
||||
stats['en_US'] = {"percentDone":100};
|
||||
stats['es_ES'] = {"percentDone":95};
|
||||
stats['eo'] = {"percentDone":31};
|
||||
stats['fi_FI'] = {"percentDone":99};
|
||||
stats['fi_FI'] = {"percentDone":90};
|
||||
stats['fr_FR'] = {"percentDone":96};
|
||||
stats['gl_ES'] = {"percentDone":36};
|
||||
stats['id_ID'] = {"percentDone":95};
|
||||
stats['it_IT'] = {"percentDone":95};
|
||||
stats['hu_HU'] = {"percentDone":83};
|
||||
stats['nl_BE'] = {"percentDone":86};
|
||||
stats['id_ID'] = {"percentDone":96};
|
||||
stats['it_IT'] = {"percentDone":96};
|
||||
stats['hu_HU'] = {"percentDone":84};
|
||||
stats['nl_BE'] = {"percentDone":87};
|
||||
stats['nl_NL'] = {"percentDone":90};
|
||||
stats['nb_NO'] = {"percentDone":96};
|
||||
stats['fa'] = {"percentDone":67};
|
||||
stats['pl_PL'] = {"percentDone":89};
|
||||
stats['pl_PL'] = {"percentDone":90};
|
||||
stats['pt_BR'] = {"percentDone":96};
|
||||
stats['pt_PT'] = {"percentDone":89};
|
||||
stats['ro'] = {"percentDone":62};
|
||||
stats['sl_SI'] = {"percentDone":90};
|
||||
stats['sv'] = {"percentDone":99};
|
||||
stats['pt_PT'] = {"percentDone":90};
|
||||
stats['ro'] = {"percentDone":63};
|
||||
stats['sl_SI'] = {"percentDone":91};
|
||||
stats['sv'] = {"percentDone":96};
|
||||
stats['th_TH'] = {"percentDone":42};
|
||||
stats['vi'] = {"percentDone":96};
|
||||
stats['tr_TR'] = {"percentDone":99};
|
||||
stats['uk_UA'] = {"percentDone":89};
|
||||
stats['el_GR'] = {"percentDone":92};
|
||||
stats['ru_RU'] = {"percentDone":89};
|
||||
stats['sr_RS'] = {"percentDone":80};
|
||||
stats['sr_RS'] = {"percentDone":81};
|
||||
stats['zh_CN'] = {"percentDone":99};
|
||||
stats['zh_TW'] = {"percentDone":95};
|
||||
stats['zh_TW'] = {"percentDone":94};
|
||||
stats['ja_JP'] = {"percentDone":95};
|
||||
stats['ko'] = {"percentDone":94};
|
||||
stats['ko'] = {"percentDone":95};
|
||||
module.exports = { locales: locales, stats: stats };
|
||||
@@ -2,7 +2,7 @@ const { setupDatabaseAndSynchronizer, switchClient } = require('../testing/test-
|
||||
const Folder = require('../models/Folder').default;
|
||||
const Note = require('../models/Note').default;
|
||||
|
||||
describe('models/BaseItem', function() {
|
||||
describe('models_BaseItem', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
|
||||
@@ -9,7 +9,7 @@ import ResourceService from '../services/ResourceService';
|
||||
|
||||
const testImagePath = `${supportDir}/photo.jpg`;
|
||||
|
||||
describe('models/Folder.sharing', function() {
|
||||
describe('models_Folder.sharing', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
|
||||
@@ -9,7 +9,7 @@ async function allItems() {
|
||||
return folders.concat(notes);
|
||||
}
|
||||
|
||||
describe('models/Folder', function() {
|
||||
describe('models_Folder', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
|
||||
@@ -15,7 +15,7 @@ async function allItems() {
|
||||
return folders.concat(notes);
|
||||
}
|
||||
|
||||
describe('models/Note', function() {
|
||||
describe('models_Note', function() {
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
|
||||
@@ -3,7 +3,7 @@ const { setupDatabaseAndSynchronizer, switchClient } = require('../testing/test-
|
||||
const Folder = require('../models/Folder').default;
|
||||
const Note = require('../models/Note').default;
|
||||
|
||||
describe('models/Note_CustomSortOrder', function() {
|
||||
describe('models_Note_CustomSortOrder', function() {
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
|
||||
@@ -6,7 +6,7 @@ const shim = require('../shim').default;
|
||||
|
||||
const testImagePath = `${supportDir}/photo.jpg`;
|
||||
|
||||
describe('models/Resource', function() {
|
||||
describe('models_Resource', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
|
||||
@@ -7,7 +7,7 @@ async function loadSettingsFromFile(): Promise<any> {
|
||||
return JSON.parse(await fs.readFile(Setting.settingFilePath, 'utf8'));
|
||||
}
|
||||
|
||||
describe('models/Setting', function() {
|
||||
describe('models_Setting', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
@@ -174,7 +174,7 @@ describe('models/Setting', function() {
|
||||
}));
|
||||
|
||||
it('should not save to file if nothing has changed', (async () => {
|
||||
Setting.setValue('sync.mobileWifiOnly', true);
|
||||
Setting.setValue('sync.target', 9);
|
||||
await Setting.saveAll();
|
||||
|
||||
{
|
||||
@@ -182,7 +182,7 @@ describe('models/Setting', function() {
|
||||
// changed.
|
||||
const beforeStat = await fs.stat(Setting.settingFilePath);
|
||||
await msleep(1001);
|
||||
Setting.setValue('sync.mobileWifiOnly', false);
|
||||
Setting.setValue('sync.target', 8);
|
||||
await Setting.saveAll();
|
||||
const afterStat = await fs.stat(Setting.settingFilePath);
|
||||
expect(afterStat.mtime.getTime()).toBeGreaterThan(beforeStat.mtime.getTime());
|
||||
@@ -191,7 +191,7 @@ describe('models/Setting', function() {
|
||||
{
|
||||
const beforeStat = await fs.stat(Setting.settingFilePath);
|
||||
await msleep(1001);
|
||||
Setting.setValue('sync.mobileWifiOnly', false);
|
||||
Setting.setValue('sync.target', 8);
|
||||
const afterStat = await fs.stat(Setting.settingFilePath);
|
||||
await Setting.saveAll();
|
||||
expect(afterStat.mtime.getTime()).toBe(beforeStat.mtime.getTime());
|
||||
|
||||