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. | |
| 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 |