void CSSAnimations::TransitionEventDelegate::onEventCondition(const AnimationEffect& animationNode) { const AnimationEffect::Phase currentPhase = animationNode.phase(); if (currentPhase == AnimationEffect::PhaseAfter && currentPhase != m_previousPhase && document().hasListenerType(Document::TRANSITIONEND_LISTENER)) { String propertyName = getPropertyNameString(m_property); const Timing& timing = animationNode.specifiedTiming(); double elapsedTime = timing.iterationDuration; const AtomicString& eventType = EventTypeNames::transitionend; String pseudoElement = PseudoElement::pseudoElementNameForEvents(pseudoId()); RefPtrWillBeRawPtr<TransitionEvent> event = TransitionEvent::create(eventType, propertyName, elapsedTime, pseudoElement); event->setTarget(eventTarget()); document().enqueueAnimationFrameEvent(event); } m_previousPhase = currentPhase; }
// With PseudoElements the DOM tree and Layout tree can differ. When you attach // a, first-letter for example, into the DOM we walk down the Layout // tree to find the correct insertion point for the LayoutObject. But, this // means if we ask for the parentOrShadowHost Node from the first-letter // pseudo element we will get some arbitrary ancestor of the LayoutObject. // // For hit testing, we need the parent Node of the LayoutObject for the // first-letter pseudo element. So, by walking up the Layout tree we know // we will get the parent and not some other ancestor. Node* PseudoElement::findAssociatedNode() const { // The ::backdrop element is parented to the LayoutView, not to the node // that it's associated with. We need to make sure ::backdrop sends the // events to the parent node correctly. if (pseudoId() == BACKDROP) return parentOrShadowHostNode(); ASSERT(layoutObject()); ASSERT(layoutObject()->parent()); // We can have any number of anonymous layout objects inserted between // us and our parent so make sure we skip over them. LayoutObject* ancestor = layoutObject()->parent(); while (ancestor->isAnonymous() || (ancestor->node() && ancestor->node()->isPseudoElement())) { ASSERT(ancestor->parent()); ancestor = ancestor->parent(); } return ancestor->node(); }