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 |