Schedule sibling invalidation sets for sibling insert/remove.

Invalidation sets have been used only for changes which do not alter the
tree structure, like changing id, class names, other attributes, and
pseudo states. For dom tree changes, style invalidation relies on attach
and detach of the layout tree for the inserted/removed element. For
subsequent siblings of inserted/removed elements, we have been marking
siblings for subtree recalc (when we know we have tried to match
adjacent combinators on one of the siblings before) based on the maximum
number of consecutive direct adjacent combinators or all subsequent
siblings for indirect adjacent combinators.

This CL starts using sibling invalidation sets on siblings instead of
doing subtree recalcs.

The following properties of invalidation sets affected how this
implementation was done:

* Even though we invalidate descendants/siblings based on tag names, we
  don't have invalidation sets for tag names as elements do not change
  tag names dynamically. For inserted/removed elements, we could have
  used invalidation sets for tag names. Take the selector "div + span".
  If we remove a div we could have scheduled an invalidation set for div
  which invalidates a span sibling.

* Invalidation sets for simple selectors and their negated versions, for
  instance ".a" and ":not(.a)", share invalidation sets and they may do
  so because invalidation sets have been applied when they change. That
  is, "a" is either part of old or the new class attribute when the
  invalidation set needs to be scheduled. When removing/inserting
  elements, a selector like ":not(.a) + .b" will need to schedule a
  sibling for ".a" for all elements not having the class "a".

* Consider the selector "* + .a". We have to schedule a sibling
  invalidation for any inserted/removed element to invalidate a sibling
  with class "a". However, invalidation set construction has only
  created an invalidation set for ".a" with the invalidateSelf flag set.

For this CL, we create a single universal sibling invalidation set to
handle the cases above. In fact this CL only do sibling invalidations on
element insert/remove for id, class, and attribute in addition to
scheduling the universal sibling invalidation set. Also, we skip
selector lists (that is, :not() and :-webkit-any() as :host()
:host-context() and :slotted() never match when followed by an adjacent
combinator).

For the following set of selectors:

  :not(.a) + .b + .c
  #x:not(.a) + .d
  div + span
  :-webkit-any(.x) + .f .g

We end up with the following universal sibling invalidation set with the
descendant invalidation set, containing ".g", to the right.

  { .c, span, .f, invalidatesSelf } => { .g }

Note that if a compound contains both :not() and for instance an id
selector, we will not add it to the universal sibling invalidation set
as we can properly invalidate ".d" siblings above using the invalidation
set for "#x".

== Scheduling sibling invalidations

For changes not modifying the tree, we schedule sibling invalidation
sets on the changed element and invalidate the siblings with descendant
sets during the invalidation process. When removing an element, however,
the element is not left in the tree, so we need to associate the
invalidation set with another element.

When we remove an element, we instead schedule the sibling invalidation
set, and the sibling invalidation set's descendant set, as descendant
invalidation sets on the parent element or shadow root.

Likewise for inserting an element. When inserting an element, we have
elements to schedule the sibling sets on, but the sets would need to be
scheduled on elements further to the right in the sibling list in order
to reach the siblings we needed to invalidate. Also, they would have to
be moved further right on subsequent insertions.

== The effect on amazon.com

This CL gets rid of all post-page-load full recalcs before you start
interacting with the page. The full recalcs after you start interacting
needs to be investigated further.

R=esprehn@chromium.org,ericwilligers@chromium.org
BUG=542082

Review-Url: https://codereview.chromium.org/2089063005
Cr-Commit-Position: refs/heads/master@{#402770}
20 files changed