summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/wml
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/wml
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/wml')
-rw-r--r--Source/WebCore/wml/WMLAElement.cpp158
-rw-r--r--Source/WebCore/wml/WMLAElement.h56
-rw-r--r--Source/WebCore/wml/WMLAccessElement.cpp77
-rw-r--r--Source/WebCore/wml/WMLAccessElement.h46
-rw-r--r--Source/WebCore/wml/WMLAnchorElement.cpp85
-rw-r--r--Source/WebCore/wml/WMLAnchorElement.h51
-rw-r--r--Source/WebCore/wml/WMLAttributeNames.in24
-rw-r--r--Source/WebCore/wml/WMLBRElement.cpp82
-rw-r--r--Source/WebCore/wml/WMLBRElement.h48
-rw-r--r--Source/WebCore/wml/WMLCardElement.cpp352
-rw-r--r--Source/WebCore/wml/WMLCardElement.h78
-rw-r--r--Source/WebCore/wml/WMLDoElement.cpp195
-rw-r--r--Source/WebCore/wml/WMLDoElement.h68
-rw-r--r--Source/WebCore/wml/WMLDocument.cpp125
-rw-r--r--Source/WebCore/wml/WMLDocument.h59
-rw-r--r--Source/WebCore/wml/WMLElement.cpp126
-rw-r--r--Source/WebCore/wml/WMLElement.h56
-rw-r--r--Source/WebCore/wml/WMLErrorHandling.cpp106
-rw-r--r--Source/WebCore/wml/WMLErrorHandling.h52
-rw-r--r--Source/WebCore/wml/WMLEventHandlingElement.cpp97
-rw-r--r--Source/WebCore/wml/WMLEventHandlingElement.h57
-rw-r--r--Source/WebCore/wml/WMLFieldSetElement.cpp85
-rw-r--r--Source/WebCore/wml/WMLFieldSetElement.h48
-rw-r--r--Source/WebCore/wml/WMLFormControlElement.cpp86
-rw-r--r--Source/WebCore/wml/WMLFormControlElement.h59
-rw-r--r--Source/WebCore/wml/WMLGoElement.cpp229
-rw-r--r--Source/WebCore/wml/WMLGoElement.h59
-rw-r--r--Source/WebCore/wml/WMLImageElement.cpp156
-rw-r--r--Source/WebCore/wml/WMLImageElement.h60
-rw-r--r--Source/WebCore/wml/WMLImageLoader.cpp78
-rw-r--r--Source/WebCore/wml/WMLImageLoader.h45
-rw-r--r--Source/WebCore/wml/WMLInputElement.cpp518
-rw-r--r--Source/WebCore/wml/WMLInputElement.h118
-rw-r--r--Source/WebCore/wml/WMLInsertedLegendElement.cpp44
-rw-r--r--Source/WebCore/wml/WMLInsertedLegendElement.h40
-rw-r--r--Source/WebCore/wml/WMLIntrinsicEvent.cpp53
-rw-r--r--Source/WebCore/wml/WMLIntrinsicEvent.h59
-rw-r--r--Source/WebCore/wml/WMLIntrinsicEventHandler.cpp61
-rw-r--r--Source/WebCore/wml/WMLIntrinsicEventHandler.h59
-rw-r--r--Source/WebCore/wml/WMLMetaElement.cpp70
-rw-r--r--Source/WebCore/wml/WMLMetaElement.h47
-rw-r--r--Source/WebCore/wml/WMLNoopElement.cpp71
-rw-r--r--Source/WebCore/wml/WMLNoopElement.h42
-rw-r--r--Source/WebCore/wml/WMLOnEventElement.cpp104
-rw-r--r--Source/WebCore/wml/WMLOnEventElement.h50
-rw-r--r--Source/WebCore/wml/WMLOptGroupElement.cpp135
-rw-r--r--Source/WebCore/wml/WMLOptGroupElement.h62
-rw-r--r--Source/WebCore/wml/WMLOptionElement.cpp186
-rw-r--r--Source/WebCore/wml/WMLOptionElement.h73
-rw-r--r--Source/WebCore/wml/WMLPElement.cpp118
-rw-r--r--Source/WebCore/wml/WMLPElement.h50
-rw-r--r--Source/WebCore/wml/WMLPageState.cpp266
-rw-r--r--Source/WebCore/wml/WMLPageState.h79
-rw-r--r--Source/WebCore/wml/WMLPostfieldElement.cpp88
-rw-r--r--Source/WebCore/wml/WMLPostfieldElement.h48
-rw-r--r--Source/WebCore/wml/WMLPrevElement.cpp73
-rw-r--r--Source/WebCore/wml/WMLPrevElement.h42
-rw-r--r--Source/WebCore/wml/WMLRefreshElement.cpp85
-rw-r--r--Source/WebCore/wml/WMLRefreshElement.h42
-rw-r--r--Source/WebCore/wml/WMLSelectElement.cpp562
-rw-r--r--Source/WebCore/wml/WMLSelectElement.h121
-rw-r--r--Source/WebCore/wml/WMLSetvarElement.cpp94
-rw-r--r--Source/WebCore/wml/WMLSetvarElement.h47
-rw-r--r--Source/WebCore/wml/WMLTableElement.cpp275
-rw-r--r--Source/WebCore/wml/WMLTableElement.h59
-rw-r--r--Source/WebCore/wml/WMLTagNames.in35
-rw-r--r--Source/WebCore/wml/WMLTaskElement.cpp119
-rw-r--r--Source/WebCore/wml/WMLTaskElement.h58
-rw-r--r--Source/WebCore/wml/WMLTemplateElement.cpp120
-rw-r--r--Source/WebCore/wml/WMLTemplateElement.h45
-rw-r--r--Source/WebCore/wml/WMLTimerElement.cpp161
-rw-r--r--Source/WebCore/wml/WMLTimerElement.h59
-rw-r--r--Source/WebCore/wml/WMLVariables.cpp286
-rw-r--r--Source/WebCore/wml/WMLVariables.h47
74 files changed, 7674 insertions, 0 deletions
diff --git a/Source/WebCore/wml/WMLAElement.cpp b/Source/WebCore/wml/WMLAElement.cpp
new file mode 100644
index 0000000..00067fe
--- /dev/null
+++ b/Source/WebCore/wml/WMLAElement.cpp
@@ -0,0 +1,158 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 2003, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
+ * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLAElement.h"
+
+#include "Attribute.h"
+#include "Event.h"
+#include "EventHandler.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "HTMLAnchorElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "KeyboardEvent.h"
+#include "MouseEvent.h"
+#include "RenderBox.h"
+#include "ResourceHandle.h"
+#include "WMLNames.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLAElement::WMLAElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLAElement> WMLAElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLAElement(tagName, document));
+}
+
+void WMLAElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::hrefAttr) {
+ bool wasLink = isLink();
+ setIsLink(!attr->isNull());
+ if (wasLink != isLink())
+ setNeedsStyleRecalc();
+ if (isLink() && document()->isDNSPrefetchEnabled()) {
+ String value = attr->value();
+ if (protocolIs(value, "http") || protocolIs(value, "https") || value.startsWith("//"))
+ ResourceHandle::prepareForURL(document()->completeURL(value));
+ }
+ } else if (attr->name() == HTMLNames::nameAttr
+ || attr->name() == HTMLNames::titleAttr
+ || attr->name() == HTMLNames::relAttr) {
+ // Do nothing.
+ } else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+bool WMLAElement::supportsFocus() const
+{
+ return isLink() || WMLElement::supportsFocus();
+}
+
+bool WMLAElement::isMouseFocusable() const
+{
+ return false;
+}
+
+bool WMLAElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+ if (!isFocusable())
+ return false;
+
+ if (!document()->frame())
+ return false;
+
+ if (!document()->frame()->eventHandler()->tabsToLinks(event))
+ return false;
+
+ if (!renderer() || !renderer()->isBoxModelObject())
+ return false;
+
+ // Before calling absoluteRects, check for the common case where the renderer
+ // is non-empty, since this is a faster check and almost always returns true.
+ RenderBoxModelObject* box = toRenderBoxModelObject(renderer());
+ if (!box->borderBoundingBox().isEmpty())
+ return true;
+
+ Vector<IntRect> rects;
+ FloatPoint absPos = renderer()->localToAbsolute();
+ renderer()->absoluteRects(rects, absPos.x(), absPos.y());
+ size_t n = rects.size();
+ for (size_t i = 0; i < n; ++i)
+ if (!rects[i].isEmpty())
+ return true;
+
+ return false;
+}
+
+void WMLAElement::defaultEventHandler(Event* event)
+{
+ if (isLink()) {
+ if (focused() && isEnterKeyKeydownEvent(event)) {
+ event->setDefaultHandled();
+ dispatchSimulatedClick(event);
+ return;
+ }
+
+ if (isLinkClick(event)) {
+ handleLinkClick(event, document(), stripLeadingAndTrailingHTMLSpaces(getAttribute(HTMLNames::hrefAttr)), target(), event);
+ return;
+ }
+ }
+
+ WMLElement::defaultEventHandler(event);
+}
+
+void WMLAElement::accessKeyAction(bool sendToAnyElement)
+{
+ // send the mouse button events if the caller specified sendToAnyElement
+ dispatchSimulatedClick(0, sendToAnyElement);
+}
+
+bool WMLAElement::isURLAttribute(Attribute *attr) const
+{
+ return attr->name() == HTMLNames::hrefAttr;
+}
+
+String WMLAElement::target() const
+{
+ return getAttribute(HTMLNames::targetAttr);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLAElement.h b/Source/WebCore/wml/WMLAElement.h
new file mode 100644
index 0000000..9dcda6b
--- /dev/null
+++ b/Source/WebCore/wml/WMLAElement.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 2007, 2008 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 WMLAElement_h
+#define WMLAElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLAElement : public WMLElement {
+public:
+ static PassRefPtr<WMLAElement> create(const QualifiedName& tagName, Document*);
+
+ WMLAElement(const QualifiedName& tagName, Document*);
+
+ virtual bool supportsFocus() const;
+ virtual bool isMouseFocusable() const;
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void defaultEventHandler(Event*);
+
+ virtual void accessKeyAction(bool fullAction);
+ virtual bool isURLAttribute(Attribute*) const;
+
+ virtual String target() const;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLAccessElement.cpp b/Source/WebCore/wml/WMLAccessElement.cpp
new file mode 100644
index 0000000..0e13106
--- /dev/null
+++ b/Source/WebCore/wml/WMLAccessElement.cpp
@@ -0,0 +1,77 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLAccessElement.h"
+
+#include "Attribute.h"
+#include "WMLDocument.h"
+#include "WMLNames.h"
+#include "WMLVariables.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLAccessElement::WMLAccessElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLAccessElement> WMLAccessElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLAccessElement(tagName, document));
+}
+
+void WMLAccessElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == domainAttr) {
+ String value = parseValueForbiddingVariableReferences(attr->value());
+ if (value.isEmpty())
+ return;
+
+ m_domain = value;
+ } else if (attr->name() == pathAttr) {
+ String value = parseValueForbiddingVariableReferences(attr->value());
+ if (value.isEmpty())
+ return;
+
+ m_path = value;
+ } else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+void WMLAccessElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ WMLPageState* pageState = wmlPageStateForDocument(document());
+ if (!pageState || pageState->processAccessControlData(m_domain, m_path))
+ return;
+
+ pageState->resetAccessControlData();
+ reportWMLError(document(), WMLErrorMultipleAccessElements);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLAccessElement.h b/Source/WebCore/wml/WMLAccessElement.h
new file mode 100644
index 0000000..eb7436c
--- /dev/null
+++ b/Source/WebCore/wml/WMLAccessElement.h
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLAccessElement_h
+#define WMLAccessElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLAccessElement : public WMLElement {
+public:
+ static PassRefPtr<WMLAccessElement> create(const QualifiedName& tagName, Document*);
+
+ WMLAccessElement(const QualifiedName& tagName, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+
+private:
+ String m_domain;
+ String m_path;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLAnchorElement.cpp b/Source/WebCore/wml/WMLAnchorElement.cpp
new file mode 100644
index 0000000..5b842bc
--- /dev/null
+++ b/Source/WebCore/wml/WMLAnchorElement.cpp
@@ -0,0 +1,85 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLAnchorElement.h"
+
+#include "EventNames.h"
+#include "KeyboardEvent.h"
+#include "WMLTaskElement.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+WMLAnchorElement::WMLAnchorElement(const QualifiedName& tagName, Document* doc)
+ : WMLAElement(tagName, doc)
+ , m_task(0)
+{
+ // Calling setIsLink(), and returning a non-null value on CSSStyleSelectors' linkAttribute
+ // method, makes it possible to 'appear as link' (just like <a href="..">) without the need to
+ // actually set the href value to an empty value in the DOM tree.
+ setIsLink();
+}
+
+PassRefPtr<WMLAnchorElement> WMLAnchorElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLAnchorElement(tagName, document));
+}
+
+WMLAnchorElement::~WMLAnchorElement()
+{
+}
+
+void WMLAnchorElement::defaultEventHandler(Event* event)
+{
+ bool shouldHandle = false;
+
+ if (event->type() == eventNames().clickEvent)
+ shouldHandle = true;
+ else if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent() && focused())
+ shouldHandle = static_cast<KeyboardEvent*>(event)->keyIdentifier() == "Enter";
+
+ if (shouldHandle && m_task) {
+ m_task->executeTask();
+ event->setDefaultHandled();
+ return;
+ }
+
+ // Skip WMLAElement::defaultEventHandler, we don't own a href attribute, that needs to be handled.
+ WMLElement::defaultEventHandler(event);
+}
+
+void WMLAnchorElement::registerTask(WMLTaskElement* task)
+{
+ ASSERT(!m_task);
+ m_task = task;
+}
+
+void WMLAnchorElement::deregisterTask(WMLTaskElement* task)
+{
+ ASSERT_UNUSED(task, m_task == task);
+ m_task = 0;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLAnchorElement.h b/Source/WebCore/wml/WMLAnchorElement.h
new file mode 100644
index 0000000..6cb36c8
--- /dev/null
+++ b/Source/WebCore/wml/WMLAnchorElement.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLAnchorElement_h
+#define WMLAnchorElement_h
+
+#if ENABLE(WML)
+#include "WMLAElement.h"
+
+namespace WebCore {
+
+class WMLTaskElement;
+
+class WMLAnchorElement : public WMLAElement {
+public:
+ static PassRefPtr<WMLAnchorElement> create(const QualifiedName& tagName, Document*);
+
+ WMLAnchorElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLAnchorElement();
+
+ virtual void defaultEventHandler(Event*);
+
+private:
+ friend class WMLTaskElement;
+ void registerTask(WMLTaskElement*);
+ void deregisterTask(WMLTaskElement*);
+
+ WMLTaskElement* m_task;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLAttributeNames.in b/Source/WebCore/wml/WMLAttributeNames.in
new file mode 100644
index 0000000..e2711fb
--- /dev/null
+++ b/Source/WebCore/wml/WMLAttributeNames.in
@@ -0,0 +1,24 @@
+namespace="WML"
+namespaceURI="http://www.wapforum.org/DTD/wml_1.1.xml"
+guardFactoryWith="ENABLE(WML)"
+attrsNullNamespace
+
+cache_control
+columns
+domain
+emptyok
+format
+forua
+iname
+ivalue
+localsrc
+mode
+newcontext
+onenterbackward
+onenterforward
+onpick
+ontimer
+optional
+ordered
+path
+sendreferer
diff --git a/Source/WebCore/wml/WMLBRElement.cpp b/Source/WebCore/wml/WMLBRElement.cpp
new file mode 100644
index 0000000..51a2f57
--- /dev/null
+++ b/Source/WebCore/wml/WMLBRElement.cpp
@@ -0,0 +1,82 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 2003, 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLBRElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "HTMLNames.h"
+#include "RenderBR.h"
+
+namespace WebCore {
+
+WMLBRElement::WMLBRElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLBRElement> WMLBRElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLBRElement(tagName, document));
+}
+
+bool WMLBRElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == HTMLNames::clearAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ return WMLElement::mapToEntry(attrName, result);
+}
+
+void WMLBRElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::clearAttr) {
+ // If the string is empty, then don't add the clear property.
+ // <br clear> and <br clear=""> are just treated like <br> by Gecko, Mac IE, etc. -dwh
+ const AtomicString& value = attr->value();
+ if (value.isEmpty())
+ return;
+
+ if (equalIgnoringCase(value, "all"))
+ addCSSProperty(attr, CSSPropertyClear, "both");
+ else
+ addCSSProperty(attr, CSSPropertyClear, value);
+ } else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+RenderObject* WMLBRElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderBR(this);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLBRElement.h b/Source/WebCore/wml/WMLBRElement.h
new file mode 100644
index 0000000..fb12688
--- /dev/null
+++ b/Source/WebCore/wml/WMLBRElement.h
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Simon Hausmann <hausmann@kde.org>
+ *
+ * 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 WMLBRElement_h
+#define WMLBRElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLBRElement : public WMLElement {
+public:
+ static PassRefPtr<WMLBRElement> create(const QualifiedName& tagName, Document*);
+
+ WMLBRElement(const QualifiedName& tagName, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLCardElement.cpp b/Source/WebCore/wml/WMLCardElement.cpp
new file mode 100644
index 0000000..38ba8ab
--- /dev/null
+++ b/Source/WebCore/wml/WMLCardElement.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLCardElement.h"
+
+#include "Attribute.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "HTMLNames.h"
+#include "NodeList.h"
+#include "Page.h"
+#include "RenderStyle.h"
+#include "WMLDoElement.h"
+#include "WMLDocument.h"
+#include "WMLInputElement.h"
+#include "WMLIntrinsicEventHandler.h"
+#include "WMLNames.h"
+#include "WMLSelectElement.h"
+#include "WMLTemplateElement.h"
+#include "WMLTimerElement.h"
+#include "WMLVariables.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLCardElement::WMLCardElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+ , m_isNewContext(false)
+ , m_isOrdered(false)
+ , m_isVisible(false)
+ , m_eventTimer(0)
+ , m_template(0)
+{
+ ASSERT(hasTagName(cardTag));
+}
+
+PassRefPtr<WMLCardElement> WMLCardElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLCardElement(tagName, document));
+}
+
+WMLCardElement::~WMLCardElement()
+{
+}
+
+void WMLCardElement::showCard()
+{
+ ASSERT(attached());
+
+ if (m_isVisible) {
+ ASSERT(renderer());
+ return;
+ }
+
+ m_isVisible = true;
+ ASSERT(!renderer());
+
+ detach();
+ attach();
+
+ ASSERT(attached());
+ ASSERT(renderer());
+}
+
+void WMLCardElement::hideCard()
+{
+ ASSERT(attached());
+
+ if (!m_isVisible) {
+ ASSERT(!renderer());
+ return;
+ }
+
+ m_isVisible = false;
+ ASSERT(renderer());
+
+ detach();
+ attach();
+
+ ASSERT(attached());
+ ASSERT(!renderer());
+}
+
+void WMLCardElement::setTemplateElement(WMLTemplateElement* temp)
+{
+ // Only one template is allowed to be attached to a card
+ if (m_template) {
+ reportWMLError(document(), WMLErrorMultipleTemplateElements);
+ return;
+ }
+
+ m_template = temp;
+}
+
+void WMLCardElement::setIntrinsicEventTimer(WMLTimerElement* timer)
+{
+ // Only one timer is allowed in a card
+ if (m_eventTimer) {
+ reportWMLError(document(), WMLErrorMultipleTimerElements);
+ return;
+ }
+
+ m_eventTimer = timer;
+}
+
+void WMLCardElement::handleIntrinsicEventIfNeeded()
+{
+ WMLPageState* pageState = wmlPageStateForDocument(document());
+ if (!pageState)
+ return;
+
+ Frame* frame = document()->frame();
+ if (!frame)
+ return;
+
+ FrameLoader* loader = frame->loader();
+ if (!loader)
+ return;
+
+ // Calculate the entry method of current card
+ WMLIntrinsicEventType eventType = WMLIntrinsicEventUnknown;
+
+ switch (loader->policyChecker()->loadType()) {
+ case FrameLoadTypeReload:
+ break;
+ case FrameLoadTypeBack:
+ eventType = WMLIntrinsicEventOnEnterBackward;
+ break;
+ case FrameLoadTypeBackWMLDeckNotAccessible:
+ reportWMLError(document(), WMLErrorDeckNotAccessible);
+ return;
+ default:
+ eventType = WMLIntrinsicEventOnEnterForward;
+ break;
+ }
+
+ // Figure out target event handler
+ WMLIntrinsicEventHandler* eventHandler = this->eventHandler();
+ bool hasIntrinsicEvent = false;
+
+ if (eventType != WMLIntrinsicEventUnknown) {
+ if (eventHandler && eventHandler->hasIntrinsicEvent(eventType))
+ hasIntrinsicEvent = true;
+ else if (m_template) {
+ eventHandler = m_template->eventHandler();
+ if (eventHandler && eventHandler->hasIntrinsicEvent(eventType))
+ hasIntrinsicEvent = true;
+ }
+ }
+
+ if (hasIntrinsicEvent)
+ eventHandler->triggerIntrinsicEvent(eventType);
+
+ // Start the timer if it exists in current card
+ if (m_eventTimer)
+ m_eventTimer->start();
+
+ for (Node* node = traverseNextNode(); node != 0; node = node->traverseNextNode()) {
+ if (!node->isElementNode())
+ continue;
+
+ if (node->hasTagName(inputTag))
+ static_cast<WMLInputElement*>(node)->initialize();
+ else if (node->hasTagName(selectTag))
+ static_cast<WMLSelectElement*>(node)->selectInitialOptions();
+ }
+}
+
+void WMLCardElement::handleDeckLevelTaskOverridesIfNeeded()
+{
+ // Spec: The event-handling element may appear inside a template element and specify
+ // event-processing behaviour for all cards in the deck. A deck-level event-handling
+ // element is equivalent to specifying the event-handling element in each card.
+ if (!m_template)
+ return;
+
+ Vector<WMLDoElement*>& templateDoElements = m_template->doElements();
+ if (templateDoElements.isEmpty())
+ return;
+
+ Vector<WMLDoElement*>& cardDoElements = doElements();
+ Vector<WMLDoElement*>::iterator it = cardDoElements.begin();
+ Vector<WMLDoElement*>::iterator end = cardDoElements.end();
+
+ HashSet<String> cardDoElementNames;
+ for (; it != end; ++it)
+ cardDoElementNames.add((*it)->name());
+
+ it = templateDoElements.begin();
+ end = templateDoElements.end();
+
+ for (; it != end; ++it)
+ (*it)->setActive(!cardDoElementNames.contains((*it)->name()));
+}
+
+void WMLCardElement::parseMappedAttribute(Attribute* attr)
+{
+ WMLIntrinsicEventType eventType = WMLIntrinsicEventUnknown;
+
+ if (attr->name() == onenterforwardAttr)
+ eventType = WMLIntrinsicEventOnEnterForward;
+ else if (attr->name() == onenterbackwardAttr)
+ eventType = WMLIntrinsicEventOnEnterBackward;
+ else if (attr->name() == ontimerAttr)
+ eventType = WMLIntrinsicEventOnTimer;
+ else if (attr->name() == newcontextAttr)
+ m_isNewContext = (attr->value() == "true");
+ else if (attr->name() == orderedAttr)
+ m_isOrdered = (attr->value() == "true");
+ else {
+ WMLElement::parseMappedAttribute(attr);
+ return;
+ }
+
+ if (eventType == WMLIntrinsicEventUnknown)
+ return;
+
+ // Register intrinsic event in card
+ RefPtr<WMLIntrinsicEvent> event = WMLIntrinsicEvent::create(document(), attr->value());
+
+ createEventHandlerIfNeeded();
+ eventHandler()->registerIntrinsicEvent(eventType, event);
+}
+
+void WMLCardElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+ Document* document = this->document();
+
+ // The first card inserted into a document, is visible by default.
+ if (!m_isVisible) {
+ RefPtr<NodeList> nodeList = document->getElementsByTagName("card");
+ if (nodeList && nodeList->length() == 1 && nodeList->item(0) == this)
+ m_isVisible = true;
+ }
+
+ // For the WML layout tests we embed WML content in a XHTML document. Navigating to different cards
+ // within the same deck has a different behaviour in HTML than in WML. HTML wants to "scroll to anchor"
+ // (see FrameLoader) but WML wants a reload. Notify the root document of the layout test that we want
+ // to mimic WML behaviour. This is rather tricky, but has been tested extensively. Usually it's not possible
+ // at all to embed WML in HTML, it's not designed that way, we're just "abusing" it for dynamically created layout tests.
+ if (document->page() && document->page()->mainFrame()) {
+ Document* rootDocument = document->page()->mainFrame()->document();
+ if (rootDocument && rootDocument != document)
+ rootDocument->setContainsWMLContent(true);
+ }
+}
+
+RenderObject* WMLCardElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ if (!m_isVisible) {
+ style->setUnique();
+ style->setDisplay(NONE);
+ }
+
+ return WMLElement::createRenderer(arena, style);
+}
+
+WMLCardElement* WMLCardElement::findNamedCardInDocument(Document* doc, const String& cardName)
+{
+ if (cardName.isEmpty())
+ return 0;
+
+ RefPtr<NodeList> nodeList = doc->getElementsByTagName("card");
+ if (!nodeList)
+ return 0;
+
+ unsigned length = nodeList->length();
+ if (length < 1)
+ return 0;
+
+ for (unsigned i = 0; i < length; ++i) {
+ WMLCardElement* card = static_cast<WMLCardElement*>(nodeList->item(i));
+ if (card->getIdAttribute() != cardName)
+ continue;
+
+ return card;
+ }
+
+ return 0;
+}
+
+WMLCardElement* WMLCardElement::determineActiveCard(Document* doc)
+{
+ WMLPageState* pageState = wmlPageStateForDocument(doc);
+ if (!pageState)
+ return 0;
+
+ RefPtr<NodeList> nodeList = doc->getElementsByTagName("card");
+ if (!nodeList)
+ return 0;
+
+ unsigned length = nodeList->length();
+ if (length < 1)
+ return 0;
+
+ // Figure out the new target card
+ String cardName = doc->url().fragmentIdentifier();
+
+ WMLCardElement* activeCard = findNamedCardInDocument(doc, cardName);
+ if (activeCard) {
+ // Hide all cards - except the destination card - in document
+ for (unsigned i = 0; i < length; ++i) {
+ WMLCardElement* card = static_cast<WMLCardElement*>(nodeList->item(i));
+
+ if (card == activeCard)
+ card->showCard();
+ else
+ card->hideCard();
+ }
+ } else {
+ // If the target URL didn't contain a fragment identifier, activeCard
+ // is 0, and has to be set to the first card element in the deck.
+ activeCard = static_cast<WMLCardElement*>(nodeList->item(0));
+ activeCard->showCard();
+ }
+
+ // Assure destination card is visible
+ ASSERT(activeCard->isVisible());
+ ASSERT(activeCard->attached());
+ ASSERT(activeCard->renderer());
+
+ // Update the document title
+ doc->setTitle(activeCard->title());
+
+ return activeCard;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLCardElement.h b/Source/WebCore/wml/WMLCardElement.h
new file mode 100644
index 0000000..f82374d
--- /dev/null
+++ b/Source/WebCore/wml/WMLCardElement.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLCardElement_h
+#define WMLCardElement_h
+
+#if ENABLE(WML)
+#include "WMLEventHandlingElement.h"
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class WMLTemplateElement;
+class WMLTimerElement;
+
+class WMLCardElement : public WMLElement, public WMLEventHandlingElement {
+public:
+ static PassRefPtr<WMLCardElement> create(const QualifiedName& tagName, Document*);
+
+ WMLCardElement(const QualifiedName&, Document*);
+ virtual ~WMLCardElement();
+
+ bool isNewContext() const { return m_isNewContext; }
+ bool isOrdered() const { return m_isOrdered; }
+ WMLTimerElement* eventTimer() const { return m_eventTimer; }
+ WMLTemplateElement* templateElement() const { return m_template; }
+
+ void setTemplateElement(WMLTemplateElement*);
+ void setIntrinsicEventTimer(WMLTimerElement*);
+
+ void handleIntrinsicEventIfNeeded();
+ void handleDeckLevelTaskOverridesIfNeeded();
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ // Switch active card in document to the one specified in the URL reference (foo.wml#mycard)
+ // If the 'targetUrl' doesn't contain a reference, use the first <card> element in the document.
+ static WMLCardElement* determineActiveCard(Document*);
+ static WMLCardElement* findNamedCardInDocument(Document*, const String& cardName);
+
+private:
+ bool isVisible() const { return m_isVisible; }
+
+ void showCard();
+ void hideCard();
+
+ bool m_isNewContext;
+ bool m_isOrdered;
+ bool m_isVisible;
+
+ WMLTimerElement* m_eventTimer;
+ WMLTemplateElement* m_template;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLDoElement.cpp b/Source/WebCore/wml/WMLDoElement.cpp
new file mode 100644
index 0000000..a8d4880
--- /dev/null
+++ b/Source/WebCore/wml/WMLDoElement.cpp
@@ -0,0 +1,195 @@
+/**
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLDoElement.h"
+
+#include "Attribute.h"
+#include "BackForwardController.h"
+#include "Event.h"
+#include "EventNames.h"
+#include "HTMLNames.h"
+#include "KeyboardEvent.h"
+#include "Page.h"
+#include "RenderButton.h"
+#include "WMLCardElement.h"
+#include "WMLDocument.h"
+#include "WMLNames.h"
+#include "WMLPageState.h"
+#include "WMLTaskElement.h"
+#include "WMLTimerElement.h"
+#include "WMLVariables.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLDoElement::WMLDoElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+ , m_task(0)
+ , m_isActive(false)
+ , m_isNoop(false)
+ , m_isOptional(false)
+{
+}
+
+PassRefPtr<WMLDoElement> WMLDoElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLDoElement(tagName, document));
+}
+
+void WMLDoElement::defaultEventHandler(Event* event)
+{
+ if (m_isOptional)
+ return;
+
+ if (event->type() == eventNames().keypressEvent) {
+ WMLElement::defaultEventHandler(event);
+ return;
+ }
+
+ if (event->type() != eventNames().clickEvent && event->type() != eventNames().keydownEvent)
+ return;
+
+ if (event->isKeyboardEvent()
+ && static_cast<KeyboardEvent*>(event)->keyIdentifier() != "Enter")
+ return;
+
+ if (m_type == "accept" || m_type == "options") {
+ if (m_task)
+ m_task->executeTask();
+ } else if (m_type == "prev") {
+ ASSERT(document()->isWMLDocument());
+ WMLDocument* document = static_cast<WMLDocument*>(this->document());
+
+ WMLPageState* pageState = wmlPageStateForDocument(document);
+ if (!pageState)
+ return;
+
+ // Stop the timer of the current card if it is active
+ if (WMLCardElement* card = document->activeCard()) {
+ if (WMLTimerElement* eventTimer = card->eventTimer())
+ eventTimer->stop();
+ }
+
+ pageState->page()->backForward()->goBack();
+ } else if (m_type == "reset") {
+ WMLPageState* pageState = wmlPageStateForDocument(document());
+ if (!pageState)
+ return;
+
+ pageState->reset();
+ }
+}
+
+void WMLDoElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::typeAttr)
+ m_type = parseValueForbiddingVariableReferences(attr->value());
+ else if (attr->name() == HTMLNames::nameAttr)
+ m_name = parseValueForbiddingVariableReferences(attr->value());
+ else if (attr->name() == optionalAttr)
+ m_isOptional = (attr->value() == "true");
+ else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+void WMLDoElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ // Spec: An unspecified 'name' defaults to the value of the 'type' attribute.
+ if (!hasAttribute(HTMLNames::nameAttr))
+ m_name = m_type;
+
+ ContainerNode* parent = parentNode();
+ if (!parent || !parent->isWMLElement())
+ return;
+
+ if (WMLEventHandlingElement* eventHandlingElement = toWMLEventHandlingElement(static_cast<WMLElement*>(parent)))
+ eventHandlingElement->registerDoElement(this, document());
+}
+
+void WMLDoElement::removedFromDocument()
+{
+ ContainerNode* parent = parentNode();
+
+ if (parent && parent->isWMLElement()) {
+ if (WMLEventHandlingElement* eventHandlingElement = toWMLEventHandlingElement(static_cast<WMLElement*>(parent)))
+ eventHandlingElement->deregisterDoElement(this);
+ }
+
+ WMLElement::removedFromDocument();
+}
+
+void WMLDoElement::attach()
+{
+ WMLElement::attach();
+
+ // The call to updateFromElement() needs to go after the call through
+ // to the base class's attach() because that can sometimes do a close
+ // on the renderer.
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+RenderObject* WMLDoElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ if (!m_isActive || m_isOptional || m_isNoop)
+ return 0;
+
+ if (style) {
+ style->setUnique();
+ style->setBackgroundColor(Color::lightGray);
+ }
+
+ return new (arena) RenderButton(this);
+}
+
+void WMLDoElement::recalcStyle(StyleChange change)
+{
+ WMLElement::recalcStyle(change);
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+void WMLDoElement::registerTask(WMLTaskElement* task)
+{
+ ASSERT(!m_task);
+ m_task = task;
+}
+
+void WMLDoElement::deregisterTask(WMLTaskElement* task)
+{
+ ASSERT_UNUSED(task, m_task == task);
+ m_task = 0;
+}
+
+String WMLDoElement::label() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::labelAttr));
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLDoElement.h b/Source/WebCore/wml/WMLDoElement.h
new file mode 100644
index 0000000..2ba6d9e
--- /dev/null
+++ b/Source/WebCore/wml/WMLDoElement.h
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLDoElement_h
+#define WMLDoElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLTaskElement;
+
+class WMLDoElement : public WMLElement {
+public:
+ static PassRefPtr<WMLDoElement> create(const QualifiedName& tagName, Document*);
+
+ WMLDoElement(const QualifiedName& tagName, Document*);
+
+ virtual void defaultEventHandler(Event*);
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ virtual void attach();
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void recalcStyle(StyleChange);
+
+ void registerTask(WMLTaskElement*);
+ void deregisterTask(WMLTaskElement*);
+
+ bool isActive() const { return m_isActive; }
+ String label() const;
+ String name() const { return m_name; }
+
+ void setActive(bool active) { m_isActive = active; }
+ void setNoop(bool noop) { m_isNoop = noop;}
+
+private:
+ WMLTaskElement* m_task;
+ bool m_isActive;
+ bool m_isNoop;
+ bool m_isOptional;
+ String m_name;
+ String m_type;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLDocument.cpp b/Source/WebCore/wml/WMLDocument.cpp
new file mode 100644
index 0000000..9b29899
--- /dev/null
+++ b/Source/WebCore/wml/WMLDocument.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLDocument.h"
+
+#include "BackForwardController.h"
+#include "BackForwardList.h"
+#include "Frame.h"
+#include "Page.h"
+#include "ScriptableDocumentParser.h"
+#include "WMLCardElement.h"
+#include "WMLErrorHandling.h"
+#include "WMLPageState.h"
+#include "WMLTemplateElement.h"
+
+namespace WebCore {
+
+WMLDocument::WMLDocument(Frame* frame, const KURL& url)
+ : Document(frame, url, false, false)
+ , m_activeCard(0)
+{
+ clearXMLVersion();
+}
+
+WMLDocument::~WMLDocument()
+{
+}
+
+void WMLDocument::finishedParsing()
+{
+ if (ScriptableDocumentParser* parser = this->scriptableDocumentParser()) {
+ if (!parser->wellFormed()) {
+ Document::finishedParsing();
+ return;
+ }
+ }
+
+ bool hasAccess = initialize(true);
+ Document::finishedParsing();
+
+ if (!hasAccess) {
+ m_activeCard = 0;
+
+ WMLPageState* wmlPageState = wmlPageStateForDocument(this);
+ if (!wmlPageState)
+ return;
+
+ Page* page = wmlPageState->page();
+ if (!page)
+ return;
+
+ HistoryItem* item = page->backForward()->backItem();
+ if (!item)
+ return;
+
+ page->goToItem(item, FrameLoadTypeBackWMLDeckNotAccessible);
+ return;
+ }
+
+ if (m_activeCard)
+ m_activeCard->handleIntrinsicEventIfNeeded();
+}
+
+bool WMLDocument::initialize(bool aboutToFinishParsing)
+{
+ WMLPageState* wmlPageState = wmlPageStateForDocument(this);
+ if (!wmlPageState || !wmlPageState->canAccessDeck())
+ return false;
+
+ // Remember that we'e successfully entered the deck
+ wmlPageState->resetAccessControlData();
+
+ // Notify the existance of templates to all cards of the current deck
+ WMLTemplateElement::registerTemplatesInDocument(this);
+
+ // Set destination card
+ m_activeCard = WMLCardElement::determineActiveCard(this);
+ if (!m_activeCard) {
+ reportWMLError(this, WMLErrorNoCardInDocument);
+ return true;
+ }
+
+ // Handle deck-level task overrides
+ m_activeCard->handleDeckLevelTaskOverridesIfNeeded();
+
+ // Handle card-level intrinsic event
+ if (!aboutToFinishParsing)
+ m_activeCard->handleIntrinsicEventIfNeeded();
+
+ return true;
+}
+
+WMLPageState* wmlPageStateForDocument(Document* doc)
+{
+ ASSERT(doc);
+
+ Page* page = doc->page();
+ ASSERT(page);
+
+ return page->wmlPageState();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLDocument.h b/Source/WebCore/wml/WMLDocument.h
new file mode 100644
index 0000000..3057d9b
--- /dev/null
+++ b/Source/WebCore/wml/WMLDocument.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLDocument_h
+#define WMLDocument_h
+
+#if ENABLE(WML)
+#include "Document.h"
+#include "WMLErrorHandling.h"
+#include "WMLPageState.h"
+
+namespace WebCore {
+
+class WMLCardElement;
+
+class WMLDocument : public Document {
+public:
+ static PassRefPtr<WMLDocument> create(Frame* frame, const KURL& url)
+ {
+ return adoptRef(new WMLDocument(frame, url));
+ }
+
+ virtual ~WMLDocument();
+
+ virtual bool isWMLDocument() const { return true; }
+ virtual void finishedParsing();
+
+ bool initialize(bool aboutToFinishParsing = false);
+
+ WMLCardElement* activeCard() const { return m_activeCard; }
+
+private:
+ WMLDocument(Frame*, const KURL&);
+ WMLCardElement* m_activeCard;
+};
+
+WMLPageState* wmlPageStateForDocument(Document*);
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLElement.cpp b/Source/WebCore/wml/WMLElement.cpp
new file mode 100644
index 0000000..9b0be47
--- /dev/null
+++ b/Source/WebCore/wml/WMLElement.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "RenderObject.h"
+#include "WMLErrorHandling.h"
+#include "WMLNames.h"
+#include "WMLVariables.h"
+
+using std::max;
+using std::min;
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLElement::WMLElement(const QualifiedName& tagName, Document* document)
+ : StyledElement(tagName, document, CreateStyledElement)
+{
+}
+
+PassRefPtr<WMLElement> WMLElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLElement(tagName, document));
+}
+
+bool WMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == HTMLNames::alignAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ return StyledElement::mapToEntry(attrName, result);
+}
+
+void WMLElement::parseMappedAttribute(Attribute* attr)
+{
+ if (isIdAttributeName(attr->name())
+ || attr->name() == HTMLNames::classAttr
+ || attr->name() == HTMLNames::styleAttr)
+ return StyledElement::parseMappedAttribute(attr);
+
+ if (attr->name() == HTMLNames::alignAttr) {
+ if (equalIgnoringCase(attr->value(), "middle"))
+ addCSSProperty(attr, CSSPropertyTextAlign, "center");
+ else
+ addCSSProperty(attr, CSSPropertyTextAlign, attr->value());
+ } else if (attr->name() == HTMLNames::tabindexAttr) {
+ String indexstring = attr->value();
+ int tabindex = 0;
+ if (parseHTMLInteger(indexstring, tabindex)) {
+ // Clamp tabindex to the range of 'short' to match Firefox's behavior.
+ setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
+ }
+ }
+}
+
+String WMLElement::title() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::titleAttr));
+}
+
+bool WMLElement::rendererIsNeeded(RenderStyle* style)
+{
+ return document()->documentElement() == this || style->display() != NONE;
+}
+
+RenderObject* WMLElement::createRenderer(RenderArena*, RenderStyle* style)
+{
+ return RenderObject::createObject(this, style);
+}
+
+String WMLElement::parseValueSubstitutingVariableReferences(const AtomicString& value, WMLErrorCode defaultErrorCode) const
+{
+ bool isValid = false;
+ if (!containsVariableReference(value, isValid))
+ return value;
+
+ if (!isValid) {
+ reportWMLError(document(), defaultErrorCode);
+ return String();
+ }
+
+ return substituteVariableReferences(value, document());
+}
+
+String WMLElement::parseValueForbiddingVariableReferences(const AtomicString& value) const
+{
+ bool isValid = false;
+ if (containsVariableReference(value, isValid)) {
+ reportWMLError(document(), WMLErrorInvalidVariableReferenceLocation);
+ return String();
+ }
+
+ return value;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLElement.h b/Source/WebCore/wml/WMLElement.h
new file mode 100644
index 0000000..a7c82c0
--- /dev/null
+++ b/Source/WebCore/wml/WMLElement.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLElement_h
+#define WMLElement_h
+
+#if ENABLE(WML)
+#include "StyledElement.h"
+#include "WMLErrorHandling.h"
+
+namespace WebCore {
+
+class WMLElement : public StyledElement {
+public:
+ static PassRefPtr<WMLElement> create(const QualifiedName& tagName, Document*);
+
+ virtual bool isWMLElement() const { return true; }
+ virtual bool isWMLTaskElement() const { return false; }
+
+ virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual String title() const;
+
+ virtual bool rendererIsNeeded(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+protected:
+ WMLElement(const QualifiedName& tagName, Document*);
+
+ // Helper function for derived classes
+ String parseValueSubstitutingVariableReferences(const AtomicString&, WMLErrorCode defaultErrorCode = WMLErrorInvalidVariableReference) const;
+ String parseValueForbiddingVariableReferences(const AtomicString&) const;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLErrorHandling.cpp b/Source/WebCore/wml/WMLErrorHandling.cpp
new file mode 100644
index 0000000..a49a71b
--- /dev/null
+++ b/Source/WebCore/wml/WMLErrorHandling.cpp
@@ -0,0 +1,106 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLErrorHandling.h"
+
+#include "Console.h"
+#include "Frame.h"
+#include "Document.h"
+#include "DOMWindow.h"
+#include "XMLDocumentParser.h"
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+void reportWMLError(Document* doc, WMLErrorCode error)
+{
+ if (!doc || error == WMLErrorUnknown)
+ return;
+
+ String errorMessage = errorMessageForErrorCode(error);
+ XMLDocumentParser* parser = static_cast<XMLDocumentParser*>(doc->parser());
+ if (parser && error != WMLErrorDeckNotAccessible) {
+ // Some errors are reported as result of an insertedIntoDocument() call.
+ // If this happened, parsing has been stopped, and the document fragment
+ // is wrapped in a XHTML error document. That means insertedIntoDocument()
+ // will be called again - do NOT report the error twice, that would result
+ // in an infinite error reporting loop.
+ if (!parser->wellFormed())
+ return;
+
+ parser->handleError(XMLDocumentParser::fatal, errorMessage.latin1().data(), parser->textPositionOneBased());
+ } else {
+ Frame* frame = doc->frame();
+ if (!frame)
+ return;
+
+ DOMWindow* domWindow = frame->domWindow();
+ if (!domWindow)
+ return;
+
+ Console* console = domWindow->console();
+ if (!console)
+ return;
+
+ console->addMessage(WMLMessageSource, LogMessageType, ErrorMessageLevel, errorMessage, 0, String());
+ }
+}
+
+String errorMessageForErrorCode(WMLErrorCode error)
+{
+ switch (error) {
+ case WMLErrorConflictingEventBinding:
+ return "Conflicting event bindings within an element.";
+ case WMLErrorDeckNotAccessible:
+ return "Deck not accessible.";
+ case WMLErrorDuplicatedDoElement:
+ return "At least two do elements share a name, which is not allowed.";
+ case WMLErrorForbiddenTaskInAnchorElement:
+ return "Forbidden task contained in anchor element.";
+ case WMLErrorInvalidColumnsNumberInTable:
+ return "A table contains an invalid number of columns.";
+ case WMLErrorInvalidVariableName:
+ return "A variable name contains invalid characters.";
+ case WMLErrorInvalidVariableReference:
+ return "A variable reference uses invalid syntax.";
+ case WMLErrorInvalidVariableReferenceLocation:
+ return "A variable reference is placed in an invalid location.";
+ case WMLErrorMultipleAccessElements:
+ return "Only one access element is allowed in a deck.";
+ case WMLErrorMultipleTemplateElements:
+ return "Only one template element is allowed in a deck.";
+ case WMLErrorNoCardInDocument:
+ return "No card contained in document.";
+ case WMLErrorMultipleTimerElements:
+ return "Only one timer element is allowed in a card.";
+ case WMLErrorUnknown:
+ return String();
+ };
+
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLErrorHandling.h b/Source/WebCore/wml/WMLErrorHandling.h
new file mode 100644
index 0000000..c75c975
--- /dev/null
+++ b/Source/WebCore/wml/WMLErrorHandling.h
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLErrorHandling_h
+#define WMLErrorHandling_h
+
+#include <wtf/Forward.h>
+
+#if ENABLE(WML)
+namespace WebCore {
+
+ class Document;
+
+ enum WMLErrorCode {
+ WMLErrorUnknown = 0,
+ WMLErrorConflictingEventBinding,
+ WMLErrorDeckNotAccessible,
+ WMLErrorDuplicatedDoElement,
+ WMLErrorForbiddenTaskInAnchorElement,
+ WMLErrorInvalidColumnsNumberInTable,
+ WMLErrorInvalidVariableName,
+ WMLErrorInvalidVariableReference,
+ WMLErrorInvalidVariableReferenceLocation,
+ WMLErrorMultipleAccessElements,
+ WMLErrorMultipleTemplateElements,
+ WMLErrorMultipleTimerElements,
+ WMLErrorNoCardInDocument
+ };
+
+ String errorMessageForErrorCode(WMLErrorCode);
+ void reportWMLError(Document*, WMLErrorCode);
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLEventHandlingElement.cpp b/Source/WebCore/wml/WMLEventHandlingElement.cpp
new file mode 100644
index 0000000..faa80c7
--- /dev/null
+++ b/Source/WebCore/wml/WMLEventHandlingElement.cpp
@@ -0,0 +1,97 @@
+/**
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLEventHandlingElement.h"
+
+#include "WMLCardElement.h"
+#include "WMLDoElement.h"
+#include "WMLIntrinsicEventHandler.h"
+#include "WMLOptionElement.h"
+#include "WMLTaskElement.h"
+#include "WMLTemplateElement.h"
+#include "WMLNames.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLEventHandlingElement::WMLEventHandlingElement()
+{
+}
+
+WMLEventHandlingElement::~WMLEventHandlingElement()
+{
+}
+
+void WMLEventHandlingElement::createEventHandlerIfNeeded()
+{
+ if (!m_eventHandler)
+ m_eventHandler.set(new WMLIntrinsicEventHandler);
+}
+
+void WMLEventHandlingElement::registerDoElement(WMLDoElement* doElement, Document* document)
+{
+ Vector<WMLDoElement*>::iterator it = m_doElements.begin();
+ Vector<WMLDoElement*>::iterator end = m_doElements.end();
+
+ for (; it != end; ++it) {
+ if ((*it)->name() == doElement->name()) {
+ reportWMLError(document, WMLErrorDuplicatedDoElement);
+ return;
+ }
+ }
+
+ ASSERT(m_doElements.find(doElement) == WTF::notFound);
+ m_doElements.append(doElement);
+ doElement->setActive(true);
+}
+
+void WMLEventHandlingElement::deregisterDoElement(WMLDoElement* doElement)
+{
+ doElement->setActive(false);
+
+ size_t position = m_doElements.find(doElement);
+ if (position == WTF::notFound)
+ return;
+
+ m_doElements.remove(position);
+}
+
+WMLEventHandlingElement* toWMLEventHandlingElement(WMLElement* element)
+{
+ if (!element->isWMLElement())
+ return 0;
+
+ if (element->hasTagName(cardTag))
+ return static_cast<WMLCardElement*>(element);
+ else if (element->hasTagName(optionTag))
+ return static_cast<WMLOptionElement*>(element);
+ else if (element->hasTagName(templateTag))
+ return static_cast<WMLTemplateElement*>(element);
+
+ return 0;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLEventHandlingElement.h b/Source/WebCore/wml/WMLEventHandlingElement.h
new file mode 100644
index 0000000..15cef7b
--- /dev/null
+++ b/Source/WebCore/wml/WMLEventHandlingElement.h
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLEventHandlingElement_h
+#define WMLEventHandlingElement_h
+
+#if ENABLE(WML)
+#include "WMLIntrinsicEventHandler.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class WMLElement;
+class WMLDoElement;
+
+class WMLEventHandlingElement {
+public:
+ WMLEventHandlingElement();
+ ~WMLEventHandlingElement();
+
+ WMLIntrinsicEventHandler* eventHandler() const { return m_eventHandler.get(); }
+ void createEventHandlerIfNeeded();
+
+ Vector<WMLDoElement*>& doElements() { return m_doElements; }
+ void registerDoElement(WMLDoElement*, Document*);
+ void deregisterDoElement(WMLDoElement*);
+
+private:
+ OwnPtr<WMLIntrinsicEventHandler> m_eventHandler;
+ Vector<WMLDoElement*> m_doElements;
+};
+
+WMLEventHandlingElement* toWMLEventHandlingElement(WMLElement*);
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLFieldSetElement.cpp b/Source/WebCore/wml/WMLFieldSetElement.cpp
new file mode 100644
index 0000000..86c1e46
--- /dev/null
+++ b/Source/WebCore/wml/WMLFieldSetElement.cpp
@@ -0,0 +1,85 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLFieldSetElement.h"
+
+#include "Attribute.h"
+#include "HTMLNames.h"
+#include "RenderFieldset.h"
+#include "Text.h"
+#include "WMLElementFactory.h"
+#include "WMLNames.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLFieldSetElement::WMLFieldSetElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLFieldSetElement> WMLFieldSetElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLFieldSetElement(tagName, document));
+}
+
+WMLFieldSetElement::~WMLFieldSetElement()
+{
+}
+
+void WMLFieldSetElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ String title = parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::titleAttr));
+ if (title.isEmpty())
+ return;
+
+ m_insertedLegendElement = WMLElementFactory::createWMLElement(insertedLegendTag, document());
+
+ // Insert <dummyLegend> element, as RenderFieldset expect it to be present
+ // to layout it's child text content, when rendering <fieldset> elements
+ ExceptionCode ec = 0;
+ appendChild(m_insertedLegendElement, ec);
+ ASSERT(ec == 0);
+
+ // Create text node holding the 'title' attribute value
+ m_insertedLegendElement->appendChild(document()->createTextNode(title), ec);
+ ASSERT(ec == 0);
+}
+
+void WMLFieldSetElement::removedFromDocument()
+{
+ m_insertedLegendElement.clear();
+ WMLElement::removedFromDocument();
+}
+
+RenderObject* WMLFieldSetElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderFieldset(this);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLFieldSetElement.h b/Source/WebCore/wml/WMLFieldSetElement.h
new file mode 100644
index 0000000..11ef2c1
--- /dev/null
+++ b/Source/WebCore/wml/WMLFieldSetElement.h
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLFieldSetElement_h
+#define WMLFieldSetElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLFieldSetElement : public WMLElement {
+public:
+ static PassRefPtr<WMLFieldSetElement> create(const QualifiedName&, Document*);
+
+ WMLFieldSetElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLFieldSetElement();
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+private:
+ RefPtr<WMLElement> m_insertedLegendElement;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLFormControlElement.cpp b/Source/WebCore/wml/WMLFormControlElement.cpp
new file mode 100644
index 0000000..c264340
--- /dev/null
+++ b/Source/WebCore/wml/WMLFormControlElement.cpp
@@ -0,0 +1,86 @@
+/**
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLFormControlElement.h"
+
+#include "RenderBox.h"
+#include "RenderObject.h"
+#include "RenderStyle.h"
+
+namespace WebCore {
+
+WMLFormControlElement::WMLFormControlElement(const QualifiedName& tagName, Document* document)
+ : WMLElement(tagName, document)
+ , m_valueMatchesRenderer(false)
+{
+}
+
+PassRefPtr<WMLFormControlElement> WMLFormControlElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLFormControlElement(tagName, document));
+}
+
+WMLFormControlElement::~WMLFormControlElement()
+{
+}
+
+bool WMLFormControlElement::supportsFocus() const
+{
+ return true;
+}
+
+bool WMLFormControlElement::isFocusable() const
+{
+ if (!renderer() || !renderer()->isBox())
+ return false;
+
+ if (toRenderBox(renderer())->size().isEmpty())
+ return false;
+
+ return WMLElement::isFocusable();
+}
+
+
+void WMLFormControlElement::attach()
+{
+ ASSERT(!attached());
+ WMLElement::attach();
+
+ // The call to updateFromElement() needs to go after the call through
+ // to the base class's attach() because that can sometimes do a close
+ // on the renderer.
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+void WMLFormControlElement::recalcStyle(StyleChange change)
+{
+ WMLElement::recalcStyle(change);
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLFormControlElement.h b/Source/WebCore/wml/WMLFormControlElement.h
new file mode 100644
index 0000000..674303b
--- /dev/null
+++ b/Source/WebCore/wml/WMLFormControlElement.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLFormControlElement_h
+#define WMLFormControlElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLFormControlElement : public WMLElement {
+public:
+ static PassRefPtr<WMLFormControlElement> create(const QualifiedName&, Document*);
+
+
+ virtual ~WMLFormControlElement();
+
+ virtual bool isFormControlElement() const { return true; }
+ virtual bool isReadOnlyFormControl() const { return false; }
+ virtual bool isTextFormControl() const { return false; }
+
+ virtual bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
+ virtual void setFormControlValueMatchesRenderer(bool b = true) { m_valueMatchesRenderer = b; }
+
+ virtual bool supportsFocus() const;
+ virtual bool isFocusable() const;
+
+ virtual void attach();
+ virtual void recalcStyle(StyleChange);
+
+protected:
+ WMLFormControlElement(const QualifiedName&, Document*);
+
+private:
+ bool m_valueMatchesRenderer;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLGoElement.cpp b/Source/WebCore/wml/WMLGoElement.cpp
new file mode 100644
index 0000000..cc41226
--- /dev/null
+++ b/Source/WebCore/wml/WMLGoElement.cpp
@@ -0,0 +1,229 @@
+/**
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLGoElement.h"
+
+#include "Attribute.h"
+#include "FormData.h"
+#include "FormDataBuilder.h"
+#include "FormSubmission.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "HTMLNames.h"
+#include "ResourceRequest.h"
+#include "TextEncoding.h"
+#include "WMLCardElement.h"
+#include "WMLDocument.h"
+#include "WMLNames.h"
+#include "WMLPageState.h"
+#include "WMLPostfieldElement.h"
+#include "WMLTimerElement.h"
+#include "WMLVariables.h"
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLGoElement::WMLGoElement(const QualifiedName& tagName, Document* doc)
+ : WMLTaskElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLGoElement> WMLGoElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLGoElement(tagName, document));
+}
+
+void WMLGoElement::registerPostfieldElement(WMLPostfieldElement* postfield)
+{
+ ASSERT(m_postfieldElements.find(postfield) == WTF::notFound);
+ m_postfieldElements.append(postfield);
+}
+
+void WMLGoElement::deregisterPostfieldElement(WMLPostfieldElement* postfield)
+{
+ size_t position = m_postfieldElements.find(postfield);
+ ASSERT(position != WTF::notFound);
+ m_postfieldElements.remove(position);
+}
+
+void WMLGoElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::methodAttr)
+ m_formAttributes.parseMethodType(attr->value());
+ else if (attr->name() == HTMLNames::enctypeAttr)
+ m_formAttributes.parseEncodingType(parseValueSubstitutingVariableReferences(attr->value()));
+ else if (attr->name() == HTMLNames::accept_charsetAttr)
+ m_formAttributes.setAcceptCharset(parseValueForbiddingVariableReferences(attr->value()));
+ else
+ WMLTaskElement::parseMappedAttribute(attr);
+}
+
+void WMLGoElement::executeTask()
+{
+ ASSERT(document()->isWMLDocument());
+ WMLDocument* document = static_cast<WMLDocument*>(this->document());
+
+ WMLPageState* pageState = wmlPageStateForDocument(document);
+ if (!pageState)
+ return;
+
+ WMLCardElement* card = document->activeCard();
+ if (!card)
+ return;
+
+ Frame* frame = document->frame();
+ if (!frame)
+ return;
+
+ FrameLoader* loader = frame->loader();
+ if (!loader)
+ return;
+
+ String href = getAttribute(HTMLNames::hrefAttr);
+ if (href.isEmpty())
+ return;
+
+ // Substitute variables within target url attribute value
+ KURL url = document->completeURL(substituteVariableReferences(href, document, WMLVariableEscapingEscape));
+ if (url.isEmpty())
+ return;
+
+ storeVariableState(pageState);
+
+ // Stop the timer of the current card if it is active
+ if (WMLTimerElement* eventTimer = card->eventTimer())
+ eventTimer->stop();
+
+ // FIXME: 'newcontext' handling not implemented for external cards
+ bool inSameDeck = document->url().path() == url.path();
+ if (inSameDeck && url.hasFragmentIdentifier()) {
+ if (WMLCardElement* card = WMLCardElement::findNamedCardInDocument(document, url.fragmentIdentifier())) {
+ if (card->isNewContext())
+ pageState->reset();
+ }
+ }
+
+ // Prepare loading the destination url
+ ResourceRequest request(url);
+
+ if (getAttribute(sendrefererAttr) == "true")
+ request.setHTTPReferrer(loader->outgoingReferrer());
+
+ String cacheControl = getAttribute(cache_controlAttr);
+
+ if (m_formAttributes.method() == FormSubmission::PostMethod)
+ preparePOSTRequest(request, inSameDeck, cacheControl);
+ else
+ prepareGETRequest(request, url);
+
+ // Set HTTP cache-control header if needed
+ if (!cacheControl.isEmpty()) {
+ request.setHTTPHeaderField("cache-control", cacheControl);
+
+ if (cacheControl == "no-cache")
+ request.setCachePolicy(ReloadIgnoringCacheData);
+ }
+
+ loader->load(request, false);
+}
+
+void WMLGoElement::preparePOSTRequest(ResourceRequest& request, bool inSameDeck, const String& cacheControl)
+{
+ request.setHTTPMethod("POST");
+
+ if (inSameDeck && cacheControl != "no-cache") {
+ request.setCachePolicy(ReturnCacheDataDontLoad);
+ return;
+ }
+
+ RefPtr<FormData> data;
+
+ if (m_formAttributes.isMultiPartForm()) { // multipart/form-data
+ Vector<char> boundary = FormDataBuilder::generateUniqueBoundaryString();
+ data = createFormData(boundary.data());
+ request.setHTTPContentType(m_formAttributes.encodingType() + "; boundary=" + boundary.data());
+ } else {
+ // text/plain or application/x-www-form-urlencoded
+ data = createFormData(CString());
+ request.setHTTPContentType(m_formAttributes.encodingType());
+ }
+
+ request.setHTTPBody(data.get());
+}
+
+void WMLGoElement::prepareGETRequest(ResourceRequest& request, const KURL& url)
+{
+ request.setHTTPMethod("GET");
+
+ // Eventually display error message?
+ if (m_formAttributes.isMultiPartForm())
+ return;
+
+ RefPtr<FormData> data = createFormData(CString());
+
+ KURL remoteURL(url);
+ remoteURL.setQuery(data->flattenToString());
+ request.setURL(remoteURL);
+}
+
+PassRefPtr<FormData> WMLGoElement::createFormData(const CString& boundary)
+{
+ CString key;
+ CString value;
+
+ Vector<char> encodedData;
+ TextEncoding encoding = FormDataBuilder::encodingFromAcceptCharset(m_formAttributes.acceptCharset(), document()).encodingForFormSubmission();
+
+ Vector<WMLPostfieldElement*>::iterator it = m_postfieldElements.begin();
+ Vector<WMLPostfieldElement*>::iterator end = m_postfieldElements.end();
+
+ RefPtr<FormData> result = FormData::create();
+ for (; it != end; ++it) {
+ (*it)->encodeData(encoding, key, value);
+
+ if (m_formAttributes.isMultiPartForm()) {
+ Vector<char> header;
+ FormDataBuilder::beginMultiPartHeader(header, boundary, key);
+ FormDataBuilder::finishMultiPartHeader(header);
+ result->appendData(header.data(), header.size());
+
+ if (size_t dataSize = value.length())
+ result->appendData(value.data(), dataSize);
+
+ result->appendData("\r\n", 2);
+ } else
+ FormDataBuilder::addKeyValuePairAsFormData(encodedData, key, value);
+ }
+
+ if (m_formAttributes.isMultiPartForm())
+ FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, boundary, true);
+
+ result->appendData(encodedData.data(), encodedData.size());
+ return result;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLGoElement.h b/Source/WebCore/wml/WMLGoElement.h
new file mode 100644
index 0000000..d29e124
--- /dev/null
+++ b/Source/WebCore/wml/WMLGoElement.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLGoElement_h
+#define WMLGoElement_h
+
+#if ENABLE(WML)
+#include "FormSubmission.h"
+#include "WMLTaskElement.h"
+
+namespace WebCore {
+
+class FormData;
+class ResourceRequest;
+class WMLPostfieldElement;
+
+class WMLGoElement : public WMLTaskElement {
+public:
+ static PassRefPtr<WMLGoElement> create(const QualifiedName&, Document*);
+
+ WMLGoElement(const QualifiedName& tagName, Document*);
+
+ void registerPostfieldElement(WMLPostfieldElement*);
+ void deregisterPostfieldElement(WMLPostfieldElement*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void executeTask();
+
+private:
+ void preparePOSTRequest(ResourceRequest&, bool inSameDeck, const String& cacheControl);
+ void prepareGETRequest(ResourceRequest&, const KURL&);
+
+ PassRefPtr<FormData> createFormData(const CString& boundary);
+
+ Vector<WMLPostfieldElement*> m_postfieldElements;
+ FormSubmission::Attributes m_formAttributes;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLImageElement.cpp b/Source/WebCore/wml/WMLImageElement.cpp
new file mode 100644
index 0000000..5e15ccb
--- /dev/null
+++ b/Source/WebCore/wml/WMLImageElement.cpp
@@ -0,0 +1,156 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLImageElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "HTMLElement.h"
+#include "HTMLNames.h"
+#include "RenderImage.h"
+#include "WMLNames.h"
+#include "WMLVariables.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLImageElement::WMLImageElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+ , m_imageLoader(this)
+ , m_useFallbackAttribute(false)
+{
+}
+
+PassRefPtr<WMLImageElement> WMLImageElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLImageElement(tagName, document));
+}
+
+WMLImageElement::~WMLImageElement()
+{
+}
+
+bool WMLImageElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == HTMLNames::widthAttr ||
+ attrName == HTMLNames::heightAttr ||
+ attrName == HTMLNames::vspaceAttr ||
+ attrName == HTMLNames::hspaceAttr) {
+ result = eUniversal;
+ return false;
+ }
+
+ if (attrName == HTMLNames::alignAttr) {
+ result = eReplaced;
+ return false;
+ }
+
+ return WMLElement::mapToEntry(attrName, result);
+}
+
+void WMLImageElement::parseMappedAttribute(Attribute* attr)
+{
+ const QualifiedName& attrName = attr->name();
+
+ if (attrName == HTMLNames::altAttr) {
+ if (renderer() && renderer()->isImage())
+ toRenderImage(renderer())->updateAltText();
+ } else if (attrName == HTMLNames::srcAttr || attrName == localsrcAttr)
+ m_imageLoader.updateFromElementIgnoringPreviousError();
+ else if (attrName == HTMLNames::widthAttr)
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
+ else if (attrName == HTMLNames::heightAttr)
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
+ else if (attrName == HTMLNames::vspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
+ } else if (attrName == HTMLNames::hspaceAttr) {
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
+ } else if (attrName == HTMLNames::alignAttr)
+ HTMLElement::addHTMLAlignmentToStyledElement(this, attr);
+ else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+void WMLImageElement::attach()
+{
+ WMLElement::attach();
+
+ if (renderer() && renderer()->isImage() && m_imageLoader.haveFiredBeforeLoadEvent()) {
+ RenderImage* imageObj = toRenderImage(renderer());
+ RenderImageResource* renderImageResource = imageObj->imageResource();
+ if (renderImageResource->hasImage())
+ return;
+ renderImageResource->setCachedImage(m_imageLoader.image());
+
+ // If we have no image at all because we have no src attribute, set
+ // image height and width for the alt text instead.
+ if (!m_imageLoader.image() && !imageObj->cachedImage())
+ imageObj->setImageSizeForAltText();
+ }
+}
+
+RenderObject* WMLImageElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ RenderImage* image = new (arena) RenderImage(this);
+ image->setImageResource(RenderImageResource::create());
+ return image;
+}
+
+void WMLImageElement::insertedIntoDocument()
+{
+ // If we have been inserted from a renderer-less document,
+ // our loader may have not fetched the image, so do it now.
+ if (!m_imageLoader.image())
+ m_imageLoader.updateFromElement();
+
+ WMLElement::insertedIntoDocument();
+}
+
+bool WMLImageElement::isURLAttribute(Attribute* attr) const
+{
+ return attr->name() == HTMLNames::srcAttr
+ || attr->name() == localsrcAttr;
+}
+
+const QualifiedName& WMLImageElement::imageSourceAttributeName() const
+{
+ // Spec: Any 'localsrc' parameter specified takes precedence over the
+ // image specified in the src parameter.
+ if (hasAttribute(localsrcAttr) && !m_useFallbackAttribute)
+ return localsrcAttr;
+
+ return HTMLNames::srcAttr;
+}
+
+String WMLImageElement::altText() const
+{
+ return substituteVariableReferences(getAttribute(HTMLNames::altAttr), document());
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLImageElement.h b/Source/WebCore/wml/WMLImageElement.h
new file mode 100644
index 0000000..6421f6e
--- /dev/null
+++ b/Source/WebCore/wml/WMLImageElement.h
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLImageElement_h
+#define WMLImageElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+#include "WMLImageLoader.h"
+
+namespace WebCore {
+
+class WMLImageElement : public WMLElement {
+public:
+ static PassRefPtr<WMLImageElement> create(const QualifiedName&, Document*);
+
+ WMLImageElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLImageElement();
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void attach();
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+
+ virtual void insertedIntoDocument();
+ virtual bool isURLAttribute(Attribute*) const;
+ virtual const QualifiedName& imageSourceAttributeName() const;
+
+ String altText() const;
+
+ bool useFallbackAttribute() { return m_useFallbackAttribute; }
+ void setUseFallbackAttribute(bool value) { m_useFallbackAttribute = value; }
+
+private:
+ WMLImageLoader m_imageLoader;
+ bool m_useFallbackAttribute;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLImageLoader.cpp b/Source/WebCore/wml/WMLImageLoader.cpp
new file mode 100644
index 0000000..1e4c96b
--- /dev/null
+++ b/Source/WebCore/wml/WMLImageLoader.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLImageLoader.h"
+
+#include "CachedImage.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "WMLImageElement.h"
+#include "WMLNames.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLImageLoader::WMLImageLoader(WMLImageElement* element)
+ : ImageLoader(element)
+{
+}
+
+WMLImageLoader::~WMLImageLoader()
+{
+}
+
+void WMLImageLoader::dispatchLoadEvent()
+{
+ // WML doesn't fire any events.
+}
+
+String WMLImageLoader::sourceURI(const AtomicString& attr) const
+{
+ return KURL(element()->baseURI(), stripLeadingAndTrailingHTMLSpaces(attr));
+}
+
+void WMLImageLoader::notifyFinished(CachedResource* image)
+{
+ ImageLoader::notifyFinished(image);
+
+ if (!image->errorOccurred())
+ return;
+
+ WMLImageElement* imageElement = static_cast<WMLImageElement*>(element());
+ ASSERT(imageElement);
+
+ // Loading both 'localsrc' and 'src' failed. Ignore this image.
+ if (imageElement->useFallbackAttribute())
+ return;
+
+ if (!imageElement->hasAttribute(localsrcAttr) && !imageElement->hasAttribute(HTMLNames::srcAttr))
+ return;
+
+ imageElement->setUseFallbackAttribute(true);
+ updateFromElementIgnoringPreviousError();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLImageLoader.h b/Source/WebCore/wml/WMLImageLoader.h
new file mode 100644
index 0000000..ecdb65a
--- /dev/null
+++ b/Source/WebCore/wml/WMLImageLoader.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLImageLoader_h
+#define WMLImageLoader_h
+
+#if ENABLE(WML)
+#include "ImageLoader.h"
+
+namespace WebCore {
+
+class WMLImageElement;
+
+class WMLImageLoader : public ImageLoader {
+public:
+ WMLImageLoader(WMLImageElement*);
+ virtual ~WMLImageLoader();
+
+ virtual void dispatchLoadEvent();
+ virtual String sourceURI(const AtomicString&) const;
+
+ virtual void notifyFinished(CachedResource*);
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLInputElement.cpp b/Source/WebCore/wml/WMLInputElement.cpp
new file mode 100644
index 0000000..2d7310a
--- /dev/null
+++ b/Source/WebCore/wml/WMLInputElement.cpp
@@ -0,0 +1,518 @@
+/**
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLInputElement.h"
+
+#include "Attribute.h"
+#include "EventNames.h"
+#include "FormDataList.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+#include "KeyboardEvent.h"
+#include "RenderTextControlSingleLine.h"
+#include "TextEvent.h"
+#include "WMLDocument.h"
+#include "WMLNames.h"
+#include "WMLPageState.h"
+
+namespace WebCore {
+
+WMLInputElement::WMLInputElement(const QualifiedName& tagName, Document* doc)
+ : WMLFormControlElement(tagName, doc)
+ , m_isPasswordField(false)
+ , m_isEmptyOk(false)
+ , m_numOfCharsAllowedByMask(0)
+{
+}
+
+PassRefPtr<WMLInputElement> WMLInputElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLInputElement(tagName, document));
+}
+
+WMLInputElement::~WMLInputElement()
+{
+ if (m_isPasswordField)
+ document()->unregisterForDocumentActivationCallbacks(this);
+}
+
+static const AtomicString& formatCodes()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, codes, ("AaNnXxMm"));
+ return codes;
+}
+
+bool WMLInputElement::isKeyboardFocusable(KeyboardEvent*) const
+{
+ return WMLFormControlElement::isFocusable();
+}
+
+bool WMLInputElement::isMouseFocusable() const
+{
+ return WMLFormControlElement::isFocusable();
+}
+
+void WMLInputElement::dispatchFocusEvent()
+{
+ InputElement::dispatchFocusEvent(this, this);
+ WMLElement::dispatchFocusEvent();
+}
+
+void WMLInputElement::dispatchBlurEvent()
+{
+ // Firstly check if it is allowed to leave this input field
+ String val = value();
+ if ((!m_isEmptyOk && val.isEmpty()) || !isConformedToInputMask(val)) {
+ updateFocusAppearance(true);
+ return;
+ }
+
+ // update the name variable of WML input elmenet
+ String nameVariable = formControlName();
+ if (!nameVariable.isEmpty())
+ wmlPageStateForDocument(document())->storeVariable(nameVariable, val);
+
+ InputElement::dispatchBlurEvent(this, this);
+ WMLElement::dispatchBlurEvent();
+}
+
+void WMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
+{
+ InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection);
+}
+
+void WMLInputElement::aboutToUnload()
+{
+ InputElement::aboutToUnload(this, this);
+}
+
+int WMLInputElement::size() const
+{
+ return m_data.size();
+}
+
+const AtomicString& WMLInputElement::formControlType() const
+{
+ // needs to be lowercase according to DOM spec
+ if (m_isPasswordField) {
+ DEFINE_STATIC_LOCAL(const AtomicString, password, ("password"));
+ return password;
+ }
+
+ DEFINE_STATIC_LOCAL(const AtomicString, text, ("text"));
+ return text;
+}
+
+const AtomicString& WMLInputElement::formControlName() const
+{
+ return m_data.name();
+}
+
+const String& WMLInputElement::suggestedValue() const
+{
+ return m_data.suggestedValue();
+}
+
+String WMLInputElement::value() const
+{
+ String value = m_data.value();
+ if (value.isNull())
+ value = constrainValue(getAttribute(HTMLNames::valueAttr));
+
+ return value;
+}
+
+void WMLInputElement::setValue(const String& value, bool sendChangeEvent)
+{
+ setFormControlValueMatchesRenderer(false);
+ m_data.setValue(constrainValue(value));
+ if (inDocument())
+ document()->updateStyleIfNeeded();
+ if (renderer())
+ renderer()->updateFromElement();
+ setNeedsStyleRecalc();
+
+ unsigned max = m_data.value().length();
+ if (document()->focusedNode() == this)
+ InputElement::updateSelectionRange(this, this, max, max);
+ else
+ cacheSelection(max, max);
+
+ InputElement::notifyFormStateChanged(this);
+}
+
+void WMLInputElement::setValueForUser(const String& value)
+{
+ /* InputElement class defines pure virtual function 'setValueForUser', which
+ will be useful only in HTMLInputElement. Do nothing in 'WMLInputElement'.
+ */
+}
+
+void WMLInputElement::setValueFromRenderer(const String& value)
+{
+ InputElement::setValueFromRenderer(m_data, this, this, value);
+}
+
+bool WMLInputElement::saveFormControlState(String& result) const
+{
+ if (m_isPasswordField)
+ return false;
+
+ result = value();
+ return true;
+}
+
+void WMLInputElement::restoreFormControlState(const String& state)
+{
+ ASSERT(!m_isPasswordField); // should never save/restore password fields
+ setValue(state);
+}
+
+void WMLInputElement::select()
+{
+ if (RenderTextControl* r = toRenderTextControl(renderer()))
+ setSelectionRange(this, 0, r->text().length());
+}
+
+void WMLInputElement::accessKeyAction(bool)
+{
+ // should never restore previous selection here
+ focus(false);
+}
+
+void WMLInputElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::nameAttr)
+ m_data.setName(parseValueForbiddingVariableReferences(attr->value()));
+ else if (attr->name() == HTMLNames::typeAttr) {
+ String type = parseValueForbiddingVariableReferences(attr->value());
+ m_isPasswordField = (type == "password");
+ } else if (attr->name() == HTMLNames::valueAttr) {
+ // We only need to setChanged if the form is looking at the default value right now.
+ if (m_data.value().isNull())
+ setNeedsStyleRecalc();
+ setFormControlValueMatchesRenderer(false);
+ } else if (attr->name() == HTMLNames::maxlengthAttr)
+ InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
+ else if (attr->name() == HTMLNames::sizeAttr)
+ InputElement::parseSizeAttribute(m_data, this, attr);
+ else if (attr->name() == WMLNames::formatAttr)
+ m_formatMask = validateInputMask(parseValueForbiddingVariableReferences(attr->value()));
+ else if (attr->name() == WMLNames::emptyokAttr)
+ m_isEmptyOk = (attr->value() == "true");
+ else
+ WMLElement::parseMappedAttribute(attr);
+
+ // FIXME: Handle 'accesskey' attribute
+ // FIXME: Handle 'tabindex' attribute
+ // FIXME: Handle 'title' attribute
+}
+
+void WMLInputElement::copyNonAttributeProperties(const Element* source)
+{
+ const WMLInputElement* sourceElement = static_cast<const WMLInputElement*>(source);
+ m_data.setValue(sourceElement->m_data.value());
+ WMLElement::copyNonAttributeProperties(source);
+}
+
+RenderObject* WMLInputElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderTextControlSingleLine(this, false);
+}
+
+void WMLInputElement::detach()
+{
+ WMLElement::detach();
+ setFormControlValueMatchesRenderer(false);
+}
+
+bool WMLInputElement::appendFormData(FormDataList& encoding, bool)
+{
+ if (formControlName().isEmpty())
+ return false;
+
+ encoding.appendData(formControlName(), value());
+ return true;
+}
+
+void WMLInputElement::reset()
+{
+ setValue(String());
+}
+
+void WMLInputElement::defaultEventHandler(Event* evt)
+{
+ bool clickDefaultFormButton = false;
+
+ if (evt->type() == eventNames().textInputEvent && evt->isTextEvent()) {
+ TextEvent* textEvent = static_cast<TextEvent*>(evt);
+ if (textEvent->data() == "\n")
+ clickDefaultFormButton = true;
+ else if (renderer() && !isConformedToInputMask(textEvent->data()[0], toRenderTextControl(renderer())->text().length() + 1))
+ // If the inputed char doesn't conform to the input mask, stop handling
+ return;
+ }
+
+ if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent() && focused() && document()->frame()
+ && document()->frame()->editor()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
+ evt->setDefaultHandled();
+ return;
+ }
+
+ // Let the key handling done in EventTargetNode take precedence over the event handling here for editable text fields
+ if (!clickDefaultFormButton) {
+ WMLElement::defaultEventHandler(evt);
+ if (evt->defaultHandled())
+ return;
+ }
+
+ // Use key press event here since sending simulated mouse events
+ // on key down blocks the proper sending of the key press event.
+ if (evt->type() == eventNames().keypressEvent && evt->isKeyboardEvent()) {
+ // Simulate mouse click on the default form button for enter for these types of elements.
+ if (static_cast<KeyboardEvent*>(evt)->charCode() == '\r')
+ clickDefaultFormButton = true;
+ }
+
+ if (clickDefaultFormButton) {
+ // Fire onChange for text fields.
+ RenderObject* r = renderer();
+ if (r && toRenderTextControl(r)->wasChangedSinceLastChangeEvent()) {
+ dispatchEvent(Event::create(eventNames().changeEvent, true, false));
+
+ // Refetch the renderer since arbitrary JS code run during onchange can do anything, including destroying it.
+ r = renderer();
+ if (r)
+ toRenderTextControl(r)->setChangedSinceLastChangeEvent(false);
+ }
+
+ evt->setDefaultHandled();
+ return;
+ }
+
+ if (evt->isBeforeTextInsertedEvent())
+ InputElement::handleBeforeTextInsertedEvent(m_data, this, this, evt);
+
+ if (renderer() && (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent() || evt->type() == eventNames().blurEvent || evt->type() == eventNames().focusEvent))
+ toRenderTextControlSingleLine(renderer())->forwardEvent(evt);
+}
+
+void WMLInputElement::cacheSelection(int start, int end)
+{
+ m_data.setCachedSelectionStart(start);
+ m_data.setCachedSelectionEnd(end);
+}
+
+String WMLInputElement::constrainValue(const String& proposedValue) const
+{
+ return InputElement::sanitizeUserInputValue(this, proposedValue, m_data.maxLength());
+}
+
+void WMLInputElement::documentDidBecomeActive()
+{
+ ASSERT(m_isPasswordField);
+ reset();
+}
+
+void WMLInputElement::willMoveToNewOwnerDocument()
+{
+ // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
+ if (m_isPasswordField)
+ document()->unregisterForDocumentActivationCallbacks(this);
+
+ WMLElement::willMoveToNewOwnerDocument();
+}
+
+void WMLInputElement::didMoveToNewOwnerDocument()
+{
+ if (m_isPasswordField)
+ document()->registerForDocumentActivationCallbacks(this);
+
+ WMLElement::didMoveToNewOwnerDocument();
+}
+
+void WMLInputElement::initialize()
+{
+ String nameVariable = formControlName();
+ String variableValue;
+ WMLPageState* pageSate = wmlPageStateForDocument(document());
+ ASSERT(pageSate);
+ if (!nameVariable.isEmpty())
+ variableValue = pageSate->getVariable(nameVariable);
+
+ if (variableValue.isEmpty() || !isConformedToInputMask(variableValue)) {
+ String val = value();
+ if (isConformedToInputMask(val))
+ variableValue = val;
+ else
+ variableValue = "";
+
+ pageSate->storeVariable(nameVariable, variableValue);
+ }
+ setValue(variableValue);
+
+ if (!hasAttribute(WMLNames::emptyokAttr)) {
+ if (m_formatMask.isEmpty() ||
+ // check if the format codes is just "*f"
+ (m_formatMask.length() == 2 && m_formatMask[0] == '*' && formatCodes().find(m_formatMask[1]) != -1))
+ m_isEmptyOk = true;
+ }
+}
+
+String WMLInputElement::validateInputMask(const String& inputMask)
+{
+ bool isValid = true;
+ bool hasWildcard = false;
+ unsigned escapeCharCount = 0;
+ unsigned maskLength = inputMask.length();
+ UChar formatCode;
+
+ for (unsigned i = 0; i < maskLength; ++i) {
+ formatCode = inputMask[i];
+ if (formatCodes().find(formatCode) == -1) {
+ if (formatCode == '*' || (WTF::isASCIIDigit(formatCode) && formatCode != '0')) {
+ // validate codes which ends with '*f' or 'nf'
+ formatCode = inputMask[++i];
+ if ((i + 1 != maskLength) || formatCodes().find(formatCode) == -1) {
+ isValid = false;
+ break;
+ }
+ hasWildcard = true;
+ } else if (formatCode == '\\') {
+ //skip over the next mask character
+ ++i;
+ ++escapeCharCount;
+ } else {
+ isValid = false;
+ break;
+ }
+ }
+ }
+
+ if (!isValid)
+ return String();
+
+ // calculate the number of characters allowed to be entered by input mask
+ m_numOfCharsAllowedByMask = maskLength;
+
+ if (escapeCharCount)
+ m_numOfCharsAllowedByMask -= escapeCharCount;
+
+ if (hasWildcard) {
+ formatCode = inputMask[maskLength - 2];
+ if (formatCode == '*')
+ m_numOfCharsAllowedByMask = m_data.maxLength();
+ else {
+ unsigned leftLen = String(&formatCode).toInt();
+ m_numOfCharsAllowedByMask = leftLen + m_numOfCharsAllowedByMask - 2;
+ }
+ }
+
+ return inputMask;
+}
+
+bool WMLInputElement::isConformedToInputMask(const String& inputChars)
+{
+ for (unsigned i = 0; i < inputChars.length(); ++i)
+ if (!isConformedToInputMask(inputChars[i], i + 1, false))
+ return false;
+
+ return true;
+}
+
+bool WMLInputElement::isConformedToInputMask(UChar inChar, unsigned inputCharCount, bool isUserInput)
+{
+ if (m_formatMask.isEmpty())
+ return true;
+
+ if (inputCharCount > m_numOfCharsAllowedByMask)
+ return false;
+
+ unsigned maskIndex = 0;
+ if (isUserInput) {
+ unsigned cursorPosition = 0;
+ if (renderer())
+ cursorPosition = toRenderTextControl(renderer())->selectionStart();
+ else
+ cursorPosition = m_data.cachedSelectionStart();
+
+ maskIndex = cursorPositionToMaskIndex(cursorPosition);
+ } else
+ maskIndex = cursorPositionToMaskIndex(inputCharCount - 1);
+
+ bool ok = true;
+ UChar mask = m_formatMask[maskIndex];
+ // match the inputed character with input mask
+ switch (mask) {
+ case 'A':
+ ok = !WTF::isASCIIDigit(inChar) && !WTF::isASCIILower(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'a':
+ ok = !WTF::isASCIIDigit(inChar) && !WTF::isASCIIUpper(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'N':
+ ok = WTF::isASCIIDigit(inChar);
+ break;
+ case 'n':
+ ok = !WTF::isASCIIAlpha(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'X':
+ ok = !WTF::isASCIILower(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'x':
+ ok = !WTF::isASCIIUpper(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'M':
+ ok = WTF::isASCIIPrintable(inChar);
+ break;
+ case 'm':
+ ok = WTF::isASCIIPrintable(inChar);
+ break;
+ default:
+ ok = (mask == inChar);
+ break;
+ }
+
+ return ok;
+}
+
+unsigned WMLInputElement::cursorPositionToMaskIndex(unsigned cursorPosition)
+{
+ UChar mask;
+ int index = -1;
+ do {
+ mask = m_formatMask[++index];
+ if (mask == '\\')
+ ++index;
+ else if (mask == '*' || (WTF::isASCIIDigit(mask) && mask != '0')) {
+ index = m_formatMask.length() - 1;
+ break;
+ }
+ } while (cursorPosition--);
+
+ return index;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLInputElement.h b/Source/WebCore/wml/WMLInputElement.h
new file mode 100644
index 0000000..df7f497
--- /dev/null
+++ b/Source/WebCore/wml/WMLInputElement.h
@@ -0,0 +1,118 @@
+/**
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLInputElement_h
+#define WMLInputElement_h
+
+#if ENABLE(WML)
+#include "WMLFormControlElement.h"
+#include "InputElement.h"
+
+namespace WebCore {
+
+class FormDataList;
+
+class WMLInputElement : public WMLFormControlElement, public InputElement {
+public:
+ static PassRefPtr<WMLInputElement> create(const QualifiedName&, Document*);
+
+ WMLInputElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLInputElement();
+
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual bool isMouseFocusable() const;
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
+ virtual void updateFocusAppearance(bool restorePreviousSelection);
+ virtual void aboutToUnload();
+
+ virtual bool shouldUseInputMethod() const { return !m_isPasswordField; }
+ virtual bool isChecked() const { return false; }
+ virtual bool isAutofilled() const { return false; }
+ virtual bool isIndeterminate() const { return false; }
+ virtual bool isTextFormControl() const { return true; }
+ virtual bool isRadioButton() const { return false; }
+ virtual bool isCheckbox() const { return false; }
+ virtual bool isTextField() const { return true; }
+ virtual bool isSearchField() const { return false; }
+ virtual bool isInputTypeHidden() const { return false; }
+ virtual bool isPasswordField() const { return m_isPasswordField; }
+ virtual bool searchEventsShouldBeDispatched() const { return false; }
+
+ virtual int size() const;
+ virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlName() const;
+ virtual const String& suggestedValue() const;
+ virtual String value() const;
+ virtual void setValue(const String&, bool sendChangeEvent = false);
+ virtual void setValueForUser(const String&);
+ virtual void setValueFromRenderer(const String&);
+
+ virtual bool saveFormControlState(String& value) const;
+ virtual void restoreFormControlState(const String&);
+
+ virtual void select();
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void copyNonAttributeProperties(const Element* source);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual void detach();
+ virtual bool appendFormData(FormDataList&, bool);
+ virtual void reset();
+
+ virtual void defaultEventHandler(Event*);
+ virtual void cacheSelection(int start, int end);
+
+ virtual bool isAcceptableValue(const String&) const { return true; }
+ virtual String sanitizeValue(const String& proposedValue) const { return constrainValue(proposedValue); }
+
+ virtual void documentDidBecomeActive();
+
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
+
+ bool isConformedToInputMask(const String&);
+ bool isConformedToInputMask(UChar, unsigned, bool isUserInput = true);
+#if ENABLE(WCSS)
+ virtual InputElementData data() const { return m_data; }
+#endif
+
+private:
+ friend class WMLCardElement;
+ void initialize();
+
+ virtual bool supportsMaxLength() const { return true; }
+ String validateInputMask(const String&);
+ unsigned cursorPositionToMaskIndex(unsigned);
+ String constrainValue(const String&) const;
+
+ InputElementData m_data;
+ bool m_isPasswordField;
+ bool m_isEmptyOk;
+ String m_formatMask;
+ unsigned m_numOfCharsAllowedByMask;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLInsertedLegendElement.cpp b/Source/WebCore/wml/WMLInsertedLegendElement.cpp
new file mode 100644
index 0000000..0a18b4a
--- /dev/null
+++ b/Source/WebCore/wml/WMLInsertedLegendElement.cpp
@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLInsertedLegendElement.h"
+
+namespace WebCore {
+
+WMLInsertedLegendElement::WMLInsertedLegendElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLInsertedLegendElement> WMLInsertedLegendElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLInsertedLegendElement(tagName, document));
+}
+
+WMLInsertedLegendElement::~WMLInsertedLegendElement()
+{
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLInsertedLegendElement.h b/Source/WebCore/wml/WMLInsertedLegendElement.h
new file mode 100644
index 0000000..e79550e
--- /dev/null
+++ b/Source/WebCore/wml/WMLInsertedLegendElement.h
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLInsertedLegendElement_h
+#define WMLInsertedLegendElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLInsertedLegendElement : public WMLElement {
+public:
+ static PassRefPtr<WMLInsertedLegendElement> create(const QualifiedName&, Document*);
+
+ WMLInsertedLegendElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLInsertedLegendElement();
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLIntrinsicEvent.cpp b/Source/WebCore/wml/WMLIntrinsicEvent.cpp
new file mode 100644
index 0000000..bb631b9
--- /dev/null
+++ b/Source/WebCore/wml/WMLIntrinsicEvent.cpp
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLIntrinsicEvent.h"
+
+#include "HTMLNames.h"
+#include "WMLElementFactory.h"
+#include "WMLNames.h"
+#include "WMLTaskElement.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+static PassRefPtr<WMLTaskElement> createTaskElement(Document* document)
+{
+ return static_pointer_cast<WMLTaskElement>(WMLElementFactory::createWMLElement(goTag, document, false));
+}
+
+WMLIntrinsicEvent::WMLIntrinsicEvent(Document* document, const String& targetURL)
+ : m_taskElement(createTaskElement(document))
+{
+ m_taskElement->setAttribute(HTMLNames::hrefAttr, targetURL);
+}
+
+WMLIntrinsicEvent::WMLIntrinsicEvent(WMLTaskElement* taskElement)
+ : m_taskElement(taskElement)
+{
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLIntrinsicEvent.h b/Source/WebCore/wml/WMLIntrinsicEvent.h
new file mode 100644
index 0000000..9a974fb
--- /dev/null
+++ b/Source/WebCore/wml/WMLIntrinsicEvent.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLIntrinsicEvent_h
+#define WMLIntrinsicEvent_h
+
+#if ENABLE(WML)
+#include "WMLTaskElement.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Document;
+
+class WMLIntrinsicEvent : public RefCounted<WMLIntrinsicEvent> {
+public:
+ static PassRefPtr<WMLIntrinsicEvent> create(Document* document, const String& targetURL)
+ {
+ return adoptRef(new WMLIntrinsicEvent(document, targetURL));
+ }
+
+ static PassRefPtr<WMLIntrinsicEvent> createWithTask(WMLTaskElement* taskElement)
+ {
+ return adoptRef(new WMLIntrinsicEvent(taskElement));
+ }
+
+ WMLTaskElement* taskElement() const { return m_taskElement.get(); }
+
+private:
+ WMLIntrinsicEvent(Document*, const String& targetURL);
+ WMLIntrinsicEvent(WMLTaskElement*);
+
+ RefPtr<WMLTaskElement> m_taskElement;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLIntrinsicEventHandler.cpp b/Source/WebCore/wml/WMLIntrinsicEventHandler.cpp
new file mode 100644
index 0000000..8e4c276
--- /dev/null
+++ b/Source/WebCore/wml/WMLIntrinsicEventHandler.cpp
@@ -0,0 +1,61 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLIntrinsicEventHandler.h"
+
+namespace WebCore {
+
+WMLIntrinsicEventHandler::WMLIntrinsicEventHandler()
+{
+}
+
+bool WMLIntrinsicEventHandler::registerIntrinsicEvent(WMLIntrinsicEventType type, PassRefPtr<WMLIntrinsicEvent> event)
+{
+ if (m_events.contains(type))
+ return false;
+
+ m_events.set(type, event);
+ return true;
+}
+
+void WMLIntrinsicEventHandler::deregisterIntrinsicEvent(WMLIntrinsicEventType type)
+{
+ if (m_events.contains(type))
+ m_events.remove(type);
+}
+
+void WMLIntrinsicEventHandler::triggerIntrinsicEvent(WMLIntrinsicEventType type) const
+{
+ RefPtr<WMLIntrinsicEvent> event = m_events.get(type);
+ ASSERT(event->taskElement());
+ event->taskElement()->executeTask();
+}
+
+bool WMLIntrinsicEventHandler::hasIntrinsicEvent(WMLIntrinsicEventType type) const
+{
+ return m_events.contains(type);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLIntrinsicEventHandler.h b/Source/WebCore/wml/WMLIntrinsicEventHandler.h
new file mode 100644
index 0000000..8ac6d1b
--- /dev/null
+++ b/Source/WebCore/wml/WMLIntrinsicEventHandler.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLIntrinsicEventHandler_h
+#define WMLIntrinsicEventHandler_h
+
+#if ENABLE(WML)
+#include <wtf/HashMap.h>
+#include <wtf/PassRefPtr.h>
+
+#include "WMLIntrinsicEvent.h"
+
+namespace WebCore {
+
+enum WMLIntrinsicEventType {
+ WMLIntrinsicEventUnknown = 0,
+ WMLIntrinsicEventOnEnterForward,
+ WMLIntrinsicEventOnEnterBackward,
+ WMLIntrinsicEventOnTimer,
+ WMLIntrinsicEventOnPick
+};
+
+class WMLIntrinsicEvent;
+
+class WMLIntrinsicEventHandler {
+public:
+ WMLIntrinsicEventHandler();
+
+ bool registerIntrinsicEvent(WMLIntrinsicEventType, PassRefPtr<WMLIntrinsicEvent>);
+ void deregisterIntrinsicEvent(WMLIntrinsicEventType);
+ void triggerIntrinsicEvent(WMLIntrinsicEventType) const;
+ bool hasIntrinsicEvent(WMLIntrinsicEventType) const;
+
+private:
+ typedef HashMap<int, RefPtr<WMLIntrinsicEvent> > EventMap;
+ EventMap m_events;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLMetaElement.cpp b/Source/WebCore/wml/WMLMetaElement.cpp
new file mode 100644
index 0000000..2b8e00d
--- /dev/null
+++ b/Source/WebCore/wml/WMLMetaElement.cpp
@@ -0,0 +1,70 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLMetaElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+WMLMetaElement::WMLMetaElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLMetaElement> WMLMetaElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLMetaElement(tagName, document));
+}
+
+WMLMetaElement::~WMLMetaElement()
+{
+}
+
+void WMLMetaElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::http_equivAttr)
+ m_equiv = parseValueForbiddingVariableReferences(attr->value());
+ else if (attr->name() == HTMLNames::contentAttr)
+ m_content = parseValueForbiddingVariableReferences(attr->value());
+ else if (attr->name() == HTMLNames::nameAttr) {
+ // FIXME: The user agent must ignore any meta-data named with this attribute.
+ } else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+void WMLMetaElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ if (m_equiv.isNull() || m_content.isNull())
+ return;
+
+ document()->processHttpEquiv(m_equiv, m_content);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLMetaElement.h b/Source/WebCore/wml/WMLMetaElement.h
new file mode 100644
index 0000000..16e2268
--- /dev/null
+++ b/Source/WebCore/wml/WMLMetaElement.h
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLMetaElement_h
+#define WMLMetaElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLMetaElement : public WMLElement {
+public:
+ static PassRefPtr<WMLMetaElement> create(const QualifiedName&, Document*);
+
+ WMLMetaElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLMetaElement();
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+
+private:
+ String m_equiv;
+ String m_content;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLNoopElement.cpp b/Source/WebCore/wml/WMLNoopElement.cpp
new file mode 100644
index 0000000..fbd3788
--- /dev/null
+++ b/Source/WebCore/wml/WMLNoopElement.cpp
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLNoopElement.h"
+
+#include "WMLDoElement.h"
+#include "WMLErrorHandling.h"
+#include "WMLNames.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLNoopElement::WMLNoopElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLNoopElement> WMLNoopElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLNoopElement(tagName, document));
+}
+
+WMLNoopElement::~WMLNoopElement()
+{
+}
+
+void WMLNoopElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ ContainerNode* parent = parentNode();
+ if (!parent || !parent->isWMLElement())
+ return;
+
+ if (parent->hasTagName(doTag)) {
+ WMLDoElement* doElement = static_cast<WMLDoElement*>(parent);
+ doElement->setNoop(true);
+
+ if (doElement->attached())
+ doElement->detach();
+
+ ASSERT(!doElement->attached());
+ doElement->attach();
+ } else if (parent->hasTagName(anchorTag))
+ reportWMLError(document(), WMLErrorForbiddenTaskInAnchorElement);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLNoopElement.h b/Source/WebCore/wml/WMLNoopElement.h
new file mode 100644
index 0000000..be0413c
--- /dev/null
+++ b/Source/WebCore/wml/WMLNoopElement.h
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLNoopElement_h
+#define WMLNoopElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLNoopElement : public WMLElement {
+public:
+ static PassRefPtr<WMLNoopElement> create(const QualifiedName&, Document*);
+
+ WMLNoopElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLNoopElement();
+
+ virtual void insertedIntoDocument();
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLOnEventElement.cpp b/Source/WebCore/wml/WMLOnEventElement.cpp
new file mode 100644
index 0000000..ad6684b
--- /dev/null
+++ b/Source/WebCore/wml/WMLOnEventElement.cpp
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLOnEventElement.h"
+
+#include "Attribute.h"
+#include "HTMLNames.h"
+#include "WMLErrorHandling.h"
+#include "WMLEventHandlingElement.h"
+#include "WMLIntrinsicEventHandler.h"
+#include "WMLNames.h"
+#include "WMLVariables.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLOnEventElement::WMLOnEventElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+ , m_type(WMLIntrinsicEventUnknown)
+{
+}
+
+PassRefPtr<WMLOnEventElement> WMLOnEventElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLOnEventElement(tagName, document));
+}
+
+void WMLOnEventElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::typeAttr) {
+ String parsedValue = parseValueForbiddingVariableReferences(attr->value());
+ if (parsedValue.isEmpty())
+ return;
+
+ if (parsedValue == onenterforwardAttr)
+ m_type = WMLIntrinsicEventOnEnterForward;
+ else if (parsedValue == onenterbackwardAttr)
+ m_type = WMLIntrinsicEventOnEnterBackward;
+ else if (parsedValue == ontimerAttr)
+ m_type = WMLIntrinsicEventOnTimer;
+ else if (parsedValue == onpickAttr)
+ m_type = WMLIntrinsicEventOnPick;
+ } else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+static inline WMLEventHandlingElement* eventHandlingParent(Node* parent)
+{
+ if (!parent || !parent->isWMLElement())
+ return 0;
+
+ return toWMLEventHandlingElement(static_cast<WMLElement*>(parent));
+}
+
+void WMLOnEventElement::registerTask(WMLTaskElement* task)
+{
+ if (m_type == WMLIntrinsicEventUnknown)
+ return;
+
+ // Register intrinsic event to the event handler of the owner of onevent element
+ WMLEventHandlingElement* eventHandlingElement = eventHandlingParent(parentNode());
+ if (!eventHandlingElement)
+ return;
+
+ eventHandlingElement->createEventHandlerIfNeeded();
+
+ RefPtr<WMLIntrinsicEvent> event = WMLIntrinsicEvent::createWithTask(task);
+ if (!eventHandlingElement->eventHandler()->registerIntrinsicEvent(m_type, event))
+ reportWMLError(document(), WMLErrorConflictingEventBinding);
+}
+
+void WMLOnEventElement::deregisterTask(WMLTaskElement*)
+{
+ WMLEventHandlingElement* eventHandlingElement = eventHandlingParent(parentNode());
+ if (!eventHandlingElement)
+ return;
+
+ eventHandlingElement->eventHandler()->deregisterIntrinsicEvent(m_type);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLOnEventElement.h b/Source/WebCore/wml/WMLOnEventElement.h
new file mode 100644
index 0000000..8bbaa1d
--- /dev/null
+++ b/Source/WebCore/wml/WMLOnEventElement.h
@@ -0,0 +1,50 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLOnEventElement_h
+#define WMLOnEventElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+#include "WMLIntrinsicEventHandler.h"
+
+namespace WebCore {
+
+class WMLTaskElement;
+
+class WMLOnEventElement : public WMLElement {
+public:
+ static PassRefPtr<WMLOnEventElement> create(const QualifiedName&, Document*);
+
+ WMLOnEventElement(const QualifiedName& tagName, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ void registerTask(WMLTaskElement*);
+ void deregisterTask(WMLTaskElement*);
+
+private:
+ WMLIntrinsicEventType m_type;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLOptGroupElement.cpp b/Source/WebCore/wml/WMLOptGroupElement.cpp
new file mode 100644
index 0000000..3e15c7b
--- /dev/null
+++ b/Source/WebCore/wml/WMLOptGroupElement.cpp
@@ -0,0 +1,135 @@
+/**
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLOptGroupElement.h"
+
+#include "Attribute.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "NodeRenderStyle.h"
+#include "RenderStyle.h"
+#include "WMLNames.h"
+#include "WMLSelectElement.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLOptGroupElement::WMLOptGroupElement(const QualifiedName& tagName, Document* doc)
+ : WMLFormControlElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLOptGroupElement> WMLOptGroupElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLOptGroupElement(tagName, document));
+}
+
+WMLOptGroupElement::~WMLOptGroupElement()
+{
+}
+
+const AtomicString& WMLOptGroupElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, optgroup, ("optgroup"));
+ return optgroup;
+}
+
+static inline WMLSelectElement* ownerSelectElement(Element* element)
+{
+ ContainerNode* select = element->parentNode();
+ while (select && !select->hasTagName(selectTag))
+ select = select->parentNode();
+
+ if (!select)
+ return 0;
+
+ return static_cast<WMLSelectElement*>(select);
+}
+
+void WMLOptGroupElement::accessKeyAction(bool)
+{
+ WMLSelectElement* select = ownerSelectElement(this);
+ if (!select || select->focused())
+ return;
+
+ // send to the parent to bring focus to the list box
+ select->accessKeyAction(false);
+}
+
+void WMLOptGroupElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ recalcSelectOptions();
+ WMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+void WMLOptGroupElement::parseMappedAttribute(Attribute* attr)
+{
+ WMLFormControlElement::parseMappedAttribute(attr);
+ recalcSelectOptions();
+}
+
+void WMLOptGroupElement::attach()
+{
+ if (parentNode()->renderStyle())
+ setRenderStyle(styleForRenderer());
+ WMLFormControlElement::attach();
+}
+
+void WMLOptGroupElement::detach()
+{
+ m_style.clear();
+ WMLFormControlElement::detach();
+}
+
+void WMLOptGroupElement::setRenderStyle(PassRefPtr<RenderStyle> style)
+{
+ m_style = style;
+}
+
+RenderStyle* WMLOptGroupElement::nonRendererRenderStyle() const
+{
+ return m_style.get();
+}
+
+String WMLOptGroupElement::groupLabelText() const
+{
+ String itemText = document()->displayStringModifiedByEncoding(title());
+
+ // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
+ itemText = itemText.stripWhiteSpace();
+ // We want to collapse our whitespace too. This will match other browsers.
+ itemText = itemText.simplifyWhiteSpace();
+
+ return itemText;
+}
+
+void WMLOptGroupElement::recalcSelectOptions()
+{
+ if (WMLSelectElement* select = ownerSelectElement(this))
+ select->setRecalcListItems();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLOptGroupElement.h b/Source/WebCore/wml/WMLOptGroupElement.h
new file mode 100644
index 0000000..c49749e
--- /dev/null
+++ b/Source/WebCore/wml/WMLOptGroupElement.h
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLOptGroupElement_h
+#define WMLOptGroupElement_h
+
+#if ENABLE(WML)
+#include "WMLFormControlElement.h"
+#include "OptionGroupElement.h"
+
+namespace WebCore {
+
+class WMLOptGroupElement : public WMLFormControlElement, public OptionGroupElement {
+public:
+ static PassRefPtr<WMLOptGroupElement> create(const QualifiedName&, Document*);
+
+ WMLOptGroupElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLOptGroupElement();
+
+ virtual const AtomicString& formControlType() const;
+
+ virtual bool rendererIsNeeded(RenderStyle*) { return false; }
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void attach();
+ virtual void detach();
+ virtual void setRenderStyle(PassRefPtr<RenderStyle>);
+
+ virtual String groupLabelText() const;
+
+private:
+ virtual RenderStyle* nonRendererRenderStyle() const;
+ void recalcSelectOptions();
+
+private:
+ RefPtr<RenderStyle> m_style;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLOptionElement.cpp b/Source/WebCore/wml/WMLOptionElement.cpp
new file mode 100644
index 0000000..6c8aa74
--- /dev/null
+++ b/Source/WebCore/wml/WMLOptionElement.cpp
@@ -0,0 +1,186 @@
+/**
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLOptionElement.h"
+
+#include "Attribute.h"
+#include "HTMLNames.h"
+#include "NodeRenderStyle.h"
+#include "RenderStyle.h"
+#include "WMLNames.h"
+#include "WMLSelectElement.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLOptionElement::WMLOptionElement(const QualifiedName& tagName, Document* doc)
+ : WMLFormControlElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLOptionElement> WMLOptionElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLOptionElement(tagName, document));
+}
+
+WMLOptionElement::~WMLOptionElement()
+{
+}
+
+const AtomicString& WMLOptionElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, option, ("option"));
+ return option;
+}
+
+static inline WMLSelectElement* ownerSelectElement(Element* element)
+{
+ ContainerNode* select = element->parentNode();
+ while (select && !select->hasTagName(selectTag))
+ select = select->parentNode();
+
+ if (!select)
+ return 0;
+
+ return static_cast<WMLSelectElement*>(select);
+}
+
+void WMLOptionElement::accessKeyAction(bool)
+{
+ if (WMLSelectElement* select = ownerSelectElement(this))
+ select->accessKeySetSelectedIndex(OptionElement::optionIndex(select, this));
+}
+
+void WMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ if (WMLSelectElement* select = ownerSelectElement(this))
+ select->childrenChanged(changedByParser);
+
+ WMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+void WMLOptionElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::valueAttr)
+ m_data.setValue(parseValueSubstitutingVariableReferences(attr->value()));
+ else if (attr->name() == HTMLNames::titleAttr)
+ m_data.setLabel(parseValueSubstitutingVariableReferences(attr->value()));
+ else if (attr->name() == onpickAttr) {
+ // Register intrinsic event in card
+ RefPtr<WMLIntrinsicEvent> event = WMLIntrinsicEvent::create(document(), attr->value());
+
+ createEventHandlerIfNeeded();
+ eventHandler()->registerIntrinsicEvent(WMLIntrinsicEventOnPick, event);
+ } else
+ WMLFormControlElement::parseMappedAttribute(attr);
+}
+
+void WMLOptionElement::attach()
+{
+ if (parentNode()->renderStyle())
+ setRenderStyle(styleForRenderer());
+ WMLFormControlElement::attach();
+}
+
+void WMLOptionElement::detach()
+{
+ m_style.clear();
+ WMLFormControlElement::detach();
+}
+
+void WMLOptionElement::setRenderStyle(PassRefPtr<RenderStyle> style)
+{
+ m_style = style;
+}
+
+void WMLOptionElement::insertedIntoDocument()
+{
+ WMLSelectElement* select;
+ if (selected() && (select = ownerSelectElement(this)))
+ select->scrollToSelection();
+
+ WMLFormControlElement::insertedIntoDocument();
+}
+
+bool WMLOptionElement::selected() const
+{
+ return m_data.selected();
+}
+
+void WMLOptionElement::setSelectedState(bool selected)
+{
+ if (this->selected() == selected)
+ return;
+
+ OptionElement::setSelectedState(m_data, this, selected);
+
+ if (WMLSelectElement* select = ownerSelectElement(this)) {
+ if (select->multiple() || selected)
+ handleIntrinsicEventIfNeeded();
+ }
+}
+
+String WMLOptionElement::value() const
+{
+ return OptionElement::collectOptionValue(m_data, this);
+}
+
+String WMLOptionElement::text() const
+{
+ return OptionElement::collectOptionLabelOrText(m_data, this);
+}
+
+String WMLOptionElement::textIndentedToRespectGroupLabel() const
+{
+ return OptionElement::collectOptionTextRespectingGroupLabel(m_data, this);
+}
+
+RenderStyle* WMLOptionElement::nonRendererRenderStyle() const
+{
+ return m_style.get();
+}
+
+void WMLOptionElement::handleIntrinsicEventIfNeeded()
+{
+ WMLSelectElement* select = ownerSelectElement(this);
+ if (!select || !select->initialized())
+ return;
+
+ WMLIntrinsicEventHandler* eventHandler = this->eventHandler();
+ if (!eventHandler)
+ return;
+
+ if (eventHandler->hasIntrinsicEvent(WMLIntrinsicEventOnPick))
+ eventHandler->triggerIntrinsicEvent(WMLIntrinsicEventOnPick);
+}
+
+bool WMLOptionElement::disabled() const
+{
+ /* Dummy implementation, as disabled() is pure virtual in OptionElement class */
+ return false;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLOptionElement.h b/Source/WebCore/wml/WMLOptionElement.h
new file mode 100644
index 0000000..41a4638
--- /dev/null
+++ b/Source/WebCore/wml/WMLOptionElement.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLOptionElement_h
+#define WMLOptionElement_h
+
+#if ENABLE(WML)
+#include "OptionElement.h"
+#include "WMLFormControlElement.h"
+#include "WMLEventHandlingElement.h"
+
+namespace WebCore {
+
+class WMLOptionElement : public WMLFormControlElement, public WMLEventHandlingElement, public OptionElement {
+public:
+ static PassRefPtr<WMLOptionElement> create(const QualifiedName&, Document*);
+
+ WMLOptionElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLOptionElement();
+
+ virtual const AtomicString& formControlType() const;
+
+ virtual bool rendererIsNeeded(RenderStyle*) { return false; }
+
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void attach();
+ virtual void detach();
+ virtual void setRenderStyle(PassRefPtr<RenderStyle>);
+
+ virtual void insertedIntoDocument();
+
+ virtual bool selected() const;
+ virtual void setSelectedState(bool);
+
+ virtual String text() const;
+ virtual String textIndentedToRespectGroupLabel() const;
+ virtual String value() const;
+
+ virtual bool disabled() const;
+
+private:
+ virtual RenderStyle* nonRendererRenderStyle() const;
+ void handleIntrinsicEventIfNeeded();
+
+private:
+ OptionElementData m_data;
+ RefPtr<RenderStyle> m_style;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLPElement.cpp b/Source/WebCore/wml/WMLPElement.cpp
new file mode 100644
index 0000000..629b49f
--- /dev/null
+++ b/Source/WebCore/wml/WMLPElement.cpp
@@ -0,0 +1,118 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLPElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "NodeList.h"
+#include "WMLNames.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLPElement::WMLPElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLPElement> WMLPElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLPElement(tagName, document));
+}
+
+bool WMLPElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == HTMLNames::alignAttr) {
+ result = eBlock; // We can share with DIV here.
+ return false;
+ }
+
+ return WMLElement::mapToEntry(attrName, result);
+}
+
+void WMLPElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::alignAttr) {
+ const AtomicString& value = attr->value();
+ if (equalIgnoringCase(value, "middle") || equalIgnoringCase(value, "center"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitCenter);
+ else if (equalIgnoringCase(value, "left"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitLeft);
+ else if (equalIgnoringCase(value, "right"))
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitRight);
+ else
+ addCSSProperty(attr, CSSPropertyTextAlign, value);
+ } else if (attr->name() == modeAttr) {
+ m_mode = attr->value();
+ if (m_mode == "wrap")
+ addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);
+ else if (m_mode == "nowrap")
+ addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValueNowrap);
+ } else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+void WMLPElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ // If not explicitly specified, the linewrap mode is identical to
+ // the line-wrap mode of the previous paragraph in the text flow of
+ // a card. The default mode for the first paragraph in a card is wrap.
+ if (!m_mode.isEmpty())
+ return;
+
+ RefPtr<NodeList> nodeList = document()->getElementsByTagName("p");
+ if (!nodeList)
+ return;
+
+ unsigned length = nodeList->length();
+ if (length < 2)
+ return;
+
+ // Assure we're the last inserted paragraph element
+ // This only works while parsing, otherwhise this statement is never true.
+ if (nodeList->item(length - 1) != this)
+ return;
+
+ WMLPElement* lastParagraph = static_cast<WMLPElement*>(nodeList->item(length - 2));
+ ASSERT(lastParagraph);
+
+ String lastMode = lastParagraph->getAttribute(modeAttr);
+ if (lastMode.isEmpty() || lastMode == "wrap") // Default value, do nothing.
+ return;
+
+ setAttribute(modeAttr, lastMode);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLPElement.h b/Source/WebCore/wml/WMLPElement.h
new file mode 100644
index 0000000..32a35b1
--- /dev/null
+++ b/Source/WebCore/wml/WMLPElement.h
@@ -0,0 +1,50 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *
+ * 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 WMLPElement_h
+#define WMLPElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLPElement : public WMLElement {
+public:
+ static PassRefPtr<WMLPElement> create(const QualifiedName&, Document*);
+
+ WMLPElement(const QualifiedName& tagName, Document*);
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void insertedIntoDocument();
+
+private:
+ String m_mode;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLPageState.cpp b/Source/WebCore/wml/WMLPageState.cpp
new file mode 100644
index 0000000..a3c6243
--- /dev/null
+++ b/Source/WebCore/wml/WMLPageState.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2004-2007 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.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLPageState.h"
+
+#include "BackForwardController.h"
+#include "BackForwardList.h"
+#include "Document.h"
+#include "Frame.h"
+#include "HistoryItem.h"
+#include "KURL.h"
+#include "Page.h"
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+WMLPageState::WMLPageState(Page* page)
+ : m_page(page)
+ , m_hasAccessControlData(false)
+{
+}
+
+WMLPageState::~WMLPageState()
+{
+ m_variables.clear();
+}
+
+#ifndef NDEBUG
+// Debugging helper for use within gdb
+void WMLPageState::dump()
+{
+ WMLVariableMap::iterator it = m_variables.begin();
+ WMLVariableMap::iterator end = m_variables.end();
+
+ fprintf(stderr, "Dumping WMLPageState (this=%p) associated with Page (page=%p)...\n", this, m_page);
+ for (; it != end; ++it)
+ fprintf(stderr, "\t-> name: '%s'\tvalue: '%s'\n", (*it).first.latin1().data(), (*it).second.latin1().data());
+}
+#endif
+
+void WMLPageState::reset()
+{
+ // Remove all the variables
+ m_variables.clear();
+
+ // Clear the navigation history state
+ if (m_page)
+ m_page->backForward()->client()->clearWMLPageHistory();
+}
+
+static inline String normalizedHostName(const String& passedHost)
+{
+ if (passedHost.contains("127.0.0.1")) {
+ String host = passedHost;
+ return host.replace("127.0.0.1", "localhost");
+ }
+
+ return passedHost;
+}
+
+static inline String hostFromURL(const KURL& url)
+{
+ // Default to "localhost"
+ String host = normalizedHostName(url.host());
+ return host.isEmpty() ? "localhost" : host;
+}
+
+static KURL urlForHistoryItem(Frame* frame, HistoryItem* item)
+{
+ // For LayoutTests we need to find the corresponding WML frame in the test document
+ // to be able to test access-control correctly. Remember that WML is never supposed
+ // to be embedded anywhere, so the purpose is to simulate a standalone WML document.
+ if (frame->document()->isWMLDocument())
+ return item->url();
+
+ const HistoryItemVector& childItems = item->children();
+ HistoryItemVector::const_iterator it = childItems.begin();
+ const HistoryItemVector::const_iterator end = childItems.end();
+
+ for (; it != end; ++it) {
+ const RefPtr<HistoryItem> childItem = *it;
+ Frame* childFrame = frame->tree()->child(childItem->target());
+ if (!childFrame)
+ continue;
+
+ if (Document* childDocument = childFrame->document()) {
+ if (childDocument->isWMLDocument())
+ return childItem->url();
+ }
+ }
+
+ return item->url();
+}
+
+static bool tryAccessHistoryURLs(Page* page, KURL& previousURL, KURL& currentURL)
+{
+ if (!page)
+ return false;
+
+ Frame* frame = page->mainFrame();
+ if (!frame || !frame->document())
+ return false;
+
+ HistoryItem* previousItem = page->backForward()->backItem();
+ if (!previousItem)
+ return false;
+
+ HistoryItem* currentItem = page->backForward()->currentItem();
+ if (!currentItem)
+ return false;
+
+ previousURL = urlForHistoryItem(frame, previousItem);
+ currentURL = urlForHistoryItem(frame, currentItem);
+
+ return true;
+}
+
+bool WMLPageState::processAccessControlData(const String& domain, const String& path)
+{
+ if (m_hasAccessControlData)
+ return false;
+
+ m_hasAccessControlData = true;
+
+ KURL previousURL, currentURL;
+ if (!tryAccessHistoryURLs(m_page, previousURL, currentURL))
+ return true;
+
+ // Spec: The path attribute defaults to the value "/"
+ m_accessPath = path.isEmpty() ? "/" : path;
+
+ // Spec: The domain attribute defaults to the current decks domain.
+ String previousHost = hostFromURL(previousURL);
+ m_accessDomain = domain.isEmpty() ? previousHost : normalizedHostName(domain);
+
+ // Spec: To simplify the development of applications that may not know the absolute path to the
+ // current deck, the path attribute accepts relative URIs. The user agent converts the relative
+ // path to an absolute path and then performs prefix matching against the PATH attribute.
+ Document* document = m_page->mainFrame() ? m_page->mainFrame()->document() : 0;
+ if (document && previousHost == m_accessDomain && !m_accessPath.startsWith("/")) {
+ String currentPath = currentURL.path();
+
+ size_t index = currentPath.reverseFind('/');
+ if (index != WTF::notFound)
+ m_accessPath = document->completeURL(currentPath.left(index + 1) + m_accessPath).path();
+ }
+
+ return true;
+}
+
+void WMLPageState::resetAccessControlData()
+{
+ m_hasAccessControlData = false;
+ m_accessDomain = String();
+ m_accessPath = String();
+}
+
+bool WMLPageState::canAccessDeck() const
+{
+ if (!m_hasAccessControlData)
+ return true;
+
+ KURL previousURL, currentURL;
+ if (!tryAccessHistoryURLs(m_page, previousURL, currentURL))
+ return true;
+
+ if (equalIgnoringFragmentIdentifier(previousURL, currentURL))
+ return true;
+
+ return hostIsAllowedToAccess(hostFromURL(previousURL)) && pathIsAllowedToAccess(previousURL.path());
+}
+
+bool WMLPageState::hostIsAllowedToAccess(const String& host) const
+{
+ // Spec: The access domain is suffix-matched against the domain name portion of the referring URI
+ Vector<String> subdomainsAllowed;
+ if (m_accessDomain.contains('.'))
+ m_accessDomain.split('.', subdomainsAllowed);
+ else
+ subdomainsAllowed.append(m_accessDomain);
+
+ Vector<String> subdomainsCheck;
+ if (host.contains('.'))
+ host.split('.', subdomainsCheck);
+ else
+ subdomainsCheck.append(host);
+
+ Vector<String>::iterator itAllowed = subdomainsAllowed.end() - 1;
+ Vector<String>::iterator beginAllowed = subdomainsAllowed.begin();
+
+ Vector<String>::iterator itCheck = subdomainsCheck.end() - 1;
+ Vector<String>::iterator beginCheck = subdomainsCheck.begin();
+
+ bool hostOk = true;
+ for (; itAllowed >= beginAllowed && itCheck >= beginCheck; ) {
+ if (*itAllowed != *itCheck) {
+ hostOk = false;
+ break;
+ }
+
+ --itAllowed;
+ --itCheck;
+ }
+
+ return hostOk;
+}
+
+bool WMLPageState::pathIsAllowedToAccess(const String& path) const
+{
+ // Spec: The access path is prefix matched against the path portion of the referring URI
+ Vector<String> subpathsAllowed;
+ if (m_accessPath.contains('/'))
+ m_accessPath.split('/', subpathsAllowed);
+ else
+ subpathsAllowed.append(m_accessPath);
+
+ Vector<String> subpathsCheck;
+ if (path.contains('/'))
+ path.split('/', subpathsCheck);
+ else
+ subpathsCheck.append(path);
+
+ Vector<String>::iterator itAllowed = subpathsAllowed.begin();
+ Vector<String>::iterator endAllowed = subpathsAllowed.end();
+
+ Vector<String>::iterator itCheck = subpathsCheck.begin();
+ Vector<String>::iterator endCheck = subpathsCheck.end();
+
+ bool pathOk = true;
+ for (; itAllowed != endAllowed && itCheck != endCheck; ) {
+ if (*itAllowed != *itCheck) {
+ pathOk = false;
+ break;
+ }
+
+ ++itAllowed;
+ ++itCheck;
+ }
+
+ return pathOk;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLPageState.h b/Source/WebCore/wml/WMLPageState.h
new file mode 100644
index 0000000..0ea7cbb
--- /dev/null
+++ b/Source/WebCore/wml/WMLPageState.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Copyright (C) 2004-2007 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 WMLPageState_h
+#define WMLPageState_h
+
+#if ENABLE(WML)
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class Page;
+class WMLCardElement;
+
+typedef HashMap<String, String> WMLVariableMap;
+
+class WMLPageState {
+public:
+ WMLPageState(Page*);
+ virtual ~WMLPageState();
+
+#ifndef NDEBUG
+ void dump();
+#endif
+
+ // Reset the browser context
+ void reset();
+
+ // Variable handling
+ void storeVariable(const String& name, const String& value) { m_variables.set(name, value); }
+ void storeVariables(WMLVariableMap& variables) { m_variables = variables; }
+ String getVariable(const String& name) const { return m_variables.get(name); }
+ bool hasVariables() const { return !m_variables.isEmpty(); }
+
+ Page* page() const { return m_page; }
+
+ // Deck access control
+ bool processAccessControlData(const String& dmain, const String& path);
+ void resetAccessControlData();
+
+ bool canAccessDeck() const;
+
+private:
+ bool hostIsAllowedToAccess(const String&) const;
+ bool pathIsAllowedToAccess(const String&) const;
+
+private:
+ Page* m_page;
+ WMLVariableMap m_variables;
+ String m_accessDomain;
+ String m_accessPath;
+ bool m_hasAccessControlData;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLPostfieldElement.cpp b/Source/WebCore/wml/WMLPostfieldElement.cpp
new file mode 100644
index 0000000..25ce05a
--- /dev/null
+++ b/Source/WebCore/wml/WMLPostfieldElement.cpp
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLPostfieldElement.h"
+
+#include "TextEncoding.h"
+#include "HTMLNames.h"
+#include "WMLDocument.h"
+#include "WMLGoElement.h"
+#include "WMLNames.h"
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLPostfieldElement::WMLPostfieldElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLPostfieldElement> WMLPostfieldElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLPostfieldElement(tagName, document));
+}
+
+void WMLPostfieldElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ ContainerNode* parent = parentNode();
+ if (parent && parent->hasTagName(goTag))
+ static_cast<WMLGoElement*>(parent)->registerPostfieldElement(this);
+}
+
+void WMLPostfieldElement::removedFromDocument()
+{
+ ContainerNode* parent = parentNode();
+ if (parent && parent->hasTagName(goTag))
+ static_cast<WMLGoElement*>(parent)->deregisterPostfieldElement(this);
+
+ WMLElement::removedFromDocument();
+}
+
+String WMLPostfieldElement::name() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::nameAttr));
+}
+
+String WMLPostfieldElement::value() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::valueAttr));
+}
+
+static inline CString encodedString(const TextEncoding& encoding, const String& data)
+{
+ return encoding.encode(data.characters(), data.length(), EntitiesForUnencodables);
+}
+
+void WMLPostfieldElement::encodeData(const TextEncoding& encoding, CString& name, CString& value)
+{
+ name = encodedString(encoding, this->name());
+ value = encodedString(encoding, this->value());
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLPostfieldElement.h b/Source/WebCore/wml/WMLPostfieldElement.h
new file mode 100644
index 0000000..8d91073
--- /dev/null
+++ b/Source/WebCore/wml/WMLPostfieldElement.h
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLPostfieldElement_h
+#define WMLPostfieldElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLPostfieldElement : public WMLElement {
+public:
+ static PassRefPtr<WMLPostfieldElement> create(const QualifiedName&, Document*);
+
+ WMLPostfieldElement(const QualifiedName& tagName, Document*);
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ String name() const;
+ String value() const;
+
+ // Encode name() and value() in a CString using the passed encoding
+ void encodeData(const TextEncoding&, CString& name, CString& value);
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLPrevElement.cpp b/Source/WebCore/wml/WMLPrevElement.cpp
new file mode 100644
index 0000000..c07f019
--- /dev/null
+++ b/Source/WebCore/wml/WMLPrevElement.cpp
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLPrevElement.h"
+
+#include "BackForwardController.h"
+#include "Page.h"
+#include "WMLCardElement.h"
+#include "WMLDocument.h"
+#include "WMLPageState.h"
+#include "WMLTimerElement.h"
+
+namespace WebCore {
+
+WMLPrevElement::WMLPrevElement(const QualifiedName& tagName, Document* doc)
+ : WMLTaskElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLPrevElement> WMLPrevElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLPrevElement(tagName, document));
+}
+
+WMLPrevElement::~WMLPrevElement()
+{
+}
+
+void WMLPrevElement::executeTask()
+{
+ ASSERT(document()->isWMLDocument());
+ WMLDocument* document = static_cast<WMLDocument*>(this->document());
+
+ WMLPageState* pageState = wmlPageStateForDocument(document);
+ if (!pageState)
+ return;
+
+ WMLCardElement* card = document->activeCard();
+ if (!card)
+ return;
+
+ storeVariableState(pageState);
+
+ // Stop the timer of the current card if it is active
+ if (WMLTimerElement* eventTimer = card->eventTimer())
+ eventTimer->stop();
+
+ pageState->page()->backForward()->goBack();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLPrevElement.h b/Source/WebCore/wml/WMLPrevElement.h
new file mode 100644
index 0000000..2db8166
--- /dev/null
+++ b/Source/WebCore/wml/WMLPrevElement.h
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLPrevElement_h
+#define WMLPrevElement_h
+
+#if ENABLE(WML)
+#include "WMLTaskElement.h"
+
+namespace WebCore {
+
+class WMLPrevElement : public WMLTaskElement {
+public:
+ static PassRefPtr<WMLPrevElement> create(const QualifiedName&, Document*);
+
+ WMLPrevElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLPrevElement();
+
+ virtual void executeTask();
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLRefreshElement.cpp b/Source/WebCore/wml/WMLRefreshElement.cpp
new file mode 100644
index 0000000..8267e20
--- /dev/null
+++ b/Source/WebCore/wml/WMLRefreshElement.cpp
@@ -0,0 +1,85 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLRefreshElement.h"
+
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "WMLCardElement.h"
+#include "WMLDocument.h"
+#include "WMLPageState.h"
+#include "WMLTimerElement.h"
+
+namespace WebCore {
+
+WMLRefreshElement::WMLRefreshElement(const QualifiedName& tagName, Document* doc)
+ : WMLTaskElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLRefreshElement> WMLRefreshElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLRefreshElement(tagName, document));
+}
+
+WMLRefreshElement::~WMLRefreshElement()
+{
+}
+
+void WMLRefreshElement::executeTask()
+{
+ ASSERT(document()->isWMLDocument());
+ WMLDocument* document = static_cast<WMLDocument*>(this->document());
+
+ WMLPageState* pageState = wmlPageStateForDocument(document);
+ if (!pageState)
+ return;
+
+ WMLCardElement* card = document->activeCard();
+ if (!card)
+ return;
+
+ // Before perform refresh task, we store the current timeout
+ // value in the page state and then stop the timer
+ WMLTimerElement* timer = card->eventTimer();
+ if (timer) {
+ timer->storeIntervalToPageState();
+ timer->stop();
+ }
+
+ storeVariableState(pageState);
+
+ // Redisplay curremt card with current variable state
+ if (Frame* frame = document->frame()) {
+ if (FrameLoader* loader = frame->loader())
+ loader->reload();
+ }
+
+ // After refreshing task, resume the timer if it exsits
+ if (timer)
+ timer->start();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLRefreshElement.h b/Source/WebCore/wml/WMLRefreshElement.h
new file mode 100644
index 0000000..1459a05
--- /dev/null
+++ b/Source/WebCore/wml/WMLRefreshElement.h
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLRefreshElement_h
+#define WMLRefreshElement_h
+
+#if ENABLE(WML)
+#include "WMLTaskElement.h"
+
+namespace WebCore {
+
+class WMLRefreshElement : public WMLTaskElement {
+public:
+ static PassRefPtr<WMLRefreshElement> create(const QualifiedName&, Document*);
+
+ WMLRefreshElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLRefreshElement();
+
+ virtual void executeTask();
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLSelectElement.cpp b/Source/WebCore/wml/WMLSelectElement.cpp
new file mode 100644
index 0000000..78749b3
--- /dev/null
+++ b/Source/WebCore/wml/WMLSelectElement.cpp
@@ -0,0 +1,562 @@
+/**
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLSelectElement.h"
+
+#include "Attribute.h"
+#include "HTMLNames.h"
+#include "OptionElement.h"
+#include "RenderListBox.h"
+#include "RenderMenuList.h"
+#include "WMLDocument.h"
+#include "WMLNames.h"
+#include "WMLVariables.h"
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLSelectElement::WMLSelectElement(const QualifiedName& tagName, Document* document)
+ : WMLFormControlElement(tagName, document)
+ , m_initialized(false)
+{
+}
+
+PassRefPtr<WMLSelectElement> WMLSelectElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLSelectElement(tagName, document));
+}
+
+WMLSelectElement::~WMLSelectElement()
+{
+}
+
+const AtomicString& WMLSelectElement::formControlName() const
+{
+ AtomicString name = this->name();
+ return name.isNull() ? emptyAtom : name;
+}
+
+const AtomicString& WMLSelectElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, selectMultiple, ("select-multiple"));
+ DEFINE_STATIC_LOCAL(const AtomicString, selectOne, ("select-one"));
+ return m_data.multiple() ? selectMultiple : selectOne;
+}
+
+bool WMLSelectElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+ if (renderer())
+ return isFocusable();
+
+ return WMLFormControlElement::isKeyboardFocusable(event);
+}
+
+bool WMLSelectElement::isMouseFocusable() const
+{
+ if (renderer())
+ return isFocusable();
+
+ return WMLFormControlElement::isMouseFocusable();
+}
+
+void WMLSelectElement::selectAll()
+{
+ SelectElement::selectAll(m_data, this);
+}
+
+void WMLSelectElement::recalcStyle(StyleChange change)
+{
+ WMLFormControlElement::recalcStyle(change);
+}
+
+void WMLSelectElement::dispatchFocusEvent()
+{
+ SelectElement::dispatchFocusEvent(m_data, this);
+ WMLFormControlElement::dispatchFocusEvent();
+}
+
+void WMLSelectElement::dispatchBlurEvent()
+{
+ SelectElement::dispatchBlurEvent(m_data, this);
+ WMLFormControlElement::dispatchBlurEvent();
+}
+
+int WMLSelectElement::selectedIndex() const
+{
+ return SelectElement::selectedIndex(m_data, this);
+}
+
+void WMLSelectElement::setSelectedIndex(int optionIndex, bool deselect)
+{
+ SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, false, false);
+}
+
+void WMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, bool fireOnChangeNow, bool allowMultipleSelection)
+{
+ UNUSED_PARAM(allowMultipleSelection);
+ SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, fireOnChangeNow, true);
+}
+
+bool WMLSelectElement::saveFormControlState(String& value) const
+{
+ return SelectElement::saveFormControlState(m_data, this, value);
+}
+
+void WMLSelectElement::restoreFormControlState(const String& state)
+{
+ SelectElement::restoreFormControlState(m_data, this, state);
+}
+
+void WMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ SelectElement::setRecalcListItems(m_data, this);
+ WMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+void WMLSelectElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::multipleAttr)
+ SelectElement::parseMultipleAttribute(m_data, this, attr);
+ else
+ WMLFormControlElement::parseMappedAttribute(attr);
+}
+
+RenderObject* WMLSelectElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ if (m_data.usesMenuList())
+ return new (arena) RenderMenuList(this);
+ return new (arena) RenderListBox(this);
+}
+
+bool WMLSelectElement::appendFormData(FormDataList& list, bool)
+{
+ return SelectElement::appendFormData(m_data, this, list);
+}
+
+int WMLSelectElement::optionToListIndex(int optionIndex) const
+{
+ return SelectElement::optionToListIndex(m_data, this, optionIndex);
+}
+
+int WMLSelectElement::listToOptionIndex(int listIndex) const
+{
+ return SelectElement::listToOptionIndex(m_data, this, listIndex);
+}
+
+void WMLSelectElement::reset()
+{
+ SelectElement::reset(m_data, this);
+}
+
+void WMLSelectElement::defaultEventHandler(Event* event)
+{
+ SelectElement::defaultEventHandler(m_data, this, event, 0);
+
+ // FIXME: There must be a better place to update the page variable state. Investigate.
+ updateVariables();
+
+ if (event->defaultHandled())
+ return;
+
+ WMLFormControlElement::defaultEventHandler(event);
+}
+
+void WMLSelectElement::accessKeyAction(bool sendToAnyElement)
+{
+ focus();
+ dispatchSimulatedClick(0, sendToAnyElement);
+}
+
+void WMLSelectElement::setActiveSelectionAnchorIndex(int index)
+{
+ SelectElement::setActiveSelectionAnchorIndex(m_data, this, index);
+}
+
+void WMLSelectElement::setActiveSelectionEndIndex(int index)
+{
+ SelectElement::setActiveSelectionEndIndex(m_data, index);
+}
+
+void WMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
+{
+ SelectElement::updateListBoxSelection(m_data, this, deselectOtherOptions);
+}
+
+void WMLSelectElement::listBoxOnChange()
+{
+ SelectElement::listBoxOnChange(m_data, this);
+}
+
+void WMLSelectElement::menuListOnChange()
+{
+ SelectElement::menuListOnChange(m_data, this);
+}
+
+int WMLSelectElement::activeSelectionStartListIndex() const
+{
+ if (m_data.activeSelectionAnchorIndex() >= 0)
+ return m_data.activeSelectionAnchorIndex();
+ return optionToListIndex(selectedIndex());
+}
+
+int WMLSelectElement::activeSelectionEndListIndex() const
+{
+ if (m_data.activeSelectionEndIndex() >= 0)
+ return m_data.activeSelectionEndIndex();
+ return SelectElement::lastSelectedListIndex(m_data, this);
+}
+
+void WMLSelectElement::accessKeySetSelectedIndex(int index)
+{
+ SelectElement::accessKeySetSelectedIndex(m_data, this, index);
+}
+
+void WMLSelectElement::setRecalcListItems()
+{
+ SelectElement::setRecalcListItems(m_data, this);
+}
+
+void WMLSelectElement::scrollToSelection()
+{
+ SelectElement::scrollToSelection(m_data, this);
+}
+
+void WMLSelectElement::selectInitialOptions()
+{
+ // Spec: Step 1 - the default option index is determined using iname and ivalue
+ calculateDefaultOptionIndices();
+
+ if (m_defaultOptionIndices.isEmpty()) {
+ m_initialized = true;
+ return;
+ }
+
+ // Spec: Step 2 – initialise variables
+ initializeVariables();
+
+ // Spec: Step 3 – pre-select option(s) specified by the default option index
+ selectDefaultOptions();
+ m_initialized = true;
+}
+
+void WMLSelectElement::insertedIntoTree(bool deep)
+{
+ SelectElement::insertedIntoTree(m_data, this);
+ WMLFormControlElement::insertedIntoTree(deep);
+}
+
+void WMLSelectElement::calculateDefaultOptionIndices()
+{
+ WMLPageState* pageState = wmlPageStateForDocument(document());
+ if (!pageState)
+ return;
+
+ String variable;
+
+ // Spec: If the 'iname' attribute is specified and names a variable that is set,
+ // then the default option index is the validated value of that variable.
+ String iname = this->iname();
+ if (!iname.isEmpty()) {
+ variable = pageState->getVariable(iname);
+ if (!variable.isEmpty())
+ m_defaultOptionIndices = parseIndexValueString(variable);
+ }
+
+ // Spec: If the default option index is empty and the 'ivalue' attribute is specified,
+ // then the default option index is the validated attribute value.
+ String ivalue = this->ivalue();
+ if (m_defaultOptionIndices.isEmpty() && !ivalue.isEmpty())
+ m_defaultOptionIndices = parseIndexValueString(ivalue);
+
+ // Spec: If the default option index is empty, and the 'name' attribute is specified
+ // and the 'name' ttribute names a variable that is set, then for each value in the 'name'
+ // variable that is present as a value in the select's option elements, the index of the
+ // first option element containing that value is added to the default index if that
+ // index has not been previously added.
+ String name = this->name();
+ if (m_defaultOptionIndices.isEmpty() && !name.isEmpty()) {
+ variable = pageState->getVariable(name);
+ if (!variable.isEmpty())
+ m_defaultOptionIndices = valueStringToOptionIndices(variable);
+ }
+
+ String value = parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::valueAttr));
+
+ // Spec: If the default option index is empty and the 'value' attribute is specified then
+ // for each value in the 'value' attribute that is present as a value in the select's
+ // option elements, the index of the first option element containing that value is added
+ // to the default index if that index has not been previously added.
+ if (m_defaultOptionIndices.isEmpty() && !value.isEmpty())
+ m_defaultOptionIndices = valueStringToOptionIndices(value);
+
+ // Spec: If the default option index is empty and the select is a multi-choice, then the
+ // default option index is set to zero. If the select is single-choice, then the default
+ // option index is set to one.
+ if (m_defaultOptionIndices.isEmpty())
+ m_defaultOptionIndices.append((unsigned) !m_data.multiple());
+}
+
+void WMLSelectElement::selectDefaultOptions()
+{
+ ASSERT(!m_defaultOptionIndices.isEmpty());
+
+ if (!m_data.multiple()) {
+ setSelectedIndex(m_defaultOptionIndices.first() - 1, false);
+ return;
+ }
+
+ Vector<unsigned>::const_iterator end = m_defaultOptionIndices.end();
+ for (Vector<unsigned>::const_iterator it = m_defaultOptionIndices.begin(); it != end; ++it)
+ setSelectedIndex((*it) - 1, false);
+}
+
+void WMLSelectElement::initializeVariables()
+{
+ ASSERT(!m_defaultOptionIndices.isEmpty());
+
+ WMLPageState* pageState = wmlPageStateForDocument(document());
+ if (!pageState)
+ return;
+
+ const Vector<Element*>& items = m_data.listItems(this);
+ if (items.isEmpty())
+ return;
+
+ // Spec: If the 'iname' attribute is specified, then the named variable is set with the default option index.
+ String iname = this->iname();
+ if (!iname.isEmpty())
+ pageState->storeVariable(iname, optionIndicesToString());
+
+ String name = this->name();
+ if (name.isEmpty())
+ return;
+
+ if (m_data.multiple()) {
+ // Spec: If the 'name' attribute is specified and the select is a multiple-choice element,
+ // then for each index greater than zero, the value of the 'value' attribute on the option
+ // element at the index is added to the name variable.
+ pageState->storeVariable(name, optionIndicesToValueString());
+ return;
+ }
+
+ // Spec: If the 'name' attribute is specified and the select is a single-choice element,
+ // then the named variable is set with the value of the 'value' attribute on the option
+ // element at the default option index.
+ unsigned optionIndex = m_defaultOptionIndices.first();
+ ASSERT(optionIndex >= 1);
+
+ int listIndex = optionToListIndex(optionIndex - 1);
+ ASSERT(listIndex >= 0);
+ ASSERT(listIndex < (int) items.size());
+
+ if (OptionElement* optionElement = toOptionElement(items[listIndex]))
+ pageState->storeVariable(name, optionElement->value());
+}
+
+void WMLSelectElement::updateVariables()
+{
+ WMLPageState* pageState = wmlPageStateForDocument(document());
+ if (!pageState)
+ return;
+
+ String name = this->name();
+ String iname = this->iname();
+ if (iname.isEmpty() && name.isEmpty())
+ return;
+
+ String nameString;
+ String inameString;
+
+ unsigned optionIndex = 0;
+ const Vector<Element*>& items = m_data.listItems(this);
+
+ for (unsigned i = 0; i < items.size(); ++i) {
+ OptionElement* optionElement = toOptionElement(items[i]);
+ if (!optionElement)
+ continue;
+
+ ++optionIndex;
+ if (!optionElement->selected())
+ continue;
+
+ if (!nameString.isEmpty())
+ nameString += ";";
+
+ if (!inameString.isEmpty())
+ inameString += ";";
+
+ nameString += optionElement->value();
+ inameString += String::number(optionIndex);
+ }
+
+ if (!name.isEmpty())
+ pageState->storeVariable(name, nameString);
+
+ if (!iname.isEmpty())
+ pageState->storeVariable(iname, inameString);
+}
+
+Vector<unsigned> WMLSelectElement::parseIndexValueString(const String& indexValue) const
+{
+ Vector<unsigned> indices;
+ if (indexValue.isEmpty())
+ return indices;
+
+ Vector<String> indexStrings;
+ indexValue.split(';', indexStrings);
+
+ bool ok = false;
+ unsigned optionCount = SelectElement::optionCount(m_data, this);
+
+ Vector<String>::const_iterator end = indexStrings.end();
+ for (Vector<String>::const_iterator it = indexStrings.begin(); it != end; ++it) {
+ unsigned parsedValue = (*it).toUIntStrict(&ok);
+ // Spec: Remove all non-integer indices from the value. Remove all out-of-range indices
+ // from the value, where out-of-range is defined as any index with a value greater than
+ // the number of options in the select or with a value less than one.
+ if (!ok || parsedValue < 1 || parsedValue > optionCount)
+ continue;
+
+ // Spec: Remove duplicate indices.
+ if (indices.find(parsedValue) == notFound)
+ indices.append(parsedValue);
+ }
+
+ return indices;
+}
+
+Vector<unsigned> WMLSelectElement::valueStringToOptionIndices(const String& value) const
+{
+ Vector<unsigned> indices;
+ if (value.isEmpty())
+ return indices;
+
+ const Vector<Element*>& items = m_data.listItems(this);
+ if (items.isEmpty())
+ return indices;
+
+ Vector<String> indexStrings;
+ value.split(';', indexStrings);
+
+ unsigned optionIndex = 0;
+
+ Vector<String>::const_iterator end = indexStrings.end();
+ for (Vector<String>::const_iterator it = indexStrings.begin(); it != end; ++it) {
+ String value = *it;
+
+ for (unsigned i = 0; i < items.size(); ++i) {
+ if (!isOptionElement(items[i]))
+ continue;
+
+ ++optionIndex;
+ if (OptionElement* optionElement = toOptionElement(items[i])) {
+ if (optionElement->value() == value) {
+ indices.append(optionIndex);
+ break;
+ }
+ }
+ }
+ }
+
+ return indices;
+}
+
+String WMLSelectElement::optionIndicesToValueString() const
+{
+ String valueString;
+ if (m_defaultOptionIndices.isEmpty())
+ return valueString;
+
+ const Vector<Element*>& items = m_data.listItems(this);
+ if (items.isEmpty())
+ return valueString;
+
+ Vector<unsigned>::const_iterator end = m_defaultOptionIndices.end();
+ for (Vector<unsigned>::const_iterator it = m_defaultOptionIndices.begin(); it != end; ++it) {
+ unsigned optionIndex = (*it);
+ if (optionIndex < 1 || optionIndex > items.size())
+ continue;
+
+ int listIndex = optionToListIndex((*it) - 1);
+ ASSERT(listIndex >= 0);
+ ASSERT(listIndex < (int) items.size());
+
+ if (OptionElement* optionElement = toOptionElement(items[listIndex])) {
+ if (!valueString.isEmpty())
+ valueString += ";";
+
+ valueString += optionElement->value();
+ }
+ }
+
+ return valueString;
+}
+
+String WMLSelectElement::optionIndicesToString() const
+{
+ String valueString;
+ if (m_defaultOptionIndices.isEmpty())
+ return valueString;
+
+ Vector<unsigned>::const_iterator end = m_defaultOptionIndices.end();
+ for (Vector<unsigned>::const_iterator it = m_defaultOptionIndices.begin(); it != end; ++it) {
+ if (!valueString.isEmpty())
+ valueString += ";";
+
+ valueString += String::number(*it);
+ }
+
+ return valueString;
+}
+
+String WMLSelectElement::name() const
+{
+ return parseValueForbiddingVariableReferences(getAttribute(HTMLNames::nameAttr));
+}
+
+String WMLSelectElement::value() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::valueAttr));
+}
+
+String WMLSelectElement::iname() const
+{
+ return parseValueForbiddingVariableReferences(getAttribute(inameAttr));
+}
+
+String WMLSelectElement::ivalue() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(ivalueAttr));
+}
+
+void WMLSelectElement::listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow)
+{
+ /* Dummy implementation as listBoxSelectItem is pure virtual in SelectElement class */
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLSelectElement.h b/Source/WebCore/wml/WMLSelectElement.h
new file mode 100644
index 0000000..3d8c726
--- /dev/null
+++ b/Source/WebCore/wml/WMLSelectElement.h
@@ -0,0 +1,121 @@
+/**
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLSelectElement_h
+#define WMLSelectElement_h
+
+#if ENABLE(WML)
+#include "WMLFormControlElement.h"
+#include "SelectElement.h"
+
+namespace WebCore {
+
+class WMLSelectElement : public WMLFormControlElement, public SelectElement {
+public:
+ static PassRefPtr<WMLSelectElement> create(const QualifiedName&, Document*);
+
+ WMLSelectElement(const QualifiedName&, Document*);
+ virtual ~WMLSelectElement();
+
+ virtual const AtomicString& formControlName() const;
+ virtual const AtomicString& formControlType() const;
+
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual bool isMouseFocusable() const;
+ virtual bool canSelectAll() const { return !m_data.usesMenuList(); }
+ virtual void selectAll();
+
+ virtual void recalcStyle(StyleChange);
+
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
+
+ virtual bool canStartSelection() const { return false; }
+
+ virtual int selectedIndex() const;
+ virtual void setSelectedIndex(int index, bool deselect = true);
+ virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false, bool allowMultipleSelection = false);
+
+ virtual int size() const { return m_data.size(); }
+ virtual bool multiple() const { return m_data.multiple(); }
+
+ virtual bool saveFormControlState(String& value) const;
+ virtual void restoreFormControlState(const String&);
+
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+ virtual bool appendFormData(FormDataList&, bool);
+ virtual int optionToListIndex(int optionIndex) const;
+ virtual int listToOptionIndex(int listIndex) const;
+
+ virtual const Vector<Element*>& listItems() const { return m_data.listItems(this); }
+ virtual void reset();
+
+ virtual void defaultEventHandler(Event*);
+ virtual void accessKeyAction(bool sendToAnyElement);
+ virtual void setActiveSelectionAnchorIndex(int index);
+ virtual void setActiveSelectionEndIndex(int index);
+ virtual void updateListBoxSelection(bool deselectOtherOptions);
+ virtual void listBoxOnChange();
+ virtual void menuListOnChange();
+
+ virtual int activeSelectionStartListIndex() const;
+ virtual int activeSelectionEndListIndex() const;
+
+ void accessKeySetSelectedIndex(int);
+ void setRecalcListItems();
+ void scrollToSelection();
+ void selectInitialOptions();
+
+ bool initialized() const { return m_initialized; }
+
+ virtual void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
+private:
+ virtual void insertedIntoTree(bool);
+
+ void calculateDefaultOptionIndices();
+ void selectDefaultOptions();
+ void initializeVariables();
+ void updateVariables();
+
+ Vector<unsigned> parseIndexValueString(const String&) const;
+ Vector<unsigned> valueStringToOptionIndices(const String&) const;
+ String optionIndicesToValueString() const;
+ String optionIndicesToString() const;
+
+ virtual void updateValidity() {}
+
+ String name() const;
+ String value() const;
+ String iname() const;
+ String ivalue() const;
+
+ SelectElementData m_data;
+ bool m_initialized;
+ Vector<unsigned> m_defaultOptionIndices;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLSetvarElement.cpp b/Source/WebCore/wml/WMLSetvarElement.cpp
new file mode 100644
index 0000000..0514602
--- /dev/null
+++ b/Source/WebCore/wml/WMLSetvarElement.cpp
@@ -0,0 +1,94 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLSetvarElement.h"
+
+#include "Attribute.h"
+#include "HTMLNames.h"
+#include "WMLErrorHandling.h"
+#include "WMLTaskElement.h"
+#include "WMLVariables.h"
+
+namespace WebCore {
+
+WMLSetvarElement::WMLSetvarElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+PassRefPtr<WMLSetvarElement> WMLSetvarElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLSetvarElement(tagName, document));
+}
+
+WMLSetvarElement::~WMLSetvarElement()
+{
+}
+
+void WMLSetvarElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::nameAttr) {
+ if (!isValidVariableName(parseValueSubstitutingVariableReferences(attr->value(), WMLErrorInvalidVariableName))) {
+ reportWMLError(document(), WMLErrorInvalidVariableName);
+ return;
+ }
+ } else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+void WMLSetvarElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ ContainerNode* parent = parentNode();
+ if (!parent || !parent->isWMLElement())
+ return;
+
+ if (static_cast<WMLElement*>(parent)->isWMLTaskElement())
+ static_cast<WMLTaskElement*>(parent)->registerVariableSetter(this);
+}
+
+void WMLSetvarElement::removedFromDocument()
+{
+ ContainerNode* parent = parentNode();
+ if (parent && parent->isWMLElement()) {
+ if (static_cast<WMLElement*>(parent)->isWMLTaskElement())
+ static_cast<WMLTaskElement*>(parent)->deregisterVariableSetter(this);
+ }
+
+ WMLElement::removedFromDocument();
+}
+
+String WMLSetvarElement::name() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::nameAttr), WMLErrorInvalidVariableName);
+}
+
+String WMLSetvarElement::value() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::valueAttr));
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLSetvarElement.h b/Source/WebCore/wml/WMLSetvarElement.h
new file mode 100644
index 0000000..0951360
--- /dev/null
+++ b/Source/WebCore/wml/WMLSetvarElement.h
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLSetvarElement_h
+#define WMLSetvarElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLSetvarElement : public WMLElement {
+public:
+ static PassRefPtr<WMLSetvarElement> create(const QualifiedName&, Document*);
+
+ WMLSetvarElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLSetvarElement();
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ String name() const;
+ String value() const;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLTableElement.cpp b/Source/WebCore/wml/WMLTableElement.cpp
new file mode 100644
index 0000000..ed3522d
--- /dev/null
+++ b/Source/WebCore/wml/WMLTableElement.cpp
@@ -0,0 +1,275 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLTableElement.h"
+
+#include "Attribute.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "CharacterNames.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "NodeList.h"
+#include "RenderObject.h"
+#include "Text.h"
+#include "WMLErrorHandling.h"
+#include "WMLNames.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLTableElement::WMLTableElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+ , m_columns(0)
+{
+}
+
+PassRefPtr<WMLTableElement> WMLTableElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLTableElement(tagName, document));
+}
+
+WMLTableElement::~WMLTableElement()
+{
+}
+
+bool WMLTableElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == HTMLNames::alignAttr) {
+ result = eTable;
+ return false;
+ }
+
+ return WMLElement::mapToEntry(attrName, result);
+}
+
+void WMLTableElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == columnsAttr) {
+ bool isNumber = false;
+ m_columns = attr->value().string().toUIntStrict(&isNumber);
+
+ // Spec: This required attribute specifies the number of columns for the table.
+ // The user agent must create a table with exactly the number of columns specified
+ // by the attribute value. It is an error to specify a value of zero ("0")
+ if (!m_columns || !isNumber)
+ reportWMLError(document(), WMLErrorInvalidColumnsNumberInTable);
+ } else if (attr->name() == HTMLNames::alignAttr)
+ m_alignment = parseValueForbiddingVariableReferences(attr->value());
+ else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+void WMLTableElement::finishParsingChildren()
+{
+ WMLElement::finishParsingChildren();
+
+ if (!m_columns) {
+ reportWMLError(document(), WMLErrorInvalidColumnsNumberInTable);
+ return;
+ }
+
+ Vector<WMLElement*> rowElements = scanTableChildElements(this, trTag);
+ if (rowElements.isEmpty())
+ return;
+
+ Vector<WMLElement*>::iterator it = rowElements.begin();
+ Vector<WMLElement*>::iterator end = rowElements.end();
+
+ for (; it != end; ++it) {
+ WMLElement* rowElement = (*it);
+
+ // Squeeze the table to fit in the desired number of columns
+ Vector<WMLElement*> columnElements = scanTableChildElements(rowElement, tdTag);
+ unsigned actualNumberOfColumns = columnElements.size();
+
+ if (actualNumberOfColumns > m_columns) {
+ joinSuperflousColumns(columnElements, rowElement);
+ columnElements = scanTableChildElements(rowElement, tdTag);
+ } else if (actualNumberOfColumns < m_columns) {
+ padWithEmptyColumns(columnElements, rowElement);
+ columnElements = scanTableChildElements(rowElement, tdTag);
+ }
+
+ // Layout cells according to the 'align' attribute
+ alignCells(columnElements, rowElement);
+ }
+}
+
+Vector<WMLElement*> WMLTableElement::scanTableChildElements(WMLElement* startElement, const QualifiedName& tagName) const
+{
+ Vector<WMLElement*> childElements;
+
+ RefPtr<NodeList> children = startElement->childNodes();
+ if (!children)
+ return childElements;
+
+ unsigned length = children->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Node* child = children->item(i);
+ if (child->hasTagName(tagName))
+ childElements.append(static_cast<WMLElement*>(child));
+ }
+
+ return childElements;
+}
+
+void WMLTableElement::transferAllChildrenOfElementToTargetElement(WMLElement* sourceElement, WMLElement* targetElement, unsigned startOffset) const
+{
+ RefPtr<NodeList> children = sourceElement->childNodes();
+ if (!children)
+ return;
+
+ ExceptionCode ec = 0;
+
+ unsigned length = children->length();
+ for (unsigned i = startOffset; i < length; ++i) {
+ RefPtr<Node> clonedNode = children->item(i)->cloneNode(true);
+ targetElement->appendChild(clonedNode.release(), ec);
+ ASSERT(ec == 0);
+ }
+}
+
+bool WMLTableElement::tryMergeAdjacentTextCells(Node* item, Node* nextItem) const
+{
+ if (!item || !nextItem)
+ return false;
+
+ if (!item->isTextNode() || !nextItem->isTextNode())
+ return false;
+
+ Text* itemText = static_cast<Text*>(item);
+ Text* nextItemText = static_cast<Text*>(nextItem);
+
+ String newContent = " ";
+ newContent += nextItemText->data();
+
+ ExceptionCode ec = 0;
+ itemText->appendData(newContent, ec);
+ ASSERT(ec == 0);
+
+ return true;
+}
+
+void WMLTableElement::joinSuperflousColumns(Vector<WMLElement*>& columnElements, WMLElement* rowElement) const
+{
+ // Spec: If the actual number of columns in a row is greater than the value specified
+ // by this attribute, the extra columns of the row must be aggregated into the last
+ // column such that the row contains exactly the number of columns specified.
+ WMLElement* lastColumn = columnElements.at(m_columns - 1);
+ ASSERT(lastColumn);
+
+ // Merge superflous columns into a single one
+ RefPtr<WMLElement> newCell = WMLElement::create(tdTag, document());
+ transferAllChildrenOfElementToTargetElement(lastColumn, newCell.get(), 0);
+
+ ExceptionCode ec = 0;
+ unsigned actualNumberOfColumns = columnElements.size();
+
+ for (unsigned i = m_columns; i < actualNumberOfColumns; ++i) {
+ WMLElement* columnElement = columnElements.at(i);
+ unsigned startOffset = 0;
+
+ // Spec: A single inter-word space must be inserted between two cells that are being aggregated.
+ if (tryMergeAdjacentTextCells(newCell->lastChild(), columnElement->firstChild()))
+ ++startOffset;
+
+ transferAllChildrenOfElementToTargetElement(columnElement, newCell.get(), startOffset);
+ }
+
+ // Remove the columns, that have just been merged
+ unsigned i = actualNumberOfColumns;
+ for (; i > m_columns; --i) {
+ rowElement->removeChild(columnElements.at(i - 1), ec);
+ ASSERT(ec == 0);
+ }
+
+ // Replace the last column in the row with the new merged column
+ rowElement->replaceChild(newCell.release(), lastColumn, ec);
+ ASSERT(ec == 0);
+}
+
+void WMLTableElement::padWithEmptyColumns(Vector<WMLElement*>& columnElements, WMLElement* rowElement) const
+{
+ // Spec: If the actual number of columns in a row is less than the value specified by the columns
+ // attribute, the row must be padded with empty columns effectively as if the user agent
+ // appended empty td elements to the row.
+ ExceptionCode ec = 0;
+
+ for (unsigned i = columnElements.size(); i < m_columns; ++i) {
+ RefPtr<WMLElement> newCell = WMLElement::create(tdTag, document());
+ rowElement->appendChild(newCell.release(), ec);
+ ASSERT(ec == 0);
+ }
+}
+
+void WMLTableElement::alignCells(Vector<WMLElement*>& columnElements, WMLElement* rowElement) const
+{
+ // Spec: User agents should consider the current language when determining
+ // the default alignment and the direction of the table.
+ bool rtl = false;
+ if (RenderObject* renderer = rowElement->renderer()) {
+ if (RenderStyle* style = renderer->style())
+ rtl = !style->isLeftToRightDirection();
+ }
+
+ rowElement->setAttribute(HTMLNames::alignAttr, rtl ? "right" : "left");
+
+ if (m_alignment.isEmpty())
+ return;
+
+ unsigned alignLength = m_alignment.length();
+
+ Vector<WMLElement*>::iterator it = columnElements.begin();
+ Vector<WMLElement*>::iterator end = columnElements.end();
+
+ for (unsigned i = 0; it != end; ++it, ++i) {
+ if (i == alignLength)
+ break;
+
+ String alignmentValue;
+ switch (m_alignment[i]) {
+ case 'C':
+ alignmentValue = "center";
+ break;
+ case 'L':
+ alignmentValue = "left";
+ break;
+ case 'R':
+ alignmentValue = "right";
+ break;
+ default:
+ break;
+ }
+
+ if (alignmentValue.isEmpty())
+ continue;
+
+ (*it)->setAttribute(HTMLNames::alignAttr, alignmentValue);
+ }
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLTableElement.h b/Source/WebCore/wml/WMLTableElement.h
new file mode 100644
index 0000000..9f0a592
--- /dev/null
+++ b/Source/WebCore/wml/WMLTableElement.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLTableElement_h
+#define WMLTableElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class HTMLCollection;
+
+class WMLTableElement : public WMLElement {
+public:
+ static PassRefPtr<WMLTableElement> create(const QualifiedName&, Document*);
+
+ WMLTableElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLTableElement();
+
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+
+ virtual void finishParsingChildren();
+
+private:
+ Vector<WMLElement*> scanTableChildElements(WMLElement* startElement, const QualifiedName& tagName) const;
+
+ bool tryMergeAdjacentTextCells(Node* item, Node* nextItem) const;
+ void transferAllChildrenOfElementToTargetElement(WMLElement* sourceElement, WMLElement* targetElement, unsigned startOffset) const;
+ void joinSuperflousColumns(Vector<WMLElement*>& columnElements, WMLElement* rowElement) const;
+ void padWithEmptyColumns(Vector<WMLElement*>& columnElements, WMLElement* rowElement) const;
+ void alignCells(Vector<WMLElement*>& columnElements, WMLElement* rowElement) const;
+
+ unsigned m_columns;
+ String m_alignment;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLTagNames.in b/Source/WebCore/wml/WMLTagNames.in
new file mode 100644
index 0000000..fd7c762
--- /dev/null
+++ b/Source/WebCore/wml/WMLTagNames.in
@@ -0,0 +1,35 @@
+namespace="WML"
+namespaceURI="http://www.wapforum.org/DTD/wml_1.1.xml"
+guardFactoryWith="ENABLE(WML)"
+
+a
+access
+anchor
+br interfaceName=WMLBRElement
+card
+do
+fieldset interfaceName=WMLFieldSetElement
+go
+head interfaceName=WMLElement
+img interfaceName=WMLImageElement
+input
+#if 0
+# Note: 'insertedLegend' is not an official WML element - internal purpose only!
+#endif
+insertedLegend interfaceName=WMLInsertedLegendElement
+meta
+noop
+onevent interfaceName=WMLOnEventElement
+optgroup interfaceName=WMLOptGroupElement
+option
+p
+postfield
+prev
+refresh
+select
+setvar
+table
+td interfaceName=WMLElement
+template
+timer
+tr interfaceName=WMLElement
diff --git a/Source/WebCore/wml/WMLTaskElement.cpp b/Source/WebCore/wml/WMLTaskElement.cpp
new file mode 100644
index 0000000..3d1d636
--- /dev/null
+++ b/Source/WebCore/wml/WMLTaskElement.cpp
@@ -0,0 +1,119 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLTaskElement.h"
+
+#include "WMLAnchorElement.h"
+#include "WMLDoElement.h"
+#include "WMLNames.h"
+#include "WMLOnEventElement.h"
+#include "WMLPageState.h"
+#include "WMLSetvarElement.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLTaskElement::WMLTaskElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+WMLTaskElement::~WMLTaskElement()
+{
+}
+
+void WMLTaskElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ ContainerNode* parent = parentNode();
+ if (!parent || !parent->isWMLElement())
+ return;
+
+ if (parent->hasTagName(anchorTag))
+ static_cast<WMLAnchorElement*>(parent)->registerTask(this);
+ else if (parent->hasTagName(doTag))
+ static_cast<WMLDoElement*>(parent)->registerTask(this);
+ else if (parent->hasTagName(oneventTag))
+ static_cast<WMLOnEventElement*>(parent)->registerTask(this);
+}
+
+void WMLTaskElement::removedFromDocument()
+{
+ ContainerNode* parent = parentNode();
+ if (parent && parent->isWMLElement()) {
+ if (parent->hasTagName(anchorTag))
+ static_cast<WMLAnchorElement*>(parent)->deregisterTask(this);
+ else if (parent->hasTagName(doTag))
+ static_cast<WMLDoElement*>(parent)->deregisterTask(this);
+ else if (parent->hasTagName(oneventTag))
+ static_cast<WMLOnEventElement*>(parent)->deregisterTask(this);
+ }
+
+ WMLElement::removedFromDocument();
+}
+
+void WMLTaskElement::registerVariableSetter(WMLSetvarElement* element)
+{
+ ASSERT(m_variableSetterElements.find(element) == WTF::notFound);
+ m_variableSetterElements.append(element);
+}
+
+void WMLTaskElement::deregisterVariableSetter(WMLSetvarElement* element)
+{
+ size_t position = m_variableSetterElements.find(element);
+ ASSERT(position != WTF::notFound);
+ m_variableSetterElements.remove(position);
+}
+
+void WMLTaskElement::storeVariableState(WMLPageState* pageState)
+{
+ if (!pageState || m_variableSetterElements.isEmpty())
+ return;
+
+ WMLVariableMap variables;
+ Vector<WMLSetvarElement*>::iterator it = m_variableSetterElements.begin();
+ Vector<WMLSetvarElement*>::iterator end = m_variableSetterElements.end();
+
+ for (; it != end; ++it) {
+ WMLSetvarElement* setterElement = (*it);
+
+ String name = setterElement->name();
+ if (name.isEmpty())
+ continue;
+
+ String value = setterElement->value();
+ variables.set(name, value);
+
+ // The next setvar element may depend on this variable value. It's safe to store the current
+ // name value pair in the page state, as the whole page state is replaced soon by this new map
+ pageState->storeVariable(name, value);
+ }
+
+ pageState->storeVariables(variables);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLTaskElement.h b/Source/WebCore/wml/WMLTaskElement.h
new file mode 100644
index 0000000..91e2a32
--- /dev/null
+++ b/Source/WebCore/wml/WMLTaskElement.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLTaskElement_h
+#define WMLTaskElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class WMLPageState;
+class WMLSetvarElement;
+
+class WMLTaskElement : public WMLElement {
+public:
+ virtual bool isWMLTaskElement() const { return true; }
+
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void executeTask() = 0;
+
+ void registerVariableSetter(WMLSetvarElement*);
+ void deregisterVariableSetter(WMLSetvarElement*);
+
+protected:
+ WMLTaskElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLTaskElement();
+
+ void storeVariableState(WMLPageState*);
+
+private:
+ Vector<WMLSetvarElement*> m_variableSetterElements;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLTemplateElement.cpp b/Source/WebCore/wml/WMLTemplateElement.cpp
new file mode 100644
index 0000000..584a762
--- /dev/null
+++ b/Source/WebCore/wml/WMLTemplateElement.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLTemplateElement.h"
+
+#include "Attribute.h"
+#include "NodeList.h"
+#include "WMLCardElement.h"
+#include "WMLDocument.h"
+#include "WMLIntrinsicEventHandler.h"
+#include "WMLNames.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLTemplateElement::WMLTemplateElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+{
+}
+
+WMLTemplateElement::~WMLTemplateElement()
+{
+}
+
+PassRefPtr<WMLTemplateElement> WMLTemplateElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLTemplateElement(tagName, document));
+}
+
+void WMLTemplateElement::parseMappedAttribute(Attribute* attr)
+{
+ WMLIntrinsicEventType eventType = WMLIntrinsicEventUnknown;
+
+ if (attr->name() == onenterforwardAttr)
+ eventType = WMLIntrinsicEventOnEnterForward;
+ else if (attr->name() == onenterbackwardAttr)
+ eventType = WMLIntrinsicEventOnEnterBackward;
+ else if (attr->name() == ontimerAttr)
+ eventType = WMLIntrinsicEventOnTimer;
+ else {
+ WMLElement::parseMappedAttribute(attr);
+ return;
+ }
+
+ if (eventType == WMLIntrinsicEventUnknown)
+ return;
+
+ // Register intrinsic event in card
+ RefPtr<WMLIntrinsicEvent> event = WMLIntrinsicEvent::create(document(), attr->value());
+
+ createEventHandlerIfNeeded();
+ eventHandler()->registerIntrinsicEvent(eventType, event);
+}
+
+void WMLTemplateElement::registerTemplatesInDocument(Document* doc)
+{
+ ASSERT(doc);
+
+ // Build list of cards in document
+ RefPtr<NodeList> nodeList = doc->getElementsByTagName("card");
+ if (!nodeList)
+ return;
+
+ unsigned length = nodeList->length();
+ if (length < 1)
+ return;
+
+ HashSet<WMLCardElement*> cards;
+ for (unsigned i = 0; i < length; ++i)
+ cards.add(static_cast<WMLCardElement*>(nodeList->item(i)));
+
+ if (cards.isEmpty())
+ return;
+
+ // Register template element to all cards
+ nodeList = doc->getElementsByTagName("template");
+ if (!nodeList)
+ return;
+
+ length = nodeList->length();
+ if (length < 1)
+ return;
+
+ // Only one template element should be allowed in a document
+ // Calling setTemplateElement() twice on a WMLCardElement, will result in a parser error.
+ for (unsigned i = 0; i < length; ++i) {
+ WMLTemplateElement* temp = static_cast<WMLTemplateElement*>(nodeList->item(i));
+
+ HashSet<WMLCardElement*>::iterator it = cards.begin();
+ HashSet<WMLCardElement*>::iterator end = cards.end();
+
+ for (; it != end; ++it)
+ (*it)->setTemplateElement(temp);
+ }
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLTemplateElement.h b/Source/WebCore/wml/WMLTemplateElement.h
new file mode 100644
index 0000000..c168753
--- /dev/null
+++ b/Source/WebCore/wml/WMLTemplateElement.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLTemplateElement_h
+#define WMLTemplateElement_h
+
+#if ENABLE(WML)
+#include "WMLElement.h"
+#include "WMLEventHandlingElement.h"
+
+namespace WebCore {
+
+class WMLTemplateElement : public WMLElement, public WMLEventHandlingElement {
+public:
+ static PassRefPtr<WMLTemplateElement> create(const QualifiedName&, Document*);
+
+ WMLTemplateElement(const QualifiedName&, Document*);
+ virtual ~WMLTemplateElement();
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ static void registerTemplatesInDocument(Document*);
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLTimerElement.cpp b/Source/WebCore/wml/WMLTimerElement.cpp
new file mode 100644
index 0000000..dd6c4aa
--- /dev/null
+++ b/Source/WebCore/wml/WMLTimerElement.cpp
@@ -0,0 +1,161 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLTimerElement.h"
+
+#include "Attribute.h"
+#include "HTMLNames.h"
+#include "WMLCardElement.h"
+#include "WMLDocument.h"
+#include "WMLNames.h"
+#include "WMLPageState.h"
+#include "WMLTemplateElement.h"
+#include "WMLVariables.h"
+
+namespace WebCore {
+
+using namespace WMLNames;
+
+WMLTimerElement::WMLTimerElement(const QualifiedName& tagName, Document* doc)
+ : WMLElement(tagName, doc)
+ , m_timer(this, &WMLTimerElement::timerFired)
+{
+}
+
+PassRefPtr<WMLTimerElement> WMLTimerElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new WMLTimerElement(tagName, document));
+}
+
+void WMLTimerElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == HTMLNames::nameAttr)
+ m_name = parseValueForbiddingVariableReferences(attr->value());
+ else
+ WMLElement::parseMappedAttribute(attr);
+}
+
+void WMLTimerElement::insertedIntoDocument()
+{
+ WMLElement::insertedIntoDocument();
+
+ // If the value of timeout is not a positive integer, ignore it
+ if (value().toInt() <= 0)
+ return;
+
+ ContainerNode* parent = parentNode();
+ if (!parent || !parent->isWMLElement())
+ return;
+
+ if (parent->hasTagName(cardTag)) {
+ m_card = static_cast<WMLCardElement*>(parent);
+ m_card->setIntrinsicEventTimer(this);
+ }
+}
+
+void WMLTimerElement::removedFromDocument()
+{
+ ContainerNode* parent = parentNode();
+ if (parent && parent->isWMLElement() && parent->hasTagName(cardTag)) {
+ m_card->setIntrinsicEventTimer(0);
+ m_card = 0;
+ }
+
+ WMLElement::removedFromDocument();
+}
+
+void WMLTimerElement::timerFired(Timer<WMLTimerElement>*)
+{
+ if (!m_card)
+ return;
+
+ WMLPageState* pageState = wmlPageStateForDocument(document());
+ if (!pageState)
+ return;
+
+ String value = this->value();
+
+ // When the timer expires, set the name varialbe of timer to '0'
+ if (!m_name.isEmpty()) {
+ value = "0";
+ pageState->storeVariable(m_name, value);
+ }
+
+ WMLIntrinsicEventType eventType = WMLIntrinsicEventOnTimer;
+ WMLIntrinsicEventHandler* eventHandler = m_card->eventHandler();
+
+ bool hasIntrinsicEvent = false;
+ if (eventHandler && eventHandler->hasIntrinsicEvent(eventType))
+ hasIntrinsicEvent = true;
+ else if (m_card->templateElement()) {
+ eventHandler = m_card->templateElement()->eventHandler();
+ if (eventHandler && eventHandler->hasIntrinsicEvent(eventType))
+ hasIntrinsicEvent = true;
+ }
+
+ if (hasIntrinsicEvent)
+ eventHandler->triggerIntrinsicEvent(eventType);
+}
+
+void WMLTimerElement::start(int interval)
+{
+ if (!m_card || m_timer.isActive())
+ return;
+
+ if (interval <= 0 && !m_name.isEmpty()) {
+ if (WMLPageState* pageState = wmlPageStateForDocument(document()))
+ interval = pageState->getVariable(m_name).toInt();
+ }
+
+ if (interval <= 0)
+ interval = value().toInt();
+
+ if (interval > 0)
+ m_timer.startOneShot(interval / 10.0f);
+}
+
+void WMLTimerElement::stop()
+{
+ if (m_timer.isActive())
+ m_timer.stop();
+}
+
+void WMLTimerElement::storeIntervalToPageState()
+{
+ if (!m_timer.isActive())
+ return;
+
+ int interval = static_cast<int>(m_timer.nextFireInterval()) * 10;
+
+ if (WMLPageState* pageState = wmlPageStateForDocument(document()))
+ pageState->storeVariable(m_name, String::number(interval));
+}
+
+String WMLTimerElement::value() const
+{
+ return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::valueAttr));
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLTimerElement.h b/Source/WebCore/wml/WMLTimerElement.h
new file mode 100644
index 0000000..894c793
--- /dev/null
+++ b/Source/WebCore/wml/WMLTimerElement.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLTimerElement_h
+#define WMLTimerElement_h
+
+#if ENABLE(WML)
+#include "Timer.h"
+#include "WMLElement.h"
+
+namespace WebCore {
+
+class WMLCardElement;
+
+class WMLTimerElement : public WMLElement {
+public:
+ static PassRefPtr<WMLTimerElement> create(const QualifiedName&, Document*);
+
+ WMLTimerElement(const QualifiedName& tagName, Document*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+
+ void timerFired(Timer<WMLTimerElement>*);
+
+ void start(int interval = -1);
+ void stop();
+ void storeIntervalToPageState();
+
+ String value() const;
+
+private:
+ WMLCardElement* m_card;
+ String m_name;
+ Timer<WMLTimerElement> m_timer;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/wml/WMLVariables.cpp b/Source/WebCore/wml/WMLVariables.cpp
new file mode 100644
index 0000000..f7be400
--- /dev/null
+++ b/Source/WebCore/wml/WMLVariables.cpp
@@ -0,0 +1,286 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WML)
+#include "WMLVariables.h"
+
+#include "WMLDocument.h"
+#include <wtf/ASCIICType.h>
+
+namespace WebCore {
+
+// WML variables specification, excluding the
+// pre-WML 1.0 deprecated variable syntax
+//
+// varname = ("_" | alpha) ("_" | alpha | digit)*
+// conv = ":" ("e" ("scape")? | "n" ("oesc")? | "u" ("nesc")?)
+// var = ("$" varname) | ("$(" varname (conv)? ")")
+
+static bool isValidFirstVariableNameCharacter(const UChar& character)
+{
+ return WTF::isASCIIAlpha(character)
+ || character == '_';
+}
+
+static bool isValidVariableNameCharacter(const UChar& character)
+{
+ return WTF::isASCIIAlpha(character)
+ || WTF::isASCIIDigit(character)
+ || character == '_';
+}
+
+static bool isValidVariableEscapingModeString(const String& mode, WMLVariableEscapingMode& escapeMode)
+{
+ if (mode == "e" || mode == "escape")
+ escapeMode = WMLVariableEscapingEscape;
+ else if (mode == "u" || mode == "unesc")
+ escapeMode = WMLVariableEscapingUnescape;
+ else if (mode == "n" || mode == "noesc")
+ escapeMode = WMLVariableEscapingNone;
+ else
+ return false;
+
+ return true;
+}
+
+bool isValidVariableName(const String& name)
+{
+ if (name.isEmpty())
+ return false;
+
+ const UChar* characters = name.characters();
+ if (!isValidFirstVariableNameCharacter(characters[0]))
+ return false;
+
+ unsigned length = name.length();
+ for (unsigned i = 1; i < length; ++i) {
+ if (!isValidVariableNameCharacter(characters[i]))
+ return false;
+ }
+
+ return true;
+}
+
+bool containsVariableReference(const String& text, bool& isValid)
+{
+ isValid = true;
+ bool foundReference = false;
+ bool finished = false;
+ int currentPosition = 0;
+ const UChar* characters = text.characters();
+
+ while (!finished) {
+ // Find beginning of variable reference
+ int referenceStartPosition = text.find('$', currentPosition);
+ if (referenceStartPosition == -1) {
+ finished = true;
+ break;
+ }
+
+ foundReference = true;
+
+ int nameStartPosition = referenceStartPosition + 1;
+ int nameEndPosition = -1;
+
+ if (characters[nameStartPosition] == '(') {
+ // If the input string contains an open brace, a close brace must exist as well
+ nameEndPosition = text.find(')', nameStartPosition + 1);
+ if (nameEndPosition == -1) {
+ finished = true;
+ isValid = false;
+ break;
+ }
+
+ ++nameStartPosition;
+ } else {
+ int length = text.length();
+ for (nameEndPosition = nameStartPosition; nameEndPosition < length; ++nameEndPosition) {
+ if (!isValidVariableNameCharacter(text[nameEndPosition]))
+ break;
+ }
+ }
+
+ if (nameEndPosition < nameStartPosition) {
+ finished = true;
+ isValid = false;
+ break;
+ }
+
+ // Eventually split of conversion string, and check its syntax afterwards
+ String conversionString;
+ String variableName = text.substring(nameStartPosition, nameEndPosition - nameStartPosition);
+
+ int conversionStringStart = variableName.find(':');
+ if (conversionStringStart != -1) {
+ conversionString = variableName.substring(conversionStringStart + 1, variableName.length() - (conversionStringStart + 1));
+ variableName = variableName.left(conversionStringStart);
+ }
+
+ isValid = isValidVariableName(variableName);
+ if (!isValid) {
+ finished = true;
+ break;
+ }
+
+ if (!conversionString.isEmpty()) {
+ isValid = isValidVariableName(conversionString);
+ if (!isValid) {
+ finished = true;
+ break;
+ }
+
+ WMLVariableEscapingMode escapeMode = WMLVariableEscapingNone;
+ isValid = isValidVariableEscapingModeString(conversionString, escapeMode);
+ if (!isValid) {
+ finished = true;
+ break;
+ }
+ }
+
+ currentPosition = nameEndPosition;
+ }
+
+ return foundReference;
+}
+
+String substituteVariableReferences(const String& reference, Document* document, WMLVariableEscapingMode escapeMode)
+{
+ ASSERT(document);
+
+ if (reference.isEmpty())
+ return reference;
+
+ WMLPageState* pageState = wmlPageStateForDocument(document);
+ if (!pageState)
+ return reference;
+
+ bool isValid = true;
+ String remainingInput = reference;
+ String result;
+
+ while (!remainingInput.isEmpty()) {
+ ASSERT(isValid);
+
+ int start = remainingInput.find("$");
+ if (start == -1) {
+ // Consume all remaining characters, as there's nothing more to substitute
+ result += remainingInput;
+ break;
+ }
+
+ // Consume all characters until the variable reference beginning
+ result += remainingInput.left(start);
+ remainingInput.remove(0, start);
+
+ // Transform adjacent dollar signs into a single dollar sign as string literal
+ if (remainingInput[1] == '$') {
+ result += "$";
+ remainingInput.remove(0, 2);
+ continue;
+ }
+
+ String variableName;
+ String conversionMode;
+
+ if (remainingInput[1] == '(') {
+ int referenceEndPosition = remainingInput.find(")");
+ if (referenceEndPosition == -1) {
+ isValid = false;
+ break;
+ }
+
+ variableName = remainingInput.substring(2, referenceEndPosition - 2);
+ remainingInput.remove(0, referenceEndPosition + 1);
+
+ // Determine variable conversion mode string
+ int pos = variableName.find(':');
+ if (pos != -1) {
+ conversionMode = variableName.substring(pos + 1, variableName.length() - (pos + 1));
+ variableName = variableName.left(pos);
+ }
+ } else {
+ int length = remainingInput.length();
+ int referenceEndPosition = 1;
+
+ for (; referenceEndPosition < length; ++referenceEndPosition) {
+ if (!isValidVariableNameCharacter(remainingInput[referenceEndPosition]))
+ break;
+ }
+
+ variableName = remainingInput.substring(1, referenceEndPosition - 1);
+ remainingInput.remove(0, referenceEndPosition);
+ }
+
+ isValid = isValidVariableName(variableName);
+ if (!isValid)
+ break;
+
+ ASSERT(!variableName.isEmpty());
+
+ String variableValue = pageState->getVariable(variableName);
+ if (variableValue.isEmpty())
+ continue;
+
+ if (containsVariableReference(variableValue, isValid)) {
+ if (!isValid)
+ break;
+
+ variableValue = substituteVariableReferences(variableValue, document, escapeMode);
+ continue;
+ }
+
+ if (!conversionMode.isEmpty()) {
+ // Override default escape mode, if desired
+ WMLVariableEscapingMode specifiedEscapeMode = WMLVariableEscapingNone;
+ if ((isValid = isValidVariableEscapingModeString(conversionMode, specifiedEscapeMode)))
+ escapeMode = specifiedEscapeMode;
+
+ if (!isValid)
+ break;
+ }
+
+ switch (escapeMode) {
+ case WMLVariableEscapingNone:
+ break;
+ case WMLVariableEscapingEscape:
+ variableValue = encodeWithURLEscapeSequences(variableValue);
+ break;
+ case WMLVariableEscapingUnescape:
+ variableValue = decodeURLEscapeSequences(variableValue);
+ break;
+ }
+
+ result += variableValue;
+ ASSERT(isValid);
+ }
+
+ if (!isValid) {
+ reportWMLError(document, WMLErrorInvalidVariableReference);
+ return reference;
+ }
+
+ return result;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/wml/WMLVariables.h b/Source/WebCore/wml/WMLVariables.h
new file mode 100644
index 0000000..3bd0f81
--- /dev/null
+++ b/Source/WebCore/wml/WMLVariables.h
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * 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 WMLVariables_h
+#define WMLVariables_h
+
+#include <wtf/Forward.h>
+
+#if ENABLE(WML)
+namespace WebCore {
+
+ class Document;
+
+ enum WMLVariableEscapingMode {
+ WMLVariableEscapingNone = 0,
+ WMLVariableEscapingEscape,
+ WMLVariableEscapingUnescape
+ };
+
+ bool isValidVariableName(const String&);
+ bool containsVariableReference(const String&, bool& isValid);
+
+ String substituteVariableReferences(const String& variableReference,
+ Document*,
+ WMLVariableEscapingMode mode = WMLVariableEscapingNone);
+
+}
+
+#endif
+#endif