Changeset 153624 in webkit


Ignore:
Timestamp:
Aug 1, 2013 5:00:29 PM (11 years ago)
Author:
dino@apple.com
Message:

Implement img element's srcset attribute
https://bugs.webkit.org/show_bug.cgi?id=110252

Patch by Romain Perier <Romain Perier> on 2013-08-01
Reviewed by Dean Jackson.

Source/WebCore:

Tests: fast/hidpi/image-srcset-simple.html

fast/hidpi/image-srcset-src-selection.html
fast/hidpi/image-srcset-simple.html
fast/hidpi/image-srcset-src-selection.html
fast/hidpi/image-srcset-only-src-attribute.html
fast/hidpi/image-srcset-same-alternative-for-both-attributes.html
fast/hidpi/image-srcset-invalid-inputs.html
fast/hidpi/image-srcset-invalid-inputs-except-one.html
fast/hidpi/image-srcset-invalid-inputs-correct-src.html
fast/hidpi/image-srcset-change-dynamically-from-js.html
fast/hidpi/image-srcset-remove-dynamically-from-js.html

  • html/HTMLAttributeNames.in: Add srcset attribute.
  • html/HTMLImageElement.cpp:

(WebCore::HTMLImageElement::HTMLImageElement):
Adding initialization for new variables member.
(WebCore::HTMLImageElement::imageSourceURL):
Override this method to return the choosen image transparently to the ImageLoader.
(WebCore::HTMLImageElement::updateBestImageForScaleFactor):
New method to select the good image candidate dependending on the scale factor. This method is separated from
parsing because it will be useful for selecting a new image candidate on the fly if the device scale factor changes.
(WebCore::HTMLImageElement::updateImagesFromSrcSet):
New method for parsing the srcset attribute and build a list of images with the corresponding scale factor.
(WebCore::HTMLImageElement::parseAttribute):
Adding support for processing the image candidates, select the good one and call ImageLoader for rendering.

  • html/HTMLImageElement.h:
  • Adding new methods declarations.
  • Adding new type definition.
  • Adding new variable member to store the URL of the choosen image.
  • Adding new variable member to store the index of the src image.
  • Adding new Vector to store the list of images after parsing.
  • html/HTMLImageElement.idl: Adding srcset attribute for the differents existing bidings.

LayoutTests:

  • fast/hidpi/image-srcset-simple.html: Ensures that the good image

is selected from srcset by the user agent according to the choosen scale factor.

  • fast/hidpi/image-srcset-src-selection.html: Ensures that the image

from the src attribute is collected by the parsing algorithm and selected by the user agent
when no other candidate matches the scale factor.

  • fast/hidpi/image-srcset-only-src-attribute.html: Ensures that the algorithms used for srcset

does not change the behaviour of the src attribute when the srcset attribute is not defined,
even using scale factor greater than 1.

  • fast/hidpi/image-srcset-same-alternative-for-both-attributes.html: Ensures that the good image

is selected by the user agent when src and srcset contain an image with a scale factor of 1.

  • fast/hidpi/image-srcset-invalid-inputs.html: Ensures that the parsing and the selection

algorithms support invalid inputs. Theses ones are simply ignored.

  • fast/hidpi/image-srcset-invalid-inputs-except-one.html: Ensures that a valid image

is selected even if this one is part of a set containing invalid inputs.

  • fast/hidpi/image-srcset-invalid-inputs-correct-src.html: Ensures that the image from

the src attribute is choosen when srcset contains only invalid inputs, this selection
should not depend on the scale factor.

  • fast/hidpi/image-srcset-change-dynamically-from-js.html: Ensures that src and srcset attributes

can be changed dynamically from javascript.

  • fast/hidpi/image-srcset-remove-dynamically-from-js.html: Ensures that src attribute

can be removed dynamically from javascript.

  • platform/mac/fast/hidpi/image-srcset-simple-expected.png:
  • platform/mac/fast/hidpi/image-srcset-simple-expected.txt:
  • platform/mac/fast/hidpi/image-srcset-src-selection-expected.png:
  • platform/mac/fast/hidpi/image-srcset-src-selection-expected.txt:
  • platform/mac/fast/hidpi/image-srcset-only-src-attribute-expected.png:
  • platform/mac/fast/hidpi/image-srcset-only-src-attribute-expected.txt:
  • platform/mac/fast/hidpi/image-srcset-same-alternative-for-both-attributes-expected.png:
  • platform/mac/fast/hidpi/image-srcset-same-alternative-for-both-attributes-expected.txt:
  • platform/mac/fast/hidpi/image-srcset-invalid-inputs-expected.png:
  • platform/mac/fast/hidpi/image-srcset-invalid-inputs-expected.txt:
  • platform/mac/fast/hidpi/image-srcset-invalid-inputs-except-one-expected.png:
  • platform/mac/fast/hidpi/image-srcset-invalid-inputs-except-one-expected.txt:
  • platform/mac/fast/hidpi/image-srcset-invalid-inputs-correct-src-expected.png:
  • platform/mac/fast/hidpi/image-srcset-invalid-inputs-correct-src-expected.txt:
  • platform/mac/fast/hidpi/image-srcset-change-dynamically-from-js-expected.png:
  • platform/mac/fast/hidpi/image-srcset-change-dynamically-from-js-expected.txt:
  • platform/mac/fast/hidpi/image-srcset-remove-dynamically-from-js-expected.png:
  • platform/mac/fast/hidpi/image-srcset-remove-dynamically-from-js-expected.txt:
Location:
trunk
Files:
27 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r153623 r153624  
     12013-08-01  Romain Perier  <romain.perier@gmail.com>
     2
     3        Implement img element's srcset attribute
     4        https://bugs.webkit.org/show_bug.cgi?id=110252
     5
     6        Reviewed by Dean Jackson.
     7
     8        * fast/hidpi/image-srcset-simple.html: Ensures that the good image
     9        is selected from srcset by the user agent according to the choosen scale factor.
     10        * fast/hidpi/image-srcset-src-selection.html: Ensures that the image
     11        from the src attribute is collected by the parsing algorithm and selected by the user agent
     12        when no other candidate matches the scale factor.
     13        * fast/hidpi/image-srcset-only-src-attribute.html: Ensures that the algorithms used for srcset
     14        does not change the behaviour of the src attribute when the srcset attribute is not defined,
     15        even using scale factor greater than 1.
     16        * fast/hidpi/image-srcset-same-alternative-for-both-attributes.html: Ensures that the good image
     17        is selected by the user agent when src and srcset contain an image with a scale factor of 1.
     18        * fast/hidpi/image-srcset-invalid-inputs.html: Ensures that the parsing and the selection
     19        algorithms support invalid inputs. Theses ones are simply ignored.
     20        * fast/hidpi/image-srcset-invalid-inputs-except-one.html: Ensures that a valid image
     21        is selected even if this one is part of a set containing invalid inputs.
     22        * fast/hidpi/image-srcset-invalid-inputs-correct-src.html: Ensures that the image from
     23        the src attribute is choosen when srcset contains only invalid inputs, this selection
     24        should not depend on the scale factor.
     25        * fast/hidpi/image-srcset-change-dynamically-from-js.html: Ensures that src and srcset attributes
     26        can be changed dynamically from javascript.
     27        * fast/hidpi/image-srcset-remove-dynamically-from-js.html: Ensures that src attribute
     28        can be removed dynamically from javascript.
     29        * platform/mac/fast/hidpi/image-srcset-simple-expected.png:
     30        * platform/mac/fast/hidpi/image-srcset-simple-expected.txt:
     31        * platform/mac/fast/hidpi/image-srcset-src-selection-expected.png:
     32        * platform/mac/fast/hidpi/image-srcset-src-selection-expected.txt:
     33        * platform/mac/fast/hidpi/image-srcset-only-src-attribute-expected.png:
     34        * platform/mac/fast/hidpi/image-srcset-only-src-attribute-expected.txt:
     35        * platform/mac/fast/hidpi/image-srcset-same-alternative-for-both-attributes-expected.png:
     36        * platform/mac/fast/hidpi/image-srcset-same-alternative-for-both-attributes-expected.txt:
     37        * platform/mac/fast/hidpi/image-srcset-invalid-inputs-expected.png:
     38        * platform/mac/fast/hidpi/image-srcset-invalid-inputs-expected.txt:
     39        * platform/mac/fast/hidpi/image-srcset-invalid-inputs-except-one-expected.png:
     40        * platform/mac/fast/hidpi/image-srcset-invalid-inputs-except-one-expected.txt:
     41        * platform/mac/fast/hidpi/image-srcset-invalid-inputs-correct-src-expected.png:
     42        * platform/mac/fast/hidpi/image-srcset-invalid-inputs-correct-src-expected.txt:
     43        * platform/mac/fast/hidpi/image-srcset-change-dynamically-from-js-expected.png:
     44        * platform/mac/fast/hidpi/image-srcset-change-dynamically-from-js-expected.txt:
     45        * platform/mac/fast/hidpi/image-srcset-remove-dynamically-from-js-expected.png:
     46        * platform/mac/fast/hidpi/image-srcset-remove-dynamically-from-js-expected.txt:
     47
    1482013-08-01  Bem Jones-Bey  <bjonesbe@adobe.com>
    249
  • trunk/Source/WebCore/ChangeLog

    r153613 r153624  
     12013-08-01  Romain Perier  <romain.perier@gmail.com>
     2
     3        Implement img element's srcset attribute
     4        https://bugs.webkit.org/show_bug.cgi?id=110252
     5
     6        Reviewed by Dean Jackson.
     7
     8        Tests: fast/hidpi/image-srcset-simple.html
     9               fast/hidpi/image-srcset-src-selection.html
     10               fast/hidpi/image-srcset-simple.html
     11               fast/hidpi/image-srcset-src-selection.html
     12               fast/hidpi/image-srcset-only-src-attribute.html
     13               fast/hidpi/image-srcset-same-alternative-for-both-attributes.html
     14               fast/hidpi/image-srcset-invalid-inputs.html
     15               fast/hidpi/image-srcset-invalid-inputs-except-one.html
     16               fast/hidpi/image-srcset-invalid-inputs-correct-src.html
     17               fast/hidpi/image-srcset-change-dynamically-from-js.html
     18               fast/hidpi/image-srcset-remove-dynamically-from-js.html
     19
     20        * html/HTMLAttributeNames.in: Add srcset attribute.
     21        * html/HTMLImageElement.cpp:
     22        (WebCore::HTMLImageElement::HTMLImageElement):
     23        Adding initialization for new variables member.
     24        (WebCore::HTMLImageElement::imageSourceURL):
     25        Override this method to return the choosen image transparently to the ImageLoader.
     26        (WebCore::HTMLImageElement::updateBestImageForScaleFactor):
     27        New method to select the good image candidate dependending on the scale factor. This method is separated from
     28        parsing because it will be useful for selecting a new image candidate on the fly if the device scale factor changes.
     29        (WebCore::HTMLImageElement::updateImagesFromSrcSet):
     30        New method for parsing the srcset attribute and build a list of images with the corresponding scale factor.
     31        (WebCore::HTMLImageElement::parseAttribute):
     32        Adding support for processing the image candidates, select the good one and call ImageLoader for rendering.
     33        * html/HTMLImageElement.h:
     34        - Adding new methods declarations.
     35        - Adding new type definition.
     36        - Adding new variable member to store the URL of the choosen image.
     37        - Adding new variable member to store the index of the src image.
     38        - Adding new Vector to store the list of images after parsing.
     39        * html/HTMLImageElement.idl: Adding srcset attribute for the differents existing bidings.
     40
    1412013-08-01  Filip Pizlo  <fpizlo@apple.com>
    242
  • trunk/Source/WebCore/html/HTMLAttributeNames.in

    r151827 r153624  
    312312spellcheck
    313313src
     314srcset
    314315srcdoc
    315316srclang
  • trunk/Source/WebCore/html/HTMLImageElement.cpp

    r151949 r153624  
    3434#include "HTMLNames.h"
    3535#include "HTMLParserIdioms.h"
     36#include "Page.h"
    3637#include "RenderImage.h"
    3738#include "ScriptEventListener.h"
     39#include <wtf/NotFound.h>
    3840
    3941using namespace std;
     
    4850    , m_form(form)
    4951    , m_compositeOperator(CompositeSourceOver)
     52    , m_bestFitImageURL(nullAtom)
     53    , m_srcImageIndex(notFound)
    5054{
    5155    ASSERT(hasTagName(imgTag));
     
    109113}
    110114
     115const AtomicString& HTMLImageElement::imageSourceURL() const
     116{
     117    return m_bestFitImageURL == nullAtom ? getAttribute(srcAttr) : m_bestFitImageURL;
     118}
     119
     120void HTMLImageElement::updateBestImageForScaleFactor()
     121{
     122    float pageScaleFactor = 1.0;
     123
     124    m_bestFitImageURL = nullAtom;
     125    if (Page* page = document()->page())
     126        pageScaleFactor = page->deviceScaleFactor();
     127    for (size_t i = 0; i < m_imagesWithScale.size(); ++i) {
     128        if (m_imagesWithScale[i].scaleFactor >= pageScaleFactor) {
     129            m_bestFitImageURL = m_imagesWithScale[i].imageURL;
     130            return;
     131        }
     132    }
     133}
     134
     135void HTMLImageElement::updateImagesFromSrcSet(const AtomicString& srcset)
     136{
     137    const String& string = static_cast<const String&>(srcset);
     138    Vector<String> srcSet;
     139
     140    string.split(',', srcSet);
     141    for (size_t i = 0; i < srcSet.size(); ++i) {
     142        Vector<String> data;
     143        float imgScaleFactor = 1.0;
     144        bool validScaleFactor = false;
     145
     146        srcSet[i].stripWhiteSpace().split(' ', data);
     147        if (data.size() > 0 && data.last().endsWith('x')) {
     148            imgScaleFactor = data.last().substring(0, data.last().length() - 1).toFloat(&validScaleFactor);
     149            if (!validScaleFactor)
     150                imgScaleFactor = 1.0;
     151        }
     152        if (!data.size() || (data.size() == 1 && validScaleFactor))
     153            continue;
     154        ImageWithScale image;
     155        image.imageURL = data[0];
     156        image.scaleFactor = imgScaleFactor;
     157        m_imagesWithScale.append(image);
     158    }
     159    const AtomicString& src = getAttribute(srcAttr);
     160    ImageWithScale image;
     161    if (!src.isEmpty()) {
     162        image.imageURL = getAttribute(srcAttr);
     163        image.scaleFactor = 1.0;
     164        m_imagesWithScale.append(image);
     165    }
     166    stable_sort(m_imagesWithScale.begin(), m_imagesWithScale.end(), compareByScaleFactor);
     167
     168    for (size_t i = 1; i < m_imagesWithScale.size(); ++i) {
     169        if (m_imagesWithScale[i-1].scaleFactor == m_imagesWithScale[i].scaleFactor) {
     170            m_imagesWithScale.remove(i);
     171            i--;
     172        }
     173    }
     174    if (!src.isEmpty())
     175        m_srcImageIndex = m_imagesWithScale.find(image);
     176}
     177
    111178void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
    112179{
     
    114181        if (renderer() && renderer()->isImage())
    115182            toRenderImage(renderer())->updateAltText();
    116     } else if (name == srcAttr)
     183    } else if (name == srcAttr) {
     184        if (m_srcImageIndex != notFound)
     185            m_imagesWithScale.remove(m_srcImageIndex);
     186        updateImagesFromSrcSet(value);
     187        updateBestImageForScaleFactor();
    117188        m_imageLoader.updateFromElementIgnoringPreviousError();
     189    } else if (name == srcsetAttr) {
     190        m_imagesWithScale.clear();
     191        updateImagesFromSrcSet(value);
     192        updateBestImageForScaleFactor();
     193        m_imageLoader.updateFromElementIgnoringPreviousError();
     194    }
    118195    else if (name == usemapAttr)
    119196        setIsLink(!value.isNull());
  • trunk/Source/WebCore/html/HTMLImageElement.h

    r152353 r153624  
    7777    virtual bool canContainRangeEndPoint() const { return false; }
    7878
     79    virtual const AtomicString& imageSourceURL() const OVERRIDE;
     80
    7981protected:
    8082    HTMLImageElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
     
    108110#endif
    109111
     112    void updateImagesFromSrcSet(const AtomicString& srcset);
     113
     114    void updateBestImageForScaleFactor();
     115
     116    struct ImageWithScale {
     117        String imageURL;
     118        float scaleFactor;
     119        bool operator==(const ImageWithScale& image) const
     120        {
     121            return scaleFactor == image.scaleFactor && imageURL == image.imageURL;
     122        }
     123    };
     124
     125    static inline bool compareByScaleFactor(const ImageWithScale& first, const ImageWithScale& second)
     126    {
     127        return first.scaleFactor < second.scaleFactor;
     128    }
     129
    110130    HTMLImageLoader m_imageLoader;
    111131    HTMLFormElement* m_form;
    112132    CompositeOperator m_compositeOperator;
     133    AtomicString m_bestFitImageURL;
     134    size_t m_srcImageIndex;
     135    Vector<ImageWithScale> m_imagesWithScale;
    113136};
    114137
  • trunk/Source/WebCore/html/HTMLImageElement.idl

    r147857 r153624  
    3232    [Reflect, URL] attribute DOMString longDesc;
    3333    [Reflect, URL] attribute DOMString src;
     34    [Reflect] attribute DOMString srcset;
    3435    [Reflect] attribute DOMString useMap;
    3536    [Reflect] attribute long vspace;
Note: See TracChangeset for help on using the changeset viewer.