New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

phosphor-keymap

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

phosphor-keymap - npm Package Compare versions

Comparing version 0.7.1 to 0.8.0

14

lib/manager.d.ts

@@ -48,6 +48,4 @@ import { IDisposable } from 'phosphor-disposable';

* The handler to execute when the key binding is matched.
*
* Returns `true` if the action is handled, `false` otherwise.
*/
handler: (args: any) => boolean;
handler: (args: any) => void;
/**

@@ -110,3 +108,3 @@ * The arguments for the handler, if necessary.

*/
private _removeBindings(array);
private _removeBindings(exbArray);
/**

@@ -121,2 +119,6 @@ * Start or restart the pending timer for the key map.

/**
* Replay the events which were suppressed.
*/
private _replayEvents();
/**
* Clear the pending state for the keymap.

@@ -130,6 +132,8 @@ */

private _timer;
private _replaying;
private _layout;
private _sequence;
private _exact;
private _bindings;
private _exactData;
private _events;
}

@@ -25,5 +25,7 @@ /*-----------------------------------------------------------------------------

this._timer = 0;
this._replaying = false;
this._sequence = [];
this._exact = null;
this._bindings = [];
this._exactData = null;
this._events = [];
this._layout = layout;

@@ -66,6 +68,6 @@ }

var exb = createExBinding(kb, this._layout);
if (exb)
if (exb !== null)
exbArray.push(exb);
}
this._bindings = this._bindings.concat(exbArray);
Array.prototype.push.apply(this._bindings, exbArray);
return new phosphor_disposable_1.DisposableDelegate(function () { return _this._removeBindings(exbArray); });

@@ -87,2 +89,6 @@ };

KeymapManager.prototype.processKeydownEvent = function (event) {
// Bail immediately if playing back keystrokes.
if (this._replaying) {
return;
}
// Get the canonical keystroke for the event. An empty string

@@ -97,30 +103,32 @@ // indicates a keystroke which cannot be a valid key shortcut.

// Find the exact and partial matches for the key sequence.
var matches = findSequenceMatches(this._bindings, this._sequence);
// If there are no exact matches and no partial matches, clear
// all pending state so the next key press starts from default.
if (matches.exact.length === 0 && matches.partial.length === 0) {
var _a = findMatch(this._bindings, this._sequence, event), exact = _a.exact, partial = _a.partial;
// If there is no exact or partial match, replay any suppressed
// events and clear the pending state so that the next key press
// starts from a fresh default state.
if (!exact && !partial) {
this._replayEvents();
this._clearPendingState();
return;
}
// If there are exact matches but no partial matches, the exact
// matches can be dispatched immediately. The pending state is
// cleared so the next key press starts from default.
if (matches.partial.length === 0) {
// Stop propagation of the event. If there is only a partial match,
// the event will be replayed if a final match is never triggered.
event.preventDefault();
event.stopPropagation();
// If there is an exact match but no partial, the exact match can
// be dispatched immediately. The pending state is cleared so the
// next key press starts from a fresh default state.
if (!partial) {
safeInvoke(exact);
this._clearPendingState();
dispatchBindings(matches.exact, event);
return;
}
// If there are both exact matches and partial matches, the exact
// matches are stored so that they can be dispatched if the timer
// expires before a more specific match is found.
if (matches.exact.length > 0) {
this._exactData = { exact: matches.exact, event: event };
}
// (Re)start the timer to trigger the most recent exact match in
// the event the pending partial match fails to result in a final
// unambiguous exact match.
//
// TODO - we may want to replay events if an exact match fails.
event.preventDefault();
event.stopPropagation();
// If there is both an exact match and a partial, the exact match
// is stored for future dispatch in case the timer expires before
// a more specific match is triggered.
if (exact)
this._exact = exact;
// Store the event for possible playback in the future.
this._events.push(event);
// (Re)start the timer to dispatch the most recent exact match
// in case the partial match fails to result in an exact match.
this._startTimer();

@@ -131,4 +139,14 @@ };

*/
KeymapManager.prototype._removeBindings = function (array) {
this._bindings = this._bindings.filter(function (exb) { return array.indexOf(exb) === -1; });
KeymapManager.prototype._removeBindings = function (exbArray) {
var count = 0;
for (var i = 0, n = this._bindings.length; i < n; ++i) {
var exb = this._bindings[i];
if (exbArray.indexOf(exb) !== -1) {
count++;
}
else {
this._bindings[i - count] = exb;
}
}
this._bindings.length -= count;
};

@@ -155,2 +173,17 @@ /**

/**
* Replay the events which were suppressed.
*/
KeymapManager.prototype._replayEvents = function () {
if (this._events.length === 0) {
return;
}
this._replaying = true;
for (var _i = 0, _a = this._events; _i < _a.length; _i++) {
var evt = _a[_i];
var clone = cloneKeyboardEvent(evt);
evt.target.dispatchEvent(clone);
}
this._replaying = false;
};
/**
* Clear the pending state for the keymap.

@@ -160,3 +193,4 @@ */

this._clearTimer();
this._exactData = null;
this._exact = null;
this._events.length = 0;
this._sequence.length = 0;

@@ -168,8 +202,10 @@ };

KeymapManager.prototype._onPendingTimeout = function () {
var data = this._exactData;
this._timer = 0;
this._exactData = null;
this._sequence.length = 0;
if (data)
dispatchBindings(data.exact, data.event);
if (this._exact) {
safeInvoke(this._exact);
}
else {
this._replayEvents();
}
this._clearPendingState();
};

@@ -210,3 +246,3 @@ return KeymapManager;

/**
* Test whether an ex-binding sequence matches a key sequence.
* Test whether a binding sequence matches a key sequence.
*

@@ -230,56 +266,78 @@ * Returns a `SequenceMatch` value indicating the type of match.

/**
* Find the extended bindings which match a key sequence.
* Find the distance from the target node to the first matching node.
*
* Returns a match result which contains the exact and partial matches.
* This traverses the event path from `target` to `currentTarget` and
* computes the distance from `target` to the first node which matches
* the CSS selector. If no match is found, `-1` is returned.
*/
function findSequenceMatches(bindings, sequence) {
var exact = [];
var partial = [];
for (var _i = 0; _i < bindings.length; _i++) {
var exb = bindings[_i];
var match = matchSequence(exb.sequence, sequence);
if (match === 1 /* Exact */) {
exact.push(exb);
function targetDistance(selector, event) {
var distance = 0;
var target = event.target;
var current = event.currentTarget;
for (; target !== null; target = target.parentElement, ++distance) {
if (matchesSelector(target, selector)) {
return distance;
}
else if (match === 2 /* Partial */) {
partial.push(exb);
if (target === current) {
return -1;
}
}
return { exact: exact, partial: partial };
return -1;
}
/**
* Find the bindings which match the given target element.
* Find the bindings which match a key sequence.
*
* The matched bindings are ordered from highest to lowest specificity.
* This returns a match result which contains the best exact matching
* binding, and a flag which indicates if there are partial matches.
*/
function findOrderedMatches(bindings, target) {
return bindings.filter(function (exb) {
return matchesSelector(target, exb.selector);
}).sort(function (a, b) {
return b.specificity - a.specificity;
});
function findMatch(bindings, sequence, event) {
// Whether a partial match has been found.
var partial = false;
// The current best exact match.
var exact = null;
// The match distance for the exact match.
var distance = Infinity;
// Iterate the bindings and search for the best match.
for (var i = 0, n = bindings.length; i < n; ++i) {
// Lookup the current binding.
var exb = bindings[i];
// Check whether the binding sequence is a match.
var match = matchSequence(exb.sequence, sequence);
// If there is no match, the binding is ignored.
if (match === 0 /* None */) {
continue;
}
// If it is a partial match and no other partial match has been
// found, ensure the selector matches and mark the partial flag.
if (match === 2 /* Partial */) {
if (!partial && targetDistance(exb.selector, event) !== -1) {
partial = true;
}
continue;
}
// Otherwise, it's an exact match. Update the best match if the
// binding is a stronger match than the current best exact match.
var td = targetDistance(exb.selector, event);
if (td !== -1 && td <= distance) {
if (exact === null || exb.specificity > exact.specificity) {
exact = exb;
distance = td;
}
}
}
// Return the match result.
return { exact: exact, partial: partial };
}
/**
* Dispatch the key bindings for the given keyboard event.
* Safely invoke the handler for the key binding.
*
* As the dispatcher walks up the DOM, the bindings will be filtered
* for the best matching keybinding. If a match is found, the handler
* is invoked and event propagation is stopped.
* Exceptions in the handler will be caught and logged.
*/
function dispatchBindings(bindings, event) {
var target = event.target;
while (target) {
for (var _i = 0, _a = findOrderedMatches(bindings, target); _i < _a.length; _i++) {
var _b = _a[_i], handler = _b.handler, args = _b.args;
if (handler(args)) {
event.preventDefault();
event.stopPropagation();
return;
}
}
if (target === event.currentTarget) {
return;
}
target = target.parentElement;
function safeInvoke(binding) {
try {
binding.handler.call(void 0, binding.args);
}
catch (err) {
console.error(err);
}
}

@@ -311,1 +369,23 @@ /**

}
/**
* Clone a keyboard event.
*
* #### Notes
* A custom event is required because Chrome nulls out the `keyCode`
* field in user-generated `KeyboardEvent` types.
*/
function cloneKeyboardEvent(event) {
var clone = document.createEvent('Event');
var bubbles = event.bubbles || true;
var cancelable = event.cancelable || true;
clone.initEvent(event.type || 'keydown', bubbles, cancelable);
clone.key = event.key || '';
clone.keyCode = event.keyCode || 0;
clone.which = event.keyCode || 0;
clone.ctrlKey = event.ctrlKey || false;
clone.altKey = event.altKey || false;
clone.shiftKey = event.shiftKey || false;
clone.metaKey = event.metaKey || false;
clone.view = event.view || window;
return clone;
}
{
"name": "phosphor-keymap",
"version": "0.7.1",
"version": "0.8.0",
"description": "A module for keyboard shortcut mapping.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc