예제 #1
0
/* static */ void
EffectCompositor::ComposeAnimationRule(dom::Element* aElement,
                                       nsCSSPseudoElements::Type aPseudoType,
                                       CascadeLevel aCascadeLevel,
                                       bool& aStyleChanging)
{
  EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
  if (!effects) {
    return;
  }

  // The caller is responsible for calling MaybeUpdateCascadeResults first.
  MOZ_ASSERT(!effects->CascadeNeedsUpdate(),
             "Animation cascade out of date when composing animation rule");

  // Get a list of effects for the current level sorted by composite order.
  nsTArray<KeyframeEffectReadOnly*> sortedEffectList;
  for (KeyframeEffectReadOnly* effect : *effects) {
    MOZ_ASSERT(effect->GetAnimation());
    if (effect->GetAnimation()->CascadeLevel() == aCascadeLevel) {
      sortedEffectList.AppendElement(effect);
    }
  }
  sortedEffectList.Sort(EffectCompositeOrderComparator());

  RefPtr<AnimValuesStyleRule>& animationRule =
    effects->AnimationRule(aCascadeLevel);
  animationRule = nullptr;

  // We'll set aStyleChanging to true below if necessary.
  aStyleChanging = false;

  // If multiple animations specify behavior for the same property the
  // animation with the *highest* composite order wins.
  // As a result, we iterate from last animation to first and, if a
  // property has already been set, we don't change it.
  nsCSSPropertySet properties;

  for (KeyframeEffectReadOnly* effect : Reversed(sortedEffectList)) {
    effect->GetAnimation()->ComposeStyle(animationRule, properties,
                                         aStyleChanging);
  }
}
예제 #2
0
		void Matrix::Reverse()
		{
			*this = Reversed();
		}
예제 #3
0
void ContentBlockingLog::ReportLog() {
  MOZ_ASSERT(NS_IsMainThread());

  if (!IsReportingEnabled()) {
    return;
  }
  LOG("ContentBlockingLog::ReportLog [this=%p]", this);
  const bool testMode =
      StaticPrefs::telemetry_origin_telemetry_test_mode_enabled();
  OriginMetricID metricId =
      testMode ? OriginMetricID::ContentBlocking_Blocked_TestOnly
               : OriginMetricID::ContentBlocking_Blocked;
  ReportOriginSingleHash(metricId, kDummyOriginHash);

  nsTArray<HashNumber> lookupTable;
  for (const auto& originEntry : mLog) {
    if (!originEntry.mData) {
      continue;
    }

    for (const auto& logEntry : Reversed(originEntry.mData->mLogs)) {
      if (logEntry.mType !=
              nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
          logEntry.mTrackingFullHashes.IsEmpty()) {
        continue;
      }

      const bool isBlocked = logEntry.mBlocked;
      Maybe<StorageAccessGrantedReason> reason = logEntry.mReason;

      metricId = testMode ? OriginMetricID::ContentBlocking_Blocked_TestOnly
                          : OriginMetricID::ContentBlocking_Blocked;
      if (!isBlocked) {
        MOZ_ASSERT(reason.isSome());
        switch (reason.value()) {
          case StorageAccessGrantedReason::eStorageAccessAPI:
            metricId =
                testMode
                    ? OriginMetricID::
                          ContentBlocking_StorageAccessAPIExempt_TestOnly
                    : OriginMetricID::ContentBlocking_StorageAccessAPIExempt;
            break;
          case StorageAccessGrantedReason::eOpenerAfterUserInteraction:
            metricId =
                testMode
                    ? OriginMetricID::
                          ContentBlocking_OpenerAfterUserInteractionExempt_TestOnly
                    : OriginMetricID::
                          ContentBlocking_OpenerAfterUserInteractionExempt;
            break;
          case StorageAccessGrantedReason::eOpener:
            metricId =
                testMode ? OriginMetricID::ContentBlocking_OpenerExempt_TestOnly
                         : OriginMetricID::ContentBlocking_OpenerExempt;
            break;
          default:
            MOZ_ASSERT_UNREACHABLE("Unknown StorageAccessGrantedReason");
        }
      }

      for (const auto& hash : logEntry.mTrackingFullHashes) {
        HashNumber key = AddToHash(HashString(hash.get(), hash.Length()),
                                   static_cast<uint32_t>(metricId));
        if (lookupTable.Contains(key)) {
          continue;
        }
        lookupTable.AppendElement(key);
        ReportOriginSingleHash(metricId, hash);
      }
      break;
    }
  }
}
예제 #4
0
/* static */ void
EffectCompositor::UpdateCascadeResults(EffectSet& aEffectSet,
                                       Element* aElement,
                                       nsCSSPseudoElements::Type aPseudoType,
                                       nsStyleContext* aStyleContext)
{
  MOZ_ASSERT(EffectSet::GetEffectSet(aElement, aPseudoType) == &aEffectSet,
             "Effect set should correspond to the specified (pseudo-)element");
  if (aEffectSet.IsEmpty()) {
    aEffectSet.MarkCascadeUpdated();
    return;
  }

  // Get a list of effects sorted by composite order.
  nsTArray<KeyframeEffectReadOnly*> sortedEffectList;
  for (KeyframeEffectReadOnly* effect : aEffectSet) {
    sortedEffectList.AppendElement(effect);
  }
  sortedEffectList.Sort(EffectCompositeOrderComparator());

  // Get properties that override the *animations* level of the cascade.
  //
  // We only do this for properties that we can animate on the compositor
  // since we will apply other properties on the main thread where the usual
  // cascade applies.
  nsCSSPropertySet overriddenProperties;
  if (aStyleContext) {
    GetOverriddenProperties(aStyleContext, aEffectSet, overriddenProperties);
  }

  bool changed = false;
  nsCSSPropertySet animatedProperties;

  // Iterate from highest to lowest composite order.
  for (KeyframeEffectReadOnly* effect : Reversed(sortedEffectList)) {
    MOZ_ASSERT(effect->GetAnimation(),
               "Effects on a target element should have an Animation");
    bool inEffect = effect->IsInEffect();
    for (AnimationProperty& prop : effect->Properties()) {

      bool winsInCascade = !animatedProperties.HasProperty(prop.mProperty) &&
                           inEffect;

      // If this property wins in the cascade, add it to the set of animated
      // properties. We need to do this even if the property is overridden
      // (in which case we set winsInCascade to false below) since we don't
      // want to fire transitions on these properties.
      if (winsInCascade) {
        animatedProperties.AddProperty(prop.mProperty);
      }

      // For effects that will be applied to the animations level of the
      // cascade, we need to check that the property isn't being set by
      // something with higher priority in the cascade.
      //
      // We only do this, however, for properties that can be animated on
      // the compositor. For properties animated on the main thread the usual
      // cascade ensures these animations will be correctly overridden.
      if (winsInCascade &&
          effect->GetAnimation()->CascadeLevel() == CascadeLevel::Animations &&
          overriddenProperties.HasProperty(prop.mProperty)) {
        winsInCascade = false;
      }

      if (winsInCascade != prop.mWinsInCascade) {
        changed = true;
      }
      prop.mWinsInCascade = winsInCascade;
    }
  }

  aEffectSet.MarkCascadeUpdated();

  // If there is any change in the cascade result, update animations on
  // layers with the winning animations.
  nsPresContext* presContext = GetPresContext(aElement);
  if (changed && presContext) {
    // We currently unconditionally update both animations and transitions
    // even if we could, for example, get away with only updating animations.
    // This is a temporary measure until we unify all animation style updating
    // under EffectCompositor.
    AnimationCollection* animations =
      presContext->AnimationManager()->GetAnimationCollection(aElement,
                                                              aPseudoType,
                                                              false);
                                                             /* don't create */
    if (animations) {
      animations->RequestRestyle(AnimationCollection::RestyleType::Layer);
    }

    AnimationCollection* transitions =
      presContext->TransitionManager()->GetAnimationCollection(aElement,
                                                               aPseudoType,
                                                               false);
                                                             /* don't create */
    if (transitions) {
      transitions->RequestRestyle(AnimationCollection::RestyleType::Layer);
    }
  }
}