Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F7147891
D1245.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Subscribers
None
D1245.id.diff
View Options
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"d3": "^5.8.2",
"datatables.net-bs4": "^1.10.19",
"ejs": "^2.6.1",
+ "elementsfrompoint-polyfill": "^1.0.0",
"eslint": "^5.15.1",
"eslint-loader": "^2.1.2",
"eslint-plugin-import": "^2.16.0",
diff --git a/swh/web/assets/src/bundles/vendors/index.js b/swh/web/assets/src/bundles/vendors/index.js
--- a/swh/web/assets/src/bundles/vendors/index.js
+++ b/swh/web/assets/src/bundles/vendors/index.js
@@ -8,10 +8,11 @@
// vendors bundles centralizing assets used in all swh-web applications
// polyfills in order to use advanced js features (like Promise or fetch)
-// in older browsers
+// in browsers that do not support them
import '@babel/polyfill';
import 'whatwg-fetch/dist/fetch.umd';
import 'url-search-params-polyfill';
+import 'elementsfrompoint-polyfill';
// jquery and bootstrap
import 'jquery';
diff --git a/swh/web/assets/src/bundles/webapp/webapp-utils.js b/swh/web/assets/src/bundles/webapp/webapp-utils.js
--- a/swh/web/assets/src/bundles/webapp/webapp-utils.js
+++ b/swh/web/assets/src/bundles/webapp/webapp-utils.js
@@ -1,5 +1,6 @@
import objectFitImages from 'object-fit-images';
import {Layout} from 'admin-lte';
+import {selectText} from 'utils/functions';
let collapseSidebar = false;
let previousSidebarState = localStorage.getItem('swh-sidebar-collapsed');
@@ -80,6 +81,47 @@
// reparent the modals to the top navigation div in order to be able
// to display them
$('.swh-browse-top-navigation').append($('.modal'));
+
+ let selectedCode = null;
+
+ function getCodeOrPreEltUnderPointer(e) {
+ let elts = document.elementsFromPoint(e.clientX, e.clientY);
+ for (let elt of elts) {
+ if (elt.nodeName === 'CODE' || elt.nodeName === 'PRE') {
+ return elt;
+ }
+ }
+ return null;
+ }
+
+ // click handler to set focus on code block for copy
+ $(document).click(e => {
+ selectedCode = getCodeOrPreEltUnderPointer(e);
+ });
+
+ function selectCode(event, selectedCode) {
+ if (selectedCode) {
+ let hljsLnCodeElts = $(selectedCode).find('.hljs-ln-code');
+ if (hljsLnCodeElts.length) {
+ selectText(hljsLnCodeElts[0], hljsLnCodeElts[hljsLnCodeElts.length - 1]);
+ } else {
+ selectText(selectedCode.firstChild, selectedCode.lastChild);
+ }
+ event.preventDefault();
+ }
+ }
+
+ // select the whole text of focused code block when user
+ // double clicks or hits Ctrl+A
+ $(document).dblclick(e => {
+ selectCode(e, getCodeOrPreEltUnderPointer(e));
+ });
+
+ $(document).keydown(e => {
+ if ((e.ctrlKey || e.metaKey) && e.key === 'a') {
+ selectCode(e, selectedCode);
+ }
+ });
});
export function initPage(page) {
diff --git a/swh/web/assets/src/utils/functions.js b/swh/web/assets/src/utils/functions.js
--- a/swh/web/assets/src/utils/functions.js
+++ b/swh/web/assets/src/utils/functions.js
@@ -47,3 +47,16 @@
export function removeUrlFragment() {
history.replaceState('', document.title, window.location.pathname + window.location.search);
}
+
+export function selectText(startNode, endNode) {
+ let selection = window.getSelection();
+ selection.removeAllRanges();
+ let range = document.createRange();
+ range.setStart(startNode, 0);
+ if (endNode.nodeName !== '#text') {
+ range.setEnd(endNode, endNode.childNodes.length);
+ } else {
+ range.setEnd(endNode, endNode.textContent.length);
+ }
+ selection.addRange(range);
+}
diff --git a/yarn.lock b/yarn.lock
--- a/yarn.lock
+++ b/yarn.lock
@@ -2941,6 +2941,11 @@
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz#b1ccf619df7295aea17bc6951dc689632629e4a9"
integrity sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==
+elementsfrompoint-polyfill@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/elementsfrompoint-polyfill/-/elementsfrompoint-polyfill-1.0.0.tgz#045291ca64fa4236e8edc01fdfe395ffc5613659"
+ integrity sha512-hw+c1PUOkZ5B8ulcIuwNH0rHLGL9tOKOjazS+jFWpoRC3we68fYEuQ+ap70CMd778iHfe+3lSEbElz0t6Y0yvw==
+
elliptic@^6.0.0:
version "6.4.1"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 23, 2:45 AM (1 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3223969
Attached To
D1245: [swh-web] Enable whole code/pre text content selection using Ctrl+A
Event Timeline
Log In to Comment