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); }
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); }
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); }
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); }
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); }
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); }
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()); }