diff --git a/__tests__/removeExtraParagraphSpacing.test.ts b/__tests__/removeExtraParagraphSpacing.test.ts
new file mode 100644
index 0000000000..a42d04468e
--- /dev/null
+++ b/__tests__/removeExtraParagraphSpacing.test.ts
@@ -0,0 +1,49 @@
+import removeExtraParagraphSpacing from '../android/app/src/main/assets/js/removeExtraParagraphSpacing';
+
+describe('removeExtraParagraphSpacing', () => {
+ const testCases = [
+ {
+ id: '#1',
+ input: '
aa
',
+ expected: 'aa
',
+ },
+ {
+ id: '#2',
+ // Including the \u200b zero-width space mentioned in your comments
+ input: 'bb
\u200b',
+ expected: 'bb
',
+ },
+ {
+ id: '#3',
+ input: 'cccc
ukauka
',
+ expected: 'cccc
ukauka
',
+ },
+ {
+ id: '#4',
+ input: 'cccc
ukauka
',
+ expected: 'cccc
ukauka
',
+ },
+ {
+ id: '#5',
+ input: 'cccc
ukauka
',
+ expected: 'cccc
ukauka
',
+ },
+ {
+ id: '#6',
+ input: 'aa
bb
cc',
+ expected: 'aa
bb
cc',
+ },
+ {
+ id: '#7',
+ input: '
aa
',
+ expected: 'aa
',
+ },
+ ];
+
+ testCases.forEach(({ id, input, expected }) => {
+ it(`should correctly transform case ${id}`, () => {
+ const result = removeExtraParagraphSpacing(input);
+ expect(result).toBe(expected);
+ });
+ });
+});
diff --git a/android/app/src/main/assets/js/core.js b/android/app/src/main/assets/js/core.js
index a218595dd9..fb70d659b3 100644
--- a/android/app/src/main/assets/js/core.js
+++ b/android/app/src/main/assets/js/core.js
@@ -771,22 +771,7 @@ window.addEventListener('load', () => {
}
if (reader.generalSettings.val.removeExtraParagraphSpacing) {
- html = html
- .replace(/(?: \s*|[\u200b]\s*)+(?=<\/?p[> ])/g, '')
- .replace(/
\s*
\s*(?:
\s*)+/g, '
') //force max 2 consecutive
, chaining regex
- .replace(
- /
\s*
[^]+/,
- _ =>
- `${
- /\/p>/.test(_)
- ? _.replace(
- /
\s*
(?:(?=\s*<\/?p[> ])|(?<=<\/?p\b[^>]*>
\s*
))\s*/g,
- '',
- )
- : _
- }`,
- ) //if p found, delete all double br near p
- .replace(/
(?:(?=\s*<\/?p[> ])|(?<=<\/?p>\s*
))\s*/g, '');
+ html = window.removeExtraParagraphSpacing(html);
}
reader.chapterElement.innerHTML = html;
});
diff --git a/android/app/src/main/assets/js/removeExtraParagraphSpacing.d.ts b/android/app/src/main/assets/js/removeExtraParagraphSpacing.d.ts
new file mode 100644
index 0000000000..b58150e95d
--- /dev/null
+++ b/android/app/src/main/assets/js/removeExtraParagraphSpacing.d.ts
@@ -0,0 +1 @@
+export default function removeExtraParagraphSpacing(html: string): string;
diff --git a/android/app/src/main/assets/js/removeExtraParagraphSpacing.js b/android/app/src/main/assets/js/removeExtraParagraphSpacing.js
new file mode 100644
index 0000000000..a443348fa3
--- /dev/null
+++ b/android/app/src/main/assets/js/removeExtraParagraphSpacing.js
@@ -0,0 +1,28 @@
+function removeExtraParagraphSpacing(html) {
+ return html
+ .replace(/(?: \s*|[\u200b]\s*)+(?=<\/?p[> ])/g, '')
+ .replace(/
\s*
\s*(?:
\s*)+/g, '
') //force max 2 consecutive
, chaining regex
+ .replace(
+ /
\s*
[^]+/,
+ _ =>
+ `${
+ /\/p>/.test(_)
+ ? _.replace(
+ /
\s*
(?:(?=\s*<\/?p[> ])|(?<=<\/?p\b[^>]*>
\s*
))\s*/g,
+ '',
+ )
+ : _
+ }`,
+ ) //if p found, delete all double br near p
+ .replace(/
(?:(?=\s*<\/?p[> ])|(?<=<\/?p>\s*
))\s*/g, '');
+}
+
+// WebView global
+if (typeof window !== 'undefined') {
+ window.removeExtraParagraphSpacing = removeExtraParagraphSpacing;
+}
+
+// Node / test
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = removeExtraParagraphSpacing;
+}
diff --git a/jest.config.js b/jest.config.js
index dd3677fd31..c49aba5485 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -74,6 +74,24 @@ module.exports = {
'!src/**/__tests__/**',
],
},
+ {
+ displayName: 'js assets',
+ preset: 'jest-expo',
+ roots: [''],
+ testMatch: ['__tests__/**/*.test.tsx', '**/__tests__/**/*.test.ts'],
+ testPathIgnorePatterns: ['/node_modules/', '/src/'],
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
+ transform: baseTransform,
+ transformIgnorePatterns: baseTransformIgnorePatterns,
+ moduleNameMapper: baseModuleNameMapper,
+ setupFiles: ['/__mocks__/index.js'],
+ setupFilesAfterEnv: ['/__tests__/jest.setup.ts'],
+ collectCoverageFrom: [
+ 'src/**/*.{ts,tsx}',
+ '!src/database/queries/**/__tests__/**',
+ '!src/**/__tests__/**',
+ ],
+ },
],
// Global settings
diff --git a/package.json b/package.json
index f5ca6e0fe1..956ac9c656 100644
--- a/package.json
+++ b/package.json
@@ -176,5 +176,5 @@
"engines": {
"node": ">=20"
},
- "packageManager": "pnpm@10.27.0"
+ "packageManager": "pnpm@11.6.0"
}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 94024e48a4..a83191ec8f 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,3 +1,8 @@
+allowBuilds:
+ better-sqlite3: true
+ esbuild: true
+ protobufjs: true
+
nodeLinker: hoisted
onlyBuiltDependencies:
diff --git a/src/screens/reader/components/WebViewReader.tsx b/src/screens/reader/components/WebViewReader.tsx
index 99befe1cc7..646e24d4e0 100644
--- a/src/screens/reader/components/WebViewReader.tsx
+++ b/src/screens/reader/components/WebViewReader.tsx
@@ -536,6 +536,7 @@ const WebViewReader: React.FC = ({ onPress }) => {
+
diff --git a/src/screens/settings/SettingsReaderScreen/SettingsReaderScreen.tsx b/src/screens/settings/SettingsReaderScreen/SettingsReaderScreen.tsx
index 6cad220489..75787ba7be 100644
--- a/src/screens/settings/SettingsReaderScreen/SettingsReaderScreen.tsx
+++ b/src/screens/settings/SettingsReaderScreen/SettingsReaderScreen.tsx
@@ -127,11 +127,12 @@ const SettingsReaderScreen = () => {
--theme-outline: ${theme.outline};
--theme-rippleColor: ${theme.rippleColor};
}
-
+
@font-face {
font-family: ${readerSettings.fontFamily};
- src: url("file:///android_asset/fonts/${readerSettings.fontFamily
- }.ttf");
+ src: url("file:///android_asset/fonts/${
+ readerSettings.fontFamily
+ }.ttf");
}
@@ -231,8 +232,9 @@ const SettingsReaderScreen = () => {
${webViewCSS}
-
+
${dummyHTML}
@@ -240,28 +242,29 @@ const SettingsReaderScreen = () => {
+