Cut down on calls to String::lower; mostly replace with convertToASCIILowercase
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Feb 2016 05:46:20 +0000 (05:46 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Feb 2016 05:46:20 +0000 (05:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153732

Reviewed by Dean Jackson.

Source/WebCore:

* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::isTypeSupported): Added comment about mysterious call
to lower(); should probably return here and remove it.

* Modules/navigatorcontentutils/NavigatorContentUtils.cpp:
(WebCore::initProtocolHandlerWhitelist): Deleted. Moved into isProtocolWhitelisted.
(WebCore::isProtocolWhitelisted): Changed set to be ASCIICaseInsensitiveHash and
initialized it using a lambda instead of a separate function.
(WebCore::verifyProtocolHandlerScheme): Added a FIXME about some case sensitive
checking of the protocol prefix here.

* Modules/plugins/QuickTimePluginReplacement.mm:
(WebCore::QuickTimePluginReplacement::supportsMimeType): Changed set to be
ASCIICaseInsensitiveHash and initialized it using a lambda instead of using
an explict check for empty.
(WebCore::QuickTimePluginReplacement::supportsFileExtension): Ditto.

* Modules/plugins/YouTubePluginReplacement.cpp:
(WebCore::queryKeysAndValues): Use convertToASCIILowercase. The keys here are
going to be all ASCII.
(WebCore::isYouTubeURL): Use equalLettersIgnoringASCIICase instead of lowercasing
the string.
(WebCore::processAndCreateYouTubeURL): Use url.protocolIsInHTTPFamily instead of
listing "http" and then "https" explicitly. Use equalLettersIgnoringASCIICase
instead of lowercasing a string.
(WebCore::YouTubePluginReplacement::youTubeURL): Ditto.

* Modules/websockets/WebSocketHandshake.cpp:
(WebCore::hostName): Use convertToASCIILowercase on host name.
(WebCore::WebSocketHandshake::host): Ditto.

* accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
(webkitAccessibleGetAttributes): Call convertToASCIILowercase instead of lower
to lowercase an element's tag name. This is a strange way to do things; typically
would be better to use some other function on Element, since tagName goes out of
its way to be capitalized, but some ATK expert can improve this later.

* css/CSSGrammar.y.in: Use the new convertToASCIILowercaseInPlace function rather
than the old lower function. We only need to lowercase the ASCII letters, and it's
also better to have the function have a clearer name.

* css/CSSParser.cpp:
(WebCore::convertToASCIILowercaseInPlace): Renamed from makeLower and made it deal
with only ASCII lowercasing.
(WebCore::CSSParserString::convertToASCIILowercaseInPlace): Renamed from lower.
(WebCore::isUniversalKeyword): Added. Helper for the function below that uses
equalLettersIgnoringASCIICase rather than lowercasing the string.
(WebCore::parseKeywordValue): Use isUniversalKeyword. Also clarified a comment.
(WebCore::CSSParser::parseAttr): Use convertToASCIILowercaseInPlace and delay
String creation until later in the function, using CSSParserString operations more.

* css/CSSParserValues.cpp:
(WebCore::CSSParserSelector::parsePseudoElementSelector): Use
convertToASCIILowercaseInPlace by its new name, with its new behavior.

* css/CSSParserValues.h: Tweaked comment and formatting a bit. Replaced the lower
function with the convertToASCIILowercaseInPlace function.

* css/CSSSelector.cpp:
(WebCore::CSSSelector::RareData::parseNth): Rewrote this to avoid the need to
make a lowercased copy of m_argument. Use equalLettersIgnoringASCIICase, and two
calls to find. Also use String::toIntStrict so we don't have to create String
objects for substrings.

* css/MediaQuery.cpp:
(WebCore::MediaQuery::MediaQuery): Use convertToASCIILowercase for media type name.
* css/MediaQueryExp.cpp:
(WebCore::MediaQueryExp::serialize): Use convertToASCIILowercase for media feature name.

* dom/Document.cpp:
(WebCore::isSeparator): Tweaked formatting and removed non-helpful comment.
(WebCore::processArguments): Changed this from a static member function to a non-member
file internal function. Use a std::function instead of a function pointer with a void*
pointer. Rewrote algorithm to simplify it and use StringView instead of String for the
keys and values.
(WebCore::Document::processViewport): Use a lambda instead of a function pointer to
call setViewportFeature, so that function's interface is no longer dictated by
the exact type of the function pointer argument to processArguments.
(WebCore::Document::processFormatDetection): Use a lambda instead of the
setParserFeature function above; use equalLettersIgnoringASCIICase for both the
key and the value, since processArguments no longer lowercases the string.
(WebCore::Document::processArguments): Deleted.

* dom/Document.h: Removed unnecessary declaration of processArguments and
ArgumentsCallback. Both are now private to the cpp file.

* dom/Element.cpp:
(WebCore::makeIdForStyleResolution): Use convertToASCIILowercase. When in quirks mode,
we want to match IDs in an ASCII case-insensitive way not match compatibility caseless.

* dom/ScriptElement.cpp:
(WebCore::ScriptElement::isScriptTypeSupported): Remove the use of lower here since
the MIME type registry is now itself ASCII case-insensitive.

* dom/ViewportArguments.cpp:
(WebCore::numericPrefix): Changed to use StringView and take a Document&, rearranged
argument order so Document& comes first.
(WebCore::findSizeValue): Ditto.
(WebCore::findScaleValue): Ditto.
(WebCore::findBooleanValue): Ditto. Also use std::abs instead of fabs, possibly
avoiding a conversion from float to double (not sure it was happening before but it's
definitely not happening now).
(WebCore::setViewportFeature): Changed to put arguments in a more logical order, to take
the ViewportArguments as a reference, not a void*, and to use StringView to avoid forcing
the caller to allocate strings. Also changed to use equalLettersIgnoringASCIICase so we
don't rely on the caller to make the key lowercase for us.
(WebCore::reportViewportWarning): Changed argument types. Added a couple comments about
mistakes in the function.

* dom/ViewportArguments.h: Removed unnecessary declaration of reportViewportWarning,
which is now private to the cpp file. Updated for new arguments to setViewportFeature.

* editing/EditorCommand.cpp:
(WebCore::executeFormatBlock): Use convertToASCIILowercase on the argument, which is
specifying a tag name.

* fileapi/Blob.cpp:
(WebCore::Blob::isValidContentType): Removed unnecessary separate loops for
8-bit and 16-bit strings. Content types are short strings and this small optimization is
not worth the additional code complexity.
(WebCore::Blob::normalizedContentType): Use convertToASCIILowercase since valid
content types are guaranteed to be all ASCII.
(WebCore::Blob::isNormalizedContentType): Removed unnecessary separate loops for
8-bit and 16-bit strings. Content types are short strings and this small optimization is
not worth the additional code complexity.

* html/parser/HTMLParserIdioms.cpp: Added now-needed include of QualifiedName.h.

* html/parser/HTMLParserIdioms.h: Removed unneeded include of QualifiedName.h and
WTFString.h. Made sure every function is declared first, even if it's also defined
later in the header in the section for functions templates and inline functions.

* loader/archive/ArchiveFactory.cpp:
(WebCore::ArchiveFactory::registerKnownArchiveMIMETypes): Use auto& for the type of
the set of MIME types here, since it's now using ASCIICaseInsensitiveHash.

* platform/MIMETypeRegistry.cpp: Changed the MIME type sets to use
ASCIICaseInsensitiveHash since MIME type are not case sensitive.
(WebCore::initializeSupportedImageMIMETypes): Use a modern for loop.
(WebCore::initializeSupportedImageMIMETypesForEncoding): Updated for HashSet type change.
(WebCore::initializePDFMIMETypes): Use a modern for loop.
(WebCore::initializeSupportedNonImageMimeTypes): Use a modern for loop.
(WebCore::initializeSupportedMediaMIMETypes): Updated for HashSet type change.
(WebCore::initializeUnsupportedTextMIMETypes): Use a modern for loop.
(WebCore::initializeMIMETypeRegistry): Updated for HashSet type change.
(WebCore::MIMETypeRegistry::getSupportedImageMIMETypes): Ditto.
(WebCore::MIMETypeRegistry::getSupportedImageResourceMIMETypes): Ditto.
(WebCore::MIMETypeRegistry::getSupportedImageMIMETypesForEncoding): Ditto.
(WebCore::MIMETypeRegistry::getSupportedNonImageMIMETypes): Ditto.
(WebCore::MIMETypeRegistry::getSupportedMediaMIMETypes): Ditto.
(WebCore::MIMETypeRegistry::getPDFMIMETypes): Ditto.
(WebCore::MIMETypeRegistry::getPDFAndPostScriptMIMETypes): Ditto.
(WebCore::MIMETypeRegistry::getUnsupportedTextMIMETypes): Ditto.
(WebCore::mimeTypeAssociationMap): Use ASCIICaseInsensitiveHash.
(WebCore::MIMETypeRegistry::getNormalizedMIMEType): Use auto to make code tighter.

* platform/MIMETypeRegistry.h: Changed return types of the getMIMETypes functions
to use ASCIICaseInsensitiveHash.

* platform/SchemeRegistry.cpp:
(WebCore::schemesForbiddenFromDomainRelaxation): Changed type to
use ASCIICaseInsensitiveHash.

* platform/URL.cpp:
(WebCore::mimeTypeFromDataURL): Use convertToASCIILowercase instead of lower.
Also removed some dead code that tried to handle the case where the data URL
has a comma as one of the first 5 characters: That can't happen since it's a
precondition of this function that the first five characters are "data:".

* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::getSupportedTypes): Change type of argument to
a HashSet with ASCIICaseInsensitiveHash.
* platform/graphics/MediaPlayer.h: Ditto.

* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::staticMIMETypeList):
Changed type of HashSet to use ASCIICaseInsensitiveHash.
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h: Ditto.

* platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:
(WebCore::avfMIMETypes):
Changed type of HashSet to use ASCIICaseInsensitiveHash.
(WebCore::MediaPlayerPrivateAVFoundationCF::getSupportedTypes): Ditto.
* platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h: Ditto.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
Changed type of HashSet to use ASCIICaseInsensitiveHash.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::paintWithImageGenerator): Removed
an unnecessary line of code to set a local variable to 0 just before it falls
out of scope.
(WebCore::avfMIMETypes): Ditto. Also tightened up the code a bit.
(WebCore::MediaPlayerPrivateAVFoundationObjC::getSupportedTypes): Ditto.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
Changed type of HashSet to use ASCIICaseInsensitiveHash.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::mimeTypeCache): Ditto.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::getSupportedTypes): Ditto.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h: Ditto.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::getSupportedTypes): Ditto.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::mimeTypeCache): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::getSupportedTypes): Ditto.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: Ditto.

* platform/graphics/mac/MediaPlayerPrivateQTKit.h: Ditto.
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::shouldRejectMIMEType): Made this non-case-sensitive by using startsWith
and the "false" argument. Later change this to startsWithIgnoringASCIICase or
startsWithLettersIgnoringASCIICase.
(WebCore::addFileTypesToCache): Use ASCIICaseInsensitiveHash. ALso rewrote to
tighten up the code a bit and use modern Objective-C for loops.
(WebCore::mimeCommonTypesCache): Use ASCIICaseInsensitiveHash.
(WebCore::mimeModernTypesCache): Ditto.
(WebCore::concatenateHashSets): Ditto.
(WebCore::MediaPlayerPrivateQTKit::getSupportedTypes): Ditto.
(WebCore::MediaPlayerPrivateQTKit::disableUnsupportedTracks): Initialied
track type set using lambda, but left it case sensitive.

* platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp:
(WebCore::mimeTypeCache): Changed type of HashSet to use ASCIICaseInsensitiveHash.
(WebCore::MediaPlayerPrivateMediaFoundation::getSupportedTypes): Ditto.
* platform/graphics/win/MediaPlayerPrivateMediaFoundation.h:

* platform/mock/mediasource/MockMediaPlayerMediaSource.cpp:
(WebCore::mimeTypeCache): Ditto.
(WebCore::MockMediaPlayerMediaSource::getSupportedTypes): Ditto.
* platform/mock/mediasource/MockMediaPlayerMediaSource.h: Ditto.

Source/WebKit/mac:

* WebView/WebHTMLRepresentation.mm:
(newArrayWithStrings): Updated to use HashSet<String, ASCIICaseInsensitiveHash>
and also to use a modern for loop.

Source/WTF:

* wtf/text/StringView.h: Added toIntStrict. Not thrilled about the name of this
function, but generally it seems likely to be useful more often than toInt.
And it's needed for one call site in WebCore that was using String::lower.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@195951 268f45cc-cd09-0410-ab3c-d52691b4dbfc

53 files changed:
Source/WTF/ChangeLog
Source/WTF/wtf/text/StringView.h
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediasource/MediaSource.cpp
Source/WebCore/Modules/navigatorcontentutils/NavigatorContentUtils.cpp
Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm
Source/WebCore/Modules/plugins/YouTubePluginReplacement.cpp
Source/WebCore/Modules/websockets/WebSocketHandshake.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.cpp
Source/WebCore/css/CSSGrammar.y.in
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParserValues.cpp
Source/WebCore/css/CSSParserValues.h
Source/WebCore/css/CSSSelector.cpp
Source/WebCore/css/MediaQuery.cpp
Source/WebCore/css/MediaQueryExp.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/ScriptElement.cpp
Source/WebCore/dom/ViewportArguments.cpp
Source/WebCore/dom/ViewportArguments.h
Source/WebCore/editing/EditorCommand.cpp
Source/WebCore/fileapi/Blob.cpp
Source/WebCore/html/parser/HTMLParserIdioms.cpp
Source/WebCore/html/parser/HTMLParserIdioms.h
Source/WebCore/loader/archive/ArchiveFactory.cpp
Source/WebCore/platform/MIMETypeRegistry.cpp
Source/WebCore/platform/MIMETypeRegistry.h
Source/WebCore/platform/SchemeRegistry.cpp
Source/WebCore/platform/URL.cpp
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp
Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp
Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h
Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp
Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebHTMLRepresentation.mm

index 3f98cbd..c51c7bb 100644 (file)
@@ -1,5 +1,16 @@
 2016-01-31  Darin Adler  <darin@apple.com>
 
+        Cut down on calls to String::lower; mostly replace with convertToASCIILowercase
+        https://bugs.webkit.org/show_bug.cgi?id=153732
+
+        Reviewed by Dean Jackson.
+
+        * wtf/text/StringView.h: Added toIntStrict. Not thrilled about the name of this
+        function, but generally it seems likely to be useful more often than toInt.
+        And it's needed for one call site in WebCore that was using String::lower.
+
+2016-01-31  Darin Adler  <darin@apple.com>
+
         Get rid of most calls to String::upper; mostly replace them with convertToASCIIUppercase
         https://bugs.webkit.org/show_bug.cgi?id=153715
 
index 4ddfe64..d24c0ab 100644 (file)
@@ -126,6 +126,7 @@ public:
     WTF_EXPORT_STRING_API bool endsWithIgnoringASCIICase(const StringView&) const;
 
     int toInt(bool& isValid) const;
+    int toIntStrict(bool& isValid) const;
     float toFloat(bool& isValid) const;
 
     static void invalidate(const StringImpl&);
@@ -461,6 +462,13 @@ inline int StringView::toInt(bool& isValid) const
     return charactersToInt(characters16(), length(), &isValid);
 }
 
+inline int StringView::toIntStrict(bool& isValid) const
+{
+    if (is8Bit())
+        return charactersToIntStrict(characters8(), m_length, &isValid);
+    return charactersToIntStrict(characters16(), length(), &isValid);
+}
+
 inline String StringView::toStringWithoutCopying() const
 {
     if (is8Bit())
index ac25619..ae30ef5 100644 (file)
@@ -1,3 +1,243 @@
+2016-01-31  Darin Adler  <darin@apple.com>
+
+        Cut down on calls to String::lower; mostly replace with convertToASCIILowercase
+        https://bugs.webkit.org/show_bug.cgi?id=153732
+
+        Reviewed by Dean Jackson.
+
+        * Modules/mediasource/MediaSource.cpp:
+        (WebCore::MediaSource::isTypeSupported): Added comment about mysterious call
+        to lower(); should probably return here and remove it.
+
+        * Modules/navigatorcontentutils/NavigatorContentUtils.cpp:
+        (WebCore::initProtocolHandlerWhitelist): Deleted. Moved into isProtocolWhitelisted.
+        (WebCore::isProtocolWhitelisted): Changed set to be ASCIICaseInsensitiveHash and
+        initialized it using a lambda instead of a separate function.
+        (WebCore::verifyProtocolHandlerScheme): Added a FIXME about some case sensitive
+        checking of the protocol prefix here.
+
+        * Modules/plugins/QuickTimePluginReplacement.mm:
+        (WebCore::QuickTimePluginReplacement::supportsMimeType): Changed set to be
+        ASCIICaseInsensitiveHash and initialized it using a lambda instead of using
+        an explict check for empty.
+        (WebCore::QuickTimePluginReplacement::supportsFileExtension): Ditto.
+
+        * Modules/plugins/YouTubePluginReplacement.cpp:
+        (WebCore::queryKeysAndValues): Use convertToASCIILowercase. The keys here are
+        going to be all ASCII.
+        (WebCore::isYouTubeURL): Use equalLettersIgnoringASCIICase instead of lowercasing
+        the string.
+        (WebCore::processAndCreateYouTubeURL): Use url.protocolIsInHTTPFamily instead of
+        listing "http" and then "https" explicitly. Use equalLettersIgnoringASCIICase
+        instead of lowercasing a string.
+        (WebCore::YouTubePluginReplacement::youTubeURL): Ditto.
+
+        * Modules/websockets/WebSocketHandshake.cpp:
+        (WebCore::hostName): Use convertToASCIILowercase on host name.
+        (WebCore::WebSocketHandshake::host): Ditto.
+
+        * accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
+        (webkitAccessibleGetAttributes): Call convertToASCIILowercase instead of lower
+        to lowercase an element's tag name. This is a strange way to do things; typically
+        would be better to use some other function on Element, since tagName goes out of
+        its way to be capitalized, but some ATK expert can improve this later.
+
+        * css/CSSGrammar.y.in: Use the new convertToASCIILowercaseInPlace function rather
+        than the old lower function. We only need to lowercase the ASCII letters, and it's
+        also better to have the function have a clearer name.
+
+        * css/CSSParser.cpp:
+        (WebCore::convertToASCIILowercaseInPlace): Renamed from makeLower and made it deal
+        with only ASCII lowercasing.
+        (WebCore::CSSParserString::convertToASCIILowercaseInPlace): Renamed from lower.
+        (WebCore::isUniversalKeyword): Added. Helper for the function below that uses
+        equalLettersIgnoringASCIICase rather than lowercasing the string.
+        (WebCore::parseKeywordValue): Use isUniversalKeyword. Also clarified a comment.
+        (WebCore::CSSParser::parseAttr): Use convertToASCIILowercaseInPlace and delay
+        String creation until later in the function, using CSSParserString operations more.
+
+        * css/CSSParserValues.cpp:
+        (WebCore::CSSParserSelector::parsePseudoElementSelector): Use
+        convertToASCIILowercaseInPlace by its new name, with its new behavior.
+
+        * css/CSSParserValues.h: Tweaked comment and formatting a bit. Replaced the lower
+        function with the convertToASCIILowercaseInPlace function.
+
+        * css/CSSSelector.cpp:
+        (WebCore::CSSSelector::RareData::parseNth): Rewrote this to avoid the need to
+        make a lowercased copy of m_argument. Use equalLettersIgnoringASCIICase, and two
+        calls to find. Also use String::toIntStrict so we don't have to create String
+        objects for substrings.
+
+        * css/MediaQuery.cpp:
+        (WebCore::MediaQuery::MediaQuery): Use convertToASCIILowercase for media type name.
+        * css/MediaQueryExp.cpp:
+        (WebCore::MediaQueryExp::serialize): Use convertToASCIILowercase for media feature name.
+
+        * dom/Document.cpp:
+        (WebCore::isSeparator): Tweaked formatting and removed non-helpful comment.
+        (WebCore::processArguments): Changed this from a static member function to a non-member
+        file internal function. Use a std::function instead of a function pointer with a void*
+        pointer. Rewrote algorithm to simplify it and use StringView instead of String for the
+        keys and values.
+        (WebCore::Document::processViewport): Use a lambda instead of a function pointer to
+        call setViewportFeature, so that function's interface is no longer dictated by
+        the exact type of the function pointer argument to processArguments.
+        (WebCore::Document::processFormatDetection): Use a lambda instead of the
+        setParserFeature function above; use equalLettersIgnoringASCIICase for both the
+        key and the value, since processArguments no longer lowercases the string.
+        (WebCore::Document::processArguments): Deleted.
+
+        * dom/Document.h: Removed unnecessary declaration of processArguments and
+        ArgumentsCallback. Both are now private to the cpp file.
+
+        * dom/Element.cpp:
+        (WebCore::makeIdForStyleResolution): Use convertToASCIILowercase. When in quirks mode,
+        we want to match IDs in an ASCII case-insensitive way not match compatibility caseless.
+
+        * dom/ScriptElement.cpp:
+        (WebCore::ScriptElement::isScriptTypeSupported): Remove the use of lower here since
+        the MIME type registry is now itself ASCII case-insensitive.
+
+        * dom/ViewportArguments.cpp:
+        (WebCore::numericPrefix): Changed to use StringView and take a Document&, rearranged
+        argument order so Document& comes first.
+        (WebCore::findSizeValue): Ditto.
+        (WebCore::findScaleValue): Ditto.
+        (WebCore::findBooleanValue): Ditto. Also use std::abs instead of fabs, possibly
+        avoiding a conversion from float to double (not sure it was happening before but it's
+        definitely not happening now).
+        (WebCore::setViewportFeature): Changed to put arguments in a more logical order, to take
+        the ViewportArguments as a reference, not a void*, and to use StringView to avoid forcing
+        the caller to allocate strings. Also changed to use equalLettersIgnoringASCIICase so we
+        don't rely on the caller to make the key lowercase for us.
+        (WebCore::reportViewportWarning): Changed argument types. Added a couple comments about
+        mistakes in the function.
+
+        * dom/ViewportArguments.h: Removed unnecessary declaration of reportViewportWarning,
+        which is now private to the cpp file. Updated for new arguments to setViewportFeature.
+
+        * editing/EditorCommand.cpp:
+        (WebCore::executeFormatBlock): Use convertToASCIILowercase on the argument, which is
+        specifying a tag name.
+
+        * fileapi/Blob.cpp:
+        (WebCore::Blob::isValidContentType): Removed unnecessary separate loops for
+        8-bit and 16-bit strings. Content types are short strings and this small optimization is
+        not worth the additional code complexity.
+        (WebCore::Blob::normalizedContentType): Use convertToASCIILowercase since valid
+        content types are guaranteed to be all ASCII.
+        (WebCore::Blob::isNormalizedContentType): Removed unnecessary separate loops for
+        8-bit and 16-bit strings. Content types are short strings and this small optimization is
+        not worth the additional code complexity.
+
+        * html/parser/HTMLParserIdioms.cpp: Added now-needed include of QualifiedName.h.
+
+        * html/parser/HTMLParserIdioms.h: Removed unneeded include of QualifiedName.h and
+        WTFString.h. Made sure every function is declared first, even if it's also defined
+        later in the header in the section for functions templates and inline functions.
+
+        * loader/archive/ArchiveFactory.cpp:
+        (WebCore::ArchiveFactory::registerKnownArchiveMIMETypes): Use auto& for the type of
+        the set of MIME types here, since it's now using ASCIICaseInsensitiveHash.
+
+        * platform/MIMETypeRegistry.cpp: Changed the MIME type sets to use
+        ASCIICaseInsensitiveHash since MIME type are not case sensitive.
+        (WebCore::initializeSupportedImageMIMETypes): Use a modern for loop.
+        (WebCore::initializeSupportedImageMIMETypesForEncoding): Updated for HashSet type change.
+        (WebCore::initializePDFMIMETypes): Use a modern for loop.
+        (WebCore::initializeSupportedNonImageMimeTypes): Use a modern for loop.
+        (WebCore::initializeSupportedMediaMIMETypes): Updated for HashSet type change.
+        (WebCore::initializeUnsupportedTextMIMETypes): Use a modern for loop.
+        (WebCore::initializeMIMETypeRegistry): Updated for HashSet type change.
+        (WebCore::MIMETypeRegistry::getSupportedImageMIMETypes): Ditto.
+        (WebCore::MIMETypeRegistry::getSupportedImageResourceMIMETypes): Ditto.
+        (WebCore::MIMETypeRegistry::getSupportedImageMIMETypesForEncoding): Ditto.
+        (WebCore::MIMETypeRegistry::getSupportedNonImageMIMETypes): Ditto.
+        (WebCore::MIMETypeRegistry::getSupportedMediaMIMETypes): Ditto.
+        (WebCore::MIMETypeRegistry::getPDFMIMETypes): Ditto.
+        (WebCore::MIMETypeRegistry::getPDFAndPostScriptMIMETypes): Ditto.
+        (WebCore::MIMETypeRegistry::getUnsupportedTextMIMETypes): Ditto.
+        (WebCore::mimeTypeAssociationMap): Use ASCIICaseInsensitiveHash.
+        (WebCore::MIMETypeRegistry::getNormalizedMIMEType): Use auto to make code tighter.
+
+        * platform/MIMETypeRegistry.h: Changed return types of the getMIMETypes functions
+        to use ASCIICaseInsensitiveHash.
+
+        * platform/SchemeRegistry.cpp:
+        (WebCore::schemesForbiddenFromDomainRelaxation): Changed type to
+        use ASCIICaseInsensitiveHash.
+
+        * platform/URL.cpp:
+        (WebCore::mimeTypeFromDataURL): Use convertToASCIILowercase instead of lower.
+        Also removed some dead code that tried to handle the case where the data URL
+        has a comma as one of the first 5 characters: That can't happen since it's a
+        precondition of this function that the first five characters are "data:".
+
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::getSupportedTypes): Change type of argument to
+        a HashSet with ASCIICaseInsensitiveHash.
+        * platform/graphics/MediaPlayer.h: Ditto.
+
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::staticMIMETypeList):
+        Changed type of HashSet to use ASCIICaseInsensitiveHash.
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h: Ditto.
+
+        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:
+        (WebCore::avfMIMETypes):
+        Changed type of HashSet to use ASCIICaseInsensitiveHash.
+        (WebCore::MediaPlayerPrivateAVFoundationCF::getSupportedTypes): Ditto.
+        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h: Ditto.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        Changed type of HashSet to use ASCIICaseInsensitiveHash.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::paintWithImageGenerator): Removed
+        an unnecessary line of code to set a local variable to 0 just before it falls
+        out of scope.
+        (WebCore::avfMIMETypes): Ditto. Also tightened up the code a bit.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::getSupportedTypes): Ditto.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+        Changed type of HashSet to use ASCIICaseInsensitiveHash.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+        (WebCore::mimeTypeCache): Ditto.
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::getSupportedTypes): Ditto.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h: Ditto.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::getSupportedTypes): Ditto.
+
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::mimeTypeCache): Ditto.
+        (WebCore::MediaPlayerPrivateGStreamer::getSupportedTypes): Ditto.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: Ditto.
+
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.h: Ditto.
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+        (WebCore::shouldRejectMIMEType): Made this non-case-sensitive by using startsWith
+        and the "false" argument. Later change this to startsWithIgnoringASCIICase or
+        startsWithLettersIgnoringASCIICase.
+        (WebCore::addFileTypesToCache): Use ASCIICaseInsensitiveHash. ALso rewrote to
+        tighten up the code a bit and use modern Objective-C for loops.
+        (WebCore::mimeCommonTypesCache): Use ASCIICaseInsensitiveHash.
+        (WebCore::mimeModernTypesCache): Ditto.
+        (WebCore::concatenateHashSets): Ditto.
+        (WebCore::MediaPlayerPrivateQTKit::getSupportedTypes): Ditto.
+        (WebCore::MediaPlayerPrivateQTKit::disableUnsupportedTracks): Initialied
+        track type set using lambda, but left it case sensitive.
+
+        * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp:
+        (WebCore::mimeTypeCache): Changed type of HashSet to use ASCIICaseInsensitiveHash.
+        (WebCore::MediaPlayerPrivateMediaFoundation::getSupportedTypes): Ditto.
+        * platform/graphics/win/MediaPlayerPrivateMediaFoundation.h:
+
+        * platform/mock/mediasource/MockMediaPlayerMediaSource.cpp:
+        (WebCore::mimeTypeCache): Ditto.
+        (WebCore::MockMediaPlayerMediaSource::getSupportedTypes): Ditto.
+        * platform/mock/mediasource/MockMediaPlayerMediaSource.h: Ditto.
+
 2016-01-31  Brent Fulgham  <bfulgham@apple.com>
 
         Add "WebKit built-in PDF" Plugin to set of publicly visible plugins
index 829d1fb..3c9105f 100644 (file)
@@ -732,6 +732,7 @@ bool MediaSource::isTypeSupported(const String& type)
     if (type.isNull() || type.isEmpty())
         return false;
 
+    // FIXME: Why do we convert to lowercase here, but not in MediaSource::addSourceBuffer?
     ContentType contentType(type.lower());
     String codecs = contentType.parameter("codecs");
 
index 3131caa..ffe022a 100644 (file)
 
 namespace WebCore {
 
-static HashSet<String>* protocolWhitelist;
-
-static void initProtocolHandlerWhitelist()
-{
-    protocolWhitelist = new HashSet<String>;
-    for (auto* protocol : { "bitcoin", "geo", "im", "irc", "ircs", "magnet", "mailto", "mms", "news", "nntp", "sip", "sms", "smsto", "ssh", "tel", "urn", "webcal", "wtai", "xmpp" })
-        protocolWhitelist->add(protocol);
-}
-
 static bool verifyCustomHandlerURL(const URL& baseURL, const String& url, ExceptionCode& ec)
 {
     // The specification requires that it is a SYNTAX_ERR if the "%s" token is
@@ -74,11 +65,15 @@ static bool verifyCustomHandlerURL(const URL& baseURL, const String& url, Except
     return true;
 }
 
-static bool isProtocolWhitelisted(const String& scheme)
+static inline bool isProtocolWhitelisted(const String& scheme)
 {
-    if (!protocolWhitelist)
-        initProtocolHandlerWhitelist();
-    return protocolWhitelist->contains(scheme.convertToASCIILowercase());
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> protocolWhitelist = []() {
+        HashSet<String, ASCIICaseInsensitiveHash> set;
+        for (auto* protocol : { "bitcoin", "geo", "im", "irc", "ircs", "magnet", "mailto", "mms", "news", "nntp", "sip", "sms", "smsto", "ssh", "tel", "urn", "webcal", "wtai", "xmpp" })
+            set.add(protocol);
+        return set;
+    }();
+    return protocolWhitelist.get().contains(scheme);
 }
 
 static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec)
@@ -86,6 +81,7 @@ static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec)
     if (isProtocolWhitelisted(scheme))
         return true;
 
+    // FIXME: Should this be case sensitive, or should it be ASCII case-insensitive?
     if (scheme.startsWith("web+")) {
         // The specification requires that the length of scheme is at least five characters (including 'web+' prefix).
         if (scheme.length() >= 5 && isValidProtocol(scheme))
index 5e14613..14fbc4c 100644 (file)
@@ -82,36 +82,36 @@ PassRefPtr<PluginReplacement> QuickTimePluginReplacement::create(HTMLPlugInEleme
 
 bool QuickTimePluginReplacement::supportsMimeType(const String& mimeType)
 {
-    static const char* types[] = {
-        "application/vnd.apple.mpegurl", "application/x-mpegurl", "audio/3gpp", "audio/3gpp2", "audio/aac", "audio/aiff",
-        "audio/amr", "audio/basic", "audio/mp3", "audio/mp4", "audio/mpeg", "audio/mpeg3", "audio/mpegurl", "audio/scpls",
-        "audio/wav", "audio/x-aac", "audio/x-aiff", "audio/x-caf", "audio/x-m4a", "audio/x-m4b", "audio/x-m4p",
-        "audio/x-m4r", "audio/x-mp3", "audio/x-mpeg", "audio/x-mpeg3", "audio/x-mpegurl", "audio/x-scpls", "audio/x-wav",
-        "video/3gpp", "video/3gpp2", "video/mp4", "video/quicktime", "video/x-m4v"
-    };
-    static NeverDestroyed<HashSet<String>> typeHash;
-    if (!typeHash.get().size()) {
-        for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i)
-            typeHash.get().add(types[i]);
-    }
-
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> typeHash = []() {
+        static const char* const types[] = {
+            "application/vnd.apple.mpegurl", "application/x-mpegurl", "audio/3gpp", "audio/3gpp2", "audio/aac", "audio/aiff",
+            "audio/amr", "audio/basic", "audio/mp3", "audio/mp4", "audio/mpeg", "audio/mpeg3", "audio/mpegurl", "audio/scpls",
+            "audio/wav", "audio/x-aac", "audio/x-aiff", "audio/x-caf", "audio/x-m4a", "audio/x-m4b", "audio/x-m4p",
+            "audio/x-m4r", "audio/x-mp3", "audio/x-mpeg", "audio/x-mpeg3", "audio/x-mpegurl", "audio/x-scpls", "audio/x-wav",
+            "video/3gpp", "video/3gpp2", "video/mp4", "video/quicktime", "video/x-m4v"
+        };
+        HashSet<String, ASCIICaseInsensitiveHash> set;
+        for (auto& type : types)
+            set.add(type);
+        return set;
+    }();
     return typeHash.get().contains(mimeType);
 }
 
 bool QuickTimePluginReplacement::supportsFileExtension(const String& extension)
 {
-    static const char* extensions[] = {
-        "3g2", "3gp", "3gp2", "3gpp", "aac", "adts", "aif", "aifc", "aiff", "AMR", "au", "bwf", "caf", "cdda", "m3u",
-        "m3u8", "m4a", "m4b", "m4p", "m4r", "m4v", "mov", "mp3", "mp3", "mp4", "mpeg", "mpg", "mqv", "pls", "qt",
-        "snd", "swa", "ts", "ulw", "wav"
-    };
-    static NeverDestroyed<HashSet<String>> extensionHash;
-    if (!extensionHash.get().size()) {
-        for (size_t i = 0; i < WTF_ARRAY_LENGTH(extensions); ++i)
-            extensionHash.get().add(extensions[i]);
-    }
-
-    return extensionHash.get().contains(extension);
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> extensionSet = []() {
+        static const char* const extensions[] = {
+            "3g2", "3gp", "3gp2", "3gpp", "aac", "adts", "aif", "aifc", "aiff", "AMR", "au", "bwf", "caf", "cdda", "m3u",
+            "m3u8", "m4a", "m4b", "m4p", "m4r", "m4v", "mov", "mp3", "mp3", "mp4", "mpeg", "mpg", "mqv", "pls", "qt",
+            "snd", "swa", "ts", "ulw", "wav"
+        };
+        HashSet<String, ASCIICaseInsensitiveHash> set;
+        for (auto& extension : extensions)
+            set.add(extension);
+        return set;
+    }();
+    return extensionSet.get().contains(extension);
 }
 
 QuickTimePluginReplacement::QuickTimePluginReplacement(HTMLPlugInElement& plugin, const Vector<String>& paramNames, const Vector<String>& paramValues)
index 9a68650..cae2111 100644 (file)
@@ -154,7 +154,7 @@ static YouTubePluginReplacement::KeyValueMap queryKeysAndValues(const String& qu
         
         // Save the key and the value.
         if (keyLength && valueLength) {
-            const String& key = queryString.substring(keyLocation, keyLength).lower();
+            String key = queryString.substring(keyLocation, keyLength).convertToASCIILowercase();
             String value = queryString.substring(valueLocation, valueLength);
             value.replace('+', ' ');
 
@@ -181,14 +181,13 @@ static bool hasCaseInsensitivePrefix(const String& input, const String& prefix)
     
 static bool isYouTubeURL(const URL& url)
 {
-    const String& hostName = url.host().lower();
-    
-    return hostName == "m.youtube.com"
-        || hostName == "youtu.be"
-        || hostName == "www.youtube.com"
-        || hostName == "youtube.com"
-        || hostName == "www.youtube-nocookie.com"
-        || hostName == "youtube-nocookie.com";
+    String hostName = url.host();
+    return equalLettersIgnoringASCIICase(hostName, "m.youtube.com")
+        || equalLettersIgnoringASCIICase(hostName, "youtu.be")
+        || equalLettersIgnoringASCIICase(hostName, "www.youtube.com")
+        || equalLettersIgnoringASCIICase(hostName, "youtube.com")
+        || equalLettersIgnoringASCIICase(hostName, "www.youtube-nocookie.com")
+        || equalLettersIgnoringASCIICase(hostName, "youtube-nocookie.com");
 }
 
 static const String& valueForKey(const YouTubePluginReplacement::KeyValueMap& dictionary, const String& key)
@@ -202,24 +201,22 @@ static const String& valueForKey(const YouTubePluginReplacement::KeyValueMap& di
 
 static URL processAndCreateYouTubeURL(const URL& url, bool& isYouTubeShortenedURL)
 {
-    if (!url.protocolIs("http") && !url.protocolIs("https"))
+    if (!url.protocolIsInHTTPFamily())
         return URL();
-    
+
     // Bail out early if we aren't even on www.youtube.com or youtube.com.
     if (!isYouTubeURL(url))
         return URL();
-    
-    const String& hostName = url.host().lower();
-    
-    bool isYouTubeMobileWebAppURL = hostName == "m.youtube.com";
-    isYouTubeShortenedURL = hostName == "youtu.be";
-    
+
+    String hostName = url.host();
+    bool isYouTubeMobileWebAppURL = equalLettersIgnoringASCIICase(hostName, "m.youtube.com");
+    isYouTubeShortenedURL = equalLettersIgnoringASCIICase(hostName, "youtu.be");
+
     // Short URL of the form: http://youtu.be/v1d301D
     if (isYouTubeShortenedURL) {
-        const String& videoID = url.lastPathComponent();
+        String videoID = url.lastPathComponent();
         if (videoID.isEmpty() || videoID == "/")
             return URL();
-        
         return createYouTubeURL(videoID, emptyString());
     }
     
@@ -241,7 +238,7 @@ static URL processAndCreateYouTubeURL(const URL& url, bool& isYouTubeShortenedUR
         fragment = emptyString();
     }
     
-    if (path.lower() == "/watch") {
+    if (equalLettersIgnoringASCIICase(path, "/watch")) {
         if (!query.isEmpty()) {
             const auto& queryDictionary = queryKeysAndValues(query);
             String videoID = valueForKey(queryDictionary, "v");
@@ -303,8 +300,9 @@ String YouTubePluginReplacement::youTubeURL(const String& srcString)
     
         // From the original URL, we need to get the part before /path/VideoId.
         locationOfPathBeforeVideoID = srcString.find(srcPath.substring(0, locationOfVideoIDInPath));
-    } else if (srcPath.lower() == "/watch") {
+    } else if (equalLettersIgnoringASCIICase(srcPath, "/watch")) {
         // From the original URL, we need to get the part before /watch/#!v=VideoID
+        // FIXME: Shouldn't this be ASCII case-insensitive?
         locationOfPathBeforeVideoID = srcString.find("/watch");
     } else
         return srcString;
index f19de94..d6a5bd9 100644 (file)
@@ -81,7 +81,7 @@ static String hostName(const URL& url, bool secure)
 {
     ASSERT(url.protocolIs("wss") == secure);
     StringBuilder builder;
-    builder.append(url.host().lower());
+    builder.append(url.host().convertToASCIILowercase());
     if (url.port() && ((!secure && url.port() != 80) || (secure && url.port() != 443))) {
         builder.append(':');
         builder.appendNumber(url.port());
@@ -143,9 +143,10 @@ void WebSocketHandshake::setURL(const URL& url)
     m_url = url.isolatedCopy();
 }
 
+// FIXME: Return type should just be String, not const String.
 const String WebSocketHandshake::host() const
 {
-    return m_url.host().lower();
+    return m_url.host().convertToASCIILowercase();
 }
 
 const String& WebSocketHandshake::clientProtocol() const
index 66c93b1..75fc9e3 100644 (file)
@@ -410,7 +410,7 @@ static AtkAttributeSet* webkitAccessibleGetAttributes(AtkObject* object)
     if (element) {
         String tagName = element->tagName();
         if (!tagName.isEmpty())
-            attributeSet = addToAtkAttributeSet(attributeSet, "tag", tagName.lower().utf8().data());
+            attributeSet = addToAtkAttributeSet(attributeSet, "tag", tagName.convertToASCIILowercase().utf8().data());
         String id = element->getIdAttribute().string();
         if (!id.isEmpty())
             attributeSet = addToAtkAttributeSet(attributeSet, "html-id", id.utf8().data());
index 8bbb420..8cc70be 100644 (file)
@@ -589,7 +589,7 @@ source_size_length: unary_term | calc_function;
 
 base_media_query_exp: '(' maybe_space IDENT maybe_space maybe_media_value ')' {
         std::unique_ptr<CSSParserValueList> mediaValue($5);
-        $3.lower();
+        $3.convertToASCIILowercaseInPlace();
         $$ = new MediaQueryExp($3, mediaValue.get());
     }
     ;
@@ -644,7 +644,7 @@ media_query:
     }
     |
     maybe_media_restrictor maybe_space IDENT maybe_space maybe_and_media_query_exp_list {
-        $3.lower();
+        $3.convertToASCIILowercaseInPlace();
         $$ = new MediaQuery($1, $3, std::unique_ptr<Vector<std::unique_ptr<MediaQueryExp>>>($5));
     }
     ;
@@ -1234,7 +1234,7 @@ specifier:
         $$ = new CSSParserSelector;
         $$->setMatch(CSSSelector::Id);
         if (parser->m_context.mode == CSSQuirksMode)
-            $1.lower();
+            $1.convertToASCIILowercaseInPlace();
         $$->setValue($1);
     }
   | HEX {
@@ -1244,7 +1244,7 @@ specifier:
             $$ = new CSSParserSelector;
             $$->setMatch(CSSSelector::Id);
             if (parser->m_context.mode == CSSQuirksMode)
-                $1.lower();
+                $1.convertToASCIILowercaseInPlace();
             $$->setValue($1);
         }
     }
@@ -1258,7 +1258,7 @@ class:
         $$ = new CSSParserSelector;
         $$->setMatch(CSSSelector::Class);
         if (parser->m_context.mode == CSSQuirksMode)
-            $2.lower();
+            $2.convertToASCIILowercaseInPlace();
         $$->setValue($2);
     }
   ;
index daeb1d1..1bf3197 100644 (file)
@@ -340,34 +340,18 @@ CSSParser::~CSSParser()
     clearProperties();
 }
 
-template <typename CharacterType>
-ALWAYS_INLINE static void makeLower(const CharacterType* input, CharacterType* output, unsigned length)
+template<typename CharacterType> ALWAYS_INLINE static void convertToASCIILowercaseInPlace(CharacterType* characters, unsigned length)
 {
-    // FIXME: If we need Unicode lowercasing here, then we probably want the real kind
-    // that can potentially change the length of the string rather than the character
-    // by character kind. If we don't need Unicode lowercasing, it would be good to
-    // simplify this function.
-
-    if (charactersAreAllASCII(input, length)) {
-        // Fast case for all-ASCII.
-        for (unsigned i = 0; i < length; ++i)
-            output[i] = toASCIILower(input[i]);
-    } else {
-        for (unsigned i = 0; i < length; ++i) {
-            ASSERT(u_tolower(input[i]) <= 0xFFFF);
-            output[i] = u_tolower(input[i]);
-        }
-    }
+    for (unsigned i = 0; i < length; ++i)
+        characters[i] = toASCIILower(characters[i]);
 }
 
-void CSSParserString::lower()
+void CSSParserString::convertToASCIILowercaseInPlace()
 {
-    if (is8Bit()) {
-        makeLower(characters8(), characters8(), length());
-        return;
-    }
-
-    makeLower(characters16(), characters16(), length());
+    if (is8Bit())
+        WebCore::convertToASCIILowercaseInPlace(characters8(), length());
+    else
+        WebCore::convertToASCIILowercaseInPlace(characters16(), length());
 }
 
 void CSSParser::setupParser(const char* prefix, unsigned prefixLength, StringView string, const char* suffix, unsigned suffixLength)
@@ -1198,17 +1182,24 @@ static inline bool isKeywordPropertyID(CSSPropertyID propertyId)
     }
 }
 
+static bool isUniversalKeyword(const String& string)
+{
+    // These keywords can be used for all properties.
+    return equalLettersIgnoringASCIICase(string, "initial")
+        || equalLettersIgnoringASCIICase(string, "inherit")
+        || equalLettersIgnoringASCIICase(string, "unset")
+        || equalLettersIgnoringASCIICase(string, "revert");
+}
+
 static CSSParser::ParseResult parseKeywordValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String& string, bool important, const CSSParserContext& parserContext, StyleSheetContents* styleSheetContents)
 {
     ASSERT(!string.isEmpty());
 
     if (!isKeywordPropertyID(propertyId)) {
-        // All properties accept the values of "initial" and "inherit".
-        String lowerCaseString = string.lower();
-        if (lowerCaseString != "initial" && lowerCaseString != "inherit" && lowerCaseString != "unset" && lowerCaseString != "revert")
+        if (!isUniversalKeyword(string))
             return CSSParser::ParseResult::Error;
 
-        // Parse initial/inherit/unset/revert shorthands using the CSSParser.
+        // Don't try to parse initial/inherit/unset/revert shorthands; return an error so the caller will use the full CSS parser.
         if (shorthandForProperty(propertyId).length())
             return CSSParser::ParseResult::Error;
     }
@@ -4342,17 +4333,19 @@ RefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList& args)
     if (argument.unit != CSSPrimitiveValue::CSS_IDENT)
         return nullptr;
 
-    String attrName = argument.string;
+    ASSERT(argument.string.length());
+
     // CSS allows identifiers with "-" at the start, like "-webkit-mask-image".
     // But HTML attribute names can't have those characters, and we should not
     // even parse them inside attr().
-    if (attrName[0] == '-')
+    if (argument.string[0] == '-')
         return nullptr;
 
     if (m_context.isHTMLDocument)
-        attrName = attrName.lower();
+        argument.string.convertToASCIILowercaseInPlace();
 
-    return CSSValuePool::singleton().createValue(attrName, CSSPrimitiveValue::CSS_ATTR);
+    // FIXME: Is there some small benefit to creating an AtomicString here instead of a String?
+    return CSSValuePool::singleton().createValue(String(argument.string), CSSPrimitiveValue::CSS_ATTR);
 }
 
 RefPtr<CSSValue> CSSParser::parseBackgroundColor()
index e8f20e6..db7540e 100644 (file)
@@ -199,7 +199,7 @@ CSSParserSelector* CSSParserSelector::parsePagePseudoSelector(const CSSParserStr
 
 CSSParserSelector* CSSParserSelector::parsePseudoElementSelector(CSSParserString& pseudoTypeString)
 {
-    pseudoTypeString.lower();
+    pseudoTypeString.convertToASCIILowercaseInPlace();
     AtomicString name = pseudoTypeString;
 
     CSSSelector::PseudoElementType pseudoType = CSSSelector::parsePseudoElementType(name);
index 4845a24..77a5b19 100644 (file)
@@ -33,9 +33,7 @@ namespace WebCore {
 class CSSValue;
 class QualifiedName;
 
-// This can't be a StringView for 2 reasons:
-// 1. lower() clobbers the data we point to.
-// 2. We are an element of a union (in CSSParserValue) so we need to have a trivial destructor.
+// This should be a StringView but currently it can't because it's used as an element of a union in CSSParserValue.
 struct CSSParserString {
     void init(LChar* characters, unsigned length)
     {
@@ -73,13 +71,12 @@ struct CSSParserString {
     bool is8Bit() const { return m_is8Bit; }
     LChar* characters8() const { ASSERT(is8Bit()); return m_data.characters8; }
     UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; }
-    template <typename CharacterType>
-    CharacterType* characters() const;
+    template<typename CharacterType> CharacterType* characters() const;
 
     unsigned length() const { return m_length; }
     void setLength(unsigned length) { m_length = length; }
 
-    void lower();
+    void convertToASCIILowercaseInPlace();
 
     UChar operator[](unsigned i) const
     {
index bb3398c..6cde1ac 100644 (file)
@@ -805,28 +805,27 @@ CSSSelector::RareData::~RareData()
 // a helper function for parsing nth-arguments
 bool CSSSelector::RareData::parseNth()
 {
-    String argument = m_argument.lower();
-
-    if (argument.isEmpty())
+    if (m_argument.isEmpty())
         return false;
 
-    m_a = 0;
-    m_b = 0;
-    if (argument == "odd") {
+    if (equalLettersIgnoringASCIICase(m_argument, "odd")) {
         m_a = 2;
         m_b = 1;
-    } else if (argument == "even") {
+    } else if (equalLettersIgnoringASCIICase(m_argument, "even")) {
         m_a = 2;
         m_b = 0;
     } else {
-        size_t n = argument.find('n');
+        m_a = 0;
+        m_b = 0;
+
+        size_t n = std::min(m_argument.find('n'), m_argument.find('N'));
         if (n != notFound) {
-            if (argument[0] == '-') {
+            if (m_argument[0] == '-') {
                 if (n == 1)
                     m_a = -1; // -n == -1n
                 else {
                     bool ok;
-                    m_a = argument.substringSharingImpl(0, n).toIntStrict(&ok);
+                    m_a = StringView(m_argument).substring(0, n).toIntStrict(ok);
                     if (!ok)
                         return false;
                 }
@@ -834,29 +833,29 @@ bool CSSSelector::RareData::parseNth()
                 m_a = 1; // n == 1n
             else {
                 bool ok;
-                m_a = argument.substringSharingImpl(0, n).toIntStrict(&ok);
+                m_a = StringView(m_argument).substring(0, n).toIntStrict(ok);
                 if (!ok)
                     return false;
             }
 
-            size_t p = argument.find('+', n);
+            size_t p = m_argument.find('+', n);
             if (p != notFound) {
                 bool ok;
-                m_b = argument.substringSharingImpl(p + 1, argument.length() - p - 1).toIntStrict(&ok);
+                m_b = StringView(m_argument).substring(p + 1).toIntStrict(ok);
                 if (!ok)
                     return false;
             } else {
-                p = argument.find('-', n);
+                p = m_argument.find('-', n);
                 if (p != notFound) {
                     bool ok;
-                    m_b = -argument.substringSharingImpl(p + 1, argument.length() - p - 1).toIntStrict(&ok);
+                    m_b = -StringView(m_argument).substring(p + 1).toIntStrict(ok);
                     if (!ok)
                         return false;
                 }
             }
         } else {
             bool ok;
-            m_b = argument.toIntStrict(&ok);
+            m_b = m_argument.string().toIntStrict(&ok);
             if (!ok)
                 return false;
         }
index b46a97f..fc24bad 100644 (file)
@@ -74,7 +74,7 @@ String MediaQuery::serialize() const
 
 MediaQuery::MediaQuery(Restrictor r, const String& mediaType, std::unique_ptr<ExpressionVector> exprs)
     : m_restrictor(r)
-    , m_mediaType(mediaType.lower())
+    , m_mediaType(mediaType.convertToASCIILowercase())
     , m_expressions(WTFMove(exprs))
     , m_ignored(false)
 {
index 066258d..e63dff6 100644 (file)
@@ -232,7 +232,7 @@ String MediaQueryExp::serialize() const
 
     StringBuilder result;
     result.append('(');
-    result.append(m_mediaFeature.lower());
+    result.append(m_mediaFeature.convertToASCIILowercase());
     if (m_value) {
         result.appendLiteral(": ");
         result.append(m_value->cssText());
index eb50e82..11591d7 100644 (file)
@@ -3278,59 +3278,40 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
     }
 }
 
-// Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
-static bool isSeparator(UChar c)
+static bool isSeparator(UChar character)
 {
-    return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
+    return character == ' ' || character == '\t' || character == '\n' || character == '\r' || character == '=' || character == ',';
 }
 
-void Document::processArguments(const String& features, void* data, ArgumentsCallback callback)
+static void processArguments(StringView features, std::function<void(StringView type, StringView value)> callback)
 {
-    // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
-    unsigned keyBegin, keyEnd;
-    unsigned valueBegin, valueEnd;
-
-    String buffer = features.lower();
-    unsigned length = buffer.length();
+    unsigned length = features.length();
     for (unsigned i = 0; i < length; ) {
-        // skip to first non-separator, but don't skip past the end of the string
-        while (isSeparator(buffer[i])) {
-            if (i >= length)
-                break;
-            i++;
-        }
-        keyBegin = i;
+        // skip to first non-separator
+        while (i < length && isSeparator(features[i]))
+            ++i;
+        unsigned keyBegin = i;
 
         // skip to first separator
-        while (!isSeparator(buffer[i]))
+        while (i < length && !isSeparator(features[i]))
             i++;
-        keyEnd = i;
+        unsigned keyEnd = i;
 
-        // skip to first '=', but don't skip past a ',' or the end of the string
-        while (buffer[i] != '=') {
-            if (buffer[i] == ',' || i >= length)
-                break;
-            i++;
-        }
+        // skip to first '=', but don't skip past a ','
+        while (i < length && features[i] != '=' && features[i] != ',')
+            ++i;
 
-        // skip to first non-separator, but don't skip past a ',' or the end of the string
-        while (isSeparator(buffer[i])) {
-            if (buffer[i] == ',' || i >= length)
-                break;
-            i++;
-        }
-        valueBegin = i;
+        // skip to first non-separator, but don't skip past a ','
+        while (i < length && isSeparator(features[i]) && features[i] != ',')
+            ++i;
+        unsigned valueBegin = i;
 
         // skip to first separator
-        while (!isSeparator(buffer[i]))
-            i++;
-        valueEnd = i;
-
-        ASSERT_WITH_SECURITY_IMPLICATION(i <= length);
+        while (i < length && !isSeparator(features[i]))
+            ++i;
+        unsigned valueEnd = i;
 
-        String keyString = buffer.substring(keyBegin, keyEnd - keyBegin);
-        String valueString = buffer.substring(valueBegin, valueEnd - valueBegin);
-        callback(keyString, valueString, this, data);
+        callback(features.substring(keyBegin, keyEnd - keyBegin), features.substring(valueBegin, valueEnd - valueBegin));
     }
 }
 
@@ -3342,7 +3323,10 @@ void Document::processViewport(const String& features, ViewportArguments::Type o
         return;
 
     m_viewportArguments = ViewportArguments(origin);
-    processArguments(features, (void*)&m_viewportArguments, setViewportFeature);
+
+    processArguments(features, [this](StringView key, StringView value) {
+        setViewportFeature(m_viewportArguments, *this, key, value);
+    });
 
     updateViewportArguments();
 }
@@ -3362,17 +3346,13 @@ void Document::updateViewportArguments()
 
 #if PLATFORM(IOS)
 
-// FIXME: Find a better place for this functionality.
-void setParserFeature(const String& key, const String& value, Document* document, void*)
-{
-    if (key == "telephone" && equalLettersIgnoringASCIICase(value, "no"))
-        document->setIsTelephoneNumberParsingAllowed(false);
-}
-
 void Document::processFormatDetection(const String& features)
 {
-    ASSERT(!features.isNull());
-    processArguments(features, nullptr, setParserFeature);
+    // FIXME: Find a better place for this function.
+    processArguments(features, [this](StringView key, StringView value) {
+        if (equalLettersIgnoringASCIICase(key, "telephone") && equalLettersIgnoringASCIICase(value, "no"))
+            setIsTelephoneNumberParsingAllowed(false);
+    });
 }
 
 void Document::processWebAppOrientations()
index ee5ce6c..cb62fe8 100644 (file)
@@ -1344,9 +1344,6 @@ private:
     void createRenderTree();
     void detachParser();
 
-    typedef void (*ArgumentsCallback)(const String& keyString, const String& valueString, Document*, void* data);
-    void processArguments(const String& features, void* data, ArgumentsCallback);
-
     // FontSelectorClient
     virtual void fontsNeedUpdate(FontSelector&) override final;
 
index f5c77a9..2a31099 100644 (file)
@@ -1201,7 +1201,7 @@ inline void Element::setAttributeInternal(unsigned index, const QualifiedName& n
 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
 {
     if (inQuirksMode)
-        return value.lower();
+        return value.convertToASCIILowercase();
     return value;
 }
 
index 3b1e547..5210281 100644 (file)
@@ -149,16 +149,20 @@ bool ScriptElement::isScriptTypeSupported(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.
-
     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))
+        if (language.isEmpty())
+            return true; // Assume text/javascript.
+        if (MIMETypeRegistry::isSupportedJavaScriptMIMEType("text/" + language))
+            return true;
+        if (isLegacySupportedJavaScriptLanguage(language))
             return true;
-    } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type)))
+        return false;
+    }
+    if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace()))
+        return true;
+    if (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))
         return true;
     return false;
 }
index 81cf79d..21ffa96 100644 (file)
@@ -286,28 +286,30 @@ void restrictScaleFactorToInitialScaleIfNotUserScalable(ViewportAttributes& resu
         result.maximumScale = result.minimumScale = result.initialScale;
 }
 
-static float numericPrefix(const String& keyString, const String& valueString, Document* document, bool* ok = nullptr)
+static void reportViewportWarning(Document&, ViewportErrorCode, StringView replacement1 = { }, StringView replacement2 = { });
+
+static float numericPrefix(Document& document, StringView key, StringView value, bool* ok = nullptr)
 {
     size_t parsedLength;
-    float value;
-    if (valueString.is8Bit())
-        value = charactersToFloat(valueString.characters8(), valueString.length(), parsedLength);
+    float numericValue;
+    if (value.is8Bit())
+        numericValue = charactersToFloat(value.characters8(), value.length(), parsedLength);
     else
-        value = charactersToFloat(valueString.characters16(), valueString.length(), parsedLength);
+        numericValue = charactersToFloat(value.characters16(), value.length(), parsedLength);
     if (!parsedLength) {
-        reportViewportWarning(document, UnrecognizedViewportArgumentValueError, valueString, keyString);
+        reportViewportWarning(document, UnrecognizedViewportArgumentValueError, value, key);
         if (ok)
             *ok = false;
         return 0;
     }
-    if (parsedLength < valueString.length())
-        reportViewportWarning(document, TruncatedViewportArgumentValueError, valueString, keyString);
+    if (parsedLength < value.length())
+        reportViewportWarning(document, TruncatedViewportArgumentValueError, value, key);
     if (ok)
         *ok = true;
-    return value;
+    return numericValue;
 }
 
-static float findSizeValue(const String& keyString, const String& valueString, Document* document, bool* valueWasExplicit = nullptr)
+static float findSizeValue(Document& document, StringView key, StringView value, bool* valueWasExplicit = nullptr)
 {
     // 1) Non-negative number values are translated to px lengths.
     // 2) Negative number values are translated to auto.
@@ -317,13 +319,13 @@ static float findSizeValue(const String& keyString, const String& valueString, D
     if (valueWasExplicit)
         *valueWasExplicit = true;
 
-    if (equalLettersIgnoringASCIICase(valueString, "device-width"))
+    if (equalLettersIgnoringASCIICase(value, "device-width"))
         return ViewportArguments::ValueDeviceWidth;
 
-    if (equalLettersIgnoringASCIICase(valueString, "device-height"))
+    if (equalLettersIgnoringASCIICase(value, "device-height"))
         return ViewportArguments::ValueDeviceHeight;
 
-    float sizeValue = numericPrefix(keyString, valueString, document);
+    float sizeValue = numericPrefix(document, key, value);
 
     if (sizeValue < 0) {
         if (valueWasExplicit)
@@ -334,7 +336,7 @@ static float findSizeValue(const String& keyString, const String& valueString, D
     return sizeValue;
 }
 
-static float findScaleValue(const String& keyString, const String& valueString, Document* document)
+static float findScaleValue(Document& document, StringView key, StringView value)
 {
     // 1) Non-negative number values are translated to <number> values.
     // 2) Negative number values are translated to auto.
@@ -342,74 +344,68 @@ static float findScaleValue(const String& keyString, const String& valueString,
     // 4) device-width and device-height are translated to 10.0.
     // 5) no and unknown values are translated to 0.0
 
-    if (equalLettersIgnoringASCIICase(valueString, "yes"))
+    if (equalLettersIgnoringASCIICase(value, "yes"))
         return 1;
-    if (equalLettersIgnoringASCIICase(valueString, "no"))
+    if (equalLettersIgnoringASCIICase(value, "no"))
         return 0;
-    if (equalLettersIgnoringASCIICase(valueString, "device-width"))
+    if (equalLettersIgnoringASCIICase(value, "device-width"))
         return 10;
-    if (equalLettersIgnoringASCIICase(valueString, "device-height"))
+    if (equalLettersIgnoringASCIICase(value, "device-height"))
         return 10;
 
-    float value = numericPrefix(keyString, valueString, document);
+    float numericValue = numericPrefix(document, key, value);
 
-    if (value < 0)
+    if (numericValue < 0)
         return ViewportArguments::ValueAuto;
 
-    if (value > 10.0)
-        reportViewportWarning(document, MaximumScaleTooLargeError, String(), String());
+    if (numericValue > 10.0)
+        reportViewportWarning(document, MaximumScaleTooLargeError);
 
-    return value;
+    return numericValue;
 }
 
-static float findBooleanValue(const String& keyString, const String& valueString, Document* document)
+// FIXME: It's kind of bizarre to use floating point values of 1 and 0 to represent true and false.
+static float findBooleanValue(Document& document, StringView key, StringView value)
 {
     // yes and no are used as keywords.
     // Numbers >= 1, numbers <= -1, device-width and device-height are mapped to yes.
     // Numbers in the range <-1, 1>, and unknown values, are mapped to no.
 
-    if (equalLettersIgnoringASCIICase(valueString, "yes"))
+    if (equalLettersIgnoringASCIICase(value, "yes"))
         return 1;
-    if (equalLettersIgnoringASCIICase(valueString, "no"))
+    if (equalLettersIgnoringASCIICase(value, "no"))
         return 0;
-    if (equalLettersIgnoringASCIICase(valueString, "device-width"))
+    if (equalLettersIgnoringASCIICase(value, "device-width"))
         return 1;
-    if (equalLettersIgnoringASCIICase(valueString, "device-height"))
+    if (equalLettersIgnoringASCIICase(value, "device-height"))
         return 1;
-
-    float value = numericPrefix(keyString, valueString, document);
-
-    if (fabs(value) < 1)
-        return 0;
-
-    return 1;
+    return std::abs(numericPrefix(document, key, value)) >= 1 ? 1 : 0;
 }
 
-void setViewportFeature(const String& keyString, const String& valueString, Document* document, void* data)
+void setViewportFeature(ViewportArguments& arguments, Document& document, StringView key, StringView value)
 {
-    ViewportArguments* arguments = static_cast<ViewportArguments*>(data);
-
-    if (keyString == "width")
-        arguments->width = findSizeValue(keyString, valueString, document, &arguments->widthWasExplicit);
-    else if (keyString == "height")
-        arguments->height = findSizeValue(keyString, valueString, document);
-    else if (keyString == "initial-scale")
-        arguments->zoom = findScaleValue(keyString, valueString, document);
-    else if (keyString == "minimum-scale")
-        arguments->minZoom = findScaleValue(keyString, valueString, document);
-    else if (keyString == "maximum-scale")
-        arguments->maxZoom = findScaleValue(keyString, valueString, document);
-    else if (keyString == "user-scalable")
-        arguments->userZoom = findBooleanValue(keyString, valueString, document);
+    if (equalLettersIgnoringASCIICase(key, "width"))
+        arguments.width = findSizeValue(document, key, value, &arguments.widthWasExplicit);
+    else if (equalLettersIgnoringASCIICase(key, "height"))
+        arguments.height = findSizeValue(document, key, value);
+    else if (equalLettersIgnoringASCIICase(key, "initial-scale"))
+        arguments.zoom = findScaleValue(document, key, value);
+    else if (equalLettersIgnoringASCIICase(key, "minimum-scale"))
+        arguments.minZoom = findScaleValue(document, key, value);
+    else if (equalLettersIgnoringASCIICase(key, "maximum-scale"))
+        arguments.maxZoom = findScaleValue(document, key, value);
+    else if (equalLettersIgnoringASCIICase(key, "user-scalable"))
+        arguments.userZoom = findBooleanValue(document, key, value);
 #if PLATFORM(IOS)
-    else if (keyString == "minimal-ui")
-        // FIXME: Ignore silently for now. This should eventually fall back to the warning.
-        { }
+    else if (equalLettersIgnoringASCIICase(key, "minimal-ui")) {
+        // FIXME: Ignore silently for now. This code should eventually be removed
+        // so we start giving the warning in the web inspector as for other unimplemented keys.
+    }
 #endif
-    else if (keyString == "shrink-to-fit")
-        arguments->shrinkToFit = findBooleanValue(keyString, valueString, document);
+    else if (equalLettersIgnoringASCIICase(key, "shrink-to-fit"))
+        arguments.shrinkToFit = findBooleanValue(document, key, value);
     else
-        reportViewportWarning(document, UnrecognizedViewportArgumentKeyError, keyString, String());
+        reportViewportWarning(document, UnrecognizedViewportArgumentKeyError, key);
 }
 
 static const char* viewportErrorMessageTemplate(ViewportErrorCode errorCode)
@@ -439,23 +435,24 @@ static MessageLevel viewportErrorMessageLevel(ViewportErrorCode errorCode)
     return MessageLevel::Error;
 }
 
-void reportViewportWarning(Document* document, ViewportErrorCode errorCode, const String& replacement1, const String& replacement2)
+void reportViewportWarning(Document& document, ViewportErrorCode errorCode, StringView replacement1, StringView replacement2)
 {
-    Frame* frame = document->frame();
-    if (!frame)
+    // FIXME: Why is this null check needed? Can't addConsoleMessage deal with this?
+    if (!document.frame())
         return;
 
     String message = viewportErrorMessageTemplate(errorCode);
     if (!replacement1.isNull())
-        message.replace("%replacement1", replacement1);
+        message.replace("%replacement1", replacement1.toStringWithoutCopying());
+    // FIXME: This will do the wrong thing if replacement1 contains the substring "%replacement2".
     if (!replacement2.isNull())
-        message.replace("%replacement2", replacement2);
+        message.replace("%replacement2", replacement2.toStringWithoutCopying());
 
-    if ((errorCode == UnrecognizedViewportArgumentValueError || errorCode == TruncatedViewportArgumentValueError) && replacement1.find(';') != WTF::notFound)
+    if ((errorCode == UnrecognizedViewportArgumentValueError || errorCode == TruncatedViewportArgumentValueError) && replacement1.contains(';'))
         message.append(" Note that ';' is not a separator in viewport values. The list should be comma-separated.");
 
     // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
-    document->addConsoleMessage(MessageSource::Rendering, viewportErrorMessageLevel(errorCode), message);
+    document.addConsoleMessage(MessageSource::Rendering, viewportErrorMessageLevel(errorCode), message);
 }
 
 TextStream& operator<<(TextStream& ts, const ViewportArguments& viewportArguments)
index edd9f86..6ce004a 100644 (file)
@@ -134,8 +134,7 @@ WEBCORE_EXPORT void restrictMinimumScaleFactorToViewportSize(ViewportAttributes&
 WEBCORE_EXPORT void restrictScaleFactorToInitialScaleIfNotUserScalable(ViewportAttributes& result);
 float computeMinimumScaleFactorForContentContained(const ViewportAttributes& result, const IntSize& viewportSize, const IntSize& contentSize);
 
-void setViewportFeature(const String& keyString, const String& valueString, Document*, void* data);
-void reportViewportWarning(Document*, ViewportErrorCode, const String& replacement1, const String& replacement2);
+void setViewportFeature(ViewportArguments&, Document&, StringView key, StringView value);
 
 TextStream& operator<<(TextStream&, const ViewportArguments&);
 
index 79e52b5..8871151 100644 (file)
@@ -411,7 +411,7 @@ static bool executeForeColor(Frame& frame, Event*, EditorCommandSource source, c
 
 static bool executeFormatBlock(Frame& frame, Event*, EditorCommandSource, const String& value)
 {
-    String tagName = value.lower();
+    String tagName = value.convertToASCIILowercase();
     if (tagName[0] == '<' && tagName[tagName.length() - 1] == '>')
         tagName = tagName.substring(1, tagName.length() - 2);
 
index 2fe5107..99488eb 100644 (file)
@@ -96,7 +96,7 @@ Blob::Blob(Vector<BlobPart> blobParts, const String& contentType)
 }
 
 Blob::Blob(DeserializationContructor, const URL& srcURL, const String& type, long long size)
-    : m_type(Blob::normalizedContentType(type))
+    : m_type(normalizedContentType(type))
     , m_size(size)
 {
     m_internalURL = BlobURL::createInternalURL();
@@ -104,7 +104,7 @@ Blob::Blob(DeserializationContructor, const URL& srcURL, const String& type, lon
 }
 
 Blob::Blob(const URL& srcURL, long long start, long long end, const String& type)
-    : m_type(Blob::normalizedContentType(type))
+    : m_type(normalizedContentType(type))
     , m_size(-1) // size is not necessarily equal to end - start.
 {
     m_internalURL = BlobURL::createInternalURL();
@@ -122,7 +122,7 @@ unsigned long long Blob::size() const
         // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to
         // come up with an exception to throw if file size is not representable.
         unsigned long long actualSize = ThreadableBlobRegistry::blobSize(m_internalURL);
-        m_size = (WTF::isInBounds<long long>(actualSize)) ? static_cast<long long>(actualSize) : 0;
+        m_size = WTF::isInBounds<long long>(actualSize) ? static_cast<long long>(actualSize) : 0;
     }
 
     return static_cast<unsigned long long>(m_size);
@@ -130,61 +130,38 @@ unsigned long long Blob::size() const
 
 bool Blob::isValidContentType(const String& contentType)
 {
-    if (contentType.isNull())
-        return true;
-
-    size_t length = contentType.length();
-    if (contentType.is8Bit()) {
-        const LChar* characters = contentType.characters8();
-        for (size_t i = 0; i < length; ++i) {
-            if (characters[i] < 0x20 || characters[i] > 0x7e)
-                return false;
-        }
-    } else {
-        const UChar* characters = contentType.characters16();
-        for (size_t i = 0; i < length; ++i) {
-            if (characters[i] < 0x20 || characters[i] > 0x7e)
-                return false;
-        }
+    // FIXME: Do we really want to treat the empty string and null string as valid content types?
+    unsigned length = contentType.length();
+    for (unsigned i = 0; i < length; ++i) {
+        if (contentType[i] < 0x20 || contentType[i] > 0x7e)
+            return false;
     }
     return true;
 }
 
 String Blob::normalizedContentType(const String& contentType)
 {
-    if (Blob::isValidContentType(contentType))
-        return contentType.lower();
-    return emptyString();
+    if (!isValidContentType(contentType))
+        return emptyString();
+    return contentType.convertToASCIILowercase();
 }
 
 bool Blob::isNormalizedContentType(const String& contentType)
 {
-    if (contentType.isNull())
-        return true;
-
-    size_t length = contentType.length();
-    if (contentType.is8Bit()) {
-        const LChar* characters = contentType.characters8();
-        for (size_t i = 0; i < length; ++i) {
-            if (characters[i] < 0x20 || characters[i] > 0x7e)
-                return false;
-            if (isASCIIUpper(characters[i]))
-                return false;
-        }
-    } else {
-        const UChar* characters = contentType.characters16();
-        for (size_t i = 0; i < length; ++i) {
-            if (characters[i] < 0x20 || characters[i] > 0x7e)
-                return false;
-            if (isASCIIUpper(characters[i]))
-                return false;
-        }
+    // FIXME: Do we really want to treat the empty string and null string as valid content types?
+    unsigned length = contentType.length();
+    for (size_t i = 0; i < length; ++i) {
+        if (contentType[i] < 0x20 || contentType[i] > 0x7e)
+            return false;
+        if (isASCIIUpper(contentType[i]))
+            return false;
     }
     return true;
 }
 
 bool Blob::isNormalizedContentType(const CString& contentType)
 {
+    // FIXME: Do we really want to treat the empty string and null string as valid content types?
     size_t length = contentType.length();
     const char* characters = contentType.data();
     for (size_t i = 0; i < length; ++i) {
index 91a6606..635b266 100644 (file)
 #include "HTMLParserIdioms.h"
 
 #include "Decimal.h"
+#include "QualifiedName.h"
 #include "URL.h"
 #include <limits>
 #include <wtf/MathExtras.h>
-#include <wtf/text/AtomicString.h>
 #include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
index 248d7d0..9e87d09 100644 (file)
 #ifndef HTMLParserIdioms_h
 #define HTMLParserIdioms_h
 
-#include "QualifiedName.h"
+#include <unicode/uchar.h>
 #include <wtf/Forward.h>
-#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
 class Decimal;
+class QualifiedName;
 
 // Space characters as defined by the HTML specification.
+template<typename CharacterType> bool isHTMLSpace(CharacterType);
+template<typename CharacterType> bool isComma(CharacterType);
+template<typename CharacterType> bool isHTMLSpaceOrComma(CharacterType);
 bool isHTMLLineBreak(UChar);
 bool isNotHTMLSpace(UChar);
-bool isHTMLSpaceButNotLineBreak(UChar character);
+bool isHTMLSpaceButNotLineBreak(UChar);
 
 // Strip leading and trailing whitespace as defined by the HTML specification. 
 WEBCORE_EXPORT String stripLeadingAndTrailingHTMLSpaces(const String&);
@@ -59,9 +62,11 @@ bool parseHTMLInteger(const String&, int&);
 // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-non-negative-integers
 bool parseHTMLNonNegativeInteger(const String&, unsigned int&);
 
+bool threadSafeMatch(const QualifiedName&, const QualifiedName&);
+
 // Inline implementations of some of the functions declared above.
-template<typename CharType>
-inline bool isHTMLSpace(CharType character)
+
+template<typename CharacterType> inline bool isHTMLSpace(CharacterType character)
 {
     // Histogram from Apple's page load test combined with some ad hoc browsing some other test suites.
     //
@@ -81,16 +86,14 @@ inline bool isHTMLLineBreak(UChar character)
     return character <= '\r' && (character == '\n' || character == '\r');
 }
 
-template<typename CharType>
-inline bool isComma(CharType character)
+template<typename CharacterType> inline bool isComma(CharacterType character)
 {
     return character == ',';
 }
 
-template<typename CharType>
-inline bool isHTMLSpaceOrComma(CharType character)
+template<typename CharacterType> inline bool isHTMLSpaceOrComma(CharacterType character)
 {
-    return isComma(character) || isHTMLSpace<CharType>(character);
+    return isComma(character) || isHTMLSpace(character);
 }
 
 inline bool isNotHTMLSpace(UChar character)
@@ -103,8 +106,6 @@ inline bool isHTMLSpaceButNotLineBreak(UChar character)
     return isHTMLSpace(character) && !isHTMLLineBreak(character);
 }
 
-bool threadSafeMatch(const QualifiedName&, const QualifiedName&);
-
 }
 
 #endif
index 012401c..2672bd2 100644 (file)
@@ -91,9 +91,8 @@ PassRefPtr<Archive> ArchiveFactory::create(const URL& url, SharedBuffer* data, c
 
 void ArchiveFactory::registerKnownArchiveMIMETypes()
 {
-    HashSet<String>& mimeTypes = MIMETypeRegistry::getSupportedNonImageMIMETypes();
-    
-    for (const auto& mimeType : archiveMIMETypes().keys())
+    auto& mimeTypes = MIMETypeRegistry::getSupportedNonImageMIMETypes();
+    for (auto& mimeType : archiveMIMETypes().keys())
         mimeTypes.add(mimeType);
 }
 
index dcde693..3a34396 100644 (file)
@@ -140,15 +140,15 @@ static const TypeExtensionPair commonMediaTypes[] = {
     { "audio/x-wav", "wav" }
 };
 
-static HashSet<String>* supportedImageResourceMIMETypes;
-static HashSet<String>* supportedImageMIMETypes;
-static HashSet<String>* supportedImageMIMETypesForEncoding;
-static HashSet<String>* supportedJavaScriptMIMETypes;
-static HashSet<String>* supportedNonImageMIMETypes;
-static HashSet<String>* supportedMediaMIMETypes;
-static HashSet<String>* pdfMIMETypes;
-static HashSet<String>* pdfAndPostScriptMIMETypes;
-static HashSet<String>* unsupportedTextMIMETypes;
+static HashSet<String, ASCIICaseInsensitiveHash>* supportedImageResourceMIMETypes;
+static HashSet<String, ASCIICaseInsensitiveHash>* supportedImageMIMETypes;
+static HashSet<String, ASCIICaseInsensitiveHash>* supportedImageMIMETypesForEncoding;
+static HashSet<String, ASCIICaseInsensitiveHash>* supportedJavaScriptMIMETypes;
+static HashSet<String, ASCIICaseInsensitiveHash>* supportedNonImageMIMETypes;
+static HashSet<String, ASCIICaseInsensitiveHash>* supportedMediaMIMETypes;
+static HashSet<String, ASCIICaseInsensitiveHash>* pdfMIMETypes;
+static HashSet<String, ASCIICaseInsensitiveHash>* pdfAndPostScriptMIMETypes;
+static HashSet<String, ASCIICaseInsensitiveHash>* unsupportedTextMIMETypes;
 
 typedef HashMap<String, Vector<String>*, ASCIICaseInsensitiveHash> MediaMIMETypeMap;
     
@@ -210,9 +210,9 @@ static void initializeSupportedImageMIMETypes()
         "image/x-bmp", "image/x-win-bitmap", "image/x-windows-bmp", "image/ms-bmp", "image/x-ms-bmp",
         "application/bmp", "application/x-bmp", "application/x-win-bitmap",
     };
-    for (size_t i = 0; i < WTF_ARRAY_LENGTH(malformedMIMETypes); ++i) {
-        supportedImageMIMETypes->add(malformedMIMETypes[i]);
-        supportedImageResourceMIMETypes->add(malformedMIMETypes[i]);
+    for (auto& type : malformedMIMETypes) {
+        supportedImageMIMETypes->add(type);
+        supportedImageResourceMIMETypes->add(type);
     }
 #endif
 
@@ -228,9 +228,9 @@ static void initializeSupportedImageMIMETypes()
         "image/x-icon",    // ico
         "image/x-xbitmap"  // xbm
     };
-    for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i) {
-        supportedImageMIMETypes->add(types[i]);
-        supportedImageResourceMIMETypes->add(types[i]);
+    for (auto& type : types) {
+        supportedImageMIMETypes->add(type);
+        supportedImageResourceMIMETypes->add(type);
     }
 
 #if USE(WEBP)
@@ -243,7 +243,7 @@ static void initializeSupportedImageMIMETypes()
 
 static void initializeSupportedImageMIMETypesForEncoding()
 {
-    supportedImageMIMETypesForEncoding = new HashSet<String>;
+    supportedImageMIMETypesForEncoding = new HashSet<String, ASCIICaseInsensitiveHash>;
 
 #if USE(CG)
 #if PLATFORM(COCOA)
@@ -307,8 +307,8 @@ static void initializePDFMIMETypes()
         "application/pdf",
         "text/pdf"
     };
-    for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i)
-        pdfMIMETypes->add(types[i]);
+    for (auto& type : types)
+        pdfMIMETypes->add(type);
 }
 
 static void initializePostScriptMIMETypes()
@@ -337,14 +337,12 @@ static void initializeSupportedNonImageMimeTypes()
         "application/x-ftp-directory",
 #endif
         "multipart/x-mixed-replace"
-        // Note: ADDING a new type here will probably render it as HTML. This can
-        // result in cross-site scripting.
+        // Note: Adding a new type here will probably render it as HTML.
+        // This can result in cross-site scripting vulnerabilities.
     };
-    COMPILE_ASSERT(sizeof(types) / sizeof(types[0]) <= 16,
-                   nonimage_mime_types_must_be_less_than_or_equal_to_16);
 
-    for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i)
-        supportedNonImageMIMETypes->add(types[i]);
+    for (auto& type : types)
+        supportedNonImageMIMETypes->add(type);
 
 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     ArchiveFactory::registerKnownArchiveMIMETypes();
@@ -414,7 +412,7 @@ Vector<String> MIMETypeRegistry::getMediaMIMETypesForExtension(const String& ext
 
 static void initializeSupportedMediaMIMETypes()
 {
-    supportedMediaMIMETypes = new HashSet<String>;
+    supportedMediaMIMETypes = new HashSet<String, ASCIICaseInsensitiveHash>;
 #if ENABLE(VIDEO)
     MediaPlayer::getSupportedTypes(*supportedMediaMIMETypes);
 #endif
@@ -441,29 +439,29 @@ static void initializeUnsupportedTextMIMETypes()
         "text/vnd.sun.j2me.app-descriptor",
 #endif
     };
-    for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i)
-      unsupportedTextMIMETypes->add(types[i]);
+    for (auto& type : types)
+        unsupportedTextMIMETypes->add(type);
 }
 
 static void initializeMIMETypeRegistry()
 {
-    supportedJavaScriptMIMETypes = new HashSet<String>;
+    supportedJavaScriptMIMETypes = new HashSet<String, ASCIICaseInsensitiveHash>;
     initializeSupportedJavaScriptMIMETypes();
 
-    supportedNonImageMIMETypes = new HashSet<String>(*supportedJavaScriptMIMETypes);
+    supportedNonImageMIMETypes = new HashSet<String, ASCIICaseInsensitiveHash>(*supportedJavaScriptMIMETypes);
     initializeSupportedNonImageMimeTypes();
 
-    supportedImageResourceMIMETypes = new HashSet<String>;
-    supportedImageMIMETypes = new HashSet<String>;
+    supportedImageResourceMIMETypes = new HashSet<String, ASCIICaseInsensitiveHash>;
+    supportedImageMIMETypes = new HashSet<String, ASCIICaseInsensitiveHash>;
     initializeSupportedImageMIMETypes();
 
-    pdfMIMETypes = new HashSet<String>;
+    pdfMIMETypes = new HashSet<String, ASCIICaseInsensitiveHash>;
     initializePDFMIMETypes();
 
-    pdfAndPostScriptMIMETypes = new HashSet<String>(*pdfMIMETypes);
+    pdfAndPostScriptMIMETypes = new HashSet<String, ASCIICaseInsensitiveHash>(*pdfMIMETypes);
     initializePostScriptMIMETypes();
 
-    unsupportedTextMIMETypes = new HashSet<String>;
+    unsupportedTextMIMETypes = new HashSet<String, ASCIICaseInsensitiveHash>;
     initializeUnsupportedTextMIMETypes();
 }
 
@@ -584,35 +582,35 @@ bool MIMETypeRegistry::canShowMIMEType(const String& mimeType)
     return false;
 }
 
-HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypes()
+HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::getSupportedImageMIMETypes()
 {
     if (!supportedImageMIMETypes)
         initializeMIMETypeRegistry();
     return *supportedImageMIMETypes;
 }
 
-HashSet<String>& MIMETypeRegistry::getSupportedImageResourceMIMETypes()
+HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::getSupportedImageResourceMIMETypes()
 {
     if (!supportedImageResourceMIMETypes)
         initializeMIMETypeRegistry();
     return *supportedImageResourceMIMETypes;
 }
 
-HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypesForEncoding()
+HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::getSupportedImageMIMETypesForEncoding()
 {
     if (!supportedImageMIMETypesForEncoding)
         initializeSupportedImageMIMETypesForEncoding();
     return *supportedImageMIMETypesForEncoding;
 }
 
-HashSet<String>& MIMETypeRegistry::getSupportedNonImageMIMETypes()
+HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::getSupportedNonImageMIMETypes()
 {
     if (!supportedNonImageMIMETypes)
         initializeMIMETypeRegistry();
     return *supportedNonImageMIMETypes;
 }
 
-HashSet<String>& MIMETypeRegistry::getSupportedMediaMIMETypes()
+HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::getSupportedMediaMIMETypes()
 {
     if (!supportedMediaMIMETypes)
         initializeSupportedMediaMIMETypes();
@@ -620,21 +618,21 @@ HashSet<String>& MIMETypeRegistry::getSupportedMediaMIMETypes()
 }
 
 
-HashSet<String>& MIMETypeRegistry::getPDFMIMETypes()
+HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::getPDFMIMETypes()
 {
     if (!pdfMIMETypes)
         initializeMIMETypeRegistry();
     return *pdfMIMETypes;
 }
 
-HashSet<String>& MIMETypeRegistry::getPDFAndPostScriptMIMETypes()
+HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::getPDFAndPostScriptMIMETypes()
 {
     if (!pdfAndPostScriptMIMETypes)
         initializeMIMETypeRegistry();
     return *pdfAndPostScriptMIMETypes;
 }
 
-HashSet<String>& MIMETypeRegistry::getUnsupportedTextMIMETypes()
+HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::getUnsupportedTextMIMETypes()
 {
     if (!unsupportedTextMIMETypes)
         initializeMIMETypeRegistry();
@@ -648,14 +646,17 @@ const String& defaultMIMEType()
 }
 
 #if !USE(CURL)
+
+// FIXME: Not sure why it makes sense to have a cross-platform function when only CURL has the concept
+// of a "normalized" MIME type.
 String MIMETypeRegistry::getNormalizedMIMEType(const String& mimeType)
 {
     return mimeType;
 }
-#endif
 
-#if USE(CURL)
-typedef HashMap<String, String> MIMETypeAssociationMap;
+#else
+
+typedef HashMap<String, String, ASCIICaseInsensitiveHash> MIMETypeAssociationMap;
 
 static const MIMETypeAssociationMap& mimeTypeAssociationMap()
 {
@@ -663,8 +664,11 @@ static const MIMETypeAssociationMap& mimeTypeAssociationMap()
     if (mimeTypeMap)
         return *mimeTypeMap;
 
+    // FIXME: Should not allocate this on the heap; use NeverDestroyed instead.
     mimeTypeMap = new MIMETypeAssociationMap;
 
+    // FIXME: Writing the function out like this will create a giant function.
+    // Should use a loop instead.
     mimeTypeMap->add(ASCIILiteral("image/x-ms-bmp"), ASCIILiteral("image/bmp"));
     mimeTypeMap->add(ASCIILiteral("image/x-windows-bmp"), ASCIILiteral("image/bmp"));
     mimeTypeMap->add(ASCIILiteral("image/x-bmp"), ASCIILiteral("image/bmp"));
@@ -716,13 +720,12 @@ static const MIMETypeAssociationMap& mimeTypeAssociationMap()
 
 String MIMETypeRegistry::getNormalizedMIMEType(const String& mimeType)
 {
-    MIMETypeAssociationMap::const_iterator it = mimeTypeAssociationMap().find(mimeType);
-
+    auto it = mimeTypeAssociationMap().find(mimeType);
     if (it != mimeTypeAssociationMap().end())
         return it->value;
-
     return mimeType;
 }
+
 #endif
 
 } // namespace WebCore
index 82477cf..4dc74e7 100644 (file)
@@ -37,6 +37,7 @@ class MIMETypeRegistry {
 public:
     WEBCORE_EXPORT static String getMIMETypeForExtension(const String& extension);
 
+    // FIXME: WebKit coding style says we should not have the word "get" in the names of these functions.
     static Vector<String> getExtensionsForMIMEType(const String& type);
     WEBCORE_EXPORT static String getPreferredExtensionForMIMEType(const String& type);
     static String getMediaMIMETypeForExtension(const String& extension);
@@ -44,57 +45,60 @@ public:
 
     static String getMIMETypeForPath(const String& path);
 
-    // Check to see if a mime type is suitable for being loaded inline as an
+    // Check to see if a MIME type is suitable for being loaded inline as an
     // image (e.g., <img> tags).
     WEBCORE_EXPORT static bool isSupportedImageMIMEType(const String& mimeType);
 
-    // Check to see if a mime type is suitable for being loaded as an image
+    // Check to see if a MIME type is suitable for being loaded as an image
     // document in a frame.
     WEBCORE_EXPORT static bool isSupportedImageResourceMIMEType(const String& mimeType);
 
-    // Check to see if a mime type is suitable for being encoded.
+    // Check to see if a MIME type is suitable for being encoded.
     static bool isSupportedImageMIMETypeForEncoding(const String& mimeType);
 
-    // Check to see if a mime type is suitable for being loaded as a JavaScript
-    // resource.
+    // Check to see if a MIME type is suitable for being loaded as a JavaScript resource.
     static bool isSupportedJavaScriptMIMEType(const String& mimeType);    
 
-    // Check to see if a non-image mime type is suitable for being loaded as a
+    // Check to see if a non-image MIME type is suitable for being loaded as a
     // document in a frame.  Includes supported JavaScript MIME types.
     WEBCORE_EXPORT static bool isSupportedNonImageMIMEType(const String& mimeType);
 
-    // Check to see if a mime type is suitable for being loaded using <video> and <audio>
+    // Check to see if a MIME type is suitable for being loaded using <video> and <audio>.
     WEBCORE_EXPORT static bool isSupportedMediaMIMEType(const String& mimeType);
 
-    // Check to see if the mime type is not suitable for being loaded as a text
-    // document in a frame. Only valid for mime types begining with "text/".
+    // Check to see if the MIME type is not suitable for being loaded as a text
+    // document in a frame. Only valid for MIME types begining with "text/".
     static bool isUnsupportedTextMIMEType(const String& mimeType);
 
-    // Check to see if a mime type is a valid Java applet mime type
+    // Check to see if a MIME type is a valid Java applet mime type.
     WEBCORE_EXPORT static bool isJavaAppletMIMEType(const String& mimeType);
 
-    // Check to see if a mime type is a plugin implemented by the
-    // browser (e.g. a Qt Plugin).
+    // Check to see if a MIME type is a plugin implemented by the browser.
     static bool isApplicationPluginMIMEType(const String& mimeType);
 
-    // Check to see if a mime type is one of the common PDF/PS types.
+    // Check to see if a MIME type is one of the common PDF/PS types.
     WEBCORE_EXPORT static bool isPDFOrPostScriptMIMEType(const String& mimeType);
     static bool isPDFMIMEType(const String& mimeType);
 
-    // Check to see if a mime type is suitable for being shown inside a page.
-    // Returns true if any of isSupportedImageMIMEType(), isSupportedNonImageMIMEType(), isSupportedMediaMIMEType() returns true
-    // or if given mime type begins with "text/" and isUnsupportedTextMIMEType() returns false.
+    // Check to see if a MIME type is suitable for being shown inside a page.
+    // Returns true if any of isSupportedImageMIMEType(), isSupportedNonImageMIMEType(), or
+    // isSupportedMediaMIMEType() returns true or if the given MIME type begins with
+    // "text/" and isUnsupportedTextMIMEType() returns false.
     WEBCORE_EXPORT static bool canShowMIMEType(const String& mimeType);
 
-    WEBCORE_EXPORT static HashSet<String>& getSupportedImageMIMETypes();
-    static HashSet<String>& getSupportedImageResourceMIMETypes();
-    static HashSet<String>& getSupportedImageMIMETypesForEncoding();
-    WEBCORE_EXPORT static HashSet<String>& getSupportedNonImageMIMETypes();
-    WEBCORE_EXPORT static HashSet<String>& getSupportedMediaMIMETypes();
-    WEBCORE_EXPORT static HashSet<String>& getPDFMIMETypes();
-    static HashSet<String>& getPDFAndPostScriptMIMETypes();
-    WEBCORE_EXPORT static HashSet<String>& getUnsupportedTextMIMETypes();
-
+    // FIXME: WebKit coding style says we should not have the word "get" in the names of these functions.
+    // FIXME: Would be nice to find a way to avoid exposing these sets, even worse exposing non-const references.
+    WEBCORE_EXPORT static HashSet<String, ASCIICaseInsensitiveHash>& getSupportedImageMIMETypes();
+    static HashSet<String, ASCIICaseInsensitiveHash>& getSupportedImageResourceMIMETypes();
+    static HashSet<String, ASCIICaseInsensitiveHash>& getSupportedImageMIMETypesForEncoding();
+    WEBCORE_EXPORT static HashSet<String, ASCIICaseInsensitiveHash>& getSupportedNonImageMIMETypes();
+    WEBCORE_EXPORT static HashSet<String, ASCIICaseInsensitiveHash>& getSupportedMediaMIMETypes();
+    WEBCORE_EXPORT static HashSet<String, ASCIICaseInsensitiveHash>& getPDFMIMETypes();
+    static HashSet<String, ASCIICaseInsensitiveHash>& getPDFAndPostScriptMIMETypes();
+    WEBCORE_EXPORT static HashSet<String, ASCIICaseInsensitiveHash>& getUnsupportedTextMIMETypes();
+
+    // FIXME: WebKit coding style says we should not have the word "get" in the name of this function.
+    // FIXME: Unclear what the concept of a normalized MIME type is; currently it's a platform-specific notion.
     static String getNormalizedMIMEType(const String&);
 };
 
index e2cdd9c..ef3473b 100644 (file)
@@ -96,9 +96,9 @@ static URLSchemesMap& emptyDocumentSchemes()
     return emptyDocumentSchemes;
 }
 
-static HashSet<String>& schemesForbiddenFromDomainRelaxation()
+static HashSet<String, ASCIICaseInsensitiveHash>& schemesForbiddenFromDomainRelaxation()
 {
-    static NeverDestroyed<HashSet<String>> schemes;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> schemes;
     return schemes;
 }
 
index 7261003..c9cb33e 100644 (file)
@@ -2121,15 +2121,19 @@ bool portAllowed(const URL& url)
 String mimeTypeFromDataURL(const String& url)
 {
     ASSERT(protocolIs(url, "data"));
-    size_t index = url.find(';');
+
+    // FIXME: What's the right behavior when the URL has a comma first, but a semicolon later?
+    // Currently this code will break at the semicolon in that case. Not sure that's correct.
+    auto index = url.find(';', 5);
     if (index == notFound)
-        index = url.find(',');
-    if (index != notFound) {
-        if (index > 5)
-            return url.substring(5, index - 5).lower();
-        return "text/plain"; // Data URLs with no MIME type are considered text/plain.
+        index = url.find(',', 5);
+    if (index == notFound) {
+        // FIXME: There was an old comment here that made it sound like this should be returning text/plain.
+        // But we have been returning empty string here for some time, so not changing its behavior at this time.
+        return emptyString();
     }
-    return "";
+    ASSERT(index >= 5);
+    return url.substring(5, index - 5).convertToASCIILowercase();
 }
 
 String mimeTypeFromURL(const URL& url)
index 579f459..ab82e48 100644 (file)
@@ -865,10 +865,10 @@ MediaPlayer::SupportsType MediaPlayer::supportsType(const MediaEngineSupportPara
     return engine->supportsTypeAndCodecs(parameters);
 }
 
-void MediaPlayer::getSupportedTypes(HashSet<String>& types)
+void MediaPlayer::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)
 {
     for (auto& engine : installedMediaEngines()) {
-        HashSet<String> engineTypes;
+        HashSet<String, ASCIICaseInsensitiveHash> engineTypes;
         engine.getSupportedTypes(engineTypes);
         types.add(engineTypes.begin(), engineTypes.end());
     }
index 9af519f..73216c9 100644 (file)
@@ -294,7 +294,7 @@ public:
     // Media engine support.
     enum SupportsType { IsNotSupported, IsSupported, MayBeSupported };
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&, const MediaPlayerSupportsTypeClient*);
-    static void getSupportedTypes(HashSet<String>&);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&);
     static bool isAvailable();
     static void getSitesInMediaCache(Vector<String>&);
     static void clearMediaCache();
@@ -631,7 +631,7 @@ private:
 };
 
 typedef std::function<std::unique_ptr<MediaPlayerPrivateInterface> (MediaPlayer*)> CreateMediaEnginePlayer;
-typedef void (*MediaEngineSupportedTypes)(HashSet<String>& types);
+typedef void (*MediaEngineSupportedTypes)(HashSet<String, ASCIICaseInsensitiveHash>& types);
 typedef MediaPlayer::SupportsType (*MediaEngineSupportsType)(const MediaEngineSupportParameters& parameters);
 typedef void (*MediaEngineGetSitesInMediaCache)(Vector<String>&);
 typedef void (*MediaEngineClearMediaCache)();
index c3ec6f7..d98eb5b 100644 (file)
@@ -1111,12 +1111,12 @@ bool MediaPlayerPrivateAVFoundation::isUnsupportedMIMEType(const String& type)
     return false;
 }
 
-const HashSet<String>& MediaPlayerPrivateAVFoundation::staticMIMETypeList()
+const HashSet<String, ASCIICaseInsensitiveHash>& MediaPlayerPrivateAVFoundation::staticMIMETypeList()
 {
-    static NeverDestroyed<HashSet<String>> cache = []() {
-        HashSet<String> types;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache = []() {
+        HashSet<String, ASCIICaseInsensitiveHash> types;
 
-        static const char* typeNames[] = {
+        static const char* const typeNames[] = {
             "application/vnd.apple.mpegurl",
             "application/x-mpegurl",
             "audio/3gpp",
@@ -1148,8 +1148,8 @@ const HashSet<String>& MediaPlayerPrivateAVFoundation::staticMIMETypeList()
             "video/x-mpeg",
             "video/x-mpg",
         };
-        for (size_t i = 0; i < WTF_ARRAY_LENGTH(typeNames); ++i)
-            types.add(typeNames[i]);
+        for (auto& type : typeNames)
+            types.add(type);
 
         return types;
     }();
index d09418f..c985b89 100644 (file)
@@ -259,7 +259,7 @@ protected:
     virtual void updateVideoLayerGravity() = 0;
 
     static bool isUnsupportedMIMEType(const String&);
-    static const HashSet<String>& staticMIMETypeList();
+    static const HashSet<String, ASCIICaseInsensitiveHash>& staticMIMETypeList();
 
 protected:
     void updateStates();
index c106baf..d569022 100644 (file)
@@ -882,25 +882,21 @@ static bool keySystemIsSupported(const String& keySystem)
 
 #endif
 
-static const HashSet<String>& avfMIMETypes()
+static const HashSet<String, ASCIICaseInsensitiveHash>& avfMIMETypes()
 {
-    static NeverDestroyed<HashSet<String>> cache = []() {
-        HashSet<String> types;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache = []() {
+        HashSet<String, ASCIICaseInsensitiveHash> types;
         RetainPtr<CFArrayRef> avTypes = adoptCF(AVCFURLAssetCopyAudiovisualMIMETypes());
-
         CFIndex typeCount = CFArrayGetCount(avTypes.get());
-        for (CFIndex i = 0; i < typeCount; ++i) {
-            String mimeType = (CFStringRef)(CFArrayGetValueAtIndex(avTypes.get(), i));
-            types.add(mimeType.lower());
-        }
-
+        for (CFIndex i = 0; i < typeCount; ++i)
+            types.add((CFStringRef)CFArrayGetValueAtIndex(avTypes.get(), i));
         return types;
     }();
 
     return cache;
 }
 
-void MediaPlayerPrivateAVFoundationCF::getSupportedTypes(HashSet<String>& supportedTypes)
+void MediaPlayerPrivateAVFoundationCF::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& supportedTypes)
 {
     supportedTypes = avfMIMETypes();
 }
index 876a189..e482d16 100644 (file)
@@ -60,7 +60,7 @@ public:
     static void registerMediaEngine(MediaEngineRegistrar);
 
 private:
-    static void getSupportedTypes(HashSet<String>& types);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
     static bool supportsKeySystem(const String& keySystem, const String& mimeType);
     static bool isAvailable();
index ab91dc5..3ffce1e 100644 (file)
@@ -145,7 +145,7 @@ public:
 
 private:
     // engine support
-    static void getSupportedTypes(HashSet<String>& types);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
     static bool supportsKeySystem(const String& keySystem, const String& mimeType);
 
index 7321ca5..87fac7e 100644 (file)
@@ -1505,22 +1505,17 @@ void MediaPlayerPrivateAVFoundationObjC::paintWithImageGenerator(GraphicsContext
         context.setImageInterpolationQuality(InterpolationLow);
         IntRect paintRect(IntPoint(0, 0), IntSize(rect.width(), rect.height()));
         CGContextDrawImage(context.platformContext(), CGRectMake(0, 0, paintRect.width(), paintRect.height()), image.get());
-        image = 0;
     }
 }
 
-static const HashSet<String>& avfMIMETypes()
+static const HashSet<String, ASCIICaseInsensitiveHash>& avfMIMETypes()
 {
-    static NeverDestroyed<HashSet<String>> cache = [] () {
-        HashSet<String> types;
-
-        NSArray *nsTypes = [AVURLAsset audiovisualMIMETypes];
-        for (NSString *mimeType in nsTypes)
-            types.add([mimeType lowercaseString]);
-
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache = []() {
+        HashSet<String, ASCIICaseInsensitiveHash> types;
+        for (NSString *type in [AVURLAsset audiovisualMIMETypes])
+            types.add(type);
         return types;
     }();
-
     
     return cache;
 }
@@ -1547,7 +1542,7 @@ RetainPtr<CGImageRef> MediaPlayerPrivateAVFoundationObjC::createImageForTimeInRe
     return image;
 }
 
-void MediaPlayerPrivateAVFoundationObjC::getSupportedTypes(HashSet<String>& supportedTypes)
+void MediaPlayerPrivateAVFoundationObjC::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& supportedTypes)
 {
     supportedTypes = avfMIMETypes();
 } 
index 4b1b823..1aa529b 100644 (file)
@@ -61,7 +61,7 @@ public:
 
     // MediaPlayer Factory Methods
     static bool isAvailable();
-    static void getSupportedTypes(HashSet<String>& types);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
 
     void addDisplayLayer(AVSampleBufferDisplayLayer*);
index 8140e71..143c046 100644 (file)
@@ -218,9 +218,9 @@ bool MediaPlayerPrivateMediaSourceAVFObjC::isAvailable()
         && class_getInstanceMethod(getAVSampleBufferAudioRendererClass(), @selector(setMuted:));
 }
 
-static const HashSet<String>& mimeTypeCache()
+static const HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeCache()
 {
-    static NeverDestroyed<HashSet<String>> cache;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache;
     static bool typeListInitialized = false;
 
     if (typeListInitialized)
@@ -234,7 +234,7 @@ static const HashSet<String>& mimeTypeCache()
     return cache;
 } 
 
-void MediaPlayerPrivateMediaSourceAVFObjC::getSupportedTypes(HashSet<String>& types)
+void MediaPlayerPrivateMediaSourceAVFObjC::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)
 {
     types = mimeTypeCache();
 }
index 71f51b0..91ae102 100644 (file)
@@ -55,7 +55,7 @@ public:
 
     // MediaPlayer Factory Methods
     static bool isAvailable();
-    static void getSupportedTypes(HashSet<String>& types);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
 
     MediaPlayer::NetworkState networkState() const override;
index 91a8896..8ee8939 100644 (file)
@@ -83,9 +83,9 @@ bool MediaPlayerPrivateMediaStreamAVFObjC::isAvailable()
     return AVFoundationLibrary() && isCoreMediaFrameworkAvailable();
 }
 
-void MediaPlayerPrivateMediaStreamAVFObjC::getSupportedTypes(HashSet<String>& types)
+void MediaPlayerPrivateMediaStreamAVFObjC::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)
 {
-    static NeverDestroyed<HashSet<String>> cache;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache;
     types = cache;
 }
 
index ddfa421..d8f5d9a 100644 (file)
@@ -41,6 +41,7 @@
 #include <limits>
 #include <wtf/HexNumber.h>
 #include <wtf/MediaTime.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/glib/GUniquePtr.h>
 #include <wtf/text/CString.h>
 
@@ -1659,116 +1660,111 @@ void MediaPlayerPrivateGStreamer::loadingFailed(MediaPlayer::NetworkState error)
     m_readyTimerHandler.stop();
 }
 
-static HashSet<String> mimeTypeCache()
-{
-    initializeGStreamerAndRegisterWebKitElements();
-
-    DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
-    static bool typeListInitialized = false;
-
-    if (typeListInitialized)
-        return cache;
-
-    const char* mimeTypes[] = {
-        "application/ogg",
-        "application/vnd.apple.mpegurl",
-        "application/vnd.rn-realmedia",
-        "application/x-3gp",
-        "application/x-pn-realaudio",
-        "application/x-mpegurl",
-        "audio/3gpp",
-        "audio/aac",
-        "audio/flac",
-        "audio/iLBC-sh",
-        "audio/midi",
-        "audio/mobile-xmf",
-        "audio/mp1",
-        "audio/mp2",
-        "audio/mp3",
-        "audio/mp4",
-        "audio/mpeg",
-        "audio/ogg",
-        "audio/opus",
-        "audio/qcelp",
-        "audio/riff-midi",
-        "audio/speex",
-        "audio/wav",
-        "audio/webm",
-        "audio/x-ac3",
-        "audio/x-aiff",
-        "audio/x-amr-nb-sh",
-        "audio/x-amr-wb-sh",
-        "audio/x-au",
-        "audio/x-ay",
-        "audio/x-celt",
-        "audio/x-dts",
-        "audio/x-flac",
-        "audio/x-gbs",
-        "audio/x-gsm",
-        "audio/x-gym",
-        "audio/x-imelody",
-        "audio/x-ircam",
-        "audio/x-kss",
-        "audio/x-m4a",
-        "audio/x-mod",
-        "audio/x-mp3",
-        "audio/x-mpeg",
-        "audio/x-musepack",
-        "audio/x-nist",
-        "audio/x-nsf",
-        "audio/x-paris",
-        "audio/x-sap",
-        "audio/x-sbc",
-        "audio/x-sds",
-        "audio/x-shorten",
-        "audio/x-sid",
-        "audio/x-spc",
-        "audio/x-speex",
-        "audio/x-svx",
-        "audio/x-ttafile",
-        "audio/x-vgm",
-        "audio/x-voc",
-        "audio/x-vorbis+ogg",
-        "audio/x-w64",
-        "audio/x-wav",
-        "audio/x-wavpack",
-        "audio/x-wavpack-correction",
-        "video/3gpp",
-        "video/flv",
-        "video/mj2",
-        "video/mp2t",
-        "video/mp4",
-        "video/mpeg",
-        "video/mpegts",
-        "video/ogg",
-        "video/quicktime",
-        "video/vivo",
-        "video/webm",
-        "video/x-cdxa",
-        "video/x-dirac",
-        "video/x-dv",
-        "video/x-fli",
-        "video/x-flv",
-        "video/x-h263",
-        "video/x-ivf",
-        "video/x-m4v",
-        "video/x-matroska",
-        "video/x-mng",
-        "video/x-ms-asf",
-        "video/x-msvideo",
-        "video/x-mve",
-        "video/x-nuv",
-        "video/x-vcd"
-    };
-
-    for (unsigned i = 0; i < (sizeof(mimeTypes) / sizeof(*mimeTypes)); ++i)
-        cache.add(String(mimeTypes[i]));
-
-    typeListInitialized = true;
+// FIXME: In what sense is this a "cache"?
+static HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeCache()
+{
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache = []() {
+        initializeGStreamerAndRegisterWebKitElements();
+        HashSet<String, ASCIICaseInsensitiveHash> set;
+        const char* mimeTypes[] = {
+            "application/ogg",
+            "application/vnd.apple.mpegurl",
+            "application/vnd.rn-realmedia",
+            "application/x-3gp",
+            "application/x-pn-realaudio",
+            "application/x-mpegurl",
+            "audio/3gpp",
+            "audio/aac",
+            "audio/flac",
+            "audio/iLBC-sh",
+            "audio/midi",
+            "audio/mobile-xmf",
+            "audio/mp1",
+            "audio/mp2",
+            "audio/mp3",
+            "audio/mp4",
+            "audio/mpeg",
+            "audio/ogg",
+            "audio/opus",
+            "audio/qcelp",
+            "audio/riff-midi",
+            "audio/speex",
+            "audio/wav",
+            "audio/webm",
+            "audio/x-ac3",
+            "audio/x-aiff",
+            "audio/x-amr-nb-sh",
+            "audio/x-amr-wb-sh",
+            "audio/x-au",
+            "audio/x-ay",
+            "audio/x-celt",
+            "audio/x-dts",
+            "audio/x-flac",
+            "audio/x-gbs",
+            "audio/x-gsm",
+            "audio/x-gym",
+            "audio/x-imelody",
+            "audio/x-ircam",
+            "audio/x-kss",
+            "audio/x-m4a",
+            "audio/x-mod",
+            "audio/x-mp3",
+            "audio/x-mpeg",
+            "audio/x-musepack",
+            "audio/x-nist",
+            "audio/x-nsf",
+            "audio/x-paris",
+            "audio/x-sap",
+            "audio/x-sbc",
+            "audio/x-sds",
+            "audio/x-shorten",
+            "audio/x-sid",
+            "audio/x-spc",
+            "audio/x-speex",
+            "audio/x-svx",
+            "audio/x-ttafile",
+            "audio/x-vgm",
+            "audio/x-voc",
+            "audio/x-vorbis+ogg",
+            "audio/x-w64",
+            "audio/x-wav",
+            "audio/x-wavpack",
+            "audio/x-wavpack-correction",
+            "video/3gpp",
+            "video/flv",
+            "video/mj2",
+            "video/mp2t",
+            "video/mp4",
+            "video/mpeg",
+            "video/mpegts",
+            "video/ogg",
+            "video/quicktime",
+            "video/vivo",
+            "video/webm",
+            "video/x-cdxa",
+            "video/x-dirac",
+            "video/x-dv",
+            "video/x-fli",
+            "video/x-flv",
+            "video/x-h263",
+            "video/x-ivf",
+            "video/x-m4v",
+            "video/x-matroska",
+            "video/x-mng",
+            "video/x-ms-asf",
+            "video/x-msvideo",
+            "video/x-mve",
+            "video/x-nuv",
+            "video/x-vcd"
+        };
+        for (auto& type : mimeTypes)
+            set.add(type);
+        return set;
+    }();
     return cache;
 }
 
-void MediaPlayerPrivateGStreamer::getSupportedTypes(HashSet<String>& types)
+void MediaPlayerPrivateGStreamer::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)
 {
     types = mimeTypeCache();
 }
index bef7a3e..24139cf 100644 (file)
@@ -126,7 +126,7 @@ public:
 #endif
 
 private:
-    static void getSupportedTypes(HashSet<String>&);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
 
     static bool isAvailable();
index 196decc..adda779 100644 (file)
@@ -65,7 +65,7 @@ public:
 
 private:
     // engine support
-    static void getSupportedTypes(HashSet<String>& types);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
 
     static void getSitesInMediaCache(Vector<String>&);
index 2100e27..b270318 100644 (file)
@@ -1232,14 +1232,13 @@ static bool shouldRejectMIMEType(const String& type)
 {
     // QTKit will return non-video MIME types which it claims to support, but which we
     // do not support in the <video> element. Disclaim all non video/ or audio/ types.
-    return !type.startsWith("video/") && !type.startsWith("audio/");
+    return !type.startsWith("video/", false) && !type.startsWith("audio/", false);
 }
 
-static void addFileTypesToCache(NSArray * fileTypes, HashSet<String> &cache)
+static void addFileTypesToCache(NSArray *fileTypes, HashSet<String, ASCIICaseInsensitiveHash> &cache)
 {
-    int count = [fileTypes count];
-    for (int n = 0; n < count; n++) {
-        CFStringRef ext = reinterpret_cast<CFStringRef>([fileTypes objectAtIndex:n]);
+    for (NSString *fileType : fileTypes) {
+        CFStringRef ext = reinterpret_cast<CFStringRef>(fileType);
         RetainPtr<CFStringRef> uti = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL));
         if (!uti)
             continue;
@@ -1254,25 +1253,18 @@ static void addFileTypesToCache(NSArray * fileTypes, HashSet<String> &cache)
         if (CFStringGetCharacterAtIndex(ext, 0) != '\'') {
             // UTI is missing many media related MIME types supported by QTKit (see rdar://6434168), and not all
             // web servers use the MIME type UTI returns for an extension (see rdar://7875393), so even if UTI 
-            // has a type for this extension add any types in hard coded table in the MIME type regsitry.
-            Vector<String> typesForExtension = MIMETypeRegistry::getMediaMIMETypesForExtension(ext);
-            unsigned count = typesForExtension.size();
-            for (unsigned ndx = 0; ndx < count; ++ndx) {
-                String type = typesForExtension[ndx].lower();
-
-                if (shouldRejectMIMEType(type))
-                    continue;
-
-                if (!cache.contains(type))
+            // has a type for this extension add any types in hard coded table in the MIME type registry.
+            for (auto& type : MIMETypeRegistry::getMediaMIMETypesForExtension(ext)) {
+                if (!shouldRejectMIMEType(type))
                     cache.add(type);
             }
         }
     }    
 }
 
-static HashSet<String> mimeCommonTypesCache()
+static HashSet<String, ASCIICaseInsensitiveHash> mimeCommonTypesCache()
 {
-    static NeverDestroyed<HashSet<String>> cache;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache;
     static bool typeListInitialized = false;
 
     if (!typeListInitialized) {
@@ -1284,9 +1276,9 @@ static HashSet<String> mimeCommonTypesCache()
     return cache;
 } 
 
-static HashSet<String> mimeModernTypesCache()
+static HashSet<String, ASCIICaseInsensitiveHash> mimeModernTypesCache()
 {
-    static NeverDestroyed<HashSet<String>> cache;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache;
     static bool typeListInitialized = false;
     
     if (!typeListInitialized) {
@@ -1298,15 +1290,13 @@ static HashSet<String> mimeModernTypesCache()
     return cache;
 }
 
-static void concatenateHashSets(HashSet<String>& destination, const HashSet<String>& source)
+static void concatenateHashSets(HashSet<String, ASCIICaseInsensitiveHash>& destination, const HashSet<String, ASCIICaseInsensitiveHash>& source)
 {
-    HashSet<String>::const_iterator it = source.begin();
-    HashSet<String>::const_iterator end = source.end();
-    for (; it != end; ++it)
-        destination.add(*it);
+    for (auto& type : source)
+        destination.add(type);
 }
 
-void MediaPlayerPrivateQTKit::getSupportedTypes(HashSet<String>& supportedTypes)
+void MediaPlayerPrivateQTKit::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& supportedTypes)
 {
     concatenateHashSets(supportedTypes, mimeModernTypesCache());
 
@@ -1378,22 +1368,26 @@ void MediaPlayerPrivateQTKit::disableUnsupportedTracks()
         return;
     }
     
-    static HashSet<String>* allowedTrackTypes = 0;
-    if (!allowedTrackTypes) {
-        allowedTrackTypes = new HashSet<String>;
-        allowedTrackTypes->add(QTMediaTypeVideo);
-        allowedTrackTypes->add(QTMediaTypeSound);
-        allowedTrackTypes->add(QTMediaTypeText);
-        allowedTrackTypes->add(QTMediaTypeBase);
-        allowedTrackTypes->add(QTMediaTypeMPEG);
-        allowedTrackTypes->add("clcp"); // Closed caption
-        allowedTrackTypes->add("sbtl"); // Subtitle
-        allowedTrackTypes->add("odsm"); // MPEG-4 object descriptor stream
-        allowedTrackTypes->add("sdsm"); // MPEG-4 scene description stream
-        allowedTrackTypes->add("tmcd"); // timecode
-        allowedTrackTypes->add("tc64"); // timcode-64
-        allowedTrackTypes->add("tmet"); // timed metadata
-    }
+    static NeverDestroyed<HashSet<String>> allowedTrackTypes = []() {
+        NSString *types[] = {
+            QTMediaTypeVideo,
+            QTMediaTypeSound,
+            QTMediaTypeText,
+            QTMediaTypeBase,
+            QTMediaTypeMPEG,
+            @"clcp", // Closed caption
+            @"sbtl", // Subtitle
+            @"odsm", // MPEG-4 object descriptor stream
+            @"sdsm", // MPEG-4 scene description stream
+            @"tmcd", // timecode
+            @"tc64", // timcode-64
+            @"tmet", // timed metadata
+        };
+        HashSet<String> set;
+        for (auto& type : types)
+            set.add(type);
+        return set;
+    }();
     
     NSArray *tracks = [m_qtMovie.get() tracks];
     
@@ -1419,7 +1413,7 @@ void MediaPlayerPrivateQTKit::disableUnsupportedTracks()
             continue;
 
         // Test whether the media type is in our white list.
-        if (!allowedTrackTypes->contains(mediaType)) {
+        if (!allowedTrackTypes.get().contains(mediaType)) {
             // If this track type is not allowed, then we need to disable it.
             [track setEnabled:NO];
             --m_enabledTrackCount;
index f8a46fb..b7cbd8b 100644 (file)
@@ -120,9 +120,9 @@ bool MediaPlayerPrivateMediaFoundation::isAvailable()
     return true;
 }
 
-static const HashSet<String>& mimeTypeCache()
+static const HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeCache()
 {
-    static NeverDestroyed<HashSet<String>> cachedTypes;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cachedTypes;
 
     if (cachedTypes.get().size() > 0)
         return cachedTypes;
@@ -148,7 +148,7 @@ static const HashSet<String>& mimeTypeCache()
     return cachedTypes;
 }
 
-void MediaPlayerPrivateMediaFoundation::getSupportedTypes(HashSet<String>& types)
+void MediaPlayerPrivateMediaFoundation::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)
 {
     types = mimeTypeCache();
 }
index cff8bf9..5fd9ad1 100644 (file)
@@ -53,7 +53,7 @@ public:
     ~MediaPlayerPrivateMediaFoundation();
     static void registerMediaEngine(MediaEngineRegistrar);
 
-    static void getSupportedTypes(HashSet<String>& types);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
     static bool isAvailable();
 
index 201cc16..f34e1c3 100644 (file)
@@ -45,9 +45,9 @@ void MockMediaPlayerMediaSource::registerMediaEngine(MediaEngineRegistrar regist
         supportsType, 0, 0, 0, 0);
 }
 
-static const HashSet<String>& mimeTypeCache()
+static const HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeCache()
 {
-    static NeverDestroyed<HashSet<String>> cache;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache;
     static bool isInitialized = false;
 
     if (!isInitialized) {
@@ -59,7 +59,7 @@ static const HashSet<String>& mimeTypeCache()
     return cache;
 }
 
-void MockMediaPlayerMediaSource::getSupportedTypes(HashSet<String>& supportedTypes)
+void MockMediaPlayerMediaSource::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& supportedTypes)
 {
     supportedTypes = mimeTypeCache();
 }
index 03261fa..4ce12d3 100644 (file)
@@ -42,7 +42,7 @@ public:
 
     // MediaPlayer Engine Support
     WEBCORE_EXPORT static void registerMediaEngine(MediaEngineRegistrar);
-    static void getSupportedTypes(HashSet<String>& types);
+    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
 
     virtual ~MockMediaPlayerMediaSource();
index f378fad..8892b9e 100644 (file)
@@ -1,3 +1,14 @@
+2016-01-31  Darin Adler  <darin@apple.com>
+
+        Cut down on calls to String::lower; mostly replace with convertToASCIILowercase
+        https://bugs.webkit.org/show_bug.cgi?id=153732
+
+        Reviewed by Dean Jackson.
+
+        * WebView/WebHTMLRepresentation.mm:
+        (newArrayWithStrings): Updated to use HashSet<String, ASCIICaseInsensitiveHash>
+        and also to use a modern for loop.
+
 2016-01-31  Dan Bernstein  <mitz@apple.com>
 
         [Cocoa] Remove __has_include guards around use of WebKitAdditions
index 91bd3b8..e8c76aa 100644 (file)
@@ -87,13 +87,12 @@ using JSC::Yarr::RegularExpression;
 
 @implementation WebHTMLRepresentation
 
-static NSMutableArray *newArrayWithStrings(const HashSet<String>& set) NS_RETURNS_RETAINED;
-static NSMutableArray *newArrayWithStrings(const HashSet<String>& set)
+static NSMutableArray *newArrayWithStrings(const HashSet<String, ASCIICaseInsensitiveHash>&) NS_RETURNS_RETAINED;
+static NSMutableArray *newArrayWithStrings(const HashSet<String, ASCIICaseInsensitiveHash>& set)
 {
     NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:set.size()];
-    HashSet<String>::const_iterator end = set.end();
-    for (HashSet<String>::const_iterator it = set.begin(); it != end; ++it)
-        [array addObject:(NSString *)(*it)];
+    for (auto& string : set)
+        [array addObject:(NSString *)string];
     return array;
 }