Fix copy & paste issue on diff list page

As multiple gr-diff on the list page, when process the selection,
should process the one with a valid selection.

Change-Id: Id8a3e05b7c898b7572b433f34c7bc1a38136f713
This commit is contained in:
Tao Zhou
2020-01-15 15:34:06 +01:00
parent 1f87620e51
commit a302cef622
2 changed files with 53 additions and 18 deletions

View File

@@ -192,15 +192,20 @@
}
}
/**
* For Polymer 2, use shadowRoot.getSelection instead.
*/
_getSelection() {
const diffHost = util.querySelector(document.body, 'gr-diff');
const selection = diffHost &&
diffHost.shadowRoot &&
diffHost.shadowRoot.getSelection();
return selection ? selection: window.getSelection();
const diffHosts = util.querySelectorAll(document.body, 'gr-diff');
if (!diffHosts.length) return window.getSelection();
const curDiffHost = diffHosts.find(diffHost => {
if (!diffHost || !diffHost.shadowRoot) return false;
const selection = diffHost.shadowRoot.getSelection();
// Pick the one with valid selection:
// https://developer.mozilla.org/en-US/docs/Web/API/Selection/type
return selection && selection.type !== 'None';
});
return curDiffHost ?
curDiffHost.shadowRoot.getSelection(): window.getSelection();
}
/**

View File

@@ -105,7 +105,7 @@
*/
util.querySelector = (el, selector) => {
let nodes = [el];
let element = null;
let result = null;
while (nodes.length) {
const node = nodes.pop();
@@ -113,19 +113,49 @@
if (!node || !node.querySelector) continue;
// Try find it with native querySelector directly
element = node.querySelector(selector);
result = node.querySelector(selector);
if (element) {
if (result) {
break;
} else if (node.shadowRoot) {
// If shadowHost detected, add the host and its children
nodes = nodes.concat(Array.from(node.children));
nodes.push(node.shadowRoot);
} else {
nodes = nodes.concat(Array.from(node.children));
}
// Add all nodes with shadowRoot and loop through
const allShadowNodes = [...node.querySelectorAll('*')]
.filter(child => !!child.shadowRoot)
.map(child => child.shadowRoot);
nodes = nodes.concat(allShadowNodes);
}
return element;
return result;
};
/**
* Query selector all dom elements matching with certain selector.
*
* This is shadow DOM compatible, but only works when selector is within
* one shadow host, won't work if your selector is crossing
* multiple shadow hosts.
*
* Note: this can be very expensive, only use when have to.
*/
util.querySelectorAll = (el, selector) => {
let nodes = [el];
const results = new Set();
while (nodes.length) {
const node = nodes.pop();
if (!node || !node.querySelectorAll) continue;
// Try find all from regular children
[...node.querySelectorAll(selector)]
.forEach(el => results.add(el));
// Add all nodes with shadowRoot and loop through
const allShadowNodes = [...node.querySelectorAll('*')]
.filter(child => !!child.shadowRoot)
.map(child => child.shadowRoot);
nodes = nodes.concat(allShadowNodes);
}
return [...results];
};
window.util = util;