diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ba02295..b644f79e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to - ♿ restyle checked checkboxes: removing strikethrough #1439 - ♿ add h1 for SR on 40X pages and remove alt texts #1438 - ♿ update labels and shared document icon accessibility #1442 +- 🍱(frontend) Fonts GDPR compliants #1453 ### Fixed @@ -38,6 +39,7 @@ and this project adheres to - 🐛(frontend) fix legacy role computation #1376 - 🛂(frontend) block editing title when not allowed #1412 - 🐛(frontend) scroll back to top when navigate to a document #1406 +- 🐛(frontend) fix export pdf emoji problem #1453 - 🐛(frontend) fix attachment download filename #1447 - 🐛(frontend) exclude h4-h6 headings from table of contents #1441 - 🔒(frontend) prevent readers from changing callout emoji #1449 diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts index 5824359d..af138421 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts @@ -11,6 +11,7 @@ import { verifyDocName, waitForLanguageSwitch, } from './utils-common'; +import { openSuggestionMenu, writeInEditor } from './utils-editor'; import { createRootSubPage } from './utils-sub-pages'; test.beforeEach(async ({ page }) => { @@ -153,11 +154,13 @@ test.describe('Doc Export', () => { await verifyDocName(page, randomDoc); - await page.locator('.ProseMirror.bn-editor').click(); - await page.locator('.ProseMirror.bn-editor').fill('Hello World'); + await writeInEditor({ + page, + text: 'Hello World 😃🎉🚀🙋‍♀️🧑🏿‍❤️‍💋‍🧑🏾', + }); await page.keyboard.press('Enter'); - await page.locator('.bn-block-outer').last().fill('/'); + await openSuggestionMenu({ page }); await page.getByText('Resizable image with caption').click(); const fileChooserPromise = page.waitForEvent('filechooser'); diff --git a/src/frontend/apps/impress/.gitignore b/src/frontend/apps/impress/.gitignore index 9a57ee73..4501359e 100644 --- a/src/frontend/apps/impress/.gitignore +++ b/src/frontend/apps/impress/.gitignore @@ -37,4 +37,6 @@ yarn-error.log* service-worker.js # Font embedding +public/assets/fonts/emoji/* +!public/assets/fonts/emoji/fallback.png public/assets/fonts/Marianne/* \ No newline at end of file diff --git a/src/frontend/apps/impress/next.config.js b/src/frontend/apps/impress/next.config.js index 73869366..a52c38db 100644 --- a/src/frontend/apps/impress/next.config.js +++ b/src/frontend/apps/impress/next.config.js @@ -47,12 +47,21 @@ const nextConfig = { config.plugins.push( new CopyPlugin({ patterns: [ + { + from: path.resolve( + __dirname, + '../../node_modules/emoji-datasource-apple/img/apple/64', + ), + to: path.resolve(__dirname, 'public/assets/fonts/emoji'), + force: true, + }, { from: path.resolve( __dirname, '../../node_modules/@gouvfr-lasuite/ui-kit/dist/assets/fonts/Marianne', ), to: path.resolve(__dirname, 'public/assets/fonts/Marianne'), + force: true, }, ], }), diff --git a/src/frontend/apps/impress/package.json b/src/frontend/apps/impress/package.json index 42cf6961..8b1990dd 100644 --- a/src/frontend/apps/impress/package.json +++ b/src/frontend/apps/impress/package.json @@ -43,6 +43,7 @@ "cmdk": "1.1.1", "crisp-sdk-web": "1.0.25", "docx": "9.5.0", + "emoji-datasource-apple": "16.0.0", "emoji-mart": "5.6.0", "emoji-regex": "10.5.0", "i18next": "25.5.2", diff --git a/src/frontend/apps/impress/public/assets/fonts/emoji/fallback.png b/src/frontend/apps/impress/public/assets/fonts/emoji/fallback.png new file mode 100644 index 00000000..7fcaf855 Binary files /dev/null and b/src/frontend/apps/impress/public/assets/fonts/emoji/fallback.png differ diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx b/src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx index 6c8bd1af..3c3505b5 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx @@ -10,6 +10,7 @@ import { useToastProvider, } from '@openfun/cunningham-react'; import { DocumentProps, pdf } from '@react-pdf/renderer'; +import jsonemoji from 'emoji-datasource-apple' assert { type: 'json' }; import i18next from 'i18next'; import { cloneElement, isValidElement, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -95,6 +96,20 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => { if (format === DocDownloadFormat.PDF) { const exporter = new PDFExporter(editor.schema, pdfDocsSchemaMappings, { resolveFileUrl: async (url) => exportCorsResolveFileUrl(doc.id, url), + emojiSource: { + format: 'png', + builder(code) { + const emoji = jsonemoji.find((e) => + e.unified.toLocaleLowerCase().includes(code.toLowerCase()), + ); + + if (emoji) { + return `/assets/fonts/emoji/${emoji.image}`; + } + + return '/assets/fonts/emoji/fallback.png'; + }, + }, }); const rawPdfDocument = (await exporter.toReactPDFDocument( exportDocument, @@ -150,7 +165,6 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => { color="secondary" fullWidth onClick={() => onClose()} - disabled={isExporting} > {t('Cancel')} diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock index 594fa679..531f3845 100644 --- a/src/frontend/yarn.lock +++ b/src/frontend/yarn.lock @@ -8633,7 +8633,7 @@ data-view-byte-offset@^1.0.1: es-errors "^1.3.0" is-data-view "^1.0.1" -debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.7, debug@^4.4.0, debug@^4.4.1: +debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4, debug@^4.3.5, debug@^4.3.7, debug@^4.4.0, debug@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== @@ -8654,6 +8654,13 @@ debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.2: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decimal.js@^10.4.3, decimal.js@^10.5.0: version "10.6.0" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.6.0.tgz#e649a43e3ab953a72192ff5983865e509f37ed9a" @@ -8907,6 +8914,11 @@ emittery@^0.13.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== +emoji-datasource-apple@16.0.0: + version "16.0.0" + resolved "https://registry.yarnpkg.com/emoji-datasource-apple/-/emoji-datasource-apple-16.0.0.tgz#c6e0794c1fd1b88765b880b2137e11d8efa94020" + integrity sha512-dVYjsK0FnCry9F+PBtnivhG2K0xdwlmqYaSgiUtztUdAGPYiHYhZcVKvNBqC791g2qyEcFNTBO6utg4eQ3uLTw== + emoji-mart@5.6.0, emoji-mart@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/emoji-mart/-/emoji-mart-5.6.0.tgz#71b3ed0091d3e8c68487b240d9d6d9a73c27f023"