(options)
| 31 | // `this` when setting up the options argument. `this` can't be referenced in subclasses prior to |
| 32 | // calling their superclass constructor. |
| 33 | init(options) { |
| 34 | // Constants; short, readable names for the return values expected by handlerStack.bubbleEvent, |
| 35 | // used here and by subclasses. |
| 36 | if (options == null) { |
| 37 | options = {}; |
| 38 | } |
| 39 | this.options = options; |
| 40 | this.continueBubbling = handlerStack.continueBubbling; |
| 41 | this.suppressEvent = handlerStack.suppressEvent; |
| 42 | this.passEventToPage = handlerStack.passEventToPage; |
| 43 | this.suppressPropagation = handlerStack.suppressPropagation; |
| 44 | this.restartBubbling = handlerStack.restartBubbling; |
| 45 | |
| 46 | this.alwaysContinueBubbling = handlerStack.alwaysContinueBubbling; |
| 47 | this.alwaysSuppressPropagation = handlerStack.alwaysSuppressPropagation; |
| 48 | |
| 49 | this.handlers = []; |
| 50 | this.exitHandlers = []; |
| 51 | this.modeIsActive = true; |
| 52 | this.modeIsExiting = false; |
| 53 | this.name = this.options.name || "anonymous"; |
| 54 | |
| 55 | this.count = ++count; |
| 56 | this.id = `${this.name}-${this.count}`; |
| 57 | this.log("activate:", this.id); |
| 58 | |
| 59 | // If options.suppressAllKeyboardEvents is truthy, then all keyboard events are suppressed. This |
| 60 | // avoids the need for modes which suppress all keyboard events 1) to provide handlers for all |
| 61 | // of those events, or 2) to worry about event suppression and event-handler return values. |
| 62 | if (this.options.suppressAllKeyboardEvents) { |
| 63 | // TODO(philc): Make a let statement. |
| 64 | const downHanlder = this.options["keydown"]; |
| 65 | this.options["keydown"] = (event) => |
| 66 | this.alwaysSuppressPropagation(() => { |
| 67 | if (downHanlder) { |
| 68 | return downHanlder(event); |
| 69 | } |
| 70 | }); |
| 71 | const pressHandler = this.options["keypress"]; |
| 72 | this.options["keypress"] = (event) => |
| 73 | this.alwaysSuppressPropagation(() => { |
| 74 | if (pressHandler) { |
| 75 | return pressHandler(event); |
| 76 | } |
| 77 | }); |
| 78 | } |
| 79 | |
| 80 | this.push({ |
| 81 | keydown: this.options.keydown || null, |
| 82 | keypress: this.options.keypress || null, |
| 83 | keyup: this.options.keyup || null, |
| 84 | indicator: () => { |
| 85 | // Update the mode indicator. Setting @options.indicator to a string shows a mode indicator |
| 86 | // in the HUD. Setting @options.indicator to 'false' forces no mode indicator. |
| 87 | // If @options.indicator is undefined, then the request propagates to the next mode. |
| 88 | // The active indicator can also be changed with @setIndicator(). |
| 89 | if (this.options.indicator != null) { |
| 90 | if (this.options.indicator) { |
no test coverage detected