Skip to content

Commit 229672e

Browse files
authored
feat(mvc.$): update methods for better backwards compatibility (#2471)
1 parent 0e6d464 commit 229672e

File tree

10 files changed

+471
-36
lines changed

10 files changed

+471
-36
lines changed

packages/joint-core/src/mvc/Dom/Dom.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ $.event.dispatch = function(nativeEvent) {
519519
}
520520

521521
return event.result;
522-
},
522+
};
523523

524524
$.event.handlers = function(event, handlers) {
525525

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import $ from './Dom.mjs';
2+
import { dataPriv } from './vars.mjs';
3+
4+
const animationKey = 'animationFrameId';
5+
const cssReset = {};
6+
7+
cssReset['transition-property'] =
8+
cssReset['transition-duration'] =
9+
cssReset['transition-delay'] =
10+
cssReset['transition-timing-function'] =
11+
cssReset['animation-name'] =
12+
cssReset['animation-duration'] =
13+
cssReset['animation-delay'] =
14+
cssReset['animation-timing-function'] = '';
15+
16+
export function animate(properties, opt = {}) {
17+
this.stop();
18+
for (let i = 0; i < this.length; i++) {
19+
animateNode(this[i], properties, opt);
20+
}
21+
return this;
22+
}
23+
24+
function animateNode(el, properties, opt = {}) {
25+
26+
let {
27+
duration = 400,
28+
easing = 'ease-in-out',
29+
delay = 0,
30+
complete
31+
} = opt;
32+
33+
const delayId = setTimeout(function() {
34+
35+
const $el = $(el);
36+
let fired = false;
37+
let endEvent = 'transitionend';
38+
39+
// Convert milliseconds to seconds for CSS
40+
duration = duration / 1000;
41+
delay = delay / 1000;
42+
43+
// Set up CSS values for transition or keyframe animation
44+
const cssValues = {};
45+
if (typeof properties === 'string') {
46+
// Keyframe animation
47+
cssValues['animation-name'] = properties;
48+
cssValues['animation-duration'] = duration + 's';
49+
cssValues['animation-delay'] = delay + 's';
50+
cssValues['animation-timing-function'] = easing;
51+
endEvent = 'animationend';
52+
} else {
53+
// CSS transitions
54+
const transitionProperties = [];
55+
for (var key in properties) {
56+
if (properties.hasOwnProperty(key)) {
57+
cssValues[key] = properties[key];
58+
transitionProperties.push(key);
59+
}
60+
}
61+
62+
if (duration > 0) {
63+
cssValues['transition-property'] = transitionProperties.join(', ');
64+
cssValues['transition-duration'] = duration + 's';
65+
cssValues['transition-delay'] = delay + 's';
66+
cssValues['transition-timing-function'] = easing;
67+
}
68+
}
69+
70+
const wrappedCallback = function(event){
71+
if (event) {
72+
if (event.target !== event.currentTarget) return; // makes sure the event didn't bubble from "below"
73+
event.target.removeEventListener(endEvent, wrappedCallback);
74+
} else {
75+
el.removeEventListener(endEvent, wrappedCallback); // triggered by setTimeout
76+
}
77+
fired = true;
78+
$el.css(cssReset);
79+
complete && complete.call(el);
80+
};
81+
82+
if (duration > 0){
83+
el.addEventListener(endEvent, wrappedCallback);
84+
// transitionEnd is not always firing on older Android phones
85+
// so make sure it gets fired
86+
const callbackId = setTimeout(function() {
87+
if (fired) return;
88+
wrappedCallback(null);
89+
}, ((duration + delay) * 1000) + 25);
90+
91+
dataPriv.set(el, animationKey, {
92+
id: callbackId,
93+
stop: () => {
94+
clearTimeout(callbackId);
95+
el.removeEventListener(endEvent, wrappedCallback);
96+
}
97+
});
98+
}
99+
100+
$el.css(cssValues);
101+
102+
if (duration <= 0) {
103+
wrappedCallback(null);
104+
}
105+
});
106+
107+
dataPriv.set(el, animationKey, {
108+
stop: () => clearTimeout(delayId)
109+
});
110+
}
111+
112+
export function stop() {
113+
for (let i = 0; i < this.length; i++) {
114+
const el = this[i];
115+
const animation = dataPriv.get(el, animationKey);
116+
if (!animation) continue;
117+
animation.stop();
118+
dataPriv.remove(el, animationKey);
119+
}
120+
this.css(cssReset);
121+
return this;
122+
}

packages/joint-core/src/mvc/Dom/events.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import $ from './Dom.mjs';
55

66
// Special events
77

8-
export const special = Object.create(null);
8+
const special = Object.create(null);
9+
10+
export default special;
911

1012
special.load = {
1113
// Prevent triggered image.load events from bubbling to window.load

packages/joint-core/src/mvc/Dom/index.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { default as $ } from './Dom.mjs';
22
import * as methods from './methods.mjs';
3-
import { special } from './events.mjs';
3+
import * as animations from './animations.mjs';
4+
import { default as props } from './props.mjs';
5+
import { default as special } from './events.mjs';
46

57
Object.assign($.fn, methods);
8+
Object.assign($.fn, animations);
9+
Object.assign($.fn, props);
610
Object.assign($.event.special, special);
711

812
export default $;

0 commit comments

Comments
 (0)