예제 #1
0
TEST_F(ActiveStyleSheetsTest, CompareActiveStyleSheets_AppendedToNonEmpty) {
  ActiveStyleSheetVector oldSheets;
  ActiveStyleSheetVector newSheets;
  HeapVector<Member<RuleSet>> changedRuleSets;

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

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

  EXPECT_EQ(ActiveSheetsAppended,
            compareActiveStyleSheets(oldSheets, newSheets, changedRuleSets));
  EXPECT_EQ(1u, changedRuleSets.size());
}
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);
}
예제 #3
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);
  }
}
TEST_F(CustomElementUpgradeSorterTest, oneCandidate) {
  NonThrowableExceptionState noExceptions;
  Element* element =
      document()->createElement("a-a", StringOrDictionary(), noExceptions);
  document()->documentElement()->appendChild(element);

  CustomElementUpgradeSorter sorter;
  sorter.add(element);

  HeapVector<Member<Element>> elements;
  sorter.sorted(&elements, document());
  EXPECT_EQ(1u, elements.size())
      << "exactly one candidate should be in the result set";
  EXPECT_TRUE(elements.contains(element))
      << "the candidate should be the element that was added";
}
예제 #5
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);
}
예제 #6
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]);
    }
}
예제 #7
0
StyleEngineTest::RuleSetInvalidation
StyleEngineTest::scheduleInvalidationsForRules(TreeScope& treeScope,
                                               const String& cssText) {
  StyleSheetContents* sheet =
      StyleSheetContents::create(CSSParserContext(HTMLStandardMode, nullptr));
  sheet->parseString(cssText);
  HeapVector<Member<RuleSet>> ruleSets;
  RuleSet& ruleSet = sheet->ensureRuleSet(MediaQueryEvaluator(),
                                          RuleHasDocumentSecurityOrigin);
  ruleSet.compactRulesIfNeeded();
  if (ruleSet.needsFullRecalcForRuleSetInvalidation())
    return RuleSetInvalidationFullRecalc;
  ruleSets.append(&ruleSet);
  styleEngine().scheduleInvalidationsForRuleSets(treeScope, ruleSets);
  return RuleSetInvalidationsScheduled;
}
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;
}
예제 #9
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();
  }
}
예제 #10
0
MIDIInputMap* MIDIAccess::inputs() const
{
    HeapVector<Member<MIDIInput>> inputs;
    HashSet<String> ids;
    for (size_t i = 0; i < m_inputs.size(); ++i) {
        MIDIInput* input = m_inputs[i];
        if (input->getState() != PortState::MIDIPortStateDisconnected) {
            inputs.append(input);
            ids.add(input->id());
        }
    }
    if (inputs.size() != ids.size()) {
        // There is id duplication that violates the spec.
        inputs.clear();
    }
    return new MIDIInputMap(inputs);
}
예제 #11
0
TEST_F(ActiveStyleSheetsTest, CompareActiveStyleSheets_RemoveNullRuleSet) {
  ActiveStyleSheetVector oldSheets;
  ActiveStyleSheetVector newSheets;
  HeapVector<Member<RuleSet>> changedRuleSets;

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

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

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

  EXPECT_EQ(NoActiveSheetsChanged,
            compareActiveStyleSheets(oldSheets, newSheets, changedRuleSets));
  EXPECT_EQ(0u, changedRuleSets.size());
}
TEST_F(CustomElementUpgradeSorterTest, inOtherDocument_notInSet) {
  NonThrowableExceptionState noExceptions;
  Element* element =
      document()->createElement("a-a", StringOrDictionary(), noExceptions);

  Document* otherDocument = HTMLDocument::create();
  otherDocument->appendChild(element);
  EXPECT_EQ(otherDocument, element->ownerDocument())
      << "sanity: another document should have adopted an element on append";

  CustomElementUpgradeSorter sorter;
  sorter.add(element);

  HeapVector<Member<Element>> elements;
  sorter.sorted(&elements, document());
  EXPECT_EQ(0u, elements.size())
      << "the adopted-away candidate should not have been included";
}
예제 #13
0
void ScopedStyleResolver::addFontFaceRules(const RuleSet& ruleSet) {
  // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for
  // the moment.
  if (!treeScope().rootNode().isDocumentNode())
    return;

  Document& document = treeScope().document();
  CSSFontSelector* cssFontSelector = document.styleEngine().fontSelector();
  const HeapVector<Member<StyleRuleFontFace>> fontFaceRules =
      ruleSet.fontFaceRules();
  for (auto& fontFaceRule : fontFaceRules) {
    if (FontFace* fontFace = FontFace::create(&document, fontFaceRule))
      cssFontSelector->fontFaceCache()->add(cssFontSelector, fontFaceRule,
                                            fontFace);
  }
  if (fontFaceRules.size())
    document.styleResolver()->invalidateMatchedPropertiesCache();
}
예제 #14
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);
}
예제 #15
0
inline void DistributionPool::populateChildren(const ContainerNode& parent) {
  clear();
  for (Node* child = parent.firstChild(); child; child = child->nextSibling()) {
    if (isHTMLSlotElement(child)) {
      // TODO(hayato): Support re-distribution across v0 and v1 shadow trees
      continue;
    }
    if (isActiveInsertionPoint(*child)) {
      InsertionPoint* insertionPoint = toInsertionPoint(child);
      for (size_t i = 0; i < insertionPoint->distributedNodesSize(); ++i)
        m_nodes.append(insertionPoint->distributedNodeAt(i));
    } else {
      m_nodes.append(child);
    }
  }
  m_distributed.resize(m_nodes.size());
  m_distributed.fill(false);
}
예제 #16
0
void ElementShadowV0::distribute() {
  HeapVector<Member<HTMLShadowElement>, 32> shadowInsertionPoints;
  DistributionPool pool(m_elementShadow->host());

  for (ShadowRoot* root = &youngestShadowRoot(); root;
       root = root->olderShadowRoot()) {
    HTMLShadowElement* shadowInsertionPoint = 0;
    for (const auto& point : root->descendantInsertionPoints()) {
      if (!point->isActive())
        continue;
      if (isHTMLShadowElement(*point)) {
        DCHECK(!shadowInsertionPoint);
        shadowInsertionPoint = toHTMLShadowElement(point);
        shadowInsertionPoints.append(shadowInsertionPoint);
      } else {
        pool.distributeTo(point, this);
        if (ElementShadow* shadow =
                shadowWhereNodeCanBeDistributedForV0(*point))
          shadow->setNeedsDistributionRecalc();
      }
    }
  }

  for (size_t i = shadowInsertionPoints.size(); i > 0; --i) {
    HTMLShadowElement* shadowInsertionPoint = shadowInsertionPoints[i - 1];
    ShadowRoot* root = shadowInsertionPoint->containingShadowRoot();
    DCHECK(root);
    if (root->isOldest()) {
      pool.distributeTo(shadowInsertionPoint, this);
    } else if (root->olderShadowRoot()->type() == root->type()) {
      // Only allow reprojecting older shadow roots between the same type to
      // disallow reprojecting UA elements into author shadows.
      DistributionPool olderShadowRootPool(*root->olderShadowRoot());
      olderShadowRootPool.distributeTo(shadowInsertionPoint, this);
      root->olderShadowRoot()->setShadowInsertionPointOfYoungerShadowRoot(
          shadowInsertionPoint);
    }
    if (ElementShadow* shadow =
            shadowWhereNodeCanBeDistributedForV0(*shadowInsertionPoint))
      shadow->setNeedsDistributionRecalc();
  }
  InspectorInstrumentation::didPerformElementShadowDistribution(
      &m_elementShadow->host());
}
예제 #17
0
HeapVector<FormDataEntryValue> FormData::getAll(const String& name)
{
    HeapVector<FormDataEntryValue> results;

    const CString encodedName = encodeAndNormalize(name);
    for (const auto& entry : entries()) {
        if (entry->name() != encodedName)
            continue;
        FormDataEntryValue value;
        if (entry->isString()) {
            value.setUSVString(decode(entry->value()));
        } else {
            ASSERT(entry->isFile());
            value.setFile(entry->file());
        }
        results.append(value);
    }
    return results;
}
예제 #18
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);
}
예제 #19
0
static void completeURLs(DocumentFragment& fragment, const String& baseURL) {
  HeapVector<AttributeChange> changes;

  KURL parsedBaseURL(ParsedURLString, baseURL);

  for (Element& element : ElementTraversal::descendantsOf(fragment)) {
    AttributeCollection attributes = element.attributes();
    // AttributeCollection::iterator end = attributes.end();
    for (const auto& attribute : attributes) {
      if (element.isURLAttribute(attribute) && !attribute.value().isEmpty())
        changes.append(AttributeChange(
            &element, attribute.name(),
            KURL(parsedBaseURL, attribute.value()).getString()));
    }
  }

  for (auto& change : changes)
    change.apply();
}
예제 #20
0
void HTMLFormControlsCollection::namedGetter(
    const AtomicString& name,
    RadioNodeListOrElement& returnValue) {
  HeapVector<Member<Element>> namedItems;
  this->namedItems(name, namedItems);

  if (namedItems.isEmpty())
    return;

  if (namedItems.size() == 1) {
    if (!isHTMLImageElement(*namedItems[0]))
      returnValue.setElement(namedItems.at(0));
    return;
  }

  // This path never returns a RadioNodeList for <img> because
  // onlyMatchingImgElements flag is false by default.
  returnValue.setRadioNodeList(ownerNode().radioNodeList(name));
}
예제 #21
0
TEST_F(CustomElementRegistryTest,
       collectCandidates_shouldNotIncludeElementsInDifferentDocument) {
  Element* element = CreateElement("a-a").inDocument(&document());
  registry().addCandidate(element);

  Document* otherDocument = HTMLDocument::create();
  otherDocument->appendChild(element);
  EXPECT_EQ(otherDocument, element->ownerDocument())
      << "sanity: another document should have adopted an element on append";

  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 adopted-away candidate should not have been found";
}
예제 #22
0
PaymentAppRequestData PaymentAppRequestDataConversion::toPaymentAppRequestData(
    ScriptState* scriptState,
    const WebPaymentAppRequestData& webData) {
  PaymentAppRequestData data;

  data.setOrigin(webData.origin);
  HeapVector<PaymentMethodData> methodData;
  for (const auto& md : webData.methodData) {
    methodData.append(toPaymentMethodData(scriptState, md));
  }
  data.setMethodData(methodData);
  data.setTotal(toPaymentItem(webData.total));
  HeapVector<PaymentDetailsModifier> modifiers;
  for (const auto& modifier : webData.modifiers) {
    modifiers.append(toPaymentDetailsModifier(scriptState, modifier));
  }
  data.setOptionId(webData.optionId);
  return data;
}
예제 #23
0
bool TouchEventManager::generateTouchInfosAfterHittest(
    const PlatformTouchEvent& event,
    HeapVector<TouchInfo>& touchInfos)
{
    bool newTouchSequence = true;
    bool allTouchesReleased = true;

    for (const auto& point : event.touchPoints()) {
        if (point.state() != PlatformTouchPoint::TouchPressed)
            newTouchSequence = false;
        if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
            allTouchesReleased = false;
    }
    if (newTouchSequence) {
        // Ideally we'd ASSERT(!m_touchSequenceDocument) here since we should
        // have cleared the active document when we saw the last release. But we
        // have some tests that violate this, ClusterFuzz could trigger it, and
        // there may be cases where the browser doesn't reliably release all
        // touches. http://crbug.com/345372 tracks this.
        m_touchSequenceDocument.clear();
        m_touchSequenceUserGestureToken.clear();
    }

    ASSERT(m_frame->view());
    if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touchSequenceDocument->frame()->view())) {
        // If the active touch document has no frame or view, it's probably being destroyed
        // so we can't dispatch events.
        return false;
    }

    for (const auto& point : event.touchPoints()) {
        TouchEventManager::TouchInfo touchInfo;
        touchInfo.point = point;
        touchInfos.append(touchInfo);
    }

    updateTargetAndRegionMapsForTouchStarts(touchInfos);

    m_touchPressed = !allTouchesReleased;

    // If there's no document receiving touch events, or no handlers on the
    // document set to receive the events, then we can skip all the rest of
    // this work.
    if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !hasTouchHandlers(m_touchSequenceDocument->frameHost()->eventHandlerRegistry()) || !m_touchSequenceDocument->frame()) {
        if (allTouchesReleased) {
            m_touchSequenceDocument.clear();
            m_touchSequenceUserGestureToken.clear();
        }
        return false;
    }

    setAllPropertiesOfTouchInfos(touchInfos);

    return true;
}
예제 #24
0
void TextFinder::updateFindMatchRects() {
  IntSize currentContentsSize = ownerFrame().contentsSize();
  if (m_contentsSizeForCurrentFindMatchRects != currentContentsSize) {
    m_contentsSizeForCurrentFindMatchRects = currentContentsSize;
    m_findMatchRectsAreValid = false;
  }

  size_t deadMatches = 0;
  for (FindMatch& match : m_findMatchesCache) {
    if (!match.m_range->boundaryPointsValid() ||
        !match.m_range->startContainer()->isConnected())
      match.m_rect = FloatRect();
    else if (!m_findMatchRectsAreValid)
      match.m_rect = findInPageRectFromRange(match.m_range.get());

    if (match.m_rect.isEmpty())
      ++deadMatches;
  }

  // Remove any invalid matches from the cache.
  if (deadMatches) {
    HeapVector<FindMatch> filteredMatches;
    filteredMatches.reserveCapacity(m_findMatchesCache.size() - deadMatches);

    for (const FindMatch& match : m_findMatchesCache) {
      if (!match.m_rect.isEmpty())
        filteredMatches.append(match);
    }

    m_findMatchesCache.swap(filteredMatches);
  }

  // Invalidate the rects in child frames. Will be updated later during
  // traversal.
  if (!m_findMatchRectsAreValid)
    for (WebFrame* child = ownerFrame().firstChild(); child;
         child = child->nextSibling())
      toWebLocalFrameImpl(child)->ensureTextFinder().m_findMatchRectsAreValid =
          false;

  m_findMatchRectsAreValid = true;
}
예제 #25
0
void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate& update, const Element* animatingElement, double timelineCurrentTime)
{
    ElementAnimations* elementAnimations = animatingElement ? animatingElement->elementAnimations() : nullptr;
    AnimationStack* animationStack = elementAnimations ? &elementAnimations->defaultStack() : nullptr;

    if (update.newAnimations().isEmpty() && update.suppressedAnimations().isEmpty()) {
        ActiveInterpolationsMap activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, 0, 0, KeyframeEffect::DefaultPriority, timelineCurrentTime));
        update.adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
        return;
    }

    HeapVector<Member<InertEffect>> newEffects;
    for (const auto& newAnimation : update.newAnimations())
        newEffects.append(newAnimation.effect.get());
    for (const auto& updatedAnimation : update.animationsWithUpdates())
        newEffects.append(updatedAnimation.effect.get()); // Animations with updates use a temporary InertEffect for the current frame.

    ActiveInterpolationsMap activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, &newEffects, &update.suppressedAnimations(), KeyframeEffect::DefaultPriority, timelineCurrentTime));
    update.adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
}
예제 #26
0
Nullable<HeapVector<WebCLImageDescriptor>> WebCLContext::getSupportedImageFormats(unsigned memFlags, ExceptionState& es)
{
    HeapVector<WebCLImageDescriptor> supportedImageDescriptor;
    if (isReleased()) {
        es.throwWebCLException(WebCLException::InvalidContext, WebCLException::invalidContextMessage);
        return supportedImageDescriptor;
    }

    if (!WebCLInputChecker::isValidMemoryObjectFlag(memFlags)) {
        es.throwWebCLException(WebCLException::InvalidValue, WebCLException::invalidValueMessage);
        return supportedImageDescriptor;
    }

    cl_uint numberOfSupportedImageFormats = 0;
    cl_int err = clGetSupportedImageFormats(m_clContext, memFlags, CL_MEM_OBJECT_IMAGE2D, 0, 0, &numberOfSupportedImageFormats);

    if (err != CL_SUCCESS) {
        es.throwWebCLException(WebCLException::InvalidImageSize, WebCLException::invalidImageSizeMessage);
        return supportedImageDescriptor;
    }

    Vector<cl_image_format> supportedImages;
    supportedImages.reserveCapacity(numberOfSupportedImageFormats);
    supportedImages.resize(numberOfSupportedImageFormats);

    err = clGetSupportedImageFormats(m_clContext, memFlags, CL_MEM_OBJECT_IMAGE2D, numberOfSupportedImageFormats, supportedImages.data(), 0);
    if (err != CL_SUCCESS) {
        WebCLException::throwException(err, es);
    } else {
        for (size_t i = 0; i < static_cast<unsigned>(numberOfSupportedImageFormats); ++i) {
            if (WebCLInputChecker::isValidChannelOrder(supportedImages[i].image_channel_order) && WebCLInputChecker::isValidChannelType(supportedImages[i].image_channel_data_type)) {
                WebCLImageDescriptor des;
                des.setChannelOrder(supportedImages[i].image_channel_order);
                des.setChannelType(supportedImages[i].image_channel_data_type);
                supportedImageDescriptor.append(des);
            }
        }
    }

    return supportedImageDescriptor;
}
예제 #27
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);
}
Element* SlotScopedTraversal::previous(const Element& current)
{
    Element* nearestAncestorAssignedToSlot = SlotScopedTraversal::nearestAncestorAssignedToSlot(current);
    ASSERT(nearestAncestorAssignedToSlot);
    // NodeTraversal within nearestAncestorAssignedToSlot
    if (Element* previous = ElementTraversal::previous(current, nearestAncestorAssignedToSlot))
        return previous;
    // If null, jump to previous assigned node's descendant
    const HeapVector<Member<Node>> assignedNodes = nearestAncestorAssignedToSlot->assignedSlot()->getAssignedNodes();
    size_t currentIndex = assignedNodes.reverseFind(*nearestAncestorAssignedToSlot);
    ASSERT(currentIndex != kNotFound);
    for (; currentIndex > 0; --currentIndex) {
        const Member<Node> assignedPrevious = assignedNodes[currentIndex - 1];
        if (assignedPrevious->isElementNode()) {
            if (Element* last = ElementTraversal::lastWithin(*toElement(assignedPrevious)))
                return last;
            return toElement(assignedPrevious);
        }
    }
    return nullptr;
}
TEST_F(CustomElementUpgradeSorterTest, candidatesInDocumentOrder) {
  Element* a = createElementWithId("a-a", "a");
  Element* b = createElementWithId("a-a", "b");
  Element* c = createElementWithId("a-a", "c");

  document()->documentElement()->appendChild(a);
  a->appendChild(b);
  document()->documentElement()->appendChild(c);

  CustomElementUpgradeSorter sorter;
  sorter.add(b);
  sorter.add(a);
  sorter.add(c);

  HeapVector<Member<Element>> elements;
  sorter.sorted(&elements, document());
  EXPECT_EQ(3u, elements.size());
  EXPECT_EQ(a, elements[0].get());
  EXPECT_EQ(b, elements[1].get());
  EXPECT_EQ(c, elements[2].get());
}
예제 #30
0
TEST_F(ActiveStyleSheetsTest, CompareActiveStyleSheets_InsertedAndRemoved) {
  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()));

  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(&sheet1->contents()->ruleSet(), changedRuleSets[0]);
  EXPECT_EQ(&sheet3->contents()->ruleSet(), changedRuleSets[1]);
}