void AnimationTimeline::serviceAnimations(TimingUpdateReason reason)
{
    TRACE_EVENT0("blink", "AnimationTimeline::serviceAnimations");

    m_lastCurrentTimeInternal = currentTimeInternal();

    HeapVector<Member<Animation>> animations;
    animations.reserveInitialCapacity(m_animationsNeedingUpdate.size());
    for (Animation* animation : m_animationsNeedingUpdate)
        animations.append(animation);

    std::sort(animations.begin(), animations.end(), Animation::hasLowerPriority);

    for (Animation* animation : animations) {
        if (!animation->update(reason))
            m_animationsNeedingUpdate.remove(animation);
    }

    ASSERT(m_outdatedAnimationCount == 0);
    ASSERT(m_lastCurrentTimeInternal == currentTimeInternal() || (std::isnan(currentTimeInternal()) && std::isnan(m_lastCurrentTimeInternal)));

#if ENABLE(ASSERT)
    for (const auto& animation : m_animationsNeedingUpdate)
        ASSERT(!animation->outdated());
#endif
}
  void onSuccess(const WebVector<WebBluetoothRemoteGATTCharacteristicInit*>&
                     webCharacteristics) override {
    if (!m_resolver->getExecutionContext() ||
        m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
      return;

    // If the resolver is not in the set of ActiveAlgorithms then the frame
    // disconnected so we reject.
    if (!m_service->device()->gatt()->RemoveFromActiveAlgorithms(
            m_resolver.get())) {
      m_resolver->reject(
          DOMException::create(NetworkError, kGATTServerDisconnected));
      return;
    }

    if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) {
      DCHECK_EQ(1u, webCharacteristics.size());
      m_resolver->resolve(BluetoothRemoteGATTCharacteristic::take(
          m_resolver, wrapUnique(webCharacteristics[0]), m_service));
      return;
    }

    HeapVector<Member<BluetoothRemoteGATTCharacteristic>> characteristics;
    characteristics.reserveInitialCapacity(webCharacteristics.size());
    for (WebBluetoothRemoteGATTCharacteristicInit* webCharacteristic :
         webCharacteristics) {
      characteristics.append(BluetoothRemoteGATTCharacteristic::take(
          m_resolver, wrapUnique(webCharacteristic), m_service));
    }
    m_resolver->resolve(characteristics);
  }
示例#3
0
  void onSuccess(
      const WebVector<WebBluetoothRemoteGATTService*>& webServices) override {
    if (!m_resolver->getExecutionContext() ||
        m_resolver->getExecutionContext()->isContextDestroyed())
      return;

    // If the resolver is not in the set of ActiveAlgorithms then the frame
    // disconnected so we reject.
    if (!m_device->gatt()->RemoveFromActiveAlgorithms(m_resolver.get())) {
      m_resolver->reject(
          DOMException::create(NetworkError, kGATTServerDisconnected));
      return;
    }

    if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) {
      DCHECK_EQ(1u, webServices.size());
      m_resolver->resolve(m_device->getOrCreateBluetoothRemoteGATTService(
          WTF::wrapUnique(webServices[0])));
      return;
    }

    HeapVector<Member<BluetoothRemoteGATTService>> services;
    services.reserveInitialCapacity(webServices.size());
    for (WebBluetoothRemoteGATTService* webService : webServices) {
      services.append(m_device->getOrCreateBluetoothRemoteGATTService(
          WTF::wrapUnique(webService)));
    }
    m_resolver->resolve(services);
  }
示例#4
0
void NodeSet::traversalSort() const {
  HeapHashSet<Member<Node>> nodes;
  bool containsAttributeNodes = false;

  unsigned nodeCount = m_nodes.size();
  DCHECK_GT(nodeCount, 1u);
  for (unsigned i = 0; i < nodeCount; ++i) {
    Node* node = m_nodes[i].get();
    nodes.add(node);
    if (node->isAttributeNode())
      containsAttributeNodes = true;
  }

  HeapVector<Member<Node>> sortedNodes;
  sortedNodes.reserveInitialCapacity(nodeCount);

  for (Node& n : NodeTraversal::startsAt(*findRootNode(m_nodes.first()))) {
    if (nodes.contains(&n))
      sortedNodes.append(&n);

    if (!containsAttributeNodes || !n.isElementNode())
      continue;

    Element* element = toElement(&n);
    AttributeCollection attributes = element->attributes();
    for (auto& attribute : attributes) {
      Attr* attr = element->attrIfExists(attribute.name());
      if (attr && nodes.contains(attr))
        sortedNodes.append(attr);
    }
  }

  DCHECK_EQ(sortedNodes.size(), nodeCount);
  const_cast<HeapVector<Member<Node>>&>(m_nodes).swap(sortedNodes);
}
示例#5
0
FontFaceSetIterable::IterationSource* FontFaceSet::startIteration(
    ScriptState*,
    ExceptionState&) {
  // Setlike should iterate each item in insertion order, and items should
  // be keep on up to date. But since blink does not have a way to hook up CSS
  // modification, take a snapshot here, and make it ordered as follows.
  HeapVector<Member<FontFace>> fontFaces;
  if (inActiveDocumentContext()) {
    const HeapListHashSet<Member<FontFace>>& cssConnectedFaces =
        cssConnectedFontFaceList();
    fontFaces.reserveInitialCapacity(cssConnectedFaces.size() +
                                     m_nonCSSConnectedFaces.size());
    for (const auto& fontFace : cssConnectedFaces)
      fontFaces.append(fontFace);
    for (const auto& fontFace : m_nonCSSConnectedFaces)
      fontFaces.append(fontFace);
  }
  return new IterationSource(fontFaces);
}
示例#6
0
void NodeSet::sort() const {
  if (m_isSorted)
    return;

  unsigned nodeCount = m_nodes.size();
  if (nodeCount < 2) {
    const_cast<bool&>(m_isSorted) = true;
    return;
  }

  if (nodeCount > traversalSortCutoff) {
    traversalSort();
    return;
  }

  bool containsAttributeNodes = false;

  HeapVector<NodeSetVector> parentMatrix(nodeCount);
  for (unsigned i = 0; i < nodeCount; ++i) {
    NodeSetVector& parentsVector = parentMatrix[i];
    Node* n = m_nodes[i].get();
    parentsVector.append(n);
    if (n->isAttributeNode()) {
      n = toAttr(n)->ownerElement();
      parentsVector.append(n);
      containsAttributeNodes = true;
    }
    for (n = n->parentNode(); n; n = n->parentNode())
      parentsVector.append(n);
  }
  sortBlock(0, nodeCount, parentMatrix, containsAttributeNodes);

  // It is not possible to just assign the result to m_nodes, because some
  // nodes may get dereferenced and destroyed.
  HeapVector<Member<Node>> sortedNodes;
  sortedNodes.reserveInitialCapacity(nodeCount);
  for (unsigned i = 0; i < nodeCount; ++i)
    sortedNodes.append(parentMatrix[i][0]);

  const_cast<HeapVector<Member<Node>>&>(m_nodes).swap(sortedNodes);
}
示例#7
0
void Permissions::batchTaskComplete(
    ScriptPromiseResolver* resolver,
    Vector<mojom::blink::PermissionDescriptorPtr> descriptors,
    Vector<int> callerIndexToInternalIndex,
    const Vector<mojom::blink::PermissionStatus>& results) {
  if (!resolver->getExecutionContext() ||
      resolver->getExecutionContext()->activeDOMObjectsAreStopped())
    return;

  // Create the response vector by finding the status for each index by
  // using the caller to internal index mapping and looking up the status
  // using the internal index obtained.
  HeapVector<Member<PermissionStatus>> result;
  result.reserveInitialCapacity(callerIndexToInternalIndex.size());
  for (int internalIndex : callerIndexToInternalIndex) {
    result.append(PermissionStatus::createAndListen(
        resolver->getExecutionContext(), results[internalIndex],
        descriptors[internalIndex]->Clone()));
  }
  resolver->resolve(result);
}
示例#8
0
void HTMLFormattingElementList::ensureNoahsArkCondition(
    HTMLStackItem* newItem) {
  HeapVector<Member<HTMLStackItem>> candidates;
  tryToEnsureNoahsArkConditionQuickly(newItem, candidates);
  if (candidates.isEmpty())
    return;

  // We pre-allocate and re-use this second vector to save one malloc per
  // attribute that we verify.
  HeapVector<Member<HTMLStackItem>> remainingCandidates;
  remainingCandidates.reserveInitialCapacity(candidates.size());

  for (const auto& attribute : newItem->attributes()) {
    for (const auto& candidate : candidates) {
      // These properties should already have been checked by
      // tryToEnsureNoahsArkConditionQuickly.
      ASSERT(newItem->attributes().size() == candidate->attributes().size());
      ASSERT(newItem->localName() == candidate->localName() &&
             newItem->namespaceURI() == candidate->namespaceURI());

      Attribute* candidateAttribute =
          candidate->getAttributeItem(attribute.name());
      if (candidateAttribute &&
          candidateAttribute->value() == attribute.value())
        remainingCandidates.append(candidate);
    }

    if (remainingCandidates.size() < kNoahsArkCapacity)
      return;

    candidates.swap(remainingCandidates);
    remainingCandidates.shrink(0);
  }

  // Inductively, we shouldn't spin this loop very many times. It's possible,
  // however, that we wil spin the loop more than once because of how the
  // formatting element list gets permuted.
  for (size_t i = kNoahsArkCapacity - 1; i < candidates.size(); ++i)
    remove(candidates[i]->element());
}