Пример #1
0
void SpeechRecognition::didReceiveResults(const HeapVector<Member<SpeechRecognitionResult>>& newFinalResults, const HeapVector<Member<SpeechRecognitionResult>>& currentInterimResults)
{
    size_t resultIndex = m_finalResults.size();

    for (size_t i = 0; i < newFinalResults.size(); ++i)
        m_finalResults.append(newFinalResults[i]);

    HeapVector<Member<SpeechRecognitionResult>> results = m_finalResults;
    for (size_t i = 0; i < currentInterimResults.size(); ++i)
        results.append(currentInterimResults[i]);

    dispatchEvent(SpeechRecognitionEvent::createResult(resultIndex, results));
}
void CSSVariableResolver::resolveAndApplyVariableReferences(StyleResolverState& state, CSSPropertyID id, const CSSVariableReferenceValue& value)
{
    CSSVariableResolver resolver(state.style()->variables());

    Vector<CSSParserToken> tokens;
    if (resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens)) {
        CSSParserContext context(HTMLStandardMode, 0);

        HeapVector<CSSProperty, 256> parsedProperties;

        // TODO: Non-shorthands should just call CSSPropertyParser::parseSingleValue
        if (CSSPropertyParser::parseValue(id, false, CSSParserTokenRange(tokens), context, parsedProperties, StyleRule::RuleType::Style)) {
            unsigned parsedPropertiesCount = parsedProperties.size();
            for (unsigned i = 0; i < parsedPropertiesCount; ++i)
                StyleBuilder::applyProperty(parsedProperties[i].id(), state, parsedProperties[i].value());
            return;
        }
    }

    RawPtr<CSSUnsetValue> unset = cssValuePool().createUnsetValue();
    if (isShorthandProperty(id)) {
        StylePropertyShorthand shorthand = shorthandForProperty(id);
        for (unsigned i = 0; i < shorthand.length(); i++)
            StyleBuilder::applyProperty(shorthand.properties()[i], state, unset.get());
        return;
    }

    StyleBuilder::applyProperty(id, state, unset.get());
}
DispatchEventResult IDBEventDispatcher::dispatch(Event* event, HeapVector<Member<EventTarget>>& eventTargets)
{
    size_t size = eventTargets.size();
    ASSERT(size);

    event->setEventPhase(Event::CAPTURING_PHASE);
    for (size_t i = size - 1; i; --i) { // Don't do the first element.
        event->setCurrentTarget(eventTargets[i].get());
        eventTargets[i]->fireEventListeners(event);
        if (event->propagationStopped())
            goto doneDispatching;
    }

    event->setEventPhase(Event::AT_TARGET);
    event->setCurrentTarget(eventTargets[0].get());
    eventTargets[0]->fireEventListeners(event);
    if (event->propagationStopped() || !event->bubbles() || event->cancelBubble())
        goto doneDispatching;

    event->setEventPhase(Event::BUBBLING_PHASE);
    for (size_t i = 1; i < size; ++i) { // Don't do the first element.
        event->setCurrentTarget(eventTargets[i].get());
        eventTargets[i]->fireEventListeners(event);
        if (event->propagationStopped() || event->cancelBubble())
            goto doneDispatching;
    }

doneDispatching:
    event->setCurrentTarget(nullptr);
    event->setEventPhase(Event::NONE);
    return EventTarget::dispatchEventResult(*event);
}
TEST_F(CustomElementUpgradeSorterTest, sorter_shadow) {
  // A*
  // + {ShadowRoot}
  // | + B
  // |   + C*
  // + D*
  Element* a = createElementWithId("a-a", "a");
  Element* b = createElementWithId("a-a", "b");
  Element* c = createElementWithId("a-a", "c");
  Element* d = createElementWithId("a-a", "d");

  document()->documentElement()->appendChild(a);
  ShadowRoot* s = attachShadowTo(a);
  a->appendChild(d);

  s->appendChild(b);
  b->appendChild(c);

  CustomElementUpgradeSorter sort;
  sort.add(a);
  sort.add(c);
  sort.add(d);

  HeapVector<Member<Element>> elements;
  sort.sorted(&elements, document());
  EXPECT_EQ(3u, elements.size());
  EXPECT_EQ(a, elements[0].get());
  EXPECT_EQ(c, elements[1].get());
  EXPECT_EQ(d, elements[2].get());
}
void GeolocationController::errorOccurred(GeolocationError* error)
{
    HeapVector<Member<Geolocation>> observersVector;
    copyToVector(m_observers, observersVector);
    for (size_t i = 0; i < observersVector.size(); ++i)
        observersVector[i]->setError(error);
}
void ScreenOrientationController::notifyOrientationChanged() {
  if (!isActiveAndVisible())
    return;

  updateOrientation();

  // Keep track of the frames that need to be notified before notifying the
  // current frame as it will prevent side effects from the change event
  // handlers.
  HeapVector<Member<LocalFrame>> childFrames;
  for (Frame* child = frame()->tree().firstChild(); child;
       child = child->tree().nextSibling()) {
    if (child->isLocalFrame())
      childFrames.append(toLocalFrame(child));
  }

  // Notify current orientation object.
  if (!m_dispatchEventTimer.isActive())
    m_dispatchEventTimer.startOneShot(0, BLINK_FROM_HERE);

  // ... and child frames, if they have a ScreenOrientationController.
  for (size_t i = 0; i < childFrames.size(); ++i) {
    if (ScreenOrientationController* controller =
            ScreenOrientationController::from(*childFrames[i]))
      controller->notifyOrientationChanged();
  }
}
Пример #7
0
TEST_F(MemoryCacheTest, ResourceMapIsolation) {
  FakeResource* resource1 = FakeResource::create(
      ResourceRequest("http://test/resource"), Resource::Raw);
  memoryCache()->add(resource1);

  FakeResource* resource2 = FakeResource::create(
      ResourceRequest("http://test/resource"), Resource::Raw);
  resource2->setCacheIdentifier("foo");
  memoryCache()->add(resource2);
  EXPECT_TRUE(memoryCache()->contains(resource1));
  EXPECT_TRUE(memoryCache()->contains(resource2));

  const KURL url = KURL(ParsedURLString, "http://test/resource");
  EXPECT_EQ(resource1, memoryCache()->resourceForURL(url));
  EXPECT_EQ(resource1, memoryCache()->resourceForURL(
                           url, memoryCache()->defaultCacheIdentifier()));
  EXPECT_EQ(resource2, memoryCache()->resourceForURL(url, "foo"));
  EXPECT_EQ(0, memoryCache()->resourceForURL(KURL()));

  FakeResource* resource3 = FakeResource::create(
      ResourceRequest("http://test/resource"), Resource::Raw);
  resource3->setCacheIdentifier("foo");
  memoryCache()->remove(resource2);
  memoryCache()->add(resource3);
  EXPECT_TRUE(memoryCache()->contains(resource1));
  EXPECT_FALSE(memoryCache()->contains(resource2));
  EXPECT_TRUE(memoryCache()->contains(resource3));

  HeapVector<Member<Resource>> resources = memoryCache()->resourcesForURL(url);
  EXPECT_EQ(2u, resources.size());

  memoryCache()->evictResources();
  EXPECT_FALSE(memoryCache()->contains(resource1));
  EXPECT_FALSE(memoryCache()->contains(resource3));
}
Пример #8
0
void WebCLEvent::callbackProxyOnMainThread(PassOwnPtr<WebCLEventHolder> holder)
{
    ASSERT(isMainThread());
    RefPtr<WebCLEvent> webEvent(static_cast<WebCLEvent*>(holder->event.get()));
#ifndef NDEBUG
    cl_event event = holder->event2;
#endif
    cl_int type = holder->type2;

    if (!webEvent)
        return;

    // Ignore the callback if the WebCLEvent is released or OpenCL event is abnormally terminated.
    if (webEvent->isReleased() || type != holder->type) {
        webEvent->m_callbacks.clear();
        return;
    }

    ASSERT(event == webEvent->getEvent());
    HeapVector<Member<WebCLCallback>> callbacks = webEvent->m_callbacks;
    ASSERT(callbacks.size());
    for (auto callback : callbacks)
        callback->handleEvent();

    webEvent->m_callbacks.clear();
}
Пример #9
0
void DistributionPool::distributeTo(InsertionPoint* insertionPoint,
                                    ElementShadowV0* elementShadow) {
  DistributedNodes distributedNodes;

  for (size_t i = 0; i < m_nodes.size(); ++i) {
    if (m_distributed[i])
      continue;

    if (isHTMLContentElement(*insertionPoint) &&
        !toHTMLContentElement(insertionPoint)->canSelectNode(m_nodes, i))
      continue;

    Node* node = m_nodes[i];
    distributedNodes.append(node);
    elementShadow->didDistributeNode(node, insertionPoint);
    m_distributed[i] = true;
  }

  // Distributes fallback elements
  if (insertionPoint->isContentInsertionPoint() && distributedNodes.isEmpty()) {
    for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode;
         fallbackNode = fallbackNode->nextSibling()) {
      distributedNodes.append(fallbackNode);
      elementShadow->didDistributeNode(fallbackNode, insertionPoint);
    }
  }
  insertionPoint->setDistributedNodes(distributedNodes);
}
Пример #10
0
static bool childRulesHaveFailedOrCanceledSubresources(
    const HeapVector<Member<StyleRuleBase>>& rules) {
    for (unsigned i = 0; i < rules.size(); ++i) {
        const StyleRuleBase* rule = rules[i].get();
        switch (rule->type()) {
        case StyleRuleBase::Style:
            if (toStyleRule(rule)->propertiesHaveFailedOrCanceledSubresources())
                return true;
            break;
        case StyleRuleBase::FontFace:
            if (toStyleRuleFontFace(rule)
                    ->properties()
                    .hasFailedOrCanceledSubresources())
                return true;
            break;
        case StyleRuleBase::Media:
            if (childRulesHaveFailedOrCanceledSubresources(
                        toStyleRuleMedia(rule)->childRules()))
                return true;
            break;
        case StyleRuleBase::Charset:
        case StyleRuleBase::Import:
        case StyleRuleBase::Namespace:
            ASSERT_NOT_REACHED();
        case StyleRuleBase::Page:
        case StyleRuleBase::Keyframes:
        case StyleRuleBase::Keyframe:
        case StyleRuleBase::Supports:
        case StyleRuleBase::Viewport:
            break;
        }
    }
    return false;
}
void TextTrackList::invalidateTrackIndexesAfterTrack(TextTrack* track)
{
    HeapVector<Member<TextTrack>>* tracks = nullptr;

    if (track->trackType() == TextTrack::TrackElement) {
        tracks = &m_elementTracks;
        for (size_t i = 0; i < m_addTrackTracks.size(); ++i)
            m_addTrackTracks[i]->invalidateTrackIndex();
        for (size_t i = 0; i < m_inbandTracks.size(); ++i)
            m_inbandTracks[i]->invalidateTrackIndex();
    } else if (track->trackType() == TextTrack::AddTrack) {
        tracks = &m_addTrackTracks;
        for (size_t i = 0; i < m_inbandTracks.size(); ++i)
            m_inbandTracks[i]->invalidateTrackIndex();
    } else if (track->trackType() == TextTrack::InBand) {
        tracks = &m_inbandTracks;
    } else {
        ASSERT_NOT_REACHED();
    }

    size_t index = tracks->find(track);
    if (index == kNotFound)
        return;

    for (size_t i = index; i < tracks->size(); ++i)
        tracks->at(index)->invalidateTrackIndex();
}
Пример #12
0
void LoadableTextTrack::addRegions(const HeapVector<Member<VTTRegion>>& newRegions)
{
    for (size_t i = 0; i < newRegions.size(); ++i) {
        newRegions[i]->setTrack(this);
        regions()->add(newRegions[i]);
    }
}
Пример #13
0
TEST_F(ActiveStyleSheetsTest, CompareActiveStyleSheets_Mutated) {
  ActiveStyleSheetVector oldSheets;
  ActiveStyleSheetVector newSheets;
  HeapVector<Member<RuleSet>> changedRuleSets;

  CSSStyleSheet* sheet1 = createSheet();
  CSSStyleSheet* sheet2 = createSheet();
  CSSStyleSheet* sheet3 = createSheet();

  oldSheets.append(std::make_pair(sheet1, &sheet1->contents()->ruleSet()));
  oldSheets.append(std::make_pair(sheet2, &sheet2->contents()->ruleSet()));
  oldSheets.append(std::make_pair(sheet3, &sheet3->contents()->ruleSet()));

  sheet2->contents()->clearRuleSet();
  sheet2->contents()->ensureRuleSet(MediaQueryEvaluator(),
                                    RuleHasDocumentSecurityOrigin);

  EXPECT_NE(oldSheets[1].second, &sheet2->contents()->ruleSet());

  newSheets.append(std::make_pair(sheet1, &sheet1->contents()->ruleSet()));
  newSheets.append(std::make_pair(sheet2, &sheet2->contents()->ruleSet()));
  newSheets.append(std::make_pair(sheet3, &sheet3->contents()->ruleSet()));

  EXPECT_EQ(ActiveSheetsChanged,
            compareActiveStyleSheets(oldSheets, newSheets, changedRuleSets));
  ASSERT_EQ(2u, changedRuleSets.size());
  EXPECT_EQ(&sheet2->contents()->ruleSet(), changedRuleSets[0]);
  EXPECT_EQ(oldSheets[1].second, changedRuleSets[1]);
}
Пример #14
0
void MutationObserver::deliver() {
  DCHECK(!shouldBeSuspended());

  // Calling clearTransientRegistrations() can modify m_registrations, so it's
  // necessary to make a copy of the transient registrations before operating on
  // them.
  HeapVector<Member<MutationObserverRegistration>, 1> transientRegistrations;
  for (auto& registration : m_registrations) {
    if (registration->hasTransientRegistrations())
      transientRegistrations.append(registration);
  }
  for (size_t i = 0; i < transientRegistrations.size(); ++i)
    transientRegistrations[i]->clearTransientRegistrations();

  if (m_records.isEmpty())
    return;

  MutationRecordVector records;
  records.swap(m_records);

  // Report the first (earliest) stack as the async cause.
  InspectorInstrumentation::AsyncTask asyncTask(
      m_callback->getExecutionContext(), records.first());
  m_callback->call(records, this);
}
Пример #15
0
TEST_F(CustomElementRegistryTest,
       collectCandidates_shouldOnlyIncludeCandidatesMatchingDescriptor) {
  CustomElementDescriptor descriptor("hello-world", "hello-world");

  // Does not match: namespace is not HTML
  Element* elementA = CreateElement("hello-world")
                          .inDocument(&document())
                          .inNamespace("data:text/date,1981-03-10");
  // Matches
  Element* elementB = CreateElement("hello-world").inDocument(&document());
  // Does not match: local name is not hello-world
  Element* elementC = CreateElement("button")
                          .inDocument(&document())
                          .withIsAttribute("hello-world");
  document().documentElement()->appendChild(elementA);
  elementA->appendChild(elementB);
  elementA->appendChild(elementC);

  registry().addCandidate(elementA);
  registry().addCandidate(elementB);
  registry().addCandidate(elementC);

  HeapVector<Member<Element>> elements;
  collectCandidates(descriptor, &elements);

  EXPECT_EQ(1u, elements.size())
      << "only one candidates should have been found";
  EXPECT_EQ(elementB, elements[0])
      << "the matching element should have been found";
}
Пример #16
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);
}
Пример #17
0
static void addRules(RuleSet* ruleSet,
                     const HeapVector<MinimalRuleData>& rules) {
  for (unsigned i = 0; i < rules.size(); ++i) {
    const MinimalRuleData& info = rules[i];
    ruleSet->addRule(info.m_rule, info.m_selectorIndex, info.m_flags);
  }
}
Element* SlotScopedTraversal::next(const Element& current)
{
    // current.assignedSlot returns a slot only when current is assigned explicitly
    // If current is assigned to a slot, return a descendant of current, which is in the assigned scope of the same slot as current.
    HTMLSlotElement* slot = current.assignedSlot();
    Element* nearestAncestorAssignedToSlot = SlotScopedTraversal::nearestAncestorAssignedToSlot(current);
    if (slot) {
        if (Element* next = ElementTraversal::next(current, &current))
            return next;
    } else {
        // If current is in assigned scope, find an assigned ancestor.
        ASSERT(nearestAncestorAssignedToSlot);
        if (Element* next = ElementTraversal::next(current, nearestAncestorAssignedToSlot))
            return next;
        slot = nearestAncestorAssignedToSlot->assignedSlot();
        ASSERT(slot);
    }
    HeapVector<Member<Node>> assignedNodes = slot->getAssignedNodes();
    size_t currentIndex = assignedNodes.find(*nearestAncestorAssignedToSlot);
    ASSERT(currentIndex != kNotFound);
    for (++currentIndex; currentIndex < assignedNodes.size(); ++currentIndex) {
        if (assignedNodes[currentIndex]->isElementNode())
            return toElement(assignedNodes[currentIndex]);
    }
    return nullptr;
}
ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess(
    ScriptState* scriptState,
    Navigator& navigator,
    const String& keySystem,
    const HeapVector<MediaKeySystemConfiguration>& supportedConfigurations)
{
    WTF_LOG(Media, "NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess()");

    // From https://w3c.github.io/encrypted-media/#requestMediaKeySystemAccess
    // When this method is invoked, the user agent must run the following steps:
    // 1. If keySystem is an empty string, return a promise rejected with a
    //    new DOMException whose name is InvalidAccessError.
    if (keySystem.isEmpty()) {
        return ScriptPromise::rejectWithDOMException(
            scriptState, DOMException::create(InvalidAccessError, "The keySystem parameter is empty."));
    }

    // 2. If supportedConfigurations was provided and is empty, return a
    //    promise rejected with a new DOMException whose name is
    //    InvalidAccessError.
    if (!supportedConfigurations.size()) {
        return ScriptPromise::rejectWithDOMException(
            scriptState, DOMException::create(InvalidAccessError, "The supportedConfigurations parameter is empty."));
    }

    // 3-4. 'May Document use powerful features?' check.
    ExecutionContext* executionContext = scriptState->executionContext();
    String errorMessage;
    if (executionContext->isPrivilegedContext(errorMessage)) {
        UseCounter::count(executionContext, UseCounter::EncryptedMediaSecureOrigin);
    } else {
        UseCounter::countDeprecation(executionContext, UseCounter::EncryptedMediaInsecureOrigin);
        // TODO(ddorwin): Implement the following:
        // Reject promise with a new DOMException whose name is NotSupportedError.
    }


    // 5. Let origin be the origin of document.
    //    (Passed with the execution context in step 7.)

    // 6. Let promise be a new promise.
    Document* document = toDocument(executionContext);
    if (!document->page()) {
        return ScriptPromise::rejectWithDOMException(
            scriptState, DOMException::create(InvalidStateError, "The context provided is not associated with a page."));
    }

    MediaKeySystemAccessInitializer* initializer = new MediaKeySystemAccessInitializer(scriptState, keySystem, supportedConfigurations);
    ScriptPromise promise = initializer->promise();

    // 7. Asynchronously determine support, and if allowed, create and
    //    initialize the MediaKeySystemAccess object.
    MediaKeysController* controller = MediaKeysController::from(document->page());
    WebEncryptedMediaClient* mediaClient = controller->encryptedMediaClient(executionContext);
    mediaClient->requestMediaKeySystemAccess(WebEncryptedMediaRequest(initializer));

    // 8. Return promise.
    return promise;
}
Пример #20
0
inline void DistributionPool::detachNonDistributedNodes() {
  for (size_t i = 0; i < m_nodes.size(); ++i) {
    if (m_distributed[i])
      continue;
    if (m_nodes[i]->layoutObject())
      m_nodes[i]->lazyReattachIfAttached();
  }
}
Пример #21
0
void Frame::didChangeVisibilityState()
{
    HeapVector<Member<Frame>> childFrames;
    for (Frame* child = tree().firstChild(); child; child = child->tree().nextSibling())
        childFrames.append(child);
    for (size_t i = 0; i < childFrames.size(); ++i)
        childFrames[i]->didChangeVisibilityState();
}
void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const
{
    // Search up the parent chain and create a vector of all scrollable parent objects
    // and ending with this object itself.
    HeapVector<Member<const AXObject>> objects;
    AXObject* parentObject;
    for (parentObject = this->parentObject(); parentObject; parentObject = parentObject->parentObject()) {
        if (parentObject->getScrollableAreaIfScrollable() && !parentObject->isAXScrollView())
            objects.prepend(parentObject);
    }
    objects.append(this);

    // Start with the outermost scrollable (the main window) and try to scroll the
    // next innermost object to the given point.
    int offsetX = 0, offsetY = 0;
    IntPoint point = globalPoint;
    size_t levels = objects.size() - 1;
    for (size_t i = 0; i < levels; i++) {
        const AXObject* outer = objects[i];
        const AXObject* inner = objects[i + 1];
        ScrollableArea* scrollableArea = outer->getScrollableAreaIfScrollable();

        IntRect innerRect = inner->isWebArea() ? pixelSnappedIntRect(inner->parentObject()->elementRect()) : pixelSnappedIntRect(inner->elementRect());
        IntRect objectRect = innerRect;
        IntPoint scrollPosition = scrollableArea->scrollPosition();

        // Convert the object rect into local coordinates.
        objectRect.move(offsetX, offsetY);
        if (!outer->isWebArea())
            objectRect.move(scrollPosition.x(), scrollPosition.y());

        int desiredX = computeBestScrollOffset(
            0,
            objectRect.x(), objectRect.maxX(),
            objectRect.x(), objectRect.maxX(),
            point.x(), point.x());
        int desiredY = computeBestScrollOffset(
            0,
            objectRect.y(), objectRect.maxY(),
            objectRect.y(), objectRect.maxY(),
            point.y(), point.y());
        outer->setScrollOffset(IntPoint(desiredX, desiredY));

        if (outer->isWebArea() && !inner->isWebArea()) {
            // If outer object we just scrolled is a web area (frame) but the inner object
            // is not, keep track of the coordinate transformation to apply to
            // future nested calculations.
            scrollPosition = scrollableArea->scrollPosition();
            offsetX -= (scrollPosition.x() + point.x());
            offsetY -= (scrollPosition.y() + point.y());
            point.move(scrollPosition.x() - innerRect.x(), scrollPosition.y() - innerRect.y());
        } else if (inner->isWebArea()) {
            // Otherwise, if the inner object is a web area, reset the coordinate transformation.
            offsetX = 0;
            offsetY = 0;
        }
    }
}
Пример #23
0
void LoadFontPromiseResolver::loadFonts(ExecutionContext* context) {
  if (!m_numLoading) {
    m_resolver->resolve(m_fontFaces);
    return;
  }

  for (size_t i = 0; i < m_fontFaces.size(); i++)
    m_fontFaces[i]->loadWithCallback(this, context);
}
Пример #24
0
TEST(FormDataTest, getAll) {
    FormData* fd = FormData::create(UTF8Encoding());
    fd->append("name1", "value1");

    HeapVector<FormDataEntryValue> results = fd->getAll("name1");
    EXPECT_EQ(1u, results.size());
    EXPECT_TRUE(results[0].isUSVString());
    EXPECT_EQ("value1", results[0].getAsUSVString());

    EXPECT_EQ(1u, fd->size());
}
Пример #25
0
bool CSPSource::firstSubsumesSecond(
    const HeapVector<Member<CSPSource>>& listA,
    const HeapVector<Member<CSPSource>>& listB) {
  // Empty vector of CSPSources has an effect of 'none'.
  if (!listA.size() || !listB.size())
    return !listB.size();

  // Walk through all the items in |listB|, ensuring that each is subsumed by at
  // least one item in |listA|. If any item in |listB| is not subsumed, return
  // false.
  for (const auto& sourceB : listB) {
    bool foundMatch = false;
    for (const auto& sourceA : listA) {
      if ((foundMatch = sourceA->subsumes(sourceB)))
        break;
    }
    if (!foundMatch)
      return false;
  }
  return true;
}
void GeolocationController::positionChanged(GeolocationPosition* position)
{
    if (!position) {
        errorOccurred(GeolocationError::create(GeolocationError::PositionUnavailable, "PositionUnavailable"));
        return;
    }
    m_lastPosition = position;
    HeapVector<Member<Geolocation>> observersVector;
    copyToVector(m_observers, observersVector);
    for (size_t i = 0; i < observersVector.size(); ++i)
        observersVector[i]->positionChanged();
}
Пример #27
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());
}
Пример #28
0
TEST_F(ActiveStyleSheetsTest, CompareActiveStyleSheets_NoChange) {
  ActiveStyleSheetVector oldSheets;
  ActiveStyleSheetVector newSheets;
  HeapVector<Member<RuleSet>> changedRuleSets;

  EXPECT_EQ(NoActiveSheetsChanged,
            compareActiveStyleSheets(oldSheets, newSheets, changedRuleSets));
  EXPECT_EQ(0u, changedRuleSets.size());

  CSSStyleSheet* sheet1 = createSheet();
  CSSStyleSheet* sheet2 = createSheet();

  oldSheets.append(std::make_pair(sheet1, &sheet1->contents()->ruleSet()));
  oldSheets.append(std::make_pair(sheet2, &sheet2->contents()->ruleSet()));

  newSheets.append(std::make_pair(sheet1, &sheet1->contents()->ruleSet()));
  newSheets.append(std::make_pair(sheet2, &sheet2->contents()->ruleSet()));

  EXPECT_EQ(NoActiveSheetsChanged,
            compareActiveStyleSheets(oldSheets, newSheets, changedRuleSets));
  EXPECT_EQ(0u, changedRuleSets.size());
}
Пример #29
0
TEST_F(CustomElementRegistryTest, collectCandidates_oneCandidate) {
  Element* element = CreateElement("a-a").inDocument(&document());
  registry().addCandidate(element);
  document().documentElement()->appendChild(element);

  HeapVector<Member<Element>> elements;
  collectCandidates(CustomElementDescriptor("a-a", "a-a"), &elements);

  EXPECT_EQ(1u, elements.size())
      << "exactly one candidate should have been found";
  EXPECT_TRUE(elements.contains(element))
      << "the candidate should be the element that was added";
}
Пример #30
0
TEST_F(CustomElementRegistryTest,
       collectCandidates_shouldNotIncludeElementsRemovedFromDocument) {
  Element* element = CreateElement("a-a").inDocument(&document());
  registry().addCandidate(element);

  HeapVector<Member<Element>> elements;
  collectCandidates(CustomElementDescriptor("a-a", "a-a"), &elements);

  EXPECT_TRUE(elements.isEmpty())
      << "no candidates should have been found, but we have "
      << elements.size();
  EXPECT_FALSE(elements.contains(element))
      << "the out-of-document candidate should not have been found";
}