support shadow dom

This commit is contained in:
Gabe Yuan
2023-08-23 17:53:46 +08:00
parent 4a3bf7e96c
commit f246efc84b
3 changed files with 91 additions and 178 deletions

View File

@@ -21,6 +21,8 @@
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">
<h2>React is a JavaScript library for building user interfaces.</h2>
<h2>Shadow 1</h2>
<div id="shadow1"></div>
<br />
<br />
<br />
@@ -53,7 +55,16 @@
<br />
<br />
<br />
<h2>React is a JavaScript library for building user interfaces.</h2>
<h2>
React Server Components (or RSC) is a new application architecture
designed by the React team.
</h2>
<iframe
id="iframe1"
width="800px"
height="600px"
src="http://localhost:3000/index.html"
></iframe>
<br />
<br />
<br />
@@ -86,7 +97,12 @@
<br />
<br />
<br />
<h2>React is a JavaScript library for building user interfaces.</h2>
<h2>
Weve first shared our research on RSC in an introductory talk and an
RFC.
</h2>
<h2>Shadow 2</h2>
<div id="shadow2"></div>
<br />
<br />
<br />
@@ -119,7 +135,17 @@
<br />
<br />
<br />
<h2>React is a JavaScript library for building user interfaces.</h2>
<h2>
To recap them, we are introducing a new kind of component—Server
Components—that run ahead of time and are excluded from your JavaScript
bundle.
</h2>
<iframe
id="iframe2"
width="800px"
height="600px"
src="https://react.dev/"
></iframe>
<br />
<br />
<br />
@@ -153,175 +179,42 @@
<br />
<br />
<div class="cont cont1">
<h2>React is a JavaScript library for building user interfaces.</h2>
<ul>
<li>
Declarative: React makes it painless to create interactive UIs.
Design simple views for each state in your application, and React
will efficiently update and render just the right components when
your data changes. Declarative views make your code more
predictable, simpler to understand, and easier to debug.
</li>
<li>
Component-Based: Build encapsulated components that manage their own
state, then compose them to make complex UIs. Since component logic
is written in JavaScript instead of templates, you can easily pass
rich data through your app and keep the state out of the DOM.
</li>
<li>
React 使创建交互式 UI
变得轻而易举。为你应用的每一个状态设计简洁的视图,当数据变动时 React
能高效更新并渲染合适的组件。
</li>
<li>以声明式编写 UI可以让你的代码更加可靠且方便调试。</li>
</ul>
</div>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<div class="cont cont2">
<h2>React is a JavaScript library for building user interfaces.</h2>
<ul>
<li>
Declarative: React makes it painless to create interactive UIs.
Design simple views for each state in your application, and React
will efficiently update and render just the right components when
your data changes. Declarative views make your code more
predictable, simpler to understand, and easier to debug.
</li>
<li>
Component-Based: Build encapsulated components that manage their own
state, then compose them to make complex UIs. Since component logic
is written in JavaScript instead of templates, you can easily pass
rich data through your app and keep the state out of the DOM.
</li>
<li>
React 使创建交互式 UI
变得轻而易举。为你应用的每一个状态设计简洁的视图,当数据变动时 React
能高效更新并渲染合适的组件。
</li>
<li>以声明式编写 UI可以让你的代码更加可靠且方便调试。</li>
</ul>
</div>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<div class="cont cont3">
<h2>React is a JavaScript library for building user interfaces.</h2>
<ul>
<li>
Declarative: React makes it painless to create interactive UIs.
Design simple views for each state in your application, and React
will efficiently update and render just the right components when
your data changes. Declarative views make your code more
predictable, simpler to understand, and easier to debug.
</li>
<li>
Component-Based: Build encapsulated components that manage their own
state, then compose them to make complex UIs. Since component logic
is written in JavaScript instead of templates, you can easily pass
rich data through your app and keep the state out of the DOM.
</li>
<li>
React 使创建交互式 UI
变得轻而易举。为你应用的每一个状态设计简洁的视图,当数据变动时 React
能高效更新并渲染合适的组件。
</li>
<li>以声明式编写 UI可以让你的代码更加可靠且方便调试。</li>
</ul>
</div>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<div class="cont cont4">
<h2>
React is a <code>JavaScript</code> <a href="#">library</a> for
building user interfaces.
Server Components can run during the build, letting you read from the
filesystem or fetch static content.
</h2>
<ul>
<li>
Declarative: React makes it painless to create interactive UIs.
Design simple views for each state in your application, and React
will efficiently update and render just the right components when
your data changes. Declarative views make your code more
predictable, simpler to understand, and easier to debug.
</li>
<li>
Component-Based: Build encapsulated components that manage their own
state, then compose them to make complex UIs. Since component logic
is written in JavaScript instead of templates, you can easily pass
rich data through your app and keep the state out of the DOM.
</li>
<li>
React 使创建交互式 UI
变得轻而易举。为你应用的每一个状态设计简洁的视图,当数据变动时 React
能高效更新并渲染合适的组件。
They can also run on the server, letting you access your data layer
without having to build an API. You can pass data by props from
Server Components to the interactive Client Components in the
browser.
</li>
<li>以声明式编写 UI可以让你的代码更加可靠且方便调试。</li>
</ul>
</div>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<div class="cont cont5">
<h2>React is a JavaScript library for building user interfaces.</h2>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<div class="cont cont2">
<h2>
Since our last update, we have merged the React Server Components RFC
to ratify the proposal.
</h2>
<ul>
<li>
Declarative: React makes it painless to create interactive UIs.
Design simple views for each state in your application, and React
will efficiently update and render just the right components when
your data changes. Declarative views make your code more
predictable, simpler to understand, and easier to debug.
</li>
<li>
Component-Based: Build encapsulated components that manage their own
state, then compose them to make complex UIs. Since component logic
is written in JavaScript instead of templates, you can easily pass
rich data through your app and keep the state out of the DOM.
RSC combines the simple “request/response” mental model of
server-centric Multi-Page Apps with the seamless interactivity of
client-centric Single-Page Apps, giving you the best of both worlds.
</li>
<li>
React 使创建交互式 UI
@@ -342,5 +235,14 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script>
for (var i = 1; i <= 2; i++) {
var shadow = document.querySelector("#shadow" + i);
var cont = document.querySelector(".cont" + i);
var root = shadow.attachShadow({ mode: "open" });
// root.appendChild(document.importNode(cont, true));
root.appendChild(cont.cloneNode(true));
}
</script>
</body>
</html>

View File

@@ -12,15 +12,6 @@ import { browser } from "./browser";
import { isMatch } from "./utils";
import { loadSubRules } from "./rules";
/**
* 获取节点列表并转为数组
* @param {*} selector
* @param {*} el
* @returns
*/
export const queryEls = (selector, el = document) =>
Array.from(el.querySelectorAll(selector));
/**
* 查询storage中的设置
* @returns

View File

@@ -8,10 +8,24 @@ import {
OPT_STYLE_DASHLINE,
OPT_STYLE_FUZZY,
} from "../config";
import { queryEls } from ".";
import Content from "../views/Content";
import { fetchUpdate, fetchClear } from "./fetch";
/**
* 获取节点列表并转为数组
* @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();
}
/**
* 翻译类
*/
@@ -20,6 +34,7 @@ export class Translator {
_minLength = 0;
_maxLength = 0;
// 显示
_interseObserver = new IntersectionObserver(
(intersections) => {
intersections.forEach((intersection) => {
@@ -34,11 +49,13 @@ export class Translator {
}
);
// 变化
_mutaObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
console.log("node", node);
try {
queryEls(this.rule.selector, node).forEach((el) => {
queryNodes(this.rule.selector, node).forEach((el) => {
this._interseObserver.observe(el);
});
} catch (err) {
@@ -101,14 +118,15 @@ export class Translator {
};
_register = () => {
// 监听节点变化
// 监听节点变化;
this._mutaObserver.observe(document, {
childList: true,
subtree: true,
characterData: true,
});
// 监听节点显示
queryEls(this.rule.selector).forEach((el) => {
queryNodes(this.rule.selector).forEach((el) => {
this._interseObserver.observe(el);
});
};
@@ -118,12 +136,14 @@ export class Translator {
this._mutaObserver.disconnect();
// 解除节点显示监听
queryEls(this.rule.selector).forEach((el) =>
queryNodes(this.rule.selector).forEach((el) =>
this._interseObserver.unobserve(el)
);
// 移除已插入元素
queryEls(APP_LCNAME).forEach((el) => el.remove());
queryNodes(this.rule.selector).forEach((el) => {
el?.querySelector(APP_LCNAME)?.remove();
});
// 清空任务池
fetchClear();
@@ -131,7 +151,7 @@ export class Translator {
_render = (el) => {
// 含子元素
if (el.querySelector(this.rule.selector)) {
if (queryNodes(this.rule.selector, el).length > 0) {
return;
}