From 7dc00af8586faa22b619cd955924ac29e8052103 Mon Sep 17 00:00:00 2001 From: Aljaz Grilc Date: Thu, 20 Jun 2024 08:52:16 +0200 Subject: [PATCH] Improve logic for adjusting correction panel dimensions to support inline elements This is still a WIP commit, hence the code is yet to be refactored eventually --- service.js | 58 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/service.js b/service.js index d95f793..b7f2de2 100644 --- a/service.js +++ b/service.js @@ -275,21 +275,35 @@ class BesService { return rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom } + // TODO: Monitor if hostElement moves in DOM and reposition correction panel and status icon. /** * Creates auxiliary DOM elements for text adornments. */ createCorrectionPanel() { const panelParent = document.createElement('div') panelParent.classList.add('bes-correction-panel-parent') + this.correctionPanel = document.createElement('div') - this.scrollPanel = document.createElement('div') - this.setCorrectionPanelSize() this.correctionPanel.classList.add('bes-correction-panel') + + this.scrollPanel = document.createElement('div') this.scrollPanel.classList.add('bes-correction-panel-scroll') - this.correctionPanel.appendChild(this.scrollPanel) panelParent.appendChild(this.correctionPanel) - this.textElement.parentElement.insertBefore(panelParent, this.textElement) + this.correctionPanel.appendChild(this.scrollPanel) + // Inline elements (textarea) and CKEditor. + if ( + this.hostElement.tagName !== 'DIV' || + this.hostElement.classList.contains('ck-editor__editable') + ) { + this.textElement.parentElement.insertBefore(panelParent, this.textElement) + this.setCorrectionPanelSize() + } + // Block elements (contenteditable = 'true', readonly). This also works correctly if DIV element has display set to inline-block. + else { + document.body.insertBefore(panelParent, document.body.firstChild) + this.setCorrectionPanelSize() + } this.statusDiv = document.createElement('div') this.statusDiv.classList.add('bes-status-div') @@ -323,20 +337,40 @@ class BesService { */ setCorrectionPanelSize() { const styles = window.getComputedStyle(this.textElement) - - this.correctionPanel.style.width = styles.width this.correctionPanel.style.marginLeft = styles.marginLeft this.correctionPanel.style.marginRight = styles.marginRight this.correctionPanel.style.paddingLeft = styles.paddingLeft this.correctionPanel.style.paddingRight = styles.paddingRight this.scrollPanel.style.width = `${this.textElement.scrollWidth}px` + if ( + this.hostElement.tagName !== 'DIV' || + this.hostElement.classList.contains('ck-editor__editable') + ) { + const hStyles = window.getComputedStyle(this.hostElement) + const totalWidth = + parseFloat(styles.paddingLeft) + + parseFloat(styles.marginLeft) + + parseFloat(styles.width) + + parseFloat(styles.marginRight) + + parseFloat(styles.paddingRight) + this.correctionPanel.style.width = `${totalWidth}px` + this.correctionPanel.style.height = hStyles.height - this.correctionPanel.style.height = styles.height - this.correctionPanel.style.marginTop = styles.marginTop - this.correctionPanel.style.marginBottom = styles.marginBottom - this.correctionPanel.style.paddingTop = styles.paddingTop - this.correctionPanel.style.paddingBottom = styles.paddingBottom - this.scrollPanel.style.height = `${this.textElement.scrollHeight}px` + this.scrollPanel.style.height = `${this.textElement.scrollHeight}px` + } else { + const rect = this.textElement.getBoundingClientRect() + this.correctionPanel.style.width = styles.width + + const totalHeight = + parseFloat(styles.paddingTop) + + parseFloat(styles.marginTop) + + parseFloat(styles.height) + + parseFloat(styles.marginBottom) + + parseFloat(styles.paddingBottom) + this.correctionPanel.style.height = `${totalHeight}px` + this.correctionPanel.style.marginTop = `${rect.top + window.scrollY}px` + this.scrollPanel.style.height = `${this.textElement.scrollHeight}px` + } } /**