diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index e7f170a3..716bbf0f 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,9 +1,9 @@ # These are supported funding model platforms -github: [jaywcjlove] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # npm/react-hot-keys -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -custom: https://jaywcjlove.github.io/sponsor.html +# github: [jaywcjlove] +# patreon: # Replace with a single Patreon username +# open_collective: # Replace with a single Open Collective username +# ko_fi: # Replace with a single Ko-fi username +# tidelift: #npm/mocker-api +# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +custom: https://jaywcjlove.github.io/#/sponsor diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90a94d17..a375f3e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,79 +6,91 @@ on: jobs: build-deploy: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + registry-url: 'https://registry.npmjs.org' - - run: npm install - - run: npm run build - - run: npm run coverage - - run: npm run doc + - run: npm install + - run: npm run build + - run: npm run bundle + - run: npm run bundle:min + - run: npm run coverage + - run: npm run doc - - name: Generate Contributors Images - uses: jaywcjlove/github-action-contributors@main - with: - filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\]) - output: build/CONTRIBUTORS.svg - avatarSize: 42 + - name: Generate Contributors Images + uses: jaywcjlove/github-action-contributors@main + with: + filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\]) + output: build/CONTRIBUTORS.svg + avatarSize: 42 - - name: Create Coverage Badges - uses: jaywcjlove/coverage-badges-cli@main - with: - source: coverage/coverage-summary.json + - name: Create Coverage Badges + uses: jaywcjlove/coverage-badges-cli@main + with: + source: coverage/coverage-summary.json - - run: cp -rp coverage build + - run: cp -rp coverage build - - name: Create Tag - id: create_tag - uses: jaywcjlove/create-tag-action@v1.3.6 - with: - package-path: ./package.json + - name: Create Tag + id: create_tag + uses: jaywcjlove/create-tag-action@main + with: + package-path: ./package.json - - name: get tag version - id: tag_version - uses: jaywcjlove/changelog-generator@v1.5.3 + - name: get tag version + id: tag_version + uses: jaywcjlove/changelog-generator@main - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - user_name: 'github-actions[bot]' - user_email: 'github-actions[bot]@users.noreply.github.com' - commit_message: ${{steps.tag_version.outputs.tag}} ${{ github.event.head_commit.message }} - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./build + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + user_name: 'github-actions[bot]' + user_email: 'github-actions[bot]@users.noreply.github.com' + commit_message: ${{steps.tag_version.outputs.tag}} ${{ github.event.head_commit.message }} + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build - - name: Generate Changelog - id: changelog - uses: jaywcjlove/changelog-generator@v1.5.3 - with: - head-ref: ${{steps.create_tag.outputs.version}} - filter-author: (小弟调调™|Renovate Bot) - filter: '[R|r]elease[d]\s+[v|V]\d(\.\d+){0,2}' + - name: Generate Changelog + id: changelog + uses: jaywcjlove/changelog-generator@main + with: + head-ref: ${{steps.create_tag.outputs.version}} + filter-author: (小弟调调™|Renovate Bot) + filter: '[R|r]elease[d]\s+[v|V]\d(\.\d+){0,2}' - - name: Create Release - uses: ncipollo/release-action@v1 - if: steps.create_tag.outputs.successful - with: - name: ${{ steps.create_tag.outputs.version }} - tag: ${{ steps.create_tag.outputs.version }} - token: ${{ secrets.GITHUB_TOKEN }} - body: | - [![](https://img.shields.io/badge/Open%20in-unpkg-blue)](https://uiwjs.github.io/npm-unpkg/#/pkg/react-hot-keys@${{steps.changelog.outputs.version}}/file/README.md) + - name: Create Release + uses: ncipollo/release-action@v1 + if: steps.create_tag.outputs.successful + with: + name: ${{ steps.create_tag.outputs.version }} + tag: ${{ steps.create_tag.outputs.version }} + token: ${{ secrets.GITHUB_TOKEN }} + body: | + [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor) [![](https://img.shields.io/badge/Open%20in-unpkg-blue)](https://uiwjs.github.io/npm-unpkg/#/pkg/react-hot-keys@${{steps.changelog.outputs.version}}/file/README.md) - Documentation ${{ steps.changelog.outputs.tag }}: https://raw.githack.com/jaywcjlove/react-hotkeys/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html - Comparing Changes: ${{ steps.changelog.outputs.compareurl }} + Documentation ${{ steps.changelog.outputs.tag }}: https://raw.githack.com/jaywcjlove/react-hotkeys/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html + Comparing Changes: ${{ steps.changelog.outputs.compareurl }} - ```bash - npm i react-hot-keys@${{steps.changelog.outputs.version}} - ``` + ```bash + npm i react-hot-keys@${{steps.changelog.outputs.version}} + ``` - ${{ steps.changelog.outputs.changelog }} + ${{ steps.changelog.outputs.changelog }} - - uses: JS-DevTools/npm-publish@v1 - with: - token: ${{ secrets.NPM_TOKEN }} - package: ./package.json \ No newline at end of file + - name: package.json info + uses: jaywcjlove/github-action-package@main + with: + unset: scripts,eslintConfig,jest,browserslist + + - run: npm publish --access public --provenance + name: 📦 react-hot-keys publish to NPM + continue-on-error: true + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.kktrc.ts b/.kktrc.ts index 5d65d9ee..95604042 100644 --- a/.kktrc.ts +++ b/.kktrc.ts @@ -37,6 +37,11 @@ export default (conf: Configuration, env: 'development' | 'production', options: VERSION: JSON.stringify(pkg.version), }), ); + /** + * fix failed to parse source map issue + * https://github.com/kktjs/kkt/issues/446 + */ + conf.ignoreWarnings = [{ module: /node_modules[\\/]parse5[\\/]/ }]; if (env === 'production') { conf.output = { ...conf.output, publicPath: './' }; } diff --git a/dist/react-hotkeys.js b/dist/react-hotkeys.js index bbf38e48..a0f0a05c 100644 --- a/dist/react-hotkeys.js +++ b/dist/react-hotkeys.js @@ -1,7 +1,7 @@ /*! * react-hotkeys v2.7.2 * React component to listen to keydown and keyup keyboard events, defining and dispatching keyboard shortcuts. - * Copyright (c) 2022 kenny wang + * Copyright (c) 2023 kenny wang * Licensed under the MIT license. */ (function webpackUniversalModuleDefinition(root, factory) { @@ -104,201 +104,77 @@ __webpack_require__.d(__webpack_exports__, { "default": () => (/* binding */ ReactHotkeys) }); -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/classCallCheck.js -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js -function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } -} - -function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - Object.defineProperty(Constructor, "prototype", { - writable: false - }); - return Constructor; -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js -function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return self; -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js -function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/inherits.js - -function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - Object.defineProperty(subClass, "prototype", { - writable: false - }); - if (superClass) _setPrototypeOf(subClass, superClass); -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js -function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js -function _isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); - return true; - } catch (e) { - return false; - } -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/typeof.js -function _typeof(obj) { - "@babel/helpers - typeof"; - - return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }, _typeof(obj); -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js - - -function _possibleConstructorReturn(self, call) { - if (call && (_typeof(call) === "object" || typeof call === "function")) { - return call; - } else if (call !== void 0) { - throw new TypeError("Derived constructors may only return object or undefined"); - } - - return _assertThisInitialized(self); -} -;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/createSuper.js - - - -function _createSuper(Derived) { - var hasNativeReflectConstruct = _isNativeReflectConstruct(); - return function _createSuperInternal() { - var Super = _getPrototypeOf(Derived), - result; - - if (hasNativeReflectConstruct) { - var NewTarget = _getPrototypeOf(this).constructor; - result = Reflect.construct(Super, arguments, NewTarget); - } else { - result = Super.apply(this, arguments); - } - - return _possibleConstructorReturn(this, result); - }; -} // EXTERNAL MODULE: external {"root":"React","commonjs2":"react","commonjs":"react","amd":"react"} var external_root_React_commonjs2_react_commonjs_react_amd_react_ = __webpack_require__(787); var external_root_React_commonjs2_react_commonjs_react_amd_react_default = /*#__PURE__*/__webpack_require__.n(external_root_React_commonjs2_react_commonjs_react_amd_react_); ;// CONCATENATED MODULE: ./node_modules/hotkeys-js/dist/hotkeys.esm.js /**! - * hotkeys-js v3.8.8 + * hotkeys-js v3.13.2 * A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies. * - * Copyright (c) 2022 kenny wong - * http://jaywcjlove.github.io/hotkeys + * Copyright (c) 2023 kenny wong + * https://github.com/jaywcjlove/hotkeys-js.git + * + * @website: https://jaywcjlove.github.io/hotkeys-js + * Licensed under the MIT license */ -var isff = typeof navigator !== 'undefined' ? navigator.userAgent.toLowerCase().indexOf('firefox') > 0 : false; // 绑定事件 +const isff = typeof navigator !== 'undefined' ? navigator.userAgent.toLowerCase().indexOf('firefox') > 0 : false; -function addEvent(object, event, method) { +// 绑定事件 +function addEvent(object, event, method, useCapture) { if (object.addEventListener) { - object.addEventListener(event, method, false); + object.addEventListener(event, method, useCapture); } else if (object.attachEvent) { - object.attachEvent("on".concat(event), function () { + object.attachEvent("on".concat(event), () => { method(window.event); }); } -} // 修饰键转换成对应的键码 - +} +// 修饰键转换成对应的键码 function getMods(modifier, key) { - var mods = key.slice(0, key.length - 1); - - for (var i = 0; i < mods.length; i++) { - mods[i] = modifier[mods[i].toLowerCase()]; - } - + const mods = key.slice(0, key.length - 1); + for (let i = 0; i < mods.length; i++) mods[i] = modifier[mods[i].toLowerCase()]; return mods; -} // 处理传的key字符串转换成数组 - +} +// 处理传的key字符串转换成数组 function getKeys(key) { if (typeof key !== 'string') key = ''; key = key.replace(/\s/g, ''); // 匹配任何空白字符,包括空格、制表符、换页符等等 + const keys = key.split(','); // 同时设置多个快捷键,以','分割 + let index = keys.lastIndexOf(''); - var keys = key.split(','); // 同时设置多个快捷键,以','分割 - - var index = keys.lastIndexOf(''); // 快捷键可能包含',',需特殊处理 - + // 快捷键可能包含',',需特殊处理 for (; index >= 0;) { keys[index - 1] += ','; keys.splice(index, 1); index = keys.lastIndexOf(''); } - return keys; -} // 比较修饰键的数组 - +} +// 比较修饰键的数组 function compareArray(a1, a2) { - var arr1 = a1.length >= a2.length ? a1 : a2; - var arr2 = a1.length >= a2.length ? a2 : a1; - var isIndex = true; - - for (var i = 0; i < arr1.length; i++) { + const arr1 = a1.length >= a2.length ? a1 : a2; + const arr2 = a1.length >= a2.length ? a2 : a1; + let isIndex = true; + for (let i = 0; i < arr1.length; i++) { if (arr2.indexOf(arr1[i]) === -1) isIndex = false; } - return isIndex; } -var _keyMap = { +// Special Keys +const _keyMap = { backspace: 8, + '⌫': 8, tab: 9, clear: 12, enter: 13, + '↩': 13, return: 13, esc: 27, escape: 27, @@ -344,9 +220,10 @@ var _keyMap = { '[': 219, ']': 221, '\\': 220 -}; // Modifier Keys +}; -var _modifier = { +// Modifier Keys +const _modifier = { // shiftKey '⇧': 16, shift: 16, @@ -363,7 +240,7 @@ var _modifier = { cmd: 91, command: 91 }; -var modifierMap = { +const modifierMap = { 16: 'shiftKey', 18: 'altKey', 17: 'ctrlKey', @@ -373,127 +250,138 @@ var modifierMap = { altKey: 18, metaKey: 91 }; -var _mods = { +const _mods = { 16: false, 18: false, 17: false, 91: false }; -var _handlers = {}; // F1~F12 special key +const _handlers = {}; -for (var k = 1; k < 20; k++) { +// F1~F12 special key +for (let k = 1; k < 20; k++) { _keyMap["f".concat(k)] = 111 + k; } -var _downKeys = []; // 记录摁下的绑定键 - -var winListendFocus = false; // window是否已经监听了focus事件 +let _downKeys = []; // 记录摁下的绑定键 +let winListendFocus = false; // window是否已经监听了focus事件 +let _scope = 'all'; // 默认热键范围 +const elementHasBindEvent = []; // 已绑定事件的节点记录 -var _scope = 'all'; // 默认热键范围 - -var elementHasBindEvent = []; // 已绑定事件的节点记录 // 返回键码 +const code = x => _keyMap[x.toLowerCase()] || _modifier[x.toLowerCase()] || x.toUpperCase().charCodeAt(0); +const getKey = x => Object.keys(_keyMap).find(k => _keyMap[k] === x); +const getModifier = x => Object.keys(_modifier).find(k => _modifier[k] === x); -var code = function code(x) { - return _keyMap[x.toLowerCase()] || _modifier[x.toLowerCase()] || x.toUpperCase().charCodeAt(0); -}; // 设置获取当前范围(默认为'所有') - - +// 设置获取当前范围(默认为'所有') function setScope(scope) { _scope = scope || 'all'; -} // 获取当前范围 - - +} +// 获取当前范围 function getScope() { return _scope || 'all'; -} // 获取摁下绑定键的键值 - - +} +// 获取摁下绑定键的键值 function getPressedKeyCodes() { return _downKeys.slice(0); -} // 表单控件控件判断 返回 Boolean -// hotkey is effective only when filter return true - +} +function getPressedKeyString() { + return _downKeys.map(c => getKey(c) || getModifier(c) || String.fromCharCode(c)); +} +function getAllKeyCodes() { + const result = []; + Object.keys(_handlers).forEach(k => { + _handlers[k].forEach(_ref => { + let { + key, + scope, + mods, + shortcut + } = _ref; + result.push({ + scope, + shortcut, + mods, + keys: key.split('+').map(v => code(v)) + }); + }); + }); + return result; +} +// 表单控件控件判断 返回 Boolean +// hotkey is effective only when filter return true function filter(event) { - var target = event.target || event.srcElement; - var tagName = target.tagName; - var flag = true; // ignore: isContentEditable === 'true', and