@joint/core 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +376 -0
- package/README.md +49 -0
- package/dist/geometry.js +6486 -0
- package/dist/geometry.min.js +8 -0
- package/dist/joint.d.ts +5536 -0
- package/dist/joint.js +39629 -0
- package/dist/joint.min.js +8 -0
- package/dist/joint.nowrap.js +39626 -0
- package/dist/joint.nowrap.min.js +8 -0
- package/dist/vectorizer.js +9135 -0
- package/dist/vectorizer.min.js +8 -0
- package/dist/version.mjs +3 -0
- package/index.js +3 -0
- package/joint.mjs +27 -0
- package/package.json +192 -0
- package/src/V/annotation.mjs +0 -0
- package/src/V/index.mjs +2642 -0
- package/src/anchors/index.mjs +123 -0
- package/src/config/index.mjs +12 -0
- package/src/connectionPoints/index.mjs +202 -0
- package/src/connectionStrategies/index.mjs +73 -0
- package/src/connectors/curve.mjs +553 -0
- package/src/connectors/index.mjs +6 -0
- package/src/connectors/jumpover.mjs +452 -0
- package/src/connectors/normal.mjs +12 -0
- package/src/connectors/rounded.mjs +17 -0
- package/src/connectors/smooth.mjs +44 -0
- package/src/connectors/straight.mjs +110 -0
- package/src/dia/Cell.mjs +945 -0
- package/src/dia/CellView.mjs +1316 -0
- package/src/dia/Element.mjs +519 -0
- package/src/dia/ElementView.mjs +859 -0
- package/src/dia/Graph.mjs +1112 -0
- package/src/dia/HighlighterView.mjs +319 -0
- package/src/dia/Link.mjs +565 -0
- package/src/dia/LinkView.mjs +2207 -0
- package/src/dia/Paper.mjs +3171 -0
- package/src/dia/PaperLayer.mjs +75 -0
- package/src/dia/ToolView.mjs +69 -0
- package/src/dia/ToolsView.mjs +128 -0
- package/src/dia/attributes/calc.mjs +128 -0
- package/src/dia/attributes/connection.mjs +75 -0
- package/src/dia/attributes/defs.mjs +76 -0
- package/src/dia/attributes/eval.mjs +64 -0
- package/src/dia/attributes/index.mjs +69 -0
- package/src/dia/attributes/legacy.mjs +148 -0
- package/src/dia/attributes/offset.mjs +53 -0
- package/src/dia/attributes/props.mjs +30 -0
- package/src/dia/attributes/shape.mjs +92 -0
- package/src/dia/attributes/text.mjs +180 -0
- package/src/dia/index.mjs +13 -0
- package/src/dia/layers/GridLayer.mjs +176 -0
- package/src/dia/ports.mjs +874 -0
- package/src/elementTools/Control.mjs +153 -0
- package/src/elementTools/HoverConnect.mjs +37 -0
- package/src/elementTools/index.mjs +5 -0
- package/src/env/index.mjs +43 -0
- package/src/g/bezier.mjs +175 -0
- package/src/g/curve.mjs +956 -0
- package/src/g/ellipse.mjs +245 -0
- package/src/g/extend.mjs +64 -0
- package/src/g/geometry.helpers.mjs +58 -0
- package/src/g/index.mjs +17 -0
- package/src/g/intersection.mjs +511 -0
- package/src/g/line.bearing.mjs +30 -0
- package/src/g/line.length.mjs +5 -0
- package/src/g/line.mjs +356 -0
- package/src/g/line.squaredLength.mjs +10 -0
- package/src/g/path.mjs +2260 -0
- package/src/g/point.mjs +375 -0
- package/src/g/points.mjs +247 -0
- package/src/g/polygon.mjs +51 -0
- package/src/g/polyline.mjs +523 -0
- package/src/g/rect.mjs +556 -0
- package/src/g/types.mjs +10 -0
- package/src/highlighters/addClass.mjs +27 -0
- package/src/highlighters/index.mjs +5 -0
- package/src/highlighters/list.mjs +111 -0
- package/src/highlighters/mask.mjs +220 -0
- package/src/highlighters/opacity.mjs +17 -0
- package/src/highlighters/stroke.mjs +100 -0
- package/src/layout/index.mjs +4 -0
- package/src/layout/ports/port.mjs +188 -0
- package/src/layout/ports/portLabel.mjs +224 -0
- package/src/linkAnchors/index.mjs +76 -0
- package/src/linkTools/Anchor.mjs +235 -0
- package/src/linkTools/Arrowhead.mjs +103 -0
- package/src/linkTools/Boundary.mjs +48 -0
- package/src/linkTools/Button.mjs +121 -0
- package/src/linkTools/Connect.mjs +85 -0
- package/src/linkTools/HoverConnect.mjs +161 -0
- package/src/linkTools/Segments.mjs +393 -0
- package/src/linkTools/Vertices.mjs +253 -0
- package/src/linkTools/helpers.mjs +33 -0
- package/src/linkTools/index.mjs +8 -0
- package/src/mvc/Collection.mjs +560 -0
- package/src/mvc/Data.mjs +46 -0
- package/src/mvc/Dom/Dom.mjs +587 -0
- package/src/mvc/Dom/Event.mjs +130 -0
- package/src/mvc/Dom/animations.mjs +122 -0
- package/src/mvc/Dom/events.mjs +69 -0
- package/src/mvc/Dom/index.mjs +13 -0
- package/src/mvc/Dom/methods.mjs +392 -0
- package/src/mvc/Dom/props.mjs +77 -0
- package/src/mvc/Dom/vars.mjs +5 -0
- package/src/mvc/Events.mjs +337 -0
- package/src/mvc/Listener.mjs +33 -0
- package/src/mvc/Model.mjs +239 -0
- package/src/mvc/View.mjs +323 -0
- package/src/mvc/ViewBase.mjs +182 -0
- package/src/mvc/index.mjs +9 -0
- package/src/mvc/mvcUtils.mjs +90 -0
- package/src/polyfills/array.js +4 -0
- package/src/polyfills/base64.js +68 -0
- package/src/polyfills/index.mjs +5 -0
- package/src/polyfills/number.js +3 -0
- package/src/polyfills/string.js +3 -0
- package/src/polyfills/typedArray.js +47 -0
- package/src/routers/index.mjs +6 -0
- package/src/routers/manhattan.mjs +856 -0
- package/src/routers/metro.mjs +91 -0
- package/src/routers/normal.mjs +6 -0
- package/src/routers/oneSide.mjs +60 -0
- package/src/routers/orthogonal.mjs +323 -0
- package/src/routers/rightAngle.mjs +1056 -0
- package/src/shapes/index.mjs +3 -0
- package/src/shapes/standard.mjs +755 -0
- package/src/util/cloneCells.mjs +67 -0
- package/src/util/getRectPoint.mjs +65 -0
- package/src/util/index.mjs +5 -0
- package/src/util/svgTagTemplate.mjs +110 -0
- package/src/util/util.mjs +1754 -0
- package/src/util/utilHelpers.mjs +2402 -0
- package/src/util/wrappers.mjs +56 -0
- package/types/geometry.d.ts +815 -0
- package/types/index.d.ts +53 -0
- package/types/joint.d.ts +4391 -0
- package/types/joint.head.d.ts +12 -0
- package/types/vectorizer.d.ts +327 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// TODO: should not read config outside the mvc package
|
|
2
|
+
import { config } from '../../config/index.mjs';
|
|
3
|
+
import $ from './Dom.mjs';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// Special events
|
|
7
|
+
|
|
8
|
+
const special = Object.create(null);
|
|
9
|
+
|
|
10
|
+
export default special;
|
|
11
|
+
|
|
12
|
+
special.load = {
|
|
13
|
+
// Prevent triggered image.load events from bubbling to window.load
|
|
14
|
+
noBubble: true,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Create mouseenter/leave events using mouseover/out and event-time checks
|
|
18
|
+
// so that event delegation works in $.
|
|
19
|
+
// Do the same for pointerenter/pointerleave and pointerover/pointerout
|
|
20
|
+
[
|
|
21
|
+
['mouseenter', 'mouseover'],
|
|
22
|
+
['mouseleave', 'mouseout'],
|
|
23
|
+
['pointerenter', 'pointerover'],
|
|
24
|
+
['pointerleave', 'pointerout'],
|
|
25
|
+
].forEach(([orig, fix]) => {
|
|
26
|
+
special[orig] = {
|
|
27
|
+
delegateType: fix,
|
|
28
|
+
bindType: fix,
|
|
29
|
+
handle: function(event) {
|
|
30
|
+
const target = this;
|
|
31
|
+
const related = event.relatedTarget;
|
|
32
|
+
const handleObj = event.handleObj;
|
|
33
|
+
let ret;
|
|
34
|
+
// For mouseenter/leave call the handler if related is outside the target.
|
|
35
|
+
// NB: No relatedTarget if the mouse left/entered the browser window
|
|
36
|
+
if (!related || !target.contains(related)) {
|
|
37
|
+
event.type = handleObj.origType;
|
|
38
|
+
ret = handleObj.handler.apply(target, arguments);
|
|
39
|
+
event.type = fix;
|
|
40
|
+
}
|
|
41
|
+
return ret;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
// Gestures
|
|
48
|
+
|
|
49
|
+
const maxDelay = config.doubleTapInterval;
|
|
50
|
+
const minDelay = 30;
|
|
51
|
+
|
|
52
|
+
special.dbltap = {
|
|
53
|
+
bindType: 'touchend',
|
|
54
|
+
delegateType: 'touchend',
|
|
55
|
+
handle: function(event, ...args) {
|
|
56
|
+
const { handleObj, target } = event;
|
|
57
|
+
const targetData = $.data.create(target);
|
|
58
|
+
const now = new Date().getTime();
|
|
59
|
+
const delta = 'lastTouch' in targetData ? now - targetData.lastTouch : 0;
|
|
60
|
+
if (delta < maxDelay && delta > minDelay) {
|
|
61
|
+
targetData.lastTouch = null;
|
|
62
|
+
event.type = handleObj.origType;
|
|
63
|
+
// let $ handle the triggering of "dbltap" event handlers
|
|
64
|
+
handleObj.handler.call(this, event, ...args);
|
|
65
|
+
} else {
|
|
66
|
+
targetData.lastTouch = now;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { default as $ } from './Dom.mjs';
|
|
2
|
+
import * as methods from './methods.mjs';
|
|
3
|
+
import * as animations from './animations.mjs';
|
|
4
|
+
import { default as props } from './props.mjs';
|
|
5
|
+
import { default as special } from './events.mjs';
|
|
6
|
+
|
|
7
|
+
Object.assign($.fn, methods);
|
|
8
|
+
Object.assign($.fn, animations);
|
|
9
|
+
Object.assign($.fn, props);
|
|
10
|
+
Object.assign($.event.special, special);
|
|
11
|
+
|
|
12
|
+
export default $;
|
|
13
|
+
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { camelCase } from '../../util/utilHelpers.mjs';
|
|
2
|
+
import $ from './Dom.mjs';
|
|
3
|
+
import V from '../../V/index.mjs';
|
|
4
|
+
import { dataPriv, dataUser } from './vars.mjs';
|
|
5
|
+
|
|
6
|
+
// Manipulation
|
|
7
|
+
|
|
8
|
+
function cleanNodesData(nodes) {
|
|
9
|
+
let i = nodes.length;
|
|
10
|
+
while (i--) cleanNodeData(nodes[i]);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function cleanNodeData(node) {
|
|
14
|
+
$.event.remove(node);
|
|
15
|
+
dataPriv.remove(node);
|
|
16
|
+
dataUser.remove(node);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function removeNodes(nodes) {
|
|
20
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
21
|
+
const node = nodes[i];
|
|
22
|
+
if (node.parentNode) {
|
|
23
|
+
node.parentNode.removeChild(node);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function remove() {
|
|
29
|
+
for (let i = 0; i < this.length; i++) {
|
|
30
|
+
const node = this[i];
|
|
31
|
+
cleanNodeData(node);
|
|
32
|
+
cleanNodesData(node.getElementsByTagName('*'));
|
|
33
|
+
}
|
|
34
|
+
removeNodes(this);
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function detach() {
|
|
39
|
+
removeNodes(this);
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function empty() {
|
|
44
|
+
for (let i = 0; i < this.length; i++) {
|
|
45
|
+
const node = this[i];
|
|
46
|
+
if (node.nodeType === 1) {
|
|
47
|
+
cleanNodesData(node.getElementsByTagName('*'));
|
|
48
|
+
// Remove any remaining nodes
|
|
49
|
+
node.textContent = '';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function clone() {
|
|
56
|
+
const clones = [];
|
|
57
|
+
for (let i = 0; i < this.length; i++) {
|
|
58
|
+
clones.push(this[i].cloneNode(true));
|
|
59
|
+
}
|
|
60
|
+
return this.pushStack(clones);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function html(html) {
|
|
64
|
+
const [el] = this;
|
|
65
|
+
if (!el) return null;
|
|
66
|
+
if (arguments.length === 0) return el.innerHTML;
|
|
67
|
+
if (html === undefined) return this; // do nothing
|
|
68
|
+
cleanNodesData(dataPriv, el.getElementsByTagName('*'));
|
|
69
|
+
if (typeof html === 'string' || typeof html === 'number') {
|
|
70
|
+
el.innerHTML = html;
|
|
71
|
+
} else {
|
|
72
|
+
el.innerHTML = '';
|
|
73
|
+
return this.append(html);
|
|
74
|
+
}
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function append(...nodes) {
|
|
79
|
+
const [parent] = this;
|
|
80
|
+
if (!parent) return this;
|
|
81
|
+
nodes.forEach((node) => {
|
|
82
|
+
if (!node) return;
|
|
83
|
+
if (typeof node === 'string') {
|
|
84
|
+
parent.append(...$.parseHTML(node));
|
|
85
|
+
} else if (node.toString() === '[object Object]') {
|
|
86
|
+
// $ object
|
|
87
|
+
this.append(...Array.from(node));
|
|
88
|
+
} else if (Array.isArray(node)) {
|
|
89
|
+
this.append(...node);
|
|
90
|
+
} else {
|
|
91
|
+
// DOM node
|
|
92
|
+
parent.appendChild(node);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function prepend(...nodes) {
|
|
99
|
+
const [parent] = this;
|
|
100
|
+
if (!parent) return this;
|
|
101
|
+
nodes.forEach((node) => {
|
|
102
|
+
if (!node) return;
|
|
103
|
+
if (typeof node === 'string') {
|
|
104
|
+
parent.prepend(...$.parseHTML(node));
|
|
105
|
+
} else if (node.toString() === '[object Object]') {
|
|
106
|
+
// $ object
|
|
107
|
+
this.prepend(...Array.from(node));
|
|
108
|
+
} else if (Array.isArray(node)) {
|
|
109
|
+
this.prepend(...node);
|
|
110
|
+
} else {
|
|
111
|
+
// DOM node
|
|
112
|
+
parent.insertBefore(node, parent.firstChild);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function appendTo(parent) {
|
|
119
|
+
$(parent).append(this);
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function prependTo(parent) {
|
|
124
|
+
$(parent).prepend(this);
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Styles and attributes
|
|
129
|
+
|
|
130
|
+
const requireUnits = {};
|
|
131
|
+
[
|
|
132
|
+
'width', 'height', 'top', 'bottom', 'left', 'right',
|
|
133
|
+
'padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight',
|
|
134
|
+
'margin', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight',
|
|
135
|
+
].forEach((cssProp) => {
|
|
136
|
+
requireUnits[cssProp] = true;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
function setCSSProperty(el, name, value) {
|
|
140
|
+
if (typeof value === 'number' && requireUnits[camelCase(name)]) {
|
|
141
|
+
value += 'px';
|
|
142
|
+
}
|
|
143
|
+
el.style[name] = value;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function css(name, value) {
|
|
147
|
+
let styles;
|
|
148
|
+
if (typeof name === 'string') {
|
|
149
|
+
if (value === undefined) {
|
|
150
|
+
const [el] = this;
|
|
151
|
+
if (!el) return null;
|
|
152
|
+
return el.style[name];
|
|
153
|
+
} else {
|
|
154
|
+
styles = { [name]: value };
|
|
155
|
+
}
|
|
156
|
+
} else if (!name) {
|
|
157
|
+
throw new Error('no styles provided');
|
|
158
|
+
} else {
|
|
159
|
+
styles = name;
|
|
160
|
+
}
|
|
161
|
+
for (let style in styles) {
|
|
162
|
+
if (styles.hasOwnProperty(style)) {
|
|
163
|
+
for (let i = 0; i < this.length; i++) {
|
|
164
|
+
setCSSProperty(this[i], style, styles[style]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return this;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function data(name, value) {
|
|
172
|
+
if (arguments.length < 2) {
|
|
173
|
+
const [el] = this;
|
|
174
|
+
if (!el) return null;
|
|
175
|
+
if (name === undefined) {
|
|
176
|
+
return el.dataset;
|
|
177
|
+
}
|
|
178
|
+
return el.dataset[name];
|
|
179
|
+
}
|
|
180
|
+
for (let i = 0; i < this.length; i++) {
|
|
181
|
+
this[i].dataset[name] = value;
|
|
182
|
+
}
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Classes
|
|
187
|
+
|
|
188
|
+
function setNodesClass(method, nodes, args) {
|
|
189
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
190
|
+
const node = nodes[i];
|
|
191
|
+
V.prototype[method].apply({ node }, args);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function removeClass() {
|
|
196
|
+
setNodesClass('removeClass', this, arguments);
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function addClass() {
|
|
201
|
+
setNodesClass('addClass', this, arguments);
|
|
202
|
+
return this;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function toggleClass() {
|
|
206
|
+
setNodesClass('toggleClass', this, arguments);
|
|
207
|
+
return this;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function hasClass() {
|
|
211
|
+
const [node] = this;
|
|
212
|
+
if (!node) return false;
|
|
213
|
+
return V.prototype.hasClass.apply({ node }, arguments);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Traversing
|
|
217
|
+
|
|
218
|
+
export function children(selector) {
|
|
219
|
+
const matches = [];
|
|
220
|
+
for(let i = 0; i < this.length; i++) {
|
|
221
|
+
const node = this[i];
|
|
222
|
+
let children = Array.from(node.children);
|
|
223
|
+
if (typeof selector === 'string') {
|
|
224
|
+
children = children.filter(child => child.matches(selector));
|
|
225
|
+
}
|
|
226
|
+
matches.push(...children);
|
|
227
|
+
}
|
|
228
|
+
return this.pushStack(matches);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function closest(selector) {
|
|
232
|
+
const closest = [];
|
|
233
|
+
for (let i = 0; i < this.length; i++) {
|
|
234
|
+
const el = this[i];
|
|
235
|
+
if (typeof selector === 'string') {
|
|
236
|
+
const closestEl = el.closest(selector);
|
|
237
|
+
if (closestEl) {
|
|
238
|
+
closest.push(closestEl);
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
const [ancestorEl] = $(selector);
|
|
242
|
+
if (ancestorEl && ancestorEl.contains(el)) {
|
|
243
|
+
closest.push(ancestorEl);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return this.pushStack(closest);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Events
|
|
251
|
+
|
|
252
|
+
export function on(types, selector, data, fn) {
|
|
253
|
+
$.event.on(this, types, selector, data, fn);
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function one(types, selector, data, fn) {
|
|
258
|
+
$.event.on(this, types, selector, data, fn, 1);
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function off(types, selector, fn) {
|
|
263
|
+
if (types && types.preventDefault && types.handleObj) {
|
|
264
|
+
// ( event ) dispatched $.Event
|
|
265
|
+
const handleObj = types.handleObj;
|
|
266
|
+
$(types.delegateTarget).off(
|
|
267
|
+
handleObj.namespace
|
|
268
|
+
? handleObj.origType + '.' + handleObj.namespace
|
|
269
|
+
: handleObj.origType,
|
|
270
|
+
handleObj.selector,
|
|
271
|
+
handleObj.handler
|
|
272
|
+
);
|
|
273
|
+
return this;
|
|
274
|
+
}
|
|
275
|
+
if (typeof types === 'object') {
|
|
276
|
+
// ( types-object [, selector] )
|
|
277
|
+
for (let type in types) {
|
|
278
|
+
this.off(type, selector, types[type]);
|
|
279
|
+
}
|
|
280
|
+
return this;
|
|
281
|
+
}
|
|
282
|
+
if (selector === false || typeof selector === 'function') {
|
|
283
|
+
// ( types [, fn] )
|
|
284
|
+
fn = selector;
|
|
285
|
+
selector = undefined;
|
|
286
|
+
}
|
|
287
|
+
for (let i = 0; i < this.length; i++) {
|
|
288
|
+
$.event.remove(this[i], types, fn, selector);
|
|
289
|
+
}
|
|
290
|
+
return this;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Measurements
|
|
294
|
+
|
|
295
|
+
export function width() {
|
|
296
|
+
const [el] = this;
|
|
297
|
+
if (el === window) return el.document.documentElement.clientWidth;
|
|
298
|
+
else if (!el) return undefined;
|
|
299
|
+
const styles = window.getComputedStyle(el);
|
|
300
|
+
const height = el.offsetWidth;
|
|
301
|
+
const borderTopWidth = parseFloat(styles.borderTopWidth);
|
|
302
|
+
const borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
|
303
|
+
const paddingTop = parseFloat(styles.paddingTop);
|
|
304
|
+
const paddingBottom = parseFloat(styles.paddingBottom);
|
|
305
|
+
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export function height() {
|
|
309
|
+
const [el] = this;
|
|
310
|
+
if (el === window) return el.document.documentElement.clientHeight;
|
|
311
|
+
if (!el) return undefined;
|
|
312
|
+
const styles = window.getComputedStyle(el);
|
|
313
|
+
const width = el.offsetHeight;
|
|
314
|
+
const borderLeftWidth = parseFloat(styles.borderLeftWidth);
|
|
315
|
+
const borderRightWidth = parseFloat(styles.borderRightWidth);
|
|
316
|
+
const paddingLeft = parseFloat(styles.paddingLeft);
|
|
317
|
+
const paddingRight = parseFloat(styles.paddingRight);
|
|
318
|
+
return width - borderLeftWidth - borderRightWidth - paddingLeft - paddingRight;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export function position() {
|
|
322
|
+
const [el] = this;
|
|
323
|
+
if (!el) return;
|
|
324
|
+
let $el = $(el);
|
|
325
|
+
let offsetParent;
|
|
326
|
+
let offset;
|
|
327
|
+
let doc;
|
|
328
|
+
let parentOffset = { top: 0, left: 0 };
|
|
329
|
+
// position:fixed elements are offset from the viewport, which itself always has zero offset
|
|
330
|
+
if ($el.css('position') === 'fixed') {
|
|
331
|
+
// Assume position:fixed implies availability of getBoundingClientRect
|
|
332
|
+
offset = el.getBoundingClientRect();
|
|
333
|
+
} else {
|
|
334
|
+
offset = $el.offset();
|
|
335
|
+
// Account for the *real* offset parent, which can be the document or its root element
|
|
336
|
+
// when a statically positioned element is identified
|
|
337
|
+
doc = el.ownerDocument;
|
|
338
|
+
offsetParent = el.offsetParent || doc.documentElement;
|
|
339
|
+
const $parentOffset = $(offsetParent);
|
|
340
|
+
const parentOffsetElementPosition = $parentOffset.css('position') || 'static';
|
|
341
|
+
while ( offsetParent && (offsetParent === doc.body || offsetParent === doc.documentElement) && parentOffsetElementPosition === 'static') {
|
|
342
|
+
offsetParent = offsetParent.parentNode;
|
|
343
|
+
}
|
|
344
|
+
if (offsetParent && offsetParent !== el && offsetParent.nodeType === 1) {
|
|
345
|
+
// Incorporate borders into its offset, since they are outside its content origin
|
|
346
|
+
const offsetParentStyles = window.getComputedStyle(offsetParent);
|
|
347
|
+
const borderTopWidth = parseFloat(offsetParentStyles.borderTopWidth) || 0;
|
|
348
|
+
const borderLeftWidth = parseFloat(offsetParentStyles.borderLeftWidth) || 0;
|
|
349
|
+
parentOffset = $parentOffset.offset();
|
|
350
|
+
parentOffset.top += borderTopWidth;
|
|
351
|
+
parentOffset.left += borderLeftWidth;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const marginTop = parseFloat(window.getComputedStyle(el).marginTop) || 0;
|
|
355
|
+
const marginLeft = parseFloat(window.getComputedStyle(el).marginLeft) || 0;
|
|
356
|
+
// Subtract parent offsets and element margins
|
|
357
|
+
return {
|
|
358
|
+
top: offset.top - parentOffset.top - marginTop,
|
|
359
|
+
left: offset.left - parentOffset.left - marginLeft
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export function offset(coordinates) {
|
|
364
|
+
const [el] = this;
|
|
365
|
+
// Getter
|
|
366
|
+
if (coordinates === undefined) {
|
|
367
|
+
if (!el) return null;
|
|
368
|
+
if (!el.getClientRects().length) {
|
|
369
|
+
return { top: 0, left: 0 };
|
|
370
|
+
}
|
|
371
|
+
const rect = el.getBoundingClientRect();
|
|
372
|
+
return {
|
|
373
|
+
top: rect.top + window.scrollY,
|
|
374
|
+
left: rect.left + window.scrollX
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
// Setter
|
|
378
|
+
if (!el) return this;
|
|
379
|
+
const currentStyle = window.getComputedStyle(el);
|
|
380
|
+
if (currentStyle.position === 'static') {
|
|
381
|
+
this.css('position', 'relative');
|
|
382
|
+
}
|
|
383
|
+
const currentOffset = this.offset();
|
|
384
|
+
const topDifference = coordinates.top - currentOffset.top;
|
|
385
|
+
const leftDifference = coordinates.left - currentOffset.left;
|
|
386
|
+
this.css({
|
|
387
|
+
top: (parseFloat(currentStyle.top) || 0) + topDifference + 'px',
|
|
388
|
+
left: (parseFloat(currentStyle.left) || 0) + leftDifference + 'px'
|
|
389
|
+
});
|
|
390
|
+
return this;
|
|
391
|
+
}
|
|
392
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const propertySetters = {
|
|
2
|
+
outerWidth: 'offsetWidth',
|
|
3
|
+
outerHeight: 'offsetHeight',
|
|
4
|
+
innerWidth: 'clientWidth',
|
|
5
|
+
innerHeight: 'clientHeight',
|
|
6
|
+
scrollLeft: 'scrollLeft',
|
|
7
|
+
scrollTop: 'scrollTop',
|
|
8
|
+
val: 'value',
|
|
9
|
+
text: 'textContent',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const propertiesMap = {
|
|
13
|
+
disabled: 'disabled',
|
|
14
|
+
value: 'value',
|
|
15
|
+
text: 'textContent',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function prop(name, value) {
|
|
19
|
+
if (!name) throw new Error('no property provided');
|
|
20
|
+
if (arguments.length === 1) {
|
|
21
|
+
const [el] = this;
|
|
22
|
+
if (!el) return null;
|
|
23
|
+
return el[name];
|
|
24
|
+
}
|
|
25
|
+
if (value === undefined) return this;
|
|
26
|
+
for (let i = 0; i < this.length; i++) {
|
|
27
|
+
this[i][name] = value;
|
|
28
|
+
}
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function attr(name, value) {
|
|
33
|
+
let attributes;
|
|
34
|
+
if (typeof name === 'string') {
|
|
35
|
+
if (value === undefined) {
|
|
36
|
+
const [el] = this;
|
|
37
|
+
if (!el) return null;
|
|
38
|
+
return el.getAttribute(name);
|
|
39
|
+
} else {
|
|
40
|
+
attributes = { [name]: value };
|
|
41
|
+
}
|
|
42
|
+
} else if (!name) {
|
|
43
|
+
throw new Error('no attributes provided');
|
|
44
|
+
} else {
|
|
45
|
+
attributes = name;
|
|
46
|
+
}
|
|
47
|
+
for (let attr in attributes) {
|
|
48
|
+
if (attributes.hasOwnProperty(attr)) {
|
|
49
|
+
const value = attributes[attr];
|
|
50
|
+
if (propertiesMap[attr]) {
|
|
51
|
+
this.prop(propertiesMap[attr], value);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
for (let i = 0; i < this.length; i++) {
|
|
55
|
+
if (value === null) {
|
|
56
|
+
this[i].removeAttribute(attr);
|
|
57
|
+
} else {
|
|
58
|
+
this[i].setAttribute(attr, value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const methods = {
|
|
67
|
+
prop,
|
|
68
|
+
attr
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
Object.keys(propertySetters).forEach(methodName => {
|
|
72
|
+
methods[methodName] = function(...args) {
|
|
73
|
+
return this.prop(propertySetters[methodName], ...args);
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export default methods;
|