fix shadow dom
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root">
|
<div id="root">
|
||||||
<h2>React is a JavaScript library for building user interfaces.</h2>
|
<h2>React is a JavaScript library for building user interfaces.</h2>
|
||||||
|
<div id="addtitle"></div>
|
||||||
<h2>Shadow 1</h2>
|
<h2>Shadow 1</h2>
|
||||||
<div id="shadow1"></div>
|
<div id="shadow1"></div>
|
||||||
<br />
|
<br />
|
||||||
@@ -236,13 +237,28 @@
|
|||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
-->
|
-->
|
||||||
<script>
|
<script>
|
||||||
for (var i = 1; i <= 2; i++) {
|
setTimeout(function () {
|
||||||
var shadow = document.querySelector("#shadow" + i);
|
for (var i = 1; i <= 2; i++) {
|
||||||
var cont = document.querySelector(".cont" + i);
|
var shadow = document.querySelector("#shadow" + i);
|
||||||
var root = shadow.attachShadow({ mode: "open" });
|
var cont = document.querySelector(".cont" + i);
|
||||||
// root.appendChild(document.importNode(cont, true));
|
var root = shadow.attachShadow({ mode: "open" });
|
||||||
root.appendChild(cont.cloneNode(true));
|
// root.appendChild(document.importNode(cont, true));
|
||||||
}
|
root.appendChild(cont.cloneNode(true));
|
||||||
|
|
||||||
|
var newLine = document.createElement("p");
|
||||||
|
newLine.innerText = "new line";
|
||||||
|
root.appendChild(newLine);
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
setTimeout(function () {
|
||||||
|
var el = document.querySelector("h2");
|
||||||
|
el.innerText = "hello world";
|
||||||
|
|
||||||
|
var title = document.querySelector("#addtitle");
|
||||||
|
title.innerHTML = "<p>second title</p>";
|
||||||
|
}, 1000);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -10,21 +10,7 @@ import {
|
|||||||
} from "../config";
|
} from "../config";
|
||||||
import Content from "../views/Content";
|
import Content from "../views/Content";
|
||||||
import { fetchUpdate, fetchClear } from "./fetch";
|
import { fetchUpdate, fetchClear } from "./fetch";
|
||||||
|
import { debounce } from "./utils";
|
||||||
/**
|
|
||||||
* 获取节点列表并转为数组
|
|
||||||
* @param {*} selector
|
|
||||||
* @param {*} rootNode
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
function queryNodes(selector, rootNode = document) {
|
|
||||||
const childRoots = Array.from(rootNode.querySelectorAll("*"))
|
|
||||||
.map((item) => item.shadowRoot)
|
|
||||||
.filter(Boolean);
|
|
||||||
const childNodes = childRoots.map((item) => queryNodes(selector, item));
|
|
||||||
const nodes = Array.from(rootNode.querySelectorAll(selector));
|
|
||||||
return nodes.concat(childNodes).flat();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 翻译类
|
* 翻译类
|
||||||
@@ -33,6 +19,7 @@ export class Translator {
|
|||||||
_rule = {};
|
_rule = {};
|
||||||
_minLength = 0;
|
_minLength = 0;
|
||||||
_maxLength = 0;
|
_maxLength = 0;
|
||||||
|
_skipNodeNames = [APP_LCNAME, "style", "svg", "img"];
|
||||||
|
|
||||||
// 显示
|
// 显示
|
||||||
_interseObserver = new IntersectionObserver(
|
_interseObserver = new IntersectionObserver(
|
||||||
@@ -52,20 +39,35 @@ export class Translator {
|
|||||||
// 变化
|
// 变化
|
||||||
_mutaObserver = new MutationObserver((mutations) => {
|
_mutaObserver = new MutationObserver((mutations) => {
|
||||||
mutations.forEach((mutation) => {
|
mutations.forEach((mutation) => {
|
||||||
mutation.addedNodes.forEach((node) => {
|
if (
|
||||||
try {
|
mutation.target.localName !== APP_LCNAME &&
|
||||||
queryNodes(this.rule.selector, node).forEach((el) => {
|
mutation.addedNodes.length > 0
|
||||||
this._interseObserver.observe(el);
|
) {
|
||||||
});
|
const addedNodes = Array.from(mutation.addedNodes).filter((node) => {
|
||||||
} catch (err) {
|
if (!this._skipNodeNames.includes(node.localName)) {
|
||||||
//
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if (addedNodes.length > 0) {
|
||||||
|
this._reTranslate();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_overrideAttachShadow = () => {
|
||||||
|
const _this = this;
|
||||||
|
const _attachShadow = HTMLElement.prototype.attachShadow;
|
||||||
|
HTMLElement.prototype.attachShadow = function () {
|
||||||
|
_this._reTranslate();
|
||||||
|
return _attachShadow.apply(this, arguments);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
constructor(rule, { fetchInterval, fetchLimit, minLength, maxLength }) {
|
constructor(rule, { fetchInterval, fetchLimit, minLength, maxLength }) {
|
||||||
fetchUpdate(fetchInterval, fetchLimit);
|
fetchUpdate(fetchInterval, fetchLimit);
|
||||||
|
this._overrideAttachShadow();
|
||||||
this._minLength = minLength ?? TRANS_MIN_LENGTH;
|
this._minLength = minLength ?? TRANS_MIN_LENGTH;
|
||||||
this._maxLength = maxLength ?? TRANS_MAX_LENGTH;
|
this._maxLength = maxLength ?? TRANS_MAX_LENGTH;
|
||||||
this.rule = rule;
|
this.rule = rule;
|
||||||
@@ -116,16 +118,27 @@ export class Translator {
|
|||||||
this.rule = { ...this.rule, textStyle };
|
this.rule = { ...this.rule, textStyle };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_queryNodes = (rootNode = document) => {
|
||||||
|
const childRoots = Array.from(rootNode.querySelectorAll("*"))
|
||||||
|
.map((item) => item.shadowRoot)
|
||||||
|
.filter(Boolean);
|
||||||
|
const childNodes = childRoots.map((item) => this._queryNodes(item));
|
||||||
|
const nodes = Array.from(rootNode.querySelectorAll(this.rule.selector));
|
||||||
|
return nodes.concat(childNodes).flat();
|
||||||
|
};
|
||||||
|
|
||||||
_register = () => {
|
_register = () => {
|
||||||
// 监听节点变化;
|
// 监听节点变化;
|
||||||
|
this._mutaObserver.disconnect();
|
||||||
this._mutaObserver.observe(document, {
|
this._mutaObserver.observe(document, {
|
||||||
childList: true,
|
childList: true,
|
||||||
subtree: true,
|
subtree: true,
|
||||||
characterData: true,
|
// characterData: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听节点显示
|
// 监听节点显示
|
||||||
queryNodes(this.rule.selector).forEach((el) => {
|
this._queryNodes().forEach((el) => {
|
||||||
|
this._interseObserver.unobserve(el);
|
||||||
this._interseObserver.observe(el);
|
this._interseObserver.observe(el);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -135,12 +148,10 @@ export class Translator {
|
|||||||
this._mutaObserver.disconnect();
|
this._mutaObserver.disconnect();
|
||||||
|
|
||||||
// 解除节点显示监听
|
// 解除节点显示监听
|
||||||
queryNodes(this.rule.selector).forEach((el) =>
|
this._queryNodes().forEach((el) => this._interseObserver.unobserve(el));
|
||||||
this._interseObserver.unobserve(el)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 移除已插入元素
|
// 移除已插入元素
|
||||||
queryNodes(this.rule.selector).forEach((el) => {
|
this._queryNodes().forEach((el) => {
|
||||||
el?.querySelector(APP_LCNAME)?.remove();
|
el?.querySelector(APP_LCNAME)?.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -148,9 +159,18 @@ export class Translator {
|
|||||||
fetchClear();
|
fetchClear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_reTranslate = debounce(() => {
|
||||||
|
if (this.rule.transOpen === "true") {
|
||||||
|
this._queryNodes().forEach((el) => {
|
||||||
|
this._interseObserver.unobserve(el);
|
||||||
|
this._interseObserver.observe(el);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
|
||||||
_render = (el) => {
|
_render = (el) => {
|
||||||
// 含子元素
|
// 含子元素
|
||||||
if (queryNodes(this.rule.selector, el).length > 0) {
|
if (this._queryNodes(el).length > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,8 +192,10 @@ export class Translator {
|
|||||||
el.appendChild(span);
|
el.appendChild(span);
|
||||||
el.style.cssText +=
|
el.style.cssText +=
|
||||||
"-webkit-line-clamp: unset; max-height: none; height: auto;";
|
"-webkit-line-clamp: unset; max-height: none; height: auto;";
|
||||||
el.parentElement.style.cssText +=
|
if (el.parentElement) {
|
||||||
"-webkit-line-clamp: unset; max-height: none; height: auto;";
|
el.parentElement.style.cssText +=
|
||||||
|
"-webkit-line-clamp: unset; max-height: none; height: auto;";
|
||||||
|
}
|
||||||
|
|
||||||
const root = createRoot(span);
|
const root = createRoot(span);
|
||||||
root.render(<Content q={q} translator={this} />);
|
root.render(<Content q={q} translator={this} />);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import { isGm } from "./libs/browser";
|
|||||||
const $action = document.createElement("div");
|
const $action = document.createElement("div");
|
||||||
$action.setAttribute("id", "kiss-translator");
|
$action.setAttribute("id", "kiss-translator");
|
||||||
document.body.parentElement.appendChild($action);
|
document.body.parentElement.appendChild($action);
|
||||||
const shadowContainer = $action.attachShadow({ mode: "open" });
|
const shadowContainer = $action.attachShadow({ mode: "closed" });
|
||||||
const emotionRoot = document.createElement("style");
|
const emotionRoot = document.createElement("style");
|
||||||
const shadowRootElement = document.createElement("div");
|
const shadowRootElement = document.createElement("div");
|
||||||
shadowContainer.appendChild(emotionRoot);
|
shadowContainer.appendChild(emotionRoot);
|
||||||
|
|||||||
Reference in New Issue
Block a user