Revise positioning and resizing

This commit is contained in:
Simon Rozman 2024-06-28 11:51:09 +02:00
parent 6c9629dec6
commit 6863bee513
2 changed files with 19 additions and 34 deletions

View File

@ -1,7 +1,4 @@
// TODO: Research if there is a way to disable languageTool & Grammarly extensions in CKEditor // TODO: Research if there is a way to disable languageTool & Grammarly extensions in CKEditor
// TODO: Revise absolute/relative placement of auxiliary <div> we inject into DOM. Absolute is more
// controllable, but lacks PlacementObserver; relative is tricky to prevent document flow
// issues, but moves with the DOM element.
/** /**
* Collection of all grammar checking services in the document * Collection of all grammar checking services in the document
@ -10,11 +7,6 @@
*/ */
let besServices = [] let besServices = []
// TODO: Window resize may cause host element(s) to move. That needs correction panel and status
// icon repositioning. Also, should any parent element of our service host element move, we
// should reposition correction panel and status icon. How to do this? Alas there is no
// PlacementObserver to monitor host element movements. Switch to relative placement for our
// auxiliary <div>s?
window.addEventListener('resize', () => window.addEventListener('resize', () =>
besServices.forEach(service => service.onReposition()) besServices.forEach(service => service.onReposition())
) )
@ -65,12 +57,10 @@ class BesService {
this.onScroll = this.onScroll.bind(this) this.onScroll = this.onScroll.bind(this)
this.hostElement.addEventListener('scroll', this.onScroll) this.hostElement.addEventListener('scroll', this.onScroll)
this.resizeObserver = new ResizeObserver(this.onResize.bind(this))
this.resizeObserver.observe(this.hostElement)
this.hostBoundingClientRect = this.hostElement.getBoundingClientRect() this.hostBoundingClientRect = this.hostElement.getBoundingClientRect()
this.positionObserver = new MutationObserver(this.onBodyMutate.bind(this)) this.mutationObserver = new MutationObserver(this.onBodyMutate.bind(this))
this.positionObserver.observe(document.body, { this.mutationObserver.observe(document.body, {
attributes: true,
childList: true, childList: true,
subtree: true subtree: true
}) })
@ -108,8 +98,7 @@ class BesService {
unregister() { unregister() {
if (this.abortController) this.abortController.abort() if (this.abortController) this.abortController.abort()
besServices = besServices.filter(item => item !== this) besServices = besServices.filter(item => item !== this)
this.positionObserver.disconnect() this.mutationObserver.disconnect()
this.resizeObserver.disconnect()
this.hostElement.removeEventListener('scroll', this.onScroll) this.hostElement.removeEventListener('scroll', this.onScroll)
this.hostElement.setAttribute('spellcheck', this.originalSpellcheck) this.hostElement.setAttribute('spellcheck', this.originalSpellcheck)
this.hostElement.setAttribute('data-gramm', this.originalDataGramm) this.hostElement.setAttribute('data-gramm', this.originalDataGramm)
@ -337,18 +326,17 @@ class BesService {
* Resizes correction and scroll panels to match host element size. * Resizes correction and scroll panels to match host element size.
*/ */
setCorrectionPanelSize() { setCorrectionPanelSize() {
// TODO: This woodoo looks so wrong it can't be true. Revise together! const styles = window.getComputedStyle(this.hostElement)
const styles = window.getComputedStyle(this.textElement)
this.correctionPanel.style.marginLeft = styles.marginLeft this.correctionPanel.style.marginLeft = styles.marginLeft
this.correctionPanel.style.marginTop = styles.marginTop
this.correctionPanel.style.marginRight = styles.marginRight this.correctionPanel.style.marginRight = styles.marginRight
this.correctionPanel.style.marginBottom = styles.marginBottom
this.correctionPanel.style.paddingLeft = styles.paddingLeft this.correctionPanel.style.paddingLeft = styles.paddingLeft
this.correctionPanel.style.paddingTop = styles.paddingTop
this.correctionPanel.style.paddingRight = styles.paddingRight this.correctionPanel.style.paddingRight = styles.paddingRight
this.scrollPanel.style.width = `${this.textElement.scrollWidth}px` this.correctionPanel.style.paddingBottom = styles.paddingBottom
this.scrollPanel.style.height = `${this.textElement.scrollHeight}px` this.scrollPanel.style.width = `${this.hostElement.scrollWidth}px`
const hStyles = this.scrollPanel.style.height = `${this.hostElement.scrollHeight}px`
this.hostElement !== this.textElement
? window.getComputedStyle(this.hostElement)
: styles
if (this.isHostElementInline()) { if (this.isHostElementInline()) {
const totalWidth = const totalWidth =
parseFloat(styles.paddingLeft) + parseFloat(styles.paddingLeft) +
@ -357,14 +345,10 @@ class BesService {
parseFloat(styles.marginRight) + parseFloat(styles.marginRight) +
parseFloat(styles.paddingRight) parseFloat(styles.paddingRight)
this.correctionPanel.style.width = `${totalWidth}px` this.correctionPanel.style.width = `${totalWidth}px`
this.correctionPanel.style.height = hStyles.height this.correctionPanel.style.height = styles.height
} else { } else {
this.correctionPanel.style.width = styles.width this.correctionPanel.style.width = styles.width
const totalHeight = this.correctionPanel.style.height = styles.height
parseFloat(styles.height) +
parseFloat(styles.paddingTop) +
parseFloat(styles.paddingBottom)
this.correctionPanel.style.height = `${totalHeight}px`
} }
} }
@ -1584,7 +1568,6 @@ class BesTAService extends BesPlainTextService {
static createTextElement(hostElement) { static createTextElement(hostElement) {
const textElement = document.createElement('div') const textElement = document.createElement('div')
textElement.classList.add('bes-text-panel') textElement.classList.add('bes-text-panel')
textElement.style.zIndex = hostElement.style.zIndex - 1
BesTAService.setTextElementSize(hostElement, textElement) BesTAService.setTextElementSize(hostElement, textElement)
hostElement.parentNode.insertBefore(textElement, hostElement) hostElement.parentNode.insertBefore(textElement, hostElement)
return textElement return textElement
@ -1592,8 +1575,6 @@ class BesTAService extends BesPlainTextService {
/** /**
* Sets the size of the clone div element to match the <textarea> element * Sets the size of the clone div element to match the <textarea> element
* TODO: This method should sync text element size only. Add another method for keeping styles in
* sync using MutationObserver.
* *
* @param {Element} hostElement The element in DOM tree we are providing grammar-checking service * @param {Element} hostElement The element in DOM tree we are providing grammar-checking service
* for * for
@ -1607,16 +1588,19 @@ class BesTAService extends BesPlainTextService {
const scrollLeft = window.scrollX || document.documentElement.scrollLeft const scrollLeft = window.scrollX || document.documentElement.scrollLeft
const styles = window.getComputedStyle(hostElement) const styles = window.getComputedStyle(hostElement)
textElement.style.zIndex = hostElement.style.zIndex - 1
textElement.style.fontSize = styles.fontSize textElement.style.fontSize = styles.fontSize
textElement.style.fontFamily = styles.fontFamily textElement.style.fontFamily = styles.fontFamily
textElement.style.lineHeight = styles.lineHeight textElement.style.lineHeight = styles.lineHeight
textElement.style.whiteSpace = styles.whiteSpace textElement.style.whiteSpace = styles.whiteSpace
textElement.style.whiteSpaceCollapse = styles.whiteSpaceCollapse textElement.style.whiteSpaceCollapse = styles.whiteSpaceCollapse
textElement.style.hyphens = styles.hyphens textElement.style.hyphens = styles.hyphens
textElement.style.margin = styles.margin
textElement.style.border = styles.border textElement.style.border = styles.border
textElement.style.borderRadius = styles.borderRadius textElement.style.borderRadius = styles.borderRadius
textElement.style.padding = styles.padding textElement.style.paddingLeft = styles.paddingLeft
textElement.style.paddingTop = styles.paddingTop
textElement.style.paddingRight = styles.paddingRight
textElement.style.paddingBottom = styles.paddingBottom
textElement.style.height = styles.height textElement.style.height = styles.height
textElement.style.minHeight = styles.minHeight textElement.style.minHeight = styles.minHeight
textElement.style.maxHeight = styles.maxHeight textElement.style.maxHeight = styles.maxHeight

View File

@ -41,6 +41,7 @@
.bes-text-panel { .bes-text-panel {
position: absolute; position: absolute;
margin: 0px;
color: transparent; color: transparent;
border-color: transparent; border-color: transparent;
background: none; background: none;