diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9712a83..8160e3e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,8 @@ name: CI +permissions: + contents: read + on: push: branches: [main, develop] diff --git a/src/features/properties/views/PropertyDetailView.vue b/src/features/properties/views/PropertyDetailView.vue index 73d6521..b515755 100644 --- a/src/features/properties/views/PropertyDetailView.vue +++ b/src/features/properties/views/PropertyDetailView.vue @@ -160,21 +160,10 @@ async function copyAnnonce() { // Convert HTML to plain text while preserving line breaks function htmlToPlainText(html: string) { if (!html) return ''; - // remove script/style blocks - const cleaned = html - .replace(/[\s\S]*?<\/script>/gi, '') - .replace(/[\s\S]*?<\/style>/gi, ''); - // replace
and closing block tags with newlines - const withBreaks = cleaned - .replace(//gi, '\n') - .replace(/<\/(p|div|h[1-6]|li|ul|ol|tr|table|section|article)>/gi, '\n') - .replace(/<(\/)?td[^>]*>/gi, '\t'); - // strip remaining tags - const stripped = withBreaks.replace(/<[^>]+>/g, ''); - // decode HTML entities - const txt = document.createElement('textarea'); - txt.innerHTML = stripped; - let decoded = txt.value; + // Use DOM parsing to safely convert HTML to text + const container = document.createElement('div'); + container.innerHTML = html; + let decoded = (container.innerText || container.textContent || ''); // Normalize line endings and collapse multiple blank lines decoded = decoded .replace(/\r/g, '') diff --git a/src/shared/components/RichTextDisplay.vue b/src/shared/components/RichTextDisplay.vue index 2df88af..c93f860 100644 --- a/src/shared/components/RichTextDisplay.vue +++ b/src/shared/components/RichTextDisplay.vue @@ -21,8 +21,11 @@ const sanitizedContent = computed(() => { }); const isEmpty = computed(() => { - // Vérifier si le contenu est vide après suppression des balises - const textOnly = sanitizedContent.value.replace(/<[^>]*>/g, '').trim(); + // Vérifier si le contenu est vide après suppression des balises, + // en extrayant le texte depuis un conteneur DOM temporaire plutôt que via une regex + const container = document.createElement('div'); + container.innerHTML = sanitizedContent.value; + const textOnly = (container.textContent || '').trim(); return !textOnly; });