diff --git .gitignore .gitignore index 5565643..c61f6e5 100644 --- .gitignore +++ .gitignore @@ -259,3 +259,7 @@ v8.log /x86-generic_out/ /xcodebuild .svn +*.orig +*.rej +*.vim +*.mod diff --git CMakeLists.txt CMakeLists.txt index f0fe4a9..77dd03e 100644 --- CMakeLists.txt +++ CMakeLists.txt @@ -453,6 +453,7 @@ SET(WebCore_IDL_FILES html/HTMLHtmlElement.idl html/HTMLIFrameElement.idl html/HTMLImageElement.idl + html/HTMLPictureElement.idl html/HTMLIntentElement.idl html/HTMLInputElement.idl html/HTMLKeygenElement.idl @@ -1385,6 +1386,7 @@ SET(WebCore_SOURCES html/HTMLHtmlElement.cpp html/HTMLIFrameElement.cpp html/HTMLImageElement.cpp + html/HTMLPictureElement.cpp html/HTMLImageLoader.cpp html/HTMLIntentElement.cpp html/HTMLInputElement.cpp diff --git DerivedSources.cpp DerivedSources.cpp index 891d17e..c1ec836 100644 --- DerivedSources.cpp +++ DerivedSources.cpp @@ -175,6 +175,7 @@ #include "JSHTMLHtmlElement.cpp" #include "JSHTMLIFrameElement.cpp" #include "JSHTMLImageElement.cpp" +#include "JSHTMLPictureElement.cpp" #include "JSHTMLInputElement.cpp" #include "JSHTMLKeygenElement.cpp" #include "JSHTMLLabelElement.cpp" diff --git DerivedSources.make DerivedSources.make index 4de8ce7..0fc868e 100644 --- DerivedSources.make +++ DerivedSources.make @@ -311,6 +311,7 @@ BINDING_IDLS = \ $(WebCore)/html/HTMLHtmlElement.idl \ $(WebCore)/html/HTMLIFrameElement.idl \ $(WebCore)/html/HTMLImageElement.idl \ + $(WebCore)/html/HTMLPictureElement.idl \ $(WebCore)/html/HTMLInputElement.idl \ $(WebCore)/html/HTMLKeygenElement.idl \ $(WebCore)/html/HTMLLIElement.idl \ diff --git DerivedSources.pri DerivedSources.pri index 5dfbf9b..533c379 100644 --- DerivedSources.pri +++ DerivedSources.pri @@ -360,6 +360,7 @@ IDL_BINDINGS += \ $$PWD/html/HTMLHtmlElement.idl \ $$PWD/html/HTMLIFrameElement.idl \ $$PWD/html/HTMLImageElement.idl \ + $$PWD/html/HTMLPictureElement.idl \ $$PWD/html/HTMLInputElement.idl \ $$PWD/html/HTMLKeygenElement.idl \ $$PWD/html/HTMLLabelElement.idl \ diff --git GNUmakefile.list.am GNUmakefile.list.am index 40f1391..d587d60 100644 --- GNUmakefile.list.am +++ GNUmakefile.list.am @@ -1449,6 +1449,7 @@ dom_binding_idls += \ $(WebCore)/html/HTMLHtmlElement.idl \ $(WebCore)/html/HTMLIFrameElement.idl \ $(WebCore)/html/HTMLImageElement.idl \ + $(WebCore)/html/HTMLPictureElement.idl \ $(WebCore)/html/HTMLInputElement.idl \ $(WebCore)/html/HTMLKeygenElement.idl \ $(WebCore)/html/HTMLLIElement.idl \ diff --git README.md README.md new file mode 100644 index 0000000..33e49dc --- /dev/null +++ README.md @@ -0,0 +1,43 @@ +The Responsive Images WebCore fork!!! +-------------------- + +This repository contains experiments in adding the `` element to +WebKit's WebCore library. + +It is based on Chromium's WebKit from 17/10/12. + +*Note*: This is a work in progress. It does not (yet) represent a full +implementation of the `` element [specification](http://picture.responsiveimages.org/). Please file any +inconsistency with the specification as an issue. + + +Build instructions: +---------------------- +* Build Chromium like you normally would on [Linux](http://code.google.com/p/chromium/wiki/LinuxBuildInstructions) or [OSX] (http://code.google.com/p/chromium/wiki/MacBuildInstructions) +* If your time is precious, use [Ninja](http://code.google.com/p/chromium/wiki/NinjaBuild) +* Download the patch from [here](https://raw.github.com/yoavweiss/RespImg-WebCore/master/picture_patch.txt) to your /tmp directory +* Apply the patch using `(cd third_party/WebKit/Source/WebCore && patch -p0 < /tmp/picture_patch.txt)` + +Binaries: +-------------------------- +* Ubuntu 64bit & OSX binaries can be found [here]( https://github.com/ResponsiveImagesCG/RespImg-WebCore/downloads) + +Test page: +--------------------- +Once you got your new binary, you can see `` in action [here] (http://demos.responsiveimages.org/) + +What should be working: +-------------------- +* `` should work. The *first* source + should be fetched by the PreloadScanner and then displayed when the +element is parsed. +* `` prefetches and displays the resource. It +overrides inner `` tags if present. +* The `media` attribute should be working as expected for both the +PreloadScanner and the actual parser. + +What shouldn't be working (yet): +-------------------- +* The `srcset` attribute is not yet supported in either the PreloadScanner or the actual parser. +* The `type` attribute is not yet supported in either the PreloadScanner or the actual parser. + diff --git Target.pri Target.pri index 3a04feb..3498bb8 100644 --- Target.pri +++ Target.pri @@ -613,6 +613,7 @@ SOURCES += \ html/HTMLHtmlElement.cpp \ html/HTMLIFrameElement.cpp \ html/HTMLImageElement.cpp \ + html/HTMLPictureElement.cpp \ html/HTMLImageLoader.cpp \ html/HTMLInputElement.cpp \ html/HTMLKeygenElement.cpp \ diff --git UseV8.cmake UseV8.cmake index 5cd42c8..2da3b8e 100755 --- UseV8.cmake +++ UseV8.cmake @@ -111,6 +111,7 @@ LIST(APPEND WebCore_SOURCES bindings/v8/custom/V8HTMLFrameElementCustom.cpp bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp bindings/v8/custom/V8HTMLImageElementConstructor.cpp + bindings/v8/custom/V8HTMLPictureElementConstructor.cpp bindings/v8/custom/V8HTMLInputElementCustom.cpp bindings/v8/custom/V8HTMLLinkElementCustom.cpp bindings/v8/custom/V8HTMLOptionElementConstructor.cpp diff --git WebCore.gypi WebCore.gypi index 0a477b8..c860bd4 100644 --- WebCore.gypi +++ WebCore.gypi @@ -1092,6 +1092,7 @@ 'html/HTMLHtmlElement.idl', 'html/HTMLIFrameElement.idl', 'html/HTMLImageElement.idl', + 'html/HTMLPictureElement.idl', 'html/HTMLInputElement.idl', 'html/HTMLIntentElement.idl', 'html/HTMLKeygenElement.idl', @@ -2405,6 +2406,8 @@ 'bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp', 'bindings/v8/custom/V8HTMLImageElementConstructor.cpp', 'bindings/v8/custom/V8HTMLImageElementConstructor.h', + 'bindings/v8/custom/V8HTMLPictureElementConstructor.cpp', + 'bindings/v8/custom/V8HTMLPictureElementConstructor.h', 'bindings/v8/custom/V8HTMLInputElementCustom.cpp', 'bindings/v8/custom/V8HTMLLinkElementCustom.cpp', 'bindings/v8/custom/V8HTMLMediaElementCustom.cpp', @@ -4169,6 +4172,8 @@ 'html/HTMLParamElement.h', 'html/HTMLParserErrorCodes.cpp', 'html/HTMLParserErrorCodes.h', + 'html/HTMLPictureElement.cpp', + 'html/HTMLPictureElement.h', 'html/HTMLPlugInElement.cpp', 'html/HTMLPlugInImageElement.cpp', 'html/HTMLPreElement.cpp', diff --git bindings/v8/custom/V8HTMLPictureElementConstructor.cpp bindings/v8/custom/V8HTMLPictureElementConstructor.cpp new file mode 100644 index 0000000..1239988 --- /dev/null +++ bindings/v8/custom/V8HTMLPictureElementConstructor.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2009, 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "V8HTMLPictureElementConstructor.h" + +#include "BindingState.h" +#include "Document.h" +#include "Frame.h" +#include "HTMLPictureElement.h" +#include "HTMLNames.h" +#include "V8Binding.h" +#include "V8Document.h" +#include "V8HTMLPictureElement.h" +#include + +namespace WebCore { + +WrapperTypeInfo V8HTMLPictureElementConstructor::info = { V8HTMLPictureElementConstructor::GetTemplate, 0, 0, 0, V8HTMLPictureElement::installPerContextPrototypeProperties, 0, WrapperTypeObjectPrototype }; + +static v8::Handle v8HTMLPictureElementConstructorCallback(const v8::Arguments& args) +{ + INC_STATS("DOM.HTMLPictureElement.Contructor"); + + if (!args.IsConstructCall()) + return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); + + if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) + return args.Holder(); + + Document* document = currentDocument(BindingState::instance()); + + // Make sure the document is added to the DOM Node map. Otherwise, the HTMLPictureElement instance + // may end up being the only node in the map and get garbage-collected prematurely. + // FIXME: The correct way to do this would be to make HTMLPictureElement derive from + // ActiveDOMObject and use its interface to keep its wrapper alive. Then we would + // remove this code and the special case in isObservableThroughDOM. + toV8(document, args.Holder(), args.GetIsolate()); + + int width; + int height; + int* optionalWidth = 0; + int* optionalHeight = 0; + if (args.Length() > 0) { + width = toInt32(args[0]); + optionalWidth = &width; + } + if (args.Length() > 1) { + height = toInt32(args[1]); + optionalHeight = &height; + } + + RefPtr image = HTMLPictureElement::createForJSConstructor(document, optionalWidth, optionalHeight); + v8::Handle wrapper = args.Holder(); + V8DOMWrapper::setDOMWrapper(wrapper, &V8HTMLPictureElementConstructor::info, image.get()); + V8DOMWrapper::setJSWrapperForDOMNode(image.release(), wrapper); + return wrapper; +} + +v8::Persistent V8HTMLPictureElementConstructor::GetTemplate() +{ + static v8::Persistent cachedTemplate; + if (!cachedTemplate.IsEmpty()) + return cachedTemplate; + + v8::HandleScope scope; + v8::Local result = v8::FunctionTemplate::New(v8HTMLPictureElementConstructorCallback); + + v8::Local instance = result->InstanceTemplate(); + instance->SetInternalFieldCount(V8HTMLPictureElement::internalFieldCount); + result->SetClassName(v8::String::New("HTMLPictureElement")); + result->Inherit(V8HTMLPictureElement::GetTemplate()); + + cachedTemplate = v8::Persistent::New(result); + return cachedTemplate; +} + +} // namespace WebCore diff --git bindings/v8/custom/V8HTMLPictureElementConstructor.h bindings/v8/custom/V8HTMLPictureElementConstructor.h new file mode 100644 index 0000000..578dfa1 --- /dev/null +++ bindings/v8/custom/V8HTMLPictureElementConstructor.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef V8HTMLPictureElementConstructor_h +#define V8HTMLPictureElementConstructor_h + +#include "WrapperTypeInfo.h" + +#include + +namespace WebCore { + +class V8HTMLPictureElementConstructor { +public: + static v8::Persistent GetTemplate(); + static WrapperTypeInfo info; +}; + +} + +#endif // V8HTMLPictureElementConstructor_h diff --git dom/Element.h dom/Element.h index 58e297d..c451424 100644 --- dom/Element.h +++ dom/Element.h @@ -364,6 +364,8 @@ public: virtual bool isMediaElement() const { return false; } #endif + virtual bool isPictureElement() const { return false; } + #if ENABLE(INPUT_SPEECH) virtual bool isInputFieldSpeechButtonElement() const { return false; } #endif diff --git html/HTMLImageElement.cpp html/HTMLImageElement.cpp index e934e4d..a6bb282 100644 --- html/HTMLImageElement.cpp +++ html/HTMLImageElement.cpp @@ -73,7 +73,7 @@ HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* docum , m_form(form) , m_compositeOperator(CompositeSourceOver) { - ASSERT(hasTagName(imgTag)); + ASSERT((hasTagName(imgTag)) || (hasTagName(pictureTag))); if (form) form->registerImgElement(this); } @@ -237,6 +237,10 @@ Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* return HTMLElement::insertedInto(insertionPoint); } +void HTMLImageElement::updateResources() +{ + m_imageLoader.updateFromElement(); +} void HTMLImageElement::removedFrom(ContainerNode* insertionPoint) { if (m_form) diff --git html/HTMLImageElement.h html/HTMLImageElement.h index 9468a79..bd65f6b 100644 --- html/HTMLImageElement.h +++ html/HTMLImageElement.h @@ -93,7 +93,9 @@ protected: HTMLImageElement(const QualifiedName&, Document*, HTMLFormElement* = 0); virtual void didMoveToNewDocument(Document* oldDocument) OVERRIDE; + void updateResources(); + virtual void parseAttribute(const Attribute&) OVERRIDE; private: virtual void createShadowSubtree(); @@ -105,7 +107,6 @@ private: void refSourceElement() { ref(); } void derefSourceElement() { deref(); } - virtual void parseAttribute(const Attribute&) OVERRIDE; virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE; virtual void collectStyleForAttribute(const Attribute&, StylePropertySet*) OVERRIDE; diff --git html/HTMLPictureElement.cpp html/HTMLPictureElement.cpp new file mode 100644 index 0000000..a7c7d3e --- /dev/null +++ html/HTMLPictureElement.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "HTMLImageElement.h" +#include "HTMLPictureElement.h" + +#include "MediaList.h" +#include "MediaQueryEvaluator.h" +#include "StyleResolver.h" + +using namespace std; + +namespace WebCore { + +using namespace HTMLNames; + +HTMLPictureElement::HTMLPictureElement(const QualifiedName& tagName, Document* document) + : HTMLImageElement(tagName, document, NULL), + m_hasSrc(false) +{ + ASSERT(hasTagName(pictureTag)); +} + +PassRefPtr HTMLPictureElement::create(Document* document) +{ + return adoptRef(new HTMLPictureElement(imgTag, document)); +} + +PassRefPtr HTMLPictureElement::create(const QualifiedName& tagName, Document* document) +{ + return adoptRef(new HTMLPictureElement(tagName, document)); +} + +HTMLPictureElement::~HTMLPictureElement() +{ +} + +PassRefPtr HTMLPictureElement::createForJSConstructor(Document* document, const int* optionalWidth, const int* optionalHeight) +{ + RefPtr picture = adoptRef(new HTMLPictureElement(imgTag, document)); + if (optionalWidth) + picture->setWidth(*optionalWidth); + if (optionalHeight) + picture->setHeight(*optionalHeight); + return picture.release(); +} + +Element* HTMLPictureElement::getMatchingSource(){ + if(!m_hasSrc){ + NodeVector potentialSourceNodes; + getChildNodes(this, potentialSourceNodes); + for( NodeVector::iterator it = potentialSourceNodes.begin(); + it != potentialSourceNodes.end(); + it++){ + RefPtr nodePtr = *it; + Node* node = nodePtr.get(); + if (node && (node->hasTagName(sourceTag)) && (node->parentNode() == this)){ + HTMLSourceElement* source = static_cast(node); + Document* document = documentInternal(); + if (source->fastHasAttribute(srcAttr)) { + if (!source->fastHasAttribute(mediaAttr)) { + return source; + } + RefPtr mediaQueries = MediaQuerySet::createAllowingDescriptionSyntax(source->media()); + RefPtr documentStyle = StyleResolver::styleForDocument(document, 0); + MediaQueryEvaluator mediaQueryEvaluator("screen", document->frame(), documentStyle.get()); + if(mediaQueryEvaluator.eval(mediaQueries.get())){ + return source; + } + } + } + } + } + return this; +} + +void HTMLPictureElement::sourceWasAdded(HTMLSourceElement* source) +{ + updateResources(); +} + +void HTMLPictureElement::parseAttribute(const Attribute& attribute) +{ + if(attribute.name() == srcAttr) + m_hasSrc = true; + + HTMLImageElement::parseAttribute(attribute); +} + +} diff --git html/HTMLPictureElement.h html/HTMLPictureElement.h new file mode 100644 index 0000000..369bad3 --- /dev/null +++ html/HTMLPictureElement.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * Copyright (C) 2004, 2008, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef HTMLPictureElement_h +#define HTMLPictureElement_h + +#include "HTMLImageElement.h" +#include "HTMLSourceElement.h" + +namespace WebCore { + +class HTMLPictureElement : public HTMLImageElement { + HTMLPictureElement(const QualifiedName& tagName, Document* document); + ~HTMLPictureElement(); + Element* sourceElement() { return getMatchingSource(); } + Element* getMatchingSource(); + + virtual bool isPictureElement() const { return true; } + virtual void parseAttribute(const Attribute&); + + bool m_hasSrc; + +public: + static PassRefPtr create(Document* document); + + static PassRefPtr create(const QualifiedName& tagName, Document* document); + static PassRefPtr createForJSConstructor(Document* document, const int* optionalWidth, const int* optionalHeight); + void sourceWasAdded(HTMLSourceElement*); + +}; + +} //namespace + +#endif diff --git html/HTMLPictureElement.idl html/HTMLPictureElement.idl new file mode 100644 index 0000000..3093c6e --- /dev/null +++ html/HTMLPictureElement.idl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2006, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +module html { + + interface [ + JSGenerateToNativeObject + ] HTMLPictureElement : HTMLImageElement { + }; + +} diff --git html/HTMLSourceElement.cpp html/HTMLSourceElement.cpp index 4ac537b..4055bb8 100644 --- html/HTMLSourceElement.cpp +++ html/HTMLSourceElement.cpp @@ -32,6 +32,7 @@ #include "EventNames.h" #include "HTMLDocument.h" #include "HTMLMediaElement.h" +#include "HTMLPictureElement.h" #include "HTMLNames.h" #include "Logging.h" @@ -60,6 +61,8 @@ Node::InsertionNotificationRequest HTMLSourceElement::insertedInto(ContainerNode Element* parent = parentElement(); if (parent && parent->isMediaElement()) static_cast(parentNode())->sourceWasAdded(this); + if (parent && parent->isPictureElement()) + static_cast(parentNode())->sourceWasAdded(this); return InsertionDone; } @@ -78,6 +81,11 @@ void HTMLSourceElement::setSrc(const String& url) setAttribute(srcAttr, url); } +String HTMLSourceElement::src() const +{ + return getAttribute(srcAttr); +} + String HTMLSourceElement::media() const { return getAttribute(mediaAttr); diff --git html/HTMLSourceElement.h html/HTMLSourceElement.h index 15920e3..0e9446c 100644 --- html/HTMLSourceElement.h +++ html/HTMLSourceElement.h @@ -37,6 +37,7 @@ class HTMLSourceElement : public HTMLElement { public: static PassRefPtr create(const QualifiedName&, Document*); + String src() const; String media() const; String type() const; void setSrc(const String&); diff --git html/HTMLTagNames.in html/HTMLTagNames.in index 3660ab9..0155115 100644 --- html/HTMLTagNames.in +++ html/HTMLTagNames.in @@ -68,6 +68,7 @@ i interfaceName=HTMLElement iframe interfaceName=HTMLIFrameElement image mapToTagName=img img interfaceName=HTMLImageElement, constructorNeedsFormElement +picture interfaceName=HTMLPictureElement webkitInnerImage interfaceName=HTMLElement, noConstructor input constructorNeedsFormElement, constructorNeedsCreatedByParser intent conditional=WEB_INTENTS_TAG diff --git html/parser/HTMLPreloadScanner.cpp html/parser/HTMLPreloadScanner.cpp index a75b52e..fad61d4 100644 --- html/parser/HTMLPreloadScanner.cpp +++ html/parser/HTMLPreloadScanner.cpp @@ -38,6 +38,7 @@ #include "LinkRelAttribute.h" #include "MediaList.h" #include "MediaQueryEvaluator.h" +#include "StyleResolver.h" namespace WebCore { @@ -45,18 +46,26 @@ using namespace HTMLNames; class PreloadTask { public: - explicit PreloadTask(const HTMLToken& token) + explicit PreloadTask(const HTMLToken& token, bool inPicture, bool picturePreloaded, Frame* frame, RenderStyle* renderStyle) : m_tagName(token.name().data(), token.name().size()) , m_linkIsStyleSheet(false) , m_linkMediaAttributeIsScreen(true) , m_inputIsImage(false) + , m_inPictureSubTree(inPicture) + , m_picturePreloaded(picturePreloaded) + , m_frame(frame) + , m_renderStyle(renderStyle) { processAttributes(token.attributes()); } + bool picturePreloaded(){return m_picturePreloaded;} + void processAttributes(const HTMLToken::AttributeList& attributes) { - if (m_tagName != imgTag + if ((m_tagName != imgTag || m_inPictureSubTree) + && (m_tagName != sourceTag || !m_inPictureSubTree || m_picturePreloaded) + && m_tagName != pictureTag && m_tagName != inputTag && m_tagName != linkTag && m_tagName != scriptTag @@ -74,6 +83,16 @@ public: if (m_tagName == scriptTag || m_tagName == imgTag) { if (attributeName == srcAttr) setUrlToLoad(attributeValue); + } else if (m_tagName == pictureTag) { + if (attributeName == srcAttr) { + setUrlToLoad(attributeValue); + m_picturePreloaded = true; + } + } else if (m_tagName == sourceTag) { + if (attributeName == srcAttr) + setUrlToLoad(attributeValue); + else if (attributeName == mediaAttr) + m_sourceMediaAttributeMatches = sourceMediaAttributeMatches(attributeValue); } else if (m_tagName == linkTag) { if (attributeName == hrefAttr) setUrlToLoad(attributeValue); @@ -99,6 +118,13 @@ public: return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == InvalidIcon && !rel.m_isDNSPrefetch; } + bool sourceMediaAttributeMatches(const String& attributeValue){ + if (attributeValue.isEmpty()) + return true; + RefPtr mediaQueries = MediaQuerySet::createAllowingDescriptionSyntax(attributeValue); + MediaQueryEvaluator mediaQueryEvaluator("screen", m_frame, m_renderStyle); + return mediaQueryEvaluator.eval(mediaQueries.get()); + } static bool linkMediaAttributeIsScreen(const String& attributeValue) { if (attributeValue.isEmpty()) @@ -130,8 +156,14 @@ public: ResourceRequest request = document->completeURL(m_urlToLoad, baseURL); if (m_tagName == scriptTag) cachedResourceLoader->preload(CachedResource::Script, request, m_charset, scanningBody); - else if (m_tagName == imgTag || (m_tagName == inputTag && m_inputIsImage)) + else if ( m_tagName == imgTag || + (m_tagName == inputTag && m_inputIsImage) || + m_tagName == pictureTag || + (m_tagName == sourceTag && m_sourceMediaAttributeMatches && !m_picturePreloaded)){ cachedResourceLoader->preload(CachedResource::ImageResource, request, String(), scanningBody); + if(m_tagName == sourceTag || m_tagName == pictureTag) + m_picturePreloaded = true; + } else if (m_tagName == linkTag && m_linkIsStyleSheet && m_linkMediaAttributeIsScreen) cachedResourceLoader->preload(CachedResource::CSSStyleSheet, request, m_charset, scanningBody); } @@ -146,7 +178,12 @@ private: String m_baseElementHref; bool m_linkIsStyleSheet; bool m_linkMediaAttributeIsScreen; + bool m_sourceMediaAttributeMatches; bool m_inputIsImage; + bool m_inPictureSubTree; + bool m_picturePreloaded; + Frame* m_frame; + RenderStyle* m_renderStyle; }; HTMLPreloadScanner::HTMLPreloadScanner(Document* document) @@ -155,6 +192,8 @@ HTMLPreloadScanner::HTMLPreloadScanner(Document* document) , m_tokenizer(HTMLTokenizer::create(HTMLDocumentParser::usePreHTML5ParserQuirks(document))) , m_bodySeen(false) , m_inStyle(false) + , m_inPicture(false) + , m_picturePreloadedSource(false) { } @@ -187,10 +226,19 @@ void HTMLPreloadScanner::processToken() } } + if (m_inPicture && (m_token.type() == HTMLTokenTypes::EndTag)){ + AtomicString tagName(m_token.name().data(), m_token.name().size()); + if(tagName == pictureTag){ + m_inPicture = false; + m_picturePreloadedSource = false; + } + } + if (m_token.type() != HTMLTokenTypes::StartTag) return; - PreloadTask task(m_token); + RefPtr documentStyle = StyleResolver::styleForDocument(m_document, 0); + PreloadTask task(m_token, m_inPicture, m_picturePreloadedSource, m_document->frame(), documentStyle.get()); m_tokenizer->updateStateFor(task.tagName(), m_document->frame()); if (task.tagName() == bodyTag) @@ -199,10 +247,16 @@ void HTMLPreloadScanner::processToken() if (task.tagName() == styleTag) m_inStyle = true; + if (task.tagName() == pictureTag){ + m_inPicture = true; + } + if (task.tagName() == baseTag) updatePredictedBaseElementURL(KURL(m_document->url(), task.baseElementHref())); task.preload(m_document, scanningBody(), m_predictedBaseElementURL.isEmpty() ? m_document->baseURL() : m_predictedBaseElementURL); + + m_picturePreloadedSource = task.picturePreloaded(); } bool HTMLPreloadScanner::scanningBody() const diff --git html/parser/HTMLPreloadScanner.h html/parser/HTMLPreloadScanner.h index 38f5772..5dc4d6c 100644 --- html/parser/HTMLPreloadScanner.h +++ html/parser/HTMLPreloadScanner.h @@ -58,6 +58,8 @@ private: HTMLToken m_token; bool m_bodySeen; bool m_inStyle; + bool m_inPicture; + bool m_picturePreloadedSource; KURL m_predictedBaseElementURL; }; diff --git page/DOMWindow.idl page/DOMWindow.idl index 0e104b6..df8f410 100644 --- page/DOMWindow.idl +++ page/DOMWindow.idl @@ -427,6 +427,7 @@ attribute HTMLHtmlElementConstructor HTMLHtmlElement; attribute HTMLIFrameElementConstructor HTMLIFrameElement; attribute HTMLImageElementConstructor HTMLImageElement; + attribute HTMLPictureElementConstructor HTMLPictureElement; attribute HTMLInputElementConstructor HTMLInputElement; attribute HTMLKeygenElementConstructor HTMLKeygenElement; attribute HTMLLIElementConstructor HTMLLIElement; diff --git picture_patch.txt picture_patch.txt new file mode 100644 index 0000000..eaa3f35 --- /dev/null +++ picture_patch.txt @@ -0,0 +1,750 @@ +diff --git .gitignore .gitignore +index 5565643..c61f6e5 100644 +--- .gitignore ++++ .gitignore +@@ -259,3 +259,7 @@ v8.log + /x86-generic_out/ + /xcodebuild + .svn ++*.orig ++*.rej ++*.vim ++*.mod +diff --git CMakeLists.txt CMakeLists.txt +index f0fe4a9..77dd03e 100644 +--- CMakeLists.txt ++++ CMakeLists.txt +@@ -453,6 +453,7 @@ SET(WebCore_IDL_FILES + html/HTMLHtmlElement.idl + html/HTMLIFrameElement.idl + html/HTMLImageElement.idl ++ html/HTMLPictureElement.idl + html/HTMLIntentElement.idl + html/HTMLInputElement.idl + html/HTMLKeygenElement.idl +@@ -1385,6 +1386,7 @@ SET(WebCore_SOURCES + html/HTMLHtmlElement.cpp + html/HTMLIFrameElement.cpp + html/HTMLImageElement.cpp ++ html/HTMLPictureElement.cpp + html/HTMLImageLoader.cpp + html/HTMLIntentElement.cpp + html/HTMLInputElement.cpp +diff --git DerivedSources.cpp DerivedSources.cpp +index 891d17e..c1ec836 100644 +--- DerivedSources.cpp ++++ DerivedSources.cpp +@@ -175,6 +175,7 @@ + #include "JSHTMLHtmlElement.cpp" + #include "JSHTMLIFrameElement.cpp" + #include "JSHTMLImageElement.cpp" ++#include "JSHTMLPictureElement.cpp" + #include "JSHTMLInputElement.cpp" + #include "JSHTMLKeygenElement.cpp" + #include "JSHTMLLabelElement.cpp" +diff --git DerivedSources.make DerivedSources.make +index 4de8ce7..0fc868e 100644 +--- DerivedSources.make ++++ DerivedSources.make +@@ -311,6 +311,7 @@ BINDING_IDLS = \ + $(WebCore)/html/HTMLHtmlElement.idl \ + $(WebCore)/html/HTMLIFrameElement.idl \ + $(WebCore)/html/HTMLImageElement.idl \ ++ $(WebCore)/html/HTMLPictureElement.idl \ + $(WebCore)/html/HTMLInputElement.idl \ + $(WebCore)/html/HTMLKeygenElement.idl \ + $(WebCore)/html/HTMLLIElement.idl \ +diff --git DerivedSources.pri DerivedSources.pri +index 5dfbf9b..533c379 100644 +--- DerivedSources.pri ++++ DerivedSources.pri +@@ -360,6 +360,7 @@ IDL_BINDINGS += \ + $$PWD/html/HTMLHtmlElement.idl \ + $$PWD/html/HTMLIFrameElement.idl \ + $$PWD/html/HTMLImageElement.idl \ ++ $$PWD/html/HTMLPictureElement.idl \ + $$PWD/html/HTMLInputElement.idl \ + $$PWD/html/HTMLKeygenElement.idl \ + $$PWD/html/HTMLLabelElement.idl \ +diff --git GNUmakefile.list.am GNUmakefile.list.am +index 40f1391..d587d60 100644 +--- GNUmakefile.list.am ++++ GNUmakefile.list.am +@@ -1449,6 +1449,7 @@ dom_binding_idls += \ + $(WebCore)/html/HTMLHtmlElement.idl \ + $(WebCore)/html/HTMLIFrameElement.idl \ + $(WebCore)/html/HTMLImageElement.idl \ ++ $(WebCore)/html/HTMLPictureElement.idl \ + $(WebCore)/html/HTMLInputElement.idl \ + $(WebCore)/html/HTMLKeygenElement.idl \ + $(WebCore)/html/HTMLLIElement.idl \ +diff --git README.md README.md +new file mode 100644 +index 0000000..33e49dc +--- /dev/null ++++ README.md +@@ -0,0 +1,43 @@ ++The Responsive Images WebCore fork!!! ++-------------------- ++ ++This repository contains experiments in adding the `` element to ++WebKit's WebCore library. ++ ++It is based on Chromium's WebKit from 17/10/12. ++ ++*Note*: This is a work in progress. It does not (yet) represent a full ++implementation of the `` element [specification](http://picture.responsiveimages.org/). Please file any ++inconsistency with the specification as an issue. ++ ++ ++Build instructions: ++---------------------- ++* Build Chromium like you normally would on [Linux](http://code.google.com/p/chromium/wiki/LinuxBuildInstructions) or [OSX] (http://code.google.com/p/chromium/wiki/MacBuildInstructions) ++* If your time is precious, use [Ninja](http://code.google.com/p/chromium/wiki/NinjaBuild) ++* Download the patch from [here](https://raw.github.com/yoavweiss/RespImg-WebCore/master/picture_patch.txt) to your /tmp directory ++* Apply the patch using `(cd third_party/WebKit/Source/WebCore && patch -p0 < /tmp/picture_patch.txt)` ++ ++Binaries: ++-------------------------- ++* Ubuntu 64bit & OSX binaries can be found [here]( https://github.com/ResponsiveImagesCG/RespImg-WebCore/downloads) ++ ++Test page: ++--------------------- ++Once you got your new binary, you can see `` in action [here] (http://demos.responsiveimages.org/) ++ ++What should be working: ++-------------------- ++* `` should work. The *first* source ++ should be fetched by the PreloadScanner and then displayed when the ++element is parsed. ++* `` prefetches and displays the resource. It ++overrides inner `` tags if present. ++* The `media` attribute should be working as expected for both the ++PreloadScanner and the actual parser. ++ ++What shouldn't be working (yet): ++-------------------- ++* The `srcset` attribute is not yet supported in either the PreloadScanner or the actual parser. ++* The `type` attribute is not yet supported in either the PreloadScanner or the actual parser. ++ +diff --git Target.pri Target.pri +index 3a04feb..3498bb8 100644 +--- Target.pri ++++ Target.pri +@@ -613,6 +613,7 @@ SOURCES += \ + html/HTMLHtmlElement.cpp \ + html/HTMLIFrameElement.cpp \ + html/HTMLImageElement.cpp \ ++ html/HTMLPictureElement.cpp \ + html/HTMLImageLoader.cpp \ + html/HTMLInputElement.cpp \ + html/HTMLKeygenElement.cpp \ +diff --git UseV8.cmake UseV8.cmake +index 5cd42c8..2da3b8e 100755 +--- UseV8.cmake ++++ UseV8.cmake +@@ -111,6 +111,7 @@ LIST(APPEND WebCore_SOURCES + bindings/v8/custom/V8HTMLFrameElementCustom.cpp + bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp + bindings/v8/custom/V8HTMLImageElementConstructor.cpp ++ bindings/v8/custom/V8HTMLPictureElementConstructor.cpp + bindings/v8/custom/V8HTMLInputElementCustom.cpp + bindings/v8/custom/V8HTMLLinkElementCustom.cpp + bindings/v8/custom/V8HTMLOptionElementConstructor.cpp +diff --git WebCore.gypi WebCore.gypi +index 0a477b8..c860bd4 100644 +--- WebCore.gypi ++++ WebCore.gypi +@@ -1092,6 +1092,7 @@ + 'html/HTMLHtmlElement.idl', + 'html/HTMLIFrameElement.idl', + 'html/HTMLImageElement.idl', ++ 'html/HTMLPictureElement.idl', + 'html/HTMLInputElement.idl', + 'html/HTMLIntentElement.idl', + 'html/HTMLKeygenElement.idl', +@@ -2405,6 +2406,8 @@ + 'bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp', + 'bindings/v8/custom/V8HTMLImageElementConstructor.cpp', + 'bindings/v8/custom/V8HTMLImageElementConstructor.h', ++ 'bindings/v8/custom/V8HTMLPictureElementConstructor.cpp', ++ 'bindings/v8/custom/V8HTMLPictureElementConstructor.h', + 'bindings/v8/custom/V8HTMLInputElementCustom.cpp', + 'bindings/v8/custom/V8HTMLLinkElementCustom.cpp', + 'bindings/v8/custom/V8HTMLMediaElementCustom.cpp', +@@ -4169,6 +4172,8 @@ + 'html/HTMLParamElement.h', + 'html/HTMLParserErrorCodes.cpp', + 'html/HTMLParserErrorCodes.h', ++ 'html/HTMLPictureElement.cpp', ++ 'html/HTMLPictureElement.h', + 'html/HTMLPlugInElement.cpp', + 'html/HTMLPlugInImageElement.cpp', + 'html/HTMLPreElement.cpp', +diff --git bindings/v8/custom/V8HTMLPictureElementConstructor.cpp bindings/v8/custom/V8HTMLPictureElementConstructor.cpp +new file mode 100644 +index 0000000..1239988 +--- /dev/null ++++ bindings/v8/custom/V8HTMLPictureElementConstructor.cpp +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (C) 2009, 2010 Google Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are ++ * met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above ++ * copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Google Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived from ++ * this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "config.h" ++#include "V8HTMLPictureElementConstructor.h" ++ ++#include "BindingState.h" ++#include "Document.h" ++#include "Frame.h" ++#include "HTMLPictureElement.h" ++#include "HTMLNames.h" ++#include "V8Binding.h" ++#include "V8Document.h" ++#include "V8HTMLPictureElement.h" ++#include ++ ++namespace WebCore { ++ ++WrapperTypeInfo V8HTMLPictureElementConstructor::info = { V8HTMLPictureElementConstructor::GetTemplate, 0, 0, 0, V8HTMLPictureElement::installPerContextPrototypeProperties, 0, WrapperTypeObjectPrototype }; ++ ++static v8::Handle v8HTMLPictureElementConstructorCallback(const v8::Arguments& args) ++{ ++ INC_STATS("DOM.HTMLPictureElement.Contructor"); ++ ++ if (!args.IsConstructCall()) ++ return throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); ++ ++ if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) ++ return args.Holder(); ++ ++ Document* document = currentDocument(BindingState::instance()); ++ ++ // Make sure the document is added to the DOM Node map. Otherwise, the HTMLPictureElement instance ++ // may end up being the only node in the map and get garbage-collected prematurely. ++ // FIXME: The correct way to do this would be to make HTMLPictureElement derive from ++ // ActiveDOMObject and use its interface to keep its wrapper alive. Then we would ++ // remove this code and the special case in isObservableThroughDOM. ++ toV8(document, args.Holder(), args.GetIsolate()); ++ ++ int width; ++ int height; ++ int* optionalWidth = 0; ++ int* optionalHeight = 0; ++ if (args.Length() > 0) { ++ width = toInt32(args[0]); ++ optionalWidth = &width; ++ } ++ if (args.Length() > 1) { ++ height = toInt32(args[1]); ++ optionalHeight = &height; ++ } ++ ++ RefPtr image = HTMLPictureElement::createForJSConstructor(document, optionalWidth, optionalHeight); ++ v8::Handle wrapper = args.Holder(); ++ V8DOMWrapper::setDOMWrapper(wrapper, &V8HTMLPictureElementConstructor::info, image.get()); ++ V8DOMWrapper::setJSWrapperForDOMNode(image.release(), wrapper); ++ return wrapper; ++} ++ ++v8::Persistent V8HTMLPictureElementConstructor::GetTemplate() ++{ ++ static v8::Persistent cachedTemplate; ++ if (!cachedTemplate.IsEmpty()) ++ return cachedTemplate; ++ ++ v8::HandleScope scope; ++ v8::Local result = v8::FunctionTemplate::New(v8HTMLPictureElementConstructorCallback); ++ ++ v8::Local instance = result->InstanceTemplate(); ++ instance->SetInternalFieldCount(V8HTMLPictureElement::internalFieldCount); ++ result->SetClassName(v8::String::New("HTMLPictureElement")); ++ result->Inherit(V8HTMLPictureElement::GetTemplate()); ++ ++ cachedTemplate = v8::Persistent::New(result); ++ return cachedTemplate; ++} ++ ++} // namespace WebCore +diff --git bindings/v8/custom/V8HTMLPictureElementConstructor.h bindings/v8/custom/V8HTMLPictureElementConstructor.h +new file mode 100644 +index 0000000..578dfa1 +--- /dev/null ++++ bindings/v8/custom/V8HTMLPictureElementConstructor.h +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (C) 2009 Google Inc. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are ++ * met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above ++ * copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Google Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived from ++ * this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef V8HTMLPictureElementConstructor_h ++#define V8HTMLPictureElementConstructor_h ++ ++#include "WrapperTypeInfo.h" ++ ++#include ++ ++namespace WebCore { ++ ++class V8HTMLPictureElementConstructor { ++public: ++ static v8::Persistent GetTemplate(); ++ static WrapperTypeInfo info; ++}; ++ ++} ++ ++#endif // V8HTMLPictureElementConstructor_h +diff --git dom/Element.h dom/Element.h +index 58e297d..c451424 100644 +--- dom/Element.h ++++ dom/Element.h +@@ -364,6 +364,8 @@ public: + virtual bool isMediaElement() const { return false; } + #endif + ++ virtual bool isPictureElement() const { return false; } ++ + #if ENABLE(INPUT_SPEECH) + virtual bool isInputFieldSpeechButtonElement() const { return false; } + #endif +diff --git html/HTMLImageElement.cpp html/HTMLImageElement.cpp +index e934e4d..a6bb282 100644 +--- html/HTMLImageElement.cpp ++++ html/HTMLImageElement.cpp +@@ -73,7 +73,7 @@ HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* docum + , m_form(form) + , m_compositeOperator(CompositeSourceOver) + { +- ASSERT(hasTagName(imgTag)); ++ ASSERT((hasTagName(imgTag)) || (hasTagName(pictureTag))); + if (form) + form->registerImgElement(this); + } +@@ -237,6 +237,10 @@ Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* + return HTMLElement::insertedInto(insertionPoint); + } + ++void HTMLImageElement::updateResources() ++{ ++ m_imageLoader.updateFromElement(); ++} + void HTMLImageElement::removedFrom(ContainerNode* insertionPoint) + { + if (m_form) +diff --git html/HTMLImageElement.h html/HTMLImageElement.h +index 9468a79..bd65f6b 100644 +--- html/HTMLImageElement.h ++++ html/HTMLImageElement.h +@@ -93,7 +93,9 @@ protected: + HTMLImageElement(const QualifiedName&, Document*, HTMLFormElement* = 0); + + virtual void didMoveToNewDocument(Document* oldDocument) OVERRIDE; ++ void updateResources(); + ++ virtual void parseAttribute(const Attribute&) OVERRIDE; + private: + virtual void createShadowSubtree(); + +@@ -105,7 +107,6 @@ private: + void refSourceElement() { ref(); } + void derefSourceElement() { deref(); } + +- virtual void parseAttribute(const Attribute&) OVERRIDE; + virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE; + virtual void collectStyleForAttribute(const Attribute&, StylePropertySet*) OVERRIDE; + +diff --git html/HTMLPictureElement.cpp html/HTMLPictureElement.cpp +new file mode 100644 +index 0000000..a7c7d3e +--- /dev/null ++++ html/HTMLPictureElement.cpp +@@ -0,0 +1,110 @@ ++/* ++ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) ++ * (C) 1999 Antti Koivisto (koivisto@kde.org) ++ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. ++ * Copyright (C) 2010 Google Inc. All rights reserved. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Library General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public License ++ * along with this library; see the file COPYING.LIB. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#include "config.h" ++#include "HTMLImageElement.h" ++#include "HTMLPictureElement.h" ++ ++#include "MediaList.h" ++#include "MediaQueryEvaluator.h" ++#include "StyleResolver.h" ++ ++using namespace std; ++ ++namespace WebCore { ++ ++using namespace HTMLNames; ++ ++HTMLPictureElement::HTMLPictureElement(const QualifiedName& tagName, Document* document) ++ : HTMLImageElement(tagName, document, NULL), ++ m_hasSrc(false) ++{ ++ ASSERT(hasTagName(pictureTag)); ++} ++ ++PassRefPtr HTMLPictureElement::create(Document* document) ++{ ++ return adoptRef(new HTMLPictureElement(imgTag, document)); ++} ++ ++PassRefPtr HTMLPictureElement::create(const QualifiedName& tagName, Document* document) ++{ ++ return adoptRef(new HTMLPictureElement(tagName, document)); ++} ++ ++HTMLPictureElement::~HTMLPictureElement() ++{ ++} ++ ++PassRefPtr HTMLPictureElement::createForJSConstructor(Document* document, const int* optionalWidth, const int* optionalHeight) ++{ ++ RefPtr picture = adoptRef(new HTMLPictureElement(imgTag, document)); ++ if (optionalWidth) ++ picture->setWidth(*optionalWidth); ++ if (optionalHeight) ++ picture->setHeight(*optionalHeight); ++ return picture.release(); ++} ++ ++Element* HTMLPictureElement::getMatchingSource(){ ++ if(!m_hasSrc){ ++ NodeVector potentialSourceNodes; ++ getChildNodes(this, potentialSourceNodes); ++ for( NodeVector::iterator it = potentialSourceNodes.begin(); ++ it != potentialSourceNodes.end(); ++ it++){ ++ RefPtr nodePtr = *it; ++ Node* node = nodePtr.get(); ++ if (node && (node->hasTagName(sourceTag)) && (node->parentNode() == this)){ ++ HTMLSourceElement* source = static_cast(node); ++ Document* document = documentInternal(); ++ if (source->fastHasAttribute(srcAttr)) { ++ if (!source->fastHasAttribute(mediaAttr)) { ++ return source; ++ } ++ RefPtr mediaQueries = MediaQuerySet::createAllowingDescriptionSyntax(source->media()); ++ RefPtr documentStyle = StyleResolver::styleForDocument(document, 0); ++ MediaQueryEvaluator mediaQueryEvaluator("screen", document->frame(), documentStyle.get()); ++ if(mediaQueryEvaluator.eval(mediaQueries.get())){ ++ return source; ++ } ++ } ++ } ++ } ++ } ++ return this; ++} ++ ++void HTMLPictureElement::sourceWasAdded(HTMLSourceElement* source) ++{ ++ updateResources(); ++} ++ ++void HTMLPictureElement::parseAttribute(const Attribute& attribute) ++{ ++ if(attribute.name() == srcAttr) ++ m_hasSrc = true; ++ ++ HTMLImageElement::parseAttribute(attribute); ++} ++ ++} +diff --git html/HTMLPictureElement.h html/HTMLPictureElement.h +new file mode 100644 +index 0000000..369bad3 +--- /dev/null ++++ html/HTMLPictureElement.h +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) ++ * (C) 1999 Antti Koivisto (koivisto@kde.org) ++ * Copyright (C) 2004, 2008, 2010 Apple Inc. All rights reserved. ++ * Copyright (C) 2010 Google Inc. All rights reserved. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Library General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public License ++ * along with this library; see the file COPYING.LIB. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ * Boston, MA 02110-1301, USA. ++ * ++ */ ++ ++#ifndef HTMLPictureElement_h ++#define HTMLPictureElement_h ++ ++#include "HTMLImageElement.h" ++#include "HTMLSourceElement.h" ++ ++namespace WebCore { ++ ++class HTMLPictureElement : public HTMLImageElement { ++ HTMLPictureElement(const QualifiedName& tagName, Document* document); ++ ~HTMLPictureElement(); ++ Element* sourceElement() { return getMatchingSource(); } ++ Element* getMatchingSource(); ++ ++ virtual bool isPictureElement() const { return true; } ++ virtual void parseAttribute(const Attribute&); ++ ++ bool m_hasSrc; ++ ++public: ++ static PassRefPtr create(Document* document); ++ ++ static PassRefPtr create(const QualifiedName& tagName, Document* document); ++ static PassRefPtr createForJSConstructor(Document* document, const int* optionalWidth, const int* optionalHeight); ++ void sourceWasAdded(HTMLSourceElement*); ++ ++}; ++ ++} //namespace ++ ++#endif +diff --git html/HTMLPictureElement.idl html/HTMLPictureElement.idl +new file mode 100644 +index 0000000..3093c6e +--- /dev/null ++++ html/HTMLPictureElement.idl +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2006, 2009, 2010 Apple Inc. All rights reserved. ++ * Copyright (C) 2006 Samuel Weinig ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Library General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public License ++ * along with this library; see the file COPYING.LIB. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++module html { ++ ++ interface [ ++ JSGenerateToNativeObject ++ ] HTMLPictureElement : HTMLImageElement { ++ }; ++ ++} +diff --git html/HTMLSourceElement.cpp html/HTMLSourceElement.cpp +index 4ac537b..4055bb8 100644 +--- html/HTMLSourceElement.cpp ++++ html/HTMLSourceElement.cpp +@@ -32,6 +32,7 @@ + #include "EventNames.h" + #include "HTMLDocument.h" + #include "HTMLMediaElement.h" ++#include "HTMLPictureElement.h" + #include "HTMLNames.h" + #include "Logging.h" + +@@ -60,6 +61,8 @@ Node::InsertionNotificationRequest HTMLSourceElement::insertedInto(ContainerNode + Element* parent = parentElement(); + if (parent && parent->isMediaElement()) + static_cast(parentNode())->sourceWasAdded(this); ++ if (parent && parent->isPictureElement()) ++ static_cast(parentNode())->sourceWasAdded(this); + return InsertionDone; + } + +@@ -78,6 +81,11 @@ void HTMLSourceElement::setSrc(const String& url) + setAttribute(srcAttr, url); + } + ++String HTMLSourceElement::src() const ++{ ++ return getAttribute(srcAttr); ++} ++ + String HTMLSourceElement::media() const + { + return getAttribute(mediaAttr); +diff --git html/HTMLSourceElement.h html/HTMLSourceElement.h +index 15920e3..0e9446c 100644 +--- html/HTMLSourceElement.h ++++ html/HTMLSourceElement.h +@@ -37,6 +37,7 @@ class HTMLSourceElement : public HTMLElement { + public: + static PassRefPtr create(const QualifiedName&, Document*); + ++ String src() const; + String media() const; + String type() const; + void setSrc(const String&); +diff --git html/HTMLTagNames.in html/HTMLTagNames.in +index 3660ab9..0155115 100644 +--- html/HTMLTagNames.in ++++ html/HTMLTagNames.in +@@ -68,6 +68,7 @@ i interfaceName=HTMLElement + iframe interfaceName=HTMLIFrameElement + image mapToTagName=img + img interfaceName=HTMLImageElement, constructorNeedsFormElement ++picture interfaceName=HTMLPictureElement + webkitInnerImage interfaceName=HTMLElement, noConstructor + input constructorNeedsFormElement, constructorNeedsCreatedByParser + intent conditional=WEB_INTENTS_TAG +diff --git html/parser/HTMLPreloadScanner.cpp html/parser/HTMLPreloadScanner.cpp +index a75b52e..fad61d4 100644 +--- html/parser/HTMLPreloadScanner.cpp ++++ html/parser/HTMLPreloadScanner.cpp +@@ -38,6 +38,7 @@ + #include "LinkRelAttribute.h" + #include "MediaList.h" + #include "MediaQueryEvaluator.h" ++#include "StyleResolver.h" + + namespace WebCore { + +@@ -45,18 +46,26 @@ using namespace HTMLNames; + + class PreloadTask { + public: +- explicit PreloadTask(const HTMLToken& token) ++ explicit PreloadTask(const HTMLToken& token, bool inPicture, bool picturePreloaded, Frame* frame, RenderStyle* renderStyle) + : m_tagName(token.name().data(), token.name().size()) + , m_linkIsStyleSheet(false) + , m_linkMediaAttributeIsScreen(true) + , m_inputIsImage(false) ++ , m_inPictureSubTree(inPicture) ++ , m_picturePreloaded(picturePreloaded) ++ , m_frame(frame) ++ , m_renderStyle(renderStyle) + { + processAttributes(token.attributes()); + } + ++ bool picturePreloaded(){return m_picturePreloaded;} ++ + void processAttributes(const HTMLToken::AttributeList& attributes) + { +- if (m_tagName != imgTag ++ if ((m_tagName != imgTag || m_inPictureSubTree) ++ && (m_tagName != sourceTag || !m_inPictureSubTree || m_picturePreloaded) ++ && m_tagName != pictureTag + && m_tagName != inputTag + && m_tagName != linkTag + && m_tagName != scriptTag +@@ -74,6 +83,16 @@ public: + if (m_tagName == scriptTag || m_tagName == imgTag) { + if (attributeName == srcAttr) + setUrlToLoad(attributeValue); ++ } else if (m_tagName == pictureTag) { ++ if (attributeName == srcAttr) { ++ setUrlToLoad(attributeValue); ++ m_picturePreloaded = true; ++ } ++ } else if (m_tagName == sourceTag) { ++ if (attributeName == srcAttr) ++ setUrlToLoad(attributeValue); ++ else if (attributeName == mediaAttr) ++ m_sourceMediaAttributeMatches = sourceMediaAttributeMatches(attributeValue); + } else if (m_tagName == linkTag) { + if (attributeName == hrefAttr) + setUrlToLoad(attributeValue); +@@ -99,6 +118,13 @@ public: + return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == InvalidIcon && !rel.m_isDNSPrefetch; + } + ++ bool sourceMediaAttributeMatches(const String& attributeValue){ ++ if (attributeValue.isEmpty()) ++ return true; ++ RefPtr mediaQueries = MediaQuerySet::createAllowingDescriptionSyntax(attributeValue); ++ MediaQueryEvaluator mediaQueryEvaluator("screen", m_frame, m_renderStyle); ++ return mediaQueryEvaluator.eval(mediaQueries.get()); ++ } + static bool linkMediaAttributeIsScreen(const String& attributeValue) + { + if (attributeValue.isEmpty()) +@@ -130,8 +156,14 @@ public: + ResourceRequest request = document->completeURL(m_urlToLoad, baseURL); + if (m_tagName == scriptTag) + cachedResourceLoader- \ No newline at end of file