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. | |
4 | |
5 #include "config.h" | |
6 #include "core/html/parser/HTMLSrcsetParser.h" | |
7 | |
8 #include "core/html/parser/HTMLParserIdioms.h" | |
9 #include "core/platform/text/DecodeEscapeSequences.h" | |
10 | |
11 namespace WebCore { | |
12 | |
13 class ImageWithScale { | |
14 const String* m_source; | |
15 int m_start; | |
16 int m_length; | |
abarth-chromium
2013/09/13 22:24:06
Instead of having a String*, a start, and a length
| |
17 float m_scaleFactor; | |
abarth-chromium
2013/09/13 22:24:06
Please place private declarations after the public
| |
18 public: | |
19 ImageWithScale(const String* source, size_t start, size_t length, float scal eFactor) | |
20 : m_source(source) | |
21 , m_start(start) | |
22 , m_length(length) | |
23 , m_scaleFactor(scaleFactor) | |
24 { | |
25 } | |
26 bool operator==(const ImageWithScale& image) const | |
27 { | |
28 return m_scaleFactor == image.m_scaleFactor && m_source == image.m_sourc e && m_length == image.m_length && m_start == image.m_start; | |
29 } | |
30 String toString() const | |
abarth-chromium
2013/09/13 22:24:06
Please add blank lines between member functions.
| |
31 { | |
32 return String(m_source->characters8() + m_start, m_length); | |
abarth-chromium
2013/09/13 22:24:06
How do you know it's always 8 bits? Anyway, Strin
| |
33 } | |
34 float scaleFactor() const | |
35 { | |
36 return m_scaleFactor; | |
37 } | |
38 }; | |
39 typedef Vector<ImageWithScale> ImageCandidates; | |
abarth-chromium
2013/09/13 22:24:06
Please add a blank line between top-level declarat
| |
40 | |
41 static inline bool compareByScaleFactor(const ImageWithScale& first, const Image WithScale& second) | |
42 { | |
43 return first.scaleFactor() < second.scaleFactor(); | |
44 } | |
45 | |
46 static inline bool isHTMLSpaceOrComma(UChar character) | |
47 { | |
48 return isHTMLSpace(character) || character == ','; | |
49 } | |
abarth-chromium
2013/09/13 22:24:06
This function should got in HTMLParserIdioms.
| |
50 | |
51 // See the specifications for more details about the algorithm to follow. | |
abarth-chromium
2013/09/13 22:24:06
Please omit this line of the comment. The second
| |
52 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content- 1.html#processing-the-image-candidates | |
53 static void parseImagesWithScaleFromSrcSetAttribute(const String& srcSetAttribut e, ImageCandidates& imageCandidates) | |
54 { | |
55 size_t imageCandidateStart = 0; | |
abarth-chromium
2013/09/13 22:24:06
Lengths within strings are unsigned rather than si
| |
56 unsigned srcSetLength = srcSetAttribute.length(); | |
57 | |
58 while (imageCandidateStart < srcSetLength) { | |
59 float imgScaleFactor = 1.0; | |
60 size_t separator; | |
61 | |
62 // 4. Splitting loop: Skip whitespace. | |
63 size_t imageUrlStart = srcSetAttribute.find(isNotHTMLSpace, imageCandida teStart); | |
64 if (imageUrlStart == notFound) | |
65 break; | |
66 // If The current candidate is either totally empty or only contains spa ce, skipping. | |
67 if (srcSetAttribute[imageUrlStart] == ',') { | |
68 imageCandidateStart = imageUrlStart + 1; | |
69 continue; | |
70 } | |
71 // 5. Collect a sequence of characters that are not space characters, an d let that be url. | |
72 size_t imageUrlEnd = srcSetAttribute.find(isHTMLSpace, imageUrlStart + 1 ); | |
73 if (imageUrlEnd == notFound) { | |
74 imageUrlEnd = srcSetLength; | |
75 separator = srcSetLength; | |
76 } else if (srcSetAttribute[imageUrlEnd - 1] == ',') { | |
77 --imageUrlEnd; | |
78 separator = imageUrlEnd; | |
79 } else { | |
80 // 7. Collect a sequence of characters that are not "," (U+002C) cha racters, and let that be descriptors. | |
81 size_t imageScaleStart = srcSetAttribute.find(isNotHTMLSpace, imageU rlEnd + 1); | |
82 if (imageScaleStart == notFound) { | |
83 separator = srcSetLength; | |
84 } else if (srcSetAttribute[imageScaleStart] == ',') { | |
85 separator = imageScaleStart; | |
86 } else { | |
87 // This part differs from the spec as the current implementation only supports pixel density descriptors for now. | |
88 size_t imageScaleEnd = srcSetAttribute.find(isHTMLSpaceOrComma, imageScaleStart + 1); | |
89 imageScaleEnd = (imageScaleEnd == notFound) ? srcSetLength : ima geScaleEnd; | |
90 size_t comma = imageScaleEnd; | |
91 // Make sure there are no other descriptors | |
92 while ((comma < srcSetLength - 1) && isHTMLSpace(srcSetAttribute [comma])) | |
93 ++comma; | |
94 // If the first not html space character after the scale modifie r is not a comma, | |
95 // the current candidate is an invalid input. | |
96 if ((comma < srcSetLength - 1) && srcSetAttribute[comma] != ',') { | |
97 // Find the nearest comma and skip the input. | |
98 comma = srcSetAttribute.find(',', comma + 1); | |
99 if (comma == notFound) | |
100 break; | |
101 imageCandidateStart = comma + 1; | |
102 continue; | |
103 } | |
104 separator = comma; | |
105 if (srcSetAttribute[imageScaleEnd - 1] != 'x') { | |
106 imageCandidateStart = separator + 1; | |
107 continue; | |
108 } | |
109 bool validScaleFactor = false; | |
110 size_t scaleFactorLengthWithoutUnit = imageScaleEnd - imageScale Start - 1; | |
111 imgScaleFactor = charactersToFloat(srcSetAttribute.characters8() + imageScaleStart, scaleFactorLengthWithoutUnit, &validScaleFactor); | |
112 | |
113 if (!validScaleFactor) { | |
114 imageCandidateStart = separator + 1; | |
115 continue; | |
116 } | |
117 } | |
118 } | |
119 | |
120 imageCandidates.append(ImageWithScale(&srcSetAttribute, imageUrlStart, i mageUrlEnd - imageUrlStart, imgScaleFactor)); | |
121 // 11. Return to the step labeled splitting loop. | |
122 imageCandidateStart = separator + 1; | |
123 } | |
124 } | |
abarth-chromium
2013/09/13 22:24:06
This parsing algorithm is too hard to read. It's
| |
125 | |
126 String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& sr cAttribute, const String& srcSetAttribute) | |
127 { | |
128 ImageCandidates imageCandidates; | |
129 | |
130 parseImagesWithScaleFromSrcSetAttribute(srcSetAttribute, imageCandidates); | |
131 | |
132 const String src = srcAttribute.simplifyWhiteSpace(isHTMLSpace); | |
abarth-chromium
2013/09/13 22:24:06
You didn't address my previous review comments abo
| |
133 if (!src.isEmpty()) { | |
134 imageCandidates.append(ImageWithScale(&srcAttribute, 0, src.length(), 1. 0)); | |
135 } | |
abarth-chromium
2013/09/13 22:24:06
No need for { } for one-line if statements.
| |
136 | |
137 if (imageCandidates.isEmpty()) | |
138 return String(); | |
139 | |
140 std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareBySc aleFactor); | |
141 | |
142 size_t i; | |
143 for (i = 0; i < imageCandidates.size() - 1; ++i) { | |
144 if (imageCandidates[i].scaleFactor() >= deviceScaleFactor) | |
145 break; | |
146 } | |
147 return imageCandidates[i].toString(); | |
148 } | |
149 | |
150 } | |
OLD | NEW |