Пример #1
0
PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumePseudo(CSSParserTokenRange& range)
{
    ASSERT(range.peek().type() == ColonToken);
    range.consume();

    int colons = 1;
    if (range.peek().type() == ColonToken) {
        range.consume();
        colons++;
    }

    const CSSParserToken& token = range.peek();
    if (token.type() != IdentToken && token.type() != FunctionToken)
        return nullptr;

    OwnPtr<CSSParserSelector> selector = CSSParserSelector::create();
    selector->setMatch(colons == 1 ? CSSSelector::PseudoClass : CSSSelector::PseudoElement);
    selector->setValue(AtomicString(String(token.value()).lower()));

    if (token.type() == IdentToken) {
        range.consume();
        if (selector->pseudoType() == CSSSelector::PseudoUnknown)
            return nullptr;
        return selector.release();
    }

    CSSParserTokenRange block = range.consumeBlock();
    block.consumeWhitespace();

    if ((colons == 1
        && (token.valueEqualsIgnoringCase("host")
            || token.valueEqualsIgnoringCase("host-context")
            || token.valueEqualsIgnoringCase("-webkit-any")))
        || (colons == 2 && token.valueEqualsIgnoringCase("cue"))) {

        CSSSelectorList* selectorList = new CSSSelectorList();
        consumeCompoundSelectorList(block, *selectorList);
        if (!selectorList->isValid() || !block.atEnd())
            return nullptr;

        selector->setSelectorList(adoptPtr(selectorList));
        selector->pseudoType(); // FIXME: Do we need to force the pseudo type to be cached?
        ASSERT(selector->pseudoType() != CSSSelector::PseudoUnknown);
        return selector.release();
    }

    if (colons == 1 && token.valueEqualsIgnoringCase("not")) {
        OwnPtr<CSSParserSelector> innerSelector = consumeCompoundSelector(block);
        if (!innerSelector || !innerSelector->isSimple() || !block.atEnd())
            return nullptr;
        Vector<OwnPtr<CSSParserSelector>> selectorVector;
        selectorVector.append(innerSelector.release());
        selector->adoptSelectorVector(selectorVector);
        return selector.release();
    }

    if (colons == 1 && token.valueEqualsIgnoringCase("lang")) {
        // FIXME: CSS Selectors Level 4 allows :lang(*-foo)
        const CSSParserToken& ident = block.consumeIncludingWhitespace();
        if (ident.type() != IdentToken || !block.atEnd())
            return nullptr;
        selector->setArgument(ident.value());
        selector->pseudoType(); // FIXME: Do we need to force the pseudo type to be cached?
        ASSERT(selector->pseudoType() == CSSSelector::PseudoLang);
        return selector.release();
    }

    if (colons == 1
        && (token.valueEqualsIgnoringCase("nth-child")
            || token.valueEqualsIgnoringCase("nth-last-child")
            || token.valueEqualsIgnoringCase("nth-of-type")
            || token.valueEqualsIgnoringCase("nth-last-of-type"))) {
        std::pair<int, int> ab;
        if (!consumeANPlusB(block, ab))
            return nullptr;
        block.consumeWhitespace();
        if (!block.atEnd())
            return nullptr;
        // FIXME: We shouldn't serialize here and reparse in CSSSelector!
        // Serialization should be in CSSSelector::selectorText instead.
        int a = ab.first;
        int b = ab.second;
        String string;
        if (a == 0 && b == 0)
            string = "0";
        else if (a == 0)
            string = String::number(b);
        else if (b == 0)
            string = String::format("%dn", a);
        else if (ab.second < 0)
            string = String::format("%dn%d", a, b);
        else
            string = String::format("%dn+%d", a, b);
        selector->setArgument(AtomicString(string));
        selector->pseudoType(); // FIXME: Do we need to force the pseudo type to be cached?
        ASSERT(selector->pseudoType() != CSSSelector::PseudoUnknown);
        return selector.release();
    }

    return nullptr;
}
Пример #2
0
void FrameTree::clearName()
{
    m_name = AtomicString();
}
Пример #3
0
void ResourceRequest::setHTTPHeaderField(const char* name, const AtomicString& value)
{
    setHTTPHeaderField(AtomicString(name), value);
}
Пример #4
0
// Given the desired base font, this will create a SimpleFontData for a specific
// font that can be used to render the given range of characters.
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(
    const FontDescription& fontDescription,
    UChar32 character,
    const SimpleFontData* originalFontData,
    FontFallbackPriority fallbackPriority) {
  // First try the specified font with standard style & weight.
  if (fallbackPriority != FontFallbackPriority::EmojiEmoji &&
      (fontDescription.style() == FontStyleItalic ||
       fontDescription.weight() >= FontWeightBold)) {
    RefPtr<SimpleFontData> fontData =
        fallbackOnStandardFontStyle(fontDescription, character);
    if (fontData)
      return fontData;
  }

  UScriptCode script;
  const wchar_t* family = getFallbackFamily(
      character, fontDescription.genericFamily(), fontDescription.locale(),
      &script, fallbackPriority, m_fontManager.get());
  FontPlatformData* data = nullptr;
  if (family) {
    FontFaceCreationParams createByFamily(AtomicString(family, wcslen(family)));
    data = getFontPlatformData(fontDescription, createByFamily);
  }

  if ((!data || !data->fontContainsCharacter(character)) &&
      s_useSkiaFontFallback) {
    const char* bcp47Locale = nullptr;
    int localeCount = 0;
    // If the font description has a locale, use that. Otherwise, Skia will
    // fall back on the user's default locale.
    // TODO(kulshin): extract locale fallback logic from
    //   FontCacheAndroid.cpp and share that code
    if (fontDescription.locale()) {
      bcp47Locale = fontDescription.locale()->localeForSkFontMgr();
      localeCount = 1;
    }

    CString familyName = fontDescription.family().family().utf8();

    SkTypeface* typeface = m_fontManager->matchFamilyStyleCharacter(
        familyName.data(), fontDescription.skiaFontStyle(), &bcp47Locale,
        localeCount, character);
    if (typeface) {
      SkString skiaFamily;
      typeface->getFamilyName(&skiaFamily);
      FontFaceCreationParams createByFamily(AtomicString(skiaFamily.c_str()));
      data = getFontPlatformData(fontDescription, createByFamily);
    }
  }

  // Last resort font list : PanUnicode. CJK fonts have a pretty
  // large repertoire. Eventually, we need to scan all the fonts
  // on the system to have a Firefox-like coverage.
  // Make sure that all of them are lowercased.
  const static wchar_t* const cjkFonts[] = {
      L"arial unicode ms", L"ms pgothic", L"simsun", L"gulim", L"pmingliu",
      L"wenquanyi zen hei",  // Partial CJK Ext. A coverage but more widely
                             // known to Chinese users.
      L"ar pl shanheisun uni", L"ar pl zenkai uni",
      L"han nom a",  // Complete CJK Ext. A coverage.
      L"code2000"    // Complete CJK Ext. A coverage.
      // CJK Ext. B fonts are not listed here because it's of no use
      // with our current non-BMP character handling because we use
      // Uniscribe for it and that code path does not go through here.
  };

  const static wchar_t* const commonFonts[] = {
      L"tahoma", L"arial unicode ms", L"lucida sans unicode",
      L"microsoft sans serif", L"palatino linotype",
      // Six fonts below (and code2000 at the end) are not from MS, but
      // once installed, cover a very wide range of characters.
      L"dejavu serif", L"dejavu sasns", L"freeserif", L"freesans", L"gentium",
      L"gentiumalt", L"ms pgothic", L"simsun", L"gulim", L"pmingliu",
      L"code2000"};

  const wchar_t* const* panUniFonts = nullptr;
  int numFonts = 0;
  if (script == USCRIPT_HAN) {
    panUniFonts = cjkFonts;
    numFonts = WTF_ARRAY_LENGTH(cjkFonts);
  } else {
    panUniFonts = commonFonts;
    numFonts = WTF_ARRAY_LENGTH(commonFonts);
  }
  // Font returned from getFallbackFamily may not cover |character|
  // because it's based on script to font mapping. This problem is
  // critical enough for non-Latin scripts (especially Han) to
  // warrant an additional (real coverage) check with fontCotainsCharacter.
  int i;
  for (i = 0;
       (!data || !data->fontContainsCharacter(character)) && i < numFonts;
       ++i) {
    family = panUniFonts[i];
    FontFaceCreationParams createByFamily(AtomicString(family, wcslen(family)));
    data = getFontPlatformData(fontDescription, createByFamily);
  }

  // For font fallback we want to match the subpixel behavior of the original
  // font. Mixing subpixel and non-subpixel in the same text run looks really
  // odd and causes problems with preferred width calculations.
  if (data && originalFontData) {
    const FontPlatformData& platformData = originalFontData->platformData();
    data->setMinSizeForAntiAlias(platformData.minSizeForAntiAlias());
    data->setMinSizeForSubpixel(platformData.minSizeForSubpixel());
  }

  // When i-th font (0-base) in |panUniFonts| contains a character and
  // we get out of the loop, |i| will be |i + 1|. That is, if only the
  // last font in the array covers the character, |i| will be numFonts.
  // So, we have to use '<=" rather than '<' to see if we found a font
  // covering the character.
  if (i <= numFonts)
    return fontDataFromFontPlatformData(data, DoNotRetain);

  return nullptr;
}
Пример #5
0
AtomicString v8NonStringValueToAtomicWebCoreString(v8::Handle<v8::Value> object)
{
    ASSERT(!object->IsString());
    return AtomicString(v8NonStringValueToWebCoreString(object));
}
Пример #6
0
JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args)
{
    Frame* frame = impl()->frame();
    if (!frame)
        return jsUndefined();
    Frame* lexicalFrame = toLexicalFrame(exec);
    if (!lexicalFrame)
        return jsUndefined();
    Frame* dynamicFrame = toDynamicFrame(exec);
    if (!dynamicFrame)
        return jsUndefined();

    Page* page = frame->page();

    String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(0));
    AtomicString frameName = args.at(1).isUndefinedOrNull() ? "_blank" : AtomicString(args.at(1).toString(exec));

    // Because FrameTree::find() returns true for empty strings, we must check for empty framenames.
    // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
    if (!DOMWindow::allowPopUp(dynamicFrame) && (frameName.isEmpty() || !frame->tree()->find(frameName)))
        return jsUndefined();

    // Get the target frame for the special cases of _top and _parent.  In those
    // cases, we can schedule a location change right now and return early.
    bool topOrParent = false;
    if (frameName == "_top") {
        frame = frame->tree()->top();
        topOrParent = true;
    } else if (frameName == "_parent") {
        if (Frame* parent = frame->tree()->parent())
            frame = parent;
        topOrParent = true;
    }
    if (topOrParent) {
        if (!shouldAllowNavigation(exec, frame))
            return jsUndefined();

        String completedURL;
        if (!urlString.isEmpty())
            completedURL = completeURL(exec, urlString).string();

        const JSDOMWindow* targetedWindow = toJSDOMWindow(frame);
        if (!completedURL.isEmpty() && (!protocolIsJavaScript(completedURL) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) {
            bool userGesture = processingUserGesture(exec);

            // For whatever reason, Firefox uses the dynamicGlobalObject to
            // determine the outgoingReferrer.  We replicate that behavior
            // here.
            String referrer = dynamicFrame->loader()->outgoingReferrer();

            frame->loader()->scheduleLocationChange(completedURL, referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture);
        }
        return toJS(exec, frame->domWindow());
    }

    // In the case of a named frame or a new window, we'll use the createWindow() helper
    WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args.at(2)));
    FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0,
                         windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0);
    DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), windowRect, windowRect);

    windowFeatures.x = windowRect.x();
    windowFeatures.y = windowRect.y();
    windowFeatures.height = windowRect.height();
    windowFeatures.width = windowRect.width();

    frame = createWindow(exec, lexicalFrame, dynamicFrame, frame, urlString, frameName, windowFeatures, JSValue());

    if (!frame)
        return jsUndefined();

    return toJS(exec, frame->domWindow());
}
Пример #7
0
inline SVGElement* SVGSMILElement::eventBaseFor(const Condition& condition)
{
    Element* eventBase = condition.baseID().isEmpty() ? targetElement() : treeScope().getElementById(AtomicString(condition.baseID()));
    if (eventBase && eventBase->isSVGElement())
        return toSVGElement(eventBase);
    return nullptr;
}
bool SVGImage::dataChanged(bool allDataReceived)
{
    TRACE_EVENT0("blink", "SVGImage::dataChanged");

    // Don't do anything if is an empty image.
    if (!data()->size())
        return true;

    if (allDataReceived) {
        // SVGImage will fire events (and the default C++ handlers run) but doesn't
        // actually allow script to run so it's fine to call into it. We allow this
        // since it means an SVG data url can synchronously load like other image
        // types.
        EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents;

        DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<FrameLoaderClient>, dummyFrameLoaderClient, (EmptyFrameLoaderClient::create()));

        if (m_page) {
            toLocalFrame(m_page->mainFrame())->loader().load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), AtomicString("image/svg+xml", AtomicString::ConstructFromLiteral),
                AtomicString("UTF-8", AtomicString::ConstructFromLiteral), KURL(), ForceSynchronousLoad)));
            return true;
        }

        Page::PageClients pageClients;
        fillWithEmptyClients(pageClients);
        m_chromeClient = SVGImageChromeClient::create(this);
        pageClients.chromeClient = m_chromeClient.get();

        // FIXME: If this SVG ends up loading itself, we might leak the world.
        // The Cache code does not know about ImageResources holding Frames and
        // won't know to break the cycle.
        // This will become an issue when SVGImage will be able to load other
        // SVGImage objects, but we're safe now, because SVGImage can only be
        // loaded by a top-level document.
        OwnPtrWillBeRawPtr<Page> page;
        {
            TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage");
            page = adoptPtrWillBeNoop(new Page(pageClients));
            page->settings().setScriptEnabled(false);
            page->settings().setPluginsEnabled(false);
            page->settings().setAcceleratedCompositingEnabled(false);

            // Because this page is detached, it can't get default font settings
            // from the embedder. Copy over font settings so we have sensible
            // defaults. These settings are fixed and will not update if changed.
            if (!Page::ordinaryPages().isEmpty()) {
                Settings& defaultSettings = (*Page::ordinaryPages().begin())->settings();
                page->settings().genericFontFamilySettings() = defaultSettings.genericFontFamilySettings();
                page->settings().setMinimumFontSize(defaultSettings.minimumFontSize());
                page->settings().setMinimumLogicalFontSize(defaultSettings.minimumLogicalFontSize());
                page->settings().setDefaultFontSize(defaultSettings.defaultFontSize());
                page->settings().setDefaultFixedFontSize(defaultSettings.defaultFixedFontSize());
            }
        }

        RefPtrWillBeRawPtr<LocalFrame> frame = nullptr;
        {
            TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame");
            frame = LocalFrame::create(dummyFrameLoaderClient.get(), &page->frameHost(), 0);
            frame->setView(FrameView::create(frame.get()));
            frame->init();
        }

        FrameLoader& loader = frame->loader();
        loader.forceSandboxFlags(SandboxAll);

        frame->view()->setScrollbarsSuppressed(true);
        frame->view()->setCanHaveScrollbars(false); // SVG Images will always synthesize a viewBox, if it's not available, and thus never see scrollbars.
        frame->view()->setTransparent(true); // SVG Images are transparent.

        m_page = page.release();

        TRACE_EVENT0("blink", "SVGImage::dataChanged::load");
        loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), AtomicString("image/svg+xml", AtomicString::ConstructFromLiteral),
            AtomicString("UTF-8", AtomicString::ConstructFromLiteral), KURL(), ForceSynchronousLoad)));

        // Set the intrinsic size before a container size is available.
        m_intrinsicSize = containerSize();
    }

    return m_page;
}
FilterOperations FilterOperationResolver::createFilterOperations(StyleResolverState& state, const CSSValue& inValue)
{
    FilterOperations operations;

    if (inValue.isPrimitiveValue()) {
        ASSERT(toCSSPrimitiveValue(inValue).getValueID() == CSSValueNone);
        return operations;
    }

    const CSSToLengthConversionData& conversionData = state.cssToLengthConversionData();
    for (auto& currValue : toCSSValueList(inValue)) {
        CSSFunctionValue* filterValue = toCSSFunctionValue(currValue.get());
        FilterOperation::OperationType operationType = filterOperationForType(filterValue->functionType());
        countFilterUse(operationType, state.document());
        ASSERT(filterValue->length() <= 1);

        if (operationType == FilterOperation::REFERENCE) {
            CSSSVGDocumentValue* svgDocumentValue = toCSSSVGDocumentValue(filterValue->item(0));
            KURL url = state.document().completeURL(svgDocumentValue->url());

            RawPtr<ReferenceFilterOperation> operation = ReferenceFilterOperation::create(svgDocumentValue->url(), AtomicString(url.fragmentIdentifier()));
            if (SVGURIReference::isExternalURIReference(svgDocumentValue->url(), state.document())) {
                if (!svgDocumentValue->loadRequested())
                    state.elementStyleResources().addPendingSVGDocument(operation.get(), svgDocumentValue);
                else if (svgDocumentValue->cachedSVGDocument())
                    ReferenceFilterBuilder::setDocumentResourceReference(operation.get(), adoptPtr(new DocumentResourceReference(svgDocumentValue->cachedSVGDocument())));
            }
            operations.operations().append(operation);
            continue;
        }

        CSSPrimitiveValue* firstValue = filterValue->length() && filterValue->item(0)->isPrimitiveValue() ? toCSSPrimitiveValue(filterValue->item(0)) : nullptr;
        switch (filterValue->functionType()) {
        case CSSValueGrayscale:
        case CSSValueSepia:
        case CSSValueSaturate: {
            double amount = 1;
            if (filterValue->length() == 1) {
                amount = firstValue->getDoubleValue();
                if (firstValue->isPercentage())
                    amount /= 100;
            }

            operations.operations().append(BasicColorMatrixFilterOperation::create(amount, operationType));
            break;
        }
        case CSSValueHueRotate: {
            double angle = 0;
            if (filterValue->length() == 1)
                angle = firstValue->computeDegrees();

            operations.operations().append(BasicColorMatrixFilterOperation::create(angle, operationType));
            break;
        }
        case CSSValueInvert:
        case CSSValueBrightness:
        case CSSValueContrast:
        case CSSValueOpacity: {
            double amount = (filterValue->functionType() == CSSValueBrightness) ? 0 : 1;
            if (filterValue->length() == 1) {
                amount = firstValue->getDoubleValue();
                if (firstValue->isPercentage())
                    amount /= 100;
            }

            operations.operations().append(BasicComponentTransferFilterOperation::create(amount, operationType));
            break;
        }
        case CSSValueBlur: {
            Length stdDeviation = Length(0, Fixed);
            if (filterValue->length() >= 1)
                stdDeviation = firstValue->convertToLength(conversionData);
            operations.operations().append(BlurFilterOperation::create(stdDeviation));
            break;
        }
        case CSSValueDropShadow: {
            CSSShadowValue* item = toCSSShadowValue(filterValue->item(0));
            IntPoint location(item->x->computeLength<int>(conversionData), item->y->computeLength<int>(conversionData));
            int blur = item->blur ? item->blur->computeLength<int>(conversionData) : 0;
            Color shadowColor = Color::black;
            if (item->color)
                shadowColor = state.document().textLinkColors().colorFromCSSValue(*item->color, state.style()->color());

            operations.operations().append(DropShadowFilterOperation::create(location, blur, shadowColor));
            break;
        }
        default:
            ASSERT_NOT_REACHED();
            break;
        }
    }

    return operations;
}
Пример #10
0
// Given the desired base font, this will create a SimpleFontData for a specific
// font that can be used to render the given range of characters.
PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*, bool)
{
    // FIXME: We should fix getFallbackFamily to take a UChar32
    // and remove this split-to-UChar16 code.
    UChar codeUnits[2];
    int codeUnitsLength;
    if (inputC <= 0xFFFF) {
        codeUnits[0] = inputC;
        codeUnitsLength = 1;
    } else {
        codeUnits[0] = U16_LEAD(inputC);
        codeUnits[1] = U16_TRAIL(inputC);
        codeUnitsLength = 2;
    }

    // FIXME: Consider passing fontDescription.dominantScript()
    // to GetFallbackFamily here.
    FontDescription fontDescription = fontDescription;
    UChar32 c;
    UScriptCode script;
    const wchar_t* family = getFallbackFamily(codeUnits, codeUnitsLength, fontDescription.genericFamily(), &c, &script);
    FontPlatformData* data = 0;
    if (family)
        data = getFontPlatformData(fontDescription,  AtomicString(family, wcslen(family)));

    // Last resort font list : PanUnicode. CJK fonts have a pretty
    // large repertoire. Eventually, we need to scan all the fonts
    // on the system to have a Firefox-like coverage.
    // Make sure that all of them are lowercased.
    const static wchar_t* const cjkFonts[] = {
        L"arial unicode ms",
        L"ms pgothic",
        L"simsun",
        L"gulim",
        L"pmingliu",
        L"wenquanyi zen hei", // partial CJK Ext. A coverage but more
                              // widely known to Chinese users.
        L"ar pl shanheisun uni",
        L"ar pl zenkai uni",
        L"han nom a",  // Complete CJK Ext. A coverage
        L"code2000",   // Complete CJK Ext. A coverage
        // CJK Ext. B fonts are not listed here because it's of no use
        // with our current non-BMP character handling because we use
        // Uniscribe for it and that code path does not go through here.
    };

    const static wchar_t* const commonFonts[] = {
        L"tahoma",
        L"arial unicode ms",
        L"lucida sans unicode",
        L"microsoft sans serif",
        L"palatino linotype",
        // Six fonts below (and code2000 at the end) are not from MS, but
        // once installed, cover a very wide range of characters.
        L"dejavu serif",
        L"dejavu sasns",
        L"freeserif",
        L"freesans",
        L"gentium",
        L"gentiumalt",
        L"ms pgothic",
        L"simsun",
        L"gulim",
        L"pmingliu",
        L"code2000",
    };

    const wchar_t* const* panUniFonts = 0;
    int numFonts = 0;
    if (script == USCRIPT_HAN) {
        panUniFonts = cjkFonts;
        numFonts = WTF_ARRAY_LENGTH(cjkFonts);
    } else {
        panUniFonts = commonFonts;
        numFonts = WTF_ARRAY_LENGTH(commonFonts);
    }
    // Font returned from GetFallbackFamily may not cover |characters|
    // because it's based on script to font mapping. This problem is
    // critical enough for non-Latin scripts (especially Han) to
    // warrant an additional (real coverage) check with fontCotainsCharacter.
    int i;
    for (i = 0; (!data || !fontContainsCharacter(data, family, c)) && i < numFonts; ++i) {
        family = panUniFonts[i];
        data = getFontPlatformData(fontDescription, AtomicString(family, wcslen(family)));
    }
    // When i-th font (0-base) in |panUniFonts| contains a character and
    // we get out of the loop, |i| will be |i + 1|. That is, if only the
    // last font in the array covers the character, |i| will be numFonts.
    // So, we have to use '<=" rather than '<' to see if we found a font
    // covering the character.
    if (i <= numFonts)
        return fontDataFromPlatformData(data, DoNotRetain);

    return 0;

}
Пример #11
0
 FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, bool bold = false, bool italic = false)
 :m_family(family), m_size(size), m_bold(bold), m_italic(italic)
 {}
Пример #12
0
void HTMLSourceElement::setSrc(const String& url)
{
    setAttribute(srcAttr, AtomicString(url));
}
Пример #13
0
WheelEvent::WheelEvent()
    : WheelEvent(AtomicString(), WheelEventInit())
{
}
TEST(ResourceRequestTest, CrossThreadResourceRequestData)
{
    ResourceRequest original;
    original.setURL(KURL(ParsedURLString, "http://www.example.com/test.htm"));
    original.setCachePolicy(UseProtocolCachePolicy);
    original.setTimeoutInterval(10);
    original.setFirstPartyForCookies(KURL(ParsedURLString, "http://www.example.com/first_party.htm"));
    original.setRequestorOrigin(SecurityOrigin::create(KURL(ParsedURLString, "http://www.example.com/first_party.htm")));
    original.setHTTPMethod(HTTPNames::GET);
    original.setHTTPHeaderField(AtomicString("Foo"), AtomicString("Bar"));
    original.setHTTPHeaderField(AtomicString("Piyo"), AtomicString("Fuga"));
    original.setPriority(ResourceLoadPriorityLow, 20);

    RefPtr<EncodedFormData> originalBody(EncodedFormData::create("Test Body"));
    original.setHTTPBody(originalBody);
    original.setAllowStoredCredentials(false);
    original.setReportUploadProgress(false);
    original.setHasUserGesture(false);
    original.setDownloadToFile(false);
    original.setSkipServiceWorker(false);
    original.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS);
    original.setFetchCredentialsMode(WebURLRequest::FetchCredentialsModeSameOrigin);
    original.setRequestorID(30);
    original.setRequestorProcessID(40);
    original.setAppCacheHostID(50);
    original.setRequestContext(WebURLRequest::RequestContextAudio);
    original.setFrameType(WebURLRequest::FrameTypeNested);
    original.setHTTPReferrer(Referrer("http://www.example.com/referrer.htm", ReferrerPolicyDefault));

    EXPECT_STREQ("http://www.example.com/test.htm", original.url().getString().utf8().data());
    EXPECT_EQ(UseProtocolCachePolicy, original.getCachePolicy());
    EXPECT_EQ(10, original.timeoutInterval());
    EXPECT_STREQ("http://www.example.com/first_party.htm", original.firstPartyForCookies().getString().utf8().data());
    EXPECT_STREQ("www.example.com", original.requestorOrigin()->host().utf8().data());
    EXPECT_STREQ("GET", original.httpMethod().utf8().data());
    EXPECT_STREQ("Bar", original.httpHeaderFields().get("Foo").utf8().data());
    EXPECT_STREQ("Fuga", original.httpHeaderFields().get("Piyo").utf8().data());
    EXPECT_EQ(ResourceLoadPriorityLow, original.priority());
    EXPECT_STREQ("Test Body", original.httpBody()->flattenToString().utf8().data());
    EXPECT_FALSE(original.allowStoredCredentials());
    EXPECT_FALSE(original.reportUploadProgress());
    EXPECT_FALSE(original.hasUserGesture());
    EXPECT_FALSE(original.downloadToFile());
    EXPECT_FALSE(original.skipServiceWorker());
    EXPECT_EQ(WebURLRequest::FetchRequestModeCORS, original.fetchRequestMode());
    EXPECT_EQ(WebURLRequest::FetchCredentialsModeSameOrigin, original.fetchCredentialsMode());
    EXPECT_EQ(30, original.requestorID());
    EXPECT_EQ(40, original.requestorProcessID());
    EXPECT_EQ(50, original.appCacheHostID());
    EXPECT_EQ(WebURLRequest::RequestContextAudio, original.requestContext());
    EXPECT_EQ(WebURLRequest::FrameTypeNested, original.frameType());
    EXPECT_STREQ("http://www.example.com/referrer.htm", original.httpReferrer().utf8().data());
    EXPECT_EQ(ReferrerPolicyDefault, original.getReferrerPolicy());

    OwnPtr<CrossThreadResourceRequestData> data1(original.copyData());
    ResourceRequest copy1(data1.get());

    EXPECT_STREQ("http://www.example.com/test.htm", copy1.url().getString().utf8().data());
    EXPECT_EQ(UseProtocolCachePolicy, copy1.getCachePolicy());
    EXPECT_EQ(10, copy1.timeoutInterval());
    EXPECT_STREQ("http://www.example.com/first_party.htm", copy1.firstPartyForCookies().getString().utf8().data());
    EXPECT_STREQ("www.example.com", copy1.requestorOrigin()->host().utf8().data());
    EXPECT_STREQ("GET", copy1.httpMethod().utf8().data());
    EXPECT_STREQ("Bar", copy1.httpHeaderFields().get("Foo").utf8().data());
    EXPECT_EQ(ResourceLoadPriorityLow, copy1.priority());
    EXPECT_STREQ("Test Body", copy1.httpBody()->flattenToString().utf8().data());
    EXPECT_FALSE(copy1.allowStoredCredentials());
    EXPECT_FALSE(copy1.reportUploadProgress());
    EXPECT_FALSE(copy1.hasUserGesture());
    EXPECT_FALSE(copy1.downloadToFile());
    EXPECT_FALSE(copy1.skipServiceWorker());
    EXPECT_EQ(WebURLRequest::FetchRequestModeCORS, copy1.fetchRequestMode());
    EXPECT_EQ(WebURLRequest::FetchCredentialsModeSameOrigin, copy1.fetchCredentialsMode());
    EXPECT_EQ(30, copy1.requestorID());
    EXPECT_EQ(40, copy1.requestorProcessID());
    EXPECT_EQ(50, copy1.appCacheHostID());
    EXPECT_EQ(WebURLRequest::RequestContextAudio, copy1.requestContext());
    EXPECT_EQ(WebURLRequest::FrameTypeNested, copy1.frameType());
    EXPECT_STREQ("http://www.example.com/referrer.htm", copy1.httpReferrer().utf8().data());
    EXPECT_EQ(ReferrerPolicyDefault, copy1.getReferrerPolicy());

    copy1.setAllowStoredCredentials(true);
    copy1.setReportUploadProgress(true);
    copy1.setHasUserGesture(true);
    copy1.setDownloadToFile(true);
    copy1.setSkipServiceWorker(true);
    copy1.setFetchRequestMode(WebURLRequest::FetchRequestModeNoCORS);
    copy1.setFetchCredentialsMode(WebURLRequest::FetchCredentialsModeInclude);

    OwnPtr<CrossThreadResourceRequestData> data2(copy1.copyData());
    ResourceRequest copy2(data2.get());
    EXPECT_TRUE(copy2.allowStoredCredentials());
    EXPECT_TRUE(copy2.reportUploadProgress());
    EXPECT_TRUE(copy2.hasUserGesture());
    EXPECT_TRUE(copy2.downloadToFile());
    EXPECT_TRUE(copy2.skipServiceWorker());
    EXPECT_EQ(WebURLRequest::FetchRequestModeNoCORS, copy1.fetchRequestMode());
    EXPECT_EQ(WebURLRequest::FetchCredentialsModeInclude, copy1.fetchCredentialsMode());
}
Пример #15
0
const AtomicString DOMSettableTokenList::item(unsigned index) const
{
    if (index >= length())
        return AtomicString();
    return m_tokens[index];
}
Пример #16
0
void createQualifiedName(void* targetAddress, StringImpl* name)
{
    new (NotNull, reinterpret_cast<void*>(targetAddress)) QualifiedName(nullAtom, AtomicString(name), nullAtom);
}
Пример #17
0
void DOMSettableTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptionState)
{
    DOMTokenList::remove(tokens, exceptionState);
    for (size_t i = 0; i < tokens.size(); ++i)
        m_tokens.remove(AtomicString(tokens[i]));
}
Пример #18
0
size_t parseHTTPHeader(const char* start, size_t length, String& failureReason, AtomicString& nameStr, String& valueStr, bool strict)
{
    const char* p = start;
    const char* end = start + length;

    Vector<char> name;
    Vector<char> value;
    nameStr = AtomicString();
    valueStr = String();

    for (; p < end; p++) {
        switch (*p) {
        case '\r':
            if (name.isEmpty()) {
                if (p + 1 < end && *(p + 1) == '\n')
                    return (p + 2) - start;
                failureReason = "CR doesn't follow LF at " + trimInputSample(p, end - p);
                return 0;
            }
            failureReason = "Unexpected CR in name at " + trimInputSample(name.data(), name.size());
            return 0;
        case '\n':
            failureReason = "Unexpected LF in name at " + trimInputSample(name.data(), name.size());
            return 0;
        case ':':
            break;
        default:
            name.append(*p);
            continue;
        }
        if (*p == ':') {
            ++p;
            break;
        }
    }

    for (; p < end && *p == 0x20; p++) { }

    for (; p < end; p++) {
        switch (*p) {
        case '\r':
            break;
        case '\n':
            if (strict) {
                failureReason = "Unexpected LF in value at " + trimInputSample(value.data(), value.size());
                return 0;
            }
            break;
        default:
            value.append(*p);
        }
        if (*p == '\r' || (!strict && *p == '\n')) {
            ++p;
            break;
        }
    }
    if (p >= end || (strict && *p != '\n')) {
        failureReason = "CR doesn't follow LF after value at " + trimInputSample(p, end - p);
        return 0;
    }
    nameStr = AtomicString::fromUTF8(name.data(), name.size());
    valueStr = String::fromUTF8(value.data(), value.size());
    if (nameStr.isNull()) {
        failureReason = "Invalid UTF-8 sequence in header name";
        return 0;
    }
    if (valueStr.isNull()) {
        failureReason = "Invalid UTF-8 sequence in header value";
        return 0;
    }
    return p - start;
}
Пример #19
0
 static void translate(AtomicString& location, const char* cString, unsigned /*hash*/)
 {
     location = AtomicString(cString);
 }
Пример #20
0
FrameLoadRequest::FrameLoadRequest(Document* originDocument,
                                   const ResourceRequest& resourceRequest)
    : FrameLoadRequest(originDocument, resourceRequest, AtomicString()) {}
Пример #21
0
static SMILEventSender& smilRepeatNEventSender()
{
    DEFINE_STATIC_LOCAL(SMILEventSender, sender, (SMILEventSender::create(AtomicString("repeatn"))));
    return sender;
}
Пример #22
0
const AtomicString HTMLCanvasElement::imageSourceURL() const
{
    return AtomicString(toDataURLInternal("image/png", 0, true));
}
Пример #23
0
AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
{
    if (value->IsNull())
        return AtomicString();
    return v8ValueToAtomicWebCoreString(value);
}
Пример #24
0
JSValuePtr JSDOMWindowBase::childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
    return toJS(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow());
}
Пример #25
0
AtomicString HTMLElement::eventNameForAttributeName(const QualifiedName& attrName) const
{
    if (!attrName.namespaceURI().isNull())
        return AtomicString();

    typedef HashMap<AtomicString, AtomicString> StringToStringMap;
    DEFINE_STATIC_LOCAL(StringToStringMap, attributeNameToEventNameMap, ());
    if (!attributeNameToEventNameMap.size()) {
        attributeNameToEventNameMap.set(onanimationstartAttr.localName(), eventNames().animationstartEvent);
        attributeNameToEventNameMap.set(onanimationiterationAttr.localName(), eventNames().animationiterationEvent);
        attributeNameToEventNameMap.set(onanimationendAttr.localName(), eventNames().animationendEvent);
        attributeNameToEventNameMap.set(onclickAttr.localName(), eventNames().clickEvent);
        attributeNameToEventNameMap.set(oncontextmenuAttr.localName(), eventNames().contextmenuEvent);
        attributeNameToEventNameMap.set(ondblclickAttr.localName(), eventNames().dblclickEvent);
        attributeNameToEventNameMap.set(onmousedownAttr.localName(), eventNames().mousedownEvent);
        attributeNameToEventNameMap.set(onmouseenterAttr.localName(), eventNames().mouseenterEvent);
        attributeNameToEventNameMap.set(onmouseleaveAttr.localName(), eventNames().mouseleaveEvent);
        attributeNameToEventNameMap.set(onmousemoveAttr.localName(), eventNames().mousemoveEvent);
        attributeNameToEventNameMap.set(onmouseoutAttr.localName(), eventNames().mouseoutEvent);
        attributeNameToEventNameMap.set(onmouseoverAttr.localName(), eventNames().mouseoverEvent);
        attributeNameToEventNameMap.set(onmouseupAttr.localName(), eventNames().mouseupEvent);
        attributeNameToEventNameMap.set(onmousewheelAttr.localName(), eventNames().mousewheelEvent);
        attributeNameToEventNameMap.set(onwheelAttr.localName(), eventNames().wheelEvent);
        attributeNameToEventNameMap.set(onfocusAttr.localName(), eventNames().focusEvent);
        attributeNameToEventNameMap.set(onfocusinAttr.localName(), eventNames().focusinEvent);
        attributeNameToEventNameMap.set(onfocusoutAttr.localName(), eventNames().focusoutEvent);
        attributeNameToEventNameMap.set(onblurAttr.localName(), eventNames().blurEvent);
        attributeNameToEventNameMap.set(onkeydownAttr.localName(), eventNames().keydownEvent);
        attributeNameToEventNameMap.set(onkeypressAttr.localName(), eventNames().keypressEvent);
        attributeNameToEventNameMap.set(onkeyupAttr.localName(), eventNames().keyupEvent);
        attributeNameToEventNameMap.set(onscrollAttr.localName(), eventNames().scrollEvent);
        attributeNameToEventNameMap.set(onbeforecutAttr.localName(), eventNames().beforecutEvent);
        attributeNameToEventNameMap.set(oncutAttr.localName(), eventNames().cutEvent);
        attributeNameToEventNameMap.set(onbeforecopyAttr.localName(), eventNames().beforecopyEvent);
        attributeNameToEventNameMap.set(oncopyAttr.localName(), eventNames().copyEvent);
        attributeNameToEventNameMap.set(onbeforepasteAttr.localName(), eventNames().beforepasteEvent);
        attributeNameToEventNameMap.set(onpasteAttr.localName(), eventNames().pasteEvent);
        attributeNameToEventNameMap.set(ondragenterAttr.localName(), eventNames().dragenterEvent);
        attributeNameToEventNameMap.set(ondragoverAttr.localName(), eventNames().dragoverEvent);
        attributeNameToEventNameMap.set(ondragleaveAttr.localName(), eventNames().dragleaveEvent);
        attributeNameToEventNameMap.set(ondropAttr.localName(), eventNames().dropEvent);
        attributeNameToEventNameMap.set(ondragstartAttr.localName(), eventNames().dragstartEvent);
        attributeNameToEventNameMap.set(ondragAttr.localName(), eventNames().dragEvent);
        attributeNameToEventNameMap.set(ondragendAttr.localName(), eventNames().dragendEvent);
        attributeNameToEventNameMap.set(onselectstartAttr.localName(), eventNames().selectstartEvent);
        attributeNameToEventNameMap.set(onsubmitAttr.localName(), eventNames().submitEvent);
        attributeNameToEventNameMap.set(onerrorAttr.localName(), eventNames().errorEvent);
        attributeNameToEventNameMap.set(onwebkitanimationstartAttr.localName(), eventNames().webkitAnimationStartEvent);
        attributeNameToEventNameMap.set(onwebkitanimationiterationAttr.localName(), eventNames().webkitAnimationIterationEvent);
        attributeNameToEventNameMap.set(onwebkitanimationendAttr.localName(), eventNames().webkitAnimationEndEvent);
        attributeNameToEventNameMap.set(onwebkittransitionendAttr.localName(), eventNames().webkitTransitionEndEvent);
        attributeNameToEventNameMap.set(ontransitionendAttr.localName(), eventNames().webkitTransitionEndEvent);
        attributeNameToEventNameMap.set(oninputAttr.localName(), eventNames().inputEvent);
        attributeNameToEventNameMap.set(oninvalidAttr.localName(), eventNames().invalidEvent);
        attributeNameToEventNameMap.set(ontouchstartAttr.localName(), eventNames().touchstartEvent);
        attributeNameToEventNameMap.set(ontouchmoveAttr.localName(), eventNames().touchmoveEvent);
        attributeNameToEventNameMap.set(ontouchendAttr.localName(), eventNames().touchendEvent);
        attributeNameToEventNameMap.set(ontouchcancelAttr.localName(), eventNames().touchcancelEvent);
        attributeNameToEventNameMap.set(onwebkitfullscreenchangeAttr.localName(), eventNames().webkitfullscreenchangeEvent);
        attributeNameToEventNameMap.set(onwebkitfullscreenerrorAttr.localName(), eventNames().webkitfullscreenerrorEvent);
        attributeNameToEventNameMap.set(onabortAttr.localName(), eventNames().abortEvent);
        attributeNameToEventNameMap.set(oncanplayAttr.localName(), eventNames().canplayEvent);
        attributeNameToEventNameMap.set(oncanplaythroughAttr.localName(), eventNames().canplaythroughEvent);
        attributeNameToEventNameMap.set(onchangeAttr.localName(), eventNames().changeEvent);
        attributeNameToEventNameMap.set(ondurationchangeAttr.localName(), eventNames().durationchangeEvent);
        attributeNameToEventNameMap.set(onemptiedAttr.localName(), eventNames().emptiedEvent);
        attributeNameToEventNameMap.set(onendedAttr.localName(), eventNames().endedEvent);
        attributeNameToEventNameMap.set(onloadeddataAttr.localName(), eventNames().loadeddataEvent);
        attributeNameToEventNameMap.set(onloadedmetadataAttr.localName(), eventNames().loadedmetadataEvent);
        attributeNameToEventNameMap.set(onloadstartAttr.localName(), eventNames().loadstartEvent);
        attributeNameToEventNameMap.set(onpauseAttr.localName(), eventNames().pauseEvent);
        attributeNameToEventNameMap.set(onplayAttr.localName(), eventNames().playEvent);
        attributeNameToEventNameMap.set(onplayingAttr.localName(), eventNames().playingEvent);
        attributeNameToEventNameMap.set(onprogressAttr.localName(), eventNames().progressEvent);
        attributeNameToEventNameMap.set(onratechangeAttr.localName(), eventNames().ratechangeEvent);
        attributeNameToEventNameMap.set(onresetAttr.localName(), eventNames().resetEvent);
        attributeNameToEventNameMap.set(onseekedAttr.localName(), eventNames().seekedEvent);
        attributeNameToEventNameMap.set(onseekingAttr.localName(), eventNames().seekingEvent);
        attributeNameToEventNameMap.set(onselectAttr.localName(), eventNames().selectEvent);
        attributeNameToEventNameMap.set(onstalledAttr.localName(), eventNames().stalledEvent);
        attributeNameToEventNameMap.set(onsuspendAttr.localName(), eventNames().suspendEvent);
        attributeNameToEventNameMap.set(ontimeupdateAttr.localName(), eventNames().timeupdateEvent);
        attributeNameToEventNameMap.set(onvolumechangeAttr.localName(), eventNames().volumechangeEvent);
        attributeNameToEventNameMap.set(onwaitingAttr.localName(), eventNames().waitingEvent);
        attributeNameToEventNameMap.set(onloadAttr.localName(), eventNames().loadEvent);
    }

    return attributeNameToEventNameMap.get(attrName.localName());
}
Пример #26
0
void WorkerGlobalScope::importScripts(const Vector<String>& urls,
                                      ExceptionState& exceptionState) {
  DCHECK(contentSecurityPolicy());
  DCHECK(getExecutionContext());

  ExecutionContext& executionContext = *this->getExecutionContext();

  Vector<KURL> completedURLs;
  for (const String& urlString : urls) {
    const KURL& url = executionContext.completeURL(urlString);
    if (!url.isValid()) {
      exceptionState.throwDOMException(
          SyntaxError, "The URL '" + urlString + "' is invalid.");
      return;
    }
    if (!contentSecurityPolicy()->allowScriptFromSource(url, AtomicString(),
                                                        NotParserInserted)) {
      exceptionState.throwDOMException(
          NetworkError,
          "The script at '" + url.elidedString() + "' failed to load.");
      return;
    }
    completedURLs.append(url);
  }

  for (const KURL& completeURL : completedURLs) {
    RefPtr<WorkerScriptLoader> scriptLoader(WorkerScriptLoader::create());
    scriptLoader->setRequestContext(WebURLRequest::RequestContextScript);
    scriptLoader->loadSynchronously(
        executionContext, completeURL, AllowCrossOriginRequests,
        executionContext.securityContext().addressSpace());

    // If the fetching attempt failed, throw a NetworkError exception and
    // abort all these steps.
    if (scriptLoader->failed()) {
      exceptionState.throwDOMException(
          NetworkError,
          "The script at '" + completeURL.elidedString() + "' failed to load.");
      return;
    }

    InspectorInstrumentation::scriptImported(
        &executionContext, scriptLoader->identifier(), scriptLoader->script());

    ErrorEvent* errorEvent = nullptr;
    std::unique_ptr<Vector<char>> cachedMetaData(
        scriptLoader->releaseCachedMetadata());
    CachedMetadataHandler* handler(createWorkerScriptCachedMetadataHandler(
        completeURL, cachedMetaData.get()));
    thread()->workerReportingProxy().willEvaluateImportedScript(
        scriptLoader->script().length(),
        scriptLoader->cachedMetadata() ? scriptLoader->cachedMetadata()->size()
                                       : 0);
    m_scriptController->evaluate(
        ScriptSourceCode(scriptLoader->script(), scriptLoader->responseURL()),
        &errorEvent, handler, m_v8CacheOptions);
    if (errorEvent) {
      m_scriptController->rethrowExceptionFromImportedScript(errorEvent,
                                                             exceptionState);
      return;
    }
  }
}
void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
{
    if (!Document::isValidName(name)) {
        ec = INVALID_CHARACTER_ERR;
        return;
    }

    const AtomicString& localName = (shouldIgnoreAttributeCase(this) && !name.string().impl()->isLower()) ? AtomicString(name.string().lower()) : name;

    // allocate attributemap if necessary
    Attribute* old = attributes(false)->getAttributeItem(localName, false);

    document()->incDOMTreeVersion();

    if (localName == idAttr.localName())
        updateId(old ? old->value() : nullAtom, value);
    
    if (old && value.isNull())
        namedAttrMap->removeAttribute(old->name());
    else if (!old && !value.isNull())
        namedAttrMap->addAttribute(createAttribute(QualifiedName(nullAtom, localName, nullAtom), value));
    else if (old && !value.isNull()) {
        old->setValue(value);
        attributeChanged(old);
    }
}
Пример #28
0
VTTCueBox::VTTCueBox(Document& document, VTTCue* cue)
    : HTMLDivElement(document)
    , m_cue(cue)
{
    setShadowPseudoId(AtomicString("-webkit-media-text-track-display", AtomicString::ConstructFromLiteral));
}
Пример #29
0
inline void ImageLoader::clearFailedLoadURL()
{
    m_failedLoadURL = AtomicString();
}
Пример #30
0
Response* Response::create(ExecutionContext* context, PassOwnPtr<FetchDataConsumerHandle> bodyHandle, const String& contentType, const ResponseInit& init, ExceptionState& exceptionState)
{
    unsigned short status = init.status;

    // "1. If |init|'s status member is not in the range 200 to 599, inclusive, throw a
    // RangeError."
    if (status < 200 || 599 < status) {
        exceptionState.throwRangeError(ExceptionMessages::indexOutsideRange<unsigned>("status", status, 200, ExceptionMessages::InclusiveBound, 599, ExceptionMessages::InclusiveBound));
        return nullptr;
    }

    // "2. If |init|'s statusText member does not match the Reason-Phrase
    // token production, throw a TypeError."
    if (!isValidReasonPhrase(init.statusText)) {
        exceptionState.throwTypeError("Invalid statusText");
        return nullptr;
    }

    // "3. Let |r| be a new Response object, associated with a new response,
    // Headers object, and Body object."
    Response* r = new Response(context);

    // "4. Set |r|'s response's status to |init|'s status member."
    r->m_response->setStatus(init.status);

    // "5. Set |r|'s response's status message to |init|'s statusText member."
    r->m_response->setStatusMessage(AtomicString(init.statusText));

    // "6. If |init|'s headers member is present, run these substeps:"
    if (init.headers) {
        // "1. Empty |r|'s response's header list."
        r->m_response->headerList()->clearList();
        // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow
        // any exceptions."
        r->m_headers->fillWith(init.headers.get(), exceptionState);
        if (exceptionState.hadException())
            return nullptr;
    } else if (!init.headersDictionary.isUndefinedOrNull()) {
        // "1. Empty |r|'s response's header list."
        r->m_response->headerList()->clearList();
        // "2. Fill |r|'s Headers object with |init|'s headers member. Rethrow
        // any exceptions."
        r->m_headers->fillWith(init.headersDictionary, exceptionState);
        if (exceptionState.hadException())
            return nullptr;
    }
    // "7. If body is given, run these substeps:"
    if (bodyHandle) {
        // "1. If |init|'s status member is a null body status, throw a
        //     TypeError."
        // "2. Let |stream| and |Content-Type| be the result of extracting
        //     body."
        // "3. Set |r|'s response's body to |stream|."
        // "4. If |Content-Type| is non-null and |r|'s response's header list
        // contains no header named `Content-Type`, append `Content-Type`/
        // |Content-Type| to |r|'s response's header list."
        // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
        // Step 3, Blob:
        // "If object's type attribute is not the empty byte sequence, set
        // Content-Type to its value."
        if (isNullBodyStatus(status)) {
            exceptionState.throwTypeError("Response with null body status cannot have body");
            return nullptr;
        }
        r->m_response->replaceBodyStreamBuffer(new BodyStreamBuffer(bodyHandle));
        if (!contentType.isEmpty() && !r->m_response->headerList()->has("Content-Type"))
            r->m_response->headerList()->append("Content-Type", contentType);
    }

    // "8. Set |r|'s MIME type to the result of extracting a MIME type
    // from |r|'s response's header list."
    r->m_response->setMIMEType(r->m_response->headerList()->extractMIMEType());

    // "9. Return |r|."
    return r;
}