summaryrefslogtreecommitdiffstats
path: root/WebCore/html
diff options
context:
space:
mode:
authorFeng Qian <fqian@google.com>2009-06-18 18:20:56 -0700
committerFeng Qian <fqian@google.com>2009-06-18 18:20:56 -0700
commit1edef79f87f9c52c21d69c87c19f8e2b140a9119 (patch)
treecad337ef493b0d9710bf3ae478cb87cb534f598d /WebCore/html
parentb83fc086000e27bc227580bd0e35b9d7bee1179a (diff)
parentc9c4d65c1547996ed3748026904d6e7f09aec2b4 (diff)
downloadexternal_webkit-1edef79f87f9c52c21d69c87c19f8e2b140a9119.zip
external_webkit-1edef79f87f9c52c21d69c87c19f8e2b140a9119.tar.gz
external_webkit-1edef79f87f9c52c21d69c87c19f8e2b140a9119.tar.bz2
Merge commit 'goog/master-webkit-merge' into webkit-merge-44544
Diffstat (limited to 'WebCore/html')
-rw-r--r--WebCore/html/CanvasPixelArray.idl2
-rw-r--r--WebCore/html/CanvasRenderingContext2D.cpp10
-rw-r--r--WebCore/html/CanvasStyle.cpp2
-rw-r--r--WebCore/html/CollectionCache.cpp88
-rw-r--r--WebCore/html/CollectionCache.h64
-rw-r--r--WebCore/html/CollectionType.h67
-rw-r--r--WebCore/html/HTMLAnchorElement.cpp17
-rw-r--r--WebCore/html/HTMLAnchorElement.idl4
-rw-r--r--WebCore/html/HTMLAppletElement.cpp3
-rw-r--r--WebCore/html/HTMLAppletElement.idl4
-rw-r--r--WebCore/html/HTMLAreaElement.cpp1
-rw-r--r--WebCore/html/HTMLAreaElement.idl2
-rw-r--r--WebCore/html/HTMLAttributeNames.in4
-rw-r--r--WebCore/html/HTMLBRElement.cpp2
-rw-r--r--WebCore/html/HTMLBaseElement.cpp1
-rw-r--r--WebCore/html/HTMLBaseFontElement.idl2
-rw-r--r--WebCore/html/HTMLBodyElement.cpp65
-rw-r--r--WebCore/html/HTMLBodyElement.h15
-rw-r--r--WebCore/html/HTMLBodyElement.idl6
-rw-r--r--WebCore/html/HTMLButtonElement.cpp8
-rw-r--r--WebCore/html/HTMLButtonElement.h2
-rw-r--r--WebCore/html/HTMLCanvasElement.cpp9
-rw-r--r--WebCore/html/HTMLCanvasElement.h5
-rw-r--r--WebCore/html/HTMLCanvasElement.idl2
-rw-r--r--WebCore/html/HTMLCollection.cpp74
-rw-r--r--WebCore/html/HTMLCollection.h90
-rw-r--r--WebCore/html/HTMLCollection.idl3
-rw-r--r--WebCore/html/HTMLDivElement.cpp2
-rw-r--r--WebCore/html/HTMLDocument.idl2
-rw-r--r--WebCore/html/HTMLElement.cpp99
-rw-r--r--WebCore/html/HTMLElement.idl4
-rw-r--r--WebCore/html/HTMLElementsAllInOne.cpp101
-rw-r--r--WebCore/html/HTMLEmbedElement.cpp12
-rw-r--r--WebCore/html/HTMLEmbedElement.idl10
-rw-r--r--WebCore/html/HTMLFieldSetElement.cpp2
-rw-r--r--WebCore/html/HTMLFieldSetElement.h2
-rw-r--r--WebCore/html/HTMLFontElement.cpp1
-rw-r--r--WebCore/html/HTMLFormCollection.cpp7
-rw-r--r--WebCore/html/HTMLFormCollection.h2
-rw-r--r--WebCore/html/HTMLFormControlElement.cpp25
-rw-r--r--WebCore/html/HTMLFormControlElement.h30
-rw-r--r--WebCore/html/HTMLFormElement.cpp159
-rw-r--r--WebCore/html/HTMLFormElement.h25
-rw-r--r--WebCore/html/HTMLFrameElement.cpp5
-rw-r--r--WebCore/html/HTMLFrameElement.h5
-rw-r--r--WebCore/html/HTMLFrameElement.idl6
-rw-r--r--WebCore/html/HTMLFrameElementBase.cpp10
-rw-r--r--WebCore/html/HTMLFrameElementBase.h2
-rw-r--r--WebCore/html/HTMLFrameOwnerElement.cpp3
-rw-r--r--WebCore/html/HTMLFrameOwnerElement.h5
-rw-r--r--WebCore/html/HTMLFrameSetElement.cpp17
-rw-r--r--WebCore/html/HTMLHRElement.cpp2
-rw-r--r--WebCore/html/HTMLHtmlElement.cpp4
-rw-r--r--WebCore/html/HTMLIFrameElement.cpp5
-rw-r--r--WebCore/html/HTMLIFrameElement.h2
-rw-r--r--WebCore/html/HTMLIFrameElement.idl6
-rw-r--r--WebCore/html/HTMLImageElement.cpp6
-rw-r--r--WebCore/html/HTMLImageElement.idl2
-rw-r--r--WebCore/html/HTMLImageLoader.cpp15
-rw-r--r--WebCore/html/HTMLInputElement.cpp164
-rw-r--r--WebCore/html/HTMLInputElement.h31
-rw-r--r--WebCore/html/HTMLInputElement.idl5
-rw-r--r--WebCore/html/HTMLIsIndexElement.cpp4
-rw-r--r--WebCore/html/HTMLKeygenElement.cpp3
-rw-r--r--WebCore/html/HTMLKeygenElement.h2
-rw-r--r--WebCore/html/HTMLLIElement.cpp1
-rw-r--r--WebCore/html/HTMLLegendElement.cpp2
-rw-r--r--WebCore/html/HTMLLegendElement.h2
-rw-r--r--WebCore/html/HTMLLinkElement.cpp49
-rw-r--r--WebCore/html/HTMLLinkElement.idl4
-rw-r--r--WebCore/html/HTMLMapElement.cpp6
-rw-r--r--WebCore/html/HTMLMarqueeElement.cpp20
-rw-r--r--WebCore/html/HTMLMarqueeElement.h8
-rw-r--r--WebCore/html/HTMLMediaElement.cpp286
-rw-r--r--WebCore/html/HTMLMediaElement.h23
-rw-r--r--WebCore/html/HTMLMediaElement.idl2
-rw-r--r--WebCore/html/HTMLMetaElement.cpp2
-rw-r--r--WebCore/html/HTMLNameCollection.cpp2
-rw-r--r--WebCore/html/HTMLNameCollection.h4
-rw-r--r--WebCore/html/HTMLNoScriptElement.cpp85
-rw-r--r--WebCore/html/HTMLNoScriptElement.h46
-rw-r--r--WebCore/html/HTMLOListElement.cpp2
-rw-r--r--WebCore/html/HTMLObjectElement.cpp11
-rw-r--r--WebCore/html/HTMLObjectElement.idl8
-rw-r--r--WebCore/html/HTMLOptGroupElement.cpp2
-rw-r--r--WebCore/html/HTMLOptGroupElement.h2
-rw-r--r--WebCore/html/HTMLOptionElement.cpp33
-rw-r--r--WebCore/html/HTMLOptionElement.h4
-rw-r--r--WebCore/html/HTMLOptionElement.idl2
-rw-r--r--WebCore/html/HTMLOptionsCollection.idl2
-rw-r--r--WebCore/html/HTMLParagraphElement.cpp2
-rw-r--r--WebCore/html/HTMLParamElement.cpp1
-rw-r--r--WebCore/html/HTMLParser.cpp86
-rw-r--r--WebCore/html/HTMLParser.h14
-rw-r--r--WebCore/html/HTMLParserQuirks.h49
-rw-r--r--WebCore/html/HTMLPlugInElement.cpp4
-rw-r--r--WebCore/html/HTMLPreElement.cpp2
-rw-r--r--WebCore/html/HTMLScriptElement.cpp13
-rw-r--r--WebCore/html/HTMLScriptElement.h5
-rw-r--r--WebCore/html/HTMLSelectElement.cpp836
-rw-r--r--WebCore/html/HTMLSelectElement.h168
-rw-r--r--WebCore/html/HTMLSelectElement.idl4
-rw-r--r--WebCore/html/HTMLSourceElement.cpp20
-rw-r--r--WebCore/html/HTMLSourceElement.h9
-rw-r--r--WebCore/html/HTMLStyleElement.cpp2
-rw-r--r--WebCore/html/HTMLStyleElement.idl2
-rw-r--r--WebCore/html/HTMLTableCaptionElement.cpp2
-rw-r--r--WebCore/html/HTMLTableCellElement.cpp2
-rw-r--r--WebCore/html/HTMLTableColElement.cpp4
-rw-r--r--WebCore/html/HTMLTableElement.cpp9
-rw-r--r--WebCore/html/HTMLTablePartElement.cpp2
-rw-r--r--WebCore/html/HTMLTableRowElement.cpp2
-rw-r--r--WebCore/html/HTMLTableRowsCollection.cpp2
-rw-r--r--WebCore/html/HTMLTableSectionElement.cpp2
-rw-r--r--WebCore/html/HTMLTagNames.in20
-rw-r--r--WebCore/html/HTMLTextAreaElement.cpp30
-rw-r--r--WebCore/html/HTMLTextAreaElement.h10
-rw-r--r--WebCore/html/HTMLTokenizer.cpp42
-rw-r--r--WebCore/html/HTMLUListElement.cpp2
-rw-r--r--WebCore/html/HTMLVideoElement.cpp1
-rw-r--r--WebCore/html/HTMLViewSourceDocument.cpp20
-rw-r--r--WebCore/html/ImageData.idl2
-rw-r--r--WebCore/html/MediaError.h2
-rw-r--r--WebCore/html/MediaError.idl2
-rw-r--r--WebCore/html/PreloadScanner.cpp7
-rw-r--r--WebCore/html/TimeRanges.cpp56
-rw-r--r--WebCore/html/TimeRanges.h40
127 files changed, 1814 insertions, 1609 deletions
diff --git a/WebCore/html/CanvasPixelArray.idl b/WebCore/html/CanvasPixelArray.idl
index 9b333e4..c815788 100644
--- a/WebCore/html/CanvasPixelArray.idl
+++ b/WebCore/html/CanvasPixelArray.idl
@@ -27,7 +27,7 @@
*/
module html {
-#if !defined(LANGUAGE_JAVASCRIPT) || defined(V8_BINDING)
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT || defined(V8_BINDING) && V8_BINDING
interface [
CustomHeader,
HasCustomIndexGetter,
diff --git a/WebCore/html/CanvasRenderingContext2D.cpp b/WebCore/html/CanvasRenderingContext2D.cpp
index 82680bd..f2541ed 100644
--- a/WebCore/html/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/CanvasRenderingContext2D.cpp
@@ -36,6 +36,7 @@
#include "CanvasGradient.h"
#include "CanvasPattern.h"
#include "CanvasStyle.h"
+#include "CSSMutableStyleDeclaration.h"
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "Document.h"
@@ -49,7 +50,6 @@
#include "ImageBuffer.h"
#include "ImageData.h"
#include "KURL.h"
-#include "NotImplemented.h"
#include "Page.h"
#include "RenderHTMLCanvas.h"
#include "SecurityOrigin.h"
@@ -60,6 +60,7 @@
#include <wtf/ByteArray.h>
#include <wtf/MathExtras.h>
+#include <wtf/OwnPtr.h>
using namespace std;
@@ -95,6 +96,9 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas)
: m_canvas(canvas)
, m_stateStack(1)
{
+ // Make sure that even if the drawingContext() has a different default
+ // thickness, it is in sync with the canvas thickness.
+ setLineWidth(lineWidth());
}
void CanvasRenderingContext2D::ref()
@@ -1442,8 +1446,8 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
// FIXME: The rect is not big enough for miters on stroked text.
IntRect maskRect = enclosingIntRect(textRect);
- auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false);
-
+ OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false);
+
GraphicsContext* maskImageContext = maskImage->context();
if (fill)
diff --git a/WebCore/html/CanvasStyle.cpp b/WebCore/html/CanvasStyle.cpp
index 0aaaab2..37308ad 100644
--- a/WebCore/html/CanvasStyle.cpp
+++ b/WebCore/html/CanvasStyle.cpp
@@ -44,8 +44,6 @@
#include <QBrush>
#include <QPen>
#include <QColor>
-#elif PLATFORM(CAIRO)
-#include "NotImplemented.h"
#endif
namespace WebCore {
diff --git a/WebCore/html/CollectionCache.cpp b/WebCore/html/CollectionCache.cpp
new file mode 100644
index 0000000..feecd96
--- /dev/null
+++ b/WebCore/html/CollectionCache.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 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.
+ *
+ */
+
+#include "config.h"
+#include "CollectionCache.h"
+
+namespace WebCore {
+
+CollectionCache::CollectionCache()
+ : version(0)
+{
+ reset();
+}
+
+inline void CollectionCache::copyCacheMap(NodeCacheMap& dest, const NodeCacheMap& src)
+{
+ ASSERT(dest.isEmpty());
+ NodeCacheMap::const_iterator end = src.end();
+ for (NodeCacheMap::const_iterator it = src.begin(); it != end; ++it)
+ dest.add(it->first, new Vector<Element*>(*it->second));
+}
+
+CollectionCache::CollectionCache(const CollectionCache& other)
+ : version(other.version)
+ , current(other.current)
+ , position(other.position)
+ , length(other.length)
+ , elementsArrayPosition(other.elementsArrayPosition)
+ , hasLength(other.hasLength)
+ , hasNameCache(other.hasNameCache)
+{
+ copyCacheMap(idCache, other.idCache);
+ copyCacheMap(nameCache, other.nameCache);
+}
+
+void CollectionCache::swap(CollectionCache& other)
+{
+ std::swap(version, other.version);
+ std::swap(current, other.current);
+ std::swap(position, other.position);
+ std::swap(length, other.length);
+ std::swap(elementsArrayPosition, other.elementsArrayPosition);
+
+ idCache.swap(other.idCache);
+ nameCache.swap(other.nameCache);
+
+ std::swap(hasLength, other.hasLength);
+ std::swap(hasNameCache, other.hasNameCache);
+}
+
+CollectionCache::~CollectionCache()
+{
+ deleteAllValues(idCache);
+ deleteAllValues(nameCache);
+}
+
+void CollectionCache::reset()
+{
+ current = 0;
+ position = 0;
+ length = 0;
+ hasLength = false;
+ elementsArrayPosition = 0;
+ deleteAllValues(idCache);
+ idCache.clear();
+ deleteAllValues(nameCache);
+ nameCache.clear();
+ hasNameCache = false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/CollectionCache.h b/WebCore/html/CollectionCache.h
new file mode 100644
index 0000000..7cdcdd5
--- /dev/null
+++ b/WebCore/html/CollectionCache.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 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 CollectionCache_h
+#define CollectionCache_h
+
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AtomicStringImpl;
+class Element;
+
+struct CollectionCache {
+ CollectionCache();
+ CollectionCache(const CollectionCache&);
+ CollectionCache& operator=(const CollectionCache& other)
+ {
+ CollectionCache tmp(other);
+ swap(tmp);
+ return *this;
+ }
+ ~CollectionCache();
+
+ void reset();
+ void swap(CollectionCache&);
+
+ typedef HashMap<AtomicStringImpl*, Vector<Element*>*> NodeCacheMap;
+
+ unsigned version;
+ Element* current;
+ unsigned position;
+ unsigned length;
+ int elementsArrayPosition;
+ NodeCacheMap idCache;
+ NodeCacheMap nameCache;
+ bool hasLength;
+ bool hasNameCache;
+
+private:
+ static void copyCacheMap(NodeCacheMap&, const NodeCacheMap&);
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/html/CollectionType.h b/WebCore/html/CollectionType.h
new file mode 100644
index 0000000..e5973a3
--- /dev/null
+++ b/WebCore/html/CollectionType.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 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 CollectionType_h
+#define CollectionType_h
+
+namespace WebCore {
+
+enum CollectionType {
+ // unnamed collection types cached in the document
+
+ DocImages, // all <img> elements in the document
+ DocApplets, // all <object> and <applet> elements
+ DocEmbeds, // all <embed> elements
+ DocObjects, // all <object> elements
+ DocForms, // all <form> elements
+ DocLinks, // all <a> _and_ <area> elements with a value for href
+ DocAnchors, // all <a> elements with a value for name
+ DocScripts, // all <script> elements
+
+ DocAll, // "all" elements (IE)
+ NodeChildren, // first-level children (IE)
+
+ // named collection types cached in the document
+
+ WindowNamedItems,
+ DocumentNamedItems,
+
+ // types not cached in the document; these are types that can't be used on a document
+
+ TableTBodies, // all <tbody> elements in this table
+ TSectionRows, // all row elements in this table section
+ TRCells, // all cells in this row
+ SelectOptions,
+ MapAreas,
+
+ OtherCollection
+};
+
+static const CollectionType FirstUnnamedDocumentCachedType = DocImages;
+static const unsigned NumUnnamedDocumentCachedTypes = NodeChildren - DocImages + 1;
+
+static const CollectionType FirstNamedDocumentCachedType = WindowNamedItems;
+static const unsigned NumNamedDocumentCachedTypes = DocumentNamedItems - WindowNamedItems + 1;
+
+} // namespace
+
+#endif
diff --git a/WebCore/html/HTMLAnchorElement.cpp b/WebCore/html/HTMLAnchorElement.cpp
index c6b2a95..354f9f0 100644
--- a/WebCore/html/HTMLAnchorElement.cpp
+++ b/WebCore/html/HTMLAnchorElement.cpp
@@ -36,6 +36,7 @@
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "KeyboardEvent.h"
+#include "MappedAttribute.h"
#include "MouseEvent.h"
#include "MutationEvent.h"
#include "Page.h"
@@ -280,11 +281,17 @@ void HTMLAnchorElement::parseMappedAttribute(MappedAttribute *attr)
bool wasLink = isLink();
setIsLink(!attr->isNull());
if (wasLink != isLink())
- setChanged();
- if (isLink() && document()->isDNSPrefetchEnabled()) {
- String value = attr->value();
- if (protocolIs(value, "http") || protocolIs(value, "https") || value.startsWith("//"))
- prefetchDNS(document()->completeURL(value).host());
+ setNeedsStyleRecalc();
+ if (isLink()) {
+ String parsedURL = parseURL(attr->value());
+ if (document()->isDNSPrefetchEnabled()) {
+ if (protocolIs(parsedURL, "http") || protocolIs(parsedURL, "https") || parsedURL.startsWith("//"))
+ prefetchDNS(document()->completeURL(parsedURL).host());
+ }
+ if (document()->page() && !document()->page()->javaScriptURLsAreAllowed() && protocolIsJavaScript(parsedURL)) {
+ setIsLink(false);
+ attr->setValue(nullAtom);
+ }
}
} else if (attr->name() == nameAttr ||
attr->name() == titleAttr ||
diff --git a/WebCore/html/HTMLAnchorElement.idl b/WebCore/html/HTMLAnchorElement.idl
index f3a15ee..c2dda3d 100644
--- a/WebCore/html/HTMLAnchorElement.idl
+++ b/WebCore/html/HTMLAnchorElement.idl
@@ -47,11 +47,11 @@ module html {
readonly attribute DOMString search;
readonly attribute DOMString text;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
[DontEnum] DOMString toString();
#endif
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// Objective-C extension:
readonly attribute URL absoluteLinkURL;
#endif
diff --git a/WebCore/html/HTMLAppletElement.cpp b/WebCore/html/HTMLAppletElement.cpp
index de8e1cf..13dd911 100644
--- a/WebCore/html/HTMLAppletElement.cpp
+++ b/WebCore/html/HTMLAppletElement.cpp
@@ -27,6 +27,7 @@
#include "Frame.h"
#include "HTMLDocument.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderApplet.h"
#include "RenderInline.h"
#include "Settings.h"
@@ -119,8 +120,6 @@ RenderObject* HTMLAppletElement::createRenderer(RenderArena*, RenderStyle* style
const AtomicString& codeBase = getAttribute(codebaseAttr);
if (!codeBase.isNull())
args.set("codeBase", codeBase);
- else
- args.set("codeBase", document()->baseURL().baseAsString());
const AtomicString& name = getAttribute(document()->isHTMLDocument() ? nameAttr : idAttr);
if (!name.isNull())
diff --git a/WebCore/html/HTMLAppletElement.idl b/WebCore/html/HTMLAppletElement.idl
index 794f000..95f03a7 100644
--- a/WebCore/html/HTMLAppletElement.idl
+++ b/WebCore/html/HTMLAppletElement.idl
@@ -35,14 +35,14 @@ module html {
attribute [ConvertNullToNullString] DOMString code;
attribute [ConvertNullToNullString] DOMString codeBase;
attribute [ConvertNullToNullString] DOMString height;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
attribute [ConvertNullToNullString] DOMString hspace;
#else
attribute [ConvertFromString] long hspace;
#endif
attribute [ConvertNullToNullString] DOMString name;
attribute [ConvertNullToNullString] DOMString object;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
attribute [ConvertNullToNullString] DOMString vspace;
#else
attribute [ConvertFromString] long vspace;
diff --git a/WebCore/html/HTMLAreaElement.cpp b/WebCore/html/HTMLAreaElement.cpp
index 9db50b7..2f7c1a5 100644
--- a/WebCore/html/HTMLAreaElement.cpp
+++ b/WebCore/html/HTMLAreaElement.cpp
@@ -27,6 +27,7 @@
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "Length.h"
+#include "MappedAttribute.h"
#include "Path.h"
#include "RenderObject.h"
diff --git a/WebCore/html/HTMLAreaElement.idl b/WebCore/html/HTMLAreaElement.idl
index 39cc719..d80ebed 100644
--- a/WebCore/html/HTMLAreaElement.idl
+++ b/WebCore/html/HTMLAreaElement.idl
@@ -42,7 +42,7 @@ module html {
readonly attribute DOMString protocol;
readonly attribute DOMString search;
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// Objective-C extension:
readonly attribute URL absoluteLinkURL;
#endif
diff --git a/WebCore/html/HTMLAttributeNames.in b/WebCore/html/HTMLAttributeNames.in
index 5cb556e..7caf0e5 100644
--- a/WebCore/html/HTMLAttributeNames.in
+++ b/WebCore/html/HTMLAttributeNames.in
@@ -22,6 +22,7 @@ aria-pressed
aria-valuemax
aria-valuemin
aria-valuenow
+autobuffer
autocomplete
autofocus
autoplay
@@ -140,6 +141,8 @@ onmouseout
onmouseover
onmouseup
onmousewheel
+ononline
+onoffline
onpaste
onreset
onresize
@@ -183,6 +186,7 @@ selected
shape
size
span
+spellcheck
src
standby
start
diff --git a/WebCore/html/HTMLBRElement.cpp b/WebCore/html/HTMLBRElement.cpp
index e98f8d1..6f86e6a 100644
--- a/WebCore/html/HTMLBRElement.cpp
+++ b/WebCore/html/HTMLBRElement.cpp
@@ -19,11 +19,13 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLBRElement.h"
#include "CSSPropertyNames.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderBR.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLBaseElement.cpp b/WebCore/html/HTMLBaseElement.cpp
index dd4f7b3..a278908 100644
--- a/WebCore/html/HTMLBaseElement.cpp
+++ b/WebCore/html/HTMLBaseElement.cpp
@@ -29,6 +29,7 @@
#include "FrameLoader.h"
#include "HTMLNames.h"
#include "KURL.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLBaseFontElement.idl b/WebCore/html/HTMLBaseFontElement.idl
index a94f3ab..f09c9d7 100644
--- a/WebCore/html/HTMLBaseFontElement.idl
+++ b/WebCore/html/HTMLBaseFontElement.idl
@@ -26,7 +26,7 @@ module html {
] HTMLBaseFontElement : HTMLElement {
attribute [ConvertNullToNullString] DOMString color;
attribute [ConvertNullToNullString] DOMString face;
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
attribute [ConvertToString] DOMString size; // this changed to a long, but our existing API is a string
#else
attribute long size;
diff --git a/WebCore/html/HTMLBodyElement.cpp b/WebCore/html/HTMLBodyElement.cpp
index a23f9be..9828dab 100644
--- a/WebCore/html/HTMLBodyElement.cpp
+++ b/WebCore/html/HTMLBodyElement.cpp
@@ -32,9 +32,12 @@
#include "CSSValueKeywords.h"
#include "Document.h"
#include "EventNames.h"
+#include "Frame.h"
#include "FrameView.h"
#include "HTMLFrameElementBase.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
+#include "ScriptEventListener.h"
namespace WebCore {
@@ -131,25 +134,26 @@ void HTMLBodyElement::parseMappedAttribute(MappedAttribute *attr)
if (attached())
document()->recalcStyle(Force);
} else if (attr->name() == onloadAttr)
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), attr));
else if (attr->name() == onbeforeunloadAttr)
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().beforeunloadEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), attr));
else if (attr->name() == onunloadAttr)
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().unloadEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), attr));
else if (attr->name() == onblurAttr)
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), attr));
else if (attr->name() == onfocusAttr)
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), attr));
else if (attr->name() == onresizeAttr)
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().resizeEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), attr));
else if (attr->name() == onscrollAttr)
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().scrollEvent, attr);
- else if (attr->name() == onstorageAttr) {
- // The HTML5 spec currently specifies that storage events are fired only at the body element of
- // an HTMLDocument, which is why the onstorage attribute differs from the ones before it.
- // The spec might change on this, and then so should we!
- setInlineEventListenerForTypeAndAttribute(eventNames().storageEvent, attr);
- } else
+ document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onstorageAttr)
+ document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == ononlineAttr)
+ document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), attr));
+ else if (attr->name() == onofflineAttr)
+ document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), attr));
+ else
HTMLElement::parseMappedAttribute(attr);
}
@@ -240,13 +244,24 @@ void HTMLBodyElement::setVLink(const String& value)
setAttribute(vlinkAttr, value);
}
+static int adjustForZoom(int value, FrameView* frameView)
+{
+ float zoomFactor = frameView->frame()->zoomFactor();
+ if (zoomFactor == 1)
+ return value;
+ // Needed because of truncation (rather than rounding) when scaling up.
+ if (zoomFactor > 1)
+ value++;
+ return static_cast<int>(value / zoomFactor);
+}
+
int HTMLBodyElement::scrollLeft() const
{
// Update the document's layout.
Document* doc = document();
doc->updateLayoutIgnorePendingStylesheets();
FrameView* view = doc->view();
- return view ? view->scrollX() : 0;
+ return view ? adjustForZoom(view->scrollX(), view) : 0;
}
void HTMLBodyElement::setScrollLeft(int scrollLeft)
@@ -255,7 +270,7 @@ void HTMLBodyElement::setScrollLeft(int scrollLeft)
if (sview) {
// Update the document's layout
document()->updateLayoutIgnorePendingStylesheets();
- sview->setScrollPosition(IntPoint(scrollLeft, sview->scrollY()));
+ sview->setScrollPosition(IntPoint(static_cast<int>(scrollLeft * sview->frame()->zoomFactor()), sview->scrollY()));
}
}
@@ -265,7 +280,7 @@ int HTMLBodyElement::scrollTop() const
Document* doc = document();
doc->updateLayoutIgnorePendingStylesheets();
FrameView* view = doc->view();
- return view ? view->scrollY() : 0;
+ return view ? adjustForZoom(view->scrollY(), view) : 0;
}
void HTMLBodyElement::setScrollTop(int scrollTop)
@@ -274,7 +289,7 @@ void HTMLBodyElement::setScrollTop(int scrollTop)
if (sview) {
// Update the document's layout
document()->updateLayoutIgnorePendingStylesheets();
- sview->setScrollPosition(IntPoint(sview->scrollX(), scrollTop));
+ sview->setScrollPosition(IntPoint(sview->scrollX(), static_cast<int>(scrollTop * sview->frame()->zoomFactor())));
}
}
@@ -284,7 +299,7 @@ int HTMLBodyElement::scrollHeight() const
Document* doc = document();
doc->updateLayoutIgnorePendingStylesheets();
FrameView* view = doc->view();
- return view ? view->contentsHeight() : 0;
+ return view ? adjustForZoom(view->contentsHeight(), view) : 0;
}
int HTMLBodyElement::scrollWidth() const
@@ -293,7 +308,7 @@ int HTMLBodyElement::scrollWidth() const
Document* doc = document();
doc->updateLayoutIgnorePendingStylesheets();
FrameView* view = doc->view();
- return view ? view->contentsWidth() : 0;
+ return view ? adjustForZoom(view->contentsWidth(), view) : 0;
}
void HTMLBodyElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
@@ -303,4 +318,16 @@ void HTMLBodyElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
addSubresourceURL(urls, document()->completeURL(background()));
}
+void HTMLBodyElement::didMoveToNewOwnerDocument()
+{
+ // When moving body elements between documents, we should have to reset the parent sheet for any
+ // link style declarations. If we don't we might crash later.
+ // In practice I can't reproduce this theoretical problem.
+ // webarchive/adopt-attribute-styled-body-webarchive.html tries to make sure this crash won't surface.
+ if (m_linkDecl)
+ m_linkDecl->setParent(document()->elementSheet());
+
+ HTMLElement::didMoveToNewOwnerDocument();
+}
+
}
diff --git a/WebCore/html/HTMLBodyElement.h b/WebCore/html/HTMLBodyElement.h
index a72e668..8e434be 100644
--- a/WebCore/html/HTMLBodyElement.h
+++ b/WebCore/html/HTMLBodyElement.h
@@ -61,19 +61,22 @@ public:
String vLink() const;
void setVLink(const String&);
- int scrollLeft() const;
- void setScrollLeft(int scrollLeft);
+ virtual int scrollLeft() const;
+ virtual void setScrollLeft(int scrollLeft);
- int scrollTop() const;
- void setScrollTop(int scrollTop);
+ virtual int scrollTop() const;
+ virtual void setScrollTop(int scrollTop);
- int scrollHeight() const;
- int scrollWidth() const;
+ virtual int scrollHeight() const;
+ virtual int scrollWidth() const;
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
protected:
RefPtr<CSSMutableStyleDeclaration> m_linkDecl;
+
+private:
+ virtual void didMoveToNewOwnerDocument();
};
} //namespace
diff --git a/WebCore/html/HTMLBodyElement.idl b/WebCore/html/HTMLBodyElement.idl
index 41d20d6..c639183 100644
--- a/WebCore/html/HTMLBodyElement.idl
+++ b/WebCore/html/HTMLBodyElement.idl
@@ -31,12 +31,6 @@ module html {
attribute [ConvertNullToNullString] DOMString link;
attribute [ConvertNullToNullString] DOMString text;
attribute [ConvertNullToNullString] DOMString vLink;
-
- // IE Extensions
- attribute long scrollLeft;
- attribute long scrollTop;
- readonly attribute long scrollWidth;
- readonly attribute long scrollHeight;
};
}
diff --git a/WebCore/html/HTMLButtonElement.cpp b/WebCore/html/HTMLButtonElement.cpp
index 571f30c..3987859 100644
--- a/WebCore/html/HTMLButtonElement.cpp
+++ b/WebCore/html/HTMLButtonElement.cpp
@@ -30,7 +30,9 @@
#include "FormDataList.h"
#include "HTMLFormElement.h"
#include "HTMLNames.h"
+#include "ScriptEventListener.h"
#include "KeyboardEvent.h"
+#include "MappedAttribute.h"
#include "RenderButton.h"
#include <wtf/StdLibExtras.h>
@@ -55,7 +57,7 @@ RenderObject* HTMLButtonElement::createRenderer(RenderArena* arena, RenderStyle*
return new (arena) RenderButton(this);
}
-const AtomicString& HTMLButtonElement::type() const
+const AtomicString& HTMLButtonElement::formControlType() const
{
switch (m_type) {
case SUBMIT: {
@@ -89,9 +91,9 @@ void HTMLButtonElement::parseMappedAttribute(MappedAttribute* attr)
// Don't map 'align' attribute. This matches what Firefox and IE do, but not Opera.
// See http://bugs.webkit.org/show_bug.cgi?id=12071
} else if (attr->name() == onfocusAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
+ setAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onblurAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
+ setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr));
} else
HTMLFormControlElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLButtonElement.h b/WebCore/html/HTMLButtonElement.h
index c8f51cb..b1d744c 100644
--- a/WebCore/html/HTMLButtonElement.h
+++ b/WebCore/html/HTMLButtonElement.h
@@ -33,7 +33,7 @@ public:
HTMLButtonElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
virtual ~HTMLButtonElement();
- virtual const AtomicString& type() const;
+ virtual const AtomicString& formControlType() const;
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp
index 1cd2796..9e635e7 100644
--- a/WebCore/html/HTMLCanvasElement.cpp
+++ b/WebCore/html/HTMLCanvasElement.cpp
@@ -39,6 +39,7 @@
#include "HTMLNames.h"
#include "ImageBuffer.h"
#include "MIMETypeRegistry.h"
+#include "MappedAttribute.h"
#include "Page.h"
#include "RenderHTMLCanvas.h"
#include "Settings.h"
@@ -71,6 +72,8 @@ HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document* doc
HTMLCanvasElement::~HTMLCanvasElement()
{
+ if (m_observer)
+ m_observer->canvasDestroyed(this);
}
#if ENABLE(DASHBOARD_SUPPORT)
@@ -256,7 +259,11 @@ void HTMLCanvasElement::createImageBuffer() const
if (!size.width() || !size.height())
return;
- m_imageBuffer.set(ImageBuffer::create(size, false).release());
+ m_imageBuffer = ImageBuffer::create(size, false);
+ // The convertLogicalToDevice MaxCanvasArea check should prevent common cases
+ // where ImageBuffer::create() returns NULL, however we could still be low on memory.
+ if (!m_imageBuffer)
+ return;
m_imageBuffer->context()->scale(FloatSize(size.width() / unscaledSize.width(), size.height() / unscaledSize.height()));
m_imageBuffer->context()->setShadowsIgnoreTransforms(true);
}
diff --git a/WebCore/html/HTMLCanvasElement.h b/WebCore/html/HTMLCanvasElement.h
index 12b3cb2..bba1f2d 100644
--- a/WebCore/html/HTMLCanvasElement.h
+++ b/WebCore/html/HTMLCanvasElement.h
@@ -49,8 +49,9 @@ class CanvasObserver {
public:
virtual ~CanvasObserver() {};
- virtual void canvasChanged(HTMLCanvasElement* element, const FloatRect& changedRect) = 0;
- virtual void canvasResized(HTMLCanvasElement* element) = 0;
+ virtual void canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect) = 0;
+ virtual void canvasResized(HTMLCanvasElement*) = 0;
+ virtual void canvasDestroyed(HTMLCanvasElement*) = 0;
};
class HTMLCanvasElement : public HTMLElement {
diff --git a/WebCore/html/HTMLCanvasElement.idl b/WebCore/html/HTMLCanvasElement.idl
index bf69ac0..13fc623 100644
--- a/WebCore/html/HTMLCanvasElement.idl
+++ b/WebCore/html/HTMLCanvasElement.idl
@@ -37,7 +37,7 @@ module html {
DOMString toDataURL(in [ConvertUndefinedOrNullToNullString] DOMString type)
raises(DOMException);
-#if !defined(LANGUAGE_OBJECTIVE_C)
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
[V8Custom] DOMObject getContext(in DOMString contextId);
#endif
diff --git a/WebCore/html/HTMLCollection.cpp b/WebCore/html/HTMLCollection.cpp
index fd588dd..de4c424 100644
--- a/WebCore/html/HTMLCollection.cpp
+++ b/WebCore/html/HTMLCollection.cpp
@@ -35,7 +35,7 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type)
+HTMLCollection::HTMLCollection(PassRefPtr<Node> base, CollectionType type)
: m_idsDone(false)
, m_base(base)
, m_type(type)
@@ -44,7 +44,7 @@ HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type)
{
}
-HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type, CollectionInfo* info)
+HTMLCollection::HTMLCollection(PassRefPtr<Node> base, CollectionType type, CollectionCache* info)
: m_idsDone(false)
, m_base(base)
, m_type(type)
@@ -53,7 +53,7 @@ HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type, CollectionInfo*
{
}
-PassRefPtr<HTMLCollection> HTMLCollection::create(PassRefPtr<Node> base, Type type)
+PassRefPtr<HTMLCollection> HTMLCollection::create(PassRefPtr<Node> base, CollectionType type)
{
return adoptRef(new HTMLCollection(base, type));
}
@@ -64,74 +64,12 @@ HTMLCollection::~HTMLCollection()
delete m_info;
}
-HTMLCollection::CollectionInfo::CollectionInfo()
- : version(0)
-{
- reset();
-}
-
-inline void HTMLCollection::CollectionInfo::copyCacheMap(NodeCacheMap& dest, const NodeCacheMap& src)
-{
- ASSERT(dest.isEmpty());
- NodeCacheMap::const_iterator end = src.end();
- for (NodeCacheMap::const_iterator it = src.begin(); it != end; ++it)
- dest.add(it->first, new Vector<Element*>(*it->second));
-}
-
-HTMLCollection::CollectionInfo::CollectionInfo(const CollectionInfo& other)
- : version(other.version)
- , current(other.current)
- , position(other.position)
- , length(other.length)
- , elementsArrayPosition(other.elementsArrayPosition)
- , hasLength(other.hasLength)
- , hasNameCache(other.hasNameCache)
-{
- copyCacheMap(idCache, other.idCache);
- copyCacheMap(nameCache, other.nameCache);
-}
-
-void HTMLCollection::CollectionInfo::swap(CollectionInfo& other)
-{
- std::swap(version, other.version);
- std::swap(current, other.current);
- std::swap(position, other.position);
- std::swap(length, other.length);
- std::swap(elementsArrayPosition, other.elementsArrayPosition);
-
- idCache.swap(other.idCache);
- nameCache.swap(other.nameCache);
-
- std::swap(hasLength, other.hasLength);
- std::swap(hasNameCache, other.hasNameCache);
-}
-
-HTMLCollection::CollectionInfo::~CollectionInfo()
-{
- deleteAllValues(idCache);
- deleteAllValues(nameCache);
-}
-
-void HTMLCollection::CollectionInfo::reset()
-{
- current = 0;
- position = 0;
- length = 0;
- hasLength = false;
- elementsArrayPosition = 0;
- deleteAllValues(idCache);
- idCache.clear();
- deleteAllValues(nameCache);
- nameCache.clear();
- hasNameCache = false;
-}
-
void HTMLCollection::resetCollectionInfo() const
{
unsigned docversion = static_cast<HTMLDocument*>(m_base->document())->domTreeVersion();
if (!m_info) {
- m_info = new CollectionInfo;
+ m_info = new CollectionCache;
m_ownsInfo = true;
m_info->version = docversion;
return;
@@ -164,7 +102,7 @@ Element* HTMLCollection::itemAfter(Element* previous) const
case DocScripts:
case DocumentNamedItems:
case MapAreas:
- case Other:
+ case OtherCollection:
case SelectOptions:
case WindowNamedItems:
break;
@@ -245,7 +183,7 @@ Element* HTMLCollection::itemAfter(Element* previous) const
case NodeChildren:
return e;
case DocumentNamedItems:
- case Other:
+ case OtherCollection:
case WindowNamedItems:
ASSERT_NOT_REACHED();
break;
diff --git a/WebCore/html/HTMLCollection.h b/WebCore/html/HTMLCollection.h
index 083ec05..b04bcbc 100644
--- a/WebCore/html/HTMLCollection.h
+++ b/WebCore/html/HTMLCollection.h
@@ -23,6 +23,7 @@
#ifndef HTMLCollection_h
#define HTMLCollection_h
+#include "CollectionType.h"
#include <wtf/RefCounted.h>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
@@ -37,46 +38,11 @@ class Node;
class NodeList;
class String;
+struct CollectionCache;
+
class HTMLCollection : public RefCounted<HTMLCollection> {
public:
- enum Type {
- // unnamed collection types cached in the document
-
- DocImages, // all <img> elements in the document
- DocApplets, // all <object> and <applet> elements
- DocEmbeds, // all <embed> elements
- DocObjects, // all <object> elements
- DocForms, // all <form> elements
- DocLinks, // all <a> _and_ <area> elements with a value for href
- DocAnchors, // all <a> elements with a value for name
- DocScripts, // all <script> elements
-
- DocAll, // "all" elements (IE)
- NodeChildren, // first-level children (IE)
-
- // named collection types cached in the document
-
- WindowNamedItems,
- DocumentNamedItems,
-
- // types not cached in the document; these are types that can't be used on a document
-
- TableTBodies, // all <tbody> elements in this table
- TSectionRows, // all row elements in this table section
- TRCells, // all cells in this row
- SelectOptions,
- MapAreas,
-
- Other
- };
-
- static const Type FirstUnnamedDocumentCachedType = DocImages;
- static const unsigned NumUnnamedDocumentCachedTypes = NodeChildren - DocImages + 1;
-
- static const Type FirstNamedDocumentCachedType = WindowNamedItems;
- static const unsigned NumNamedDocumentCachedTypes = DocumentNamedItems - WindowNamedItems + 1;
-
- static PassRefPtr<HTMLCollection> create(PassRefPtr<Node> base, Type);
+ static PassRefPtr<HTMLCollection> create(PassRefPtr<Node> base, CollectionType);
virtual ~HTMLCollection();
unsigned length() const;
@@ -94,52 +60,18 @@ public:
PassRefPtr<NodeList> tags(const String&);
Node* base() const { return m_base.get(); }
- Type type() const { return m_type; }
-
- // FIXME: This class name is a bad in two ways. First, "info" is much too vague,
- // and doesn't convey the job of this class (caching collection state).
- // Second, since this is a member of HTMLCollection, it doesn't need "collection"
- // in its name.
- struct CollectionInfo {
- CollectionInfo();
- CollectionInfo(const CollectionInfo&);
- CollectionInfo& operator=(const CollectionInfo& other)
- {
- CollectionInfo tmp(other);
- swap(tmp);
- return *this;
- }
- ~CollectionInfo();
-
- void reset();
- void swap(CollectionInfo&);
-
- typedef HashMap<AtomicStringImpl*, Vector<Element*>*> NodeCacheMap;
-
- unsigned version;
- Element* current;
- unsigned position;
- unsigned length;
- int elementsArrayPosition;
- NodeCacheMap idCache;
- NodeCacheMap nameCache;
- bool hasLength;
- bool hasNameCache;
-
- private:
- static void copyCacheMap(NodeCacheMap&, const NodeCacheMap&);
- };
+ CollectionType type() const { return m_type; }
protected:
- HTMLCollection(PassRefPtr<Node> base, Type, CollectionInfo*);
+ HTMLCollection(PassRefPtr<Node> base, CollectionType, CollectionCache*);
- CollectionInfo* info() const { return m_info; }
- virtual void resetCollectionInfo() const;
+ CollectionCache* info() const { return m_info; }
+ void resetCollectionInfo() const;
mutable bool m_idsDone; // for nextNamedItem()
private:
- HTMLCollection(PassRefPtr<Node> base, Type);
+ HTMLCollection(PassRefPtr<Node> base, CollectionType);
virtual Element* itemAfter(Element*) const;
virtual unsigned calcLength() const;
@@ -148,9 +80,9 @@ private:
bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const;
RefPtr<Node> m_base;
- Type m_type;
+ CollectionType m_type;
- mutable CollectionInfo* m_info;
+ mutable CollectionCache* m_info;
mutable bool m_ownsInfo;
};
diff --git a/WebCore/html/HTMLCollection.idl b/WebCore/html/HTMLCollection.idl
index 8290e1a..1ba5ec7 100644
--- a/WebCore/html/HTMLCollection.idl
+++ b/WebCore/html/HTMLCollection.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
*
* This library is free software; you can redistribute it and/or
@@ -26,6 +26,7 @@ module html {
HasNameGetter,
CustomCall,
CustomToJS,
+ Polymorphic,
InterfaceUUID=b0d215ff-6f9c-4d1f-86c3-f200a65a5134,
ImplementationUUID=8e81b17f-7f74-4121-8f2f-a339a7e66447
] HTMLCollection {
diff --git a/WebCore/html/HTMLDivElement.cpp b/WebCore/html/HTMLDivElement.cpp
index 7ffccd7..bd7195e 100644
--- a/WebCore/html/HTMLDivElement.cpp
+++ b/WebCore/html/HTMLDivElement.cpp
@@ -19,12 +19,14 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#include "config.h"
#include "HTMLDivElement.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLDocument.idl b/WebCore/html/HTMLDocument.idl
index 4345195..3dd7a07 100644
--- a/WebCore/html/HTMLDocument.idl
+++ b/WebCore/html/HTMLDocument.idl
@@ -37,7 +37,7 @@ module html {
// Extensions
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
// FIXME: This should eventually be available (if they are wanted) for all languages.
attribute [Custom, Deletable] HTMLCollection all;
#endif
diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp
index 906f847..c50e6ba 100644
--- a/WebCore/html/HTMLElement.cpp
+++ b/WebCore/html/HTMLElement.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * 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
@@ -32,12 +33,15 @@
#include "ExceptionCode.h"
#include "Frame.h"
#include "HTMLBRElement.h"
+#include "HTMLCollection.h"
#include "HTMLDocument.h"
#include "HTMLElementFactory.h"
#include "HTMLFormElement.h"
#include "HTMLNames.h"
-#include "HTMLTokenizer.h" // parseHTMLDocumentFragment
+#include "HTMLTokenizer.h"
+#include "MappedAttribute.h"
#include "RenderWordBreak.h"
+#include "ScriptEventListener.h"
#include "Settings.h"
#include "Text.h"
#include "TextIterator.h"
@@ -65,7 +69,8 @@ String HTMLElement::nodeName() const
{
// FIXME: Would be nice to have an atomicstring lookup based off uppercase chars that does not have to copy
// the string on a hit in the hash.
- if (document()->isHTMLDocument())
+ // FIXME: We should have a way to detect XHTML elements and replace the hasPrefix() check with it.
+ if (document()->isHTMLDocument() && !tagQName().hasPrefix())
return tagQName().localName().string().upper();
return Element::nodeName();
}
@@ -141,84 +146,84 @@ void HTMLElement::parseMappedAttribute(MappedAttribute *attr)
}
// standard events
else if (attr->name() == onclickAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().clickEvent, attr);
+ setAttributeEventListener(eventNames().clickEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == oncontextmenuAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().contextmenuEvent, attr);
+ setAttributeEventListener(eventNames().contextmenuEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ondblclickAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().dblclickEvent, attr);
+ setAttributeEventListener(eventNames().dblclickEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onmousedownAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().mousedownEvent, attr);
+ setAttributeEventListener(eventNames().mousedownEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onmousemoveAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().mousemoveEvent, attr);
+ setAttributeEventListener(eventNames().mousemoveEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onmouseoutAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().mouseoutEvent, attr);
+ setAttributeEventListener(eventNames().mouseoutEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onmouseoverAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().mouseoverEvent, attr);
+ setAttributeEventListener(eventNames().mouseoverEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onmouseupAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().mouseupEvent, attr);
+ setAttributeEventListener(eventNames().mouseupEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onmousewheelAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().mousewheelEvent, attr);
+ setAttributeEventListener(eventNames().mousewheelEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onfocusAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
+ setAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onblurAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
+ setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onkeydownAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().keydownEvent, attr);
+ setAttributeEventListener(eventNames().keydownEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onkeypressAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().keypressEvent, attr);
+ setAttributeEventListener(eventNames().keypressEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onkeyupAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().keyupEvent, attr);
+ setAttributeEventListener(eventNames().keyupEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onscrollAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().scrollEvent, attr);
+ setAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onbeforecutAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().beforecutEvent, attr);
+ setAttributeEventListener(eventNames().beforecutEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == oncutAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().cutEvent, attr);
+ setAttributeEventListener(eventNames().cutEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onbeforecopyAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().beforecopyEvent, attr);
+ setAttributeEventListener(eventNames().beforecopyEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == oncopyAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().copyEvent, attr);
+ setAttributeEventListener(eventNames().copyEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onbeforepasteAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().beforepasteEvent, attr);
+ setAttributeEventListener(eventNames().beforepasteEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onpasteAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().pasteEvent, attr);
+ setAttributeEventListener(eventNames().pasteEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ondragenterAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().dragenterEvent, attr);
+ setAttributeEventListener(eventNames().dragenterEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ondragoverAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().dragoverEvent, attr);
+ setAttributeEventListener(eventNames().dragoverEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ondragleaveAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().dragleaveEvent, attr);
+ setAttributeEventListener(eventNames().dragleaveEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ondropAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().dropEvent, attr);
+ setAttributeEventListener(eventNames().dropEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ondragstartAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().dragstartEvent, attr);
+ setAttributeEventListener(eventNames().dragstartEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ondragAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().dragEvent, attr);
+ setAttributeEventListener(eventNames().dragEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ondragendAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().dragendEvent, attr);
+ setAttributeEventListener(eventNames().dragendEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onselectstartAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().selectstartEvent, attr);
+ setAttributeEventListener(eventNames().selectstartEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onsubmitAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().submitEvent, attr);
+ setAttributeEventListener(eventNames().submitEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onerrorAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().errorEvent, attr);
+ setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onwebkitanimationstartAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationStartEvent, attr);
+ setAttributeEventListener(eventNames().webkitAnimationStartEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onwebkitanimationiterationAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationIterationEvent, attr);
+ setAttributeEventListener(eventNames().webkitAnimationIterationEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onwebkitanimationendAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationEndEvent, attr);
+ setAttributeEventListener(eventNames().webkitAnimationEndEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onwebkittransitionendAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().webkitTransitionEndEvent, attr);
+ setAttributeEventListener(eventNames().webkitTransitionEndEvent, createAttributeEventListener(this, attr));
#if ENABLE(TOUCH_EVENTS) // Android
} else if (attr->name() == ontouchstartAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().touchstartEvent, attr);
+ setAttributeEventListener(eventNames().touchstartEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ontouchendAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().touchendEvent, attr);
+ setAttributeEventListener(eventNames().touchendEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ontouchmoveAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().touchmoveEvent, attr);
+ setAttributeEventListener(eventNames().touchmoveEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ontouchcancelAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().touchcancelEvent, attr);
+ setAttributeEventListener(eventNames().touchcancelEvent, createAttributeEventListener(this, attr));
#endif
}
}
@@ -394,7 +399,7 @@ void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
}
// FIXME: Do we need to be able to detect preserveNewline style even when there's no renderer?
- // FIXME: Can the renderer be out of date here? Do we need to call updateRendering?
+ // FIXME: Can the renderer be out of date here? Do we need to call updateStyleIfNeeded?
// For example, for the contents of textarea elements that are display:none?
RenderObject* r = renderer();
if (r && r->style()->preserveNewline()) {
@@ -611,7 +616,7 @@ bool HTMLElement::isContentEditable() const
// FIXME: this is a terrible thing to do here:
// https://bugs.webkit.org/show_bug.cgi?id=21834
- document()->updateRendering();
+ document()->updateStyleIfNeeded();
if (!renderer()) {
if (parentNode())
@@ -628,7 +633,7 @@ bool HTMLElement::isContentRichlyEditable() const
if (document()->frame() && document()->frame()->isContentEditable())
return true;
- document()->updateRendering();
+ document()->updateStyleIfNeeded();
if (!renderer()) {
if (parentNode())
@@ -642,7 +647,7 @@ bool HTMLElement::isContentRichlyEditable() const
String HTMLElement::contentEditable() const
{
- document()->updateRendering();
+ document()->updateStyleIfNeeded();
if (!renderer())
return "false";
@@ -777,7 +782,7 @@ void HTMLElement::setTabIndex(int value)
PassRefPtr<HTMLCollection> HTMLElement::children()
{
- return HTMLCollection::create(this, HTMLCollection::NodeChildren);
+ return HTMLCollection::create(this, NodeChildren);
}
// DOM Section 1.1.1
@@ -987,11 +992,13 @@ bool HTMLElement::checkDTD(const Node* newChild)
bool HTMLElement::rendererIsNeeded(RenderStyle *style)
{
+#if !ENABLE(XHTMLMP)
if (hasLocalName(noscriptTag)) {
Settings* settings = document()->settings();
if (settings && settings->isJavaScriptEnabled())
return false;
}
+#endif
return StyledElement::rendererIsNeeded(style);
}
diff --git a/WebCore/html/HTMLElement.idl b/WebCore/html/HTMLElement.idl
index 8ce5542..ed21628 100644
--- a/WebCore/html/HTMLElement.idl
+++ b/WebCore/html/HTMLElement.idl
@@ -36,8 +36,6 @@ module html {
attribute [ConvertNullToNullString] DOMString className;
attribute long tabIndex;
- void blur();
- void focus();
// Extensions
attribute [ConvertNullToNullString] DOMString innerHTML
@@ -64,7 +62,7 @@ module html {
attribute [ConvertNullToNullString] DOMString contentEditable;
readonly attribute boolean isContentEditable;
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
readonly attribute DOMString titleDisplayString;
#endif
};
diff --git a/WebCore/html/HTMLElementsAllInOne.cpp b/WebCore/html/HTMLElementsAllInOne.cpp
new file mode 100644
index 0000000..dad548c
--- /dev/null
+++ b/WebCore/html/HTMLElementsAllInOne.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This source file coalesces the HTML elements into a single object file to
+// reduce bloat and allow us to link release builds on 32-bit Windows.
+
+#include "HTMLAnchorElement.cpp"
+#include "HTMLAppletElement.cpp"
+#include "HTMLAreaElement.cpp"
+#include "HTMLAudioElement.cpp"
+#include "HTMLBRElement.cpp"
+#include "HTMLBaseElement.cpp"
+#include "HTMLBaseFontElement.cpp"
+#include "HTMLBlockquoteElement.cpp"
+#include "HTMLBodyElement.cpp"
+#include "HTMLButtonElement.cpp"
+#include "HTMLCanvasElement.cpp"
+#include "HTMLDListElement.cpp"
+#include "HTMLDirectoryElement.cpp"
+#include "HTMLDivElement.cpp"
+#include "HTMLElement.cpp"
+#include "HTMLEmbedElement.cpp"
+#include "HTMLFieldSetElement.cpp"
+#include "HTMLFontElement.cpp"
+#include "HTMLFormControlElement.cpp"
+#include "HTMLFormElement.cpp"
+#include "HTMLFrameElement.cpp"
+#include "HTMLFrameElementBase.cpp"
+#include "HTMLFrameOwnerElement.cpp"
+#include "HTMLFrameSetElement.cpp"
+#include "HTMLHRElement.cpp"
+#include "HTMLHeadElement.cpp"
+#include "HTMLHeadingElement.cpp"
+#include "HTMLHtmlElement.cpp"
+#include "HTMLIFrameElement.cpp"
+#include "HTMLImageElement.cpp"
+#include "HTMLInputElement.cpp"
+#include "HTMLIsIndexElement.cpp"
+#include "HTMLKeygenElement.cpp"
+#include "HTMLLIElement.cpp"
+#include "HTMLLabelElement.cpp"
+#include "HTMLLegendElement.cpp"
+#include "HTMLLinkElement.cpp"
+#include "HTMLMapElement.cpp"
+#include "HTMLMarqueeElement.cpp"
+#include "HTMLMediaElement.cpp"
+#include "HTMLMenuElement.cpp"
+#include "HTMLMetaElement.cpp"
+#include "HTMLModElement.cpp"
+#include "HTMLOListElement.cpp"
+#include "HTMLObjectElement.cpp"
+#include "HTMLOptGroupElement.cpp"
+#include "HTMLOptionElement.cpp"
+#include "HTMLParagraphElement.cpp"
+#include "HTMLParamElement.cpp"
+#include "HTMLPlugInElement.cpp"
+#include "HTMLPlugInImageElement.cpp"
+#include "HTMLPreElement.cpp"
+#include "HTMLQuoteElement.cpp"
+#include "HTMLScriptElement.cpp"
+#include "HTMLSelectElement.cpp"
+#include "HTMLSourceElement.cpp"
+#include "HTMLStyleElement.cpp"
+#include "HTMLTableCaptionElement.cpp"
+#include "HTMLTableCellElement.cpp"
+#include "HTMLTableColElement.cpp"
+#include "HTMLTableElement.cpp"
+#include "HTMLTablePartElement.cpp"
+#include "HTMLTableRowElement.cpp"
+#include "HTMLTableSectionElement.cpp"
+#include "HTMLTextAreaElement.cpp"
+#include "HTMLTitleElement.cpp"
+#include "HTMLUListElement.cpp"
+#include "HTMLVideoElement.cpp"
diff --git a/WebCore/html/HTMLEmbedElement.cpp b/WebCore/html/HTMLEmbedElement.cpp
index f467849..2500dd6 100644
--- a/WebCore/html/HTMLEmbedElement.cpp
+++ b/WebCore/html/HTMLEmbedElement.cpp
@@ -31,10 +31,12 @@
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
#include "HTMLObjectElement.h"
+#include "MappedAttribute.h"
#include "RenderImage.h"
#include "RenderPartObject.h"
#include "RenderWidget.h"
#include "ScriptController.h"
+#include "Settings.h"
namespace WebCore {
@@ -137,6 +139,14 @@ bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style)
return false;
}
+#if ENABLE(DASHBOARD_SUPPORT)
+ // Workaround for <rdar://problem/6642221>.
+ if (Settings* settings = frame->settings()) {
+ if (settings->usesDashboardBackwardCompatibilityMode())
+ return true;
+ }
+#endif
+
return HTMLPlugInElement::rendererIsNeeded(style);
}
@@ -170,7 +180,7 @@ void HTMLEmbedElement::attach()
void HTMLEmbedElement::updateWidget()
{
- document()->updateRendering();
+ document()->updateStyleIfNeeded();
if (m_needWidgetUpdate && renderer() && !isImageType())
static_cast<RenderPartObject*>(renderer())->updateWidget(true);
}
diff --git a/WebCore/html/HTMLEmbedElement.idl b/WebCore/html/HTMLEmbedElement.idl
index 10c3007..ecf8a96 100644
--- a/WebCore/html/HTMLEmbedElement.idl
+++ b/WebCore/html/HTMLEmbedElement.idl
@@ -30,7 +30,7 @@ module html {
ImplementationUUID=93e0407a-8380-4ff0-978d-f773f2dee6a3
] HTMLEmbedElement : HTMLElement {
attribute [ConvertNullToNullString] DOMString align;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
attribute [ConvertNullToNullString] DOMString height;
#else
attribute [ConvertFromString] long height;
@@ -38,18 +38,20 @@ module html {
attribute [ConvertNullToNullString] DOMString name;
attribute [ConvertNullToNullString] DOMString src;
attribute [ConvertNullToNullString] DOMString type;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
attribute [ConvertNullToNullString] DOMString width;
#else
attribute [ConvertFromString] long width;
#endif
-#if !defined(LANGUAGE_COM)
-#if ENABLE_SVG
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+#if defined(ENABLE_SVG) && ENABLE_SVG
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
[SVGCheckSecurityDocument] SVGDocument getSVGDocument()
raises(DOMException);
#endif
#endif
+#endif
};
}
diff --git a/WebCore/html/HTMLFieldSetElement.cpp b/WebCore/html/HTMLFieldSetElement.cpp
index d90550d..eb8d4ed 100644
--- a/WebCore/html/HTMLFieldSetElement.cpp
+++ b/WebCore/html/HTMLFieldSetElement.cpp
@@ -53,7 +53,7 @@ bool HTMLFieldSetElement::isFocusable() const
return HTMLElement::isFocusable();
}
-const AtomicString& HTMLFieldSetElement::type() const
+const AtomicString& HTMLFieldSetElement::formControlType() const
{
DEFINE_STATIC_LOCAL(const AtomicString, fieldset, ("fieldset"));
return fieldset;
diff --git a/WebCore/html/HTMLFieldSetElement.h b/WebCore/html/HTMLFieldSetElement.h
index 9a6cff1..e79f2c5 100644
--- a/WebCore/html/HTMLFieldSetElement.h
+++ b/WebCore/html/HTMLFieldSetElement.h
@@ -46,7 +46,7 @@ public:
virtual bool isFocusable() const;
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
- virtual const AtomicString& type() const;
+ virtual const AtomicString& formControlType() const;
virtual bool willValidate() const { return false; }
};
diff --git a/WebCore/html/HTMLFontElement.cpp b/WebCore/html/HTMLFontElement.cpp
index 91b6448..d19032a 100644
--- a/WebCore/html/HTMLFontElement.cpp
+++ b/WebCore/html/HTMLFontElement.cpp
@@ -26,6 +26,7 @@
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
using namespace WTF;
diff --git a/WebCore/html/HTMLFormCollection.cpp b/WebCore/html/HTMLFormCollection.cpp
index 03796d6..812d98a 100644
--- a/WebCore/html/HTMLFormCollection.cpp
+++ b/WebCore/html/HTMLFormCollection.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "HTMLFormCollection.h"
+#include "CollectionCache.h"
#include "HTMLFormControlElement.h"
#include "HTMLFormElement.h"
#include "HTMLImageElement.h"
@@ -35,15 +36,15 @@ using namespace HTMLNames;
// Since the collections are to be "live", we have to do the
// calculation every time if anything has changed.
-inline HTMLCollection::CollectionInfo* HTMLFormCollection::formCollectionInfo(HTMLFormElement* form)
+inline CollectionCache* HTMLFormCollection::formCollectionInfo(HTMLFormElement* form)
{
if (!form->collectionInfo)
- form->collectionInfo = new CollectionInfo;
+ form->collectionInfo = new CollectionCache;
return form->collectionInfo;
}
HTMLFormCollection::HTMLFormCollection(PassRefPtr<HTMLFormElement> form)
- : HTMLCollection(form.get(), Other, formCollectionInfo(form.get()))
+ : HTMLCollection(form.get(), OtherCollection, formCollectionInfo(form.get()))
{
}
diff --git a/WebCore/html/HTMLFormCollection.h b/WebCore/html/HTMLFormCollection.h
index 524a59b..a204446 100644
--- a/WebCore/html/HTMLFormCollection.h
+++ b/WebCore/html/HTMLFormCollection.h
@@ -51,7 +51,7 @@ private:
virtual void updateNameCache() const;
virtual unsigned calcLength() const;
- static CollectionInfo* formCollectionInfo(HTMLFormElement*);
+ static CollectionCache* formCollectionInfo(HTMLFormElement*);
Element* getNamedItem(const QualifiedName& attrName, const AtomicString& name) const;
Element* nextNamedItemInternal(const String& name) const;
diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp
index 5238ad5..36d20ac 100644
--- a/WebCore/html/HTMLFormControlElement.cpp
+++ b/WebCore/html/HTMLFormControlElement.cpp
@@ -34,6 +34,7 @@
#include "HTMLNames.h"
#include "HTMLParser.h"
#include "HTMLTokenizer.h"
+#include "MappedAttribute.h"
#include "RenderBox.h"
#include "RenderTheme.h"
@@ -68,7 +69,7 @@ void HTMLFormControlElement::parseMappedAttribute(MappedAttribute *attr)
bool oldDisabled = m_disabled;
m_disabled = !attr->isNull();
if (oldDisabled != m_disabled) {
- setChanged();
+ setNeedsStyleRecalc();
if (renderer() && renderer()->style()->hasAppearance())
theme()->stateChanged(renderer(), EnabledState);
}
@@ -76,7 +77,7 @@ void HTMLFormControlElement::parseMappedAttribute(MappedAttribute *attr)
bool oldReadOnly = m_readOnly;
m_readOnly = !attr->isNull();
if (oldReadOnly != m_readOnly) {
- setChanged();
+ setNeedsStyleRecalc();
if (renderer() && renderer()->style()->hasAppearance())
theme()->stateChanged(renderer(), ReadOnlyState);
}
@@ -103,7 +104,7 @@ void HTMLFormControlElement::attach()
if (hasTagName(inputTag))
isInputTypeHidden = static_cast<HTMLInputElement*>(this)->isInputTypeHidden();
- if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyControl() &&
+ if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyFormControl() &&
((hasTagName(inputTag) && !isInputTypeHidden) || hasTagName(selectTag) ||
hasTagName(buttonTag) || hasTagName(textareaTag)))
focus();
@@ -151,7 +152,7 @@ void HTMLFormControlElement::removedFromTree(bool deep)
HTMLElement::removedFromTree(deep);
}
-const AtomicString& HTMLFormControlElement::name() const
+const AtomicString& HTMLFormControlElement::formControlName() const
{
const AtomicString& n = getAttribute(nameAttr);
return n.isNull() ? emptyAtom : n;
@@ -162,9 +163,9 @@ void HTMLFormControlElement::setName(const AtomicString &value)
setAttribute(nameAttr, value);
}
-void HTMLFormControlElement::onChange()
+void HTMLFormControlElement::dispatchFormControlChangeEvent()
{
- dispatchEventForType(eventNames().changeEvent, true, false);
+ dispatchEvent(eventNames().changeEvent, true, false);
}
bool HTMLFormControlElement::disabled() const
@@ -238,7 +239,7 @@ bool HTMLFormControlElement::willValidate() const
// The control does not have a repetition template as an ancestor.
// The control does not have a datalist element as an ancestor.
// The control is not an output element.
- return form() && name().length() && !disabled() && !isReadOnlyControl();
+ return form() && name().length() && !disabled() && !isReadOnlyFormControl();
}
bool HTMLFormControlElement::supportsFocus() const
@@ -262,23 +263,23 @@ void HTMLFormControlElement::removeFromForm()
HTMLFormControlElementWithState::HTMLFormControlElementWithState(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
: HTMLFormControlElement(tagName, doc, f)
{
- FormControlElementWithState::registerFormControlElementWithState(this, document());
+ document()->registerFormElementWithState(this);
}
HTMLFormControlElementWithState::~HTMLFormControlElementWithState()
{
- FormControlElementWithState::unregisterFormControlElementWithState(this, document());
+ document()->unregisterFormElementWithState(this);
}
void HTMLFormControlElementWithState::willMoveToNewOwnerDocument()
{
- FormControlElementWithState::unregisterFormControlElementWithState(this, document());
+ document()->unregisterFormElementWithState(this);
HTMLFormControlElement::willMoveToNewOwnerDocument();
}
void HTMLFormControlElementWithState::didMoveToNewOwnerDocument()
{
- FormControlElementWithState::registerFormControlElementWithState(this, document());
+ document()->registerFormElementWithState(this);
HTMLFormControlElement::didMoveToNewOwnerDocument();
}
@@ -289,7 +290,7 @@ void HTMLFormControlElementWithState::finishParsingChildren()
if (doc->hasStateForNewFormElements()) {
String state;
if (doc->takeStateForFormElement(name().impl(), type().impl(), state))
- restoreState(state);
+ restoreFormControlState(state);
}
}
diff --git a/WebCore/html/HTMLFormControlElement.h b/WebCore/html/HTMLFormControlElement.h
index 7430df7..0a7bbd1 100644
--- a/WebCore/html/HTMLFormControlElement.h
+++ b/WebCore/html/HTMLFormControlElement.h
@@ -24,8 +24,6 @@
#ifndef HTMLFormControlElement_h
#define HTMLFormControlElement_h
-#include "FormControlElement.h"
-#include "FormControlElementWithState.h"
#include "HTMLElement.h"
namespace WebCore {
@@ -33,7 +31,7 @@ namespace WebCore {
class FormDataList;
class HTMLFormElement;
-class HTMLFormControlElement : public HTMLElement, public FormControlElement {
+class HTMLFormControlElement : public HTMLElement {
public:
HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
virtual ~HTMLFormControlElement();
@@ -43,10 +41,8 @@ public:
HTMLFormElement* form() const { return m_form; }
- virtual const AtomicString& type() const = 0;
-
- virtual bool isTextControl() const { return false; }
- virtual bool isEnabled() const { return !disabled(); }
+ virtual bool isTextFormControl() const { return false; }
+ virtual bool isEnabledFormControl() const { return !disabled(); }
virtual void parseMappedAttribute(MappedAttribute*);
virtual void attach();
@@ -55,10 +51,10 @@ public:
virtual void reset() {}
- virtual bool valueMatchesRenderer() const { return m_valueMatchesRenderer; }
- virtual void setValueMatchesRenderer(bool b = true) { m_valueMatchesRenderer = b; }
+ virtual bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
+ virtual void setFormControlValueMatchesRenderer(bool b) { m_valueMatchesRenderer = b; }
- void onChange();
+ virtual void dispatchFormControlChangeEvent();
bool disabled() const;
void setDisabled(bool);
@@ -69,7 +65,7 @@ public:
virtual bool isMouseFocusable() const;
virtual bool isEnumeratable() const { return false; }
- virtual bool isReadOnlyControl() const { return m_readOnly; }
+ virtual bool isReadOnlyFormControl() const { return m_readOnly; }
void setReadOnly(bool);
// Determines whether or not a control will be automatically focused
@@ -78,7 +74,12 @@ public:
virtual void recalcStyle(StyleChange);
- virtual const AtomicString& name() const;
+ virtual const AtomicString& formControlName() const;
+ virtual const AtomicString& formControlType() const = 0;
+
+ const AtomicString& type() const { return formControlType(); }
+ const AtomicString& name() const { return formControlName(); }
+
void setName(const AtomicString& name);
virtual bool isFormControlElement() const { return true; }
@@ -111,14 +112,11 @@ private:
bool m_valueMatchesRenderer;
};
-class HTMLFormControlElementWithState : public HTMLFormControlElement, public FormControlElementWithState {
+class HTMLFormControlElementWithState : public HTMLFormControlElement {
public:
HTMLFormControlElementWithState(const QualifiedName& tagName, Document*, HTMLFormElement*);
virtual ~HTMLFormControlElementWithState();
- virtual bool isFormControlElementWithState() const { return true; }
-
- virtual FormControlElement* toFormControlElement() { return this; }
virtual void finishParsingChildren();
protected:
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index df4e541..64cac37 100644
--- a/WebCore/html/HTMLFormElement.cpp
+++ b/WebCore/html/HTMLFormElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
* This library is free software; you can redistribute it and/or
@@ -34,6 +34,7 @@
#include "FileSystem.h"
#include "FormData.h"
#include "FormDataList.h"
+#include "FormState.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "HTMLDocument.h"
@@ -41,22 +42,21 @@
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include "ScriptEventListener.h"
#include "MIMETypeRegistry.h"
+#include "MappedAttribute.h"
#include "Page.h"
#include "RenderTextControl.h"
+#include <limits>
#include <wtf/CurrentTime.h>
#include <wtf/RandomNumber.h>
-#include <limits>
-
#if PLATFORM(WX)
#include <wx/defs.h>
#include <wx/filename.h>
#endif
-#if PLATFORM(WIN_OS)
-#include <shlwapi.h>
-#endif
+using namespace std;
namespace WebCore {
@@ -79,6 +79,7 @@ HTMLFormElement::HTMLFormElement(const QualifiedName& tagName, Document* doc)
, m_doingsubmit(false)
, m_inreset(false)
, m_malformed(false)
+ , m_demoted(false)
{
ASSERT(hasTagName(formTag));
}
@@ -107,6 +108,31 @@ void HTMLFormElement::attach()
HTMLElement::attach();
}
+bool HTMLFormElement::rendererIsNeeded(RenderStyle* style)
+{
+ if (!isDemoted())
+ return HTMLElement::rendererIsNeeded(style);
+
+ Node* node = parentNode();
+ RenderObject* parentRenderer = node->renderer();
+ bool parentIsTableElementPart = (parentRenderer->isTable() && node->hasTagName(tableTag))
+ || (parentRenderer->isTableRow() && node->hasTagName(trTag))
+ || (parentRenderer->isTableSection() && node->hasTagName(tbodyTag))
+ || (parentRenderer->isTableCol() && node->hasTagName(colTag))
+ || (parentRenderer->isTableCell() && node->hasTagName(trTag));
+
+ if (!parentIsTableElementPart)
+ return true;
+
+ EDisplay display = style->display();
+ bool formIsTablePart = display == TABLE || display == INLINE_TABLE || display == TABLE_ROW_GROUP
+ || display == TABLE_HEADER_GROUP || display == TABLE_FOOTER_GROUP || display == TABLE_ROW
+ || display == TABLE_COLUMN_GROUP || display == TABLE_COLUMN || display == TABLE_CELL
+ || display == TABLE_CAPTION;
+
+ return formIsTablePart;
+}
+
void HTMLFormElement::insertedIntoDocument()
{
if (document()->isHTMLDocument())
@@ -269,7 +295,7 @@ bool HTMLFormElement::prepareSubmit(Event* event)
m_insubmit = true;
m_doingsubmit = false;
- if (dispatchEventForType(eventNames().submitEvent, true, true) && !m_doingsubmit)
+ if (dispatchEvent(eventNames().submitEvent, true, true) && !m_doingsubmit)
m_doingsubmit = true;
m_insubmit = false;
@@ -280,6 +306,28 @@ bool HTMLFormElement::prepareSubmit(Event* event)
return m_doingsubmit;
}
+static void transferMailtoPostFormDataToURL(RefPtr<FormData>& data, KURL& url, const String& encodingType)
+{
+ String body = data->flattenToString();
+ data = FormData::create();
+
+ if (equalIgnoringCase(encodingType, "text/plain")) {
+ // Convention seems to be to decode, and s/&/\r\n/. Also, spaces are encoded as %20.
+ body = decodeURLEscapeSequences(body.replace('&', "\r\n").replace('+', ' ') + "\r\n");
+ }
+
+ Vector<char> bodyData;
+ bodyData.append("body=", 5);
+ FormDataBuilder::encodeStringAsFormData(bodyData, body.utf8());
+ body = String(bodyData.data(), bodyData.size()).replace('+', "%20");
+
+ String query = url.query();
+ if (!query.isEmpty())
+ query.append('&');
+ query.append(body);
+ url.setQuery(query);
+}
+
void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockHistory, bool lockBackForwardList)
{
FrameView* view = document()->view();
@@ -297,14 +345,14 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockH
HTMLFormControlElement* firstSuccessfulSubmitButton = 0;
bool needButtonActivation = activateSubmitButton; // do we need to activate a submit button?
- frame->loader()->clearRecordedFormValues();
- frame->loader()->setFormAboutToBeSubmitted(this);
+ Vector<pair<String, String> > formValues;
+
for (unsigned i = 0; i < formElements.size(); ++i) {
HTMLFormControlElement* control = formElements[i];
if (control->hasLocalName(inputTag)) {
HTMLInputElement* input = static_cast<HTMLInputElement*>(control);
if (input->isTextField()) {
- frame->loader()->recordFormValue(input->name(), input->value());
+ formValues.append(pair<String, String>(input->name(), input->value()));
if (input->isSearchField())
input->addSearchResult();
}
@@ -317,6 +365,8 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockH
}
}
+ RefPtr<FormState> formState = FormState::create(this, formValues, frame);
+
if (needButtonActivation && firstSuccessfulSubmitButton)
firstSuccessfulSubmitButton->setActivatedSubmit(true);
@@ -331,25 +381,22 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockH
if (!m_formDataBuilder.isMultiPartForm()) {
RefPtr<FormData> data = createFormData(CString());
+
if (isMailtoForm()) {
- String body = data->flattenToString();
- if (equalIgnoringCase(m_formDataBuilder.encodingType(), "text/plain")) {
- // Convention seems to be to decode, and s/&/\r\n/. Also, spaces are encoded as %20.
- body = decodeURLEscapeSequences(body.replace('&', "\r\n").replace('+', ' ') + "\r\n");
- }
- Vector<char> bodyData;
- bodyData.append("body=", 5);
- FormDataBuilder::encodeStringAsFormData(bodyData, body.utf8());
- data = FormData::create(String(bodyData.data(), bodyData.size()).replace('+', "%20").latin1());
+ // Convert the form data into a string that we put into the URL.
+ KURL url = document()->completeURL(m_url);
+ transferMailtoPostFormDataToURL(data, url, m_formDataBuilder.encodingType());
+ m_url = url.string();
}
- frame->loader()->submitForm("POST", m_url, data, m_target, m_formDataBuilder.encodingType(), String(), event, lockHistory, lockBackForwardList);
+
+ frame->loader()->submitForm("POST", m_url, data.release(), m_target, m_formDataBuilder.encodingType(), String(), lockHistory, lockBackForwardList, event, formState.release());
} else {
Vector<char> boundary = m_formDataBuilder.generateUniqueBoundaryString();
- frame->loader()->submitForm("POST", m_url, createFormData(boundary.data()), m_target, m_formDataBuilder.encodingType(), boundary.data(), event, lockHistory, lockBackForwardList);
+ frame->loader()->submitForm("POST", m_url, createFormData(boundary.data()), m_target, m_formDataBuilder.encodingType(), boundary.data(), lockHistory, lockBackForwardList, event, formState.release());
}
} else {
m_formDataBuilder.setIsMultiPartForm(false);
- frame->loader()->submitForm("GET", m_url, createFormData(CString()), m_target, String(), String(), event, lockHistory, lockBackForwardList);
+ frame->loader()->submitForm("GET", m_url, createFormData(CString()), m_target, String(), String(), lockHistory, lockBackForwardList, event, formState.release());
}
if (needButtonActivation && firstSuccessfulSubmitButton)
@@ -368,7 +415,7 @@ void HTMLFormElement::reset()
// ### DOM2 labels this event as not cancelable, however
// common browsers( sick! ) allow it be cancelled.
- if ( !dispatchEventForType(eventNames().resetEvent,true, true) ) {
+ if ( !dispatchEvent(eventNames().resetEvent,true, true) ) {
m_inreset = false;
return;
}
@@ -402,9 +449,9 @@ void HTMLFormElement::parseMappedAttribute(MappedAttribute* attr)
else
document()->unregisterForDocumentActivationCallbacks(this);
} else if (attr->name() == onsubmitAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().submitEvent, attr);
+ setAttributeEventListener(eventNames().submitEvent, createAttributeEventListener(this, attr));
else if (attr->name() == onresetAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().resetEvent, attr);
+ setAttributeEventListener(eventNames().resetEvent, createAttributeEventListener(this, attr));
else if (attr->name() == nameAttr) {
const AtomicString& newName = attr->value();
if (inDocument() && document()->isHTMLDocument()) {
@@ -581,70 +628,14 @@ void HTMLFormElement::willMoveToNewOwnerDocument()
{
if (!m_autocomplete)
document()->unregisterForDocumentActivationCallbacks(this);
+ HTMLElement::willMoveToNewOwnerDocument();
}
void HTMLFormElement::didMoveToNewOwnerDocument()
{
- if(m_autocomplete)
+ if (!m_autocomplete)
document()->registerForDocumentActivationCallbacks(this);
-}
-
-void HTMLFormElement::CheckedRadioButtons::addButton(HTMLFormControlElement* element)
-{
- // We only want to add radio buttons.
- if (!element->isRadioButton())
- return;
-
- // Without a name, there is no group.
- if (element->name().isEmpty())
- return;
-
- HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element);
-
- // We only track checked buttons.
- if (!inputElement->checked())
- return;
-
- if (!m_nameToCheckedRadioButtonMap)
- m_nameToCheckedRadioButtonMap.set(new NameToInputMap);
-
- pair<NameToInputMap::iterator, bool> result = m_nameToCheckedRadioButtonMap->add(element->name().impl(), inputElement);
- if (result.second)
- return;
-
- HTMLInputElement* oldCheckedButton = result.first->second;
- if (oldCheckedButton == inputElement)
- return;
-
- result.first->second = inputElement;
- oldCheckedButton->setChecked(false);
-}
-
-HTMLInputElement* HTMLFormElement::CheckedRadioButtons::checkedButtonForGroup(const AtomicString& name) const
-{
- if (!m_nameToCheckedRadioButtonMap)
- return 0;
-
- return m_nameToCheckedRadioButtonMap->get(name.impl());
-}
-
-void HTMLFormElement::CheckedRadioButtons::removeButton(HTMLFormControlElement* element)
-{
- if (element->name().isEmpty() || !m_nameToCheckedRadioButtonMap)
- return;
-
- NameToInputMap::iterator it = m_nameToCheckedRadioButtonMap->find(element->name().impl());
- if (it == m_nameToCheckedRadioButtonMap->end() || it->second != element)
- return;
-
- InputElement* inputElement = toInputElement(element);
- ASSERT_UNUSED(inputElement, inputElement);
- ASSERT(inputElement->isChecked());
- ASSERT(element->isRadioButton());
-
- m_nameToCheckedRadioButtonMap->remove(it);
- if (m_nameToCheckedRadioButtonMap->isEmpty())
- m_nameToCheckedRadioButtonMap.clear();
+ HTMLElement::didMoveToNewOwnerDocument();
}
} // namespace
diff --git a/WebCore/html/HTMLFormElement.h b/WebCore/html/HTMLFormElement.h
index 8e5027c..d08e16c 100644
--- a/WebCore/html/HTMLFormElement.h
+++ b/WebCore/html/HTMLFormElement.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -24,10 +24,9 @@
#ifndef HTMLFormElement_h
#define HTMLFormElement_h
+#include "CheckedRadioButtons.h"
#include "FormDataBuilder.h"
-#include "HTMLCollection.h"
#include "HTMLElement.h"
-
#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -40,6 +39,8 @@ class HTMLInputElement;
class HTMLFormCollection;
class TextEncoding;
+struct CollectionCache;
+
class HTMLFormElement : public HTMLElement {
public:
HTMLFormElement(const QualifiedName&, Document*);
@@ -49,6 +50,7 @@ public:
virtual int tagPriority() const { return 3; }
virtual void attach();
+ virtual bool rendererIsNeeded(RenderStyle*);
virtual void insertedIntoDocument();
virtual void removedFromDocument();
@@ -83,6 +85,9 @@ public:
void setMalformed(bool malformed) { m_malformed = malformed; }
bool isMalformed() const { return m_malformed; }
+ void setDemoted(bool demoted) { m_demoted = demoted; }
+ bool isDemoted() const { return m_demoted; }
+
virtual bool isURLAttribute(Attribute*) const;
void submitClick(Event*);
@@ -109,17 +114,6 @@ public:
// FIXME: Change this to be private after getting rid of all the clients.
Vector<HTMLFormControlElement*> formElements;
- class CheckedRadioButtons {
- public:
- void addButton(HTMLFormControlElement*);
- void removeButton(HTMLFormControlElement*);
- HTMLInputElement* checkedButtonForGroup(const AtomicString& name) const;
-
- private:
- typedef HashMap<AtomicStringImpl*, HTMLInputElement*> NameToInputMap;
- OwnPtr<NameToInputMap> m_nameToCheckedRadioButtonMap;
- };
-
CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
virtual void documentDidBecomeActive();
@@ -140,7 +134,7 @@ private:
FormDataBuilder m_formDataBuilder;
AliasMap* m_elementAliases;
- HTMLCollection::CollectionInfo* collectionInfo;
+ CollectionCache* collectionInfo;
CheckedRadioButtons m_checkedRadioButtons;
@@ -152,6 +146,7 @@ private:
bool m_doingsubmit : 1;
bool m_inreset : 1;
bool m_malformed : 1;
+ bool m_demoted : 1;
AtomicString m_name;
};
diff --git a/WebCore/html/HTMLFrameElement.cpp b/WebCore/html/HTMLFrameElement.cpp
index 63ec265..adc3ff1 100644
--- a/WebCore/html/HTMLFrameElement.cpp
+++ b/WebCore/html/HTMLFrameElement.cpp
@@ -27,14 +27,15 @@
#include "Frame.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderFrame.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLFrameElement::HTMLFrameElement(const QualifiedName& tagName, Document* doc, bool createdByParser)
- : HTMLFrameElementBase(tagName, doc, createdByParser)
+HTMLFrameElement::HTMLFrameElement(const QualifiedName& tagName, Document* document)
+ : HTMLFrameElementBase(tagName, document)
, m_frameBorder(true)
, m_frameBorderSet(false)
{
diff --git a/WebCore/html/HTMLFrameElement.h b/WebCore/html/HTMLFrameElement.h
index 5cd9b92..ab602ee 100644
--- a/WebCore/html/HTMLFrameElement.h
+++ b/WebCore/html/HTMLFrameElement.h
@@ -33,10 +33,9 @@ class RenderObject;
class RenderArena;
class RenderStyle;
-class HTMLFrameElement : public HTMLFrameElementBase
-{
+class HTMLFrameElement : public HTMLFrameElementBase {
public:
- HTMLFrameElement(const QualifiedName&, Document*, bool createdByParser);
+ HTMLFrameElement(const QualifiedName&, Document*);
virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
virtual int tagPriority() const { return 0; }
diff --git a/WebCore/html/HTMLFrameElement.idl b/WebCore/html/HTMLFrameElement.idl
index bc512ff..106e57e 100644
--- a/WebCore/html/HTMLFrameElement.idl
+++ b/WebCore/html/HTMLFrameElement.idl
@@ -38,15 +38,17 @@ module html {
// Introduced in DOM Level 2:
readonly attribute [CheckFrameSecurity] Document contentDocument;
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
// Extensions
readonly attribute DOMWindow contentWindow;
-#if ENABLE_SVG
+#if defined(ENABLE_SVG) && ENABLE_SVG
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
[SVGCheckSecurityDocument] SVGDocument getSVGDocument()
raises(DOMException);
#endif
#endif
+#endif
attribute [ConvertNullToNullString, CustomSetter] DOMString location;
readonly attribute long width;
diff --git a/WebCore/html/HTMLFrameElementBase.cpp b/WebCore/html/HTMLFrameElementBase.cpp
index 59e7d46..1e09595 100644
--- a/WebCore/html/HTMLFrameElementBase.cpp
+++ b/WebCore/html/HTMLFrameElementBase.cpp
@@ -34,7 +34,9 @@
#include "FrameView.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
+#include "ScriptEventListener.h"
#include "KURL.h"
+#include "MappedAttribute.h"
#include "Page.h"
#include "RenderFrame.h"
#include "Settings.h"
@@ -43,8 +45,8 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Document* doc, bool createdByParser)
- : HTMLFrameOwnerElement(tagName, doc, createdByParser)
+HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Document* document)
+ : HTMLFrameOwnerElement(tagName, document)
, m_scrolling(ScrollbarAuto)
, m_marginWidth(-1)
, m_marginHeight(-1)
@@ -140,10 +142,10 @@ void HTMLFrameElementBase::parseMappedAttribute(MappedAttribute *attr)
if (contentFrame())
contentFrame()->setInViewSourceMode(viewSourceMode());
} else if (attr->name() == onloadAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onbeforeunloadAttr) {
// FIXME: should <frame> elements have beforeunload handlers?
- setInlineEventListenerForTypeAndAttribute(eventNames().beforeunloadEvent, attr);
+ setAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(this, attr));
} else
HTMLFrameOwnerElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLFrameElementBase.h b/WebCore/html/HTMLFrameElementBase.h
index 923cd2f..4a24451 100644
--- a/WebCore/html/HTMLFrameElementBase.h
+++ b/WebCore/html/HTMLFrameElementBase.h
@@ -82,7 +82,7 @@ public:
bool viewSourceMode() const { return m_viewSource; }
protected:
- HTMLFrameElementBase(const QualifiedName&, Document*, bool createdByParser);
+ HTMLFrameElementBase(const QualifiedName&, Document*);
bool isURLAllowed(const AtomicString&) const;
void setNameAndOpenURL();
diff --git a/WebCore/html/HTMLFrameOwnerElement.cpp b/WebCore/html/HTMLFrameOwnerElement.cpp
index 2e16e33..a98a3df 100644
--- a/WebCore/html/HTMLFrameOwnerElement.cpp
+++ b/WebCore/html/HTMLFrameOwnerElement.cpp
@@ -32,10 +32,9 @@
namespace WebCore {
-HTMLFrameOwnerElement::HTMLFrameOwnerElement(const QualifiedName& tagName, Document* document, bool createdByParser)
+HTMLFrameOwnerElement::HTMLFrameOwnerElement(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
, m_contentFrame(0)
- , m_createdByParser(createdByParser)
{
}
diff --git a/WebCore/html/HTMLFrameOwnerElement.h b/WebCore/html/HTMLFrameOwnerElement.h
index e887be0..3f50a02 100644
--- a/WebCore/html/HTMLFrameOwnerElement.h
+++ b/WebCore/html/HTMLFrameOwnerElement.h
@@ -35,7 +35,7 @@ class SVGDocument;
class HTMLFrameOwnerElement : public HTMLElement {
protected:
- HTMLFrameOwnerElement(const QualifiedName& tagName, Document*, bool createdByParser);
+ HTMLFrameOwnerElement(const QualifiedName& tagName, Document*);
public:
virtual ~HTMLFrameOwnerElement();
@@ -49,8 +49,6 @@ public:
virtual bool isFrameOwnerElement() const { return true; }
virtual bool isKeyboardFocusable(KeyboardEvent*) const { return m_contentFrame; }
- bool createdByParser() const { return m_createdByParser; }
-
virtual ScrollbarMode scrollingMode() const { return ScrollbarAuto; }
#if ENABLE(SVG)
@@ -60,7 +58,6 @@ public:
private:
friend class Frame;
Frame* m_contentFrame;
- bool m_createdByParser;
};
} // namespace WebCore
diff --git a/WebCore/html/HTMLFrameSetElement.cpp b/WebCore/html/HTMLFrameSetElement.cpp
index 3994de4..f8e244c 100644
--- a/WebCore/html/HTMLFrameSetElement.cpp
+++ b/WebCore/html/HTMLFrameSetElement.cpp
@@ -29,8 +29,9 @@
#include "Event.h"
#include "EventNames.h"
#include "HTMLNames.h"
+#include "ScriptEventListener.h"
#include "Length.h"
-#include "Length.h"
+#include "MappedAttribute.h"
#include "MouseEvent.h"
#include "RenderFrameSet.h"
#include "Text.h"
@@ -88,13 +89,13 @@ void HTMLFrameSetElement::parseMappedAttribute(MappedAttribute *attr)
if (!attr->isNull()) {
if (m_rows) delete [] m_rows;
m_rows = newLengthArray(attr->value().string(), m_totalRows);
- setChanged();
+ setNeedsStyleRecalc();
}
} else if (attr->name() == colsAttr) {
if (!attr->isNull()) {
delete [] m_cols;
m_cols = newLengthArray(attr->value().string(), m_totalCols);
- setChanged();
+ setNeedsStyleRecalc();
}
} else if (attr->name() == frameborderAttr) {
if (!attr->isNull()) {
@@ -125,11 +126,11 @@ void HTMLFrameSetElement::parseMappedAttribute(MappedAttribute *attr)
m_borderColorSet = true;
}
} else if (attr->name() == onloadAttr) {
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), attr));
} else if (attr->name() == onbeforeunloadAttr) {
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().beforeunloadEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), attr));
} else if (attr->name() == onunloadAttr) {
- document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().unloadEvent, attr);
+ document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), attr));
} else
HTMLElement::parseMappedAttribute(attr);
}
@@ -186,12 +187,12 @@ void HTMLFrameSetElement::defaultEventHandler(Event* evt)
void HTMLFrameSetElement::recalcStyle(StyleChange ch)
{
- if (changed() && renderer()) {
+ if (needsStyleRecalc() && renderer()) {
renderer()->setNeedsLayout(true);
#ifdef FLATTEN_FRAMESET
static_cast<RenderFrameSet*>(renderer())->setGridNeedsLayout();
#endif
- setChanged(NoStyleChange);
+ setNeedsStyleRecalc(NoStyleChange);
}
HTMLElement::recalcStyle(ch);
}
diff --git a/WebCore/html/HTMLHRElement.cpp b/WebCore/html/HTMLHRElement.cpp
index 8be23fd..d6cc58e 100644
--- a/WebCore/html/HTMLHRElement.cpp
+++ b/WebCore/html/HTMLHRElement.cpp
@@ -19,12 +19,14 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#include "config.h"
#include "HTMLHRElement.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLHtmlElement.cpp b/WebCore/html/HTMLHtmlElement.cpp
index 4ed2400..d4867a4 100644
--- a/WebCore/html/HTMLHtmlElement.cpp
+++ b/WebCore/html/HTMLHtmlElement.cpp
@@ -53,10 +53,8 @@ void HTMLHtmlElement::setVersion(const String &value)
bool HTMLHtmlElement::checkDTD(const Node* newChild)
{
- // FIXME: Why is <script> allowed here?
return newChild->hasTagName(headTag) || newChild->hasTagName(bodyTag) ||
- newChild->hasTagName(framesetTag) || newChild->hasTagName(noframesTag) ||
- newChild->hasTagName(scriptTag);
+ newChild->hasTagName(framesetTag) || newChild->hasTagName(noframesTag);
}
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/WebCore/html/HTMLIFrameElement.cpp b/WebCore/html/HTMLIFrameElement.cpp
index 9ba3b13..a190bca 100644
--- a/WebCore/html/HTMLIFrameElement.cpp
+++ b/WebCore/html/HTMLIFrameElement.cpp
@@ -28,14 +28,15 @@
#include "Frame.h"
#include "HTMLDocument.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderPartObject.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLIFrameElement::HTMLIFrameElement(const QualifiedName& tagName, Document* doc, bool createdByParser)
- : HTMLFrameElementBase(tagName, doc, createdByParser)
+HTMLIFrameElement::HTMLIFrameElement(const QualifiedName& tagName, Document* document)
+ : HTMLFrameElementBase(tagName, document)
{
ASSERT(hasTagName(iframeTag));
}
diff --git a/WebCore/html/HTMLIFrameElement.h b/WebCore/html/HTMLIFrameElement.h
index 3407a6d..362b991 100644
--- a/WebCore/html/HTMLIFrameElement.h
+++ b/WebCore/html/HTMLIFrameElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLIFrameElement : public HTMLFrameElementBase {
public:
- HTMLIFrameElement(const QualifiedName&, Document*, bool createdByParser);
+ HTMLIFrameElement(const QualifiedName&, Document*);
virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
virtual int tagPriority() const { return 1; }
diff --git a/WebCore/html/HTMLIFrameElement.idl b/WebCore/html/HTMLIFrameElement.idl
index c6a8599..b5684ca 100644
--- a/WebCore/html/HTMLIFrameElement.idl
+++ b/WebCore/html/HTMLIFrameElement.idl
@@ -40,15 +40,17 @@ module html {
// Introduced in DOM Level 2:
readonly attribute [CheckFrameSecurity] Document contentDocument;
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
// Extensions
readonly attribute DOMWindow contentWindow;
-#if ENABLE_SVG
+#if defined(ENABLE_SVG) && ENABLE_SVG
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
[SVGCheckSecurityDocument] SVGDocument getSVGDocument()
raises(DOMException);
#endif
#endif
+#endif
};
diff --git a/WebCore/html/HTMLImageElement.cpp b/WebCore/html/HTMLImageElement.cpp
index c4e7608..c4bf5dc 100644
--- a/WebCore/html/HTMLImageElement.cpp
+++ b/WebCore/html/HTMLImageElement.cpp
@@ -30,7 +30,9 @@
#include "HTMLDocument.h"
#include "HTMLFormElement.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderImage.h"
+#include "ScriptEventListener.h"
using namespace std;
@@ -113,9 +115,9 @@ void HTMLImageElement::parseMappedAttribute(MappedAttribute* attr)
} else if (attrName == ismapAttr)
ismap = true;
else if (attrName == onabortAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().abortEvent, attr);
+ setAttributeEventListener(eventNames().abortEvent, createAttributeEventListener(this, attr));
else if (attrName == onloadAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
else if (attrName == compositeAttr) {
if (!parseCompositeOperator(attr->value(), m_compositeOperator))
m_compositeOperator = CompositeSourceOver;
diff --git a/WebCore/html/HTMLImageElement.idl b/WebCore/html/HTMLImageElement.idl
index fe64e6f..d7da088 100644
--- a/WebCore/html/HTMLImageElement.idl
+++ b/WebCore/html/HTMLImageElement.idl
@@ -46,7 +46,7 @@ module html {
readonly attribute long x;
readonly attribute long y;
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// Objective-C extension:
readonly attribute DOMString altDisplayString;
readonly attribute URL absoluteImageURL;
diff --git a/WebCore/html/HTMLImageLoader.cpp b/WebCore/html/HTMLImageLoader.cpp
index 5dac8bf..ea53d7e 100644
--- a/WebCore/html/HTMLImageLoader.cpp
+++ b/WebCore/html/HTMLImageLoader.cpp
@@ -42,7 +42,10 @@ HTMLImageLoader::~HTMLImageLoader()
void HTMLImageLoader::dispatchLoadEvent()
{
- element()->dispatchEventForType(image()->errorOccurred() ? eventNames().errorEvent : eventNames().loadEvent, false, false);
+ bool errorOccurred = image()->errorOccurred();
+ if (!errorOccurred && image()->httpStatusCodeErrorOccurred())
+ errorOccurred = element()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror.
+ element()->dispatchEvent(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false);
}
String HTMLImageLoader::sourceURI(const AtomicString& attr) const
@@ -50,12 +53,14 @@ String HTMLImageLoader::sourceURI(const AtomicString& attr) const
return parseURL(attr);
}
-void HTMLImageLoader::notifyFinished(CachedResource* image)
-{
+void HTMLImageLoader::notifyFinished(CachedResource*)
+{
+ CachedImage* cachedImage = image();
+
Element* elem = element();
- ImageLoader::notifyFinished(image);
+ ImageLoader::notifyFinished(cachedImage);
- if (image->errorOccurred() && elem->hasTagName(HTMLNames::objectTag))
+ if ((cachedImage->errorOccurred() || cachedImage->httpStatusCodeErrorOccurred()) && elem->hasTagName(HTMLNames::objectTag))
static_cast<HTMLObjectElement*>(elem)->renderFallbackContent();
}
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index 103b740..2d1b3d0 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -26,8 +26,8 @@
#include "config.h"
#include "HTMLInputElement.h"
-#include "ChromeClient.h"
#include "CSSPropertyNames.h"
+#include "ChromeClient.h"
#include "Document.h"
#include "Editor.h"
#include "Event.h"
@@ -41,8 +41,10 @@
#include "HTMLFormElement.h"
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
+#include "ScriptEventListener.h"
#include "KeyboardEvent.h"
#include "LocalizedStrings.h"
+#include "MappedAttribute.h"
#include "MouseEvent.h"
#include "Page.h"
#include "RenderButton.h"
@@ -68,7 +70,6 @@ const int maxSavedResults = 256;
HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
: HTMLFormControlElementWithState(tagName, doc, f)
- , m_data(this, this)
, m_xPos(0)
, m_yPos(0)
, m_maxResults(-1)
@@ -98,7 +99,7 @@ HTMLInputElement::~HTMLInputElement()
removeFromForm();
}
-const AtomicString& HTMLInputElement::name() const
+const AtomicString& HTMLInputElement::formControlName() const
{
return m_data.name();
}
@@ -116,8 +117,7 @@ bool HTMLInputElement::autoComplete() const
return true;
}
-
-static inline HTMLFormElement::CheckedRadioButtons& checkedRadioButtons(const HTMLInputElement *element)
+static inline CheckedRadioButtons& checkedRadioButtons(const HTMLInputElement *element)
{
if (HTMLFormElement* form = element->form())
return form->checkedRadioButtons();
@@ -164,14 +164,14 @@ bool HTMLInputElement::isMouseFocusable() const
void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
{
if (isTextField())
- InputElement::updateFocusAppearance(m_data, document(), restorePreviousSelection);
+ InputElement::updateFocusAppearance(m_data, this, this, restorePreviousSelection);
else
HTMLFormControlElementWithState::updateFocusAppearance(restorePreviousSelection);
}
void HTMLInputElement::aboutToUnload()
{
- InputElement::aboutToUnload(m_data, document());
+ InputElement::aboutToUnload(this, this);
}
bool HTMLInputElement::shouldUseInputMethod() const
@@ -181,7 +181,7 @@ bool HTMLInputElement::shouldUseInputMethod() const
void HTMLInputElement::dispatchFocusEvent()
{
- InputElement::dispatchFocusEvent(m_data, document());
+ InputElement::dispatchFocusEvent(m_data, this, this);
if (isTextField())
m_autofilled = false;
@@ -191,7 +191,7 @@ void HTMLInputElement::dispatchFocusEvent()
void HTMLInputElement::dispatchBlurEvent()
{
- InputElement::dispatchBlurEvent(m_data, document());
+ InputElement::dispatchBlurEvent(m_data, this, this);
HTMLFormControlElementWithState::dispatchBlurEvent();
}
@@ -242,6 +242,14 @@ void HTMLInputElement::setInputType(const String& t)
newType = SEARCH;
else if (equalIgnoringCase(t, "range"))
newType = RANGE;
+ else if (equalIgnoringCase(t, "email"))
+ newType = EMAIL;
+ else if (equalIgnoringCase(t, "number"))
+ newType = NUMBER;
+ else if (equalIgnoringCase(t, "tel"))
+ newType = TELEPHONE;
+ else if (equalIgnoringCase(t, "url"))
+ newType = URL;
else
newType = TEXT;
@@ -278,7 +286,7 @@ void HTMLInputElement::setInputType(const String& t)
if (!didStoreValue && willStoreValue)
m_data.setValue(constrainValue(getAttribute(valueAttr)));
else
- InputElement::updateValueIfNeeded(m_data);
+ InputElement::updateValueIfNeeded(m_data, this);
if (wasPasswordField && !isPasswordField)
unregisterForActivationCallbackIfNeeded();
@@ -287,6 +295,7 @@ void HTMLInputElement::setInputType(const String& t)
if (didRespectHeightAndWidth != willRespectHeightAndWidth) {
NamedMappedAttrMap* map = mappedAttributes();
+ ASSERT(map);
if (Attribute* height = map->getAttributeItem(heightAttr))
attributeChanged(height, false);
if (Attribute* width = map->getAttributeItem(widthAttr))
@@ -304,7 +313,7 @@ void HTMLInputElement::setInputType(const String& t)
checkedRadioButtons(this).addButton(this);
}
- InputElement::notifyFormStateChanged(m_data, document());
+ InputElement::notifyFormStateChanged(this);
}
m_haveType = true;
@@ -312,7 +321,7 @@ void HTMLInputElement::setInputType(const String& t)
m_imageLoader.clear();
}
-const AtomicString& HTMLInputElement::type() const
+const AtomicString& HTMLInputElement::formControlType() const
{
// needs to be lowercase according to DOM spec
switch (inputType()) {
@@ -324,6 +333,10 @@ const AtomicString& HTMLInputElement::type() const
DEFINE_STATIC_LOCAL(const AtomicString, checkbox, ("checkbox"));
return checkbox;
}
+ case EMAIL: {
+ DEFINE_STATIC_LOCAL(const AtomicString, email, ("email"));
+ return email;
+ }
case FILE: {
DEFINE_STATIC_LOCAL(const AtomicString, file, ("file"));
return file;
@@ -338,6 +351,10 @@ const AtomicString& HTMLInputElement::type() const
}
case ISINDEX:
return emptyAtom;
+ case NUMBER: {
+ DEFINE_STATIC_LOCAL(const AtomicString, number, ("number"));
+ return number;
+ }
case PASSWORD: {
DEFINE_STATIC_LOCAL(const AtomicString, password, ("password"));
return password;
@@ -362,30 +379,42 @@ const AtomicString& HTMLInputElement::type() const
DEFINE_STATIC_LOCAL(const AtomicString, submit, ("submit"));
return submit;
}
+ case TELEPHONE: {
+ DEFINE_STATIC_LOCAL(const AtomicString, telephone, ("tel"));
+ return telephone;
+ }
case TEXT: {
DEFINE_STATIC_LOCAL(const AtomicString, text, ("text"));
return text;
}
+ case URL: {
+ DEFINE_STATIC_LOCAL(const AtomicString, url, ("url"));
+ return url;
+ }
}
return emptyAtom;
}
-bool HTMLInputElement::saveState(String& result) const
+bool HTMLInputElement::saveFormControlState(String& result) const
{
if (!autoComplete())
return false;
switch (inputType()) {
case BUTTON:
+ case EMAIL:
case FILE:
case HIDDEN:
case IMAGE:
case ISINDEX:
+ case NUMBER:
case RANGE:
case RESET:
case SEARCH:
case SUBMIT:
+ case TELEPHONE:
case TEXT:
+ case URL:
result = value();
return true;
case CHECKBOX:
@@ -399,20 +428,24 @@ bool HTMLInputElement::saveState(String& result) const
return false;
}
-void HTMLInputElement::restoreState(const String& state)
+void HTMLInputElement::restoreFormControlState(const String& state)
{
ASSERT(inputType() != PASSWORD); // should never save/restore password fields
switch (inputType()) {
case BUTTON:
+ case EMAIL:
case FILE:
case HIDDEN:
case IMAGE:
case ISINDEX:
+ case NUMBER:
case RANGE:
case RESET:
case SEARCH:
case SUBMIT:
+ case TELEPHONE:
case TEXT:
+ case URL:
setValue(state);
break;
case CHECKBOX:
@@ -487,7 +520,7 @@ void HTMLInputElement::select()
void HTMLInputElement::setSelectionRange(int start, int end)
{
- InputElement::updateSelectionRange(m_data, start, end);
+ InputElement::updateSelectionRange(this, this, start, end);
}
void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
@@ -508,10 +541,14 @@ void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
case HIDDEN:
// a no-op for this type
break;
+ case EMAIL:
case ISINDEX:
+ case NUMBER:
case PASSWORD:
case SEARCH:
+ case TELEPHONE:
case TEXT:
+ case URL:
// should never restore previous selection here
focus(false);
break;
@@ -561,8 +598,8 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
} else if (attr->name() == valueAttr) {
// We only need to setChanged if the form is looking at the default value right now.
if (m_data.value().isNull())
- setChanged();
- setValueMatchesRenderer(false);
+ setNeedsStyleRecalc();
+ setFormControlValueMatchesRenderer(false);
} else if (attr->name() == checkedAttr) {
m_defaultChecked = !attr->isNull();
if (m_useDefaultChecked) {
@@ -570,9 +607,9 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
m_useDefaultChecked = true;
}
} else if (attr->name() == maxlengthAttr)
- InputElement::parseMaxLengthAttribute(m_data, attr);
+ InputElement::parseMaxLengthAttribute(m_data, this, this, attr);
else if (attr->name() == sizeAttr)
- InputElement::parseSizeAttribute(m_data, attr);
+ InputElement::parseSizeAttribute(m_data, this, attr);
else if (attr->name() == altAttr) {
if (renderer() && inputType() == IMAGE)
toRenderImage(renderer())->updateAltText();
@@ -601,20 +638,20 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
if (respectHeightAndWidthAttrs())
addCSSLength(attr, CSSPropertyHeight, attr->value());
} else if (attr->name() == onfocusAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
+ setAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onblurAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
+ setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onselectAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().selectEvent, attr);
+ setAttributeEventListener(eventNames().selectEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onchangeAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().changeEvent, attr);
+ setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == oninputAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().inputEvent, attr);
+ setAttributeEventListener(eventNames().inputEvent, createAttributeEventListener(this, attr));
}
// Search field and slider attributes all just cause updateFromElement to be called through style
// recalcing.
else if (attr->name() == onsearchAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().searchEvent, attr);
+ setAttributeEventListener(eventNames().searchEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == resultsAttr) {
int oldResults = m_maxResults;
m_maxResults = !attr->isNull() ? min(attr->value().toInt(), maxSavedResults) : -1;
@@ -624,17 +661,17 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
detach();
attach();
}
- setChanged();
+ setNeedsStyleRecalc();
} else if (attr->name() == placeholderAttr) {
if (isTextField())
- InputElement::updatePlaceholderVisibility(m_data, document(), true);
+ updatePlaceholderVisibility();
} else if (attr->name() == autosaveAttr ||
attr->name() == incrementalAttr ||
attr->name() == minAttr ||
attr->name() == maxAttr ||
attr->name() == multipleAttr ||
attr->name() == precisionAttr)
- setChanged();
+ setNeedsStyleRecalc();
else
HTMLFormControlElementWithState::parseMappedAttribute(attr);
}
@@ -644,16 +681,20 @@ bool HTMLInputElement::rendererIsNeeded(RenderStyle *style)
switch (inputType()) {
case BUTTON:
case CHECKBOX:
+ case EMAIL:
case FILE:
case IMAGE:
case ISINDEX:
+ case NUMBER:
case PASSWORD:
case RADIO:
case RANGE:
case RESET:
case SEARCH:
case SUBMIT:
+ case TELEPHONE:
case TEXT:
+ case URL:
return HTMLFormControlElementWithState::rendererIsNeeded(style);
case HIDDEN:
return false;
@@ -680,10 +721,14 @@ RenderObject *HTMLInputElement::createRenderer(RenderArena *arena, RenderStyle *
return new (arena) RenderImage(this);
case RANGE:
return new (arena) RenderSlider(this);
+ case EMAIL:
case ISINDEX:
+ case NUMBER:
case PASSWORD:
case SEARCH:
+ case TELEPHONE:
case TEXT:
+ case URL:
return new (arena) RenderTextControlSingleLine(this);
}
ASSERT(false);
@@ -719,7 +764,7 @@ void HTMLInputElement::attach()
void HTMLInputElement::detach()
{
HTMLFormControlElementWithState::detach();
- setValueMatchesRenderer(false);
+ setFormControlValueMatchesRenderer(false);
}
String HTMLInputElement::altText() const
@@ -762,12 +807,16 @@ bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
return false;
switch (inputType()) {
+ case EMAIL:
case HIDDEN:
case ISINDEX:
+ case NUMBER:
case PASSWORD:
case RANGE:
case SEARCH:
+ case TELEPHONE:
case TEXT:
+ case URL:
// always successful
encoding.appendData(name(), value());
return true;
@@ -842,7 +891,7 @@ void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
m_useDefaultChecked = false;
m_checked = nowChecked;
- setChanged();
+ setNeedsStyleRecalc();
checkedRadioButtons(this).addButton(this);
@@ -855,7 +904,7 @@ void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
// because it says only to fire change events at "lose focus" time, which is
// definitely wrong in practice for these types of elements.
if (sendChangeEvent && inDocument() && (inputType() != RADIO || nowChecked))
- onChange();
+ dispatchFormControlChangeEvent();
}
void HTMLInputElement::setIndeterminate(bool _indeterminate)
@@ -866,7 +915,7 @@ void HTMLInputElement::setIndeterminate(bool _indeterminate)
m_indeterminate = _indeterminate;
- setChanged();
+ setNeedsStyleRecalc();
if (renderer() && renderer()->style()->hasAppearance())
theme()->stateChanged(renderer(), CheckedState);
@@ -917,15 +966,19 @@ String HTMLInputElement::valueWithDefault() const
switch (inputType()) {
case BUTTON:
case CHECKBOX:
+ case EMAIL:
case FILE:
case HIDDEN:
case IMAGE:
case ISINDEX:
+ case NUMBER:
case PASSWORD:
case RADIO:
case RANGE:
case SEARCH:
+ case TELEPHONE:
case TEXT:
+ case URL:
break;
case RESET:
v = resetButtonDefaultLabel();
@@ -946,21 +999,21 @@ void HTMLInputElement::setValue(const String& value)
if (inputType() == FILE && !value.isEmpty())
return;
- setValueMatchesRenderer(false);
+ setFormControlValueMatchesRenderer(false);
if (storesValueSeparateFromAttribute()) {
if (inputType() == FILE)
m_fileList->clear();
else {
m_data.setValue(constrainValue(value));
if (isTextField()) {
- InputElement::updatePlaceholderVisibility(m_data, document());
+ InputElement::updatePlaceholderVisibility(m_data, this, this);
if (inDocument())
- document()->updateRendering();
+ document()->updateStyleIfNeeded();
}
}
if (renderer())
renderer()->updateFromElement();
- setChanged();
+ setNeedsStyleRecalc();
} else
setAttribute(valueAttr, constrainValue(value));
@@ -972,21 +1025,26 @@ void HTMLInputElement::setValue(const String& value)
// Make sure our UI side textfield changes to match the RenderTextControl
android::WebViewCore::getWebViewCore(document()->view())->updateTextfield(this, false, value);
#endif
- InputElement::updateSelectionRange(m_data, max, max);
+ InputElement::updateSelectionRange(this, this, max, max);
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
}
#endif
else
cacheSelection(max, max);
}
- InputElement::notifyFormStateChanged(m_data, document());
+ InputElement::notifyFormStateChanged(this);
}
-String HTMLInputElement::placeholderValue() const
+String HTMLInputElement::placeholder() const
{
return getAttribute(placeholderAttr).string();
}
+void HTMLInputElement::setPlaceholder(const String& value)
+{
+ setAttribute(placeholderAttr, value);
+}
+
bool HTMLInputElement::searchEventsShouldBeDispatched() const
{
return hasAttribute(incrementalAttr);
@@ -996,7 +1054,7 @@ void HTMLInputElement::setValueFromRenderer(const String& value)
{
// File upload controls will always use setFileListFromRenderer.
ASSERT(inputType() != FILE);
- InputElement::setValueFromRenderer(m_data, document(), value);
+ InputElement::setValueFromRenderer(m_data, this, this, value);
}
void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
@@ -1006,8 +1064,8 @@ void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
for (int i = 0; i < size; i++)
m_fileList->append(File::create(paths[i]));
- setValueMatchesRenderer();
- InputElement::notifyFormStateChanged(m_data, document());
+ setFormControlValueMatchesRenderer(true);
+ InputElement::notifyFormStateChanged(this);
}
bool HTMLInputElement::storesValueSeparateFromAttribute() const
@@ -1021,12 +1079,16 @@ bool HTMLInputElement::storesValueSeparateFromAttribute() const
case RESET:
case SUBMIT:
return false;
+ case EMAIL:
case FILE:
case ISINDEX:
+ case NUMBER:
case PASSWORD:
case RANGE:
case SEARCH:
+ case TELEPHONE:
case TEXT:
+ case URL:
return true;
}
return false;
@@ -1192,12 +1254,16 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
if (charCode == '\r') {
switch (inputType()) {
case CHECKBOX:
+ case EMAIL:
case HIDDEN:
case ISINDEX:
+ case NUMBER:
case PASSWORD:
case RANGE:
case SEARCH:
+ case TELEPHONE:
case TEXT:
+ case URL:
// Simulate mouse click on the default form button for enter for these types of elements.
clickDefaultFormButton = true;
break;
@@ -1316,12 +1382,16 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
if (!checked())
clickElement = true;
break;
+ case EMAIL:
case HIDDEN:
case ISINDEX:
+ case NUMBER:
case PASSWORD:
case RANGE:
case SEARCH:
+ case TELEPHONE:
case TEXT:
+ case URL:
break;
}
}
@@ -1342,7 +1412,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
// Fire onChange for text fields.
RenderObject* r = renderer();
if (r && r->isTextField() && toRenderTextControl(r)->isEdited()) {
- onChange();
+ dispatchFormControlChangeEvent();
// Refetch the renderer since arbitrary JS code run during onchange can do anything, including destroying it.
r = renderer();
if (r && r->isTextField())
@@ -1356,7 +1426,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
}
if (evt->isBeforeTextInsertedEvent())
- InputElement::handleBeforeTextInsertedEvent(m_data, document(), evt);
+ InputElement::handleBeforeTextInsertedEvent(m_data, this, document(), evt);
if (isTextField() && renderer() && (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent() || evt->type() == eventNames().blurEvent || evt->type() == eventNames().focusEvent))
static_cast<RenderTextControlSingleLine*>(renderer())->forwardEvent(evt);
@@ -1489,7 +1559,7 @@ void HTMLInputElement::setAutofilled(bool b)
return;
m_autofilled = b;
- setChanged();
+ setNeedsStyleRecalc();
}
FileList* HTMLInputElement::files()
@@ -1501,7 +1571,7 @@ FileList* HTMLInputElement::files()
String HTMLInputElement::constrainValue(const String& proposedValue) const
{
- return InputElement::constrainValue(m_data, proposedValue, m_data.maxLength());
+ return InputElement::constrainValue(this, proposedValue, m_data.maxLength());
}
bool HTMLInputElement::needsActivationCallback()
@@ -1539,7 +1609,7 @@ void HTMLInputElement::onSearch()
ASSERT(isSearchField());
if (renderer())
static_cast<RenderTextControlSingleLine*>(renderer())->stopSearchEventTimer();
- dispatchEventForType(eventNames().searchEvent, true, false);
+ dispatchEvent(eventNames().searchEvent, true, false);
}
VisibleSelection HTMLInputElement::selection() const
diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h
index 5b6a5d6..be2b4f4 100644
--- a/WebCore/html/HTMLInputElement.h
+++ b/WebCore/html/HTMLInputElement.h
@@ -50,7 +50,11 @@ public:
IMAGE,
BUTTON,
SEARCH,
- RANGE
+ RANGE,
+ EMAIL,
+ NUMBER,
+ TELEPHONE,
+ URL
};
enum AutoCompleteSetting {
@@ -74,7 +78,7 @@ public:
virtual void aboutToUnload();
virtual bool shouldUseInputMethod() const;
- virtual const AtomicString& name() const;
+ virtual const AtomicString& formControlName() const;
bool autoComplete() const;
@@ -82,13 +86,13 @@ public:
virtual bool isChecked() const { return checked() && (inputType() == CHECKBOX || inputType() == RADIO); }
virtual bool isIndeterminate() const { return indeterminate(); }
- bool readOnly() const { return isReadOnlyControl(); }
+ bool readOnly() const { return isReadOnlyFormControl(); }
- virtual bool isTextControl() const { return isTextField(); }
+ virtual bool isTextFormControl() const { return isTextField(); }
bool isTextButton() const { return m_type == SUBMIT || m_type == RESET || m_type == BUTTON; }
virtual bool isRadioButton() const { return m_type == RADIO; }
- virtual bool isTextField() const { return m_type == TEXT || m_type == PASSWORD || m_type == SEARCH || m_type == ISINDEX; }
+ virtual bool isTextField() const { return m_type == TEXT || m_type == PASSWORD || m_type == SEARCH || m_type == ISINDEX || m_type == EMAIL || m_type == NUMBER || m_type == TELEPHONE || m_type == URL; }
virtual bool isSearchField() const { return m_type == SEARCH; }
virtual bool isInputTypeHidden() const { return m_type == HIDDEN; }
virtual bool isPasswordField() const { return m_type == PASSWORD; }
@@ -98,13 +102,15 @@ public:
bool indeterminate() const { return m_indeterminate; }
void setIndeterminate(bool);
virtual int size() const;
- virtual const AtomicString& type() const;
+ virtual const AtomicString& formControlType() const;
void setType(const String&);
virtual String value() const;
virtual void setValue(const String&);
- virtual String placeholderValue() const;
+ virtual String placeholder() const;
+ virtual void setPlaceholder(const String&);
+
virtual bool searchEventsShouldBeDispatched() const;
String valueWithDefault() const;
@@ -112,8 +118,8 @@ public:
virtual void setValueFromRenderer(const String&);
void setFileListFromRenderer(const Vector<String>&);
- virtual bool saveState(String& value) const;
- virtual void restoreState(const String&);
+ virtual bool saveFormControlState(String& value) const;
+ virtual void restoreFormControlState(const String&);
virtual bool canStartSelection() const;
@@ -219,6 +225,11 @@ protected:
virtual void willMoveToNewOwnerDocument();
virtual void didMoveToNewOwnerDocument();
+ void updatePlaceholderVisibility()
+ {
+ InputElement::updatePlaceholderVisibility(m_data, this, this, true);
+ }
+
private:
bool storesValueSeparateFromAttribute() const;
@@ -232,7 +243,7 @@ private:
short m_maxResults;
OwnPtr<HTMLImageLoader> m_imageLoader;
RefPtr<FileList> m_fileList;
- unsigned m_type : 4; // InputType
+ unsigned m_type : 5; // InputType
bool m_checked : 1;
bool m_defaultChecked : 1;
bool m_useDefaultChecked : 1;
diff --git a/WebCore/html/HTMLInputElement.idl b/WebCore/html/HTMLInputElement.idl
index 0734e6a..5536733 100644
--- a/WebCore/html/HTMLInputElement.idl
+++ b/WebCore/html/HTMLInputElement.idl
@@ -38,15 +38,16 @@ module html {
attribute long maxLength;
attribute boolean multiple;
attribute [ConvertNullToNullString] DOMString name;
+ attribute DOMString placeholder;
attribute boolean readOnly;
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
attribute [ConvertToString] DOMString size; // DOM level 2 changed this to a long, but our existing API is a string
#else
// FIXME: the spec says this should be a long, not an unsigned long
attribute unsigned long size; // Changed string -> long as part of DOM level 2
#endif
attribute [ConvertNullToNullString] DOMString src;
- attribute [ConvertNullToNullString] DOMString type; // readonly dropped as part of DOM level 2
+ attribute [ConvertNullToNullString, JSCCustomGetter] DOMString type; // readonly dropped as part of DOM level 2
attribute [ConvertNullToNullString] DOMString useMap;
attribute [ConvertNullToNullString] DOMString value;
readonly attribute boolean willValidate;
diff --git a/WebCore/html/HTMLIsIndexElement.cpp b/WebCore/html/HTMLIsIndexElement.cpp
index 7bc98b6..bcfa623 100644
--- a/WebCore/html/HTMLIsIndexElement.cpp
+++ b/WebCore/html/HTMLIsIndexElement.cpp
@@ -24,7 +24,9 @@
#include "config.h"
#include "HTMLIsIndexElement.h"
+
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
@@ -41,6 +43,8 @@ void HTMLIsIndexElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == promptAttr)
setValue(attr->value());
+ else if (attr->name() == placeholderAttr)
+ updatePlaceholderVisibility();
else
// don't call HTMLInputElement::parseMappedAttribute here, as it would
// accept attributes this element does not support
diff --git a/WebCore/html/HTMLKeygenElement.cpp b/WebCore/html/HTMLKeygenElement.cpp
index 563ad3c..b1b6238 100644
--- a/WebCore/html/HTMLKeygenElement.cpp
+++ b/WebCore/html/HTMLKeygenElement.cpp
@@ -29,6 +29,7 @@
#include "FormDataList.h"
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
+#include "MappedAttribute.h"
#include "SSLKeyGenerator.h"
#include "Text.h"
#include <wtf/StdLibExtras.h>
@@ -54,7 +55,7 @@ HTMLKeygenElement::HTMLKeygenElement(const QualifiedName& tagName, Document* doc
}
}
-const AtomicString& HTMLKeygenElement::type() const
+const AtomicString& HTMLKeygenElement::formControlType() const
{
DEFINE_STATIC_LOCAL(const AtomicString, keygen, ("keygen"));
return keygen;
diff --git a/WebCore/html/HTMLKeygenElement.h b/WebCore/html/HTMLKeygenElement.h
index 7997635..b2a0c26 100644
--- a/WebCore/html/HTMLKeygenElement.h
+++ b/WebCore/html/HTMLKeygenElement.h
@@ -33,7 +33,7 @@ public:
HTMLKeygenElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
virtual int tagPriority() const { return 0; }
- virtual const AtomicString& type() const;
+ virtual const AtomicString& formControlType() const;
virtual bool isEnumeratable() const { return false; }
virtual void parseMappedAttribute(MappedAttribute*);
virtual bool appendFormData(FormDataList&, bool);
diff --git a/WebCore/html/HTMLLIElement.cpp b/WebCore/html/HTMLLIElement.cpp
index 2d5518e..044b93c 100644
--- a/WebCore/html/HTMLLIElement.cpp
+++ b/WebCore/html/HTMLLIElement.cpp
@@ -26,6 +26,7 @@
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderListItem.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLLegendElement.cpp b/WebCore/html/HTMLLegendElement.cpp
index 4092643..d6e08c7 100644
--- a/WebCore/html/HTMLLegendElement.cpp
+++ b/WebCore/html/HTMLLegendElement.cpp
@@ -47,7 +47,7 @@ bool HTMLLegendElement::isFocusable() const
return HTMLElement::isFocusable();
}
-const AtomicString& HTMLLegendElement::type() const
+const AtomicString& HTMLLegendElement::formControlType() const
{
DEFINE_STATIC_LOCAL(const AtomicString, legend, ("legend"));
return legend;
diff --git a/WebCore/html/HTMLLegendElement.h b/WebCore/html/HTMLLegendElement.h
index 6d01dce..713d73c 100644
--- a/WebCore/html/HTMLLegendElement.h
+++ b/WebCore/html/HTMLLegendElement.h
@@ -34,7 +34,7 @@ public:
virtual ~HTMLLegendElement();
virtual bool isFocusable() const;
- virtual const AtomicString& type() const;
+ virtual const AtomicString& formControlType() const;
virtual void accessKeyAction(bool sendToAnyElement);
/**
diff --git a/WebCore/html/HTMLLinkElement.cpp b/WebCore/html/HTMLLinkElement.cpp
index 28bf2fa..76a9703 100644
--- a/WebCore/html/HTMLLinkElement.cpp
+++ b/WebCore/html/HTMLLinkElement.cpp
@@ -3,6 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Rob Buis (rwlbuis@gmail.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -33,6 +34,7 @@
#include "FrameLoaderClient.h"
#include "FrameTree.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
#include "Page.h"
@@ -182,37 +184,28 @@ void HTMLLinkElement::process()
// Stylesheet
// This was buggy and would incorrectly match <link rel="alternate">, which has a different specified meaning. -dwh
if (m_disabledState != 2 && m_isStyleSheet && document()->frame() && m_url.isValid()) {
- // no need to load style sheets which aren't for the screen output
- // ### there may be in some situations e.g. for an editor or script to manipulate
// also, don't load style sheets for standalone documents
- MediaQueryEvaluator allEval(true);
- MediaQueryEvaluator screenEval("screen", true);
- MediaQueryEvaluator printEval("print", true);
- RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media);
- if (allEval.eval(media.get()) || screenEval.eval(media.get()) || printEval.eval(media.get())) {
-
- // Add ourselves as a pending sheet, but only if we aren't an alternate
- // stylesheet. Alternate stylesheets don't hold up render tree construction.
- if (!isAlternate())
- document()->addPendingSheet();
+ // Add ourselves as a pending sheet, but only if we aren't an alternate
+ // stylesheet. Alternate stylesheets don't hold up render tree construction.
+ if (!isAlternate())
+ document()->addPendingSheet();
+
+ String charset = getAttribute(charsetAttr);
+ if (charset.isEmpty() && document()->frame())
+ charset = document()->frame()->loader()->encoding();
- String chset = getAttribute(charsetAttr);
- if (chset.isEmpty() && document()->frame())
- chset = document()->frame()->loader()->encoding();
-
- if (m_cachedSheet) {
- if (m_loading)
- document()->removePendingSheet();
- m_cachedSheet->removeClient(this);
- }
- m_loading = true;
- m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(m_url.string(), chset);
- if (m_cachedSheet)
- m_cachedSheet->addClient(this);
- else if (!isAlternate()) { // request may have been denied if stylesheet is local and document is remote.
- m_loading = false;
+ if (m_cachedSheet) {
+ if (m_loading)
document()->removePendingSheet();
- }
+ m_cachedSheet->removeClient(this);
+ }
+ m_loading = true;
+ m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(m_url, charset);
+ if (m_cachedSheet)
+ m_cachedSheet->addClient(this);
+ else if (!isAlternate()) { // The request may have been denied if stylesheet is local and document is remote.
+ m_loading = false;
+ document()->removePendingSheet();
}
} else if (m_sheet) {
// we no longer contain a stylesheet, e.g. perhaps rel or type was changed
diff --git a/WebCore/html/HTMLLinkElement.idl b/WebCore/html/HTMLLinkElement.idl
index 532ac31..98de809 100644
--- a/WebCore/html/HTMLLinkElement.idl
+++ b/WebCore/html/HTMLLinkElement.idl
@@ -35,12 +35,12 @@ module html {
attribute [ConvertNullToNullString] DOMString target;
attribute [ConvertNullToNullString] DOMString type;
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
// DOM Level 2 Style
readonly attribute StyleSheet sheet;
#endif
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// Objective-C extension:
readonly attribute URL absoluteLinkURL;
#endif
diff --git a/WebCore/html/HTMLMapElement.cpp b/WebCore/html/HTMLMapElement.cpp
index d7109c9..90204e0 100644
--- a/WebCore/html/HTMLMapElement.cpp
+++ b/WebCore/html/HTMLMapElement.cpp
@@ -18,6 +18,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLMapElement.h"
@@ -25,8 +26,9 @@
#include "HTMLAreaElement.h"
#include "HTMLCollection.h"
#include "HTMLNames.h"
-#include "IntSize.h"
#include "HitTestResult.h"
+#include "IntSize.h"
+#include "MappedAttribute.h"
using namespace std;
@@ -96,7 +98,7 @@ void HTMLMapElement::parseMappedAttribute(MappedAttribute* attr)
PassRefPtr<HTMLCollection> HTMLMapElement::areas()
{
- return HTMLCollection::create(this, HTMLCollection::MapAreas);
+ return HTMLCollection::create(this, MapAreas);
}
String HTMLMapElement::name() const
diff --git a/WebCore/html/HTMLMarqueeElement.cpp b/WebCore/html/HTMLMarqueeElement.cpp
index 040b6fb..d62eaab 100644
--- a/WebCore/html/HTMLMarqueeElement.cpp
+++ b/WebCore/html/HTMLMarqueeElement.cpp
@@ -19,12 +19,14 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#include "config.h"
#include "HTMLMarqueeElement.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderLayer.h"
#include "RenderMarquee.h"
@@ -37,6 +39,7 @@ const int defaultMinimumDelay = 60;
HTMLMarqueeElement::HTMLMarqueeElement(const QualifiedName& tagName, Document* doc)
: HTMLElement(tagName, doc)
+ , ActiveDOMObject(doc, this)
, m_minimumDelay(defaultMinimumDelay)
{
ASSERT(hasTagName(marqueeTag));
@@ -119,4 +122,21 @@ void HTMLMarqueeElement::stop()
renderBox()->layer()->marquee()->stop();
}
+bool HTMLMarqueeElement::canSuspend() const
+{
+ return true;
+}
+
+void HTMLMarqueeElement::suspend()
+{
+ if (renderer() && renderer()->hasLayer() && renderBox()->layer()->marquee())
+ renderBox()->layer()->marquee()->suspend();
+}
+
+void HTMLMarqueeElement::resume()
+{
+ if (renderer() && renderer()->hasLayer() && renderBox()->layer()->marquee())
+ renderBox()->layer()->marquee()->updateMarqueePosition();
+}
+
} // namespace WebCore
diff --git a/WebCore/html/HTMLMarqueeElement.h b/WebCore/html/HTMLMarqueeElement.h
index acd639b..2423fc6 100644
--- a/WebCore/html/HTMLMarqueeElement.h
+++ b/WebCore/html/HTMLMarqueeElement.h
@@ -23,11 +23,12 @@
#ifndef HTMLMarqueeElement_h
#define HTMLMarqueeElement_h
+#include "ActiveDOMObject.h"
#include "HTMLElement.h"
namespace WebCore {
-class HTMLMarqueeElement : public HTMLElement {
+class HTMLMarqueeElement : public HTMLElement, private ActiveDOMObject {
public:
HTMLMarqueeElement(const QualifiedName&, Document*);
@@ -45,6 +46,11 @@ public:
void stop();
private:
+ // ActiveDOMObject
+ virtual bool canSuspend() const;
+ virtual void suspend();
+ virtual void resume();
+
int m_minimumDelay;
};
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index df0ed04..6ad0653 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -28,10 +28,11 @@
#if ENABLE(VIDEO)
#include "HTMLMediaElement.h"
-#include "ContentType.h"
#include "CSSHelper.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
+#include "ContentType.h"
+#include "DocLoader.h"
#include "Event.h"
#include "EventNames.h"
#include "ExceptionCode.h"
@@ -41,25 +42,25 @@
#include "HTMLNames.h"
#include "HTMLSourceElement.h"
#include "HTMLVideoElement.h"
-#include <limits>
+#include "MIMETypeRegistry.h"
+#include "MappedAttribute.h"
+#include "MediaDocument.h"
#include "MediaError.h"
#include "MediaList.h"
-#include "MediaQueryEvaluator.h"
-#include "MIMETypeRegistry.h"
#include "MediaPlayer.h"
+#include "MediaQueryEvaluator.h"
#include "Page.h"
#include "ProgressEvent.h"
#include "RenderVideo.h"
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-#include "RenderPartObject.h"
-#endif
#include "TimeRanges.h"
+#include <limits>
+#include <wtf/CurrentTime.h>
+#include <wtf/MathExtras.h>
+
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "RenderPartObject.h"
#include "Widget.h"
#endif
-#include <wtf/CurrentTime.h>
-#include <wtf/MathExtras.h>
-#include <limits>
using namespace std;
@@ -73,12 +74,13 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired)
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
, m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
+ , m_playedTimeRanges()
, m_playbackRate(1.0f)
, m_defaultPlaybackRate(1.0f)
, m_networkState(NETWORK_EMPTY)
, m_readyState(HAVE_NOTHING)
, m_volume(1.0f)
- , m_currentTimeDuringSeek(0)
+ , m_lastSeekTime(0)
, m_previousProgress(0)
, m_previousProgressTime(numeric_limits<double>::max())
, m_lastTimeUpdateEventWallTime(0)
@@ -87,6 +89,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_currentSourceNode(0)
, m_player(0)
, m_restrictions(NoRestrictions)
+ , m_playing(false)
, m_processingMediaPlayerCallback(0)
, m_processingLoad(false)
, m_delayingTheLoadEvent(false)
@@ -140,7 +143,16 @@ void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
}
#endif
}
-
+
+void HTMLMediaElement::parseMappedAttribute(MappedAttribute *attr)
+{
+ if (attr->name() == autobufferAttr) {
+ if (m_player)
+ m_player->setAutobuffer(!attr->isNull());
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
bool HTMLMediaElement::rendererIsNeeded(RenderStyle* style)
{
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
@@ -231,7 +243,7 @@ void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
void HTMLMediaElement::enqueueEvent(RefPtr<Event> event)
{
m_pendingEvents.append(event);
- if (!m_asyncEventTimer.isActive())
+ if (!m_asyncEventTimer.isActive())
m_asyncEventTimer.startOneShot(0);
}
@@ -362,7 +374,7 @@ void HTMLMediaElement::loadInternal()
// 3 - If there are any tasks from the media element's media element event task source in
// one of the task queues, then remove those tasks.
- m_pendingEvents.clear();
+ cancelPendingEventsAndCallbacks();
// 4 - If the media element's networkState is set to NETWORK_LOADING or NETWORK_IDLE, set the
// error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORTED,
@@ -380,6 +392,8 @@ void HTMLMediaElement::loadInternal()
// 5
m_error = 0;
m_autoplaying = true;
+ m_playedTimeRanges = TimeRanges::create();
+ m_lastSeekTime = 0;
// 6
setPlaybackRate(defaultPlaybackRate());
@@ -392,9 +406,10 @@ void HTMLMediaElement::loadInternal()
m_seeking = false;
if (m_player) {
m_player->pause();
+ m_playing = false;
m_player->seek(0);
}
- dispatchEventForType(eventNames().emptiedEvent, false, true);
+ dispatchEvent(eventNames().emptiedEvent, false, true);
}
selectMediaResource();
@@ -430,9 +445,13 @@ void HTMLMediaElement::selectMediaResource()
// 5 - If the media element has a src attribute, then run these substeps
ContentType contentType("");
if (!mediaSrc.isEmpty()) {
- mediaSrc = document()->completeURL(mediaSrc).string();
- m_loadState = LoadingFromSrcAttr;
- loadResource(mediaSrc, contentType);
+ KURL mediaURL = document()->completeURL(mediaSrc);
+ if (isSafeToLoadURL(mediaURL, Complain)) {
+ m_loadState = LoadingFromSrcAttr;
+ loadResource(mediaURL, contentType);
+ } else
+ noneSupported();
+
return;
}
@@ -444,22 +463,23 @@ void HTMLMediaElement::selectMediaResource()
void HTMLMediaElement::loadNextSourceChild()
{
ContentType contentType("");
- String mediaSrc;
-
- mediaSrc = nextSourceChild(&contentType);
- if (mediaSrc.isEmpty()) {
- noneSupported();
+ KURL mediaURL = selectNextSourceChild(&contentType, Complain);
+ if (!mediaURL.isValid()) {
+ // It seems wrong to fail silently when we give up because no suitable <source>
+ // element can be found and set the error attribute if the element's 'src' attribute
+ // fails, but that is what the spec says.
return;
}
m_loadState = LoadingFromSourceElement;
- loadResource(mediaSrc, contentType);
+ loadResource(mediaURL, contentType);
}
-void HTMLMediaElement::loadResource(String url, ContentType& contentType)
+void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType)
{
- // The resource fetch algorithm
+ ASSERT(isSafeToLoadURL(url, Complain));
+ // The resource fetch algorithm
m_networkState = NETWORK_LOADING;
m_currentSrc = url;
@@ -483,6 +503,21 @@ void HTMLMediaElement::loadResource(String url, ContentType& contentType)
renderer()->updateFromElement();
}
+bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction actionIfInvalid)
+{
+ Frame* frame = document()->frame();
+ FrameLoader* loader = frame ? frame->loader() : 0;
+
+ // don't allow remote to local urls
+ if (!loader || !loader->canLoad(url, String(), document())) {
+ if (actionIfInvalid == Complain)
+ FrameLoader::reportLocalLoadFailed(frame, url.string());
+ return false;
+ }
+
+ return true;
+}
+
void HTMLMediaElement::startProgressEventTimer()
{
if (m_progressEventTimer.isActive())
@@ -502,8 +537,8 @@ void HTMLMediaElement::noneSupported()
// 3 - Reaching this step indicates that either the URL failed to resolve, or the media
// resource failed to load. Set the error attribute to a new MediaError object whose
- // code attribute is set to MEDIA_ERR_NONE_SUPPORTED.
- m_error = MediaError::create(MediaError::MEDIA_ERR_NONE_SUPPORTED);
+ // code attribute is set to MEDIA_ERR_SRC_NOT_SUPPORTED.
+ m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
// 4- Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
m_networkState = NETWORK_NO_SOURCE;
@@ -548,6 +583,16 @@ void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
}
+void HTMLMediaElement::cancelPendingEventsAndCallbacks()
+{
+ m_pendingEvents.clear();
+
+ for (Node* node = firstChild(); node; node = node->nextSibling()) {
+ if (node->hasTagName(sourceTag))
+ static_cast<HTMLSourceElement*>(node)->cancelPendingErrorEvent();
+ }
+}
+
void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
{
beginProcessingMediaPlayerCallback();
@@ -567,9 +612,11 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
stopPeriodicTimers();
// If we failed while trying to load a <source> element, the movie was never parsed, and there are more
- // <source> children, schedule the next one without reporting an error
- if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement && havePotentialSourceChild()) {
- scheduleLoad();
+ // <source> children, schedule the next one
+ if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
+ m_currentSourceNode->scheduleErrorEvent();
+ if (havePotentialSourceChild())
+ scheduleLoad();
return;
}
@@ -577,7 +624,7 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_NETWORK));
else if (state == MediaPlayer::DecodeError)
mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_DECODE));
- else if (state == MediaPlayer::FormatError)
+ else if (state == MediaPlayer::FormatError && m_loadState == LoadingFromSrcAttr)
noneSupported();
if (isVideo())
@@ -586,31 +633,37 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
return;
}
- if (state == MediaPlayer::Idle && m_networkState > NETWORK_IDLE) {
+ if (state == MediaPlayer::Idle) {
ASSERT(static_cast<ReadyState>(m_player->readyState()) < HAVE_ENOUGH_DATA);
+ if (m_networkState > NETWORK_IDLE) {
+ stopPeriodicTimers();
+ scheduleProgressEvent(eventNames().suspendEvent);
+ }
m_networkState = NETWORK_IDLE;
- stopPeriodicTimers();
- scheduleProgressEvent(eventNames().suspendEvent);
}
- if (state == MediaPlayer::Loading && (m_networkState < NETWORK_LOADING || m_networkState == NETWORK_NO_SOURCE)) {
- ASSERT(static_cast<ReadyState>(m_player->readyState()) < HAVE_ENOUGH_DATA);
+ if (state == MediaPlayer::Loading) {
+ if (m_networkState < NETWORK_LOADING || m_networkState == NETWORK_NO_SOURCE)
+ startProgressEventTimer();
m_networkState = NETWORK_LOADING;
- startProgressEventTimer();
}
- if (state == MediaPlayer::Loaded && (m_networkState < NETWORK_LOADED || m_networkState == NETWORK_NO_SOURCE)) {
+ if (state == MediaPlayer::Loaded) {
+ NetworkState oldState = m_networkState;
+
m_networkState = NETWORK_LOADED;
- m_progressEventTimer.stop();
+ if (oldState < NETWORK_LOADED || oldState == NETWORK_NO_SOURCE) {
+ m_progressEventTimer.stop();
- // Check to see if readyState changes need to be dealt with before sending the
- // 'load' event so we report 'canplaythrough' first. This is necessary because a
- // media engine reports readyState and networkState changes separately
- MediaPlayer::ReadyState currentState = m_player->readyState();
- if (static_cast<ReadyState>(currentState) != m_readyState)
- setReadyState(currentState);
+ // Check to see if readyState changes need to be dealt with before sending the
+ // 'load' event so we report 'canplaythrough' first. This is necessary because a
+ // media engine reports readyState and networkState changes separately
+ MediaPlayer::ReadyState currentState = m_player->readyState();
+ if (static_cast<ReadyState>(currentState) != m_readyState)
+ setReadyState(currentState);
- scheduleProgressEvent(eventNames().loadEvent);
+ scheduleProgressEvent(eventNames().loadEvent);
+ }
}
}
@@ -676,11 +729,6 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
}
bool isPotentiallyPlaying = potentiallyPlaying();
- if (m_readyState <= HAVE_CURRENT_DATA && oldState >= HAVE_FUTURE_DATA) {
- if (isPotentiallyPlaying)
- scheduleEvent(eventNames().waitingEvent);
- }
-
if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA) {
scheduleEvent(eventNames().canplayEvent);
if (isPotentiallyPlaying)
@@ -763,7 +811,11 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec)
return;
// 5
- m_currentTimeDuringSeek = time;
+ if (m_playing) {
+ if (m_lastSeekTime < now)
+ m_playedTimeRanges->add(m_lastSeekTime, now);
+ }
+ m_lastSeekTime = time;
// 6 - set the seeking flag, it will be cleared when the engine tells is the time has actually changed
m_seeking = true;
@@ -794,7 +846,7 @@ float HTMLMediaElement::currentTime() const
if (!m_player)
return 0;
if (m_seeking)
- return m_currentTimeDuringSeek;
+ return m_lastSeekTime;
return m_player->currentTime();
}
@@ -803,6 +855,13 @@ void HTMLMediaElement::setCurrentTime(float time, ExceptionCode& ec)
seek(time, ec);
}
+float HTMLMediaElement::startTime() const
+{
+ if (!m_player)
+ return 0;
+ return m_player->startTime();
+}
+
float HTMLMediaElement::duration() const
{
if (m_readyState >= HAVE_METADATA)
@@ -859,6 +918,16 @@ void HTMLMediaElement::setAutoplay(bool b)
setBooleanAttribute(autoplayAttr, b);
}
+bool HTMLMediaElement::autobuffer() const
+{
+ return hasAttribute(autobufferAttr);
+}
+
+void HTMLMediaElement::setAutobuffer(bool b)
+{
+ setBooleanAttribute(autobufferAttr, b);
+}
+
void HTMLMediaElement::play()
{
if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture())
@@ -1065,55 +1134,65 @@ bool HTMLMediaElement::havePotentialSourceChild()
{
// Stash the current <source> node so we can restore it after checking
// to see there is another potential
- Node* currentSourceNode = m_currentSourceNode;
- String nextUrl = nextSourceChild();
+ HTMLSourceElement* currentSourceNode = m_currentSourceNode;
+ KURL nextURL = selectNextSourceChild(0, DoNothing);
m_currentSourceNode = currentSourceNode;
- return !nextUrl.isEmpty();
+ return nextURL.isValid();
}
-String HTMLMediaElement::nextSourceChild(ContentType *contentType)
+KURL HTMLMediaElement::selectNextSourceChild(ContentType *contentType, InvalidSourceAction actionIfInvalid)
{
- String mediaSrc;
+ KURL mediaURL;
+ Node* node;
bool lookingForPreviousNode = m_currentSourceNode;
+ bool canUse = false;
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
+ for (node = firstChild(); !canUse && node; node = node->nextSibling()) {
if (!node->hasTagName(sourceTag))
continue;
if (lookingForPreviousNode) {
- if (m_currentSourceNode == node)
+ if (m_currentSourceNode == static_cast<HTMLSourceElement*>(node))
lookingForPreviousNode = false;
continue;
}
-
+
HTMLSourceElement* source = static_cast<HTMLSourceElement*>(node);
if (!source->hasAttribute(srcAttr))
- continue;
+ goto check_again;
+
if (source->hasAttribute(mediaAttr)) {
MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media());
- if (!screenEval.eval(media.get()))
- continue;
+ if (!screenEval.eval(media.get()))
+ goto check_again;
}
- if (source->hasAttribute(typeAttr)) {
- ContentType type(source->type());
- if (!MediaPlayer::supportsType(type))
- continue;
- // return type with all parameters in place so the media engine can use them
- if (contentType)
- *contentType = type;
+ if (source->hasAttribute(typeAttr)) {
+ if (!MediaPlayer::supportsType(ContentType(source->type())))
+ goto check_again;
}
- mediaSrc = source->src().string();
- m_currentSourceNode = node;
- break;
- }
- if (!mediaSrc.isEmpty())
- mediaSrc = document()->completeURL(mediaSrc).string();
+ // Is it safe to load this url?
+ mediaURL = source->src();
+ if (!mediaURL.isValid() || !isSafeToLoadURL(mediaURL, actionIfInvalid))
+ goto check_again;
+
+ // Making it this far means the <source> looks reasonable
+ canUse = true;
+ if (contentType)
+ *contentType = ContentType(source->type());
+
+check_again:
+ if (!canUse && actionIfInvalid == Complain)
+ source->scheduleErrorEvent();
+ m_currentSourceNode = static_cast<HTMLSourceElement*>(node);
+ }
- return mediaSrc;
+ if (!canUse)
+ m_currentSourceNode = 0;
+ return canUse ? mediaURL : KURL();
}
void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
@@ -1127,7 +1206,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
float now = currentTime();
float dur = duration();
- if (now >= dur) {
+ if (!isnan(dur) && dur && now >= dur) {
if (loop()) {
ExceptionCode ignoredException;
m_sentEndEvent = false;
@@ -1195,6 +1274,17 @@ void HTMLMediaElement::mediaPlayerSizeChanged(MediaPlayer*)
endProcessingMediaPlayerCallback();
}
+void HTMLMediaElement::mediaPlayerSawUnsupportedTracks(MediaPlayer*)
+{
+ // The MediaPlayer came across content it cannot completely handle.
+ // This is normally acceptable except when we are in a standalone
+ // MediaDocument. If so, tell the document what has happened.
+ if (ownerDocument()->isMediaDocument()) {
+ MediaDocument* mediaDocument = static_cast<MediaDocument*>(ownerDocument());
+ mediaDocument->mediaElementSawUnsupportedTracks();
+ }
+}
+
PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
{
// FIXME real ranges support
@@ -1205,8 +1295,16 @@ PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
PassRefPtr<TimeRanges> HTMLMediaElement::played() const
{
- // FIXME track played
- return TimeRanges::create();
+ if (!m_playedTimeRanges) {
+ // We are not yet loaded
+ return TimeRanges::create();
+ }
+ if (m_playing) {
+ float time = currentTime();
+ if (m_lastSeekTime < time)
+ m_playedTimeRanges->add(m_lastSeekTime, time);
+ }
+ return m_playedTimeRanges->copy();
}
PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
@@ -1224,7 +1322,11 @@ bool HTMLMediaElement::potentiallyPlaying() const
bool HTMLMediaElement::endedPlayback() const
{
- return m_player && m_readyState >= HAVE_METADATA && currentTime() >= duration() && !loop();
+ if (!m_player || m_readyState < HAVE_METADATA)
+ return false;
+
+ float dur = duration();
+ return !isnan(dur) && currentTime() >= dur && !loop();
}
bool HTMLMediaElement::stoppedDueToErrors() const
@@ -1281,9 +1383,14 @@ void HTMLMediaElement::updatePlayState()
m_player->setRate(m_playbackRate);
m_player->play();
startPlaybackProgressTimer();
+ m_playing = true;
} else if (!shouldBePlaying && !playerPaused) {
m_player->pause();
m_playbackProgressTimer.stop();
+ m_playing = false;
+ float time = currentTime();
+ if (m_lastSeekTime < time)
+ m_playedTimeRanges->add(m_lastSeekTime, time);
}
if (renderer())
@@ -1419,15 +1526,12 @@ void HTMLMediaElement::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
String HTMLMediaElement::initialURL()
{
- String initialSrc = mediaSrc = getAttribute(srcAttr);
+ KURL initialSrc = document()->completeURL(getAttribute(srcAttr));
- if (initialSrc.isEmpty())
- initialSrc = nextSourceChild();
-
- if (!initialSrc.isEmpty())
- initialSrc = document()->completeURL(initialSrc).string();
+ if (!initialSrc.isValid())
+ initialSrc = selectNextSourceChild(0, DoNothing).string();
- m_currentSrc = initialSrc;
+ m_currentSrc = initialSrc.string();
return initialSrc;
}
@@ -1438,7 +1542,7 @@ void HTMLMediaElement::finishParsingChildren()
if (!m_player)
m_player.set(new MediaPlayer(this));
- document()->updateRendering();
+ document()->updateStyleIfNeeded();
if (m_needWidgetUpdate && renderer())
static_cast<RenderPartObject*>(renderer())->updateWidget(true);
}
diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h
index ab0ab11..65c542b 100644
--- a/WebCore/html/HTMLMediaElement.h
+++ b/WebCore/html/HTMLMediaElement.h
@@ -39,6 +39,7 @@
namespace WebCore {
class Event;
+class HTMLSourceElement;
class MediaError;
class KURL;
class TimeRanges;
@@ -51,6 +52,7 @@ public:
bool checkDTD(const Node* newChild);
void attributeChanged(Attribute*, bool preserveDecls);
+ void parseMappedAttribute(MappedAttribute *);
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
@@ -84,9 +86,11 @@ public:
enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_LOADED, NETWORK_NO_SOURCE };
NetworkState networkState() const;
+ bool autobuffer() const;
+ void setAutobuffer(bool);
+
PassRefPtr<TimeRanges> buffered() const;
void load(ExceptionCode&);
-
String canPlayType(const String& mimeType) const;
// ready state
@@ -97,6 +101,7 @@ public:
// playback state
float currentTime() const;
void setCurrentTime(float, ExceptionCode&);
+ float startTime() const;
float duration() const;
bool paused() const;
float defaultPlaybackRate() const;
@@ -154,6 +159,7 @@ private: // MediaPlayerObserver
virtual void mediaPlayerDurationChanged(MediaPlayer*);
virtual void mediaPlayerRateChanged(MediaPlayer*);
virtual void mediaPlayerSizeChanged(MediaPlayer*);
+ virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
private:
void loadTimerFired(Timer<HTMLMediaElement>*);
@@ -174,13 +180,17 @@ private:
// loading
void selectMediaResource();
- void loadResource(String url, ContentType& contentType);
+ void loadResource(const KURL&, ContentType&);
void loadNextSourceChild();
void userCancelledLoad();
- String nextSourceChild(ContentType* contentType = 0);
bool havePotentialSourceChild();
void noneSupported();
void mediaEngineError(PassRefPtr<MediaError> err);
+ void cancelPendingEventsAndCallbacks();
+
+ enum InvalidSourceAction { DoNothing, Complain };
+ bool isSafeToLoadURL(const KURL&, InvalidSourceAction);
+ KURL selectNextSourceChild(ContentType*, InvalidSourceAction);
// These "internal" functions do not check user gesture restrictions.
void loadInternal();
@@ -214,6 +224,7 @@ protected:
Timer<HTMLMediaElement> m_progressEventTimer;
Timer<HTMLMediaElement> m_playbackProgressTimer;
Vector<RefPtr<Event> > m_pendingEvents;
+ RefPtr<TimeRanges> m_playedTimeRanges;
float m_playbackRate;
float m_defaultPlaybackRate;
@@ -224,7 +235,7 @@ protected:
RefPtr<MediaError> m_error;
float m_volume;
- float m_currentTimeDuringSeek;
+ float m_lastSeekTime;
unsigned m_previousProgress;
double m_previousProgressTime;
@@ -238,12 +249,14 @@ protected:
// loading state
enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
LoadState m_loadState;
- Node *m_currentSourceNode;
+ HTMLSourceElement *m_currentSourceNode;
OwnPtr<MediaPlayer> m_player;
BehaviorRestrictions m_restrictions;
+ bool m_playing;
+
// counter incremented while processing a callback from the media player, so we can avoid
// calling the media engine recursively
int m_processingMediaPlayerCallback;
diff --git a/WebCore/html/HTMLMediaElement.idl b/WebCore/html/HTMLMediaElement.idl
index 931980b..008e059 100644
--- a/WebCore/html/HTMLMediaElement.idl
+++ b/WebCore/html/HTMLMediaElement.idl
@@ -39,6 +39,7 @@ interface [GenerateConstructor, Conditional=VIDEO] HTMLMediaElement : HTMLElemen
const unsigned short NETWORK_LOADED = 3;
const unsigned short NETWORK_NO_SOURCE = 4;
readonly attribute unsigned short networkState;
+ attribute boolean autobuffer;
readonly attribute TimeRanges buffered;
void load()
@@ -57,6 +58,7 @@ interface [GenerateConstructor, Conditional=VIDEO] HTMLMediaElement : HTMLElemen
// playback state
attribute float currentTime
setter raises (DOMException);
+ readonly attribute float startTime;
readonly attribute float duration;
readonly attribute boolean paused;
attribute float defaultPlaybackRate;
diff --git a/WebCore/html/HTMLMetaElement.cpp b/WebCore/html/HTMLMetaElement.cpp
index 0a07651..48284e3 100644
--- a/WebCore/html/HTMLMetaElement.cpp
+++ b/WebCore/html/HTMLMetaElement.cpp
@@ -19,11 +19,13 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLMetaElement.h"
#include "Document.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLNameCollection.cpp b/WebCore/html/HTMLNameCollection.cpp
index fdebe78..d5657da 100644
--- a/WebCore/html/HTMLNameCollection.cpp
+++ b/WebCore/html/HTMLNameCollection.cpp
@@ -32,7 +32,7 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLNameCollection::HTMLNameCollection(PassRefPtr<Document> document, Type type, const String& name)
+HTMLNameCollection::HTMLNameCollection(PassRefPtr<Document> document, CollectionType type, const String& name)
: HTMLCollection(document.get(), type, document->nameCollectionInfo(type, name))
, m_name(name)
{
diff --git a/WebCore/html/HTMLNameCollection.h b/WebCore/html/HTMLNameCollection.h
index 9add926..3e990d7 100644
--- a/WebCore/html/HTMLNameCollection.h
+++ b/WebCore/html/HTMLNameCollection.h
@@ -32,13 +32,13 @@ class Document;
class HTMLNameCollection : public HTMLCollection {
public:
- static PassRefPtr<HTMLNameCollection> create(PassRefPtr<Document> document, Type type, const String& name)
+ static PassRefPtr<HTMLNameCollection> create(PassRefPtr<Document> document, CollectionType type, const String& name)
{
return adoptRef(new HTMLNameCollection(document, type, name));
}
private:
- HTMLNameCollection(PassRefPtr<Document>, Type, const String& name);
+ HTMLNameCollection(PassRefPtr<Document>, CollectionType, const String& name);
virtual Element* itemAfter(Element*) const;
diff --git a/WebCore/html/HTMLNoScriptElement.cpp b/WebCore/html/HTMLNoScriptElement.cpp
new file mode 100644
index 0000000..3bbfbe6
--- /dev/null
+++ b/WebCore/html/HTMLNoScriptElement.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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(XHTMLMP)
+#include "HTMLNoScriptElement.h"
+
+#include "CSSStyleSelector.h"
+#include "HTMLNames.h"
+#include "RenderObject.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLNoScriptElement::HTMLNoScriptElement(const QualifiedName& tagName, Document* doc)
+ : HTMLElement(tagName, doc)
+{
+ ASSERT(hasTagName(noscriptTag));
+}
+
+HTMLNoScriptElement::~HTMLNoScriptElement()
+{
+}
+
+bool HTMLNoScriptElement::checkDTD(const Node* newChild)
+{
+ return newChild->isTextNode() || inBlockTagList(newChild);
+}
+
+void HTMLNoScriptElement::attach()
+{
+ HTMLElement::attach();
+
+ // If no need to process <noscript>, we hide it by setting display:none temporarily
+ if (!document()->shouldProcessNoscriptElement()) {
+ if (renderer() && renderer()->style())
+ renderer()->style()->setDisplay(NONE);
+ setNeedsStyleRecalc();
+ }
+}
+
+void HTMLNoScriptElement::recalcStyle(StyleChange change)
+{
+ if (!document()->shouldProcessNoscriptElement() || !renderer() || !renderer()->style())
+ return;
+
+ // If <noscript> needs processing, we make it visiable here, including its visible children
+ RefPtr<RenderStyle> style = renderer()->style();
+ if (style->display() == NONE) {
+ style->setDisplay(INLINE);
+
+ // Create renderers for its children
+ if (hasChildNodes()) {
+ for (Node* n = firstChild(); n; n = n->traverseNextNode(this))
+ if (!n->renderer())
+ n->createRendererIfNeeded();
+ }
+ }
+}
+
+bool HTMLNoScriptElement::childShouldCreateRenderer(Node* child) const
+{
+ return document()->shouldProcessNoscriptElement();
+}
+
+}
+#endif
diff --git a/WebCore/html/HTMLNoScriptElement.h b/WebCore/html/HTMLNoScriptElement.h
new file mode 100644
index 0000000..2cc5a3c
--- /dev/null
+++ b/WebCore/html/HTMLNoScriptElement.h
@@ -0,0 +1,46 @@
+/*
+ * 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 HTMLNoScriptElement_h
+#define HTMLNoScriptElement_h
+
+#if ENABLE(XHTMLMP)
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLNoScriptElement : public HTMLElement {
+public:
+ HTMLNoScriptElement(const QualifiedName&, Document*);
+
+private:
+ virtual ~HTMLNoScriptElement();
+
+ virtual bool checkDTD(const Node*);
+ virtual void attach();
+ virtual void recalcStyle(StyleChange);
+ virtual bool childShouldCreateRenderer(Node*) const;
+ virtual bool rendererIsNeeded(RenderStyle*) { return true; }
+};
+
+} //namespace
+
+#endif
+#endif
diff --git a/WebCore/html/HTMLOListElement.cpp b/WebCore/html/HTMLOListElement.cpp
index c1e0d7c..63fd437 100644
--- a/WebCore/html/HTMLOListElement.cpp
+++ b/WebCore/html/HTMLOListElement.cpp
@@ -18,12 +18,14 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#include "config.h"
#include "HTMLOListElement.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderListItem.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLObjectElement.cpp b/WebCore/html/HTMLObjectElement.cpp
index a41e037..6be41c9 100644
--- a/WebCore/html/HTMLObjectElement.cpp
+++ b/WebCore/html/HTMLObjectElement.cpp
@@ -32,14 +32,15 @@
#include "HTMLFormElement.h"
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
+#include "ScriptEventListener.h"
#include "MIMETypeRegistry.h"
+#include "MappedAttribute.h"
#include "RenderImage.h"
#include "RenderPartObject.h"
#include "RenderWidget.h"
#include "ScriptController.h"
#include "Text.h"
-
namespace WebCore {
using namespace HTMLNames;
@@ -94,7 +95,7 @@ void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr)
if (renderer())
m_needWidgetUpdate = true;
} else if (attr->name() == onloadAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == nameAttr) {
const AtomicString& newName = attr->value();
if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
@@ -163,7 +164,7 @@ void HTMLObjectElement::attach()
void HTMLObjectElement::updateWidget()
{
- document()->updateRendering();
+ document()->updateStyleIfNeeded();
if (m_needWidgetUpdate && renderer() && !m_useFallbackContent && !isImageType())
static_cast<RenderPartObject*>(renderer())->updateWidget(true);
}
@@ -174,7 +175,7 @@ void HTMLObjectElement::finishParsingChildren()
if (!m_useFallbackContent) {
m_needWidgetUpdate = true;
if (inDocument())
- setChanged();
+ setNeedsStyleRecalc();
}
}
@@ -222,7 +223,7 @@ void HTMLObjectElement::childrenChanged(bool changedByParser, Node* beforeChange
updateDocNamedItem();
if (inDocument() && !m_useFallbackContent) {
m_needWidgetUpdate = true;
- setChanged();
+ setNeedsStyleRecalc();
}
HTMLPlugInElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
diff --git a/WebCore/html/HTMLObjectElement.idl b/WebCore/html/HTMLObjectElement.idl
index c225238..5d4562c 100644
--- a/WebCore/html/HTMLObjectElement.idl
+++ b/WebCore/html/HTMLObjectElement.idl
@@ -50,14 +50,16 @@ module html {
// Introduced in DOM Level 2:
readonly attribute [CheckFrameSecurity] Document contentDocument;
-#if !defined(LANGUAGE_COM)
-#if ENABLE_SVG
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
+#if defined(ENABLE_SVG) && ENABLE_SVG
+#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
[SVGCheckSecurityDocument] SVGDocument getSVGDocument()
raises(DOMException);
#endif
#endif
+#endif
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
// Objective-C extension:
readonly attribute URL absoluteImageURL;
#endif
diff --git a/WebCore/html/HTMLOptGroupElement.cpp b/WebCore/html/HTMLOptGroupElement.cpp
index 5c79e74..af81b07 100644
--- a/WebCore/html/HTMLOptGroupElement.cpp
+++ b/WebCore/html/HTMLOptGroupElement.cpp
@@ -49,7 +49,7 @@ bool HTMLOptGroupElement::isFocusable() const
return HTMLElement::isFocusable();
}
-const AtomicString& HTMLOptGroupElement::type() const
+const AtomicString& HTMLOptGroupElement::formControlType() const
{
DEFINE_STATIC_LOCAL(const AtomicString, optgroup, ("optgroup"));
return optgroup;
diff --git a/WebCore/html/HTMLOptGroupElement.h b/WebCore/html/HTMLOptGroupElement.h
index b161728..13e92ca 100644
--- a/WebCore/html/HTMLOptGroupElement.h
+++ b/WebCore/html/HTMLOptGroupElement.h
@@ -36,7 +36,7 @@ public:
HTMLOptGroupElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
virtual bool checkDTD(const Node*);
- virtual const AtomicString& type() const;
+ virtual const AtomicString& formControlType() const;
virtual bool isFocusable() const;
virtual void parseMappedAttribute(MappedAttribute*);
virtual bool rendererIsNeeded(RenderStyle*) { return false; }
diff --git a/WebCore/html/HTMLOptionElement.cpp b/WebCore/html/HTMLOptionElement.cpp
index e59537d..66968b0 100644
--- a/WebCore/html/HTMLOptionElement.cpp
+++ b/WebCore/html/HTMLOptionElement.cpp
@@ -30,9 +30,10 @@
#include "ExceptionCode.h"
#include "HTMLNames.h"
#include "HTMLSelectElement.h"
+#include "MappedAttribute.h"
+#include "NodeRenderStyle.h"
#include "RenderMenuList.h"
#include "Text.h"
-#include "NodeRenderStyle.h"
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
@@ -42,7 +43,6 @@ using namespace HTMLNames;
HTMLOptionElement::HTMLOptionElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
: HTMLFormControlElement(tagName, doc, f)
- , m_data(this)
, m_style(0)
{
ASSERT(hasTagName(optionTag));
@@ -71,7 +71,7 @@ bool HTMLOptionElement::isFocusable() const
return HTMLElement::isFocusable();
}
-const AtomicString& HTMLOptionElement::type() const
+const AtomicString& HTMLOptionElement::formControlType() const
{
DEFINE_STATIC_LOCAL(const AtomicString, option, ("option"));
return option;
@@ -79,7 +79,7 @@ const AtomicString& HTMLOptionElement::type() const
String HTMLOptionElement::text() const
{
- return OptionElement::collectOptionText(m_data, document());
+ return OptionElement::collectOptionText(m_data, this);
}
void HTMLOptionElement::setText(const String &text, ExceptionCode& ec)
@@ -104,22 +104,7 @@ void HTMLOptionElement::accessKeyAction(bool)
int HTMLOptionElement::index() const
{
- // Let's do this dynamically. Might be a bit slow, but we're sure
- // we won't forget to update a member variable in some cases...
- HTMLSelectElement* select = ownerSelectElement();
- if (select) {
- const Vector<HTMLElement*>& items = select->listItems();
- int l = items.size();
- int optionIndex = 0;
- for(int i = 0; i < l; i++) {
- if (items[i]->hasLocalName(optionTag)) {
- if (static_cast<HTMLOptionElement*>(items[i]) == this)
- return optionIndex;
- optionIndex++;
- }
- }
- }
- return 0;
+ return OptionElement::optionIndex(ownerSelectElement(), this);
}
void HTMLOptionElement::parseMappedAttribute(MappedAttribute *attr)
@@ -136,7 +121,7 @@ void HTMLOptionElement::parseMappedAttribute(MappedAttribute *attr)
String HTMLOptionElement::value() const
{
- return OptionElement::collectOptionValue(m_data, document());
+ return OptionElement::collectOptionValue(m_data, this);
}
void HTMLOptionElement::setValue(const String& value)
@@ -154,7 +139,7 @@ void HTMLOptionElement::setSelected(bool selected)
if (m_data.selected() == selected)
return;
- OptionElement::setSelectedState(m_data, selected);
+ OptionElement::setSelectedState(m_data, this, selected);
if (HTMLSelectElement* select = ownerSelectElement())
select->setSelectedIndex(selected ? index() : -1, false);
@@ -162,7 +147,7 @@ void HTMLOptionElement::setSelected(bool selected)
void HTMLOptionElement::setSelectedState(bool selected)
{
- OptionElement::setSelectedState(m_data, selected);
+ OptionElement::setSelectedState(m_data, this, selected);
}
void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -221,7 +206,7 @@ RenderStyle* HTMLOptionElement::nonRendererRenderStyle() const
String HTMLOptionElement::textIndentedToRespectGroupLabel() const
{
- return OptionElement::collectOptionTextRespectingGroupLabel(m_data, document());
+ return OptionElement::collectOptionTextRespectingGroupLabel(m_data, this);
}
bool HTMLOptionElement::disabled() const
diff --git a/WebCore/html/HTMLOptionElement.h b/WebCore/html/HTMLOptionElement.h
index 8c0f260..f13a802 100644
--- a/WebCore/html/HTMLOptionElement.h
+++ b/WebCore/html/HTMLOptionElement.h
@@ -48,9 +48,9 @@ public:
virtual void detach();
virtual void setRenderStyle(PassRefPtr<RenderStyle>);
- virtual const AtomicString& type() const;
+ virtual const AtomicString& formControlType() const;
- String text() const;
+ virtual String text() const;
void setText(const String&, ExceptionCode&);
int index() const;
diff --git a/WebCore/html/HTMLOptionElement.idl b/WebCore/html/HTMLOptionElement.idl
index 34fa999..612d459 100644
--- a/WebCore/html/HTMLOptionElement.idl
+++ b/WebCore/html/HTMLOptionElement.idl
@@ -28,7 +28,7 @@ module html {
] HTMLOptionElement : HTMLElement {
readonly attribute HTMLFormElement form;
attribute boolean defaultSelected;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
attribute [ConvertNullToNullString] DOMString text
setter raises(DOMException);
#else
diff --git a/WebCore/html/HTMLOptionsCollection.idl b/WebCore/html/HTMLOptionsCollection.idl
index 226f3d7..5f85fcb 100644
--- a/WebCore/html/HTMLOptionsCollection.idl
+++ b/WebCore/html/HTMLOptionsCollection.idl
@@ -36,7 +36,7 @@ module html {
raises (DOMException);
[Custom] void remove(in unsigned long index);
-#if !defined(LANGUAGE_JAVASCRIPT)
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
Node item(in unsigned long index);
Node namedItem(in DOMString name);
#endif
diff --git a/WebCore/html/HTMLParagraphElement.cpp b/WebCore/html/HTMLParagraphElement.cpp
index 44eaecc..a8deb10 100644
--- a/WebCore/html/HTMLParagraphElement.cpp
+++ b/WebCore/html/HTMLParagraphElement.cpp
@@ -19,6 +19,7 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#include "config.h"
#include "HTMLParagraphElement.h"
@@ -26,6 +27,7 @@
#include "CSSValueKeywords.h"
#include "Document.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLParamElement.cpp b/WebCore/html/HTMLParamElement.cpp
index 6e1197b..d5fc6e7 100644
--- a/WebCore/html/HTMLParamElement.cpp
+++ b/WebCore/html/HTMLParamElement.cpp
@@ -25,6 +25,7 @@
#include "Document.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLParser.cpp b/WebCore/html/HTMLParser.cpp
index a4d4671..dab58b3 100644
--- a/WebCore/html/HTMLParser.cpp
+++ b/WebCore/html/HTMLParser.cpp
@@ -3,7 +3,8 @@
(C) 1997 Torben Weis (weis@kde.org)
(C) 1999,2001 Lars Knoll (knoll@kde.org)
(C) 2000,2001 Dirk Mueller (mueller@kde.org)
- Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ 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
@@ -27,6 +28,7 @@
#include "CharacterNames.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
+#include "ChromeClient.h"
#include "Comment.h"
#include "Console.h"
#include "DOMWindow.h"
@@ -45,15 +47,17 @@
#include "HTMLIsIndexElement.h"
#include "HTMLMapElement.h"
#include "HTMLNames.h"
+#include "HTMLParserQuirks.h"
#include "HTMLTableCellElement.h"
#include "HTMLTableRowElement.h"
#include "HTMLTableSectionElement.h"
#include "HTMLTokenizer.h"
#include "LocalizedStrings.h"
+#include "Page.h"
#include "Settings.h"
#include "Text.h"
#include <wtf/StdLibExtras.h>
-
+
namespace WebCore {
using namespace HTMLNames;
@@ -126,7 +130,6 @@ HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
, m_blockStack(0)
, m_blocksInStack(0)
, m_hasPElementInScope(NotInScope)
- , m_head(0)
, m_inBody(false)
, m_haveContent(false)
, m_haveFrameSet(false)
@@ -134,6 +137,7 @@ HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
, m_reportErrors(reportErrors)
, m_handlingResidualStyleAcrossBlocks(false)
, m_inStrayTableContent(0)
+ , m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0)
{
}
@@ -144,7 +148,6 @@ HTMLParser::HTMLParser(DocumentFragment* frag)
, m_blockStack(0)
, m_blocksInStack(0)
, m_hasPElementInScope(NotInScope)
- , m_head(0)
, m_inBody(true)
, m_haveContent(false)
, m_haveFrameSet(false)
@@ -152,6 +155,7 @@ HTMLParser::HTMLParser(DocumentFragment* frag)
, m_reportErrors(false)
, m_handlingResidualStyleAcrossBlocks(false)
, m_inStrayTableContent(0)
+ , m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0)
{
if (frag)
frag->ref();
@@ -161,7 +165,7 @@ HTMLParser::~HTMLParser()
{
freeBlock();
if (m_didRefCurrent)
- m_current->deref();
+ m_current->deref();
}
void HTMLParser::reset()
@@ -183,6 +187,9 @@ void HTMLParser::reset()
m_isindexElement = 0;
m_skipModeTag = nullAtom;
+
+ if (m_parserQuirks)
+ m_parserQuirks->reset();
}
void HTMLParser::setCurrent(Node* newCurrent)
@@ -334,6 +341,9 @@ bool HTMLParser::insertNode(Node* n, bool flat)
popBlock(m_blockStack->tagName);
}
+ if (m_parserQuirks && !m_parserQuirks->shouldInsertNode(m_current, n))
+ return false;
+
// let's be stupid and just try to insert it.
// this should work if the document is well-formed
Node* newNode = m_current->addChild(n);
@@ -347,6 +357,8 @@ bool HTMLParser::insertNode(Node* n, bool flat)
// This case should only be hit when a demoted <form> is placed inside a table.
ASSERT(localName == formTag);
reportError(FormInsideTablePartError, &m_current->localName());
+ HTMLFormElement* form = static_cast<HTMLFormElement*>(n);
+ form->setDemoted(true);
} else {
// The pushBlock function transfers ownership of current to the block stack
// so we're guaranteed that m_didRefCurrent is false. The code below is an
@@ -417,9 +429,9 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
reportError(RedundantHTMLBodyError, &localName);
// we have another <HTML> element.... apply attributes to existing one
// make sure we don't overwrite already existing attributes
- NamedAttrMap* map = static_cast<Element*>(n)->attributes(true);
+ NamedNodeMap* map = static_cast<Element*>(n)->attributes(true);
Element* existingHTML = static_cast<Element*>(m_document->documentElement());
- NamedAttrMap* bmap = existingHTML->attributes(false);
+ NamedNodeMap* bmap = existingHTML->attributes(false);
for (unsigned l = 0; map && l < map->length(); ++l) {
Attribute* it = map->attributeItem(l);
if (!bmap->getAttributeItem(it->name()))
@@ -428,7 +440,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
}
return false;
}
- } else if (h->hasLocalName(titleTag) || h->hasLocalName(styleTag)) {
+ } else if (h->hasLocalName(titleTag) || h->hasLocalName(styleTag) || h->hasLocalName(scriptTag)) {
bool createdHead = false;
if (!m_head) {
createHead();
@@ -461,9 +473,9 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
// make sure we don't overwrite already existing attributes
// some sites use <body bgcolor=rightcolor>...<body bgcolor=wrongcolor>
reportError(RedundantHTMLBodyError, &localName);
- NamedAttrMap* map = static_cast<Element*>(n)->attributes(true);
+ NamedNodeMap* map = static_cast<Element*>(n)->attributes(true);
Element* existingBody = m_document->body();
- NamedAttrMap* bmap = existingBody->attributes(false);
+ NamedNodeMap* bmap = existingBody->attributes(false);
for (unsigned l = 0; map && l < map->length(); ++l) {
Attribute* it = map->attributeItem(l);
if (!bmap->getAttributeItem(it->name()))
@@ -506,8 +518,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
elt->hasLocalName(baseTag))) {
if (!m_head) {
m_head = new HTMLHeadElement(headTag, m_document);
- e = m_head;
- insertNode(e);
+ insertNode(m_head.get());
handled = true;
}
} else {
@@ -517,6 +528,12 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
return false;
}
if (!m_haveFrameSet) {
+ // Ensure that head exists.
+ // But not for older versions of Mail, where the implicit <head> isn't expected - <rdar://problem/6863795>
+ if (shouldCreateImplicitHead(m_document))
+ createHead();
+
+ popBlock(headTag);
e = new HTMLBodyElement(bodyTag, m_document);
startBody();
insertNode(e);
@@ -530,6 +547,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
else {
// This means the body starts here...
if (!m_haveFrameSet) {
+ ASSERT(currentTagName == headTag);
popBlock(currentTagName);
e = new HTMLBodyElement(bodyTag, m_document);
startBody();
@@ -699,6 +717,12 @@ bool HTMLParser::bodyCreateErrorCheck(Token*, RefPtr<Node>&)
// body no longer allowed if we have a frameset
if (m_haveFrameSet)
return false;
+
+ // Ensure that head exists (unless parsing a fragment).
+ // But not for older versions of Mail, where the implicit <head> isn't expected - <rdar://problem/6863795>
+ if (!m_isParsingFragment && shouldCreateImplicitHead(m_document))
+ createHead();
+
popBlock(headTag);
startBody();
return true;
@@ -886,7 +910,9 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t)
gFunctionMap.set(nobrTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
gFunctionMap.set(noembedTag.localName().impl(), &HTMLParser::noembedCreateErrorCheck);
gFunctionMap.set(noframesTag.localName().impl(), &HTMLParser::noframesCreateErrorCheck);
+#if !ENABLE(XHTMLMP)
gFunctionMap.set(noscriptTag.localName().impl(), &HTMLParser::noscriptCreateErrorCheck);
+#endif
gFunctionMap.set(olTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(pTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(plaintextTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
@@ -992,11 +1018,13 @@ bool HTMLParser::isInline(Node* node) const
e->hasLocalName(noframesTag) || e->hasLocalName(nolayerTag) ||
e->hasLocalName(noembedTag))
return true;
+#if !ENABLE(XHTMLMP)
if (e->hasLocalName(noscriptTag) && !m_isParsingFragment) {
Settings* settings = m_document->settings();
if (settings && settings->isJavaScriptEnabled())
return true;
}
+#endif
}
return false;
@@ -1335,7 +1363,10 @@ void HTMLParser::pushBlock(const AtomicString& tagName, int level)
void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
{
HTMLStackElem* elem = m_blockStack;
-
+
+ if (m_parserQuirks && elem && !m_parserQuirks->shouldPopBlock(elem->tagName, tagName))
+ return;
+
int maxLevel = 0;
while (elem && (elem->tagName != tagName)) {
@@ -1510,20 +1541,25 @@ void HTMLParser::freeBlock()
void HTMLParser::createHead()
{
- if (m_head || !m_document->documentElement())
+ if (m_head)
return;
+ if (!m_document->documentElement()) {
+ insertNode(new HTMLHtmlElement(htmlTag, m_document));
+ ASSERT(m_document->documentElement());
+ }
+
m_head = new HTMLHeadElement(headTag, m_document);
HTMLElement* body = m_document->body();
ExceptionCode ec = 0;
- m_document->documentElement()->insertBefore(m_head, body, ec);
+ m_document->documentElement()->insertBefore(m_head.get(), body, ec);
if (ec)
m_head = 0;
// If the body does not exist yet, then the <head> should be pushed as the current block.
if (m_head && !body) {
pushBlock(m_head->localName(), m_head->tagPriority());
- setCurrent(m_head);
+ setCurrent(m_head.get());
}
}
@@ -1624,4 +1660,22 @@ void HTMLParser::reportErrorToConsole(HTMLParserErrorCode errorCode, const Atomi
message, lineNumber, m_document->url().string());
}
+#ifdef BUILDING_ON_LEOPARD
+bool shouldCreateImplicitHead(Document* document)
+{
+ ASSERT(document);
+
+ Settings* settings = document->page() ? document->page()->settings() : 0;
+ return settings ? !settings->needsLeopardMailQuirks() : true;
+}
+#elif defined(BUILDING_ON_TIGER)
+bool shouldCreateImplicitHead(Document* document)
+{
+ ASSERT(document);
+
+ Settings* settings = document->page() ? document->page()->settings() : 0;
+ return settings ? !settings->needsTigerMailQuirks() : true;
+}
+#endif
+
}
diff --git a/WebCore/html/HTMLParser.h b/WebCore/html/HTMLParser.h
index 23fb980..19f553e 100644
--- a/WebCore/html/HTMLParser.h
+++ b/WebCore/html/HTMLParser.h
@@ -3,7 +3,7 @@
(C) 1997 Torben Weis (weis@kde.org)
(C) 1998 Waldo Bastian (bastian@kde.org)
(C) 1999 Lars Knoll (knoll@kde.org)
- Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -26,6 +26,7 @@
#include "QualifiedName.h"
#include <wtf/Forward.h>
+#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
#include "HTMLParserErrorCodes.h"
@@ -38,6 +39,7 @@ class HTMLDocument;
class HTMLFormElement;
class HTMLHeadElement;
class HTMLMapElement;
+class HTMLParserQuirks;
class Node;
struct HTMLStackElem;
@@ -169,7 +171,7 @@ private:
RefPtr<HTMLFormElement> m_currentFormElement; // currently active form
RefPtr<HTMLMapElement> m_currentMapElement; // current map
- HTMLHeadElement* m_head; // head element; needed for HTML which defines <base> after </head>
+ RefPtr<HTMLHeadElement> m_head; // head element; needed for HTML which defines <base> after </head>
RefPtr<Node> m_isindexElement; // a possible <isindex> element in the head
bool m_inBody;
@@ -182,8 +184,16 @@ private:
bool m_reportErrors;
bool m_handlingResidualStyleAcrossBlocks;
int m_inStrayTableContent;
+
+ OwnPtr<HTMLParserQuirks> m_parserQuirks;
};
+#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_TIGER)
+bool shouldCreateImplicitHead(Document*);
+#else
+inline bool shouldCreateImplicitHead(Document*) { return true; }
+#endif
+
}
#endif // HTMLParser_h
diff --git a/WebCore/html/HTMLParserQuirks.h b/WebCore/html/HTMLParserQuirks.h
new file mode 100644
index 0000000..b5972a6
--- /dev/null
+++ b/WebCore/html/HTMLParserQuirks.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLParserQuirks_h
+#define HTMLParserQuirks_h
+
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class AtomicString;
+class Node;
+
+class HTMLParserQuirks : Noncopyable {
+public:
+ HTMLParserQuirks() { }
+ virtual ~HTMLParserQuirks() { }
+
+ virtual void reset() = 0;
+
+ virtual bool shouldInsertNode(Node* parent, Node* newNode) = 0;
+ virtual bool shouldPopBlock(const AtomicString& tagNameOnStack, const AtomicString& tagNameToPop) = 0;
+};
+
+} // namespace WebCore
+
+#endif // HTMLParserQuirks_h
diff --git a/WebCore/html/HTMLPlugInElement.cpp b/WebCore/html/HTMLPlugInElement.cpp
index 4344b3d..d950d9d 100644
--- a/WebCore/html/HTMLPlugInElement.cpp
+++ b/WebCore/html/HTMLPlugInElement.cpp
@@ -21,6 +21,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLPlugInElement.h"
@@ -30,6 +31,7 @@
#include "FrameLoader.h"
#include "FrameTree.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "Page.h"
#include "RenderWidget.h"
#include "ScriptController.h"
@@ -46,7 +48,7 @@ using namespace HTMLNames;
HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc)
// FIXME: Always passing false as createdByParser is odd (see bug22851).
- : HTMLFrameOwnerElement(tagName, doc, false)
+ : HTMLFrameOwnerElement(tagName, doc)
#if ENABLE(NETSCAPE_PLUGIN_API)
, m_NPObject(0)
#endif
diff --git a/WebCore/html/HTMLPreElement.cpp b/WebCore/html/HTMLPreElement.cpp
index 23ecaaa..f340ae3 100644
--- a/WebCore/html/HTMLPreElement.cpp
+++ b/WebCore/html/HTMLPreElement.cpp
@@ -21,12 +21,14 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#include "config.h"
#include "HTMLPreElement.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLScriptElement.cpp b/WebCore/html/HTMLScriptElement.cpp
index 4744b34..86cc3a2 100644
--- a/WebCore/html/HTMLScriptElement.cpp
+++ b/WebCore/html/HTMLScriptElement.cpp
@@ -26,6 +26,8 @@
#include "Document.h"
#include "EventNames.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
+#include "ScriptEventListener.h"
#include "Text.h"
namespace WebCore {
@@ -67,7 +69,7 @@ void HTMLScriptElement::parseMappedAttribute(MappedAttribute* attr)
if (attrName == srcAttr)
handleSourceAttribute(m_data, attr->value());
else if (attrName == onloadAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
+ setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
else
HTMLElement::parseMappedAttribute(attr);
}
@@ -209,18 +211,23 @@ String HTMLScriptElement::languageAttributeValue() const
{
return getAttribute(languageAttr).string();
}
+
+String HTMLScriptElement::forAttributeValue() const
+{
+ return getAttribute(forAttr).string();
+}
void HTMLScriptElement::dispatchLoadEvent()
{
ASSERT(!m_data.haveFiredLoadEvent());
m_data.setHaveFiredLoadEvent(true);
- dispatchEventForType(eventNames().loadEvent, false, false);
+ dispatchEvent(eventNames().loadEvent, false, false);
}
void HTMLScriptElement::dispatchErrorEvent()
{
- dispatchEventForType(eventNames().errorEvent, true, false);
+ dispatchEvent(eventNames().errorEvent, true, false);
}
}
diff --git a/WebCore/html/HTMLScriptElement.h b/WebCore/html/HTMLScriptElement.h
index 8839131..4d18beb 100644
--- a/WebCore/html/HTMLScriptElement.h
+++ b/WebCore/html/HTMLScriptElement.h
@@ -35,7 +35,7 @@ public:
HTMLScriptElement(const QualifiedName&, Document*, bool createdByParser);
~HTMLScriptElement();
- bool shouldExecuteAsJavaScript() const;
+ virtual bool shouldExecuteAsJavaScript() const;
virtual String scriptContent() const;
virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
@@ -75,11 +75,14 @@ public:
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ bool haveFiredLoadEvent() const { return m_data.haveFiredLoadEvent(); }
+
protected:
virtual String sourceAttributeValue() const;
virtual String charsetAttributeValue() const;
virtual String typeAttributeValue() const;
virtual String languageAttributeValue() const;
+ virtual String forAttributeValue() const;
virtual void dispatchLoadEvent();
virtual void dispatchErrorEvent();
diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp
index 107fbd0..95038e6 100644
--- a/WebCore/html/HTMLSelectElement.cpp
+++ b/WebCore/html/HTMLSelectElement.cpp
@@ -21,67 +21,31 @@
* Boston, MA 02110-1301, USA.
*
*/
-
+
#include "config.h"
#include "HTMLSelectElement.h"
#include "AXObjectCache.h"
-#include "CSSPropertyNames.h"
-#include "CSSStyleSelector.h"
-#include "CharacterNames.h"
-#include "ChromeClient.h"
-#include "Document.h"
-#include "Event.h"
-#include "EventHandler.h"
#include "EventNames.h"
-#include "FormDataList.h"
-#include "Frame.h"
-#include "FrameLoader.h"
-#include "FrameLoaderClient.h"
-#include "HTMLFormElement.h"
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
#include "HTMLOptionsCollection.h"
-#include "KeyboardEvent.h"
-#include "MouseEvent.h"
-#include "Page.h"
+#include "MappedAttribute.h"
#include "RenderListBox.h"
#include "RenderMenuList.h"
-#include <math.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/Vector.h>
-
-#if PLATFORM(MAC)
-#define ARROW_KEYS_POP_MENU 1
-#else
-#define ARROW_KEYS_POP_MENU 0
-#endif
+#include "ScriptEventListener.h"
using namespace std;
-using namespace WTF;
-using namespace Unicode;
namespace WebCore {
using namespace HTMLNames;
-static const DOMTimeStamp typeAheadTimeout = 1000;
-
// Upper limit agreed upon with representatives of Opera and Mozilla.
static const unsigned maxSelectItems = 10000;
-HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
- : HTMLFormControlElementWithState(tagName, doc, f)
- , m_minwidth(0)
- , m_size(0)
- , m_multiple(false)
- , m_recalcListItems(false)
- , m_lastOnChangeIndex(-1)
- , m_activeSelectionAnchorIndex(-1)
- , m_activeSelectionEndIndex(-1)
- , m_activeSelectionState(false)
- , m_repeatingChar(0)
- , m_lastCharTime(0)
+HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElementWithState(tagName, document, form)
{
ASSERT(hasTagName(selectTag) || hasTagName(keygenTag));
}
@@ -93,120 +57,52 @@ bool HTMLSelectElement::checkDTD(const Node* newChild)
newChild->hasTagName(scriptTag);
}
-void HTMLSelectElement::recalcStyle( StyleChange ch )
+void HTMLSelectElement::recalcStyle(StyleChange change)
{
- if (hasChangedChild() && renderer()) {
- if (usesMenuList())
- static_cast<RenderMenuList*>(renderer())->setOptionsChanged(true);
- else
- static_cast<RenderListBox*>(renderer())->setOptionsChanged(true);
- } else if (m_recalcListItems)
- recalcListItems();
-
- HTMLFormControlElementWithState::recalcStyle(ch);
+ SelectElement::recalcStyle(m_data, this);
+ HTMLFormControlElementWithState::recalcStyle(change);
}
-const AtomicString& HTMLSelectElement::type() const
+const AtomicString& HTMLSelectElement::formControlType() const
{
DEFINE_STATIC_LOCAL(const AtomicString, selectMultiple, ("select-multiple"));
DEFINE_STATIC_LOCAL(const AtomicString, selectOne, ("select-one"));
- return m_multiple ? selectMultiple : selectOne;
+ return m_data.multiple() ? selectMultiple : selectOne;
}
int HTMLSelectElement::selectedIndex() const
{
- // return the number of the first option selected
- unsigned index = 0;
- const Vector<HTMLElement*>& items = listItems();
- for (unsigned int i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
- if (static_cast<HTMLOptionElement*>(items[i])->selected())
- return index;
- index++;
- }
- }
- return -1;
-}
-
-int HTMLSelectElement::lastSelectedListIndex() const
-{
- // return the number of the last option selected
- unsigned index = 0;
- bool found = false;
- const Vector<HTMLElement*>& items = listItems();
- for (unsigned int i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
- if (static_cast<HTMLOptionElement*>(items[i])->selected()) {
- index = i;
- found = true;
- }
- }
- }
- return found ? (int) index : -1;
+ return SelectElement::selectedIndex(m_data, this);
}
void HTMLSelectElement::deselectItems(HTMLOptionElement* excludeElement)
{
- const Vector<HTMLElement*>& items = listItems();
- unsigned i;
- for (i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag) && (items[i] != excludeElement)) {
- HTMLOptionElement* element = static_cast<HTMLOptionElement*>(items[i]);
- element->setSelectedState(false);
- }
- }
+ SelectElement::deselectItems(m_data, this, excludeElement);
}
void HTMLSelectElement::setSelectedIndex(int optionIndex, bool deselect, bool fireOnChange)
{
- const Vector<HTMLElement*>& items = listItems();
- int listIndex = optionToListIndex(optionIndex);
- HTMLOptionElement* element = 0;
-
- if (!multiple())
- deselect = true;
-
- if (listIndex >= 0) {
- if (m_activeSelectionAnchorIndex < 0 || deselect)
- setActiveSelectionAnchorIndex(listIndex);
- if (m_activeSelectionEndIndex < 0 || deselect)
- setActiveSelectionEndIndex(listIndex);
- element = static_cast<HTMLOptionElement*>(items[listIndex]);
- element->setSelectedState(true);
- }
-
- if (deselect)
- deselectItems(element);
-
- scrollToSelection();
-
- // This only gets called with fireOnChange for menu lists.
- if (fireOnChange && usesMenuList())
- menuListOnChange();
-
- Frame* frame = document()->frame();
- if (frame)
- frame->page()->chrome()->client()->formStateDidChange(this);
+ SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, fireOnChange);
}
int HTMLSelectElement::activeSelectionStartListIndex() const
{
- if (m_activeSelectionAnchorIndex >= 0)
- return m_activeSelectionAnchorIndex;
+ if (m_data.activeSelectionAnchorIndex() >= 0)
+ return m_data.activeSelectionAnchorIndex();
return optionToListIndex(selectedIndex());
}
int HTMLSelectElement::activeSelectionEndListIndex() const
{
- if (m_activeSelectionEndIndex >= 0)
- return m_activeSelectionEndIndex;
- return lastSelectedListIndex();
+ if (m_data.activeSelectionEndIndex() >= 0)
+ return m_data.activeSelectionEndIndex();
+ return SelectElement::lastSelectedListIndex(m_data, this);
}
unsigned HTMLSelectElement::length() const
{
unsigned len = 0;
- const Vector<HTMLElement*>& items = listItems();
+ const Vector<Element*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
if (items[i]->hasLocalName(optionTag))
++len;
@@ -226,27 +122,24 @@ void HTMLSelectElement::add(HTMLElement *element, HTMLElement *before, Exception
void HTMLSelectElement::remove(int index)
{
- ExceptionCode ec = 0;
int listIndex = optionToListIndex(index);
+ if (listIndex < 0)
+ return;
- const Vector<HTMLElement*>& items = listItems();
- if (listIndex < 0 || index >= int(items.size()))
- return; // ### what should we do ? remove the last item?
-
- Element *item = items[listIndex];
+ Element* item = listItems()[listIndex];
ASSERT(item->parentNode());
+ ExceptionCode ec;
item->parentNode()->removeChild(item, ec);
}
String HTMLSelectElement::value()
{
- unsigned i;
- const Vector<HTMLElement*>& items = listItems();
- for (i = 0; i < items.size(); i++) {
+ const Vector<Element*>& items = listItems();
+ for (unsigned i = 0; i < items.size(); i++) {
if (items[i]->hasLocalName(optionTag) && static_cast<HTMLOptionElement*>(items[i])->selected())
return static_cast<HTMLOptionElement*>(items[i])->value();
}
- return String("");
+ return "";
}
void HTMLSelectElement::setValue(const String &value)
@@ -255,9 +148,9 @@ void HTMLSelectElement::setValue(const String &value)
return;
// find the option with value() matching the given parameter
// and make it the current selection.
- const Vector<HTMLElement*>& items = listItems();
+ const Vector<Element*>& items = listItems();
unsigned optionIndex = 0;
- for (unsigned i = 0; i < items.size(); i++)
+ for (unsigned i = 0; i < items.size(); i++) {
if (items[i]->hasLocalName(optionTag)) {
if (static_cast<HTMLOptionElement*>(items[i])->value() == value) {
setSelectedIndex(optionIndex, true);
@@ -265,40 +158,24 @@ void HTMLSelectElement::setValue(const String &value)
}
optionIndex++;
}
+ }
}
-bool HTMLSelectElement::saveState(String& value) const
+bool HTMLSelectElement::saveFormControlState(String& value) const
{
- const Vector<HTMLElement*>& items = listItems();
- int l = items.size();
- Vector<char, 1024> characters(l);
- for (int i = 0; i < l; ++i) {
- HTMLElement* e = items[i];
- bool selected = e->hasLocalName(optionTag) && static_cast<HTMLOptionElement*>(e)->selected();
- characters[i] = selected ? 'X' : '.';
- }
- value = String(characters.data(), l);
- return true;
+ return SelectElement::saveFormControlState(m_data, this, value);
}
-void HTMLSelectElement::restoreState(const String& state)
+void HTMLSelectElement::restoreFormControlState(const String& state)
{
- recalcListItems();
-
- const Vector<HTMLElement*>& items = listItems();
- int l = items.size();
- for (int i = 0; i < l; i++)
- if (items[i]->hasLocalName(optionTag))
- static_cast<HTMLOptionElement*>(items[i])->setSelectedState(state[i] == 'X');
-
- setChanged();
+ SelectElement::restoreFormControlState(m_data, this, state);
}
-void HTMLSelectElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLSelectElement::parseMappedAttribute(MappedAttribute* attr)
{
- bool oldUsesMenuList = usesMenuList();
+ bool oldUsesMenuList = m_data.usesMenuList();
if (attr->name() == sizeAttr) {
- int oldSize = m_size;
+ int oldSize = m_data.size();
// Set the attribute value to a number.
// This is important since the style rules for this attribute can determine the appearance property.
int size = attr->value().toInt();
@@ -306,31 +183,25 @@ void HTMLSelectElement::parseMappedAttribute(MappedAttribute *attr)
if (attrSize != attr->value())
attr->setValue(attrSize);
- m_size = max(size, 1);
- if ((oldUsesMenuList != usesMenuList() || (!oldUsesMenuList && m_size != oldSize)) && attached()) {
+ m_data.setSize(max(size, 1));
+ if ((oldUsesMenuList != m_data.usesMenuList() || (!oldUsesMenuList && m_data.size() != oldSize)) && attached()) {
detach();
attach();
setRecalcListItems();
}
- } else if (attr->name() == widthAttr) {
- m_minwidth = max(attr->value().toInt(), 0);
- } else if (attr->name() == multipleAttr) {
- m_multiple = (!attr->isNull());
- if (oldUsesMenuList != usesMenuList() && attached()) {
- detach();
- attach();
- }
- } else if (attr->name() == accesskeyAttr) {
+ } else if (attr->name() == multipleAttr)
+ SelectElement::parseMultipleAttribute(m_data, this, attr);
+ else if (attr->name() == accesskeyAttr) {
// FIXME: ignore for the moment
} else if (attr->name() == alignAttr) {
// Don't map 'align' attribute. This matches what Firefox, Opera and IE do.
// See http://bugs.webkit.org/show_bug.cgi?id=12072
} else if (attr->name() == onfocusAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
+ setAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onblurAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
+ setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onchangeAttr) {
- setInlineEventListenerForTypeAndAttribute(eventNames().changeEvent, attr);
+ setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr));
} else
HTMLFormControlElementWithState::parseMappedAttribute(attr);
}
@@ -351,98 +222,34 @@ bool HTMLSelectElement::isMouseFocusable() const
bool HTMLSelectElement::canSelectAll() const
{
- return !usesMenuList();
+ return !m_data.usesMenuList();
}
void HTMLSelectElement::selectAll()
{
- ASSERT(!usesMenuList());
- if (!renderer() || !multiple())
- return;
-
- // Save the selection so it can be compared to the new selectAll selection when we call onChange
- saveLastSelection();
-
- m_activeSelectionState = true;
- setActiveSelectionAnchorIndex(nextSelectableListIndex(-1));
- setActiveSelectionEndIndex(previousSelectableListIndex(-1));
-
- updateListBoxSelection(false);
- listBoxOnChange();
+ SelectElement::selectAll(m_data, this);
}
RenderObject* HTMLSelectElement::createRenderer(RenderArena* arena, RenderStyle*)
{
- if (usesMenuList())
+ if (m_data.usesMenuList())
return new (arena) RenderMenuList(this);
return new (arena) RenderListBox(this);
}
bool HTMLSelectElement::appendFormData(FormDataList& list, bool)
{
- if (name().isEmpty())
- return false;
-
- bool successful = false;
- const Vector<HTMLElement*>& items = listItems();
-
- unsigned i;
- for (i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
- HTMLOptionElement *option = static_cast<HTMLOptionElement*>(items[i]);
- if (option->selected()) {
- list.appendData(name(), option->value());
- successful = true;
- }
- }
- }
-
- // ### this case should not happen. make sure that we select the first option
- // in any case. otherwise we have no consistency with the DOM interface. FIXME!
- // we return the first one if it was a combobox select
- if (!successful && !m_multiple && m_size <= 1 && items.size() &&
- (items[0]->hasLocalName(optionTag))) {
- HTMLOptionElement *option = static_cast<HTMLOptionElement*>(items[0]);
- if (option->value().isNull())
- list.appendData(name(), option->text().stripWhiteSpace());
- else
- list.appendData(name(), option->value());
- successful = true;
- }
-
- return successful;
+ return SelectElement::appendFormData(m_data, this, list);
}
int HTMLSelectElement::optionToListIndex(int optionIndex) const
{
- const Vector<HTMLElement*>& items = listItems();
- int listSize = (int)items.size();
- if (optionIndex < 0 || optionIndex >= listSize)
- return -1;
-
- int optionIndex2 = -1;
- for (int listIndex = 0; listIndex < listSize; listIndex++) {
- if (items[listIndex]->hasLocalName(optionTag)) {
- optionIndex2++;
- if (optionIndex2 == optionIndex)
- return listIndex;
- }
- }
- return -1;
+ return SelectElement::optionToListIndex(m_data, this, optionIndex);
}
int HTMLSelectElement::listToOptionIndex(int listIndex) const
{
- const Vector<HTMLElement*>& items = listItems();
- if (listIndex < 0 || listIndex >= int(items.size()) ||
- !items[listIndex]->hasLocalName(optionTag))
- return -1;
-
- int optionIndex = 0; // actual index of option not counting OPTGROUP entries that may be in list
- for (int i = 0; i < listIndex; i++)
- if (items[i]->hasLocalName(optionTag))
- optionIndex++;
- return optionIndex;
+ return SelectElement::listToOptionIndex(m_data, this, listIndex);
}
PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
@@ -452,37 +259,7 @@ PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
{
- m_listItems.clear();
- HTMLOptionElement* foundSelected = 0;
- for (Node* current = firstChild(); current; current = current->traverseNextSibling(this)) {
- if (current->hasTagName(optgroupTag) && current->firstChild()) {
- // FIXME: It doesn't make sense to add an optgroup to the list items,
- // when it has children, but not to add it if it happens to have,
- // children (say some comment nodes or text nodes), yet that's what
- // this code does!
- m_listItems.append(static_cast<HTMLElement*>(current));
- current = current->firstChild();
- // FIXME: It doesn't make sense to handle an <optgroup> inside another <optgroup>
- // if it's not the first child, but not handle it if it happens to be the first
- // child, yet that's what this code does!
- }
-
- if (current->hasTagName(optionTag)) {
- m_listItems.append(static_cast<HTMLElement*>(current));
- if (updateSelectedStates) {
- if (!foundSelected && (usesMenuList() || (!m_multiple && static_cast<HTMLOptionElement*>(current)->selected()))) {
- foundSelected = static_cast<HTMLOptionElement*>(current);
- foundSelected->setSelectedState(true);
- } else if (foundSelected && !m_multiple && static_cast<HTMLOptionElement*>(current)->selected()) {
- foundSelected->setSelectedState(false);
- foundSelected = static_cast<HTMLOptionElement*>(current);
- }
- }
- }
- if (current->hasTagName(hrTag))
- m_listItems.append(static_cast<HTMLElement*>(current));
- }
- m_recalcListItems = false;
+ SelectElement::recalcListItems(const_cast<SelectElementData&>(m_data), this, updateSelectedStates);
}
void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -496,493 +273,65 @@ void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange
void HTMLSelectElement::setRecalcListItems()
{
- m_recalcListItems = true;
- m_activeSelectionAnchorIndex = -1; // Manual selection anchor is reset when manipulating the select programmatically.
- if (renderer()) {
- if (usesMenuList())
- static_cast<RenderMenuList*>(renderer())->setOptionsChanged(true);
- else
- static_cast<RenderListBox*>(renderer())->setOptionsChanged(true);
- }
+ SelectElement::setRecalcListItems(m_data, this);
+
if (!inDocument())
m_collectionInfo.reset();
- setChanged();
}
void HTMLSelectElement::reset()
{
- bool optionSelected = false;
- HTMLOptionElement* firstOption = 0;
- const Vector<HTMLElement*>& items = listItems();
- unsigned i;
- for (i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
- HTMLOptionElement *option = static_cast<HTMLOptionElement*>(items[i]);
- if (!option->getAttribute(selectedAttr).isNull()) {
- option->setSelectedState(true);
- optionSelected = true;
- } else
- option->setSelectedState(false);
- if (!firstOption)
- firstOption = option;
- }
- }
- if (!optionSelected && firstOption && usesMenuList())
- firstOption->setSelectedState(true);
-
- setChanged();
+ SelectElement::reset(m_data, this);
}
void HTMLSelectElement::dispatchFocusEvent()
{
- if (usesMenuList())
- // Save the selection so it can be compared to the new selection when we call onChange during dispatchBlurEvent.
- saveLastSelection();
+ SelectElement::dispatchFocusEvent(m_data, this);
HTMLFormControlElementWithState::dispatchFocusEvent();
}
void HTMLSelectElement::dispatchBlurEvent()
{
- // We only need to fire onChange here for menu lists, because we fire onChange for list boxes whenever the selection change is actually made.
- // This matches other browsers' behavior.
- if (usesMenuList())
- menuListOnChange();
+ SelectElement::dispatchBlurEvent(m_data, this);
HTMLFormControlElementWithState::dispatchBlurEvent();
}
-void HTMLSelectElement::defaultEventHandler(Event* evt)
+void HTMLSelectElement::defaultEventHandler(Event* event)
{
- if (!renderer())
+ SelectElement::defaultEventHandler(m_data, this, event, form());
+ if (event->defaultHandled())
return;
-
- if (usesMenuList())
- menuListDefaultEventHandler(evt);
- else
- listBoxDefaultEventHandler(evt);
-
- if (evt->defaultHandled())
- return;
-
- if (evt->type() == eventNames().keypressEvent && evt->isKeyboardEvent()) {
- KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(evt);
-
- if (!keyboardEvent->ctrlKey() && !keyboardEvent->altKey() && !keyboardEvent->metaKey() &&
- isPrintableChar(keyboardEvent->charCode())) {
- typeAheadFind(keyboardEvent);
- evt->setDefaultHandled();
- return;
- }
- }
-
- HTMLFormControlElementWithState::defaultEventHandler(evt);
-}
-
-void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
-{
- if (evt->type() == eventNames().keydownEvent) {
- if (!renderer() || !evt->isKeyboardEvent())
- return;
- String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
- bool handled = false;
-#if ARROW_KEYS_POP_MENU
- if (keyIdentifier == "Down" || keyIdentifier == "Up") {
- focus();
- // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
- // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
- saveLastSelection();
- if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer()))
- menuList->showPopup();
- handled = true;
- }
-#elif defined ANDROID_KEYBOARD_NAVIGATION
- if ("Enter" == keyIdentifier && usesMenuList()) {
- menuList->showPopup();
- handled = true;
- }
-#else
- int listIndex = optionToListIndex(selectedIndex());
- if (keyIdentifier == "Down" || keyIdentifier == "Right") {
- int size = listItems().size();
- for (listIndex += 1;
- listIndex >= 0 && listIndex < size && (listItems()[listIndex]->disabled() || !listItems()[listIndex]->hasTagName(optionTag));
- ++listIndex) { }
-
- if (listIndex >= 0 && listIndex < size)
- setSelectedIndex(listToOptionIndex(listIndex));
- handled = true;
- } else if (keyIdentifier == "Up" || keyIdentifier == "Left") {
- int size = listItems().size();
- for (listIndex -= 1;
- listIndex >= 0 && listIndex < size && (listItems()[listIndex]->disabled() || !listItems()[listIndex]->hasTagName(optionTag));
- --listIndex) { }
-
- if (listIndex >= 0 && listIndex < size)
- setSelectedIndex(listToOptionIndex(listIndex));
- handled = true;
- }
-#endif
- if (handled)
- evt->setDefaultHandled();
- }
-
- // 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) {
- if (!renderer() || !evt->isKeyboardEvent())
- return;
- int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode();
- bool handled = false;
-#if ARROW_KEYS_POP_MENU
- if (keyCode == ' ') {
- focus();
- // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
- // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
- saveLastSelection();
- if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer()))
- menuList->showPopup();
- handled = true;
- }
- if (keyCode == '\r') {
- menuListOnChange();
- if (form())
- form()->submitClick(evt);
- handled = true;
- }
-#else
- int listIndex = optionToListIndex(selectedIndex());
- if (keyCode == '\r') {
- // listIndex should already be selected, but this will fire the onchange handler.
- setSelectedIndex(listToOptionIndex(listIndex), true, true);
- handled = true;
- }
-#endif
- if (handled)
- evt->setDefaultHandled();
- }
-
- if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
- focus();
- if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer())) {
- if (menuList->popupIsVisible())
- menuList->hidePopup();
- else {
- // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
- // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
- saveLastSelection();
- menuList->showPopup();
- }
- }
- evt->setDefaultHandled();
- }
+ HTMLFormControlElementWithState::defaultEventHandler(event);
}
-void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt)
+void HTMLSelectElement::setActiveSelectionAnchorIndex(int index)
{
- if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
- focus();
-
- // Convert to coords relative to the list box if needed.
- MouseEvent* mouseEvent = static_cast<MouseEvent*>(evt);
- IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
- int listIndex = static_cast<RenderListBox*>(renderer())->listIndexAtOffset(localOffset.x(), localOffset.y());
- if (listIndex >= 0) {
- // Save the selection so it can be compared to the new selection when we call onChange during mouseup, or after autoscroll finishes.
- saveLastSelection();
-
- m_activeSelectionState = true;
-
- bool multiSelectKeyPressed = false;
-#if PLATFORM(MAC)
- multiSelectKeyPressed = mouseEvent->metaKey();
-#else
- multiSelectKeyPressed = mouseEvent->ctrlKey();
-#endif
-
- bool shiftSelect = multiple() && mouseEvent->shiftKey();
- bool multiSelect = multiple() && multiSelectKeyPressed && !mouseEvent->shiftKey();
-
- HTMLElement* clickedElement = listItems()[listIndex];
- HTMLOptionElement* option = 0;
- if (clickedElement->hasLocalName(optionTag)) {
- option = static_cast<HTMLOptionElement*>(clickedElement);
-
- // Keep track of whether an active selection (like during drag selection), should select or deselect
- if (option->selected() && multiSelectKeyPressed)
- m_activeSelectionState = false;
-
- if (!m_activeSelectionState)
- option->setSelectedState(false);
- }
-
- // If we're not in any special multiple selection mode, then deselect all other items, excluding the clicked option.
- // If no option was clicked, then this will deselect all items in the list.
- if (!shiftSelect && !multiSelect)
- deselectItems(option);
-
- // If the anchor hasn't been set, and we're doing a single selection or a shift selection, then initialize the anchor to the first selected index.
- if (m_activeSelectionAnchorIndex < 0 && !multiSelect)
- setActiveSelectionAnchorIndex(selectedIndex());
-
- // Set the selection state of the clicked option
- if (option && !option->disabled())
- option->setSelectedState(true);
-
- // If there was no selectedIndex() for the previous initialization, or
- // If we're doing a single selection, or a multiple selection (using cmd or ctrl), then initialize the anchor index to the listIndex that just got clicked.
- if (listIndex >= 0 && (m_activeSelectionAnchorIndex < 0 || !shiftSelect))
- setActiveSelectionAnchorIndex(listIndex);
-
- setActiveSelectionEndIndex(listIndex);
- updateListBoxSelection(!multiSelect);
-
- if (Frame* frame = document()->frame())
- frame->eventHandler()->setMouseDownMayStartAutoscroll();
-
- evt->setDefaultHandled();
- }
- } else if (evt->type() == eventNames().mouseupEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer())
- // This makes sure we fire onChange for a single click. For drag selection, onChange will fire when the autoscroll timer stops.
- listBoxOnChange();
- else if (evt->type() == eventNames().keydownEvent) {
- if (!evt->isKeyboardEvent())
- return;
- String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
-
- int endIndex = 0;
- if (m_activeSelectionEndIndex < 0) {
- // Initialize the end index
- if (keyIdentifier == "Down")
- endIndex = nextSelectableListIndex(lastSelectedListIndex());
- else if (keyIdentifier == "Up")
- endIndex = previousSelectableListIndex(optionToListIndex(selectedIndex()));
- } else {
- // Set the end index based on the current end index
- if (keyIdentifier == "Down")
- endIndex = nextSelectableListIndex(m_activeSelectionEndIndex);
- else if (keyIdentifier == "Up")
- endIndex = previousSelectableListIndex(m_activeSelectionEndIndex);
- }
-
- if (keyIdentifier == "Down" || keyIdentifier == "Up") {
- // Save the selection so it can be compared to the new selection when we call onChange immediately after making the new selection.
- saveLastSelection();
-
- ASSERT(endIndex >= 0 && (unsigned)endIndex < listItems().size());
- setActiveSelectionEndIndex(endIndex);
-
- // If the anchor is unitialized, or if we're going to deselect all other options, then set the anchor index equal to the end index.
- bool deselectOthers = !multiple() || !static_cast<KeyboardEvent*>(evt)->shiftKey();
- if (m_activeSelectionAnchorIndex < 0 || deselectOthers) {
- m_activeSelectionState = true;
- if (deselectOthers)
- deselectItems();
- setActiveSelectionAnchorIndex(m_activeSelectionEndIndex);
- }
-
- static_cast<RenderListBox*>(renderer())->scrollToRevealElementAtListIndex(endIndex);
- updateListBoxSelection(deselectOthers);
- listBoxOnChange();
- evt->setDefaultHandled();
- }
- } else if (evt->type() == eventNames().keypressEvent) {
- if (!evt->isKeyboardEvent())
- return;
- int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode();
-
- if (keyCode == '\r') {
- if (form())
- form()->submitClick(evt);
- evt->setDefaultHandled();
- return;
- }
- }
+ SelectElement::setActiveSelectionAnchorIndex(m_data, this, index);
}
-void HTMLSelectElement::setActiveSelectionAnchorIndex(int index)
+void HTMLSelectElement::setActiveSelectionEndIndex(int index)
{
- m_activeSelectionAnchorIndex = index;
-
- // Cache the selection state so we can restore the old selection as the new selection pivots around this anchor index
- const Vector<HTMLElement*>& items = listItems();
- m_cachedStateForActiveSelection.clear();
- for (unsigned i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
- HTMLOptionElement* option = static_cast<HTMLOptionElement*>(items[i]);
- m_cachedStateForActiveSelection.append(option->selected());
- } else
- m_cachedStateForActiveSelection.append(false);
- }
+ SelectElement::setActiveSelectionEndIndex(m_data, index);
}
void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
{
- ASSERT(renderer() && renderer()->isListBox());
-
- unsigned start;
- unsigned end;
- ASSERT(m_activeSelectionAnchorIndex >= 0);
- start = min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
- end = max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
-
- const Vector<HTMLElement*>& items = listItems();
- for (unsigned i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
- HTMLOptionElement* option = static_cast<HTMLOptionElement*>(items[i]);
- if (!option->disabled()) {
- if (i >= start && i <= end)
- option->setSelectedState(m_activeSelectionState);
- else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.size())
- option->setSelectedState(false);
- else
- option->setSelectedState(m_cachedStateForActiveSelection[i]);
- }
- }
- }
-
- scrollToSelection();
+ SelectElement::updateListBoxSelection(m_data, this, deselectOtherOptions);
}
void HTMLSelectElement::menuListOnChange()
{
- ASSERT(usesMenuList());
- int selected = selectedIndex();
- if (m_lastOnChangeIndex != selected) {
- m_lastOnChangeIndex = selected;
- onChange();
- }
+ SelectElement::menuListOnChange(m_data, this);
}
void HTMLSelectElement::listBoxOnChange()
{
- ASSERT(!usesMenuList());
-
- const Vector<HTMLElement*>& items = listItems();
-
- // If the cached selection list is empty, or the size has changed, then fire onChange, and return early.
- if (m_lastOnChangeSelection.isEmpty() || m_lastOnChangeSelection.size() != items.size()) {
- onChange();
- return;
- }
-
- // Update m_lastOnChangeSelection and fire onChange
- bool fireOnChange = false;
- for (unsigned i = 0; i < items.size(); i++) {
- bool selected = false;
- if (items[i]->hasLocalName(optionTag))
- selected = static_cast<HTMLOptionElement*>(items[i])->selected();
- if (selected != m_lastOnChangeSelection[i])
- fireOnChange = true;
- m_lastOnChangeSelection[i] = selected;
- }
- if (fireOnChange)
- onChange();
+ SelectElement::listBoxOnChange(m_data, this);
}
void HTMLSelectElement::saveLastSelection()
{
- const Vector<HTMLElement*>& items = listItems();
-
- if (usesMenuList()) {
- m_lastOnChangeIndex = selectedIndex();
- return;
- }
-
- m_lastOnChangeSelection.clear();
- for (unsigned i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
- HTMLOptionElement* option = static_cast<HTMLOptionElement*>(items[i]);
- m_lastOnChangeSelection.append(option->selected());
- } else
- m_lastOnChangeSelection.append(false);
- }
-}
-
-static String stripLeadingWhiteSpace(const String& string)
-{
- int length = string.length();
- int i;
- for (i = 0; i < length; ++i)
- if (string[i] != noBreakSpace &&
- (string[i] <= 0x7F ? !isASCIISpace(string[i]) : (direction(string[i]) != WhiteSpaceNeutral)))
- break;
-
- return string.substring(i, length - i);
-}
-
-void HTMLSelectElement::typeAheadFind(KeyboardEvent* event)
-{
- if (event->timeStamp() < m_lastCharTime)
- return;
-
- DOMTimeStamp delta = event->timeStamp() - m_lastCharTime;
-
- m_lastCharTime = event->timeStamp();
-
- UChar c = event->charCode();
-
- String prefix;
- int searchStartOffset = 1;
- if (delta > typeAheadTimeout) {
- m_typedString = prefix = String(&c, 1);
- m_repeatingChar = c;
- } else {
- m_typedString.append(c);
-
- if (c == m_repeatingChar)
- // The user is likely trying to cycle through all the items starting with this character, so just search on the character
- prefix = String(&c, 1);
- else {
- m_repeatingChar = 0;
- prefix = m_typedString;
- searchStartOffset = 0;
- }
- }
-
- const Vector<HTMLElement*>& items = listItems();
- int itemCount = items.size();
- if (itemCount < 1)
- return;
-
- int selected = selectedIndex();
- int index = (optionToListIndex(selected >= 0 ? selected : 0) + searchStartOffset) % itemCount;
- ASSERT(index >= 0);
- for (int i = 0; i < itemCount; i++, index = (index + 1) % itemCount) {
- if (!items[index]->hasTagName(optionTag) || items[index]->disabled())
- continue;
-
- String text = static_cast<HTMLOptionElement*>(items[index])->textIndentedToRespectGroupLabel();
- if (stripLeadingWhiteSpace(text).startsWith(prefix, false)) {
- setSelectedIndex(listToOptionIndex(index));
- if(!usesMenuList())
- listBoxOnChange();
- setChanged();
- return;
- }
- }
-}
-
-int HTMLSelectElement::nextSelectableListIndex(int startIndex)
-{
- const Vector<HTMLElement*>& items = listItems();
- int index = startIndex + 1;
- while (index >= 0 && (unsigned)index < items.size() && (!items[index]->hasLocalName(optionTag) || items[index]->disabled()))
- index++;
- if ((unsigned) index == items.size())
- return startIndex;
- return index;
-}
-
-int HTMLSelectElement::previousSelectableListIndex(int startIndex)
-{
- const Vector<HTMLElement*>& items = listItems();
- if (startIndex == -1)
- startIndex = items.size();
- int index = startIndex - 1;
- while (index >= 0 && (unsigned)index < items.size() && (!items[index]->hasLocalName(optionTag) || items[index]->disabled()))
- index--;
- if (index == -1)
- return startIndex;
- return index;
+ SelectElement::saveLastSelection(m_data, this);
}
void HTMLSelectElement::accessKeyAction(bool sendToAnyElement)
@@ -992,23 +341,8 @@ void HTMLSelectElement::accessKeyAction(bool sendToAnyElement)
}
void HTMLSelectElement::accessKeySetSelectedIndex(int index)
-{
- // first bring into focus the list box
- if (!focused())
- accessKeyAction(false);
-
- // if this index is already selected, unselect. otherwise update the selected index
- Node* listNode = item(index);
- if (listNode && listNode->hasTagName(optionTag)) {
- HTMLOptionElement* listElement = static_cast<HTMLOptionElement*>(listNode);
- if (listElement->selected())
- listElement->setSelectedState(false);
- else
- setSelectedIndex(index, false, true);
- }
-
- listBoxOnChange();
- scrollToSelection();
+{
+ SelectElement::accessKeySetSelectedIndex(m_data, this, index);
}
void HTMLSelectElement::setMultiple(bool multiple)
@@ -1050,7 +384,7 @@ void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, Exc
if (!ec) {
add(option, before, ec);
if (diff >= 0 && option->selected())
- setSelectedIndex(index, !m_multiple);
+ setSelectedIndex(index, !m_data.multiple());
}
}
@@ -1069,27 +403,29 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
if (ec)
break;
} while (++diff);
+ } else {
+ const Vector<Element*>& items = listItems();
+
+ size_t optionIndex = 0;
+ for (size_t listIndex = 0; listIndex < items.size(); listIndex++) {
+ if (items[listIndex]->hasLocalName(optionTag) && optionIndex++ >= newLen) {
+ Element *item = items[listIndex];
+ ASSERT(item->parentNode());
+ item->parentNode()->removeChild(item, ec);
+ }
+ }
}
- else // remove elements
- while (diff-- > 0)
- remove(newLen);
}
void HTMLSelectElement::scrollToSelection()
{
- if (renderer() && !usesMenuList())
- static_cast<RenderListBox*>(renderer())->selectionChanged();
+ SelectElement::scrollToSelection(m_data, this);
}
-#ifndef NDEBUG
-
-void HTMLSelectElement::checkListItems() const
+void HTMLSelectElement::insertedIntoTree(bool deep)
{
- Vector<HTMLElement*> items = m_listItems;
- recalcListItems(false);
- ASSERT(items == m_listItems);
+ SelectElement::insertedIntoTree(m_data, this);
+ HTMLFormControlElementWithState::insertedIntoTree(deep);
}
-#endif
-
} // namespace
diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h
index 59e4a4b..df7832c 100644
--- a/WebCore/html/HTMLSelectElement.h
+++ b/WebCore/html/HTMLSelectElement.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009 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
@@ -24,10 +24,9 @@
#ifndef HTMLSelectElement_h
#define HTMLSelectElement_h
-#include "Event.h"
-#include "HTMLCollection.h"
+#include "CollectionCache.h"
#include "HTMLFormControlElement.h"
-#include <wtf/Vector.h>
+#include "SelectElement.h"
namespace WebCore {
@@ -35,77 +34,32 @@ class HTMLOptionElement;
class HTMLOptionsCollection;
class KeyboardEvent;
-class HTMLSelectElement : public HTMLFormControlElementWithState {
+class HTMLSelectElement : public HTMLFormControlElementWithState, public SelectElement {
public:
HTMLSelectElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
- virtual int tagPriority() const { return 6; }
- virtual bool checkDTD(const Node* newChild);
-
- virtual const AtomicString& type() const;
-
- virtual bool isKeyboardFocusable(KeyboardEvent*) const;
- virtual bool isMouseFocusable() const;
- virtual bool canSelectAll() const;
- virtual void selectAll();
-
- virtual void recalcStyle(StyleChange);
-
- virtual void dispatchFocusEvent();
- virtual void dispatchBlurEvent();
-
- virtual bool canStartSelection() const { return false; }
-
- int selectedIndex() const;
- void setSelectedIndex(int index, bool deselect = true, bool fireOnChange = false);
- int lastSelectedListIndex() const;
-
- virtual bool isEnumeratable() const { return true; }
+ virtual int selectedIndex() const;
+ virtual void setSelectedIndex(int index, bool deselect = true, bool fireOnChange = false);
unsigned length() const;
- int minWidth() const { return m_minwidth; }
-
- int size() const { return m_size; }
-
- bool multiple() const { return m_multiple; }
+ virtual int size() const { return m_data.size(); }
+ virtual bool multiple() const { return m_data.multiple(); }
void add(HTMLElement* element, HTMLElement* before, ExceptionCode&);
void remove(int index);
String value();
void setValue(const String&);
-
- PassRefPtr<HTMLOptionsCollection> options();
- virtual bool saveState(String& value) const;
- virtual void restoreState(const String&);
+ PassRefPtr<HTMLOptionsCollection> options();
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
- virtual void parseMappedAttribute(MappedAttribute*);
-
- virtual RenderObject* createRenderer(RenderArena*, RenderStyle *);
- virtual bool appendFormData(FormDataList&, bool);
-
- // get the actual listbox index of the optionIndexth option
- int optionToListIndex(int optionIndex) const;
- // reverse of optionToListIndex - get optionIndex from listboxIndex
- int listToOptionIndex(int listIndex) const;
-
void setRecalcListItems();
- const Vector<HTMLElement*>& listItems() const
- {
- if (m_recalcListItems)
- recalcListItems();
- else
- checkListItems();
- return m_listItems;
- }
- virtual void reset();
+ virtual const Vector<Element*>& listItems() const { return m_data.listItems(this); }
- virtual void defaultEventHandler(Event*);
virtual void accessKeyAction(bool sendToAnyElement);
void accessKeySetSelectedIndex(int);
@@ -119,64 +73,72 @@ public:
Node* namedItem(const AtomicString& name);
Node* item(unsigned index);
- HTMLCollection::CollectionInfo* collectionInfo() { return &m_collectionInfo; }
-
- void setActiveSelectionAnchorIndex(int index);
- void setActiveSelectionEndIndex(int index) { m_activeSelectionEndIndex = index; }
- void updateListBoxSelection(bool deselectOtherOptions);
- void listBoxOnChange();
- void menuListOnChange();
+ CollectionCache* collectionInfo() { return &m_collectionInfo; }
+
+ void scrollToSelection();
+
+private:
+ virtual int tagPriority() const { return 6; }
+ virtual bool checkDTD(const Node* newChild);
+
+ virtual const AtomicString& formControlType() const;
- int activeSelectionStartListIndex() const;
- int activeSelectionEndListIndex() const;
+ virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+ virtual bool isMouseFocusable() const;
+ virtual bool canSelectAll() const;
+ virtual void selectAll();
+
+ virtual void recalcStyle(StyleChange);
+
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
- void scrollToSelection();
+ virtual bool canStartSelection() const { return false; }
+
+ virtual bool isEnumeratable() const { return true; }
+
+ virtual bool saveFormControlState(String& value) const;
+ virtual void restoreFormControlState(const String&);
+ virtual void parseMappedAttribute(MappedAttribute*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle *);
+ virtual bool appendFormData(FormDataList&, bool);
+
+#if PLATFORM(ANDROID)
+public:
+ virtual int listToOptionIndex(int listIndex) const;
+ virtual int optionToListIndex(int optionIndex) const;
private:
+#else
+ virtual int listToOptionIndex(int listIndex) const;
+ virtual int optionToListIndex(int optionIndex) const;
+#endif
+
+ virtual void reset();
+
+ virtual void defaultEventHandler(Event*);
+
+ 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 recalcListItems(bool updateSelectedStates = true) const;
- void checkListItems() const;
void deselectItems(HTMLOptionElement* excludeElement = 0);
-#ifdef ANDROID_LISTBOX_USES_MENU_LIST
- bool usesMenuList() const { return true; }
-#else
- bool usesMenuList() const { return !m_multiple && m_size <= 1; }
-#endif
- int nextSelectableListIndex(int startIndex);
- int previousSelectableListIndex(int startIndex);
- void menuListDefaultEventHandler(Event*);
- void listBoxDefaultEventHandler(Event*);
void typeAheadFind(KeyboardEvent*);
void saveLastSelection();
- mutable Vector<HTMLElement*> m_listItems;
- Vector<bool> m_cachedStateForActiveSelection;
- Vector<bool> m_lastOnChangeSelection;
- int m_minwidth;
- int m_size;
- bool m_multiple;
- mutable bool m_recalcListItems;
- mutable int m_lastOnChangeIndex;
-
- int m_activeSelectionAnchorIndex;
- int m_activeSelectionEndIndex;
- bool m_activeSelectionState;
-
- // Instance variables for type-ahead find
- UChar m_repeatingChar;
- DOMTimeStamp m_lastCharTime;
- String m_typedString;
-
- HTMLCollection::CollectionInfo m_collectionInfo;
-};
+ virtual void insertedIntoTree(bool);
-#ifdef NDEBUG
-
-inline void HTMLSelectElement::checkListItems() const
-{
-}
-
-#endif
+ SelectElementData m_data;
+ CollectionCache m_collectionInfo;
+};
} // namespace
diff --git a/WebCore/html/HTMLSelectElement.idl b/WebCore/html/HTMLSelectElement.idl
index d3e85a8..fb08bb1 100644
--- a/WebCore/html/HTMLSelectElement.idl
+++ b/WebCore/html/HTMLSelectElement.idl
@@ -33,7 +33,7 @@ module html {
attribute [ConvertNullToNullString] DOMString value;
// Modified in DOM Level 2:
-#if defined(LANGUAGE_OBJECTIVE_C)
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
readonly attribute long length;
#else
attribute unsigned long length
@@ -56,7 +56,7 @@ module html {
in HTMLElement before)
raises(DOMException);
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
// In JS, we support both options index and options object parameters - this cannot be autogenerated now.
[Custom] void remove(/* 1 */);
#else
diff --git a/WebCore/html/HTMLSourceElement.cpp b/WebCore/html/HTMLSourceElement.cpp
index 609bcbf..2f09997 100644
--- a/WebCore/html/HTMLSourceElement.cpp
+++ b/WebCore/html/HTMLSourceElement.cpp
@@ -28,6 +28,7 @@
#if ENABLE(VIDEO)
#include "HTMLSourceElement.h"
+#include "EventNames.h"
#include "HTMLDocument.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
@@ -40,6 +41,7 @@ using namespace HTMLNames;
HTMLSourceElement::HTMLSourceElement(const QualifiedName& tagName, Document* doc)
: HTMLElement(tagName, doc)
+ , m_errorEventTimer(this, &HTMLSourceElement::errorEventTimerFired)
{
ASSERT(hasTagName(sourceTag));
}
@@ -88,5 +90,23 @@ void HTMLSourceElement::setType(const String& type)
setAttribute(typeAttr, type);
}
+void HTMLSourceElement::scheduleErrorEvent()
+{
+ if (m_errorEventTimer.isActive())
+ return;
+
+ m_errorEventTimer.startOneShot(0);
+}
+
+void HTMLSourceElement::cancelPendingErrorEvent()
+{
+ m_errorEventTimer.stop();
+}
+
+void HTMLSourceElement::errorEventTimerFired(Timer<HTMLSourceElement>*)
+{
+ dispatchEvent(eventNames().errorEvent, false, true);
+}
+
}
#endif
diff --git a/WebCore/html/HTMLSourceElement.h b/WebCore/html/HTMLSourceElement.h
index 9027b88..50d6687 100644
--- a/WebCore/html/HTMLSourceElement.h
+++ b/WebCore/html/HTMLSourceElement.h
@@ -29,6 +29,7 @@
#if ENABLE(VIDEO)
#include "HTMLElement.h"
+#include "Timer.h"
#include <limits>
namespace WebCore {
@@ -51,6 +52,14 @@ public:
void setSrc(const String&);
void setMedia(const String&);
void setType(const String&);
+
+ void scheduleErrorEvent();
+ void cancelPendingErrorEvent();
+
+private:
+ void errorEventTimerFired(Timer<HTMLSourceElement>*);
+
+ Timer<HTMLSourceElement> m_errorEventTimer;
};
} //namespace
diff --git a/WebCore/html/HTMLStyleElement.cpp b/WebCore/html/HTMLStyleElement.cpp
index bed1cdc..f6b5924 100644
--- a/WebCore/html/HTMLStyleElement.cpp
+++ b/WebCore/html/HTMLStyleElement.cpp
@@ -20,11 +20,13 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLStyleElement.h"
#include "Document.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLStyleElement.idl b/WebCore/html/HTMLStyleElement.idl
index e6238b7..a1b86f8 100644
--- a/WebCore/html/HTMLStyleElement.idl
+++ b/WebCore/html/HTMLStyleElement.idl
@@ -29,7 +29,7 @@ module html {
attribute [ConvertNullToNullString] DOMString media;
attribute [ConvertNullToNullString] DOMString type;
-#if !defined(LANGUAGE_COM)
+#if !defined(LANGUAGE_COM) || !LANGUAGE_COM
// DOM Level 2 Style
readonly attribute StyleSheet sheet;
#endif
diff --git a/WebCore/html/HTMLTableCaptionElement.cpp b/WebCore/html/HTMLTableCaptionElement.cpp
index 35cf8a1..2c94727 100644
--- a/WebCore/html/HTMLTableCaptionElement.cpp
+++ b/WebCore/html/HTMLTableCaptionElement.cpp
@@ -21,11 +21,13 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLTableCaptionElement.h"
#include "CSSPropertyNames.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLTableCellElement.cpp b/WebCore/html/HTMLTableCellElement.cpp
index 1313393..05f02c7 100644
--- a/WebCore/html/HTMLTableCellElement.cpp
+++ b/WebCore/html/HTMLTableCellElement.cpp
@@ -23,6 +23,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLTableCellElement.h"
@@ -30,6 +31,7 @@
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
#include "HTMLTableElement.h"
+#include "MappedAttribute.h"
#include "RenderTableCell.h"
#ifdef ANDROID_LAYOUT
#include "Document.h"
diff --git a/WebCore/html/HTMLTableColElement.cpp b/WebCore/html/HTMLTableColElement.cpp
index 11f6df6..ae18ab1 100644
--- a/WebCore/html/HTMLTableColElement.cpp
+++ b/WebCore/html/HTMLTableColElement.cpp
@@ -23,13 +23,15 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLTableColElement.h"
#include "CSSPropertyNames.h"
#include "HTMLNames.h"
-#include "RenderTableCol.h"
#include "HTMLTableElement.h"
+#include "MappedAttribute.h"
+#include "RenderTableCol.h"
#include "Text.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLTableElement.cpp b/WebCore/html/HTMLTableElement.cpp
index bb2c2ee..e37c171 100644
--- a/WebCore/html/HTMLTableElement.cpp
+++ b/WebCore/html/HTMLTableElement.cpp
@@ -31,9 +31,10 @@
#include "ExceptionCode.h"
#include "HTMLNames.h"
#include "HTMLTableCaptionElement.h"
-#include "HTMLTableRowsCollection.h"
#include "HTMLTableRowElement.h"
+#include "HTMLTableRowsCollection.h"
#include "HTMLTableSectionElement.h"
+#include "MappedAttribute.h"
#include "RenderTable.h"
#include "Text.h"
@@ -310,7 +311,7 @@ static bool setTableCellsChanged(Node* n)
}
if (cellChanged)
- n->setChanged();
+ n->setNeedsStyleRecalc();
return cellChanged;
}
@@ -455,7 +456,7 @@ void HTMLTableElement::parseMappedAttribute(MappedAttribute* attr)
for (Node* child = firstChild(); child; child = child->nextSibling())
cellChanged |= setTableCellsChanged(child);
if (cellChanged)
- setChanged();
+ setNeedsStyleRecalc();
}
}
@@ -655,7 +656,7 @@ PassRefPtr<HTMLCollection> HTMLTableElement::rows()
PassRefPtr<HTMLCollection> HTMLTableElement::tBodies()
{
- return HTMLCollection::create(this, HTMLCollection::TableTBodies);
+ return HTMLCollection::create(this, TableTBodies);
}
String HTMLTableElement::align() const
diff --git a/WebCore/html/HTMLTablePartElement.cpp b/WebCore/html/HTMLTablePartElement.cpp
index 6341197..19babf6 100644
--- a/WebCore/html/HTMLTablePartElement.cpp
+++ b/WebCore/html/HTMLTablePartElement.cpp
@@ -23,6 +23,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLTablePartElement.h"
@@ -31,6 +32,7 @@
#include "CSSValueKeywords.h"
#include "Document.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLTableRowElement.cpp b/WebCore/html/HTMLTableRowElement.cpp
index 98d928a..94be02e 100644
--- a/WebCore/html/HTMLTableRowElement.cpp
+++ b/WebCore/html/HTMLTableRowElement.cpp
@@ -168,7 +168,7 @@ void HTMLTableRowElement::deleteCell(int index, ExceptionCode& ec)
PassRefPtr<HTMLCollection> HTMLTableRowElement::cells()
{
- return HTMLCollection::create(this, HTMLCollection::TRCells);
+ return HTMLCollection::create(this, TRCells);
}
void HTMLTableRowElement::setCells(HTMLCollection *, ExceptionCode& ec)
diff --git a/WebCore/html/HTMLTableRowsCollection.cpp b/WebCore/html/HTMLTableRowsCollection.cpp
index 7047576..b38c271 100644
--- a/WebCore/html/HTMLTableRowsCollection.cpp
+++ b/WebCore/html/HTMLTableRowsCollection.cpp
@@ -149,7 +149,7 @@ HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
}
HTMLTableRowsCollection::HTMLTableRowsCollection(PassRefPtr<HTMLTableElement> table)
- : HTMLCollection(table, Other, 0)
+ : HTMLCollection(table, OtherCollection, 0)
{
}
diff --git a/WebCore/html/HTMLTableSectionElement.cpp b/WebCore/html/HTMLTableSectionElement.cpp
index 900976c..e91a96a 100644
--- a/WebCore/html/HTMLTableSectionElement.cpp
+++ b/WebCore/html/HTMLTableSectionElement.cpp
@@ -167,7 +167,7 @@ void HTMLTableSectionElement::setVAlign(const String &value)
PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows()
{
- return HTMLCollection::create(this, HTMLCollection::TSectionRows);
+ return HTMLCollection::create(this, TSectionRows);
}
}
diff --git a/WebCore/html/HTMLTagNames.in b/WebCore/html/HTMLTagNames.in
index 8b1fa2b..14119ef 100644
--- a/WebCore/html/HTMLTagNames.in
+++ b/WebCore/html/HTMLTagNames.in
@@ -8,9 +8,7 @@ acronym interfaceName=HTMLElement
address interfaceName=HTMLElement
applet
area
-#if ENABLE_VIDEO
-audio wrapperOnlyIfMediaIsAvailable
-#endif
+audio wrapperOnlyIfMediaIsAvailable,conditional=VIDEO
b interfaceName=HTMLElement
base
basefont interfaceName=HTMLBaseFontElement
@@ -39,7 +37,7 @@ embed
fieldset interfaceName=HTMLFieldSetElement, constructorNeedsFormElement
font
form
-frame constructorNeedsCreatedByParser
+frame
frameset interfaceName=HTMLFrameSetElement
head
h1 interfaceName=HTMLHeadingElement
@@ -51,7 +49,7 @@ h6 interfaceName=HTMLHeadingElement
hr interfaceName=HTMLHRElement
html
i interfaceName=HTMLElement
-iframe interfaceName=HTMLIFrameElement, constructorNeedsCreatedByParser
+iframe interfaceName=HTMLIFrameElement
image mapToTagName=img
img interfaceName=HTMLImageElement, constructorNeedsFormElement
input constructorNeedsFormElement
@@ -73,7 +71,11 @@ nobr interfaceName=HTMLElement
noembed interfaceName=HTMLElement
noframes interfaceName=HTMLElement
nolayer interfaceName=HTMLElement
+#if ENABLE_XHTMLMP
+noscript interfaceName=HTMLNoScriptElement
+#else
noscript interfaceName=HTMLElement
+#endif
object constructorNeedsCreatedByParser
ol interfaceName=HTMLOListElement
optgroup interfaceName=HTMLOptGroupElement, constructorNeedsFormElement
@@ -88,9 +90,7 @@ samp interfaceName=HTMLElement
script constructorNeedsCreatedByParser
select constructorNeedsFormElement
small interfaceName=HTMLElement
-#if ENABLE_VIDEO
-source wrapperOnlyIfMediaIsAvailable
-#endif
+source wrapperOnlyIfMediaIsAvailable,conditional=VIDEO
span interfaceName=HTMLElement
strike interfaceName=HTMLElement
strong interfaceName=HTMLElement
@@ -110,8 +110,6 @@ tt interfaceName=HTMLElement
u interfaceName=HTMLElement
ul interfaceName=HTMLUListElement
var interfaceName=HTMLElement
-#if ENABLE_VIDEO
-video wrapperOnlyIfMediaIsAvailable
-#endif
+video wrapperOnlyIfMediaIsAvailable,conditional=VIDEO
wbr interfaceName=HTMLElement
xmp interfaceName=HTMLPreElement
diff --git a/WebCore/html/HTMLTextAreaElement.cpp b/WebCore/html/HTMLTextAreaElement.cpp
index 4eec088..41a0126 100644
--- a/WebCore/html/HTMLTextAreaElement.cpp
+++ b/WebCore/html/HTMLTextAreaElement.cpp
@@ -34,11 +34,13 @@
#include "FormDataList.h"
#include "Frame.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "Page.h"
#include "RenderStyle.h"
#include "RenderTextControlMultiLine.h"
-#include "VisibleSelection.h"
+#include "ScriptEventListener.h"
#include "Text.h"
+#include "VisibleSelection.h"
#include <wtf/StdLibExtras.h>
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
@@ -69,23 +71,23 @@ HTMLTextAreaElement::HTMLTextAreaElement(const QualifiedName& tagName, Document*
, m_cachedSelectionEnd(-1)
{
ASSERT(hasTagName(textareaTag));
- setValueMatchesRenderer();
+ setFormControlValueMatchesRenderer(true);
notifyFormStateChanged(this);
}
-const AtomicString& HTMLTextAreaElement::type() const
+const AtomicString& HTMLTextAreaElement::formControlType() const
{
DEFINE_STATIC_LOCAL(const AtomicString, textarea, ("textarea"));
return textarea;
}
-bool HTMLTextAreaElement::saveState(String& result) const
+bool HTMLTextAreaElement::saveFormControlState(String& result) const
{
result = value();
return true;
}
-void HTMLTextAreaElement::restoreState(const String& state)
+void HTMLTextAreaElement::restoreFormControlState(const String& state)
{
setDefaultValue(state);
}
@@ -183,13 +185,13 @@ void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute* attr)
// Don't map 'align' attribute. This matches what Firefox, Opera and IE do.
// See http://bugs.webkit.org/show_bug.cgi?id=7075
} else if (attr->name() == onfocusAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
+ setAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(this, attr));
else if (attr->name() == onblurAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
+ setAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(this, attr));
else if (attr->name() == onselectAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().selectEvent, attr);
+ setAttributeEventListener(eventNames().selectEvent, createAttributeEventListener(this, attr));
else if (attr->name() == onchangeAttr)
- setInlineEventListenerForTypeAndAttribute(eventNames().changeEvent, attr);
+ setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr));
else
HTMLFormControlElementWithState::parseMappedAttribute(attr);
}
@@ -268,12 +270,12 @@ void HTMLTextAreaElement::rendererWillBeDestroyed()
void HTMLTextAreaElement::updateValue() const
{
- if (valueMatchesRenderer())
+ if (formControlValueMatchesRenderer())
return;
ASSERT(renderer());
m_value = toRenderTextControl(renderer())->text();
- const_cast<HTMLTextAreaElement*>(this)->setValueMatchesRenderer();
+ const_cast<HTMLTextAreaElement*>(this)->setFormControlValueMatchesRenderer(true);
notifyFormStateChanged(this);
}
@@ -297,9 +299,9 @@ void HTMLTextAreaElement::setValue(const String& value)
return;
m_value = normalizedValue;
- setValueMatchesRenderer();
+ setFormControlValueMatchesRenderer(true);
if (inDocument())
- document()->updateRendering();
+ document()->updateStyleIfNeeded();
if (renderer())
renderer()->updateFromElement();
@@ -313,7 +315,7 @@ void HTMLTextAreaElement::setValue(const String& value)
setSelectionRange(endOfString, endOfString);
}
- setChanged();
+ setNeedsStyleRecalc();
notifyFormStateChanged(this);
}
diff --git a/WebCore/html/HTMLTextAreaElement.h b/WebCore/html/HTMLTextAreaElement.h
index f78386c..e22b5d5 100644
--- a/WebCore/html/HTMLTextAreaElement.h
+++ b/WebCore/html/HTMLTextAreaElement.h
@@ -43,14 +43,14 @@ public:
virtual bool isEnumeratable() const { return true; }
- virtual const AtomicString& type() const;
+ virtual const AtomicString& formControlType() const;
- virtual bool saveState(String& value) const;
- virtual void restoreState(const String&);
+ virtual bool saveFormControlState(String& value) const;
+ virtual void restoreFormControlState(const String&);
- bool readOnly() const { return isReadOnlyControl(); }
+ bool readOnly() const { return isReadOnlyFormControl(); }
- virtual bool isTextControl() const { return true; }
+ virtual bool isTextFormControl() const { return true; }
int selectionStart();
int selectionEnd();
diff --git a/WebCore/html/HTMLTokenizer.cpp b/WebCore/html/HTMLTokenizer.cpp
index e4952f7..25e9adf 100644
--- a/WebCore/html/HTMLTokenizer.cpp
+++ b/WebCore/html/HTMLTokenizer.cpp
@@ -7,6 +7,7 @@
(C) 2001 Dirk Mueller (mueller@kde.org)
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
Copyright (C) 2005, 2006 Alexey Proskuryakov (ap@nypop.com)
+ 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
@@ -40,6 +41,7 @@
#include "HTMLParser.h"
#include "HTMLScriptElement.h"
#include "HTMLViewSourceDocument.h"
+#include "MappedAttribute.h"
#include "Page.h"
#include "PreloadScanner.h"
#include "ScriptController.h"
@@ -449,6 +451,10 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
} else {
// Parse m_scriptCode containing <script> info
doScriptExec = m_scriptNode->shouldExecuteAsJavaScript();
+#if ENABLE(XHTMLMP)
+ if (!doScriptExec)
+ m_doc->setShouldProcessNoscriptElement(true);
+#endif
m_scriptNode = 0;
}
}
@@ -1884,7 +1890,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
ScriptController* scriptController = (!m_fragment && m_doc->frame()) ? m_doc->frame()->script() : 0;
if (scriptController && scriptController->isEnabled())
// FIXME: Why isn't this m_currentScriptTagStartLineNumber? I suspect this is wrong.
- scriptController->setEventHandlerLineno(m_currentTagStartLineNumber + 1); // Script line numbers are 1 based.
+ scriptController->setEventHandlerLineNumber(m_currentTagStartLineNumber + 1); // Script line numbers are 1 based.
if (m_dest > m_buffer) {
m_currentToken.text = StringImpl::createStrippingNullCharacters(m_buffer, m_dest - m_buffer);
if (m_currentToken.tagName != commentAtom)
@@ -1892,7 +1898,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
} else if (m_currentToken.tagName == nullAtom) {
m_currentToken.reset();
if (scriptController)
- scriptController->setEventHandlerLineno(m_lineNumber + 1); // Script line numbers are 1 based.
+ scriptController->setEventHandlerLineNumber(m_lineNumber + 1); // Script line numbers are 1 based.
return 0;
}
@@ -1911,7 +1917,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
}
m_currentToken.reset();
if (scriptController)
- scriptController->setEventHandlerLineno(0);
+ scriptController->setEventHandlerLineNumber(0);
return n.release();
}
@@ -1933,7 +1939,16 @@ HTMLTokenizer::~HTMLTokenizer()
void HTMLTokenizer::enlargeBuffer(int len)
{
- int newSize = max(m_bufferSize * 2, m_bufferSize + len);
+ // Resize policy: Always at least double the size of the buffer each time.
+ int delta = max(len, m_bufferSize);
+
+ // Check for overflow.
+ // For now, handle overflow the same way we handle fastRealloc failure, with CRASH.
+ static const int maxSize = INT_MAX / sizeof(UChar);
+ if (delta > maxSize - m_bufferSize)
+ CRASH();
+
+ int newSize = m_bufferSize + delta;
int oldOffset = m_dest - m_buffer;
m_buffer = static_cast<UChar*>(fastRealloc(m_buffer, newSize * sizeof(UChar)));
m_dest = m_buffer + oldOffset;
@@ -1942,7 +1957,16 @@ void HTMLTokenizer::enlargeBuffer(int len)
void HTMLTokenizer::enlargeScriptBuffer(int len)
{
- int newSize = max(m_scriptCodeCapacity * 2, m_scriptCodeCapacity + len);
+ // Resize policy: Always at least double the size of the buffer each time.
+ int delta = max(len, m_scriptCodeCapacity);
+
+ // Check for overflow.
+ // For now, handle overflow the same way we handle fastRealloc failure, with CRASH.
+ static const int maxSize = INT_MAX / sizeof(UChar);
+ if (delta > maxSize - m_scriptCodeCapacity)
+ CRASH();
+
+ int newSize = m_scriptCodeCapacity + delta;
m_scriptCode = static_cast<UChar*>(fastRealloc(m_scriptCode, newSize * sizeof(UChar)));
m_scriptCodeCapacity = newSize;
}
@@ -1992,11 +2016,15 @@ void HTMLTokenizer::notifyFinished(CachedResource*)
#endif
if (errorOccurred)
- n->dispatchEventForType(eventNames().errorEvent, true, false);
+ n->dispatchEvent(eventNames().errorEvent, true, false);
else {
if (static_cast<HTMLScriptElement*>(n.get())->shouldExecuteAsJavaScript())
m_state = scriptExecution(sourceCode, m_state);
- n->dispatchEventForType(eventNames().loadEvent, false, false);
+#if ENABLE(XHTMLMP)
+ else
+ m_doc->setShouldProcessNoscriptElement(true);
+#endif
+ n->dispatchEvent(eventNames().loadEvent, false, false);
}
// The state of m_pendingScripts.isEmpty() can change inside the scriptExecution()
diff --git a/WebCore/html/HTMLUListElement.cpp b/WebCore/html/HTMLUListElement.cpp
index c1a7644..f36cb57 100644
--- a/WebCore/html/HTMLUListElement.cpp
+++ b/WebCore/html/HTMLUListElement.cpp
@@ -18,11 +18,13 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#include "config.h"
#include "HTMLUListElement.h"
#include "CSSPropertyNames.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
namespace WebCore {
diff --git a/WebCore/html/HTMLVideoElement.cpp b/WebCore/html/HTMLVideoElement.cpp
index b0aac3c..d465b73 100644
--- a/WebCore/html/HTMLVideoElement.cpp
+++ b/WebCore/html/HTMLVideoElement.cpp
@@ -33,6 +33,7 @@
#include "Document.h"
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
+#include "MappedAttribute.h"
#include "RenderImage.h"
#include "RenderVideo.h"
diff --git a/WebCore/html/HTMLViewSourceDocument.cpp b/WebCore/html/HTMLViewSourceDocument.cpp
index 596f16e..d4d6df7 100644
--- a/WebCore/html/HTMLViewSourceDocument.cpp
+++ b/WebCore/html/HTMLViewSourceDocument.cpp
@@ -26,18 +26,19 @@
#include "HTMLViewSourceDocument.h"
#include "DOMImplementation.h"
-#include "HTMLTokenizer.h"
-#include "HTMLHtmlElement.h"
#include "HTMLAnchorElement.h"
#include "HTMLBodyElement.h"
#include "HTMLDivElement.h"
-#include "HTMLTableElement.h"
+#include "HTMLHtmlElement.h"
+#include "HTMLNames.h"
#include "HTMLTableCellElement.h"
+#include "HTMLTableElement.h"
#include "HTMLTableRowElement.h"
#include "HTMLTableSectionElement.h"
+#include "HTMLTokenizer.h"
+#include "MappedAttribute.h"
#include "Text.h"
#include "TextDocument.h"
-#include "HTMLNames.h"
namespace WebCore {
@@ -150,6 +151,17 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
m_current = static_cast<Element*>(m_current->parent());
} else {
const String& value = attr->value().string();
+
+ // Compare ignoring case since HTMLTokenizer doesn't
+ // lower names when passing in tokens to
+ // HTMLViewSourceDocument.
+ if (equalIgnoringCase(token->tagName, "base") && equalIgnoringCase(attr->name().localName(), "href")) {
+ // Catch the href attribute in the base element.
+ // It will be used for rendering anchors created
+ // by addLink() below.
+ setBaseElementURL(KURL(url(), value));
+ }
+
// FIXME: XML could use namespace prefixes and confuse us.
if (equalIgnoringCase(attr->name().localName(), "src") || equalIgnoringCase(attr->name().localName(), "href"))
m_current = addLink(value, equalIgnoringCase(token->tagName, "a"));
diff --git a/WebCore/html/ImageData.idl b/WebCore/html/ImageData.idl
index 9be14ff..7f37b52 100644
--- a/WebCore/html/ImageData.idl
+++ b/WebCore/html/ImageData.idl
@@ -34,7 +34,7 @@ module html {
] ImageData {
readonly attribute long width;
readonly attribute long height;
-#if !defined(LANGUAGE_JAVASCRIPT) || defined(V8_BINDING)
+#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT || defined(V8_BINDING) && V8_BINDING
readonly attribute CanvasPixelArray data;
#endif
};
diff --git a/WebCore/html/MediaError.h b/WebCore/html/MediaError.h
index 7dcf72a..5e77d9e 100644
--- a/WebCore/html/MediaError.h
+++ b/WebCore/html/MediaError.h
@@ -34,7 +34,7 @@ namespace WebCore {
class MediaError : public RefCounted<MediaError> {
public:
- enum Code { MEDIA_ERR_ABORTED = 1, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE, MEDIA_ERR_NONE_SUPPORTED };
+ enum Code { MEDIA_ERR_ABORTED = 1, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE, MEDIA_ERR_SRC_NOT_SUPPORTED };
static PassRefPtr<MediaError> create(Code code) { return adoptRef(new MediaError(code)); }
diff --git a/WebCore/html/MediaError.idl b/WebCore/html/MediaError.idl
index 162170f..4dcea7d 100644
--- a/WebCore/html/MediaError.idl
+++ b/WebCore/html/MediaError.idl
@@ -28,7 +28,7 @@ module html {
const unsigned short MEDIA_ERR_ABORTED = 1;
const unsigned short MEDIA_ERR_NETWORK = 2;
const unsigned short MEDIA_ERR_DECODE = 3;
- const unsigned short MEDIA_ERR_NONE_SUPPORTED = 4;
+ const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
readonly attribute unsigned short code;
};
}
diff --git a/WebCore/html/PreloadScanner.cpp b/WebCore/html/PreloadScanner.cpp
index 782e9bd..1c1d28a 100644
--- a/WebCore/html/PreloadScanner.cpp
+++ b/WebCore/html/PreloadScanner.cpp
@@ -44,7 +44,8 @@
#include <wtf/CurrentTime.h>
#include <wtf/unicode/Unicode.h>
-#if COMPILER(GCC)
+// Use __GNUC__ instead of PLATFORM(GCC) to stay consistent with the gperf generated c file
+#ifdef __GNUC__
// The main tokenizer includes this too so we are getting two copies of the data. However, this way the code gets inlined.
#include "HTMLEntityNames.c"
#else
@@ -225,8 +226,8 @@ unsigned PreloadScanner::consumeEntity(SegmentedString& source, bool& notEnoughC
else if (cc >= 'A' && cc <= 'F')
result = 10 + cc - 'A';
else {
- source.push(seenChars[1]);
source.push('#');
+ source.push(seenChars[1]);
return 0;
}
entityState = Hex;
@@ -280,8 +281,8 @@ unsigned PreloadScanner::consumeEntity(SegmentedString& source, bool& notEnoughC
if (seenChars.size() == 2)
source.push(seenChars[0]);
else if (seenChars.size() == 3) {
- source.push(seenChars[1]);
source.push(seenChars[0]);
+ source.push(seenChars[1]);
} else
source.prepend(SegmentedString(String(seenChars.data(), seenChars.size() - 1)));
return 0;
diff --git a/WebCore/html/TimeRanges.cpp b/WebCore/html/TimeRanges.cpp
index ad81ac8..e5b070d 100644
--- a/WebCore/html/TimeRanges.cpp
+++ b/WebCore/html/TimeRanges.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,17 @@ TimeRanges::TimeRanges(float start, float end)
add(start, end);
}
+PassRefPtr<TimeRanges> TimeRanges::copy()
+{
+ RefPtr<TimeRanges> newSession = TimeRanges::create();
+
+ unsigned size = m_ranges.size();
+ for (unsigned i = 0; i < size; i++)
+ newSession->add(m_ranges[i].m_start, m_ranges[i].m_end);
+
+ return newSession.release();
+}
+
float TimeRanges::start(unsigned index, ExceptionCode& ec) const
{
if (index >= length()) {
@@ -53,9 +64,46 @@ float TimeRanges::end(unsigned index, ExceptionCode& ec) const
}
void TimeRanges::add(float start, float end)
-{
- m_ranges.append(Range(start, end));
- // FIXME normalize
+{
+ ASSERT(start <= end);
+ unsigned int overlappingArcIndex;
+ Range addedRange(start, end);
+
+ // For each present range check if we need to:
+ // - merge with the added range, in case we are overlapping or contiguous
+ // - Need to insert in place, we we are completely, not overlapping and not contiguous
+ // in between two ranges.
+ //
+ // TODO: Given that we assume that ranges are correctly ordered, this could be optimized.
+
+ for (overlappingArcIndex = 0; overlappingArcIndex < m_ranges.size(); overlappingArcIndex++) {
+ if (addedRange.isOverlappingRange(m_ranges[overlappingArcIndex])
+ || addedRange.isContiguousWithRange(m_ranges[overlappingArcIndex])) {
+ // We need to merge the addedRange and that range.
+ addedRange = addedRange.unionWithOverlappingOrContiguousRange(m_ranges[overlappingArcIndex]);
+ m_ranges.remove(overlappingArcIndex);
+ overlappingArcIndex--;
+ } else {
+ // Check the case for which there is no more to do
+ if (!overlappingArcIndex) {
+ if (addedRange.isBeforeRange(m_ranges[0])) {
+ // First index, and we are completely before that range (and not contiguous, nor overlapping).
+ // We just need to be inserted here.
+ break;
+ }
+ } else {
+ if (m_ranges[overlappingArcIndex - 1].isBeforeRange(addedRange)
+ && addedRange.isBeforeRange(m_ranges[overlappingArcIndex])) {
+ // We are exactly after the current previous range, and before the current range, while
+ // not overlapping with none of them. Insert here.
+ break;
+ }
+ }
+ }
+ }
+
+ // Now that we are sure we don't overlap with any range, just add it.
+ m_ranges.insert(overlappingArcIndex, addedRange);
}
bool TimeRanges::contain(float time) const
diff --git a/WebCore/html/TimeRanges.h b/WebCore/html/TimeRanges.h
index eb54f6b..37820dc 100644
--- a/WebCore/html/TimeRanges.h
+++ b/WebCore/html/TimeRanges.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,8 @@
#define TimeRanges_h
#include "ExceptionCode.h"
+
+#include <algorithm>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
@@ -44,6 +46,8 @@ public:
return adoptRef(new TimeRanges(start, end));
}
+ PassRefPtr<TimeRanges> copy();
+
unsigned length() const { return m_ranges.size(); }
float start(unsigned index, ExceptionCode&) const;
float end(unsigned index, ExceptionCode&) const;
@@ -55,7 +59,9 @@ public:
private:
TimeRanges() { }
TimeRanges(float start, float end);
-
+ TimeRanges(const TimeRanges&);
+
+ // We consider all the Ranges to be semi-bounded as follow: [start, end[
struct Range {
Range() { }
Range(float start, float end) {
@@ -64,6 +70,36 @@ private:
}
float m_start;
float m_end;
+
+ inline bool isPointInRange(float point) const
+ {
+ return m_start <= point && point < m_end;
+ }
+
+ inline bool isOverlappingRange(const Range& range) const
+ {
+ return isPointInRange(range.m_start) || isPointInRange(range.m_end) || range.isPointInRange(m_start);
+ }
+
+ inline bool isContiguousWithRange(const Range& range) const
+ {
+ return range.m_start == m_end || range.m_end == m_start;
+ }
+
+ inline Range unionWithOverlappingOrContiguousRange(const Range& range) const
+ {
+ Range ret;
+
+ ret.m_start = std::min(m_start, range.m_start);
+ ret.m_end = std::max(m_end, range.m_end);
+
+ return ret;
+ }
+
+ inline bool isBeforeRange(const Range& range) const
+ {
+ return range.m_start >= m_end;
+ }
};
Vector<Range> m_ranges;