Skip to content

Commit

Permalink
fix area update propagation (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaultJanBeyer authored Oct 26, 2024
2 parents ed1457c + a812c20 commit 422b4e7
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 324 deletions.
4 changes: 4 additions & 0 deletions DragSelect/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 3.1.1

- Fix for [#231](https://github.com/ThibaultJanBeyer/DragSelect/issues/231) where the Area would alert everyone on any update, but we actually only care about certain position values

# 3.1.0

- Add `useLayers` option to enable/disable the `z-index` manipulation on drag/select of nodes. Thanks to [@digitalclubb](https://github.com/digitalclubb) for the contributing PR [#234](https://github.com/ThibaultJanBeyer/DragSelect/pull/234)
Expand Down
2 changes: 1 addition & 1 deletion DragSelect/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dragselect",
"version": "3.1.0",
"version": "3.1.1",
"description": "Easy JavaScript library for selecting and moving elements. With no dependencies. Drag-Select & Drag-And-Drop.",
"main": "./dist/DragSelect.js",
"module": "./dist/DragSelect.esm.js",
Expand Down
9 changes: 6 additions & 3 deletions DragSelect/src/methods/handleElementPositionAttribute.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { DSArea } from "../types"
import { DSArea } from '../types'

type Props = {
computedStyle: CSSStyleDeclaration
computedStyle: { position: CSSStyleDeclaration['position'] }
node: DSArea
}

/** Fix: some elements have to have a special position attribute for calculations */
export const handleElementPositionAttribute = ({ computedStyle, node }: Props) => {
export const handleElementPositionAttribute = ({
computedStyle,
node,
}: Props) => {
const { position } = computedStyle
const isPositioned =
position === 'absolute' || position === 'relative' || position === 'fixed'
Expand Down
47 changes: 43 additions & 4 deletions DragSelect/src/modules/Area.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ export default class Area<E extends DSInputElement> {
private _observers?: { cleanup: () => void }
private _node: DSArea
private _parentNodes?: Node[]
private _computedStyle?: CSSStyleDeclaration
private _computedStyle?: {
borderTopWidth: CSSStyleDeclaration['borderTopWidth']
borderBottomWidth: CSSStyleDeclaration['borderBottomWidth']
borderLeftWidth: CSSStyleDeclaration['borderLeftWidth']
borderRightWidth: CSSStyleDeclaration['borderRightWidth']
position: CSSStyleDeclaration['position']
}
private _computedBorder?: DSEdgesObj
private _rect?: DSBoundingRect

Expand Down Expand Up @@ -92,13 +98,38 @@ export default class Area<E extends DSInputElement> {
this._observers = addModificationObservers(
this.parentNodes,
debounce((event: MutationCallbackEvent) => {
if (!this.hasRelevantBeenModified()) return
this.PS.publish('Area:modified:pre', { event, item: this.HTMLNode })
this.reset()
this.PS.publish('Area:modified', { event, item: this.HTMLNode })
}, 60)
)
}

// Check whether the for us relevant values have been changed before making a fuzz
private hasRelevantBeenModified = () => {
const prevComputedStyle = this.computedStyle
const prevRect = this.rect
const prevComputedBorder = this.computedBorder
const prevParentNodes = this.parentNodes
this.reset()
if (
JSON.stringify(prevComputedStyle) !== JSON.stringify(this.computedStyle)
)
return true
if (JSON.stringify(prevRect) !== JSON.stringify(this.rect)) return true
if (
JSON.stringify(prevComputedBorder) !== JSON.stringify(this.computedBorder)
)
return true
if (
prevParentNodes.length !== this.parentNodes.length &&
prevParentNodes.some((el) => !this.parentNodes.includes(el))
)
return true
return false
}

private reset = () => {
this._computedStyle = undefined
this._rect = undefined
Expand Down Expand Up @@ -146,11 +177,19 @@ export default class Area<E extends DSInputElement> {
/** The computed styles from the element (caches result) */
private get computedStyle() {
if (this._computedStyle) return this._computedStyle
let tempStyles
if (this.HTMLNode instanceof Document)
return (this._computedStyle = window.getComputedStyle(
tempStyles = window.getComputedStyle(
this.HTMLNode.body || this.HTMLNode.documentElement
))
return (this._computedStyle = window.getComputedStyle(this.HTMLNode!))
)
else tempStyles = window.getComputedStyle(this.HTMLNode!)
return (this._computedStyle = {
borderTopWidth: tempStyles.borderTopWidth,
borderBottomWidth: tempStyles.borderBottomWidth,
borderLeftWidth: tempStyles.borderLeftWidth,
borderRightWidth: tempStyles.borderRightWidth,
position: tempStyles.position,
})
}

/** The element rect (caches result) (without scrollbar or borders) */
Expand Down
Loading

0 comments on commit 422b4e7

Please sign in to comment.