Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
|
abarth-chromium
2013/09/19 18:09:52
Same problem with the license block.
| |
| 4 | |
| 5 #include "config.h" | |
| 6 #include "core/html/parser/HTMLSrcsetParser.h" | |
| 7 | |
| 8 #include "core/html/parser/HTMLParserIdioms.h" | |
| 9 #include "core/platform/ParsingUtilities.h" | |
| 10 | |
| 11 namespace WebCore { | |
| 12 | |
| 13 static inline bool compareByScaleFactor(const ImageCandidate& first, const Image Candidate& second) | |
|
abarth-chromium
2013/09/19 18:09:52
The |static| and |inline| keywords are redundant h
| |
| 14 { | |
| 15 return first.scaleFactor() < second.scaleFactor(); | |
| 16 } | |
| 17 | |
| 18 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content- 1.html#processing-the-image-candidates | |
| 19 template<typename CharType> | |
| 20 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, con st CharType* attributeStart, unsigned length, Vector<ImageCandidate>& imageCandi dates) | |
| 21 { | |
| 22 const CharType* position = attributeStart; | |
| 23 const CharType* attributeEnd = position + length; | |
| 24 | |
| 25 while (position < attributeEnd) { | |
| 26 float imgScaleFactor = 1.0; | |
| 27 // 4. Splitting loop: Skip whitespace. | |
| 28 skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd); | |
| 29 if (position == attributeEnd) | |
| 30 break; | |
| 31 const CharType* imageURLStart = position; | |
| 32 | |
| 33 // If The current candidate is either totally empty or only contains spa ce, skipping. | |
| 34 if (*position == ',') { | |
| 35 ++position; | |
| 36 continue; | |
| 37 } | |
| 38 // 5. Collect a sequence of characters that are not space characters, an d let that be url. | |
| 39 ++position; | |
| 40 skipWhile<CharType, isNotHTMLSpace<CharType> >(position, attributeEnd); | |
|
abarth-chromium
2013/09/19 18:09:52
skipUntil<CharType, isHTMLSpaceOrComma<CharType> >
Yoav Weiss
2013/09/20 07:31:36
skipUntil<CharType, isHTMLSpace<CharType> >
The a
| |
| 41 const CharType* imageURLEnd = position; | |
| 42 | |
| 43 if (position != attributeEnd && *(position - 1) == ',') { | |
| 44 --imageURLEnd; | |
| 45 } else { | |
| 46 // 7. Collect a sequence of characters that are not "," (U+002C) cha racters, and let that be descriptors. | |
| 47 skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd); | |
| 48 const CharType* qualifierStart = position; | |
| 49 if (position != attributeEnd && *position != ',') { | |
| 50 // This part differs from the spec as the current implementation only supports pixel density descriptors for now. | |
| 51 skipUntil<CharType, isHTMLSpaceOrComma<CharType> >(position, att ributeEnd); | |
| 52 const CharType* qualifierEnd = position; | |
| 53 // Make sure there are no other descriptors | |
| 54 skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeE nd); | |
| 55 // If the first non-html-space character after the scale modifie r is not a comma, | |
| 56 // the current candidate is an invalid input. | |
| 57 if (position != attributeEnd && *position != ',') { | |
| 58 skipUntil<CharType>(position, attributeEnd, ','); | |
| 59 ++position; | |
| 60 continue; | |
| 61 } | |
| 62 // If the current qualifier is not an 'x', the resource is ignor ed | |
| 63 if (*(qualifierEnd - 1) != 'x') | |
|
abarth-chromium
2013/09/19 18:09:52
How do we know qualifierEnd - 1 is a valid address
Yoav Weiss
2013/09/20 07:31:36
When going into the skipUntil at line 51, we know
abarth-chromium
2013/09/20 16:08:07
I think an ASSERT is probably enough.
| |
| 64 continue; | |
| 65 | |
| 66 bool validScaleFactor = false; | |
| 67 unsigned scaleFactorLengthWithoutUnit = qualifierEnd - qualifier Start - 1; | |
| 68 imgScaleFactor = charactersToFloat(qualifierStart, scaleFactorLe ngthWithoutUnit, &validScaleFactor); | |
| 69 | |
| 70 if (!validScaleFactor) | |
| 71 continue; | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 imageCandidates.append(ImageCandidate(attribute, imageURLStart - attribu teStart, imageURLEnd - imageURLStart, imgScaleFactor)); | |
| 76 // 11. Return to the step labeled splitting loop. | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, Vec tor<ImageCandidate>& imageCandidates) | |
| 81 { | |
| 82 if (attribute.is8Bit()) | |
|
abarth-chromium
2013/09/19 18:09:52
What if attribute.isNull() ? Calling is8Bit() on
| |
| 83 parseImageCandidatesFromSrcsetAttribute<LChar>(attribute, attribute.char acters8(), attribute.length(), imageCandidates); | |
| 84 else | |
| 85 parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.char acters16(), attribute.length(), imageCandidates); | |
| 86 } | |
| 87 | |
| 88 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, Vector<Ima geCandidate>& imageCandidates) | |
| 89 { | |
| 90 std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareBySc aleFactor); | |
| 91 | |
| 92 unsigned i; | |
| 93 for (i = 0; i < imageCandidates.size() - 1; ++i) { | |
| 94 if (imageCandidates[i].scaleFactor() >= deviceScaleFactor) | |
| 95 break; | |
| 96 } | |
| 97 return imageCandidates[i]; | |
|
abarth-chromium
2013/09/19 18:09:52
This will crash if imageCandidates is empty.
Rath
| |
| 98 } | |
| 99 | |
| 100 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const St ring& srcsetAttribute) | |
| 101 { | |
| 102 Vector<ImageCandidate> imageCandidates; | |
| 103 | |
| 104 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); | |
| 105 if (imageCandidates.isEmpty()) | |
| 106 return ImageCandidate(); | |
| 107 return pickBestImageCandidate(deviceScaleFactor, imageCandidates); | |
| 108 } | |
| 109 | |
| 110 String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& sr cAttribute, const String& srcsetAttribute) | |
| 111 { | |
| 112 if (srcsetAttribute.isNull()) | |
| 113 return srcAttribute; | |
|
abarth-chromium
2013/09/19 18:09:52
Or just:
return String()
cbiesinger
2013/09/19 23:01:44
But that's not equivalent, right? If srcset is emp
abarth-chromium
2013/09/20 16:08:07
In this case, you're testing for isNull(). There'
abarth-chromium
2013/09/20 16:08:58
Oh, you're totally right. Please ignore me.
| |
| 114 | |
| 115 Vector<ImageCandidate> imageCandidates; | |
| 116 | |
| 117 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); | |
| 118 | |
| 119 if (!srcAttribute.isEmpty()) | |
| 120 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng th(), 1.0)); | |
| 121 | |
| 122 if (imageCandidates.isEmpty()) | |
| 123 return String(); | |
| 124 | |
| 125 return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString() ; | |
| 126 } | |
| 127 | |
| 128 String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& sr cAttribute, ImageCandidate& srcsetImageCandidate) | |
| 129 { | |
| 130 if (srcsetImageCandidate.isEmpty()) | |
| 131 return srcAttribute; | |
| 132 | |
| 133 Vector<ImageCandidate> imageCandidates; | |
| 134 imageCandidates.append(srcsetImageCandidate); | |
| 135 | |
| 136 if (!srcAttribute.isEmpty()) | |
| 137 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng th(), 1.0)); | |
| 138 | |
| 139 return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString() ; | |
| 140 } | |
| 141 | |
| 142 } | |
| OLD | NEW |