From 4721d45c2aa9ea7f0587188938ea78bec584c5b6 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sat, 8 Feb 2020 00:03:42 +0100 Subject: [PATCH] move clipboard.js to npm/webpack (#10183) - created lazy-loaded webpack chunk for clipboard.js - upgraded clipboard.js from 1.5.9 to 2.0.4 - parallelize initialization of all lazy-loaded features Co-authored-by: Antoine GIRARD --- .eslintrc | 1 - package-lock.json | 33 +++++++++++++++++++ package.json | 1 + public/vendor/librejs.html | 4 +-- public/vendor/plugins/clipboard/LICENSE | 18 ---------- .../vendor/plugins/clipboard/clipboard.min.js | 7 ---- templates/base/footer.tmpl | 1 - templates/pwa/serviceworker_js.tmpl | 2 +- web_src/js/features/clipboard.js | 23 +++++++++++++ web_src/js/index.js | 23 +++---------- 10 files changed, 64 insertions(+), 49 deletions(-) delete mode 100644 public/vendor/plugins/clipboard/LICENSE delete mode 100644 public/vendor/plugins/clipboard/clipboard.min.js create mode 100644 web_src/js/features/clipboard.js diff --git a/.eslintrc b/.eslintrc index 6dfe6a050..3a8dc93fc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -18,7 +18,6 @@ env: globals: __webpack_public_path__: true - Clipboard: false CodeMirror: false Dropzone: false emojify: false diff --git a/package-lock.json b/package-lock.json index 768683d2b..e00bae199 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2660,6 +2660,16 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, + "clipboard": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", + "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", @@ -3597,6 +3607,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" + }, "deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", @@ -5941,6 +5956,14 @@ } } }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "requires": { + "delegate": "^3.1.2" + } + }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", @@ -12230,6 +12253,11 @@ "ajv-keywords": "^3.4.1" } }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -13653,6 +13681,11 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index e4987baca..cfae51b56 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "node": ">=10" }, "dependencies": { + "clipboard": "2.0.4", "fomantic-ui": "2.8.3", "highlight.js": "9.18.1", "jquery": "3.4.1", diff --git a/public/vendor/librejs.html b/public/vendor/librejs.html index 74f446f1a..40a727327 100644 --- a/public/vendor/librejs.html +++ b/public/vendor/librejs.html @@ -41,9 +41,9 @@ *.js - clipboard.min.js + clipboard.js Expat - clipboard-1.5.9.tar.gz + clipboard-2.0.4.tar.gz gitgraph.js diff --git a/public/vendor/plugins/clipboard/LICENSE b/public/vendor/plugins/clipboard/LICENSE deleted file mode 100644 index 0374ebc83..000000000 --- a/public/vendor/plugins/clipboard/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -The MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the 'Software'), to deal in the -Software without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/public/vendor/plugins/clipboard/clipboard.min.js b/public/vendor/plugins/clipboard/clipboard.min.js deleted file mode 100644 index 35c4e1b9d..000000000 --- a/public/vendor/plugins/clipboard/clipboard.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * clipboard.js v1.5.9 - * https://zenorocha.github.io/clipboard.js - * - * Licensed MIT © Zeno Rocha - */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function r(c,s){if(!n[c]){if(!e[c]){var a="function"==typeof require&&require;if(!s&&a)return a(c,!0);if(i)return i(c,!0);var l=new Error("Cannot find module '"+c+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[c]={exports:{}};e[c][0].call(u.exports,function(t){var n=e[c][1][t];return r(n?n:t)},u,u.exports,t,e,n,o)}return n[c].exports}for(var i="function"==typeof require&&require,c=0;co;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,c=o.length;c>i;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},e.exports=o},{}],8:[function(e,n,o){!function(r,i){if("function"==typeof t&&t.amd)t(["module","select"],i);else if("undefined"!=typeof o)i(n,e("select"));else{var c={exports:{}};i(c,r.select),r.clipboardAction=c.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var r=n(e),i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},c=function(){function t(t,e){for(var n=0;n {{end}} - diff --git a/templates/pwa/serviceworker_js.tmpl b/templates/pwa/serviceworker_js.tmpl index 5140cd489..e7751714f 100644 --- a/templates/pwa/serviceworker_js.tmpl +++ b/templates/pwa/serviceworker_js.tmpl @@ -2,12 +2,12 @@ var STATIC_CACHE = 'static-cache-v1'; var urlsToCache = [ // js '{{StaticUrlPrefix}}/fomantic/semantic.min.js?v={{MD5 AppVer}}', + '{{StaticUrlPrefix}}/js/clipboard.js', '{{StaticUrlPrefix}}/js/gitgraph.js', '{{StaticUrlPrefix}}/js/highlight.js', '{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/jquery.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/swagger.js?v={{MD5 AppVer}}', - '{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js', '{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js', '{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/meta.js', '{{StaticUrlPrefix}}/vendor/plugins/dropzone/dropzone.js', diff --git a/web_src/js/features/clipboard.js b/web_src/js/features/clipboard.js new file mode 100644 index 000000000..bd4a664c7 --- /dev/null +++ b/web_src/js/features/clipboard.js @@ -0,0 +1,23 @@ +export default async function initClipboard() { + const els = document.querySelectorAll('.clipboard'); + if (!els || !els.length) return; + + const { default: ClipboardJS } = await import(/* webpackChunkName: "clipboard" */'clipboard'); + + const clipboard = new ClipboardJS(els); + clipboard.on('success', (e) => { + e.clearSelection(); + + $(`#${e.trigger.getAttribute('id')}`).popup('destroy'); + e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-success')); + $(`#${e.trigger.getAttribute('id')}`).popup('show'); + e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')); + }); + + clipboard.on('error', (e) => { + $(`#${e.trigger.getAttribute('id')}`).popup('destroy'); + e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-error')); + $(`#${e.trigger.getAttribute('id')}`).popup('show'); + e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')); + }); +} diff --git a/web_src/js/index.js b/web_src/js/index.js index 3fa6303c8..128779c15 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -10,6 +10,7 @@ import './vendor/semanticDropdown.js'; import initContextPopups from './features/contextPopup.js'; import initHighlight from './features/highlight.js'; import initGitGraph from './features/gitGraph.js'; +import initClipboard from './features/clipboard.js'; import ActivityTopAuthors from './components/ActivityTopAuthors.vue'; @@ -2453,24 +2454,6 @@ $(document).ready(async () => { } } - // Clipboard JS - const clipboard = new Clipboard('.clipboard'); - clipboard.on('success', (e) => { - e.clearSelection(); - - $(`#${e.trigger.getAttribute('id')}`).popup('destroy'); - e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-success')); - $(`#${e.trigger.getAttribute('id')}`).popup('show'); - e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')); - }); - - clipboard.on('error', (e) => { - $(`#${e.trigger.getAttribute('id')}`).popup('destroy'); - e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-error')); - $(`#${e.trigger.getAttribute('id')}`).popup('show'); - e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')); - }); - // Helpers. $('.delete-button').click(showDeletePopup); $('.add-all-button').click(showAddAllPopup); @@ -2579,7 +2562,6 @@ $(document).ready(async () => { initRepoStatusChecker(); initTemplateSearch(); initContextPopups(suburl); - initGitGraph(); // Repo clone url. if ($('#repo-clone-url').length > 0) { @@ -2616,8 +2598,11 @@ $(document).ready(async () => { } }); + // parallel init of lazy-loaded features [hljs] = await Promise.all([ initHighlight(), + initGitGraph(), + initClipboard(), ]); });