@activecollab/components
Version:
ActiveCollab Components
474 lines (468 loc) • 15.8 kB
JavaScript
;
var _resizePolicy = require("./resizePolicy");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var FREE = {
proportional: false
};
var start = function start(w, h) {
var minW = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var minH = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
return (0, _resizePolicy.makeStart)({
w,
h
}, {
w: minW,
h: minH
});
};
describe("clamp / snap", function () {
it("clamps to the floor and, when given, the ceiling", function () {
expect((0, _resizePolicy.clamp)(5, 10)).toBe(10);
expect((0, _resizePolicy.clamp)(50, 10, 20)).toBe(20);
expect((0, _resizePolicy.clamp)(15, 10, 20)).toBe(15);
});
it("treats a missing ceiling as unbounded", function () {
expect((0, _resizePolicy.clamp)(1e9, 10)).toBe(1e9);
});
it("snaps to the nearest multiple, and passes through without a step", function () {
expect((0, _resizePolicy.snap)(217, 8)).toBe(216);
expect((0, _resizePolicy.snap)(220, 8)).toBe(224);
expect((0, _resizePolicy.snap)(217)).toBe(217);
expect((0, _resizePolicy.snap)(217, 0)).toBe(217);
});
});
describe("effectiveBounds", function () {
it("floors the policy minimum with the content minimum", function () {
var bounds = (0, _resizePolicy.effectiveBounds)({
minW: 96,
minH: 40,
proportional: false
}, {
w: 160,
h: 72
});
// The content wins on both axes here: a card may not be crushed below it.
expect(bounds.wMin).toBe(160);
expect(bounds.hMin).toBe(72);
});
it("keeps the policy minimum when it is the higher of the two", function () {
var bounds = (0, _resizePolicy.effectiveBounds)({
minW: 200,
proportional: false
}, {
w: 160,
h: 0
});
expect(bounds.wMin).toBe(200);
});
it("reports an unset maximum as unbounded", function () {
var bounds = (0, _resizePolicy.effectiveBounds)(FREE, {
w: 0,
h: 0
});
expect(bounds.wMax).toBe(Number.POSITIVE_INFINITY);
expect(bounds.hMax).toBe(Number.POSITIVE_INFINITY);
});
});
describe("applyResize — bounds", function () {
it("stops at minW", function () {
var policy = {
minW: 180,
proportional: false
};
expect((0, _resizePolicy.applyResize)(start(300, 200), {
dx: -500,
dy: 0
}, policy).w).toBe(180);
});
it("stops at maxW", function () {
var policy = {
maxW: 420,
proportional: false
};
expect((0, _resizePolicy.applyResize)(start(300, 200), {
dx: +500,
dy: 0
}, policy).w).toBe(420);
});
it("stops at minH", function () {
var policy = {
minH: 120,
proportional: false
};
expect((0, _resizePolicy.applyResize)(start(300, 200), {
dx: 0,
dy: -500
}, policy).h).toBe(120);
});
it("stops at maxH", function () {
var policy = {
maxH: 540,
proportional: false
};
expect((0, _resizePolicy.applyResize)(start(300, 200), {
dx: 0,
dy: +500
}, policy).h).toBe(540);
});
it("leaves an unset bound unbounded", function () {
// No maxW at all: a huge delta is applied in full.
expect((0, _resizePolicy.applyResize)(start(300, 200), {
dx: +5000,
dy: 0
}, FREE).w).toBe(5300);
// No minW either, so the floor is 0 rather than some implied width.
expect((0, _resizePolicy.applyResize)(start(300, 200), {
dx: -5000,
dy: 0
}, FREE).w).toBe(0);
});
it("lets the content minimum override a lower policy minimum", function () {
var policy = {
minW: 96,
proportional: false
};
var measured = (0, _resizePolicy.makeStart)({
w: 300,
h: 200
}, {
w: 160,
h: 0
});
// 96 is the policy floor, but the content needs 160 — the higher wins.
expect((0, _resizePolicy.applyResize)(measured, {
dx: -500,
dy: 0
}, policy).w).toBe(160);
});
});
describe("applyResize — proportional", function () {
/* The worked example from the spec: a proportional policy meeting a bound
must not distort the ratio — the binding axis stops both. */
var policy = {
minW: 96,
maxW: 620,
minH: 72,
maxH: 540,
proportional: true,
step: 8
};
var proportionalStart = (0, _resizePolicy.makeStart)({
w: 300,
h: 200
}, {
w: 96,
h: 72
});
it("holds the ratio when the WIDTH axis binds at the maximum", function () {
// scaleMax = min(620/300, 540/200) = 2.066 → width binds
expect((0, _resizePolicy.applyResize)(proportionalStart, {
dx: +400,
dy: 0
}, policy)).toEqual({
w: 620,
h: 413
});
});
it("holds the ratio when the HEIGHT axis binds at the minimum", function () {
// scaleMin = max(96/300, 72/200) = 0.36 → height binds
expect((0, _resizePolicy.applyResize)(proportionalStart, {
dx: -400,
dy: 0
}, policy)).toEqual({
w: 108,
h: 72
});
});
it("drives the scale from whichever axis the corner moved further", function () {
var free = {
proportional: true
};
// A purely vertical drag scales the width too, so the corner is not
// width-biased: +100 on a 200-tall card is a 1.5× scale.
expect((0, _resizePolicy.applyResize)(start(300, 200), {
dx: 0,
dy: +100
}, free)).toEqual({
w: 450,
h: 300
});
});
it("lets the grid yield rather than break the ratio at a bound", function () {
// Snapping 108 to the 8px grid would give 112 — above the binding minimum.
// The bound is a hard stop, so the card sits exactly on it instead.
var result = (0, _resizePolicy.applyResize)(proportionalStart, {
dx: -400,
dy: 0
}, policy);
expect(result.w % 8).not.toBe(0);
expect(result.w).toBe(108);
});
it("still snaps to the grid away from any bound", function () {
var result = (0, _resizePolicy.applyResize)(proportionalStart, {
dx: +37,
dy: 0
}, policy);
// 337 snaps to 336, and the height follows the same scale.
expect(result).toEqual({
w: 336,
h: 224
});
});
it("falls back to free-form when a side has no length to form a ratio", function () {
// Width-only cards park a placeholder height; the ratio math must not
// divide by zero.
var result = (0, _resizePolicy.applyResize)((0, _resizePolicy.makeStart)({
w: 300,
h: 0
}, {
w: 0,
h: 0
}), {
dx: +40,
dy: +40
}, {
proportional: true
});
expect(result.w).toBe(340);
expect(Number.isNaN(result.h)).toBe(false);
});
});
describe("applyResize — shift to constrain", function () {
it("locks the ratio for one gesture on a free-form policy", function () {
var result = (0, _resizePolicy.applyResize)(start(300, 200), {
dx: +150,
dy: 0
}, FREE, {
constrain: true
});
// 1.5× on both axes, from a purely horizontal drag.
expect(result).toEqual({
w: 450,
h: 300
});
});
it("leaves the axes independent without it", function () {
expect((0, _resizePolicy.applyResize)(start(300, 200), {
dx: +150,
dy: 0
}, FREE)).toEqual({
w: 450,
h: 200
});
});
it("changes nothing on a policy that is already proportional", function () {
var policy = {
proportional: true
};
var delta = {
dx: +150,
dy: 0
};
expect((0, _resizePolicy.applyResize)(start(300, 200), delta, policy, {
constrain: true
})).toEqual((0, _resizePolicy.applyResize)(start(300, 200), delta, policy));
});
});
describe("applyResize — width-only axis", function () {
/* The worked example from the spec: an auto-height card ignores the vertical
component entirely. */
it("ignores the vertical component and holds the height", function () {
var policy = {
minW: 180,
maxW: 420,
proportional: false,
step: 8
};
var result = (0, _resizePolicy.applyResize)((0, _resizePolicy.makeStart)({
w: 180,
h: 240
}, {
w: 180,
h: 0
}), {
dx: +37,
dy: +200
}, policy, {
axis: "width"
});
expect(result).toEqual({
w: 216,
h: 240
});
});
it("still lets the height follow the ratio in proportional mode", function () {
// `axis: "width"` drops the pointer's vertical INPUT; it does not turn a
// proportional card into a free-form one.
var result = (0, _resizePolicy.applyResize)(start(300, 200), {
dx: +150,
dy: +999
}, {
proportional: true
}, {
axis: "width"
});
expect(result).toEqual({
w: 450,
h: 300
});
});
});
describe("keyboardResize", function () {
var policy = {
minW: 180,
maxW: 420,
minH: 120,
maxH: 400,
proportional: false
};
var contentMin = {
w: 180,
h: 120
};
var size = {
w: 300,
h: 200
};
it("nudges by the default step when the policy has none", function () {
var _keyboardResize, _keyboardResize2, _keyboardResize3, _keyboardResize4;
expect((_keyboardResize = (0, _resizePolicy.keyboardResize)("ArrowRight", size, policy, contentMin)) === null || _keyboardResize === void 0 ? void 0 : _keyboardResize.w).toBe(300 + _resizePolicy.DEFAULT_KEYBOARD_STEP);
expect((_keyboardResize2 = (0, _resizePolicy.keyboardResize)("ArrowLeft", size, policy, contentMin)) === null || _keyboardResize2 === void 0 ? void 0 : _keyboardResize2.w).toBe(300 - _resizePolicy.DEFAULT_KEYBOARD_STEP);
expect((_keyboardResize3 = (0, _resizePolicy.keyboardResize)("ArrowDown", size, policy, contentMin)) === null || _keyboardResize3 === void 0 ? void 0 : _keyboardResize3.h).toBe(200 + _resizePolicy.DEFAULT_KEYBOARD_STEP);
expect((_keyboardResize4 = (0, _resizePolicy.keyboardResize)("ArrowUp", size, policy, contentMin)) === null || _keyboardResize4 === void 0 ? void 0 : _keyboardResize4.h).toBe(200 - _resizePolicy.DEFAULT_KEYBOARD_STEP);
});
it("nudges by the policy step when there is one", function () {
var _keyboardResize5;
expect((_keyboardResize5 = (0, _resizePolicy.keyboardResize)("ArrowRight", size, _objectSpread(_objectSpread({}, policy), {}, {
step: 20
}), contentMin)) === null || _keyboardResize5 === void 0 ? void 0 : _keyboardResize5.w).toBe(320);
});
it("makes Shift a coarse nudge", function () {
var _keyboardResize6;
expect((_keyboardResize6 = (0, _resizePolicy.keyboardResize)("ArrowRight", size, policy, contentMin, {
shiftKey: true
})) === null || _keyboardResize6 === void 0 ? void 0 : _keyboardResize6.w).toBe(300 + _resizePolicy.DEFAULT_KEYBOARD_STEP * _resizePolicy.SHIFT_STEP_MULTIPLIER);
});
it("clamps a nudge exactly like the pointer does", function () {
var _keyboardResize7;
expect((_keyboardResize7 = (0, _resizePolicy.keyboardResize)("ArrowLeft", {
w: 184,
h: 200
}, policy, contentMin, {
shiftKey: true
})) === null || _keyboardResize7 === void 0 ? void 0 : _keyboardResize7.w).toBe(180);
});
it("jumps to the minimum on Home and the maximum on End", function () {
expect((0, _resizePolicy.keyboardResize)("Home", size, policy, contentMin)).toEqual({
w: 180,
h: 120
});
expect((0, _resizePolicy.keyboardResize)("End", size, policy, contentMin)).toEqual({
w: 420,
h: 400
});
});
it("leaves an axis with no maximum where it is on End", function () {
var unbounded = {
minW: 180,
maxW: 420,
proportional: false
};
expect((0, _resizePolicy.keyboardResize)("End", size, unbounded, {
w: 180,
h: 0
})).toEqual({
w: 420,
h: 200
});
});
it("leaves an axis with no minimum where it is on Home", function () {
// Nobody asked for a floor on either axis, so Home has nothing to jump to —
// it must not collapse the card to zero.
expect((0, _resizePolicy.keyboardResize)("Home", size, FREE, {
w: 0,
h: 0
})).toEqual(size);
});
it("ignores the vertical keys on a width-only card", function () {
expect((0, _resizePolicy.keyboardResize)("ArrowUp", size, policy, contentMin, {
axis: "width"
})).toBeNull();
expect((0, _resizePolicy.keyboardResize)("ArrowDown", size, policy, contentMin, {
axis: "width"
})).toBeNull();
});
it("holds the height on a width-only Home and End", function () {
expect((0, _resizePolicy.keyboardResize)("Home", size, policy, contentMin, {
axis: "width"
})).toEqual({
w: 180,
h: 200
});
expect((0, _resizePolicy.keyboardResize)("End", size, policy, contentMin, {
axis: "width"
})).toEqual({
w: 420,
h: 200
});
});
it("returns null for a key it does not own", function () {
expect((0, _resizePolicy.keyboardResize)("Enter", size, policy, contentMin)).toBeNull();
expect((0, _resizePolicy.keyboardResize)("a", size, policy, contentMin)).toBeNull();
});
});
describe("isResizeKey", function () {
it("owns the arrows plus Home and End, and nothing else", function () {
_resizePolicy.RESIZE_KEYS.forEach(function (key) {
return expect((0, _resizePolicy.isResizeKey)(key)).toBe(true);
});
expect((0, _resizePolicy.isResizeKey)("Enter")).toBe(false);
expect((0, _resizePolicy.isResizeKey)("Tab")).toBe(false);
});
});
describe("measurePercent", function () {
var policy = {
minW: 200,
maxW: 400,
proportional: false
};
var contentMin = {
w: 0,
h: 0
};
it("reports the width axis as a percent of its allowed range", function () {
expect((0, _resizePolicy.measurePercent)({
w: 200,
h: 0
}, policy, contentMin)).toBe(0);
expect((0, _resizePolicy.measurePercent)({
w: 300,
h: 0
}, policy, contentMin)).toBe(50);
expect((0, _resizePolicy.measurePercent)({
w: 400,
h: 0
}, policy, contentMin)).toBe(100);
});
it("stays inside 0–100 for a size outside the bounds", function () {
expect((0, _resizePolicy.measurePercent)({
w: 40,
h: 0
}, policy, contentMin)).toBe(0);
expect((0, _resizePolicy.measurePercent)({
w: 900,
h: 0
}, policy, contentMin)).toBe(100);
});
it("reports 0 when the range is not finite", function () {
expect((0, _resizePolicy.measurePercent)({
w: 300,
h: 0
}, FREE, contentMin)).toBe(0);
});
});
//# sourceMappingURL=resizePolicy.test.js.map