OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host, SubdomainSetting subdomainSetting)
    : m_protocol(protocol.lower())
    , m_host(host.lower())
    , m_subdomainSettings(subdomainSetting)
    , m_hostIsPublicSuffix(false)
{
    ASSERT(subdomainSetting >= AllowSubdomains || subdomainSetting <= DisallowSubdomains);

    m_hostIsIPAddress = HostIsIPAddress(host);

    // Look for top-level domains, either with or without an additional dot.
    if (!m_hostIsIPAddress) {
        WebPublicSuffixList* suffixList = Platform::current()->publicSuffixList();
        if (!suffixList)
            return;

        size_t publicSuffixLength = suffixList->getPublicSuffixLength(m_host);
        if (m_host.length() <= publicSuffixLength + 1) {
            m_hostIsPublicSuffix = true;
        } else if (subdomainSetting == AllowRegisterableDomains && publicSuffixLength) {
            // The "2" in the next line is 1 for the '.', plus a 1-char minimum label length.
            const size_t dot = m_host.reverseFind('.', m_host.length() - publicSuffixLength - 2);
            if (dot == kNotFound)
                m_registerableDomain = host;
            else
                m_registerableDomain = host.substring(dot + 1);
        }
    }
}
Example #2
0
void NetworkJob::handleNotifyHeaderReceived(const String& key, const String& value)
{
    // Check for messages out of order or after cancel.
    if (!m_statusReceived || m_responseSent || m_cancelled)
        return;

    String lowerKey = key.lower();
    if (lowerKey == "content-type")
        m_contentType = value.lower();
    else if (lowerKey == "content-disposition")
        m_contentDisposition = value;
    else if (lowerKey == "set-cookie") {
        // FIXME: If a tab is closed, sometimes network data will come in after the frame has been detached from its page but before it is deleted.
        // If this happens, m_frame->page() will return 0, and m_frame->loader()->client() will be in a bad state and calling into it will crash.
        // For now we check for this explicitly by checking m_frame->page(). But we should find out why the network job hasn't been cancelled when the frame was detached.
        // See RIM PR 134207
        if (m_frame && m_frame->page() && m_frame->loader() && m_frame->loader()->client()
            && static_cast<FrameLoaderClientBlackBerry*>(m_frame->loader()->client())->cookiesEnabled())
            handleSetCookieHeader(value);

        if (m_response.httpHeaderFields().contains("Set-Cookie")) {
            m_response.setHTTPHeaderField(key, m_response.httpHeaderField(key) + "\r\n" + value);
            return;
        }
    } else if (equalIgnoringCase(key, BlackBerry::Platform::NetworkRequest::HEADER_BLACKBERRY_FTP))
        handleFTPHeader(value);

    m_response.setHTTPHeaderField(key, value);
}
void FetchHeaderList::append(const String& name, const String& value)
{
    // "To append a name/value (|name|/|value|) pair to a header list (|list|),
    // append a new header whose name is |name|, byte lowercased, and value is
    // |value|, to |list|."
    m_headerList.append(wrapUnique(new Header(name.lower(), value)));
}
Example #4
0
HTMLMapElement* TreeScope::getImageMap(const String& url) const {
  if (url.isNull())
    return nullptr;
  if (!m_imageMapsByName)
    return nullptr;
  size_t hashPos = url.find('#');
  String name = hashPos == kNotFound ? url : url.substring(hashPos + 1);
  HTMLMapElement* map = toHTMLMapElement(
      rootNode().document().isHTMLDocument()
          ? m_imageMapsByName->getElementByLowercasedMapName(
                AtomicString(name.lower()), this)
          : m_imageMapsByName->getElementByMapName(AtomicString(name), this));
  if (!map || !rootNode().document().isHTMLDocument())
    return map;
  const AtomicString& nameValue = map->fastGetAttribute(nameAttr);
  if (nameValue.isNull())
    return map;
  String strippedName = nameValue;
  if (strippedName.startsWith('#'))
    strippedName = strippedName.substring(1);
  if (strippedName == name)
    UseCounter::count(rootNode().document(), UseCounter::MapNameMatchingStrict);
  else if (equalIgnoringASCIICase(strippedName, name))
    UseCounter::count(rootNode().document(),
                      UseCounter::MapNameMatchingASCIICaseless);
  else
    UseCounter::count(rootNode().document(),
                      UseCounter::MapNameMatchingUnicodeLower);
  return map;
}
Example #5
0
void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    // FIXME: This logic seems wrong for XML documents.
    // Either the id or name will be used depending on the order the attributes are parsed.

    if (isIdAttributeName(name) || name == nameAttr) {
        if (isIdAttributeName(name)) {
            // Call base class so that hasID bit gets set.
            HTMLElement::parseAttribute(name, value);
            if (document().isHTMLDocument())
                return;
        }
        if (inDocument())
            treeScope().removeImageMap(this);
        String mapName = value;
        if (mapName[0] == '#')
            mapName = mapName.substring(1);
        m_name = AtomicString(document().isHTMLDocument() ? mapName.lower() : mapName);
        if (inDocument())
            treeScope().addImageMap(this);

        return;
    }

    HTMLElement::parseAttribute(name, value);
}
static UScriptCode scriptCodeForHanFromSubtag(const String& subtag)
{
    struct SubtagScript {
        const char* subtag;
        UScriptCode script;
    };

    static const SubtagScript subtagScriptList[] = {
        { "cn", USCRIPT_SIMPLIFIED_HAN },
        { "hans", USCRIPT_SIMPLIFIED_HAN },
        { "hant", USCRIPT_TRADITIONAL_HAN },
        { "hk", USCRIPT_TRADITIONAL_HAN },
        { "jp", USCRIPT_KATAKANA_OR_HIRAGANA },
        { "kr", USCRIPT_HANGUL },
        { "tw", USCRIPT_TRADITIONAL_HAN },
    };

    typedef HashMap<String, UScriptCode> SubtagScriptMap;
    DEFINE_STATIC_LOCAL(SubtagScriptMap, subtagScriptMap, ());
    if (subtagScriptMap.isEmpty()) {
        for (size_t i = 0; i < WTF_ARRAY_LENGTH(subtagScriptList); ++i)
            subtagScriptMap.set(subtagScriptList[i].subtag, subtagScriptList[i].script);
    }

    const auto& it = subtagScriptMap.find(subtag.lower());
    return it != subtagScriptMap.end() ? it->value : USCRIPT_COMMON;
}
Example #7
0
MediaQuery::MediaQuery(Restrictor r, const String& mediaType, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > exprs)
    : m_restrictor(r)
    , m_mediaType(mediaType.lower())
    , m_expressions(exprs)
    , m_ignored(false)
{
    if (!m_expressions) {
        m_expressions = adoptPtr(new Vector<OwnPtr<MediaQueryExp> >);
        return;
    }

    nonCopyingSort(m_expressions->begin(), m_expressions->end(), expressionCompare);

    // remove all duplicated expressions
    String key;
    for (int i = m_expressions->size() - 1; i >= 0; --i) {

        // if not all of the expressions is valid the media query must be ignored.
        if (!m_ignored)
            m_ignored = !m_expressions->at(i)->isValid();

        if (m_expressions->at(i)->serialize() == key)
            m_expressions->remove(i);
        else
            key = m_expressions->at(i)->serialize();
    }
}
String ImageBuffer::toDataURL(const String& mimeType, const double*) const
{
    if (!m_data.m_bitmap->bytes())
        return "data:,";

    Vector<char> output;
    const char* header;
    if (mimeType.lower() == "image/png") {
        if (!compressBitmapToPng(m_data.m_bitmap.get(), output))
            return "data:,";
        header = "data:image/png;base64,";
    } else {
        if (!compressBitmapToJpeg(m_data.m_bitmap.get(), output))
            return "data:,";
        header = "data:image/jpeg;base64,";
    }

    Vector<char> base64;
    base64Encode(output, base64);

    output.clear();

    Vector<char> url;
    url.append(header, strlen(header));
    url.append(base64);

    return String(url.data(), url.size());
}
String ColorInputType::sanitizeValue(const String& proposedValue) const
{
    if (!isValidColorString(proposedValue))
        return fallbackValue();

    return proposedValue.lower();
}
bool DOMImplementation::hasFeature(const String& feature, const String& version)
{
    String lower = feature.lower();
    if (lower == "core" || lower == "html" || lower == "xml" || lower == "xhtml")
        return version.isEmpty() || version == "1.0" || version == "2.0";
    if (lower == "css"
            || lower == "css2"
            || lower == "events"
            || lower == "htmlevents"
            || lower == "mouseevents"
            || lower == "mutationevents"
            || lower == "range"
            || lower == "stylesheets"
            || lower == "traversal"
            || lower == "uievents"
            || lower == "views")
        return version.isEmpty() || version == "2.0";
    if (lower == "xpath" || lower == "textevents")
        return version.isEmpty() || version == "3.0";

#if ENABLE(SVG)
    if ((version.isEmpty() || version == "1.1") && feature.startsWith("http://www.w3.org/tr/svg11/feature#", false)) {
        if (isSVG11Feature(feature.right(feature.length() - 35)))
            return true;
    }

    if ((version.isEmpty() || version == "1.0") && feature.startsWith("org.w3c.", false)) {
        if (isSVG10Feature(feature.right(feature.length() - 8)))
            return true;
    }
#endif
    
    return false;
}
void LinkHeader::setValue(LinkParameterName name, String value)
{
    // FIXME: Add support for more header parameters as neccessary.
    if (name == LinkParameterRel && !m_rel)
        m_rel = value.lower();
    else if (name == LinkParameterAnchor)
        m_isValid = false;
    else if (name == LinkParameterCrossOrigin)
        m_crossOrigin = crossOriginAttributeValue(value);
    else if (name == LinkParameterAs)
        m_as = value.lower();
    else if (name == LinkParameterType)
        m_mimeType = value.lower();
    else if (name == LinkParameterMedia)
        m_media = value.lower();
}
Example #12
0
String HTMLCanvasElement::toDataURL(const String& mimeType, const double* quality, ExceptionCode& ec)
{
	if (!m_originClean) {
    	Settings* settings = document()->settings();
    	if (settings && settings->isWebSecurityEnabled()) {
    		ec = SECURITY_ERR;
    		return String();
    	}
    }

    if (m_size.isEmpty() || !buffer())
        return String("data:,");

    String lowercaseMimeType = mimeType.lower();

    // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread).
    if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType))
        lowercaseMimeType = "image/png";

#if USE(CG) || USE(SKIA)
    // Try to get ImageData first, as that may avoid lossy conversions.
    RefPtr<ImageData> imageData = getImageData();

    if (imageData)
        return ImageDataToDataURL(*imageData, lowercaseMimeType, quality);
#endif

    makeRenderingResultsAvailable();
      
    return buffer()->toDataURL(lowercaseMimeType, quality);
}
Example #13
0
void NetscapePluginModule::parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
{
    ASSERT_ARG(result, result.isEmpty());

    Vector<String> types;
    mimeDescription.lower().split(UChar(';'), false, types);
    result.reserveInitialCapacity(types.size());

    size_t mimeInfoCount = 0;
    for (size_t i = 0; i < types.size(); ++i) {
        Vector<String> mimeTypeParts;
        types[i].split(UChar(':'), true, mimeTypeParts);
        if (mimeTypeParts.size() <= 0)
            continue;

        result.uncheckedAppend(MimeClassInfo());
        MimeClassInfo& mimeInfo = result[mimeInfoCount++];
        mimeInfo.type = mimeTypeParts[0];

        if (mimeTypeParts.size() > 1)
            mimeTypeParts[1].split(UChar(','), false, mimeInfo.extensions);

        if (mimeTypeParts.size() > 2)
            mimeInfo.desc = mimeTypeParts[2];
    }
}
Example #14
0
bool MediaPlayer::load(const URL& url, const ContentType& contentType, const String& keySystem)
{
    m_contentMIMEType = contentType.type().lower();
    m_contentTypeCodecs = contentType.parameter(codecs());
    m_url = url;
    m_keySystem = keySystem.lower();
    m_contentMIMETypeWasInferredFromExtension = false;

#if ENABLE(MEDIA_SOURCE)
    m_mediaSource = 0;
#endif

    // If the MIME type is missing or is not meaningful, try to figure it out from the URL.
    if (m_contentMIMEType.isEmpty() || m_contentMIMEType == applicationOctetStream() || m_contentMIMEType == textPlain()) {
        if (m_url.protocolIsData())
            m_contentMIMEType = mimeTypeFromDataURL(m_url.string());
        else {
            String lastPathComponent = url.lastPathComponent();
            size_t pos = lastPathComponent.reverseFind('.');
            if (pos != notFound) {
                String extension = lastPathComponent.substring(pos + 1);
                String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
                if (!mediaType.isEmpty()) {
                    m_contentMIMEType = mediaType;
                    m_contentMIMETypeWasInferredFromExtension = true;
                }
            }
        }
    }

    loadWithNextMediaEngine(0);
    return m_currentMediaEngine;
}
bool FetchHeaderList::has(const String& name) const
{
    const String lowercasedName = name.lower();
    for (size_t i = 0; i < m_headerList.size(); ++i) {
        if (m_headerList[i]->first == lowercasedName)
            return true;
    }
    return false;
}
void FetchHeaderList::getAll(const String& name, Vector<String>& result) const
{
    const String lowercasedName = name.lower();
    result.clear();
    for (size_t i = 0; i < m_headerList.size(); ++i) {
        if (m_headerList[i]->first == lowercasedName)
            result.append(m_headerList[i]->second);
    }
}
PassRefPtr<Node> NamedAttrMap::getNamedItem(const String& name) const
{
    String localName = inHTMLDocument(element) ? name.lower() : name;
    Attribute* a = getAttributeItem(localName);
    if (!a)
        return 0;
    
    return a->createAttrIfNeeded(element);
}
OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host, SubdomainSetting subdomainSetting, IPAddressSetting ipAddressSetting)
    : m_protocol(protocol.lower())
    , m_host(host.lower())
    , m_subdomainSettings(subdomainSetting)
    , m_ipAddressSettings(ipAddressSetting)
    , m_hostIsPublicSuffix(false)
{
    ASSERT(subdomainSetting == AllowSubdomains || subdomainSetting == DisallowSubdomains);

    // Assume that any host that ends with a digit is trying to be an IP address.
    m_hostIsIPAddress = !m_host.isEmpty() && isASCIIDigit(m_host[m_host.length() - 1]);

    // Look for top-level domains, either with or without an additional dot.
    if (!m_hostIsIPAddress) {
        blink::WebPublicSuffixList* suffixList = blink::Platform::current()->publicSuffixList();
        if (suffixList && m_host.length() <= suffixList->getPublicSuffixLength(m_host) + 1)
            m_hostIsPublicSuffix = true;
    }
}
Example #19
0
String HTMLCanvasElement::toEncodingMimeType(const String& mimeType)
{
    String lowercaseMimeType = mimeType.lower();

    // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread).
    if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType))
        lowercaseMimeType = "image/png";

    return lowercaseMimeType;
}
bool FetchHeaderList::get(const String& name, String& result) const
{
    const String lowercasedName = name.lower();
    for (size_t i = 0; i < m_headerList.size(); ++i) {
        if (m_headerList[i]->first == lowercasedName) {
            result = m_headerList[i]->second;
            return true;
        }
    }
    return false;
}
PassRefPtr<Node> NamedAttrMap::removeNamedItem(const String& name, ExceptionCode& ec)
{
    String localName = inHTMLDocument(element) ? name.lower() : name;
    Attribute* a = getAttributeItem(localName);
    if (!a) {
        ec = NOT_FOUND_ERR;
        return 0;
    }
    
    return removeNamedItem(a->name(), ec);
}
Example #22
0
bool SelectionController::modify(const String &alterString, const String &directionString, const String &granularityString)
{
    String alterStringLower = alterString.lower();
    EAlter alter;
    if (alterStringLower == "extend")
        alter = EXTEND;
    else if (alterStringLower == "move")
        alter = MOVE;
    else 
        return false;
    
    String directionStringLower = directionString.lower();
    EDirection direction;
    if (directionStringLower == "forward")
        direction = FORWARD;
    else if (directionStringLower == "backward")
        direction = BACKWARD;
    else if (directionStringLower == "left")
        direction = LEFT;
    else if (directionStringLower == "right")
        direction = RIGHT;
    else
        return false;
        
    String granularityStringLower = granularityString.lower();
    TextGranularity granularity;
    if (granularityStringLower == "character")
        granularity = CharacterGranularity;
    else if (granularityStringLower == "word")
        granularity = WordGranularity;
    else if (granularityStringLower == "sentence")
        granularity = SentenceGranularity;
    else if (granularityStringLower == "line")
        granularity = LineGranularity;
    else if (granularityStringLower == "paragraph")
        granularity = ParagraphGranularity;
    else
        return false;
                
    return modify(alter, direction, granularity);
}
String FetchHeaderList::extractMIMEType() const
{
    // To extract a MIME type from a header list (headers), run these steps:
    // 1. Let MIMEType be the result of parsing `Content-Type` in headers.
    String mimeType;
    if (!get("Content-Type", mimeType)) {
        // 2. If MIMEType is null or failure, return the empty byte sequence.
        return String();
    }
    // 3. Return MIMEType, byte lowercased.
    return mimeType.lower();
}
void FetchHeaderList::remove(const String& name)
{
    // "To delete a name (|name|) from a header list (|list|), remove all headers
    // whose name is |name|, byte lowercased, from |list|."
    const String lowercasedName = name.lower();
    for (size_t i = 0; i < m_headerList.size(); ) {
        if (m_headerList[i]->first == lowercasedName)
            m_headerList.remove(i);
        else
            ++i;
    }
}
Example #25
0
void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr)
{
    String val = attr->value();
    int pos;
    if (attr->name() == typeAttr) {
        m_serviceType = val.lower();
        pos = m_serviceType.find(";");
        if (pos != -1)
          m_serviceType = m_serviceType.left(pos);
        if (renderer())
          m_needWidgetUpdate = true;
        if (!isImageType() && m_imageLoader) {
          delete m_imageLoader;
          m_imageLoader = 0;
        }
    } else if (attr->name() == dataAttr) {
        m_url = parseURL(val);
        if (renderer())
          m_needWidgetUpdate = true;
        if (renderer() && isImageType()) {
          if (!m_imageLoader)
              m_imageLoader = new HTMLImageLoader(this);
          m_imageLoader->updateFromElement();
        }
    } else if (attr->name() == classidAttr) {
        m_classId = val;
        if (renderer())
          m_needWidgetUpdate = true;
    } else if (attr->name() == onloadAttr) {
        setHTMLEventListener(loadEvent, attr);
    } else if (attr->name() == onunloadAttr) {
        setHTMLEventListener(unloadEvent, attr);
    } else if (attr->name() == nameAttr) {
            String newNameAttr = attr->value();
            if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
                HTMLDocument *doc = static_cast<HTMLDocument *>(document());
                doc->removeNamedItem(oldNameAttr);
                doc->addNamedItem(newNameAttr);
            }
            oldNameAttr = newNameAttr;
    } else if (attr->name() == idAttr) {
        String newIdAttr = attr->value();
        if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
            HTMLDocument* doc = static_cast<HTMLDocument*>(document());
            doc->removeDocExtraNamedItem(oldIdAttr);
            doc->addDocExtraNamedItem(newIdAttr);
        }
        oldIdAttr = newIdAttr;
        // also call superclass
        HTMLPlugInElement::parseMappedAttribute(attr);
    } else
        HTMLPlugInElement::parseMappedAttribute(attr);
}
String MIMETypeRegistry::getMIMETypeForExtension(const String &ext)
{
    ASSERT(isMainThread());

    String lowerCaseExt = ext.lower();
    const ExtensionMap* extMap = extensionMap;
    while (extMap->extension) {
        if (lowerCaseExt == extMap->extension)
            return extMap->mimeType;
        ++extMap;
    }

    return String();
}
static PassRefPtr<TextResourceDecoder> createOtherResourceTextDecoder(const String& mimeType, const String& textEncodingName)
{
    RefPtr<TextResourceDecoder> decoder;
    if (!textEncodingName.isEmpty())
        decoder = TextResourceDecoder::create("text/plain", textEncodingName);
    else if (DOMImplementation::isXMLMIMEType(mimeType.lower())) {
        decoder = TextResourceDecoder::create("application/xml");
        decoder->useLenientXMLDecoding();
    } else if (equalIgnoringCase(mimeType, "text/html"))
        decoder = TextResourceDecoder::create("text/html", "UTF-8");
    else if (mimeType == "text/plain")
        decoder = TextResourceDecoder::create("text/plain", "ISO-8859-1");
    return decoder;
}
Example #28
0
void NetworkJob::handleNotifyMultipartHeaderReceived(const String& key, const String& value)
{
    if (!m_multipartResponse) {
        // Create a new response based on the original set of headers + the
        // replacement headers. We only replace the same few headers that gecko
        // does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp.
        m_multipartResponse = adoptPtr(new ResourceResponse);
        m_multipartResponse->setURL(m_response.url());

        // The list of BlackBerry::Platform::replaceHeaders that we do not copy from the original
        // response when generating a response.
        const WebCore::HTTPHeaderMap& map = m_response.httpHeaderFields();

        for (WebCore::HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it) {
            bool needsCopyfromOriginalResponse = true;
            int replaceHeadersIndex = 0;
            while (BlackBerry::Platform::MultipartStream::replaceHeaders[replaceHeadersIndex]) {
                if (it->first.lower() == BlackBerry::Platform::MultipartStream::replaceHeaders[replaceHeadersIndex]) {
                    needsCopyfromOriginalResponse = false;
                    break;
                }
                replaceHeadersIndex++;
            }
            if (needsCopyfromOriginalResponse)
                m_multipartResponse->setHTTPHeaderField(it->first, it->second);
        }

        m_multipartResponse->setIsMultipartPayload(true);
    } else {
        if (key.lower() == "content-type") {
            String contentType = value.lower();
            m_multipartResponse->setMimeType(extractMIMETypeFromMediaType(contentType));
            m_multipartResponse->setTextEncodingName(extractCharsetFromMediaType(contentType));
        }
        m_multipartResponse->setHTTPHeaderField(key, value);
    }
}
HTMLMapElement* TreeScope::getImageMap(const String& url) const
{
    if (url.isNull())
        return nullptr;
    if (!m_imageMapsByName)
        return nullptr;
    size_t hashPos = url.find('#');
    String name = (hashPos == notFound ? String() : url.substring(hashPos + 1)).impl();
    if (name.isEmpty())
        return nullptr;
    if (m_rootNode.document().isHTMLDocument()) {
        AtomicString lowercasedName = name.lower();
        return m_imageMapsByName->getElementByLowercasedMapName(*lowercasedName.impl(), *this);
    }
    return m_imageMapsByName->getElementByMapName(*AtomicString(name).impl(), *this);
}
Example #30
0
bool ScriptElement::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) const
{
    // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used here to maintain backwards compatibility with existing layout tests. The specific violations are:
    // - Allowing type=javascript. type= should only support MIME types, such as text/javascript.
    // - Allowing a different set of languages for language= and type=. language= supports Javascript 1.1 and 1.4-1.6, but type= does not.

    String type = typeAttributeValue();
    String language = languageAttributeValue();
    if (type.isEmpty() && language.isEmpty())
        return true; // Assume text/javascript.
    if (type.isEmpty()) {
        type = "text/" + language.lower();
        if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySupportedJavaScriptLanguage(language))
            return true;
    } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type)))
        return true;
    return false;
}