UNPKG

lisn.js

Version:

Simply handle user gestures and actions. Includes widgets.

202 lines (191 loc) 6.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseScrollOffset = exports.isValidViewList = exports.isValidView = exports.isValidScrollOffset = exports.getViewsBitmask = exports.getOppositeViews = exports.VIEWS_SPACE = void 0; var MC = _interopRequireWildcard(require("../globals/minification-constants.cjs")); var MH = _interopRequireWildcard(require("../globals/minification-helpers.cjs")); var _validation = require("./validation.cjs"); var _bitSpaces = require("../modules/bit-spaces.cjs"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /** * @module Utils */ /** * Returns true if the given string is a valid {@link ScrollOffset}. * * @category Validation */ const isValidScrollOffset = offset => offset.match(OFFSET_REGEX) !== null; /** * Returns true if the given string is a valid "view". * * @category Validation */ exports.isValidScrollOffset = isValidScrollOffset; const isValidView = view => MH.includes(VIEWS, view); /** * Returns true if the given string or array is a list of valid views. * * @category Validation */ exports.isValidView = isValidView; const isValidViewList = views => (0, _validation.isValidStrList)(views, isValidView, false); /** * Returns the views that are opposite to the given set of views. * * Above and below are opposites, and so are left and right. * * "at" is a special case. It is considered opposite to any view in the sense * that if it is not present in `views` it will always be included in the * returned array. However it is not "strongly" opposite in the sense that it * will not cause other views to be included in the result unless it is the * only view in `views`. That is, there are two sets of strongly opposite pairs * ("above"/"below" and "left"/"right") and at least one of the two opposing * views of a pair must be present for the other one to be included, _except in * the special case of `views` being "at"_. See examples below for * clarification. * * **Note** that the order of the returned array is not defined. * * @example * Returns ["above", "below", "left", "right"] (not definite order), since * "at" is the only view present and is opposite to all: * * ```javascript * getOppositeViews("at"); // -> ["above", "below", "left", "right"] (not necessarily in this order) * ``` * * @example * Returns ["below"]. "left" and "right" are NOT included even though "at" is * given, because at least one of the two opposing views of a pair must be * present for the other one to be included (except in the special case of * `views` being "at"). * * ```javascript * getOppositeViews("at,above"); // -> ["below"] * ``` * * @example * ```javascript * getOppositeViews("above"); // -> ["at", "below"] (not necessarily in this order) * ``` * * @example * ```javascript * getOppositeViews("above,below"); // -> ["at"] * ``` * * @example * ```javascript * getOppositeViews("at,above,below"); // -> [] * ``` * * @example * ```javascript * getOppositeViews("above,right"); // -> ["at", "below", "left"] (not necessarily in this order) * ``` * * @example * ```javascript * getOppositeViews("at,above,right"); // -> ["below", "left"] (not necessarily in this order) * ``` * * @throws {@link Errors.LisnUsageError | LisnUsageError} * If the given view is not valid, including if it's empty "". * * @category Views */ exports.isValidViewList = isValidViewList; const getOppositeViews = views => { if (!views) { throw MH.usageError("'views' cannot be empty"); } const bitmask = getViewsBitmask(views); let oppositeBitmask = VIEWS_SPACE.bitmask & ~bitmask; // initial, all not present in bitmask // If the given view is "at", then include all the other ones. // Otherwise include only the opposite views of those directional // (above/below/left/right) that are present. I.e. if neither left not right // is given, then don't include them if (bitmask !== VIEWS_SPACE.bit.at) { // remove the opposite ones to those not present if (!(bitmask & VIEWS_SPACE.bit.above)) { oppositeBitmask &= ~VIEWS_SPACE.bit.below; } if (!(bitmask & VIEWS_SPACE.bit.below)) { oppositeBitmask &= ~VIEWS_SPACE.bit.above; } if (!(bitmask & VIEWS_SPACE.bit.left)) { oppositeBitmask &= ~VIEWS_SPACE.bit.right; } if (!(bitmask & VIEWS_SPACE.bit.right)) { oppositeBitmask &= ~VIEWS_SPACE.bit.left; } } return getViewsFromBitmask(oppositeBitmask); }; /** * @ignore * @internal */ exports.getOppositeViews = getOppositeViews; const getViewsBitmask = viewsStr => { let viewsBitmask = 0; const views = (0, _validation.validateStrList)("views", viewsStr, isValidView); if (views) { for (const v of views) { if (!isValidView(v)) { throw MH.usageError(`Unknown view '${v}'`); } viewsBitmask |= VIEWS_SPACE.bit[v]; } } else { viewsBitmask = VIEWS_SPACE.bitmask; // default: all } return viewsBitmask; }; /** * @ignore * @internal */ exports.getViewsBitmask = getViewsBitmask; const parseScrollOffset = input => { const match = input.match(OFFSET_REGEX); if (!match) { throw MH.usageError(`Invalid offset: '${input}'`); } const reference = match[1]; const value = match[2]; /* istanbul ignore next */ // shouldn't happen if (!reference || !value) { throw MH.bugError("Offset regex: blank capture groups"); } return { reference, value }; }; exports.parseScrollOffset = parseScrollOffset; const VIEWS = [MC.S_AT, MC.S_ABOVE, MC.S_BELOW, MC.S_LEFT, MC.S_RIGHT]; /** * @ignore * @internal */ const VIEWS_SPACE = exports.VIEWS_SPACE = (0, _bitSpaces.createBitSpace)((0, _bitSpaces.newBitSpaces)(), ...VIEWS); // -------------------- // Don't use capture groups for old browser support const OFFSET_REGEX = RegExp("(top|bottom|left|right): *([^ ].+)"); const getViewsFromBitmask = bitmask => { const views = []; for (let bit = VIEWS_SPACE.start; bit <= VIEWS_SPACE.end; bit++) { const value = 1 << bit; if (bitmask & value) { const name = VIEWS_SPACE.nameOf(value); if (name) { views.push(name); } } } return views; }; //# sourceMappingURL=views.cjs.map