select 如何在 CSS 规则中使用 Windows 格式路径的属性?

How can one select an attribute with a Windows-format path in a CSS rule?

我希望在 VS Code 中设置一些元素的样式(但实际上可以是任何网络应用程序、Electron/NWjs-based 应用程序、基于 Neutralino 的应用程序等,任何具有 webview 并可以枚举文件系统的东西)在包含其绝对路径但格式为 Windows 的元素属性上。示例:

<li data-path="C:\Windows\System32\etc">
  <a href="#">/etc</a>
</li>

作为

li[data-path="C\:\Windows\System32\etc"]

在 JavaScript 中,我尝试使用 Element.querySelectorCSS.escape select 它,但尝试使用整个路径失败,我基本上必须以编程方式生成一个通过在反斜杠上拆分并制作超级特定的 select 或类似的可用规则:

li[data-path^="C\:"]
  [data-path*="Windows"]
  [data-path*="System32"]
  [data-path*="etc"]

这不仅看起来很糟糕,而且很容易匹配错误的项目:

<li data-path="C:\Windows\System32\Drivers\etc\some-extra-folder\some-folder-with-the-word-etc\etc">
  <a href="#">/etc</a>
</li>

是否有一些工作方法可以生成有效的 CSS 属性 select 或者这样的字符串?

如果可能的话,我宁愿避免使用像 jQuery 这样的第 3 方库来最小化依赖性,但是如果像 Sizzle.js 或其他类似 CSS querySelector 的实现是绝对是获取工作属性 select 或函数的唯一方法,我将在绝对必要时使用。

目前我正在使用 document.querySelectorAll('li[data-path]') 并循环遍历和原始比较字符串值,同时我仍在寻找 CSS 属性 select 或实际适用于 Windows-样式路径。

编辑:添加 VS Code 在其资源管理器视图中实际为文件生成的 HTML

<div class="monaco-list-row focused selected" role="treeitem" data-index="16" data-last-element="false" aria-setsize="8" aria-posinset="5" id="list_id_4_16" aria-label="app.js" aria-level="3" draggable="true" style="top: 352px; height: 22px; line-height: 22px;" aria-selected="true">
  <div class="monaco-tl-row">
    <div class="monaco-tl-indent" style="width: 40px;">
      <div class="indent-guide" style="width: 16px"></div>
      <div class="indent-guide active" style="width: 16px"></div>
    </div>
    <div class="monaco-tl-twistie" style="padding-left: 40px;"></div>
    <div class="monaco-tl-contents">
      <div class="monaco-icon-label file-icon app.js-name-file-icon js-ext-file-icon ext-file-icon javascript-lang-file-icon explorer-item" title="C:\Users\liqui\Documents\dev\neu-lx-dash\app\assets\app.js" style="display: flex;">
        <div class="monaco-icon-label-container">
          <span class="monaco-icon-name-container">
            <a class="label-name">
              <span class="monaco-highlighted-label" title="C:\Users\liqui\Documents\dev\neu-lx-dash\app\assets\app.js">
                <span>app.js</span>
              </span>
            </a>
          </span>
          <span class="monaco-icon-description-container"></span>
        </div>
      </div>
    </div>
  </div>
</div>

这是 Regex 的服务。不幸的是,AFAIK 没有 CSS 的正则表达式选择器之类的东西。但是,如果您不是直接在 CSS 中执行操作,您可以 运行 一些 js,这会使事情变得容易得多,因为您可以使用正则表达式过滤元素。这是一个例子:

var lis = document.querySelectorAll('li[data-path]');

var windowsPathRegEx = /[A-Z]\:\.*/

var winLis = [...lis].filter(
        li=>li.dataset.path.match(windowsPathRegEx)
    );

console.log(winLis);
<li id='a' data-path="C:\Windows\System32\etc">
  <a href="#">li with windows path</a>
</li>
<li id='b' no-data>
  <a href="#">li without path</a>
</li>
<li id='c' data-path="C:\Program Files\whatever">
  <a href="#">another li with windows path</a>
</li>
<li id='d' data-path="/usr/local/share">
  <a href="#">li with linux path</a>
</li>

只需开发一个适合您需要的正则表达式,您就可以开始了。

我不使用 VSCode,但我想如果它是可样式化的,应该有某种 js 初始化,您可以在其中放置这段代码。

现在有解决办法了!

I asked the CSSWG on GitHub and in JavaScript at least the escaped attribute needs to be run through the String.raw method进一步巩固越狱。给出的示例如下(使用 Element.matches 并手动转义,但也确实适用于 Element.querySelector and/or 和 CSS.escape 结果:

var li = document.createElement("li");
li.dataset.path = String.raw`c:\WINDOWS\system32\mspaint.exe`;
li.matches(String.raw`li[data-path^="c:\WINDOWS\system32\mspaint.exe"]`); // true
li.matches(String.raw`li[data-path^=c\:\WINDOWS\system32\mspaint\.exe]`); // true

万岁!将需要一个正确兼容 ES6 的浏览器。