| OLD | NEW | 
| (Empty) |  | 
 |    1 /* | 
 |    2  * Copyright (C) 2013 Google Inc. All rights reserved. | 
 |    3  * | 
 |    4  * Redistribution and use in source and binary forms, with or without | 
 |    5  * modification, are permitted provided that the following conditions are | 
 |    6  * met: | 
 |    7  * | 
 |    8  *     * Redistributions of source code must retain the above copyright | 
 |    9  * notice, this list of conditions and the following disclaimer. | 
 |   10  *     * Redistributions in binary form must reproduce the above | 
 |   11  * copyright notice, this list of conditions and the following disclaimer | 
 |   12  * in the documentation and/or other materials provided with the | 
 |   13  * distribution. | 
 |   14  *     * Neither the name of Google Inc. nor the names of its | 
 |   15  * contributors may be used to endorse or promote products derived from | 
 |   16  * this software without specific prior written permission. | 
 |   17  * | 
 |   18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
 |   19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
 |   20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
 |   21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
 |   22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
 |   23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
 |   24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
 |   25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
 |   26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
 |   27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
 |   28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 |   29  */ | 
 |   30  | 
 |   31 #include "config.h" | 
 |   32 #include "core/html/parser/HTMLSrcsetParser.h" | 
 |   33  | 
 |   34 #include "core/html/parser/HTMLParserIdioms.h" | 
 |   35 #include "core/platform/ParsingUtilities.h" | 
 |   36  | 
 |   37 namespace WebCore { | 
 |   38  | 
 |   39 static bool compareByScaleFactor(const ImageCandidate& first, const ImageCandida
     te& second) | 
 |   40 { | 
 |   41     return first.scaleFactor() < second.scaleFactor(); | 
 |   42 } | 
 |   43  | 
 |   44 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-
     1.html#processing-the-image-candidates | 
 |   45 template<typename CharType> | 
 |   46 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, con
     st CharType* attributeStart, unsigned length, Vector<ImageCandidate>& imageCandi
     dates) | 
 |   47 { | 
 |   48     const CharType* position = attributeStart; | 
 |   49     const CharType* attributeEnd = position + length; | 
 |   50  | 
 |   51     while (position < attributeEnd) { | 
 |   52         float imgScaleFactor = 1.0; | 
 |   53         // 4. Splitting loop: Skip whitespace. | 
 |   54         skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd); | 
 |   55         if (position == attributeEnd) | 
 |   56             break; | 
 |   57         const CharType* imageURLStart = position; | 
 |   58  | 
 |   59         // If The current candidate is either totally empty or only contains spa
     ce, skipping. | 
 |   60         if (*position == ',') { | 
 |   61             ++position; | 
 |   62             continue; | 
 |   63         } | 
 |   64         // 5. Collect a sequence of characters that are not space characters, an
     d let that be url. | 
 |   65         ++position; | 
 |   66         skipUntil<CharType, isHTMLSpace<CharType> >(position, attributeEnd); | 
 |   67         const CharType* imageURLEnd = position; | 
 |   68  | 
 |   69         if (position != attributeEnd && *(position - 1) == ',') { | 
 |   70             --imageURLEnd; | 
 |   71         } else { | 
 |   72             // 7. Collect a sequence of characters that are not "," (U+002C) cha
     racters, and let that be descriptors. | 
 |   73             skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd); | 
 |   74             const CharType* qualifierStart = position; | 
 |   75             if (position != attributeEnd && *position != ',') { | 
 |   76                 // This part differs from the spec as the current implementation
      only supports pixel density descriptors for now. | 
 |   77                 skipUntil<CharType, isHTMLSpaceOrComma<CharType> >(position, att
     ributeEnd); | 
 |   78                 const CharType* qualifierEnd = position; | 
 |   79                 ASSERT(qualifierEnd > qualifierStart); | 
 |   80                 // Make sure there are no other descriptors | 
 |   81                 skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeE
     nd); | 
 |   82                 // If the first non-html-space character after the scale modifie
     r is not a comma, | 
 |   83                 // the current candidate is an invalid input. | 
 |   84                 if (position != attributeEnd && *position != ',') { | 
 |   85                     skipUntil<CharType>(position, attributeEnd, ','); | 
 |   86                     ++position; | 
 |   87                     continue; | 
 |   88                 } | 
 |   89                 // If the current qualifier is not an 'x', the resource is ignor
     ed | 
 |   90                 if (*(qualifierEnd - 1) != 'x') | 
 |   91                     continue; | 
 |   92  | 
 |   93                 bool validScaleFactor = false; | 
 |   94                 unsigned scaleFactorLengthWithoutUnit = qualifierEnd - qualifier
     Start - 1; | 
 |   95                 imgScaleFactor = charactersToFloat(qualifierStart, scaleFactorLe
     ngthWithoutUnit, &validScaleFactor); | 
 |   96  | 
 |   97                 if (!validScaleFactor) | 
 |   98                     continue; | 
 |   99             } | 
 |  100         } | 
 |  101  | 
 |  102         imageCandidates.append(ImageCandidate(attribute, imageURLStart - attribu
     teStart, imageURLEnd - imageURLStart, imgScaleFactor)); | 
 |  103         // 11. Return to the step labeled splitting loop. | 
 |  104     } | 
 |  105 } | 
 |  106  | 
 |  107 static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, Vec
     tor<ImageCandidate>& imageCandidates) | 
 |  108 { | 
 |  109     if (attribute.isNull()) | 
 |  110         return; | 
 |  111  | 
 |  112     if (attribute.is8Bit()) | 
 |  113         parseImageCandidatesFromSrcsetAttribute<LChar>(attribute, attribute.char
     acters8(), attribute.length(), imageCandidates); | 
 |  114     else | 
 |  115         parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.char
     acters16(), attribute.length(), imageCandidates); | 
 |  116 } | 
 |  117  | 
 |  118 static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, Vector<Ima
     geCandidate>& imageCandidates) | 
 |  119 { | 
 |  120     if (imageCandidates.isEmpty()) | 
 |  121         return ImageCandidate(); | 
 |  122  | 
 |  123     std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareBySc
     aleFactor); | 
 |  124  | 
 |  125     unsigned i; | 
 |  126     for (i = 0; i < imageCandidates.size() - 1; ++i) { | 
 |  127         if (imageCandidates[i].scaleFactor() >= deviceScaleFactor) | 
 |  128             break; | 
 |  129     } | 
 |  130     return imageCandidates[i]; | 
 |  131 } | 
 |  132  | 
 |  133 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const St
     ring& srcsetAttribute) | 
 |  134 { | 
 |  135     Vector<ImageCandidate> imageCandidates; | 
 |  136  | 
 |  137     parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); | 
 |  138  | 
 |  139     return pickBestImageCandidate(deviceScaleFactor, imageCandidates); | 
 |  140 } | 
 |  141  | 
 |  142 String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& sr
     cAttribute, const String& srcsetAttribute) | 
 |  143 { | 
 |  144     if (srcsetAttribute.isNull()) | 
 |  145         return srcAttribute; | 
 |  146  | 
 |  147     Vector<ImageCandidate> imageCandidates; | 
 |  148  | 
 |  149     parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates); | 
 |  150  | 
 |  151     if (!srcAttribute.isEmpty()) | 
 |  152         imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
     th(), 1.0)); | 
 |  153  | 
 |  154     return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString()
     ; | 
 |  155 } | 
 |  156  | 
 |  157 String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& sr
     cAttribute, ImageCandidate& srcsetImageCandidate) | 
 |  158 { | 
 |  159     if (srcsetImageCandidate.isEmpty()) | 
 |  160         return srcAttribute; | 
 |  161  | 
 |  162     Vector<ImageCandidate> imageCandidates; | 
 |  163     imageCandidates.append(srcsetImageCandidate); | 
 |  164  | 
 |  165     if (!srcAttribute.isEmpty()) | 
 |  166         imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.leng
     th(), 1.0)); | 
 |  167  | 
 |  168     return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString()
     ; | 
 |  169 } | 
 |  170  | 
 |  171 } | 
| OLD | NEW |