| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2013 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ | 30 */ |
| 31 | 31 |
| 32 #include "config.h" | 32 #include "config.h" |
| 33 #include "core/html/parser/HTMLSrcsetParser.h" | 33 #include "core/html/parser/HTMLSrcsetParser.h" |
| 34 | 34 |
| 35 #include "core/dom/Document.h" |
| 36 #include "core/frame/FrameConsole.h" |
| 37 #include "core/frame/LocalFrame.h" |
| 38 #include "core/frame/UseCounter.h" |
| 35 #include "core/html/parser/HTMLParserIdioms.h" | 39 #include "core/html/parser/HTMLParserIdioms.h" |
| 40 #include "core/inspector/ConsoleMessage.h" |
| 36 #include "platform/ParsingUtilities.h" | 41 #include "platform/ParsingUtilities.h" |
| 37 #include "platform/RuntimeEnabledFeatures.h" | 42 #include "platform/RuntimeEnabledFeatures.h" |
| 38 | 43 |
| 39 namespace blink { | 44 namespace blink { |
| 40 | 45 |
| 41 static bool compareByDensity(const ImageCandidate& first, const ImageCandidate&
second) | 46 static bool compareByDensity(const ImageCandidate& first, const ImageCandidate&
second) |
| 42 { | 47 { |
| 43 return first.density() < second.density(); | 48 return first.density() < second.density(); |
| 44 } | 49 } |
| 45 | 50 |
| 46 enum DescriptorTokenizerState { | 51 enum DescriptorTokenizerState { |
| 47 Start, | 52 TokenStart, |
| 48 InParenthesis, | 53 InParenthesis, |
| 49 AfterToken, | 54 AfterToken, |
| 50 }; | 55 }; |
| 51 | 56 |
| 52 struct DescriptorToken { | 57 struct DescriptorToken { |
| 53 unsigned start; | 58 unsigned start; |
| 54 unsigned length; | 59 unsigned length; |
| 55 | 60 |
| 56 DescriptorToken(unsigned start, unsigned length) | 61 DescriptorToken(unsigned start, unsigned length) |
| 57 : start(start) | 62 : start(start) |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 { | 122 { |
| 118 return position >= end; | 123 return position >= end; |
| 119 } | 124 } |
| 120 | 125 |
| 121 template<typename CharType> | 126 template<typename CharType> |
| 122 static void tokenizeDescriptors(const CharType* attributeStart, | 127 static void tokenizeDescriptors(const CharType* attributeStart, |
| 123 const CharType*& position, | 128 const CharType*& position, |
| 124 const CharType* attributeEnd, | 129 const CharType* attributeEnd, |
| 125 Vector<DescriptorToken>& descriptors) | 130 Vector<DescriptorToken>& descriptors) |
| 126 { | 131 { |
| 127 DescriptorTokenizerState state = Start; | 132 DescriptorTokenizerState state = TokenStart; |
| 128 const CharType* descriptorsStart = position; | 133 const CharType* descriptorsStart = position; |
| 129 const CharType* currentDescriptorStart = descriptorsStart; | 134 const CharType* currentDescriptorStart = descriptorsStart; |
| 130 while (true) { | 135 while (true) { |
| 131 switch (state) { | 136 switch (state) { |
| 132 case Start: | 137 case TokenStart: |
| 133 if (isEOF(position, attributeEnd)) { | 138 if (isEOF(position, attributeEnd)) { |
| 134 appendDescriptorAndReset(attributeStart, currentDescriptorStart,
attributeEnd, descriptors); | 139 appendDescriptorAndReset(attributeStart, currentDescriptorStart,
attributeEnd, descriptors); |
| 135 return; | 140 return; |
| 136 } | 141 } |
| 137 if (isComma(*position)) { | 142 if (isComma(*position)) { |
| 138 appendDescriptorAndReset(attributeStart, currentDescriptorStart,
position, descriptors); | 143 appendDescriptorAndReset(attributeStart, currentDescriptorStart,
position, descriptors); |
| 139 ++position; | 144 ++position; |
| 140 return; | 145 return; |
| 141 } | 146 } |
| 142 if (isHTMLSpace(*position)) { | 147 if (isHTMLSpace(*position)) { |
| 143 appendDescriptorAndReset(attributeStart, currentDescriptorStart,
position, descriptors); | 148 appendDescriptorAndReset(attributeStart, currentDescriptorStart,
position, descriptors); |
| 144 currentDescriptorStart = position + 1; | 149 currentDescriptorStart = position + 1; |
| 145 state = AfterToken; | 150 state = AfterToken; |
| 146 } else if (*position == '(') { | 151 } else if (*position == '(') { |
| 147 appendCharacter(currentDescriptorStart, position); | 152 appendCharacter(currentDescriptorStart, position); |
| 148 state = InParenthesis; | 153 state = InParenthesis; |
| 149 } else { | 154 } else { |
| 150 appendCharacter(currentDescriptorStart, position); | 155 appendCharacter(currentDescriptorStart, position); |
| 151 } | 156 } |
| 152 break; | 157 break; |
| 153 case InParenthesis: | 158 case InParenthesis: |
| 154 if (isEOF(position, attributeEnd)) { | 159 if (isEOF(position, attributeEnd)) { |
| 155 appendDescriptorAndReset(attributeStart, currentDescriptorStart,
attributeEnd, descriptors); | 160 appendDescriptorAndReset(attributeStart, currentDescriptorStart,
attributeEnd, descriptors); |
| 156 return; | 161 return; |
| 157 } | 162 } |
| 158 if (*position == ')') { | 163 if (*position == ')') { |
| 159 appendCharacter(currentDescriptorStart, position); | 164 appendCharacter(currentDescriptorStart, position); |
| 160 state = Start; | 165 state = TokenStart; |
| 161 } else { | 166 } else { |
| 162 appendCharacter(currentDescriptorStart, position); | 167 appendCharacter(currentDescriptorStart, position); |
| 163 } | 168 } |
| 164 break; | 169 break; |
| 165 case AfterToken: | 170 case AfterToken: |
| 166 if (isEOF(position, attributeEnd)) | 171 if (isEOF(position, attributeEnd)) |
| 167 return; | 172 return; |
| 168 if (!isHTMLSpace(*position)) { | 173 if (!isHTMLSpace(*position)) { |
| 169 state = Start; | 174 state = TokenStart; |
| 170 currentDescriptorStart = position; | 175 currentDescriptorStart = position; |
| 171 --position; | 176 --position; |
| 172 } | 177 } |
| 173 break; | 178 break; |
| 174 } | 179 } |
| 175 ++position; | 180 ++position; |
| 176 } | 181 } |
| 177 } | 182 } |
| 178 | 183 |
| 184 static void consoleMessage(Document* document, String message) |
| 185 { |
| 186 if (document && document->frame()) |
| 187 document->frame()->console().addMessage(ConsoleMessage::create(OtherMess
ageSource, ErrorMessageLevel, message)); |
| 188 } |
| 189 |
| 179 template<typename CharType> | 190 template<typename CharType> |
| 180 static bool parseDescriptors(const CharType* attribute, Vector<DescriptorToken>&
descriptors, DescriptorParsingResult& result) | 191 static bool parseDescriptors(const CharType* attribute, Vector<DescriptorToken>&
descriptors, DescriptorParsingResult& result, Document* document) |
| 181 { | 192 { |
| 182 for (Vector<DescriptorToken>::iterator it = descriptors.begin(); it != descr
iptors.end(); ++it) { | 193 for (Vector<DescriptorToken>::iterator it = descriptors.begin(); it != descr
iptors.end(); ++it) { |
| 183 if (it->length == 0) | 194 if (it->length == 0) |
| 184 continue; | 195 continue; |
| 185 CharType c = attribute[it->lastIndex()]; | 196 CharType c = attribute[it->lastIndex()]; |
| 186 bool isValid = false; | 197 bool isValid = false; |
| 187 if (RuntimeEnabledFeatures::pictureSizesEnabled() && c == 'w') { | 198 if (RuntimeEnabledFeatures::pictureSizesEnabled() && c == 'w') { |
| 188 if (result.hasDensity() || result.hasWidth()) | 199 if (result.hasDensity() || result.hasWidth()) { |
| 200 consoleMessage(document, "srcset has multiple 'w' descriptors or
a mix of 'x' and 'w' descriptors."); |
| 189 return false; | 201 return false; |
| 202 } |
| 190 int resourceWidth = it->toInt(attribute, isValid); | 203 int resourceWidth = it->toInt(attribute, isValid); |
| 191 if (!isValid || resourceWidth <= 0) | 204 if (!isValid || resourceWidth <= 0) { |
| 205 consoleMessage(document, "srcset 'w' descriptor is invalid."); |
| 192 return false; | 206 return false; |
| 207 } |
| 193 result.setResourceWidth(resourceWidth); | 208 result.setResourceWidth(resourceWidth); |
| 194 } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && c == 'h') { | 209 } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && c == 'h') { |
| 195 // This is here only for future compat purposes. | 210 // This is here only for future compat purposes. |
| 196 // The value of the 'h' descriptor is not used. | 211 // The value of the 'h' descriptor is not used. |
| 197 if (result.hasDensity() || result.hasHeight()) | 212 if (result.hasDensity() || result.hasHeight()) { |
| 213 consoleMessage(document, "srcset has multiple 'h' descriptors or
a mix of 'x' and 'h' descriptors."); |
| 198 return false; | 214 return false; |
| 215 } |
| 199 int resourceHeight = it->toInt(attribute, isValid); | 216 int resourceHeight = it->toInt(attribute, isValid); |
| 200 if (!isValid || resourceHeight <= 0) | 217 if (!isValid || resourceHeight <= 0) { |
| 218 consoleMessage(document, "srcset 'h' descriptor is invalid."); |
| 201 return false; | 219 return false; |
| 220 } |
| 202 result.setResourceHeight(resourceHeight); | 221 result.setResourceHeight(resourceHeight); |
| 203 } else if (c == 'x') { | 222 } else if (c == 'x') { |
| 204 if (result.hasDensity() || result.hasHeight() || result.hasWidth()) | 223 if (result.hasDensity() || result.hasHeight() || result.hasWidth())
{ |
| 224 consoleMessage(document, "srcset has multiple 'x' descriptors or
a mix of 'x' and 'w'/'h' descriptors."); |
| 205 return false; | 225 return false; |
| 226 } |
| 206 float density = it->toFloat(attribute, isValid); | 227 float density = it->toFloat(attribute, isValid); |
| 207 if (!isValid || density < 0) | 228 if (!isValid || density < 0) { |
| 229 consoleMessage(document, "srcset 'x' descriptor is invalid."); |
| 208 return false; | 230 return false; |
| 231 } |
| 209 result.setDensity(density); | 232 result.setDensity(density); |
| 210 } else { | 233 } else { |
| 234 consoleMessage(document, "srcset has an unknown descriptor."); |
| 211 return false; | 235 return false; |
| 212 } | 236 } |
| 213 } | 237 } |
| 214 return (!result.hasHeight() || result.hasWidth()); | 238 bool res = !result.hasHeight() || result.hasWidth(); |
| 239 if (!res) |
| 240 consoleMessage(document, "srcset has an 'h' descriptor and no 'w' descri
ptor."); |
| 241 return res; |
| 215 } | 242 } |
| 216 | 243 |
| 217 static bool parseDescriptors(const String& attribute, Vector<DescriptorToken>& d
escriptors, DescriptorParsingResult& result) | 244 static bool parseDescriptors(const String& attribute, Vector<DescriptorToken>& d
escriptors, DescriptorParsingResult& result, Document* document) |
| 218 { | 245 { |
| 219 // FIXME: See if StringView can't be extended to replace DescriptorToken her
e. | 246 // FIXME: See if StringView can't be extended to replace DescriptorToken her
e. |
| 220 if (attribute.is8Bit()) { | 247 if (attribute.is8Bit()) { |
| 221 return parseDescriptors(attribute.characters8(), descriptors, result); | 248 return parseDescriptors(attribute.characters8(), descriptors, result, do
cument); |
| 222 } | 249 } |
| 223 return parseDescriptors(attribute.characters16(), descriptors, result); | 250 return parseDescriptors(attribute.characters16(), descriptors, result, docum
ent); |
| 224 } | 251 } |
| 225 | 252 |
| 226 // http://picture.responsiveimages.org/#parse-srcset-attr | 253 // http://picture.responsiveimages.org/#parse-srcset-attr |
| 227 template<typename CharType> | 254 template<typename CharType> |
| 228 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, con
st CharType* attributeStart, unsigned length, Vector<ImageCandidate>& imageCandi
dates) | 255 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, con
st CharType* attributeStart, unsigned length, Vector<ImageCandidate>& imageCandi
dates, Document* document) |
| 229 { | 256 { |
| 230 const CharType* position = attributeStart; | 257 const CharType* position = attributeStart; |
| 231 const CharType* attributeEnd = position + length; | 258 const CharType* attributeEnd = position + length; |
| 232 | 259 |
| 233 while (position < attributeEnd) { | 260 while (position < attributeEnd) { |
| 234 // 4. Splitting loop: Collect a sequence of characters that are space ch
aracters or U+002C COMMA characters. | 261 // 4. Splitting loop: Collect a sequence of characters that are space ch
aracters or U+002C COMMA characters. |
| 235 skipWhile<CharType, isHTMLSpaceOrComma<CharType> >(position, attributeEn
d); | 262 skipWhile<CharType, isHTMLSpaceOrComma<CharType> >(position, attributeEn
d); |
| 236 if (position == attributeEnd) { | 263 if (position == attributeEnd) { |
| 237 // Contrary to spec language - descriptor parsing happens on each ca
ndidate, so when we reach the attributeEnd, we can exit. | 264 // Contrary to spec language - descriptor parsing happens on each ca
ndidate, so when we reach the attributeEnd, we can exit. |
| 238 break; | 265 break; |
| 239 } | 266 } |
| 240 const CharType* imageURLStart = position; | 267 const CharType* imageURLStart = position; |
| 268 |
| 241 // 6. Collect a sequence of characters that are not space characters, an
d let that be url. | 269 // 6. Collect a sequence of characters that are not space characters, an
d let that be url. |
| 242 | |
| 243 skipUntil<CharType, isHTMLSpace<CharType> >(position, attributeEnd); | 270 skipUntil<CharType, isHTMLSpace<CharType> >(position, attributeEnd); |
| 244 const CharType* imageURLEnd = position; | 271 const CharType* imageURLEnd = position; |
| 245 | 272 |
| 246 DescriptorParsingResult result; | 273 DescriptorParsingResult result; |
| 247 | 274 |
| 248 // 8. If url ends with a U+002C COMMA character (,) | 275 // 8. If url ends with a U+002C COMMA character (,) |
| 249 if (isComma(*(position - 1))) { | 276 if (isComma(*(position - 1))) { |
| 250 // Remove all trailing U+002C COMMA characters from url. | 277 // Remove all trailing U+002C COMMA characters from url. |
| 251 imageURLEnd = position - 1; | 278 imageURLEnd = position - 1; |
| 252 reverseSkipWhile<CharType, isComma>(imageURLEnd, imageURLStart); | 279 reverseSkipWhile<CharType, isComma>(imageURLEnd, imageURLStart); |
| 253 ++imageURLEnd; | 280 ++imageURLEnd; |
| 254 // If url is empty, then jump to the step labeled splitting loop. | 281 // If url is empty, then jump to the step labeled splitting loop. |
| 255 if (imageURLStart == imageURLEnd) | 282 if (imageURLStart == imageURLEnd) |
| 256 continue; | 283 continue; |
| 257 } else { | 284 } else { |
| 258 // Advancing position here (contrary to spec) to avoid an useless ex
tra state machine step. | 285 skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd); |
| 259 // Filed a spec bug: https://github.com/ResponsiveImagesCG/picture-e
lement/issues/189 | |
| 260 ++position; | |
| 261 Vector<DescriptorToken> descriptorTokens; | 286 Vector<DescriptorToken> descriptorTokens; |
| 262 tokenizeDescriptors(attributeStart, position, attributeEnd, descript
orTokens); | 287 tokenizeDescriptors(attributeStart, position, attributeEnd, descript
orTokens); |
| 263 // Contrary to spec language - descriptor parsing happens on each ca
ndidate. | 288 // Contrary to spec language - descriptor parsing happens on each ca
ndidate. |
| 264 // This is a black-box equivalent, to avoid storing descriptor lists
for each candidate. | 289 // This is a black-box equivalent, to avoid storing descriptor lists
for each candidate. |
| 265 if (!parseDescriptors(attribute, descriptorTokens, result)) | 290 if (!parseDescriptors(attribute, descriptorTokens, result, document)
) { |
| 291 if (document) { |
| 292 UseCounter::count(document, UseCounter::SrcsetDroppedCandida
te); |
| 293 if (document->frame()) |
| 294 document->frame()->console().addMessage(ConsoleMessage::
create(OtherMessageSource, ErrorMessageLevel, String("Dropped srcset candidate "
) + String(imageURLStart, imageURLEnd - imageURLStart))); |
| 295 } |
| 266 continue; | 296 continue; |
| 297 } |
| 267 } | 298 } |
| 268 | 299 |
| 269 ASSERT(imageURLEnd > attributeStart); | 300 ASSERT(imageURLEnd > attributeStart); |
| 270 unsigned imageURLStartingPosition = imageURLStart - attributeStart; | 301 unsigned imageURLStartingPosition = imageURLStart - attributeStart; |
| 271 ASSERT(imageURLEnd > imageURLStart); | 302 ASSERT(imageURLEnd > imageURLStart); |
| 272 unsigned imageURLLength = imageURLEnd - imageURLStart; | 303 unsigned imageURLLength = imageURLEnd - imageURLStart; |
| 273 imageCandidates.append(ImageCandidate(attribute, imageURLStartingPositio
n, imageURLLength, result, ImageCandidate::SrcsetOrigin)); | 304 imageCandidates.append(ImageCandidate(attribute, imageURLStartingPositio
n, imageURLLength, result, ImageCandidate::SrcsetOrigin)); |
| 274 // 11. Return to the step labeled splitting loop. | 305 // 11. Return to the step labeled splitting loop. |
| 275 } | 306 } |
| 276 } | 307 } |
| 277 | 308 |
| 278 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, Vec
tor<ImageCandidate>& imageCandidates) | 309 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, Vec
tor<ImageCandidate>& imageCandidates, Document* document) |
| 279 { | 310 { |
| 280 if (attribute.isNull()) | 311 if (attribute.isNull()) |
| 281 return; | 312 return; |
| 282 | 313 |
| 283 if (attribute.is8Bit()) | 314 if (attribute.is8Bit()) |
| 284 parseImageCandidatesFromSrcsetAttribute<LChar>(attribute, attribute.char
acters8(), attribute.length(), imageCandidates); | 315 parseImageCandidatesFromSrcsetAttribute<LChar>(attribute, attribute.char
acters8(), attribute.length(), imageCandidates, document); |
| 285 else | 316 else |
| 286 parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.char
acters16(), attribute.length(), imageCandidates); | 317 parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.char
acters16(), attribute.length(), imageCandidates, document); |
| 287 } | 318 } |
| 288 | 319 |
| 289 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, float sour
ceSize, Vector<ImageCandidate>& imageCandidates) | 320 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, float sour
ceSize, Vector<ImageCandidate>& imageCandidates) |
| 290 { | 321 { |
| 291 const float defaultDensityValue = 1.0; | 322 const float defaultDensityValue = 1.0; |
| 292 bool ignoreSrc = false; | 323 bool ignoreSrc = false; |
| 293 if (imageCandidates.isEmpty()) | 324 if (imageCandidates.isEmpty()) |
| 294 return ImageCandidate(); | 325 return ImageCandidate(); |
| 295 | 326 |
| 296 // http://picture.responsiveimages.org/#normalize-source-densities | 327 // http://picture.responsiveimages.org/#normalize-source-densities |
| (...skipping 22 matching lines...) Expand all Loading... |
| 319 | 350 |
| 320 unsigned winner = i; | 351 unsigned winner = i; |
| 321 // 16. If an entry b in candidates has the same associated ... pixel density
as an earlier entry a in candidates, | 352 // 16. If an entry b in candidates has the same associated ... pixel density
as an earlier entry a in candidates, |
| 322 // then remove entry b | 353 // then remove entry b |
| 323 while ((i > 0) && (imageCandidates[--i].density() == winningDensity)) | 354 while ((i > 0) && (imageCandidates[--i].density() == winningDensity)) |
| 324 winner = i; | 355 winner = i; |
| 325 | 356 |
| 326 return imageCandidates[winner]; | 357 return imageCandidates[winner]; |
| 327 } | 358 } |
| 328 | 359 |
| 329 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, float so
urceSize, const String& srcsetAttribute) | 360 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, float so
urceSize, const String& srcsetAttribute, Document* document) |
| 330 { | 361 { |
| 331 Vector<ImageCandidate> imageCandidates; | 362 Vector<ImageCandidate> imageCandidates; |
| 332 | 363 |
| 333 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); | 364 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates, do
cument); |
| 334 | 365 |
| 335 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates
); | 366 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates
); |
| 336 } | 367 } |
| 337 | 368 |
| 338 ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, float so
urceSize, const String& srcAttribute, const String& srcsetAttribute) | 369 ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, float so
urceSize, const String& srcAttribute, const String& srcsetAttribute, Document* d
ocument) |
| 339 { | 370 { |
| 340 if (srcsetAttribute.isNull()) { | 371 if (srcsetAttribute.isNull()) { |
| 341 if (srcAttribute.isNull()) | 372 if (srcAttribute.isNull()) |
| 342 return ImageCandidate(); | 373 return ImageCandidate(); |
| 343 return ImageCandidate(srcAttribute, 0, srcAttribute.length(), Descriptor
ParsingResult(), ImageCandidate::SrcOrigin); | 374 return ImageCandidate(srcAttribute, 0, srcAttribute.length(), Descriptor
ParsingResult(), ImageCandidate::SrcOrigin); |
| 344 } | 375 } |
| 345 | 376 |
| 346 Vector<ImageCandidate> imageCandidates; | 377 Vector<ImageCandidate> imageCandidates; |
| 347 | 378 |
| 348 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); | 379 parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates, do
cument); |
| 349 | 380 |
| 350 if (!srcAttribute.isEmpty()) | 381 if (!srcAttribute.isEmpty()) |
| 351 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), DescriptorParsingResult(), ImageCandidate::SrcOrigin)); | 382 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), DescriptorParsingResult(), ImageCandidate::SrcOrigin)); |
| 352 | 383 |
| 353 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates
); | 384 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates
); |
| 354 } | 385 } |
| 355 | 386 |
| 356 String bestFitSourceForImageAttributes(float deviceScaleFactor, float sourceSize
, const String& srcAttribute, ImageCandidate& srcsetImageCandidate) | 387 String bestFitSourceForImageAttributes(float deviceScaleFactor, float sourceSize
, const String& srcAttribute, ImageCandidate& srcsetImageCandidate) |
| 357 { | 388 { |
| 358 if (srcsetImageCandidate.isEmpty()) | 389 if (srcsetImageCandidate.isEmpty()) |
| 359 return srcAttribute; | 390 return srcAttribute; |
| 360 | 391 |
| 361 Vector<ImageCandidate> imageCandidates; | 392 Vector<ImageCandidate> imageCandidates; |
| 362 imageCandidates.append(srcsetImageCandidate); | 393 imageCandidates.append(srcsetImageCandidate); |
| 363 | 394 |
| 364 if (!srcAttribute.isEmpty()) | 395 if (!srcAttribute.isEmpty()) |
| 365 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), DescriptorParsingResult(), ImageCandidate::SrcOrigin)); | 396 imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
th(), DescriptorParsingResult(), ImageCandidate::SrcOrigin)); |
| 366 | 397 |
| 367 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates
).toString(); | 398 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates
).toString(); |
| 368 } | 399 } |
| 369 | 400 |
| 370 } | 401 } |
| OLD | NEW |