summaryrefslogtreecommitdiffstats
path: root/WebCore/dom
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom')
-rw-r--r--WebCore/dom/ActiveDOMObject.cpp2
-rw-r--r--WebCore/dom/ActiveDOMObject.h7
-rw-r--r--WebCore/dom/AsyncScriptRunner.cpp2
-rw-r--r--WebCore/dom/ContainerNode.cpp15
-rw-r--r--WebCore/dom/DOMStringMap.h3
-rw-r--r--WebCore/dom/DatasetDOMStringMap.h2
-rw-r--r--WebCore/dom/Document.cpp112
-rw-r--r--WebCore/dom/Document.h4
-rw-r--r--WebCore/dom/Document.idl2
-rw-r--r--WebCore/dom/Element.cpp29
-rw-r--r--WebCore/dom/Event.cpp5
-rw-r--r--WebCore/dom/Event.h1
-rw-r--r--WebCore/dom/EventTarget.cpp2
-rw-r--r--WebCore/dom/EventTarget.h2
-rw-r--r--WebCore/dom/ExceptionCode.h2
-rw-r--r--WebCore/dom/HashChangeEvent.h65
-rw-r--r--WebCore/dom/HashChangeEvent.idl35
-rw-r--r--WebCore/dom/InputElement.cpp2
-rw-r--r--WebCore/dom/MouseRelatedEvent.cpp9
-rw-r--r--WebCore/dom/Node.cpp58
-rw-r--r--WebCore/dom/Node.h10
-rw-r--r--WebCore/dom/Range.cpp17
-rw-r--r--WebCore/dom/Range.h2
-rw-r--r--WebCore/dom/ScriptElement.cpp24
-rw-r--r--WebCore/dom/ScriptExecutionContext.cpp33
-rw-r--r--WebCore/dom/ScriptExecutionContext.h13
-rw-r--r--WebCore/dom/Touch.cpp8
-rw-r--r--WebCore/dom/ViewportArguments.cpp318
-rw-r--r--WebCore/dom/ViewportArguments.h41
-rw-r--r--WebCore/dom/XMLDocumentParser.h4
-rw-r--r--WebCore/dom/XMLDocumentParserLibxml2.cpp45
31 files changed, 608 insertions, 266 deletions
diff --git a/WebCore/dom/ActiveDOMObject.cpp b/WebCore/dom/ActiveDOMObject.cpp
index 98c9761..0b70b24 100644
--- a/WebCore/dom/ActiveDOMObject.cpp
+++ b/WebCore/dom/ActiveDOMObject.cpp
@@ -66,7 +66,7 @@ bool ActiveDOMObject::canSuspend() const
return false;
}
-void ActiveDOMObject::suspend()
+void ActiveDOMObject::suspend(ReasonForSuspension)
{
}
diff --git a/WebCore/dom/ActiveDOMObject.h b/WebCore/dom/ActiveDOMObject.h
index 73b52d5..a6ec7d3 100644
--- a/WebCore/dom/ActiveDOMObject.h
+++ b/WebCore/dom/ActiveDOMObject.h
@@ -48,8 +48,13 @@ namespace WebCore {
// However, 'suspend' can be called even if canSuspend() would return 'false'. That
// happens in step-by-step JS debugging for example - in this case it would be incorrect
// to stop the object. Exact semantics of suspend is up to the object then.
+ enum ReasonForSuspension {
+ JavaScriptDebuggerPaused,
+ WillShowDialog,
+ DocumentWillBecomeInactive
+ };
virtual bool canSuspend() const;
- virtual void suspend();
+ virtual void suspend(ReasonForSuspension);
virtual void resume();
virtual void stop();
diff --git a/WebCore/dom/AsyncScriptRunner.cpp b/WebCore/dom/AsyncScriptRunner.cpp
index 86251b8..a72df7c 100644
--- a/WebCore/dom/AsyncScriptRunner.cpp
+++ b/WebCore/dom/AsyncScriptRunner.cpp
@@ -78,6 +78,8 @@ void AsyncScriptRunner::timerFired(Timer<AsyncScriptRunner>* timer)
{
ASSERT_UNUSED(timer, timer == &m_timer);
+ RefPtr<Document> protect(m_document);
+
Vector<pair<ScriptElementData*, CachedResourceHandle<CachedScript> > > scripts;
scripts.swap(m_scriptsToExecuteSoon);
size_t size = scripts.size();
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index 46de749..2dd50bb 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -72,7 +72,6 @@ void ContainerNode::removeAllChildren()
removeAllChildrenInContainer<Node, ContainerNode>(this);
}
-
void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
{
NodeVector children;
@@ -82,10 +81,14 @@ void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
for (unsigned i = 0; i < children.size(); ++i) {
ExceptionCode ec = 0;
+ if (children[i]->attached())
+ children[i]->detach();
// FIXME: We need a no mutation event version of adoptNode.
RefPtr<Node> child = document()->adoptNode(children[i].release(), ec);
ASSERT(!ec);
- parserAddChild(child.release());
+ parserAddChild(child.get());
+ if (attached() && !child->attached())
+ child->attach();
}
}
@@ -359,9 +362,7 @@ static void willRemoveChild(Node* child)
// fire removed from document mutation events.
dispatchChildRemovalEvents(child);
-
- if (child->attached())
- child->willRemove();
+ child->willRemove();
}
static void willRemoveChildren(ContainerNode* container)
@@ -373,9 +374,7 @@ static void willRemoveChildren(ContainerNode* container)
for (RefPtr<Node> child = container->firstChild(); child; child = child->nextSibling()) {
// fire removed from document mutation events.
dispatchChildRemovalEvents(child.get());
-
- if (child->attached())
- child->willRemove();
+ child->willRemove();
}
}
diff --git a/WebCore/dom/DOMStringMap.h b/WebCore/dom/DOMStringMap.h
index e91d884..86a22b0 100644
--- a/WebCore/dom/DOMStringMap.h
+++ b/WebCore/dom/DOMStringMap.h
@@ -32,6 +32,7 @@
namespace WebCore {
+class Element;
typedef int ExceptionCode;
class DOMStringMap : public Noncopyable {
@@ -47,6 +48,8 @@ public:
virtual void setItem(const String& name, const String& value, ExceptionCode&) = 0;
virtual void deleteItem(const String& name, ExceptionCode&) = 0;
+ virtual Element* element() = 0;
+
protected:
DOMStringMap()
{
diff --git a/WebCore/dom/DatasetDOMStringMap.h b/WebCore/dom/DatasetDOMStringMap.h
index f82eaa5..632e365 100644
--- a/WebCore/dom/DatasetDOMStringMap.h
+++ b/WebCore/dom/DatasetDOMStringMap.h
@@ -49,6 +49,8 @@ public:
virtual void setItem(const String& name, const String& value, ExceptionCode&);
virtual void deleteItem(const String& name, ExceptionCode&);
+ virtual Element* element() { return m_element; }
+
private:
DatasetDOMStringMap(Element* element)
: m_element(element)
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index a92c5ab..262dad2 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -43,6 +43,7 @@
#include "Console.h"
#include "CookieJar.h"
#include "CustomEvent.h"
+#include "DateComponents.h"
#include "DOMImplementation.h"
#include "DOMWindow.h"
#include "DeviceMotionEvent.h"
@@ -64,6 +65,7 @@
#include "FrameLoader.h"
#include "FrameTree.h"
#include "FrameView.h"
+#include "HashChangeEvent.h"
#include "HTMLAllCollection.h"
#include "HTMLAnchorElement.h"
#include "HTMLBodyElement.h"
@@ -369,7 +371,7 @@ private:
Document* m_document;
};
-Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
+Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML, const KURL& baseURL)
: ContainerNode(0)
, m_compatibilityMode(NoQuirksMode)
, m_compatibilityModeLocked(false)
@@ -439,7 +441,15 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
if (frame || !url.isEmpty())
setURL(url);
+<<<<<<< HEAD
#if !PLATFORM(ANDROID)
+=======
+ // Setting of m_baseURL needs to happen after the setURL call, since that
+ // calls updateBaseURL, which would clobber the passed in value.
+ if (!baseURL.isNull())
+ m_baseURL = baseURL;
+
+>>>>>>> webkit.org at r67908
m_axObjectCache = 0;
#endif
@@ -623,6 +633,11 @@ void Document::setCompatibilityMode(CompatibilityMode mode)
}
}
+String Document::compatMode() const
+{
+ return inQuirksMode() ? "BackCompat" : "CSS1Compat";
+}
+
void Document::resetLinkColor()
{
m_linkColor = Color(0, 0, 238);
@@ -1079,7 +1094,7 @@ PassRefPtr<NodeList> Document::nodesFromRect(int centerX, int centerY, unsigned
if (!frameView)
return 0;
- float zoomFactor = frameView->pageZoomFactor();
+ float zoomFactor = frame->pageZoomFactor();
IntPoint point = roundedIntPoint(FloatPoint(centerX * zoomFactor + view()->scrollX(), centerY * zoomFactor + view()->scrollY()));
IntSize padding(hPadding, vPadding);
@@ -1132,7 +1147,7 @@ Element* Document::elementFromPoint(int x, int y) const
if (!frameView)
return 0;
- float zoomFactor = frameView->pageZoomFactor();
+ float zoomFactor = frame->pageZoomFactor();
IntPoint point = roundedIntPoint(FloatPoint(x * zoomFactor + view()->scrollX(), y * zoomFactor + view()->scrollY()));
if (!frameView->visibleContentRect().contains(point))
@@ -1162,7 +1177,7 @@ PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
if (!frameView)
return 0;
- float zoomFactor = frameView->pageZoomFactor();
+ float zoomFactor = frame->pageZoomFactor();
IntPoint point = roundedIntPoint(FloatPoint(x * zoomFactor + view()->scrollX(), y * zoomFactor + view()->scrollY()));
if (!frameView->visibleContentRect().contains(point))
@@ -2000,26 +2015,6 @@ void Document::close()
}
}
-// FIXME: These settings probably don't work anymore. We should either remove
-// them or make them work properly.
-#ifdef BUILDING_ON_LEOPARD
-static bool shouldCreateImplicitHead(Document* document)
-{
- ASSERT(document);
- Settings* settings = document->page() ? document->page()->settings() : 0;
- return settings ? !settings->needsLeopardMailQuirks() : true;
-}
-#elif defined(BUILDING_ON_TIGER)
-static bool shouldCreateImplicitHead(Document* document)
-{
- ASSERT(document);
- Settings* settings = document->page() ? document->page()->settings() : 0;
- return settings ? !settings->needsTigerMailQuirks() : true;
-}
-#else
-inline bool shouldCreateImplicitHead(Document*) { return true; }
-#endif
-
void Document::implicitClose()
{
// If we're in the middle of recalcStyle, we need to defer the close until the style information is accurate and all elements are re-attached.
@@ -2046,21 +2041,6 @@ void Document::implicitClose()
// Parser should have picked up all preloads by now
m_cachedResourceLoader->clearPreloads();
- // Create a head and a body if we don't have those yet (e.g. for about:blank).
- if (!this->body() && isHTMLDocument()) {
- if (Node* documentElement = this->documentElement()) {
- ExceptionCode ec = 0;
-
- // The implicit <head> isn't expected in older versions of Mail - <rdar://problem/6863795>
- if (!head() && shouldCreateImplicitHead(this)) {
- documentElement->appendChild(HTMLHeadElement::create(this), ec);
- ASSERT(!ec);
- }
- documentElement->appendChild(HTMLBodyElement::create(this), ec);
- ASSERT(!ec);
- }
- }
-
// FIXME: We kick off the icon loader when the Document is done parsing.
// There are earlier opportunities we could start it:
// -When the <head> finishes parsing
@@ -2591,13 +2571,15 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
parseDNSPrefetchControlHeader(content);
else if (equalIgnoringCase(equiv, "x-frame-options")) {
- FrameLoader* frameLoader = frame->loader();
- if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) {
- frameLoader->stopAllLoaders();
- frame->redirectScheduler()->scheduleLocationChange(blankURL(), String());
-
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to display document because display forbidden by X-Frame-Options.\n"));
- frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
+ if (frame) {
+ FrameLoader* frameLoader = frame->loader();
+ if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) {
+ frameLoader->stopAllLoaders();
+ frame->redirectScheduler()->scheduleLocationChange(blankURL(), String());
+
+ DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to display document because display forbidden by X-Frame-Options.\n"));
+ frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
+ }
}
}
}
@@ -3321,7 +3303,7 @@ void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
if (Frame* frame = this->frame()) {
for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
frame->selection()->nodeWillBeRemoved(n);
- frame->dragCaretController()->nodeWillBeRemoved(n);
+ frame->page()->dragCaretController()->nodeWillBeRemoved(n);
}
}
}
@@ -3340,7 +3322,7 @@ void Document::nodeWillBeRemoved(Node* n)
if (Frame* frame = this->frame()) {
frame->selection()->nodeWillBeRemoved(n);
- frame->dragCaretController()->nodeWillBeRemoved(n);
+ frame->page()->dragCaretController()->nodeWillBeRemoved(n);
}
#if ENABLE(FULLSCREEN_API)
@@ -3695,15 +3677,24 @@ void Document::setDomain(const String& newDomain, ExceptionCode& ec)
m_frame->script()->updateSecurityOrigin();
}
+// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-lastmodified
String Document::lastModified() const
{
- Frame* f = frame();
- if (!f)
- return String();
- DocumentLoader* loader = f->loader()->documentLoader();
- if (!loader)
- return String();
- return loader->response().httpHeaderField("Last-Modified");
+ DateComponents date;
+ bool foundDate = false;
+ if (m_frame) {
+ String httpLastModified = m_frame->loader()->documentLoader()->response().httpHeaderField("Last-Modified");
+ if (!httpLastModified.isEmpty()) {
+ date.setMillisecondsSinceEpochForDateTime(parseDate(httpLastModified));
+ foundDate = true;
+ }
+ }
+ // FIXME: If this document came from the file system, the HTML5
+ // specificiation tells us to read the last modification date from the file
+ // system.
+ if (!foundDate)
+ date.setMillisecondsSinceEpochForDateTime(currentTimeMS());
+ return String::format("%02d/%02d/%04d %02d:%02d:%02d", date.month() + 1, date.monthDay(), date.fullYear(), date.hour(), date.minute(), date.second());
}
static bool isValidNameNonASCII(const UChar* characters, unsigned length)
@@ -4037,10 +4028,9 @@ bool Document::inDesignMode() const
Document* Document::parentDocument() const
{
- Frame* childPart = frame();
- if (!childPart)
+ if (!m_frame)
return 0;
- Frame* parent = childPart->tree()->parent();
+ Frame* parent = m_frame->tree()->parent();
if (!parent)
return 0;
return parent->document();
@@ -4711,11 +4701,9 @@ void Document::enqueuePageshowEvent(PageshowEventPersistence persisted)
dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, persisted), this);
}
-void Document::enqueueHashchangeEvent(const String& /*oldURL*/, const String& /*newURL*/)
+void Document::enqueueHashchangeEvent(const String& oldURL, const String& newURL)
{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36335 Hashchange event is now its own interface and takes two
- // URL arguments which we need to pass in here.
- enqueueEvent(Event::create(eventNames().hashchangeEvent, false, false));
+ enqueueEvent(HashChangeEvent::create(oldURL, newURL));
}
void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index a8e3562..c1065fb 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -579,6 +579,8 @@ public:
void lockCompatibilityMode() { m_compatibilityModeLocked = true; }
CompatibilityMode compatibilityMode() const { return m_compatibilityMode; }
+ String compatMode() const;
+
bool inQuirksMode() const { return m_compatibilityMode == QuirksMode; }
bool inLimitedQuirksMode() const { return m_compatibilityMode == LimitedQuirksMode; }
bool inNoQuirksMode() const { return m_compatibilityMode == NoQuirksMode; }
@@ -1033,7 +1035,7 @@ public:
bool isDelayingLoadEvent() const { return m_loadEventDelayCount; }
protected:
- Document(Frame*, const KURL&, bool isXHTML, bool isHTML);
+ Document(Frame*, const KURL& url, bool isXHTML, bool isHTML, const KURL& baseURL = KURL());
void clearXMLVersion() { m_xmlVersion = String(); }
diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl
index 0bd93b8..296bd44 100644
--- a/WebCore/dom/Document.idl
+++ b/WebCore/dom/Document.idl
@@ -233,6 +233,8 @@ module core {
// HTML 5
NodeList getElementsByClassName(in DOMString tagname);
+ readonly attribute DOMString compatMode;
+
// NodeSelector - Selector API
Element querySelector(in DOMString selectors)
raises(DOMException);
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 6ff47e0..5f53c2d 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -50,6 +50,7 @@
#include "RenderLayer.h"
#include "RenderView.h"
#include "RenderWidget.h"
+#include "SVGStyledLocatableElement.h"
#include "Settings.h"
#include "TextIterator.h"
#include "XMLNames.h"
@@ -476,12 +477,25 @@ PassRefPtr<ClientRectList> Element::getClientRects() const
PassRefPtr<ClientRect> Element::getBoundingClientRect() const
{
document()->updateLayoutIgnorePendingStylesheets();
- RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
- if (!renderBoxModelObject)
- return ClientRect::create();
Vector<FloatQuad> quads;
- renderBoxModelObject->absoluteQuads(quads);
+#if ENABLE(SVG)
+ if (isSVGElement()) {
+ // Get the bounding rectangle from the SVG model.
+ const SVGElement* svgElement = static_cast<const SVGElement*>(this);
+ if (svgElement->isStyledLocatable()) {
+ if (renderer()) {
+ const FloatRect& localRect = static_cast<const SVGStyledLocatableElement*>(svgElement)->getBBox();
+ quads.append(renderer()->localToAbsoluteQuad(localRect));
+ }
+ }
+ } else
+#endif
+ {
+ // Get the bounding rectangle from the box model.
+ if (renderBoxModelObject())
+ renderBoxModelObject()->absoluteQuads(quads);
+ }
if (quads.isEmpty())
return ClientRect::create();
@@ -495,7 +509,8 @@ PassRefPtr<ClientRect> Element::getBoundingClientRect() const
result.move(-visibleContentRect.x(), -visibleContentRect.y());
}
- adjustIntRectForAbsoluteZoom(result, renderBoxModelObject);
+ if (renderBoxModelObject())
+ adjustIntRectForAbsoluteZoom(result, renderBoxModelObject());
return ClientRect::create(result);
}
@@ -1347,9 +1362,9 @@ void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
// FIXME: We should restore the previous selection if there is one.
VisibleSelection newSelection = VisibleSelection(Position(this, 0), DOWNSTREAM);
- if (frame->shouldChangeSelection(newSelection)) {
+ if (frame->selection()->shouldChangeSelection(newSelection)) {
frame->selection()->setSelection(newSelection);
- frame->revealSelection();
+ frame->selection()->revealSelection();
}
} else if (renderer() && !renderer()->isWidget())
renderer()->enclosingLayer()->scrollRectToVisible(getRect());
diff --git a/WebCore/dom/Event.cpp b/WebCore/dom/Event.cpp
index c76f951..bb404fa 100644
--- a/WebCore/dom/Event.cpp
+++ b/WebCore/dom/Event.cpp
@@ -172,6 +172,11 @@ bool Event::isBeforeLoadEvent() const
return false;
}
+bool Event::isHashChangeEvent() const
+{
+ return false;
+}
+
#if ENABLE(SVG)
bool Event::isSVGZoomEvent() const
{
diff --git a/WebCore/dom/Event.h b/WebCore/dom/Event.h
index b992237..2a00eee 100644
--- a/WebCore/dom/Event.h
+++ b/WebCore/dom/Event.h
@@ -123,6 +123,7 @@ namespace WebCore {
virtual bool isWebKitAnimationEvent() const;
virtual bool isWebKitTransitionEvent() const;
virtual bool isBeforeLoadEvent() const;
+ virtual bool isHashChangeEvent() const;
#if ENABLE(SVG)
virtual bool isSVGZoomEvent() const;
#endif
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index effd2a2..d2b6f49 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -162,7 +162,7 @@ FileReader* EventTarget::toFileReader()
return 0;
}
#endif
-#if ENABLE(FILE_WRITER)
+#if ENABLE(FILE_SYSTEM)
FileWriter* EventTarget::toFileWriter()
{
return 0;
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index b2985f7..de7c2e0 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -124,7 +124,7 @@ namespace WebCore {
#if ENABLE(BLOB)
virtual FileReader* toFileReader();
#endif
-#if ENABLE(FILE_WRITER)
+#if ENABLE(FILE_SYSTEM)
virtual FileWriter* toFileWriter();
#endif
diff --git a/WebCore/dom/ExceptionCode.h b/WebCore/dom/ExceptionCode.h
index ed15a2e..cbbf650 100644
--- a/WebCore/dom/ExceptionCode.h
+++ b/WebCore/dom/ExceptionCode.h
@@ -61,7 +61,7 @@ namespace WebCore {
// Introduced in File API:
// http://www.w3.org/TR/file-upload/#dfn-fileerror
-#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
+#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
NOT_READABLE_ERR = 24,
ENCODING_ERR = 26,
#endif
diff --git a/WebCore/dom/HashChangeEvent.h b/WebCore/dom/HashChangeEvent.h
new file mode 100644
index 0000000..f1fa6af
--- /dev/null
+++ b/WebCore/dom/HashChangeEvent.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef HashChangeEvent_h
+#define HashChangeEvent_h
+
+#include "Event.h"
+#include "EventNames.h"
+
+namespace WebCore {
+
+class HashChangeEvent : public Event {
+public:
+ virtual bool isHashChangeEvent() const { return true; }
+
+ static PassRefPtr<HashChangeEvent> create(const String& oldURL, const String& newURL)
+ {
+ return adoptRef(new HashChangeEvent(oldURL, newURL));
+ }
+
+ void initHashChangeEvent(const AtomicString& eventType, bool canBubble, bool cancelable, const String& oldURL, const String& newURL)
+ {
+ if (dispatched())
+ return;
+
+ initEvent(eventType, canBubble, cancelable);
+
+ m_oldURL = oldURL;
+ m_newURL = newURL;
+ }
+
+ const String& oldURL() const { return m_oldURL; }
+ const String& newURL() const { return m_newURL; }
+
+private:
+ HashChangeEvent(const String& oldURL, const String& newURL)
+ : Event(eventNames().hashchangeEvent, false, false)
+ , m_oldURL(oldURL)
+ , m_newURL(newURL)
+ {}
+
+ String m_oldURL;
+ String m_newURL;
+};
+
+} // namespace WebCore
+
+#endif // HashChangeEvent_h
diff --git a/WebCore/dom/HashChangeEvent.idl b/WebCore/dom/HashChangeEvent.idl
new file mode 100644
index 0000000..63073c4
--- /dev/null
+++ b/WebCore/dom/HashChangeEvent.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+module events {
+
+ // Introduced in http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#event-hashchange
+ interface [
+ GenerateConstructor
+ ] HashChangeEvent : Event {
+ void initHashChangeEvent(in DOMString type,
+ in boolean canBubble,
+ in boolean cancelable,
+ in DOMString oldURL,
+ in DOMString newURL);
+ readonly attribute DOMString oldURL;
+ readonly attribute DOMString newURL;
+ };
+
+}
diff --git a/WebCore/dom/InputElement.cpp b/WebCore/dom/InputElement.cpp
index f0284d8..b2a9714 100644
--- a/WebCore/dom/InputElement.cpp
+++ b/WebCore/dom/InputElement.cpp
@@ -99,7 +99,7 @@ void InputElement::updateFocusAppearance(InputElementData& data, InputElement* i
Document* document = element->document();
if (document && document->frame())
- document->frame()->revealSelection();
+ document->frame()->selection()->revealSelection();
}
void InputElement::updateSelectionRange(InputElement* inputElement, Element* element, int start, int end)
diff --git a/WebCore/dom/MouseRelatedEvent.cpp b/WebCore/dom/MouseRelatedEvent.cpp
index ce4c175..61c35e8 100644
--- a/WebCore/dom/MouseRelatedEvent.cpp
+++ b/WebCore/dom/MouseRelatedEvent.cpp
@@ -57,7 +57,7 @@ static int contentsX(AbstractView* abstractView)
FrameView* frameView = frame->view();
if (!frameView)
return 0;
- return frameView->scrollX() / frameView->pageZoomFactor();
+ return frameView->scrollX() / frame->pageZoomFactor();
}
static int contentsY(AbstractView* abstractView)
@@ -70,7 +70,7 @@ static int contentsY(AbstractView* abstractView)
FrameView* frameView = frame->view();
if (!frameView)
return 0;
- return frameView->scrollY() / frameView->pageZoomFactor();
+ return frameView->scrollY() / frame->pageZoomFactor();
}
MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> viewArg,
@@ -126,10 +126,7 @@ static float pageZoomFactor(UIEvent* event)
Frame* frame = window->frame();
if (!frame)
return 1;
- FrameView* view = frame->view();
- if (!view)
- return 1;
- return view->pageZoomFactor();
+ return frame->pageZoomFactor();
}
void MouseRelatedEvent::computePageLocation()
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 9b27089..92b42fe 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -723,6 +723,15 @@ inline void Node::setStyleChange(StyleChangeType changeType)
m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType;
}
+inline void Node::markAncestorsWithChildNeedsStyleRecalc()
+{
+ for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
+ p->setChildNeedsStyleRecalc();
+
+ if (document()->childNeedsStyleRecalc())
+ document()->scheduleStyleRecalc();
+}
+
void Node::setNeedsStyleRecalc(StyleChangeType changeType)
{
ASSERT(changeType != NoStyleChange);
@@ -733,49 +742,20 @@ void Node::setNeedsStyleRecalc(StyleChangeType changeType)
if (changeType > existingChangeType)
setStyleChange(changeType);
- if (existingChangeType == NoStyleChange) {
- for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
- p->setChildNeedsStyleRecalc();
-
- if (document()->childNeedsStyleRecalc())
- document()->scheduleStyleRecalc();
- }
+ if (existingChangeType == NoStyleChange)
+ markAncestorsWithChildNeedsStyleRecalc();
}
-static Node* outermostLazyAttachedAncestor(Node* start)
+void Node::lazyAttach(ShouldSetAttached shouldSetAttached)
{
- Node* p = start;
- for (Node* next = p->parentNode(); !next->renderer(); p = next, next = next->parentNode()) {}
- return p;
-}
-
-void Node::lazyAttach()
-{
- bool mustDoFullAttach = false;
-
for (Node* n = this; n; n = n->traverseNextNode(this)) {
- if (!n->canLazyAttach()) {
- mustDoFullAttach = true;
- break;
- }
-
if (n->firstChild())
n->setChildNeedsStyleRecalc();
n->setStyleChange(FullStyleChange);
- n->setAttached();
- }
-
- if (mustDoFullAttach) {
- Node* lazyAttachedAncestor = outermostLazyAttachedAncestor(this);
- if (lazyAttachedAncestor->attached())
- lazyAttachedAncestor->detach();
- lazyAttachedAncestor->attach();
- } else {
- for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
- p->setChildNeedsStyleRecalc();
- if (document()->childNeedsStyleRecalc())
- document()->scheduleStyleRecalc();
+ if (shouldSetAttached == SetAttached)
+ n->setAttached();
}
+ markAncestorsWithChildNeedsStyleRecalc();
}
void Node::setFocus(bool b)
@@ -2939,8 +2919,8 @@ bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int det
int adjustedPageX = pageX;
int adjustedPageY = pageY;
- if (FrameView* view = document()->view()) {
- float pageZoom = view->pageZoomFactor();
+ if (Frame* frame = document()->frame()) {
+ float pageZoom = frame->pageZoomFactor();
if (pageZoom != 1.0f) {
// Adjust our pageX and pageY to account for the page zoom.
adjustedPageX = lroundf(pageX / pageZoom);
@@ -2996,8 +2976,8 @@ void Node::dispatchWheelEvent(PlatformWheelEvent& e)
int adjustedPageX = pos.x();
int adjustedPageY = pos.y();
- if (FrameView* view = document()->view()) {
- float pageZoom = view->pageZoomFactor();
+ if (Frame* frame = document()->frame()) {
+ float pageZoom = frame->pageZoomFactor();
if (pageZoom != 1.0f) {
// Adjust our pageX and pageY to account for the page zoom.
adjustedPageX = lroundf(pos.x() / pageZoom);
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index c7f07f1..603829b 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -310,8 +310,11 @@ public:
void setIsLink() { setFlag(IsLinkFlag); }
void clearIsLink() { clearFlag(IsLinkFlag); }
- void lazyAttach();
- virtual bool canLazyAttach() { return true; }
+ enum ShouldSetAttached {
+ SetAttached,
+ DoNotSetAttached
+ };
+ void lazyAttach(ShouldSetAttached = SetAttached);
virtual void setFocus(bool b = true);
virtual void setActive(bool f = true, bool /*pause*/ = false) { setFlag(f, IsActiveFlag); }
@@ -693,6 +696,9 @@ private:
void setStyleChange(StyleChangeType);
+ // Used to share code between lazyAttach and setNeedsStyleRecalc.
+ void markAncestorsWithChildNeedsStyleRecalc();
+
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp
index d93a58e..95502df 100644
--- a/WebCore/dom/Range.cpp
+++ b/WebCore/dom/Range.cpp
@@ -107,6 +107,17 @@ Range::~Range()
#endif
}
+void Range::setDocument(Document* document)
+{
+ ASSERT(m_ownerDocument != document);
+ if (m_ownerDocument)
+ m_ownerDocument->detachRange(this);
+ m_ownerDocument = document;
+ m_start.setToStartOfNode(document);
+ m_end.setToStartOfNode(document);
+ m_ownerDocument->attachRange(this);
+}
+
Node* Range::startContainer(ExceptionCode& ec) const
{
if (!m_start.container()) {
@@ -1316,6 +1327,9 @@ void Range::selectNode(Node* refNode, ExceptionCode& ec)
return;
}
+ if (m_ownerDocument != refNode->document())
+ setDocument(refNode->document());
+
ec = 0;
setStartBefore(refNode, ec);
if (ec)
@@ -1358,6 +1372,9 @@ void Range::selectNodeContents(Node* refNode, ExceptionCode& ec)
}
}
+ if (m_ownerDocument != refNode->document())
+ setDocument(refNode->document());
+
m_start.setToStartOfNode(refNode);
m_end.setToEndOfNode(refNode);
}
diff --git a/WebCore/dom/Range.h b/WebCore/dom/Range.h
index c81bf45..9834aec 100644
--- a/WebCore/dom/Range.h
+++ b/WebCore/dom/Range.h
@@ -135,6 +135,8 @@ private:
Range(PassRefPtr<Document>);
Range(PassRefPtr<Document>, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset);
+ void setDocument(Document*);
+
Node* checkNodeWOffset(Node*, int offset, ExceptionCode&) const;
void checkNodeBA(Node*, ExceptionCode&) const;
void checkDeleteExtract(ExceptionCode&);
diff --git a/WebCore/dom/ScriptElement.cpp b/WebCore/dom/ScriptElement.cpp
index bb46f0a..46c85e3 100644
--- a/WebCore/dom/ScriptElement.cpp
+++ b/WebCore/dom/ScriptElement.cpp
@@ -264,6 +264,8 @@ bool ScriptElementData::shouldExecuteAsJavaScript() const
WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't.
Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace.
We want to accept all the values that either of these browsers accept, but not other values.
+
+ FIXME: Is this HTML5 compliant?
*/
String type = m_scriptElement->typeAttributeValue();
if (!type.isEmpty()) {
@@ -276,20 +278,20 @@ bool ScriptElementData::shouldExecuteAsJavaScript() const
}
// No type or language is specified, so we assume the script to be JavaScript.
- // We don't yet support setting event listeners via the 'for' attribute for scripts.
- // If there is such an attribute it's likely better to not execute the script than to do so
- // immediately and unconditionally.
- // FIXME: After <rdar://problem/4471751> / https://bugs.webkit.org/show_bug.cgi?id=16915 are resolved
- // and we support the for syntax in script tags, this check can be removed and we should just
- // return 'true' here.
+
String forAttribute = m_scriptElement->forAttributeValue();
String eventAttribute = m_scriptElement->eventAttributeValue();
- if (forAttribute.isEmpty() || eventAttribute.isEmpty())
- return true;
+ if (!forAttribute.isEmpty() && !eventAttribute.isEmpty()) {
+ forAttribute = forAttribute.stripWhiteSpace();
+ if (!equalIgnoringCase(forAttribute, "window"))
+ return false;
+
+ eventAttribute = eventAttribute.stripWhiteSpace();
+ if (!equalIgnoringCase(eventAttribute, "onload") && !equalIgnoringCase(eventAttribute, "onload()"))
+ return false;
+ }
- forAttribute = forAttribute.stripWhiteSpace();
- eventAttribute = eventAttribute.stripWhiteSpace();
- return equalIgnoringCase(forAttribute, "window") && (equalIgnoringCase(eventAttribute, "onload") || equalIgnoringCase(eventAttribute, "onload()"));
+ return true;
}
String ScriptElementData::scriptCharset() const
diff --git a/WebCore/dom/ScriptExecutionContext.cpp b/WebCore/dom/ScriptExecutionContext.cpp
index d014d47..bfda17b 100644
--- a/WebCore/dom/ScriptExecutionContext.cpp
+++ b/WebCore/dom/ScriptExecutionContext.cpp
@@ -87,20 +87,17 @@ ScriptExecutionContext::~ScriptExecutionContext()
m_databaseThread = 0;
}
#endif
-#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
+#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
if (m_fileThread) {
m_fileThread->stop();
m_fileThread = 0;
}
#endif
- HashSet<Blob*>::iterator blobsEnd = m_blobs.end();
- for (HashSet<Blob*>::iterator iter = m_blobs.begin(); iter != blobsEnd; ++iter)
- (*iter)->contextDestroyed();
#if ENABLE(BLOB)
HashSet<String>::iterator publicBlobURLsEnd = m_publicBlobURLs.end();
for (HashSet<String>::iterator iter = m_publicBlobURLs.begin(); iter != publicBlobURLsEnd; ++iter)
- ThreadableBlobRegistry::unregisterBlobURL(this, KURL(ParsedURLString, *iter));
+ ThreadableBlobRegistry::unregisterBlobURL(KURL(ParsedURLString, *iter));
#endif
}
@@ -175,18 +172,6 @@ void ScriptExecutionContext::destroyedMessagePort(MessagePort* port)
m_messagePorts.remove(port);
}
-void ScriptExecutionContext::addBlob(Blob* blob)
-{
- ASSERT(blob);
- m_blobs.add(blob);
-}
-
-void ScriptExecutionContext::removeBlob(Blob* blob)
-{
- ASSERT(blob);
- m_blobs.remove(blob);
-}
-
bool ScriptExecutionContext::canSuspendActiveDOMObjects()
{
// No protection against m_activeDOMObjects changing during iteration: canSuspend() shouldn't execute arbitrary JS.
@@ -199,13 +184,13 @@ bool ScriptExecutionContext::canSuspendActiveDOMObjects()
return true;
}
-void ScriptExecutionContext::suspendActiveDOMObjects()
+void ScriptExecutionContext::suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension why)
{
// No protection against m_activeDOMObjects changing during iteration: suspend() shouldn't execute arbitrary JS.
HashMap<ActiveDOMObject*, void*>::iterator activeObjectsEnd = m_activeDOMObjects.end();
for (HashMap<ActiveDOMObject*, void*>::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
ASSERT(iter->first->scriptExecutionContext() == this);
- iter->first->suspend();
+ iter->first->suspend(why);
}
}
@@ -277,8 +262,10 @@ DOMTimer* ScriptExecutionContext::findTimeout(int timeoutId)
#if ENABLE(BLOB)
KURL ScriptExecutionContext::createPublicBlobURL(Blob* blob)
{
- KURL publicURL = BlobURL::createURL(this);
- ThreadableBlobRegistry::registerBlobURL(this, publicURL, blob->url());
+ if (!blob)
+ return KURL();
+ KURL publicURL = BlobURL::createPublicURL(securityOrigin());
+ ThreadableBlobRegistry::registerBlobURL(publicURL, blob->url());
m_publicBlobURLs.add(publicURL.string());
return publicURL;
}
@@ -286,13 +273,13 @@ KURL ScriptExecutionContext::createPublicBlobURL(Blob* blob)
void ScriptExecutionContext::revokePublicBlobURL(const KURL& url)
{
if (m_publicBlobURLs.contains(url.string())) {
- ThreadableBlobRegistry::unregisterBlobURL(this, url);
+ ThreadableBlobRegistry::unregisterBlobURL(url);
m_publicBlobURLs.remove(url.string());
}
}
#endif
-#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
+#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
FileThread* ScriptExecutionContext::fileThread()
{
if (!m_fileThread) {
diff --git a/WebCore/dom/ScriptExecutionContext.h b/WebCore/dom/ScriptExecutionContext.h
index 30c12e5..d39cb64 100644
--- a/WebCore/dom/ScriptExecutionContext.h
+++ b/WebCore/dom/ScriptExecutionContext.h
@@ -27,6 +27,7 @@
#ifndef ScriptExecutionContext_h
#define ScriptExecutionContext_h
+#include "ActiveDOMObject.h"
#include "Console.h"
#include "KURL.h"
#include <wtf/Forward.h>
@@ -44,7 +45,6 @@
namespace WebCore {
- class ActiveDOMObject;
class Blob;
#if ENABLE(DATABASE)
class Database;
@@ -52,7 +52,7 @@ namespace WebCore {
class DatabaseThread;
#endif
class DOMTimer;
-#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
+#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
class FileThread;
#endif
class MessagePort;
@@ -99,7 +99,7 @@ namespace WebCore {
bool canSuspendActiveDOMObjects();
// Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' -
// step-by-step JS debugging is one example.
- void suspendActiveDOMObjects();
+ void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
void resumeActiveDOMObjects();
void stopActiveDOMObjects();
void createdActiveDOMObject(ActiveDOMObject*, void* upcastPointer);
@@ -131,8 +131,6 @@ namespace WebCore {
void removeTimeout(int timeoutId);
DOMTimer* findTimeout(int timeoutId);
- void addBlob(Blob*);
- void removeBlob(Blob*);
#if ENABLE(BLOB)
KURL createPublicBlobURL(Blob*);
void revokePublicBlobURL(const KURL&);
@@ -142,7 +140,7 @@ namespace WebCore {
JSC::JSGlobalData* globalData();
#endif
-#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
+#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
FileThread* fileThread();
void stopFileThread();
#endif
@@ -167,7 +165,6 @@ namespace WebCore {
HashMap<int, DOMTimer*> m_timeouts;
- HashSet<Blob*> m_blobs;
#if ENABLE(BLOB)
HashSet<String> m_publicBlobURLs;
#endif
@@ -180,7 +177,7 @@ namespace WebCore {
bool m_hasOpenDatabases; // This never changes back to false, even after the database thread is closed.
#endif
-#if ENABLE(BLOB) || ENABLE(FILE_WRITER)
+#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
RefPtr<FileThread> m_fileThread;
#endif
};
diff --git a/WebCore/dom/Touch.cpp b/WebCore/dom/Touch.cpp
index 585d9d4..fbb3fed 100644
--- a/WebCore/dom/Touch.cpp
+++ b/WebCore/dom/Touch.cpp
@@ -40,7 +40,7 @@ static int contentsX(Frame* frame)
FrameView* frameView = frame->view();
if (!frameView)
return 0;
- return frameView->scrollX() / frameView->pageZoomFactor();
+ return frameView->scrollX() / frame->pageZoomFactor();
}
static int contentsY(Frame* frame)
@@ -50,11 +50,10 @@ static int contentsY(Frame* frame)
FrameView* frameView = frame->view();
if (!frameView)
return 0;
- return frameView->scrollY() / frameView->pageZoomFactor();
+ return frameView->scrollY() / frame->pageZoomFactor();
}
-Touch::Touch(Frame* frame, EventTarget* target, unsigned identifier,
- int screenX, int screenY, int pageX, int pageY)
+Touch::Touch(Frame* frame, EventTarget* target, unsigned identifier, int screenX, int screenY, int pageX, int pageY)
: m_target(target)
, m_identifier(identifier)
, m_clientX(pageX - contentsX(frame))
@@ -69,4 +68,3 @@ Touch::Touch(Frame* frame, EventTarget* target, unsigned identifier,
} // namespace WebCore
#endif
-
diff --git a/WebCore/dom/ViewportArguments.cpp b/WebCore/dom/ViewportArguments.cpp
index 9f831dd..356f9ed 100644
--- a/WebCore/dom/ViewportArguments.cpp
+++ b/WebCore/dom/ViewportArguments.cpp
@@ -5,6 +5,7 @@
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -31,76 +32,275 @@
#include "DOMWindow.h"
#include "Document.h"
#include "Frame.h"
+#include "IntSize.h"
#include "Page.h"
#include "PlatformString.h"
#include "ScriptableDocumentParser.h"
+using namespace std;
+
namespace WebCore {
+ViewportConfiguration findConfigurationForViewportData(ViewportArguments args, int desktopWidth, int deviceWidth, int deviceHeight, int deviceDPI, IntSize visibleViewport)
+{
+ ViewportConfiguration result;
+
+ float availableWidth = visibleViewport.width();
+ float availableHeight = visibleViewport.height();
+
+ ASSERT(availableWidth > 0 && availableHeight > 0);
+
+ switch (int(args.width)) {
+ case ViewportArguments::ValueDesktopWidth:
+ args.width = desktopWidth;
+ break;
+ case ViewportArguments::ValueDeviceWidth:
+ args.width = deviceWidth;
+ break;
+ case ViewportArguments::ValueDeviceHeight:
+ args.width = deviceHeight;
+ break;
+ }
+
+ switch (int(args.height)) {
+ case ViewportArguments::ValueDesktopWidth:
+ args.height = desktopWidth;
+ break;
+ case ViewportArguments::ValueDeviceWidth:
+ args.height = deviceWidth;
+ break;
+ case ViewportArguments::ValueDeviceHeight:
+ args.height = deviceHeight;
+ break;
+ }
+
+ result.devicePixelRatio = float(deviceDPI / 160.0);
+
+ // Resolve non-'auto' width and height to pixel values.
+ if (deviceDPI != 1.0) {
+ deviceWidth /= result.devicePixelRatio;
+ deviceHeight /= result.devicePixelRatio;
+
+ if (args.width != ViewportArguments::ValueAuto)
+ args.width /= result.devicePixelRatio;
+ if (args.height != ViewportArguments::ValueAuto)
+ args.height /= result.devicePixelRatio;
+ }
+
+ // Clamp values to range defined by spec and resolve minimum-scale and maximum-scale values
+ if (args.width != ViewportArguments::ValueAuto)
+ args.width = min(float(10000), max(args.width, float(1)));
+ if (args.height != ViewportArguments::ValueAuto)
+ args.height = min(float(10000), max(args.height, float(1)));
+
+ if (args.initialScale != ViewportArguments::ValueAuto)
+ args.initialScale = min(float(10), max(args.initialScale, float(0.1)));
+ if (args.minimumScale != ViewportArguments::ValueAuto)
+ args.minimumScale = min(float(10), max(args.minimumScale, float(0.1)));
+ if (args.maximumScale != ViewportArguments::ValueAuto)
+ args.maximumScale = min(float(10), max(args.maximumScale, float(0.1)));
+
+ // Resolve minimum-scale and maximum-scale values according to spec.
+ if (args.minimumScale == ViewportArguments::ValueAuto)
+ result.minimumScale = float(0.25);
+ else
+ result.minimumScale = args.minimumScale;
+
+ if (args.maximumScale == ViewportArguments::ValueAuto) {
+ result.maximumScale = float(5.0);
+ result.minimumScale = min(float(5.0), result.minimumScale);
+ } else
+ result.maximumScale = args.maximumScale;
+ result.maximumScale = max(result.minimumScale, result.maximumScale);
+
+ // Resolve initial-scale value.
+ result.initialScale = args.initialScale;
+ if (result.initialScale == ViewportArguments::ValueAuto) {
+ result.initialScale = availableWidth / desktopWidth;
+ if (args.width != ViewportArguments::ValueAuto)
+ result.initialScale = availableWidth / args.width;
+ if (args.height != ViewportArguments::ValueAuto) {
+ // if 'auto', the initial-scale will be negative here and thus ignored.
+ result.initialScale = max(result.initialScale, availableHeight / args.height);
+ }
+ }
+
+ // Constrain initial-scale value to minimum-scale/maximum-scale range.
+ result.initialScale = min(result.maximumScale, max(result.minimumScale, result.initialScale));
+
+ // Resolve width value.
+ float width;
+ if (args.width != ViewportArguments::ValueAuto)
+ width = args.width;
+ else {
+ if (args.initialScale == ViewportArguments::ValueAuto)
+ width = desktopWidth;
+ else if (args.height != ViewportArguments::ValueAuto)
+ width = args.height * (availableWidth / availableHeight);
+ else
+ width = availableWidth / result.initialScale;
+ }
+
+ // Resolve height value.
+ float height;
+ if (args.height != ViewportArguments::ValueAuto)
+ height = args.height;
+ else
+ height = width * availableHeight / availableWidth;
+
+ // Extend width and height to fill the visual viewport for the resolved initial-scale.
+ width = max(width, availableWidth / result.initialScale);
+ height = max(height, availableHeight / result.initialScale);
+ result.layoutViewport.setWidth(width);
+ result.layoutViewport.setHeight(height);
+
+ // Update minimum scale factor, to never allow zooming out more than viewport
+ result.minimumScale = max(result.minimumScale, max(availableWidth / width, availableHeight / height));
+
+ return result;
+}
+
+static float findSizeValue(const String& keyString, const String& valueString, Document* document)
+{
+ // 1) Non-negative number values are translated to px lengths.
+ // 2) Negative number values are translated to auto.
+ // 3) device-width and device-height are used as keywords.
+ // 4) Other keywords and unknown values translate to 0.0.
+
+ if (equalIgnoringCase(valueString, "desktop-width"))
+ return ViewportArguments::ValueDesktopWidth;
+ if (equalIgnoringCase(valueString, "device-width"))
+ return ViewportArguments::ValueDeviceWidth;
+ if (equalIgnoringCase(valueString, "device-height"))
+ return ViewportArguments::ValueDeviceHeight;
+
+ bool ok;
+ float value = valueString.toFloat(&ok);
+ if (!ok) {
+ reportViewportWarning(document, UnrecognizedViewportArgumentError, keyString);
+ return float(0.0);
+ }
+
+ if (value < 0)
+ return ViewportArguments::ValueAuto;
+
+ if (keyString == "width")
+ reportViewportWarning(document, DeviceWidthShouldBeUsedWarning, keyString);
+ else if (keyString == "height")
+ reportViewportWarning(document, DeviceHeightShouldBeUsedWarning, keyString);
+
+ return value;
+}
+
+static float findScaleValue(const String& keyString, const String& valueString, Document* document)
+{
+ // 1) Non-negative number values are translated to <number> values.
+ // 2) Negative number values are translated to auto.
+ // 3) yes is translated to 1.0.
+ // 4) device-width and device-height are translated to 10.0.
+ // 5) no and unknown values are translated to 0.0
+
+ if (equalIgnoringCase(valueString, "yes"))
+ return float(1.0);
+ if (equalIgnoringCase(valueString, "no"))
+ return float(0.0);
+ if (equalIgnoringCase(valueString, "desktop-width"))
+ return float(10.0);
+ if (equalIgnoringCase(valueString, "device-width"))
+ return float(10.0);
+ if (equalIgnoringCase(valueString, "device-height"))
+ return float(10.0);
+
+ bool ok;
+ float value = valueString.toFloat(&ok);
+ if (!ok) {
+ reportViewportWarning(document, UnrecognizedViewportArgumentError, keyString);
+ return float(0.0);
+ }
+
+ if (value < 0)
+ return ViewportArguments::ValueAuto;
+
+ if (value > 10.0)
+ reportViewportWarning(document, MaximumScaleTooLargeError, keyString);
+
+ return value;
+}
+
+static bool findUserScalableValue(const String& keyString, const String& valueString, Document* document)
+{
+ // yes and no are used as keywords.
+ // Numbers >= 1, numbers <= -1, device-width and device-height are mapped to yes.
+ // Numbers in the range <-1, 1>, and unknown values, are mapped to no.
+
+ if (equalIgnoringCase(valueString, "yes"))
+ return true;
+ if (equalIgnoringCase(valueString, "no"))
+ return false;
+ if (equalIgnoringCase(valueString, "desktop-width"))
+ return true;
+ if (equalIgnoringCase(valueString, "device-width"))
+ return true;
+ if (equalIgnoringCase(valueString, "device-height"))
+ return true;
+
+ bool ok;
+ float value = valueString.toFloat(&ok);
+ if (!ok) {
+ reportViewportWarning(document, UnrecognizedViewportArgumentError, keyString);
+ return false;
+ }
+
+ if (fabs(value) < 1)
+ return false;
+
+ return true;
+}
+
+static float findTargetDensityDPIValue(const String& keyString, const String& valueString, Document* document)
+{
+ if (equalIgnoringCase(valueString, "device-dpi"))
+ return ViewportArguments::ValueDeviceDPI;
+ if (equalIgnoringCase(valueString, "low-dpi"))
+ return ViewportArguments::ValueLowDPI;
+ if (equalIgnoringCase(valueString, "medium-dpi"))
+ return ViewportArguments::ValueMediumDPI;
+ if (equalIgnoringCase(valueString, "high-dpi"))
+ return ViewportArguments::ValueHighDPI;
+
+ bool ok;
+ float value = valueString.toFloat(&ok);
+ if (!ok) {
+ reportViewportWarning(document, UnrecognizedViewportArgumentError, keyString);
+ return ViewportArguments::ValueAuto;
+ }
+
+ if (value < 70 || value > 400) {
+ reportViewportWarning(document, TargetDensityDpiTooSmallOrLargeError, keyString);
+ return ViewportArguments::ValueAuto;
+ }
+
+ return value;
+}
+
void setViewportFeature(const String& keyString, const String& valueString, Document* document, void* data)
{
ViewportArguments* arguments = static_cast<ViewportArguments*>(data);
- float value = ViewportArguments::ValueUndefined;
- bool didUseConstants = false;
- if (equalIgnoringCase(valueString, "yes"))
- value = 1;
- else if (equalIgnoringCase(valueString, "device-width")) {
- didUseConstants = true;
- if (document->page())
- value = document->page()->chrome()->windowRect().width();
- } else if (equalIgnoringCase(valueString, "device-height")) {
- didUseConstants = true;
- if (document->page())
- value = document->page()->chrome()->windowRect().height();
- } else if (equalIgnoringCase(valueString, "device-dpi")) {
- didUseConstants = true;
- // Default of today is 160dpi, resulting in a scaleFactor of 1.0.
- if (document->page())
- value = 160 * document->page()->chrome()->scaleFactor();
- } else if (equalIgnoringCase(valueString, "low-dpi")) {
- didUseConstants = true;
- value = 120;
- } else if (equalIgnoringCase(valueString, "medium-dpi")) {
- didUseConstants = true;
- value = 160;
- } else if (equalIgnoringCase(valueString, "high-dpi")) {
- didUseConstants = true;
- value = 240;
- } else if (equalIgnoringCase(valueString, "default")) // This allows us to distinguish the omission of a key from asking for the default value.
- value = -2;
- else if (valueString.length()) // listing a key with no value is shorthand for key=default
- value = valueString.toFloat();
-
- if (keyString == "initial-scale")
- arguments->initialScale = value;
+ if (keyString == "width")
+ arguments->width = findSizeValue(keyString, valueString, document);
+ else if (keyString == "height")
+ arguments->height = findSizeValue(keyString, valueString, document);
+ else if (keyString == "initial-scale")
+ arguments->initialScale = findScaleValue(keyString, valueString, document);
else if (keyString == "minimum-scale")
- arguments->minimumScale = value;
- else if (keyString == "maximum-scale") {
- arguments->maximumScale = value;
- if (value > 10.0)
- reportViewportWarning(document, MaximumScaleTooLargeError, keyString);
- } else if (keyString == "user-scalable")
- arguments->userScalable = value;
- else if (keyString == "width") {
- if (document->page() && value == document->page()->chrome()->windowRect().width() && !didUseConstants)
- reportViewportWarning(document, DeviceWidthShouldBeUsedWarning, keyString);
- else if (document->page() && value == document->page()->chrome()->windowRect().height() && !didUseConstants)
- reportViewportWarning(document, DeviceHeightShouldBeUsedWarning, keyString);
-
- arguments->width = value;
- } else if (keyString == "height") {
- if (document->page() && value == document->page()->chrome()->windowRect().width() && !didUseConstants)
- reportViewportWarning(document, DeviceWidthShouldBeUsedWarning, keyString);
- else if (document->page() && value == document->page()->chrome()->windowRect().height() && !didUseConstants)
- reportViewportWarning(document, DeviceHeightShouldBeUsedWarning, keyString);
- arguments->height = value;
- } else if (keyString == "target-densitydpi" || keyString == "target-densityDpi") {
- if (!didUseConstants && (value < 70 || value > 400))
- reportViewportWarning(document, TargetDensityDpiTooSmallOrLargeError, keyString);
- arguments->targetDensityDpi = value;
- } else
- reportViewportWarning(document, UnrecognizedViewportArgumentError, keyString);
+ arguments->minimumScale = findScaleValue(keyString, valueString, document);
+ else if (keyString == "maximum-scale")
+ arguments->maximumScale = findScaleValue(keyString, valueString, document);
+ else if (keyString == "user-scalable")
+ arguments->userScalable = findUserScalableValue(keyString, valueString, document);
+ else if (keyString == "target-densitydpi")
+ arguments->targetDensityDpi = findTargetDensityDPIValue(keyString, valueString, document);
}
static const char* viewportErrorMessageTemplate(ViewportErrorCode errorCode)
diff --git a/WebCore/dom/ViewportArguments.h b/WebCore/dom/ViewportArguments.h
index 1fac0df..5731842 100644
--- a/WebCore/dom/ViewportArguments.h
+++ b/WebCore/dom/ViewportArguments.h
@@ -5,6 +5,7 @@
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,6 +27,7 @@
#ifndef ViewportArguments_h
#define ViewportArguments_h
+#include "IntSize.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -40,18 +42,37 @@ enum ViewportErrorCode {
TargetDensityDpiTooSmallOrLargeError
};
+struct ViewportConfiguration {
+ IntSize layoutViewport;
+
+ float devicePixelRatio;
+
+ float initialScale;
+ float minimumScale;
+ float maximumScale;
+};
+
struct ViewportArguments {
- enum { ValueUndefined = -1 };
+ enum {
+ ValueAuto = -1,
+ ValueDesktopWidth = -2,
+ ValueDeviceWidth = -3,
+ ValueDeviceHeight = -4,
+ ValueDeviceDPI = -5,
+ ValueLowDPI = -6,
+ ValueMediumDPI = -7,
+ ValueHighDPI = -8
+ };
ViewportArguments()
- : initialScale(ValueUndefined)
- , minimumScale(ValueUndefined)
- , maximumScale(ValueUndefined)
- , width(ValueUndefined)
- , height(ValueUndefined)
- , targetDensityDpi(ValueUndefined)
- , userScalable(ValueUndefined)
+ : initialScale(ValueAuto)
+ , minimumScale(ValueAuto)
+ , maximumScale(ValueAuto)
+ , width(ValueAuto)
+ , height(ValueAuto)
+ , targetDensityDpi(ValueAuto)
+ , userScalable(ValueAuto)
{
}
@@ -66,10 +87,12 @@ struct ViewportArguments {
bool hasCustomArgument() const
{
- return initialScale != ValueUndefined || minimumScale != ValueUndefined || maximumScale != ValueUndefined || width != ValueUndefined || height != ValueUndefined || userScalable != ValueUndefined || targetDensityDpi != ValueUndefined;
+ return initialScale != ValueAuto || minimumScale != ValueAuto || maximumScale != ValueAuto || width != ValueAuto || height != ValueAuto || userScalable != ValueAuto || targetDensityDpi != ValueAuto;
}
};
+ViewportConfiguration findConfigurationForViewportData(ViewportArguments args, int desktopWidth, int deviceWidth, int deviceHeight, int deviceDPI, IntSize visibleViewport);
+
void setViewportFeature(const String& keyString, const String& valueString, Document*, void* data);
void reportViewportWarning(Document*, ViewportErrorCode, const String& replacement);
diff --git a/WebCore/dom/XMLDocumentParser.h b/WebCore/dom/XMLDocumentParser.h
index 47e65c6..358be1f 100644
--- a/WebCore/dom/XMLDocumentParser.h
+++ b/WebCore/dom/XMLDocumentParser.h
@@ -320,9 +320,9 @@ public:
int m_scriptStartLine;
bool m_parsingFragment;
- String m_defaultNamespaceURI;
+ AtomicString m_defaultNamespaceURI;
- typedef HashMap<String, String> PrefixForNamespaceMap;
+ typedef HashMap<AtomicString, AtomicString> PrefixForNamespaceMap;
PrefixForNamespaceMap m_prefixToNamespaceMap;
SegmentedString m_pendingSrc;
FragmentScriptingPermission m_scriptingPermission;
diff --git a/WebCore/dom/XMLDocumentParserLibxml2.cpp b/WebCore/dom/XMLDocumentParserLibxml2.cpp
index 927fbbe..5539072 100644
--- a/WebCore/dom/XMLDocumentParserLibxml2.cpp
+++ b/WebCore/dom/XMLDocumentParserLibxml2.cpp
@@ -1,11 +1,12 @@
/*
- * Copyright (C) 2000 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2000 Peter Kelly <pmk@post.com>
* Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
+ * Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
+ * Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008 Holger Hans Peter Freyther
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -671,17 +672,26 @@ void XMLDocumentParser::doWrite(const String& parseString)
}
}
-static inline String toString(const xmlChar* str, unsigned len)
+static inline String toString(const xmlChar* string, size_t size)
{
- return UTF8Encoding().decode(reinterpret_cast<const char*>(str), len);
+ return String::fromUTF8(reinterpret_cast<const char*>(string), size);
}
-static inline String toString(const xmlChar* str)
+static inline String toString(const xmlChar* string)
{
- if (!str)
- return String();
+ return String::fromUTF8(reinterpret_cast<const char*>(string));
+}
- return UTF8Encoding().decode(reinterpret_cast<const char*>(str), strlen(reinterpret_cast<const char*>(str)));
+static inline AtomicString toAtomicString(const xmlChar* string, size_t size)
+{
+ // FIXME: Use AtomicString::fromUTF8.
+ return AtomicString(toString(string, size));
+}
+
+static inline AtomicString toAtomicString(const xmlChar* string)
+{
+ // FIXME: Use AtomicString::fromUTF8.
+ return AtomicString(toString(string));
}
struct _xmlSAX2Namespace {
@@ -695,7 +705,7 @@ static inline void handleElementNamespaces(Element* newElement, const xmlChar**
xmlSAX2Namespace* namespaces = reinterpret_cast<xmlSAX2Namespace*>(libxmlNamespaces);
for (int i = 0; i < nb_namespaces; i++) {
AtomicString namespaceQName = xmlnsAtom;
- String namespaceURI = toString(namespaces[i].uri);
+ AtomicString namespaceURI = toAtomicString(namespaces[i].uri);
if (namespaces[i].prefix)
namespaceQName = "xmlns:" + toString(namespaces[i].prefix);
newElement->setAttributeNS(XMLNSNames::xmlnsNamespaceURI, namespaceQName, namespaceURI, ec, scriptingPermission);
@@ -717,12 +727,11 @@ static inline void handleElementAttributes(Element* newElement, const xmlChar**
{
xmlSAX2Attributes* attributes = reinterpret_cast<xmlSAX2Attributes*>(libxmlAttributes);
for (int i = 0; i < nb_attributes; i++) {
- String attrLocalName = toString(attributes[i].localname);
- int valueLength = (int) (attributes[i].end - attributes[i].value);
- String attrValue = toString(attributes[i].value, valueLength);
+ int valueLength = static_cast<int>(attributes[i].end - attributes[i].value);
+ AtomicString attrValue = toAtomicString(attributes[i].value, valueLength);
String attrPrefix = toString(attributes[i].prefix);
- String attrURI = attrPrefix.isEmpty() ? String() : toString(attributes[i].uri);
- String attrQName = attrPrefix.isEmpty() ? attrLocalName : attrPrefix + ":" + attrLocalName;
+ AtomicString attrURI = attrPrefix.isEmpty() ? AtomicString() : toAtomicString(attributes[i].uri);
+ AtomicString attrQName = attrPrefix.isEmpty() ? toAtomicString(attributes[i].localname) : AtomicString(attrPrefix + ":" + toString(attributes[i].localname));
newElement->setAttributeNS(attrURI, attrQName, attrValue, ec, scriptingPermission);
if (ec) // exception setting attributes
@@ -752,9 +761,9 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha
exitText();
- String localName = toString(xmlLocalName);
- String uri = toString(xmlURI);
- String prefix = toString(xmlPrefix);
+ AtomicString localName = toAtomicString(xmlLocalName);
+ AtomicString uri = toAtomicString(xmlURI);
+ AtomicString prefix = toAtomicString(xmlPrefix);
if (m_parsingFragment && uri.isNull()) {
if (!prefix.isNull())