diff options
author | Steve Block <steveblock@google.com> | 2011-05-18 13:36:51 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-24 15:38:28 +0100 |
commit | 2fc2651226baac27029e38c9d6ef883fa32084db (patch) | |
tree | e396d4bf89dcce6ed02071be66212495b1df1dec /Source/WebCore/html | |
parent | b3725cedeb43722b3b175aaeff70552e562d2c94 (diff) | |
download | external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.zip external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.gz external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.bz2 |
Merge WebKit at r78450: Initial merge by git.
Change-Id: I6d3e5f1f868ec266a0aafdef66182ddc3f265dc1
Diffstat (limited to 'Source/WebCore/html')
157 files changed, 2595 insertions, 814 deletions
diff --git a/Source/WebCore/html/DOMURL.cpp b/Source/WebCore/html/DOMURL.cpp index 87f9f45..d0f0aeb 100644 --- a/Source/WebCore/html/DOMURL.cpp +++ b/Source/WebCore/html/DOMURL.cpp @@ -37,6 +37,20 @@ namespace WebCore { DOMURL::DOMURL(ScriptExecutionContext* scriptExecutionContext) : m_scriptExecutionContext(scriptExecutionContext) { + if (m_scriptExecutionContext) + m_scriptExecutionContext->createdDomUrl(this); +} + +DOMURL::~DOMURL() +{ + if (m_scriptExecutionContext) + m_scriptExecutionContext->destroyedDomUrl(this); +} + +void DOMURL::contextDestroyed() +{ + ASSERT(m_scriptExecutionContext); + m_scriptExecutionContext = 0; } String DOMURL::createObjectURL(Blob* blob) diff --git a/Source/WebCore/html/DOMURL.h b/Source/WebCore/html/DOMURL.h index 57f3000..dff4dd8 100644 --- a/Source/WebCore/html/DOMURL.h +++ b/Source/WebCore/html/DOMURL.h @@ -40,10 +40,14 @@ class ScriptExecutionContext; class DOMURL : public RefCounted<DOMURL> { public: static PassRefPtr<DOMURL> create(ScriptExecutionContext* scriptExecutionContext) { return adoptRef(new DOMURL(scriptExecutionContext)); } + ~DOMURL(); String createObjectURL(Blob*); void revokeObjectURL(const String&); - + + void contextDestroyed(); + ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; } + private: explicit DOMURL(ScriptExecutionContext*); diff --git a/Source/WebCore/html/FTPDirectoryDocument.cpp b/Source/WebCore/html/FTPDirectoryDocument.cpp index 2a08696..dc89045 100644 --- a/Source/WebCore/html/FTPDirectoryDocument.cpp +++ b/Source/WebCore/html/FTPDirectoryDocument.cpp @@ -26,7 +26,6 @@ #if ENABLE(FTPDIR) #include "FTPDirectoryDocument.h" -#include "CharacterNames.h" #include "HTMLDocumentParser.h" #include "HTMLNames.h" #include "HTMLTableElement.h" @@ -37,11 +36,11 @@ #include "Settings.h" #include "SharedBuffer.h" #include "Text.h" - #include <wtf/text/CString.h> #include <wtf/text/StringConcatenate.h> #include <wtf/CurrentTime.h> #include <wtf/StdLibExtras.h> +#include <wtf/unicode/CharacterNames.h> using namespace std; diff --git a/Source/WebCore/html/FormAssociatedElement.cpp b/Source/WebCore/html/FormAssociatedElement.cpp index 574dfe5..3571744 100644 --- a/Source/WebCore/html/FormAssociatedElement.cpp +++ b/Source/WebCore/html/FormAssociatedElement.cpp @@ -59,11 +59,24 @@ void FormAssociatedElement::willMoveToNewOwnerDocument() element->document()->unregisterFormElementWithFormAttribute(this); } +void FormAssociatedElement::insertedIntoDocument() +{ + HTMLElement* element = toHTMLElement(this); + if (element->fastHasAttribute(formAttr)) + element->document()->registerFormElementWithFormAttribute(this); +} + +void FormAssociatedElement::removedFromDocument() +{ + HTMLElement* element = toHTMLElement(this); + if (element->fastHasAttribute(formAttr)) + element->document()->unregisterFormElementWithFormAttribute(this); +} + void FormAssociatedElement::insertedIntoTree() { HTMLElement* element = toHTMLElement(this); if (element->fastHasAttribute(formAttr)) { - element->document()->registerFormElementWithFormAttribute(this); Element* formElement = element->document()->getElementById(element->fastGetAttribute(formAttr)); if (formElement && formElement->hasTagName(formTag)) { if (m_form) @@ -94,8 +107,6 @@ static inline Node* findRoot(Node* n) void FormAssociatedElement::removedFromTree() { HTMLElement* element = toHTMLElement(this); - if (element->fastHasAttribute(formAttr)) - element->document()->unregisterFormElementWithFormAttribute(this); // If the form and element are both in the same tree, preserve the connection to the form. // Otherwise, null out our form and remove ourselves from the form's list of elements. diff --git a/Source/WebCore/html/FormAssociatedElement.h b/Source/WebCore/html/FormAssociatedElement.h index ebefdc6..aa5abd9 100644 --- a/Source/WebCore/html/FormAssociatedElement.h +++ b/Source/WebCore/html/FormAssociatedElement.h @@ -63,7 +63,8 @@ protected: void insertedIntoTree(); void removedFromTree(); - + void insertedIntoDocument(); + void removedFromDocument(); void willMoveToNewOwnerDocument(); void setForm(HTMLFormElement* form) { m_form = form; } diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp index dcdde28..0c10022 100644 --- a/Source/WebCore/html/HTMLAnchorElement.cpp +++ b/Source/WebCore/html/HTMLAnchorElement.cpp @@ -541,7 +541,7 @@ bool isMiddleMouseButtonEvent(Event* event) bool isLinkClick(Event* event) { - return event->type() == eventNames().clickEvent || (event->type() == eventNames().mouseupEvent && isMiddleMouseButtonEvent(event)); + return event->type() == eventNames().clickEvent && (!event->isMouseEvent() || static_cast<MouseEvent*>(event)->button() != RightButton); } void handleLinkClick(Event* event, Document* document, const String& url, const String& target, bool hideReferrer) @@ -551,8 +551,6 @@ void handleLinkClick(Event* event, Document* document, const String& url, const Frame* frame = document->frame(); if (!frame) return; - // FIXME: This seems wrong. Why are we manufactuing a user gesture? - UserGestureIndicator indicator(DefinitelyProcessingUserGesture); frame->loader()->urlSelected(document->completeURL(url), target, event, false, false, hideReferrer ? NoReferrer : SendReferrer); } diff --git a/Source/WebCore/html/HTMLAreaElement.cpp b/Source/WebCore/html/HTMLAreaElement.cpp index ac4c865..9832d06 100644 --- a/Source/WebCore/html/HTMLAreaElement.cpp +++ b/Source/WebCore/html/HTMLAreaElement.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2009, 2011 Apple 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 @@ -30,7 +30,7 @@ #include "HTMLNames.h" #include "HitTestResult.h" #include "Path.h" -#include "RenderObject.h" +#include "RenderImage.h" using namespace std; @@ -64,7 +64,7 @@ void HTMLAreaElement::parseMappedAttribute(Attribute* attr) else if (equalIgnoringCase(attr->value(), "rect")) m_shape = Rect; } else if (attr->name() == coordsAttr) { - m_coords.set(newCoordsArray(attr->value().string(), m_coordsLen)); + m_coords = newCoordsArray(attr->value().string(), m_coordsLen); } else if (attr->name() == altAttr || attr->name() == accesskeyAttr) { // Do nothing. } else @@ -86,7 +86,7 @@ bool HTMLAreaElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestRe return true; } -Path HTMLAreaElement::getPath(RenderObject* obj) const +Path HTMLAreaElement::computePath(RenderObject* obj) const { if (!obj) return Path(); @@ -111,9 +111,9 @@ Path HTMLAreaElement::getPath(RenderObject* obj) const return p; } -IntRect HTMLAreaElement::getRect(RenderObject* obj) const +IntRect HTMLAreaElement::computeRect(RenderObject* obj) const { - return enclosingIntRect(getPath(obj).boundingRect()); + return enclosingIntRect(computePath(obj).boundingRect()); } Path HTMLAreaElement::getRegion(const IntSize& size) const @@ -196,33 +196,34 @@ bool HTMLAreaElement::isFocusable() const return supportsFocus() && Element::tabIndex() >= 0; } -void HTMLAreaElement::dispatchBlurEvent() +void HTMLAreaElement::setFocus(bool shouldBeFocused) { - HTMLAnchorElement::dispatchBlurEvent(); - - // On a blur, we might need to remove our focus rings by repainting. - updateFocusAppearance(false); + if (focused() == shouldBeFocused) + return; + + HTMLAnchorElement::setFocus(shouldBeFocused); + + HTMLImageElement* imageElement = this->imageElement(); + if (!imageElement) + return; + + RenderObject* renderer = imageElement->renderer(); + if (!renderer || !renderer->isImage()) + return; + + toRenderImage(renderer)->areaElementFocusChanged(this); } void HTMLAreaElement::updateFocusAppearance(bool restorePreviousSelection) { if (!isFocusable()) return; - - ContainerNode* parent = parentNode(); - if (!parent || !parent->hasTagName(mapTag)) - return; - - HTMLImageElement* imageElement = static_cast<HTMLMapElement*>(parent)->imageElement(); + + HTMLImageElement* imageElement = this->imageElement(); if (!imageElement) return; - - // This will handle scrolling to the image if necessary. + imageElement->updateFocusAppearance(restorePreviousSelection); - - RenderObject* imageRenderer = imageElement->renderer(); - if (imageRenderer) - imageRenderer->setNeedsLayout(true); } bool HTMLAreaElement::supportsFocus() const diff --git a/Source/WebCore/html/HTMLAreaElement.h b/Source/WebCore/html/HTMLAreaElement.h index 42d4198..34f5ba9 100644 --- a/Source/WebCore/html/HTMLAreaElement.h +++ b/Source/WebCore/html/HTMLAreaElement.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2008, 2009, 2011 Apple 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 @@ -41,8 +41,8 @@ public: bool mapMouseEvent(int x, int y, const IntSize&, HitTestResult&); - IntRect getRect(RenderObject*) const; - Path getPath(RenderObject*) const; + IntRect computeRect(RenderObject*) const; + Path computePath(RenderObject*) const; // The parent map's image. HTMLImageElement* imageElement() const; @@ -57,7 +57,7 @@ private: virtual bool isMouseFocusable() const; virtual bool isFocusable() const; virtual void updateFocusAppearance(bool /*restorePreviousSelection*/); - virtual void dispatchBlurEvent(); + virtual void setFocus(bool); enum Shape { Default, Poly, Rect, Circle, Unknown }; Path getRegion(const IntSize&) const; diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in index eac9a73..d195a6f 100644 --- a/Source/WebCore/html/HTMLAttributeNames.in +++ b/Source/WebCore/html/HTMLAttributeNames.in @@ -41,6 +41,7 @@ aria-readonly aria-relevant aria-required aria-selected +aria-sort aria-valuemax aria-valuemin aria-valuenow diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp index 0fdb7b2..09e8d04 100644 --- a/Source/WebCore/html/HTMLCanvasElement.cpp +++ b/Source/WebCore/html/HTMLCanvasElement.cpp @@ -48,7 +48,11 @@ #include <math.h> #include <stdio.h> -#if ENABLE(3D_CANVAS) +#if USE(JSC) +#include <runtime/JSLock.h> +#endif + +#if ENABLE(WEBGL) #include "WebGLContextAttributes.h" #include "WebGLRenderingContext.h" #endif @@ -166,7 +170,7 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas } return m_context.get(); } -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) Settings* settings = document()->settings(); if (settings && settings->webGLEnabled() #if !PLATFORM(CHROMIUM) && !PLATFORM(QT) @@ -232,7 +236,7 @@ void HTMLCanvasElement::reset() IntSize oldSize = size(); setSurfaceSize(IntSize(w, h)); // The image buffer gets cleared here. -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) if (m_context && m_context->is3d() && oldSize != size()) static_cast<WebGLRenderingContext*>(m_context.get())->reshape(width(), height()); #endif @@ -279,7 +283,7 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r) } } -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) bool HTMLCanvasElement::is3D() const { return m_context && m_context->is3d(); @@ -344,10 +348,10 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const { - float left = floorf(logicalRect.left() * m_pageScaleFactor); - float top = floorf(logicalRect.top() * m_pageScaleFactor); - float right = ceilf(logicalRect.right() * m_pageScaleFactor); - float bottom = ceilf(logicalRect.bottom() * m_pageScaleFactor); + float left = floorf(logicalRect.x() * m_pageScaleFactor); + float top = floorf(logicalRect.y() * m_pageScaleFactor); + float right = ceilf(logicalRect.maxX() * m_pageScaleFactor); + float bottom = ceilf(logicalRect.maxY() * m_pageScaleFactor); return IntRect(IntPoint(left, top), convertToValidDeviceSize(right - left, bottom - top)); } @@ -408,8 +412,10 @@ void HTMLCanvasElement::createImageBuffer() const m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality); #if USE(JSC) - if (hasCachedDOMNodeWrapperUnchecked(document(), const_cast<HTMLCanvasElement*>(this))) + if (hasCachedDOMNodeWrapperUnchecked(document(), const_cast<HTMLCanvasElement*>(this))) { + JSC::JSLock lock(JSC::SilenceAssertionsOnly); scriptExecutionContext()->globalData()->heap.reportExtraMemoryCost(m_imageBuffer->dataSize()); + } #endif } diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h index 1f32dec..5c8ac9a 100644 --- a/Source/WebCore/html/HTMLCanvasElement.h +++ b/Source/WebCore/html/HTMLCanvasElement.h @@ -118,7 +118,7 @@ public: AffineTransform baseTransform() const; -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) bool is3D() const; #endif diff --git a/Source/WebCore/html/HTMLCollection.cpp b/Source/WebCore/html/HTMLCollection.cpp index 9b4e566..7d776d1 100644 --- a/Source/WebCore/html/HTMLCollection.cpp +++ b/Source/WebCore/html/HTMLCollection.cpp @@ -264,7 +264,7 @@ bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const A if (!element->isHTMLElement()) return false; - HTMLElement* e = static_cast<HTMLElement*>(element); + HTMLElement* e = toHTMLElement(element); if (!checkName) return e->getIdAttribute() == name; @@ -318,7 +318,7 @@ void HTMLCollection::updateNameCache() const for (Element* element = itemAfter(0); element; element = itemAfter(element)) { if (!element->isHTMLElement()) continue; - HTMLElement* e = static_cast<HTMLElement*>(element); + HTMLElement* e = toHTMLElement(element); const AtomicString& idAttrVal = e->getIdAttribute(); const AtomicString& nameAttrVal = e->getAttribute(nameAttr); if (!idAttrVal.isEmpty()) { diff --git a/Source/WebCore/html/HTMLDocument.cpp b/Source/WebCore/html/HTMLDocument.cpp index 84ad706..dd41514 100644 --- a/Source/WebCore/html/HTMLDocument.cpp +++ b/Source/WebCore/html/HTMLDocument.cpp @@ -69,7 +69,7 @@ #include "HTMLBodyElement.h" #include "HTMLElementFactory.h" #include "HTMLNames.h" -#include "InspectorController.h" +#include "InspectorInstrumentation.h" #include "KURL.h" #include "Page.h" #include "Settings.h" @@ -79,8 +79,8 @@ namespace WebCore { using namespace HTMLNames; -HTMLDocument::HTMLDocument(Frame* frame, const KURL& url, const KURL& baseURL) - : Document(frame, url, false, true, baseURL) +HTMLDocument::HTMLDocument(Frame* frame, const KURL& url) + : Document(frame, url, false, true) { clearXMLVersion(); } @@ -277,11 +277,7 @@ void HTMLDocument::releaseEvents() PassRefPtr<DocumentParser> HTMLDocument::createParser() { - bool reportErrors = false; -#if ENABLE(INSPECTOR) - if (Page* page = this->page()) - reportErrors = page->inspectorController()->hasFrontend(); -#endif + bool reportErrors = InspectorInstrumentation::hasFrontend(this->page()); return HTMLDocumentParser::create(this, reportErrors); } diff --git a/Source/WebCore/html/HTMLDocument.h b/Source/WebCore/html/HTMLDocument.h index 37edd87..3310b71 100644 --- a/Source/WebCore/html/HTMLDocument.h +++ b/Source/WebCore/html/HTMLDocument.h @@ -35,9 +35,9 @@ class HTMLElement; class HTMLDocument : public Document, public CachedResourceClient { public: - static PassRefPtr<HTMLDocument> create(Frame* frame, const KURL& url, const KURL& baseURL = KURL()) + static PassRefPtr<HTMLDocument> create(Frame* frame, const KURL& url) { - return adoptRef(new HTMLDocument(frame, url, baseURL)); + return adoptRef(new HTMLDocument(frame, url)); } virtual ~HTMLDocument(); @@ -80,7 +80,7 @@ public: bool hasExtraNamedItem(AtomicStringImpl* name); protected: - HTMLDocument(Frame* frame, const KURL& url, const KURL& baseURL = KURL()); + HTMLDocument(Frame*, const KURL&); #ifdef ANDROID_INSTRUMENT // Overridden to resolve the ambiguous diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp index b7eca06..22fc2f2 100644 --- a/Source/WebCore/html/HTMLElement.cpp +++ b/Source/WebCore/html/HTMLElement.cpp @@ -371,7 +371,7 @@ void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec) ec = NO_MODIFICATION_ALLOWED_ERR; return; } - HTMLElement* parent = static_cast<HTMLElement*>(p); + HTMLElement* parent = toHTMLElement(p); RefPtr<DocumentFragment> fragment = createFragmentFromSource(html, parent, ec); if (fragment) { @@ -735,6 +735,8 @@ void HTMLElement::setContentEditable(const String& enabled, ExceptionCode& ec) setAttribute(contenteditableAttr, "true", ec); else if (equalIgnoringCase(enabled, "false")) setAttribute(contenteditableAttr, "false", ec); + else if (equalIgnoringCase(enabled, "plaintext-only")) + setAttribute(contenteditableAttr, "plaintext-only"); else if (equalIgnoringCase(enabled, "inherit")) removeAttribute(contenteditableAttr, ec); else @@ -850,7 +852,7 @@ HTMLFormElement* HTMLElement::shadowAncestorOwnerForm() if (!ancestorNode->isHTMLElement()) return 0; - HTMLElement* ancestorHTML = static_cast<HTMLElement*>(ancestorNode); + HTMLElement* ancestorHTML = toHTMLElement(ancestorNode); if (!ancestorHTML) return 0; return ancestorHTML->form(); diff --git a/Source/WebCore/html/HTMLElement.h b/Source/WebCore/html/HTMLElement.h index ad84f5d..2f6bc41 100644 --- a/Source/WebCore/html/HTMLElement.h +++ b/Source/WebCore/html/HTMLElement.h @@ -108,6 +108,18 @@ private: HTMLFormElement* shadowAncestorOwnerForm(); }; +inline HTMLElement* toHTMLElement(Node* node) +{ + ASSERT(!node || node->isHTMLElement()); + return static_cast<HTMLElement*>(node); +} + +inline const HTMLElement* toHTMLElement(const Node* node) +{ + ASSERT(!node || node->isHTMLElement()); + return static_cast<const HTMLElement*>(node); +} + inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document* document) : StyledElement(tagName, document, CreateHTMLElement) { diff --git a/Source/WebCore/html/HTMLEmbedElement.cpp b/Source/WebCore/html/HTMLEmbedElement.cpp index df97280..f419e2a 100644 --- a/Source/WebCore/html/HTMLEmbedElement.cpp +++ b/Source/WebCore/html/HTMLEmbedElement.cpp @@ -138,7 +138,7 @@ void HTMLEmbedElement::parametersForPlugin(Vector<String>& paramNames, Vector<St // FIXME: This should be unified with HTMLObjectElement::updateWidget and // moved down into HTMLPluginImageElement.cpp -void HTMLEmbedElement::updateWidget(bool onlyCreateNonNetscapePlugins) +void HTMLEmbedElement::updateWidget(PluginCreationOption pluginCreationOption) { ASSERT(!renderEmbeddedObject()->pluginCrashedOrWasMissing()); // FIXME: We should ASSERT(needsWidgetUpdate()), but currently @@ -153,7 +153,10 @@ void HTMLEmbedElement::updateWidget(bool onlyCreateNonNetscapePlugins) // <object> which modifies url and serviceType before calling these. if (!allowedToLoadFrameURL(m_url)) return; - if (onlyCreateNonNetscapePlugins && wouldLoadAsNetscapePlugin(m_url, m_serviceType)) + // FIXME: It's sadness that we have this special case here. + // See http://trac.webkit.org/changeset/25128 and + // plugins/netscape-plugin-setwindow-size.html + if (pluginCreationOption == CreateOnlyNonNetscapePlugins && wouldLoadAsNetscapePlugin(m_url, m_serviceType)) return; // FIXME: These should be joined into a PluginParameters class. diff --git a/Source/WebCore/html/HTMLEmbedElement.h b/Source/WebCore/html/HTMLEmbedElement.h index 70eb0dc..863c09b 100644 --- a/Source/WebCore/html/HTMLEmbedElement.h +++ b/Source/WebCore/html/HTMLEmbedElement.h @@ -47,7 +47,7 @@ private: virtual RenderWidget* renderWidgetForJSBindings() const; - virtual void updateWidget(bool onlyCreateNonNetscapePlugins); + virtual void updateWidget(PluginCreationOption); virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const; diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp index bb42dfd..2f3db08 100644 --- a/Source/WebCore/html/HTMLFormControlElement.cpp +++ b/Source/WebCore/html/HTMLFormControlElement.cpp @@ -26,7 +26,6 @@ #include "HTMLFormControlElement.h" #include "Attribute.h" -#include "CharacterNames.h" #include "Chrome.h" #include "ChromeClient.h" #include "Document.h" @@ -49,6 +48,7 @@ #include "ValidityState.h" #include <limits> #include <wtf/Vector.h> +#include <wtf/unicode/CharacterNames.h> namespace WebCore { @@ -165,6 +165,18 @@ void HTMLFormControlElement::removedFromTree(bool deep) HTMLElement::removedFromTree(deep); } +void HTMLFormControlElement::insertedIntoDocument() +{ + HTMLElement::insertedIntoDocument(); + FormAssociatedElement::insertedIntoDocument(); +} + +void HTMLFormControlElement::removedFromDocument() +{ + HTMLElement::removedFromDocument(); + FormAssociatedElement::removedFromDocument(); +} + const AtomicString& HTMLFormControlElement::formControlName() const { const AtomicString& name = fastGetAttribute(nameAttr); @@ -570,8 +582,8 @@ bool HTMLTextFormControlElement::placeholderShouldBeVisible() const { return supportsPlaceholder() && isEmptyValue() - && document()->focusedNode() != this - && !isPlaceholderEmpty(); + && !isPlaceholderEmpty() + && (document()->focusedNode() != this || (renderer() && renderer()->theme()->shouldShowPlaceholderWhenFocused())); } void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderValueChanged) diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h index c88905c..368dcfa 100644 --- a/Source/WebCore/html/HTMLFormControlElement.h +++ b/Source/WebCore/html/HTMLFormControlElement.h @@ -111,6 +111,8 @@ protected: virtual void attach(); virtual void insertedIntoTree(bool deep); virtual void removedFromTree(bool deep); + virtual void insertedIntoDocument(); + virtual void removedFromDocument(); virtual void willMoveToNewOwnerDocument(); virtual bool isKeyboardFocusable(KeyboardEvent*) const; @@ -170,14 +172,13 @@ protected: HTMLFormControlElementWithState(const QualifiedName& tagName, Document*, HTMLFormElement*); virtual bool autoComplete() const; - + virtual void finishParsingChildren(); virtual void willMoveToNewOwnerDocument(); virtual void didMoveToNewOwnerDocument(); virtual void defaultEventHandler(Event*); private: virtual bool shouldSaveAndRestoreFormControlState() const; - virtual void finishParsingChildren(); }; // FIXME: Give this class its own header file. diff --git a/Source/WebCore/html/HTMLFormElement.cpp b/Source/WebCore/html/HTMLFormElement.cpp index d778601..8535027 100644 --- a/Source/WebCore/html/HTMLFormElement.cpp +++ b/Source/WebCore/html/HTMLFormElement.cpp @@ -221,8 +221,7 @@ bool HTMLFormElement::validateInteractively(Event* event) } Vector<RefPtr<FormAssociatedElement> > unhandledInvalidControls; - collectUnhandledInvalidControls(unhandledInvalidControls); - if (unhandledInvalidControls.isEmpty()) + if (!checkInvalidControlsAndCollectUnhandled(unhandledInvalidControls)) return true; // If the form has invalid controls, abort submission. @@ -463,7 +462,7 @@ unsigned HTMLFormElement::formElementIndex(FormAssociatedElement* associatedElem if (node->isHTMLElement() && (static_cast<Element*>(node)->isFormControlElement() || node->hasTagName(objectTag)) - && static_cast<HTMLElement*>(node)->form() == this) + && toHTMLElement(node)->form() == this) ++i; } } @@ -586,8 +585,7 @@ HTMLFormControlElement* HTMLFormElement::defaultButton() const bool HTMLFormElement::checkValidity() { Vector<RefPtr<FormAssociatedElement> > controls; - collectUnhandledInvalidControls(controls); - return controls.isEmpty(); + return !checkInvalidControlsAndCollectUnhandled(controls); } void HTMLFormElement::broadcastFormEvent(const AtomicString& eventName) @@ -623,7 +621,7 @@ void HTMLFormElement::dispatchFormChange() broadcastFormEvent(eventNames().formchangeEvent); } -void HTMLFormElement::collectUnhandledInvalidControls(Vector<RefPtr<FormAssociatedElement> >& unhandledInvalidControls) +bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >& unhandledInvalidControls) { RefPtr<HTMLFormElement> protector(this); // Copy m_associatedElements because event handlers called from @@ -632,10 +630,15 @@ void HTMLFormElement::collectUnhandledInvalidControls(Vector<RefPtr<FormAssociat elements.reserveCapacity(m_associatedElements.size()); for (unsigned i = 0; i < m_associatedElements.size(); ++i) elements.append(m_associatedElements[i]); + bool hasInvalidControls = false; for (unsigned i = 0; i < elements.size(); ++i) { - if (elements[i]->form() == this && elements[i]->isFormControlElement()) - static_cast<HTMLFormControlElement*>(elements[i].get())->checkValidity(&unhandledInvalidControls); + if (elements[i]->form() == this && elements[i]->isFormControlElement()) { + HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(elements[i].get()); + if (!control->checkValidity(&unhandledInvalidControls) && control->form() == this) + hasInvalidControls = true; + } } + return hasInvalidControls; } HTMLFormControlElement* HTMLFormElement::elementForAlias(const AtomicString& alias) diff --git a/Source/WebCore/html/HTMLFormElement.h b/Source/WebCore/html/HTMLFormElement.h index 7d7f4f8..f723533 100644 --- a/Source/WebCore/html/HTMLFormElement.h +++ b/Source/WebCore/html/HTMLFormElement.h @@ -144,8 +144,9 @@ private: bool validateInteractively(Event*); // Validates each of the controls, and stores controls of which 'invalid' - // event was not canceled to the specified vector. - void collectUnhandledInvalidControls(Vector<RefPtr<FormAssociatedElement> >&); + // event was not canceled to the specified vector. Returns true if there + // are any invalid controls in this form. + bool checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >&); void broadcastFormEvent(const AtomicString&); diff --git a/Source/WebCore/html/HTMLFrameElementBase.cpp b/Source/WebCore/html/HTMLFrameElementBase.cpp index 47465c6..cf079ea 100644 --- a/Source/WebCore/html/HTMLFrameElementBase.cpp +++ b/Source/WebCore/html/HTMLFrameElementBase.cpp @@ -80,7 +80,7 @@ bool HTMLFrameElementBase::isURLAllowed() const // But we don't allow more than one. bool foundSelfReference = false; for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) { - if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) { + if (equalIgnoringFragmentIdentifier(frame->document()->url(), completeURL)) { if (foundSelfReference) return false; foundSelfReference = true; diff --git a/Source/WebCore/html/HTMLFrameSetElement.cpp b/Source/WebCore/html/HTMLFrameSetElement.cpp index 0bb6c56..50f921b 100644 --- a/Source/WebCore/html/HTMLFrameSetElement.cpp +++ b/Source/WebCore/html/HTMLFrameSetElement.cpp @@ -75,12 +75,12 @@ void HTMLFrameSetElement::parseMappedAttribute(Attribute* attr) { if (attr->name() == rowsAttr) { if (!attr->isNull()) { - m_rowLengths.set(newLengthArray(attr->value().string(), m_totalRows)); + m_rowLengths = newLengthArray(attr->value().string(), m_totalRows); setNeedsStyleRecalc(); } } else if (attr->name() == colsAttr) { if (!attr->isNull()) { - m_colLengths.set(newLengthArray(attr->value().string(), m_totalCols)); + m_colLengths = newLengthArray(attr->value().string(), m_totalCols); setNeedsStyleRecalc(); } } else if (attr->name() == frameborderAttr) { diff --git a/Source/WebCore/html/HTMLImageLoader.cpp b/Source/WebCore/html/HTMLImageLoader.cpp index 710c177..ab4ae29 100644 --- a/Source/WebCore/html/HTMLImageLoader.cpp +++ b/Source/WebCore/html/HTMLImageLoader.cpp @@ -33,6 +33,7 @@ #if USE(JSC) #include "JSDOMWindowBase.h" +#include <runtime/JSLock.h> #endif namespace WebCore { @@ -76,6 +77,7 @@ void HTMLImageLoader::notifyFinished(CachedResource*) #if USE(JSC) if (!loadError) { if (!elem->inDocument()) { + JSC::JSLock lock(JSC::SilenceAssertionsOnly); JSC::JSGlobalData* globalData = JSDOMWindowBase::commonJSGlobalData(); globalData->heap.reportExtraMemoryCost(cachedImage->encodedSize()); } diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index 0d20389..14dd149 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -45,6 +45,7 @@ #include "KeyboardEvent.h" #include "LocalizedStrings.h" #include "MouseEvent.h" +#include "PlatformMouseEvent.h" #include "RenderTextControlSingleLine.h" #include "RenderTheme.h" #include "RuntimeEnabledFeatures.h" @@ -69,7 +70,7 @@ using namespace HTMLNames; const int maxSavedResults = 256; -HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) +HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser) : HTMLTextFormControlElement(tagName, document, form) , m_maxResults(-1) , m_isChecked(false) @@ -79,14 +80,16 @@ HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* docum , m_isActivatedSubmit(false) , m_autocomplete(Uninitialized) , m_isAutofilled(false) + , m_stateRestored(false) + , m_parsingInProgress(createdByParser) , m_inputType(InputType::createText(this)) { ASSERT(hasTagName(inputTag) || hasTagName(isindexTag)); } -PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form) +PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser) { - return adoptRef(new HTMLInputElement(tagName, document, form)); + return adoptRef(new HTMLInputElement(tagName, document, form, createdByParser)); } HTMLInputElement::~HTMLInputElement() @@ -146,7 +149,7 @@ void HTMLInputElement::updateCheckedRadioButtons() control->setNeedsValidityCheck(); } } - + if (renderer() && renderer()->style()->hasAppearance()) renderer()->theme()->stateChanged(renderer(), CheckedState); } @@ -356,7 +359,7 @@ void HTMLInputElement::applyStep(double count, ExceptionCode& ec) if (newValue > m_inputType->maximum()) newValue = m_inputType->maximum(); setValueAsNumber(newValue, ec); - + if (AXObjectCache::accessibilityEnabled()) document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true); } @@ -386,7 +389,7 @@ bool HTMLInputElement::isMouseFocusable() const } void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection) -{ +{ if (isTextField()) InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection); else @@ -517,6 +520,7 @@ bool HTMLInputElement::saveFormControlState(String& result) const void HTMLInputElement::restoreFormControlState(const String& state) { m_inputType->restoreFormControlState(state); + m_stateRestored = true; } bool HTMLInputElement::canStartSelection() const @@ -539,11 +543,11 @@ void HTMLInputElement::accessKeyAction(bool sendToAnyElement) bool HTMLInputElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const { if (((attrName == heightAttr || attrName == widthAttr) && m_inputType->shouldRespectHeightAndWidthAttributes()) - || attrName == vspaceAttr + || attrName == vspaceAttr || attrName == hspaceAttr) { result = eUniversal; return false; - } + } if (attrName == alignAttr && m_inputType->shouldRespectAlignAttribute()) { // Share with <img> since the alignment behavior is the same. @@ -585,11 +589,14 @@ void HTMLInputElement::parseMappedAttribute(Attribute* attr) setFormControlValueMatchesRenderer(false); setNeedsValidityCheck(); } else if (attr->name() == checkedAttr) { - if (m_reflectsCheckedAttribute) { + // Another radio button in the same group might be checked by state + // restore. We shouldn't call setChecked() even if this has the checked + // attribute. So, delay the setChecked() call until + // finishParsingChildren() is called if parsing is in progress. + if (!m_parsingInProgress && m_reflectsCheckedAttribute) { setChecked(!attr->isNull()); m_reflectsCheckedAttribute = true; } - setNeedsValidityCheck(); } else if (attr->name() == maxlengthAttr) { InputElement::parseMaxLengthAttribute(m_data, this, this, attr); setNeedsValidityCheck(); @@ -658,6 +665,18 @@ void HTMLInputElement::parseMappedAttribute(Attribute* attr) HTMLTextFormControlElement::parseMappedAttribute(attr); } +void HTMLInputElement::finishParsingChildren() +{ + m_parsingInProgress = false; + HTMLFormControlElementWithState::finishParsingChildren(); + if (!m_stateRestored) { + bool checked = hasAttribute(checkedAttr); + if (checked) + setChecked(checked); + m_reflectsCheckedAttribute = true; + } +} + bool HTMLInputElement::rendererIsNeeded(RenderStyle* style) { return m_inputType->rendererIsNeeded() && HTMLFormControlElementWithState::rendererIsNeeded(style); @@ -756,6 +775,7 @@ void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent) setNeedsStyleRecalc(); updateCheckedRadioButtons(); + setNeedsValidityCheck(); // Ideally we'd do this from the render tree (matching // RenderTextView), but it's not possible to do it at the moment @@ -883,6 +903,7 @@ void HTMLInputElement::setValue(const String& value, bool sendChangeEvent) cacheSelection(max, max); m_data.setSuggestedValue(String()); } + m_inputType->valueChanged(); // Don't dispatch the change event when focused, it will be dispatched // when the control loses focus. @@ -958,6 +979,8 @@ void* HTMLInputElement::preDispatchEventHandler(Event* event) { if (event->type() != eventNames().clickEvent) return 0; + if (!event->isMouseEvent() || static_cast<MouseEvent*>(event)->button() != LeftButton) + return 0; // FIXME: Check whether there are any cases where this actually ends up leaking. return m_inputType->willDispatchClick().leakPtr(); } @@ -965,8 +988,6 @@ void* HTMLInputElement::preDispatchEventHandler(Event* event) void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch) { OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch)); - if (event->type() != eventNames().clickEvent) - return; if (!state) return; m_inputType->didDispatchClick(event, *state); @@ -974,7 +995,7 @@ void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreD void HTMLInputElement::defaultEventHandler(Event* evt) { - if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent) { + if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) { m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt)); if (evt->defaultHandled()) return; @@ -1134,7 +1155,7 @@ void HTMLInputElement::setAutofilled(bool autofilled) { if (autofilled == m_isAutofilled) return; - + m_isAutofilled = autofilled; setNeedsStyleRecalc(); } @@ -1144,6 +1165,11 @@ FileList* HTMLInputElement::files() return m_inputType->files(); } +String HTMLInputElement::visibleValue() const +{ + return m_inputType->visibleValue(); +} + bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const { return m_inputType->isAcceptableValue(proposedValue); @@ -1225,7 +1251,7 @@ void HTMLInputElement::willMoveToNewOwnerDocument() // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered if (needsActivationCallback()) document()->unregisterForDocumentActivationCallbacks(this); - + document()->checkedRadioButtons().removeButton(this); HTMLFormControlElementWithState::willMoveToNewOwnerDocument(); @@ -1234,10 +1260,10 @@ void HTMLInputElement::willMoveToNewOwnerDocument() void HTMLInputElement::didMoveToNewOwnerDocument() { registerForActivationCallbackIfNeeded(); - + HTMLFormControlElementWithState::didMoveToNewOwnerDocument(); } - + void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const { HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls); diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h index 403248c..757992a 100644 --- a/Source/WebCore/html/HTMLInputElement.h +++ b/Source/WebCore/html/HTMLInputElement.h @@ -37,7 +37,7 @@ class KURL; class HTMLInputElement : public HTMLTextFormControlElement, public InputElement { public: - static PassRefPtr<HTMLInputElement> create(const QualifiedName&, Document*, HTMLFormElement*); + static PassRefPtr<HTMLInputElement> create(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser); virtual ~HTMLInputElement(); DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange); @@ -198,7 +198,7 @@ public: void updateCheckedRadioButtons(); protected: - HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement* = 0); + HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser); virtual void defaultEventHandler(Event*); @@ -240,6 +240,7 @@ private: virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const; virtual void parseMappedAttribute(Attribute*); + virtual void finishParsingChildren(); virtual void copyNonAttributeProperties(const Element* source); @@ -258,6 +259,7 @@ private: virtual void cacheSelection(int start, int end); + virtual String visibleValue() const; virtual bool isAcceptableValue(const String&) const; virtual String sanitizeValue(const String&) const; virtual bool hasUnacceptableValue() const; @@ -312,6 +314,8 @@ private: #if ENABLE(DATALIST) bool m_hasNonEmptyList : 1; #endif + bool m_stateRestored : 1; + bool m_parsingInProgress : 1; OwnPtr<InputType> m_inputType; }; diff --git a/Source/WebCore/html/HTMLIsIndexElement.cpp b/Source/WebCore/html/HTMLIsIndexElement.cpp index a23a353..f865790 100644 --- a/Source/WebCore/html/HTMLIsIndexElement.cpp +++ b/Source/WebCore/html/HTMLIsIndexElement.cpp @@ -33,7 +33,7 @@ namespace WebCore { using namespace HTMLNames; HTMLIsIndexElement::HTMLIsIndexElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) - : HTMLInputElement(tagName, document, form) + : HTMLInputElement(tagName, document, form, false) { ASSERT(hasTagName(isindexTag)); setDefaultName(isindexTag.localName()); diff --git a/Source/WebCore/html/HTMLKeygenElement.cpp b/Source/WebCore/html/HTMLKeygenElement.cpp index 881a0a8..b90335e 100644 --- a/Source/WebCore/html/HTMLKeygenElement.cpp +++ b/Source/WebCore/html/HTMLKeygenElement.cpp @@ -29,6 +29,7 @@ #include "Document.h" #include "FormDataList.h" #include "HTMLNames.h" +#include "HTMLSelectElement.h" #include "HTMLOptionElement.h" #include "SSLKeyGenerator.h" #include "Text.h" @@ -40,20 +41,41 @@ namespace WebCore { using namespace HTMLNames; +class KeygenSelectElement : public HTMLSelectElement { +public: + static PassRefPtr<KeygenSelectElement> create(Document* document) + { + return adoptRef(new KeygenSelectElement(document)); + } + + virtual const AtomicString& shadowPseudoId() const + { + DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-keygen-select")); + return pseudoId; + } + +protected: + KeygenSelectElement(Document* document) + : HTMLSelectElement(selectTag, document, 0) + { + } +}; + inline HTMLKeygenElement::HTMLKeygenElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) - : HTMLSelectElement(tagName, document, form) + : HTMLFormControlElementWithState(tagName, document, form) { ASSERT(hasTagName(keygenTag)); - // FIXME: This markup should go in the shadow tree. - // Add one option element for each key size. + // Create a select element with one option element for each key size. + RefPtr<HTMLSelectElement> select = KeygenSelectElement::create(document); Vector<String> keys; getSupportedKeySizes(keys); for (size_t i = 0; i < keys.size(); ++i) { RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document, this->form()); - parserAddChild(option); + select->parserAddChild(option); option->parserAddChild(Text::create(document, keys[i])); } + setShadowRoot(select); } PassRefPtr<HTMLKeygenElement> HTMLKeygenElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form) @@ -61,22 +83,18 @@ PassRefPtr<HTMLKeygenElement> HTMLKeygenElement::create(const QualifiedName& tag return adoptRef(new HTMLKeygenElement(tagName, document, form)); } -const AtomicString& HTMLKeygenElement::formControlType() const -{ - DEFINE_STATIC_LOCAL(const AtomicString, keygen, ("keygen")); - return keygen; -} - void HTMLKeygenElement::parseMappedAttribute(Attribute* attr) { + // Reflect disabled attribute on the shadow select element + if (attr->name() == disabledAttr) + selectShadow()->setAttribute(attr->name(), attr->value()); + if (attr->name() == challengeAttr) m_challenge = attr->value(); else if (attr->name() == keytypeAttr) m_keyType = attr->value(); - else { - // Skip HTMLSelectElement parsing. + else HTMLFormControlElement::parseMappedAttribute(attr); - } } bool HTMLKeygenElement::appendFormData(FormDataList& encoded_values, bool) @@ -84,11 +102,27 @@ bool HTMLKeygenElement::appendFormData(FormDataList& encoded_values, bool) // Only RSA is supported at this time. if (!m_keyType.isNull() && !equalIgnoringCase(m_keyType, "rsa")) return false; - String value = signedPublicKeyAndChallengeString(selectedIndex(), m_challenge, document()->baseURL()); + String value = signedPublicKeyAndChallengeString(selectShadow()->selectedIndex(), m_challenge, document()->baseURL()); if (value.isNull()) return false; encoded_values.appendData(name(), value.utf8()); return true; } +const AtomicString& HTMLKeygenElement::formControlType() const +{ + DEFINE_STATIC_LOCAL(const AtomicString, keygen, ("keygen")); + return keygen; +} + +void HTMLKeygenElement::reset() +{ + static_cast<HTMLFormControlElement*>(selectShadow())->reset(); +} + +HTMLSelectElement* HTMLKeygenElement::selectShadow() +{ + return static_cast<HTMLSelectElement*>(shadowRoot()); +} + } // namespace diff --git a/Source/WebCore/html/HTMLKeygenElement.h b/Source/WebCore/html/HTMLKeygenElement.h index 3dc4ad2..a7a8a64 100644 --- a/Source/WebCore/html/HTMLKeygenElement.h +++ b/Source/WebCore/html/HTMLKeygenElement.h @@ -24,11 +24,13 @@ #ifndef HTMLKeygenElement_h #define HTMLKeygenElement_h -#include "HTMLSelectElement.h" +#include "HTMLFormControlElement.h" namespace WebCore { -class HTMLKeygenElement : public HTMLSelectElement { +class HTMLSelectElement; + +class HTMLKeygenElement : public HTMLFormControlElementWithState { public: static PassRefPtr<HTMLKeygenElement> create(const QualifiedName&, Document*, HTMLFormElement*); @@ -37,13 +39,21 @@ public: private: HTMLKeygenElement(const QualifiedName&, Document*, HTMLFormElement*); - virtual bool isResettable() const { return true; } + virtual bool canStartSelection() const { return false; } - virtual const AtomicString& formControlType() const; virtual void parseMappedAttribute(Attribute*); + virtual bool appendFormData(FormDataList&, bool); + virtual const AtomicString& formControlType() const; virtual bool isOptionalFormControl() const { return false; } + virtual bool isEnumeratable() const { return true; } + + virtual bool isResettable() const { return true; } + virtual void reset(); + + HTMLSelectElement* selectShadow(); + AtomicString m_challenge; AtomicString m_keyType; }; diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp index 8b2ae08..04cfda4 100644 --- a/Source/WebCore/html/HTMLLinkElement.cpp +++ b/Source/WebCore/html/HTMLLinkElement.cpp @@ -56,6 +56,7 @@ inline HTMLLinkElement::HTMLLinkElement(const QualifiedName& tagName, Document* , m_disabledState(Unset) , m_loading(false) , m_createdByParser(createdByParser) + , m_isInShadowTree(false) , m_pendingSheetType(None) { ASSERT(hasTagName(linkTag)); @@ -204,7 +205,7 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute void HTMLLinkElement::process() { - if (!inDocument()) { + if (!inDocument() || m_isInShadowTree) { ASSERT(!m_sheet); return; } @@ -247,7 +248,7 @@ void HTMLLinkElement::process() String charset = getAttribute(charsetAttr); if (charset.isEmpty() && document()->frame()) - charset = document()->frame()->loader()->writer()->encoding(); + charset = document()->charset(); if (m_cachedSheet) { removePendingSheet(); @@ -298,6 +299,11 @@ void HTMLLinkElement::process() void HTMLLinkElement::insertedIntoDocument() { HTMLElement::insertedIntoDocument(); + + m_isInShadowTree = isInShadowTree(); + if (m_isInShadowTree) + return; + document()->addStyleSheetCandidateNode(this, m_createdByParser); process(); @@ -307,6 +313,10 @@ void HTMLLinkElement::removedFromDocument() { HTMLElement::removedFromDocument(); + if (m_isInShadowTree) { + ASSERT(!m_sheet); + return; + } document()->removeStyleSheetCandidateNode(this); if (m_sheet) { diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h index e1198b1..3798c33 100644 --- a/Source/WebCore/html/HTMLLinkElement.h +++ b/Source/WebCore/html/HTMLLinkElement.h @@ -147,6 +147,7 @@ private: RelAttribute m_relAttribute; bool m_loading; bool m_createdByParser; + bool m_isInShadowTree; PendingSheetType m_pendingSheetType; }; diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index be478b3..04d0a1d 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -48,6 +48,7 @@ #include "HTMLSourceElement.h" #include "HTMLVideoElement.h" #include "Logging.h" +#include "MediaControls.h" #include "MediaDocument.h" #include "MediaError.h" #include "MediaList.h" @@ -2181,6 +2182,7 @@ void HTMLMediaElement::userCancelledLoad() m_player.clear(); #endif stopPeriodicTimers(); + m_loadTimer.stop(); m_loadState = WaitingForSource; // 2 - Set the error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORTED. @@ -2297,7 +2299,7 @@ void HTMLMediaElement::defaultEventHandler(Event* event) widget->handleEvent(event); #else if (renderer() && renderer()->isMedia()) - toRenderMedia(renderer())->forwardEvent(event); + toRenderMedia(renderer())->controls()->forwardEvent(event); if (event->defaultHandled()) return; HTMLElement::defaultEventHandler(event); @@ -2401,7 +2403,7 @@ void HTMLMediaElement::createMediaPlayerProxy() m_needWidgetUpdate = false; } -void HTMLMediaElement::updateWidget(bool) +void HTMLMediaElement::updateWidget(PluginCreationOption) { mediaElement->setNeedWidgetUpdate(false); @@ -2493,6 +2495,22 @@ bool HTMLMediaElement::webkitHasClosedCaptions() const return hasClosedCaptions(); } +#if ENABLE(MEDIA_STATISTICS) +unsigned long HTMLMediaElement::webkitAudioBytesDecoded() const +{ + if (!m_player) + return 0; + return m_player->audioBytesDecoded(); +} + +unsigned long HTMLMediaElement::webkitVideoBytesDecoded() const +{ + if (!m_player) + return 0; + return m_player->videoBytesDecoded(); +} +#endif + void HTMLMediaElement::mediaCanStart() { LOG(Media, "HTMLMediaElement::mediaCanStart"); diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h index bdc3447..9778fd4 100644 --- a/Source/WebCore/html/HTMLMediaElement.h +++ b/Source/WebCore/html/HTMLMediaElement.h @@ -129,6 +129,12 @@ public: bool webkitClosedCaptionsVisible() const; void setWebkitClosedCaptionsVisible(bool); +#if ENABLE(MEDIA_STATISTICS) +// Statistics + unsigned long webkitAudioBytesDecoded() const; + unsigned long webkitVideoBytesDecoded() const; +#endif + // controls bool controls() const; void setControls(bool); @@ -152,7 +158,7 @@ public: void getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values); virtual void finishParsingChildren(); void createMediaPlayerProxy(); - void updateWidget(bool onlyCreateNonNetscapePlugins); + void updateWidget(PluginCreationOption); #endif bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); } diff --git a/Source/WebCore/html/HTMLMediaElement.idl b/Source/WebCore/html/HTMLMediaElement.idl index d6ba79d..9d4602d 100644 --- a/Source/WebCore/html/HTMLMediaElement.idl +++ b/Source/WebCore/html/HTMLMediaElement.idl @@ -81,5 +81,11 @@ interface [Conditional=VIDEO] HTMLMediaElement : HTMLElement { readonly attribute boolean webkitHasClosedCaptions; attribute boolean webkitClosedCaptionsVisible; + +#if defined(ENABLE_MEDIA_STATISTICS) && ENABLE_MEDIA_STATISTICS + // The number of bytes consumed by the media decoder. + readonly attribute unsigned long webkitAudioBytesDecoded; + readonly attribute unsigned long webkitVideoBytesDecoded; +#endif }; } diff --git a/Source/WebCore/html/HTMLObjectElement.cpp b/Source/WebCore/html/HTMLObjectElement.cpp index a1dde1a..0f05a3a 100644 --- a/Source/WebCore/html/HTMLObjectElement.cpp +++ b/Source/WebCore/html/HTMLObjectElement.cpp @@ -236,14 +236,14 @@ bool HTMLObjectElement::hasFallbackContent() const return false; } -bool HTMLObjectElement::hasValidClassId() +inline bool HTMLObjectElement::hasValidClassId() { // HTML5 says that fallback content should be rendered if a non-empty // classid is specified for which the UA can't find a suitable plug-in. // WebKit supports no classids, with the exception of Qt plug-ins, which use // classid to specify which QObject to load. #if PLATFORM(QT) - return classId().isEmpty() || equalIgnoringCase(serviceType(), "application/x-qt-plugin"); + return classId().isEmpty() || equalIgnoringCase(serviceType(), "application/x-qt-plugin") || equalIgnoringCase(serviceType(), "application/x-qt-styled-widget"); #else return classId().isEmpty(); #endif @@ -251,7 +251,7 @@ bool HTMLObjectElement::hasValidClassId() // FIXME: This should be unified with HTMLEmbedElement::updateWidget and // moved down into HTMLPluginImageElement.cpp -void HTMLObjectElement::updateWidget(bool onlyCreateNonNetscapePlugins) +void HTMLObjectElement::updateWidget(PluginCreationOption pluginCreationOption) { ASSERT(!renderEmbeddedObject()->pluginCrashedOrWasMissing()); // FIXME: We should ASSERT(needsWidgetUpdate()), but currently @@ -277,7 +277,7 @@ void HTMLObjectElement::updateWidget(bool onlyCreateNonNetscapePlugins) bool fallbackContent = hasFallbackContent(); renderEmbeddedObject()->setHasFallbackContent(fallbackContent); - if (onlyCreateNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType)) + if (pluginCreationOption == CreateOnlyNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType)) return; ASSERT(!m_inBeforeLoadEventHandler); @@ -318,6 +318,7 @@ void HTMLObjectElement::insertedIntoDocument() } HTMLPlugInImageElement::insertedIntoDocument(); + FormAssociatedElement::insertedIntoDocument(); } void HTMLObjectElement::removedFromDocument() @@ -329,6 +330,7 @@ void HTMLObjectElement::removedFromDocument() } HTMLPlugInImageElement::removedFromDocument(); + FormAssociatedElement::removedFromDocument(); } void HTMLObjectElement::attributeChanged(Attribute* attr, bool preserveDecls) @@ -508,4 +510,9 @@ const AtomicString& HTMLObjectElement::formControlName() const return m_name.isNull() ? emptyAtom : m_name; } +HTMLFormElement* HTMLObjectElement::virtualForm() const +{ + return FormAssociatedElement::form(); +} + } diff --git a/Source/WebCore/html/HTMLObjectElement.h b/Source/WebCore/html/HTMLObjectElement.h index cc8a03c..82d63f7 100644 --- a/Source/WebCore/html/HTMLObjectElement.h +++ b/Source/WebCore/html/HTMLObjectElement.h @@ -85,7 +85,7 @@ private: virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const; - virtual void updateWidget(bool onlyCreateNonNetscapePlugins); + virtual void updateWidget(PluginCreationOption); void updateDocNamedItem(); bool hasFallbackContent() const; @@ -98,6 +98,7 @@ private: virtual void refFormAssociatedElement() { ref(); } virtual void derefFormAssociatedElement() { deref(); } + virtual HTMLFormElement* virtualForm() const; virtual const AtomicString& formControlName() const; diff --git a/Source/WebCore/html/HTMLOptionElement.cpp b/Source/WebCore/html/HTMLOptionElement.cpp index e8f624c..966f837 100644 --- a/Source/WebCore/html/HTMLOptionElement.cpp +++ b/Source/WebCore/html/HTMLOptionElement.cpp @@ -194,7 +194,7 @@ void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const { ContainerNode* select = parentNode(); - while (select && !(select->hasTagName(selectTag) || select->hasTagName(keygenTag))) + while (select && !select->hasTagName(selectTag)) select = select->parentNode(); if (!select) @@ -221,6 +221,9 @@ String HTMLOptionElement::label() const void HTMLOptionElement::setRenderStyle(PassRefPtr<RenderStyle> newStyle) { m_style = newStyle; + if (HTMLSelectElement* select = ownerSelectElement()) + if (RenderObject* renderer = select->renderer()) + renderer->repaint(); } RenderStyle* HTMLOptionElement::nonRendererRenderStyle() const diff --git a/Source/WebCore/html/HTMLOutputElement.cpp b/Source/WebCore/html/HTMLOutputElement.cpp index 2f1d490..8be5d91 100644 --- a/Source/WebCore/html/HTMLOutputElement.cpp +++ b/Source/WebCore/html/HTMLOutputElement.cpp @@ -74,7 +74,7 @@ void HTMLOutputElement::setFor(const String& value) m_tokens->setValue(value); } -void HTMLOutputElement::childrenChanged(bool createdByParser, Node*, Node*, int) +void HTMLOutputElement::childrenChanged(bool createdByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { if (createdByParser || m_isSetTextContentInProgress) { m_isSetTextContentInProgress = false; @@ -83,6 +83,7 @@ void HTMLOutputElement::childrenChanged(bool createdByParser, Node*, Node*, int) if (m_isDefaultValueMode) m_defaultValue = textContent(); + HTMLFormControlElement::childrenChanged(createdByParser, beforeChange, afterChange, childCountDelta); } void HTMLOutputElement::reset() diff --git a/Source/WebCore/html/HTMLParamElement.cpp b/Source/WebCore/html/HTMLParamElement.cpp index 2dc9d1d..45a74b2 100644 --- a/Source/WebCore/html/HTMLParamElement.cpp +++ b/Source/WebCore/html/HTMLParamElement.cpp @@ -42,6 +42,11 @@ PassRefPtr<HTMLParamElement> HTMLParamElement::create(const QualifiedName& tagNa return adoptRef(new HTMLParamElement(tagName, document)); } +bool HTMLParamElement::isURLParameter(const String& name) +{ + return equalIgnoringCase(name, "data") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "src"); +} + void HTMLParamElement::parseMappedAttribute(Attribute* attr) { if (isIdAttributeName(attr->name())) { @@ -64,7 +69,7 @@ bool HTMLParamElement::isURLAttribute(Attribute* attr) const Attribute* attr = attributes()->getAttributeItem(nameAttr); if (attr) { const AtomicString& value = attr->value(); - if (equalIgnoringCase(value, "data") || equalIgnoringCase(value, "movie") || equalIgnoringCase(value, "src")) + if (isURLParameter(value)) return true; } } @@ -75,11 +80,9 @@ void HTMLParamElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) cons { HTMLElement::addSubresourceAttributeURLs(urls); - if (!equalIgnoringCase(name(), "data") && - !equalIgnoringCase(name(), "movie") && - !equalIgnoringCase(name(), "src")) + if (!isURLParameter(name())) return; - + addSubresourceURL(urls, document()->completeURL(value())); } diff --git a/Source/WebCore/html/HTMLParamElement.h b/Source/WebCore/html/HTMLParamElement.h index f13f8fa..f448547 100644 --- a/Source/WebCore/html/HTMLParamElement.h +++ b/Source/WebCore/html/HTMLParamElement.h @@ -34,6 +34,8 @@ public: String name() const { return m_name; } String value() const { return m_value; } + static bool isURLParameter(const String&); + private: HTMLParamElement(const QualifiedName&, Document*); diff --git a/Source/WebCore/html/HTMLParserErrorCodes.cpp b/Source/WebCore/html/HTMLParserErrorCodes.cpp index 6f973df..e1861a7 100644 --- a/Source/WebCore/html/HTMLParserErrorCodes.cpp +++ b/Source/WebCore/html/HTMLParserErrorCodes.cpp @@ -24,47 +24,5 @@ */ #include "config.h" -#include "HTMLParserErrorCodes.h" -namespace WebCore { - -const char* htmlParserErrorMessageTemplate(HTMLParserErrorCode errorCode) -{ - static const char* const errors[] = { - "%tag1 is not allowed inside %tag2. Moving %tag1 into the nearest enclosing <table>.", - "<head> must be a child of <html>. Content ignored.", - "%tag1 is not allowed inside %tag2. Moving %tag1 into the <head>.", - "Extra %tag1 encountered. Migrating attributes back to the original %tag1 element and ignoring the tag.", - "<area> is not allowed inside %tag1. Moving the <area> into the nearest enclosing <map>.", - "%tag1 is not allowed inside %tag2. Content ignored.", - "%tag1 is not allowed in a <frameset> page. Content ignored.", - "%tag1 is not allowed inside %tag2. Closing %tag2 and trying the insertion again.", - "%tag1 is not allowed inside <caption>. Closing the <caption> and trying the insertion again.", - "<table> is not allowed inside %tag1. Closing the current <table> and inserting the new <table> as a sibling.", - "%tag1 is not allowed inside %tag2. Inserting %tag1 before the <table> instead.", - "%tag1 misplaced in <table>. Creating %tag2 and putting %tag1 inside it.", - "</br> encountered. Converting </br> into <br>.", - "XML self-closing tag syntax used on %tag1. The tag will not be closed.", - "Unmatched </p> encountered. Converting </p> into <p></p>.", - "Unmatched %tag1 encountered. Ignoring tag.", - "%tag1 misnested or not properly closed. Cloning %tag1 in order to preserve the styles applied by it.", - "<form> cannot act as a container inside %tag1 without disrupting the table. The children of the <form> will be placed inside the %tag1 instead.", - "XML self-closing tag syntax used on <script>. The tag will be closed by WebKit, but not all browsers do this. Change to <script></script> instead for best cross-browser compatibility." - }; - - if (errorCode >= MisplacedTablePartError && errorCode <= IncorrectXMLCloseScriptWarning) - return errors[errorCode]; - return 0; -} - -const char* htmlParserDocumentWriteMessage() -{ - return "[The HTML that caused this error was generated by a script.] "; -} - -bool isWarning(HTMLParserErrorCode code) -{ - return code >= IncorrectXMLCloseScriptWarning; -} - -} +// FIXME: Delete this file. diff --git a/Source/WebCore/html/HTMLParserErrorCodes.h b/Source/WebCore/html/HTMLParserErrorCodes.h index 4da6b90..1d88bc6 100644 --- a/Source/WebCore/html/HTMLParserErrorCodes.h +++ b/Source/WebCore/html/HTMLParserErrorCodes.h @@ -23,38 +23,4 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HTMLParserErrorCodes_h -#define HTMLParserErrorCodes_h - -namespace WebCore { - -enum HTMLParserErrorCode { - MisplacedTablePartError, - MisplacedHeadError, - MisplacedHeadContentError, - RedundantHTMLBodyError, - MisplacedAreaError, - IgnoredContentError, - MisplacedFramesetContentError, - MisplacedContentRetryError, - MisplacedCaptionContentError, - MisplacedTableError, - StrayTableContentError, - TablePartRequiredError, - MalformedBRError, - IncorrectXMLSelfCloseError, - StrayParagraphCloseError, - StrayCloseTagError, - ResidualStyleError, - FormInsideTablePartError, - IncorrectXMLCloseScriptWarning -}; - -const char* htmlParserErrorMessageTemplate(HTMLParserErrorCode); -const char* htmlParserDocumentWriteMessage(); - -bool isWarning(HTMLParserErrorCode); - -} - -#endif +// FIXME: Delete this file. diff --git a/Source/WebCore/html/HTMLParserQuirks.h b/Source/WebCore/html/HTMLParserQuirks.h index 3bf22a4..4ac6db8 100644 --- a/Source/WebCore/html/HTMLParserQuirks.h +++ b/Source/WebCore/html/HTMLParserQuirks.h @@ -23,27 +23,4 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HTMLParserQuirks_h -#define HTMLParserQuirks_h - -#include <wtf/Forward.h> - -namespace WebCore { - -class Node; - -class HTMLParserQuirks { - WTF_MAKE_NONCOPYABLE(HTMLParserQuirks); -public: - HTMLParserQuirks() { } - virtual ~HTMLParserQuirks() { } - - virtual void reset() = 0; - - virtual bool shouldInsertNode(Node* parent, Node* newNode) = 0; - virtual bool shouldPopBlock(const AtomicString& tagNameOnStack, const AtomicString& tagNameToPop) = 0; -}; - -} // namespace WebCore - -#endif // HTMLParserQuirks_h +// FIXME: Delete this file. diff --git a/Source/WebCore/html/HTMLPlugInImageElement.cpp b/Source/WebCore/html/HTMLPlugInImageElement.cpp index 9ac5ad8..db07334 100644 --- a/Source/WebCore/html/HTMLPlugInImageElement.cpp +++ b/Source/WebCore/html/HTMLPlugInImageElement.cpp @@ -78,7 +78,7 @@ bool HTMLPlugInImageElement::allowedToLoadFrameURL(const String& url) KURL completeURL = document()->completeURL(url); bool foundSelfReference = false; for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) { - if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) { + if (equalIgnoringFragmentIdentifier(frame->document()->url(), completeURL)) { if (foundSelfReference) return false; foundSelfReference = true; @@ -166,8 +166,7 @@ void HTMLPlugInImageElement::updateWidgetIfNecessary() if (!renderEmbeddedObject() || renderEmbeddedObject()->pluginCrashedOrWasMissing()) return; - // True indicates that this code path should only create non-netscape plugins (no clue why). - updateWidget(true); + updateWidget(CreateOnlyNonNetscapePlugins); } void HTMLPlugInImageElement::finishParsingChildren() diff --git a/Source/WebCore/html/HTMLPlugInImageElement.h b/Source/WebCore/html/HTMLPlugInImageElement.h index f394d40..364262b 100644 --- a/Source/WebCore/html/HTMLPlugInImageElement.h +++ b/Source/WebCore/html/HTMLPlugInImageElement.h @@ -29,12 +29,17 @@ namespace WebCore { class HTMLImageLoader; class FrameLoader; +enum PluginCreationOption { + CreateAnyWidgetType, + CreateOnlyNonNetscapePlugins, +}; + // Base class for HTMLObjectElement and HTMLEmbedElement class HTMLPlugInImageElement : public HTMLPlugInElement { public: RenderEmbeddedObject* renderEmbeddedObject() const; - virtual void updateWidget(bool onlyCreateNonNetscapePlugins) = 0; + virtual void updateWidget(PluginCreationOption) = 0; const String& serviceType() const { return m_serviceType; } const String& url() const { return m_url; } diff --git a/Source/WebCore/html/HTMLProgressElement.cpp b/Source/WebCore/html/HTMLProgressElement.cpp index 4a55a1e..cab0429 100644 --- a/Source/WebCore/html/HTMLProgressElement.cpp +++ b/Source/WebCore/html/HTMLProgressElement.cpp @@ -26,9 +26,11 @@ #include "EventNames.h" #include "ExceptionCode.h" #include "FormDataList.h" +#include "HTMLDivElement.h" #include "HTMLFormElement.h" #include "HTMLNames.h" #include "HTMLParserIdioms.h" +#include "ProgressBarValueElement.h" #include "RenderProgress.h" #include <wtf/StdLibExtras.h> @@ -60,21 +62,19 @@ const AtomicString& HTMLProgressElement::formControlType() const void HTMLProgressElement::parseMappedAttribute(Attribute* attribute) { - if (attribute->name() == valueAttr) { - if (renderer()) - renderer()->updateFromElement(); - } else if (attribute->name() == maxAttr) { - if (renderer()) - renderer()->updateFromElement(); - } else + if (attribute->name() == valueAttr) + didElementStateChange(); + else if (attribute->name() == maxAttr) + didElementStateChange(); + else HTMLFormControlElement::parseMappedAttribute(attribute); } void HTMLProgressElement::attach() { + createShadowSubtreeIfNeeded(); HTMLFormControlElement::attach(); - if (renderer()) - renderer()->updateFromElement(); + didElementStateChange(); } double HTMLProgressElement::value() const @@ -121,5 +121,18 @@ double HTMLProgressElement::position() const return value() / max(); } +void HTMLProgressElement::didElementStateChange() +{ + if (renderer()) + renderer()->updateFromElement(); +} + +void HTMLProgressElement::createShadowSubtreeIfNeeded() +{ + if (shadowRoot()) + return; + setShadowRoot(ProgressBarValueElement::create(document()).get()); +} + } // namespace #endif diff --git a/Source/WebCore/html/HTMLProgressElement.h b/Source/WebCore/html/HTMLProgressElement.h index c80f50f..a0db966 100644 --- a/Source/WebCore/html/HTMLProgressElement.h +++ b/Source/WebCore/html/HTMLProgressElement.h @@ -50,6 +50,9 @@ private: virtual void parseMappedAttribute(Attribute*); virtual void attach(); + + void didElementStateChange(); + void createShadowSubtreeIfNeeded(); }; } // namespace diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp index c7f47f2..d23e56a 100644 --- a/Source/WebCore/html/HTMLSelectElement.cpp +++ b/Source/WebCore/html/HTMLSelectElement.cpp @@ -49,7 +49,7 @@ static const unsigned maxSelectItems = 10000; HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) : HTMLFormControlElementWithState(tagName, document, form) { - ASSERT(hasTagName(selectTag) || hasTagName(keygenTag)); + ASSERT(hasTagName(selectTag)); } PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form) @@ -206,7 +206,7 @@ void HTMLSelectElement::remove(HTMLOptionElement* option) option->remove(ec); } -String HTMLSelectElement::value() +String HTMLSelectElement::value() const { const Vector<Element*>& items = listItems(); for (unsigned i = 0; i < items.size(); i++) { @@ -464,7 +464,7 @@ void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, Exc setLength(index, ec); // replace an existing entry ? } else if (diff < 0) { - before = static_cast<HTMLElement*>(options()->item(index+1)); + before = toHTMLElement(options()->item(index+1)); remove(index); } // finally add the new element @@ -486,7 +486,7 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec) do { RefPtr<Element> option = document()->createElement(optionTag, false); ASSERT(option); - add(static_cast<HTMLElement*>(option.get()), 0, ec); + add(toHTMLElement(option.get()), 0, ec); if (ec) break; } while (++diff); diff --git a/Source/WebCore/html/HTMLSelectElement.h b/Source/WebCore/html/HTMLSelectElement.h index 42e8963..837675c 100644 --- a/Source/WebCore/html/HTMLSelectElement.h +++ b/Source/WebCore/html/HTMLSelectElement.h @@ -55,7 +55,7 @@ public: void remove(int index); void remove(HTMLOptionElement*); - String value(); + String value() const; void setValue(const String&); PassRefPtr<HTMLOptionsCollection> options(); diff --git a/Source/WebCore/html/HTMLTagNames.in b/Source/WebCore/html/HTMLTagNames.in index f5ff077..83d41de 100644 --- a/Source/WebCore/html/HTMLTagNames.in +++ b/Source/WebCore/html/HTMLTagNames.in @@ -67,7 +67,7 @@ i interfaceName=HTMLElement iframe interfaceName=HTMLIFrameElement image mapToTagName=img img interfaceName=HTMLImageElement, constructorNeedsFormElement -input constructorNeedsFormElement +input constructorNeedsFormElement, constructorNeedsCreatedByParser ins interfaceName=HTMLModElement isindex interfaceName=HTMLIsIndexElement, constructorNeedsFormElement kbd interfaceName=HTMLElement diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp index 2741bfe..b8b04de 100644 --- a/Source/WebCore/html/HTMLTextAreaElement.cpp +++ b/Source/WebCore/html/HTMLTextAreaElement.cpp @@ -281,6 +281,7 @@ void HTMLTextAreaElement::updateValue() const const_cast<HTMLTextAreaElement*>(this)->setFormControlValueMatchesRenderer(true); notifyFormStateChanged(this); m_isDirty = true; + const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility(false); } String HTMLTextAreaElement::value() const diff --git a/Source/WebCore/html/HTMLVideoElement.cpp b/Source/WebCore/html/HTMLVideoElement.cpp index bbda53a..2004e48 100644 --- a/Source/WebCore/html/HTMLVideoElement.cpp +++ b/Source/WebCore/html/HTMLVideoElement.cpp @@ -263,6 +263,24 @@ void HTMLVideoElement::willMoveToNewOwnerDocument() HTMLMediaElement::willMoveToNewOwnerDocument(); } +#if ENABLE(MEDIA_STATISTICS) +unsigned long HTMLVideoElement::webkitDecodedFrames() const +{ + if (!player()) + return 0; + + return player()->decodedFrames(); +} + +unsigned long HTMLVideoElement::webkitDroppedFrames() const +{ + if (!player()) + return 0; + + return player()->droppedFrames(); +} +#endif + } #endif diff --git a/Source/WebCore/html/HTMLVideoElement.h b/Source/WebCore/html/HTMLVideoElement.h index d893411..dd38a59 100644 --- a/Source/WebCore/html/HTMLVideoElement.h +++ b/Source/WebCore/html/HTMLVideoElement.h @@ -55,6 +55,12 @@ public: void webkitEnterFullScreen(bool isUserGesture, ExceptionCode& ec) { webkitEnterFullscreen(isUserGesture, ec); } void webkitExitFullScreen() { webkitExitFullscreen(); } +#if ENABLE(MEDIA_STATISTICS) + // Statistics + unsigned long webkitDecodedFrames() const; + unsigned long webkitDroppedFrames() const; +#endif + // Used by canvas to gain raw pixel access void paintCurrentFrameInContext(GraphicsContext*, const IntRect&); diff --git a/Source/WebCore/html/HTMLVideoElement.idl b/Source/WebCore/html/HTMLVideoElement.idl index 770e4b2..50513d4 100644 --- a/Source/WebCore/html/HTMLVideoElement.idl +++ b/Source/WebCore/html/HTMLVideoElement.idl @@ -42,5 +42,15 @@ module html { [NeedsUserGestureCheck] void webkitEnterFullScreen() raises (DOMException); void webkitExitFullScreen(); + +#if defined(ENABLE_MEDIA_STATISTICS) && ENABLE_MEDIA_STATISTICS + // The number of frames that have been decoded and made available for + // playback. + readonly attribute unsigned long webkitDecodedFrames; + + // The number of decoded frames that have been dropped by the player + // for performance reasons during playback. + readonly attribute unsigned long webkitDroppedFrames; +#endif }; } diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp index 8e3a9e3..21ba7c2 100644 --- a/Source/WebCore/html/InputType.cpp +++ b/Source/WebCore/html/InputType.cpp @@ -435,6 +435,10 @@ void InputType::srcAttributeChanged() { } +void InputType::valueChanged() +{ +} + void InputType::willMoveToNewOwnerDocument() { } @@ -512,6 +516,11 @@ void InputType::didDispatchClick(Event*, const ClickHandlingState&) { } +String InputType::visibleValue() const +{ + return element()->value(); +} + bool InputType::isAcceptableValue(const String&) { return true; diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h index 40606d1..8c35af3 100644 --- a/Source/WebCore/html/InputType.h +++ b/Source/WebCore/html/InputType.h @@ -152,6 +152,7 @@ public: virtual String typeMismatchText() const; virtual String valueMissingText() const; virtual bool canSetStringValue() const; + virtual String visibleValue() const; virtual bool isAcceptableValue(const String&); virtual String sanitizeValue(const String&); virtual bool hasUnacceptableValue(); @@ -197,9 +198,11 @@ public: virtual void minOrMaxAttributeChanged(); virtual void altAttributeChanged(); virtual void srcAttributeChanged(); + virtual void valueChanged(); virtual void willMoveToNewOwnerDocument(); virtual bool shouldRespectAlignAttribute(); virtual FileList* files(); + // Should return true if the corresponding renderer for a type can display a suggested value. virtual bool canSetSuggestedValue(); virtual bool shouldSendChangeEventAfterCheckedChanged(); virtual bool canSetValue(const String&); diff --git a/Source/WebCore/html/MediaDocument.cpp b/Source/WebCore/html/MediaDocument.cpp index d6fe6dd..cd1fdfb 100644 --- a/Source/WebCore/html/MediaDocument.cpp +++ b/Source/WebCore/html/MediaDocument.cpp @@ -209,7 +209,7 @@ void MediaDocument::replaceMediaElementTimerFired(Timer<MediaDocument>*) embedElement->setAttribute(heightAttr, "100%"); embedElement->setAttribute(nameAttr, "plugin"); embedElement->setAttribute(srcAttr, url().string()); - embedElement->setAttribute(typeAttr, frame()->loader()->writer()->mimeType()); + embedElement->setAttribute(typeAttr, loader()->writer()->mimeType()); ExceptionCode ec; videoElement->parentNode()->replaceChild(embedElement, videoElement, ec); diff --git a/Source/WebCore/html/NumberInputType.cpp b/Source/WebCore/html/NumberInputType.cpp index 3916527..0011115 100644 --- a/Source/WebCore/html/NumberInputType.cpp +++ b/Source/WebCore/html/NumberInputType.cpp @@ -38,6 +38,7 @@ #include "HTMLNames.h" #include "HTMLParserIdioms.h" #include "KeyboardEvent.h" +#include "LocalizedNumber.h" #include "RenderTextControl.h" #include <limits> #include <wtf/ASCIICType.h> @@ -49,17 +50,21 @@ namespace WebCore { using namespace HTMLNames; using namespace std; -static const double numberDefaultMinimum = -FLT_MAX; -static const double numberDefaultMaximum = FLT_MAX; - static const double numberDefaultStep = 1.0; static const double numberStepScaleFactor = 1.0; -static bool isNumberCharacter(UChar ch) +// Returns true if the specified character can be a part of 'valid floating +// point number' of HTML5. +static bool isHTMLNumberCharacter(UChar ch) { return ch == '+' || ch == '-' || ch == '.' || ch == 'e' || ch == 'E' || isASCIIDigit(ch); } +static bool isNumberCharacter(UChar ch) +{ + return isLocalizedNumberCharacter(ch) || isHTMLNumberCharacter(ch); +} + PassOwnPtr<InputType> NumberInputType::create(HTMLInputElement* element) { return adoptPtr(new NumberInputType(element)); @@ -77,11 +82,11 @@ double NumberInputType::valueAsNumber() const void NumberInputType::setValueAsNumber(double newValue, ExceptionCode& ec) const { - if (newValue < numberDefaultMinimum) { + if (newValue < -numeric_limits<float>::max()) { ec = INVALID_STATE_ERR; return; } - if (newValue > numberDefaultMaximum) { + if (newValue > numeric_limits<float>::max()) { ec = INVALID_STATE_ERR; return; } @@ -120,12 +125,12 @@ bool NumberInputType::supportsRangeLimitation() const double NumberInputType::minimum() const { - return parseToDouble(element()->fastGetAttribute(minAttr), numberDefaultMinimum); + return parseToDouble(element()->fastGetAttribute(minAttr), -numeric_limits<float>::max()); } double NumberInputType::maximum() const { - return parseToDouble(element()->fastGetAttribute(maxAttr), numberDefaultMaximum); + return parseToDouble(element()->fastGetAttribute(maxAttr), numeric_limits<float>::max()); } bool NumberInputType::stepMismatch(const String& value, double step) const @@ -248,13 +253,29 @@ void NumberInputType::handleBlurEvent() element()->renderer()->updateFromElement(); } +String NumberInputType::visibleValue() const +{ + String currentValue = element()->value(); + if (currentValue.isEmpty()) + return currentValue; + double doubleValue = numeric_limits<double>::quiet_NaN(); + parseToDoubleForNumberType(currentValue, &doubleValue); + String localized = formatLocalizedNumber(doubleValue); + return localized.isEmpty() ? currentValue : localized; +} + bool NumberInputType::isAcceptableValue(const String& proposedValue) { - return proposedValue.isEmpty() || parseToDoubleForNumberType(proposedValue, 0); + return proposedValue.isEmpty() || isfinite(parseLocalizedNumber(proposedValue)) || parseToDoubleForNumberType(proposedValue, 0); } String NumberInputType::sanitizeValue(const String& proposedValue) { + // Try to parse the value as a localized number, then try to parse it as + // the standard format. + double parsedValue = parseLocalizedNumber(proposedValue); + if (isfinite(parsedValue)) + return serializeForNumberType(parsedValue); return parseToDoubleForNumberType(proposedValue, 0) ? proposedValue : String(); } diff --git a/Source/WebCore/html/NumberInputType.h b/Source/WebCore/html/NumberInputType.h index 0b23d34..9d97134 100644 --- a/Source/WebCore/html/NumberInputType.h +++ b/Source/WebCore/html/NumberInputType.h @@ -64,6 +64,7 @@ private: virtual String serialize(double) const; virtual double acceptableError(double) const; virtual void handleBlurEvent(); + virtual String visibleValue() const; virtual bool isAcceptableValue(const String&); virtual String sanitizeValue(const String&); virtual bool hasUnacceptableValue(); diff --git a/Source/WebCore/html/PluginDocument.cpp b/Source/WebCore/html/PluginDocument.cpp index cebb949..94f44cf 100644 --- a/Source/WebCore/html/PluginDocument.cpp +++ b/Source/WebCore/html/PluginDocument.cpp @@ -28,6 +28,7 @@ #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoaderClient.h" +#include "FrameView.h" #include "HTMLEmbedElement.h" #include "HTMLHtmlElement.h" #include "HTMLNames.h" @@ -91,7 +92,7 @@ void PluginDocumentParser::createDocumentStructure() m_embedElement->setAttribute(nameAttr, "plugin"); m_embedElement->setAttribute(srcAttr, document()->url().string()); - m_embedElement->setAttribute(typeAttr, document()->frame()->loader()->writer()->mimeType()); + m_embedElement->setAttribute(typeAttr, document()->loader()->writer()->mimeType()); static_cast<PluginDocument*>(document())->setPluginNode(m_embedElement); @@ -115,6 +116,13 @@ void PluginDocumentParser::appendBytes(DocumentWriter*, const char*, int, bool) document()->updateLayout(); + // Below we assume that renderer->widget() to have been created by + // document()->updateLayout(). However, in some cases, updateLayout() will + // recurse too many times and delay its post-layout tasks (such as creating + // the widget). Here we kick off the pending post-layout tasks so that we + // can synchronously redirect data to the plugin. + frame->view()->flushAnyPendingPostLayoutTasks(); + if (RenderPart* renderer = m_embedElement->renderPart()) { if (Widget* widget = renderer->widget()) { frame->loader()->client()->redirectDataToPlugin(widget); diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp index 7c74206..be7e0c6 100644 --- a/Source/WebCore/html/RangeInputType.cpp +++ b/Source/WebCore/html/RangeInputType.cpp @@ -158,6 +158,8 @@ void RangeInputType::handleMouseDownEvent(MouseEvent* event) void RangeInputType::handleKeydownEvent(KeyboardEvent* event) { + if (element()->disabled() || element()->readOnly()) + return; const String& key = event->keyIdentifier(); if (key != "Up" && key != "Right" && key != "Down" && key != "Left") return; @@ -257,6 +259,11 @@ void RangeInputType::minOrMaxAttributeChanged() element()->setNeedsStyleRecalc(); } +void RangeInputType::valueChanged() +{ + element()->shadowRoot()->setNeedsStyleRecalc(); +} + String RangeInputType::fallbackValue() { return serializeForNumberType(StepRange(element()).defaultValue()); diff --git a/Source/WebCore/html/RangeInputType.h b/Source/WebCore/html/RangeInputType.h index 1447018..ac89d02 100644 --- a/Source/WebCore/html/RangeInputType.h +++ b/Source/WebCore/html/RangeInputType.h @@ -63,6 +63,7 @@ private: virtual String serialize(double) const; virtual void accessKeyAction(bool sendToAnyElement); virtual void minOrMaxAttributeChanged(); + virtual void valueChanged(); virtual String fallbackValue(); virtual String sanitizeValue(const String& proposedValue); virtual bool shouldRespectListAttribute(); diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp index 54527b1..1d06be3 100644 --- a/Source/WebCore/html/TextFieldInputType.cpp +++ b/Source/WebCore/html/TextFieldInputType.cpp @@ -52,6 +52,11 @@ bool TextFieldInputType::valueMissing(const String& value) const return value.isEmpty(); } +bool TextFieldInputType::canSetSuggestedValue() +{ + return true; +} + void TextFieldInputType::handleKeydownEvent(KeyboardEvent* event) { if (!element()->focused()) @@ -64,6 +69,8 @@ void TextFieldInputType::handleKeydownEvent(KeyboardEvent* event) void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent* event) { + if (element()->disabled() || element()->readOnly()) + return; const String& key = event->keyIdentifier(); int step = 0; if (key == "Up") @@ -78,6 +85,8 @@ void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent* event) void TextFieldInputType::handleWheelEventForSpinButton(WheelEvent* event) { + if (element()->disabled() || element()->readOnly()) + return; int step = 0; if (event->wheelDeltaY() > 0) step = 1; diff --git a/Source/WebCore/html/TextFieldInputType.h b/Source/WebCore/html/TextFieldInputType.h index e882c82..86ad0ef 100644 --- a/Source/WebCore/html/TextFieldInputType.h +++ b/Source/WebCore/html/TextFieldInputType.h @@ -40,6 +40,7 @@ namespace WebCore { class TextFieldInputType : public InputType { protected: TextFieldInputType(HTMLInputElement* element) : InputType(element) { } + virtual bool canSetSuggestedValue(); virtual void handleKeydownEvent(KeyboardEvent*); void handleKeydownEventForSpinButton(KeyboardEvent*); void handleWheelEventForSpinButton(WheelEvent*); diff --git a/Source/WebCore/html/TextInputType.cpp b/Source/WebCore/html/TextInputType.cpp index c37263a..a369976 100644 --- a/Source/WebCore/html/TextInputType.cpp +++ b/Source/WebCore/html/TextInputType.cpp @@ -45,12 +45,6 @@ const AtomicString& TextInputType::formControlType() const return InputTypeNames::text(); } -bool TextInputType::canSetSuggestedValue() -{ - // FIXME: Should this really be restricted to plain text? What about search, for example? - return true; -} - bool TextInputType::shouldRespectSpeechAttribute() { return true; diff --git a/Source/WebCore/html/TextInputType.h b/Source/WebCore/html/TextInputType.h index 3b6810e..243f656 100644 --- a/Source/WebCore/html/TextInputType.h +++ b/Source/WebCore/html/TextInputType.h @@ -42,7 +42,6 @@ public: private: TextInputType(HTMLInputElement* element) : BaseTextInputType(element) { } virtual const AtomicString& formControlType() const; - virtual bool canSetSuggestedValue(); virtual bool shouldRespectSpeechAttribute(); }; diff --git a/Source/WebCore/html/ValidationMessage.cpp b/Source/WebCore/html/ValidationMessage.cpp index 2c441c7..f772b92 100644 --- a/Source/WebCore/html/ValidationMessage.cpp +++ b/Source/WebCore/html/ValidationMessage.cpp @@ -105,7 +105,7 @@ protected: ElementWithPseudoId(Document* doc, const AtomicString& pseudoName) : HTMLElement(divTag, doc) , m_pseudoName(pseudoName) { }; - virtual AtomicString shadowPseudoId() const { return m_pseudoName; } + virtual const AtomicString& shadowPseudoId() const { return m_pseudoName; } private: AtomicString m_pseudoName; diff --git a/Source/WebCore/html/canvas/ArrayBuffer.cpp b/Source/WebCore/html/canvas/ArrayBuffer.cpp index 2136f64..4f75cc3 100644 --- a/Source/WebCore/html/canvas/ArrayBuffer.cpp +++ b/Source/WebCore/html/canvas/ArrayBuffer.cpp @@ -24,9 +24,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "ArrayBuffer.h" #include <wtf/RefPtr.h> @@ -100,5 +97,3 @@ void* ArrayBuffer::tryAllocate(unsigned numElements, unsigned elementByteSize) } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/ArrayBuffer.idl b/Source/WebCore/html/canvas/ArrayBuffer.idl index 79a4685..6f63e65 100644 --- a/Source/WebCore/html/canvas/ArrayBuffer.idl +++ b/Source/WebCore/html/canvas/ArrayBuffer.idl @@ -26,7 +26,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, NoStaticTables, diff --git a/Source/WebCore/html/canvas/ArrayBufferView.cpp b/Source/WebCore/html/canvas/ArrayBufferView.cpp index 7f41bda..a2f61ca 100644 --- a/Source/WebCore/html/canvas/ArrayBufferView.cpp +++ b/Source/WebCore/html/canvas/ArrayBufferView.cpp @@ -24,9 +24,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "ArrayBufferView.h" #include "ArrayBuffer.h" @@ -105,5 +102,3 @@ void ArrayBufferView::calculateOffsetAndLength(int start, int end, unsigned arra } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/ArrayBufferView.idl b/Source/WebCore/html/canvas/ArrayBufferView.idl index be217c1..1ea451d 100644 --- a/Source/WebCore/html/canvas/ArrayBufferView.idl +++ b/Source/WebCore/html/canvas/ArrayBufferView.idl @@ -24,7 +24,7 @@ */ module html { - interface [Conditional=3D_CANVAS|BLOB, CustomToJS, NoStaticTables, OmitConstructor] ArrayBufferView { + interface [CustomToJS, NoStaticTables, OmitConstructor] ArrayBufferView { readonly attribute ArrayBuffer buffer; readonly attribute unsigned long byteOffset; readonly attribute unsigned long byteLength; diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp index e029128..9ef2dba 100644 --- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -234,7 +234,7 @@ void CanvasRenderingContext2D::setAllAttributesToDefault() if (!context) return; - context->setShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB); + context->setLegacyShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB); context->setAlpha(1); context->setCompositeOperation(CompositeSourceOver); } @@ -574,7 +574,7 @@ void CanvasRenderingContext2D::setStrokeColor(const String& color) { if (color == state().m_unparsedStrokeColor) return; - setStrokeStyle(CanvasStyle::createFromString(color)); + setStrokeStyle(CanvasStyle::createFromString(color, canvas()->document())); state().m_unparsedStrokeColor = color; } @@ -615,7 +615,7 @@ void CanvasRenderingContext2D::setFillColor(const String& color) { if (color == state().m_unparsedFillColor) return; - setFillStyle(CanvasStyle::createFromString(color)); + setFillStyle(CanvasStyle::createFromString(color, canvas()->document())); state().m_unparsedFillColor = color; } @@ -1000,7 +1000,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur, if (!c) return; - c->setShadow(IntSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); + c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); } void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color, float alpha) @@ -1018,7 +1018,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur, if (!c) return; - c->setShadow(IntSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); + c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); } void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel, float alpha) @@ -1031,7 +1031,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur, if (!c) return; - c->setShadow(IntSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); + c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); } void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float r, float g, float b, float a) @@ -1044,7 +1044,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur, if (!c) return; - c->setShadow(IntSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); + c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); } void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float c, float m, float y, float k, float a) @@ -1064,7 +1064,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur, CGContextSetShadowWithColor(dc->platformContext(), adjustedShadowSize(width, -height), blur, shadowColor); CGColorRelease(shadowColor); #else - dc->setShadow(IntSize(width, -height), blur, state().m_shadowColor, ColorSpaceDeviceRGB); + dc->setLegacyShadow(FloatSize(width, -height), blur, state().m_shadowColor, ColorSpaceDeviceRGB); #endif } @@ -1084,7 +1084,7 @@ void CanvasRenderingContext2D::applyShadow() float width = state().m_shadowOffset.width(); float height = state().m_shadowOffset.height(); - c->setShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); + c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB); } static IntSize size(HTMLImageElement* image) @@ -1105,8 +1105,8 @@ static IntSize size(HTMLVideoElement* video) static inline FloatRect normalizeRect(const FloatRect& rect) { - return FloatRect(min(rect.x(), rect.right()), - min(rect.y(), rect.bottom()), + return FloatRect(min(rect.x(), rect.maxX()), + min(rect.y(), rect.maxY()), max(rect.width(), -rect.width()), max(rect.height(), -rect.height())); } @@ -1760,7 +1760,8 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo return; const Font& font = accessFont(); - + const FontMetrics& fontMetrics = font.fontMetrics(); + // FIXME: Handle maxWidth. // FIXME: Need to turn off font smoothing. @@ -1770,21 +1771,21 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo unsigned length = text.length(); const UChar* string = text.characters(); - TextRun textRun(string, length, 0, 0, 0, rtl, override, false, false); + TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, override, false, false); // Draw the item text at the correct point. FloatPoint location(x, y); switch (state().m_textBaseline) { case TopTextBaseline: case HangingTextBaseline: - location.setY(y + font.ascent()); + location.setY(y + fontMetrics.ascent()); break; case BottomTextBaseline: case IdeographicTextBaseline: - location.setY(y - font.descent()); + location.setY(y - fontMetrics.descent()); break; case MiddleTextBaseline: - location.setY(y - font.descent() + font.height() / 2); + location.setY(y - fontMetrics.descent() + fontMetrics.height() / 2); break; case AlphabeticTextBaseline: default: @@ -1792,7 +1793,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo break; } - float width = font.width(TextRun(text, false, 0, 0, rtl, override)); + float width = font.width(TextRun(text, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, override)); TextAlign align = state().m_textAlign; if (align == StartTextAlign) @@ -1812,8 +1813,8 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo } // The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text. - FloatRect textRect = FloatRect(location.x() - font.height() / 2, location.y() - font.ascent() - font.lineGap(), - width + font.height(), font.lineSpacing()); + FloatRect textRect = FloatRect(location.x() - fontMetrics.height() / 2, location.y() - fontMetrics.ascent() - fontMetrics.lineGap(), + width + fontMetrics.height(), fontMetrics.lineSpacing()); if (!fill) textRect.inflate(c->strokeThickness() / 2); diff --git a/Source/WebCore/html/canvas/CanvasStyle.cpp b/Source/WebCore/html/canvas/CanvasStyle.cpp index a4e87e3..ee8567c 100644 --- a/Source/WebCore/html/canvas/CanvasStyle.cpp +++ b/Source/WebCore/html/canvas/CanvasStyle.cpp @@ -51,14 +51,16 @@ namespace WebCore { -enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParseFailed }; +enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParsedSystemColor, ParseFailed }; -static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString) +static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString, Document* document = 0) { if (equalIgnoringCase(colorString, "currentcolor")) return ParsedCurrentColor; if (CSSParser::parseColor(parsedColor, colorString)) return ParsedRGBA; + if (CSSParser::parseSystemColor(parsedColor, colorString, document)) + return ParsedSystemColor; return ParseFailed; } @@ -73,9 +75,10 @@ RGBA32 currentColor(HTMLCanvasElement* canvas) bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement* canvas) { - ColorParseResult parseResult = parseColor(parsedColor, colorString); + ColorParseResult parseResult = parseColor(parsedColor, colorString, canvas ? canvas->document() : 0); switch (parseResult) { case ParsedRGBA: + case ParsedSystemColor: return true; case ParsedCurrentColor: parsedColor = currentColor(canvas); @@ -131,12 +134,13 @@ CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern) { } -PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color) +PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color, Document* document) { RGBA32 rgba; - ColorParseResult parseResult = parseColor(rgba, color); + ColorParseResult parseResult = parseColor(rgba, color, document); switch (parseResult) { case ParsedRGBA: + case ParsedSystemColor: return adoptRef(new CanvasStyle(rgba)); case ParsedCurrentColor: return adoptRef(new CanvasStyle(CurrentColor)); diff --git a/Source/WebCore/html/canvas/CanvasStyle.h b/Source/WebCore/html/canvas/CanvasStyle.h index 91dc923..1c136d3 100644 --- a/Source/WebCore/html/canvas/CanvasStyle.h +++ b/Source/WebCore/html/canvas/CanvasStyle.h @@ -35,13 +35,14 @@ namespace WebCore { class CanvasGradient; class CanvasPattern; + class Document; class GraphicsContext; class HTMLCanvasElement; class CanvasStyle : public RefCounted<CanvasStyle> { public: static PassRefPtr<CanvasStyle> createFromRGBA(RGBA32 rgba) { return adoptRef(new CanvasStyle(rgba)); } - static PassRefPtr<CanvasStyle> createFromString(const String& color); + static PassRefPtr<CanvasStyle> createFromString(const String& color, Document* = 0); static PassRefPtr<CanvasStyle> createFromStringWithOverrideAlpha(const String& color, float alpha); static PassRefPtr<CanvasStyle> createFromGrayLevelWithAlpha(float grayLevel, float alpha) { return adoptRef(new CanvasStyle(grayLevel, alpha)); } static PassRefPtr<CanvasStyle> createFromRGBAChannels(float r, float g, float b, float a) { return adoptRef(new CanvasStyle(r, g, b, a)); } diff --git a/Source/WebCore/html/canvas/DataView.cpp b/Source/WebCore/html/canvas/DataView.cpp index 82b10b3..e00443d 100755 --- a/Source/WebCore/html/canvas/DataView.cpp +++ b/Source/WebCore/html/canvas/DataView.cpp @@ -24,9 +24,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "DataView.h" #include "CheckedInt.h" @@ -231,5 +228,3 @@ void DataView::setFloat64(unsigned byteOffset, double value, bool littleEndian, } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/DataView.h b/Source/WebCore/html/canvas/DataView.h index 5707aa3..a8aba5c 100755 --- a/Source/WebCore/html/canvas/DataView.h +++ b/Source/WebCore/html/canvas/DataView.h @@ -75,7 +75,7 @@ private: DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength); template<typename T> - inline bool beyondRange(unsigned byteOffset) const { return byteOffset + sizeof(T) > m_byteLength; } + inline bool beyondRange(unsigned byteOffset) const { return byteOffset >= m_byteLength || byteOffset + sizeof(T) > m_byteLength; } template<typename T> T getData(unsigned byteOffset, bool littleEndian, ExceptionCode&) const; diff --git a/Source/WebCore/html/canvas/DataView.idl b/Source/WebCore/html/canvas/DataView.idl index f99a814..2e173d7 100755 --- a/Source/WebCore/html/canvas/DataView.idl +++ b/Source/WebCore/html/canvas/DataView.idl @@ -26,7 +26,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, CustomToJS, diff --git a/Source/WebCore/html/canvas/Float32Array.cpp b/Source/WebCore/html/canvas/Float32Array.cpp index 1b26aef..209b20f 100644 --- a/Source/WebCore/html/canvas/Float32Array.cpp +++ b/Source/WebCore/html/canvas/Float32Array.cpp @@ -25,9 +25,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "Float32Array.h" namespace WebCore { @@ -52,16 +49,14 @@ Float32Array::Float32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, { } -PassRefPtr<Float32Array> Float32Array::slice(int start) const +PassRefPtr<Float32Array> Float32Array::subarray(int start) const { - return slice(start, length()); + return subarray(start, length()); } -PassRefPtr<Float32Array> Float32Array::slice(int start, int end) const +PassRefPtr<Float32Array> Float32Array::subarray(int start, int end) const { - return sliceImpl<Float32Array>(start, end); + return subarrayImpl<Float32Array>(start, end); } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/Float32Array.h b/Source/WebCore/html/canvas/Float32Array.h index d00a7c5..ee1ea56 100644 --- a/Source/WebCore/html/canvas/Float32Array.h +++ b/Source/WebCore/html/canvas/Float32Array.h @@ -56,8 +56,8 @@ public: return result; } - PassRefPtr<Float32Array> slice(int start) const; - PassRefPtr<Float32Array> slice(int start, int end) const; + PassRefPtr<Float32Array> subarray(int start) const; + PassRefPtr<Float32Array> subarray(int start, int end) const; private: Float32Array(PassRefPtr<ArrayBuffer> buffer, diff --git a/Source/WebCore/html/canvas/Float32Array.idl b/Source/WebCore/html/canvas/Float32Array.idl index b979d29..c797f31 100644 --- a/Source/WebCore/html/canvas/Float32Array.idl +++ b/Source/WebCore/html/canvas/Float32Array.idl @@ -26,7 +26,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, V8CustomConstructor, @@ -40,7 +39,7 @@ module html { const unsigned int BYTES_PER_ELEMENT = 4; readonly attribute unsigned long length; - Float32Array slice(in long start, in [Optional] long end); + Float32Array subarray(in long start, in [Optional] long end); // void set(in Float32Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); diff --git a/Source/WebCore/html/canvas/Int16Array.cpp b/Source/WebCore/html/canvas/Int16Array.cpp index a3d04bc..9aaa1d5 100644 --- a/Source/WebCore/html/canvas/Int16Array.cpp +++ b/Source/WebCore/html/canvas/Int16Array.cpp @@ -24,9 +24,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "Int16Array.h" namespace WebCore { @@ -51,16 +48,14 @@ Int16Array::Int16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi { } -PassRefPtr<Int16Array> Int16Array::slice(int start) const +PassRefPtr<Int16Array> Int16Array::subarray(int start) const { - return slice(start, length()); + return subarray(start, length()); } -PassRefPtr<Int16Array> Int16Array::slice(int start, int end) const +PassRefPtr<Int16Array> Int16Array::subarray(int start, int end) const { - return sliceImpl<Int16Array>(start, end); + return subarrayImpl<Int16Array>(start, end); } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/Int16Array.h b/Source/WebCore/html/canvas/Int16Array.h index a6286c6..6c4f54b 100644 --- a/Source/WebCore/html/canvas/Int16Array.h +++ b/Source/WebCore/html/canvas/Int16Array.h @@ -41,8 +41,8 @@ public: using TypedArrayBase<short>::set; using IntegralTypedArrayBase<short>::set; - PassRefPtr<Int16Array> slice(int start) const; - PassRefPtr<Int16Array> slice(int start, int end) const; + PassRefPtr<Int16Array> subarray(int start) const; + PassRefPtr<Int16Array> subarray(int start, int end) const; private: Int16Array(PassRefPtr<ArrayBuffer> buffer, diff --git a/Source/WebCore/html/canvas/Int16Array.idl b/Source/WebCore/html/canvas/Int16Array.idl index f1f5c8b..40123d7 100644 --- a/Source/WebCore/html/canvas/Int16Array.idl +++ b/Source/WebCore/html/canvas/Int16Array.idl @@ -25,7 +25,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, V8CustomConstructor, @@ -39,7 +38,7 @@ module html { const unsigned int BYTES_PER_ELEMENT = 2; readonly attribute unsigned long length; - Int16Array slice(in long start, in [Optional] long end); + Int16Array subarray(in long start, in [Optional] long end); // void set(in Int16Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); diff --git a/Source/WebCore/html/canvas/Int32Array.cpp b/Source/WebCore/html/canvas/Int32Array.cpp index 266c941..6d2793c 100644 --- a/Source/WebCore/html/canvas/Int32Array.cpp +++ b/Source/WebCore/html/canvas/Int32Array.cpp @@ -25,9 +25,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "Int32Array.h" namespace WebCore { @@ -52,16 +49,14 @@ Int32Array::Int32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi { } -PassRefPtr<Int32Array> Int32Array::slice(int start) const +PassRefPtr<Int32Array> Int32Array::subarray(int start) const { - return slice(start, length()); + return subarray(start, length()); } -PassRefPtr<Int32Array> Int32Array::slice(int start, int end) const +PassRefPtr<Int32Array> Int32Array::subarray(int start, int end) const { - return sliceImpl<Int32Array>(start, end); + return subarrayImpl<Int32Array>(start, end); } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/Int32Array.h b/Source/WebCore/html/canvas/Int32Array.h index 068a677..c657300 100644 --- a/Source/WebCore/html/canvas/Int32Array.h +++ b/Source/WebCore/html/canvas/Int32Array.h @@ -37,13 +37,12 @@ public: static PassRefPtr<Int32Array> create(int* array, unsigned length); static PassRefPtr<Int32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); -#if !COMPILER(RVCT) - using TypedArrayBase<int>::set; - using IntegralTypedArrayBase<int>::set; -#endif + // Can’t use "using" here due to a bug in the RVCT compiler. + void set(TypedArrayBase<int>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<int>::set(array, offset, ec); } + void set(unsigned index, double value) { return IntegralTypedArrayBase<int>::set(index, value); } - PassRefPtr<Int32Array> slice(int start) const; - PassRefPtr<Int32Array> slice(int start, int end) const; + PassRefPtr<Int32Array> subarray(int start) const; + PassRefPtr<Int32Array> subarray(int start, int end) const; private: Int32Array(PassRefPtr<ArrayBuffer> buffer, diff --git a/Source/WebCore/html/canvas/Int32Array.idl b/Source/WebCore/html/canvas/Int32Array.idl index f96b53c..dd9082a 100644 --- a/Source/WebCore/html/canvas/Int32Array.idl +++ b/Source/WebCore/html/canvas/Int32Array.idl @@ -26,7 +26,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, V8CustomConstructor, @@ -40,7 +39,7 @@ module html { const unsigned int BYTES_PER_ELEMENT = 4; readonly attribute unsigned long length; - Int32Array slice(in long start, in [Optional] long end); + Int32Array subarray(in long start, in [Optional] long end); // void set(in Int32Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); diff --git a/Source/WebCore/html/canvas/Int8Array.cpp b/Source/WebCore/html/canvas/Int8Array.cpp index 89ed316..ceb7579 100644 --- a/Source/WebCore/html/canvas/Int8Array.cpp +++ b/Source/WebCore/html/canvas/Int8Array.cpp @@ -25,9 +25,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "Int8Array.h" namespace WebCore { @@ -52,16 +49,14 @@ Int8Array::Int8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsign { } -PassRefPtr<Int8Array> Int8Array::slice(int start) const +PassRefPtr<Int8Array> Int8Array::subarray(int start) const { - return slice(start, length()); + return subarray(start, length()); } -PassRefPtr<Int8Array> Int8Array::slice(int start, int end) const +PassRefPtr<Int8Array> Int8Array::subarray(int start, int end) const { - return sliceImpl<Int8Array>(start, end); + return subarrayImpl<Int8Array>(start, end); } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/Int8Array.h b/Source/WebCore/html/canvas/Int8Array.h index a5df302..aabdb97 100644 --- a/Source/WebCore/html/canvas/Int8Array.h +++ b/Source/WebCore/html/canvas/Int8Array.h @@ -39,11 +39,12 @@ public: static PassRefPtr<Int8Array> create(signed char* array, unsigned length); static PassRefPtr<Int8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); - using TypedArrayBase<signed char>::set; - using IntegralTypedArrayBase<signed char>::set; + // Can’t use "using" here due to a bug in the RVCT compiler. + void set(TypedArrayBase<signed char>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<signed char>::set(array, offset, ec); } + void set(unsigned index, double value) { return IntegralTypedArrayBase<signed char>::set(index, value); } - PassRefPtr<Int8Array> slice(int start) const; - PassRefPtr<Int8Array> slice(int start, int end) const; + PassRefPtr<Int8Array> subarray(int start) const; + PassRefPtr<Int8Array> subarray(int start, int end) const; private: Int8Array(PassRefPtr<ArrayBuffer> buffer, diff --git a/Source/WebCore/html/canvas/Int8Array.idl b/Source/WebCore/html/canvas/Int8Array.idl index 08a608b..ab000f2 100644 --- a/Source/WebCore/html/canvas/Int8Array.idl +++ b/Source/WebCore/html/canvas/Int8Array.idl @@ -26,7 +26,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, V8CustomConstructor, @@ -40,7 +39,7 @@ module html { const unsigned int BYTES_PER_ELEMENT = 1; readonly attribute unsigned long length; - Int8Array slice(in long start, in [Optional] long end); + Int8Array subarray(in long start, in [Optional] long end); // void set(in Int8Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.cpp b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp index 25aae2f..5bd3163 100644 --- a/Source/WebCore/html/canvas/OESStandardDerivatives.cpp +++ b/Source/WebCore/html/canvas/OESStandardDerivatives.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "OESStandardDerivatives.h" @@ -51,4 +51,4 @@ PassRefPtr<OESStandardDerivatives> OESStandardDerivatives::create() } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/OESStandardDerivatives.idl b/Source/WebCore/html/canvas/OESStandardDerivatives.idl index a9d1dd6..6c0f788 100644 --- a/Source/WebCore/html/canvas/OESStandardDerivatives.idl +++ b/Source/WebCore/html/canvas/OESStandardDerivatives.idl @@ -24,7 +24,7 @@ */ module html { - interface [Conditional=3D_CANVAS, OmitConstructor, DontCheckEnums] OESStandardDerivatives { + interface [Conditional=WEBGL, OmitConstructor, DontCheckEnums] OESStandardDerivatives { const unsigned int FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B; }; } diff --git a/Source/WebCore/html/canvas/OESTextureFloat.cpp b/Source/WebCore/html/canvas/OESTextureFloat.cpp index dab3caf..9518764 100644 --- a/Source/WebCore/html/canvas/OESTextureFloat.cpp +++ b/Source/WebCore/html/canvas/OESTextureFloat.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "OESTextureFloat.h" @@ -51,4 +51,4 @@ PassRefPtr<OESTextureFloat> OESTextureFloat::create() } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/OESTextureFloat.idl b/Source/WebCore/html/canvas/OESTextureFloat.idl index e255875..3319fd9 100644 --- a/Source/WebCore/html/canvas/OESTextureFloat.idl +++ b/Source/WebCore/html/canvas/OESTextureFloat.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS, OmitConstructor] OESTextureFloat { + interface [Conditional=WEBGL, OmitConstructor] OESTextureFloat { }; } diff --git a/Source/WebCore/html/canvas/TypedArrayBase.h b/Source/WebCore/html/canvas/TypedArrayBase.h index a828620..e2a7c63 100644 --- a/Source/WebCore/html/canvas/TypedArrayBase.h +++ b/Source/WebCore/html/canvas/TypedArrayBase.h @@ -104,7 +104,7 @@ protected: } template <class Subclass> - PassRefPtr<Subclass> sliceImpl(int start, int end) const + PassRefPtr<Subclass> subarrayImpl(int start, int end) const { unsigned offset, length; calculateOffsetAndLength(start, end, m_length, &offset, &length); diff --git a/Source/WebCore/html/canvas/Uint16Array.cpp b/Source/WebCore/html/canvas/Uint16Array.cpp index 5312888..92b2361 100644 --- a/Source/WebCore/html/canvas/Uint16Array.cpp +++ b/Source/WebCore/html/canvas/Uint16Array.cpp @@ -25,9 +25,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "Uint16Array.h" namespace WebCore { @@ -52,16 +49,14 @@ Uint16Array::Uint16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, un { } -PassRefPtr<Uint16Array> Uint16Array::slice(int start) const +PassRefPtr<Uint16Array> Uint16Array::subarray(int start) const { - return slice(start, length()); + return subarray(start, length()); } -PassRefPtr<Uint16Array> Uint16Array::slice(int start, int end) const +PassRefPtr<Uint16Array> Uint16Array::subarray(int start, int end) const { - return sliceImpl<Uint16Array>(start, end); + return subarrayImpl<Uint16Array>(start, end); } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/Uint16Array.h b/Source/WebCore/html/canvas/Uint16Array.h index f63b67d..8ef04a4 100644 --- a/Source/WebCore/html/canvas/Uint16Array.h +++ b/Source/WebCore/html/canvas/Uint16Array.h @@ -39,11 +39,12 @@ public: static PassRefPtr<Uint16Array> create(unsigned short* array, unsigned length); static PassRefPtr<Uint16Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); - using TypedArrayBase<unsigned short>::set; - using IntegralTypedArrayBase<unsigned short>::set; + // Can’t use "using" here due to a bug in the RVCT compiler. + void set(TypedArrayBase<unsigned short>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<unsigned short>::set(array, offset, ec); } + void set(unsigned index, double value) { return IntegralTypedArrayBase<unsigned short>::set(index, value); } - PassRefPtr<Uint16Array> slice(int start) const; - PassRefPtr<Uint16Array> slice(int start, int end) const; + PassRefPtr<Uint16Array> subarray(int start) const; + PassRefPtr<Uint16Array> subarray(int start, int end) const; private: Uint16Array(PassRefPtr<ArrayBuffer> buffer, diff --git a/Source/WebCore/html/canvas/Uint16Array.idl b/Source/WebCore/html/canvas/Uint16Array.idl index 8e778b4..fc8775d 100644 --- a/Source/WebCore/html/canvas/Uint16Array.idl +++ b/Source/WebCore/html/canvas/Uint16Array.idl @@ -26,7 +26,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, V8CustomConstructor, @@ -40,7 +39,7 @@ module html { const unsigned int BYTES_PER_ELEMENT = 2; readonly attribute unsigned long length; - Uint16Array slice(in long start, in [Optional] long end); + Uint16Array subarray(in long start, in [Optional] long end); // void set(in Uint16Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); diff --git a/Source/WebCore/html/canvas/Uint32Array.cpp b/Source/WebCore/html/canvas/Uint32Array.cpp index f5bd959..621b53c 100644 --- a/Source/WebCore/html/canvas/Uint32Array.cpp +++ b/Source/WebCore/html/canvas/Uint32Array.cpp @@ -25,9 +25,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "Uint32Array.h" namespace WebCore { @@ -52,16 +49,14 @@ Uint32Array::Uint32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, un { } -PassRefPtr<Uint32Array> Uint32Array::slice(int start) const +PassRefPtr<Uint32Array> Uint32Array::subarray(int start) const { - return slice(start, length()); + return subarray(start, length()); } -PassRefPtr<Uint32Array> Uint32Array::slice(int start, int end) const +PassRefPtr<Uint32Array> Uint32Array::subarray(int start, int end) const { - return sliceImpl<Uint32Array>(start, end); + return subarrayImpl<Uint32Array>(start, end); } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/Uint32Array.h b/Source/WebCore/html/canvas/Uint32Array.h index 9c0f137..196a67f 100644 --- a/Source/WebCore/html/canvas/Uint32Array.h +++ b/Source/WebCore/html/canvas/Uint32Array.h @@ -39,11 +39,12 @@ public: static PassRefPtr<Uint32Array> create(unsigned int* array, unsigned length); static PassRefPtr<Uint32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); - using TypedArrayBase<unsigned int>::set; - using IntegralTypedArrayBase<unsigned int>::set; + // Can’t use "using" here due to a bug in the RVCT compiler. + void set(TypedArrayBase<unsigned int>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<unsigned int>::set(array, offset, ec); } + void set(unsigned index, double value) { return IntegralTypedArrayBase<unsigned int>::set(index, value); } - PassRefPtr<Uint32Array> slice(int start) const; - PassRefPtr<Uint32Array> slice(int start, int end) const; + PassRefPtr<Uint32Array> subarray(int start) const; + PassRefPtr<Uint32Array> subarray(int start, int end) const; private: Uint32Array(PassRefPtr<ArrayBuffer> buffer, diff --git a/Source/WebCore/html/canvas/Uint32Array.idl b/Source/WebCore/html/canvas/Uint32Array.idl index 9fbf30c..4d95eab 100644 --- a/Source/WebCore/html/canvas/Uint32Array.idl +++ b/Source/WebCore/html/canvas/Uint32Array.idl @@ -26,7 +26,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, V8CustomConstructor, @@ -40,7 +39,7 @@ module html { const unsigned int BYTES_PER_ELEMENT = 4; readonly attribute unsigned long length; - Uint32Array slice(in long start, in [Optional] long end); + Uint32Array subarray(in long start, in [Optional] long end); // void set(in Uint32Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); diff --git a/Source/WebCore/html/canvas/Uint8Array.cpp b/Source/WebCore/html/canvas/Uint8Array.cpp index 99b8a09..572e7ec 100644 --- a/Source/WebCore/html/canvas/Uint8Array.cpp +++ b/Source/WebCore/html/canvas/Uint8Array.cpp @@ -25,9 +25,6 @@ */ #include "config.h" - -#if ENABLE(3D_CANVAS) || ENABLE(BLOB) - #include "Uint8Array.h" namespace WebCore { @@ -52,16 +49,14 @@ Uint8Array::Uint8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi { } -PassRefPtr<Uint8Array> Uint8Array::slice(int start) const +PassRefPtr<Uint8Array> Uint8Array::subarray(int start) const { - return slice(start, length()); + return subarray(start, length()); } -PassRefPtr<Uint8Array> Uint8Array::slice(int start, int end) const +PassRefPtr<Uint8Array> Uint8Array::subarray(int start, int end) const { - return sliceImpl<Uint8Array>(start, end); + return subarrayImpl<Uint8Array>(start, end); } } - -#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB) diff --git a/Source/WebCore/html/canvas/Uint8Array.h b/Source/WebCore/html/canvas/Uint8Array.h index 66154b5..a3a42dc 100644 --- a/Source/WebCore/html/canvas/Uint8Array.h +++ b/Source/WebCore/html/canvas/Uint8Array.h @@ -39,13 +39,12 @@ public: static PassRefPtr<Uint8Array> create(unsigned char* array, unsigned length); static PassRefPtr<Uint8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length); -#if !COMPILER(RVCT) - using TypedArrayBase<unsigned char>::set; - using IntegralTypedArrayBase<unsigned char>::set; -#endif + // Can’t use "using" here due to a bug in the RVCT compiler. + void set(TypedArrayBase<unsigned char>* array, unsigned offset, ExceptionCode& ec) { return TypedArrayBase<unsigned char>::set(array, offset, ec); } + void set(unsigned index, double value) { return IntegralTypedArrayBase<unsigned char>::set(index, value); } - PassRefPtr<Uint8Array> slice(int start) const; - PassRefPtr<Uint8Array> slice(int start, int end) const; + PassRefPtr<Uint8Array> subarray(int start) const; + PassRefPtr<Uint8Array> subarray(int start, int end) const; private: Uint8Array(PassRefPtr<ArrayBuffer> buffer, diff --git a/Source/WebCore/html/canvas/Uint8Array.idl b/Source/WebCore/html/canvas/Uint8Array.idl index 7fe7e21..1bdd299 100644 --- a/Source/WebCore/html/canvas/Uint8Array.idl +++ b/Source/WebCore/html/canvas/Uint8Array.idl @@ -26,7 +26,6 @@ module html { interface [ - Conditional=3D_CANVAS|BLOB, CanBeConstructed, CustomConstructFunction, V8CustomConstructor, @@ -40,7 +39,7 @@ module html { const unsigned int BYTES_PER_ELEMENT = 1; readonly attribute unsigned long length; - Uint8Array slice(in long start, in [Optional] long end); + Uint8Array subarray(in long start, in [Optional] long end); // void set(in Uint8Array array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); diff --git a/Source/WebCore/html/canvas/WebGLActiveInfo.idl b/Source/WebCore/html/canvas/WebGLActiveInfo.idl index 28f7136..d544970 100644 --- a/Source/WebCore/html/canvas/WebGLActiveInfo.idl +++ b/Source/WebCore/html/canvas/WebGLActiveInfo.idl @@ -26,7 +26,7 @@ module html { interface [ - Conditional=3D_CANVAS + Conditional=WEBGL ] WebGLActiveInfo { readonly attribute int size; readonly attribute unsigned int type; diff --git a/Source/WebCore/html/canvas/WebGLBuffer.cpp b/Source/WebCore/html/canvas/WebGLBuffer.cpp index 849472b..ee0ebe6 100644 --- a/Source/WebCore/html/canvas/WebGLBuffer.cpp +++ b/Source/WebCore/html/canvas/WebGLBuffer.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLBuffer.h" @@ -34,7 +34,7 @@ #include "WebGLRenderingContext.h" namespace WebCore { - + PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx) { return adoptRef(new WebGLBuffer(ctx)); @@ -207,4 +207,4 @@ void WebGLBuffer::clearCachedMaxIndices() } -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLBuffer.h b/Source/WebCore/html/canvas/WebGLBuffer.h index ec79a2d..6153cf1 100644 --- a/Source/WebCore/html/canvas/WebGLBuffer.h +++ b/Source/WebCore/html/canvas/WebGLBuffer.h @@ -42,10 +42,10 @@ public: static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*); bool associateBufferData(GC3Dsizeiptr size); - bool associateBufferData(ArrayBuffer* array); - bool associateBufferData(ArrayBufferView* array); - bool associateBufferSubData(GC3Dintptr offset, ArrayBuffer* array); - bool associateBufferSubData(GC3Dintptr offset, ArrayBufferView* array); + bool associateBufferData(ArrayBuffer*); + bool associateBufferData(ArrayBufferView*); + bool associateBufferSubData(GC3Dintptr offset, ArrayBuffer*); + bool associateBufferSubData(GC3Dintptr offset, ArrayBufferView*); GC3Dsizeiptr byteLength() const; const ArrayBuffer* elementArrayBuffer() const { return m_elementArrayBuffer.get(); } diff --git a/Source/WebCore/html/canvas/WebGLBuffer.idl b/Source/WebCore/html/canvas/WebGLBuffer.idl index 30b7606..2b6daec 100644 --- a/Source/WebCore/html/canvas/WebGLBuffer.idl +++ b/Source/WebCore/html/canvas/WebGLBuffer.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLBuffer { + interface [Conditional=WEBGL] WebGLBuffer { }; } diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp index a0725ca..6a47ea9 100644 --- a/Source/WebCore/html/canvas/WebGLContextAttributes.cpp +++ b/Source/WebCore/html/canvas/WebGLContextAttributes.cpp @@ -26,7 +26,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLContextAttributes.h" @@ -114,4 +114,4 @@ GraphicsContext3D::Attributes WebGLContextAttributes::attributes() const } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLContextAttributes.idl b/Source/WebCore/html/canvas/WebGLContextAttributes.idl index be2b20c..0fa0c2c 100644 --- a/Source/WebCore/html/canvas/WebGLContextAttributes.idl +++ b/Source/WebCore/html/canvas/WebGLContextAttributes.idl @@ -26,7 +26,7 @@ module html { interface [ - Conditional=3D_CANVAS, + Conditional=WEBGL, OmitConstructor ] WebGLContextAttributes { attribute boolean alpha; diff --git a/Source/WebCore/html/canvas/WebGLContextEvent.idl b/Source/WebCore/html/canvas/WebGLContextEvent.idl index 30973a9..9ee4769 100644 --- a/Source/WebCore/html/canvas/WebGLContextEvent.idl +++ b/Source/WebCore/html/canvas/WebGLContextEvent.idl @@ -25,7 +25,7 @@ module html { interface [ - Conditional=3D_CANVAS, + Conditional=WEBGL, ] WebGLContextEvent : Event { readonly attribute DOMString statusMessage; [StrictTypeChecking] void initEvent(in DOMString eventTypeArg, diff --git a/Source/WebCore/html/canvas/WebGLExtension.cpp b/Source/WebCore/html/canvas/WebGLExtension.cpp index 580e635..64b0bf5 100644 --- a/Source/WebCore/html/canvas/WebGLExtension.cpp +++ b/Source/WebCore/html/canvas/WebGLExtension.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLExtension.h" @@ -41,4 +41,4 @@ WebGLExtension::~WebGLExtension() } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp index dbc714b..4b721eb 100644 --- a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp +++ b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLFramebuffer.h" @@ -354,4 +354,4 @@ bool WebGLFramebuffer::initializeRenderbuffers() } -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.idl b/Source/WebCore/html/canvas/WebGLFramebuffer.idl index 8c1d9fd..7211d15 100644 --- a/Source/WebCore/html/canvas/WebGLFramebuffer.idl +++ b/Source/WebCore/html/canvas/WebGLFramebuffer.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLFramebuffer { + interface [Conditional=WEBGL] WebGLFramebuffer { }; } diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.cpp b/Source/WebCore/html/canvas/WebGLGetInfo.cpp index 6aff82f..d0c8c65 100644 --- a/Source/WebCore/html/canvas/WebGLGetInfo.cpp +++ b/Source/WebCore/html/canvas/WebGLGetInfo.cpp @@ -26,7 +26,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLGetInfo.h" @@ -63,9 +63,9 @@ WebGLGetInfo::WebGLGetInfo(float value) { } -WebGLGetInfo::WebGLGetInfo(long value) - : m_type(kTypeLong) - , m_long(value) +WebGLGetInfo::WebGLGetInfo(int value) + : m_type(kTypeInt) + , m_int(value) { } @@ -80,9 +80,9 @@ WebGLGetInfo::WebGLGetInfo(const String& value) { } -WebGLGetInfo::WebGLGetInfo(unsigned long value) - : m_type(kTypeUnsignedLong) - , m_unsignedLong(value) +WebGLGetInfo::WebGLGetInfo(unsigned int value) + : m_type(kTypeUnsignedInt) + , m_unsignedInt(value) { } @@ -161,10 +161,10 @@ float WebGLGetInfo::getFloat() const return m_float; } -long WebGLGetInfo::getLong() const +int WebGLGetInfo::getInt() const { - ASSERT(getType() == kTypeLong); - return m_long; + ASSERT(getType() == kTypeInt); + return m_int; } const String& WebGLGetInfo::getString() const @@ -173,10 +173,10 @@ const String& WebGLGetInfo::getString() const return m_string; } -unsigned long WebGLGetInfo::getUnsignedLong() const +unsigned int WebGLGetInfo::getUnsignedInt() const { - ASSERT(getType() == kTypeUnsignedLong); - return m_unsignedLong; + ASSERT(getType() == kTypeUnsignedInt); + return m_unsignedInt; } PassRefPtr<WebGLBuffer> WebGLGetInfo::getWebGLBuffer() const @@ -229,4 +229,4 @@ PassRefPtr<Uint8Array> WebGLGetInfo::getWebGLUnsignedByteArray() const } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.h b/Source/WebCore/html/canvas/WebGLGetInfo.h index caee520..91f9233 100644 --- a/Source/WebCore/html/canvas/WebGLGetInfo.h +++ b/Source/WebCore/html/canvas/WebGLGetInfo.h @@ -53,10 +53,10 @@ public: kTypeBool, kTypeBoolArray, kTypeFloat, - kTypeLong, + kTypeInt, kTypeNull, kTypeString, - kTypeUnsignedLong, + kTypeUnsignedInt, kTypeWebGLBuffer, kTypeWebGLFloatArray, kTypeWebGLFramebuffer, @@ -71,11 +71,11 @@ public: WebGLGetInfo(bool value); WebGLGetInfo(const bool* value, int size); WebGLGetInfo(float value); - WebGLGetInfo(long value); + WebGLGetInfo(int value); // Represents the null value and type. WebGLGetInfo(); WebGLGetInfo(const String& value); - WebGLGetInfo(unsigned long value); + WebGLGetInfo(unsigned int value); WebGLGetInfo(PassRefPtr<WebGLBuffer> value); WebGLGetInfo(PassRefPtr<Float32Array> value); WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value); @@ -94,9 +94,9 @@ public: bool getBool() const; const Vector<bool>& getBoolArray() const; float getFloat() const; - long getLong() const; + int getInt() const; const String& getString() const; - unsigned long getUnsignedLong() const; + unsigned int getUnsignedInt() const; PassRefPtr<WebGLBuffer> getWebGLBuffer() const; PassRefPtr<Float32Array> getWebGLFloatArray() const; PassRefPtr<WebGLFramebuffer> getWebGLFramebuffer() const; @@ -113,9 +113,9 @@ private: bool m_bool; Vector<bool> m_boolArray; float m_float; - long m_long; + int m_int; String m_string; - unsigned long m_unsignedLong; + unsigned int m_unsignedInt; RefPtr<WebGLBuffer> m_webglBuffer; RefPtr<Float32Array> m_webglFloatArray; RefPtr<WebGLFramebuffer> m_webglFramebuffer; diff --git a/Source/WebCore/html/canvas/WebGLObject.cpp b/Source/WebCore/html/canvas/WebGLObject.cpp index 41ad0f1..d47013e 100644 --- a/Source/WebCore/html/canvas/WebGLObject.cpp +++ b/Source/WebCore/html/canvas/WebGLObject.cpp @@ -25,14 +25,14 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLObject.h" #include "WebGLRenderingContext.h" namespace WebCore { - + WebGLObject::WebGLObject(WebGLRenderingContext* context) : m_object(0) , m_context(context) @@ -68,4 +68,4 @@ void WebGLObject::deleteObject() } -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLProgram.cpp b/Source/WebCore/html/canvas/WebGLProgram.cpp index b3fa363..d3efda4 100644 --- a/Source/WebCore/html/canvas/WebGLProgram.cpp +++ b/Source/WebCore/html/canvas/WebGLProgram.cpp @@ -25,14 +25,14 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLProgram.h" #include "WebGLRenderingContext.h" namespace WebCore { - + PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx) { return adoptRef(new WebGLProgram(ctx)); @@ -103,7 +103,7 @@ bool WebGLProgram::isUsingVertexAttrib0() const return false; } -WebGLShader* WebGLProgram::getAttachedShader(GraphicsContext3D::WebGLEnumType type) +WebGLShader* WebGLProgram::getAttachedShader(GC3Denum type) { switch (type) { case GraphicsContext3D::VERTEX_SHADER: @@ -157,4 +157,4 @@ bool WebGLProgram::detachShader(WebGLShader* shader) } -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLProgram.h b/Source/WebCore/html/canvas/WebGLProgram.h index f2acef8..0dd3ba0 100644 --- a/Source/WebCore/html/canvas/WebGLProgram.h +++ b/Source/WebCore/html/canvas/WebGLProgram.h @@ -60,7 +60,7 @@ public: // will never be linked so many times. void increaseLinkCount() { ++m_linkCount; } - WebGLShader* getAttachedShader(GraphicsContext3D::WebGLEnumType); + WebGLShader* getAttachedShader(GC3Denum); bool attachShader(WebGLShader*); bool detachShader(WebGLShader*); diff --git a/Source/WebCore/html/canvas/WebGLProgram.idl b/Source/WebCore/html/canvas/WebGLProgram.idl index 562fa3a..480dfce 100644 --- a/Source/WebCore/html/canvas/WebGLProgram.idl +++ b/Source/WebCore/html/canvas/WebGLProgram.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLProgram { + interface [Conditional=WEBGL] WebGLProgram { }; } diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp index 03a419a..93b9165 100644 --- a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp +++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp @@ -25,14 +25,14 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLRenderbuffer.h" #include "WebGLRenderingContext.h" namespace WebCore { - + PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* ctx) { return adoptRef(new WebGLRenderbuffer(ctx)); @@ -57,4 +57,4 @@ void WebGLRenderbuffer::deleteObjectImpl(Platform3DObject object) } -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.idl b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl index 2524433..5aa7db8 100644 --- a/Source/WebCore/html/canvas/WebGLRenderbuffer.idl +++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLRenderbuffer { + interface [Conditional=WEBGL] WebGLRenderbuffer { }; } diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp index a3b9699..bd155c9 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLRenderingContext.h" @@ -48,6 +48,7 @@ #include "OESTextureFloat.h" #include "RenderBox.h" #include "RenderLayer.h" +#include "Settings.h" #include "Uint16Array.h" #include "WebGLActiveInfo.h" #include "WebGLBuffer.h" @@ -341,17 +342,33 @@ void WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired() } } +class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback { +public: + WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_contextLostCallback(cb) {} + virtual void onContextLost() { m_contextLostCallback->forceLostContext(); } + virtual ~WebGLRenderingContextLostCallback() {} +private: + WebGLRenderingContext* m_contextLostCallback; +}; + PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs) { HostWindow* hostWindow = canvas->document()->view()->root()->hostWindow(); GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : GraphicsContext3D::Attributes(); + + if (attributes.antialias) { + Page* p = canvas->document()->page(); + if (p && !p->settings()->openGLMultisamplingEnabled()) + attributes.antialias = false; + } + RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, hostWindow)); if (!context) { canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context.")); return 0; } - + return new WebGLRenderingContext(canvas, context, attributes); } @@ -416,6 +433,8 @@ void WebGLRenderingContext::initializeNewContext() m_context->reshape(canvas()->width(), canvas()->height()); m_context->viewport(0, 0, canvas()->width(), canvas()->height()); + + m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this))); } void WebGLRenderingContext::setupFlags() @@ -437,6 +456,7 @@ void WebGLRenderingContext::setupFlags() WebGLRenderingContext::~WebGLRenderingContext() { detachAndRemoveAllObjects(); + m_context->setContextLostCallback(0); } void WebGLRenderingContext::markContextChanged() @@ -487,7 +507,24 @@ void WebGLRenderingContext::reshape(int width, int height) unsigned int WebGLRenderingContext::sizeInBytes(GC3Denum type) { - return m_context->sizeInBytes(type); + switch (type) { + case GraphicsContext3D::BYTE: + return sizeof(GC3Dbyte); + case GraphicsContext3D::UNSIGNED_BYTE: + return sizeof(GC3Dubyte); + case GraphicsContext3D::SHORT: + return sizeof(GC3Dshort); + case GraphicsContext3D::UNSIGNED_SHORT: + return sizeof(GC3Dushort); + case GraphicsContext3D::INT: + return sizeof(GC3Dint); + case GraphicsContext3D::UNSIGNED_INT: + return sizeof(GC3Duint); + case GraphicsContext3D::FLOAT: + return sizeof(GC3Dfloat); + } + ASSERT_NOT_REACHED(); + return 0; } void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec) @@ -529,20 +566,33 @@ void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint i cleanupAfterGraphicsCall(false); } +bool WebGLRenderingContext::checkObjectToBeBound(WebGLObject* object, bool& deleted) +{ + deleted = false; + if (isContextLost()) + return false; + if (object) { + if (object->context() != this) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return false; + } + deleted = !object->object(); + } + return true; +} + void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost()) + bool deleted; + if (!checkObjectToBeBound(buffer, deleted)) return; - if (buffer && buffer->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); - return; - } + if (deleted) + buffer = 0; if (buffer && buffer->getTarget() && buffer->getTarget() != target) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } - if (target == GraphicsContext3D::ARRAY_BUFFER) m_boundArrayBuffer = buffer; else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER) @@ -558,16 +608,14 @@ void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, Exc cleanupAfterGraphicsCall(false); } - void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* buffer, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost()) - return; - if (buffer && buffer->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + bool deleted; + if (!checkObjectToBeBound(buffer, deleted)) return; - } + if (deleted) + buffer = 0; if (target != GraphicsContext3D::FRAMEBUFFER) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return; @@ -582,12 +630,11 @@ void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* b void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost()) + bool deleted; + if (!checkObjectToBeBound(renderBuffer, deleted)) return; - if (renderBuffer && renderBuffer->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); - return; - } + if (deleted) + renderBuffer = 0; if (target != GraphicsContext3D::RENDERBUFFER) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return; @@ -599,13 +646,15 @@ void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* cleanupAfterGraphicsCall(false); } - void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost()) + bool deleted; + if (!checkObjectToBeBound(texture, deleted)) return; - if (texture && texture->context() != this) { + if (deleted) + texture = 0; + if (texture && texture->getTarget() && texture->getTarget() != target) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } @@ -667,7 +716,7 @@ void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor) return; m_context->blendFunc(sfactor, dfactor); cleanupAfterGraphicsCall(false); -} +} void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha) { @@ -685,6 +734,10 @@ void WebGLRenderingContext::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3De WebGLBuffer* buffer = validateBufferDataParameters(target, usage); if (!buffer) return; + if (size < 0) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + return; + } if (!isErrorGeneratedOnOutOfBoundsAccesses()) { if (!buffer->associateBufferData(size)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); @@ -750,6 +803,10 @@ void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, Ar WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW); if (!buffer) return; + if (offset < 0) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + return; + } if (!data) return; if (!isErrorGeneratedOnOutOfBoundsAccesses()) { @@ -771,6 +828,10 @@ void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, Ar WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW); if (!buffer) return; + if (offset < 0) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + return; + } if (!data) return; if (!isErrorGeneratedOnOutOfBoundsAccesses()) { @@ -972,7 +1033,7 @@ PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer() addObject(o.get()); return o; } - + PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer() { if (isContextLost()) @@ -1018,7 +1079,7 @@ PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(GC3Denum type, Excep m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return 0; } - + RefPtr<WebGLShader> o = WebGLShader::create(this, type); addObject(o.get()); return o; @@ -1032,13 +1093,27 @@ void WebGLRenderingContext::cullFace(GC3Denum mode) cleanupAfterGraphicsCall(false); } +bool WebGLRenderingContext::deleteObject(WebGLObject* object) +{ + if (isContextLost() || !object) + return false; + if (object->context() != this) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return false; + } + if (object->object()) + object->deleteObject(); + return true; +} + void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer) { - if (isContextLost() || !buffer) + if (!deleteObject(buffer)) return; - - buffer->deleteObject(); - + if (m_boundArrayBuffer == buffer) + m_boundArrayBuffer = 0; + if (m_boundElementArrayBuffer == buffer) + m_boundElementArrayBuffer = 0; if (!isGLES2Compliant()) { VertexAttribState& state = m_vertexAttribState[0]; if (buffer == state.bufferBinding) { @@ -1056,54 +1131,47 @@ void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer) void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer) { - if (isContextLost() || !framebuffer) + if (!deleteObject(framebuffer)) return; if (framebuffer == m_framebufferBinding) { m_framebufferBinding = 0; // Have to call bindFramebuffer here to bind back to internal fbo. m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0); } - framebuffer->deleteObject(); } void WebGLRenderingContext::deleteProgram(WebGLProgram* program) { - if (isContextLost() || !program) - return; - if (program->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); - return; - } - if (!program->object()) - return; - program->deleteObject(); + deleteObject(program); + // We don't reset m_currentProgram to 0 here because the deletion of the + // current program is delayed. } void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer) { - if (isContextLost() || !renderbuffer) + if (!deleteObject(renderbuffer)) return; if (renderbuffer == m_renderbufferBinding) m_renderbufferBinding = 0; - renderbuffer->deleteObject(); if (m_framebufferBinding) m_framebufferBinding->removeAttachment(renderbuffer); } void WebGLRenderingContext::deleteShader(WebGLShader* shader) { - if (isContextLost() || !shader) - return; - - shader->deleteObject(); + deleteObject(shader); } void WebGLRenderingContext::deleteTexture(WebGLTexture* texture) { - if (isContextLost() || !texture) + if (!deleteObject(texture)) return; - - texture->deleteObject(); + for (size_t i = 0; i < m_textureUnits.size(); ++i) { + if (texture == m_textureUnits[i].m_texture2DBinding) + m_textureUnits[i].m_texture2DBinding = 0; + if (texture == m_textureUnits[i].m_textureCubeMapBinding) + m_textureUnits[i].m_textureCubeMapBinding = 0; + } if (m_framebufferBinding) m_framebufferBinding->removeAttachment(texture); } @@ -1150,7 +1218,6 @@ void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* sha cleanupAfterGraphicsCall(false); } - void WebGLRenderingContext::disable(GC3Denum cap) { if (isContextLost() || !validateCapability(cap)) @@ -1168,7 +1235,7 @@ void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index, ExceptionCo m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; } - + if (index < m_vertexAttribState.size()) m_vertexAttribState[index].enabled = false; @@ -1291,8 +1358,8 @@ bool WebGLRenderingContext::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum lastIndex = *p; ++p; } - } - + } + // Then set the last index in the index array and make sure it is valid. numElementsRequired = lastIndex + 1; return numElementsRequired > 0; @@ -1336,10 +1403,10 @@ bool WebGLRenderingContext::validateRenderingState(int numElementsRequired) } } } - + if (smallestNumElements == INT_MAX) smallestNumElements = 0; - + return numElementsRequired <= smallestNumElements; } @@ -1435,6 +1502,11 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu if (!count) return; + if (!m_boundElementArrayBuffer) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } + int numElements = 0; if (!isErrorGeneratedOnOutOfBoundsAccesses()) { // Ensure we have a valid rendering state @@ -1495,12 +1567,12 @@ void WebGLRenderingContext::enableVertexAttribArray(GC3Duint index, ExceptionCod m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; } - + if (index >= m_vertexAttribState.size()) m_vertexAttribState.resize(index + 1); - + m_vertexAttribState[index].enabled = true; - + m_context->enableVertexAttribArray(index); cleanupAfterGraphicsCall(false); } @@ -1513,7 +1585,6 @@ void WebGLRenderingContext::finish() cleanupAfterGraphicsCall(true); } - void WebGLRenderingContext::flush() { if (isContextLost()) @@ -1689,7 +1760,7 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Web GC3Dint numShaders = 0; m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::ATTACHED_SHADERS, &numShaders); if (numShaders) { - OwnArrayPtr<Platform3DObject> shaders(new Platform3DObject[numShaders]); + OwnArrayPtr<Platform3DObject> shaders = adoptArrayPtr(new Platform3DObject[numShaders]); GC3Dsizei count = 0; m_context->getAttachedShaders(objectOrZero(program), numShaders, &count, shaders.get()); if (count != numShaders) @@ -1735,8 +1806,8 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum GC3Dint value = 0; m_context->getBufferParameteriv(target, pname, &value); if (pname == GraphicsContext3D::BUFFER_SIZE) - return WebGLGetInfo(static_cast<long>(value)); - return WebGLGetInfo(static_cast<unsigned long>(value)); + return WebGLGetInfo(value); + return WebGLGetInfo(static_cast<unsigned int>(value)); } PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes() @@ -1809,8 +1880,8 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum t GC3Dint value = 0; m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value); if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) - return WebGLGetInfo(static_cast<unsigned long>(value)); - return WebGLGetInfo(static_cast<long>(value)); + return WebGLGetInfo(static_cast<unsigned int>(value)); + return WebGLGetInfo(value); } WebGLStateRestorer(this, false); @@ -1839,13 +1910,13 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& WebGLStateRestorer(this, false); switch (pname) { case GraphicsContext3D::ACTIVE_TEXTURE: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE: return getWebGLFloatArrayParameter(pname); case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE: return getWebGLFloatArrayParameter(pname); case GraphicsContext3D::ALPHA_BITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::ARRAY_BUFFER_BINDING: return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer)); case GraphicsContext3D::BLEND: @@ -1853,19 +1924,19 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& case GraphicsContext3D::BLEND_COLOR: return getWebGLFloatArrayParameter(pname); case GraphicsContext3D::BLEND_DST_ALPHA: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::BLEND_DST_RGB: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::BLEND_EQUATION_ALPHA: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::BLEND_EQUATION_RGB: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::BLEND_SRC_ALPHA: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::BLEND_SRC_RGB: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::BLUE_BITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::COLOR_CLEAR_VALUE: return getWebGLFloatArrayParameter(pname); case GraphicsContext3D::COLOR_WRITEMASK: @@ -1876,15 +1947,15 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& case GraphicsContext3D::CULL_FACE: return getBooleanParameter(pname); case GraphicsContext3D::CULL_FACE_MODE: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::CURRENT_PROGRAM: return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram)); case GraphicsContext3D::DEPTH_BITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::DEPTH_CLEAR_VALUE: return getFloatParameter(pname); case GraphicsContext3D::DEPTH_FUNC: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::DEPTH_RANGE: return getWebGLFloatArrayParameter(pname); case GraphicsContext3D::DEPTH_TEST: @@ -1898,43 +1969,43 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& case GraphicsContext3D::FRAMEBUFFER_BINDING: return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding)); case GraphicsContext3D::FRONT_FACE: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::GENERATE_MIPMAP_HINT: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::GREEN_BITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::LINE_WIDTH: return getFloatParameter(pname); case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_RENDERBUFFER_SIZE: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_TEXTURE_SIZE: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_VARYING_VECTORS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_VERTEX_ATTRIBS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::MAX_VIEWPORT_DIMS: return getWebGLIntArrayParameter(pname); case GraphicsContext3D::NUM_COMPRESSED_TEXTURE_FORMATS: // WebGL 1.0 specifies that there are no compressed texture formats. - return WebGLGetInfo(static_cast<long>(0)); + return WebGLGetInfo(static_cast<int>(0)); case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS: // FIXME: should we always return 0 for this? - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::PACK_ALIGNMENT: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::POLYGON_OFFSET_FACTOR: return getFloatParameter(pname); case GraphicsContext3D::POLYGON_OFFSET_FILL: @@ -1942,19 +2013,19 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& case GraphicsContext3D::POLYGON_OFFSET_UNITS: return getFloatParameter(pname); case GraphicsContext3D::RED_BITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::RENDERBUFFER_BINDING: return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding)); case GraphicsContext3D::RENDERER: return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER)); case GraphicsContext3D::SAMPLE_BUFFERS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::SAMPLE_COVERAGE_INVERT: return getBooleanParameter(pname); case GraphicsContext3D::SAMPLE_COVERAGE_VALUE: return getFloatParameter(pname); case GraphicsContext3D::SAMPLES: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::SCISSOR_BOX: return getWebGLIntArrayParameter(pname); case GraphicsContext3D::SCISSOR_TEST: @@ -1962,54 +2033,53 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& case GraphicsContext3D::SHADING_LANGUAGE_VERSION: return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")"); case GraphicsContext3D::STENCIL_BACK_FAIL: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_BACK_FUNC: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_BACK_REF: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::STENCIL_BACK_VALUE_MASK: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_BACK_WRITEMASK: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_BITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::STENCIL_CLEAR_VALUE: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::STENCIL_FAIL: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_FUNC: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_REF: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::STENCIL_TEST: return getBooleanParameter(pname); case GraphicsContext3D::STENCIL_VALUE_MASK: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::STENCIL_WRITEMASK: - return getUnsignedLongParameter(pname); + return getUnsignedIntParameter(pname); case GraphicsContext3D::SUBPIXEL_BITS: - return getLongParameter(pname); + return getIntParameter(pname); case GraphicsContext3D::TEXTURE_BINDING_2D: return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding)); case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP: return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding)); case GraphicsContext3D::UNPACK_ALIGNMENT: - // FIXME: should this be "long" in the spec? return getIntParameter(pname); case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL: return WebGLGetInfo(m_unpackFlipY); case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL: return WebGLGetInfo(m_unpackPremultiplyAlpha); case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL: - return WebGLGetInfo(static_cast<unsigned long>(m_unpackColorspaceConversion)); + return WebGLGetInfo(m_unpackColorspaceConversion); case GraphicsContext3D::VENDOR: return WebGLGetInfo("Webkit (" + m_context->getString(GraphicsContext3D::VENDOR) + ")"); case GraphicsContext3D::VERSION: @@ -2018,7 +2088,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& return getWebGLIntArrayParameter(pname); case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives if (m_oesStandardDerivatives) - return getUnsignedLongParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES); + return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES); m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); default: @@ -2043,14 +2113,11 @@ WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, G return WebGLGetInfo(static_cast<bool>(value)); case GraphicsContext3D::LINK_STATUS: return WebGLGetInfo(program->getLinkStatus()); - case GraphicsContext3D::INFO_LOG_LENGTH: case GraphicsContext3D::ATTACHED_SHADERS: case GraphicsContext3D::ACTIVE_ATTRIBUTES: - case GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH: case GraphicsContext3D::ACTIVE_UNIFORMS: - case GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH: m_context->getProgramiv(objectOrZero(program), pname, &value); - return WebGLGetInfo(static_cast<long>(value)); + return WebGLGetInfo(value); default: m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); @@ -2085,13 +2152,13 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC if (m_renderbufferBinding->getInternalFormat() == GraphicsContext3D::DEPTH_STENCIL && !m_renderbufferBinding->isValid()) { ASSERT(!isDepthStencilSupported()); - long value = 0; + int value = 0; switch (pname) { case GraphicsContext3D::RENDERBUFFER_WIDTH: - value = static_cast<long>(m_renderbufferBinding->getWidth()); + value = m_renderbufferBinding->getWidth(); break; case GraphicsContext3D::RENDERBUFFER_HEIGHT: - value = static_cast<long>(m_renderbufferBinding->getHeight()); + value = m_renderbufferBinding->getHeight(); break; case GraphicsContext3D::RENDERBUFFER_RED_SIZE: case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE: @@ -2106,7 +2173,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC value = 8; break; case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT: - return WebGLGetInfo(static_cast<unsigned long>(m_renderbufferBinding->getInternalFormat())); + return WebGLGetInfo(m_renderbufferBinding->getInternalFormat()); default: m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); @@ -2126,9 +2193,9 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE: case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE: m_context->getRenderbufferParameteriv(target, pname, &value); - return WebGLGetInfo(static_cast<long>(value)); + return WebGLGetInfo(value); case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT: - return WebGLGetInfo(static_cast<unsigned long>(m_renderbufferBinding->getInternalFormat())); + return WebGLGetInfo(m_renderbufferBinding->getInternalFormat()); default: m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); @@ -2150,11 +2217,7 @@ WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3D return WebGLGetInfo(static_cast<bool>(value)); case GraphicsContext3D::SHADER_TYPE: m_context->getShaderiv(objectOrZero(shader), pname, &value); - return WebGLGetInfo(static_cast<unsigned long>(value)); - case GraphicsContext3D::INFO_LOG_LENGTH: - case GraphicsContext3D::SHADER_SOURCE_LENGTH: - m_context->getShaderiv(objectOrZero(shader), pname, &value); - return WebGLGetInfo(static_cast<long>(value)); + return WebGLGetInfo(static_cast<unsigned int>(value)); default: m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); @@ -2179,8 +2242,7 @@ String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode return String(); if (!validateWebGLObject(shader)) return ""; - WebGLStateRestorer(this, false); - return m_context->getShaderSource(objectOrZero(shader)); + return shader->getSource(); } Vector<String> WebGLRenderingContext::getSupportedExtensions() @@ -2210,7 +2272,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn case GraphicsContext3D::TEXTURE_WRAP_S: case GraphicsContext3D::TEXTURE_WRAP_T: m_context->getTexParameteriv(target, pname, &value); - return WebGLGetInfo(static_cast<unsigned long>(value)); + return WebGLGetInfo(static_cast<unsigned int>(value)); default: m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); @@ -2227,7 +2289,7 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG return WebGLGetInfo(); } GC3Dint location = uniformLocation->location(); - + WebGLStateRestorer(this, false); // FIXME: make this more efficient using WebGLUniformLocation and caching types in it GC3Dint activeUniforms = 0; @@ -2314,9 +2376,13 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG baseType = GraphicsContext3D::FLOAT; length = 16; break; + case GraphicsContext3D::SAMPLER_2D: + case GraphicsContext3D::SAMPLER_CUBE: + baseType = GraphicsContext3D::INT; + length = 1; + break; default: // Can't handle this type - // FIXME: what to do about samplers? m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return WebGLGetInfo(); } @@ -2332,7 +2398,7 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG GC3Dint value[4] = {0}; m_context->getUniformiv(objectOrZero(program), location, value); if (length == 1) - return WebGLGetInfo(static_cast<long>(value[0])); + return WebGLGetInfo(value[0]); return WebGLGetInfo(Int32Array::create(value, length)); } case GraphicsContext3D::BOOL: { @@ -2399,16 +2465,16 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pna return WebGLGetInfo(m_vertexAttribState[index].normalized); case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE: if (index >= m_vertexAttribState.size()) - return WebGLGetInfo(static_cast<long>(4)); - return WebGLGetInfo(static_cast<long>(m_vertexAttribState[index].size)); + return WebGLGetInfo(static_cast<int>(4)); + return WebGLGetInfo(m_vertexAttribState[index].size); case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE: if (index >= m_vertexAttribState.size()) - return WebGLGetInfo(static_cast<long>(0)); - return WebGLGetInfo(static_cast<long>(m_vertexAttribState[index].originalStride)); + return WebGLGetInfo(static_cast<int>(0)); + return WebGLGetInfo(m_vertexAttribState[index].originalStride); case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE: if (index >= m_vertexAttribState.size()) - return WebGLGetInfo(static_cast<unsigned long>(GraphicsContext3D::FLOAT)); - return WebGLGetInfo(static_cast<unsigned long>(m_vertexAttribState[index].type)); + return WebGLGetInfo(static_cast<unsigned int>(GraphicsContext3D::FLOAT)); + return WebGLGetInfo(m_vertexAttribState[index].type); case GraphicsContext3D::CURRENT_VERTEX_ATTRIB: if (index >= m_vertexAttribState.size()) { float value[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -2760,6 +2826,7 @@ void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& stri String stringWithoutComments = StripComments(string).result(); if (!validateString(stringWithoutComments)) return; + shader->setSource(string); m_context->shaderSource(objectOrZero(shader), stringWithoutComments); cleanupAfterGraphicsCall(false); } @@ -2980,6 +3047,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum m_unpackFlipY, m_unpackPremultiplyAlpha, ec); } +#if ENABLE(VIDEO) PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video) { if (!video || !video->videoWidth() || !video->videoHeight()) { @@ -3010,6 +3078,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum return; texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec); } +#endif void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat paramf, GC3Dint parami, bool isFloat) { @@ -3062,12 +3131,21 @@ void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC ec = 0; if (isContextLost()) return; - if (!validateTexFuncFormatAndType(format, type)) + if (!validateTexFuncParameters(target, level, format, width, height, 0, format, type)) return; - if (!validateTextureBinding(target, true)) + if (!validateSize(xoffset, yoffset)) return; - if (!validateSize(xoffset, yoffset) || !validateSize(width, height)) + WebGLTexture* tex = validateTextureBinding(target, true); + if (!tex) return; + if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + return; + } + if (tex->getInternalFormat(target, level) != format || tex->getType(target, level) != type) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); cleanupAfterGraphicsCall(false); } @@ -3159,6 +3237,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din m_unpackFlipY, m_unpackPremultiplyAlpha, ec); } +#if ENABLE(VIDEO) void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec) { @@ -3170,6 +3249,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din return; texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec); } +#endif void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode& ec) { @@ -3508,13 +3588,12 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (isContextLost()) + bool deleted; + if (!checkObjectToBeBound(program, deleted)) return; - if (program && program->context() != this) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); - return; - } - if (program && program->object() && !program->getLinkStatus()) { + if (deleted) + program = 0; + if (program && !program->getLinkStatus()) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); cleanupAfterGraphicsCall(false); return; @@ -3524,7 +3603,7 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec) m_currentProgram->onDetached(); m_currentProgram = program; m_context->useProgram(objectOrZero(program)); - if (program && program->object()) + if (program) program->onAttached(); } cleanupAfterGraphicsCall(false); @@ -3732,7 +3811,7 @@ void WebGLRenderingContext::detachAndRemoveAllObjects() HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end(); for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) (*it)->detachContext(); - + m_canvasObjects.clear(); } @@ -3814,22 +3893,16 @@ WebGLGetInfo WebGLRenderingContext::getFloatParameter(GC3Denum pname) WebGLGetInfo WebGLRenderingContext::getIntParameter(GC3Denum pname) { - return getLongParameter(pname); -} - -WebGLGetInfo WebGLRenderingContext::getLongParameter(GC3Denum pname) -{ GC3Dint value = 0; m_context->getIntegerv(pname, &value); - return WebGLGetInfo(static_cast<long>(value)); + return WebGLGetInfo(value); } -WebGLGetInfo WebGLRenderingContext::getUnsignedLongParameter(GC3Denum pname) +WebGLGetInfo WebGLRenderingContext::getUnsignedIntParameter(GC3Denum pname) { GC3Dint value = 0; m_context->getIntegerv(pname, &value); - GC3Duint uValue = static_cast<GC3Duint>(value); - return WebGLGetInfo(static_cast<unsigned long>(uValue)); + return WebGLGetInfo(static_cast<unsigned int>(value)); } WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(GC3Denum pname) @@ -4382,7 +4455,7 @@ bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLo m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return false; } - if (size < requiredMinSize) { + if (size < requiredMinSize || (size % requiredMinSize)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return false; } @@ -4518,34 +4591,49 @@ void WebGLRenderingContext::initVertexAttrib0() m_vertexAttrib0BufferValue[1] = 0.0f; m_vertexAttrib0BufferValue[2] = 0.0f; m_vertexAttrib0BufferValue[3] = 1.0f; + m_forceAttrib0BufferRefill = false; + m_vertexAttrib0UsedBefore = false; } bool WebGLRenderingContext::simulateVertexAttrib0(GC3Dsizei numVertex) { const VertexAttribState& state = m_vertexAttribState[0]; - if (state.enabled || !m_currentProgram || !m_currentProgram->object() - || !m_currentProgram->isUsingVertexAttrib0()) + if (!m_currentProgram) return false; + bool usingVertexAttrib0 = m_currentProgram->isUsingVertexAttrib0(); + if (usingVertexAttrib0) + m_vertexAttrib0UsedBefore = true; + if (state.enabled && usingVertexAttrib0) + return false; + if (!usingVertexAttrib0 && !m_vertexAttrib0UsedBefore) + return false; + m_vertexAttrib0UsedBefore = true; m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer->object()); GC3Dsizeiptr bufferDataSize = (numVertex + 1) * 4 * sizeof(GC3Dfloat); - if (bufferDataSize > m_vertexAttrib0BufferSize - || state.value[0] != m_vertexAttrib0BufferValue[0] - || state.value[1] != m_vertexAttrib0BufferValue[1] - || state.value[2] != m_vertexAttrib0BufferValue[2] - || state.value[3] != m_vertexAttrib0BufferValue[3]) { - OwnArrayPtr<GC3Dfloat> bufferData(new GC3Dfloat[(numVertex + 1) * 4]); + if (bufferDataSize > m_vertexAttrib0BufferSize) { + m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferDataSize, 0, GraphicsContext3D::DYNAMIC_DRAW); + m_vertexAttrib0BufferSize = bufferDataSize; + m_forceAttrib0BufferRefill = true; + } + if (usingVertexAttrib0 + && (m_forceAttrib0BufferRefill + || state.value[0] != m_vertexAttrib0BufferValue[0] + || state.value[1] != m_vertexAttrib0BufferValue[1] + || state.value[2] != m_vertexAttrib0BufferValue[2] + || state.value[3] != m_vertexAttrib0BufferValue[3])) { + OwnArrayPtr<GC3Dfloat> bufferData = adoptArrayPtr(new GC3Dfloat[(numVertex + 1) * 4]); for (GC3Dsizei ii = 0; ii < numVertex + 1; ++ii) { bufferData[ii * 4] = state.value[0]; bufferData[ii * 4 + 1] = state.value[1]; bufferData[ii * 4 + 2] = state.value[2]; bufferData[ii * 4 + 3] = state.value[3]; } - m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferDataSize, bufferData.get(), GraphicsContext3D::DYNAMIC_DRAW); - m_vertexAttrib0BufferSize = bufferDataSize; m_vertexAttrib0BufferValue[0] = state.value[0]; m_vertexAttrib0BufferValue[1] = state.value[1]; m_vertexAttrib0BufferValue[2] = state.value[2]; m_vertexAttrib0BufferValue[3] = state.value[3]; + m_forceAttrib0BufferRefill = false; + m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, bufferDataSize, bufferData.get()); } m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, 0, 0, 0); return true; @@ -4588,7 +4676,7 @@ WebGLExtension* WebGLRenderingContext::getExtensionNumber(int i) } WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity) - : m_buffers(new OwnPtr<ImageBuffer>[capacity]) + : m_buffers(adoptArrayPtr(new OwnPtr<ImageBuffer>[capacity])) , m_capacity(capacity) { } @@ -4625,4 +4713,4 @@ void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx) } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h index 01b5438..dd71620 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.h +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h @@ -69,13 +69,13 @@ public: virtual bool isAccelerated() const { return true; } virtual bool paintsIntoCanvasBuffer() const; - void activeTexture(GC3Denum texture, ExceptionCode& ec); - void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode& ec); - void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name, ExceptionCode& ec); - void bindBuffer(GC3Denum target, WebGLBuffer*, ExceptionCode& ec); - void bindFramebuffer(GC3Denum target, WebGLFramebuffer*, ExceptionCode& ec); - void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*, ExceptionCode& ec); - void bindTexture(GC3Denum target, WebGLTexture*, ExceptionCode& ec); + void activeTexture(GC3Denum texture, ExceptionCode&); + void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode&); + void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name, ExceptionCode&); + void bindBuffer(GC3Denum target, WebGLBuffer*, ExceptionCode&); + void bindFramebuffer(GC3Denum target, WebGLFramebuffer*, ExceptionCode&); + void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*, ExceptionCode&); + void bindTexture(GC3Denum target, WebGLTexture*, ExceptionCode&); void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha); void blendEquation(GC3Denum mode); void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha); @@ -94,7 +94,7 @@ public: void clearDepth(GC3Dfloat); void clearStencil(GC3Dint); void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha); - void compileShader(WebGLShader*, ExceptionCode& ec); + void compileShader(WebGLShader*, ExceptionCode&); // void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data); // void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data); @@ -131,8 +131,8 @@ public: void enableVertexAttribArray(GC3Duint index, ExceptionCode&); void finish(); void flush(); - void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*, ExceptionCode& ec); - void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level, ExceptionCode& ec); + void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*, ExceptionCode&); + void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level, ExceptionCode&); void frontFace(GC3Denum mode); void generateMipmap(GC3Denum target); @@ -147,10 +147,10 @@ public: WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&); WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&); WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname, ExceptionCode&); - String getProgramInfoLog(WebGLProgram*, ExceptionCode& ec); + String getProgramInfoLog(WebGLProgram*, ExceptionCode&); WebGLGetInfo getRenderbufferParameter(GC3Denum target, GC3Denum pname, ExceptionCode&); - WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname, ExceptionCode& ec); - String getShaderInfoLog(WebGLShader*, ExceptionCode& ec); + WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname, ExceptionCode&); + String getShaderInfoLog(WebGLShader*, ExceptionCode&); // TBD // void glGetShaderPrecisionFormat (GC3Denum shadertype, GC3Denum precisiontype, GC3Dint* range, GC3Dint* precision); @@ -192,30 +192,34 @@ public: void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, - GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&); + GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&); void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, - GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode&); + GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&); void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, - GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode&); + GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&); void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, - GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode&); + GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&); +#if ENABLE(VIDEO) void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, - GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode&); + GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&); +#endif void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param); void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param); void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, - GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&); + GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&); void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, - GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode&); + GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&); void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, - GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode&); + GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&); void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, - GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode&); + GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&); +#if ENABLE(VIDEO) void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, - GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode&); + GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&); +#endif void uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode&); void uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode&); @@ -334,9 +338,11 @@ public: // If numElements <= 0, we only check if each enabled vertex attribute is bound to a buffer. bool validateRenderingState(int numElements); - bool validateWebGLObject(WebGLObject* object); + bool validateWebGLObject(WebGLObject*); - PassRefPtr<Image> videoFrameToImage(HTMLVideoElement* video); +#if ENABLE(VIDEO) + PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*); +#endif RefPtr<GraphicsContext3D> m_context; @@ -399,6 +405,8 @@ public: RefPtr<WebGLBuffer> m_vertexAttrib0Buffer; long m_vertexAttrib0BufferSize; GC3Dfloat m_vertexAttrib0BufferValue[4]; + bool m_forceAttrib0BufferRefill; + bool m_vertexAttrib0UsedBefore; RefPtr<WebGLProgram> m_currentProgram; RefPtr<WebGLFramebuffer> m_framebufferBinding; @@ -457,20 +465,19 @@ public: RefPtr<WebKitLoseContext> m_webkitLoseContext; // Helpers for getParameter and others - WebGLGetInfo getBooleanParameter(GC3Denum pname); - WebGLGetInfo getBooleanArrayParameter(GC3Denum pname); - WebGLGetInfo getFloatParameter(GC3Denum pname); - WebGLGetInfo getIntParameter(GC3Denum pname); - WebGLGetInfo getLongParameter(GC3Denum pname); - WebGLGetInfo getUnsignedLongParameter(GC3Denum pname); - WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum pname); - WebGLGetInfo getWebGLIntArrayParameter(GC3Denum pname); + WebGLGetInfo getBooleanParameter(GC3Denum); + WebGLGetInfo getBooleanArrayParameter(GC3Denum); + WebGLGetInfo getFloatParameter(GC3Denum); + WebGLGetInfo getIntParameter(GC3Denum); + WebGLGetInfo getUnsignedIntParameter(GC3Denum); + WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum); + WebGLGetInfo getWebGLIntArrayParameter(GC3Denum); void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, void* pixels, ExceptionCode&); void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, - GC3Denum format, GC3Denum type, Image* image, + GC3Denum format, GC3Denum type, Image*, bool flipY, bool premultiplyAlpha, ExceptionCode&); void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, @@ -547,7 +554,7 @@ public: // Helper function to print warnings to console. Currently // used only to warn about use of obsolete functions. - void printWarningToConsole(const String& message); + void printWarningToConsole(const String&); // Helper function to validate input parameters for framebuffer functions. // Generate GL error if parameters are illegal. @@ -563,20 +570,29 @@ public: bool validateCapability(GC3Denum); // Helper function to validate input parameters for uniform functions. - bool validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei mod); - bool validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei mod); - bool validateUniformParameters(const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei mod); - bool validateUniformMatrixParameters(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei mod); - bool validateUniformMatrixParameters(const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei mod); + bool validateUniformParameters(const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod); + bool validateUniformParameters(const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod); + bool validateUniformParameters(const WebGLUniformLocation*, void*, GC3Dsizei size, GC3Dsizei mod); + bool validateUniformMatrixParameters(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod); + bool validateUniformMatrixParameters(const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei size, GC3Dsizei mod); // Helper function to validate parameters for bufferData. // Return the current bound buffer to target, or 0 if parameters are invalid. WebGLBuffer* validateBufferDataParameters(GC3Denum target, GC3Denum usage); // Helper functions for vertexAttribNf{v}. - void vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3); - void vertexAttribfvImpl(GC3Duint index, Float32Array* v, GC3Dsizei expectedSize); - void vertexAttribfvImpl(GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize); + void vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat); + void vertexAttribfvImpl(GC3Duint index, Float32Array*, GC3Dsizei expectedSize); + void vertexAttribfvImpl(GC3Duint index, GC3Dfloat*, GC3Dsizei size, GC3Dsizei expectedSize); + + // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions. + // Return false if caller should return without further processing. + bool deleteObject(WebGLObject*); + + // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram. + // If the object has already been deleted, set deleted to true upon return. + // Return false if caller should return without further processing. + bool checkObjectToBeBound(WebGLObject*, bool& deleted); // Helpers for simulating vertexAttrib0 void initVertexAttrib0(); diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.idl b/Source/WebCore/html/canvas/WebGLRenderingContext.idl index 40b9bb0..7a19814 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.idl +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.idl @@ -26,7 +26,7 @@ module html { interface [ - Conditional=3D_CANVAS, + Conditional=WEBGL, InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443, ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54, CustomMarkFunction, @@ -258,9 +258,7 @@ module html { const unsigned int VALIDATE_STATUS = 0x8B83; const unsigned int ATTACHED_SHADERS = 0x8B85; const unsigned int ACTIVE_UNIFORMS = 0x8B86; - const unsigned int ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87; const unsigned int ACTIVE_ATTRIBUTES = 0x8B89; - const unsigned int ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A; const unsigned int SHADING_LANGUAGE_VERSION = 0x8B8C; const unsigned int CURRENT_PROGRAM = 0x8B8D; @@ -389,8 +387,6 @@ module html { /* Shader Source */ const unsigned int COMPILE_STATUS = 0x8B81; - const unsigned int INFO_LOG_LENGTH = 0x8B84; - const unsigned int SHADER_SOURCE_LENGTH = 0x8B88; const unsigned int SHADER_COMPILER = 0x8DFA; /* Shader Precision-Specified Types */ @@ -613,8 +609,10 @@ module html { in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException); [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException); +#if defined(ENABLE_VIDEO) && ENABLE_VIDEO [StrictTypeChecking] void texImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException); +#endif [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in long width, in long height, @@ -625,8 +623,10 @@ module html { in unsigned long format, in unsigned long type, in HTMLImageElement image) raises (DOMException); [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long format, in unsigned long type, in HTMLCanvasElement canvas) raises (DOMException); +#if defined(ENABLE_VIDEO) && ENABLE_VIDEO [StrictTypeChecking] void texSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long format, in unsigned long type, in HTMLVideoElement video) raises (DOMException); +#endif [StrictTypeChecking] void uniform1f(in WebGLUniformLocation location, in float x) raises(DOMException); [StrictTypeChecking, Custom] void uniform1fv(in WebGLUniformLocation location, in Float32Array v) raises(DOMException); diff --git a/Source/WebCore/html/canvas/WebGLShader.cpp b/Source/WebCore/html/canvas/WebGLShader.cpp index a07023f..59695e4 100644 --- a/Source/WebCore/html/canvas/WebGLShader.cpp +++ b/Source/WebCore/html/canvas/WebGLShader.cpp @@ -25,14 +25,14 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLShader.h" #include "WebGLRenderingContext.h" namespace WebCore { - + PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GC3Denum type) { return adoptRef(new WebGLShader(ctx, type)); @@ -41,6 +41,7 @@ PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GC3Denum WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GC3Denum type) : WebGLObject(ctx) , m_type(type) + , m_source("") { setObject(context()->graphicsContext3D()->createShader(type)); } @@ -52,4 +53,4 @@ void WebGLShader::deleteObjectImpl(Platform3DObject object) } -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLShader.h b/Source/WebCore/html/canvas/WebGLShader.h index 5deaf20..1d7a10c 100644 --- a/Source/WebCore/html/canvas/WebGLShader.h +++ b/Source/WebCore/html/canvas/WebGLShader.h @@ -40,6 +40,9 @@ public: static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GC3Denum); GC3Denum getType() const { return m_type; } + const String& getSource() const { return m_source; } + + void setSource(const String& source) { m_source = source; } private: WebGLShader(WebGLRenderingContext*, GC3Denum); @@ -49,6 +52,7 @@ private: virtual bool isShader() const { return true; } GC3Denum m_type; + String m_source; }; } // namespace WebCore diff --git a/Source/WebCore/html/canvas/WebGLShader.idl b/Source/WebCore/html/canvas/WebGLShader.idl index 45e7f54..21bba65 100644 --- a/Source/WebCore/html/canvas/WebGLShader.idl +++ b/Source/WebCore/html/canvas/WebGLShader.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLShader { + interface [Conditional=WEBGL] WebGLShader { }; } diff --git a/Source/WebCore/html/canvas/WebGLTexture.cpp b/Source/WebCore/html/canvas/WebGLTexture.cpp index a57500f..e8e8bf8 100644 --- a/Source/WebCore/html/canvas/WebGLTexture.cpp +++ b/Source/WebCore/html/canvas/WebGLTexture.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLTexture.h" @@ -33,7 +33,7 @@ #include "WebGLRenderingContext.h" namespace WebCore { - + PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx) { return adoptRef(new WebGLTexture(ctx)); @@ -353,4 +353,4 @@ const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GC3Denum target, GC3Di } -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLTexture.h b/Source/WebCore/html/canvas/WebGLTexture.h index 27eb8ee..6bd1272 100644 --- a/Source/WebCore/html/canvas/WebGLTexture.h +++ b/Source/WebCore/html/canvas/WebGLTexture.h @@ -44,6 +44,8 @@ public: void setParameteri(GC3Denum pname, GC3Dint param); void setParameterf(GC3Denum pname, GC3Dfloat param); + GC3Denum getTarget() const { return m_target; } + int getMinFilter() const { return m_minFilter; } void setLevelInfo(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Denum type); diff --git a/Source/WebCore/html/canvas/WebGLTexture.idl b/Source/WebCore/html/canvas/WebGLTexture.idl index da7e066..d287f35 100644 --- a/Source/WebCore/html/canvas/WebGLTexture.idl +++ b/Source/WebCore/html/canvas/WebGLTexture.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLTexture { + interface [Conditional=WEBGL] WebGLTexture { }; } diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.cpp b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp index a8220b0..1aeddb5 100644 --- a/Source/WebCore/html/canvas/WebGLUniformLocation.cpp +++ b/Source/WebCore/html/canvas/WebGLUniformLocation.cpp @@ -26,12 +26,12 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebGLUniformLocation.h" namespace WebCore { - + PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GC3Dint location) { return adoptRef(new WebGLUniformLocation(program, location)); @@ -64,4 +64,4 @@ GC3Dint WebGLUniformLocation::location() const } -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.h b/Source/WebCore/html/canvas/WebGLUniformLocation.h index 3ef9fa8..6e05c7a 100644 --- a/Source/WebCore/html/canvas/WebGLUniformLocation.h +++ b/Source/WebCore/html/canvas/WebGLUniformLocation.h @@ -39,14 +39,14 @@ class WebGLUniformLocation : public RefCounted<WebGLUniformLocation> { public: virtual ~WebGLUniformLocation() { } - static PassRefPtr<WebGLUniformLocation> create(WebGLProgram* program, GC3Dint location); + static PassRefPtr<WebGLUniformLocation> create(WebGLProgram*, GC3Dint location); WebGLProgram* program() const; GC3Dint location() const; protected: - WebGLUniformLocation(WebGLProgram* program, GC3Dint location); + WebGLUniformLocation(WebGLProgram*, GC3Dint location); private: RefPtr<WebGLProgram> m_program; diff --git a/Source/WebCore/html/canvas/WebGLUniformLocation.idl b/Source/WebCore/html/canvas/WebGLUniformLocation.idl index b080241..5cd6404 100644 --- a/Source/WebCore/html/canvas/WebGLUniformLocation.idl +++ b/Source/WebCore/html/canvas/WebGLUniformLocation.idl @@ -25,6 +25,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLUniformLocation { + interface [Conditional=WEBGL] WebGLUniformLocation { }; } diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.cpp b/Source/WebCore/html/canvas/WebKitLoseContext.cpp index c7dd078..05e82f4 100644 --- a/Source/WebCore/html/canvas/WebKitLoseContext.cpp +++ b/Source/WebCore/html/canvas/WebKitLoseContext.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if ENABLE(3D_CANVAS) +#if ENABLE(WEBGL) #include "WebKitLoseContext.h" @@ -60,4 +60,4 @@ void WebKitLoseContext::loseContext() } // namespace WebCore -#endif // ENABLE(3D_CANVAS) +#endif // ENABLE(WEBGL) diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.idl b/Source/WebCore/html/canvas/WebKitLoseContext.idl index 741aa4a..83fc909 100644 --- a/Source/WebCore/html/canvas/WebKitLoseContext.idl +++ b/Source/WebCore/html/canvas/WebKitLoseContext.idl @@ -24,7 +24,7 @@ */ module html { - interface [Conditional=3D_CANVAS, OmitConstructor] WebKitLoseContext { + interface [Conditional=WEBGL, OmitConstructor] WebKitLoseContext { [StrictTypeChecking] void loseContext(); }; } diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.cpp b/Source/WebCore/html/parser/HTMLConstructionSite.cpp index c46b9b9..a026ef9 100644 --- a/Source/WebCore/html/parser/HTMLConstructionSite.cpp +++ b/Source/WebCore/html/parser/HTMLConstructionSite.cpp @@ -130,10 +130,20 @@ void HTMLConstructionSite::attachAtSite(const AttachmentSite& site, PassRefPtr<N child->attach(); } -HTMLConstructionSite::HTMLConstructionSite(Document* document, FragmentScriptingPermission scriptingPermission, bool isParsingFragment) +HTMLConstructionSite::HTMLConstructionSite(Document* document) : m_document(document) + , m_attachmentRoot(document) + , m_fragmentScriptingPermission(FragmentScriptingAllowed) + , m_isParsingFragment(false) + , m_redirectAttachToFosterParent(false) +{ +} + +HTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment, FragmentScriptingPermission scriptingPermission) + : m_document(fragment->document()) + , m_attachmentRoot(fragment) , m_fragmentScriptingPermission(scriptingPermission) - , m_isParsingFragment(isParsingFragment) + , m_isParsingFragment(true) , m_redirectAttachToFosterParent(false) { } @@ -145,6 +155,7 @@ HTMLConstructionSite::~HTMLConstructionSite() void HTMLConstructionSite::detach() { m_document = 0; + m_attachmentRoot = 0; } void HTMLConstructionSite::setForm(HTMLFormElement* form) @@ -170,7 +181,7 @@ void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken& tok { RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(m_document); element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission); - m_openElements.pushHTMLHtmlElement(attach<Element>(m_document, element.get())); + m_openElements.pushHTMLHtmlElement(attach<Element>(m_attachmentRoot, element.get())); #if ENABLE(OFFLINE_WEB_APPLICATIONS) element->insertedByParser(); #endif @@ -205,7 +216,16 @@ void HTMLConstructionSite::insertHTMLBodyStartTagInBody(AtomicHTMLToken& token) void HTMLConstructionSite::insertDoctype(AtomicHTMLToken& token) { ASSERT(token.type() == HTMLToken::DOCTYPE); - attach(m_document, DocumentType::create(m_document, token.name(), String::adopt(token.publicIdentifier()), String::adopt(token.systemIdentifier()))); + attach(m_attachmentRoot, DocumentType::create(m_document, token.name(), String::adopt(token.publicIdentifier()), String::adopt(token.systemIdentifier()))); + + // DOCTYPE nodes are only processed when parsing fragments w/o contextElements, which + // never occurs. However, if we ever chose to support such, this code is subtly wrong, + // because context-less fragments can determine their own quirks mode, and thus change + // parsing rules (like <p> inside <table>). For now we ASSERT that we never hit this code + // in a fragment, as changing the owning document's compatibility mode would be wrong. + ASSERT(!m_isParsingFragment); + if (m_isParsingFragment) + return; if (token.forceQuirks()) m_document->setCompatibilityMode(Document::QuirksMode); @@ -222,7 +242,7 @@ void HTMLConstructionSite::insertComment(AtomicHTMLToken& token) void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken& token) { ASSERT(token.type() == HTMLToken::Comment); - attach(m_document, Comment::create(m_document, token.comment())); + attach(m_attachmentRoot, Comment::create(m_document, token.comment())); } void HTMLConstructionSite::insertCommentOnHTMLHtmlElement(AtomicHTMLToken& token) diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.h b/Source/WebCore/html/parser/HTMLConstructionSite.h index 5a4a65d..0298503 100644 --- a/Source/WebCore/html/parser/HTMLConstructionSite.h +++ b/Source/WebCore/html/parser/HTMLConstructionSite.h @@ -43,7 +43,8 @@ class Element; class HTMLConstructionSite { WTF_MAKE_NONCOPYABLE(HTMLConstructionSite); public: - HTMLConstructionSite(Document*, FragmentScriptingPermission, bool isParsingFragment); + HTMLConstructionSite(Document*); + HTMLConstructionSite(DocumentFragment*, FragmentScriptingPermission); ~HTMLConstructionSite(); void detach(); @@ -130,6 +131,12 @@ private: void dispatchDocumentElementAvailableIfNeeded(); Document* m_document; + + // This is the root ContainerNode to which the parser attaches all newly + // constructed nodes. It points to a DocumentFragment when parsing fragments + // and a Document in all other cases. + ContainerNode* m_attachmentRoot; + RefPtr<Element> m_head; RefPtr<HTMLFormElement> m_form; mutable HTMLElementStack m_openElements; diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp index 93e1309..2fe9486 100644 --- a/Source/WebCore/html/parser/HTMLDocumentParser.cpp +++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp @@ -39,7 +39,6 @@ #include "InspectorInstrumentation.h" #include "NestingLevelIncrementer.h" #include "Settings.h" -#include "XSSAuditor.h" #include <wtf/CurrentTime.h> #ifdef ANDROID_INSTRUMENT @@ -85,6 +84,7 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors , m_scriptRunner(HTMLScriptRunner::create(document, this)) , m_treeBuilder(HTMLTreeBuilder::create(this, document, reportErrors, usePreHTML5ParserQuirks(document))) , m_parserScheduler(HTMLParserScheduler::create(this)) + , m_xssFilter(this) , m_endWasDelayed(false) , m_writeNestingLevel(0) { @@ -96,6 +96,7 @@ HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont : ScriptableDocumentParser(fragment->document()) , m_tokenizer(HTMLTokenizer::create(usePreHTML5ParserQuirks(fragment->document()))) , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks(fragment->document()))) + , m_xssFilter(this) , m_endWasDelayed(false) , m_writeNestingLevel(0) { @@ -230,8 +231,13 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) if (!m_treeBuilder->isParsingFragment() && document()->frame() && document()->frame()->navigationScheduler()->locationChangePending()) break; + + m_sourceTracker.start(m_input, m_token); if (!m_tokenizer->nextToken(m_input.current(), m_token)) break; + m_sourceTracker.end(m_input, m_token); + + m_xssFilter.filterToken(m_token); m_treeBuilder->constructTreeFromToken(m_token); m_token.clear(); @@ -274,7 +280,12 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) bool HTMLDocumentParser::hasInsertionPoint() { - return m_input.hasInsertionPoint(); + // FIXME: The wasCreatedByScript() branch here might not be fully correct. + // Our model of the EOF character differs slightly from the one in + // the spec because our treatment is uniform between network-sourced + // and script-sourced input streams whereas the spec treats them + // differently. + return m_input.hasInsertionPoint() || (wasCreatedByScript() && !m_input.haveSeenEndOfFile()); } void HTMLDocumentParser::insert(const SegmentedString& source) @@ -414,6 +425,11 @@ bool HTMLDocumentParser::inScriptExecution() const return m_scriptRunner->isExecutingScript(); } +String HTMLDocumentParser::sourceForToken(const HTMLToken& token) +{ + return m_sourceTracker.sourceForToken(token); +} + int HTMLDocumentParser::lineNumber() const { return m_tokenizer->lineNumber(); @@ -460,9 +476,7 @@ void HTMLDocumentParser::stopWatchingForLoad(CachedResource* cachedScript) bool HTMLDocumentParser::shouldLoadExternalScriptFromSrc(const AtomicString& srcValue) { - if (!xssAuditor()) - return true; - return xssAuditor()->canLoadExternalScriptFromSrc(srcValue); + return document()->contentSecurityPolicy()->canLoadExternalScriptFromSrc(srcValue); } void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource) diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.h b/Source/WebCore/html/parser/HTMLDocumentParser.h index f925269..be2ca1b 100644 --- a/Source/WebCore/html/parser/HTMLDocumentParser.h +++ b/Source/WebCore/html/parser/HTMLDocumentParser.h @@ -30,10 +30,12 @@ #include "FragmentScriptingPermission.h" #include "HTMLInputStream.h" #include "HTMLScriptRunnerHost.h" +#include "HTMLSourceTracker.h" #include "HTMLToken.h" #include "ScriptableDocumentParser.h" #include "SegmentedString.h" #include "Timer.h" +#include "XSSFilter.h" #include <wtf/OwnPtr.h> namespace WebCore { @@ -71,8 +73,11 @@ public: static bool usePreHTML5ParserQuirks(Document*); HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); } + String sourceForToken(const HTMLToken&); virtual TextPosition0 textPosition() const; + virtual int lineNumber() const; + virtual void suspendScheduledTasks(); virtual void resumeScheduledTasks(); @@ -97,7 +102,6 @@ private: virtual bool isWaitingForScripts() const; virtual bool isExecutingScript() const; virtual void executeScriptsWaitingForStylesheets(); - virtual int lineNumber() const; // HTMLScriptRunnerHost virtual void watchForLoad(CachedResource*); @@ -141,6 +145,8 @@ private: OwnPtr<HTMLTreeBuilder> m_treeBuilder; OwnPtr<HTMLPreloadScanner> m_preloadScanner; OwnPtr<HTMLParserScheduler> m_parserScheduler; + HTMLSourceTracker m_sourceTracker; + XSSFilter m_xssFilter; bool m_endWasDelayed; unsigned m_writeNestingLevel; diff --git a/Source/WebCore/html/parser/HTMLInputStream.h b/Source/WebCore/html/parser/HTMLInputStream.h index d95ec31..512ae88 100644 --- a/Source/WebCore/html/parser/HTMLInputStream.h +++ b/Source/WebCore/html/parser/HTMLInputStream.h @@ -67,17 +67,7 @@ public: bool hasInsertionPoint() const { - if (&m_first != m_last) - return true; - if (!haveSeenEndOfFile()) { - // FIXME: Somehow we need to understand the difference between - // input streams that are coming off the network and streams that - // were created with document.open(). In the later case, we always - // have an isertion point at the end of the stream until someone - // calls document.close(). - return true; - } - return false; + return &m_first != m_last; } void markEndOfFile() diff --git a/Source/WebCore/html/parser/HTMLParserIdioms.cpp b/Source/WebCore/html/parser/HTMLParserIdioms.cpp index 91ff8d3..2be6af9 100644 --- a/Source/WebCore/html/parser/HTMLParserIdioms.cpp +++ b/Source/WebCore/html/parser/HTMLParserIdioms.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "HTMLParserIdioms.h" +#include <limits> #include <wtf/MathExtras.h> #include <wtf/dtoa.h> #include <wtf/text/AtomicString.h> @@ -85,7 +86,7 @@ bool parseToDoubleForNumberType(const String& string, double* result) // Numbers are considered finite IEEE 754 single-precision floating point values. // See HTML5 2.4.4.3 `Real numbers.' - if (-FLT_MAX > value || value > FLT_MAX) + if (-std::numeric_limits<float>::max() > value || value > std::numeric_limits<float>::max()) return false; if (result) { diff --git a/Source/WebCore/html/parser/HTMLScriptRunner.cpp b/Source/WebCore/html/parser/HTMLScriptRunner.cpp index 2fe1d30..c99858d 100644 --- a/Source/WebCore/html/parser/HTMLScriptRunner.cpp +++ b/Source/WebCore/html/parser/HTMLScriptRunner.cpp @@ -264,6 +264,7 @@ bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Elemen ASSERT(!pendingScript.element()); const AtomicString& srcValue = script->getAttribute(srcAttr); // Allow the host to disllow script loads (using the XSSAuditor, etc.) + // FIXME: this check should be performed on the final URL in a redirect chain. if (!m_host->shouldLoadExternalScriptFromSrc(srcValue)) return false; // FIXME: We need to resolve the url relative to the element. diff --git a/Source/WebCore/html/parser/HTMLSourceTracker.cpp b/Source/WebCore/html/parser/HTMLSourceTracker.cpp new file mode 100644 index 0000000..cf43105 --- /dev/null +++ b/Source/WebCore/html/parser/HTMLSourceTracker.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Adam Barth. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 "HTMLSourceTracker.h" + +namespace WebCore { + +HTMLSourceTracker::HTMLSourceTracker() +{ +} + +void HTMLSourceTracker::start(const HTMLInputStream& input, HTMLToken& token) +{ + m_sourceFromPreviousSegments = token.type() == HTMLToken::Uninitialized ? String() : m_sourceFromPreviousSegments + m_source.toString(); + m_source = input.current(); + token.setBaseOffset(input.current().numberOfCharactersConsumed() - m_sourceFromPreviousSegments.length()); +} + +void HTMLSourceTracker::end(const HTMLInputStream& input, HTMLToken& token) +{ + m_cachedSourceForToken = String(); + // FIXME: This work should really be done by the HTMLTokenizer. + token.end(input.current().numberOfCharactersConsumed()); +} + +String HTMLSourceTracker::sourceForToken(const HTMLToken& token) +{ + if (token.type() == HTMLToken::EndOfFile) + return String(); // Hides the null character we use to mark the end of file. + + if (!m_cachedSourceForToken.isEmpty()) + return m_cachedSourceForToken; + + ASSERT(!token.startIndex()); + UChar* data = 0; + int length = token.endIndex() - token.startIndex() - m_sourceFromPreviousSegments.length(); + String source = String::createUninitialized(length, data); + for (int i = 0; i < length; ++i) { + data[i] = *m_source; + m_source.advance(); + } + m_cachedSourceForToken = m_sourceFromPreviousSegments + source; + return m_cachedSourceForToken; +} + +} diff --git a/Source/WebCore/html/parser/HTMLSourceTracker.h b/Source/WebCore/html/parser/HTMLSourceTracker.h new file mode 100644 index 0000000..17ae191 --- /dev/null +++ b/Source/WebCore/html/parser/HTMLSourceTracker.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 Adam Barth. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 HTMLSourceTracker_h +#define HTMLSourceTracker_h + +#include "HTMLInputStream.h" +#include "HTMLToken.h" + +namespace WebCore { + +class HTMLSourceTracker { + WTF_MAKE_NONCOPYABLE(HTMLSourceTracker); +public: + HTMLSourceTracker(); + + // FIXME: Once we move "end" into HTMLTokenizer, rename "start" to + // something that makes it obvious that this method can be called multiple + // times. + void start(const HTMLInputStream&, HTMLToken&); + void end(const HTMLInputStream&, HTMLToken&); + + String sourceForToken(const HTMLToken&); + +private: + String m_sourceFromPreviousSegments; + SegmentedString m_source; + String m_cachedSourceForToken; +}; + +} + +#endif diff --git a/Source/WebCore/html/parser/HTMLToken.h b/Source/WebCore/html/parser/HTMLToken.h index 1cbc151..aa16ab2 100644 --- a/Source/WebCore/html/parser/HTMLToken.h +++ b/Source/WebCore/html/parser/HTMLToken.h @@ -64,20 +64,26 @@ public: HTMLToken() { clear(); } - void clear(int startIndex = 0) + void clear() { m_type = Uninitialized; - m_range.m_start = startIndex; - m_range.m_end = startIndex; + m_range.m_start = 0; + m_range.m_end = 0; + m_baseOffset = 0; m_data.clear(); } int startIndex() const { return m_range.m_start; } int endIndex() const { return m_range.m_end; } - void end(int endIndex) + void setBaseOffset(int offset) { - m_range.m_end = endIndex; + m_baseOffset = offset; + } + + void end(int endOffset) + { + m_range.m_end = endOffset - m_baseOffset; } void makeEndOfFile() @@ -172,29 +178,30 @@ public: #endif } - void beginAttributeName(int index) + void beginAttributeName(int offset) { - m_currentAttribute->m_nameRange.m_start = index; + m_currentAttribute->m_nameRange.m_start = offset - m_baseOffset; } - void endAttributeName(int index) + void endAttributeName(int offset) { + int index = offset - m_baseOffset; m_currentAttribute->m_nameRange.m_end = index; m_currentAttribute->m_valueRange.m_start = index; m_currentAttribute->m_valueRange.m_end = index; } - void beginAttributeValue(int index) + void beginAttributeValue(int offset) { - m_currentAttribute->m_valueRange.m_start = index; + m_currentAttribute->m_valueRange.m_start = offset - m_baseOffset; #ifndef NDEBUG m_currentAttribute->m_valueRange.m_end = 0; #endif } - void endAttributeValue(int index) + void endAttributeValue(int offset) { - m_currentAttribute->m_valueRange.m_end = index; + m_currentAttribute->m_valueRange.m_end = offset - m_baseOffset; } void appendToAttributeName(UChar character) @@ -213,6 +220,13 @@ public: m_currentAttribute->m_value.append(character); } + void appendToAttributeValue(size_t i, const String& value) + { + ASSERT(!value.isEmpty()); + ASSERT(m_type == StartTag || m_type == EndTag); + m_attributes[i].m_value.append(value.characters(), value.length()); + } + Type type() const { return m_type; } bool selfClosing() const @@ -239,6 +253,18 @@ public: return m_data; } + void eraseCharacters() + { + ASSERT(m_type == Character); + m_data.clear(); + } + + void eraseValueOfAttribute(size_t i) + { + ASSERT(m_type == StartTag || m_type == EndTag); + m_attributes[i].m_value.clear(); + } + const DataVector& characters() const { ASSERT(m_type == Character); @@ -331,9 +357,8 @@ private: }; Type m_type; - - // Which characters from the input stream are represented by this token. - Range m_range; + Range m_range; // Always starts at zero. + int m_baseOffset; // "name" for DOCTYPE, StartTag, and EndTag // "characters" for Character diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp index 97cee13..d2931ac 100644 --- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp @@ -26,8 +26,8 @@ #include "config.h" #include "HTMLTreeBuilder.h" -#include "CharacterNames.h" #include "Comment.h" +#include "DOMWindow.h" #include "DocumentFragment.h" #include "DocumentType.h" #include "Frame.h" @@ -50,6 +50,7 @@ #include "XLinkNames.h" #include "XMLNSNames.h" #include "XMLNames.h" +#include <wtf/unicode/CharacterNames.h> namespace WebCore { @@ -341,7 +342,7 @@ private: HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks) : m_framesetOk(true) , m_document(document) - , m_tree(document, FragmentScriptingAllowed, false) + , m_tree(document) , m_reportErrors(reportErrors) , m_isPaused(false) , m_insertionMode(InitialMode) @@ -359,8 +360,8 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* docum HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks) : m_framesetOk(true) , m_fragmentContext(fragment, contextElement, scriptingPermission) - , m_document(m_fragmentContext.document()) - , m_tree(m_document, scriptingPermission, true) + , m_document(fragment->document()) + , m_tree(fragment, scriptingPermission) , m_reportErrors(false) // FIXME: Why not report errors in fragments? , m_isPaused(false) , m_insertionMode(InitialMode) @@ -374,7 +375,6 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f if (contextElement) { // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm: // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case - m_document->setCompatibilityMode(contextElement->document()->compatibilityMode()); processFakeStartTag(htmlTag); resetInsertionModeAppropriately(); m_tree.setForm(closestFormAncestor(contextElement)); @@ -403,27 +403,24 @@ HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext() } HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission) - : m_dummyDocumentForFragmentParsing(HTMLDocument::create(0, KURL(), fragment->document()->baseURI())) - , m_fragment(fragment) + : m_fragment(fragment) , m_contextElement(contextElement) , m_scriptingPermission(scriptingPermission) { - m_dummyDocumentForFragmentParsing->setCompatibilityMode(fragment->document()->compatibilityMode()); -} - -Document* HTMLTreeBuilder::FragmentParsingContext::document() const -{ - ASSERT(m_fragment); - return m_dummyDocumentForFragmentParsing.get(); + ASSERT(!fragment->hasChildNodes()); } void HTMLTreeBuilder::FragmentParsingContext::finished() { - // Populate the DocumentFragment with the parsed content now that we're done. - ContainerNode* root = m_dummyDocumentForFragmentParsing.get(); - if (m_contextElement) - root = m_dummyDocumentForFragmentParsing->documentElement(); - m_fragment->takeAllChildrenFrom(root); + if (!m_contextElement) + return; + + // The HTML5 spec says to return the children of the fragment's document + // element when there is a context element (10.4.7). + RefPtr<ContainerNode> documentElement = firstElementChild(m_fragment); + m_fragment->removeChildren(); + ASSERT(documentElement); + m_fragment->takeAllChildrenFrom(documentElement.get()); } HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext() @@ -2807,6 +2804,20 @@ void HTMLTreeBuilder::finished() m_document->finishedParsing(); } +void HTMLTreeBuilder::parseError(AtomicHTMLToken&) +{ + DEFINE_STATIC_LOCAL(String, parseErrorMessage, ("HTML parse error (recovered gracefully)")); + + if (!m_reportErrors) + return; + + DOMWindow* domWindow = m_document->domWindow(); + if (!domWindow) + return; + + domWindow->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, parseErrorMessage, m_parser->lineNumber(), m_document->url().string()); +} + bool HTMLTreeBuilder::scriptEnabled(Frame* frame) { if (!frame) diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.h b/Source/WebCore/html/parser/HTMLTreeBuilder.h index 309ac6f..0cec667 100644 --- a/Source/WebCore/html/parser/HTMLTreeBuilder.h +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.h @@ -183,8 +183,7 @@ private: bool m_framesetOk; - // FIXME: Implement error reporting. - void parseError(AtomicHTMLToken&) { } + void parseError(AtomicHTMLToken&); InsertionMode insertionMode() const { return m_insertionMode; } void setInsertionMode(InsertionMode mode) @@ -212,7 +211,6 @@ private: FragmentParsingContext(DocumentFragment*, Element* contextElement, FragmentScriptingPermission); ~FragmentParsingContext(); - Document* document() const; DocumentFragment* fragment() const { return m_fragment; } Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; } FragmentScriptingPermission scriptingPermission() const { ASSERT(m_fragment); return m_scriptingPermission; } @@ -220,7 +218,6 @@ private: void finished(); private: - RefPtr<Document> m_dummyDocumentForFragmentParsing; DocumentFragment* m_fragment; Element* m_contextElement; diff --git a/Source/WebCore/html/parser/HTMLViewSourceParser.cpp b/Source/WebCore/html/parser/HTMLViewSourceParser.cpp index ace8590..7cdbdc7 100644 --- a/Source/WebCore/html/parser/HTMLViewSourceParser.cpp +++ b/Source/WebCore/html/parser/HTMLViewSourceParser.cpp @@ -49,35 +49,27 @@ void HTMLViewSourceParser::insert(const SegmentedString&) void HTMLViewSourceParser::pumpTokenizer() { - while (m_tokenizer->nextToken(m_input.current(), m_token)) { - m_token.end(m_input.current().numberOfCharactersConsumed()); + while (true) { + m_sourceTracker.start(m_input, m_token); + if (!m_tokenizer->nextToken(m_input.current(), m_token)) + break; + m_sourceTracker.end(m_input, m_token); + document()->addSource(sourceForToken(), m_token); updateTokenizerState(); - m_token.clear(m_input.current().numberOfCharactersConsumed()); + m_token.clear(); } } void HTMLViewSourceParser::append(const SegmentedString& input) { m_input.appendToEnd(input); - m_source.append(input); pumpTokenizer(); } String HTMLViewSourceParser::sourceForToken() { - if (m_token.type() == HTMLToken::EndOfFile) - return String(); - - ASSERT(m_source.numberOfCharactersConsumed() == m_token.startIndex()); - UChar* data = 0; - int length = m_token.endIndex() - m_token.startIndex(); - String source = String::createUninitialized(length, data); - for (int i = 0; i < length; ++i) { - data[i] = *m_source; - m_source.advance(); - } - return source; + return m_sourceTracker.sourceForToken(m_token); } void HTMLViewSourceParser::updateTokenizerState() diff --git a/Source/WebCore/html/parser/HTMLViewSourceParser.h b/Source/WebCore/html/parser/HTMLViewSourceParser.h index abe55b4..2e6ddfe 100644 --- a/Source/WebCore/html/parser/HTMLViewSourceParser.h +++ b/Source/WebCore/html/parser/HTMLViewSourceParser.h @@ -28,6 +28,7 @@ #include "DecodedDataDocumentParser.h" #include "HTMLInputStream.h" +#include "HTMLSourceTracker.h" #include "HTMLToken.h" #include "HTMLTokenizer.h" #include "HTMLViewSourceDocument.h" @@ -69,8 +70,8 @@ private: void updateTokenizerState(); HTMLInputStream m_input; - SegmentedString m_source; HTMLToken m_token; + HTMLSourceTracker m_sourceTracker; OwnPtr<HTMLTokenizer> m_tokenizer; }; diff --git a/Source/WebCore/html/parser/XSSFilter.cpp b/Source/WebCore/html/parser/XSSFilter.cpp new file mode 100644 index 0000000..de31f76 --- /dev/null +++ b/Source/WebCore/html/parser/XSSFilter.cpp @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2011 Adam Barth. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 "XSSFilter.h" + +#include "DOMWindow.h" +#include "Document.h" +#include "DocumentLoader.h" +#include "Frame.h" +#include "HTMLDocumentParser.h" +#include "HTMLNames.h" +#include "HTMLParamElement.h" +#include "HTMLParserIdioms.h" +#include "Settings.h" +#include "TextEncoding.h" +#include "TextResourceDecoder.h" +#include <wtf/text/CString.h> + +namespace WebCore { + +using namespace HTMLNames; + +namespace { + +bool isNonCanonicalCharacter(UChar c) +{ + // We remove all non-ASCII characters, including non-printable ASCII characters. + // + // Note, we don't remove backslashes like PHP stripslashes(), which among other things converts "\\0" to the \0 character. + // Instead, we remove backslashes and zeros (since the string "\\0" =(remove backslashes)=> "0"). However, this has the + // adverse effect that we remove any legitimate zeros from a string. + // + // For instance: new String("http://localhost:8000") => new String("http://localhost:8"). + return (c == '\\' || c == '0' || c == '\0' || c >= 127); +} + +String canonicalize(const String& string) +{ + return string.removeCharacters(&isNonCanonicalCharacter); +} + +bool isRequiredForInjection(UChar c) +{ + return (c == '\'' || c == '"' || c == '<' || c == '>'); +} + +bool hasName(const HTMLToken& token, const QualifiedName& name) +{ + return equalIgnoringNullity(token.name(), static_cast<const String&>(name.localName())); +} + +bool findAttributeWithName(const HTMLToken& token, const QualifiedName& name, size_t& indexOfMatchingAttribute) +{ + for (size_t i = 0; i < token.attributes().size(); ++i) { + if (equalIgnoringNullity(token.attributes().at(i).m_name, name.localName())) { + indexOfMatchingAttribute = i; + return true; + } + } + return false; +} + +bool isNameOfInlineEventHandler(const Vector<UChar, 32>& name) +{ + const size_t lengthOfShortestInlineEventHandlerName = 5; // To wit: oncut. + if (name.size() < lengthOfShortestInlineEventHandlerName) + return false; + return name[0] == 'o' && name[1] == 'n'; +} + +bool containsJavaScriptURL(const Vector<UChar, 32>& value) +{ + static const char javaScriptScheme[] = "javascript:"; + static const size_t lengthOfJavaScriptScheme = sizeof(javaScriptScheme) - 1; + + size_t i; + for (i = 0; i < value.size(); ++i) { + if (!isHTMLSpace(value[i])) + break; + } + + if (value.size() - i < lengthOfJavaScriptScheme) + return false; + + return equalIgnoringCase(value.data() + i, javaScriptScheme, lengthOfJavaScriptScheme); +} + +String decodeURL(const String& string, const TextEncoding& encoding) +{ + String workingString = string; + workingString.replace('+', ' '); + workingString = decodeURLEscapeSequences(workingString); + CString workingStringUTF8 = workingString.utf8(); + String decodedString = encoding.decode(workingStringUTF8.data(), workingStringUTF8.length()); + // FIXME: Is this check necessary? + if (decodedString.isEmpty()) + return canonicalize(workingString); + return canonicalize(decodedString); +} + +} + +XSSFilter::XSSFilter(HTMLDocumentParser* parser) + : m_parser(parser) + , m_isEnabled(false) + , m_xssProtection(XSSProtectionEnabled) + , m_state(Uninitialized) +{ + ASSERT(m_parser); + if (Frame* frame = parser->document()->frame()) { + if (Settings* settings = frame->settings()) + m_isEnabled = settings->xssAuditorEnabled(); + } + // Although tempting to call init() at this point, the various objects + // we want to reference might not all have been constructed yet. +} + +void XSSFilter::init() +{ + const size_t miniumLengthForSuffixTree = 512; // FIXME: Tune this parameter. + const int suffixTreeDepth = 5; + + ASSERT(m_state == Uninitialized); + m_state = Initial; + + if (!m_isEnabled) + return; + + // In theory, the Document could have detached from the Frame after the + // XSSFilter was constructed. + if (!m_parser->document()->frame()) { + m_isEnabled = false; + return; + } + + const KURL& url = m_parser->document()->url(); + + if (url.protocolIsData()) { + m_isEnabled = false; + return; + } + + TextResourceDecoder* decoder = m_parser->document()->decoder(); + m_decodedURL = decoder ? decodeURL(url.string(), decoder->encoding()) : url.string(); + if (m_decodedURL.find(isRequiredForInjection, 0) == notFound) + m_decodedURL = String(); + + if (DocumentLoader* documentLoader = m_parser->document()->frame()->loader()->documentLoader()) { + DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, ("X-XSS-Protection")); + m_xssProtection = parseXSSProtectionHeader(documentLoader->response().httpHeaderField(XSSProtectionHeader)); + + FormData* httpBody = documentLoader->originalRequest().httpBody(); + if (httpBody && !httpBody->isEmpty()) { + String httpBodyAsString = httpBody->flattenToString(); + m_decodedHTTPBody = decoder ? decodeURL(httpBodyAsString, decoder->encoding()) : httpBodyAsString; + if (m_decodedHTTPBody.find(isRequiredForInjection, 0) == notFound) + m_decodedHTTPBody = String(); + if (m_decodedHTTPBody.length() >= miniumLengthForSuffixTree) + m_decodedHTTPBodySuffixTree = adoptPtr(new SuffixTree<ASCIICodebook>(m_decodedHTTPBody, suffixTreeDepth)); + } + } + + if (m_decodedURL.isEmpty() && m_decodedHTTPBody.isEmpty()) + m_isEnabled = false; +} + +void XSSFilter::filterToken(HTMLToken& token) +{ + if (m_state == Uninitialized) { + init(); + ASSERT(m_state == Initial); + } + + if (!m_isEnabled || m_xssProtection == XSSProtectionDisabled) + return; + + bool didBlockScript = false; + + switch (m_state) { + case Uninitialized: + ASSERT_NOT_REACHED(); + break; + case Initial: + didBlockScript = filterTokenInitial(token); + break; + case AfterScriptStartTag: + didBlockScript = filterTokenAfterScriptStartTag(token); + ASSERT(m_state == Initial); + m_cachedSnippet = String(); + break; + } + + if (didBlockScript) { + // FIXME: Consider using a more helpful console message. + DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); + // FIXME: We should add the real line number to the console. + m_parser->document()->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); + + if (m_xssProtection == XSSProtectionBlockEnabled) { + m_parser->document()->frame()->loader()->stopAllLoaders(); + m_parser->document()->frame()->navigationScheduler()->scheduleLocationChange(m_parser->document()->securityOrigin(), blankURL(), String()); + } + } +} + +bool XSSFilter::filterTokenInitial(HTMLToken& token) +{ + ASSERT(m_state == Initial); + + if (token.type() != HTMLToken::StartTag) + return false; + + bool didBlockScript = eraseDangerousAttributesIfInjected(token); + + if (hasName(token, scriptTag)) + didBlockScript |= filterScriptToken(token); + else if (hasName(token, objectTag)) + didBlockScript |= filterObjectToken(token); + else if (hasName(token, paramTag)) + didBlockScript |= filterParamToken(token); + else if (hasName(token, embedTag)) + didBlockScript |= filterEmbedToken(token); + else if (hasName(token, appletTag)) + didBlockScript |= filterAppletToken(token); + else if (hasName(token, metaTag)) + didBlockScript |= filterMetaToken(token); + else if (hasName(token, baseTag)) + didBlockScript |= filterBaseToken(token); + + return didBlockScript; +} + +bool XSSFilter::filterTokenAfterScriptStartTag(HTMLToken& token) +{ + ASSERT(m_state == AfterScriptStartTag); + m_state = Initial; + + if (token.type() != HTMLToken::Character) { + ASSERT(token.type() == HTMLToken::EndTag || token.type() == HTMLToken::EndOfFile); + return false; + } + + int start = 0; + // FIXME: We probably want to grab only the first few characters of the + // contents of the script element. + int end = token.endIndex() - token.startIndex(); + if (isContainedInRequest(m_cachedSnippet + snippetForRange(token, start, end))) { + token.eraseCharacters(); + token.appendToCharacter(' '); // Technically, character tokens can't be empty. + return true; + } + return false; +} + +bool XSSFilter::filterScriptToken(HTMLToken& token) +{ + ASSERT(m_state == Initial); + ASSERT(token.type() == HTMLToken::StartTag); + ASSERT(hasName(token, scriptTag)); + + if (eraseAttributeIfInjected(token, srcAttr, blankURL().string())) + return true; + + m_state = AfterScriptStartTag; + m_cachedSnippet = m_parser->sourceForToken(token); + return false; +} + +bool XSSFilter::filterObjectToken(HTMLToken& token) +{ + ASSERT(m_state == Initial); + ASSERT(token.type() == HTMLToken::StartTag); + ASSERT(hasName(token, objectTag)); + + bool didBlockScript = false; + + didBlockScript |= eraseAttributeIfInjected(token, dataAttr, blankURL().string()); + didBlockScript |= eraseAttributeIfInjected(token, typeAttr); + didBlockScript |= eraseAttributeIfInjected(token, classidAttr); + + return didBlockScript; +} + +bool XSSFilter::filterParamToken(HTMLToken& token) +{ + ASSERT(m_state == Initial); + ASSERT(token.type() == HTMLToken::StartTag); + ASSERT(hasName(token, paramTag)); + + size_t indexOfNameAttribute; + if (!findAttributeWithName(token, nameAttr, indexOfNameAttribute)) + return false; + + const HTMLToken::Attribute& nameAttribute = token.attributes().at(indexOfNameAttribute); + String name = String(nameAttribute.m_value.data(), nameAttribute.m_value.size()); + + if (!HTMLParamElement::isURLParameter(name)) + return false; + + return eraseAttributeIfInjected(token, valueAttr, blankURL().string()); +} + +bool XSSFilter::filterEmbedToken(HTMLToken& token) +{ + ASSERT(m_state == Initial); + ASSERT(token.type() == HTMLToken::StartTag); + ASSERT(hasName(token, embedTag)); + + bool didBlockScript = false; + + didBlockScript |= eraseAttributeIfInjected(token, srcAttr, blankURL().string()); + didBlockScript |= eraseAttributeIfInjected(token, typeAttr); + + return didBlockScript; +} + +bool XSSFilter::filterAppletToken(HTMLToken& token) +{ + ASSERT(m_state == Initial); + ASSERT(token.type() == HTMLToken::StartTag); + ASSERT(hasName(token, appletTag)); + + bool didBlockScript = false; + + didBlockScript |= eraseAttributeIfInjected(token, codeAttr); + didBlockScript |= eraseAttributeIfInjected(token, objectAttr); + + return didBlockScript; +} + +bool XSSFilter::filterMetaToken(HTMLToken& token) +{ + ASSERT(m_state == Initial); + ASSERT(token.type() == HTMLToken::StartTag); + ASSERT(hasName(token, metaTag)); + + return eraseAttributeIfInjected(token, http_equivAttr); +} + +bool XSSFilter::filterBaseToken(HTMLToken& token) +{ + ASSERT(m_state == Initial); + ASSERT(token.type() == HTMLToken::StartTag); + ASSERT(hasName(token, baseTag)); + + return eraseAttributeIfInjected(token, hrefAttr); +} + +bool XSSFilter::eraseDangerousAttributesIfInjected(HTMLToken& token) +{ + DEFINE_STATIC_LOCAL(String, safeJavaScriptURL, ("javascript:void(0)")); + + bool didBlockScript = false; + for (size_t i = 0; i < token.attributes().size(); ++i) { + const HTMLToken::Attribute& attribute = token.attributes().at(i); + bool isInlineEventHandler = isNameOfInlineEventHandler(attribute.m_name); + bool valueContainsJavaScriptURL = isInlineEventHandler ? false : containsJavaScriptURL(attribute.m_value); + if (!isInlineEventHandler && !valueContainsJavaScriptURL) + continue; + if (!isContainedInRequest(snippetForAttribute(token, attribute))) + continue; + token.eraseValueOfAttribute(i); + if (valueContainsJavaScriptURL) + token.appendToAttributeValue(i, safeJavaScriptURL); + didBlockScript = true; + } + return didBlockScript; +} + +bool XSSFilter::eraseAttributeIfInjected(HTMLToken& token, const QualifiedName& attributeName, const String& replacementValue) +{ + size_t indexOfAttribute; + if (findAttributeWithName(token, attributeName, indexOfAttribute)) { + const HTMLToken::Attribute& attribute = token.attributes().at(indexOfAttribute); + if (isContainedInRequest(snippetForAttribute(token, attribute))) { + if (attributeName == srcAttr && isSameOriginResource(String(attribute.m_value.data(), attribute.m_value.size()))) + return false; + token.eraseValueOfAttribute(indexOfAttribute); + if (!replacementValue.isEmpty()) + token.appendToAttributeValue(indexOfAttribute, replacementValue); + return true; + } + } + return false; +} + +String XSSFilter::snippetForRange(const HTMLToken& token, int start, int end) +{ + // FIXME: There's an extra allocation here that we could save by + // passing the range to the parser. + return m_parser->sourceForToken(token).substring(start, end - start); +} + +String XSSFilter::snippetForAttribute(const HTMLToken& token, const HTMLToken::Attribute& attribute) +{ + // FIXME: We should grab one character before the name also. + int start = attribute.m_nameRange.m_start - token.startIndex(); + // FIXME: We probably want to grab only the first few characters of the attribute value. + int end = attribute.m_valueRange.m_end - token.startIndex(); + return snippetForRange(token, start, end); +} + +bool XSSFilter::isContainedInRequest(const String& snippet) +{ + ASSERT(!snippet.isEmpty()); + String canonicalizedSnippet = canonicalize(snippet); + ASSERT(!canonicalizedSnippet.isEmpty()); + if (m_decodedURL.find(canonicalizedSnippet, 0, false) != notFound) + return true; + if (m_decodedHTTPBodySuffixTree && !m_decodedHTTPBodySuffixTree->mightContain(canonicalizedSnippet)) + return false; + return m_decodedHTTPBody.find(canonicalizedSnippet, 0, false) != notFound; +} + +bool XSSFilter::isSameOriginResource(const String& url) +{ + // If the resource is loaded from the same URL as the enclosing page, it's + // probably not an XSS attack, so we reduce false positives by allowing the + // request. If the resource has a query string, we're more suspicious, + // however, because that's pretty rare and the attacker might be able to + // trick a server-side script into doing something dangerous with the query + // string. + KURL resourceURL(m_parser->document()->url(), url); + return (m_parser->document()->url().host() == resourceURL.host() && resourceURL.query().isEmpty()); +} + +} diff --git a/Source/WebCore/html/parser/XSSFilter.h b/Source/WebCore/html/parser/XSSFilter.h new file mode 100644 index 0000000..2c7d428 --- /dev/null +++ b/Source/WebCore/html/parser/XSSFilter.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2011 Adam Barth. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 XSSFilter_h +#define XSSFilter_h + +#include "HTMLToken.h" +#include "HTTPParsers.h" +#include "SuffixTree.h" + +namespace WebCore { + +class HTMLDocumentParser; + +class XSSFilter { + WTF_MAKE_NONCOPYABLE(XSSFilter); +public: + explicit XSSFilter(HTMLDocumentParser*); + + void filterToken(HTMLToken&); + +private: + enum State { + Uninitialized, + Initial, + AfterScriptStartTag, + }; + + void init(); + + bool filterTokenInitial(HTMLToken&); + bool filterTokenAfterScriptStartTag(HTMLToken&); + + bool filterScriptToken(HTMLToken&); + bool filterObjectToken(HTMLToken&); + bool filterParamToken(HTMLToken&); + bool filterEmbedToken(HTMLToken&); + bool filterAppletToken(HTMLToken&); + bool filterMetaToken(HTMLToken&); + bool filterBaseToken(HTMLToken&); + + bool eraseDangerousAttributesIfInjected(HTMLToken&); + bool eraseAttributeIfInjected(HTMLToken&, const QualifiedName&, const String& replacementValue = String()); + + String snippetForRange(const HTMLToken&, int start, int end); + String snippetForAttribute(const HTMLToken&, const HTMLToken::Attribute&); + + bool isContainedInRequest(const String&); + bool isSameOriginResource(const String& url); + + HTMLDocumentParser* m_parser; + bool m_isEnabled; + XSSProtectionDisposition m_xssProtection; + + String m_decodedURL; + String m_decodedHTTPBody; + OwnPtr<SuffixTree<ASCIICodebook> > m_decodedHTTPBodySuffixTree; + + State m_state; + String m_cachedSnippet; +}; + +} + +#endif diff --git a/Source/WebCore/html/shadow/MediaControls.cpp b/Source/WebCore/html/shadow/MediaControls.cpp new file mode 100644 index 0000000..731a934 --- /dev/null +++ b/Source/WebCore/html/shadow/MediaControls.cpp @@ -0,0 +1,572 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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" + +#if ENABLE(VIDEO) +#include "MediaControls.h" + +#include "EventNames.h" +#include "FloatConversion.h" +#include "HTMLNames.h" +#include "MediaControlElements.h" +#include "MouseEvent.h" +#include "Page.h" +#include "RenderLayer.h" +#include "RenderTheme.h" +#include <wtf/CurrentTime.h> +#include <wtf/MathExtras.h> + + +using namespace std; + +namespace WebCore { + +using namespace HTMLNames; + +static const double cTimeUpdateRepeatDelay = 0.2; +static const double cOpacityAnimationRepeatDelay = 0.05; + +MediaControls::MediaControls(HTMLMediaElement* mediaElement) + : m_mediaElement(mediaElement) + , m_timeUpdateTimer(this, &MediaControls::timeUpdateTimerFired) + , m_opacityAnimationTimer(this, &MediaControls::opacityAnimationTimerFired) + , m_opacityAnimationStartTime(0) + , m_opacityAnimationDuration(0) + , m_opacityAnimationFrom(0) + , m_opacityAnimationTo(1.0f) + , m_mouseOver(false) +{ +} + +void MediaControls::updateStyle() +{ + if (!m_controlsShadowRoot) + return; + + if (m_panel) + m_panel->updateStyle(); + if (m_muteButton) + m_muteButton->updateStyle(); + if (m_playButton) + m_playButton->updateStyle(); + if (m_seekBackButton) + m_seekBackButton->updateStyle(); + if (m_seekForwardButton) + m_seekForwardButton->updateStyle(); + if (m_rewindButton) + m_rewindButton->updateStyle(); + if (m_returnToRealtimeButton) + m_returnToRealtimeButton->updateStyle(); + if (m_toggleClosedCaptionsButton) + m_toggleClosedCaptionsButton->updateStyle(); + if (m_statusDisplay) + m_statusDisplay->updateStyle(); + if (m_timelineContainer) + m_timelineContainer->updateStyle(); + if (m_timeline) + m_timeline->updateStyle(); + if (m_fullscreenButton) + m_fullscreenButton->updateStyle(); + if (m_currentTimeDisplay) + m_currentTimeDisplay->updateStyle(); + if (m_timeRemainingDisplay) + m_timeRemainingDisplay->updateStyle(); + if (m_volumeSliderContainer) + m_volumeSliderContainer->updateStyle(); + if (m_volumeSliderMuteButton) + m_volumeSliderMuteButton->updateStyle(); + if (m_volumeSlider) + m_volumeSlider->updateStyle(); +} + +void MediaControls::destroy() +{ + ASSERT(m_mediaElement->renderer()); + + if (m_controlsShadowRoot && m_controlsShadowRoot->renderer()) { + + // detach the panel before removing the shadow renderer to prevent a crash in m_controlsShadowRoot->detach() + // when display: style changes + m_panel->detach(); + + m_mediaElement->renderer()->removeChild(m_controlsShadowRoot->renderer()); + m_controlsShadowRoot->detach(); + m_controlsShadowRoot = 0; + } +} + +void MediaControls::update() +{ + HTMLMediaElement* media = m_mediaElement; + if (!media->controls() || !media->inActiveDocument()) { + if (m_controlsShadowRoot) { + m_controlsShadowRoot->detach(); + m_panel = 0; + m_muteButton = 0; + m_playButton = 0; + m_statusDisplay = 0; + m_timelineContainer = 0; + m_timeline = 0; + m_seekBackButton = 0; + m_seekForwardButton = 0; + m_rewindButton = 0; + m_returnToRealtimeButton = 0; + m_currentTimeDisplay = 0; + m_timeRemainingDisplay = 0; + m_fullscreenButton = 0; + m_volumeSliderContainer = 0; + m_volumeSlider = 0; + m_volumeSliderMuteButton = 0; + m_controlsShadowRoot = 0; + m_toggleClosedCaptionsButton = 0; + } + m_opacityAnimationTo = 1.0f; + m_opacityAnimationTimer.stop(); + m_timeUpdateTimer.stop(); + return; + } + + if (!m_controlsShadowRoot) { + createControlsShadowRoot(); + createPanel(); + if (m_panel) { + createRewindButton(); + createPlayButton(); + createReturnToRealtimeButton(); + createStatusDisplay(); + createTimelineContainer(); + if (m_timelineContainer) { + createCurrentTimeDisplay(); + createTimeline(); + createTimeRemainingDisplay(); + } + createSeekBackButton(); + createSeekForwardButton(); + createToggleClosedCaptionsButton(); + createFullscreenButton(); + createMuteButton(); + createVolumeSliderContainer(); + if (m_volumeSliderContainer) { + createVolumeSlider(); + createVolumeSliderMuteButton(); + } + m_panel->attach(); + } + } + + if (media->canPlay()) { + if (m_timeUpdateTimer.isActive()) + m_timeUpdateTimer.stop(); + } else if (media->renderer()->style()->visibility() == VISIBLE && m_timeline && m_timeline->renderer() && m_timeline->renderer()->style()->display() != NONE) { + m_timeUpdateTimer.startRepeating(cTimeUpdateRepeatDelay); + } + + if (m_panel) { + // update() might alter the opacity of the element, especially if we are in the middle + // of an animation. This is the only element concerned as we animate only this element. + float opacityBeforeChangingStyle = m_panel->renderer() ? m_panel->renderer()->style()->opacity() : 0; + m_panel->update(); + changeOpacity(m_panel.get(), opacityBeforeChangingStyle); + } + if (m_muteButton) + m_muteButton->update(); + if (m_playButton) + m_playButton->update(); + if (m_timelineContainer) + m_timelineContainer->update(); + if (m_volumeSliderContainer) + m_volumeSliderContainer->update(); + if (m_timeline) + m_timeline->update(); + if (m_currentTimeDisplay) + m_currentTimeDisplay->update(); + if (m_timeRemainingDisplay) + m_timeRemainingDisplay->update(); + if (m_seekBackButton) + m_seekBackButton->update(); + if (m_seekForwardButton) + m_seekForwardButton->update(); + if (m_rewindButton) + m_rewindButton->update(); + if (m_returnToRealtimeButton) + m_returnToRealtimeButton->update(); + if (m_toggleClosedCaptionsButton) + m_toggleClosedCaptionsButton->update(); + if (m_statusDisplay) + m_statusDisplay->update(); + if (m_fullscreenButton) + m_fullscreenButton->update(); + if (m_volumeSlider) + m_volumeSlider->update(); + if (m_volumeSliderMuteButton) + m_volumeSliderMuteButton->update(); + + updateTimeDisplay(); + updateControlVisibility(); +} + +void MediaControls::createControlsShadowRoot() +{ + ASSERT(!m_controlsShadowRoot); + m_controlsShadowRoot = MediaControlShadowRootElement::create(m_mediaElement); + m_mediaElement->renderer()->addChild(m_controlsShadowRoot->renderer()); +} + +void MediaControls::createPanel() +{ + ASSERT(!m_panel); + m_panel = MediaControlPanelElement::create(m_mediaElement); + m_panel->attachToParent(m_controlsShadowRoot.get()); +} + +void MediaControls::createMuteButton() +{ + ASSERT(!m_muteButton); + m_muteButton = MediaControlMuteButtonElement::create(m_mediaElement); + m_muteButton->attachToParent(m_panel.get()); +} + +void MediaControls::createPlayButton() +{ + ASSERT(!m_playButton); + m_playButton = MediaControlPlayButtonElement::create(m_mediaElement); + m_playButton->attachToParent(m_panel.get()); +} + +void MediaControls::createSeekBackButton() +{ + ASSERT(!m_seekBackButton); + m_seekBackButton = MediaControlSeekBackButtonElement::create(m_mediaElement); + m_seekBackButton->attachToParent(m_panel.get()); +} + +void MediaControls::createSeekForwardButton() +{ + ASSERT(!m_seekForwardButton); + m_seekForwardButton = MediaControlSeekForwardButtonElement::create(m_mediaElement); + m_seekForwardButton->attachToParent(m_panel.get()); +} + +void MediaControls::createRewindButton() +{ + ASSERT(!m_rewindButton); + m_rewindButton = MediaControlRewindButtonElement::create(m_mediaElement); + m_rewindButton->attachToParent(m_panel.get()); +} + +void MediaControls::createReturnToRealtimeButton() +{ + ASSERT(!m_returnToRealtimeButton); + m_returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(m_mediaElement); + m_returnToRealtimeButton->attachToParent(m_panel.get()); +} + +void MediaControls::createToggleClosedCaptionsButton() +{ + ASSERT(!m_toggleClosedCaptionsButton); + m_toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(m_mediaElement); + m_toggleClosedCaptionsButton->attachToParent(m_panel.get()); +} + +void MediaControls::createStatusDisplay() +{ + ASSERT(!m_statusDisplay); + m_statusDisplay = MediaControlStatusDisplayElement::create(m_mediaElement); + m_statusDisplay->attachToParent(m_panel.get()); +} + +void MediaControls::createTimelineContainer() +{ + ASSERT(!m_timelineContainer); + m_timelineContainer = MediaControlTimelineContainerElement::create(m_mediaElement); + m_timelineContainer->attachToParent(m_panel.get()); +} + +void MediaControls::createTimeline() +{ + ASSERT(!m_timeline); + m_timeline = MediaControlTimelineElement::create(m_mediaElement); + m_timeline->setAttribute(precisionAttr, "float"); + m_timeline->attachToParent(m_timelineContainer.get()); +} + +void MediaControls::createVolumeSliderContainer() +{ + ASSERT(!m_volumeSliderContainer); + m_volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(m_mediaElement); + m_volumeSliderContainer->attachToParent(m_panel.get()); +} + +void MediaControls::createVolumeSlider() +{ + ASSERT(!m_volumeSlider); + m_volumeSlider = MediaControlVolumeSliderElement::create(m_mediaElement); + m_volumeSlider->setAttribute(precisionAttr, "float"); + m_volumeSlider->setAttribute(maxAttr, "1"); + m_volumeSlider->setAttribute(valueAttr, String::number(m_mediaElement->volume())); + m_volumeSlider->attachToParent(m_volumeSliderContainer.get()); +} + +void MediaControls::createVolumeSliderMuteButton() +{ + ASSERT(!m_volumeSliderMuteButton); + m_volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(m_mediaElement); + m_volumeSliderMuteButton->attachToParent(m_volumeSliderContainer.get()); +} + +void MediaControls::createCurrentTimeDisplay() +{ + ASSERT(!m_currentTimeDisplay); + m_currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(m_mediaElement); + m_currentTimeDisplay->attachToParent(m_timelineContainer.get()); +} + +void MediaControls::createTimeRemainingDisplay() +{ + ASSERT(!m_timeRemainingDisplay); + m_timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(m_mediaElement); + m_timeRemainingDisplay->attachToParent(m_timelineContainer.get()); +} + +void MediaControls::createFullscreenButton() +{ + ASSERT(!m_fullscreenButton); + m_fullscreenButton = MediaControlFullscreenButtonElement::create(m_mediaElement); + m_fullscreenButton->attachToParent(m_panel.get()); +} + +void MediaControls::timeUpdateTimerFired(Timer<MediaControls>*) +{ + if (m_timeline) + m_timeline->update(false); + updateTimeDisplay(); +} + +void MediaControls::updateTimeDisplay() +{ + ASSERT(m_mediaElement->renderer()); + + if (!m_currentTimeDisplay || !m_currentTimeDisplay->renderer() || m_currentTimeDisplay->renderer()->style()->display() == NONE || m_mediaElement->renderer()->style()->visibility() != VISIBLE) + return; + + float now = m_mediaElement->currentTime(); + float duration = m_mediaElement->duration(); + + // Allow the theme to format the time + ExceptionCode ec; + m_currentTimeDisplay->setInnerText(m_mediaElement->renderer()->theme()->formatMediaControlsCurrentTime(now, duration), ec); + m_currentTimeDisplay->setCurrentValue(now); + m_timeRemainingDisplay->setInnerText(m_mediaElement->renderer()->theme()->formatMediaControlsRemainingTime(now, duration), ec); + m_timeRemainingDisplay->setCurrentValue(now - duration); +} + +RenderBox* MediaControls::renderBox() +{ + return m_controlsShadowRoot ? m_controlsShadowRoot->renderBox() : 0; +} + +void MediaControls::updateControlVisibility() +{ + if (!m_panel || !m_panel->renderer()) + return; + + // Don't fade for audio controls. + HTMLMediaElement* media = m_mediaElement; + if (!media->hasVideo()) + return; + + ASSERT(media->renderer()); + + // Don't fade if the media element is not visible + if (media->renderer()->style()->visibility() != VISIBLE) + return; + + bool shouldHideController = !m_mouseOver && !media->canPlay(); + + // Do fading manually, css animations don't work with shadow trees + + float animateFrom = m_panel->renderer()->style()->opacity(); + float animateTo = shouldHideController ? 0.0f : 1.0f; + + if (animateFrom == animateTo) + return; + + if (m_opacityAnimationTimer.isActive()) { + if (m_opacityAnimationTo == animateTo) + return; + m_opacityAnimationTimer.stop(); + } + + if (animateFrom < animateTo) + m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeInDuration(); + else + m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeOutDuration(); + + m_opacityAnimationFrom = animateFrom; + m_opacityAnimationTo = animateTo; + + m_opacityAnimationStartTime = currentTime(); + m_opacityAnimationTimer.startRepeating(cOpacityAnimationRepeatDelay); +} + +void MediaControls::changeOpacity(HTMLElement* e, float opacity) +{ + if (!e || !e->renderer() || !e->renderer()->style()) + return; + RefPtr<RenderStyle> s = RenderStyle::clone(e->renderer()->style()); + s->setOpacity(opacity); + // z-index can't be auto if opacity is used + s->setZIndex(0); + e->renderer()->setStyle(s.release()); +} + +void MediaControls::opacityAnimationTimerFired(Timer<MediaControls>*) +{ + double time = currentTime() - m_opacityAnimationStartTime; + if (time >= m_opacityAnimationDuration) { + time = m_opacityAnimationDuration; + m_opacityAnimationTimer.stop(); + } + float opacity = narrowPrecisionToFloat(m_opacityAnimationFrom + (m_opacityAnimationTo - m_opacityAnimationFrom) * time / m_opacityAnimationDuration); + changeOpacity(m_panel.get(), opacity); +} + +void MediaControls::updateVolumeSliderContainer(bool visible) +{ + if (!m_mediaElement->hasAudio() || !m_volumeSliderContainer || !m_volumeSlider) + return; + + if (visible && !m_volumeSliderContainer->isVisible()) { + if (!m_muteButton || !m_muteButton->renderer() || !m_muteButton->renderBox()) + return; + + RefPtr<RenderStyle> s = m_volumeSliderContainer->styleForElement(); + int height = s->height().isPercent() ? 0 : s->height().value(); + int width = s->width().isPercent() ? 0 : s->width().value(); + IntPoint offset = m_mediaElement->document()->page()->theme()->volumeSliderOffsetFromMuteButton(m_muteButton->renderer()->node(), IntSize(width, height)); + int x = offset.x() + m_muteButton->renderBox()->offsetLeft(); + int y = offset.y() + m_muteButton->renderBox()->offsetTop(); + + m_volumeSliderContainer->setPosition(x, y); + m_volumeSliderContainer->setVisible(true); + m_volumeSliderContainer->update(); + m_volumeSlider->update(); + } else if (!visible && m_volumeSliderContainer->isVisible()) { + m_volumeSliderContainer->setVisible(false); + m_volumeSliderContainer->updateStyle(); + } +} + +void MediaControls::forwardEvent(Event* event) +{ + ASSERT(m_mediaElement->renderer()); + + if (event->isMouseEvent() && m_controlsShadowRoot) { + MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); + IntPoint point(mouseEvent->absoluteLocation()); + + bool defaultHandled = false; + if (m_volumeSliderMuteButton && m_volumeSliderMuteButton->hitTest(point)) { + m_volumeSliderMuteButton->defaultEventHandler(event); + defaultHandled = event->defaultHandled(); + } + + bool showVolumeSlider = false; + if (!defaultHandled && m_muteButton && m_muteButton->hitTest(point)) { + m_muteButton->defaultEventHandler(event); + if (event->type() != eventNames().mouseoutEvent) + showVolumeSlider = true; + } + + if (m_volumeSliderContainer && m_volumeSliderContainer->hitTest(point)) + showVolumeSlider = true; + + if (m_volumeSlider && m_volumeSlider->hitTest(point)) { + m_volumeSlider->defaultEventHandler(event); + showVolumeSlider = true; + } + + updateVolumeSliderContainer(showVolumeSlider); + + if (m_playButton && m_playButton->hitTest(point)) + m_playButton->defaultEventHandler(event); + + if (m_seekBackButton && m_seekBackButton->hitTest(point)) + m_seekBackButton->defaultEventHandler(event); + + if (m_seekForwardButton && m_seekForwardButton->hitTest(point)) + m_seekForwardButton->defaultEventHandler(event); + + if (m_rewindButton && m_rewindButton->hitTest(point)) + m_rewindButton->defaultEventHandler(event); + + if (m_returnToRealtimeButton && m_returnToRealtimeButton->hitTest(point)) + m_returnToRealtimeButton->defaultEventHandler(event); + + if (m_toggleClosedCaptionsButton && m_toggleClosedCaptionsButton->hitTest(point)) + m_toggleClosedCaptionsButton->defaultEventHandler(event); + + if (m_timeline && m_timeline->hitTest(point)) + m_timeline->defaultEventHandler(event); + + if (m_fullscreenButton && m_fullscreenButton->hitTest(point)) + m_fullscreenButton->defaultEventHandler(event); + + if (event->type() == eventNames().mouseoverEvent) { + m_mouseOver = true; + updateControlVisibility(); + } + if (event->type() == eventNames().mouseoutEvent) { + // When the scrollbar thumb captures mouse events, we should treat the mouse as still being over our renderer if the new target is a descendant + Node* mouseOverNode = mouseEvent->relatedTarget() ? mouseEvent->relatedTarget()->toNode() : 0; + RenderObject* mouseOverRenderer = mouseOverNode ? mouseOverNode->renderer() : 0; + m_mouseOver = mouseOverRenderer && mouseOverRenderer->isDescendantOf(m_mediaElement->renderer()); + updateControlVisibility(); + } + } +} + +// We want the timeline slider to be at least 100 pixels wide. +static const int minWidthToDisplayTimeDisplays = 16 + 16 + 45 + 100 + 45 + 16 + 1; + +void MediaControls::updateTimeDisplayVisibility() +{ + ASSERT(m_mediaElement->renderer()); + + if (!m_currentTimeDisplay && !m_timeRemainingDisplay) + return; + + int width = m_mediaElement->renderBox()->width(); + bool shouldShowTimeDisplays = width >= minWidthToDisplayTimeDisplays * m_mediaElement->renderer()->style()->effectiveZoom(); + + m_currentTimeDisplay->setVisible(shouldShowTimeDisplays); + m_timeRemainingDisplay->setVisible(shouldShowTimeDisplays); +} + +} + +#endif diff --git a/Source/WebCore/html/shadow/MediaControls.h b/Source/WebCore/html/shadow/MediaControls.h new file mode 100644 index 0000000..98e017f --- /dev/null +++ b/Source/WebCore/html/shadow/MediaControls.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 MediaControls_h +#define MediaControls_h + +#if ENABLE(VIDEO) + +#include "Timer.h" +#include <wtf/RefPtr.h> + +namespace WebCore { + +class HTMLElement; +class HTMLInputElement; +class HTMLMediaElement; +class Event; +class MediaControlMuteButtonElement; +class MediaControlPlayButtonElement; +class MediaControlSeekButtonElement; +class MediaControlShadowRootElement; +class MediaControlRewindButtonElement; +class MediaControlReturnToRealtimeButtonElement; +class MediaControlToggleClosedCaptionsButtonElement; +class MediaControlTimelineElement; +class MediaControlVolumeSliderElement; +class MediaControlFullscreenButtonElement; +class MediaControlTimeDisplayElement; +class MediaControlStatusDisplayElement; +class MediaControlTimelineContainerElement; +class MediaControlVolumeSliderContainerElement; +class MediaControlElement; +class MediaPlayer; + +class RenderBox; +class RenderMedia; + +class MediaControls { +public: + MediaControls(HTMLMediaElement*); + + void destroy(); + void update(); + void updateStyle(); + void forwardEvent(Event*); + void updateTimeDisplay(); + void updateTimeDisplayVisibility(); + + // FIXME: This is temporary to allow RenderMedia::layout tweak the position of controls. + // Once shadow DOM refactoring is complete, the tweaking will be in MediaControlsShadowRoot and this accessor will no longer be necessary. + RenderBox* renderBox(); + +private: + void createControlsShadowRoot(); + void destroyControlsShadowRoot(); + void createPanel(); + void createMuteButton(); + void createPlayButton(); + void createSeekBackButton(); + void createSeekForwardButton(); + void createRewindButton(); + void createReturnToRealtimeButton(); + void createToggleClosedCaptionsButton(); + void createStatusDisplay(); + void createTimelineContainer(); + void createTimeline(); + void createVolumeSliderContainer(); + void createVolumeSlider(); + void createVolumeSliderMuteButton(); + void createCurrentTimeDisplay(); + void createTimeRemainingDisplay(); + void createFullscreenButton(); + + void timeUpdateTimerFired(Timer<MediaControls>*); + + void updateControlVisibility(); + void changeOpacity(HTMLElement*, float opacity); + void opacityAnimationTimerFired(Timer<MediaControls>*); + + void updateVolumeSliderContainer(bool visible); + +private: + RefPtr<MediaControlShadowRootElement> m_controlsShadowRoot; + RefPtr<MediaControlElement> m_panel; + RefPtr<MediaControlMuteButtonElement> m_muteButton; + RefPtr<MediaControlPlayButtonElement> m_playButton; + RefPtr<MediaControlSeekButtonElement> m_seekBackButton; + RefPtr<MediaControlSeekButtonElement> m_seekForwardButton; + RefPtr<MediaControlRewindButtonElement> m_rewindButton; + RefPtr<MediaControlReturnToRealtimeButtonElement> m_returnToRealtimeButton; + RefPtr<MediaControlToggleClosedCaptionsButtonElement> m_toggleClosedCaptionsButton; + RefPtr<MediaControlTimelineElement> m_timeline; + RefPtr<MediaControlVolumeSliderElement> m_volumeSlider; + RefPtr<MediaControlMuteButtonElement> m_volumeSliderMuteButton; + RefPtr<MediaControlFullscreenButtonElement> m_fullscreenButton; + RefPtr<MediaControlTimelineContainerElement> m_timelineContainer; + RefPtr<MediaControlVolumeSliderContainerElement> m_volumeSliderContainer; + RefPtr<MediaControlTimeDisplayElement> m_currentTimeDisplay; + RefPtr<MediaControlTimeDisplayElement> m_timeRemainingDisplay; + RefPtr<MediaControlStatusDisplayElement> m_statusDisplay; + + HTMLMediaElement* m_mediaElement; + Timer<MediaControls> m_timeUpdateTimer; + Timer<MediaControls> m_opacityAnimationTimer; + + double m_opacityAnimationStartTime; + double m_opacityAnimationDuration; + float m_opacityAnimationFrom; + float m_opacityAnimationTo; + + bool m_mouseOver; +}; + + +} + +#endif +#endif diff --git a/Source/WebCore/html/shadow/ProgressBarValueElement.h b/Source/WebCore/html/shadow/ProgressBarValueElement.h new file mode 100644 index 0000000..22f4e57 --- /dev/null +++ b/Source/WebCore/html/shadow/ProgressBarValueElement.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 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. + */ + +#ifndef ProgressBarValueElement_h +#define ProgressBarValueElement_h + +#include "HTMLDivElement.h" +#include "HTMLNames.h" +#include "RenderProgress.h" +#include <wtf/Forward.h> + +namespace WebCore { + +class ProgressBarValueElement : public HTMLDivElement { +public: + ProgressBarValueElement(Document* document) + : HTMLDivElement(HTMLNames::divTag, document) + { + } + + virtual const AtomicString& shadowPseudoId() const; + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); + static PassRefPtr<ProgressBarValueElement> create(Document*); + +}; + +inline const AtomicString& ProgressBarValueElement::shadowPseudoId() const +{ + DEFINE_STATIC_LOCAL(AtomicString, pseudId, ("-webkit-progress-bar-value")); + return pseudId; +} + +inline RenderObject* ProgressBarValueElement::createRenderer(RenderArena* arena, RenderStyle*) +{ + return new (arena) RenderProgressBarValuePart(this); +} + +inline PassRefPtr<ProgressBarValueElement> ProgressBarValueElement::create(Document* document) +{ + return adoptRef(new ProgressBarValueElement(document)); +} + +} + +#endif diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp index 758d3c7..2c049cb 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.cpp +++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp @@ -163,6 +163,8 @@ void SliderThumbElement::stopDragging() frame->page()->mainFrame()->eventHandler()->setCapturingTouchEventsNode(0); #endif m_inDragMode = false; + if (renderer()) + renderer()->setNeedsLayout(true); } void SliderThumbElement::defaultEventHandler(Event* event) @@ -246,5 +248,11 @@ void SliderThumbElement::detach() HTMLDivElement::detach(); } +const AtomicString& SliderThumbElement::shadowPseudoId() const +{ + DEFINE_STATIC_LOCAL(AtomicString, sliderThumb, ("-webkit-slider-thumb")); + return sliderThumb; +} + } diff --git a/Source/WebCore/html/shadow/SliderThumbElement.h b/Source/WebCore/html/shadow/SliderThumbElement.h index 1f1c869..7c4c179 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.h +++ b/Source/WebCore/html/shadow/SliderThumbElement.h @@ -53,7 +53,7 @@ public: void dragFrom(const IntPoint&); virtual void defaultEventHandler(Event*); virtual void detach(); - virtual AtomicString shadowPseudoId() const; + virtual const AtomicString& shadowPseudoId() const; private: SliderThumbElement(Document*); @@ -77,12 +77,6 @@ inline PassRefPtr<SliderThumbElement> SliderThumbElement::create(Document* docum return adoptRef(new SliderThumbElement(document)); } -inline AtomicString SliderThumbElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, sliderThumb, ("-webkit-slider-thumb")); - return sliderThumb; -} - inline SliderThumbElement* toSliderThumbElement(Node* node) { ASSERT(!node || node->isHTMLElement()); |