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 |