wechat-web-devtools-linux/docs/修正主题监听.MD
2022-04-08 21:48:12 +08:00

5.0 KiB
Raw Permalink Blame History

设置位置

菜单栏 -> 设置 -> 外观设置 -> 主题

定位点

  1. F12打开调试器
  2. 进入Elements标签
  3. 变更设置,发现body标签的class属性发生变化
  4. 变化:深色添加dark类,浅色则移除
  5. 完整class: class="with-vscode-font-patch --with-theming dark"

可以将这三个class作为定位点入手处理

定位具体代码

使用--with-theming

在解压后的core.wxvpkg中搜索 grep -lr '\-\-with\-theming' . 得到两个位置:

  1. (exports.ThemingEnabledClass = "--with-theming");
  2. t.body.classList.add("--with-theming"),

第二个大概率是目标了; 正好第二个后面紧接着this.themeChange(),好了,看命名可以确定是这个了

this.setup().finally(() => {
    var e, t;
    document.body.classList.add("with-vscode-font-patch"),
        null === (e = this.ourDocumentRef) ||
            void 0 === e ||
            e.body.classList.add("with-vscode-font-patch"),
        null === (t = this.ourDocumentRef) ||
            void 0 === t ||
            t.body.classList.add("--with-theming"),
        this.themeChange();
});

分析实现

themeChange 函数:

themeChange(e) {
    var t, n, i, s, o;
    "dark" ===
    (null !==
        (n =
            null === (t = (e = e || this.props).settings.appearance) ||
            void 0 === t
                ? void 0
                : t.theme) && void 0 !== n
        ? n
        : "dark")
        ? null === (i = this.ourDocumentRef) ||
          void 0 === i ||
          i.body.classList.add("dark")
        : null === (s = this.ourDocumentRef) ||
          void 0 === s ||
          s.body.classList.remove("dark"),
        null === (o = this.ourDocumentRef) ||
            void 0 === o ||
            o.body.classList.add("with-vscode-font-patch");
}

命名处理:

themeChange(config) {
    var appearance, theme, docRef1, docRef2, docRef3;
    console.warn('themeChange', config);
    "dark" ===
    (null !==
        (theme =
            null === (appearance = (config = config || this.props).settings.appearance) ||
            void 0 === appearance
                ? void 0
                : appearance.theme) && void 0 !== theme
        ? theme
        : "dark")
        ? null === (docRef1 = this.ourDocumentRef) ||
          void 0 === docRef1 ||
          docRef1.body.classList.add("dark")
        : null === (docRef2 = this.ourDocumentRef) ||
          void 0 === docRef2 ||
          docRef2.body.classList.remove("dark"),
        null === (docRef3 = this.ourDocumentRef) ||
            void 0 === docRef3 ||
            docRef3.body.classList.add("with-vscode-font-patch");
}

审查代码,得出大致逻辑:

  1. 有传入配置使用配置;没有传入,则使用当前配置
  2. 获取主题配置
  3. 有主题配置则直接使用,否则默认dark
  4. 主题配置是dark添加dark类,否则移除

很明显,theme的值只有dark非dark的区别(根据console.warn的结果看,另一个值是white,当然这不重要) 此处没有跟随系统的判断,应该在别处。 另外,根据console.warn可以知道跟随系统也会触发themeChange

好的,我们卡住了,需要另辟蹊径。

另辟蹊径

简述: 通过字符串定位触发位置

  1. 搜索应用(除调试器外)的主题设置,即grep -lr '应用(除调试器外)的主题设置' .
  2. 获取对应标志SETTING_THEME_DESC
  3. 搜索SETTING_THEME_DESC,即grep -lr 'SETTING_THEME_DESC' .
  4. 三个结果,两个翻译,确定了

关键代码:

t.createElement(
    "div",
    { className: "uiv2-padding" },
    t.createElement(
        "label",
        {
            className: "uiv2-radio",
            onClick: this.handleAutoDetectThemeClick,
        },
        t.createElement("i", {
            className: r
                ? "uiv2-radio-icon-o"
                : "uiv2-radio-icon",
        }),
        t.createElement(
            "span",
            { className: "uiv2-radio-text" },
            o.config.FOLLOW_SYSTEM
        )
    )
)

可以看到处理“跟随系统”的函数是handleAutoDetectThemeClick 函数内执行this.props.updateIDESetting("appearance", "autoDetectTheme", !0);

通过搜索autoDetectTheme,找到一个跟主题控制相关的实现

constructor() {
    (this.onDidOSThemeChange = () => {
        const o = s.OSThemeController.shared.getCurrentTheme();
        if (o === s.OSTheme.Unknown) return;
        const n = o === s.OSTheme.Dark ? "dark" : "white";
        this._enabledThemeAutoDetect &&
            e.dispatch(t.updateIDESetting("appearance", "theme", n)),
            this._enabledDevtoolsThemeAutoDetect &&
                e.dispatch(
                    t.updateIDESetting("appearance", "devtoolsTheme", n)
                );
    }),
        (this._enabledThemeAutoDetect = !1),
        (this._enabledDevtoolsThemeAutoDetect = !1),
        this.registerListeners();
}

好了,去看看OSThemeController就知道怎么回事了