diff --git a/service.js b/service.js index a3fa1f3..0e3026d 100644 --- a/service.js +++ b/service.js @@ -41,7 +41,7 @@ class BesService { this.enabledCategories = [] this.disabledCategories = [] this.results = [] // Results of grammar-checking, one per each block/paragraph of text - this.highlightedRects = [] + this.highlightElements = [] this.createCorrectionPanel() // Disable browser built-in spell-checker to prevent collision with our grammar markup. @@ -58,7 +58,7 @@ class BesService { this.hostElement.setAttribute('data-gramm', 'false') this.hostElement.setAttribute('data-gramm_editor', 'false') this.hostElement.setAttribute('data-enable-grammarly', 'false') - this.textFont = window.getComputedStyle(this.textElement).fontFamily + this.textFont = window.getComputedStyle(this.hostElement).fontFamily this.onScroll = this.onScroll.bind(this) this.hostElement.addEventListener('scroll', this.onScroll) @@ -334,8 +334,8 @@ class BesService { const dpr = window.devicePixelRatio this.ctx.lineWidth = 2 * dpr // Use 2 for clearer visibility this.ctx.strokeStyle = ruleId.startsWith('MORFOLOGIK_RULE') - ? '#ff7300' - : '#007bff' + ? 'rgba(255, 115, 0, 0.5)' + : 'rgba(0, 123, 255, 0.5)' for (let rect of range.getClientRects()) { const x = (rect.left - scrollPanelRect.left) * dpr const y = (rect.top - scrollPanelRect.top) * dpr @@ -455,7 +455,9 @@ class BesService { * @param {PointerEvent} source Click event source */ popupCorrectionPanel(el, match, source) { + this.dismissPopup() const popup = document.querySelector('bes-popup-el') + // TODO: popup.setContent(elements, matches, this, this.isContentEditable()) popup.changeMessage(match.match.message) popup.appendReplacements(el, match, this, this.isContentEditable()) this.highlightMistake(match) @@ -469,27 +471,32 @@ class BesService { */ highlightMistake(match) { // TODO: Če sta 2 napaki v istem rectu, se prikaže samo zgornja/zadnja (oz. tista, ki jo uporabnik klikne). To pa pomeni, da se lahko podčrtana barva razlikuje od "highlight" barve. - const highlightColor = match.match.rule.id.startsWith('MORFOLOGIK_RULE') - ? '#ff7300' - : '#007bff' - - match.highlights.forEach(highlight => { - const rect = highlight - const highlightElement = document.createElement('div') - highlightElement.classList.add('highlight-rect') - highlightElement.style.position = 'absolute' - highlightElement.style.left = `${rect.x}px` - highlightElement.style.top = `${rect.y}px` - highlightElement.style.width = `${rect.width}px` - highlightElement.style.height = `${rect.height}px` - highlightElement.style.backgroundColor = highlightColor - highlightElement.style.opacity = '0.5' - highlightElement.style.cursor = 'text' - document.body.appendChild(highlightElement) - this.highlightedRects.push(highlightElement) + match.highlights.forEach(rect => { + const el = document.createElement('div') + el.classList.add('bes-highlight-rect') + el.classList.add( + match.match.rule.id.startsWith('MORFOLOGIK_RULE') + ? 'bes-highlight-spelling-rect' + : 'bes-highlight-grammar-rect' + ) + el.style.left = `${rect.x}px` + el.style.top = `${rect.y}px` + el.style.width = `${rect.width}px` + el.style.height = `${rect.height}px` + document.body.appendChild(el) + this.highlightElements.push(el) }) } + /** + * Clears highlight and hides popup + */ + dismissPopup() { + BesPopup.hide() + this.highlightElements.forEach(el => el.remove()) + this.highlightElements = [] + } + /** * Checks if host element content is editable. * @@ -764,34 +771,10 @@ class BesTreeService extends BesService { * @param {Element} el DOM element for removal */ clearProofing(el) { - this.clearMarkup(el) this.results = this.results.filter( result => !BesTreeService.isSameParagraph(result.element, el) ) - } - - /** - * Clears given block element grammar mistake markup. - * - * @param {Element} el DOM element we want to clean markup for - */ - clearMarkup(el) { - const dpr = window.devicePixelRatio - this.results - .filter(result => BesTreeService.isSameParagraph(result.element, el)) - .forEach(result => { - let sourceRect = result.element.getBoundingClientRect() - let targetRect = this.canvasPanel.getBoundingClientRect() - let newX = sourceRect.left - targetRect.left - let newY = sourceRect.top - targetRect.top - this.ctx.clearRect( - newX * dpr, - newY * dpr, - sourceRect.width * dpr, - sourceRect.height * dpr - ) - delete result.matches - }) + this.repositionAllMarkup() } /** @@ -930,16 +913,15 @@ class BesTreeService extends BesService { for (let result of this.results) { for (let m of result.matches) { - for (let h of m.highlights) { - if (BesService.isPointInRect(source.clientX, source.clientY, h)) { + for (let rect of m.highlights) { + if (BesService.isPointInRect(source.clientX, source.clientY, rect)) { this.popupCorrectionPanel(el, m, source) return } } } } - BesPopup.hide() - this.highlightedRects.forEach(h => h.remove()) + this.dismissPopup() } } @@ -1024,8 +1006,7 @@ class BesDOMService extends BesTreeService { onInput() { // Now that the text is done changing, we can correctly calculate markup position. this.repositionAllMarkup() - BesPopup.hide() - this.highlightedRects.forEach(h => h.remove()) + this.dismissPopup() // Defer grammar-checking to reduce stress on grammar-checking server. this.scheduleProofing(1000) } @@ -1536,30 +1517,10 @@ class BesPlainTextService extends BesService { * @param {Range} range Paragraph range */ clearProofing(range) { - this.clearMarkup(range) this.results = this.results.filter( result => !BesPlainTextService.isSameParagraph(result.range, range) ) - } - - /** - * Clears given paragraph grammar mistake markup. - * - * @param {Range} range Paragraph range - */ - clearMarkup(range) { - this.results - .filter(result => - BesPlainTextService.isSameParagraph(result.range, range) - ) - .forEach(result => - result.matches.forEach(match => { - if (match.highlights) { - match.highlights.forEach(h => h.remove()) - delete match.highlights - } - }) - ) + this.repositionAllMarkup() } /** @@ -1605,16 +1566,15 @@ class BesPlainTextService extends BesService { for (let result of this.results) { for (let m of result.matches) { - for (let h of m.highlights) { - if (BesService.isPointInRect(source.clientX, source.clientY, h)) { + for (let rect of m.highlights) { + if (BesService.isPointInRect(source.clientX, source.clientY, rect)) { this.popupCorrectionPanel(result.range, m, source) return } } } } - BesPopup.hide() - this.highlightedRects.forEach(h => h.remove()) + this.dismissPopup() } /** @@ -1729,8 +1689,7 @@ class BesDOMPlainTextService extends BesPlainTextService { // Now that the text is done changing, we can correctly calculate markup position. this.repositionAllMarkup() - BesPopup.hide() - this.highlightedRects.forEach(h => h.remove()) + this.dismissPopup() // Defer grammar-checking to reduce stress on grammar-checking server. this.scheduleProofing(1000) } @@ -1862,28 +1821,21 @@ class BesTAService extends BesPlainTextService { const styles = window.getComputedStyle(hostElement) textElement.style.zIndex = hostElement.style.zIndex - 1 - textElement.style.fontSize = styles.fontSize - textElement.style.fontFamily = styles.fontFamily + textElement.style.font = styles.font textElement.style.lineHeight = styles.lineHeight textElement.style.whiteSpace = styles.whiteSpace textElement.style.whiteSpaceCollapse = styles.whiteSpaceCollapse textElement.style.hyphens = styles.hyphens + textElement.style.boxSizing = styles.boxSizing + textElement.style.scrollBehavior = styles.scrollBehavior + textElement.style.overflow = 'hidden' textElement.style.border = styles.border textElement.style.borderRadius = styles.borderRadius - 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.minHeight = styles.minHeight - textElement.style.maxHeight = styles.maxHeight - textElement.style.overflow = styles.overflow - textElement.style.overflowWrap = styles.overflowWrap - textElement.style.top = `${rect.top + scrollTop}px` + textElement.style.padding = styles.padding textElement.style.left = `${rect.left + scrollLeft}px` + textElement.style.top = `${rect.top + scrollTop}px` textElement.style.width = styles.width - textElement.style.minWidth = styles.minWidth - textElement.style.maxWidth = styles.maxWidth + textElement.style.height = styles.height } /** @@ -2137,7 +2089,7 @@ class BesPopup extends HTMLElement {