Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: Source/core/html/parser/HTMLSrcsetParser.cpp

Issue 23861003: Enable srcset support in HTMLImageElement (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Addressed issues raised in review. Merged Romain Perier's new parser implementation. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698