"Fossies" - the Fresh Open Source Software Archive

Member "ember.js-3.28.1/packages/@ember/-internals/glimmer/lib/modifiers/action.ts" (30 Aug 2021, 8962 Bytes) of package /linux/www/ember.js-3.28.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TypeScript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "action.ts": 3.27.0_vs_3.27.1.

    1 import { Owner } from '@ember/-internals/owner';
    2 import { uuid } from '@ember/-internals/utils';
    3 import { ActionManager, isSimpleClick } from '@ember/-internals/views';
    4 import { assert, deprecate } from '@ember/debug';
    5 import { flaggedInstrument } from '@ember/instrumentation';
    6 import { join } from '@ember/runloop';
    7 import { registerDestructor } from '@glimmer/destroyable';
    8 import { DEBUG } from '@glimmer/env';
    9 import {
   10   CapturedArguments,
   11   CapturedNamedArguments,
   12   CapturedPositionalArguments,
   13   InternalModifierManager,
   14 } from '@glimmer/interfaces';
   15 import { setInternalModifierManager } from '@glimmer/manager';
   16 import { isInvokableRef, updateRef, valueForRef } from '@glimmer/reference';
   17 import { createUpdatableTag, UpdatableTag } from '@glimmer/validator';
   18 import { SimpleElement } from '@simple-dom/interface';
   19 import { INVOKE } from '../helpers/action';
   20 
   21 const MODIFIERS = ['alt', 'shift', 'meta', 'ctrl'];
   22 const POINTER_EVENT_TYPE_REGEX = /^click|mouse|touch/;
   23 
   24 function isAllowedEvent(event: Event, allowedKeys: any) {
   25   if (allowedKeys === null || allowedKeys === undefined) {
   26     if (POINTER_EVENT_TYPE_REGEX.test(event.type)) {
   27       return isSimpleClick(event);
   28     } else {
   29       allowedKeys = '';
   30     }
   31   }
   32 
   33   if (allowedKeys.indexOf('any') >= 0) {
   34     return true;
   35   }
   36 
   37   for (let i = 0; i < MODIFIERS.length; i++) {
   38     if (event[MODIFIERS[i] + 'Key'] && allowedKeys.indexOf(MODIFIERS[i]) === -1) {
   39       return false;
   40     }
   41   }
   42 
   43   return true;
   44 }
   45 
   46 export let ActionHelper = {
   47   // registeredActions is re-exported for compatibility with older plugins
   48   // that were using this undocumented API.
   49   registeredActions: ActionManager.registeredActions,
   50 
   51   registerAction(actionState: ActionState) {
   52     let { actionId } = actionState;
   53 
   54     ActionManager.registeredActions[actionId] = actionState;
   55 
   56     return actionId;
   57   },
   58 
   59   unregisterAction(actionState: ActionState) {
   60     let { actionId } = actionState;
   61 
   62     delete ActionManager.registeredActions[actionId];
   63   },
   64 };
   65 
   66 export class ActionState {
   67   public element: SimpleElement;
   68   public actionId: number;
   69   public actionName: any;
   70   public actionArgs: any;
   71   public namedArgs: CapturedNamedArguments;
   72   public positional: CapturedPositionalArguments;
   73   public implicitTarget: any;
   74   public eventName: any;
   75   public tag = createUpdatableTag();
   76 
   77   constructor(
   78     element: SimpleElement,
   79     actionId: number,
   80     actionArgs: any[],
   81     namedArgs: CapturedNamedArguments,
   82     positionalArgs: CapturedPositionalArguments
   83   ) {
   84     this.element = element;
   85     this.actionId = actionId;
   86     this.actionArgs = actionArgs;
   87     this.namedArgs = namedArgs;
   88     this.positional = positionalArgs;
   89     this.eventName = this.getEventName();
   90 
   91     registerDestructor(this, () => ActionHelper.unregisterAction(this));
   92   }
   93 
   94   getEventName() {
   95     let { on } = this.namedArgs;
   96 
   97     return on !== undefined ? valueForRef(on) : 'click';
   98   }
   99 
  100   getActionArgs() {
  101     let result = new Array(this.actionArgs.length);
  102 
  103     for (let i = 0; i < this.actionArgs.length; i++) {
  104       result[i] = valueForRef(this.actionArgs[i]);
  105     }
  106 
  107     return result;
  108   }
  109 
  110   getTarget(): any {
  111     let { implicitTarget, namedArgs } = this;
  112     let { target } = namedArgs;
  113 
  114     return target !== undefined ? valueForRef(target) : valueForRef(implicitTarget);
  115   }
  116 
  117   handler(event: Event): boolean {
  118     let { actionName, namedArgs } = this;
  119     let { bubbles, preventDefault, allowedKeys } = namedArgs;
  120 
  121     let bubblesVal = bubbles !== undefined ? valueForRef(bubbles) : undefined;
  122     let preventDefaultVal = preventDefault !== undefined ? valueForRef(preventDefault) : undefined;
  123     let allowedKeysVal = allowedKeys !== undefined ? valueForRef(allowedKeys) : undefined;
  124 
  125     let target = this.getTarget();
  126 
  127     let shouldBubble = bubblesVal !== false;
  128 
  129     if (!isAllowedEvent(event, allowedKeysVal)) {
  130       return true;
  131     }
  132 
  133     if (preventDefaultVal !== false) {
  134       event.preventDefault();
  135     }
  136 
  137     if (!shouldBubble) {
  138       event.stopPropagation();
  139     }
  140 
  141     join(() => {
  142       let args = this.getActionArgs();
  143       let payload = {
  144         args,
  145         target,
  146         name: null,
  147       };
  148       if (typeof actionName[INVOKE] === 'function') {
  149         deprecate(
  150           `Usage of the private INVOKE API to make an object callable via action or fn is no longer supported. Please update to pass in a callback function instead. Received: ${String(
  151             actionName
  152           )}`,
  153           false,
  154           {
  155             until: '3.25.0',
  156             id: 'actions.custom-invoke-invokable',
  157             for: 'ember-source',
  158             since: {
  159               enabled: '3.23.0-beta.1',
  160             },
  161           }
  162         );
  163 
  164         flaggedInstrument('interaction.ember-action', payload, () => {
  165           actionName[INVOKE].apply(actionName, args);
  166         });
  167         return;
  168       }
  169       if (isInvokableRef(actionName)) {
  170         flaggedInstrument('interaction.ember-action', payload, () => {
  171           updateRef(actionName, args[0]);
  172         });
  173         return;
  174       }
  175       if (typeof actionName === 'function') {
  176         flaggedInstrument('interaction.ember-action', payload, () => {
  177           actionName.apply(target, args);
  178         });
  179         return;
  180       }
  181       payload.name = actionName;
  182       if (target.send) {
  183         flaggedInstrument('interaction.ember-action', payload, () => {
  184           target.send.apply(target, [actionName, ...args]);
  185         });
  186       } else {
  187         assert(
  188           `The action '${actionName}' did not exist on ${target}`,
  189           typeof target[actionName] === 'function'
  190         );
  191         flaggedInstrument('interaction.ember-action', payload, () => {
  192           target[actionName].apply(target, args);
  193         });
  194       }
  195     });
  196 
  197     return shouldBubble;
  198   }
  199 }
  200 
  201 class ActionModifierManager implements InternalModifierManager<ActionState, object> {
  202   create(
  203     _owner: Owner,
  204     element: SimpleElement,
  205     _state: object,
  206     { named, positional }: CapturedArguments
  207   ): ActionState {
  208     let actionArgs: any[] = [];
  209     // The first two arguments are (1) `this` and (2) the action name.
  210     // Everything else is a param.
  211     for (let i = 2; i < positional.length; i++) {
  212       actionArgs.push(positional[i]);
  213     }
  214 
  215     let actionId = uuid();
  216     let actionState = new ActionState(element, actionId, actionArgs, named, positional);
  217 
  218     deprecate(
  219       `Using the \`{{action}}\` modifier with \`${actionState.eventName}\` events has been deprecated.`,
  220       actionState.eventName !== 'mouseEnter' &&
  221         actionState.eventName !== 'mouseLeave' &&
  222         actionState.eventName !== 'mouseMove',
  223       {
  224         id: 'ember-views.event-dispatcher.mouseenter-leave-move',
  225         until: '4.0.0',
  226         url: 'https://deprecations.emberjs.com/v3.x#toc_action-mouseenter-leave-move',
  227         for: 'ember-source',
  228         since: {
  229           enabled: '3.13.0-beta.1',
  230         },
  231       }
  232     );
  233 
  234     return actionState;
  235   }
  236 
  237   getDebugName(): string {
  238     return 'action';
  239   }
  240 
  241   install(actionState: ActionState): void {
  242     let { element, actionId, positional } = actionState;
  243 
  244     let actionName;
  245     let actionNameRef: any;
  246     let implicitTarget;
  247 
  248     if (positional.length > 1) {
  249       implicitTarget = positional[0];
  250       actionNameRef = positional[1];
  251 
  252       if (isInvokableRef(actionNameRef)) {
  253         actionName = actionNameRef;
  254       } else {
  255         actionName = valueForRef(actionNameRef);
  256 
  257         if (DEBUG) {
  258           let actionPath = actionNameRef.debugLabel;
  259           let actionPathParts = actionPath.split('.');
  260           let actionLabel = actionPathParts[actionPathParts.length - 1];
  261 
  262           assert(
  263             'You specified a quoteless path, `' +
  264               actionPath +
  265               '`, to the ' +
  266               '{{action}} helper which did not resolve to an action name (a ' +
  267               'string). Perhaps you meant to use a quoted actionName? (e.g. ' +
  268               '{{action "' +
  269               actionLabel +
  270               '"}}).',
  271             typeof actionName === 'string' || typeof actionName === 'function'
  272           );
  273         }
  274       }
  275     }
  276 
  277     actionState.actionName = actionName;
  278     actionState.implicitTarget = implicitTarget;
  279 
  280     ActionHelper.registerAction(actionState);
  281 
  282     element.setAttribute('data-ember-action', '');
  283     element.setAttribute(`data-ember-action-${actionId}`, String(actionId));
  284   }
  285 
  286   update(actionState: ActionState): void {
  287     let { positional } = actionState;
  288     let actionNameRef = positional[1];
  289 
  290     if (!isInvokableRef(actionNameRef)) {
  291       actionState.actionName = valueForRef(actionNameRef);
  292     }
  293 
  294     actionState.eventName = actionState.getEventName();
  295   }
  296 
  297   getTag(actionState: ActionState): UpdatableTag {
  298     return actionState.tag;
  299   }
  300 
  301   getDestroyable(actionState: ActionState): object {
  302     return actionState;
  303   }
  304 }
  305 
  306 const ACTION_MODIFIER_MANAGER = new ActionModifierManager();
  307 
  308 export default setInternalModifierManager(ACTION_MODIFIER_MANAGER, {});