Skip to content

Commit 728a4c2

Browse files
committed
Rewritten stickTo binding handler into behavior.
1 parent 08c458f commit 728a4c2

File tree

3 files changed

+7
-198
lines changed

3 files changed

+7
-198
lines changed

src/behaviors/hyperlinkBehavior.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import * as ko from "knockout";
22
import { HyperlinkModel } from "@paperbits/common/permalinks";
3-
import { HyperlinkBehavior } from "../../behaviors/hyperlinkBehavior";
3+
import { HyperlinkBehavior } from "@paperbits/common/behaviors/hyperlinkBehavior";
44

55
ko.bindingHandlers["hyperlink"] = {
66
update(element: HTMLElement, valueAccessor: () => HyperlinkModel): void {
77
const hyperlink: HyperlinkModel = valueAccessor();
88
const behavior = new HyperlinkBehavior();
99

1010
if (ko.isObservable(hyperlink)) {
11-
hyperlink.subscribe(newValue => behavior.apply(element, newValue));
11+
hyperlink.subscribe(newValue => behavior.attach(element, newValue));
1212
}
1313

1414
const initial = ko.unwrap(hyperlink);
15-
behavior.apply(element, initial);
15+
behavior.attach(element, initial);
1616
}
1717
};

src/ko/bindingHandlers/bindingHandlers.stickTo.ts

Lines changed: 4 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,150 +1,17 @@
11
import * as ko from "knockout";
2-
import { ViewManager, ViewManagerMode } from "@paperbits/common/ui";
3-
import { Events } from "@paperbits/common/events";
2+
import { ViewManager } from "@paperbits/common/ui";
3+
import { StickToBehavior, StickToConfig } from "@paperbits/common/behaviors/behavior.stickTo";
44

5-
export enum StickToPlacement {
6-
border = "border",
7-
outside = "outside"
8-
}
9-
10-
export interface StickToConfig {
11-
/**
12-
* Target element.
13-
*/
14-
target: HTMLElement;
15-
16-
/**
17-
* Element position, e.g. `top`, `bottom`, `left`, `right`, `center`.
18-
*/
19-
position: string;
20-
21-
/**
22-
* border (default), outside
23-
*/
24-
placement: StickToPlacement;
25-
26-
/**
27-
* Horizontal offset from the assigned position.
28-
*/
29-
offsetX: number;
30-
31-
/**
32-
* Vertical offset from the assigned position.
33-
*/
34-
offsetY: number;
35-
}
365

376
export class StickToBindingHandler {
387
constructor(viewManager: ViewManager) {
398
ko.bindingHandlers["stickTo"] = {
409
init(element: HTMLElement, valueAccessor: () => StickToConfig): void {
4110
const config = valueAccessor();
42-
43-
const updatePosition = () => {
44-
if (!config.target) {
45-
return;
46-
}
47-
48-
if (viewManager.mode !== ViewManagerMode.selecting && viewManager.mode !== ViewManagerMode.selected) {
49-
return;
50-
}
51-
52-
const frameElement = config.target.ownerDocument.defaultView.frameElement;
53-
54-
if (!frameElement) {
55-
return;
56-
}
57-
58-
const offsetX = config.offsetX || 0;
59-
const offsetY = config.offsetY || 0;
60-
const anchors = config.position.split(" ");
61-
62-
const frameRect = frameElement.getBoundingClientRect();
63-
const targetRect = config.target.getBoundingClientRect();
64-
65-
const placement = config.placement || StickToPlacement.border;
66-
let coordX: number;
67-
let coordY: number;
68-
69-
element.style.right = null;
70-
element.style.left = null;
71-
72-
coordX = targetRect.left + Math.floor((targetRect.width) / 2) - Math.floor(element.clientWidth / 2);
73-
coordY = targetRect.top + Math.floor((targetRect.height) / 2) - Math.floor(element.clientHeight / 2);
74-
75-
if (anchors.includes("top")) {
76-
coordY = targetRect.top - offsetY;
77-
78-
switch (placement) {
79-
case StickToPlacement.border:
80-
coordY = coordY - Math.floor(element.clientHeight / 2);
81-
break;
82-
83-
case StickToPlacement.outside:
84-
coordY = coordY - element.clientHeight;
85-
break;
86-
}
87-
88-
if (coordY < 0) { // keeping the element within viewport
89-
coordY = 0
90-
}
91-
}
92-
93-
if (anchors.includes("bottom")) {
94-
coordY = targetRect.top + offsetY + targetRect.height - element.clientHeight;
95-
96-
switch (placement) {
97-
case StickToPlacement.border:
98-
coordY = coordY + Math.floor(element.clientHeight / 2);
99-
break;
100-
101-
case StickToPlacement.outside:
102-
coordY = coordY + element.clientHeight;
103-
break;
104-
}
105-
}
106-
107-
element.style.top = frameRect.top + coordY + "px";
108-
109-
if (anchors.includes("left")) {
110-
element.style.left = frameRect.left + targetRect.left + offsetX + "px";
111-
}
112-
else if (anchors.includes("right")) {
113-
element.style.right = frameRect.right - targetRect.right + offsetX + "px";
114-
}
115-
else {
116-
element.style.left = frameRect.left + coordX + "px";
117-
}
118-
119-
if (anchors.includes("parent-left")) {
120-
if (!config.target.parentElement) {
121-
return;
122-
}
123-
124-
const targetParentRect = config.target.parentElement.getBoundingClientRect();
125-
element.style.left = targetParentRect.left - Math.floor(element.clientWidth / 2) + "px";
126-
}
127-
128-
if (anchors.includes("parent-top")) {
129-
if (!config.target.parentElement) {
130-
return;
131-
}
132-
133-
const targetParentRect = config.target.parentElement.getBoundingClientRect();
134-
element.style.top = targetParentRect.top - Math.floor(element.clientHeight / 2) + "px";
135-
}
136-
};
137-
138-
updatePosition();
139-
140-
const onScroll = async (event: MouseEvent): Promise<void> => {
141-
requestAnimationFrame(updatePosition);
142-
};
143-
144-
window.addEventListener(Events.Scroll, onScroll, true);
11+
const handle = StickToBehavior.attach(element, config, viewManager);
14512

14613
ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
147-
window.removeEventListener(Events.Scroll, onScroll, true);
14+
handle.detach();
14815
});
14916
}
15017
};

0 commit comments

Comments
 (0)