Chromium Code Reviews| Index: Source/core/html/parser/HTMLParserIdioms.cpp |
| diff --git a/Source/core/html/parser/HTMLParserIdioms.cpp b/Source/core/html/parser/HTMLParserIdioms.cpp |
| index 6f136305f07ee01108d46d0b8da093bcfc11b83c..4a9b663d0b02e40f2918d48994a17c407365179f 100644 |
| --- a/Source/core/html/parser/HTMLParserIdioms.cpp |
| +++ b/Source/core/html/parser/HTMLParserIdioms.cpp |
| @@ -29,6 +29,7 @@ |
| #include "core/dom/QualifiedName.h" |
| #include "core/html/parser/HTMLIdentifier.h" |
| #include "core/platform/Decimal.h" |
| +#include "weborigin/KURL.h" |
| #include "wtf/MathExtras.h" |
| #include "wtf/text/AtomicString.h" |
| #include "wtf/text/StringBuilder.h" |
| @@ -296,4 +297,74 @@ bool threadSafeMatch(const HTMLIdentifier& localName, const QualifiedName& qName |
| return threadSafeEqual(localName.asStringImpl(), qName.localName().impl()); |
| } |
| +struct ImageWithScale { |
| + String imageURL; |
| + float scaleFactor; |
| + bool operator==(const ImageWithScale& image) const |
| + { |
| + return scaleFactor == image.scaleFactor && imageURL == image.imageURL; |
| + } |
| +}; |
| +typedef Vector<ImageWithScale> ImageCandidates; |
| + |
| +static inline bool compareByScaleFactor(const ImageWithScale& first, const ImageWithScale& second) |
| +{ |
| + return first.scaleFactor < second.scaleFactor; |
| +} |
| + |
| +String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcSetAttribute) |
| +{ |
| + ImageCandidates imageCandidates; |
| + |
| + const String srcSetAttributeValue = srcSetAttribute.simplifyWhiteSpace(isHTMLSpace); |
| + Vector<String> srcSetTokens; |
| + |
| + srcSetAttributeValue.split(',', srcSetTokens); |
| + for (size_t i = 0; i < srcSetTokens.size(); ++i) { |
| + Vector<String> data; |
| + float imgScaleFactor = 1.0; |
| + bool validScaleFactor = false; |
| + |
| + srcSetTokens[i].stripWhiteSpace().split(' ', data); |
| + // There must be at least one candidate descriptor, and the last one must |
| + // be a scale factor. Since we don't support descriptors other than scale, |
| + // it's better to discard any rule with such descriptors rather than accept |
| + // only the scale data. |
| + if (data.size() != 2) |
| + continue; |
| + if (!data.last().endsWith('x')) |
| + continue; |
| + |
| + imgScaleFactor = data.last().substring(0, data.last().length() - 1).toFloat(&validScaleFactor); |
| + if (!validScaleFactor) |
| + continue; |
| + |
| + ImageWithScale image; |
| + image.imageURL = decodeURLEscapeSequences(data[0]); |
|
cbiesinger
2013/09/06 22:45:36
why decode them?
|
| + image.scaleFactor = imgScaleFactor; |
| + |
| + imageCandidates.append(image); |
| + } |
| + |
| + const String src = srcAttribute.simplifyWhiteSpace(isHTMLSpace); |
| + if (!src.isEmpty()) { |
| + ImageWithScale image; |
| + image.imageURL = decodeURLEscapeSequences(src); |
|
cbiesinger
2013/09/06 22:45:36
same
|
| + image.scaleFactor = 1.0; |
| + |
| + imageCandidates.append(image); |
| + } |
| + |
| + if (imageCandidates.isEmpty()) |
| + return String(); |
| + |
| + std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByScaleFactor); |
| + |
| + for (size_t i = 0; i < imageCandidates.size() - 1; ++i) { |
| + if (imageCandidates[i].scaleFactor >= deviceScaleFactor) |
| + return imageCandidates[i].imageURL; |
| + } |
| + return imageCandidates.last().imageURL; |
| +} |
| + |
| } |