Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix text cutting off when printing and differences between clicking print and doing ctrl + P #10670

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft
49 changes: 35 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"@ckeditor/ckeditor5-ui": "37.1.0",
"@ckeditor/ckeditor5-upload": "37.1.0",
"@ckeditor/ckeditor5-vue2": "^3.0.1",
"@iframe-resizer/child": "^5.3.3",
"@iframe-resizer/parent": "^5.3.3",
"@mdi/svg": "^7.4.47",
"@nextcloud/auth": "^2.4.0",
"@nextcloud/axios": "^2.5.1",
Expand All @@ -61,7 +63,6 @@
"dompurify": "^3.2.3",
"html-to-text": "^9.0.5",
"ical.js": "^1.5.0",
"iframe-resizer": "^4.4.5",
"js-base64": "^3.7.7",
"jstz": "^2.1.1",
"lodash": "^4.17.21",
Expand Down
5 changes: 1 addition & 4 deletions src/components/MenuEnvelope.vue
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,7 @@ export default {
this.onSnooze(this.customSnoozeDateTime.valueOf())
},
onPrint() {
// needed for the actions menu to actually close and not be shown in the print preview
setTimeout(() => {
window.print()
}, 10)
this.$emit('print')
},
},
}
Expand Down
16 changes: 9 additions & 7 deletions src/components/MessageHTMLBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
</template>

<script>
import { iframeResizer } from 'iframe-resizer'
import iframeResize from '@iframe-resizer/parent'
import PrintScout from 'printscout'
import { trustSender } from '../service/TrustedSenderService.js'
import { NcActionButton as ActionButton, NcActions as Actions } from '@nextcloud/vue'
Expand Down Expand Up @@ -97,10 +97,10 @@ export default {
scout.on('beforeprint', this.onBeforePrint)
},
mounted() {
iframeResizer({
iframeResize({
license: 'GPLv3',
log: false,
heightCalculationMethod: 'taggedElement',
scrolling: true,
scrolling: false,
}, this.$refs.iframe)
},
beforeDestroy() {
Expand Down Expand Up @@ -178,9 +178,11 @@ export default {
background-color: #FFFFFF;

// TODO: collapse quoted text and remove inner scrollbar
&.scroll {
max-height: 50vh;
overflow-y: auto;
@media only screen {
&.scroll {
max-height: 50vh;
overflow-y: auto;
}
}
}
:deep(.button-vue__text) {
Expand Down
130 changes: 128 additions & 2 deletions src/components/Thread.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,18 @@
</div>
</div>
<ThreadSummary v-if="showSummaryBox" :loading="summaryLoading" :summary="summaryText" />
<ThreadEnvelope v-for="env in thread"
<ThreadEnvelope v-for="(env, index) in thread"
:key="env.databaseId"
:envelope="env"
:mailbox-id="$route.params.mailboxId"
:thread-subject="threadSubject"
:expanded="expandedThreads.includes(env.databaseId)"
:full-height="thread.length === 1"
:thread-index="index"
@delete="$emit('delete', env.databaseId)"
@move="onMove(env.databaseId)"
@toggle-expand="toggleExpand(env.databaseId)" />
@toggle-expand="toggleExpand(env.databaseId)"
@print="print" />
</template>
</AppContentDetails>
</template>
Expand Down Expand Up @@ -189,9 +191,11 @@ export default {
created() {
this.resetThread()
window.addEventListener('resize', this.resizeDebounced)
window.addEventListener('keydown', this.handleKeyDown)
},
beforeDestroy() {
window.removeEventListener('resize', this.resizeDebounced)
window.removeEventListener('keydown', this.handleKeyDown)
},
methods: {
async updateSummary() {
Expand Down Expand Up @@ -317,6 +321,107 @@ export default {
}
}
},
handleKeyDown(event) {
if ((event.ctrlKey || event.metaKey) && event.key === 'p') {
event.preventDefault()

// So when the menu envelope is opened then closed, the element in html doesn't get immediately deleted, just hidden
// This causes firefox pdf formatting to break, making the pdf content be very narrow and only take a small piece of the page
// We need to manually remove the element from the dom
const menuEnvelope = document.querySelectorAll('.v-popper__popper')
menuEnvelope.forEach((element) => {
element.remove()
})

window.print()
}
},
print(threadIndex) {
setTimeout(() => {
try {
const messages = Array.from(document.querySelectorAll('.html-message-body, .mail-message-body'))

let message

if (threadIndex !== undefined) {
message = messages[threadIndex] ?? messages.pop()
} else {
// By default, we print the last opened message in the thread
message = messages.pop()
}

const iframe = message.querySelector('iframe')

const addThreadInfo = (document) => {
const threadInfo = document.createElement('div')
threadInfo.style.marginBottom = '20px'
threadInfo.className = 'mail-thread-info'

const subjectLine = document.createElement('h2')
subjectLine.textContent = `${this.threadSubject}`
threadInfo.appendChild(subjectLine)

const participantsLine = document.createElement('p')
participantsLine.textContent = this.threadParticipants
.map(participant => `${participant.label} <${participant.email}>`)
.join(', ')
threadInfo.appendChild(participantsLine)

document.body.insertBefore(threadInfo, document.body.firstChild)

setTimeout(() => {
threadInfo.remove()
}, 200)
}

if (iframe === null) {
// Handle plain text messages
const messageContainer = message.querySelector('#message-container')

if (messageContainer) {
// Create a new iframe
const newIframe = document.createElement('iframe')
newIframe.style.display = 'none' // Hide the iframe
document.body.appendChild(newIframe)

// Insert the message content into the iframe
const iframeDocument = newIframe.contentDocument || newIframe.contentWindow.document
iframeDocument.open()
iframeDocument.write(`
<html>
<head>
<title>${this.threadSubject}</title>
</head>
<body>
<div class="message-container">${messageContainer.innerHTML}</div>
</body>
</html>
`)
iframeDocument.close()

addThreadInfo(iframeDocument)

newIframe.contentWindow.print()

// Clean up: remove the iframe after printing
setTimeout(() => {
document.body.removeChild(newIframe)
}, 500)
}

return
}

const iframeDocument = iframe.contentDocument || iframe.contentWindow.document

addThreadInfo(iframeDocument)

iframe.contentWindow.print()
} catch (error) {
showError(t('mail', 'Could not print message'))
}
}, 100)
},
},
}
</script>
Expand Down Expand Up @@ -462,6 +567,9 @@ export default {
}
.app-content {
margin-left: 0 !important;
break-inside: avoid;
page-break-inside: avoid;
page-break-after: always;
}
.mail-message-body {
margin-bottom: 0 !important;
Expand All @@ -475,6 +583,24 @@ export default {
.envelope {
border: none !important;
}
.v-popper__popper {
display: none !important;
}
iframe {
display: block !important;
visibility: visible !important;
position: relative !important;
width: 100% !important;
}

iframe body {
display: block !important;
}

@page {
size: auto;
margin: 10mm;
}
}

.message-source {
Expand Down
10 changes: 9 additions & 1 deletion src/components/ThreadEnvelope.vue
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@
@open-move-modal="onOpenMoveModal"
@open-event-modal="onOpenEventModal"
@open-task-modal="onOpenTaskModal"
@open-translation-modal="onOpenTranslationModal" />
@open-translation-modal="onOpenTranslationModal"
@print="onPrint" />
</NcActions>
<NcModal v-if="showSourceModal" class="source-modal" @close="onCloseSourceModal">
<div class="source-modal-content">
Expand Down Expand Up @@ -386,6 +387,10 @@ export default {
required: true,
type: String,
},
threadIndex: {
required: true,
type: Number,
},
},
data() {
return {
Expand Down Expand Up @@ -905,6 +910,9 @@ export default {
onCloseSourceModal() {
this.showSourceModal = false
},
onPrint() {
this.$emit('print', this.threadIndex)
}
},
}
</script>
Expand Down
4 changes: 1 addition & 3 deletions src/html-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

// injected styles
import '../css/html-response.css'

// iframe-resizer client script
import 'iframe-resizer/js/iframeResizer.contentWindow.js'
import '@iframe-resizer/child'

// Fix width of some newsletter mails
document.addEventListener('DOMContentLoaded', function() {
Expand Down
Loading