bool ScriptLoader::isValidScriptTypeAndLanguage( const String& type, const String& language, LegacyTypeSupport supportLegacyTypes) { // 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. if (type.isEmpty()) { return language.isEmpty() || // assume text/javascript. MIMETypeRegistry::isSupportedJavaScriptMIMEType("text/" + language) || isLegacySupportedJavaScriptLanguage(language); } else if (RuntimeEnabledFeatures::moduleScriptsEnabled() && type == "module") { return true; } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType( type.stripWhiteSpace()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) { return true; } return false; }
Optional<ScriptElement::ScriptType> ScriptElement::determineScriptType(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()) { if (language.isEmpty()) return ScriptType::Classic; // Assume text/javascript. if (MIMETypeRegistry::isSupportedJavaScriptMIMEType("text/" + language)) return ScriptType::Classic; if (isLegacySupportedJavaScriptLanguage(language)) return ScriptType::Classic; return Nullopt; } if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace())) return ScriptType::Classic; if (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type)) return ScriptType::Classic; #if ENABLE(ES6_MODULES) // https://html.spec.whatwg.org/multipage/scripting.html#attr-script-type // Setting the attribute to an ASCII case-insensitive match for the string "module" means that the script is a module script. if (equalLettersIgnoringASCIICase(type, "module")) return ScriptType::Module; #endif return Nullopt; }
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; }
void ScriptLoader::logScriptMIMEType(LocalFrame* frame, ScriptResource* resource, const String& mimeType) { if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType)) return; bool isText = mimeType.startsWith("text/", TextCaseASCIIInsensitive); if (isText && isLegacySupportedJavaScriptLanguage(mimeType.substring(5))) return; bool isSameOrigin = m_element->document().getSecurityOrigin()->canRequest(resource->url()); bool isApplication = !isText && mimeType.startsWith("application/", TextCaseASCIIInsensitive); UseCounter::Feature feature = isSameOrigin ? (isText ? UseCounter::SameOriginTextScript : isApplication ? UseCounter::SameOriginApplicationScript : UseCounter::SameOriginOtherScript) : (isText ? UseCounter::CrossOriginTextScript : isApplication ? UseCounter::CrossOriginApplicationScript : UseCounter::CrossOriginOtherScript); UseCounter::count(frame, feature); }
void ScriptLoader::logScriptMimetype(ScriptResource* resource, LocalFrame* frame, String mimetype) { String lowerMimetype = mimetype.lower(); bool text = lowerMimetype.startsWith("text/"); bool application = lowerMimetype.startsWith("application/"); bool expectedJs = MIMETypeRegistry::isSupportedJavaScriptMIMEType(lowerMimetype) || (text && isLegacySupportedJavaScriptLanguage(lowerMimetype.substring(5))); bool sameOrigin = m_element->document().getSecurityOrigin()->canRequest(m_resource->url()); if (expectedJs) { return; } UseCounter::Feature feature = sameOrigin ? (text ? UseCounter::SameOriginTextScript : application ? UseCounter::SameOriginApplicationScript : UseCounter::SameOriginOtherScript) : (text ? UseCounter::CrossOriginTextScript : application ? UseCounter::CrossOriginApplicationScript : UseCounter::CrossOriginOtherScript); UseCounter::count(frame, feature); }