| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /* global $ $$ $create */// dom.js
- /* global API */// msg.js
- /* global debounce */// toolbox.js
- /* global t */// localization.js
- 'use strict';
- const hotkeys = (() => {
- const entries = document.getElementsByClassName('entry');
- let togglablesShown = true;
- let togglables = getTogglables();
- let enabled;
- window.on('resize', adjustInfoPosition);
- initHotkeyInfo();
- return {
- setState(newState = !enabled) {
- if (!newState !== !enabled) {
- window[newState ? 'on' : 'off']('keydown', onKeyDown);
- enabled = newState;
- }
- },
- };
- function onKeyDown(event) {
- if (event.ctrlKey || event.altKey || event.metaKey || !enabled ||
- /^(text|search)$/.test((document.activeElement || {}).type)) {
- return;
- }
- let entry;
- let {key, code, shiftKey} = event;
- if (key >= '0' && key <= '9') {
- entry = entries[(Number(key) || 10) - 1];
- } else if (code >= 'Digit0' && code <= 'Digit9') {
- entry = entries[(Number(code.slice(-1)) || 10) - 1];
- } else if (key === '`' || key === '*' || code === 'Backquote' || code === 'NumpadMultiply') {
- invertTogglables();
- } else if (key === '-' || code === 'NumpadSubtract') {
- toggleState(entries, 'enabled', false);
- } else if (key === '+' || code === 'NumpadAdd') {
- toggleState(entries, 'disabled', true);
- } else if (key.length === 1) {
- shiftKey = false; // typing ':' etc. needs Shift so we hide it here to avoid opening editor
- key = key.toLocaleLowerCase();
- entry = [...entries].find(e => e.innerText.toLocaleLowerCase().startsWith(key));
- }
- if (!entry) {
- return;
- }
- const target = $(shiftKey ? '.style-edit-link' : 'input', entry);
- target.dispatchEvent(new MouseEvent('click', {cancelable: true}));
- }
- function getTogglables() {
- const enabledOrAll = $('.entry.enabled') ? $$('.entry.enabled') : [...entries];
- return enabledOrAll.map(entry => entry.id);
- }
- function countEnabledTogglables() {
- let num = 0;
- for (const id of togglables) {
- num += $(`#${id}`).classList.contains('enabled');
- }
- return num;
- }
- function invertTogglables() {
- togglables = togglables.length ? togglables : getTogglables();
- togglablesShown = countEnabledTogglables() > togglables.length / 2;
- toggleState(togglables, null, !togglablesShown);
- togglablesShown = !togglablesShown;
- }
- function toggleState(list, match, enable) {
- const results = [];
- let task = Promise.resolve();
- for (let entry of list) {
- entry = typeof entry === 'string' ? $('#' + entry) : entry;
- if (!match && $('input', entry).checked !== enable || entry.classList.contains(match)) {
- results.push(entry.id);
- task = task
- .then(() => API.styles.toggle(entry.styleId, enable))
- .then(() => {
- entry.classList.toggle('enabled', enable);
- entry.classList.toggle('disabled', !enable);
- $('input', entry).checked = enable;
- });
- }
- }
- if (results.length) task.then(API.refreshAllTabs);
- return results;
- }
- function initHotkeyInfo() {
- const container = $('#hotkey-info');
- let title;
- container.onclick = ({target}) => {
- if (target.localName === 'button') {
- close();
- } else if (!container.dataset.active) {
- open();
- }
- };
- function close() {
- delete container.dataset.active;
- document.body.style.height = '';
- container.title = title;
- window.on('resize', adjustInfoPosition);
- }
- function open() {
- window.off('resize', adjustInfoPosition);
- debounce.unregister(adjustInfoPosition);
- title = container.title;
- container.title = '';
- container.style = '';
- container.dataset.active = true;
- if (!container.firstElementChild) {
- buildElement();
- }
- const height = 3 +
- container.firstElementChild.scrollHeight +
- container.lastElementChild.scrollHeight;
- if (height > document.body.clientHeight) {
- document.body.style.height = height + 'px';
- }
- }
- function buildElement() {
- const keysToElements = line =>
- line
- .split(/(<.*?>)/)
- .map(s => (!s.startsWith('<') ? s :
- $create('mark', s.slice(1, -1))));
- const linesToElements = text =>
- text
- .trim()
- .split('\n')
- .map((line, i, array) =>
- $create(i < array.length - 1 ? {
- tag: 'p',
- appendChild: keysToElements(line),
- } : {
- tag: 'a',
- target: '_blank',
- href: 'https://github.com/openstyles/stylus/wiki/Popup',
- textContent: line,
- }));
- [
- linesToElements(t('popupHotkeysInfo')),
- $create('button', t('confirmOK')),
- ].forEach(child => {
- container.appendChild($create('div', child));
- });
- }
- }
- function adjustInfoPosition(debounced) {
- if (debounced !== true) {
- debounce(adjustInfoPosition, 100, true);
- return;
- }
- }
- })();
- hotkeys.setState(true);
|