diff --git a/.eslintrc b/.eslintrc
index 6dfe6a0509..3a8dc93fc6 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 768683d2b4..e00bae199c 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 e4987baca6..cfae51b567 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 74f446f1a1..40a727327c 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 0374ebc839..0000000000
--- 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 35c4e1b9da..0000000000
--- 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 5140cd489b..e7751714f4 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 0000000000..bd4a664c7a
--- /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 3fa6303c8a..128779c153 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(),
]);
});