mirror of
https://github.com/alyssaxuu/omni.git
synced 2026-03-11 08:54:35 +00:00
Multiple improvements
- Focus fighting! - Toast for "invisible" actions - Bookmarks fix
This commit is contained in:
parent
e8a0ef5965
commit
a03877ea09
7 changed files with 547 additions and 13 deletions
BIN
src/assets/.DS_Store
vendored
Normal file
BIN
src/assets/.DS_Store
vendored
Normal file
Binary file not shown.
3
src/assets/check.svg
Normal file
3
src/assets/check.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.5 17C13.1944 17 17 13.1944 17 8.5C17 3.80558 13.1944 0 8.5 0C3.80558 0 0 3.80558 0 8.5C0 13.1944 3.80558 17 8.5 17ZM13.2337 6.97078C13.6242 6.58025 13.6242 5.94709 13.2337 5.55657C12.8431 5.16604 12.21 5.16604 11.8194 5.55657L7.60549 9.77051L6.07576 8.24078C5.68524 7.85025 5.05207 7.85025 4.66155 8.24078C4.27102 8.6313 4.27102 9.26446 4.66155 9.65499L6.89839 11.8918C7.08592 12.0794 7.34028 12.1847 7.60549 12.1847C7.87071 12.1847 8.12506 12.0794 8.3126 11.8918L13.2337 6.97078Z" fill="#6068D2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 654 B |
|
|
@ -2,7 +2,6 @@
|
|||
.omni-extension ::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
transition: 1s;
|
||||
}
|
||||
|
||||
.omni-extension ::-webkit-scrollbar-thumb {
|
||||
|
|
@ -10,13 +9,11 @@
|
|||
background-clip: padding-box;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 5px;
|
||||
transition: 1s;
|
||||
}
|
||||
|
||||
.omni-extension ::-webkit-scrollbar-thumb:vertical:hover,
|
||||
.omni-extension ::-webkit-scrollbar-thumb:horizontal:hover {
|
||||
background-color: rgb(110, 110, 110);
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.omni-extension ::-webkit-scrollbar-track {
|
||||
|
|
@ -345,10 +342,38 @@
|
|||
.omni-extension .omni-keys span {
|
||||
margin-left: 3px;
|
||||
}
|
||||
#body-wrap {
|
||||
width: calc(100% - 350px);
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
#omni-extension-toast {
|
||||
text-align: center;
|
||||
font-family: Inter;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
position: fixed;
|
||||
width: fit-content;
|
||||
color: var(--text);
|
||||
bottom: 10px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
margin: auto;
|
||||
background: var(--background);
|
||||
border-radius: 5px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
display: block;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.2s cubic-bezier(0.05, 0.03, 0.35, 1);
|
||||
z-index: 99999999;
|
||||
}
|
||||
#omni-extension-toast img {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.omni-show-toast {
|
||||
bottom: 20px !important;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,5 +18,6 @@
|
|||
</div>
|
||||
<div id="omni-overlay"></div>
|
||||
</div>
|
||||
<div id="omni-extension-toast"><img src=''><span>The action has been successful</span></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ $(document).ready(() => {
|
|||
$.get(chrome.runtime.getURL('/content.html'), (data) => {
|
||||
$(data).appendTo('body');
|
||||
|
||||
// Get checkmark image for toast
|
||||
$("#omni-extension-toast img").attr("src", chrome.runtime.getURL("assets/check.svg"));
|
||||
|
||||
// Request actions from the background
|
||||
chrome.runtime.sendMessage({request:"get-actions"}, (response) => {
|
||||
actions = response.actions;
|
||||
|
|
@ -114,6 +117,8 @@ $(document).ready(() => {
|
|||
$("#omni-extension").removeClass("omni-closing");
|
||||
window.setTimeout(() => {
|
||||
$("#omni-extension input").focus();
|
||||
focusLock.on($("#omni-extension input").get(0));
|
||||
$("#omni-extension input").focus();
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
|
@ -134,6 +139,15 @@ $(document).ready(() => {
|
|||
$(this).addClass("omni-item-active");
|
||||
}
|
||||
|
||||
// Show a toast when an action has been performed
|
||||
function showToast(action) {
|
||||
$("#omni-extension-toast span").html('"'+action.title+'" has been successfully performed');
|
||||
$("#omni-extension-toast").addClass("omni-show-toast");
|
||||
setTimeout(() => {
|
||||
$(".omni-show-toast").removeClass("omni-show-toast");
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
// Autocomplete commands. Since they all start with different letters, it can be the default behavior
|
||||
function checkShortHand(e, value) {
|
||||
var el = $(".omni-extension input");
|
||||
|
|
@ -273,9 +287,15 @@ $(document).ready(() => {
|
|||
chrome.runtime.sendMessage({request:"remove", type:action.type, action:action});
|
||||
} else if ($(".omni-extension input").val().toLowerCase().startsWith("/history")) {
|
||||
if (e.ctrlKey || e.metaKey) {
|
||||
window.open($(".omni-item-active").attr("data-url"), "_self");
|
||||
} else {
|
||||
window.open($(".omni-item-active").attr("data-url"));
|
||||
} else {
|
||||
window.open($(".omni-item-active").attr("data-url"), "_self");
|
||||
}
|
||||
} else if ($(".omni-extension input").val().toLowerCase().startsWith("/bookmarks")) {
|
||||
if (e.ctrlKey || e.metaKey) {
|
||||
window.open($(".omni-item-active").attr("data-url"));
|
||||
} else {
|
||||
window.open($(".omni-item-active").attr("data-url"), "_self");
|
||||
}
|
||||
} else {
|
||||
chrome.runtime.sendMessage({request:action.action, tab:action, query:$(".omni-extension input").val()});
|
||||
|
|
@ -289,12 +309,13 @@ $(document).ready(() => {
|
|||
break;
|
||||
case "scroll-bottom":
|
||||
window.scrollTo(0,document.body.scrollHeight);
|
||||
showToast(action);
|
||||
break;
|
||||
case "scroll-top":
|
||||
window.scrollTo(0,0);
|
||||
break;
|
||||
case "navigation":
|
||||
if (e.ctrlKey) {
|
||||
if (e.ctrlKey || e.metaKey) {
|
||||
window.open(action.url);
|
||||
} else {
|
||||
window.open(action.url, "_self");
|
||||
|
|
@ -327,6 +348,14 @@ $(document).ready(() => {
|
|||
case "print":
|
||||
window.print();
|
||||
break;
|
||||
case "remove-all":
|
||||
case "remove-history":
|
||||
case "remove-cookies":
|
||||
case "remove-cache":
|
||||
case "remove-local-storage":
|
||||
case "remove-passwords":
|
||||
showToast(action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
476
src/focus.js
Normal file
476
src/focus.js
Normal file
|
|
@ -0,0 +1,476 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = global || self, global.focusLock = factory());
|
||||
}(this, function () { 'use strict';
|
||||
|
||||
var toArray = function toArray(a) {
|
||||
var ret = Array(a.length);
|
||||
for (var i = 0; i < a.length; ++i) {
|
||||
ret[i] = a[i];
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
var arrayFind = function arrayFind(array, search) {
|
||||
return array.filter(function (a) {
|
||||
return a === search;
|
||||
})[0];
|
||||
};
|
||||
|
||||
var asArray = function asArray(a) {
|
||||
return Array.isArray(a) ? a : [a];
|
||||
};
|
||||
|
||||
var tabSort = function tabSort(a, b) {
|
||||
var tabDiff = a.tabIndex - b.tabIndex;
|
||||
var indexDiff = a.index - b.index;
|
||||
|
||||
if (tabDiff) {
|
||||
if (!a.tabIndex) return 1;
|
||||
if (!b.tabIndex) return -1;
|
||||
}
|
||||
|
||||
return tabDiff || indexDiff;
|
||||
};
|
||||
|
||||
var orderByTabIndex = function orderByTabIndex(nodes, filterNegative, keepGuards) {
|
||||
return toArray(nodes).map(function (node, index) {
|
||||
return {
|
||||
node: node,
|
||||
index: index,
|
||||
tabIndex: keepGuards && node.tabIndex === -1 ? (node.dataset || {}).focusGuard ? 0 : -1 : node.tabIndex
|
||||
};
|
||||
}).filter(function (data) {
|
||||
return !filterNegative || data.tabIndex >= 0;
|
||||
}).sort(tabSort);
|
||||
};
|
||||
|
||||
var tabbables = ['button:enabled:not([readonly])', 'select:enabled:not([readonly])', 'textarea:enabled:not([readonly])', 'input:enabled:not([readonly])', 'a[href]', 'area[href]', 'iframe', 'object', 'embed', '[tabindex]', '[contenteditable]', '[autofocus]'];
|
||||
|
||||
var FOCUS_GROUP = 'data-focus-lock';
|
||||
var FOCUS_DISABLED = 'data-focus-lock-disabled';
|
||||
var FOCUS_ALLOW = 'data-no-focus-lock';
|
||||
var FOCUS_AUTO = 'data-autofocus-inside';
|
||||
|
||||
var queryTabbables = tabbables.join(',');
|
||||
var queryGuardTabbables = queryTabbables + ', [data-focus-guard]';
|
||||
|
||||
var getFocusables = function getFocusables(parents, withGuards) {
|
||||
return parents.reduce(function (acc, parent) {
|
||||
return acc.concat(
|
||||
// add all tabbables inside
|
||||
toArray(parent.querySelectorAll(withGuards ? queryGuardTabbables : queryTabbables)),
|
||||
// add if node is tabble itself
|
||||
parent.parentNode ? toArray(parent.parentNode.querySelectorAll(tabbables.join(','))).filter(function (node) {
|
||||
return node === parent;
|
||||
}) : []);
|
||||
}, []);
|
||||
};
|
||||
|
||||
var getParentAutofocusables = function getParentAutofocusables(parent) {
|
||||
var parentFocus = parent.querySelectorAll('[' + FOCUS_AUTO + ']');
|
||||
return toArray(parentFocus).map(function (node) {
|
||||
return getFocusables([node]);
|
||||
}).reduce(function (acc, nodes) {
|
||||
return acc.concat(nodes);
|
||||
}, []);
|
||||
};
|
||||
|
||||
var isElementHidden = function isElementHidden(computedStyle) {
|
||||
if (!computedStyle || !computedStyle.getPropertyValue) {
|
||||
return false;
|
||||
}
|
||||
return computedStyle.getPropertyValue('display') === 'none' || computedStyle.getPropertyValue('visibility') === 'hidden';
|
||||
};
|
||||
|
||||
var isVisible = function isVisible(node) {
|
||||
return !node || node === document || !isElementHidden(window.getComputedStyle(node, null)) && isVisible(node.parentNode);
|
||||
};
|
||||
|
||||
var notHiddenInput = function notHiddenInput(node) {
|
||||
return !((node.tagName === 'INPUT' || node.tagName === 'BUTTON') && (node.type === 'hidden' || node.disabled));
|
||||
};
|
||||
|
||||
var getParents = function getParents(node) {
|
||||
var parents = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
||||
|
||||
parents.push(node);
|
||||
if (node.parentNode) {
|
||||
getParents(node.parentNode, parents);
|
||||
}
|
||||
return parents;
|
||||
};
|
||||
|
||||
var getCommonParent = function getCommonParent(nodea, nodeb) {
|
||||
var parentsA = getParents(nodea);
|
||||
var parentsB = getParents(nodeb);
|
||||
|
||||
for (var i = 0; i < parentsA.length; i += 1) {
|
||||
var currentParent = parentsA[i];
|
||||
if (parentsB.indexOf(currentParent) >= 0) {
|
||||
return currentParent;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var filterFocusable = function filterFocusable(nodes) {
|
||||
return toArray(nodes).filter(function (node) {
|
||||
return isVisible(node);
|
||||
}).filter(function (node) {
|
||||
return notHiddenInput(node);
|
||||
});
|
||||
};
|
||||
|
||||
var getTabbableNodes = function getTabbableNodes(topNodes, withGuards) {
|
||||
return orderByTabIndex(filterFocusable(getFocusables(topNodes, withGuards)), true, withGuards);
|
||||
};
|
||||
|
||||
var getAllTabbableNodes = function getAllTabbableNodes(topNodes) {
|
||||
return orderByTabIndex(filterFocusable(getFocusables(topNodes)), false);
|
||||
};
|
||||
|
||||
var parentAutofocusables = function parentAutofocusables(topNode) {
|
||||
return filterFocusable(getParentAutofocusables(topNode));
|
||||
};
|
||||
|
||||
var isRadio = function isRadio(node) {
|
||||
return node.tagName === 'INPUT' && node.type === 'radio';
|
||||
};
|
||||
|
||||
var findSelectedRadio = function findSelectedRadio(node, nodes) {
|
||||
return nodes.filter(isRadio).filter(function (el) {
|
||||
return el.name === node.name;
|
||||
}).filter(function (el) {
|
||||
return el.checked;
|
||||
})[0] || node;
|
||||
};
|
||||
|
||||
var pickFirstFocus = function pickFirstFocus(nodes) {
|
||||
if (nodes[0] && nodes.length > 1) {
|
||||
if (isRadio(nodes[0]) && nodes[0].name) {
|
||||
return findSelectedRadio(nodes[0], nodes);
|
||||
}
|
||||
}
|
||||
return nodes[0];
|
||||
};
|
||||
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||
|
||||
var filterNested = function filterNested(nodes) {
|
||||
var l = nodes.length;
|
||||
for (var i = 0; i < l; i += 1) {
|
||||
var _loop = function _loop(j) {
|
||||
if (i !== j) {
|
||||
if (nodes[i].contains(nodes[j])) {
|
||||
return {
|
||||
v: filterNested(nodes.filter(function (x) {
|
||||
return x !== nodes[j];
|
||||
}))
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (var j = 0; j < l; j += 1) {
|
||||
var _ret = _loop(j);
|
||||
|
||||
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
};
|
||||
|
||||
var getTopParent = function getTopParent(node) {
|
||||
return node.parentNode ? getTopParent(node.parentNode) : node;
|
||||
};
|
||||
|
||||
var getAllAffectedNodes = function getAllAffectedNodes(node) {
|
||||
var nodes = asArray(node);
|
||||
return nodes.filter(Boolean).reduce(function (acc, currentNode) {
|
||||
var group = currentNode.getAttribute(FOCUS_GROUP);
|
||||
acc.push.apply(acc, group ? filterNested(toArray(getTopParent(currentNode).querySelectorAll('[' + FOCUS_GROUP + '="' + group + '"]:not([' + FOCUS_DISABLED + '="disabled"])'))) : [currentNode]);
|
||||
return acc;
|
||||
}, []);
|
||||
};
|
||||
|
||||
var findAutoFocused = function findAutoFocused(autoFocusables) {
|
||||
return function (node) {
|
||||
return !!node.autofocus || node.dataset && !!node.dataset.autofocus || autoFocusables.indexOf(node) >= 0;
|
||||
};
|
||||
};
|
||||
|
||||
var newFocus = function newFocus(innerNodes, outerNodes, activeElement, lastNode, autoFocused) {
|
||||
var cnt = innerNodes.length;
|
||||
var firstFocus = innerNodes[0];
|
||||
var lastFocus = innerNodes[cnt - 1];
|
||||
|
||||
// focus is inside
|
||||
if (innerNodes.indexOf(activeElement) >= 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var activeIndex = outerNodes.indexOf(activeElement);
|
||||
var lastIndex = outerNodes.indexOf(lastNode || activeIndex);
|
||||
var lastNodeInside = innerNodes.indexOf(lastNode);
|
||||
var indexDiff = activeIndex - lastIndex;
|
||||
var firstNodeIndex = outerNodes.indexOf(firstFocus);
|
||||
var lastNodeIndex = outerNodes.indexOf(lastFocus);
|
||||
|
||||
// new focus
|
||||
if (activeIndex === -1 || lastNodeInside === -1) {
|
||||
return innerNodes.indexOf(autoFocused.length ? pickFirstFocus(autoFocused) : pickFirstFocus(innerNodes));
|
||||
}
|
||||
// old focus
|
||||
if (!indexDiff && lastNodeInside >= 0) {
|
||||
return lastNodeInside;
|
||||
}
|
||||
// jump out
|
||||
if (indexDiff && Math.abs(indexDiff) > 1) {
|
||||
return lastNodeInside;
|
||||
}
|
||||
// focus above lock
|
||||
if (activeIndex <= firstNodeIndex) {
|
||||
return cnt - 1;
|
||||
}
|
||||
// focus below lock
|
||||
if (activeIndex > lastNodeIndex) {
|
||||
return 0;
|
||||
}
|
||||
// index is inside tab order, but outside Lock
|
||||
if (indexDiff) {
|
||||
if (Math.abs(indexDiff) > 1) {
|
||||
return lastNodeInside;
|
||||
}
|
||||
return (cnt + lastNodeInside + indexDiff) % cnt;
|
||||
}
|
||||
// do nothing
|
||||
return undefined;
|
||||
};
|
||||
|
||||
var getTopCommonParent = function getTopCommonParent(baseActiveElement, leftEntry, rightEntries) {
|
||||
var activeElements = asArray(baseActiveElement);
|
||||
var leftEntries = asArray(leftEntry);
|
||||
var activeElement = activeElements[0];
|
||||
var topCommon = null;
|
||||
leftEntries.filter(Boolean).forEach(function (entry) {
|
||||
topCommon = getCommonParent(topCommon || entry, entry) || topCommon;
|
||||
rightEntries.filter(Boolean).forEach(function (subEntry) {
|
||||
var common = getCommonParent(activeElement, subEntry);
|
||||
if (common) {
|
||||
if (!topCommon || common.contains(topCommon)) {
|
||||
topCommon = common;
|
||||
} else {
|
||||
topCommon = getCommonParent(common, topCommon);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return topCommon;
|
||||
};
|
||||
|
||||
var allParentAutofocusables = function allParentAutofocusables(entries) {
|
||||
return entries.reduce(function (acc, node) {
|
||||
return acc.concat(parentAutofocusables(node));
|
||||
}, []);
|
||||
};
|
||||
|
||||
var notAGuard = function notAGuard(node) {
|
||||
return !(node.dataset && node.dataset.focusGuard);
|
||||
};
|
||||
|
||||
var reorderNodes = function reorderNodes(srcNodes, dstNodes) {
|
||||
return srcNodes.map(function (dnode) {
|
||||
return dstNodes.find(function (_ref) {
|
||||
var node = _ref.node;
|
||||
return dnode === node;
|
||||
});
|
||||
}).filter(Boolean);
|
||||
};
|
||||
|
||||
var getFocusMerge = function getFocusMerge(topNode, lastNode) {
|
||||
var activeElement = document && document.activeElement;
|
||||
var entries = getAllAffectedNodes(topNode).filter(notAGuard);
|
||||
|
||||
var commonParent = getTopCommonParent(activeElement || topNode, topNode, entries);
|
||||
|
||||
var innerElements = getTabbableNodes(entries).filter(function (_ref5) {
|
||||
var node = _ref5.node;
|
||||
return notAGuard(node);
|
||||
});
|
||||
|
||||
if (!innerElements[0]) {
|
||||
innerElements = getAllTabbableNodes(entries).filter(function (_ref6) {
|
||||
var node = _ref6.node;
|
||||
return notAGuard(node);
|
||||
});
|
||||
if (!innerElements[0]) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
var outerNodes = getTabbableNodes([commonParent]).map(function (_ref7) {
|
||||
var node = _ref7.node;
|
||||
return node;
|
||||
});
|
||||
var orderedInnerElements = reorderNodes(outerNodes, innerElements);
|
||||
var innerNodes = orderedInnerElements.map(function (_ref8) {
|
||||
var node = _ref8.node;
|
||||
return node;
|
||||
});
|
||||
|
||||
var newId = newFocus(innerNodes, outerNodes, activeElement, lastNode, innerNodes.filter(findAutoFocused(allParentAutofocusables(entries))));
|
||||
|
||||
if (newId === undefined) {
|
||||
return newId;
|
||||
}
|
||||
return orderedInnerElements[newId];
|
||||
};
|
||||
|
||||
var focusInFrame = function focusInFrame(frame) {
|
||||
return frame === document.activeElement;
|
||||
};
|
||||
|
||||
var focusInsideIframe = function focusInsideIframe(topNode) {
|
||||
return !!arrayFind(toArray(topNode.querySelectorAll('iframe')), focusInFrame);
|
||||
};
|
||||
|
||||
var focusInside = function focusInside(topNode) {
|
||||
var activeElement = document && document.activeElement;
|
||||
|
||||
if (!activeElement || activeElement.dataset && activeElement.dataset.focusGuard) {
|
||||
return false;
|
||||
}
|
||||
return getAllAffectedNodes(topNode).reduce(function (result, node) {
|
||||
return result || node.contains(activeElement) || focusInsideIframe(node);
|
||||
}, false);
|
||||
};
|
||||
|
||||
var focusIsHidden = function focusIsHidden() {
|
||||
return document && toArray(document.querySelectorAll('[' + FOCUS_ALLOW + ']')).some(function (node) {
|
||||
return node.contains(document.activeElement);
|
||||
});
|
||||
};
|
||||
|
||||
var focusOn = function focusOn(target) {
|
||||
target.focus();
|
||||
if (target.contentWindow) {
|
||||
target.contentWindow.focus();
|
||||
}
|
||||
};
|
||||
|
||||
var guardCount = 0;
|
||||
var lockDisabled = false;
|
||||
|
||||
var setFocus = (function (topNode, lastNode) {
|
||||
var focusable = getFocusMerge(topNode, lastNode);
|
||||
|
||||
if (lockDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (focusable) {
|
||||
if (guardCount > 2) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('FocusLock: focus-fighting detected. Only one focus management system could be active. ' + 'See https://github.com/theKashey/focus-lock/#focus-fighting');
|
||||
lockDisabled = true;
|
||||
setTimeout(function () {
|
||||
lockDisabled = false;
|
||||
}, 1);
|
||||
return;
|
||||
}
|
||||
guardCount++;
|
||||
focusOn(focusable.node);
|
||||
guardCount--;
|
||||
}
|
||||
});
|
||||
|
||||
var lastActiveTrap = 0;
|
||||
var lastActiveFocus = null;
|
||||
|
||||
var focusOnBody = function focusOnBody() {
|
||||
return document && document.activeElement === document.body;
|
||||
};
|
||||
|
||||
var isFreeFocus = function isFreeFocus() {
|
||||
return focusOnBody() || focusIsHidden();
|
||||
};
|
||||
|
||||
var activateTrap = function activateTrap() {
|
||||
var result = false;
|
||||
|
||||
if (lastActiveTrap) {
|
||||
var observed = lastActiveTrap;
|
||||
|
||||
if (!isFreeFocus()) {
|
||||
if (observed && !focusInside(observed)) {
|
||||
result = setFocus(observed, lastActiveFocus);
|
||||
}
|
||||
|
||||
lastActiveFocus = document.activeElement;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
var reducePropsToState = function reducePropsToState(propsList) {
|
||||
return propsList.filter(function (node) {
|
||||
return node;
|
||||
}).slice(-1)[0];
|
||||
};
|
||||
|
||||
var handleStateChangeOnClient = function handleStateChangeOnClient(trap) {
|
||||
lastActiveTrap = trap;
|
||||
|
||||
if (trap) {
|
||||
activateTrap();
|
||||
}
|
||||
};
|
||||
|
||||
var instances = [];
|
||||
|
||||
var emitChange = function emitChange(event) {
|
||||
if (handleStateChangeOnClient(reducePropsToState(instances))) {
|
||||
event && event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
var attachHandler = function attachHandler() {
|
||||
document.addEventListener('focusin', emitChange);
|
||||
};
|
||||
|
||||
var detachHandler = function detachHandler() {
|
||||
document.removeEventListener('focusin', emitChange);
|
||||
};
|
||||
|
||||
var focusLock = {
|
||||
on: function on(domNode) {
|
||||
if (instances.length === 0) {
|
||||
attachHandler();
|
||||
}
|
||||
|
||||
if (instances.indexOf(domNode) < 0) {
|
||||
instances.push(domNode);
|
||||
emitChange();
|
||||
}
|
||||
},
|
||||
off: function off(domNode) {
|
||||
instances = instances.filter(function (node) {
|
||||
return node !== domNode;
|
||||
});
|
||||
emitChange();
|
||||
|
||||
if (instances.length === 0) {
|
||||
detachHandler();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return focusLock;
|
||||
|
||||
}));
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Omni",
|
||||
"description": "Supercharge Chrome with commands, shortcuts, and more",
|
||||
"offline_enabled": true,
|
||||
"version": "1.4.1",
|
||||
"version": "1.4.2",
|
||||
"manifest_version": 3,
|
||||
"action": {
|
||||
"icons": {
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
"<all_urls>"
|
||||
],
|
||||
"run_at": "document_end",
|
||||
"js": ["jquery.js", "content.js"],
|
||||
"js": ["focus.js", "jquery.js", "content.js"],
|
||||
"css": ["content.css"]
|
||||
}
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in a new issue