Chromium 的 :has() 實做進展

前陣子在「Chromiu 看起來正在實做 CSS4 的 :has()」這邊提到了 Chromium:has() 實做,對應的票在「Issue 669058: CSS selectors Level 4: support :has()」這邊,不過看起來當時沒有實做完整,而且有測出問題:

The following css/selectors  web tests are failing on below platform:

css/selectors/has-basic.html - Failing on chrome/edge/firefox/safari/webkit
css/selectors/parsing/parse-has.html - Failing on chrome/edge/firefox/safari/webkit

昨天又看到新進度了:「Supports all ':has' relative argument cases」。

Supports all ':has' relative argument cases

Currently the relative selector is not supported yet, so this CL
provides the relative argument cases as follows.
 - :has(:scope > <complex-selector>)
 - :has(:scope ~ <complex-selector>)
 - :has(:scope + <complex-selector>)

看起來補上了之前沒實做的部份。更完整的討論過程可以參考 Gerrit 的「Supports all ':has' relative argument cases」這邊。

沒問題的話應該就是時間的問題了,也許三個月到半年左右?

Chromium 看起來正在實做 CSS4 的 :has()

先前一直都有在盯著「Issue 669058: CSS selectors Level 4: support :has()」這個,主要是有這個功能會對於很多應用很方便,無論是對 designer 在設計上,或是對 javascript developer 的操作。

Chromium 上對應的 commit 在「Supports :has() pseudo class matching」這邊,可以看到目前只實做了一部分:

So this CL only supports :has argument selectors starting with
descendant combinator. Argument selectors starting with other
combinators are not supported yet.
 - .a:has(.b)    : Supported
 - .a:has(> .b)  : Not supported yet
 - .a:has(~ .b)  : Not supported yet
 - .a:has(+ .b)  : Not supported yet

但至少是個進展了...

uBlock Origin 支援的 :has()

查資料的時候發現 uBlock Origin 的「Static filter syntax」已經自己實作 :has() 了 (雖然有一些限制)。

這個 CSS4 (draft) 的特性目前還沒有瀏覽器支援,所以 uBlock Origin 決定自己來:

This is a planned CSS4 operator, but no browser supports it yet. I decided to go ahead and implement it so that it can already be used. See The Relational Pseudo-class: :has() in the Selector Level 4/Editor's Draft.

由於效能問題,要求一定要有 hostname,而不能是 global rule:

uBO's implementation is simplified so as to ensure performance. The :has operator must be used with at least one hostname (it must be specific), and must be of the form (example)[.]

這對於 html block 長的幾乎一樣,只有在某個地方多出 Promoted by ... 之類的結構處理起來很方便,可以拿來找出「裡面有廣告 div 的母體 div」然後整包處理掉... (你不會只想要拿掉 Promoted by ...,而是連廣告內容都拿掉)