OSDN Git Service

Merge WebKit at Chromium 9.0.597.69: Trivial merge by Git.
authorBen Murdoch <benm@google.com>
Sun, 16 Jan 2011 13:59:45 +0000 (13:59 +0000)
committerBen Murdoch <benm@google.com>
Sun, 16 Jan 2011 14:14:41 +0000 (14:14 +0000)
http://svn.webkit.org/repository/webkit/branches/chromium/597/WebCore@75681

Change-Id: Ibe552cf7af31f74b81e337eadf3d3b73a53daf60

36 files changed:
WebCore/ChangeLog
WebCore/css/CSSCanvasValue.cpp
WebCore/css/CSSCursorImageValue.cpp
WebCore/css/CSSRuleList.cpp
WebCore/css/CSSStyleSheet.cpp
WebCore/dom/Node.cpp
WebCore/dom/Range.cpp
WebCore/editing/ReplaceSelectionCommand.cpp
WebCore/html/HTMLCanvasElement.cpp
WebCore/html/HTMLCanvasElement.h
WebCore/html/HTMLElement.cpp
WebCore/html/HTMLFormControlElement.cpp
WebCore/html/HTMLFormControlElement.h
WebCore/html/MediaDocument.cpp
WebCore/inspector/InspectorCSSAgent.cpp
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorStyleSheet.cpp
WebCore/inspector/InspectorStyleSheet.h
WebCore/inspector/front-end/AuditLauncherView.js
WebCore/inspector/front-end/AuditsPanel.js
WebCore/inspector/front-end/ResourceManager.js
WebCore/inspector/front-end/StylesSidebarPane.js
WebCore/loader/ResourceLoadNotifier.cpp
WebCore/page/DOMWindow.cpp
WebCore/page/FrameView.cpp
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderTable.cpp
WebCore/rendering/RenderTableRow.cpp
WebCore/rendering/RenderTableSection.cpp
WebCore/svg/SVGElement.cpp
WebCore/svg/SVGElement.h
WebCore/svg/SVGElementInstance.cpp
WebCore/svg/SVGElementInstance.h
WebCore/svg/SVGLength.cpp
WebCore/svg/SVGUseElement.cpp
WebCore/svg/SVGUseElement.h

index 2f8e863..b56a885 100644 (file)
@@ -1,3 +1,69 @@
+2011-01-12  Kenichi Ishibashi  <bashi@google.com>
+
+        Reviewed by Kent Tamura.
+
+        M_formElementsWithFormAttribute not cleared when FormAssociatedElement is inserted with a null m_form and then removed.
+        https://bugs.webkit.org/show_bug.cgi?id=51905
+
+        Calls unregisterFormElementWithFormAttribute() when 'form' attribute
+        is removed.
+
+        Tests: fast/forms/form-associated-element-crash.html
+               fast/forms/form-associated-element-crash2.html
+
+        * html/FormAssociatedElement.cpp:
+        (WebCore::FormAssociatedElement::formAttributeChanged):
+
+2011-01-12  Kenichi Ishibashi  <bashi@google.com>
+
+        Reviewed by Kent Tamura.
+
+        M_formElementsWithFormAttribute not cleared when Node is moved to another document.
+        https://bugs.webkit.org/show_bug.cgi?id=51418
+
+        Calls unregisterFormElementWithFormAttribute() when form associated elements
+        are moved to another document.
+
+        Test: fast/forms/change-form-element-document-crash.html
+
+        * html/FormAssociatedElement.cpp:
+        (WebCore::FormAssociatedElement::willMoveToNewOwnerDocument): Added.
+        * html/FormAssociatedElement.h: Added willMoveToNewOwnerDocument().
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::willMoveToNewOwnerDocument): Added.
+        * html/HTMLFormControlElement.h: Added willMoveToNewOwnerDocument().
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::willMoveToNewOwnerDocument): Added.
+        * html/HTMLObjectElement.h: Added willMoveToNewOwnerDocument().
+        * html/HTMLPlugInImageElement.h: Moves willMoveToNewOwnerDocument() to protected.
+
+2011-01-11  Merge 75548 - BUGCR69275 - Abhishek Arya  <inferno@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        RefPtr the FrameView to prevent scrollbar from getting deleted inside
+        its scroll event.
+        https://bugs.webkit.org/show_bug.cgi?id=52238
+
+        Test: scrollbars/scrollable-iframe-remove-crash.html
+
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::scrollTo):
+
+2011-01-11  Abhishek Arya  <inferno@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        RefPtr text node in setOuterText since calling appendData
+        on a text node can fire away dom event listener which might
+        remove the text node from underneath.
+        https://bugs.webkit.org/show_bug.cgi?id=52163
+
+        Test: fast/dom/text-node-append-data-remove-crash.html
+
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::setOuterText):
+
 2010-12-07  Jeremy Orlow  <jorlow@chromium.org>
 
         Reviewed by Steve Block.
index 767c11e..948dc74 100644 (file)
@@ -34,7 +34,7 @@ namespace WebCore {
 CSSCanvasValue::~CSSCanvasValue()
 {
     if (m_element)
-        m_element->setObserver(0);
+        m_element->removeObserver(this);
 }
 
 String CSSCanvasValue::cssText() const
@@ -79,7 +79,7 @@ HTMLCanvasElement* CSSCanvasValue::element(Document* document)
         m_element = document->getCSSCanvasElement(m_name);
         if (!m_element)
             return 0;
-        m_element->setObserver(this);
+        m_element->addObserver(this);
     }
     return m_element;
 }
index 2ebbece..c4b5de7 100644 (file)
@@ -70,7 +70,7 @@ CSSCursorImageValue::~CSSCursorImageValue()
 
     for (; it != end; ++it) {
         SVGElement* referencedElement = *it;
-        referencedElement->cursorElementRemoved();
+        referencedElement->cursorImageValueRemoved();
         if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->document()))
             cursorElement->removeClient(referencedElement);
     }
index 7367ab2..0a312af 100644 (file)
@@ -76,6 +76,7 @@ void CSSRuleList::deleteRule(unsigned index)
         return;
     }
 
+    m_lstCSSRules[index]->setParent(0);
     m_lstCSSRules.remove(index);
 }
 
index 04df693..d5487a1 100644 (file)
@@ -164,6 +164,7 @@ void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec)
     }
 
     ec = 0;
+    item(index)->setParent(0);
     remove(index);
     styleSheetChanged();
 }
index 42a200b..23096df 100644 (file)
@@ -2642,6 +2642,22 @@ static const EventContext* topEventContext(const Vector<EventContext>& ancestors
     return ancestors.isEmpty() ? 0 : &ancestors.last();
 }
 
+static EventDispatchBehavior determineDispatchBehavior(Event* event)
+{
+    // Per XBL 2.0 spec, mutation events should never cross shadow DOM boundary:
+    // http://dev.w3.org/2006/xbl2/#event-flow-and-targeting-across-shadow-s
+    if (event->isMutationEvent())
+        return StayInsideShadowDOM;
+
+    // WebKit never allowed selectstart event to cross the the shadow DOM boundary.
+    // Changing this breaks existing sites.
+    // See https://bugs.webkit.org/show_bug.cgi?id=52195 for details.
+    if (event->type() == eventNames().selectstartEvent)
+        return StayInsideShadowDOM;
+
+    return RetargetEvent;
+}
+
 bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
 {
     RefPtr<Event> event(prpEvent);
@@ -2656,7 +2672,7 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
     RefPtr<Node> thisNode(this);
     RefPtr<EventTarget> originalTarget = event->target();
     Vector<EventContext> ancestors;
-    getEventAncestors(ancestors, originalTarget.get(), event->isMutationEvent() ? StayInsideShadowDOM : RetargetEvent);
+    getEventAncestors(ancestors, originalTarget.get(), determineDispatchBehavior(event.get()));
 
     WindowEventContext windowContext(event.get(), this, topEventContext(ancestors));
 
index 5507b83..71bf08e 100644 (file)
 #include <stdio.h>
 #include <wtf/text/CString.h>
 #include <wtf/RefCountedLeakCounter.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
+typedef Vector<RefPtr<Node> > NodeVector;
+
 using namespace std;
 
 #ifndef NDEBUG
@@ -595,9 +598,6 @@ bool Range::intersectsNode(Node* refNode, ExceptionCode& ec)
 
 PassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionCode& ec)
 {
-    // FIXME: To work properly with mutation events, we will have to take into account
-    // situations where the tree is being transformed while we work on it - ugh!
-
     RefPtr<DocumentFragment> fragment;
     if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
         fragment = DocumentFragment::create(m_ownerDocument.get());
@@ -655,21 +655,20 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
                 pi->setData(data, ec);
             }
         } else {
-            Node* n = m_start.container()->firstChild();
+            RefPtr<Node> n = m_start.container()->firstChild();
             int i;
             for (i = 0; n && i < m_start.offset(); i++) // skip until start offset
                 n = n->nextSibling();
             int endOffset = m_end.offset();
-            while (n && i < endOffset) { // delete until end offset
-                Node* next = n->nextSibling();
+            RefPtr<Node> next;
+            for (; n && i < endOffset; n = next, i++) { // delete until end offset
+                next = n->nextSibling();
                 if (action == EXTRACT_CONTENTS)
                     fragment->appendChild(n, ec); // will remove n from its parent
                 else if (action == CLONE_CONTENTS)
                     fragment->appendChild(n->cloneNode(true), ec);
                 else
-                    toContainerNode(m_start.container())->removeChild(n, ec);
-                n = next;
-                i++;
+                    m_start.container()->removeChild(n.get(), ec);
             }
         }
         return fragment.release();
@@ -720,39 +719,47 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
         } else {
             if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
                 leftContents = m_start.container()->cloneNode(false);
+            NodeVector nodes;
             Node* n = m_start.container()->firstChild();
-            for (int i = 0; n && i < m_start.offset(); i++) // skip until start offset
-                n = n->nextSibling();
-            while (n) { // process until end
-                Node* next = n->nextSibling();
+            for (int i = 0; n; n = n->nextSibling(), i++) {
+                if (i < m_start.offset())
+                    continue; // Skip until start offset.
+                nodes.append(n);
+            }
+            for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) {
+                Node* n = it->get();
                 if (action == EXTRACT_CONTENTS)
-                    leftContents->appendChild(n, ec); // will remove n from start container
+                    leftContents->appendChild(n, ec); // Will remove n from start container.
                 else if (action == CLONE_CONTENTS)
                     leftContents->appendChild(n->cloneNode(true), ec);
                 else
                     toContainerNode(m_start.container())->removeChild(n, ec);
-                n = next;
             }
         }
 
-        ContainerNode* leftParent = m_start.container()->parentNode();
-        Node* n = m_start.container()->nextSibling();
-        for (; leftParent != commonRoot; leftParent = leftParent->parentNode()) {
+        NodeVector ancestorNodes;
+        for (ContainerNode* n = m_start.container()->parentNode(); n && n != commonRoot; n = n->parentNode())
+            ancestorNodes.append(n);
+        RefPtr<Node> n = m_start.container()->nextSibling();
+        for (NodeVector::const_iterator it = ancestorNodes.begin(); it != ancestorNodes.end(); it++) {
+            Node* leftParent = it->get();
             if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
                 RefPtr<Node> leftContentsParent = leftParent->cloneNode(false);
-                leftContentsParent->appendChild(leftContents, ec);
-                leftContents = leftContentsParent;
+                if (leftContentsParent) { // Might have been removed already during mutation event.
+                    leftContentsParent->appendChild(leftContents, ec);
+                    leftContents = leftContentsParent;
+                }
             }
 
-            Node* next;
+            RefPtr<Node> next;
             for (; n; n = next) {
                 next = n->nextSibling();
                 if (action == EXTRACT_CONTENTS)
-                    leftContents->appendChild(n, ec); // will remove n from leftParent
+                    leftContents->appendChild(n.get(), ec); // will remove n from leftParent
                 else if (action == CLONE_CONTENTS)
                     leftContents->appendChild(n->cloneNode(true), ec);
                 else
-                    leftParent->removeChild(n, ec);
+                    leftParent->removeChild(n.get(), ec);
             }
             n = leftParent->nextSibling();
         }
@@ -786,15 +793,16 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
                 rightContents = m_end.container()->cloneNode(false);
             Node* n = m_end.container()->firstChild();
             if (n && m_end.offset()) {
-                for (int i = 0; i + 1 < m_end.offset(); i++) { // skip to end.offset()
-                    Node* next = n->nextSibling();
-                    if (!next)
+                NodeVector nodes;
+                int i = 0;
+                do {
+                    nodes.append(n);
+                    if (!n->nextSibling())
                         break;
-                    n = next;
-                }
-                Node* prev;
-                for (; n; n = prev) {
-                    prev = n->previousSibling();
+                    n = n->nextSibling();
+                } while (i + 1 < m_end.offset());
+                for (int i = nodes.size() - 1; i >= 0; i--) {
+                    n = nodes[i].get();
                     if (action == EXTRACT_CONTENTS)
                         rightContents->insertBefore(n, rightContents->firstChild(), ec); // will remove n from its parent
                     else if (action == CLONE_CONTENTS)
@@ -868,11 +876,12 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
     if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents)
         fragment->appendChild(leftContents, ec);
 
-    Node* next;
-    Node* n;
     if (processStart) {
-        for (n = processStart; n && n != processEnd; n = next) {
-            next = n->nextSibling();
+        NodeVector nodes;
+        for (Node* n = processStart; n && n != processEnd; n = n->nextSibling())
+            nodes.append(n);
+        for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) {
+            Node* n = it->get();
             if (action == EXTRACT_CONTENTS)
                 fragment->appendChild(n, ec); // will remove from commonRoot
             else if (action == CLONE_CONTENTS)
index fb52e56..d7b101a 100644 (file)
 #include "markup.h"
 #include "visible_units.h"
 #include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
+typedef Vector<RefPtr<Node> > NodeVector;
+
 using namespace HTMLNames;
 
 enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment };
@@ -682,7 +685,12 @@ void ReplaceSelectionCommand::handleStyleSpans()
 void ReplaceSelectionCommand::copyStyleToChildren(Node* parentNode, const CSSMutableStyleDeclaration* parentStyle)
 {
     ASSERT(parentNode->hasTagName(spanTag));
-    for (Node* childNode = parentNode->firstChild(); childNode; childNode = childNode->nextSibling()) {
+    NodeVector childNodes;
+    for (RefPtr<Node> childNode = parentNode->firstChild(); childNode; childNode = childNode->nextSibling())
+        childNodes.append(childNode);
+        
+    for (NodeVector::const_iterator it = childNodes.begin(); it != childNodes.end(); it++) {
+        Node* childNode = it->get();
         if (childNode->isTextNode() || !isBlock(childNode) || childNode->hasTagName(preTag)) {
             // In this case, put a span tag around the child node.
             RefPtr<Node> newNode = parentNode->cloneNode(false);
@@ -864,6 +872,10 @@ void ReplaceSelectionCommand::doApply()
     
     // Inserting content could cause whitespace to collapse, e.g. inserting <div>foo</div> into hello^ world.
     prepareWhitespaceAtPositionForSplit(insertionPos);
+
+    // If the downstream node has been removed there's no point in continuing.
+    if (!insertionPos.downstream().node())
+      return;
     
     // NOTE: This would be an incorrect usage of downstream() if downstream() were changed to mean the last position after 
     // p that maps to the same visible position as p (since in the case where a br is at the end of a block and collapsed 
@@ -942,8 +954,8 @@ void ReplaceSelectionCommand::doApply()
     bool plainTextFragment = isPlainTextMarkup(refNode.get());
 
     while (node) {
-        Node* next = node->nextSibling();
-        fragment.removeNode(node);
+        RefPtr<Node> next = node->nextSibling();
+        fragment.removeNode(node.get());
         insertNodeAfterAndUpdateNodesInserted(node, refNode.get());
 
         // Mutation events (bug 22634) may have already removed the inserted content
index fea70d1..e8ffe5e 100644 (file)
@@ -71,7 +71,6 @@ static const float MaxSkiaDim = 32767.0F; // Maximum width/height in CSS pixels.
 
 HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document* document)
     : HTMLElement(tagName, document)
-    , m_observer(0)
     , m_size(DefaultWidth, DefaultHeight)
     , m_ignoreReset(false)
     , m_pageScaleFactor(document->frame() ? document->frame()->page()->chrome()->scaleFactor() : 1)
@@ -93,8 +92,9 @@ PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(const QualifiedName& tag
 
 HTMLCanvasElement::~HTMLCanvasElement()
 {
-    if (m_observer)
-        m_observer->canvasDestroyed(this);
+    HashSet<CanvasObserver*>::iterator end = m_observers.end();
+    for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+        (*it)->canvasDestroyed(this);
 }
 
 void HTMLCanvasElement::parseMappedAttribute(Attribute* attr)
@@ -117,6 +117,16 @@ RenderObject* HTMLCanvasElement::createRenderer(RenderArena* arena, RenderStyle*
     return HTMLElement::createRenderer(arena, style);
 }
 
+void HTMLCanvasElement::addObserver(CanvasObserver* observer)
+{
+    m_observers.add(observer);
+}
+
+void HTMLCanvasElement::removeObserver(CanvasObserver* observer)
+{
+    m_observers.remove(observer);
+}
+
 void HTMLCanvasElement::setHeight(int value)
 {
     setAttribute(heightAttr, String::number(value));
@@ -200,8 +210,9 @@ void HTMLCanvasElement::didDraw(const FloatRect& rect)
         ro->repaintRectangle(enclosingIntRect(m_dirtyRect));
     }
 
-    if (m_observer)
-        m_observer->canvasChanged(this, rect);
+    HashSet<CanvasObserver*>::iterator end = m_observers.end();
+    for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+        (*it)->canvasChanged(this, rect);
 }
 
 void HTMLCanvasElement::reset()
@@ -238,8 +249,9 @@ void HTMLCanvasElement::reset()
         }
     }
 
-    if (m_observer)
-        m_observer->canvasResized(this);
+    HashSet<CanvasObserver*>::iterator end = m_observers.end();
+    for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+        (*it)->canvasResized(this);
 }
 
 void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r)
index e6c0155..30f0d35 100644 (file)
@@ -65,7 +65,8 @@ public:
     static PassRefPtr<HTMLCanvasElement> create(const QualifiedName&, Document*);
     virtual ~HTMLCanvasElement();
 
-    void setObserver(CanvasObserver* observer) { m_observer = observer; }
+    void addObserver(CanvasObserver* observer);
+    void removeObserver(CanvasObserver* observer);
 
     // Attributes and functions exposed to script
     int width() const { return size().width(); }
@@ -154,7 +155,7 @@ private:
     void setSurfaceSize(const IntSize&);
     bool hasCreatedImageBuffer() const { return m_hasCreatedImageBuffer; }
 
-    CanvasObserver* m_observer;
+    HashSet<CanvasObserver*> m_observers;
 
     IntSize m_size;
 
index 4dcf998..0bd6ba5 100644 (file)
@@ -474,7 +474,7 @@ void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
     // Is previous node a text node? If so, merge into it.
     Node* prev = t->previousSibling();
     if (prev && prev->isTextNode()) {
-        Text* textPrev = static_cast<Text*>(prev);
+        RefPtr<Text> textPrev = static_cast<Text*>(prev);
         textPrev->appendData(t->data(), ec);
         if (ec)
             return;
@@ -487,7 +487,7 @@ void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
     // Is next node a text node? If so, merge it in.
     Node* next = t->nextSibling();
     if (next && next->isTextNode()) {
-        Text* textNext = static_cast<Text*>(next);
+        RefPtr<Text> textNext = static_cast<Text*>(next);
         t->appendData(textNext->data(), ec);
         if (ec)
             return;
index 2f5d414..daf4b93 100644 (file)
@@ -152,6 +152,13 @@ void HTMLFormControlElement::attach()
          focus();
 }
 
+void HTMLFormControlElement::willMoveToNewOwnerDocument()
+{
+    if (fastHasAttribute(formAttr))
+        document()->unregisterFormElementWithFormAttribute(this);
+    HTMLElement::willMoveToNewOwnerDocument();
+}
+
 void HTMLFormControlElement::insertedIntoTree(bool deep)
 {
     if (fastHasAttribute(formAttr)) {
@@ -482,6 +489,7 @@ void HTMLFormControlElement::attributeChanged(Attribute* attr, bool preserveDecl
                 m_form->registerFormElement(this);
             else
                 document()->checkedRadioButtons().addButton(this);
+            document()->unregisterFormElementWithFormAttribute(this);
         } else
             resetFormOwner(0);
     }
index 568f63e..c5ed013 100644 (file)
@@ -109,6 +109,7 @@ protected:
     virtual void attach();
     virtual void insertedIntoTree(bool deep);
     virtual void removedFromTree(bool deep);
+    virtual void willMoveToNewOwnerDocument();
 
     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
     virtual bool isMouseFocusable() const;
index af66795..d6fe6dd 100644 (file)
@@ -131,47 +131,52 @@ PassRefPtr<DocumentParser> MediaDocument::createParser()
     return MediaDocumentParser::create(this);
 }
 
+static inline HTMLVideoElement* descendentVideoElement(Node* node)
+{
+    ASSERT(node);
+
+    if (node->hasTagName(videoTag))
+        return static_cast<HTMLVideoElement*>(node);
+
+    RefPtr<NodeList> nodeList = node->getElementsByTagNameNS(videoTag.namespaceURI(), videoTag.localName());
+   
+    if (nodeList.get()->length() > 0)
+        return static_cast<HTMLVideoElement*>(nodeList.get()->item(0));
+
+    return 0;
+}
+
 void MediaDocument::defaultEventHandler(Event* event)
 {
     // Match the default Quicktime plugin behavior to allow 
     // clicking and double-clicking to pause and play the media.
     Node* targetNode = event->target()->toNode();
-    if (targetNode && targetNode->hasTagName(videoTag)) {
-        HTMLVideoElement* video = static_cast<HTMLVideoElement*>(targetNode);
-        if (event->type() == eventNames().clickEvent) {
-            if (!video->canPlay()) {
-                video->pause(event->fromUserGesture());
-                event->setDefaultHandled();
-            }
-        } else if (event->type() == eventNames().dblclickEvent) {
-            if (video->canPlay()) {
-                video->play(event->fromUserGesture());
-                event->setDefaultHandled();
-            }
-        }
-    }
+    if (!targetNode)
+        return;
+
+    HTMLVideoElement* video = descendentVideoElement(targetNode);
+    if (!video)
+        return;
 
-    if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent()) {
-        HTMLVideoElement* video = 0;
-        if (targetNode) {
-            if (targetNode->hasTagName(videoTag))
-                video = static_cast<HTMLVideoElement*>(targetNode);
-            else {
-                RefPtr<NodeList> nodeList = targetNode->getElementsByTagName("video");
-                if (nodeList.get()->length() > 0)
-                    video = static_cast<HTMLVideoElement*>(nodeList.get()->item(0));
-            }
+    if (event->type() == eventNames().clickEvent) {
+        if (!video->canPlay()) {
+            video->pause(event->fromUserGesture());
+            event->setDefaultHandled();
         }
-        if (video) {
-            KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(event);
-            if (keyboardEvent->keyIdentifier() == "U+0020") { // space
-                if (video->paused()) {
-                    if (video->canPlay())
-                        video->play(event->fromUserGesture());
-                } else
-                    video->pause(event->fromUserGesture());
-                event->setDefaultHandled();
-            }
+    } else if (event->type() == eventNames().dblclickEvent) {
+        if (video->canPlay()) {
+            video->play(event->fromUserGesture());
+            event->setDefaultHandled();
+        }
+    } else if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent()) {
+        KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(event);
+        if (keyboardEvent->keyIdentifier() == "U+0020") { // space
+            if (video->paused()) {
+                if (video->canPlay())
+                    video->play(event->fromUserGesture());
+            } else
+                video->pause(event->fromUserGesture());
+            event->setDefaultHandled();
         }
     }
 }
@@ -196,11 +201,7 @@ void MediaDocument::replaceMediaElementTimerFired(Timer<MediaDocument>*)
     htmlBody->setAttribute(marginwidthAttr, "0");
     htmlBody->setAttribute(marginheightAttr, "0");
 
-    RefPtr<NodeList> nodeList = htmlBody->getElementsByTagName("video");
-
-    if (nodeList.get()->length() > 0) {
-        HTMLVideoElement* videoElement = static_cast<HTMLVideoElement*>(nodeList.get()->item(0));
-
+    if (HTMLVideoElement* videoElement = descendentVideoElement(htmlBody)) {
         RefPtr<Element> element = Document::createElement(embedTag, false);
         HTMLEmbedElement* embedElement = static_cast<HTMLEmbedElement*>(element.get());
 
index 31d951a..ee06e54 100644 (file)
@@ -186,7 +186,7 @@ void InspectorCSSAgent::getStylesForNode2(long nodeId, RefPtr<InspectorValue>* r
         resultObject->setObject("inlineStyle", styleSheet->buildObjectForStyle(element->style()));
 
     RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(element, true); // Support the viewing of :visited information in computed style.
-    RefPtr<InspectorStyle> computedInspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo.get(), 0);
+    RefPtr<InspectorStyle> computedInspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0);
     resultObject->setObject("computedStyle", computedInspectorStyle->buildObjectForStyle());
 
     CSSStyleSelector* selector = element->ownerDocument()->styleSelector();
@@ -248,7 +248,7 @@ void InspectorCSSAgent::getComputedStyleForNode2(long nodeId, RefPtr<InspectorVa
         return;
 
     RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(element, true);
-    RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo.get(), 0);
+    RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0);
     *style = inspectorStyle->buildObjectForStyle();
 }
 
index 243b7ac..d0ae442 100644 (file)
@@ -839,11 +839,12 @@ void InspectorController::willSendRequest(unsigned long identifier, ResourceRequ
     if (!enabled())
         return;
 
-    request.setReportLoadTiming(true);
-    // Only enable raw headers if front-end is attached, as otherwise we may lack
+    // Only enable load timing and raw headers if front-end is attached, as otherwise we may produce overhead.
     // permissions to fetch the headers.
-    if (m_frontend)
+    if (m_frontend) {
+        request.setReportLoadTiming(true);
         request.setReportRawHeaders(true);
+    }
 
     bool isMainResource = m_mainResourceIdentifier == identifier;
 
index c468e3b..b115d85 100644 (file)
@@ -131,6 +131,19 @@ static PassRefPtr<CSSRuleList> asCSSRuleList(StyleBase* styleBase)
     return 0;
 }
 
+PassRefPtr<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
+{
+    return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet));
+}
+
+InspectorStyle::InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
+    : m_styleId(styleId)
+    , m_style(style)
+    , m_parentStyleSheet(parentStyleSheet)
+{
+    ASSERT(m_style);
+}
+
 PassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const
 {
     RefPtr<InspectorObject> result = InspectorObject::create();
@@ -141,7 +154,7 @@ PassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const
     propertiesObject->setString("width", m_style->getPropertyValue("width"));
     propertiesObject->setString("height", m_style->getPropertyValue("height"));
 
-    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet ? m_parentStyleSheet->ruleSourceDataFor(m_style) : 0;
+    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet ? m_parentStyleSheet->ruleSourceDataFor(m_style.get()) : 0;
     if (sourceData) {
         propertiesObject->setNumber("startOffset", sourceData->styleSourceData->styleBodyRange.start);
         propertiesObject->setNumber("endOffset", sourceData->styleSourceData->styleBodyRange.end);
@@ -215,7 +228,7 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText,
         }
     } else {
         // Insert at index.
-        RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style);
+        RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get());
         if (!sourceData)
             return false;
         String text;
@@ -255,7 +268,7 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText,
         }
 
         text.insert(textToSet, propertyStart);
-        m_parentStyleSheet->setStyleText(m_style, text);
+        m_parentStyleSheet->setStyleText(m_style.get(), text);
     }
 
     // Recompute subsequent disabled property ranges if acting on a non-disabled property.
@@ -269,7 +282,7 @@ bool InspectorStyle::toggleProperty(unsigned index, bool disable)
     ASSERT(m_parentStyleSheet);
     if (!m_parentStyleSheet->ensureParsedDataReady())
         return false; // Can toggle only source-based properties.
-    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style);
+    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get());
     if (!sourceData)
         return false; // No source data for the style.
 
@@ -310,7 +323,7 @@ unsigned InspectorStyle::disabledIndexByOrdinal(unsigned ordinal, bool canUseSub
 bool InspectorStyle::styleText(String* result) const
 {
     // Precondition: m_parentStyleSheet->ensureParsedDataReady() has been called successfully.
-    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style);
+    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get());
     if (!sourceData)
         return false;
 
@@ -379,7 +392,7 @@ bool InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>* resul
     if (disabledIndex < disabledLength)
         disabledProperty = m_disabledProperties.at(disabledIndex);
 
-    RefPtr<CSSRuleSourceData> sourceData = (m_parentStyleSheet && m_parentStyleSheet->ensureParsedDataReady()) ? m_parentStyleSheet->ruleSourceDataFor(m_style) : 0;
+    RefPtr<CSSRuleSourceData> sourceData = (m_parentStyleSheet && m_parentStyleSheet->ensureParsedDataReady()) ? m_parentStyleSheet->ruleSourceDataFor(m_style.get()) : 0;
     Vector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : 0;
     if (sourcePropertyData) {
         String styleDeclaration;
@@ -506,7 +519,7 @@ bool InspectorStyle::replacePropertyInStyleText(const InspectorStyleProperty& pr
         return false;
     const SourceRange& range = property.sourceData.range;
     text.replace(range.start, range.end - range.start, newText);
-    success = m_parentStyleSheet->setStyleText(m_style, text);
+    success = m_parentStyleSheet->setStyleText(m_style.get(), text);
     return success;
 }
 
@@ -561,7 +574,12 @@ Vector<String> InspectorStyle::longhandProperties(const String& shorthandPropert
     return properties;
 }
 
-InspectorStyleSheet::InspectorStyleSheet(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL)
+PassRefPtr<InspectorStyleSheet> InspectorStyleSheet::create(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL)
+{
+    return adoptRef(new InspectorStyleSheet(id, pageStyleSheet, origin, documentURL));
+}
+
+InspectorStyleSheet::InspectorStyleSheet(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL)
     : m_id(id)
     , m_pageStyleSheet(pageStyleSheet)
     , m_origin(origin)
@@ -1090,12 +1108,17 @@ void InspectorStyleSheet::collectFlatRules(PassRefPtr<CSSRuleList> ruleList, Vec
     }
 }
 
-InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const String& id, Element* element, const String& origin)
+PassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(const String& id, PassRefPtr<Element> element, const String& origin)
+{
+    return adoptRef(new InspectorStyleSheetForInlineStyle(id, element, origin));
+}
+
+InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const String& id, PassRefPtr<Element> element, const String& origin)
     : InspectorStyleSheet(id, 0, origin, "")
     , m_element(element)
     , m_ruleSourceData(0)
 {
-    ASSERT(element);
+    ASSERT(m_element);
     m_inspectorStyle = InspectorStyle::create(InspectorCSSId(id, 0), inlineStyle(), this);
 }
 
@@ -1152,7 +1175,7 @@ bool InspectorStyleSheetForInlineStyle::getStyleAttributeRanges(RefPtr<CSSStyleS
     if (!m_element->isStyledElement())
         return false;
 
-    String styleText = static_cast<StyledElement*>(m_element)->getAttribute(styleAttributeName);
+    String styleText = static_cast<StyledElement*>(m_element.get())->getAttribute(styleAttributeName);
     if (styleText.isEmpty()) {
         (*result)->styleBodyRange.start = 0;
         (*result)->styleBodyRange.end = 0;
index b649bed..2e5f2bc 100644 (file)
@@ -26,6 +26,7 @@
 #define InspectorStyleSheet_h
 
 #include "CSSPropertySourceData.h"
+#include "CSSStyleDeclaration.h"
 #include "InspectorValues.h"
 #include "PlatformString.h"
 
@@ -40,7 +41,6 @@ class ParsedStyleSheet;
 namespace WebCore {
 
 class CSSRuleList;
-class CSSStyleDeclaration;
 class CSSStyleSheet;
 class Document;
 class Element;
@@ -121,26 +121,17 @@ struct InspectorStyleProperty {
 
 class InspectorStyle : public RefCounted<InspectorStyle> {
 public:
-    static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, CSSStyleDeclaration* style, InspectorStyleSheet* parentStyleSheet)
-    {
-        return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet));
-    }
-
-    InspectorStyle(const InspectorCSSId& styleId, CSSStyleDeclaration* style, InspectorStyleSheet* parentStyleSheet)
-        : m_styleId(styleId)
-        , m_style(style)
-        , m_parentStyleSheet(parentStyleSheet)
-    {
-        ASSERT(style);
-    }
+    static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
 
-    CSSStyleDeclaration* cssStyle() const { return m_style; }
+    CSSStyleDeclaration* cssStyle() const { return m_style.get(); }
     PassRefPtr<InspectorObject> buildObjectForStyle() const;
     bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); }
     bool setPropertyText(unsigned index, const String& text, bool overwrite);
     bool toggleProperty(unsigned index, bool disable);
 
 private:
+    InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
+
     static unsigned disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent, Vector<InspectorStyleProperty>& allProperties);
 
     bool styleText(String* result) const;
@@ -155,7 +146,7 @@ private:
     Vector<String> longhandProperties(const String& shorthandProperty) const;
 
     InspectorCSSId m_styleId;
-    CSSStyleDeclaration* m_style;
+    RefPtr<CSSStyleDeclaration> m_style;
     InspectorStyleSheet* m_parentStyleSheet;
     Vector<InspectorStyleProperty> m_disabledProperties;
 };
@@ -163,17 +154,13 @@ private:
 class InspectorStyleSheet : public RefCounted<InspectorStyleSheet> {
 public:
     typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle> > InspectorStyleMap;
-    static PassRefPtr<InspectorStyleSheet> create(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL)
-    {
-        return adoptRef(new InspectorStyleSheet(id, pageStyleSheet, origin, documentURL));
-    }
+    static PassRefPtr<InspectorStyleSheet> create(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL);
 
-    InspectorStyleSheet(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL);
     virtual ~InspectorStyleSheet();
 
     String id() const { return m_id; }
     String finalURL() const;
-    CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet; }
+    CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); }
     void reparseStyleSheet(const String&);
     bool setText(const String&);
     bool setRuleSelector(const InspectorCSSId&, const String& selector);
@@ -189,6 +176,8 @@ public:
     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
 
 protected:
+    InspectorStyleSheet(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL);
+
     bool canBind() const { return m_origin != "userAgent" && m_origin != "user"; }
     InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const;
     virtual Document* ownerDocument() const;
@@ -218,7 +207,7 @@ private:
     PassRefPtr<InspectorArray> buildArrayForRuleList(CSSRuleList*);
 
     String m_id;
-    CSSStyleSheet* m_pageStyleSheet;
+    RefPtr<CSSStyleSheet> m_pageStyleSheet;
     String m_origin;
     String m_documentURL;
     bool m_isRevalidating;
@@ -231,16 +220,14 @@ private:
 
 class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet {
 public:
-    static PassRefPtr<InspectorStyleSheetForInlineStyle> create(const String& id, Element* element, const String& origin)
-    {
-        return adoptRef(new InspectorStyleSheetForInlineStyle(id, element, origin));
-    }
+    static PassRefPtr<InspectorStyleSheetForInlineStyle> create(const String& id, PassRefPtr<Element> element, const String& origin);
 
-    InspectorStyleSheetForInlineStyle(const String& id, Element* element, const String& origin);
     virtual bool text(String* result) const;
     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
 
 protected:
+    InspectorStyleSheetForInlineStyle(const String& id, PassRefPtr<Element> element, const String& origin);
+
     virtual Document* ownerDocument() const;
     virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; }
@@ -256,7 +243,7 @@ private:
     CSSStyleDeclaration* inlineStyle() const;
     bool getStyleAttributeRanges(RefPtr<CSSStyleSourceData>* result);
 
-    Element* m_element;
+    RefPtr<Element> m_element;
     RefPtr<CSSRuleSourceData> m_ruleSourceData;
     RefPtr<InspectorStyle> m_inspectorStyle;
 };
index d4bbf90..3ec4ba2 100644 (file)
@@ -53,24 +53,6 @@ WebInspector.AuditLauncherView = function(runnerCallback)
 }
 
 WebInspector.AuditLauncherView.prototype = {
-    updateResourceTrackingState: function(isTracking)
-    {
-        if (!this._auditPresentStateLabelElement)
-            return;
-
-        if (isTracking) {
-            this._auditPresentStateLabelElement.nodeValue = WebInspector.UIString("Audit Present State");
-            this._auditPresentStateElement.disabled = false;
-            this._auditPresentStateElement.parentElement.removeStyleClass("disabled");
-        } else {
-            this._resetResourceCount();
-            this._auditPresentStateLabelElement.nodeValue = WebInspector.UIString("Audit Present State (Resource Tracking must be enabled)");
-            this._auditPresentStateElement.disabled = true;
-            this._auditPresentStateElement.parentElement.addStyleClass("disabled");
-            this.auditReloadedStateElement.checked = true;
-        }
-    },
-
     get totalResources()
     {
         return this._totalResources;
@@ -237,7 +219,7 @@ WebInspector.AuditLauncherView.prototype = {
         this._auditPresentStateElement.name = "audit-mode";
         this._auditPresentStateElement.type = "radio";
         this._auditPresentStateElement.checked = true;
-        this._auditPresentStateLabelElement = document.createTextNode("");
+        this._auditPresentStateLabelElement = document.createTextNode(WebInspector.UIString("Audit Present State"));
         labelElement.appendChild(this._auditPresentStateElement);
         labelElement.appendChild(this._auditPresentStateLabelElement);
         this._buttonContainerElement.appendChild(labelElement);
@@ -267,7 +249,6 @@ WebInspector.AuditLauncherView.prototype = {
         this._contentElement.appendChild(this._buttonContainerElement);
 
         this._selectAllClicked(this._selectAllCheckboxElement.checked);
-        this.updateResourceTrackingState();
         this._updateButton();
         this._updateResourceProgress();
     },
index 096f8ce..c42077f 100644 (file)
@@ -248,12 +248,6 @@ WebInspector.AuditsPanel.prototype = {
             x.show(this.viewsContainerElement);
     },
 
-    show: function()
-    {
-        WebInspector.Panel.prototype.show.call(this);
-        this._updateLauncherViewControls(!WebInspector.panels.resources || WebInspector.panels.resources.resourceTrackingEnabled);
-    },
-
     reset: function()
     {
         this._launcherView.reset();
@@ -271,12 +265,6 @@ WebInspector.AuditsPanel.prototype = {
         this.viewsContainerElement.style.left = width + "px";
     },
 
-    _updateLauncherViewControls: function(isTracking)
-    {
-        if (this._launcherView)
-            this._launcherView.updateResourceTrackingState(isTracking);
-    },
-
     _clearButtonClicked: function()
     {
         this.auditsItemTreeElement.reveal();
index 8c1ddac..992d8c7 100644 (file)
@@ -268,6 +268,7 @@ WebInspector.ResourceManager.prototype = {
             if (mainResource) {
                 WebInspector.mainResource = mainResource;
                 mainResource.isMainResource = true;
+                WebInspector.panels.network.refreshResource(mainResource); 
             }
         }
     },
index db72486..5399953 100644 (file)
@@ -1202,6 +1202,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
         this.valueElement = valueElement;
 
         if (value) {
+            var self = this;
+
             function processValue(regex, processor, nextProcessor, valueText)
             {
                 var container = document.createDocumentFragment();
@@ -1225,10 +1227,19 @@ WebInspector.StylePropertyTreeElement.prototype = {
 
             function linkifyURL(url)
             {
+                var hrefUrl = url;
+                var match = hrefUrl.match(/['"]?([^'"]+)/);
+                if (match)
+                    hrefUrl = match[1];
                 var container = document.createDocumentFragment();
                 container.appendChild(document.createTextNode("url("));
-                var hasResource = !!WebInspector.resourceForURL(url);
-                container.appendChild(WebInspector.linkifyURLAsNode(url, url, null, hasResource));
+                if (self._styleRule.sourceURL)
+                    hrefUrl = WebInspector.completeURL(self._styleRule.sourceURL, hrefUrl);
+                else if (WebInspector.panels.elements.focusedDOMNode)
+                    hrefUrl = WebInspector.resourceURLForRelatedNode(WebInspector.panels.elements.focusedDOMNode, hrefUrl);
+                var hasResource = !!WebInspector.resourceForURL(hrefUrl);
+                // FIXME: WebInspector.linkifyURLAsNode() should really use baseURI.
+                container.appendChild(WebInspector.linkifyURLAsNode(hrefUrl, url, null, hasResource));
                 container.appendChild(document.createTextNode(")"));
                 return container;
             }
@@ -1330,7 +1341,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
             var colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?!-))/g;
             var colorProcessor = processValue.bind(window, colorRegex, processColor, null);
 
-            valueElement.appendChild(processValue(/url\(([^)]+)\)/g, linkifyURL, colorProcessor, value));
+            valueElement.appendChild(processValue(/url\(\s*([^)\s]+)\s*\)/g, linkifyURL, colorProcessor, value));
         }
 
         this.listItemElement.removeChildren();
index d002ef3..a36ed94 100644 (file)
@@ -128,6 +128,10 @@ void ResourceLoadNotifier::dispatchWillSendRequest(DocumentLoader* loader, unsig
     if (Page* page = m_frame->page())
         page->inspectorController()->willSendRequest(identifier, request, redirectResponse);
 #endif
+
+    // Report WebTiming for all frames.
+    if (loader && !request.isNull() && request.url() == loader->requestURL())
+        request.setReportLoadTiming(true);
 }
 
 void ResourceLoadNotifier::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
index fb64a76..22e1355 100644 (file)
@@ -1341,7 +1341,7 @@ void DOMWindow::scrollBy(int x, int y) const
 
     m_frame->document()->updateLayoutIgnorePendingStylesheets();
 
-    FrameView* view = m_frame->view();
+    RefPtr<FrameView> view = m_frame->view();
     if (!view)
         return;
 
index 0e2404e..3154a67 100644 (file)
@@ -1254,8 +1254,11 @@ bool FrameView::scrollToAnchor(const String& name)
             if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) {
                 RefPtr<SVGViewElement> viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0;
                 if (viewElement.get()) {
-                    RefPtr<SVGSVGElement> svg = static_cast<SVGSVGElement*>(SVGLocatable::nearestViewportElement(viewElement.get()));
-                    svg->inheritViewAttributes(viewElement.get());
+                    SVGElement* element = SVGLocatable::nearestViewportElement(viewElement.get());
+                    if (element->hasTagName(SVGNames::svgTag)) {
+                        RefPtr<SVGSVGElement> svg = static_cast<SVGSVGElement*>(element);
+                        svg->inheritViewAttributes(viewElement.get());
+                    }
                 }
             }
         }
index 8c5b994..4609f1b 100644 (file)
@@ -393,10 +393,15 @@ RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
 
 RenderBlock* RenderBlock::clone() const
 {
-    RenderBlock* o = new (renderArena()) RenderBlock(node());
-    o->setStyle(style());
-    o->setChildrenInline(childrenInline());
-    return o;
+    RenderBlock* cloneBlock;
+    if (isAnonymousBlock())
+        cloneBlock = createAnonymousBlock();
+    else {
+        cloneBlock = new (renderArena()) RenderBlock(node());
+        cloneBlock->setStyle(style());
+    }
+    cloneBlock->setChildrenInline(childrenInline());
+    return cloneBlock;
 }
 
 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
@@ -404,13 +409,9 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
 {
     // Create a clone of this inline.
-    RenderBlock* cloneBlock;
-    if (isAnonymousBlock())
-        cloneBlock = createAnonymousBlock();
-    else {
-        cloneBlock = clone();
+    RenderBlock* cloneBlock = clone();
+    if (!isAnonymousBlock())
         cloneBlock->setContinuation(oldCont);
-    }
 
     // Now take all of the children from beforeChild to the end and remove
     // them from |this| and place them in the clone.
@@ -435,7 +436,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
         
         // Create a new clone.
         RenderBlock* cloneChild = cloneBlock;
-        cloneBlock = blockCurr->isAnonymousBlock() ? blockCurr->createAnonymousBlock() : blockCurr->clone();
+        cloneBlock = blockCurr->clone();
 
         // Insert our child clone as the first child.
         cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
@@ -946,7 +947,7 @@ static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObje
 
     // Make sure the types of the anonymous blocks match up.
     return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
-           && prev->isAnonymousColumnSpanBlock() == prev->isAnonymousColumnSpanBlock();
+           && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
 }
 
 void RenderBlock::removeChild(RenderObject* oldChild)
@@ -980,14 +981,36 @@ void RenderBlock::removeChild(RenderObject* oldChild)
             blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
                                                             inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer());
             next->setNeedsLayoutAndPrefWidthsRecalc();
+            
+            // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
+            // of "this". we null out prev or next so that is not used later in the function.
+            if (inlineChildrenBlock == prevBlock)
+                prev = 0;
+            else
+                next = 0;
         } else {
             // Take all the children out of the |next| block and put them in
             // the |prev| block.
             nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
-       
+
+            // FIXME: When we destroy nextBlock, it might happen that nextBlock's next sibling block and
+            // oldChild can get merged. Since oldChild is getting removed, we do not want to move
+            // nextBlock's next sibling block's children into it. By setting a fake continuation,
+            // we prevent this from happening.
+            RenderBlock* oldChildBlock = 0;
+            if (oldChild->isAnonymous() && oldChild->isRenderBlock() && !toRenderBlock(oldChild)->continuation()) {
+                oldChildBlock = toRenderBlock(oldChild);
+                oldChildBlock->setContinuation(oldChildBlock);                
+            }          
+            
             // Delete the now-empty block's lines and nuke it.
             nextBlock->deleteLineBoxTree();
             nextBlock->destroy();
+            next = 0;
+
+            // FIXME: Revert the continuation change done above.
+            if (oldChildBlock)
+                oldChildBlock->setContinuation(0);
         }
     }
 
index de10680..43b6b03 100644 (file)
@@ -183,6 +183,8 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
     while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableSection() && lastBox->style()->display() != TABLE_CAPTION && lastBox->style()->display() != TABLE_COLUMN_GROUP)
         lastBox = lastBox->parent();
     if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox)) {
+        if (beforeChild == lastBox)
+            beforeChild = lastBox->firstChild();
         lastBox->addChild(child, beforeChild);
         return;
     }
index 98544a6..ec523b0 100644 (file)
@@ -73,7 +73,9 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
         if (!last)
             last = lastChild();
         if (last && last->isAnonymous() && last->isTableCell()) {
-            last->addChild(child);
+            if (beforeChild == last)
+                beforeChild = last->firstChild();
+            last->addChild(child, beforeChild);
             return;
         }
 
index 30620d2..3598053 100644 (file)
@@ -100,7 +100,9 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
         if (!last)
             last = lastChild();
         if (last && last->isAnonymous()) {
-            last->addChild(child);
+            if (beforeChild == last)
+                beforeChild = last->firstChild();
+            last->addChild(child, beforeChild);
             return;
         }
 
index 615aaab..09773d3 100644 (file)
@@ -222,7 +222,7 @@ void SVGElement::setCursorImageValue(CSSCursorImageValue* cursorImageValue)
     rareData->setCursorImageValue(cursorImageValue);
 }
 
-void SVGElement::cursorImageElementRemoved()
+void SVGElement::cursorImageValueRemoved()
 {
     ASSERT(hasRareSVGData());
     rareSVGData()->setCursorImageValue(0);
index 3098335..0471fcc 100644 (file)
@@ -77,7 +77,7 @@ namespace WebCore {
         void setCursorElement(SVGCursorElement*);
         void cursorElementRemoved();
         void setCursorImageValue(CSSCursorImageValue*);
-        void cursorImageElementRemoved();
+        void cursorImageValueRemoved();
 
         virtual void updateAnimatedSVGAttribute(const QualifiedName&) const;
 
index f2812dd..a873f0b 100644 (file)
@@ -103,7 +103,8 @@ void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
     const HashSet<SVGElementInstance*>::const_iterator end = set.end();
     for (HashSet<SVGElementInstance*>::const_iterator it = set.begin(); it != end; ++it) {
         ASSERT((*it)->correspondingElement() == element);
-        (*it)->correspondingUseElement()->invalidateShadowTree();
+        if (SVGUseElement* element = (*it)->correspondingUseElement())
+            element->invalidateShadowTree();
     }
 
     // Be sure to rebuild use trees, if needed
index 54471c1..160a366 100644 (file)
@@ -57,6 +57,7 @@ namespace WebCore {
         SVGElement* correspondingElement() const { return m_element.get(); }
         SVGUseElement* correspondingUseElement() const { return m_useElement; }
         SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); }
+    void clearUseElement() { m_useElement = 0; }
 
         SVGElementInstance* parentNode() const { return parent(); }
         PassRefPtr<SVGElementInstanceList> childNodes();
index 8168cf6..5377c7f 100644 (file)
@@ -92,13 +92,9 @@ inline SVGLengthType stringToLengthType(const UChar*& ptr, const UChar* end)
         return LengthTypeNumber;
 
     const UChar firstChar = *ptr;
-    ++ptr;
 
-    if (firstChar == '%') {
-        if (ptr == end)
-            return LengthTypePercentage;
-        return LengthTypeUnknown;
-    }
+    if (++ptr == end) 
+        return firstChar == '%' ? LengthTypePercentage : LengthTypeUnknown; 
 
     const UChar secondChar = *ptr;
 
index fc01fd9..909c663 100644 (file)
@@ -130,7 +130,7 @@ void SVGUseElement::insertedIntoDocument()
 void SVGUseElement::removedFromDocument()
 {
     SVGStyledTransformableElement::removedFromDocument();
-    m_targetElementInstance = 0;
+    detachInstance();
 }
 
 void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -496,8 +496,7 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     if (targetElement && targetElement->isSVGElement())
         target = static_cast<SVGElement*>(targetElement);
 
-    if (m_targetElementInstance)
-        m_targetElementInstance = 0;
+    detachInstance();
 
     // Do not allow self-referencing.
     // 'target' may be null, if it's a non SVG namespaced element.
@@ -523,7 +522,7 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     // SVG specification does not say a word about <use> & cycles. My view on this is: just ignore it!
     // Non-appearing <use> content is easier to debug, then half-appearing content.
     if (foundProblem) {
-        m_targetElementInstance = 0;
+        detachInstance();
         return;
     }
 
@@ -556,7 +555,7 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     // Do NOT leave an inconsistent instance tree around, instead destruct it.
     if (!m_targetElementInstance->shadowTreeElement()) {
         shadowRoot->removeAllChildren();
-        m_targetElementInstance = 0;
+        detachInstance();
         return;
     }
 
@@ -595,6 +594,14 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     updateRelativeLengthsInformation();
 }
 
+void SVGUseElement::detachInstance()
+{
+    if (!m_targetElementInstance)
+        return;
+    m_targetElementInstance->clearUseElement();
+    m_targetElementInstance = 0;
+}
+
 RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*)
 {
     return new (arena) RenderSVGShadowTreeRootContainer(this);
@@ -617,7 +624,7 @@ void SVGUseElement::attach()
 void SVGUseElement::detach()
 {
     SVGStyledTransformableElement::detach();
-    m_targetElementInstance = 0;
+    detachInstance();
 }
 
 static bool isDirectReference(Node* n)
index b127450..845270d 100644 (file)
@@ -78,6 +78,7 @@ namespace WebCore {
         friend class RenderSVGShadowTreeRootContainer;
         bool isPendingResource() const { return m_isPendingResource; }
         void buildShadowAndInstanceTree(SVGShadowTreeRootElement*);
+    void detachInstance();
 
         virtual bool selfHasRelativeLengths() const;