| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 if (position > descriptorStart) | 109 if (position > descriptorStart) |
| 110 descriptors.append(DescriptorToken(descriptorStart - attributeStart, | 110 descriptors.append(DescriptorToken(descriptorStart - attributeStart, |
| 111 position - descriptorStart)); | 111 position - descriptorStart)); |
| 112 descriptorStart = 0; | 112 descriptorStart = 0; |
| 113 } | 113 } |
| 114 | 114 |
| 115 // The following is called appendCharacter to match the spec's terminology. | 115 // The following is called appendCharacter to match the spec's terminology. |
| 116 template <typename CharType> | 116 template <typename CharType> |
| 117 static void appendCharacter(const CharType* descriptorStart, | 117 static void appendCharacter(const CharType* descriptorStart, |
| 118 const CharType* position) { | 118 const CharType* position) { |
| 119 // Since we don't copy the tokens, this just set the point where the descripto
r tokens start. | 119 // Since we don't copy the tokens, this just set the point where the |
| 120 // descriptor tokens start. |
| 120 if (!descriptorStart) | 121 if (!descriptorStart) |
| 121 descriptorStart = position; | 122 descriptorStart = position; |
| 122 } | 123 } |
| 123 | 124 |
| 124 template <typename CharType> | 125 template <typename CharType> |
| 125 static bool isEOF(const CharType* position, const CharType* end) { | 126 static bool isEOF(const CharType* position, const CharType* end) { |
| 126 return position >= end; | 127 return position >= end; |
| 127 } | 128 } |
| 128 | 129 |
| 129 template <typename CharType> | 130 template <typename CharType> |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 "descriptors."); | 215 "descriptors."); |
| 215 return false; | 216 return false; |
| 216 } | 217 } |
| 217 int resourceWidth = descriptor.toInt(attribute, isValid); | 218 int resourceWidth = descriptor.toInt(attribute, isValid); |
| 218 if (!isValid || resourceWidth <= 0) { | 219 if (!isValid || resourceWidth <= 0) { |
| 219 srcsetError(document, "its 'w' descriptor is invalid."); | 220 srcsetError(document, "its 'w' descriptor is invalid."); |
| 220 return false; | 221 return false; |
| 221 } | 222 } |
| 222 result.setResourceWidth(resourceWidth); | 223 result.setResourceWidth(resourceWidth); |
| 223 } else if (c == 'h') { | 224 } else if (c == 'h') { |
| 224 // This is here only for future compat purposes. | 225 // This is here only for future compat purposes. The value of the 'h' |
| 225 // The value of the 'h' descriptor is not used. | 226 // descriptor is not used. |
| 226 if (result.hasDensity() || result.hasHeight()) { | 227 if (result.hasDensity() || result.hasHeight()) { |
| 227 srcsetError(document, | 228 srcsetError(document, |
| 228 "it has multiple 'h' descriptors or a mix of 'x' and 'h' " | 229 "it has multiple 'h' descriptors or a mix of 'x' and 'h' " |
| 229 "descriptors."); | 230 "descriptors."); |
| 230 return false; | 231 return false; |
| 231 } | 232 } |
| 232 int resourceHeight = descriptor.toInt(attribute, isValid); | 233 int resourceHeight = descriptor.toInt(attribute, isValid); |
| 233 if (!isValid || resourceHeight <= 0) { | 234 if (!isValid || resourceHeight <= 0) { |
| 234 srcsetError(document, "its 'h' descriptor is invalid."); | 235 srcsetError(document, "its 'h' descriptor is invalid."); |
| 235 return false; | 236 return false; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 static void parseImageCandidatesFromSrcsetAttribute( | 278 static void parseImageCandidatesFromSrcsetAttribute( |
| 278 const String& attribute, | 279 const String& attribute, |
| 279 const CharType* attributeStart, | 280 const CharType* attributeStart, |
| 280 unsigned length, | 281 unsigned length, |
| 281 Vector<ImageCandidate>& imageCandidates, | 282 Vector<ImageCandidate>& imageCandidates, |
| 282 Document* document) { | 283 Document* document) { |
| 283 const CharType* position = attributeStart; | 284 const CharType* position = attributeStart; |
| 284 const CharType* attributeEnd = position + length; | 285 const CharType* attributeEnd = position + length; |
| 285 | 286 |
| 286 while (position < attributeEnd) { | 287 while (position < attributeEnd) { |
| 287 // 4. Splitting loop: Collect a sequence of characters that are space charac
ters or U+002C COMMA characters. | 288 // 4. Splitting loop: Collect a sequence of characters that are space |
| 289 // characters or U+002C COMMA characters. |
| 288 skipWhile<CharType, isHTMLSpaceOrComma<CharType>>(position, attributeEnd); | 290 skipWhile<CharType, isHTMLSpaceOrComma<CharType>>(position, attributeEnd); |
| 289 if (position == attributeEnd) { | 291 if (position == attributeEnd) { |
| 290 // Contrary to spec language - descriptor parsing happens on each candidat
e, so when we reach the attributeEnd, we can exit. | 292 // Contrary to spec language - descriptor parsing happens on each |
| 293 // candidate, so when we reach the attributeEnd, we can exit. |
| 291 break; | 294 break; |
| 292 } | 295 } |
| 293 const CharType* imageURLStart = position; | 296 const CharType* imageURLStart = position; |
| 294 | 297 |
| 295 // 6. Collect a sequence of characters that are not space characters, and le
t that be url. | 298 // 6. Collect a sequence of characters that are not space characters, and |
| 299 // let that be url. |
| 296 skipUntil<CharType, isHTMLSpace<CharType>>(position, attributeEnd); | 300 skipUntil<CharType, isHTMLSpace<CharType>>(position, attributeEnd); |
| 297 const CharType* imageURLEnd = position; | 301 const CharType* imageURLEnd = position; |
| 298 | 302 |
| 299 DescriptorParsingResult result; | 303 DescriptorParsingResult result; |
| 300 | 304 |
| 301 // 8. If url ends with a U+002C COMMA character (,) | 305 // 8. If url ends with a U+002C COMMA character (,) |
| 302 if (isComma(*(position - 1))) { | 306 if (isComma(*(position - 1))) { |
| 303 // Remove all trailing U+002C COMMA characters from url. | 307 // Remove all trailing U+002C COMMA characters from url. |
| 304 imageURLEnd = position - 1; | 308 imageURLEnd = position - 1; |
| 305 reverseSkipWhile<CharType, isComma>(imageURLEnd, imageURLStart); | 309 reverseSkipWhile<CharType, isComma>(imageURLEnd, imageURLStart); |
| 306 ++imageURLEnd; | 310 ++imageURLEnd; |
| 307 // If url is empty, then jump to the step labeled splitting loop. | 311 // If url is empty, then jump to the step labeled splitting loop. |
| 308 if (imageURLStart == imageURLEnd) | 312 if (imageURLStart == imageURLEnd) |
| 309 continue; | 313 continue; |
| 310 } else { | 314 } else { |
| 311 skipWhile<CharType, isHTMLSpace<CharType>>(position, attributeEnd); | 315 skipWhile<CharType, isHTMLSpace<CharType>>(position, attributeEnd); |
| 312 Vector<DescriptorToken> descriptorTokens; | 316 Vector<DescriptorToken> descriptorTokens; |
| 313 tokenizeDescriptors(attributeStart, position, attributeEnd, | 317 tokenizeDescriptors(attributeStart, position, attributeEnd, |
| 314 descriptorTokens); | 318 descriptorTokens); |
| 315 // Contrary to spec language - descriptor parsing happens on each candidat
e. | 319 // Contrary to spec language - descriptor parsing happens on each |
| 316 // This is a black-box equivalent, to avoid storing descriptor lists for e
ach candidate. | 320 // candidate. This is a black-box equivalent, to avoid storing descriptor |
| 321 // lists for each candidate. |
| 317 if (!parseDescriptors(attribute, descriptorTokens, result, document)) { | 322 if (!parseDescriptors(attribute, descriptorTokens, result, document)) { |
| 318 if (document) { | 323 if (document) { |
| 319 UseCounter::count(document, UseCounter::SrcsetDroppedCandidate); | 324 UseCounter::count(document, UseCounter::SrcsetDroppedCandidate); |
| 320 if (document->frame()) | 325 if (document->frame()) |
| 321 document->frame()->console().addMessage(ConsoleMessage::create( | 326 document->frame()->console().addMessage(ConsoleMessage::create( |
| 322 OtherMessageSource, ErrorMessageLevel, | 327 OtherMessageSource, ErrorMessageLevel, |
| 323 String("Dropped srcset candidate ") + | 328 String("Dropped srcset candidate ") + |
| 324 JSONValue::quoteString( | 329 JSONValue::quoteString( |
| 325 String(imageURLStart, imageURLEnd - imageURLStart)))); | 330 String(imageURLStart, imageURLEnd - imageURLStart)))); |
| 326 } | 331 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 if (image.density() != prevDensity && (!ignoreSrc || !image.srcOrigin())) | 430 if (image.density() != prevDensity && (!ignoreSrc || !image.srcOrigin())) |
| 426 deDupedImageCandidates.append(&image); | 431 deDupedImageCandidates.append(&image); |
| 427 prevDensity = image.density(); | 432 prevDensity = image.density(); |
| 428 } | 433 } |
| 429 unsigned winner = selectionLogic(deDupedImageCandidates, deviceScaleFactor); | 434 unsigned winner = selectionLogic(deDupedImageCandidates, deviceScaleFactor); |
| 430 ASSERT(winner < deDupedImageCandidates.size()); | 435 ASSERT(winner < deDupedImageCandidates.size()); |
| 431 winner = avoidDownloadIfHigherDensityResourceIsInCache(deDupedImageCandidates, | 436 winner = avoidDownloadIfHigherDensityResourceIsInCache(deDupedImageCandidates, |
| 432 winner, document); | 437 winner, document); |
| 433 | 438 |
| 434 float winningDensity = deDupedImageCandidates[winner]->density(); | 439 float winningDensity = deDupedImageCandidates[winner]->density(); |
| 435 // 16. If an entry b in candidates has the same associated ... pixel density a
s an earlier entry a in candidates, | 440 // 16. If an entry b in candidates has the same associated ... pixel density |
| 441 // as an earlier entry a in candidates, |
| 436 // then remove entry b | 442 // then remove entry b |
| 437 while ((winner > 0) && | 443 while ((winner > 0) && |
| 438 (deDupedImageCandidates[winner - 1]->density() == winningDensity)) | 444 (deDupedImageCandidates[winner - 1]->density() == winningDensity)) |
| 439 --winner; | 445 --winner; |
| 440 | 446 |
| 441 return *deDupedImageCandidates[winner]; | 447 return *deDupedImageCandidates[winner]; |
| 442 } | 448 } |
| 443 | 449 |
| 444 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, | 450 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, |
| 445 float sourceSize, | 451 float sourceSize, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 if (!srcAttribute.isEmpty()) | 499 if (!srcAttribute.isEmpty()) |
| 494 imageCandidates.append( | 500 imageCandidates.append( |
| 495 ImageCandidate(srcAttribute, 0, srcAttribute.length(), | 501 ImageCandidate(srcAttribute, 0, srcAttribute.length(), |
| 496 DescriptorParsingResult(), ImageCandidate::SrcOrigin)); | 502 DescriptorParsingResult(), ImageCandidate::SrcOrigin)); |
| 497 | 503 |
| 498 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates) | 504 return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates) |
| 499 .toString(); | 505 .toString(); |
| 500 } | 506 } |
| 501 | 507 |
| 502 } // namespace blink | 508 } // namespace blink |
| OLD | NEW |