summaryrefslogtreecommitdiffstats
path: root/WebCore/html
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:15 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:15 -0800
commit1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353 (patch)
tree4457a7306ea5acb43fe05bfe0973b1f7faf97ba2 /WebCore/html
parent9364f22aed35e1a1e9d07c121510f80be3ab0502 (diff)
downloadexternal_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.zip
external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.gz
external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'WebCore/html')
-rw-r--r--WebCore/html/CanvasGradient.cpp261
-rw-r--r--WebCore/html/CanvasGradient.h84
-rw-r--r--WebCore/html/CanvasGradient.idl3
-rw-r--r--WebCore/html/CanvasPattern.cpp187
-rw-r--r--WebCore/html/CanvasPattern.h62
-rw-r--r--WebCore/html/CanvasPixelArray.cpp45
-rw-r--r--WebCore/html/CanvasPixelArray.h72
-rw-r--r--WebCore/html/CanvasPixelArray.idl39
-rw-r--r--WebCore/html/CanvasRenderingContext2D.cpp949
-rw-r--r--WebCore/html/CanvasRenderingContext2D.h76
-rw-r--r--WebCore/html/CanvasRenderingContext2D.idl32
-rw-r--r--WebCore/html/CanvasStyle.cpp238
-rw-r--r--WebCore/html/CanvasStyle.h30
-rw-r--r--WebCore/html/File.cpp51
-rw-r--r--WebCore/html/File.h56
-rw-r--r--WebCore/html/File.idl35
-rw-r--r--WebCore/html/FileList.cpp44
-rw-r--r--WebCore/html/FileList.h59
-rw-r--r--WebCore/html/FileList.idl36
-rw-r--r--WebCore/html/FormDataList.cpp22
-rw-r--r--WebCore/html/FormDataList.h41
-rw-r--r--WebCore/html/HTMLAnchorElement.cpp119
-rw-r--r--WebCore/html/HTMLAnchorElement.h8
-rw-r--r--WebCore/html/HTMLAnchorElement.idl4
-rw-r--r--WebCore/html/HTMLAppletElement.cpp97
-rw-r--r--WebCore/html/HTMLAppletElement.h17
-rw-r--r--WebCore/html/HTMLAreaElement.cpp16
-rw-r--r--WebCore/html/HTMLAreaElement.h13
-rw-r--r--WebCore/html/HTMLAreaElement.idl1
-rw-r--r--WebCore/html/HTMLAttributeNames.in31
-rw-r--r--WebCore/html/HTMLBRElement.cpp4
-rw-r--r--WebCore/html/HTMLBaseElement.cpp20
-rw-r--r--WebCore/html/HTMLBodyElement.cpp89
-rw-r--r--WebCore/html/HTMLBodyElement.h2
-rw-r--r--WebCore/html/HTMLButtonElement.cpp43
-rw-r--r--WebCore/html/HTMLButtonElement.h6
-rw-r--r--WebCore/html/HTMLButtonElement.idl4
-rw-r--r--WebCore/html/HTMLCanvasElement.cpp254
-rw-r--r--WebCore/html/HTMLCanvasElement.h92
-rw-r--r--WebCore/html/HTMLCanvasElement.idl5
-rw-r--r--WebCore/html/HTMLCollection.cpp14
-rw-r--r--WebCore/html/HTMLCollection.h4
-rw-r--r--WebCore/html/HTMLDivElement.cpp8
-rw-r--r--WebCore/html/HTMLDocument.cpp332
-rw-r--r--WebCore/html/HTMLDocument.h55
-rw-r--r--WebCore/html/HTMLDocument.idl12
-rw-r--r--WebCore/html/HTMLElement.cpp272
-rw-r--r--WebCore/html/HTMLElement.h17
-rw-r--r--WebCore/html/HTMLElement.idl14
-rw-r--r--WebCore/html/HTMLElementFactory.cpp18
-rw-r--r--WebCore/html/HTMLEmbedElement.cpp163
-rw-r--r--WebCore/html/HTMLEmbedElement.h24
-rw-r--r--WebCore/html/HTMLFieldSetElement.cpp4
-rw-r--r--WebCore/html/HTMLFieldSetElement.h6
-rw-r--r--WebCore/html/HTMLFieldSetElement.idl1
-rw-r--r--WebCore/html/HTMLFontElement.cpp40
-rw-r--r--WebCore/html/HTMLFontElement.h8
-rw-r--r--WebCore/html/HTMLFormCollection.cpp17
-rw-r--r--WebCore/html/HTMLFormCollection.h9
-rw-r--r--WebCore/html/HTMLFormControlElement.cpp (renamed from WebCore/html/HTMLGenericFormElement.cpp)102
-rw-r--r--WebCore/html/HTMLFormControlElement.h (renamed from WebCore/html/HTMLGenericFormElement.h)23
-rw-r--r--WebCore/html/HTMLFormElement.cpp366
-rw-r--r--WebCore/html/HTMLFormElement.h35
-rw-r--r--WebCore/html/HTMLFrameElementBase.cpp51
-rw-r--r--WebCore/html/HTMLFrameElementBase.h11
-rw-r--r--WebCore/html/HTMLFrameSetElement.cpp14
-rw-r--r--WebCore/html/HTMLHRElement.cpp44
-rw-r--r--WebCore/html/HTMLHtmlElement.cpp22
-rw-r--r--WebCore/html/HTMLHtmlElement.h4
-rw-r--r--WebCore/html/HTMLIFrameElement.cpp37
-rw-r--r--WebCore/html/HTMLIFrameElement.h11
-rw-r--r--WebCore/html/HTMLImageElement.cpp116
-rw-r--r--WebCore/html/HTMLImageElement.h28
-rw-r--r--WebCore/html/HTMLImageLoader.cpp108
-rw-r--r--WebCore/html/HTMLImageLoader.h33
-rw-r--r--WebCore/html/HTMLInputElement.cpp282
-rw-r--r--WebCore/html/HTMLInputElement.h41
-rw-r--r--WebCore/html/HTMLInputElement.idl23
-rw-r--r--WebCore/html/HTMLIsIndexElement.cpp2
-rw-r--r--WebCore/html/HTMLKeygenElement.cpp6
-rw-r--r--WebCore/html/HTMLLIElement.cpp12
-rw-r--r--WebCore/html/HTMLLabelElement.cpp3
-rw-r--r--WebCore/html/HTMLLabelElement.idl2
-rw-r--r--WebCore/html/HTMLLegendElement.cpp7
-rw-r--r--WebCore/html/HTMLLegendElement.h4
-rw-r--r--WebCore/html/HTMLLegendElement.idl2
-rw-r--r--WebCore/html/HTMLLinkElement.cpp145
-rw-r--r--WebCore/html/HTMLLinkElement.h44
-rw-r--r--WebCore/html/HTMLMapElement.cpp6
-rw-r--r--WebCore/html/HTMLMarqueeElement.cpp29
-rw-r--r--WebCore/html/HTMLMediaElement.cpp161
-rw-r--r--WebCore/html/HTMLMediaElement.h12
-rw-r--r--WebCore/html/HTMLNameCollection.h7
-rw-r--r--WebCore/html/HTMLOListElement.cpp10
-rw-r--r--WebCore/html/HTMLObjectElement.cpp174
-rw-r--r--WebCore/html/HTMLObjectElement.h39
-rw-r--r--WebCore/html/HTMLObjectElement.idl1
-rw-r--r--WebCore/html/HTMLOptGroupElement.cpp81
-rw-r--r--WebCore/html/HTMLOptGroupElement.h23
-rw-r--r--WebCore/html/HTMLOptionElement.cpp66
-rw-r--r--WebCore/html/HTMLOptionElement.h19
-rw-r--r--WebCore/html/HTMLOptionElement.idl1
-rw-r--r--WebCore/html/HTMLOptionsCollection.cpp5
-rw-r--r--WebCore/html/HTMLOptionsCollection.h7
-rw-r--r--WebCore/html/HTMLParagraphElement.cpp8
-rw-r--r--WebCore/html/HTMLParagraphElement.h2
-rw-r--r--WebCore/html/HTMLParamElement.cpp39
-rw-r--r--WebCore/html/HTMLParamElement.h2
-rw-r--r--WebCore/html/HTMLParser.cpp177
-rw-r--r--WebCore/html/HTMLParser.h18
-rw-r--r--WebCore/html/HTMLPlugInElement.cpp108
-rw-r--r--WebCore/html/HTMLPlugInElement.h45
-rw-r--r--WebCore/html/HTMLPlugInImageElement.cpp54
-rw-r--r--WebCore/html/HTMLPlugInImageElement.h49
-rw-r--r--WebCore/html/HTMLPreElement.cpp2
-rw-r--r--WebCore/html/HTMLScriptElement.cpp287
-rw-r--r--WebCore/html/HTMLScriptElement.h42
-rw-r--r--WebCore/html/HTMLSelectElement.cpp75
-rw-r--r--WebCore/html/HTMLSelectElement.h11
-rw-r--r--WebCore/html/HTMLSelectElement.idl5
-rw-r--r--WebCore/html/HTMLSourceElement.cpp5
-rw-r--r--WebCore/html/HTMLSourceElement.h11
-rw-r--r--WebCore/html/HTMLStyleElement.cpp25
-rw-r--r--WebCore/html/HTMLStyleElement.h4
-rw-r--r--WebCore/html/HTMLTableCaptionElement.cpp2
-rw-r--r--WebCore/html/HTMLTableCellElement.cpp11
-rw-r--r--WebCore/html/HTMLTableCellElement.h2
-rw-r--r--WebCore/html/HTMLTableColElement.cpp2
-rw-r--r--WebCore/html/HTMLTableElement.cpp194
-rw-r--r--WebCore/html/HTMLTableElement.h2
-rw-r--r--WebCore/html/HTMLTablePartElement.cpp28
-rw-r--r--WebCore/html/HTMLTableRowElement.cpp2
-rw-r--r--WebCore/html/HTMLTableRowsCollection.cpp7
-rw-r--r--WebCore/html/HTMLTableRowsCollection.h4
-rw-r--r--WebCore/html/HTMLTableSectionElement.cpp2
-rw-r--r--WebCore/html/HTMLTagNames.in66
-rw-r--r--WebCore/html/HTMLTextAreaElement.cpp207
-rw-r--r--WebCore/html/HTMLTextAreaElement.h21
-rw-r--r--WebCore/html/HTMLTextAreaElement.idl6
-rw-r--r--WebCore/html/HTMLTextFieldInnerElement.cpp126
-rw-r--r--WebCore/html/HTMLTextFieldInnerElement.h71
-rw-r--r--WebCore/html/HTMLTitleElement.cpp4
-rw-r--r--WebCore/html/HTMLTitleElement.h2
-rw-r--r--WebCore/html/HTMLTokenizer.cpp532
-rw-r--r--WebCore/html/HTMLTokenizer.h81
-rw-r--r--WebCore/html/HTMLUListElement.cpp2
-rw-r--r--WebCore/html/HTMLVideoElement.cpp28
-rw-r--r--WebCore/html/HTMLVideoElement.h16
-rw-r--r--WebCore/html/HTMLVideoElement.idl4
-rw-r--r--WebCore/html/HTMLViewSourceDocument.cpp135
-rw-r--r--WebCore/html/HTMLViewSourceDocument.h18
-rw-r--r--WebCore/html/ImageData.cpp49
-rw-r--r--WebCore/html/ImageData.h54
-rw-r--r--WebCore/html/ImageData.idl40
-rw-r--r--WebCore/html/MediaError.h5
-rw-r--r--WebCore/html/PreloadScanner.cpp66
-rw-r--r--WebCore/html/PreloadScanner.h40
-rw-r--r--WebCore/html/TextMetrics.h50
-rw-r--r--WebCore/html/TextMetrics.idl34
-rw-r--r--WebCore/html/TimeRanges.h16
-rw-r--r--WebCore/html/VoidCallback.h4
161 files changed, 4995 insertions, 4391 deletions
diff --git a/WebCore/html/CanvasGradient.cpp b/WebCore/html/CanvasGradient.cpp
index e3e3726..693d8f7 100644
--- a/WebCore/html/CanvasGradient.cpp
+++ b/WebCore/html/CanvasGradient.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -28,269 +28,34 @@
#include "CanvasGradient.h"
#include "CSSParser.h"
-
-#if PLATFORM(CG)
-#include <ApplicationServices/ApplicationServices.h>
-#elif PLATFORM(QT)
-#include <QGradient>
-#elif PLATFORM(CAIRO)
-#include <cairo.h>
-#endif
-
-#ifdef ANDROID_CANVAS_IMPL
-#include "GraphicsContext.h"
-#include "SkColorShader.h"
-#endif
+#include "ExceptionCode.h"
namespace WebCore {
CanvasGradient::CanvasGradient(const FloatPoint& p0, const FloatPoint& p1)
- : m_radial(false), m_p0(p0), m_p1(p1), m_stopsSorted(false), m_lastStop(0)
-#if PLATFORM(CG)
- , m_shading(0)
-#elif PLATFORM(QT)
- , m_shading(0)
-#elif PLATFORM(CAIRO)
- , m_shading(0)
-#endif
-#ifdef ANDROID_CANVAS_IMPL
- , m_platformGradient(NULL)
-#endif
+ : m_gradient(Gradient::create(p0, p1))
{
}
CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
- : m_radial(true), m_p0(p0), m_p1(p1), m_r0(r0), m_r1(r1), m_stopsSorted(false), m_lastStop(0)
-#if PLATFORM(CG)
- , m_shading(0)
-#elif PLATFORM(QT)
- , m_shading(0)
-#elif PLATFORM(CAIRO)
- , m_shading(0)
-#endif
-#ifdef ANDROID_CANVAS_IMPL
- , m_platformGradient(NULL)
-#endif
-{
-}
-
-CanvasGradient::~CanvasGradient()
-{
-#if PLATFORM(CG)
- CGShadingRelease(m_shading);
-#elif PLATFORM(QT)
- delete m_shading;
-#elif PLATFORM(CAIRO)
- cairo_pattern_destroy(m_shading);
-#endif
-#ifdef ANDROID_CANVAS_IMPL
- if (m_platformGradient)
- GraphicsContext::freePlatformGradient(m_platformGradient);
-#endif
-}
-
-void CanvasGradient::addColorStop(float value, const String& color)
+ : m_gradient(Gradient::create(p0, r0, p1, r1))
{
- RGBA32 rgba = 0; // default is transparant black
- CSSParser::parseColor(rgba, color);
- m_stops.append(ColorStop(value,
- ((rgba >> 16) & 0xFF) / 255.0f,
- ((rgba >> 8) & 0xFF) / 255.0f,
- (rgba & 0xFF) / 255.0f,
- ((rgba >> 24) & 0xFF) / 255.0f));
-
- m_stopsSorted = false;
-
-#if PLATFORM(CG)
- CGShadingRelease(m_shading);
- m_shading = 0;
-#elif PLATFORM(QT)
- delete m_shading;
- m_shading = 0;
-#elif PLATFORM(CAIRO)
- cairo_pattern_destroy(m_shading);
- m_shading = 0;
-#endif
-}
-
-#if PLATFORM(CG)
-
-static void gradientCallback(void* info, const CGFloat* in, CGFloat* out)
-{
- float r, g, b, a;
- static_cast<CanvasGradient*>(info)->getColor(*in, &r, &g, &b, &a);
- out[0] = r;
- out[1] = g;
- out[2] = b;
- out[3] = a;
}
-CGShadingRef CanvasGradient::platformShading()
-{
- if (m_shading)
- return m_shading;
-
- const CGFloat intervalRanges[2] = { 0, 1 };
- const CGFloat colorComponentRanges[4 * 2] = { 0, 1, 0, 1, 0, 1, 0, 1 };
- const CGFunctionCallbacks gradientCallbacks = { 0, gradientCallback, 0 };
- CGFunctionRef colorFunction = CGFunctionCreate(this, 1, intervalRanges, 4, colorComponentRanges, &gradientCallbacks);
-
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
-
- if (m_radial)
- m_shading = CGShadingCreateRadial(colorSpace, m_p0, m_r0, m_p1, m_r1, colorFunction, true, true);
- else
- m_shading = CGShadingCreateAxial(colorSpace, m_p0, m_p1, colorFunction, true, true);
-
- CGColorSpaceRelease(colorSpace);
- CGFunctionRelease(colorFunction);
-
- return m_shading;
-}
-
-#elif PLATFORM(QT)
-
-QGradient* CanvasGradient::platformShading()
-{
- if (m_shading)
- return m_shading;
-
- if (m_radial)
- m_shading = new QRadialGradient(m_p0.x(), m_p0.y(), m_r0, m_p1.x(), m_p1.y());
- else m_shading = new QLinearGradient(m_p0.x(), m_p0.y(), m_p1.x(), m_p1.y());
-
- QColor stopColor;
- Vector<ColorStop>::iterator stopIterator = m_stops.begin();;
- while (stopIterator != m_stops.end()) {
- stopColor.setRgbF(stopIterator->red, stopIterator->green, stopIterator->blue, stopIterator->alpha);
- m_shading->setColorAt(stopIterator->stop, stopColor);
- ++stopIterator;
- }
-
- return m_shading;
-}
-
-#elif PLATFORM(CAIRO)
-
-cairo_pattern_t* CanvasGradient::platformShading()
+void CanvasGradient::addColorStop(float value, const String& color, ExceptionCode& ec)
{
- if (m_shading)
- return m_shading;
-
- if (m_radial)
- m_shading = cairo_pattern_create_radial(m_p0.x(), m_p0.y(), m_r0, m_p1.x(), m_p1.y(), m_r1);
- else
- m_shading = cairo_pattern_create_linear(m_p0.x(), m_p0.y(), m_p1.x(), m_p1.y());
-
- Vector<ColorStop>::iterator stopIterator = m_stops.begin();
- while (stopIterator != m_stops.end()) {
- cairo_pattern_add_color_stop_rgba(m_shading, stopIterator->stop, stopIterator->red, stopIterator->green, stopIterator->blue, stopIterator->alpha);
- ++stopIterator;
- }
-
- return m_shading;
-}
-
-#endif
-
-static inline bool compareStops(const CanvasGradient::ColorStop &a, const CanvasGradient::ColorStop &b)
-{
- return a.stop < b.stop;
-}
-
-void CanvasGradient::getColor(float value, float* r, float* g, float* b, float* a)
-{
- ASSERT(value >= 0);
- ASSERT(value <= 1);
-
- if (m_stops.isEmpty()) {
- *r = 0;
- *g = 0;
- *b = 0;
- *a = 0;
- return;
- }
- if (!m_stopsSorted) {
- if (m_stops.size())
- std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
- m_stopsSorted = true;
- }
- if (value <= 0 || value <= m_stops.first().stop) {
- *r = m_stops.first().red;
- *g = m_stops.first().green;
- *b = m_stops.first().blue;
- *a = m_stops.first().alpha;
+ if (!(value >= 0 && value <= 1.0f)) {
+ ec = INDEX_SIZE_ERR;
return;
}
- if (value >= 1 || value >= m_stops.last().stop) {
- *r = m_stops.last().red;
- *g = m_stops.last().green;
- *b = m_stops.last().blue;
- *a = m_stops.last().alpha;
+
+ RGBA32 rgba = 0;
+ if (!CSSParser::parseColor(rgba, color)) {
+ ec = SYNTAX_ERR;
return;
}
- // Find stop before and stop after and interpolate.
- int stop = findStop(value);
- const ColorStop& lastStop = m_stops[stop];
- const ColorStop& nextStop = m_stops[stop + 1];
- float stopFraction = (value - lastStop.stop) / (nextStop.stop - lastStop.stop);
- *r = lastStop.red + (nextStop.red - lastStop.red) * stopFraction;
- *g = lastStop.green + (nextStop.green - lastStop.green) * stopFraction;
- *b = lastStop.blue + (nextStop.blue - lastStop.blue) * stopFraction;
- *a = lastStop.alpha + (nextStop.alpha - lastStop.alpha) * stopFraction;
-}
-
-int CanvasGradient::findStop(float value) const
-{
- ASSERT(value >= 0);
- ASSERT(value <= 1);
- ASSERT(m_stopsSorted);
-
- int numStops = m_stops.size();
- ASSERT(numStops >= 2);
- ASSERT(m_lastStop < numStops - 1);
-
- int i = m_lastStop;
- if (value < m_stops[i].stop)
- i = 1;
- else
- i = m_lastStop + 1;
-
- for (; i < numStops - 1; ++i)
- if (value < m_stops[i].stop)
- break;
-
- m_lastStop = i - 1;
- return m_lastStop;
-}
-
-#ifdef ANDROID_CANVAS_IMPL
-PlatformGradient* CanvasGradient::platformGradient()
-{
- PlatformGradient* pg = m_platformGradient;
- int count = m_stops.size();
-
- if (NULL == pg) {
- // it seems the spec says a zero-size gradient draws transparent
- if (0 == count) {
- pg = new SkColorShader(0);
- } else {
- // call this to ensure that data[] is sorted
- float r, g, b, a;
- (void)getColor(0, &r, &g, &b, &a);
-
- const float* data = (const float*)m_stops.data();
-
- if (m_radial)
- pg = GraphicsContext::newPlatformRadialGradient(m_p0, m_r0, m_p1, m_r1, data, count);
- else
- pg = GraphicsContext::newPlatformLinearGradient(m_p0, m_p1, data, count);
- }
- m_platformGradient = pg;
- }
- return pg;
+ m_gradient->addColorStop(value, Color(rgba));
}
-#endif
-} //namespace
+} // namespace
diff --git a/WebCore/html/CanvasGradient.h b/WebCore/html/CanvasGradient.h
index 2648599..3b81dbd 100644
--- a/WebCore/html/CanvasGradient.h
+++ b/WebCore/html/CanvasGradient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -27,80 +27,38 @@
#ifndef CanvasGradient_h
#define CanvasGradient_h
-#include "FloatPoint.h"
+#include "Gradient.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-
-#ifdef ANDROID_CANVAS_IMPL
- #include "PlatformGraphics.h"
-#endif
-
-#if PLATFORM(CG)
-typedef struct CGShading* CGShadingRef;
-#elif PLATFORM(QT)
-class QGradient;
-#elif PLATFORM(CAIRO)
-typedef struct _cairo_pattern cairo_pattern_t;
-#endif
namespace WebCore {
class String;
+ typedef int ExceptionCode;
+
class CanvasGradient : public RefCounted<CanvasGradient> {
public:
- CanvasGradient(const FloatPoint& p0, const FloatPoint& p1);
- CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1);
- ~CanvasGradient();
+ static PassRefPtr<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1)
+ {
+ return adoptRef(new CanvasGradient(p0, p1));
+ }
+ static PassRefPtr<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
+ {
+ return adoptRef(new CanvasGradient(p0, r0, p1, r1));
+ }
+
+ Gradient* gradient() const { return m_gradient.get(); }
- void addColorStop(float, const String& color);
+ void addColorStop(float value, const String& color, ExceptionCode&);
- void getColor(float value, float* r, float* g, float* b, float* a);
-
-#ifdef ANDROID_CANVAS_IMPL
- PlatformGradient* platformGradient();
-#endif
-
-#if PLATFORM(CG)
- CGShadingRef platformShading();
-#elif PLATFORM(QT)
- QGradient *platformShading();
-#elif PLATFORM(CAIRO)
- cairo_pattern_t* platformShading();
-#endif
-
- struct ColorStop {
- float stop;
- float red;
- float green;
- float blue;
- float alpha;
-
- ColorStop() : stop(0), red(0), green(0), blue(0), alpha(0) { }
- ColorStop(float s, float r, float g, float b, float a) : stop(s), red(r), green(g), blue(b), alpha(a) { }
- };
+ void getColor(float value, float* r, float* g, float* b, float* a) const { m_gradient->getColor(value, r, g, b, a); }
private:
- int findStop(float value) const;
-
- bool m_radial;
- FloatPoint m_p0, m_p1;
- float m_r0, m_r1;
- mutable Vector<ColorStop> m_stops;
- mutable bool m_stopsSorted;
- mutable int m_lastStop;
-
-#if PLATFORM(CG)
- CGShadingRef m_shading;
-#elif PLATFORM(QT)
- QGradient *m_shading;
-#elif PLATFORM(CAIRO)
- cairo_pattern_t* m_shading;
-#endif
-
-#ifdef ANDROID_CANVAS_IMPL
- PlatformGradient* m_platformGradient;
-#endif
+ CanvasGradient(const FloatPoint& p0, const FloatPoint& p1);
+ CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1);
+
+ RefPtr<Gradient> m_gradient;
};
} //namespace
diff --git a/WebCore/html/CanvasGradient.idl b/WebCore/html/CanvasGradient.idl
index 578be2b..a925a26 100644
--- a/WebCore/html/CanvasGradient.idl
+++ b/WebCore/html/CanvasGradient.idl
@@ -30,7 +30,8 @@ module html {
ImplementationUUID=a2942ae6-2731-4286-98cc-9d5e79e20de1
] CanvasGradient {
- void addColorStop(in float offset, in DOMString color);
+ void addColorStop(in float offset, in DOMString color)
+ raises (DOMException);
};
diff --git a/WebCore/html/CanvasPattern.cpp b/WebCore/html/CanvasPattern.cpp
index 585fc62..62a4620 100644
--- a/WebCore/html/CanvasPattern.cpp
+++ b/WebCore/html/CanvasPattern.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,216 +26,41 @@
#include "config.h"
#include "CanvasPattern.h"
-#include "CachedImage.h"
#include "ExceptionCode.h"
-#include "FloatRect.h"
-#include "GraphicsContext.h"
-#include "Image.h"
+#include "PlatformString.h"
namespace WebCore {
void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool& repeatY, ExceptionCode& ec)
{
+ ec = 0;
if (type.isEmpty() || type == "repeat") {
repeatX = true;
repeatY = true;
- ec = 0;
return;
}
if (type == "no-repeat") {
repeatX = false;
repeatY = false;
- ec = 0;
return;
}
if (type == "repeat-x") {
repeatX = true;
repeatY = false;
- ec = 0;
return;
}
if (type == "repeat-y") {
repeatX = false;
repeatY = true;
- ec = 0;
return;
}
ec = SYNTAX_ERR;
}
-#if PLATFORM(CG)
-
-CanvasPattern::CanvasPattern(CGImageRef image, bool repeatX, bool repeatY)
- : m_platformImage(image)
- , m_cachedImage(0)
- , m_repeatX(repeatX)
- , m_repeatY(repeatY)
-{
-}
-
-#elif PLATFORM(CAIRO)
-
-CanvasPattern::CanvasPattern(cairo_surface_t* surface, bool repeatX, bool repeatY)
- : m_platformImage(cairo_surface_reference(surface))
- , m_cachedImage(0)
- , m_repeatX(repeatX)
- , m_repeatY(repeatY)
-{
-}
-
-#endif
-
-CanvasPattern::CanvasPattern(CachedImage* cachedImage, bool repeatX, bool repeatY)
- :
-#if PLATFORM(CG) || PLATFORM(CAIRO)
- m_platformImage(0)
- ,
-#endif
- m_cachedImage(cachedImage)
- , m_repeatX(repeatX)
- , m_repeatY(repeatY)
-#ifdef ANDROID_CANVAS_IMPL
- , m_platformPattern(NULL)
-#endif
-{
- if (cachedImage)
- cachedImage->ref(this);
-}
-
-CanvasPattern::~CanvasPattern()
-{
-#ifdef ANDROID_CANVAS_IMPL
- if (m_platformPattern)
- GraphicsContext::freePlatformPattern(m_platformPattern);
-#endif
-#if PLATFORM(CAIRO)
- if (m_platformImage)
- cairo_surface_destroy(m_platformImage);
-#endif
- if (m_cachedImage)
- m_cachedImage->deref(this);
-}
-
-#if PLATFORM(CG)
-
-static void patternCallback(void* info, CGContextRef context)
-{
- CGImageRef platformImage = static_cast<CanvasPattern*>(info)->platformImage();
- if (platformImage) {
- CGRect rect = GraphicsContext(context).roundToDevicePixels(
- FloatRect(0, 0, CGImageGetWidth(platformImage), CGImageGetHeight(platformImage)));
- CGContextDrawImage(context, rect, platformImage);
- return;
- }
-
- CachedImage* cachedImage = static_cast<CanvasPattern*>(info)->cachedImage();
- if (!cachedImage)
- return;
- Image* image = cachedImage->image();
- if (!image)
- return;
-
- FloatRect rect = GraphicsContext(context).roundToDevicePixels(image->rect());
-
- if (image->getCGImageRef()) {
- CGContextDrawImage(context, rect, image->getCGImageRef());
- // FIXME: We should refactor this code to use the platform-independent
- // drawing API in all cases. Then, this didDraw call will happen
- // automatically, and we can remove it.
- cachedImage->didDraw(image);
- return;
- }
-
- GraphicsContext(context).drawImage(image, rect);
-}
-
-static void patternReleaseCallback(void* info)
-{
- static_cast<CanvasPattern*>(info)->deref();
-}
-
-CGPatternRef CanvasPattern::createPattern(const CGAffineTransform& transform)
-{
- CGRect rect;
- rect.origin.x = 0;
- rect.origin.y = 0;
- if (m_platformImage) {
- rect.size.width = CGImageGetWidth(m_platformImage.get());
- rect.size.height = CGImageGetHeight(m_platformImage.get());
- } else {
- if (!m_cachedImage)
- return 0;
- Image* image = m_cachedImage->image();
- if (!image)
- return 0;
- rect.size.width = image->width();
- rect.size.height = image->height();
- }
-
- CGAffineTransform patternTransform =
- CGAffineTransformTranslate(CGAffineTransformScale(transform, 1, -1), 0, -rect.size.height);
-
- float xStep = m_repeatX ? rect.size.width : FLT_MAX;
- // If FLT_MAX should also be used for yStep, nothing is rendered. Using fractions of FLT_MAX also
- // result in nothing being rendered. This is not a problem with xStep.
- // INT_MAX is almost correct, but there seems to be some number wrapping occuring making the fill
- // pattern is not filled correctly.
- // So, just pick a really large number that works.
- float yStep = m_repeatY ? rect.size.height : (100000000.0f);
-
- const CGPatternCallbacks patternCallbacks = { 0, patternCallback, patternReleaseCallback };
- ref();
- return CGPatternCreate(this, rect, patternTransform, xStep, yStep,
- kCGPatternTilingConstantSpacing, TRUE, &patternCallbacks);
-}
-
-#elif PLATFORM(CAIRO)
-
-cairo_pattern_t* CanvasPattern::createPattern(const cairo_matrix_t& m)
-{
- cairo_surface_t* surface = 0;
- if (m_platformImage) {
- surface = m_platformImage;
- } else {
- if (!m_cachedImage)
- return 0;
- Image* image = m_cachedImage->image();
- if (!image)
- return 0;
- surface = image->nativeImageForCurrentFrame();
- }
-
- if (!surface)
- return 0;
-
- cairo_pattern_t* pattern = cairo_pattern_create_for_surface(surface);
- cairo_pattern_set_matrix(pattern, &m);
- if (m_repeatX || m_repeatY)
- cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
- return pattern;
-}
-
-#endif
-
-#ifdef ANDROID_CANVAS_IMPL
-/* TODO
- 1) pass in graphics context or something in case Apple needs to see the current matrix. If so,
- we may need to pass the current (if any) platformPatter to it, so it can free it in and build
- a new one, if that is required (not needed by our platform).
- 2) Need a RepeatTile mode for Decal, so we can represent <canvas> notion of "no-repeat"
-*/
-PlatformPattern* CanvasPattern::platformPattern()
+CanvasPattern::CanvasPattern(Image* image, bool repeatX, bool repeatY, bool originClean)
+ : m_pattern(Pattern::create(image, repeatX, repeatY))
+ , m_originClean(originClean)
{
- if (NULL == m_platformPattern && m_cachedImage)
- {
- Image* image = m_cachedImage->image();
- if (image)
- m_platformPattern = GraphicsContext::newPlatformPattern(image,
- m_repeatX ? Image::RepeatTile : Image::StretchTile,
- m_repeatY ? Image::RepeatTile : Image::StretchTile);
- }
- return m_platformPattern;
}
-#endif
}
diff --git a/WebCore/html/CanvasPattern.h b/WebCore/html/CanvasPattern.h
index d74dc8a..6c012d1 100644
--- a/WebCore/html/CanvasPattern.h
+++ b/WebCore/html/CanvasPattern.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,69 +26,37 @@
#ifndef CanvasPattern_h
#define CanvasPattern_h
-#include "CachedResourceClient.h"
+#include "Pattern.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#ifdef ANDROID_CANVAS_IMPL
- #include "PlatformGraphics.h"
-#endif
-#if PLATFORM(CG)
-#include <wtf/RetainPtr.h>
-#include <ApplicationServices/ApplicationServices.h>
-#elif PLATFORM(CAIRO)
-#include <cairo.h>
-#endif
-
namespace WebCore {
- class CachedImage;
+ class Image;
class String;
typedef int ExceptionCode;
- class CanvasPattern : public RefCounted<CanvasPattern>, CachedResourceClient {
+ class CanvasPattern : public RefCounted<CanvasPattern> {
public:
static void parseRepetitionType(const String&, bool& repeatX, bool& repeatY, ExceptionCode&);
-#if PLATFORM(CG)
- CanvasPattern(CGImageRef, bool repeatX, bool repeatY);
-#elif PLATFORM(CAIRO)
- CanvasPattern(cairo_surface_t*, bool repeatX, bool repeatY);
-#endif
- CanvasPattern(CachedImage*, bool repeatX, bool repeatY);
- ~CanvasPattern();
+ static PassRefPtr<CanvasPattern> create(Image* image, bool repeatX, bool repeatY, bool originClean)
+ {
+ return adoptRef(new CanvasPattern(image, repeatX, repeatY, originClean));
+ }
-#if PLATFORM(CG)
- CGImageRef platformImage() const { return m_platformImage.get(); }
-#elif PLATFORM(CAIRO)
- cairo_surface_t* platformImage() const { return m_platformImage; }
-#endif
- CachedImage* cachedImage() const { return m_cachedImage; }
+ Pattern* pattern() const { return m_pattern.get(); }
-#if PLATFORM(CG)
- CGPatternRef createPattern(const CGAffineTransform&);
-#elif PLATFORM(CAIRO)
- cairo_pattern_t* createPattern(const cairo_matrix_t&);
-#endif
-
-#ifdef ANDROID_CANVAS_IMPL
- PlatformPattern* platformPattern();
-#endif
+ bool originClean() const { return m_originClean; }
private:
-#if PLATFORM(CG)
- const RetainPtr<CGImageRef> m_platformImage;
-#elif PLATFORM(CAIRO)
- cairo_surface_t* const m_platformImage;
-#endif
- CachedImage* const m_cachedImage;
- const bool m_repeatX;
- const bool m_repeatY;
+ CanvasPattern(Image*, bool repeatX, bool repeatY, bool originClean);
-#ifdef ANDROID_CANVAS_IMPL
- PlatformPattern* m_platformPattern;
-#endif
+ RefPtr<Pattern> m_pattern;
+ bool m_originClean;
};
+
} // namespace WebCore
#endif
diff --git a/WebCore/html/CanvasPixelArray.cpp b/WebCore/html/CanvasPixelArray.cpp
new file mode 100644
index 0000000..82bc27b
--- /dev/null
+++ b/WebCore/html/CanvasPixelArray.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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.
+ */
+
+#include "config.h"
+#include "CanvasPixelArray.h"
+
+namespace WebCore {
+
+PassRefPtr<CanvasPixelArray> CanvasPixelArray::create(unsigned size)
+{
+ return adoptRef(new CanvasPixelArray(size));
+}
+
+CanvasPixelArray::CanvasPixelArray(unsigned size)
+ : m_data(size)
+{
+ ASSERT((reinterpret_cast<size_t>(m_data.data()) & 3) == 0);
+}
+
+}
diff --git a/WebCore/html/CanvasPixelArray.h b/WebCore/html/CanvasPixelArray.h
new file mode 100644
index 0000000..5560538
--- /dev/null
+++ b/WebCore/html/CanvasPixelArray.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 CanvasPixelArray_h
+#define CanvasPixelArray_h
+
+#include <wtf/MathExtras.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class CanvasPixelArray : public RefCounted<CanvasPixelArray> {
+ public:
+ static PassRefPtr<CanvasPixelArray> create(unsigned size);
+
+ Vector<unsigned char>& data() { return m_data; }
+ unsigned length() const { return m_data.size(); }
+
+ void set(unsigned index, double value)
+ {
+ if (index >= m_data.size())
+ return;
+ if (!(value > 0)) // Clamp NaN to 0
+ value = 0;
+ else if (value > 255)
+ value = 255;
+ m_data[index] = static_cast<unsigned char>(value + 0.5);
+ }
+
+ bool get(unsigned index, unsigned char& result) const
+ {
+ if (index >= m_data.size())
+ return false;
+ result = m_data[index];
+ return true;
+ }
+
+ private:
+ CanvasPixelArray(unsigned size);
+ Vector<unsigned char> m_data;
+ };
+
+} // namespace WebCore
+
+#endif // CanvasPixelArray_h
diff --git a/WebCore/html/CanvasPixelArray.idl b/WebCore/html/CanvasPixelArray.idl
new file mode 100644
index 0000000..d4dcecb
--- /dev/null
+++ b/WebCore/html/CanvasPixelArray.idl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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.
+ */
+
+module html {
+
+ interface [
+ CustomHeader,
+ HasCustomIndexGetter,
+ HasCustomIndexSetter
+ ] CanvasPixelArray {
+ readonly attribute long length;
+ };
+
+}
diff --git a/WebCore/html/CanvasRenderingContext2D.cpp b/WebCore/html/CanvasRenderingContext2D.cpp
index 04cd1b5..5e3f36c 100644
--- a/WebCore/html/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/CanvasRenderingContext2D.cpp
@@ -1,7 +1,8 @@
/*
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,49 +34,53 @@
#include "CachedImage.h"
#include "CanvasGradient.h"
#include "CanvasPattern.h"
+#include "CanvasPixelArray.h"
#include "CanvasStyle.h"
+#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
#include "Document.h"
#include "ExceptionCode.h"
+#include "FloatConversion.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "KURL.h"
#include "NotImplemented.h"
+#include "Page.h"
#include "RenderHTMLCanvas.h"
+#include "SecurityOrigin.h"
#include "Settings.h"
+#include "TextMetrics.h"
+#include <kjs/interpreter.h>
+#include <stdio.h>
#include <wtf/MathExtras.h>
-#if PLATFORM(QT)
-#include <QPainter>
-#include <QPixmap>
-#include <QPainterPath>
-#elif PLATFORM(CAIRO)
-#include "CairoPath.h"
-#include <cairo.h>
-#endif
+using namespace std;
namespace WebCore {
using namespace HTMLNames;
-#ifdef ANDROID_CANVAS_IMPL
-static PlatformGradient* extractGradient(CanvasStyle* style)
+const char* defaultFont = "10px sans-serif";
+
+CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas)
+ : m_canvas(canvas)
+ , m_stateStack(1)
{
- CanvasGradient* grad = style->gradient();
- return grad ? grad->platformGradient() : NULL;
}
-static PlatformPattern* extractPattern(CanvasStyle* style)
+
+void CanvasRenderingContext2D::ref()
{
- CanvasPattern* pat = style->pattern();
- return pat ? pat->platformPattern() : NULL;
+ m_canvas->ref();
}
-#endif
-CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas)
- : m_canvas(canvas)
- , m_stateStack(1)
+void CanvasRenderingContext2D::deref()
{
+ m_canvas->deref();
}
void CanvasRenderingContext2D::reset()
@@ -85,8 +90,8 @@ void CanvasRenderingContext2D::reset()
}
CanvasRenderingContext2D::State::State()
- : m_strokeStyle(new CanvasStyle("black"))
- , m_fillStyle(new CanvasStyle("black"))
+ : m_strokeStyle(CanvasStyle::create("black"))
+ , m_fillStyle(CanvasStyle::create("black"))
, m_lineWidth(1)
, m_lineCap(ButtCap)
, m_lineJoin(MiterJoin)
@@ -95,8 +100,10 @@ CanvasRenderingContext2D::State::State()
, m_shadowColor("black")
, m_globalAlpha(1)
, m_globalComposite(CompositeSourceOver)
- , m_appliedStrokePattern(false)
- , m_appliedFillPattern(false)
+ , m_textAlign(StartTextAlign)
+ , m_textBaseline(AlphabeticTextBaseline)
+ , m_unparsedFont(defaultFont)
+ , m_realizedFont(false)
{
}
@@ -115,7 +122,9 @@ void CanvasRenderingContext2D::restore()
ASSERT(m_stateStack.size() >= 1);
if (m_stateStack.size() <= 1)
return;
+ m_path.transform(state().m_transform);
m_stateStack.removeLast();
+ m_path.transform(state().m_transform.inverse());
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -131,12 +140,19 @@ void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> style)
{
if (!style)
return;
+
+ if (m_canvas->originClean()) {
+ if (CanvasPattern* pattern = style->canvasPattern()) {
+ if (!pattern->originClean())
+ m_canvas->setOriginTainted();
+ }
+ }
+
state().m_strokeStyle = style;
GraphicsContext* c = drawingContext();
if (!c)
return;
state().m_strokeStyle->applyStrokeColor(c);
- state().m_appliedStrokePattern = false;
}
CanvasStyle* CanvasRenderingContext2D::fillStyle() const
@@ -148,17 +164,19 @@ void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> style)
{
if (!style)
return;
+
+ if (m_canvas->originClean()) {
+ if (CanvasPattern* pattern = style->canvasPattern()) {
+ if (!pattern->originClean())
+ m_canvas->setOriginTainted();
+ }
+ }
+
state().m_fillStyle = style;
GraphicsContext* c = drawingContext();
if (!c)
return;
-#if PLATFORM(CAIRO)
- // FIXME: hack to reduce code duplication in CanvasStyle.cpp
- state().m_fillStyle->applyStrokeColor(c);
-#else
state().m_fillStyle->applyFillColor(c);
-#endif
- state().m_appliedFillPattern = false;
}
float CanvasRenderingContext2D::lineWidth() const
@@ -311,7 +329,8 @@ void CanvasRenderingContext2D::scale(float sx, float sy)
if (!c)
return;
c->scale(FloatSize(sx, sy));
- state().m_path.transform(AffineTransform().scale(1.0/sx, 1.0/sy));
+ state().m_transform.scale(sx, sy);
+ m_path.transform(AffineTransform().scale(1.0/sx, 1.0/sy));
}
void CanvasRenderingContext2D::rotate(float angleInRadians)
@@ -320,7 +339,8 @@ void CanvasRenderingContext2D::rotate(float angleInRadians)
if (!c)
return;
c->rotate(angleInRadians);
- state().m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
+ state().m_transform.rotate(angleInRadians / piDouble * 180.0);
+ m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
}
void CanvasRenderingContext2D::translate(float tx, float ty)
@@ -329,7 +349,8 @@ void CanvasRenderingContext2D::translate(float tx, float ty)
if (!c)
return;
c->translate(tx, ty);
- state().m_path.transform(AffineTransform().translate(-tx, -ty));
+ state().m_transform.translate(tx, ty);
+ m_path.transform(AffineTransform().translate(-tx, -ty));
}
void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float m22, float dx, float dy)
@@ -339,208 +360,192 @@ void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float
return;
// HTML5 3.14.11.1 -- ignore any calls that pass non-finite numbers
- if (!isfinite(m11) || !isfinite(m21) || !isfinite(dx) ||
- !isfinite(m12) || !isfinite(m22) || !isfinite(dy))
+ if (!isfinite(m11) | !isfinite(m21) | !isfinite(dx) |
+ !isfinite(m12) | !isfinite(m22) | !isfinite(dy))
return;
AffineTransform transform(m11, m12, m21, m22, dx, dy);
c->concatCTM(transform);
- state().m_path.transform(transform.inverse());
+ state().m_transform.multiply(transform);
+ m_path.transform(transform.inverse());
}
void CanvasRenderingContext2D::setStrokeColor(const String& color)
{
- setStrokeStyle(new CanvasStyle(color));
+ setStrokeStyle(CanvasStyle::create(color));
}
void CanvasRenderingContext2D::setStrokeColor(float grayLevel)
{
- setStrokeStyle(new CanvasStyle(grayLevel, 1));
+ setStrokeStyle(CanvasStyle::create(grayLevel, 1));
}
void CanvasRenderingContext2D::setStrokeColor(const String& color, float alpha)
{
- setStrokeStyle(new CanvasStyle(color, alpha));
+ setStrokeStyle(CanvasStyle::create(color, alpha));
}
void CanvasRenderingContext2D::setStrokeColor(float grayLevel, float alpha)
{
- setStrokeStyle(new CanvasStyle(grayLevel, alpha));
+ setStrokeStyle(CanvasStyle::create(grayLevel, alpha));
}
void CanvasRenderingContext2D::setStrokeColor(float r, float g, float b, float a)
{
- setStrokeStyle(new CanvasStyle(r, g, b, a));
+ setStrokeStyle(CanvasStyle::create(r, g, b, a));
}
void CanvasRenderingContext2D::setStrokeColor(float c, float m, float y, float k, float a)
{
- setStrokeStyle(new CanvasStyle(c, m, y, k, a));
+ setStrokeStyle(CanvasStyle::create(c, m, y, k, a));
}
void CanvasRenderingContext2D::setFillColor(const String& color)
{
- setFillStyle(new CanvasStyle(color));
+ setFillStyle(CanvasStyle::create(color));
}
void CanvasRenderingContext2D::setFillColor(float grayLevel)
{
- setFillStyle(new CanvasStyle(grayLevel, 1));
+ setFillStyle(CanvasStyle::create(grayLevel, 1));
}
void CanvasRenderingContext2D::setFillColor(const String& color, float alpha)
{
- setFillStyle(new CanvasStyle(color, 1));
+ setFillStyle(CanvasStyle::create(color, 1));
}
void CanvasRenderingContext2D::setFillColor(float grayLevel, float alpha)
{
- setFillStyle(new CanvasStyle(grayLevel, alpha));
+ setFillStyle(CanvasStyle::create(grayLevel, alpha));
}
void CanvasRenderingContext2D::setFillColor(float r, float g, float b, float a)
{
- setFillStyle(new CanvasStyle(r, g, b, a));
+ setFillStyle(CanvasStyle::create(r, g, b, a));
}
void CanvasRenderingContext2D::setFillColor(float c, float m, float y, float k, float a)
{
- setFillStyle(new CanvasStyle(c, m, y, k, a));
+ setFillStyle(CanvasStyle::create(c, m, y, k, a));
}
void CanvasRenderingContext2D::beginPath()
{
- state().m_path.clear();
+ m_path.clear();
}
void CanvasRenderingContext2D::closePath()
{
- state().m_path.closeSubpath();
+ m_path.closeSubpath();
}
void CanvasRenderingContext2D::moveTo(float x, float y)
{
- state().m_path.moveTo(FloatPoint(x, y));
+ if (!isfinite(x) | !isfinite(y))
+ return;
+ m_path.moveTo(FloatPoint(x, y));
}
void CanvasRenderingContext2D::lineTo(float x, float y)
{
- state().m_path.addLineTo(FloatPoint(x, y));
+ if (!isfinite(x) | !isfinite(y))
+ return;
+ m_path.addLineTo(FloatPoint(x, y));
}
void CanvasRenderingContext2D::quadraticCurveTo(float cpx, float cpy, float x, float y)
{
- state().m_path.addQuadCurveTo(FloatPoint(cpx, cpy), FloatPoint(x, y));
+ if (!isfinite(cpx) | !isfinite(cpy) | !isfinite(x) | !isfinite(y))
+ return;
+ m_path.addQuadCurveTo(FloatPoint(cpx, cpy), FloatPoint(x, y));
}
void CanvasRenderingContext2D::bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y)
{
- state().m_path.addBezierCurveTo(FloatPoint(cp1x, cp1y), FloatPoint(cp2x, cp2y), FloatPoint(x, y));
+ if (!isfinite(cp1x) | !isfinite(cp1y) | !isfinite(cp2x) | !isfinite(cp2y) | !isfinite(x) | !isfinite(y))
+ return;
+ m_path.addBezierCurveTo(FloatPoint(cp1x, cp1y), FloatPoint(cp2x, cp2y), FloatPoint(x, y));
}
void CanvasRenderingContext2D::arcTo(float x0, float y0, float x1, float y1, float r, ExceptionCode& ec)
{
ec = 0;
- if (!(r > 0)) {
+ if (!isfinite(x0) | !isfinite(y0) | !isfinite(x1) | !isfinite(y1) | !isfinite(r))
+ return;
+
+ if (r < 0) {
ec = INDEX_SIZE_ERR;
return;
}
-// SkDebugf("------ arcTo %g %g %g %g %g\n", x0, y0, x1, y1, r);
- state().m_path.addArcTo(FloatPoint(x0, y0), FloatPoint(x1, y1), r);
+
+ m_path.addArcTo(FloatPoint(x0, y0), FloatPoint(x1, y1), r);
}
void CanvasRenderingContext2D::arc(float x, float y, float r, float sa, float ea, bool anticlockwise, ExceptionCode& ec)
{
ec = 0;
- if (!(r > 0)) {
+ if (!isfinite(x) | !isfinite(y) | !isfinite(r) | !isfinite(sa) | !isfinite(ea))
+ return;
+
+ if (r < 0) {
ec = INDEX_SIZE_ERR;
return;
}
- state().m_path.addArc(FloatPoint(x, y), r, sa, ea, anticlockwise);
+
+ m_path.addArc(FloatPoint(x, y), r, sa, ea, anticlockwise);
+}
+
+static bool validateRectForCanvas(float& x, float& y, float& width, float& height)
+{
+ if (!isfinite(x) | !isfinite(y) | !isfinite(width) | !isfinite(height))
+ return false;
+
+ if (width < 0) {
+ width = -width;
+ x -= width;
+ }
+
+ if (height < 0) {
+ height = -height;
+ y -= height;
+ }
+
+ return true;
}
-void CanvasRenderingContext2D::rect(float x, float y, float width, float height, ExceptionCode& ec)
+void CanvasRenderingContext2D::rect(float x, float y, float width, float height)
{
- ec = 0;
- if (!(width >= 0 && height >= 0)) {
- ec = INDEX_SIZE_ERR;
+ if (!validateRectForCanvas(x, y, width, height))
return;
- }
- state().m_path.addRect(FloatRect(x, y, width, height));
+
+ m_path.addRect(FloatRect(x, y, width, height));
}
+#if ENABLE(DASHBOARD_SUPPORT)
void CanvasRenderingContext2D::clearPathForDashboardBackwardCompatibilityMode()
{
- if (m_canvas)
- if (Settings* settings = m_canvas->document()->settings())
- if (settings->usesDashboardBackwardCompatibilityMode())
- state().m_path.clear();
+ if (Settings* settings = m_canvas->document()->settings())
+ if (settings->usesDashboardBackwardCompatibilityMode())
+ m_path.clear();
}
+#endif
void CanvasRenderingContext2D::fill()
{
GraphicsContext* c = drawingContext();
if (!c)
return;
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextBeginPath(c->platformContext());
- CGContextAddPath(c->platformContext(), state().m_path.platformPath());
- if (!state().m_path.isEmpty())
- willDraw(CGContextGetPathBoundingBox(c->platformContext()));
+ c->beginPath();
+ c->addPath(m_path);
+ if (!m_path.isEmpty())
+ willDraw(m_path.boundingRect());
- if (state().m_fillStyle->gradient()) {
- // Shading works on the entire clip region, so convert the current path to a clip.
- c->save();
- CGContextClip(c->platformContext());
- CGContextDrawShading(c->platformContext(), state().m_fillStyle->gradient()->platformShading());
- c->restore();
- } else {
- if (state().m_fillStyle->pattern())
- applyFillPattern();
- CGContextFillPath(c->platformContext());
- }
-#elif defined(ANDROID_CANVAS_IMPL)
- CanvasStyle* s = state().m_fillStyle.get();
- const Path& path = state().m_path;
- if (path.isEmpty()) { // <canvas> treats empty path filling as the entire visible area
- FloatRect rect = c->getClipLocalBounds();
- willDraw(rect);
- c->fillRect(rect, extractGradient(s), extractPattern(s));
- }
- else {
- willDraw(path.boundingRect());
- c->fillPath(path, extractGradient(s), extractPattern(s));
- }
-#elif PLATFORM(QT)
- QPainterPath* path = state().m_path.platformPath();
- QPainter* p = static_cast<QPainter*>(c->platformContext());
- willDraw(path->controlPointRect());
- if (state().m_fillStyle->gradient()) {
- p->fillPath(*path, QBrush(*(state().m_fillStyle->gradient()->platformShading())));
- } else {
- if (state().m_fillStyle->pattern())
- applyFillPattern();
- p->fillPath(*path, p->brush());
- }
-#elif PLATFORM(CAIRO)
- cairo_t* cr = c->platformContext();
- cairo_save(cr);
- willDraw(state().m_path.boundingRect());
- if (state().m_fillStyle->gradient()) {
- cairo_set_source(cr, state().m_fillStyle->gradient()->platformShading());
- c->addPath(state().m_path);
- cairo_fill(cr);
- } else {
- if (state().m_fillStyle->pattern())
- applyFillPattern();
- c->addPath(state().m_path);
- cairo_fill(cr);
- }
- cairo_restore(cr);
-#endif
+ c->fillPath();
+#if ENABLE(DASHBOARD_SUPPORT)
clearPathForDashboardBackwardCompatibilityMode();
+#endif
}
void CanvasRenderingContext2D::stroke()
@@ -548,70 +553,23 @@ void CanvasRenderingContext2D::stroke()
GraphicsContext* c = drawingContext();
if (!c)
return;
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextBeginPath(c->platformContext());
- CGContextAddPath(c->platformContext(), state().m_path.platformPath());
+ c->beginPath();
+ c->addPath(m_path);
- if (!state().m_path.isEmpty()) {
+ if (!m_path.isEmpty()) {
+ // FIXME: This is insufficient, need to use CGContextReplacePathWithStrokedPath to expand to required bounds
float lineWidth = state().m_lineWidth;
- float inset = -lineWidth / 2;
- CGRect boundingRect = CGRectInset(CGContextGetPathBoundingBox(c->platformContext()), inset, inset);
+ float inset = lineWidth / 2;
+ FloatRect boundingRect = m_path.boundingRect();
+ boundingRect.inflate(inset);
willDraw(boundingRect);
}
- if (state().m_strokeStyle->gradient()) {
- // Shading works on the entire clip region, so convert the current path to a clip.
- c->save();
- CGContextReplacePathWithStrokedPath(c->platformContext());
- CGContextClip(c->platformContext());
- CGContextDrawShading(c->platformContext(), state().m_strokeStyle->gradient()->platformShading());
- c->restore();
- } else {
- if (state().m_strokeStyle->pattern())
- applyStrokePattern();
- CGContextStrokePath(c->platformContext());
- }
-#elif defined(ANDROID_CANVAS_IMPL)
- CanvasStyle* s = state().m_strokeStyle.get();
- const Path& path = state().m_path;
- FloatRect bounds = path.boundingRect();
- bounds.inflate(state().m_lineWidth * 0.5f);
- willDraw(bounds);
- c->strokePath(path, extractGradient(s), extractPattern(s));
-#elif PLATFORM(QT)
- QPainterPath* path = state().m_path.platformPath();
- QPainter* p = static_cast<QPainter*>(c->platformContext());
- willDraw(path->controlPointRect());
- if (state().m_strokeStyle->gradient()) {
- p->save();
- p->setBrush(*(state().m_strokeStyle->gradient()->platformShading()));
- p->strokePath(*path, p->pen());
- p->restore();
- } else {
- if (state().m_strokeStyle->pattern())
- applyStrokePattern();
- p->strokePath(*path, p->pen());
- }
-#elif PLATFORM(CAIRO)
- cairo_t* cr = c->platformContext();
- cairo_save(cr);
- // FIXME: consider inset, as in CG
- willDraw(state().m_path.boundingRect());
- if (state().m_strokeStyle->gradient()) {
- cairo_set_source(cr, state().m_strokeStyle->gradient()->platformShading());
- c->addPath(state().m_path);
- cairo_stroke(cr);
- } else {
- if (state().m_strokeStyle->pattern())
- applyStrokePattern();
- c->addPath(state().m_path);
- cairo_stroke(cr);
- }
- cairo_restore(cr);
-#endif
+ c->strokePath();
+#if ENABLE(DASHBOARD_SUPPORT)
clearPathForDashboardBackwardCompatibilityMode();
+#endif
}
void CanvasRenderingContext2D::clip()
@@ -619,8 +577,10 @@ void CanvasRenderingContext2D::clip()
GraphicsContext* c = drawingContext();
if (!c)
return;
- c->clip(state().m_path);
+ c->clip(m_path);
+#if ENABLE(DASHBOARD_SUPPORT)
clearPathForDashboardBackwardCompatibilityMode();
+#endif
}
bool CanvasRenderingContext2D::isPointInPath(const float x, const float y)
@@ -631,20 +591,17 @@ bool CanvasRenderingContext2D::isPointInPath(const float x, const float y)
FloatPoint point(x, y);
// We have to invert the current transform to ensure we correctly handle the
// transforms applied to the current path.
- AffineTransform ctm = c->getCTM();
+ AffineTransform ctm = state().m_transform;
if (!ctm.isInvertible())
return false;
FloatPoint transformedPoint = ctm.inverse().mapPoint(point);
- return state().m_path.contains(transformedPoint);
+ return m_path.contains(transformedPoint);
}
-void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height, ExceptionCode& ec)
+void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
{
- ec = 0;
- if (!(width >= 0 && height >= 0)) {
- ec = INDEX_SIZE_ERR;
+ if (!validateRectForCanvas(x, y, width, height))
return;
- }
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -653,81 +610,37 @@ void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he
c->clearRect(rect);
}
-void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height, ExceptionCode& ec)
+void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height)
{
- ec = 0;
-
- if (!(width >= 0 && height >= 0)) {
- ec = INDEX_SIZE_ERR;
+ if (!validateRectForCanvas(x, y, width, height))
return;
- }
GraphicsContext* c = drawingContext();
if (!c)
return;
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGRect rect = CGRectMake(x, y, width, height);
- willDraw(rect);
-
- if (state().m_fillStyle->gradient()) {
- // Shading works on the entire clip region, so convert the rect to a clip.
- c->save();
- CGContextClipToRect(c->platformContext(), rect);
- CGContextDrawShading(c->platformContext(), state().m_fillStyle->gradient()->platformShading());
- c->restore();
- } else {
- if (state().m_fillStyle->pattern())
- applyFillPattern();
- CGContextFillRect(c->platformContext(), rect);
- }
-#elif defined(ANDROID_CANVAS_IMPL)
- CanvasStyle* s = state().m_fillStyle.get();
- FloatRect rect = FloatRect(x, y, width, height);
- willDraw(rect);
- c->fillRect(rect, extractGradient(s), extractPattern(s));
-#elif PLATFORM(QT)
- QRectF rect(x, y, width, height);
- willDraw(rect);
- QPainter* p = static_cast<QPainter*>(c->platformContext());
- if (state().m_fillStyle->gradient()) {
- p->fillRect(rect, QBrush(*(state().m_fillStyle->gradient()->platformShading())));
- } else {
- if (state().m_fillStyle->pattern())
- applyFillPattern();
- p->fillRect(rect, p->brush());
- }
-#elif PLATFORM(CAIRO)
FloatRect rect(x, y, width, height);
willDraw(rect);
- cairo_t* cr = c->platformContext();
- cairo_save(cr);
- if (state().m_fillStyle->gradient()) {
- cairo_set_source(cr, state().m_fillStyle->gradient()->platformShading());
- } else {
- if (state().m_fillStyle->pattern())
- applyFillPattern();
- }
- cairo_rectangle(cr, x, y, width, height);
- cairo_fill(cr);
- cairo_restore(cr);
-#endif
+
+ c->save();
+ c->fillRect(rect);
+ c->restore();
}
-void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height, ExceptionCode& ec)
+void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height)
{
- strokeRect(x, y, width, height, state().m_lineWidth, ec);
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+ strokeRect(x, y, width, height, state().m_lineWidth);
}
-void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height, float lineWidth, ExceptionCode& ec)
+void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float height, float lineWidth)
{
- ec = 0;
-
- if (!(width >= 0 && height >= 0 && lineWidth >= 0)) {
- ec = INDEX_SIZE_ERR;
+ if (!validateRectForCanvas(x, y, width, height))
+ return;
+
+ if (!(lineWidth >= 0))
return;
- }
GraphicsContext* c = drawingContext();
if (!c)
@@ -739,18 +652,29 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
boundingRect.inflate(lineWidth / 2);
willDraw(boundingRect);
-#ifndef ANDROID_CANVAS_IMPL
- // FIXME: No support for gradients!
- if (state().m_strokeStyle->pattern())
- applyStrokePattern();
-
c->strokeRect(rect, lineWidth);
-#else
- CanvasStyle* s = state().m_strokeStyle.get();
- c->strokeRect(rect, lineWidth, extractGradient(s), extractPattern(s));
-#endif
}
+#if PLATFORM(CG)
+static inline CGSize adjustedShadowSize(CGFloat width, CGFloat height)
+{
+ // Work around <rdar://problem/5539388> by ensuring that shadow offsets will get truncated
+ // to the desired integer.
+ static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128);
+ if (width > 0)
+ width += extraShadowOffset;
+ else if (width < 0)
+ width -= extraShadowOffset;
+
+ if (height > 0)
+ height += extraShadowOffset;
+ else if (height < 0)
+ height -= extraShadowOffset;
+
+ return CGSizeMake(width, height);
+}
+#endif
+
void CanvasRenderingContext2D::setShadow(float width, float height, float blur)
{
state().m_shadowOffset = FloatSize(width, height);
@@ -782,7 +706,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGColorRef color = CGColorCreate(colorSpace, components);
CGColorSpaceRelease(colorSpace);
- CGContextSetShadowWithColor(c->platformContext(), CGSizeMake(width, height), blur, color);
+ CGContextSetShadowWithColor(c->platformContext(), adjustedShadowSize(width, -height), blur, color);
CGColorRelease(color);
#endif
}
@@ -809,7 +733,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef shadowColor = CGColorCreate(colorSpace, components);
CGColorSpaceRelease(colorSpace);
- CGContextSetShadowWithColor(c->platformContext(), CGSizeMake(width, height), blur, shadowColor);
+ CGContextSetShadowWithColor(c->platformContext(), adjustedShadowSize(width, -height), blur, shadowColor);
CGColorRelease(shadowColor);
#endif
}
@@ -829,7 +753,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGColorRef color = CGColorCreate(colorSpace, components);
CGColorSpaceRelease(colorSpace);
- CGContextSetShadowWithColor(c->platformContext(), CGSizeMake(width, height), blur, color);
+ CGContextSetShadowWithColor(c->platformContext(), adjustedShadowSize(width, -height), blur, color);
CGColorRelease(color);
#endif
}
@@ -849,7 +773,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef shadowColor = CGColorCreate(colorSpace, components);
CGColorSpaceRelease(colorSpace);
- CGContextSetShadowWithColor(c->platformContext(), CGSizeMake(width, height), blur, shadowColor);
+ CGContextSetShadowWithColor(c->platformContext(), adjustedShadowSize(width, -height), blur, shadowColor);
CGColorRelease(shadowColor);
#endif
}
@@ -869,7 +793,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceCMYK();
CGColorRef shadowColor = CGColorCreate(colorSpace, components);
CGColorSpaceRelease(colorSpace);
- CGContextSetShadowWithColor(dc->platformContext(), CGSizeMake(width, height), blur, shadowColor);
+ CGContextSetShadowWithColor(dc->platformContext(), adjustedShadowSize(width, -height), blur, shadowColor);
CGColorRelease(shadowColor);
#endif
}
@@ -901,7 +825,8 @@ void CanvasRenderingContext2D::applyShadow()
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef color = CGColorCreate(colorSpace, components);
CGColorSpaceRelease(colorSpace);
- CGContextSetShadowWithColor(c->platformContext(), state().m_shadowOffset, state().m_shadowBlur, color);
+
+ CGContextSetShadowWithColor(c->platformContext(), adjustedShadowSize(state().m_shadowOffset.width(), -state().m_shadowOffset.height()), state().m_shadowBlur, color);
CGColorRelease(color);
#endif
}
@@ -909,10 +834,18 @@ void CanvasRenderingContext2D::applyShadow()
static IntSize size(HTMLImageElement* image)
{
if (CachedImage* cachedImage = image->cachedImage())
- return cachedImage->imageSize();
+ return cachedImage->imageSize(1.0f); // FIXME: Not sure about this.
return IntSize();
}
+static inline FloatRect normalizeRect(const FloatRect& rect)
+{
+ return FloatRect(min(rect.x(), rect.right()),
+ min(rect.y(), rect.bottom()),
+ max(rect.width(), -rect.width()),
+ max(rect.height(), -rect.height()));
+}
+
void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y)
{
ASSERT(image);
@@ -929,12 +862,12 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
drawImage(image, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
}
-#if defined(ANDROID_CANVAS_IMPL)
-static void dumprect(const char label[], const FloatRect& r)
+void CanvasRenderingContext2D::checkOrigin(const KURL& url)
{
- printf("----- %s [%g %g %g %g]\n", label, r.x(), r.y(), r.width(), r.height());
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
+ if (!m_canvas->document()->securityOrigin()->canAccess(origin.get()))
+ m_canvas->setOriginTainted();
}
-#endif
void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect,
ExceptionCode& ec)
@@ -944,13 +877,12 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
ec = 0;
FloatRect imageRect = FloatRect(FloatPoint(), size(image));
- if (!(imageRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0
- && dstRect.width() >= 0 && dstRect.height() >= 0)) {
+ if (!imageRect.contains(normalizeRect(srcRect)) || srcRect.width() == 0 || srcRect.height() == 0) {
ec = INDEX_SIZE_ERR;
return;
}
- if (srcRect.isEmpty() || dstRect.isEmpty())
+ if (!dstRect.width() || !dstRect.height())
return;
GraphicsContext* c = drawingContext();
@@ -961,10 +893,16 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec
if (!cachedImage)
return;
+ if (m_canvas->originClean())
+ checkOrigin(cachedImage->response().url());
+
+ if (m_canvas->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
+ m_canvas->setOriginTainted();
+
FloatRect sourceRect = c->roundToDevicePixels(srcRect);
FloatRect destRect = c->roundToDevicePixels(dstRect);
willDraw(destRect);
-#if defined(ANDROID_CANVAS_IMPL)
+#if PLATFORM(SGL)
// this seems like a bug fix as well.
// can't see how the std code can use destRect/sourceRect, since they are scaled by matrix
c->drawImage(cachedImage->image(), dstRect, srcRect, state().m_globalComposite);
@@ -995,13 +933,12 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatR
ec = 0;
FloatRect srcCanvasRect = FloatRect(FloatPoint(), canvas->size());
- if (!(srcCanvasRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0
- && dstRect.width() >= 0 && dstRect.height() >= 0)) {
+ if (!srcCanvasRect.contains(normalizeRect(srcRect)) || srcRect.width() == 0 || srcRect.height() == 0) {
ec = INDEX_SIZE_ERR;
return;
}
- if (srcRect.isEmpty() || dstRect.isEmpty())
+ if (!dstRect.width() || !dstRect.height())
return;
GraphicsContext* c = drawingContext();
@@ -1012,68 +949,16 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatR
FloatRect destRect = c->roundToDevicePixels(dstRect);
// FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGImageRef platformImage = canvas->createPlatformImage();
- if (!platformImage)
+ ImageBuffer* buffer = canvas->buffer();
+ if (!buffer)
return;
- willDraw(destRect);
+ if (!canvas->originClean())
+ m_canvas->setOriginTainted();
- float iw = CGImageGetWidth(platformImage);
- float ih = CGImageGetHeight(platformImage);
- if (sourceRect.x() == 0 && sourceRect.y() == 0 && iw == sourceRect.width() && ih == sourceRect.height()) {
- // Fast path, yay!
- CGContextDrawImage(c->platformContext(), destRect, platformImage);
- } else {
- // Slow path, boo!
- // Create a new bitmap of the appropriate size and then draw that into our context.
-
- size_t csw = static_cast<size_t>(ceilf(sourceRect.width()));
- size_t csh = static_cast<size_t>(ceilf(sourceRect.height()));
-
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- size_t bytesPerRow = csw * 4;
- void* buffer = fastMalloc(csh * bytesPerRow);
-
- CGContextRef clippedSourceContext = CGBitmapContextCreate(buffer, csw, csh,
- 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
- CGColorSpaceRelease(colorSpace);
- CGContextTranslateCTM(clippedSourceContext, -sourceRect.x(), -sourceRect.y());
- CGContextDrawImage(clippedSourceContext, CGRectMake(0, 0, iw, ih), platformImage);
-
- CGImageRef clippedSourceImage = CGBitmapContextCreateImage(clippedSourceContext);
- CGContextRelease(clippedSourceContext);
-
- CGContextDrawImage(c->platformContext(), destRect, clippedSourceImage);
- CGImageRelease(clippedSourceImage);
-
- fastFree(buffer);
- }
-
- CGImageRelease(platformImage);
-#elif defined(ANDROID_CANVAS_IMPL)
- willDraw(destRect);
- c->drawOffscreenContext(canvas->drawingContext(), &srcRect, dstRect);
-#elif PLATFORM(QT)
- QImage px = canvas->createPlatformImage();
- if (px.isNull())
- return;
- willDraw(dstRect);
- QPainter* painter = static_cast<QPainter*>(c->platformContext());
- painter->drawImage(dstRect, px, srcRect);
-#elif PLATFORM(CAIRO)
- cairo_surface_t* image = canvas->createPlatformImage();
- if (!image)
- return;
- willDraw(dstRect);
- cairo_t* cr = c->platformContext();
- cairo_save(cr);
- cairo_set_source_surface(cr, image, srcRect.x(), srcRect.y());
- cairo_surface_destroy(image);
- cairo_rectangle(cr, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height());
- cairo_fill(cr);
- cairo_restore(cr);
-#endif
+ c->drawImage(buffer->image(), destRect, sourceRect, state().m_globalComposite);
+ willDraw(destRect); // This call comes after drawImage, since the buffer we draw into may be our own, and we need to make sure it is dirty.
+ // FIXME: Arguably willDraw should become didDraw and occur after drawing calls and not before them to avoid problems like this.
}
// FIXME: Why isn't this just another overload of drawImage? Why have a different name?
@@ -1089,6 +974,12 @@ void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
if (!cachedImage)
return;
+ if (m_canvas->originClean())
+ checkOrigin(cachedImage->response().url());
+
+ if (m_canvas->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
+ m_canvas->setOriginTainted();
+
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -1112,14 +1003,24 @@ void CanvasRenderingContext2D::setCompositeOperation(const String& operation)
setGlobalCompositeOperation(operation);
}
-PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1)
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode& ec)
{
- return new CanvasGradient(FloatPoint(x0, y0), FloatPoint(x1, y1));
+ if (!isfinite(x0) || !isfinite(y0) || !isfinite(x1) || !isfinite(y1)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+
+ return CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
}
-PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1)
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode& ec)
{
- return new CanvasGradient(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
+ if (!isfinite(x0) || !isfinite(y0) || !isfinite(r0) ||
+ !isfinite(x1) || !isfinite(y1) || !isfinite(r1)) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+ return CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
}
PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
@@ -1130,42 +1031,40 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageEleme
CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
if (ec)
return 0;
- return new CanvasPattern(image ? image->cachedImage() : 0, repeatX, repeatY);
+
+ if (!image->complete()) {
+ ec = INVALID_STATE_ERR;
+ return 0;
+ }
+
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage || !image->cachedImage()->image())
+ return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
+
+ KURL url(cachedImage->url());
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
+ bool originClean = m_canvas->document()->securityOrigin()->canAccess(origin.get());
+ return CanvasPattern::create(cachedImage->image(), repeatX, repeatY, originClean);
}
PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
const String& repetitionType, ExceptionCode& ec)
{
+ if (!canvas->width() || !canvas->height()) {
+ ec = INVALID_STATE_ERR;
+ return 0;
+ }
+
bool repeatX, repeatY;
ec = 0;
CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
if (ec)
return 0;
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGImageRef image = canvas->createPlatformImage();
- if (!image)
- return 0;
- PassRefPtr<CanvasPattern> pattern = new CanvasPattern(image, repeatX, repeatY);
- CGImageRelease(image);
- return pattern;
-#elif PLATFORM(CAIRO)
- cairo_surface_t* surface = canvas->createPlatformImage();
- if (!surface)
- return 0;
- PassRefPtr<CanvasPattern> pattern = new CanvasPattern(surface, repeatX, repeatY);
- cairo_surface_destroy(surface);
- return pattern;
-#else
- notImplemented();
- return 0;
-#endif
+ return CanvasPattern::create(canvas->buffer()->image(), repeatX, repeatY, canvas->originClean());
}
void CanvasRenderingContext2D::willDraw(const FloatRect& r)
{
- if (!m_canvas)
- return;
GraphicsContext* c = drawingContext();
if (!c)
return;
@@ -1175,111 +1074,293 @@ void CanvasRenderingContext2D::willDraw(const FloatRect& r)
GraphicsContext* CanvasRenderingContext2D::drawingContext() const
{
- if (!m_canvas)
- return 0;
return m_canvas->drawingContext();
}
-void CanvasRenderingContext2D::applyStrokePattern()
+static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
{
- GraphicsContext* c = drawingContext();
- if (!c)
- return;
+ PassRefPtr<ImageData> data = ImageData::create(size.width(), size.height());
+ memset(data->data()->data().data(), 0, data->data()->length());
+ return data;
+}
-#if PLATFORM(CG)
- // Check for case where the pattern is already set.
- CGAffineTransform m = CGContextGetCTM(c->platformContext());
- if (state().m_appliedStrokePattern
- && CGAffineTransformEqualToTransform(m, state().m_strokeStylePatternTransform))
- return;
+PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh) const
+{
+ FloatSize unscaledSize(sw, sh);
+ IntSize scaledSize = m_canvas->convertLogicalToDevice(unscaledSize);
+ if (scaledSize.width() < 1)
+ scaledSize.setWidth(1);
+ if (scaledSize.height() < 1)
+ scaledSize.setHeight(1);
+
+ return createEmptyImageData(scaledSize);
+}
- CanvasPattern* pattern = state().m_strokeStyle->pattern();
- if (!pattern)
- return;
+PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
+{
+ if (!m_canvas->originClean()) {
+ ec = SECURITY_ERR;
+ return 0;
+ }
+
+ FloatRect unscaledRect(sx, sy, sw, sh);
+ IntRect scaledRect = m_canvas->convertLogicalToDevice(unscaledRect);
+ if (scaledRect.width() < 1)
+ scaledRect.setWidth(1);
+ if (scaledRect.height() < 1)
+ scaledRect.setHeight(1);
+ ImageBuffer* buffer = m_canvas ? m_canvas->buffer() : 0;
+ if (!buffer)
+ return createEmptyImageData(scaledRect.size());
+ return buffer->getImageData(scaledRect);
+}
- CGPatternRef platformPattern = pattern->createPattern(m);
- if (!platformPattern)
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, ExceptionCode& ec)
+{
+ if (!data) {
+ ec = TYPE_MISMATCH_ERR;
return;
+ }
+ putImageData(data, dx, dy, 0, 0, data->width(), data->height(), ec);
+}
- CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(0);
- CGContextSetStrokeColorSpace(c->platformContext(), patternSpace);
- CGColorSpaceRelease(patternSpace);
-
- const CGFloat patternAlpha = 1;
- CGContextSetStrokePattern(c->platformContext(), platformPattern, &patternAlpha);
- CGPatternRelease(platformPattern);
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY,
+ float dirtyWidth, float dirtyHeight, ExceptionCode& ec)
+{
+ if (!data) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+ if (!isfinite(dx) || !isfinite(dy) || !isfinite(dirtyX) ||
+ !isfinite(dirtyY) || !isfinite(dirtyWidth) || !isfinite(dirtyHeight)) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
- state().m_strokeStylePatternTransform = m;
-#elif PLATFORM(QT)
- fprintf(stderr, "FIXME: CanvasRenderingContext2D::applyStrokePattern\n");
-#elif PLATFORM(CAIRO)
- CanvasPattern* pattern = state().m_strokeStyle->pattern();
- if (!pattern)
+ ImageBuffer* buffer = m_canvas->buffer();
+ if (!buffer)
return;
- cairo_t* cr = c->platformContext();
- cairo_matrix_t m;
- cairo_get_matrix(cr, &m);
+ if (dirtyWidth < 0) {
+ dirtyX += dirtyWidth;
+ dirtyWidth = -dirtyWidth;
+ }
- cairo_pattern_t* platformPattern = pattern->createPattern(m);
- if (!platformPattern)
- return;
+ if (dirtyHeight < 0) {
+ dirtyY += dirtyHeight;
+ dirtyHeight = -dirtyHeight;
+ }
- cairo_set_source(cr, platformPattern);
- cairo_pattern_destroy(platformPattern);
-#endif
- state().m_appliedStrokePattern = true;
+ FloatRect clipRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
+ clipRect.intersect(IntRect(0, 0, data->width(), data->height()));
+ IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy));
+ IntRect sourceRect = enclosingIntRect(clipRect);
+ sourceRect.move(destOffset);
+ sourceRect.intersect(IntRect(IntPoint(), buffer->size()));
+ if (sourceRect.isEmpty())
+ return;
+ willDraw(sourceRect);
+ sourceRect.move(-destOffset);
+ IntPoint destPoint(destOffset.width(), destOffset.height());
+
+ buffer->putImageData(data, sourceRect, destPoint);
+}
+
+String CanvasRenderingContext2D::font() const
+{
+ return state().m_unparsedFont;
}
-void CanvasRenderingContext2D::applyFillPattern()
+void CanvasRenderingContext2D::setFont(const String& newFont)
{
+ RefPtr<CSSMutableStyleDeclaration> tempDecl = CSSMutableStyleDeclaration::create();
+ CSSParser parser(!m_canvas->document()->inCompatMode()); // Use the parse mode of the canvas' document when parsing CSS.
+
+ String declarationText("font: ");
+ declarationText += newFont;
+ parser.parseDeclaration(tempDecl.get(), declarationText);
+ if (!tempDecl->length())
+ return;
+
+ // The parse succeeded.
+ state().m_unparsedFont = newFont;
+
+ // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
+ // relative to the canvas.
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ if (m_canvas->computedStyle())
+ newStyle->setFontDescription(m_canvas->computedStyle()->fontDescription());
+
+ // Now map the font property into the style.
+ CSSStyleSelector* styleSelector = m_canvas->document()->styleSelector();
+ styleSelector->applyPropertyToStyle(CSSPropertyFont, tempDecl->getPropertyCSSValue(CSSPropertyFont).get(), newStyle.get());
+
+ state().m_font = newStyle->font();
+ state().m_font.update(styleSelector->fontSelector());
+ state().m_realizedFont = true;
+
+ // Set the font in the graphics context.
GraphicsContext* c = drawingContext();
if (!c)
return;
+ c->setFont(state().m_font);
+}
+
+String CanvasRenderingContext2D::textAlign() const
+{
+ return textAlignName(state().m_textAlign);
+}
-#if PLATFORM(CG)
- // Check for case where the pattern is already set.
- CGAffineTransform m = CGContextGetCTM(c->platformContext());
- if (state().m_appliedFillPattern
- && CGAffineTransformEqualToTransform(m, state().m_fillStylePatternTransform))
+void CanvasRenderingContext2D::setTextAlign(const String& s)
+{
+ TextAlign align;
+ if (!parseTextAlign(s, align))
return;
+ state().m_textAlign = align;
+}
+
+String CanvasRenderingContext2D::textBaseline() const
+{
+ return textBaselineName(state().m_textBaseline);
+}
- CanvasPattern* pattern = state().m_fillStyle->pattern();
- if (!pattern)
+void CanvasRenderingContext2D::setTextBaseline(const String& s)
+{
+ TextBaseline baseline;
+ if (!parseTextBaseline(s, baseline))
return;
+ state().m_textBaseline = baseline;
+}
- CGPatternRef platformPattern = pattern->createPattern(m);
- if (!platformPattern)
- return;
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y)
+{
+ drawTextInternal(text, x, y, true);
+}
+
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y, float maxWidth)
+{
+ drawTextInternal(text, x, y, true, maxWidth, true);
+}
+
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y)
+{
+ drawTextInternal(text, x, y, false);
+}
- CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(0);
- CGContextSetFillColorSpace(c->platformContext(), patternSpace);
- CGColorSpaceRelease(patternSpace);
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y, float maxWidth)
+{
+ drawTextInternal(text, x, y, false, maxWidth, true);
+}
- const CGFloat patternAlpha = 1;
- CGContextSetFillPattern(c->platformContext(), platformPattern, &patternAlpha);
- CGPatternRelease(platformPattern);
+PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+{
+ RefPtr<TextMetrics> metrics = TextMetrics::create();
+ metrics->setWidth(accessFont().width(TextRun(text.characters(), text.length())));
+ return metrics;
+}
- state().m_fillStylePatternTransform = m;
-#elif PLATFORM(QT)
- fprintf(stderr, "FIXME: CanvasRenderingContext2D::applyFillPattern\n");
-#elif PLATFORM(CAIRO)
- CanvasPattern* pattern = state().m_fillStyle->pattern();
- if (!pattern)
+void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth, bool useMaxWidth)
+{
+ GraphicsContext* c = drawingContext();
+ if (!c)
return;
+
+ const Font& font = accessFont();
+
+ // FIXME: Handle maxWidth.
+ // FIXME: Need to turn off font smoothing.
+
+ bool rtl = m_canvas->computedStyle() ? m_canvas->computedStyle()->direction() == RTL : false;
+ bool override = m_canvas->computedStyle() ? m_canvas->computedStyle()->unicodeBidi() == Override : false;
+
+ unsigned length = text.length();
+ const UChar* string = text.characters();
+ TextRun textRun(string, length, 0, 0, 0, rtl, override, false, false);
+
+ // Draw the item text at the correct point.
+ FloatPoint location(x, y);
+ switch (state().m_textBaseline) {
+ case TopTextBaseline:
+ case HangingTextBaseline:
+ location.setY(y + font.ascent());
+ break;
+ case BottomTextBaseline:
+ case IdeographicTextBaseline:
+ location.setY(y - font.descent());
+ break;
+ case MiddleTextBaseline:
+ location.setY(y - font.descent() + font.height() / 2);
+ break;
+ case AlphabeticTextBaseline:
+ default:
+ // Do nothing.
+ break;
+ }
+
+ float width = font.width(TextRun(text, false, 0, 0, rtl, override));
+
+ TextAlign align = state().m_textAlign;
+ if (align == StartTextAlign)
+ align = rtl ? RightTextAlign : LeftTextAlign;
+ else if (align == EndTextAlign)
+ align = rtl ? LeftTextAlign : RightTextAlign;
+
+ switch (align) {
+ case CenterTextAlign:
+ location.setX(location.x() - width / 2);
+ break;
+ case RightTextAlign:
+ location.setX(location.x() - width);
+ break;
+ default:
+ break;
+ }
+
+ // The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text.
+ FloatRect textRect = FloatRect(location.x() - font.height() / 2, location.y() - font.ascent() - font.lineGap(),
+ width + font.height(), font.lineSpacing());
+ if (!fill)
+ textRect.inflate(c->strokeThickness() / 2);
+
+ CanvasStyle* drawStyle = fill ? state().m_fillStyle.get() : state().m_strokeStyle.get();
+ if (drawStyle->canvasGradient() || drawStyle->canvasPattern()) {
+ IntRect maskRect = enclosingIntRect(textRect);
+
+ auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false);
+
+ GraphicsContext* maskImageContext = maskImage->context();
- cairo_t* cr = c->platformContext();
- cairo_matrix_t m;
- cairo_get_matrix(cr, &m);
+ if (fill)
+ maskImageContext->setFillColor(Color::black);
+ else {
+ maskImageContext->setStrokeColor(Color::black);
+ maskImageContext->setStrokeThickness(c->strokeThickness());
+ }
+
+ maskImageContext->setTextDrawingMode(fill ? cTextFill : cTextStroke);
+ maskImageContext->translate(-maskRect.x(), -maskRect.y());
+
+ maskImageContext->setFont(font);
+ maskImageContext->drawBidiText(textRun, location);
+
+ c->save();
+ c->clipToImageBuffer(maskRect, maskImage.get());
+ drawStyle->applyFillColor(c);
+ c->fillRect(maskRect);
+ c->restore();
- cairo_pattern_t* platformPattern = pattern->createPattern(m);
- if (!platformPattern)
return;
+ }
- cairo_set_source(cr, platformPattern);
- cairo_pattern_destroy(platformPattern);
-#endif
- state().m_appliedFillPattern = true;
+ c->setTextDrawingMode(fill ? cTextFill : cTextStroke);
+ c->drawBidiText(textRun, location);
+}
+
+const Font& CanvasRenderingContext2D::accessFont()
+{
+ if (!state().m_realizedFont)
+ setFont(state().m_unparsedFont);
+ return state().m_font;
}
} // namespace WebCore
diff --git a/WebCore/html/CanvasRenderingContext2D.h b/WebCore/html/CanvasRenderingContext2D.h
index 30f7a53..e720f21 100644
--- a/WebCore/html/CanvasRenderingContext2D.h
+++ b/WebCore/html/CanvasRenderingContext2D.h
@@ -26,7 +26,9 @@
#ifndef CanvasRenderingContext2D_h
#define CanvasRenderingContext2D_h
+#include "AffineTransform.h"
#include "FloatSize.h"
+#include "Font.h"
#include "GraphicsTypes.h"
#include "Path.h"
#include "PlatformString.h"
@@ -45,13 +47,19 @@ namespace WebCore {
class GraphicsContext;
class HTMLCanvasElement;
class HTMLImageElement;
+ class ImageData;
+ class KURL;
+ class TextMetrics;
typedef int ExceptionCode;
- class CanvasRenderingContext2D : public RefCounted<CanvasRenderingContext2D> {
+ class CanvasRenderingContext2D : Noncopyable {
public:
CanvasRenderingContext2D(HTMLCanvasElement*);
-
+
+ void ref();
+ void deref();
+
HTMLCanvasElement* canvas() const { return m_canvas; }
CanvasStyle* strokeStyle() const;
@@ -121,7 +129,7 @@ namespace WebCore {
void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
void arcTo(float x0, float y0, float x1, float y1, float radius, ExceptionCode&);
void arc(float x, float y, float r, float sa, float ea, bool clockwise, ExceptionCode&);
- void rect(float x, float y, float width, float height, ExceptionCode&);
+ void rect(float x, float y, float width, float height);
void fill();
void stroke();
@@ -129,10 +137,10 @@ namespace WebCore {
bool isPointInPath(const float x, const float y);
- void clearRect(float x, float y, float width, float height, ExceptionCode&);
- void fillRect(float x, float y, float width, float height, ExceptionCode&);
- void strokeRect(float x, float y, float width, float height, ExceptionCode&);
- void strokeRect(float x, float y, float width, float height, float lineWidth, ExceptionCode&);
+ void clearRect(float x, float y, float width, float height);
+ void fillRect(float x, float y, float width, float height);
+ void strokeRect(float x, float y, float width, float height);
+ void strokeRect(float x, float y, float width, float height, float lineWidth);
void setShadow(float width, float height, float blur);
void setShadow(float width, float height, float blur, const String& color);
@@ -158,21 +166,39 @@ namespace WebCore {
void setCompositeOperation(const String&);
- PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1);
- PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
+ PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode&);
+ PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode&);
PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionCode&);
PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionCode&);
-
+
+ PassRefPtr<ImageData> createImageData(float width, float height) const;
+ PassRefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionCode&) const;
+ void putImageData(ImageData*, float dx, float dy, ExceptionCode&);
+ void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&);
+
void reset();
- void detachCanvas() { m_canvas = 0; }
+
+ String font() const;
+ void setFont(const String&);
+
+ String textAlign() const;
+ void setTextAlign(const String&);
+
+ String textBaseline() const;
+ void setTextBaseline(const String&);
+
+ void fillText(const String& text, float x, float y);
+ void fillText(const String& text, float x, float y, float maxWidth);
+ void strokeText(const String& text, float x, float y);
+ void strokeText(const String& text, float x, float y, float maxWidth);
+ PassRefPtr<TextMetrics> measureText(const String& text);
private:
struct State {
State();
-
+
RefPtr<CanvasStyle> m_strokeStyle;
RefPtr<CanvasStyle> m_fillStyle;
- Path m_path;
float m_lineWidth;
LineCap m_lineCap;
LineJoin m_lineJoin;
@@ -182,13 +208,17 @@ namespace WebCore {
String m_shadowColor;
float m_globalAlpha;
CompositeOperator m_globalComposite;
- bool m_appliedStrokePattern;
- bool m_appliedFillPattern;
-#if PLATFORM(CG)
- CGAffineTransform m_strokeStylePatternTransform;
- CGAffineTransform m_fillStylePatternTransform;
-#endif
+ AffineTransform m_transform;
+
+ // Text state.
+ TextAlign m_textAlign;
+ TextBaseline m_textBaseline;
+
+ String m_unparsedFont;
+ Font m_font;
+ bool m_realizedFont;
};
+ Path m_path;
State& state() { return m_stateStack.last(); }
const State& state() const { return m_stateStack.last(); }
@@ -202,7 +232,15 @@ namespace WebCore {
void applyStrokePattern();
void applyFillPattern();
+ void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
+
+ const Font& accessFont();
+
+#if ENABLE(DASHBOARD_SUPPORT)
void clearPathForDashboardBackwardCompatibilityMode();
+#endif
+
+ void checkOrigin(const KURL&);
HTMLCanvasElement* m_canvas;
Vector<State, 1> m_stateStack;
diff --git a/WebCore/html/CanvasRenderingContext2D.idl b/WebCore/html/CanvasRenderingContext2D.idl
index 3d566d4..29c9a7a 100644
--- a/WebCore/html/CanvasRenderingContext2D.idl
+++ b/WebCore/html/CanvasRenderingContext2D.idl
@@ -26,6 +26,7 @@
module html {
interface [
+ GenerateConstructor,
InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54
] CanvasRenderingContext2D {
@@ -45,8 +46,10 @@ module html {
attribute float globalAlpha;
attribute [ConvertNullToNullString] DOMString globalCompositeOperation;
- CanvasGradient createLinearGradient(in float x0, in float y0, in float x1, in float y1);
- CanvasGradient createRadialGradient(in float x0, in float y0, in float r0, in float x1, in float y1, in float r1);
+ CanvasGradient createLinearGradient(in float x0, in float y0, in float x1, in float y1)
+ raises (DOMException);
+ CanvasGradient createRadialGradient(in float x0, in float y0, in float r0, in float x1, in float y1, in float r1)
+ raises (DOMException);
attribute float lineWidth;
attribute [ConvertNullToNullString] DOMString lineCap;
@@ -58,10 +61,8 @@ module html {
attribute float shadowBlur;
attribute [ConvertNullToNullString] DOMString shadowColor;
- void clearRect(in float x, in float y, in float width, in float height)
- raises (DOMException);
- void fillRect(in float x, in float y, in float width, in float height)
- raises (DOMException);
+ void clearRect(in float x, in float y, in float width, in float height);
+ void fillRect(in float x, in float y, in float width, in float height);
void beginPath();
void closePath();
@@ -71,8 +72,7 @@ module html {
void bezierCurveTo(in float cp1x, in float cp1y, in float cp2x, in float cp2y, in float x, in float y);
void arcTo(in float x1, in float y1, in float x2, in float y2, in float radius)
raises (DOMException);
- void rect(in float x, in float y, in float width, in float height)
- raises (DOMException);
+ void rect(in float x, in float y, in float width, in float height);
void arc(in float x, in float y, in float radius, in float startAngle, in float endAngle, in boolean anticlockwise)
raises (DOMException);
void fill();
@@ -80,6 +80,14 @@ module html {
void clip();
boolean isPointInPath(in float x, in float y);
+ // text
+ attribute DOMString font;
+ attribute DOMString textAlign;
+ attribute DOMString textBaseline;
+ [Custom] void fillText(/* 4 */);
+ [Custom] void strokeText(/* 4 */);
+ TextMetrics measureText(in DOMString text);
+
// other
void setAlpha(in float alpha);
@@ -101,7 +109,13 @@ module html {
[Custom] void createPattern(/* 2 */);
attribute [Custom] custom strokeStyle;
- attribute [Custom] custom fillStyle;
+ attribute [Custom] custom fillStyle;
+
+ // pixel manipulation
+ ImageData createImageData(in float sw, in float sh);
+ ImageData getImageData(in float sx, in float sy, in float sw, in float sh)
+ raises(DOMException);
+ [Custom] void putImageData(/* in ImageData imagedata, in float dx, in float dy [, in float dirtyX, in float dirtyY, in float dirtyWidth, in float dirtyHeight] */);
};
}
diff --git a/WebCore/html/CanvasStyle.cpp b/WebCore/html/CanvasStyle.cpp
index 073fb35..27d8a84 100644
--- a/WebCore/html/CanvasStyle.cpp
+++ b/WebCore/html/CanvasStyle.cpp
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,11 +35,8 @@
#include "GraphicsContext.h"
#include <wtf/PassRefPtr.h>
-#ifdef ANDROID_CANVAS_IMPL
-static int F2B(float unit)
-{
- return (int)(unit * 255);
-}
+#if PLATFORM(CG)
+#include <CoreGraphics/CGContext.h>
#endif
#if PLATFORM(QT)
@@ -48,28 +46,34 @@ static int F2B(float unit)
#include <QColor>
#elif PLATFORM(CAIRO)
#include "NotImplemented.h"
-#include <cairo.h>
#endif
namespace WebCore {
CanvasStyle::CanvasStyle(const String& color)
- : m_type(ColorString), m_color(color)
+ : m_type(ColorString)
+ , m_color(color)
{
}
CanvasStyle::CanvasStyle(float grayLevel)
- : m_type(GrayLevel), m_alpha(1), m_grayLevel(grayLevel)
+ : m_type(GrayLevel)
+ , m_alpha(1)
+ , m_grayLevel(grayLevel)
{
}
CanvasStyle::CanvasStyle(const String& color, float alpha)
- : m_type(ColorStringWithAlpha), m_color(color), m_alpha(alpha)
+ : m_type(ColorStringWithAlpha)
+ , m_color(color)
+ , m_alpha(alpha)
{
}
CanvasStyle::CanvasStyle(float grayLevel, float alpha)
- : m_type(GrayLevel), m_alpha(alpha), m_grayLevel(grayLevel)
+ : m_type(GrayLevel)
+ , m_alpha(alpha)
+ , m_grayLevel(grayLevel)
{
}
@@ -84,12 +88,14 @@ CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a)
}
CanvasStyle::CanvasStyle(PassRefPtr<CanvasGradient> gradient)
- : m_type(gradient ? Gradient : ColorString), m_gradient(gradient)
+ : m_type(gradient ? Gradient : ColorString)
+ , m_gradient(gradient)
{
}
CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
- : m_type(pattern ? ImagePattern : ColorString), m_pattern(pattern)
+ : m_type(pattern ? ImagePattern : ColorString)
+ , m_pattern(pattern)
{
}
@@ -97,230 +103,104 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context)
{
if (!context)
return;
-#if PLATFORM(QT)
- QPainter* p = static_cast<QPainter*>(context->platformContext());
-#elif PLATFORM(CAIRO)
- cairo_t* cr = context->platformContext();
-#endif
switch (m_type) {
case ColorString: {
RGBA32 color = 0; // default is transparant black
- CSSParser::parseColor(color, m_color);
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextSetRGBStrokeColor(context->platformContext(),
- ((color >> 16) & 0xFF) / 255.0f,
- ((color >> 8) & 0xFF) / 255.0f,
- (color & 0xFF) / 255.0f,
- ((color >> 24) & 0xFF) / 255.0f);
-#elif defined(ANDROID_CANVAS_IMPL)
- context->setStrokeColor(Color(color));
-#elif PLATFORM(QT)
- QPen currentPen = p->pen();
- currentPen.setColor((QColor(QRgb(color))));
- p->setPen(currentPen);
-#elif PLATFORM(CAIRO)
- // FIXME: fill and stroke color should be dealt with separately
- cairo_set_source_rgba(cr,
- ((color >> 16) & 0xFF) / 255.0f,
- ((color >> 8) & 0xFF) / 255.0f,
- (color & 0xFF) / 255.0f,
- ((color >> 24) & 0xFF) / 255.0f);
-#endif
+ if (CSSParser::parseColor(color, m_color))
+ context->setStrokeColor(color);
break;
}
case ColorStringWithAlpha: {
RGBA32 color = 0; // default is transparant black
- CSSParser::parseColor(color, m_color);
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextSetRGBStrokeColor(context->platformContext(),
- ((color >> 16) & 0xFF) / 255.0f,
- ((color >> 8) & 0xFF) / 255.0f,
- (color & 0xFF) / 255.0f,
- m_alpha);
-#elif defined(ANDROID_CANVAS_IMPL)
- context->setStrokeColor(Color((color & 0x00FFFFFF) | (F2B(m_alpha) << 8)));
-#elif PLATFORM(QT)
- QPen currentPen = p->pen();
- QColor clr = QColor(QRgb(color));
- clr.setAlphaF(m_alpha);
- currentPen.setColor(clr);
- p->setPen(currentPen);
-#elif PLATFORM(CAIRO)
- // FIXME: fill and stroke color should be dealt with separately
- cairo_set_source_rgba(cr,
- ((color >> 16) & 0xFF) / 255.0f,
- ((color >> 8) & 0xFF) / 255.0f,
- (color & 0xFF) / 255.0f,
- ((color >> 24) & 0xFF) / 255.0f);
-#endif
+ if (CSSParser::parseColor(color, m_color))
+ context->setStrokeColor(colorWithOverrideAlpha(color, m_alpha));
break;
}
- case GrayLevel: {
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextSetGrayStrokeColor(context->platformContext(), m_grayLevel, m_alpha);
-#elif defined(ANDROID_CANVAS_IMPL)
- {
- int gray = F2B(m_grayLevel);
- context->setStrokeColor(Color(makeRGBA(gray, gray, gray, F2B(m_alpha))));
- }
-#elif PLATFORM(QT)
- QColor clr;
- QPen currentPen = p->pen();
- clr.setRgbF(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha);
- currentPen.setColor(clr);
- p->setPen(currentPen);
-#elif PLATFORM(CAIRO)
- cairo_set_source_rgba(cr, m_grayLevel, m_grayLevel, m_grayLevel, m_alpha);
-#endif
+ case GrayLevel:
+ // We're only supporting 255 levels of gray here. Since this isn't
+ // even part of HTML5, I don't expect anyone will care. If they do
+ // we'll make a fancier Color abstraction.
+ context->setStrokeColor(Color(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha));
break;
- }
- case RGBA: {
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextSetRGBStrokeColor(context->platformContext(), m_red, m_green, m_blue, m_alpha);
-#elif defined(ANDROID_CANVAS_IMPL)
- context->setStrokeColor(Color(makeRGBA(F2B(m_red), F2B(m_green), F2B(m_blue), F2B(m_alpha))));
-#elif PLATFORM(QT)
- QPen currentPen = p->pen();
- QColor clr;
- clr.setRgbF(m_red, m_green, m_blue, m_alpha);
- currentPen.setColor(clr);
- p->setPen(currentPen);
-#elif PLATFORM(CAIRO)
- // FIXME: fill and stroke color should be dealt with separately
- cairo_set_source_rgba(cr, m_red, m_green, m_blue, m_alpha);
-#endif
+ case RGBA:
+ context->setStrokeColor(Color(m_red, m_green, m_blue, m_alpha));
break;
- }
case CMYKA: {
// FIXME: Do this through platform-independent GraphicsContext API.
+ // We'll need a fancier Color abstraction to support CYMKA correctly
#if PLATFORM(CG)
CGContextSetCMYKStrokeColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha);
#elif PLATFORM(QT)
- QPen currentPen = p->pen();
+ QPen currentPen = context->platformContext()->pen();
QColor clr;
clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
currentPen.setColor(clr);
- p->setPen(currentPen);
+ context->platformContext()->setPen(currentPen);
#elif PLATFORM(CAIRO)
notImplemented();
+#elif PLATFORM(SGL)
+ context->setCMYKAStrokeColor(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
#endif
break;
}
case Gradient:
+ context->setStrokeGradient(canvasGradient()->gradient());
+ break;
case ImagePattern:
+ context->setStrokePattern(canvasPattern()->pattern());
break;
}
}
-// Cairo's graphics model allows us to share a single code path for
-// stroke and fill.
-#if !PLATFORM(CAIRO)
void CanvasStyle::applyFillColor(GraphicsContext* context)
{
if (!context)
return;
-#if PLATFORM(QT)
- QPainter* p = static_cast<QPainter*>(context->platformContext());
-#endif
switch (m_type) {
case ColorString: {
- RGBA32 color = 0; // default is transparant black
- CSSParser::parseColor(color, m_color);
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextSetRGBFillColor(context->platformContext(),
- ((color >> 16) & 0xFF) / 255.0f,
- ((color >> 8) & 0xFF) / 255.0f,
- (color & 0xFF) / 255.0f,
- ((color >> 24) & 0xFF) / 255.0f);
-#elif defined(ANDROID_CANVAS_IMPL)
- context->setFillColor(Color(color));
-#elif PLATFORM(QT)
- QBrush currentBrush = p->brush();
- QColor clr;
- clr.setRgb(QRgb(color));
- currentBrush.setColor(clr);
- p->setBrush(currentBrush);
-#endif
+ RGBA32 rgba = 0; // default is transparant black
+ if (CSSParser::parseColor(rgba, m_color))
+ context->setFillColor(rgba);
break;
}
case ColorStringWithAlpha: {
RGBA32 color = 0; // default is transparant black
- CSSParser::parseColor(color, m_color);
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextSetRGBFillColor(context->platformContext(),
- ((color >> 16) & 0xFF) / 255.0f,
- ((color >> 8) & 0xFF) / 255.0f,
- (color & 0xFF) / 255.0f,
- m_alpha);
-#elif defined(ANDROID_CANVAS_IMPL)
- context->setFillColor(Color((color & 0x00FFFFFF) | (F2B(m_alpha) << 8)));
-#elif PLATFORM(QT)
- QBrush currentBrush = p->brush();
- QColor clr;
- clr.setRgb(QRgb(color));
- clr.setAlphaF(m_alpha);
- currentBrush.setColor(clr);
- p->setBrush(currentBrush);
-#endif
+ if (CSSParser::parseColor(color, m_color))
+ context->setFillColor(colorWithOverrideAlpha(color, m_alpha));
break;
}
- case GrayLevel: {
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextSetGrayFillColor(context->platformContext(), m_grayLevel, m_alpha);
-#elif defined(ANDROID_CANVAS_IMPL)
- {
- int gray = F2B(m_grayLevel);
- context->setFillColor(Color(gray, gray, gray, F2B(m_alpha)));
- }
-#elif PLATFORM(QT)
- QBrush currentBrush = p->brush();
- QColor clr;
- clr.setRgbF(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha);
- currentBrush.setColor(clr);
- p->setBrush(currentBrush);
-#endif
+ case GrayLevel:
+ // We're only supporting 255 levels of gray here. Since this isn't
+ // even part of HTML5, I don't expect anyone will care. If they do
+ // we'll make a fancier Color abstraction.
+ context->setFillColor(Color(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha));
break;
- }
- case RGBA: {
- // FIXME: Do this through platform-independent GraphicsContext API.
-#if PLATFORM(CG)
- CGContextSetRGBFillColor(context->platformContext(), m_red, m_green, m_blue, m_alpha);
-#elif defined(ANDROID_CANVAS_IMPL)
- context->setFillColor(Color(F2B(m_red), F2B(m_green), F2B(m_blue), F2B(m_alpha)));
-#elif PLATFORM(QT)
- QBrush currentBrush = p->brush();
- QColor clr;
- clr.setRgbF(m_red, m_green, m_blue, m_alpha);
- currentBrush.setColor(clr);
- p->setBrush(currentBrush);
-#endif
+ case RGBA:
+ context->setFillColor(Color(m_red, m_green, m_blue, m_alpha));
break;
- }
case CMYKA: {
// FIXME: Do this through platform-independent GraphicsContext API.
+ // We'll need a fancier Color abstraction to support CYMKA correctly
#if PLATFORM(CG)
CGContextSetCMYKFillColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha);
#elif PLATFORM(QT)
- QBrush currentBrush = p->brush();
+ QBrush currentBrush = context->platformContext()->brush();
QColor clr;
clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
currentBrush.setColor(clr);
- p->setBrush(currentBrush);
+ context->platformContext()->setBrush(currentBrush);
+#elif PLATFORM(SGL)
+ context->setCMYKAFillColor(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
#endif
break;
}
case Gradient:
+ context->setFillGradient(canvasGradient()->gradient());
+ break;
case ImagePattern:
+ context->setFillPattern(canvasPattern()->pattern());
break;
}
}
-#endif
}
diff --git a/WebCore/html/CanvasStyle.h b/WebCore/html/CanvasStyle.h
index b98e79a..fe01bd1 100644
--- a/WebCore/html/CanvasStyle.h
+++ b/WebCore/html/CanvasStyle.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,6 +36,23 @@ namespace WebCore {
class CanvasStyle : public RefCounted<CanvasStyle> {
public:
+ static PassRefPtr<CanvasStyle> create(const String& color) { return adoptRef(new CanvasStyle(color)); }
+ static PassRefPtr<CanvasStyle> create(float grayLevel) { return adoptRef(new CanvasStyle(grayLevel)); }
+ static PassRefPtr<CanvasStyle> create(const String& color, float alpha) { return adoptRef(new CanvasStyle(color, alpha)); }
+ static PassRefPtr<CanvasStyle> create(float grayLevel, float alpha) { return adoptRef(new CanvasStyle(grayLevel, alpha)); }
+ static PassRefPtr<CanvasStyle> create(float r, float g, float b, float a) { return adoptRef(new CanvasStyle(r, g, b, a)); }
+ static PassRefPtr<CanvasStyle> create(float c, float m, float y, float k, float a) { return adoptRef(new CanvasStyle(c, m, y, k, a)); }
+ static PassRefPtr<CanvasStyle> create(PassRefPtr<CanvasGradient> gradient) { return adoptRef(new CanvasStyle(gradient)); }
+ static PassRefPtr<CanvasStyle> create(PassRefPtr<CanvasPattern> pattern) { return adoptRef(new CanvasStyle(pattern)); }
+
+ String color() const { return m_color; }
+ CanvasGradient* canvasGradient() const { return m_gradient.get(); }
+ CanvasPattern* canvasPattern() const { return m_pattern.get(); }
+
+ void applyFillColor(GraphicsContext*);
+ void applyStrokeColor(GraphicsContext*);
+
+ private:
CanvasStyle(const String& color);
CanvasStyle(float grayLevel);
CanvasStyle(const String& color, float alpha);
@@ -45,17 +62,6 @@ namespace WebCore {
CanvasStyle(PassRefPtr<CanvasGradient>);
CanvasStyle(PassRefPtr<CanvasPattern>);
- String color() const { return m_color; }
- CanvasGradient* gradient() const { return m_gradient.get(); }
- CanvasPattern* pattern() const { return m_pattern.get(); }
-
- // These do nothing for gradients or patterns.
-#if !PLATFORM(CAIRO)
- void applyFillColor(GraphicsContext*);
-#endif
- void applyStrokeColor(GraphicsContext*);
-
- private:
enum Type { ColorString, ColorStringWithAlpha, GrayLevel, RGBA, CMYKA, Gradient, ImagePattern };
Type m_type;
diff --git a/WebCore/html/File.cpp b/WebCore/html/File.cpp
new file mode 100644
index 0000000..dbbbfa6
--- /dev/null
+++ b/WebCore/html/File.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 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 INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "File.h"
+
+#include "FileSystem.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+File::File(const String& path)
+ : m_path(path)
+ , m_fileName(pathGetFileName(path))
+{
+}
+
+unsigned long long File::fileSize()
+{
+ // FIXME: Should we cache this?
+ // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to
+ // come up with an exception to throw if file size is not represetable.
+ long long size;
+ if (!getFileSize(m_path, size))
+ return 0;
+ return size;
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/File.h b/WebCore/html/File.h
new file mode 100644
index 0000000..7d79aa5
--- /dev/null
+++ b/WebCore/html/File.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 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 INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef File_h
+#define File_h
+
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class File : public RefCounted<File> {
+ public:
+ static PassRefPtr<File> create(const String& path)
+ {
+ return adoptRef(new File(path));
+ }
+
+ const String& fileName() const { return m_fileName; }
+ unsigned long long fileSize();
+
+ const String& path() const { return m_path; }
+
+ private:
+ File(const String& path);
+
+ String m_path;
+ String m_fileName;
+ };
+
+} // namespace WebCore
+
+#endif // FileList_h
diff --git a/WebCore/html/File.idl b/WebCore/html/File.idl
new file mode 100644
index 0000000..ada9f0c
--- /dev/null
+++ b/WebCore/html/File.idl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 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 INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ GenerateConstructor
+ ] File {
+ readonly attribute DOMString fileName;
+ readonly attribute unsigned long long fileSize;
+ };
+
+}
diff --git a/WebCore/html/FileList.cpp b/WebCore/html/FileList.cpp
new file mode 100644
index 0000000..ba81087
--- /dev/null
+++ b/WebCore/html/FileList.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 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 INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FileList.h"
+
+#include "File.h"
+
+namespace WebCore {
+
+FileList::FileList()
+{
+}
+
+File* FileList::item(unsigned index) const
+{
+ if (index >= m_files.size())
+ return 0;
+ return m_files[index].get();
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/FileList.h b/WebCore/html/FileList.h
new file mode 100644
index 0000000..e078191
--- /dev/null
+++ b/WebCore/html/FileList.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 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 INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FileList_h
+#define FileList_h
+
+#include "File.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class FileList : public RefCounted<FileList> {
+ public:
+ static PassRefPtr<FileList> create()
+ {
+ return adoptRef(new FileList);
+ }
+
+ unsigned length() const { return m_files.size(); }
+ File* item(unsigned index) const;
+
+ bool isEmpty() const { return m_files.isEmpty(); }
+ void clear() { m_files.clear(); }
+ void append(PassRefPtr<File> file) { m_files.append(file); }
+
+ private:
+ FileList();
+
+ Vector<RefPtr<File> > m_files;
+ };
+
+} // namespace WebCore
+
+#endif // FileList_h
diff --git a/WebCore/html/FileList.idl b/WebCore/html/FileList.idl
new file mode 100644
index 0000000..01c286e
--- /dev/null
+++ b/WebCore/html/FileList.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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 INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ GenerateConstructor,
+ HasIndexGetter
+ ] FileList {
+ readonly attribute unsigned long length;
+ File item(in [IsIndex] unsigned long index);
+ };
+
+}
diff --git a/WebCore/html/FormDataList.cpp b/WebCore/html/FormDataList.cpp
index 8698666..281c9fe 100644
--- a/WebCore/html/FormDataList.cpp
+++ b/WebCore/html/FormDataList.cpp
@@ -1,11 +1,5 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
- * 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 Apple Computer, Inc.
- * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ * Copyright (C) 2005, 2006, 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
@@ -40,11 +34,11 @@ void FormDataList::appendString(const CString& s)
}
// Change plain CR and plain LF to CRLF pairs.
-static CString fixLineBreaks(const CString &s)
+static CString fixLineBreaks(const CString& s)
{
// Compute the length.
unsigned newLen = 0;
- const char *p = s.data();
+ const char* p = s.data();
while (char c = *p++) {
if (c == '\r') {
// Safe to look ahead because of trailing '\0'.
@@ -66,7 +60,7 @@ static CString fixLineBreaks(const CString &s)
// Make a copy of the string.
p = s.data();
- char *q;
+ char* q;
CString result = CString::newUninitialized(newLen, q);
while (char c = *p++) {
if (c == '\r') {
@@ -90,14 +84,8 @@ static CString fixLineBreaks(const CString &s)
void FormDataList::appendString(const String& s)
{
- CString cstr = fixLineBreaks(m_encoding.encode(s.characters(), s.length(), true));
+ CString cstr = fixLineBreaks(m_encoding.encode(s.characters(), s.length(), EntitiesForUnencodables));
m_list.append(cstr);
}
-void FormDataList::appendFile(const String& key, const String& filename)
-{
- appendString(key);
- m_list.append(filename);
-}
-
} // namespace
diff --git a/WebCore/html/FormDataList.h b/WebCore/html/FormDataList.h
index cdff8f7..aec1a52 100644
--- a/WebCore/html/FormDataList.h
+++ b/WebCore/html/FormDataList.h
@@ -1,11 +1,5 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
- * 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 Apple Computer, Inc.
- * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ * Copyright (C) 2005, 2006, 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
@@ -28,21 +22,11 @@
#define FormDataList_h
#include "CString.h"
-#include "PlatformString.h"
+#include "File.h"
#include "TextEncoding.h"
-#include <wtf/Vector.h>
namespace WebCore {
-struct FormDataListItem {
- FormDataListItem() { }
- FormDataListItem(const CString& data) : m_data(data) { }
- FormDataListItem(const String& path) : m_path(path) { }
-
- String m_path;
- CString m_data;
-};
-
class FormDataList {
public:
FormDataList(const TextEncoding&);
@@ -53,16 +37,31 @@ public:
{ appendString(key); appendString(value); }
void appendData(const String& key, int value)
{ appendString(key); appendString(String::number(value)); }
- void appendFile(const String& key, const String& filename);
+ void appendFile(const String& key, PassRefPtr<File> file)
+ { appendString(key); m_list.append(file); }
+
+ class Item {
+ public:
+ Item() { }
+ Item(const CString& data) : m_data(data) { }
+ Item(PassRefPtr<File> file) : m_file(file) { }
+
+ const CString& data() const { return m_data; }
+ File* file() const { return m_file.get(); }
+
+ private:
+ CString m_data;
+ RefPtr<File> m_file;
+ };
- const Vector<FormDataListItem>& list() const { return m_list; }
+ const Vector<Item>& list() const { return m_list; }
private:
void appendString(const CString&);
void appendString(const String&);
TextEncoding m_encoding;
- Vector<FormDataListItem> m_list;
+ Vector<Item> m_list;
};
} // namespace WebCore
diff --git a/WebCore/html/HTMLAnchorElement.cpp b/WebCore/html/HTMLAnchorElement.cpp
index 5daf2a0..0e09b5d 100644
--- a/WebCore/html/HTMLAnchorElement.cpp
+++ b/WebCore/html/HTMLAnchorElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
* (C) 2006 Graham Dennis (graham.dennis@gmail.com)
*
* This library is free software; you can redistribute it and/or
@@ -25,12 +25,14 @@
#include "HTMLAnchorElement.h"
#include "CSSHelper.h"
+#include "DNS.h"
#include "Document.h"
#include "Event.h"
#include "EventHandler.h"
#include "EventNames.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "KeyboardEvent.h"
@@ -46,7 +48,6 @@
namespace WebCore {
using namespace HTMLNames;
-using namespace EventNames;
HTMLAnchorElement::HTMLAnchorElement(Document* doc)
: HTMLElement(aTag, doc)
@@ -70,7 +71,7 @@ bool HTMLAnchorElement::supportsFocus() const
{
if (isContentEditable())
return HTMLElement::supportsFocus();
- return isFocusable() || (m_isLink && document() && !document()->haveStylesheetsLoaded());
+ return isFocusable() || (isLink() && document() && !document()->haveStylesheetsLoaded());
}
bool HTMLAnchorElement::isFocusable() const
@@ -80,7 +81,30 @@ bool HTMLAnchorElement::isFocusable() const
// FIXME: Even if we are not visible, we might have a child that is visible.
// Dave wants to fix that some day with a "has visible content" flag or the like.
- if (!(m_isLink && renderer() && renderer()->style()->visibility() == VISIBLE))
+ if (!(isLink() && renderer() && renderer()->style()->visibility() == VISIBLE))
+ return false;
+
+ return true;
+}
+
+bool HTMLAnchorElement::isMouseFocusable() const
+{
+#if PLATFORM(GTK)
+ return HTMLElement::isMouseFocusable();
+#else
+ return false;
+#endif
+}
+
+bool HTMLAnchorElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+ if (!isFocusable())
+ return false;
+
+ if (!document()->frame())
+ return false;
+
+ if (!document()->frame()->eventHandler()->tabsToLinks(event))
return false;
// Before calling absoluteRects, check for the common case where the renderer
@@ -102,34 +126,18 @@ bool HTMLAnchorElement::isFocusable() const
return false;
}
-bool HTMLAnchorElement::isMouseFocusable() const
-{
- return false;
-}
-
-bool HTMLAnchorElement::isKeyboardFocusable(KeyboardEvent* event) const
-{
- if (!isFocusable())
- return false;
-
- if (!document()->frame())
- return false;
-
- return document()->frame()->eventHandler()->tabsToLinks(event);
-}
-
void HTMLAnchorElement::defaultEventHandler(Event* evt)
{
// React on clicks and on keypresses.
// Don't make this KEYUP_EVENT again, it makes khtml follow links it shouldn't,
// when pressing Enter in the combo.
- if (m_isLink && (evt->type() == clickEvent || (evt->type() == keydownEvent && m_focused))) {
+ if (isLink() && (evt->type() == eventNames().clickEvent || (evt->type() == eventNames().keydownEvent && focused()))) {
MouseEvent* e = 0;
- if (evt->type() == clickEvent && evt->isMouseEvent())
+ if (evt->type() == eventNames().clickEvent && evt->isMouseEvent())
e = static_cast<MouseEvent*>(evt);
KeyboardEvent* k = 0;
- if (evt->type() == keydownEvent && evt->isKeyboardEvent())
+ if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent())
k = static_cast<KeyboardEvent*>(evt);
if (e && e->button() == RightButton) {
@@ -197,9 +205,9 @@ void HTMLAnchorElement::defaultEventHandler(Event* evt)
int x = e->pageX() - absx;
int y = e->pageY() - absy;
url += "?";
- url += DeprecatedString::number(x);
+ url += String::number(x);
url += ",";
- url += DeprecatedString::number(y);
+ url += String::number(y);
} else {
evt->setDefaultHandled();
HTMLElement::defaultEventHandler(evt);
@@ -212,17 +220,17 @@ void HTMLAnchorElement::defaultEventHandler(Event* evt)
document()->frame()->loader()->urlSelected(document()->completeURL(url), getAttribute(targetAttr), evt, false, true);
evt->setDefaultHandled();
- } else if (m_isLink && isContentEditable()) {
- // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
- // for the LiveWhenNotFocused editable link behavior
- if (evt->type() == mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() != RightButton && document()->frame() && document()->frame()->selectionController()) {
+ } else if (isLink() && isContentEditable()) {
+ // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
+ // for the LiveWhenNotFocused editable link behavior
+ if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() != RightButton && document()->frame() && document()->frame()->selection()) {
MouseEvent* e = static_cast<MouseEvent*>(evt);
- m_rootEditableElementForSelectionOnMouseDown = document()->frame()->selectionController()->rootEditableElement();
+ m_rootEditableElementForSelectionOnMouseDown = document()->frame()->selection()->rootEditableElement();
m_wasShiftKeyDownOnMouseDown = e && e->shiftKey();
- } else if (evt->type() == mouseoverEvent) {
- // These are cleared on mouseover and not mouseout because their values are needed for drag events, but these happen
- // after mouse out events.
+ } else if (evt->type() == eventNames().mouseoverEvent) {
+ // These are cleared on mouseover and not mouseout because their values are needed for drag events, but these happen
+ // after mouse out events.
m_rootEditableElementForSelectionOnMouseDown = 0;
m_wasShiftKeyDownOnMouseDown = false;
}
@@ -250,8 +258,8 @@ void HTMLAnchorElement::setActive(bool down, bool pause)
// Don't set the link to be active if the current selection is in the same editable block as
// this link
case EditableLinkLiveWhenNotFocused:
- if (down && document()->frame() && document()->frame()->selectionController() &&
- document()->frame()->selectionController()->rootEditableElement() == rootEditableElement())
+ if (down && document()->frame() && document()->frame()->selection() &&
+ document()->frame()->selection()->rootEditableElement() == rootEditableElement())
return;
break;
@@ -267,10 +275,15 @@ void HTMLAnchorElement::setActive(bool down, bool pause)
void HTMLAnchorElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == hrefAttr) {
- bool wasLink = m_isLink;
- m_isLink = !attr->isNull();
- if (wasLink != m_isLink)
+ 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());
+ }
} else if (attr->name() == nameAttr ||
attr->name() == titleAttr ||
attr->name() == relAttr) {
@@ -328,7 +341,7 @@ void HTMLAnchorElement::setCoords(const String &value)
setAttribute(coordsAttr, value);
}
-String HTMLAnchorElement::href() const
+KURL HTMLAnchorElement::href() const
{
return document()->completeURL(getAttribute(hrefAttr));
}
@@ -388,9 +401,10 @@ void HTMLAnchorElement::setShape(const String &value)
setAttribute(shapeAttr, value);
}
-void HTMLAnchorElement::setTabIndex(int tabIndex)
+short HTMLAnchorElement::tabIndex() const
{
- setAttribute(tabindexAttr, String::number(tabIndex));
+ // Skip the supportsFocus check in HTMLElement.
+ return Element::tabIndex();
}
String HTMLAnchorElement::target() const
@@ -415,41 +429,40 @@ void HTMLAnchorElement::setType(const String &value)
String HTMLAnchorElement::hash() const
{
- return '#' + KURL(href().deprecatedString()).ref();
+ return "#" + href().ref();
}
String HTMLAnchorElement::host() const
{
- return KURL(href().deprecatedString()).host();
+ return href().host();
}
String HTMLAnchorElement::hostname() const
{
- KURL url(href().deprecatedString());
- if (url.port()==0)
+ const KURL& url = href();
+ if (url.port() == 0)
return url.host();
- else
- return url.host() + ":" + String::number(url.port());
+ return url.host() + ":" + String::number(url.port());
}
String HTMLAnchorElement::pathname() const
{
- return KURL(href().deprecatedString()).path();
+ return href().path();
}
String HTMLAnchorElement::port() const
{
- return DeprecatedString::number(KURL(href().deprecatedString()).port());
+ return String::number(href().port());
}
String HTMLAnchorElement::protocol() const
{
- return KURL(href().deprecatedString()).protocol() + ":";
+ return href().protocol() + ":";
}
String HTMLAnchorElement::search() const
{
- return KURL(href().deprecatedString()).query();
+ return href().query();
}
String HTMLAnchorElement::text() const
@@ -459,12 +472,12 @@ String HTMLAnchorElement::text() const
String HTMLAnchorElement::toString() const
{
- return href();
+ return href().string();
}
bool HTMLAnchorElement::isLiveLink() const
{
- if (!m_isLink)
+ if (!isLink())
return false;
if (!isContentEditable())
return true;
diff --git a/WebCore/html/HTMLAnchorElement.h b/WebCore/html/HTMLAnchorElement.h
index 98e37e0..2457acb 100644
--- a/WebCore/html/HTMLAnchorElement.h
+++ b/WebCore/html/HTMLAnchorElement.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,8 +28,6 @@
namespace WebCore {
-class String;
-
class HTMLAnchorElement : public HTMLElement {
public:
HTMLAnchorElement(Document*);
@@ -60,7 +58,7 @@ public:
String coords() const;
void setCoords(const String&);
- String href() const;
+ KURL href() const;
void setHref(const String&);
String hreflang() const;
@@ -78,7 +76,7 @@ public:
String shape() const;
void setShape(const String&);
- void setTabIndex(int);
+ virtual short tabIndex() const;
virtual String target() const;
void setTarget(const String&);
diff --git a/WebCore/html/HTMLAnchorElement.idl b/WebCore/html/HTMLAnchorElement.idl
index c7789ab..f3a15ee 100644
--- a/WebCore/html/HTMLAnchorElement.idl
+++ b/WebCore/html/HTMLAnchorElement.idl
@@ -34,13 +34,9 @@ module html {
attribute [ConvertNullToNullString] DOMString rel;
attribute [ConvertNullToNullString] DOMString rev;
attribute [ConvertNullToNullString] DOMString shape;
- attribute long tabIndex;
attribute [ConvertNullToNullString] DOMString target;
attribute [ConvertNullToNullString] DOMString type;
- void blur();
- void focus();
-
// IE Extensions
readonly attribute DOMString hash;
readonly attribute DOMString host;
diff --git a/WebCore/html/HTMLAppletElement.cpp b/WebCore/html/HTMLAppletElement.cpp
index d5100d1..d637ce0 100644
--- a/WebCore/html/HTMLAppletElement.cpp
+++ b/WebCore/html/HTMLAppletElement.cpp
@@ -1,11 +1,9 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,6 +20,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLAppletElement.h"
@@ -31,13 +30,14 @@
#include "RenderApplet.h"
#include "RenderInline.h"
#include "Settings.h"
+#include "ScriptController.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLAppletElement::HTMLAppletElement(Document *doc)
-: HTMLPlugInElement(appletTag, doc)
+HTMLAppletElement::HTMLAppletElement(Document* doc)
+ : HTMLPlugInElement(appletTag, doc)
{
}
@@ -45,21 +45,16 @@ HTMLAppletElement::~HTMLAppletElement()
{
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure the m_name and m_id are removed from HTMLDocument's NameCountMap
if (oldNameIdCount && document()->isHTMLDocument()) {
HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->removeDocExtraNamedItem(oldIdAttr);
+ doc->removeNamedItem(m_name);
+ doc->removeExtraNamedItem(m_id);
}
#endif
-
-#if USE(JAVASCRIPTCORE_BINDINGS)
- // m_instance should have been cleaned up in detach().
- ASSERT(!m_instance);
-#endif
}
-void HTMLAppletElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLAppletElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == altAttr ||
attr->name() == archiveAttr ||
@@ -69,21 +64,21 @@ void HTMLAppletElement::parseMappedAttribute(MappedAttribute *attr)
attr->name() == objectAttr) {
// Do nothing.
} else if (attr->name() == nameAttr) {
- String newNameAttr = attr->value();
+ const AtomicString& newName = attr->value();
if (inDocument() && document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->addNamedItem(newNameAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(newName);
}
- oldNameAttr = newNameAttr;
+ m_name = newName;
} else if (attr->name() == idAttr) {
- String newIdAttr = attr->value();
+ const AtomicString& newId = attr->value();
if (inDocument() && document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeDocExtraNamedItem(oldIdAttr);
- doc->addDocExtraNamedItem(newIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeExtraNamedItem(m_id);
+ document->addExtraNamedItem(newId);
}
- oldIdAttr = newIdAttr;
+ m_id = newId;
// also call superclass
HTMLPlugInElement::parseMappedAttribute(attr);
} else
@@ -93,12 +88,12 @@ void HTMLAppletElement::parseMappedAttribute(MappedAttribute *attr)
void HTMLAppletElement::insertedIntoDocument()
{
if (document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->addNamedItem(oldNameAttr);
- doc->addDocExtraNamedItem(oldIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->addNamedItem(m_name);
+ document->addExtraNamedItem(m_id);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure the m_name and m_id are removed from HTMLDocument's NameCountMap
oldNameIdCount++;
#endif
}
@@ -109,12 +104,12 @@ void HTMLAppletElement::insertedIntoDocument()
void HTMLAppletElement::removedFromDocument()
{
if (document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->removeDocExtraNamedItem(oldIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->removeExtraNamedItem(m_id);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure the m_name and m_id are removed from HTMLDocument's NameCountMap
oldNameIdCount--;
#endif
}
@@ -122,12 +117,12 @@ void HTMLAppletElement::removedFromDocument()
HTMLPlugInElement::removedFromDocument();
}
-bool HTMLAppletElement::rendererIsNeeded(RenderStyle *style)
+bool HTMLAppletElement::rendererIsNeeded(RenderStyle* style)
{
return !getAttribute(codeAttr).isNull();
}
-RenderObject *HTMLAppletElement::createRenderer(RenderArena *arena, RenderStyle *style)
+RenderObject* HTMLAppletElement::createRenderer(RenderArena* arena, RenderStyle* style)
{
Settings* settings = document()->settings();
@@ -138,14 +133,14 @@ RenderObject *HTMLAppletElement::createRenderer(RenderArena *arena, RenderStyle
const AtomicString& codeBase = getAttribute(codebaseAttr);
if(!codeBase.isNull())
args.set("codeBase", codeBase);
- const AtomicString& name = getAttribute(document()->htmlMode() != Document::XHtml ? nameAttr : idAttr);
+ const AtomicString& name = getAttribute(document()->isHTMLDocument() ? nameAttr : idAttr);
if (!name.isNull())
args.set("name", name);
const AtomicString& archive = getAttribute(archiveAttr);
if (!archive.isNull())
args.set("archive", archive);
- args.set("baseURL", document()->baseURL());
+ args.set("baseURL", document()->baseURL().string());
const AtomicString& mayScript = getAttribute(mayscriptAttr);
if (!mayScript.isNull())
@@ -159,24 +154,18 @@ RenderObject *HTMLAppletElement::createRenderer(RenderArena *arena, RenderStyle
return RenderObject::createObject(this, style);
}
-#if USE(JAVASCRIPTCORE_BINDINGS)
-KJS::Bindings::Instance *HTMLAppletElement::getInstance() const
+RenderWidget* HTMLAppletElement::renderWidgetForJSBindings() const
{
Settings* settings = document()->settings();
if (!settings || !settings->isJavaEnabled())
return 0;
- if (m_instance)
- return m_instance.get();
-
- if (RenderApplet* r = static_cast<RenderApplet*>(renderer())) {
- r->createWidgetIfNecessary();
- if (r->widget() && document()->frame())
- m_instance = document()->frame()->createScriptInstanceForWidget(r->widget());
- }
- return m_instance.get();
+ RenderApplet* applet = static_cast<RenderApplet*>(renderer());
+ if (applet)
+ applet->createWidgetIfNecessary();
+
+ return applet;
}
-#endif
void HTMLAppletElement::finishParsingChildren()
{
@@ -186,14 +175,6 @@ void HTMLAppletElement::finishParsingChildren()
renderer()->setNeedsLayout(true); // This will cause it to create its widget & the Java applet
}
-void HTMLAppletElement::detach()
-{
-#if USE(JAVASCRIPTCORE_BINDINGS)
- m_instance = 0;
-#endif
- HTMLPlugInElement::detach();
-}
-
String HTMLAppletElement::alt() const
{
return getAttribute(altAttr);
diff --git a/WebCore/html/HTMLAppletElement.h b/WebCore/html/HTMLAppletElement.h
index 5025277..6c23170 100644
--- a/WebCore/html/HTMLAppletElement.h
+++ b/WebCore/html/HTMLAppletElement.h
@@ -1,9 +1,7 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 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
@@ -27,12 +25,6 @@
#include "HTMLPlugInElement.h"
-#if USE(JAVASCRIPTCORE_BINDINGS)
-#include <bindings/runtime.h>
-#else
-namespace KJS { namespace Bindings { class Instance; } }
-#endif
-
namespace WebCore {
class HTMLFormElement;
@@ -51,11 +43,8 @@ public:
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual void finishParsingChildren();
- virtual void detach();
-#if USE(JAVASCRIPTCORE_BINDINGS)
- virtual KJS::Bindings::Instance* getInstance() const;
-#endif
+ virtual RenderWidget* renderWidgetForJSBindings() const;
String alt() const;
void setAlt(const String&);
@@ -84,7 +73,7 @@ public:
virtual void removedFromDocument();
private:
- String oldIdAttr;
+ AtomicString m_id;
};
}
diff --git a/WebCore/html/HTMLAreaElement.cpp b/WebCore/html/HTMLAreaElement.cpp
index 09e1e30..7c6d65f 100644
--- a/WebCore/html/HTMLAreaElement.cpp
+++ b/WebCore/html/HTMLAreaElement.cpp
@@ -1,6 +1,4 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
@@ -20,13 +18,15 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLAreaElement.h"
#include "Document.h"
-#include "HTMLNames.h"
#include "FloatRect.h"
+#include "HTMLNames.h"
#include "HitTestResult.h"
+#include "Length.h"
#include "RenderObject.h"
#ifdef ANDROID_NAVIGATE_AREAMAPS
@@ -69,7 +69,7 @@ void HTMLAreaElement::parseMappedAttribute(MappedAttribute *attr)
m_shape = Rect;
} else if (attr->name() == coordsAttr) {
delete [] m_coords;
- m_coords = attr->value().toCoordsArray(m_coordsLen);
+ m_coords = newCoordsArray(attr->value().string(), m_coordsLen);
} else if (attr->name() == altAttr || attr->name() == accesskeyAttr) {
// Do nothing.
} else
@@ -186,7 +186,7 @@ void HTMLAreaElement::setCoords(const String& value)
setAttribute(coordsAttr, value);
}
-String HTMLAreaElement::href() const
+KURL HTMLAreaElement::href() const
{
return document()->completeURL(getAttribute(hrefAttr));
}
@@ -216,9 +216,9 @@ void HTMLAreaElement::setShape(const String& value)
setAttribute(shapeAttr, value);
}
-void HTMLAreaElement::setTabIndex(int tabIndex)
+bool HTMLAreaElement::isFocusable() const
{
- setAttribute(tabindexAttr, String::number(tabIndex));
+ return HTMLElement::isFocusable();
}
String HTMLAreaElement::target() const
diff --git a/WebCore/html/HTMLAreaElement.h b/WebCore/html/HTMLAreaElement.h
index 98e10f5..2cce901 100644
--- a/WebCore/html/HTMLAreaElement.h
+++ b/WebCore/html/HTMLAreaElement.h
@@ -1,9 +1,7 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004 Apple Computer, Inc.
+ * Copyright (C) 2004, 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
@@ -43,8 +41,6 @@ class HitTestResult;
class HTMLAreaElement : public HTMLAnchorElement {
public:
- enum Shape { Default, Poly, Rect, Circle, Unknown };
-
HTMLAreaElement(Document*);
~HTMLAreaElement();
@@ -68,7 +64,7 @@ public:
String coords() const;
void setCoords(const String&);
- String href() const;
+ KURL href() const;
void setHref(const String&);
bool noHref() const;
@@ -77,7 +73,7 @@ public:
String shape() const;
void setShape(const String&);
- void setTabIndex(int);
+ virtual bool isFocusable() const;
virtual String target() const;
void setTarget(const String&);
@@ -87,7 +83,8 @@ public:
void setMap(RenderImage* map) { m_map = map; }
#endif
-protected:
+private:
+ enum Shape { Default, Poly, Rect, Circle, Unknown };
Path getRegion(const IntSize&) const;
Path region;
Length* m_coords;
diff --git a/WebCore/html/HTMLAreaElement.idl b/WebCore/html/HTMLAreaElement.idl
index 7effb98..39cc719 100644
--- a/WebCore/html/HTMLAreaElement.idl
+++ b/WebCore/html/HTMLAreaElement.idl
@@ -31,7 +31,6 @@ module html {
attribute [ConvertNullToNullString] DOMString href;
attribute boolean noHref;
attribute [ConvertNullToNullString] DOMString shape;
- attribute long tabIndex;
attribute [ConvertNullToNullString] DOMString target;
// IE Extensions
diff --git a/WebCore/html/HTMLAttributeNames.in b/WebCore/html/HTMLAttributeNames.in
index a949640..3b70aee 100644
--- a/WebCore/html/HTMLAttributeNames.in
+++ b/WebCore/html/HTMLAttributeNames.in
@@ -1,3 +1,8 @@
+namespace="HTML"
+namespacePrefix="xhtml"
+namespaceURI="http://www.w3.org/1999/xhtml"
+attrsNullNamespace="1"
+
abbr
accept_charset
accept
@@ -7,7 +12,18 @@ align
alink
alt
archive
+aria-activedescendant
+aria-checked
+aria-describedby
+aria-labeledby
+aria-labelledby
+aria-level
+aria-pressed
+aria-valuemax
+aria-valuemin
+aria-valuenow
autocomplete
+autofocus
autoplay
autosave
axis
@@ -26,7 +42,7 @@ charset
checked
cellborder
cite
-class
+class exportString="1"
classid
clear
code
@@ -77,6 +93,7 @@ playcount
loopend
loopstart
lowsrc
+manifest
marginheight
marginwidth
max
@@ -131,8 +148,19 @@ onscroll
onsearch
onselect
onselectstart
+onstorage
onsubmit
+/* #if ENABLE(TOUCH_EVENTS) // Android */
+ontouchstart
+ontouchmove
+ontouchend
+ontouchcancel
+/* #endif */
onunload
+onwebkitanimationstart
+onwebkitanimationiteration
+onwebkitanimationend
+onwebkittransitionend
pagex
pagey
placeholder
@@ -148,6 +176,7 @@ readonly
rel
results
rev
+role
rows
rowspan
rules
diff --git a/WebCore/html/HTMLBRElement.cpp b/WebCore/html/HTMLBRElement.cpp
index 44bdf59..75ee30c 100644
--- a/WebCore/html/HTMLBRElement.cpp
+++ b/WebCore/html/HTMLBRElement.cpp
@@ -58,9 +58,9 @@ void HTMLBRElement::parseMappedAttribute(MappedAttribute *attr)
const AtomicString& str = attr->value();
if (!str.isEmpty()) {
if (equalIgnoringCase(str, "all"))
- addCSSProperty(attr, CSS_PROP_CLEAR, "both");
+ addCSSProperty(attr, CSSPropertyClear, "both");
else
- addCSSProperty(attr, CSS_PROP_CLEAR, str);
+ addCSSProperty(attr, CSSPropertyClear, str);
}
} else
HTMLElement::parseMappedAttribute(attr);
diff --git a/WebCore/html/HTMLBaseElement.cpp b/WebCore/html/HTMLBaseElement.cpp
index 7a94c7b..4de62f9 100644
--- a/WebCore/html/HTMLBaseElement.cpp
+++ b/WebCore/html/HTMLBaseElement.cpp
@@ -1,10 +1,8 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 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
@@ -36,7 +34,7 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLBaseElement::HTMLBaseElement(Document *doc)
+HTMLBaseElement::HTMLBaseElement(Document* doc)
: HTMLElement(baseTag, doc)
{
}
@@ -45,7 +43,7 @@ HTMLBaseElement::~HTMLBaseElement()
{
}
-void HTMLBaseElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLBaseElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == hrefAttr) {
m_href = parseURL(attr->value());
@@ -69,8 +67,8 @@ void HTMLBaseElement::removedFromDocument()
// Since the document doesn't have a base element...
// (This will break in the case of multiple base elements, but that's not valid anyway (?))
- document()->setBaseURL(DeprecatedString::null);
- document()->setBaseTarget(DeprecatedString::null);
+ document()->setBaseElementURL(KURL());
+ document()->setBaseElementTarget(String());
}
void HTMLBaseElement::process()
@@ -78,11 +76,11 @@ void HTMLBaseElement::process()
if (!inDocument())
return;
- if (!m_href.isEmpty() && document()->frame())
- document()->setBaseURL(KURL(document()->frame()->loader()->url(), m_href.deprecatedString()).deprecatedString());
+ if (!m_href.isEmpty())
+ document()->setBaseElementURL(KURL(document()->url(), m_href));
if (!m_target.isEmpty())
- document()->setBaseTarget(m_target);
+ document()->setBaseElementTarget(m_target);
// ### should changing a document's base URL dynamically automatically update all images, stylesheets etc?
}
diff --git a/WebCore/html/HTMLBodyElement.cpp b/WebCore/html/HTMLBodyElement.cpp
index 6231fc2..7dca064 100644
--- a/WebCore/html/HTMLBodyElement.cpp
+++ b/WebCore/html/HTMLBodyElement.cpp
@@ -1,9 +1,9 @@
-/**
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann (hausmann@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 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
@@ -38,7 +38,6 @@
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
HTMLBodyElement::HTMLBodyElement(Document* doc)
@@ -56,7 +55,7 @@ HTMLBodyElement::~HTMLBodyElement()
void HTMLBodyElement::createLinkDecl()
{
- m_linkDecl = new CSSMutableStyleDeclaration;
+ m_linkDecl = CSSMutableStyleDeclaration::create();
m_linkDecl->setParent(document()->elementSheet());
m_linkDecl->setNode(this);
m_linkDecl->setStrictParsing(!document()->inCompatMode());
@@ -88,20 +87,20 @@ void HTMLBodyElement::parseMappedAttribute(MappedAttribute *attr)
if (attr->name() == backgroundAttr) {
String url = parseURL(attr->value());
if (!url.isEmpty())
- addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, document()->completeURL(url));
+ addCSSImageProperty(attr, CSSPropertyBackgroundImage, document()->completeURL(url).string());
} else if (attr->name() == marginwidthAttr || attr->name() == leftmarginAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
} else if (attr->name() == marginheightAttr || attr->name() == topmarginAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
} else if (attr->name() == bgcolorAttr) {
- addCSSColor(attr, CSS_PROP_BACKGROUND_COLOR, attr->value());
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
} else if (attr->name() == textAttr) {
- addCSSColor(attr, CSS_PROP_COLOR, attr->value());
+ addCSSColor(attr, CSSPropertyColor, attr->value());
} else if (attr->name() == bgpropertiesAttr) {
if (equalIgnoringCase(attr->value(), "fixed"))
- addCSSProperty(attr, CSS_PROP_BACKGROUND_ATTACHMENT, CSS_VAL_FIXED);
+ addCSSProperty(attr, CSSPropertyBackgroundAttachment, CSSValueFixed);
} else if (attr->name() == vlinkAttr ||
attr->name() == alinkAttr ||
attr->name() == linkAttr) {
@@ -115,8 +114,8 @@ void HTMLBodyElement::parseMappedAttribute(MappedAttribute *attr)
} else {
if (!m_linkDecl)
createLinkDecl();
- m_linkDecl->setProperty(CSS_PROP_COLOR, attr->value(), false, false);
- RefPtr<CSSValue> val = m_linkDecl->getPropertyCSSValue(CSS_PROP_COLOR);
+ m_linkDecl->setProperty(CSSPropertyColor, attr->value(), false, false);
+ RefPtr<CSSValue> val = m_linkDecl->getPropertyCSSValue(CSSPropertyColor);
if (val && val->isPrimitiveValue()) {
Color col = document()->styleSelector()->getColorFromPrimitiveValue(static_cast<CSSPrimitiveValue*>(val.get()));
if (attr->name() == linkAttr)
@@ -130,20 +129,25 @@ void HTMLBodyElement::parseMappedAttribute(MappedAttribute *attr)
if (attached())
document()->recalcStyle(Force);
- } else if (attr->name() == onloadAttr) {
- document()->setHTMLWindowEventListener(loadEvent, attr);
- } else if (attr->name() == onbeforeunloadAttr) {
- document()->setHTMLWindowEventListener(beforeunloadEvent, attr);
- } else if (attr->name() == onunloadAttr) {
- document()->setHTMLWindowEventListener(unloadEvent, attr);
- } else if (attr->name() == onblurAttr) {
- document()->setHTMLWindowEventListener(blurEvent, attr);
- } else if (attr->name() == onfocusAttr) {
- document()->setHTMLWindowEventListener(focusEvent, attr);
- } else if (attr->name() == onresizeAttr) {
- document()->setHTMLWindowEventListener(resizeEvent, attr);
- } else if (attr->name() == onscrollAttr) {
- document()->setHTMLWindowEventListener(scrollEvent, attr);
+ } else if (attr->name() == onloadAttr)
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
+ else if (attr->name() == onbeforeunloadAttr)
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().beforeunloadEvent, attr);
+ else if (attr->name() == onunloadAttr)
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().unloadEvent, attr);
+ else if (attr->name() == onblurAttr)
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
+ else if (attr->name() == onfocusAttr)
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
+ else if (attr->name() == onresizeAttr)
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().resizeEvent, 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
HTMLElement::parseMappedAttribute(attr);
}
@@ -180,7 +184,7 @@ String HTMLBodyElement::aLink() const
return getAttribute(alinkAttr);
}
-void HTMLBodyElement::setALink(const String &value)
+void HTMLBodyElement::setALink(const String& value)
{
setAttribute(alinkAttr, value);
}
@@ -190,7 +194,7 @@ String HTMLBodyElement::background() const
return getAttribute(backgroundAttr);
}
-void HTMLBodyElement::setBackground(const String &value)
+void HTMLBodyElement::setBackground(const String& value)
{
setAttribute(backgroundAttr, value);
}
@@ -200,7 +204,7 @@ String HTMLBodyElement::bgColor() const
return getAttribute(bgcolorAttr);
}
-void HTMLBodyElement::setBgColor(const String &value)
+void HTMLBodyElement::setBgColor(const String& value)
{
setAttribute(bgcolorAttr, value);
}
@@ -210,7 +214,7 @@ String HTMLBodyElement::link() const
return getAttribute(linkAttr);
}
-void HTMLBodyElement::setLink(const String &value)
+void HTMLBodyElement::setLink(const String& value)
{
setAttribute(linkAttr, value);
}
@@ -220,7 +224,7 @@ String HTMLBodyElement::text() const
return getAttribute(textAttr);
}
-void HTMLBodyElement::setText(const String &value)
+void HTMLBodyElement::setText(const String& value)
{
setAttribute(textAttr, value);
}
@@ -230,7 +234,7 @@ String HTMLBodyElement::vLink() const
return getAttribute(vlinkAttr);
}
-void HTMLBodyElement::setVLink(const String &value)
+void HTMLBodyElement::setVLink(const String& value)
{
setAttribute(vlinkAttr, value);
}
@@ -241,8 +245,7 @@ int HTMLBodyElement::scrollLeft() const
Document* doc = document();
doc->updateLayoutIgnorePendingStylesheets();
FrameView* view = doc->view();
-
- return view ? view->contentsX() : 0;
+ return view ? view->scrollX() : 0;
}
void HTMLBodyElement::setScrollLeft(int scrollLeft)
@@ -251,7 +254,7 @@ void HTMLBodyElement::setScrollLeft(int scrollLeft)
if (sview) {
// Update the document's layout
document()->updateLayoutIgnorePendingStylesheets();
- sview->setContentsPos(scrollLeft, sview->contentsY());
+ sview->setScrollPosition(IntPoint(scrollLeft, sview->scrollY()));
}
}
@@ -261,8 +264,7 @@ int HTMLBodyElement::scrollTop() const
Document* doc = document();
doc->updateLayoutIgnorePendingStylesheets();
FrameView* view = doc->view();
-
- return view ? view->contentsY() : 0;
+ return view ? view->scrollY() : 0;
}
void HTMLBodyElement::setScrollTop(int scrollTop)
@@ -271,7 +273,7 @@ void HTMLBodyElement::setScrollTop(int scrollTop)
if (sview) {
// Update the document's layout
document()->updateLayoutIgnorePendingStylesheets();
- sview->setContentsPos(sview->contentsX(), scrollTop);
+ sview->setScrollPosition(IntPoint(sview->scrollX(), scrollTop));
}
}
@@ -281,7 +283,6 @@ int HTMLBodyElement::scrollHeight() const
Document* doc = document();
doc->updateLayoutIgnorePendingStylesheets();
FrameView* view = doc->view();
-
return view ? view->contentsHeight() : 0;
}
@@ -291,8 +292,12 @@ int HTMLBodyElement::scrollWidth() const
Document* doc = document();
doc->updateLayoutIgnorePendingStylesheets();
FrameView* view = doc->view();
-
return view ? view->contentsWidth() : 0;
}
+void HTMLBodyElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ urls.append(background());
+}
+
}
diff --git a/WebCore/html/HTMLBodyElement.h b/WebCore/html/HTMLBodyElement.h
index 6fe5b17..2c5ce98 100644
--- a/WebCore/html/HTMLBodyElement.h
+++ b/WebCore/html/HTMLBodyElement.h
@@ -70,6 +70,8 @@ public:
int scrollHeight() const;
int scrollWidth() const;
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
protected:
RefPtr<CSSMutableStyleDeclaration> m_linkDecl;
};
diff --git a/WebCore/html/HTMLButtonElement.cpp b/WebCore/html/HTMLButtonElement.cpp
index 6e57540..f65e748 100644
--- a/WebCore/html/HTMLButtonElement.cpp
+++ b/WebCore/html/HTMLButtonElement.cpp
@@ -35,11 +35,10 @@
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
HTMLButtonElement::HTMLButtonElement(Document* doc, HTMLFormElement* form)
- : HTMLGenericFormElement(buttonTag, doc, form)
+ : HTMLFormControlElement(buttonTag, doc, form)
, m_type(SUBMIT)
, m_activeSubmit(false)
{
@@ -56,32 +55,48 @@ RenderObject* HTMLButtonElement::createRenderer(RenderArena* arena, RenderStyle*
const AtomicString& HTMLButtonElement::type() const
{
- return getAttribute(typeAttr);
+ switch (m_type) {
+ case SUBMIT: {
+ static const AtomicString submit("submit");
+ return submit;
+ }
+ case BUTTON: {
+ static const AtomicString button("button");
+ return button;
+ }
+ case RESET: {
+ static const AtomicString reset("reset");
+ return reset;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
}
void HTMLButtonElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == typeAttr) {
- if (equalIgnoringCase(attr->value(), "submit"))
- m_type = SUBMIT;
- else if (equalIgnoringCase(attr->value(), "reset"))
+ if (equalIgnoringCase(attr->value(), "reset"))
m_type = RESET;
else if (equalIgnoringCase(attr->value(), "button"))
m_type = BUTTON;
+ else
+ m_type = SUBMIT;
} else if (attr->name() == alignAttr) {
// 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) {
- setHTMLEventListener(focusEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
} else if (attr->name() == onblurAttr) {
- setHTMLEventListener(blurEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
} else
- HTMLGenericFormElement::parseMappedAttribute(attr);
+ HTMLFormControlElement::parseMappedAttribute(attr);
}
void HTMLButtonElement::defaultEventHandler(Event* evt)
{
- if (evt->type() == DOMActivateEvent && !disabled()) {
+ if (evt->type() == eventNames().DOMActivateEvent && !disabled()) {
if (form() && m_type == SUBMIT) {
m_activeSubmit = true;
form()->prepareSubmit(evt);
@@ -92,12 +107,12 @@ void HTMLButtonElement::defaultEventHandler(Event* evt)
}
if (evt->isKeyboardEvent()) {
- if (evt->type() == keydownEvent && static_cast<KeyboardEvent*>(evt)->keyIdentifier() == "U+0020") {
+ if (evt->type() == eventNames().keydownEvent && static_cast<KeyboardEvent*>(evt)->keyIdentifier() == "U+0020") {
setActive(true, true);
// No setDefaultHandled() - IE dispatches a keypress in this case.
return;
}
- if (evt->type() == keypressEvent) {
+ if (evt->type() == eventNames().keypressEvent) {
switch (static_cast<KeyboardEvent*>(evt)->charCode()) {
case '\r':
dispatchSimulatedClick(evt);
@@ -111,7 +126,7 @@ void HTMLButtonElement::defaultEventHandler(Event* evt)
break;
}
}
- if (evt->type() == keyupEvent && static_cast<KeyboardEvent*>(evt)->keyIdentifier() == "U+0020") {
+ if (evt->type() == eventNames().keyupEvent && static_cast<KeyboardEvent*>(evt)->keyIdentifier() == "U+0020") {
if (active())
dispatchSimulatedClick(evt);
evt->setDefaultHandled();
@@ -119,7 +134,7 @@ void HTMLButtonElement::defaultEventHandler(Event* evt)
}
}
- HTMLGenericFormElement::defaultEventHandler(evt);
+ HTMLFormControlElement::defaultEventHandler(evt);
}
bool HTMLButtonElement::isSuccessfulSubmitButton() const
diff --git a/WebCore/html/HTMLButtonElement.h b/WebCore/html/HTMLButtonElement.h
index fc42b42..4d55ba5 100644
--- a/WebCore/html/HTMLButtonElement.h
+++ b/WebCore/html/HTMLButtonElement.h
@@ -24,11 +24,11 @@
#ifndef HTMLButtonElement_h
#define HTMLButtonElement_h
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
namespace WebCore {
-class HTMLButtonElement : public HTMLGenericFormElement {
+class HTMLButtonElement : public HTMLFormControlElement {
public:
HTMLButtonElement(Document*, HTMLFormElement* = 0);
virtual ~HTMLButtonElement();
@@ -56,6 +56,8 @@ public:
String value() const;
void setValue(const String&);
+
+ virtual bool willValidate() const { return false; }
private:
enum Type { SUBMIT, RESET, BUTTON };
diff --git a/WebCore/html/HTMLButtonElement.idl b/WebCore/html/HTMLButtonElement.idl
index be39119..028e92b 100644
--- a/WebCore/html/HTMLButtonElement.idl
+++ b/WebCore/html/HTMLButtonElement.idl
@@ -28,11 +28,11 @@ module html {
readonly attribute HTMLFormElement form;
attribute [ConvertNullToNullString] DOMString accessKey;
attribute boolean disabled;
+ attribute boolean autofocus;
attribute [ConvertNullToNullString] DOMString name;
- attribute long tabIndex;
readonly attribute DOMString type;
attribute [ConvertNullToNullString] DOMString value;
-
+ readonly attribute boolean willValidate;
void click();
};
diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp
index 8c3fc15..f3ca1fd 100644
--- a/WebCore/html/HTMLCanvasElement.cpp
+++ b/WebCore/html/HTMLCanvasElement.cpp
@@ -33,20 +33,18 @@
#include "CanvasStyle.h"
#include "Chrome.h"
#include "Document.h"
+#include "ExceptionCode.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "HTMLNames.h"
+#include "ImageBuffer.h"
+#include "MIMETypeRegistry.h"
#include "Page.h"
#include "RenderHTMLCanvas.h"
#include "Settings.h"
+#include <kjs/interpreter.h>
#include <math.h>
-
-#if PLATFORM(QT)
-#include <QPainter>
-#include <QPixmap>
-#elif PLATFORM(CAIRO)
-#include <cairo.h>
-#endif
+#include <stdio.h>
namespace WebCore {
@@ -59,38 +57,24 @@ static const int defaultHeight = 150;
// Firefox limits width/height to 32767 pixels, but slows down dramatically before it
// reaches that limit. We limit by area instead, giving us larger maximum dimensions,
// in exchange for a smaller maximum canvas size.
-static const float maxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
+const float HTMLCanvasElement::MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
HTMLCanvasElement::HTMLCanvasElement(Document* doc)
: HTMLElement(canvasTag, doc)
, m_size(defaultWidth, defaultHeight)
- , m_createdDrawingContext(false)
- , m_data(0)
-#if PLATFORM(QT)
- , m_painter(0)
-#elif PLATFORM(CAIRO)
- , m_surface(0)
-#endif
- , m_drawingContext(0)
+ , m_observer(0)
+ , m_originClean(true)
+ , m_ignoreReset(false)
+ , m_createdImageBuffer(false)
{
}
HTMLCanvasElement::~HTMLCanvasElement()
{
- if (m_2DContext)
- m_2DContext->detachCanvas();
-#if PLATFORM(CG)
- fastFree(m_data);
-#elif PLATFORM(QT)
- delete m_painter;
- delete m_data;
-#elif PLATFORM(CAIRO)
- if (m_surface)
- cairo_surface_destroy(m_surface);
-#endif
- delete m_drawingContext;
}
+#if ENABLE(DASHBOARD_SUPPORT)
+
HTMLTagStatus HTMLCanvasElement::endTagRequirement() const
{
Settings* settings = document()->settings();
@@ -109,6 +93,8 @@ int HTMLCanvasElement::tagPriority() const
return HTMLElement::tagPriority();
}
+#endif
+
void HTMLCanvasElement::parseMappedAttribute(MappedAttribute* attr)
{
const QualifiedName& attrName = attr->name();
@@ -139,11 +125,27 @@ void HTMLCanvasElement::setWidth(int value)
setAttribute(widthAttr, String::number(value));
}
+String HTMLCanvasElement::toDataURL(const String& mimeType, ExceptionCode& ec)
+{
+ if (!m_originClean) {
+ ec = SECURITY_ERR;
+ return String();
+ }
+
+ if (m_size.isEmpty())
+ return String("data:,");
+
+ if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType))
+ return buffer()->toDataURL("image/png");
+
+ return buffer()->toDataURL(mimeType);
+}
+
CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type)
{
if (type == "2d") {
if (!m_2DContext)
- m_2DContext = new CanvasRenderingContext2D(this);
+ m_2DContext.set(new CanvasRenderingContext2D(this));
return m_2DContext.get();
}
return 0;
@@ -151,6 +153,8 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type)
void HTMLCanvasElement::willDraw(const FloatRect& rect)
{
+ m_imageBuffer->clearImage();
+
if (RenderObject* ro = renderer()) {
#ifdef CANVAS_INCREMENTAL_REPAINT
// Handle CSS triggered scaling
@@ -162,10 +166,16 @@ void HTMLCanvasElement::willDraw(const FloatRect& rect)
ro->repaint();
#endif
}
+
+ if (m_observer)
+ m_observer->canvasChanged(this, rect);
}
void HTMLCanvasElement::reset()
{
+ if (m_ignoreReset)
+ return;
+
bool ok;
int w = getAttribute(widthAttr).toInt(&ok);
if (!ok)
@@ -177,22 +187,9 @@ void HTMLCanvasElement::reset()
IntSize oldSize = m_size;
m_size = IntSize(w, h);
- bool hadDrawingContext = m_createdDrawingContext;
- m_createdDrawingContext = false;
-#if PLATFORM(CG)
- fastFree(m_data);
-#elif PLATFORM(QT)
- delete m_painter;
- m_painter = 0;
- delete m_data;
-#elif PLATFORM(CAIRO)
- if (m_surface)
- cairo_surface_destroy(m_surface);
- m_surface = 0;
-#endif
- m_data = 0;
- delete m_drawingContext;
- m_drawingContext = 0;
+ bool hadImageBuffer = m_createdImageBuffer;
+ m_createdImageBuffer = false;
+ m_imageBuffer.clear();
if (m_2DContext)
m_2DContext->reset();
@@ -200,156 +197,75 @@ void HTMLCanvasElement::reset()
if (m_rendererIsCanvas) {
if (oldSize != m_size)
static_cast<RenderHTMLCanvas*>(ro)->canvasSizeChanged();
- if (hadDrawingContext)
+ if (hadImageBuffer)
ro->repaint();
}
+
+ if (m_observer)
+ m_observer->canvasResized(this);
}
-void HTMLCanvasElement::paint(GraphicsContext* p, const IntRect& r)
+void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r)
{
- if (p->paintingDisabled())
+ if (context->paintingDisabled())
return;
-#if PLATFORM(CG)
- if (CGImageRef image = createPlatformImage()) {
- CGContextDrawImage(p->platformContext(), p->roundToDevicePixels(r), image);
- CGImageRelease(image);
+
+ if (m_imageBuffer) {
+ Image* image = m_imageBuffer->image();
+ if (image)
+ context->drawImage(image, r);
}
-#elif defined(ANDROID_CANVAS_IMPL)
- if (m_drawingContext) {
- p->drawOffscreenContext(m_drawingContext, NULL, FloatRect(r));
- }
-#elif PLATFORM(QT)
- if (m_data) {
- QPen currentPen = m_painter->pen();
- qreal currentOpacity = m_painter->opacity();
- QBrush currentBrush = m_painter->brush();
- QBrush currentBackground = m_painter->background();
- if (m_painter->isActive())
- m_painter->end();
- static_cast<QPainter*>(p->platformContext())->drawImage(r, *m_data);
- m_painter->begin(m_data);
- m_painter->setPen(currentPen);
- m_painter->setBrush(currentBrush);
- m_painter->setOpacity(currentOpacity);
- m_painter->setBackground(currentBackground);
- }
-#elif PLATFORM(CAIRO)
- if (cairo_surface_t* image = createPlatformImage()) {
- cairo_t* cr = p->platformContext();
- cairo_save(cr);
- cairo_translate(cr, r.x(), r.y());
- cairo_set_source_surface(cr, image, 0, 0);
- cairo_surface_destroy(image);
- cairo_rectangle(cr, 0, 0, r.width(), r.height());
- cairo_fill(cr);
- cairo_restore(cr);
- }
-#endif
}
-void HTMLCanvasElement::createDrawingContext() const
+IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const
{
- ASSERT(!m_createdDrawingContext);
- ASSERT(!m_data);
-
- m_createdDrawingContext = true;
+ return IntRect(convertLogicalToDevice(logicalRect.location()), convertLogicalToDevice(logicalRect.size()));
+}
- float unscaledWidth = width();
- float unscaledHeight = height();
+IntSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const
+{
float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f;
- float wf = ceilf(unscaledWidth * pageScaleFactor);
- float hf = ceilf(unscaledHeight * pageScaleFactor);
-
- if (!(wf >= 1 && hf >= 1 && wf * hf <= maxCanvasArea))
- return;
-
- unsigned w = static_cast<unsigned>(wf);
- unsigned h = static_cast<unsigned>(hf);
+ float wf = ceilf(logicalSize.width() * pageScaleFactor);
+ float hf = ceilf(logicalSize.height() * pageScaleFactor);
+
+ if (!(wf >= 1 && hf >= 1 && wf * hf <= MaxCanvasArea))
+ return IntSize();
-#if PLATFORM(CG)
- size_t bytesPerRow = w * 4;
- if (bytesPerRow / 4 != w) // check for overflow
- return;
- m_data = fastCalloc(h, bytesPerRow);
- if (!m_data)
- return;
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGContextRef bitmapContext = CGBitmapContextCreate(m_data, w, h, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
- CGContextScaleCTM(bitmapContext, w / unscaledWidth, h / unscaledHeight);
- CGColorSpaceRelease(colorSpace);
- m_drawingContext = new GraphicsContext(bitmapContext);
- CGContextRelease(bitmapContext);
-#elif PLATFORM(QT)
- m_data = new QImage(w, h, QImage::Format_ARGB32_Premultiplied);
- if (!m_data)
- return;
- m_painter = new QPainter(m_data);
- m_painter->setBackground(QBrush(Qt::transparent));
- m_painter->fillRect(0, 0, w, h, QColor(Qt::transparent));
- m_drawingContext = new GraphicsContext(m_painter);
-#elif defined(ANDROID_CANVAS_IMPL)
- m_drawingContext = GraphicsContext::createOffscreenContext(w, h);
- m_drawingContext->scale(FloatSize(w / unscaledWidth, h / unscaledHeight));
-#elif PLATFORM(CAIRO)
- m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
- // m_data is owned by m_surface
- m_data = cairo_image_surface_get_data(m_surface);
- cairo_t* cr = cairo_create(m_surface);
- cairo_scale(cr, w / unscaledWidth, h / unscaledHeight);
- m_drawingContext = new GraphicsContext(cr);
- cairo_destroy(cr);
-#endif
+ return IntSize(static_cast<unsigned>(wf), static_cast<unsigned>(hf));
}
-GraphicsContext* HTMLCanvasElement::drawingContext() const
+IntPoint HTMLCanvasElement::convertLogicalToDevice(const FloatPoint& logicalPos) const
{
- if (!m_createdDrawingContext)
- createDrawingContext();
- return m_drawingContext;
+ float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f;
+ float xf = logicalPos.x() * pageScaleFactor;
+ float yf = logicalPos.y() * pageScaleFactor;
+
+ return IntPoint(static_cast<unsigned>(xf), static_cast<unsigned>(yf));
}
-#if PLATFORM(CG)
-
-CGImageRef HTMLCanvasElement::createPlatformImage() const
+void HTMLCanvasElement::createImageBuffer() const
{
- GraphicsContext* context = drawingContext();
- if (!context)
- return 0;
-
- CGContextRef contextRef = context->platformContext();
- if (!contextRef)
- return 0;
-
- CGContextFlush(contextRef);
+ ASSERT(!m_imageBuffer);
- return CGBitmapContextCreateImage(contextRef);
+ m_createdImageBuffer = true;
+
+ FloatSize unscaledSize(width(), height());
+ IntSize size = convertLogicalToDevice(unscaledSize);
+ if (!size.width() || !size.height())
+ return;
+ m_imageBuffer.set(ImageBuffer::create(size, false).release());
}
-#elif PLATFORM(QT)
-
-QImage HTMLCanvasElement::createPlatformImage() const
+GraphicsContext* HTMLCanvasElement::drawingContext() const
{
- if (m_data)
- return *m_data;
- return QImage();
+ return buffer() ? m_imageBuffer->context() : 0;
}
-#elif PLATFORM(CAIRO)
-
-cairo_surface_t* HTMLCanvasElement::createPlatformImage() const
+ImageBuffer* HTMLCanvasElement::buffer() const
{
- if (!m_surface)
- return 0;
-
- // Note that unlike CG, our returned image is not a copy or
- // copy-on-write, but the original. This is fine, since it is only
- // ever used as a source.
-
- cairo_surface_flush(m_surface);
- cairo_surface_reference(m_surface);
- return m_surface;
+ if (!m_createdImageBuffer)
+ createImageBuffer();
+ return m_imageBuffer.get();
}
-#endif
-
}
diff --git a/WebCore/html/HTMLCanvasElement.h b/WebCore/html/HTMLCanvasElement.h
index add1bf7..a118364 100644
--- a/WebCore/html/HTMLCanvasElement.h
+++ b/WebCore/html/HTMLCanvasElement.h
@@ -30,83 +30,97 @@
#include "HTMLElement.h"
#include "IntSize.h"
-#if PLATFORM(CG)
-// FIXME: CG-specific parts need to move to the platform directory.
-typedef struct CGContext* CGContextRef;
-typedef struct CGImage* CGImageRef;
-#elif PLATFORM(QT)
-class QImage;
-class QPainter;
-#elif PLATFORM(CAIRO)
-typedef struct _cairo_surface cairo_surface_t;
-#endif
-
namespace WebCore {
class CanvasRenderingContext2D;
typedef CanvasRenderingContext2D CanvasRenderingContext;
+class FloatPoint;
class FloatRect;
+class FloatSize;
class GraphicsContext;
+class HTMLCanvasElement;
+class ImageBuffer;
+class IntPoint;
+class InttRect;
+class IntSize;
+
+class CanvasObserver {
+public:
+ virtual ~CanvasObserver() {};
+
+ virtual void canvasChanged(HTMLCanvasElement* element, const FloatRect& changedRect) = 0;
+ virtual void canvasResized(HTMLCanvasElement* element) = 0;
+};
class HTMLCanvasElement : public HTMLElement {
public:
HTMLCanvasElement(Document*);
virtual ~HTMLCanvasElement();
+#if ENABLE(DASHBOARD_SUPPORT)
virtual HTMLTagStatus endTagRequirement() const;
virtual int tagPriority() const;
+#endif
int width() const { return m_size.width(); }
int height() const { return m_size.height(); }
void setWidth(int);
void setHeight(int);
+ String toDataURL(const String& mimeType, ExceptionCode&);
+
CanvasRenderingContext* getContext(const String&);
- // FIXME: Web Applications 1.0 describes a toDataURL function.
virtual void parseMappedAttribute(MappedAttribute*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
IntSize size() const { return m_size; }
+ void setSize(const IntSize& size)
+ {
+ if (size == m_size)
+ return;
+ m_ignoreReset = true;
+ setWidth(size.width());
+ setHeight(size.height());
+ m_ignoreReset = false;
+ reset();
+ }
+
void willDraw(const FloatRect&);
void paint(GraphicsContext*, const IntRect&);
GraphicsContext* drawingContext() const;
-#if PLATFORM(CG)
- CGImageRef createPlatformImage() const;
-#elif PLATFORM(QT)
- QImage createPlatformImage() const;
-#elif PLATFORM(CAIRO)
- cairo_surface_t* createPlatformImage() const;
-#endif
+ ImageBuffer* buffer() const;
+
+ IntRect convertLogicalToDevice(const FloatRect&) const;
+ IntSize convertLogicalToDevice(const FloatSize&) const;
+ IntPoint convertLogicalToDevice(const FloatPoint&) const;
+
+ void setOriginTainted() { m_originClean = false; }
+ bool originClean() const { return m_originClean; }
+
+ static const float MaxCanvasArea;
+
+ void setObserver(CanvasObserver* o) { m_observer = o; }
private:
- void createDrawingContext() const;
+ void createImageBuffer() const;
void reset();
bool m_rendererIsCanvas;
- RefPtr<CanvasRenderingContext2D> m_2DContext;
- IntSize m_size;
-
- // FIXME: Web Applications 1.0 describes a security feature where we track
- // if we ever drew any images outside the domain, so we can disable toDataURL.
-
- mutable bool m_createdDrawingContext;
-#if PLATFORM(CG)
- mutable void* m_data;
-#elif PLATFORM(QT)
- mutable QImage* m_data;
- mutable QPainter* m_painter;
-#elif PLATFORM(CAIRO)
- mutable void* m_data;
- mutable cairo_surface_t* m_surface;
-#else
- mutable void* m_data;
-#endif
- mutable GraphicsContext* m_drawingContext;
+ OwnPtr<CanvasRenderingContext2D> m_2DContext;
+ IntSize m_size;
+ CanvasObserver* m_observer;
+
+ bool m_originClean;
+ bool m_ignoreReset;
+
+ // m_createdImageBuffer means we tried to malloc the buffer. We didn't necessarily get it.
+ mutable bool m_createdImageBuffer;
+ mutable OwnPtr<ImageBuffer> m_imageBuffer;
};
} //namespace
diff --git a/WebCore/html/HTMLCanvasElement.idl b/WebCore/html/HTMLCanvasElement.idl
index 35c7383..e457c15 100644
--- a/WebCore/html/HTMLCanvasElement.idl
+++ b/WebCore/html/HTMLCanvasElement.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2008 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,9 @@ module html {
attribute long width;
attribute long height;
+ DOMString toDataURL(in [ConvertUndefinedOrNullToNullString] DOMString type)
+ raises(DOMException);
+
#if !defined(LANGUAGE_OBJECTIVE_C)
DOMObject getContext(in DOMString contextId);
#endif
diff --git a/WebCore/html/HTMLCollection.cpp b/WebCore/html/HTMLCollection.cpp
index 474e6a6..44b84a0 100644
--- a/WebCore/html/HTMLCollection.cpp
+++ b/WebCore/html/HTMLCollection.cpp
@@ -53,6 +53,11 @@ HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type, CollectionInfo*
{
}
+PassRefPtr<HTMLCollection> HTMLCollection::create(PassRefPtr<Node> base, Type type)
+{
+ return adoptRef(new HTMLCollection(base, type));
+}
+
HTMLCollection::~HTMLCollection()
{
if (m_ownsInfo)
@@ -346,11 +351,10 @@ bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const S
e->hasLocalName(selectTag)))
return false;
- return e->getAttribute(nameAttr).domString().lower() == name.lower() &&
- e->getAttribute(idAttr).domString().lower() != name.lower();
- } else {
- return e->getAttribute(idAttr).domString().lower() == name.lower();
- }
+ return equalIgnoringCase(e->getAttribute(nameAttr), name)
+ && !equalIgnoringCase(e->getAttribute(idAttr), name);
+ } else
+ return equalIgnoringCase(e->getAttribute(idAttr), name);
}
}
diff --git a/WebCore/html/HTMLCollection.h b/WebCore/html/HTMLCollection.h
index d992c81..3d75108 100644
--- a/WebCore/html/HTMLCollection.h
+++ b/WebCore/html/HTMLCollection.h
@@ -76,7 +76,7 @@ public:
static const Type FirstNamedDocumentCachedType = WindowNamedItems;
static const unsigned NumNamedDocumentCachedTypes = DocumentNamedItems - WindowNamedItems + 1;
- HTMLCollection(PassRefPtr<Node> base, Type);
+ static PassRefPtr<HTMLCollection> create(PassRefPtr<Node> base, Type);
virtual ~HTMLCollection();
unsigned length() const;
@@ -139,6 +139,8 @@ protected:
mutable bool m_idsDone; // for nextNamedItem()
private:
+ HTMLCollection(PassRefPtr<Node> base, Type);
+
virtual Element* itemAfter(Element*) const;
virtual unsigned calcLength() const;
virtual void updateNameCache() const;
diff --git a/WebCore/html/HTMLDivElement.cpp b/WebCore/html/HTMLDivElement.cpp
index 0951de8..3aab91b 100644
--- a/WebCore/html/HTMLDivElement.cpp
+++ b/WebCore/html/HTMLDivElement.cpp
@@ -55,13 +55,13 @@ void HTMLDivElement::parseMappedAttribute(MappedAttribute *attr)
if (attr->name() == alignAttr) {
String v = attr->value();
if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_CENTER);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitCenter);
else if (equalIgnoringCase(attr->value(), "left"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_LEFT);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitLeft);
else if (equalIgnoringCase(attr->value(), "right"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_RIGHT);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitRight);
else
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, v);
+ addCSSProperty(attr, CSSPropertyTextAlign, v);
} else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLDocument.cpp b/WebCore/html/HTMLDocument.cpp
index 8db8422..97557f9 100644
--- a/WebCore/html/HTMLDocument.cpp
+++ b/WebCore/html/HTMLDocument.cpp
@@ -1,7 +1,7 @@
-/**
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * 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
@@ -60,8 +60,10 @@
#include "DocumentLoader.h"
#include "DocumentType.h"
#include "ExceptionCode.h"
+#include "FocusController.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "FrameTree.h"
#include "FrameView.h"
#include "HTMLBodyElement.h"
#include "HTMLElement.h"
@@ -83,10 +85,11 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLDocument::HTMLDocument(DOMImplementation* implementation, Frame* frame)
- : Document(implementation, frame)
+HTMLDocument::HTMLDocument(Frame* frame)
+ : Document(frame, false)
{
clearXMLVersion();
+ setParseMode(Compat);
}
HTMLDocument::~HTMLDocument()
@@ -144,6 +147,25 @@ String HTMLDocument::compatMode() const
return inCompatMode() ? "BackCompat" : "CSS1Compat";
}
+Element* HTMLDocument::activeElement()
+{
+ if (Node* node = focusedNode())
+ if (node->isElementNode())
+ return static_cast<Element*>(node);
+ return body();
+}
+
+bool HTMLDocument::hasFocus()
+{
+ if (!page()->focusController()->isActive())
+ return false;
+ if (Frame* focusedFrame = page()->focusController()->focusedFrame()) {
+ if (focusedFrame->tree()->isDescendantOf(frame()))
+ return true;
+ }
+ return false;
+}
+
String HTMLDocument::bgColor()
{
HTMLElement* b = body();
@@ -278,22 +300,22 @@ Tokenizer *HTMLDocument::createTokenizer()
bool HTMLDocument::childAllowed(Node *newChild)
{
- return newChild->hasTagName(htmlTag) || newChild->isCommentNode();
+ return newChild->hasTagName(htmlTag) || newChild->isCommentNode() || (newChild->nodeType() == DOCUMENT_TYPE_NODE && !doctype());
}
-PassRefPtr<Element> HTMLDocument::createElement(const String &name, ExceptionCode& ec)
+PassRefPtr<Element> HTMLDocument::createElement(const AtomicString& name, ExceptionCode& ec)
{
- String lowerName(name.lower());
- if (!isValidName(lowerName)) {
+ if (!isValidName(name)) {
ec = INVALID_CHARACTER_ERR;
return 0;
}
- return HTMLElementFactory::createHTMLElement(AtomicString(lowerName), this, 0, false);
+ AtomicString lowerName = name.string().impl()->isLower() ? name : AtomicString(name.string().lower());
+ return HTMLElementFactory::createHTMLElement(lowerName, this, 0, false);
}
-static void addItemToMap(HTMLDocument::NameCountMap& map, const String& name)
+static void addItemToMap(HTMLDocument::NameCountMap& map, const AtomicString& name)
{
- if (name.length() == 0)
+ if (name.isEmpty())
return;
HTMLDocument::NameCountMap::iterator it = map.find(name.impl());
@@ -303,9 +325,9 @@ static void addItemToMap(HTMLDocument::NameCountMap& map, const String& name)
++(it->second);
}
-static void removeItemFromMap(HTMLDocument::NameCountMap& map, const String& name)
+static void removeItemFromMap(HTMLDocument::NameCountMap& map, const AtomicString& name)
{
- if (name.length() == 0)
+ if (name.isEmpty())
return;
HTMLDocument::NameCountMap::iterator it = map.find(name.impl());
@@ -321,266 +343,96 @@ static void removeItemFromMap(HTMLDocument::NameCountMap& map, const String& nam
it->second = newVal;
}
-void HTMLDocument::addNamedItem(const String& name)
+void HTMLDocument::addNamedItem(const AtomicString& name)
{
- addItemToMap(namedItemCounts, name);
+ addItemToMap(m_namedItemCounts, name);
}
-void HTMLDocument::removeNamedItem(const String &name)
+void HTMLDocument::removeNamedItem(const AtomicString &name)
{
- removeItemFromMap(namedItemCounts, name);
-}
-
-bool HTMLDocument::hasNamedItem(const String& name)
-{
- return namedItemCounts.get(name.impl()) != 0;
+ removeItemFromMap(m_namedItemCounts, name);
}
-void HTMLDocument::addDocExtraNamedItem(const String& name)
+void HTMLDocument::addExtraNamedItem(const AtomicString& name)
{
- addItemToMap(docExtraNamedItemCounts, name);
+ addItemToMap(m_extraNamedItemCounts, name);
}
-void HTMLDocument::removeDocExtraNamedItem(const String& name)
+void HTMLDocument::removeExtraNamedItem(const AtomicString& name)
{
- removeItemFromMap(docExtraNamedItemCounts, name);
+ removeItemFromMap(m_extraNamedItemCounts, name);
}
-bool HTMLDocument::hasDocExtraNamedItem(const String& name)
+void HTMLDocument::determineParseMode()
{
- return docExtraNamedItemCounts.get(name.impl()) != 0;
-}
-
-const int PARSEMODE_HAVE_DOCTYPE = (1<<0);
-const int PARSEMODE_HAVE_PUBLIC_ID = (1<<1);
-const int PARSEMODE_HAVE_SYSTEM_ID = (1<<2);
-const int PARSEMODE_HAVE_INTERNAL = (1<<3);
-
-static int parseDocTypePart(const String& buffer, int index)
-{
- while (true) {
- UChar ch = buffer[index];
- if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
- ++index;
- else if (ch == '-') {
- int tmpIndex=index;
- if (buffer[index+1] == '-' &&
- ((tmpIndex=buffer.find("--", index+2)) != -1))
- index = tmpIndex+2;
- else
- return index;
- }
- else
- return index;
- }
-}
-
-static bool containsString(const char* str, const String& buffer, int offset)
-{
- String startString(str);
- if (offset + startString.length() > buffer.length())
- return false;
-
- String bufferString = buffer.substring(offset, startString.length()).lower();
- String lowerStart = startString.lower();
-
- return bufferString.startsWith(lowerStart);
-}
-
-static bool parseDocTypeDeclaration(const String& buffer,
- int* resultFlags,
- String& name,
- String& publicID,
- String& systemID)
-{
- bool haveDocType = false;
- *resultFlags = 0;
-
- // Skip through any comments and processing instructions.
- int index = 0;
- do {
- index = buffer.find('<', index);
- if (index == -1) break;
- UChar nextChar = buffer[index+1];
- if (nextChar == '!') {
- if (containsString("doctype", buffer, index+2)) {
- haveDocType = true;
- index += 9; // Skip "<!DOCTYPE"
- break;
- }
- index = parseDocTypePart(buffer,index);
- index = buffer.find('>', index);
- }
- else if (nextChar == '?')
- index = buffer.find('>', index);
- else
- break;
- } while (index != -1);
-
- if (!haveDocType)
- return true;
- *resultFlags |= PARSEMODE_HAVE_DOCTYPE;
-
- index = parseDocTypePart(buffer, index);
- if (!containsString("html", buffer, index))
- return false;
-
- name = buffer.substring(index, 4);
- index = parseDocTypePart(buffer, index+4);
- bool hasPublic = containsString("public", buffer, index);
- if (hasPublic) {
- index = parseDocTypePart(buffer, index+6);
-
- // We've read <!DOCTYPE HTML PUBLIC (not case sensitive).
- // Now we find the beginning and end of the public identifers
- // and system identifiers (assuming they're even present).
- UChar theChar = buffer[index];
- if (theChar != '\"' && theChar != '\'')
- return false;
-
- // |start| is the first character (after the quote) and |end|
- // is the final quote, so there are |end|-|start| characters.
- int publicIDStart = index+1;
- int publicIDEnd = buffer.find(theChar, publicIDStart);
- if (publicIDEnd == -1)
- return false;
- index = parseDocTypePart(buffer, publicIDEnd+1);
- UChar next = buffer[index];
- if (next == '>') {
- // Public identifier present, but no system identifier.
- // Do nothing. Note that this is the most common
- // case.
- }
- else if (next == '\"' || next == '\'') {
- // We have a system identifier.
- *resultFlags |= PARSEMODE_HAVE_SYSTEM_ID;
- int systemIDStart = index+1;
- int systemIDEnd = buffer.find(next, systemIDStart);
- if (systemIDEnd == -1)
- return false;
- systemID = buffer.substring(systemIDStart, systemIDEnd - systemIDStart);
- }
- else if (next == '[') {
- // We found an internal subset.
- *resultFlags |= PARSEMODE_HAVE_INTERNAL;
- }
- else
- return false; // Something's wrong.
-
- // We need to trim whitespace off the public identifier.
- publicID = buffer.substring(publicIDStart, publicIDEnd - publicIDStart);
- publicID = publicID.stripWhiteSpace();
- *resultFlags |= PARSEMODE_HAVE_PUBLIC_ID;
- } else {
- if (containsString("system", buffer, index)) {
- // Doctype has a system ID but no public ID
- *resultFlags |= PARSEMODE_HAVE_SYSTEM_ID;
- index = parseDocTypePart(buffer, index+6);
- UChar next = buffer[index];
- if (next != '\"' && next != '\'')
- return false;
- int systemIDStart = index+1;
- int systemIDEnd = buffer.find(next, systemIDStart);
- if (systemIDEnd == -1)
- return false;
- systemID = buffer.substring(systemIDStart, systemIDEnd - systemIDStart);
- index = parseDocTypePart(buffer, systemIDEnd+1);
- }
-
- UChar nextChar = buffer[index];
- if (nextChar == '[')
- *resultFlags |= PARSEMODE_HAVE_INTERNAL;
- else if (nextChar != '>')
- return false;
- }
+ // FIXME: It's terrible that this code runs separately and isn't just built in to the
+ // HTML tokenizer/parser.
- return true;
-}
-
-void HTMLDocument::determineParseMode(const String& str)
-{
// This code more or less mimics Mozilla's implementation (specifically the
// doctype parsing implemented by David Baron in Mozilla's nsParser.cpp).
//
// There are three possible parse modes:
- // COMPAT - quirks mode emulates WinIE
- // and NS4. CSS parsing is also relaxed in this mode, e.g., unit types can
+ // COMPAT - quirks mode emulates WinIE and NS4. CSS parsing is also relaxed in this mode, e.g., unit types can
// be omitted from numbers.
- // ALMOST STRICT - This mode is identical to strict mode
- // except for its treatment of line-height in the inline box model. For
- // now (until the inline box model is re-written), this mode is identical
- // to STANDARDS mode.
- // STRICT - no quirks apply. Web pages will obey the specifications to
- // the letter.
-
- String name, systemID, publicID;
- int resultFlags = 0;
- if (parseDocTypeDeclaration(str, &resultFlags, name, publicID, systemID)) {
- if (resultFlags & PARSEMODE_HAVE_DOCTYPE)
- setDocType(new DocumentType(this, name, publicID, systemID));
- if (!(resultFlags & PARSEMODE_HAVE_DOCTYPE)) {
- // No doctype found at all. Default to quirks mode and Html4.
- setParseMode(Compat);
- setHTMLMode(Html4);
+ // ALMOST STRICT - This mode is identical to strict mode except for its treatment of line-height in the inline box model. For
+ // now (until the inline box model is re-written), this mode is identical to STANDARDS mode.
+ // STRICT - no quirks apply. Web pages will obey the specifications to the letter.
+ bool wasInCompatMode = inCompatMode();
+ DocumentType* docType = doctype();
+ if (!docType || !equalIgnoringCase(docType->name(), "html"))
+ // No doctype found at all or the doctype is not HTML. Default to quirks mode and Html4.
+ setParseMode(Compat);
+ else if (!doctype()->systemId().isEmpty() && equalIgnoringCase(docType->systemId(), "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"))
+ // Assume quirks mode for this particular system ID. In the HTML5 spec, this is the only
+ // system identifier that is examined.
+ setParseMode(Compat);
+ else if (docType->publicId().isEmpty())
+ // A doctype without a public ID means use strict mode.
+ setParseMode(Strict);
+ else {
+ // We have to check a list of public IDs to see what we
+ // should do.
+ String lowerPubID = docType->publicId().lower();
+ CString pubIDStr = lowerPubID.latin1();
+
+#ifdef ANDROID_META_SUPPORT
+ if ((!frame()->tree() || !frame()->tree()->parent()) &&
+ strstr(pubIDStr.data(), "-//wapforum//dtd xhtml mobile 1.") == pubIDStr.data()) {
+ // fit mobile sites directly in the screen
+ frame()->settings()->setMetadataSettings("width", "device-width");
}
- else if ((resultFlags & PARSEMODE_HAVE_INTERNAL) ||
- !(resultFlags & PARSEMODE_HAVE_PUBLIC_ID)) {
- // Internal subsets always denote full standards, as does
- // a doctype without a public ID.
+#endif
+ // Look up the entry in our gperf-generated table.
+ const PubIDInfo* doctypeEntry = findDoctypeEntry(pubIDStr.data(), pubIDStr.length());
+ if (!doctypeEntry)
+ // The DOCTYPE is not in the list. Assume strict mode.
setParseMode(Strict);
- setHTMLMode(Html4);
- }
else {
- // We have to check a list of public IDs to see what we
- // should do.
- String lowerPubID = publicID.lower();
- CString pubIDStr = lowerPubID.latin1();
-
-#ifdef ANDROID_META_SUPPORT
- if ((!frame()->tree() || !frame()->tree()->parent()) &&
- strstr(pubIDStr.data(), "-//wapforum//dtd xhtml mobile 1.") == pubIDStr.data()) {
- // fit mobile sites directly in the screen
- frame()->settings()->setMetadataSettings("width", "device-width");
- }
-#endif
- // Look up the entry in our gperf-generated table.
- const PubIDInfo* doctypeEntry = findDoctypeEntry(pubIDStr.data(), pubIDStr.length());
- if (!doctypeEntry) {
- // The DOCTYPE is not in the list. Assume strict mode.
- setParseMode(Strict);
- setHTMLMode(Html4);
- return;
- }
-
- switch ((resultFlags & PARSEMODE_HAVE_SYSTEM_ID) ?
- doctypeEntry->mode_if_sysid :
- doctypeEntry->mode_if_no_sysid)
- {
+ switch (docType->systemId().isEmpty() ?
+ doctypeEntry->mode_if_no_sysid :
+ doctypeEntry->mode_if_sysid) {
case PubIDInfo::eQuirks3:
- setParseMode(Compat);
- setHTMLMode(Html3);
- break;
case PubIDInfo::eQuirks:
setParseMode(Compat);
- setHTMLMode(Html4);
break;
case PubIDInfo::eAlmostStandards:
setParseMode(AlmostStrict);
- setHTMLMode(Html4);
break;
default:
ASSERT(false);
}
- }
- }
- else {
- // Malformed doctype implies quirks mode.
- setParseMode(Compat);
- setHTMLMode(Html3);
+ }
}
-
- styleSelector()->strictParsing = !inCompatMode();
-
+
+ if (inCompatMode() != wasInCompatMode)
+ updateStyleSelector();
+}
+
+void HTMLDocument::clear()
+{
+ // FIXME: This does nothing, and that seems unlikely to be correct.
+ // We've long had a comment saying that IE doesn't support this.
+ // But I do see it in the documentation for Mozilla.
}
}
diff --git a/WebCore/html/HTMLDocument.h b/WebCore/html/HTMLDocument.h
index fefbdb7..de84c70 100644
--- a/WebCore/html/HTMLDocument.h
+++ b/WebCore/html/HTMLDocument.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 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
@@ -33,11 +33,12 @@ class HTMLElement;
class HTMLDocument : public Document, public CachedResourceClient {
public:
- HTMLDocument(DOMImplementation*, Frame*);
+ static PassRefPtr<HTMLDocument> create(Frame* frame)
+ {
+ return new HTMLDocument(frame);
+ }
virtual ~HTMLDocument();
- virtual bool isHTMLDocument() const { return true; }
-
int width();
int height();
@@ -49,6 +50,9 @@ public:
String compatMode() const;
+ Element* activeElement();
+ bool hasFocus();
+
String bgColor();
void setBgColor(const String&);
String fgColor();
@@ -60,32 +64,49 @@ public:
String vlinkColor();
void setVlinkColor(const String&);
+ void clear();
+
void captureEvents();
void releaseEvents();
- virtual Tokenizer* createTokenizer();
-
virtual bool childAllowed(Node*);
- virtual PassRefPtr<Element> createElement(const String& tagName, ExceptionCode&);
+ virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
- virtual void determineParseMode(const String&);
+ void addNamedItem(const AtomicString& name);
+ void removeNamedItem(const AtomicString& name);
+ bool hasNamedItem(AtomicStringImpl* name);
- void addNamedItem(const String& name);
- void removeNamedItem(const String& name);
- bool hasNamedItem(const String& name);
+ void addExtraNamedItem(const AtomicString& name);
+ void removeExtraNamedItem(const AtomicString& name);
+ bool hasExtraNamedItem(AtomicStringImpl* name);
- void addDocExtraNamedItem(const String& name);
- void removeDocExtraNamedItem(const String& name);
- bool hasDocExtraNamedItem(const String& name);
+ typedef HashMap<AtomicStringImpl*, int> NameCountMap;
- typedef HashMap<StringImpl*, int> NameCountMap;
+protected:
+ HTMLDocument(Frame*);
private:
- NameCountMap namedItemCounts;
- NameCountMap docExtraNamedItemCounts;
+ virtual bool isHTMLDocument() const { return true; }
+ virtual Tokenizer* createTokenizer();
+ virtual void determineParseMode();
+
+ NameCountMap m_namedItemCounts;
+ NameCountMap m_extraNamedItemCounts;
};
+inline bool HTMLDocument::hasNamedItem(AtomicStringImpl* name)
+{
+ ASSERT(name);
+ return m_namedItemCounts.contains(name);
+}
+
+inline bool HTMLDocument::hasExtraNamedItem(AtomicStringImpl* name)
+{
+ ASSERT(name);
+ return m_extraNamedItemCounts.contains(name);
+}
+
} // namespace
#endif
diff --git a/WebCore/html/HTMLDocument.idl b/WebCore/html/HTMLDocument.idl
index c0aabfe..4345195 100644
--- a/WebCore/html/HTMLDocument.idl
+++ b/WebCore/html/HTMLDocument.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 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
@@ -38,13 +38,12 @@ module html {
// Extensions
#if defined(LANGUAGE_JAVASCRIPT)
- // FIXME: These should eventually be available (if they are wanted) for all languages.
-
+ // FIXME: This should eventually be available (if they are wanted) for all languages.
attribute [Custom, Deletable] HTMLCollection all;
-
- [Custom] void clear();
#endif
+ void clear();
+
void captureEvents();
void releaseEvents();
@@ -54,6 +53,9 @@ module html {
attribute [ConvertNullToNullString] DOMString designMode;
readonly attribute DOMString compatMode;
+ readonly attribute Element activeElement;
+ boolean hasFocus();
+
// Deprecated attributes
attribute [ConvertNullToNullString] DOMString bgColor;
attribute [ConvertNullToNullString] DOMString fgColor;
diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp
index 1f84e23..3f8a983 100644
--- a/WebCore/html/HTMLElement.cpp
+++ b/WebCore/html/HTMLElement.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * 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
@@ -46,7 +46,6 @@
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
using std::min;
@@ -66,7 +65,7 @@ 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())
- return tagQName().localName().domString().upper();
+ return tagQName().localName().string().upper();
return Element::nodeName();
}
@@ -103,7 +102,7 @@ PassRefPtr<Node> HTMLElement::cloneNode(bool deep)
return 0;
if (namedAttrMap)
- *clone->attributes() = *namedAttrMap;
+ clone->attributes()->setAttributes(*namedAttrMap);
clone->copyNonAttributeProperties(this);
@@ -136,85 +135,107 @@ void HTMLElement::parseMappedAttribute(MappedAttribute *attr)
String indexstring;
if (attr->name() == alignAttr) {
if (equalIgnoringCase(attr->value(), "middle"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, "center");
+ addCSSProperty(attr, CSSPropertyTextAlign, "center");
else
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, attr->value());
+ addCSSProperty(attr, CSSPropertyTextAlign, attr->value());
} else if (attr->name() == contenteditableAttr) {
setContentEditable(attr);
} else if (attr->name() == tabindexAttr) {
indexstring = getAttribute(tabindexAttr);
- if (indexstring.length())
- // Clamp tabindex to the range of 'short' to match Firefox's behavior.
- setTabIndex(max(static_cast<int>(std::numeric_limits<short>::min()), min(indexstring.toInt(), static_cast<int>(std::numeric_limits<short>::max()))));
+ if (indexstring.length()) {
+ bool parsedOK;
+ int tabindex = indexstring.toIntStrict(&parsedOK);
+ if (parsedOK)
+ // Clamp tabindex to the range of 'short' to match Firefox's behavior.
+ setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
+ }
} else if (attr->name() == langAttr) {
// FIXME: Implement
} else if (attr->name() == dirAttr) {
- addCSSProperty(attr, CSS_PROP_DIRECTION, attr->value());
- addCSSProperty(attr, CSS_PROP_UNICODE_BIDI, hasLocalName(bdoTag) ? CSS_VAL_BIDI_OVERRIDE : CSS_VAL_EMBED);
+ addCSSProperty(attr, CSSPropertyDirection, attr->value());
+ addCSSProperty(attr, CSSPropertyUnicodeBidi, hasLocalName(bdoTag) ? CSSValueBidiOverride : CSSValueEmbed);
}
// standard events
else if (attr->name() == onclickAttr) {
- setHTMLEventListener(clickEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().clickEvent, attr);
} else if (attr->name() == oncontextmenuAttr) {
- setHTMLEventListener(contextmenuEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().contextmenuEvent, attr);
} else if (attr->name() == ondblclickAttr) {
- setHTMLEventListener(dblclickEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().dblclickEvent, attr);
} else if (attr->name() == onmousedownAttr) {
- setHTMLEventListener(mousedownEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().mousedownEvent, attr);
} else if (attr->name() == onmousemoveAttr) {
- setHTMLEventListener(mousemoveEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().mousemoveEvent, attr);
} else if (attr->name() == onmouseoutAttr) {
- setHTMLEventListener(mouseoutEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().mouseoutEvent, attr);
} else if (attr->name() == onmouseoverAttr) {
- setHTMLEventListener(mouseoverEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().mouseoverEvent, attr);
} else if (attr->name() == onmouseupAttr) {
- setHTMLEventListener(mouseupEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().mouseupEvent, attr);
} else if (attr->name() == onmousewheelAttr) {
- setHTMLEventListener(mousewheelEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().mousewheelEvent, attr);
} else if (attr->name() == onfocusAttr) {
- setHTMLEventListener(focusEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
} else if (attr->name() == onblurAttr) {
- setHTMLEventListener(blurEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
} else if (attr->name() == onkeydownAttr) {
- setHTMLEventListener(keydownEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().keydownEvent, attr);
} else if (attr->name() == onkeypressAttr) {
- setHTMLEventListener(keypressEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().keypressEvent, attr);
} else if (attr->name() == onkeyupAttr) {
- setHTMLEventListener(keyupEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().keyupEvent, attr);
} else if (attr->name() == onscrollAttr) {
- setHTMLEventListener(scrollEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().scrollEvent, attr);
} else if (attr->name() == onbeforecutAttr) {
- setHTMLEventListener(beforecutEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().beforecutEvent, attr);
} else if (attr->name() == oncutAttr) {
- setHTMLEventListener(cutEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().cutEvent, attr);
} else if (attr->name() == onbeforecopyAttr) {
- setHTMLEventListener(beforecopyEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().beforecopyEvent, attr);
} else if (attr->name() == oncopyAttr) {
- setHTMLEventListener(copyEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().copyEvent, attr);
} else if (attr->name() == onbeforepasteAttr) {
- setHTMLEventListener(beforepasteEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().beforepasteEvent, attr);
} else if (attr->name() == onpasteAttr) {
- setHTMLEventListener(pasteEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().pasteEvent, attr);
} else if (attr->name() == ondragenterAttr) {
- setHTMLEventListener(dragenterEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().dragenterEvent, attr);
} else if (attr->name() == ondragoverAttr) {
- setHTMLEventListener(dragoverEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().dragoverEvent, attr);
} else if (attr->name() == ondragleaveAttr) {
- setHTMLEventListener(dragleaveEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().dragleaveEvent, attr);
} else if (attr->name() == ondropAttr) {
- setHTMLEventListener(dropEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().dropEvent, attr);
} else if (attr->name() == ondragstartAttr) {
- setHTMLEventListener(dragstartEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().dragstartEvent, attr);
} else if (attr->name() == ondragAttr) {
- setHTMLEventListener(dragEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().dragEvent, attr);
} else if (attr->name() == ondragendAttr) {
- setHTMLEventListener(dragendEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().dragendEvent, attr);
} else if (attr->name() == onselectstartAttr) {
- setHTMLEventListener(selectstartEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().selectstartEvent, attr);
} else if (attr->name() == onsubmitAttr) {
- setHTMLEventListener(submitEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().submitEvent, attr);
} else if (attr->name() == onerrorAttr) {
- setHTMLEventListener(errorEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().errorEvent, attr);
+ } else if (attr->name() == onwebkitanimationstartAttr) {
+ setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationStartEvent, attr);
+ } else if (attr->name() == onwebkitanimationiterationAttr) {
+ setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationIterationEvent, attr);
+ } else if (attr->name() == onwebkitanimationendAttr) {
+ setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationEndEvent, attr);
+ } else if (attr->name() == onwebkittransitionendAttr) {
+ setInlineEventListenerForTypeAndAttribute(eventNames().webkitTransitionEndEvent, attr);
+#if ENABLE(TOUCH_EVENTS) // Android
+ } else if (attr->name() == ontouchstartAttr) {
+ setInlineEventListenerForTypeAndAttribute(eventNames().touchstartEvent, attr);
+ } else if (attr->name() == ontouchendAttr) {
+ setInlineEventListenerForTypeAndAttribute(eventNames().touchendEvent, attr);
+ } else if (attr->name() == ontouchmoveAttr) {
+ setInlineEventListenerForTypeAndAttribute(eventNames().touchmoveEvent, attr);
+ } else if (attr->name() == ontouchcancelAttr) {
+ setInlineEventListenerForTypeAndAttribute(eventNames().touchcancelEvent, attr);
+#endif
}
}
@@ -492,6 +513,71 @@ void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
}
}
+Node* HTMLElement::insertAdjacent(const String& where, Node* newChild, ExceptionCode& ec)
+{
+ // In Internet Explorer if the element has no parent and where is "beforeBegin" or "afterEnd",
+ // a document fragment is created and the elements appended in the correct order. This document
+ // fragment isn't returned anywhere.
+ //
+ // This is impossible for us to implement as the DOM tree does not allow for such structures,
+ // Opera also appears to disallow such usage.
+
+ if (equalIgnoringCase(where, "beforeBegin")) {
+ if (Node* p = parent())
+ return p->insertBefore(newChild, this, ec) ? newChild : 0;
+ return 0;
+ }
+
+ if (equalIgnoringCase(where, "afterBegin"))
+ return insertBefore(newChild, firstChild(), ec) ? newChild : 0;
+
+ if (equalIgnoringCase(where, "beforeEnd"))
+ return appendChild(newChild, ec) ? newChild : 0;
+
+ if (equalIgnoringCase(where, "afterEnd")) {
+ if (Node* p = parent())
+ return p->insertBefore(newChild, nextSibling(), ec) ? newChild : 0;
+ return 0;
+ }
+
+ // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+}
+
+Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChild, ExceptionCode& ec)
+{
+ if (!newChild) {
+ // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative
+ ec = TYPE_MISMATCH_ERR;
+ return 0;
+ }
+
+ Node* returnValue = insertAdjacent(where, newChild, ec);
+ ASSERT(!returnValue || returnValue->isElementNode());
+ return static_cast<Element*>(returnValue);
+}
+
+void HTMLElement::insertAdjacentHTML(const String& where, const String& html, ExceptionCode& ec)
+{
+ RefPtr<DocumentFragment> fragment = document()->createDocumentFragment();
+ if (document()->isHTMLDocument())
+ parseHTMLDocumentFragment(html, fragment.get());
+ else {
+ if (!parseXMLDocumentFragment(html, fragment.get(), this))
+ // FIXME: We should propagate a syntax error exception out here.
+ return;
+ }
+
+ insertAdjacent(where, fragment.get(), ec);
+}
+
+void HTMLElement::insertAdjacentText(const String& where, const String& text, ExceptionCode& ec)
+{
+ RefPtr<Text> textNode = document()->createTextNode(text);
+ insertAdjacent(where, textNode.get(), ec);
+}
+
void HTMLElement::addHTMLAlignment(MappedAttribute* attr)
{
// vertical alignment with respect to the current baseline of the text
@@ -500,36 +586,36 @@ void HTMLElement::addHTMLAlignment(MappedAttribute* attr)
int propvalign = -1;
const AtomicString& alignment = attr->value();
if (equalIgnoringCase(alignment, "absmiddle")) {
- propvalign = CSS_VAL_MIDDLE;
+ propvalign = CSSValueMiddle;
} else if (equalIgnoringCase(alignment, "absbottom")) {
- propvalign = CSS_VAL_BOTTOM;
+ propvalign = CSSValueBottom;
} else if (equalIgnoringCase(alignment, "left")) {
- propfloat = CSS_VAL_LEFT;
- propvalign = CSS_VAL_TOP;
+ propfloat = CSSValueLeft;
+ propvalign = CSSValueTop;
} else if (equalIgnoringCase(alignment, "right")) {
- propfloat = CSS_VAL_RIGHT;
- propvalign = CSS_VAL_TOP;
+ propfloat = CSSValueRight;
+ propvalign = CSSValueTop;
} else if (equalIgnoringCase(alignment, "top")) {
- propvalign = CSS_VAL_TOP;
+ propvalign = CSSValueTop;
} else if (equalIgnoringCase(alignment, "middle")) {
- propvalign = CSS_VAL__WEBKIT_BASELINE_MIDDLE;
+ propvalign = CSSValueWebkitBaselineMiddle;
} else if (equalIgnoringCase(alignment, "center")) {
- propvalign = CSS_VAL_MIDDLE;
+ propvalign = CSSValueMiddle;
} else if (equalIgnoringCase(alignment, "bottom")) {
- propvalign = CSS_VAL_BASELINE;
+ propvalign = CSSValueBaseline;
} else if (equalIgnoringCase(alignment, "texttop")) {
- propvalign = CSS_VAL_TEXT_TOP;
+ propvalign = CSSValueTextTop;
}
if ( propfloat != -1 )
- addCSSProperty( attr, CSS_PROP_FLOAT, propfloat );
+ addCSSProperty( attr, CSSPropertyFloat, propfloat );
if ( propvalign != -1 )
- addCSSProperty( attr, CSS_PROP_VERTICAL_ALIGN, propvalign );
+ addCSSProperty( attr, CSSPropertyVerticalAlign, propvalign );
}
bool HTMLElement::isFocusable() const
{
- return isContentEditable() && parent() && !parent()->isContentEditable();
+ return Element::isFocusable() || (isContentEditable() && parent() && !parent()->isContentEditable());
}
bool HTMLElement::isContentEditable() const
@@ -589,25 +675,25 @@ void HTMLElement::setContentEditable(MappedAttribute* attr)
{
const AtomicString& enabled = attr->value();
if (enabled.isEmpty() || equalIgnoringCase(enabled, "true")) {
- addCSSProperty(attr, CSS_PROP__WEBKIT_USER_MODIFY, CSS_VAL_READ_WRITE);
- addCSSProperty(attr, CSS_PROP_WORD_WRAP, CSS_VAL_BREAK_WORD);
- addCSSProperty(attr, CSS_PROP__WEBKIT_NBSP_MODE, CSS_VAL_SPACE);
- addCSSProperty(attr, CSS_PROP__WEBKIT_LINE_BREAK, CSS_VAL_AFTER_WHITE_SPACE);
+ addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWrite);
+ addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);
+ addCSSProperty(attr, CSSPropertyWebkitNbspMode, CSSValueSpace);
+ addCSSProperty(attr, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
} else if (equalIgnoringCase(enabled, "false")) {
- addCSSProperty(attr, CSS_PROP__WEBKIT_USER_MODIFY, CSS_VAL_READ_ONLY);
- attr->decl()->removeProperty(CSS_PROP_WORD_WRAP, false);
- attr->decl()->removeProperty(CSS_PROP__WEBKIT_NBSP_MODE, false);
- attr->decl()->removeProperty(CSS_PROP__WEBKIT_LINE_BREAK, false);
+ addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadOnly);
+ attr->decl()->removeProperty(CSSPropertyWordWrap, false);
+ attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false);
+ attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false);
} else if (equalIgnoringCase(enabled, "inherit")) {
- addCSSProperty(attr, CSS_PROP__WEBKIT_USER_MODIFY, CSS_VAL_INHERIT);
- attr->decl()->removeProperty(CSS_PROP_WORD_WRAP, false);
- attr->decl()->removeProperty(CSS_PROP__WEBKIT_NBSP_MODE, false);
- attr->decl()->removeProperty(CSS_PROP__WEBKIT_LINE_BREAK, false);
+ addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueInherit);
+ attr->decl()->removeProperty(CSSPropertyWordWrap, false);
+ attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false);
+ attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false);
} else if (equalIgnoringCase(enabled, "plaintext-only")) {
- addCSSProperty(attr, CSS_PROP__WEBKIT_USER_MODIFY, CSS_VAL_READ_WRITE_PLAINTEXT_ONLY);
- addCSSProperty(attr, CSS_PROP_WORD_WRAP, CSS_VAL_BREAK_WORD);
- addCSSProperty(attr, CSS_PROP__WEBKIT_NBSP_MODE, CSS_VAL_SPACE);
- addCSSProperty(attr, CSS_PROP__WEBKIT_LINE_BREAK, CSS_VAL_AFTER_WHITE_SPACE);
+ addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);
+ addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);
+ addCSSProperty(attr, CSSPropertyWebkitNbspMode, CSSValueSpace);
+ addCSSProperty(attr, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
}
}
@@ -639,24 +725,6 @@ void HTMLElement::accessKeyAction(bool sendToAnyElement)
dispatchSimulatedClick(0, true);
}
-String HTMLElement::toString() const
-{
- if (!hasChildNodes() && document()->isHTMLDocument()) {
- String result = openTagStartToString();
- result += ">";
-
- if (endTagRequirement() == TagStatusRequired) {
- result += "</";
- result += nodeName();
- result += ">";
- }
-
- return result;
- }
-
- return Element::toString();
-}
-
String HTMLElement::id() const
{
return getAttribute(idAttr);
@@ -707,9 +775,21 @@ void HTMLElement::setClassName(const String &value)
setAttribute(classAttr, value);
}
+short HTMLElement::tabIndex() const
+{
+ if (supportsFocus())
+ return Element::tabIndex();
+ return -1;
+}
+
+void HTMLElement::setTabIndex(int value)
+{
+ setAttribute(tabindexAttr, String::number(value));
+}
+
PassRefPtr<HTMLCollection> HTMLElement::children()
{
- return new HTMLCollection(this, HTMLCollection::NodeChildren);
+ return HTMLCollection::create(this, HTMLCollection::NodeChildren);
}
// DOM Section 1.1.1
@@ -786,6 +866,8 @@ HashSet<AtomicStringImpl*>* inlineTagList()
tagList.add(basefontTag.localName().impl());
tagList.add(brTag.localName().impl());
tagList.add(scriptTag.localName().impl());
+ tagList.add(styleTag.localName().impl());
+ tagList.add(linkTag.localName().impl());
tagList.add(mapTag.localName().impl());
tagList.add(qTag.localName().impl());
tagList.add(subTag.localName().impl());
@@ -803,8 +885,10 @@ HashSet<AtomicStringImpl*>* inlineTagList()
tagList.add(delTag.localName().impl());
tagList.add(nobrTag.localName().impl());
tagList.add(wbrTag.localName().impl());
+#if ENABLE(VIDEO)
tagList.add(audioTag.localName().impl());
tagList.add(videoTag.localName().impl());
+#endif
}
return &tagList;
}
@@ -902,12 +986,6 @@ bool HTMLElement::checkDTD(const Node* newChild)
return true;
return inEitherTagList(newChild);
}
-
-void HTMLElement::setHTMLEventListener(const AtomicString& eventType, Attribute* attr)
-{
- Element::setHTMLEventListener(eventType,
- document()->createHTMLEventListener(attr->localName().domString(), attr->value(), this));
-}
bool HTMLElement::rendererIsNeeded(RenderStyle *style)
{
diff --git a/WebCore/html/HTMLElement.h b/WebCore/html/HTMLElement.h
index 729dd91..1fba130 100644
--- a/WebCore/html/HTMLElement.h
+++ b/WebCore/html/HTMLElement.h
@@ -59,6 +59,8 @@ public:
void setDir(const String&);
String className() const;
void setClassName(const String&);
+ virtual short tabIndex() const;
+ void setTabIndex(int);
String innerHTML() const;
String outerHTML() const;
@@ -67,7 +69,11 @@ public:
void setOuterHTML(const String&, ExceptionCode&);
void setInnerText(const String&, ExceptionCode&);
void setOuterText(const String&, ExceptionCode&);
-
+
+ Element* insertAdjacentElement(const String& where, Element* newChild, ExceptionCode&);
+ void insertAdjacentHTML(const String& where, const String& html, ExceptionCode&);
+ void insertAdjacentText(const String& where, const String& text, ExceptionCode&);
+
virtual bool isFocusable() const;
virtual bool isContentEditable() const;
virtual bool isContentRichlyEditable() const;
@@ -81,8 +87,6 @@ public:
virtual bool isGenericFormElement() const { return false; }
- virtual String toString() const;
-
virtual HTMLTagStatus endTagRequirement() const;
virtual int tagPriority() const;
virtual bool childAllowed(Node* newChild); // Error-checking during parsing that checks the DTD
@@ -94,8 +98,6 @@ public:
static bool inBlockTagList(const Node*);
static bool isRecognizedTagName(const QualifiedName&);
- void setHTMLEventListener(const AtomicString& eventType, Attribute*);
-
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
@@ -107,8 +109,9 @@ protected:
private:
virtual HTMLFormElement* virtualForm() const;
+ Node* insertAdjacent(const String& where, Node* newChild, ExceptionCode&);
};
-} //namespace
+} // namespace WebCore
-#endif
+#endif // HTMLElement_h
diff --git a/WebCore/html/HTMLElement.idl b/WebCore/html/HTMLElement.idl
index 819b610..8ce5542 100644
--- a/WebCore/html/HTMLElement.idl
+++ b/WebCore/html/HTMLElement.idl
@@ -35,6 +35,10 @@ module html {
attribute [ConvertNullToNullString] DOMString dir;
attribute [ConvertNullToNullString] DOMString className;
+ attribute long tabIndex;
+ void blur();
+ void focus();
+
// Extensions
attribute [ConvertNullToNullString] DOMString innerHTML
setter raises(DOMException);
@@ -45,6 +49,16 @@ module html {
attribute [ConvertNullToNullString] DOMString outerText
setter raises(DOMException);
+ Element insertAdjacentElement(in DOMString where,
+ in Element element)
+ raises(DOMException);
+ void insertAdjacentHTML(in DOMString where,
+ in DOMString html)
+ raises(DOMException);
+ void insertAdjacentText(in DOMString where,
+ in DOMString text)
+ raises(DOMException);
+
readonly attribute HTMLCollection children;
attribute [ConvertNullToNullString] DOMString contentEditable;
diff --git a/WebCore/html/HTMLElementFactory.cpp b/WebCore/html/HTMLElementFactory.cpp
index e8a2bbe..1b9b0cc 100644
--- a/WebCore/html/HTMLElementFactory.cpp
+++ b/WebCore/html/HTMLElementFactory.cpp
@@ -113,9 +113,11 @@ static PassRefPtr<HTMLElement> baseConstructor(const AtomicString&, Document* do
return new HTMLBaseElement(doc);
}
-static PassRefPtr<HTMLElement> linkConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool)
+static PassRefPtr<HTMLElement> linkConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool createdByParser)
{
- return new HTMLLinkElement(doc);
+ RefPtr<HTMLLinkElement> link = new HTMLLinkElement(doc);
+ link->setCreatedByParser(createdByParser);
+ return link.release();
}
static PassRefPtr<HTMLElement> metaConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool)
@@ -135,9 +137,11 @@ static PassRefPtr<HTMLElement> titleConstructor(const AtomicString&, Document* d
return new HTMLTitleElement(doc);
}
-static PassRefPtr<HTMLElement> frameConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool)
+static PassRefPtr<HTMLElement> frameConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool createdByParser)
{
- return new HTMLFrameElement(doc);
+ RefPtr<HTMLFrameElement> frame = new HTMLFrameElement(doc);
+ frame->setCreatedByParser(createdByParser);
+ return frame.release();
}
static PassRefPtr<HTMLElement> framesetConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool)
@@ -145,9 +149,11 @@ static PassRefPtr<HTMLElement> framesetConstructor(const AtomicString&, Document
return new HTMLFrameSetElement(doc);
}
-static PassRefPtr<HTMLElement> iframeConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool)
+static PassRefPtr<HTMLElement> iframeConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool createdByParser)
{
- return new HTMLIFrameElement(doc);
+ RefPtr<HTMLIFrameElement> iFrame = new HTMLIFrameElement(doc);
+ iFrame->setCreatedByParser(createdByParser);
+ return iFrame.release();
}
static PassRefPtr<HTMLElement> formConstructor(const AtomicString&, Document* doc, HTMLFormElement*, bool)
diff --git a/WebCore/html/HTMLEmbedElement.cpp b/WebCore/html/HTMLEmbedElement.cpp
index eb449fc..7ffe3b1 100644
--- a/WebCore/html/HTMLEmbedElement.cpp
+++ b/WebCore/html/HTMLEmbedElement.cpp
@@ -1,11 +1,9 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,24 +20,28 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLEmbedElement.h"
#include "CSSHelper.h"
#include "CSSPropertyNames.h"
#include "Frame.h"
-#include "FrameView.h"
#include "HTMLDocument.h"
-#include "HTMLObjectElement.h"
+#include "HTMLImageLoader.h"
#include "HTMLNames.h"
+#include "HTMLObjectElement.h"
+#include "RenderImage.h"
#include "RenderPartObject.h"
+#include "RenderWidget.h"
+#include "ScriptController.h"
namespace WebCore {
using namespace HTMLNames;
HTMLEmbedElement::HTMLEmbedElement(Document* doc)
- : HTMLPlugInElement(embedTag, doc)
+ : HTMLPlugInImageElement(embedTag, doc)
, m_needWidgetUpdate(false)
{
}
@@ -48,52 +50,36 @@ HTMLEmbedElement::~HTMLEmbedElement()
{
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
if (oldNameIdCount && document()->isHTMLDocument()) {
HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeNamedItem(oldNameAttr);
+ doc->removeNamedItem(m_name);
}
#endif
-
-#if USE(JAVASCRIPTCORE_BINDINGS)
- // m_instance should have been cleaned up in detach().
- ASSERT(!m_instance);
-#endif
}
-#if USE(JAVASCRIPTCORE_BINDINGS)
static inline RenderWidget* findWidgetRenderer(const Node* n)
{
if (!n->renderer())
do
n = n->parentNode();
while (n && !n->hasTagName(objectTag));
-
- return (n && n->renderer() && n->renderer()->isWidget())
- ? static_cast<RenderWidget*>(n->renderer()) : 0;
+
+ if (n && n->renderer() && n->renderer()->isWidget())
+ return static_cast<RenderWidget*>(n->renderer());
+
+ return 0;
}
-
-KJS::Bindings::Instance *HTMLEmbedElement::getInstance() const
-{
- Frame* frame = document()->frame();
- if (!frame)
- return 0;
- if (m_instance)
- return m_instance.get();
-
+RenderWidget* HTMLEmbedElement::renderWidgetForJSBindings() const
+{
RenderWidget* renderWidget = findWidgetRenderer(this);
if (renderWidget && !renderWidget->widget()) {
document()->updateLayoutIgnorePendingStylesheets();
renderWidget = findWidgetRenderer(this);
}
-
- if (renderWidget && renderWidget->widget())
- m_instance = frame->createScriptInstanceForWidget(renderWidget->widget());
-
- return m_instance.get();
+ return renderWidget;
}
-#endif
bool HTMLEmbedElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
@@ -107,42 +93,54 @@ bool HTMLEmbedElement::mapToEntry(const QualifiedName& attrName, MappedAttribute
void HTMLEmbedElement::parseMappedAttribute(MappedAttribute* attr)
{
- String val = attr->value();
+ const AtomicString& value = attr->value();
if (attr->name() == typeAttr) {
- m_serviceType = val.lower();
+ m_serviceType = value.string().lower();
int pos = m_serviceType.find(";");
if (pos != -1)
m_serviceType = m_serviceType.left(pos);
- } else if (attr->name() == codeAttr || attr->name() == srcAttr)
- url = parseURL(val).deprecatedString();
- else if (attr->name() == pluginpageAttr || attr->name() == pluginspageAttr)
- m_pluginPage = val;
+ if (!isImageType() && m_imageLoader)
+ m_imageLoader.clear();
+ } else if (attr->name() == codeAttr)
+ m_url = parseURL(value.string());
+ else if (attr->name() == srcAttr) {
+ m_url = parseURL(value.string());
+ if (renderer() && isImageType()) {
+ if (!m_imageLoader)
+ m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElement();
+ }
+ } else if (attr->name() == pluginpageAttr || attr->name() == pluginspageAttr)
+ m_pluginPage = value;
else if (attr->name() == hiddenAttr) {
- if (val.lower() == "yes" || val.lower() == "true") {
- // FIXME: Not dynamic, but it's not really important that such a rarely-used
- // feature work dynamically.
- addCSSLength(attr, CSS_PROP_WIDTH, "0");
- addCSSLength(attr, CSS_PROP_HEIGHT, "0");
+ if (equalIgnoringCase(value.string(), "yes") || equalIgnoringCase(value.string(), "true")) {
+ // FIXME: Not dynamic, since we add this but don't remove it, but it may be OK for now
+ // that this rarely-used attribute won't work properly if you remove it.
+ addCSSLength(attr, CSSPropertyWidth, "0");
+ addCSSLength(attr, CSSPropertyHeight, "0");
}
} else if (attr->name() == nameAttr) {
if (inDocument() && document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->addNamedItem(val);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(value);
}
- oldNameAttr = val;
+ m_name = value;
} else
HTMLPlugInElement::parseMappedAttribute(attr);
}
-bool HTMLEmbedElement::rendererIsNeeded(RenderStyle *style)
+bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style)
{
- Frame *frame = document()->frame();
+ if (isImageType())
+ return HTMLPlugInElement::rendererIsNeeded(style);
+
+ Frame* frame = document()->frame();
if (!frame)
return false;
- Node *p = parentNode();
+ Node* p = parentNode();
if (p && p->hasTagName(objectTag)) {
ASSERT(p->renderer());
return false;
@@ -151,43 +149,51 @@ bool HTMLEmbedElement::rendererIsNeeded(RenderStyle *style)
return true;
}
-RenderObject *HTMLEmbedElement::createRenderer(RenderArena *arena, RenderStyle *style)
+RenderObject* HTMLEmbedElement::createRenderer(RenderArena* arena, RenderStyle* style)
{
+ if (isImageType())
+ return new (arena) RenderImage(this);
return new (arena) RenderPartObject(this);
}
void HTMLEmbedElement::attach()
{
m_needWidgetUpdate = true;
- queuePostAttachCallback(&HTMLPlugInElement::updateWidgetCallback, this);
+
+ bool isImage = isImageType();
+
+ if (!isImage)
+ queuePostAttachCallback(&HTMLPlugInElement::updateWidgetCallback, this);
+
HTMLPlugInElement::attach();
-}
-void HTMLEmbedElement::detach()
-{
-#if USE(JAVASCRIPTCORE_BINDINGS)
- m_instance = 0;
-#endif
- HTMLPlugInElement::detach();
+ if (isImage && renderer()) {
+ if (!m_imageLoader)
+ m_imageLoader.set(new HTMLImageLoader(this));
+ m_imageLoader->updateFromElement();
+
+ if (renderer())
+ static_cast<RenderImage*>(renderer())->setCachedImage(m_imageLoader->image());
+ }
}
void HTMLEmbedElement::updateWidget()
{
- if (m_needWidgetUpdate && renderer())
+ document()->updateRendering();
+ if (m_needWidgetUpdate && renderer() && !isImageType())
static_cast<RenderPartObject*>(renderer())->updateWidget(true);
}
void HTMLEmbedElement::insertedIntoDocument()
{
- if (document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->addNamedItem(oldNameAttr);
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->addNamedItem(m_name);
#ifdef ANDROID_FIX
- // addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
+ if (document()->isHTMLDocument())
oldNameIdCount++;
#endif
- }
String width = getAttribute(widthAttr);
String height = getAttribute(heightAttr);
@@ -208,15 +214,14 @@ void HTMLEmbedElement::insertedIntoDocument()
void HTMLEmbedElement::removedFromDocument()
{
- if (document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeNamedItem(oldNameAttr);
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->removeNamedItem(m_name);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
+ if (document()->isHTMLDocument())
oldNameIdCount--;
#endif
- }
HTMLPlugInElement::removedFromDocument();
}
@@ -234,11 +239,16 @@ void HTMLEmbedElement::attributeChanged(Attribute* attr, bool preserveDecls)
}
}
-bool HTMLEmbedElement::isURLAttribute(Attribute *attr) const
+bool HTMLEmbedElement::isURLAttribute(Attribute* attr) const
{
return attr->name() == srcAttr;
}
+const QualifiedName& HTMLEmbedElement::imageSourceAttributeName() const
+{
+ return srcAttr;
+}
+
String HTMLEmbedElement::src() const
{
return getAttribute(srcAttr);
@@ -259,4 +269,9 @@ void HTMLEmbedElement::setType(const String& value)
setAttribute(typeAttr, value);
}
+void HTMLEmbedElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ urls.append(src());
+}
+
}
diff --git a/WebCore/html/HTMLEmbedElement.h b/WebCore/html/HTMLEmbedElement.h
index 8645489..2f45998 100644
--- a/WebCore/html/HTMLEmbedElement.h
+++ b/WebCore/html/HTMLEmbedElement.h
@@ -1,9 +1,7 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 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
@@ -25,15 +23,11 @@
#ifndef HTMLEmbedElement_h
#define HTMLEmbedElement_h
-#include "HTMLPlugInElement.h"
-
-#if USE(JAVASCRIPTCORE_BINDINGS)
-#include <bindings/runtime.h>
-#endif
+#include "HTMLPlugInImageElement.h"
namespace WebCore {
-class HTMLEmbedElement : public HTMLPlugInElement {
+class HTMLEmbedElement : public HTMLPlugInImageElement {
public:
HTMLEmbedElement(Document*);
~HTMLEmbedElement();
@@ -45,7 +39,7 @@ public:
virtual void parseMappedAttribute(MappedAttribute*);
virtual void attach();
- virtual void detach();
+ virtual bool canLazyAttach() { return false; }
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual void insertedIntoDocument();
@@ -53,13 +47,12 @@ public:
virtual void attributeChanged(Attribute*, bool preserveDecls = false);
virtual bool isURLAttribute(Attribute*) const;
+ virtual const QualifiedName& imageSourceAttributeName() const;
virtual void updateWidget();
void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
-#if USE(JAVASCRIPTCORE_BINDINGS)
- virtual KJS::Bindings::Instance* getInstance() const;
-#endif
+ virtual RenderWidget* renderWidgetForJSBindings() const;
String src() const;
void setSrc(const String&);
@@ -67,9 +60,10 @@ public:
String type() const;
void setType(const String&);
- DeprecatedString url;
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
+private:
String m_pluginPage;
- String m_serviceType;
bool m_needWidgetUpdate;
};
diff --git a/WebCore/html/HTMLFieldSetElement.cpp b/WebCore/html/HTMLFieldSetElement.cpp
index 00ae7fa..c4594de 100644
--- a/WebCore/html/HTMLFieldSetElement.cpp
+++ b/WebCore/html/HTMLFieldSetElement.cpp
@@ -35,7 +35,7 @@ namespace WebCore {
using namespace HTMLNames;
HTMLFieldSetElement::HTMLFieldSetElement(Document *doc, HTMLFormElement *f)
- : HTMLGenericFormElement(fieldsetTag, doc, f)
+ : HTMLFormControlElement(fieldsetTag, doc, f)
{
}
@@ -50,7 +50,7 @@ bool HTMLFieldSetElement::checkDTD(const Node* newChild)
bool HTMLFieldSetElement::isFocusable() const
{
- return false;
+ return HTMLElement::isFocusable();
}
const AtomicString& HTMLFieldSetElement::type() const
diff --git a/WebCore/html/HTMLFieldSetElement.h b/WebCore/html/HTMLFieldSetElement.h
index 645b173..637a2ff 100644
--- a/WebCore/html/HTMLFieldSetElement.h
+++ b/WebCore/html/HTMLFieldSetElement.h
@@ -26,7 +26,7 @@
#ifndef HTMLFieldSetElement_h
#define HTMLFieldSetElement_h
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
namespace WebCore {
class RenderStyle;
@@ -38,7 +38,7 @@ class HTMLFormElement;
class Document;
class Node;
-class HTMLFieldSetElement : public HTMLGenericFormElement {
+class HTMLFieldSetElement : public HTMLFormControlElement {
public:
HTMLFieldSetElement(Document*, HTMLFormElement* = 0);
virtual ~HTMLFieldSetElement();
@@ -49,6 +49,8 @@ public:
virtual bool isFocusable() const;
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual const AtomicString& type() const;
+
+ virtual bool willValidate() const { return false; }
};
} //namespace
diff --git a/WebCore/html/HTMLFieldSetElement.idl b/WebCore/html/HTMLFieldSetElement.idl
index 80f8e8e..c48f8d6 100644
--- a/WebCore/html/HTMLFieldSetElement.idl
+++ b/WebCore/html/HTMLFieldSetElement.idl
@@ -25,6 +25,7 @@ module html {
ImplementationUUID=93573758-96db-415d-9bdc-ee7238604094
] HTMLFieldSetElement : HTMLElement {
readonly attribute HTMLFormElement form;
+ readonly attribute boolean willValidate;
};
}
diff --git a/WebCore/html/HTMLFontElement.cpp b/WebCore/html/HTMLFontElement.cpp
index c776f15..b32f492 100644
--- a/WebCore/html/HTMLFontElement.cpp
+++ b/WebCore/html/HTMLFontElement.cpp
@@ -1,10 +1,8 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2003, 2006 Apple Computer, Inc.
+ * Copyright (C) 2003, 2006, 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
@@ -35,12 +33,8 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLFontElement::HTMLFontElement(Document* doc)
- : HTMLElement(fontTag, doc)
-{
-}
-
-HTMLFontElement::~HTMLFontElement()
+HTMLFontElement::HTMLFontElement(Document* document)
+ : HTMLElement(fontTag, document)
{
}
@@ -67,12 +61,12 @@ static bool parseFontSizeNumber(const String& s, int& size)
}
// Parse a single digit.
- if (!Unicode::isDigit(s[pos]))
+ if (!isASCIIDigit(s[pos]))
return false;
- int num = Unicode::digitValue(s[pos++]);
+ int num = s[pos++] - '0';
// Check for an additional digit.
- if (Unicode::isDigit(s[pos]))
+ if (isASCIIDigit(s[pos]))
num = 10;
if (sawPlus) {
@@ -110,26 +104,26 @@ bool HTMLFontElement::cssValueFromFontSizeNumber(const String& s, int& size)
switch (num) {
case 2:
- size = CSS_VAL_SMALL;
+ size = CSSValueSmall;
break;
case 0: // treat 0 the same as 3, because people expect it to be between -1 and +1
case 3:
- size = CSS_VAL_MEDIUM;
+ size = CSSValueMedium;
break;
case 4:
- size = CSS_VAL_LARGE;
+ size = CSSValueLarge;
break;
case 5:
- size = CSS_VAL_X_LARGE;
+ size = CSSValueXLarge;
break;
case 6:
- size = CSS_VAL_XX_LARGE;
+ size = CSSValueXxLarge;
break;
default:
if (num > 6)
- size = CSS_VAL__WEBKIT_XXX_LARGE;
+ size = CSSValueWebkitXxxLarge;
else
- size = CSS_VAL_X_SMALL;
+ size = CSSValueXSmall;
}
return true;
}
@@ -139,11 +133,11 @@ void HTMLFontElement::parseMappedAttribute(MappedAttribute *attr)
if (attr->name() == sizeAttr) {
int size;
if (cssValueFromFontSizeNumber(attr->value(), size))
- addCSSProperty(attr, CSS_PROP_FONT_SIZE, size);
+ addCSSProperty(attr, CSSPropertyFontSize, size);
} else if (attr->name() == colorAttr) {
- addCSSColor(attr, CSS_PROP_COLOR, attr->value());
+ addCSSColor(attr, CSSPropertyColor, attr->value());
} else if (attr->name() == faceAttr) {
- addCSSProperty(attr, CSS_PROP_FONT_FAMILY, attr->value());
+ addCSSProperty(attr, CSSPropertyFontFamily, attr->value());
} else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLFontElement.h b/WebCore/html/HTMLFontElement.h
index fd889f7..272f63c 100644
--- a/WebCore/html/HTMLFontElement.h
+++ b/WebCore/html/HTMLFontElement.h
@@ -1,6 +1,4 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
@@ -28,13 +26,9 @@
namespace WebCore {
-class String;
-
-class HTMLFontElement : public HTMLElement
-{
+class HTMLFontElement : public HTMLElement {
public:
HTMLFontElement(Document*);
- ~HTMLFontElement();
virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
virtual int tagPriority() const { return 1; }
diff --git a/WebCore/html/HTMLFormCollection.cpp b/WebCore/html/HTMLFormCollection.cpp
index fa69710..823291a 100644
--- a/WebCore/html/HTMLFormCollection.cpp
+++ b/WebCore/html/HTMLFormCollection.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "HTMLFormCollection.h"
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
#include "HTMLFormElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
@@ -47,6 +47,11 @@ HTMLFormCollection::HTMLFormCollection(PassRefPtr<HTMLFormElement> form)
{
}
+PassRefPtr<HTMLFormCollection> HTMLFormCollection::create(PassRefPtr<HTMLFormElement> form)
+{
+ return adoptRef(new HTMLFormCollection(form));
+}
+
HTMLFormCollection::~HTMLFormCollection()
{
}
@@ -72,7 +77,7 @@ Node* HTMLFormCollection::item(unsigned index) const
info()->elementsArrayPosition = 0;
}
- Vector<HTMLGenericFormElement*>& l = static_cast<HTMLFormElement*>(base())->formElements;
+ Vector<HTMLFormControlElement*>& l = static_cast<HTMLFormElement*>(base())->formElements;
unsigned currentIndex = info()->position;
for (unsigned i = info()->elementsArrayPosition; i < l.size(); i++) {
@@ -103,13 +108,13 @@ Element* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, con
bool foundInputElements = false;
for (unsigned i = 0; i < form->formElements.size(); ++i) {
- HTMLGenericFormElement* e = form->formElements[i];
+ HTMLFormControlElement* e = form->formElements[i];
if (e->isEnumeratable()) {
bool found;
if (caseSensitive)
found = e->getAttribute(attrName) == name;
else
- found = e->getAttribute(attrName).domString().lower() == name.lower();
+ found = equalIgnoringCase(e->getAttribute(attrName), name);
if (found) {
foundInputElements = true;
if (!duplicateNumber)
@@ -126,7 +131,7 @@ Element* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, con
if (caseSensitive)
found = e->getAttribute(attrName) == name;
else
- found = e->getAttribute(attrName).domString().lower() == name.lower();
+ found = equalIgnoringCase(e->getAttribute(attrName), name);
if (found) {
if (!duplicateNumber)
return e;
@@ -195,7 +200,7 @@ void HTMLFormCollection::updateNameCache() const
HTMLFormElement* f = static_cast<HTMLFormElement*>(base());
for (unsigned i = 0; i < f->formElements.size(); ++i) {
- HTMLGenericFormElement* e = f->formElements[i];
+ HTMLFormControlElement* e = f->formElements[i];
if (e->isEnumeratable()) {
const AtomicString& idAttrVal = e->getAttribute(idAttr);
const AtomicString& nameAttrVal = e->getAttribute(nameAttr);
diff --git a/WebCore/html/HTMLFormCollection.h b/WebCore/html/HTMLFormCollection.h
index ae2fb11..b81138f 100644
--- a/WebCore/html/HTMLFormCollection.h
+++ b/WebCore/html/HTMLFormCollection.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * 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
@@ -35,8 +35,9 @@ class QualifiedName;
class HTMLFormCollection : public HTMLCollection {
public:
- HTMLFormCollection(PassRefPtr<HTMLFormElement>);
- ~HTMLFormCollection();
+ static PassRefPtr<HTMLFormCollection> create(PassRefPtr<HTMLFormElement>);
+
+ virtual ~HTMLFormCollection();
virtual Node* item(unsigned index) const;
virtual Node* nextItem() const;
@@ -45,6 +46,8 @@ public:
virtual Node* nextNamedItem(const String& name) const;
private:
+ HTMLFormCollection(PassRefPtr<HTMLFormElement>);
+
virtual void updateNameCache() const;
virtual unsigned calcLength() const;
diff --git a/WebCore/html/HTMLGenericFormElement.cpp b/WebCore/html/HTMLFormControlElement.cpp
index 2eab0a8..8e879fd 100644
--- a/WebCore/html/HTMLGenericFormElement.cpp
+++ b/WebCore/html/HTMLFormControlElement.cpp
@@ -23,7 +23,7 @@
*/
#include "config.h"
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
#include "Document.h"
#include "EventHandler.h"
@@ -37,16 +37,11 @@
#include "RenderTheme.h"
#include "Tokenizer.h"
-#if USE(LOW_BANDWIDTH_DISPLAY)
-#include "FrameLoader.h"
-#endif
-
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
-HTMLGenericFormElement::HTMLGenericFormElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
+HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
: HTMLElement(tagName, doc)
, m_form(f)
, m_disabled(false)
@@ -59,13 +54,13 @@ HTMLGenericFormElement::HTMLGenericFormElement(const QualifiedName& tagName, Doc
m_form->registerFormElement(this);
}
-HTMLGenericFormElement::~HTMLGenericFormElement()
+HTMLFormControlElement::~HTMLFormControlElement()
{
if (m_form)
m_form->removeFormElement(this);
}
-void HTMLGenericFormElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLFormControlElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == nameAttr) {
// Do nothing.
@@ -89,7 +84,7 @@ void HTMLGenericFormElement::parseMappedAttribute(MappedAttribute *attr)
HTMLElement::parseMappedAttribute(attr);
}
-void HTMLGenericFormElement::attach()
+void HTMLFormControlElement::attach()
{
ASSERT(!attached());
@@ -100,9 +95,17 @@ void HTMLGenericFormElement::attach()
// on the renderer.
if (renderer())
renderer()->updateFromElement();
+
+ // Focus the element if it should honour its autofocus attribute.
+ // We have to determine if the element is a TextArea/Input/Button/Select,
+ // if input type hidden ignore autofocus. So if disabled or readonly.
+ if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyControl() &&
+ ((hasTagName(inputTag) && !isInputTypeHidden()) || hasTagName(selectTag) ||
+ hasTagName(buttonTag) || hasTagName(textareaTag)))
+ focus();
}
-void HTMLGenericFormElement::insertedIntoTree(bool deep)
+void HTMLFormControlElement::insertedIntoTree(bool deep)
{
if (!m_form) {
// This handles the case of a new form element being created by
@@ -127,7 +130,7 @@ static inline Node* findRoot(Node* n)
return root;
}
-void HTMLGenericFormElement::removedFromTree(bool deep)
+void HTMLFormControlElement::removedFromTree(bool deep)
{
// If the form and element are both in the same tree, preserve the connection to the form.
// Otherwise, null out our form and remove ourselves from the form's list of elements.
@@ -144,38 +147,48 @@ void HTMLGenericFormElement::removedFromTree(bool deep)
HTMLElement::removedFromTree(deep);
}
-const AtomicString& HTMLGenericFormElement::name() const
+const AtomicString& HTMLFormControlElement::name() const
{
const AtomicString& n = getAttribute(nameAttr);
return n.isNull() ? emptyAtom : n;
}
-void HTMLGenericFormElement::setName(const AtomicString &value)
+void HTMLFormControlElement::setName(const AtomicString &value)
{
setAttribute(nameAttr, value);
}
-void HTMLGenericFormElement::onChange()
+void HTMLFormControlElement::onChange()
{
- dispatchHTMLEvent(changeEvent, true, false);
+ dispatchEventForType(eventNames().changeEvent, true, false);
}
-bool HTMLGenericFormElement::disabled() const
+bool HTMLFormControlElement::disabled() const
{
return m_disabled;
}
-void HTMLGenericFormElement::setDisabled(bool b)
+void HTMLFormControlElement::setDisabled(bool b)
{
setAttribute(disabledAttr, b ? "" : 0);
}
-void HTMLGenericFormElement::setReadOnly(bool b)
+void HTMLFormControlElement::setReadOnly(bool b)
{
setAttribute(readonlyAttr, b ? "" : 0);
}
-void HTMLGenericFormElement::recalcStyle(StyleChange change)
+bool HTMLFormControlElement::autofocus() const
+{
+ return hasAttribute(autofocusAttr);
+}
+
+void HTMLFormControlElement::setAutofocus(bool b)
+{
+ setAttribute(autofocusAttr, b ? "autofocus" : 0);
+}
+
+void HTMLFormControlElement::recalcStyle(StyleChange change)
{
HTMLElement::recalcStyle(change);
@@ -183,7 +196,7 @@ void HTMLGenericFormElement::recalcStyle(StyleChange change)
renderer()->updateFromElement();
}
-bool HTMLGenericFormElement::isFocusable() const
+bool HTMLFormControlElement::isFocusable() const
{
if (disabled() || !renderer() ||
(renderer()->style() && renderer()->style()->visibility() != VISIBLE) ||
@@ -192,7 +205,7 @@ bool HTMLGenericFormElement::isFocusable() const
return true;
}
-bool HTMLGenericFormElement::isKeyboardFocusable(KeyboardEvent* event) const
+bool HTMLFormControlElement::isKeyboardFocusable(KeyboardEvent* event) const
{
if (isFocusable())
if (document()->frame())
@@ -200,27 +213,41 @@ bool HTMLGenericFormElement::isKeyboardFocusable(KeyboardEvent* event) const
return false;
}
-bool HTMLGenericFormElement::isMouseFocusable() const
+bool HTMLFormControlElement::isMouseFocusable() const
{
+#if PLATFORM(GTK)
+ return HTMLElement::isMouseFocusable();
+#else
return false;
+#endif
}
-void HTMLGenericFormElement::setTabIndex(int value)
+short HTMLFormControlElement::tabIndex() const
{
- setAttribute(tabindexAttr, String::number(value));
+ // Skip the supportsFocus check in HTMLElement.
+ return Element::tabIndex();
+}
+
+bool HTMLFormControlElement::willValidate() const
+{
+ // FIXME: Implementation shall be completed with these checks:
+ // 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();
}
-bool HTMLGenericFormElement::supportsFocus() const
+bool HTMLFormControlElement::supportsFocus() const
{
return isFocusable() || (!disabled() && !document()->haveStylesheetsLoaded());
}
-HTMLFormElement* HTMLGenericFormElement::virtualForm() const
+HTMLFormElement* HTMLFormControlElement::virtualForm() const
{
return m_form;
}
-void HTMLGenericFormElement::removeFromForm()
+void HTMLFormControlElement::removeFromForm()
{
if (!m_form)
return;
@@ -229,7 +256,7 @@ void HTMLGenericFormElement::removeFromForm()
}
HTMLFormControlElementWithState::HTMLFormControlElementWithState(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
- : HTMLGenericFormElement(tagName, doc, f)
+ : HTMLFormControlElement(tagName, doc, f)
{
doc->registerFormElementWithState(this);
}
@@ -242,18 +269,18 @@ HTMLFormControlElementWithState::~HTMLFormControlElementWithState()
void HTMLFormControlElementWithState::willMoveToNewOwnerDocument()
{
document()->unregisterFormElementWithState(this);
- HTMLGenericFormElement::willMoveToNewOwnerDocument();
+ HTMLFormControlElement::willMoveToNewOwnerDocument();
}
void HTMLFormControlElementWithState::didMoveToNewOwnerDocument()
{
document()->registerFormElementWithState(this);
- HTMLGenericFormElement::didMoveToNewOwnerDocument();
+ HTMLFormControlElement::didMoveToNewOwnerDocument();
}
void HTMLFormControlElementWithState::finishParsingChildren()
{
- HTMLGenericFormElement::finishParsingChildren();
+ HTMLFormControlElement::finishParsingChildren();
Document* doc = document();
if (doc->hasStateForNewFormElements()) {
String state;
@@ -262,15 +289,4 @@ void HTMLFormControlElementWithState::finishParsingChildren()
}
}
-#if USE(LOW_BANDWIDTH_DISPLAY)
-bool HTMLGenericFormElement::rendererIsNeeded(RenderStyle* style)
-{
- if (document()->inLowBandwidthDisplay()) {
- document()->frame()->loader()->needToSwitchOutLowBandwidthDisplay();
- return false;
- }
- return HTMLElement::rendererIsNeeded(style);
-}
-#endif
-
} // namespace Webcore
diff --git a/WebCore/html/HTMLGenericFormElement.h b/WebCore/html/HTMLFormControlElement.h
index ec18aa9..0978a90 100644
--- a/WebCore/html/HTMLGenericFormElement.h
+++ b/WebCore/html/HTMLFormControlElement.h
@@ -21,8 +21,8 @@
*
*/
-#ifndef HTMLGenericFormElement_h
-#define HTMLGenericFormElement_h
+#ifndef HTMLFormControlElement_h
+#define HTMLFormControlElement_h
#include "HTMLElement.h"
@@ -31,11 +31,10 @@ namespace WebCore {
class FormDataList;
class HTMLFormElement;
-// FIXME: Rename this class to HTMLFormControlElement.
-class HTMLGenericFormElement : public HTMLElement {
+class HTMLFormControlElement : public HTMLElement {
public:
- HTMLGenericFormElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
- virtual ~HTMLGenericFormElement();
+ HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
+ virtual ~HTMLFormControlElement();
virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
virtual int tagPriority() const { return 1; }
@@ -71,6 +70,10 @@ public:
virtual bool isReadOnlyControl() const { return m_readOnly; }
void setReadOnly(bool);
+ // Determines whether or not a control will be automatically focused
+ virtual bool autofocus() const;
+ void setAutofocus(bool);
+
virtual void recalcStyle(StyleChange);
virtual const AtomicString& name() const;
@@ -88,11 +91,9 @@ public:
virtual bool isActivatedSubmit() const { return false; }
virtual void setActivatedSubmit(bool flag) { }
-#if USE(LOW_BANDWIDTH_DISPLAY)
- virtual bool rendererIsNeeded(RenderStyle*);
-#endif
+ virtual short tabIndex() const;
- void setTabIndex(int);
+ virtual bool willValidate() const;
void formDestroyed() { m_form = 0; }
@@ -108,7 +109,7 @@ private:
mutable bool m_valueMatchesRenderer;
};
-class HTMLFormControlElementWithState : public HTMLGenericFormElement {
+class HTMLFormControlElementWithState : public HTMLFormControlElement {
public:
HTMLFormControlElementWithState(const QualifiedName& tagName, Document*, HTMLFormElement*);
virtual ~HTMLFormControlElementWithState();
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index 267c3bf..28ea290 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 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
* This library is free software; you can redistribute it and/or
@@ -25,11 +25,13 @@
#include "config.h"
#include "HTMLFormElement.h"
-#include "Base64.h"
#include "CSSHelper.h"
-#include "CString.h"
+#include "ChromeClient.h"
+#include "Document.h"
#include "Event.h"
#include "EventNames.h"
+#include "FileList.h"
+#include "FileSystem.h"
#include "FormData.h"
#include "FormDataList.h"
#include "Frame.h"
@@ -40,6 +42,7 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "MIMETypeRegistry.h"
+#include "Page.h"
#include "RenderTextControl.h"
#if PLATFORM(QT)
@@ -57,9 +60,10 @@
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
+static const char hexDigits[17] = "0123456789ABCDEF";
+
HTMLFormElement::HTMLFormElement(Document* doc)
: HTMLElement(formTag, doc)
, m_elementAliases(0)
@@ -74,7 +78,7 @@ HTMLFormElement::HTMLFormElement(Document* doc)
, m_malformed(false)
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr is removed from HTMLDocument's NameCountMap
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
, oldNameCount(0)
#endif
{
@@ -84,27 +88,27 @@ HTMLFormElement::~HTMLFormElement()
{
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr is removed from HTMLDocument's NameCountMap
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
if (oldNameCount && document()->isHTMLDocument()) {
HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeNamedItem(oldNameAttr);
+ doc->removeNamedItem(m_name);
}
#endif
+ if (!m_autocomplete)
+ document()->unregisterForDocumentActivationCallbacks(this);
+
delete m_elementAliases;
delete collectionInfo;
-
+
for (unsigned i = 0; i < formElements.size(); ++i)
formElements[i]->formDestroyed();
for (unsigned i = 0; i < imgElements.size(); ++i)
imgElements[i]->m_form = 0;
}
-bool HTMLFormElement::formWouldHaveSecureSubmission(const String &url)
+bool HTMLFormElement::formWouldHaveSecureSubmission(const String& url)
{
- if (url.isNull()) {
- return false;
- }
- return document()->completeURL(url.deprecatedString()).startsWith("https:", false);
+ return document()->completeURL(url).protocolIs("https");
}
void HTMLFormElement::attach()
@@ -114,30 +118,28 @@ void HTMLFormElement::attach()
void HTMLFormElement::insertedIntoDocument()
{
- if (document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->addNamedItem(oldNameAttr);
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->addNamedItem(m_name);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr is removed from HTMLDocument's NameCountMap
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
+ if (document()->isHTMLDocument())
oldNameCount++;
#endif
- }
HTMLElement::insertedIntoDocument();
}
void HTMLFormElement::removedFromDocument()
{
- if (document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeNamedItem(oldNameAttr);
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->removeNamedItem(m_name);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr is removed from HTMLDocument's NameCountMap
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
+ if (document()->isHTMLDocument())
oldNameCount--;
#endif
- }
HTMLElement::removedFromDocument();
}
@@ -145,7 +147,7 @@ void HTMLFormElement::removedFromDocument()
void HTMLFormElement::handleLocalEvents(Event* event, bool useCapture)
{
EventTargetNode* targetNode = event->target()->toNode();
- if (!useCapture && targetNode && targetNode != this && (event->type() == submitEvent || event->type() == resetEvent)) {
+ if (!useCapture && targetNode && targetNode != this && (event->type() == eventNames().submitEvent || event->type() == eventNames().resetEvent)) {
event->stopPropagation();
return;
}
@@ -172,7 +174,7 @@ void HTMLFormElement::submitClick(Event* event)
bool submitFound = false;
for (unsigned i = 0; i < formElements.size(); ++i) {
if (formElements[i]->hasLocalName(inputTag)) {
- HTMLInputElement *element = static_cast<HTMLInputElement *>(formElements[i]);
+ HTMLInputElement* element = static_cast<HTMLInputElement*>(formElements[i]);
if (element->isSuccessfulSubmitButton() && element->renderer()) {
submitFound = true;
element->dispatchSimulatedClick(event);
@@ -184,48 +186,40 @@ void HTMLFormElement::submitClick(Event* event)
prepareSubmit(event);
}
-static DeprecatedCString encodeCString(const CString& cstr)
+static void appendString(Vector<char>& buffer, const char* string)
{
- DeprecatedCString e = cstr.deprecatedCString();
+ buffer.append(string, strlen(string));
+}
- // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
- // same safe characters as Netscape for compatibility
- static const char *safe = "-._*";
- int elen = e.length();
- DeprecatedCString encoded((elen + e.contains('\n')) * 3 + 1);
- int enclen = 0;
+static void appendString(Vector<char>& buffer, const CString& string)
+{
+ buffer.append(string.data(), string.length());
+}
- for (int pos = 0; pos < elen; pos++) {
- unsigned char c = e[pos];
+static void appendEncodedString(Vector<char>& buffer, const CString& string)
+{
+ // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
+ int length = string.length();
+ for (int i = 0; i < length; i++) {
+ unsigned char c = string.data()[i];
+ // Same safe characters as Netscape for compatibility.
+ static const char safe[] = "-._*";
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || strchr(safe, c))
- encoded[enclen++] = c;
+ buffer.append(c);
else if (c == ' ')
- encoded[enclen++] = '+';
- else if (c == '\n' || (c == '\r' && e[pos + 1] != '\n')) {
- encoded[enclen++] = '%';
- encoded[enclen++] = '0';
- encoded[enclen++] = 'D';
- encoded[enclen++] = '%';
- encoded[enclen++] = '0';
- encoded[enclen++] = 'A';
- } else if (c != '\r') {
- encoded[enclen++] = '%';
- unsigned int h = c / 16;
- h += (h > 9) ? ('A' - 10) : '0';
- encoded[enclen++] = h;
-
- unsigned int l = c % 16;
- l += (l > 9) ? ('A' - 10) : '0';
- encoded[enclen++] = l;
+ buffer.append('+');
+ else if (c == '\n' || (c == '\r' && (i + 1 >= length || string.data()[i + 1] != '\n')))
+ appendString(buffer, "%0D%0A");
+ else if (c != '\r') {
+ buffer.append('%');
+ buffer.append(hexDigits[c >> 4]);
+ buffer.append(hexDigits[c & 0xF]);
}
}
- encoded[enclen++] = '\0';
- encoded.truncate(enclen);
-
- return encoded;
}
+// FIXME: Move to platform directory?
static int randomNumber()
{
static bool randomSeeded = false;
@@ -245,22 +239,6 @@ static int randomNumber()
#endif
}
-// Warning: this helper doesn't currently have a reliable cross-platform behavior in certain edge cases
-// (see basename(3) specification for examples).
-// Consider this if it ever needs to become a general purpose method.
-static String pathGetFilename(String path)
-{
-#if PLATFORM(QT)
- return QFileInfo(path).fileName();
-#elif PLATFORM(WX)
- return wxFileName(path).GetFullName();
-#elif PLATFORM(WIN_OS)
- return String(PathFindFileName(path.charactersWithNullTermination()));
-#else
- return path.substring(path.reverseFind('/') + 1);
-#endif
-}
-
TextEncoding HTMLFormElement::dataEncoding() const
{
if (isMailtoForm())
@@ -269,7 +247,8 @@ TextEncoding HTMLFormElement::dataEncoding() const
TextEncoding encoding;
String str = m_acceptcharset;
str.replace(',', ' ');
- Vector<String> charsets = str.split(' ');
+ Vector<String> charsets;
+ str.split(' ', charsets);
Vector<String>::const_iterator end = charsets.end();
for (Vector<String>::const_iterator it = charsets.begin(); it != end; ++it)
if ((encoding = TextEncoding(*it)).isValid())
@@ -281,80 +260,89 @@ TextEncoding HTMLFormElement::dataEncoding() const
PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const
{
- DeprecatedCString enc_string = "";
+ Vector<char> encodedData;
TextEncoding encoding = dataEncoding();
- RefPtr<FormData> result = new FormData;
+ RefPtr<FormData> result = FormData::create();
for (unsigned i = 0; i < formElements.size(); ++i) {
- HTMLGenericFormElement* current = formElements[i];
- FormDataList lst(encoding);
-
- if (!current->disabled() && current->appendFormData(lst, m_multipart)) {
- size_t ln = lst.list().size();
- for (size_t j = 0; j < ln; ++j) {
- const FormDataListItem& item = lst.list()[j];
+ HTMLFormControlElement* control = formElements[i];
+ FormDataList list(encoding);
+
+ if (!control->disabled() && control->appendFormData(list, m_multipart)) {
+ size_t formDataListSize = list.list().size();
+ ASSERT(formDataListSize % 2 == 0);
+ for (size_t j = 0; j < formDataListSize; j += 2) {
+ const FormDataList::Item& key = list.list()[j];
+ const FormDataList::Item& value = list.list()[j + 1];
if (!m_multipart) {
- // handle ISINDEX / <input name=isindex> special
- // but only if its the first entry
- if (enc_string.isEmpty() && item.m_data == "isindex") {
- enc_string += encodeCString(lst.list()[j + 1].m_data);
- ++j;
- } else {
- if (!enc_string.isEmpty())
- enc_string += '&';
-
- enc_string += encodeCString(item.m_data);
- enc_string += "=";
- enc_string += encodeCString(lst.list()[j + 1].m_data);
- ++j;
+ // Omit the name "isindex" if it's the first form data element.
+ // FIXME: Why is this a good rule? Is this obsolete now?
+ if (encodedData.isEmpty() && key.data() == "isindex")
+ appendEncodedString(encodedData, value.data());
+ else {
+ if (!encodedData.isEmpty())
+ encodedData.append('&');
+ appendEncodedString(encodedData, key.data());
+ encodedData.append('=');
+ appendEncodedString(encodedData, value.data());
}
- }
- else
- {
- DeprecatedCString hstr("--");
- hstr += boundary;
- hstr += "\r\n";
- hstr += "Content-Disposition: form-data; name=\"";
- hstr += item.m_data.data();
- hstr += "\"";
-
+ } else {
+ Vector<char> header;
+ appendString(header, "--");
+ appendString(header, boundary);
+ appendString(header, "\r\n");
+ appendString(header, "Content-Disposition: form-data; name=\"");
+ header.append(key.data().data(), key.data().length());
+ header.append('"');
+
+ bool shouldGenerateFile = false;
// if the current type is FILE, then we also need to
// include the filename
- if (current->hasLocalName(inputTag) &&
- static_cast<HTMLInputElement*>(current)->inputType() == HTMLInputElement::FILE) {
- String path = static_cast<HTMLInputElement*>(current)->value();
- String filename = pathGetFilename(path);
+ if (value.file()) {
+ const String& path = value.file()->path();
+ String filename = value.file()->fileName();
+
+ // Let the application specify a filename if it's going to generate a replacement file for the upload.
+ if (!path.isEmpty()) {
+ if (Page* page = document()->page()) {
+ String generatedFilename;
+ shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFilename);
+ if (shouldGenerateFile)
+ filename = generatedFilename;
+ }
+ }
// FIXME: This won't work if the filename includes a " mark,
// or control characters like CR or LF. This also does strange
// things if the filename includes characters you can't encode
// in the website's character set.
- hstr += "; filename=\"";
- hstr += encoding.encode(reinterpret_cast<const UChar*>(filename.characters()), filename.length(), true).data();
- hstr += "\"";
-
- if (!static_cast<HTMLInputElement*>(current)->value().isEmpty()) {
- DeprecatedString mimeType = MIMETypeRegistry::getMIMETypeForPath(path).deprecatedString();
+ appendString(header, "; filename=\"");
+ appendString(header, encoding.encode(filename.characters(), filename.length(), QuestionMarksForUnencodables));
+ header.append('"');
+
+ if (!filename.isEmpty()) {
+ // FIXME: The MIMETypeRegistry function's name makes it sound like it takes a path,
+ // not just a basename. But filename is not the path. But note that it's not safe to
+ // just use path instead since in the generated-file case it will not reflect the
+ // MIME type of the generated file.
+ String mimeType = MIMETypeRegistry::getMIMETypeForPath(filename);
if (!mimeType.isEmpty()) {
- hstr += "\r\nContent-Type: ";
- hstr += mimeType.ascii();
+ appendString(header, "\r\nContent-Type: ");
+ appendString(header, mimeType.latin1());
}
}
}
- hstr += "\r\n\r\n";
+ appendString(header, "\r\n\r\n");
// append body
- result->appendData(hstr.data(), hstr.length());
- const FormDataListItem& item = lst.list()[j + 1];
- if (size_t dataSize = item.m_data.length())
- result->appendData(item.m_data.data(), dataSize);
- else if (!item.m_path.isEmpty())
- result->appendFile(item.m_path);
+ result->appendData(header.data(), header.size());
+ if (size_t dataSize = value.data().length())
+ result->appendData(value.data().data(), dataSize);
+ else if (value.file() && !value.file()->path().isEmpty())
+ result->appendFile(value.file()->path(), shouldGenerateFile);
result->appendData("\r\n", 2);
-
- ++j;
}
}
}
@@ -362,12 +350,12 @@ PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const
if (m_multipart) {
- enc_string = "--";
- enc_string += boundary;
- enc_string += "--\r\n";
+ appendString(encodedData, "--");
+ appendString(encodedData, boundary);
+ appendString(encodedData, "--\r\n");
}
- result->appendData(enc_string.data(), enc_string.length());
+ result->appendData(encodedData.data(), encodedData.size());
return result;
}
@@ -387,7 +375,7 @@ void HTMLFormElement::parseEnctype(const String& type)
bool HTMLFormElement::isMailtoForm() const
{
- return m_url.startsWith("mailto:", false);
+ return protocolIs(m_url, "mailto");
}
bool HTMLFormElement::prepareSubmit(Event* event)
@@ -399,7 +387,7 @@ bool HTMLFormElement::prepareSubmit(Event* event)
m_insubmit = true;
m_doingsubmit = false;
- if (dispatchHTMLEvent(submitEvent, true, true) && !m_doingsubmit)
+ if (dispatchEventForType(eventNames().submitEvent, true, true) && !m_doingsubmit)
m_doingsubmit = true;
m_insubmit = false;
@@ -467,8 +455,8 @@ static void getUniqueBoundaryString(Vector<char>& boundary)
void HTMLFormElement::submit(Event* event, bool activateSubmitButton)
{
- FrameView *view = document()->view();
- Frame *frame = document()->frame();
+ FrameView* view = document()->view();
+ Frame* frame = document()->frame();
if (!view || !frame)
return;
@@ -479,33 +467,34 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton)
m_insubmit = true;
- HTMLGenericFormElement* firstSuccessfulSubmitButton = 0;
+ HTMLFormControlElement* firstSuccessfulSubmitButton = 0;
bool needButtonActivation = activateSubmitButton; // do we need to activate a submit button?
frame->loader()->clearRecordedFormValues();
+ frame->loader()->setFormAboutToBeSubmitted(this);
for (unsigned i = 0; i < formElements.size(); ++i) {
- HTMLGenericFormElement* current = formElements[i];
- if (current->hasLocalName(inputTag)) {
- HTMLInputElement* input = static_cast<HTMLInputElement*>(current);
+ HTMLFormControlElement* control = formElements[i];
+ if (control->hasLocalName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(control);
if (input->isTextField()) {
- frame->loader()->recordFormValue(input->name(), input->value(), this);
+ frame->loader()->recordFormValue(input->name(), input->value());
if (input->isSearchField())
input->addSearchResult();
}
}
if (needButtonActivation) {
- if (current->isActivatedSubmit())
+ if (control->isActivatedSubmit())
needButtonActivation = false;
- else if (firstSuccessfulSubmitButton == 0 && current->isSuccessfulSubmitButton())
- firstSuccessfulSubmitButton = current;
+ else if (firstSuccessfulSubmitButton == 0 && control->isSuccessfulSubmitButton())
+ firstSuccessfulSubmitButton = control;
}
}
if (needButtonActivation && firstSuccessfulSubmitButton)
firstSuccessfulSubmitButton->setActivatedSubmit(true);
- if (!m_url)
- m_url = document()->url();
+ if (m_url.isEmpty())
+ m_url = document()->url().string();
if (m_post) {
if (m_multipart && isMailtoForm()) {
@@ -519,9 +508,12 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton)
String body = data->flattenToString();
if (equalIgnoringCase(enctype(), "text/plain")) {
// Convention seems to be to decode, and s/&/\r\n/. Also, spaces are encoded as %20.
- body = KURL::decode_string(body.replace('&', "\r\n").replace('+', ' ').deprecatedString() + "\r\n");
+ body = decodeURLEscapeSequences(body.replace('&', "\r\n").replace('+', ' ') + "\r\n");
}
- data = new FormData((String("body=") + encodeCString(body.utf8())).replace('+', "%20").latin1());
+ Vector<char> bodyData;
+ appendString(bodyData, "body=");
+ appendEncodedString(bodyData, body.utf8());
+ data = FormData::create(String(bodyData.data(), bodyData.size()).replace('+', "%20").latin1());
}
frame->loader()->submitForm("POST", m_url, data, m_target, enctype(), String(), event);
} else {
@@ -542,7 +534,7 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton)
void HTMLFormElement::reset()
{
- Frame *frame = document()->frame();
+ Frame* frame = document()->frame();
if (m_inreset || !frame)
return;
@@ -550,7 +542,7 @@ void HTMLFormElement::reset()
// ### DOM2 labels this event as not cancelable, however
// common browsers( sick! ) allow it be cancelled.
- if ( !dispatchHTMLEvent(resetEvent,true, true) ) {
+ if ( !dispatchEventForType(eventNames().resetEvent,true, true) ) {
m_inreset = false;
return;
}
@@ -561,7 +553,7 @@ void HTMLFormElement::reset()
m_inreset = false;
}
-void HTMLFormElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLFormElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == actionAttr)
m_url = parseURL(attr->value());
@@ -580,20 +572,24 @@ void HTMLFormElement::parseMappedAttribute(MappedAttribute *attr)
m_acceptcharset = attr->value();
else if (attr->name() == acceptAttr) {
// ignore this one for the moment...
- } else if (attr->name() == autocompleteAttr)
+ } else if (attr->name() == autocompleteAttr) {
m_autocomplete = !equalIgnoringCase(attr->value(), "off");
- else if (attr->name() == onsubmitAttr)
- setHTMLEventListener(submitEvent, attr);
+ if (!m_autocomplete)
+ document()->registerForDocumentActivationCallbacks(this);
+ else
+ document()->unregisterForDocumentActivationCallbacks(this);
+ } else if (attr->name() == onsubmitAttr)
+ setInlineEventListenerForTypeAndAttribute(eventNames().submitEvent, attr);
else if (attr->name() == onresetAttr)
- setHTMLEventListener(resetEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().resetEvent, attr);
else if (attr->name() == nameAttr) {
- String newNameAttr = attr->value();
+ const AtomicString& newName = attr->value();
if (inDocument() && document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->addNamedItem(newNameAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(newName);
}
- oldNameAttr = newNameAttr;
+ m_name = newName;
} else
HTMLElement::parseMappedAttribute(attr);
}
@@ -608,7 +604,7 @@ template<class T, size_t n> static void removeFromVector(Vector<T*, n> & vec, T*
}
}
-unsigned HTMLFormElement::formElementIndex(HTMLGenericFormElement *e)
+unsigned HTMLFormElement::formElementIndex(HTMLFormControlElement* e)
{
// Check for the special case where this element is the very last thing in
// the form's tree of children; we don't want to walk the entire tree in that
@@ -616,49 +612,49 @@ unsigned HTMLFormElement::formElementIndex(HTMLGenericFormElement *e)
// that says "add this form element to the end of the array".
if (e->traverseNextNode(this)) {
unsigned i = 0;
- for (Node *node = this; node; node = node->traverseNextNode(this)) {
+ for (Node* node = this; node; node = node->traverseNextNode(this)) {
if (node == e)
return i;
if (node->isHTMLElement()
- && static_cast<HTMLElement *>(node)->isGenericFormElement()
- && static_cast<HTMLGenericFormElement *>(node)->form() == this)
+ && static_cast<HTMLElement*>(node)->isGenericFormElement()
+ && static_cast<HTMLFormControlElement*>(node)->form() == this)
++i;
}
}
return formElements.size();
}
-void HTMLFormElement::registerFormElement(HTMLGenericFormElement* e)
+void HTMLFormElement::registerFormElement(HTMLFormControlElement* e)
{
document()->checkedRadioButtons().removeButton(e);
m_checkedRadioButtons.addButton(e);
formElements.insert(formElementIndex(e), e);
}
-void HTMLFormElement::removeFormElement(HTMLGenericFormElement* e)
+void HTMLFormElement::removeFormElement(HTMLFormControlElement* e)
{
m_checkedRadioButtons.removeButton(e);
removeFromVector(formElements, e);
}
-bool HTMLFormElement::isURLAttribute(Attribute *attr) const
+bool HTMLFormElement::isURLAttribute(Attribute* attr) const
{
return attr->name() == actionAttr;
}
-void HTMLFormElement::registerImgElement(HTMLImageElement *e)
+void HTMLFormElement::registerImgElement(HTMLImageElement* e)
{
imgElements.append(e);
}
-void HTMLFormElement::removeImgElement(HTMLImageElement *e)
+void HTMLFormElement::removeImgElement(HTMLImageElement* e)
{
removeFromVector(imgElements, e);
}
PassRefPtr<HTMLCollection> HTMLFormElement::elements()
{
- return new HTMLFormCollection(this);
+ return HTMLFormCollection::create(this);
}
String HTMLFormElement::name() const
@@ -716,14 +712,14 @@ void HTMLFormElement::setTarget(const String &value)
setAttribute(targetAttr, value);
}
-PassRefPtr<HTMLGenericFormElement> HTMLFormElement::elementForAlias(const AtomicString& alias)
+PassRefPtr<HTMLFormControlElement> HTMLFormElement::elementForAlias(const AtomicString& alias)
{
if (alias.isEmpty() || !m_elementAliases)
return 0;
return m_elementAliases->get(alias.impl());
}
-void HTMLFormElement::addElementAlias(HTMLGenericFormElement* element, const AtomicString& alias)
+void HTMLFormElement::addElementAlias(HTMLFormControlElement* element, const AtomicString& alias)
{
if (alias.isEmpty())
return;
@@ -737,7 +733,7 @@ void HTMLFormElement::getNamedElements(const AtomicString& name, Vector<RefPtr<N
elements()->namedItems(name, namedItems);
// see if we have seen something with this name before
- RefPtr<HTMLGenericFormElement> aliasElem;
+ RefPtr<HTMLFormControlElement> aliasElem;
if (aliasElem = elementForAlias(name)) {
bool found = false;
for (unsigned n = 0; n < namedItems.size(); n++) {
@@ -752,10 +748,30 @@ void HTMLFormElement::getNamedElements(const AtomicString& name, Vector<RefPtr<N
}
// name has been accessed, remember it
if (namedItems.size() && aliasElem != namedItems.first())
- addElementAlias(static_cast<HTMLGenericFormElement*>(namedItems.first().get()), name);
+ addElementAlias(static_cast<HTMLFormControlElement*>(namedItems.first().get()), name);
+}
+
+void HTMLFormElement::documentDidBecomeActive()
+{
+ ASSERT(!m_autocomplete);
+
+ for (unsigned i = 0; i < formElements.size(); ++i)
+ formElements[i]->reset();
+}
+
+void HTMLFormElement::willMoveToNewOwnerDocument()
+{
+ if (!m_autocomplete)
+ document()->unregisterForDocumentActivationCallbacks(this);
+}
+
+void HTMLFormElement::didMoveToNewOwnerDocument()
+{
+ if(m_autocomplete)
+ document()->registerForDocumentActivationCallbacks(this);
}
-void HTMLFormElement::CheckedRadioButtons::addButton(HTMLGenericFormElement* element)
+void HTMLFormElement::CheckedRadioButtons::addButton(HTMLFormControlElement* element)
{
// We only want to add radio buttons.
if (!element->isRadioButton())
@@ -794,7 +810,7 @@ HTMLInputElement* HTMLFormElement::CheckedRadioButtons::checkedButtonForGroup(co
return m_nameToCheckedRadioButtonMap->get(name.impl());
}
-void HTMLFormElement::CheckedRadioButtons::removeButton(HTMLGenericFormElement* element)
+void HTMLFormElement::CheckedRadioButtons::removeButton(HTMLFormControlElement* element)
{
if (element->name().isEmpty() || !m_nameToCheckedRadioButtonMap)
return;
diff --git a/WebCore/html/HTMLFormElement.h b/WebCore/html/HTMLFormElement.h
index 73a4aba..c65304b 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 Apple Inc. All rights reserved.
+ * 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
@@ -33,7 +33,7 @@ namespace WebCore {
class Event;
class FormData;
-class HTMLGenericFormElement;
+class HTMLFormControlElement;
class HTMLImageElement;
class HTMLInputElement;
class HTMLFormCollection;
@@ -69,8 +69,8 @@ public:
virtual void parseMappedAttribute(MappedAttribute*);
- void registerFormElement(HTMLGenericFormElement*);
- void removeFormElement(HTMLGenericFormElement*);
+ void registerFormElement(HTMLFormControlElement*);
+ void removeFormElement(HTMLFormControlElement*);
void registerImgElement(HTMLImageElement*);
void removeImgElement(HTMLImageElement*);
@@ -79,8 +79,9 @@ public:
void submit(Event*, bool activateSubmitButton = false);
void reset();
+ // Used to indicate a malformed state to keep from applying the bottom margin of the form.
void setMalformed(bool malformed) { m_malformed = malformed; }
- virtual bool isMalformed() { return m_malformed; }
+ bool isMalformed() const { return m_malformed; }
virtual bool isURLAttribute(Attribute*) const;
@@ -102,16 +103,16 @@ public:
virtual String target() const;
void setTarget(const String&);
- PassRefPtr<HTMLGenericFormElement> elementForAlias(const AtomicString&);
- void addElementAlias(HTMLGenericFormElement*, const AtomicString& alias);
+ PassRefPtr<HTMLFormControlElement> elementForAlias(const AtomicString&);
+ void addElementAlias(HTMLFormControlElement*, const AtomicString& alias);
// FIXME: Change this to be private after getting rid of all the clients.
- Vector<HTMLGenericFormElement*> formElements;
+ Vector<HTMLFormControlElement*> formElements;
class CheckedRadioButtons {
public:
- void addButton(HTMLGenericFormElement*);
- void removeButton(HTMLGenericFormElement*);
+ void addButton(HTMLFormControlElement*);
+ void removeButton(HTMLFormControlElement*);
HTMLInputElement* checkedButtonForGroup(const AtomicString& name) const;
private:
@@ -121,16 +122,22 @@ public:
CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
+ virtual void documentDidBecomeActive();
+
+protected:
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
+
private:
void parseEnctype(const String&);
bool isMailtoForm() const;
TextEncoding dataEncoding() const;
PassRefPtr<FormData> formData(const char* boundary) const;
- unsigned formElementIndex(HTMLGenericFormElement*);
+ unsigned formElementIndex(HTMLFormControlElement*);
friend class HTMLFormCollection;
- typedef HashMap<RefPtr<AtomicStringImpl>, RefPtr<HTMLGenericFormElement> > AliasMap;
+ typedef HashMap<RefPtr<AtomicStringImpl>, RefPtr<HTMLFormControlElement> > AliasMap;
AliasMap* m_elementAliases;
HTMLCollection::CollectionInfo* collectionInfo;
@@ -149,10 +156,10 @@ private:
bool m_doingsubmit : 1;
bool m_inreset : 1;
bool m_malformed : 1;
- String oldNameAttr;
+ AtomicString m_name;
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr is removed from HTMLDocument's NameCountMap
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
int oldNameCount;
#endif
};
diff --git a/WebCore/html/HTMLFrameElementBase.cpp b/WebCore/html/HTMLFrameElementBase.cpp
index 6438f3c..1c80155 100644
--- a/WebCore/html/HTMLFrameElementBase.cpp
+++ b/WebCore/html/HTMLFrameElementBase.cpp
@@ -1,11 +1,9 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann (hausmann@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 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
@@ -22,6 +20,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLFrameElementBase.h"
@@ -42,7 +41,6 @@
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Document *doc)
@@ -61,28 +59,25 @@ bool HTMLFrameElementBase::isURLAllowed(const AtomicString& URLString) const
if (URLString.isEmpty())
return true;
- KURL completeURL(document()->completeURL(URLString.deprecatedString()));
- completeURL.setRef(DeprecatedString::null);
+ const KURL& completeURL = document()->completeURL(URLString);
// Don't allow more than 200 total frames in a set. This seems
// like a reasonable upper bound, and otherwise mutually recursive
// frameset pages can quickly bring the program to its knees with
// exponential growth in the number of frames.
-
- // FIXME: This limit could be higher, but WebKit has some
+ // FIXME: This limit could be higher, but because WebKit has some
// algorithms that happen while loading which appear to be N^2 or
- // worse in the number of frames
- if (Frame* parentFrame = document()->frame())
+ // worse in the number of frames, we'll keep it at 200 for now.
+ if (Frame* parentFrame = document()->frame()) {
if (parentFrame->page()->frameCount() > 200)
return false;
+ }
// We allow one level of self-reference because some sites depend on that.
// But we don't allow more than one.
bool foundSelfReference = false;
for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) {
- KURL frameURL = frame->loader()->url();
- frameURL.setRef(DeprecatedString::null);
- if (frameURL == completeURL) {
+ if (equalIgnoringRef(frame->loader()->url(), completeURL)) {
if (foundSelfReference)
return false;
foundSelfReference = true;
@@ -94,19 +89,19 @@ bool HTMLFrameElementBase::isURLAllowed(const AtomicString& URLString) const
void HTMLFrameElementBase::openURL()
{
- ASSERT(!m_name.isEmpty());
+ ASSERT(!m_frameName.isEmpty());
if (!isURLAllowed(m_URL))
return;
if (m_URL.isEmpty())
- m_URL = "about:blank";
+ m_URL = blankURL().string();
Frame* parentFrame = document()->frame();
if (!parentFrame)
return;
- parentFrame->loader()->requestFrame(this, m_URL, m_name);
+ parentFrame->loader()->requestFrame(this, m_URL, m_frameName);
if (contentFrame())
contentFrame()->setInViewSourceMode(viewSourceMode());
}
@@ -118,9 +113,9 @@ void HTMLFrameElementBase::parseMappedAttribute(MappedAttribute *attr)
else if (attr->name() == idAttr) {
// Important to call through to base for the id attribute so the hasID bit gets set.
HTMLFrameOwnerElement::parseMappedAttribute(attr);
- m_name = attr->value();
+ m_frameName = attr->value();
} else if (attr->name() == nameAttr) {
- m_name = attr->value();
+ m_frameName = attr->value();
// FIXME: If we are already attached, this doesn't actually change the frame's name.
// FIXME: If we are already attached, this doesn't check for frame name
// conflicts and generate a unique frame name.
@@ -145,24 +140,22 @@ void HTMLFrameElementBase::parseMappedAttribute(MappedAttribute *attr)
if (contentFrame())
contentFrame()->setInViewSourceMode(viewSourceMode());
} else if (attr->name() == onloadAttr) {
- setHTMLEventListener(loadEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
} else if (attr->name() == onbeforeunloadAttr) {
// FIXME: should <frame> elements have beforeunload handlers?
- setHTMLEventListener(beforeunloadEvent, attr);
- } else if (attr->name() == onunloadAttr) {
- setHTMLEventListener(unloadEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().beforeunloadEvent, attr);
} else
HTMLFrameOwnerElement::parseMappedAttribute(attr);
}
void HTMLFrameElementBase::setNameAndOpenURL()
{
- m_name = getAttribute(nameAttr);
- if (m_name.isNull())
- m_name = getAttribute(idAttr);
+ m_frameName = getAttribute(nameAttr);
+ if (m_frameName.isNull())
+ m_frameName = getAttribute(idAttr);
if (Frame* parentFrame = document()->frame())
- m_name = parentFrame->tree()->uniqueChildName(m_name);
+ m_frameName = parentFrame->tree()->uniqueChildName(m_frameName);
openURL();
}
@@ -203,7 +196,7 @@ void HTMLFrameElementBase::attach()
renderPart->setWidget(frame->view());
}
-String HTMLFrameElementBase::location() const
+KURL HTMLFrameElementBase::location() const
{
return src();
}
@@ -302,7 +295,7 @@ void HTMLFrameElementBase::setScrolling(const String &value)
setAttribute(scrollingAttr, value);
}
-String HTMLFrameElementBase::src() const
+KURL HTMLFrameElementBase::src() const
{
return document()->completeURL(getAttribute(srcAttr));
}
diff --git a/WebCore/html/HTMLFrameElementBase.h b/WebCore/html/HTMLFrameElementBase.h
index bcb63ac..4a24451 100644
--- a/WebCore/html/HTMLFrameElementBase.h
+++ b/WebCore/html/HTMLFrameElementBase.h
@@ -1,10 +1,8 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 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
@@ -39,8 +37,9 @@ public:
virtual void removedFromDocument();
virtual void attach();
+ virtual bool canLazyAttach() { return false; }
- String location() const;
+ KURL location() const;
void setLocation(const String&);
virtual bool isFocusable() const;
@@ -74,7 +73,7 @@ public:
String scrolling() const;
void setScrolling(const String&);
- String src() const;
+ KURL src() const;
void setSrc(const String&);
int width() const;
@@ -92,7 +91,7 @@ protected:
static void setNameAndOpenURLCallback(Node*);
AtomicString m_URL;
- AtomicString m_name;
+ AtomicString m_frameName;
ScrollbarMode m_scrolling;
diff --git a/WebCore/html/HTMLFrameSetElement.cpp b/WebCore/html/HTMLFrameSetElement.cpp
index c49b0f8..75fd516 100644
--- a/WebCore/html/HTMLFrameSetElement.cpp
+++ b/WebCore/html/HTMLFrameSetElement.cpp
@@ -32,13 +32,13 @@
#include "EventNames.h"
#include "HTMLNames.h"
#include "Length.h"
+#include "Length.h"
#include "MouseEvent.h"
#include "RenderFrameSet.h"
#include "Text.h"
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
HTMLFrameSetElement::HTMLFrameSetElement(Document *doc)
@@ -88,13 +88,13 @@ void HTMLFrameSetElement::parseMappedAttribute(MappedAttribute *attr)
if (attr->name() == rowsAttr) {
if (!attr->isNull()) {
if (m_rows) delete [] m_rows;
- m_rows = attr->value().toLengthArray(m_totalRows);
+ m_rows = newLengthArray(attr->value().string(), m_totalRows);
setChanged();
}
} else if (attr->name() == colsAttr) {
if (!attr->isNull()) {
delete [] m_cols;
- m_cols = attr->value().toLengthArray(m_totalCols);
+ m_cols = newLengthArray(attr->value().string(), m_totalCols);
setChanged();
}
} else if (attr->name() == frameborderAttr) {
@@ -122,15 +122,15 @@ void HTMLFrameSetElement::parseMappedAttribute(MappedAttribute *attr)
} else if (attr->name() == bordercolorAttr) {
m_borderColorSet = attr->decl();
if (!attr->decl() && !attr->isEmpty()) {
- addCSSColor(attr, CSS_PROP_BORDER_COLOR, attr->value());
+ addCSSColor(attr, CSSPropertyBorderColor, attr->value());
m_borderColorSet = true;
}
} else if (attr->name() == onloadAttr) {
- document()->setHTMLWindowEventListener(loadEvent, attr);
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
} else if (attr->name() == onbeforeunloadAttr) {
- document()->setHTMLWindowEventListener(beforeunloadEvent, attr);
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().beforeunloadEvent, attr);
} else if (attr->name() == onunloadAttr) {
- document()->setHTMLWindowEventListener(unloadEvent, attr);
+ document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().unloadEvent, attr);
} else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLHRElement.cpp b/WebCore/html/HTMLHRElement.cpp
index 9bef9bd..743b0d2 100644
--- a/WebCore/html/HTMLHRElement.cpp
+++ b/WebCore/html/HTMLHRElement.cpp
@@ -58,43 +58,43 @@ void HTMLHRElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == alignAttr) {
if (equalIgnoringCase(attr->value(), "left")) {
- addCSSProperty(attr, CSS_PROP_MARGIN_LEFT, "0");
- addCSSProperty(attr, CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO);
+ addCSSProperty(attr, CSSPropertyMarginLeft, "0");
+ addCSSProperty(attr, CSSPropertyMarginRight, CSSValueAuto);
} else if (equalIgnoringCase(attr->value(), "right")) {
- addCSSProperty(attr, CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO);
- addCSSProperty(attr, CSS_PROP_MARGIN_RIGHT, "0");
+ addCSSProperty(attr, CSSPropertyMarginLeft, CSSValueAuto);
+ addCSSProperty(attr, CSSPropertyMarginRight, "0");
} else {
- addCSSProperty(attr, CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO);
- addCSSProperty(attr, CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO);
+ addCSSProperty(attr, CSSPropertyMarginLeft, CSSValueAuto);
+ addCSSProperty(attr, CSSPropertyMarginRight, CSSValueAuto);
}
} else if (attr->name() == widthAttr) {
bool ok;
int v = attr->value().toInt(&ok);
if(ok && !v)
- addCSSLength(attr, CSS_PROP_WIDTH, "1");
+ addCSSLength(attr, CSSPropertyWidth, "1");
else
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
} else if (attr->name() == colorAttr) {
- addCSSProperty(attr, CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
- addCSSColor(attr, CSS_PROP_BORDER_COLOR, attr->value());
- addCSSColor(attr, CSS_PROP_BACKGROUND_COLOR, attr->value());
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
+ addCSSColor(attr, CSSPropertyBorderColor, attr->value());
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
} else if (attr->name() == noshadeAttr) {
- addCSSProperty(attr, CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
- addCSSColor(attr, CSS_PROP_BORDER_COLOR, String("grey"));
- addCSSColor(attr, CSS_PROP_BACKGROUND_COLOR, String("grey"));
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
+ addCSSColor(attr, CSSPropertyBorderColor, String("grey"));
+ addCSSColor(attr, CSSPropertyBackgroundColor, String("grey"));
} else if (attr->name() == sizeAttr) {
StringImpl* si = attr->value().impl();
int size = si->toInt();
if (size <= 1)
- addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_WIDTH, String("0"));
+ addCSSProperty(attr, CSSPropertyBorderBottomWidth, String("0"));
else
- addCSSLength(attr, CSS_PROP_HEIGHT, String::number(size-2));
+ addCSSLength(attr, CSSPropertyHeight, String::number(size-2));
} else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLHtmlElement.cpp b/WebCore/html/HTMLHtmlElement.cpp
index 5d8d1b6..dd8a609 100644
--- a/WebCore/html/HTMLHtmlElement.cpp
+++ b/WebCore/html/HTMLHtmlElement.cpp
@@ -25,6 +25,8 @@
#include "config.h"
#include "HTMLHtmlElement.h"
+#include "ApplicationCacheGroup.h"
+#include "Document.h"
#include "HTMLNames.h"
namespace WebCore {
@@ -58,4 +60,24 @@ bool HTMLHtmlElement::checkDTD(const Node* newChild)
newChild->hasTagName(scriptTag);
}
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+void HTMLHtmlElement::insertedIntoDocument()
+{
+ HTMLElement::insertedIntoDocument();
+
+ if (!document()->parsing())
+ return;
+
+ if (!document()->frame())
+ return;
+
+ // Check the manifest attribute
+ AtomicString manifest = getAttribute(manifestAttr);
+ if (manifest.isNull())
+ ApplicationCacheGroup::selectCacheWithoutManifestURL(document()->frame());
+ else
+ ApplicationCacheGroup::selectCache(document()->frame(), document()->completeURL(manifest));
+}
+#endif
+
}
diff --git a/WebCore/html/HTMLHtmlElement.h b/WebCore/html/HTMLHtmlElement.h
index 2e3b05a..2154d95 100644
--- a/WebCore/html/HTMLHtmlElement.h
+++ b/WebCore/html/HTMLHtmlElement.h
@@ -40,6 +40,10 @@ public:
virtual int tagPriority() const { return 11; }
virtual bool checkDTD(const Node* newChild);
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void insertedIntoDocument();
+#endif
+
String version() const;
void setVersion(const String&);
};
diff --git a/WebCore/html/HTMLIFrameElement.cpp b/WebCore/html/HTMLIFrameElement.cpp
index c52587d..4a071bf 100644
--- a/WebCore/html/HTMLIFrameElement.cpp
+++ b/WebCore/html/HTMLIFrameElement.cpp
@@ -1,11 +1,9 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann (hausmann@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 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
@@ -22,6 +20,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLIFrameElement.h"
@@ -60,28 +59,28 @@ bool HTMLIFrameElement::mapToEntry(const QualifiedName& attrName, MappedAttribut
return HTMLFrameElementBase::mapToEntry(attrName, result);
}
-void HTMLIFrameElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLIFrameElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == widthAttr)
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
else if (attr->name() == heightAttr)
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
else if (attr->name() == alignAttr)
addHTMLAlignment(attr);
else if (attr->name() == nameAttr) {
- String newNameAttr = attr->value();
+ const AtomicString& newName = attr->value();
if (inDocument() && document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument* >(document());
- doc->removeDocExtraNamedItem(oldNameAttr);
- doc->addDocExtraNamedItem(newNameAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeExtraNamedItem(m_name);
+ document->addExtraNamedItem(newName);
}
- oldNameAttr = newNameAttr;
+ m_name = newName;
} else if (attr->name() == frameborderAttr) {
// Frame border doesn't really match the HTML4 spec definition for iframes. It simply adds
// a presentational hint that the border should be off if set to zero.
if (!attr->isNull() && !attr->value().toInt())
// Add a rule that nulls out our border width.
- addCSSLength(attr, CSS_PROP_BORDER_WIDTH, "0");
+ addCSSLength(attr, CSSPropertyBorderWidth, "0");
} else
HTMLFrameElementBase::parseMappedAttribute(attr);
}
@@ -98,20 +97,16 @@ RenderObject* HTMLIFrameElement::createRenderer(RenderArena* arena, RenderStyle*
void HTMLIFrameElement::insertedIntoDocument()
{
- if (document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->addDocExtraNamedItem(oldNameAttr);
- }
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->addExtraNamedItem(m_name);
HTMLFrameElementBase::insertedIntoDocument();
}
void HTMLIFrameElement::removedFromDocument()
{
- if (document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeDocExtraNamedItem(oldNameAttr);
- }
+ if (document()->isHTMLDocument())
+ static_cast<HTMLDocument*>(document())->removeExtraNamedItem(m_name);
HTMLFrameElementBase::removedFromDocument();
}
diff --git a/WebCore/html/HTMLIFrameElement.h b/WebCore/html/HTMLIFrameElement.h
index c1f7ea8..adead51 100644
--- a/WebCore/html/HTMLIFrameElement.h
+++ b/WebCore/html/HTMLIFrameElement.h
@@ -1,10 +1,8 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 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
@@ -30,10 +28,9 @@
namespace WebCore {
-class HTMLIFrameElement : public HTMLFrameElementBase
-{
+class HTMLIFrameElement : public HTMLFrameElementBase {
public:
- HTMLIFrameElement(Document* doc);
+ HTMLIFrameElement(Document*);
virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
virtual int tagPriority() const { return 1; }
@@ -61,7 +58,7 @@ public:
void setWidth(const String&);
private:
- String oldNameAttr;
+ AtomicString m_name;
};
} // namespace WebCore
diff --git a/WebCore/html/HTMLImageElement.cpp b/WebCore/html/HTMLImageElement.cpp
index d2c74eb..d319553 100644
--- a/WebCore/html/HTMLImageElement.cpp
+++ b/WebCore/html/HTMLImageElement.cpp
@@ -26,6 +26,7 @@
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "EventNames.h"
+#include "Frame.h"
#include "HTMLDocument.h"
#include "HTMLFormElement.h"
#include "HTMLNames.h"
@@ -35,7 +36,6 @@ using namespace std;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
HTMLImageElement::HTMLImageElement(Document* doc, HTMLFormElement* f)
@@ -46,7 +46,7 @@ HTMLImageElement::HTMLImageElement(Document* doc, HTMLFormElement* f)
, m_compositeOperator(CompositeSourceOver)
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
, oldNameIdCount(0)
#endif
{
@@ -62,7 +62,7 @@ HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* doc)
, m_compositeOperator(CompositeSourceOver)
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
, oldNameIdCount(0)
#endif
{
@@ -72,11 +72,11 @@ HTMLImageElement::~HTMLImageElement()
{
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
if (oldNameIdCount && document()->isHTMLDocument()) {
HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->removeDocExtraNamedItem(oldIdAttr);
+ doc->removeNamedItem(m_name);
+ doc->removeExtraNamedItem(m_id);
}
#endif
if (m_form)
@@ -111,57 +111,57 @@ void HTMLImageElement::parseMappedAttribute(MappedAttribute* attr)
} else if (attrName == srcAttr)
m_imageLoader.updateFromElement();
else if (attrName == widthAttr)
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
else if (attrName == heightAttr)
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
else if (attrName == borderAttr) {
// border="noborder" -> border="0"
- addCSSLength(attr, CSS_PROP_BORDER_WIDTH, attr->value().toInt() ? attr->value() : "0");
- addCSSProperty(attr, CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
+ addCSSLength(attr, CSSPropertyBorderWidth, attr->value().toInt() ? attr->value() : "0");
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
} else if (attrName == vspaceAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
} else if (attrName == hspaceAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
} else if (attrName == alignAttr)
addHTMLAlignment(attr);
else if (attrName == valignAttr)
- addCSSProperty(attr, CSS_PROP_VERTICAL_ALIGN, attr->value());
+ addCSSProperty(attr, CSSPropertyVerticalAlign, attr->value());
else if (attrName == usemapAttr) {
- if (attr->value().domString()[0] == '#')
+ if (attr->value().string()[0] == '#')
usemap = attr->value();
else
- usemap = document()->completeURL(parseURL(attr->value()));
- m_isLink = !attr->isNull();
+ usemap = document()->completeURL(parseURL(attr->value())).string();
+ setIsLink(!attr->isNull());
} else if (attrName == ismapAttr)
ismap = true;
else if (attrName == onabortAttr)
- setHTMLEventListener(abortEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().abortEvent, attr);
else if (attrName == onloadAttr)
- setHTMLEventListener(loadEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
else if (attrName == compositeAttr) {
if (!parseCompositeOperator(attr->value(), m_compositeOperator))
m_compositeOperator = CompositeSourceOver;
} else if (attrName == nameAttr) {
- String newNameAttr = attr->value();
+ const AtomicString& newName = attr->value();
if (inDocument() && document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->addNamedItem(newNameAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(newName);
}
- oldNameAttr = newNameAttr;
+ m_name = newName;
} else if (attr->name() == idAttr) {
- String newIdAttr = attr->value();
+ const AtomicString& newId = attr->value();
if (inDocument() && document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeDocExtraNamedItem(oldIdAttr);
- doc->addDocExtraNamedItem(newIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeExtraNamedItem(m_id);
+ document->addExtraNamedItem(newId);
}
- oldIdAttr = newIdAttr;
+ m_id = newId;
// also call superclass
HTMLElement::parseMappedAttribute(attr);
} else
@@ -194,6 +194,8 @@ void HTMLImageElement::attach()
if (renderer() && renderer()->isImage()) {
RenderImage* imageObj = static_cast<RenderImage*>(renderer());
+ if (imageObj->hasImage())
+ return;
imageObj->setCachedImage(m_imageLoader.image());
// If we have no image at all because we have no src attribute, set
@@ -206,13 +208,12 @@ void HTMLImageElement::attach()
void HTMLImageElement::insertedIntoDocument()
{
if (document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument*>(document());
-
- doc->addNamedItem(oldNameAttr);
- doc->addDocExtraNamedItem(oldIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->addNamedItem(m_name);
+ document->addExtraNamedItem(m_id);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
oldNameIdCount++;
#endif
}
@@ -223,13 +224,12 @@ void HTMLImageElement::insertedIntoDocument()
void HTMLImageElement::removedFromDocument()
{
if (document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument*>(document());
-
- doc->removeNamedItem(oldNameAttr);
- doc->removeDocExtraNamedItem(oldIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->removeExtraNamedItem(m_id);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
oldNameIdCount--;
#endif
}
@@ -247,8 +247,10 @@ int HTMLImageElement::width(bool ignorePendingStylesheets) const
return width;
// if the image is available, use its width
- if (m_imageLoader.image())
- return m_imageLoader.image()->imageSize().width();
+ if (m_imageLoader.image()) {
+ float zoomFactor = document()->frame() ? document()->frame()->pageZoomFactor() : 1.0f;
+ return m_imageLoader.image()->imageSize(zoomFactor).width();
+ }
}
if (ignorePendingStylesheets)
@@ -269,8 +271,10 @@ int HTMLImageElement::height(bool ignorePendingStylesheets) const
return height;
// if the image is available, use its height
- if (m_imageLoader.image())
- return m_imageLoader.image()->imageSize().height();
+ if (m_imageLoader.image()) {
+ float zoomFactor = document()->frame() ? document()->frame()->pageZoomFactor() : 1.0f;
+ return m_imageLoader.image()->imageSize(zoomFactor).height();
+ }
}
if (ignorePendingStylesheets)
@@ -286,7 +290,7 @@ int HTMLImageElement::naturalWidth() const
if (!m_imageLoader.image())
return 0;
- return m_imageLoader.image()->imageSize().width();
+ return m_imageLoader.image()->imageSize(1.0f).width();
}
int HTMLImageElement::naturalHeight() const
@@ -294,7 +298,7 @@ int HTMLImageElement::naturalHeight() const
if (!m_imageLoader.image())
return 0;
- return m_imageLoader.image()->imageSize().height();
+ return m_imageLoader.image()->imageSize(1.0f).height();
}
bool HTMLImageElement::isURLAttribute(Attribute* attr) const
@@ -302,7 +306,7 @@ bool HTMLImageElement::isURLAttribute(Attribute* attr) const
return attr->name() == srcAttr
|| attr->name() == lowsrcAttr
|| attr->name() == longdescAttr
- || (attr->name() == usemapAttr && attr->value().domString()[0] != '#');
+ || (attr->name() == usemapAttr && attr->value().string()[0] != '#');
}
String HTMLImageElement::name() const
@@ -371,7 +375,7 @@ void HTMLImageElement::setIsMap(bool isMap)
setAttribute(ismapAttr, isMap ? "" : 0);
}
-String HTMLImageElement::longDesc() const
+KURL HTMLImageElement::longDesc() const
{
return document()->completeURL(getAttribute(longdescAttr));
}
@@ -381,7 +385,7 @@ void HTMLImageElement::setLongDesc(const String& value)
setAttribute(longdescAttr, value);
}
-String HTMLImageElement::lowsrc() const
+KURL HTMLImageElement::lowsrc() const
{
return document()->completeURL(getAttribute(lowsrcAttr));
}
@@ -391,7 +395,7 @@ void HTMLImageElement::setLowsrc(const String& value)
setAttribute(lowsrcAttr, value);
}
-String HTMLImageElement::src() const
+KURL HTMLImageElement::src() const
{
return document()->completeURL(getAttribute(srcAttr));
}
@@ -452,4 +456,10 @@ bool HTMLImageElement::complete() const
return m_imageLoader.imageComplete();
}
+void HTMLImageElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ urls.append(src().string());
+ urls.append(useMap());
+}
+
}
diff --git a/WebCore/html/HTMLImageElement.h b/WebCore/html/HTMLImageElement.h
index 1ce3a74..848ecb1 100644
--- a/WebCore/html/HTMLImageElement.h
+++ b/WebCore/html/HTMLImageElement.h
@@ -1,9 +1,7 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004 Apple Computer, Inc.
+ * Copyright (C) 2004, 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
@@ -25,12 +23,13 @@
#ifndef HTMLImageElement_h
#define HTMLImageElement_h
-#include "HTMLElement.h"
#include "GraphicsTypes.h"
+#include "HTMLElement.h"
#include "HTMLImageLoader.h"
namespace WebCore {
- class HTMLFormElement;
+
+class HTMLFormElement;
class HTMLImageElement : public HTMLElement {
friend class HTMLFormElement;
@@ -62,8 +61,6 @@ public:
String altText() const;
- String imageMap() const { return usemap; }
-
virtual bool isURLAttribute(Attribute*) const;
CompositeOperator compositeOperator() const { return m_compositeOperator; }
@@ -93,13 +90,13 @@ public:
bool isMap() const;
void setIsMap(bool);
- String longDesc() const;
+ KURL longDesc() const;
void setLongDesc(const String&);
- String lowsrc() const;
+ KURL lowsrc() const;
void setLowsrc(const String&);
- String src() const;
+ KURL src() const;
void setSrc(const String&);
String useMap() const;
@@ -116,17 +113,20 @@ public:
bool complete() const;
bool haveFiredLoadEvent() const { return m_imageLoader.haveFiredLoadEvent(); }
-protected:
+
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
+private:
HTMLImageLoader m_imageLoader;
String usemap;
bool ismap;
HTMLFormElement* m_form;
- String oldNameAttr;
- String oldIdAttr;
+ AtomicString m_name;
+ AtomicString m_id;
CompositeOperator m_compositeOperator;
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
int oldNameIdCount;
#endif
};
diff --git a/WebCore/html/HTMLImageLoader.cpp b/WebCore/html/HTMLImageLoader.cpp
index f7fecb6..22e3abc 100644
--- a/WebCore/html/HTMLImageLoader.cpp
+++ b/WebCore/html/HTMLImageLoader.cpp
@@ -24,124 +24,42 @@
#include "CSSHelper.h"
#include "CachedImage.h"
-#include "DocLoader.h"
-#include "Document.h"
#include "Element.h"
#include "EventNames.h"
#include "HTMLNames.h"
-#include "RenderImage.h"
-
-using namespace std;
+#include "HTMLObjectElement.h"
namespace WebCore {
-using namespace EventNames;
-using namespace HTMLNames;
-
-HTMLImageLoader::HTMLImageLoader(Element* elt)
- : m_element(elt)
- , m_image(0)
- , m_firedLoad(true)
- , m_imageComplete(true)
- , m_loadManually(false)
+HTMLImageLoader::HTMLImageLoader(Element* node)
+ : ImageLoader(node)
{
}
HTMLImageLoader::~HTMLImageLoader()
{
- if (m_image)
- m_image->deref(this);
- m_element->document()->removeImage(this);
}
-void HTMLImageLoader::setImage(CachedImage *newImage)
+void HTMLImageLoader::dispatchLoadEvent()
{
- CachedImage *oldImage = m_image;
- if (newImage != oldImage) {
- setLoadingImage(newImage);
- m_firedLoad = true;
- m_imageComplete = true;
- if (newImage)
- newImage->ref(this);
- if (oldImage)
- oldImage->deref(this);
+ if (!haveFiredLoadEvent() && image()) {
+ setHaveFiredLoadEvent(true);
+ element()->dispatchEventForType(image()->errorOccurred() ? eventNames().errorEvent : eventNames().loadEvent, false, false);
}
-
- if (RenderObject* renderer = element()->renderer())
- if (renderer->isImage())
- static_cast<RenderImage*>(renderer)->resetAnimation();
}
-void HTMLImageLoader::setLoadingImage(CachedImage *loadingImage)
+String HTMLImageLoader::sourceURI(const AtomicString& attr) const
{
- m_firedLoad = false;
- m_imageComplete = false;
- m_image = loadingImage;
+ return parseURL(attr);
}
-void HTMLImageLoader::updateFromElement()
+void HTMLImageLoader::notifyFinished(CachedResource* image)
{
- // If we're not making renderers for the page, then don't load images. We don't want to slow
- // down the raw HTML parsing case by loading images we don't intend to display.
Element* elem = element();
- Document* doc = elem->document();
- if (!doc->renderer())
- return;
-
- AtomicString attr = elem->getAttribute(elem->imageSourceAttributeName());
-
- // Treat a lack of src or empty string for src as no image at all.
- CachedImage *newImage = 0;
- if (!attr.isEmpty()) {
- if (m_loadManually) {
- doc->docLoader()->setAutoLoadImages(false);
- newImage = new CachedImage(doc->docLoader(), parseURL(attr), false /* not for cache */);
- newImage->setLoading(true);
- newImage->setDocLoader(doc->docLoader());
- doc->docLoader()->m_docResources.set(newImage->url(), newImage);
- } else
- newImage = doc->docLoader()->requestImage(parseURL(attr));
- }
-
- CachedImage *oldImage = m_image;
- if (newImage != oldImage) {
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (!doc->ownerElement() && newImage)
- printf("Image requested at %d\n", doc->elapsedTime());
-#endif
- setLoadingImage(newImage);
- if (newImage)
- newImage->ref(this);
- if (oldImage)
- oldImage->deref(this);
- }
-
- if (RenderObject* renderer = elem->renderer())
- if (renderer->isImage())
- static_cast<RenderImage*>(renderer)->resetAnimation();
-}
-
-void HTMLImageLoader::dispatchLoadEvent()
-{
- if (!haveFiredLoadEvent() && image()) {
- setHaveFiredLoadEvent(true);
- element()->dispatchHTMLEvent(image()->errorOccurred() ? errorEvent : loadEvent, false, false);
- }
-}
+ ImageLoader::notifyFinished(image);
-void HTMLImageLoader::notifyFinished(CachedResource *image)
-{
- m_imageComplete = true;
- Element* elem = element();
- Document* doc = elem->document();
- doc->dispatchImageLoadEventSoon(this);
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (!doc->ownerElement())
- printf("Image loaded at %d\n", doc->elapsedTime());
-#endif
- if (RenderObject* renderer = elem->renderer())
- if (renderer->isImage())
- static_cast<RenderImage*>(renderer)->setCachedImage(m_image);
+ if (image->errorOccurred() && elem->hasTagName(HTMLNames::objectTag))
+ static_cast<HTMLObjectElement*>(elem)->renderFallbackContent();
}
}
diff --git a/WebCore/html/HTMLImageLoader.h b/WebCore/html/HTMLImageLoader.h
index b0ebd48..9e9564b 100644
--- a/WebCore/html/HTMLImageLoader.h
+++ b/WebCore/html/HTMLImageLoader.h
@@ -25,46 +25,21 @@
#ifndef HTMLImageLoader_h
#define HTMLImageLoader_h
-#include "CachedResourceClient.h"
+#include "ImageLoader.h"
namespace WebCore {
-class Element;
-
-class HTMLImageLoader : public CachedResourceClient {
+class HTMLImageLoader : public ImageLoader {
public:
HTMLImageLoader(Element*);
virtual ~HTMLImageLoader();
- virtual void updateFromElement();
-
virtual void dispatchLoadEvent();
+ virtual String sourceURI(const AtomicString&) const;
- Element* element() const { return m_element; }
- bool imageComplete() const { return m_imageComplete; }
-
- CachedImage* image() const { return m_image; }
- void setImage(CachedImage*);
-
- void setLoadManually(bool loadManually) { m_loadManually = loadManually; }
-
- // CachedResourceClient API
virtual void notifyFinished(CachedResource*);
-
- bool haveFiredLoadEvent() const { return m_firedLoad; }
-protected:
- void setLoadingImage(CachedImage*);
-
- void setHaveFiredLoadEvent(bool firedLoad) { m_firedLoad = firedLoad; }
-
-private:
- Element* m_element;
- CachedImage* m_image;
- bool m_firedLoad : 1;
- bool m_imageComplete : 1;
- bool m_loadManually : 1;
};
-} //namespace
+}
#endif
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index e9c2267..cebfb51 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.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 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
*
@@ -33,6 +33,8 @@
#include "Event.h"
#include "EventHandler.h"
#include "EventNames.h"
+#include "File.h"
+#include "FileList.h"
#include "FocusController.h"
#include "FormDataList.h"
#include "Frame.h"
@@ -46,10 +48,10 @@
#include "RenderButton.h"
#include "RenderFileUploadControl.h"
#include "RenderImage.h"
+#include "RenderSlider.h"
#include "RenderText.h"
#include "RenderTextControl.h"
#include "RenderTheme.h"
-#include "RenderSlider.h"
#include "SelectionController.h"
#include "TextBreakIterator.h"
#include "TextEvent.h"
@@ -57,9 +59,7 @@
#include "FrameLoader.h"
#endif
#ifdef ANDROID // multiple additions: see below
-#include "FrameAndroid.h"
-#include "FrameView.h"
-#include "WebCoreViewBridge.h"
+#include "WebViewCore.h"
#endif
#include "TextIterator.h"
@@ -67,7 +67,6 @@ using namespace std;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
const int maxSavedResults = 256;
@@ -130,10 +129,11 @@ void HTMLInputElement::init()
m_haveType = false;
m_activeSubmit = false;
- m_autocomplete = true;
+ m_autocomplete = Uninitialized;
m_inited = false;
m_autofilled = false;
-
+ m_placeholderShouldBeVisible = false;
+
xPos = 0;
yPos = 0;
@@ -141,15 +141,12 @@ void HTMLInputElement::init()
cachedSelEnd = -1;
m_maxResults = -1;
-
- if (form())
- m_autocomplete = form()->autoComplete();
}
HTMLInputElement::~HTMLInputElement()
{
- if (inputType() == PASSWORD)
- document()->unregisterForCacheCallbacks(this);
+ if (needsActivationCallback())
+ document()->unregisterForDocumentActivationCallbacks(this);
document()->checkedRadioButtons().removeButton(this);
@@ -163,6 +160,20 @@ const AtomicString& HTMLInputElement::name() const
return m_name.isNull() ? emptyAtom : m_name;
}
+bool HTMLInputElement::autoComplete() const
+{
+ if (m_autocomplete != Uninitialized)
+ return m_autocomplete == On;
+
+ // Assuming we're still in a Form, respect the Form's setting
+ if (HTMLFormElement* form = this->form())
+ return form->autoComplete();
+
+ // The default is true
+ return true;
+}
+
+
static inline HTMLFormElement::CheckedRadioButtons& checkedRadioButtons(const HTMLInputElement *element)
{
if (HTMLFormElement* form = element->form())
@@ -242,6 +253,7 @@ void HTMLInputElement::dispatchFocusEvent()
{
if (isTextField()) {
setAutofilled(false);
+ updatePlaceholderVisibility();
if (inputType() == PASSWORD && document()->frame())
document()->setUseSecureKeyboardEntryWhenActive(true);
}
@@ -251,6 +263,7 @@ void HTMLInputElement::dispatchFocusEvent()
void HTMLInputElement::dispatchBlurEvent()
{
if (isTextField() && document()->frame()) {
+ updatePlaceholderVisibility();
if (inputType() == PASSWORD)
document()->setUseSecureKeyboardEntryWhenActive(false);
document()->frame()->textFieldDidEndEditing(this);
@@ -276,8 +289,7 @@ void HTMLInputElement::setInputType(const String& t)
{
if (document()->focusedNode() == this)
{
- WebCoreViewBridge* viewImpl = document()->frame()->view()->getWebCoreViewBridge();
- viewImpl->updateTextfield(this, true, String());
+ android::WebViewCore::getWebViewCore(document()->view())->updateTextfield(this, true, String());
}
#endif
newType = PASSWORD;
@@ -320,7 +332,10 @@ void HTMLInputElement::setInputType(const String& t)
else {
checkedRadioButtons(this).removeButton(this);
- bool wasAttached = m_attached;
+ if (newType == FILE && !m_fileList)
+ m_fileList = FileList::create();
+
+ bool wasAttached = attached();
if (wasAttached)
detach();
@@ -342,22 +357,25 @@ void HTMLInputElement::setInputType(const String& t)
recheckValue();
if (wasPasswordField && !isPasswordField)
- document()->unregisterForCacheCallbacks(this);
+ unregisterForActivationCallbackIfNeeded();
else if (!wasPasswordField && isPasswordField)
- document()->registerForCacheCallbacks(this);
+ registerForActivationCallbackIfNeeded();
if (didRespectHeightAndWidth != willRespectHeightAndWidth) {
NamedMappedAttrMap* map = mappedAttributes();
- if (MappedAttribute* height = map->getAttributeItem(heightAttr))
+ if (Attribute* height = map->getAttributeItem(heightAttr))
attributeChanged(height, false);
- if (MappedAttribute* width = map->getAttributeItem(widthAttr))
+ if (Attribute* width = map->getAttributeItem(widthAttr))
attributeChanged(width, false);
- if (MappedAttribute* align = map->getAttributeItem(alignAttr))
+ if (Attribute* align = map->getAttributeItem(alignAttr))
attributeChanged(align, false);
}
- if (wasAttached)
+ if (wasAttached) {
attach();
+ if (document()->focusedNode() == this)
+ updateFocusAppearance(true);
+ }
checkedRadioButtons(this).addButton(this);
}
@@ -428,6 +446,9 @@ const AtomicString& HTMLInputElement::type() const
bool HTMLInputElement::saveState(String& result) const
{
+ if (!autoComplete())
+ return false;
+
switch (inputType()) {
case BUTTON:
case FILE:
@@ -602,7 +623,17 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
m_name = attr->value();
checkedRadioButtons(this).addButton(this);
} else if (attr->name() == autocompleteAttr) {
- m_autocomplete = !equalIgnoringCase(attr->value(), "off");
+ if (equalIgnoringCase(attr->value(), "off")) {
+ m_autocomplete = Off;
+ registerForActivationCallbackIfNeeded();
+ } else {
+ if (m_autocomplete == Off)
+ unregisterForActivationCallbackIfNeeded();
+ if (attr->isEmpty())
+ m_autocomplete = Uninitialized;
+ else
+ m_autocomplete = On;
+ }
} else if (attr->name() == typeAttr) {
setInputType(attr->value());
} else if (attr->name() == valueAttr) {
@@ -639,35 +670,35 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
attr->name() == accesskeyAttr) {
// FIXME: ignore for the moment
} else if (attr->name() == vspaceAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
} else if (attr->name() == hspaceAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
} else if (attr->name() == alignAttr) {
if (inputType() == IMAGE)
addHTMLAlignment(attr);
} else if (attr->name() == widthAttr) {
if (respectHeightAndWidthAttrs())
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
} else if (attr->name() == heightAttr) {
if (respectHeightAndWidthAttrs())
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
} else if (attr->name() == onfocusAttr) {
- setHTMLEventListener(focusEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
} else if (attr->name() == onblurAttr) {
- setHTMLEventListener(blurEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
} else if (attr->name() == onselectAttr) {
- setHTMLEventListener(selectEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().selectEvent, attr);
} else if (attr->name() == onchangeAttr) {
- setHTMLEventListener(changeEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().changeEvent, attr);
} else if (attr->name() == oninputAttr) {
- setHTMLEventListener(inputEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().inputEvent, attr);
}
// Search field and slider attributes all just cause updateFromElement to be called through style
// recalcing.
else if (attr->name() == onsearchAttr) {
- setHTMLEventListener(searchEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().searchEvent, attr);
} else if (attr->name() == resultsAttr) {
int oldResults = m_maxResults;
m_maxResults = !attr->isNull() ? min(attr->value().toInt(), maxSavedResults) : -1;
@@ -678,14 +709,16 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
attach();
}
setChanged();
- } else if (attr->name() == autosaveAttr ||
+ } else if (attr->name() == placeholderAttr)
+ updatePlaceholderVisibility(true);
+ else if (attr->name() == autosaveAttr ||
attr->name() == incrementalAttr ||
- attr->name() == placeholderAttr ||
attr->name() == minAttr ||
attr->name() == maxAttr ||
- attr->name() == precisionAttr) {
+ attr->name() == multipleAttr ||
+ attr->name() == precisionAttr)
setChanged();
- } else
+ else
HTMLFormControlElementWithState::parseMappedAttribute(attr);
}
@@ -860,20 +893,23 @@ bool HTMLInputElement::appendFormData(FormDataList& encoding, bool multipart)
}
break;
- case FILE:
+ case FILE: {
// Can't submit file on GET.
if (!multipart)
return false;
// If no filename at all is entered, return successful but empty.
// Null would be more logical, but Netscape posts an empty file. Argh.
- if (value().isEmpty()) {
- encoding.appendData(name(), String(""));
+ unsigned numFiles = m_fileList->length();
+ if (!numFiles) {
+ encoding.appendFile(name(), File::create(""));
return true;
}
- encoding.appendFile(name(), value());
+ for (unsigned i = 0; i < numFiles; ++i)
+ encoding.appendFile(name(), m_fileList->item(i));
return true;
+ }
}
return false;
}
@@ -939,17 +975,22 @@ void HTMLInputElement::copyNonAttributeProperties(const Element *source)
String HTMLInputElement::value() const
{
- String value = m_value;
+ // The HTML5 spec (as of the 10/24/08 working draft) says that the value attribute isn't applicable to the file upload control
+ // but we don't want to break existing websites, who may be relying on being able to get the file name as a value.
+ if (inputType() == FILE) {
+ if (!m_fileList->isEmpty())
+ return m_fileList->item(0)->fileName();
+ return String();
+ }
- // It's important *not* to fall back to the value attribute for file inputs,
- // because that would allow a malicious web page to upload files by setting the
- // value attribute in markup.
- if (value.isNull() && inputType() != FILE)
+ String value = m_value;
+ if (value.isNull()) {
value = constrainValue(getAttribute(valueAttr));
- // If no attribute exists, then just use "on" or "" based off the checked() state of the control.
- if (value.isNull() && (inputType() == CHECKBOX || inputType() == RADIO))
- return checked() ? "on" : "";
+ // If no attribute exists, then just use "on" or "" based off the checked() state of the control.
+ if (value.isNull() && (inputType() == CHECKBOX || inputType() == RADIO))
+ return checked() ? "on" : "";
+ }
return value;
}
@@ -985,14 +1026,23 @@ String HTMLInputElement::valueWithDefault() const
void HTMLInputElement::setValue(const String& value)
{
// For security reasons, we don't allow setting the filename, but we do allow clearing it.
+ // The HTML5 spec (as of the 10/24/08 working draft) says that the value attribute isn't applicable to the file upload control
+ // but we don't want to break existing websites, who may be relying on this method to clear things.
if (inputType() == FILE && !value.isEmpty())
return;
+ if (isTextField())
+ updatePlaceholderVisibility();
+
setValueMatchesRenderer(false);
if (storesValueSeparateFromAttribute()) {
- m_value = constrainValue(value);
- if (isTextField() && inDocument())
- document()->updateRendering();
+ if (inputType() == FILE)
+ m_fileList->clear();
+ else {
+ m_value = constrainValue(value);
+ if (isTextField() && inDocument())
+ document()->updateRendering();
+ }
if (renderer())
renderer()->updateFromElement();
setChanged();
@@ -1007,8 +1057,7 @@ void HTMLInputElement::setValue(const String& value)
#else
{
// Make sure our UI side textfield changes to match the RenderTextControl
- WebCoreViewBridge* viewImpl = document()->frame()->view()->getWebCoreViewBridge();
- viewImpl->updateTextfield(this, false, value);
+ android::WebViewCore::getWebViewCore(document()->view())->updateTextfield(this, false, value);
setSelectionRange(max, max);
}
#endif
@@ -1024,6 +1073,12 @@ void HTMLInputElement::setValueFromRenderer(const String& value)
// Renderer and our event handler are responsible for constraining values.
ASSERT(value == constrainValue(value) || constrainValue(value).isEmpty());
+ // File upload controls will always use setFileListFromRenderer.
+ ASSERT (inputType() != FILE);
+
+ if (isTextField())
+ updatePlaceholderVisibility();
+
// Workaround for bug where trailing \n is included in the result of textContent.
// The assert macro above may also be simplified to: value == constrainValue(value)
// http://bugs.webkit.org/show_bug.cgi?id=9661
@@ -1035,7 +1090,17 @@ void HTMLInputElement::setValueFromRenderer(const String& value)
setValueMatchesRenderer();
// Fire the "input" DOM event.
- dispatchHTMLEvent(inputEvent, true, false);
+ dispatchEventForType(eventNames().inputEvent, true, false);
+}
+
+void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
+{
+ m_fileList->clear();
+ int size = paths.size();
+ for (int i = 0; i < size; i++)
+ m_fileList->append(File::create(paths[i]));
+
+ setValueMatchesRenderer();
}
bool HTMLInputElement::storesValueSeparateFromAttribute() const
@@ -1066,7 +1131,7 @@ void* HTMLInputElement::preDispatchEventHandler(Event *evt)
// This result gives us enough info to perform the "undo" in postDispatch of the action we take here.
void* result = 0;
if ((inputType() == CHECKBOX || inputType() == RADIO) && evt->isMouseEvent()
- && evt->type() == clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
+ && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
if (inputType() == CHECKBOX) {
// As a way to store the state, we return 0 if we were unchecked, 1 if we were checked, and 2 for
// indeterminate.
@@ -1104,7 +1169,7 @@ void* HTMLInputElement::preDispatchEventHandler(Event *evt)
void HTMLInputElement::postDispatchEventHandler(Event *evt, void* data)
{
if ((inputType() == CHECKBOX || inputType() == RADIO) && evt->isMouseEvent()
- && evt->type() == clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
+ && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
if (inputType() == CHECKBOX) {
// Reverse the checking we did in preDispatch.
if (evt->defaultPrevented() || evt->defaultHandled()) {
@@ -1139,10 +1204,10 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
{
bool clickDefaultFormButton = false;
- if (isTextField() && evt->type() == textInputEvent && evt->isTextEvent() && static_cast<TextEvent*>(evt)->data() == "\n")
+ if (isTextField() && evt->type() == eventNames().textInputEvent && evt->isTextEvent() && static_cast<TextEvent*>(evt)->data() == "\n")
clickDefaultFormButton = true;
- if (inputType() == IMAGE && evt->isMouseEvent() && evt->type() == clickEvent) {
+ if (inputType() == IMAGE && evt->isMouseEvent() && evt->type() == eventNames().clickEvent) {
// record the mouse position for when we get the DOMActivate event
MouseEvent* me = static_cast<MouseEvent*>(evt);
// FIXME: We could just call offsetX() and offsetY() on the event,
@@ -1159,14 +1224,14 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
}
}
- if (isTextField() && evt->type() == keydownEvent && evt->isKeyboardEvent() && focused() && document()->frame()
+ if (isTextField() && evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent() && focused() && document()->frame()
&& document()->frame()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
evt->setDefaultHandled();
return;
}
if (inputType() == RADIO && evt->isMouseEvent()
- && evt->type() == clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
+ && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
evt->setDefaultHandled();
return;
}
@@ -1182,7 +1247,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
// actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
// on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
// must dispatch a DOMActivate event - a click event will not do the job.
- if (evt->type() == DOMActivateEvent && !disabled()) {
+ if (evt->type() == eventNames().DOMActivateEvent && !disabled()) {
if (inputType() == IMAGE || inputType() == SUBMIT || inputType() == RESET) {
if (!form())
return;
@@ -1206,7 +1271,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
// 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() == keypressEvent && evt->isKeyboardEvent()) {
+ if (evt->type() == eventNames().keypressEvent && evt->isKeyboardEvent()) {
bool clickElement = false;
int charCode = static_cast<KeyboardEvent*>(evt)->charCode();
@@ -1263,7 +1328,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
}
}
- if (evt->type() == keydownEvent && evt->isKeyboardEvent()) {
+ if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent()) {
String key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
if (key == "U+0020") {
@@ -1322,7 +1387,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
#endif
}
- if (evt->type() == keyupEvent && evt->isKeyboardEvent()) {
+ if (evt->type() == eventNames().keyupEvent && evt->isKeyboardEvent()) {
bool clickElement = false;
String key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
@@ -1388,7 +1453,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
// Make sure that the text to be inserted will not violate the maxLength.
int oldLen = numGraphemeClusters(value().impl());
ASSERT(oldLen <= maxLength());
- int selectionLen = numGraphemeClusters(plainText(document()->frame()->selectionController()->selection().toRange().get()).impl());
+ int selectionLen = numGraphemeClusters(plainText(document()->frame()->selection()->selection().toRange().get()).impl());
ASSERT(oldLen >= selectionLen);
int maxNewLen = maxLength() - (oldLen - selectionLen);
@@ -1397,12 +1462,12 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
textEvent->setText(constrainValue(textEvent->text(), maxNewLen));
}
- if (isTextField() && renderer() && (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent() || evt->type() == blurEvent || evt->type() == focusEvent))
+ if (isTextField() && renderer() && (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent() || evt->type() == eventNames().blurEvent || evt->type() == eventNames().focusEvent))
static_cast<RenderTextControl*>(renderer())->forwardEvent(evt);
if (inputType() == RANGE && renderer()) {
RenderSlider* slider = static_cast<RenderSlider*>(renderer());
- if (evt->isMouseEvent() && evt->type() == mousedownEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
+ if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
MouseEvent* mEvt = static_cast<MouseEvent*>(evt);
if (!slider->mouseEventIsInThumb(mEvt)) {
IntPoint eventOffset(mEvt->offsetX(), mEvt->offsetY());
@@ -1494,7 +1559,7 @@ void HTMLInputElement::setSize(unsigned _size)
setAttribute(sizeAttr, String::number(_size));
}
-String HTMLInputElement::src() const
+KURL HTMLInputElement::src() const
{
return document()->completeURL(getAttribute(srcAttr));
}
@@ -1514,6 +1579,13 @@ void HTMLInputElement::setUseMap(const String &value)
setAttribute(usemapAttr, value);
}
+FileList* HTMLInputElement::files()
+{
+ if (inputType() != FILE)
+ return 0;
+ return m_fileList.get();
+}
+
String HTMLInputElement::constrainValue(const String& proposedValue) const
{
return constrainValue(proposedValue, m_maxLen);
@@ -1527,10 +1599,45 @@ void HTMLInputElement::recheckValue()
setValue(newValue);
}
+bool HTMLInputElement::needsActivationCallback()
+{
+ return inputType() == PASSWORD || m_autocomplete == Off;
+}
+
+void HTMLInputElement::registerForActivationCallbackIfNeeded()
+{
+ if (needsActivationCallback())
+ document()->registerForDocumentActivationCallbacks(this);
+}
+
+void HTMLInputElement::unregisterForActivationCallbackIfNeeded()
+{
+ if (!needsActivationCallback())
+ document()->unregisterForDocumentActivationCallbacks(this);
+}
+
+void HTMLInputElement::updatePlaceholderVisibility(bool placeholderValueChanged)
+{
+ ASSERT(isTextField());
+
+ bool oldPlaceholderShouldBeVisible = m_placeholderShouldBeVisible;
+
+ m_placeholderShouldBeVisible = value().isEmpty()
+ && document()->focusedNode() != this
+ && !getAttribute(placeholderAttr).isEmpty();
+
+ if ((oldPlaceholderShouldBeVisible != m_placeholderShouldBeVisible || placeholderValueChanged) && renderer())
+ static_cast<RenderTextControl*>(renderer())->updatePlaceholderVisibility();
+}
+
String HTMLInputElement::constrainValue(const String& proposedValue, int maxLen) const
{
+ String string = proposedValue;
if (isTextField()) {
- StringImpl* s = proposedValue.impl();
+ string.replace("\r\n", " ");
+ string.replace('\r', ' ');
+ string.replace('\n', ' ');
+ StringImpl* s = string.impl();
int newLen = numCharactersInGraphemeClusters(s, maxLen);
for (int i = 0; i < newLen; ++i) {
const UChar current = (*s)[i];
@@ -1539,10 +1646,10 @@ String HTMLInputElement::constrainValue(const String& proposedValue, int maxLen)
break;
}
}
- if (newLen < static_cast<int>(proposedValue.length()))
- return proposedValue.substring(0, newLen);
+ if (newLen < static_cast<int>(string.length()))
+ return string.substring(0, newLen);
}
- return proposedValue;
+ return string;
}
void HTMLInputElement::addSearchResult()
@@ -1557,7 +1664,7 @@ void HTMLInputElement::onSearch()
ASSERT(isSearchField());
if (renderer())
static_cast<RenderTextControl*>(renderer())->stopSearchEventTimer();
- dispatchHTMLEvent(searchEvent, true, false);
+ dispatchEventForType(eventNames().searchEvent, true, false);
}
Selection HTMLInputElement::selection() const
@@ -1567,16 +1674,17 @@ Selection HTMLInputElement::selection() const
return static_cast<RenderTextControl*>(renderer())->selection(cachedSelStart, cachedSelEnd);
}
-void HTMLInputElement::didRestoreFromCache()
+void HTMLInputElement::documentDidBecomeActive()
{
- ASSERT(inputType() == PASSWORD);
+ ASSERT(needsActivationCallback());
reset();
}
void HTMLInputElement::willMoveToNewOwnerDocument()
{
- if (inputType() == PASSWORD)
- document()->unregisterForCacheCallbacks(this);
+ // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered
+ if (needsActivationCallback())
+ document()->unregisterForDocumentActivationCallbacks(this);
document()->checkedRadioButtons().removeButton(this);
@@ -1585,10 +1693,20 @@ void HTMLInputElement::willMoveToNewOwnerDocument()
void HTMLInputElement::didMoveToNewOwnerDocument()
{
- if (inputType() == PASSWORD)
- document()->registerForCacheCallbacks(this);
+ registerForActivationCallbackIfNeeded();
HTMLFormControlElementWithState::didMoveToNewOwnerDocument();
}
+void HTMLInputElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ urls.append(src().string());
+}
+
+bool HTMLInputElement::willValidate() const
+{
+ // FIXME: This shall check for new WF2 input types too
+ return HTMLFormControlElementWithState::willValidate() && inputType() != HIDDEN &&
+ inputType() != BUTTON && inputType() != RESET;
+}
} // namespace
diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h
index 410f2e1..7f090a8 100644
--- a/WebCore/html/HTMLInputElement.h
+++ b/WebCore/html/HTMLInputElement.h
@@ -24,12 +24,14 @@
#ifndef HTMLInputElement_h
#define HTMLInputElement_h
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
#include <wtf/OwnPtr.h>
namespace WebCore {
+class FileList;
class HTMLImageLoader;
+class KURL;
class Selection;
class HTMLInputElement : public HTMLFormControlElementWithState {
@@ -49,6 +51,12 @@ public:
SEARCH,
RANGE
};
+
+ enum AutoCompleteSetting {
+ Uninitialized,
+ On,
+ Off
+ };
HTMLInputElement(Document*, HTMLFormElement* = 0);
HTMLInputElement(const QualifiedName& tagName, Document*, HTMLFormElement* = 0);
@@ -68,7 +76,7 @@ public:
virtual const AtomicString& name() const;
- bool autoComplete() const { return m_autocomplete; }
+ bool autoComplete() const;
// isChecked is used by the rendering tree/CSS while checked() is used by JS to determine checked state
virtual bool isChecked() const { return checked() && (inputType() == CHECKBOX || inputType() == RADIO); }
@@ -76,11 +84,14 @@ public:
bool readOnly() const { return isReadOnlyControl(); }
+ virtual bool isTextControl() const { return isTextField(); }
+
bool isTextButton() const { return m_type == SUBMIT || m_type == RESET || m_type == BUTTON; }
virtual bool isRadioButton() const { return m_type == RADIO; }
bool isTextField() const { return m_type == TEXT || m_type == PASSWORD || m_type == SEARCH || m_type == ISINDEX; }
bool isSearchField() const { return m_type == SEARCH; }
virtual bool isInputTypeHidden() const { return m_type == HIDDEN; }
+ virtual bool isPasswordField() const { return m_type == PASSWORD; }
bool checked() const { return m_checked; }
void setChecked(bool, bool sendChangeEvent = false);
@@ -97,6 +108,7 @@ public:
String valueWithDefault() const;
void setValueFromRenderer(const String&);
+ void setFileListFromRenderer(const Vector<String>&);
virtual bool saveState(String& value) const;
virtual void restoreState(const String&);
@@ -166,7 +178,7 @@ public:
void setSize(unsigned);
- String src() const;
+ KURL src() const;
void setSrc(const String&);
void setMaxLength(int);
@@ -176,7 +188,9 @@ public:
bool autofilled() const { return m_autofilled; }
void setAutofilled(bool b = true) { m_autofilled = b; }
-
+
+ FileList* files();
+
void cacheSelection(int s, int e) { cachedSelStart = s; cachedSelEnd = e; };
void addSearchResult();
void onSearch();
@@ -185,7 +199,13 @@ public:
String constrainValue(const String& proposedValue) const;
- virtual void didRestoreFromCache();
+ virtual void documentDidBecomeActive();
+
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
+ virtual bool willValidate() const;
+
+ bool placeholderShouldBeVisible() const { return m_placeholderShouldBeVisible; }
protected:
virtual void willMoveToNewOwnerDocument();
@@ -198,7 +218,13 @@ private:
bool storesValueSeparateFromAttribute() const;
String constrainValue(const String& proposedValue, int maxLen) const;
void recheckValue();
+
+ bool needsActivationCallback();
+ void registerForActivationCallbackIfNeeded();
+ void unregisterForActivationCallbackIfNeeded();
+ void updatePlaceholderVisibility(bool placeholderValueChanged = false);
+
String m_value;
String m_originalValue;
int xPos;
@@ -210,6 +236,8 @@ private:
OwnPtr<HTMLImageLoader> m_imageLoader;
+ RefPtr<FileList> m_fileList;
+
unsigned m_type : 4; // InputType
bool m_checked : 1;
bool m_defaultChecked : 1;
@@ -217,9 +245,10 @@ private:
bool m_indeterminate : 1;
bool m_haveType : 1;
bool m_activeSubmit : 1;
- bool m_autocomplete : 1;
+ unsigned m_autocomplete : 2; // AutoCompleteSetting
bool m_autofilled : 1;
bool m_inited : 1;
+ bool m_placeholderShouldBeVisible : 1;
int cachedSelStart;
int cachedSelEnd;
diff --git a/WebCore/html/HTMLInputElement.idl b/WebCore/html/HTMLInputElement.idl
index 29522be..a9b6d2c 100644
--- a/WebCore/html/HTMLInputElement.idl
+++ b/WebCore/html/HTMLInputElement.idl
@@ -21,7 +21,7 @@
module html {
interface [
- LegacyParent=JSHTMLInputElementBase,
+ CustomGetOwnPropertySlot,
GenerateConstructor,
InterfaceUUID=8f388ea3-1c31-4cca-8edd-449d14e222e1,
ImplementationUUID=aeb56b87-a90e-4d9d-a4d5-7eec3687c338
@@ -35,6 +35,7 @@ module html {
attribute [ConvertNullToNullString] DOMString alt;
attribute boolean checked;
attribute boolean disabled;
+ attribute boolean autofocus;
attribute long maxLength;
attribute [ConvertNullToNullString] DOMString name;
attribute boolean readOnly;
@@ -45,33 +46,31 @@ module html {
attribute unsigned long size; // Changed string -> long as part of DOM level 2
#endif
attribute [ConvertNullToNullString] DOMString src;
- attribute long tabIndex;
attribute [ConvertNullToNullString] DOMString type; // readonly dropped as part of DOM level 2
attribute [ConvertNullToNullString] DOMString useMap;
attribute [ConvertNullToNullString] DOMString value;
-
- void blur();
- void focus();
+ readonly attribute boolean willValidate;
void select();
void click();
// WinIE extension:
attribute boolean indeterminate;
-
+
// WinIE & FireFox extension:
-
- // Handled by JSHTMLInputElementBase to allow hiding based on input type
-#if !defined(LANGUAGE_JAVASCRIPT)
- attribute long selectionStart;
- attribute long selectionEnd;
+
+ attribute [CustomGetter] long selectionStart;
+ attribute [CustomGetter] long selectionEnd;
void setSelectionRange(in long start, in long end);
-#endif
#if defined(LANGUAGE_OBJECTIVE_C)
// Objective-C extension:
readonly attribute DOMString altDisplayString;
readonly attribute URL absoluteImageURL;
#endif
+
+#if !defined(LANGUAGE_COM)
+ readonly attribute FileList files;
+#endif
};
}
diff --git a/WebCore/html/HTMLIsIndexElement.cpp b/WebCore/html/HTMLIsIndexElement.cpp
index fe2acbd..2abc23f 100644
--- a/WebCore/html/HTMLIsIndexElement.cpp
+++ b/WebCore/html/HTMLIsIndexElement.cpp
@@ -45,7 +45,7 @@ void HTMLIsIndexElement::parseMappedAttribute(MappedAttribute* attr)
else
// don't call HTMLInputElement::parseMappedAttribute here, as it would
// accept attributes this element does not support
- HTMLGenericFormElement::parseMappedAttribute(attr);
+ HTMLFormControlElement::parseMappedAttribute(attr);
}
String HTMLIsIndexElement::prompt() const
diff --git a/WebCore/html/HTMLKeygenElement.cpp b/WebCore/html/HTMLKeygenElement.cpp
index 509d415..b918d78 100644
--- a/WebCore/html/HTMLKeygenElement.cpp
+++ b/WebCore/html/HTMLKeygenElement.cpp
@@ -31,7 +31,6 @@
#include "FormDataList.h"
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
-#include "KURL.h"
#include "SSLKeyGenerator.h"
#include "Text.h"
@@ -44,7 +43,8 @@ using namespace HTMLNames;
HTMLKeygenElement::HTMLKeygenElement(Document* doc, HTMLFormElement* f)
: HTMLSelectElement(keygenTag, doc, f)
{
- Vector<String> keys = supportedKeySizes();
+ Vector<String> keys;
+ getSupportedKeySizes(keys);
Vector<String>::const_iterator end = keys.end();
for (Vector<String>::const_iterator it = keys.begin(); it != end; ++it) {
@@ -68,7 +68,7 @@ void HTMLKeygenElement::parseMappedAttribute(MappedAttribute* attr)
m_keyType = attr->value();
else
// skip HTMLSelectElement parsing!
- HTMLGenericFormElement::parseMappedAttribute(attr);
+ HTMLFormControlElement::parseMappedAttribute(attr);
}
bool HTMLKeygenElement::appendFormData(FormDataList& encoded_values, bool)
diff --git a/WebCore/html/HTMLLIElement.cpp b/WebCore/html/HTMLLIElement.cpp
index e5a0d76..6cb9304 100644
--- a/WebCore/html/HTMLLIElement.cpp
+++ b/WebCore/html/HTMLLIElement.cpp
@@ -60,17 +60,17 @@ void HTMLLIElement::parseMappedAttribute(MappedAttribute* attr)
}
} else if (attr->name() == typeAttr) {
if (attr->value() == "a")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_LOWER_ALPHA);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueLowerAlpha);
else if (attr->value() == "A")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_UPPER_ALPHA);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueUpperAlpha);
else if (attr->value() == "i")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_LOWER_ROMAN);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueLowerRoman);
else if (attr->value() == "I")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_UPPER_ROMAN);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueUpperRoman);
else if (attr->value() == "1")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_DECIMAL);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueDecimal);
else
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, attr->value());
+ addCSSProperty(attr, CSSPropertyListStyleType, attr->value());
} else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLLabelElement.cpp b/WebCore/html/HTMLLabelElement.cpp
index b445888..6d97bc1 100644
--- a/WebCore/html/HTMLLabelElement.cpp
+++ b/WebCore/html/HTMLLabelElement.cpp
@@ -34,7 +34,6 @@
namespace WebCore {
using namespace HTMLNames;
-using namespace EventNames;
HTMLLabelElement::HTMLLabelElement(Document *doc)
: HTMLElement(labelTag, doc)
@@ -103,7 +102,7 @@ void HTMLLabelElement::defaultEventHandler(Event* evt)
{
static bool processingClick = false;
- if (evt->type() == clickEvent && !processingClick) {
+ if (evt->type() == eventNames().clickEvent && !processingClick) {
RefPtr<HTMLElement> control = correspondingControl();
// If we can't find a control or if the control received the click
diff --git a/WebCore/html/HTMLLabelElement.idl b/WebCore/html/HTMLLabelElement.idl
index c40aad9..85b7ef3 100644
--- a/WebCore/html/HTMLLabelElement.idl
+++ b/WebCore/html/HTMLLabelElement.idl
@@ -28,8 +28,6 @@ module html {
readonly attribute HTMLFormElement form;
attribute [ConvertNullToNullString] DOMString accessKey;
attribute [ConvertNullToNullString] DOMString htmlFor;
-
- void focus();
};
}
diff --git a/WebCore/html/HTMLLegendElement.cpp b/WebCore/html/HTMLLegendElement.cpp
index 7f47861..573f06f 100644
--- a/WebCore/html/HTMLLegendElement.cpp
+++ b/WebCore/html/HTMLLegendElement.cpp
@@ -35,7 +35,7 @@ namespace WebCore {
using namespace HTMLNames;
HTMLLegendElement::HTMLLegendElement(Document *doc, HTMLFormElement *f)
-: HTMLGenericFormElement(legendTag, doc, f)
+ : HTMLFormControlElement(legendTag, doc, f)
{
}
@@ -45,7 +45,7 @@ HTMLLegendElement::~HTMLLegendElement()
bool HTMLLegendElement::isFocusable() const
{
- return false;
+ return HTMLElement::isFocusable();
}
RenderObject* HTMLLegendElement::createRenderer(RenderArena* arena, RenderStyle* style)
@@ -107,6 +107,9 @@ Element *HTMLLegendElement::formElement()
void HTMLLegendElement::focus(bool)
{
+ if (isFocusable())
+ Element::focus();
+
// to match other browsers, never restore previous selection
if (Element *element = formElement())
element->focus(false);
diff --git a/WebCore/html/HTMLLegendElement.h b/WebCore/html/HTMLLegendElement.h
index f48ea02..0873f34 100644
--- a/WebCore/html/HTMLLegendElement.h
+++ b/WebCore/html/HTMLLegendElement.h
@@ -26,11 +26,11 @@
#ifndef HTMLLegendElement_h
#define HTMLLegendElement_h
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
namespace WebCore {
-class HTMLLegendElement : public HTMLGenericFormElement {
+class HTMLLegendElement : public HTMLFormControlElement {
public:
HTMLLegendElement(Document*, HTMLFormElement* = 0);
virtual ~HTMLLegendElement();
diff --git a/WebCore/html/HTMLLegendElement.idl b/WebCore/html/HTMLLegendElement.idl
index 8a78d77..da00cc1 100644
--- a/WebCore/html/HTMLLegendElement.idl
+++ b/WebCore/html/HTMLLegendElement.idl
@@ -28,8 +28,6 @@ module html {
readonly attribute HTMLFormElement form;
attribute [ConvertNullToNullString] DOMString accessKey;
attribute [ConvertNullToNullString] DOMString align;
-
- void focus();
};
}
diff --git a/WebCore/html/HTMLLinkElement.cpp b/WebCore/html/HTMLLinkElement.cpp
index b002a0c..6cbcd80 100644
--- a/WebCore/html/HTMLLinkElement.cpp
+++ b/WebCore/html/HTMLLinkElement.cpp
@@ -1,10 +1,8 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 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
@@ -21,19 +19,24 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLLinkElement.h"
#include "CSSHelper.h"
#include "CachedCSSStyleSheet.h"
+#include "DNS.h"
#include "DocLoader.h"
#include "Document.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
#include "FrameTree.h"
#include "HTMLNames.h"
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
+#include "Page.h"
+#include "Settings.h"
namespace WebCore {
@@ -47,13 +50,15 @@ HTMLLinkElement::HTMLLinkElement(Document *doc)
, m_alternate(false)
, m_isStyleSheet(false)
, m_isIcon(false)
+ , m_isDNSPrefetch(false)
+ , m_createdByParser(false)
{
}
HTMLLinkElement::~HTMLLinkElement()
{
if (m_cachedSheet) {
- m_cachedSheet->deref(this);
+ m_cachedSheet->removeClient(this);
if (m_loading && !isDisabled() && !isAlternate())
document()->removePendingSheet();
}
@@ -105,20 +110,16 @@ StyleSheet* HTMLLinkElement::sheet() const
void HTMLLinkElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == relAttr) {
-#ifdef ANDROID_PRELOAD_CHANGES
- tokenizeRelAttribute(attr->value(), m_isStyleSheet, m_alternate, m_isIcon);
-#else
- tokenizeRelAttribute(attr->value());
-#endif
+ tokenizeRelAttribute(attr->value(), m_isStyleSheet, m_alternate, m_isIcon, m_isDNSPrefetch);
process();
} else if (attr->name() == hrefAttr) {
- m_url = document()->completeURL(parseURL(attr->value()));
+ m_url = document()->completeURL(parseURL(attr->value())).string();
process();
} else if (attr->name() == typeAttr) {
m_type = attr->value();
process();
} else if (attr->name() == mediaAttr) {
- m_media = attr->value().domString().lower();
+ m_media = attr->value().string().lower();
process();
} else if (attr->name() == disabledAttr) {
setDisabledState(!attr->isNull());
@@ -129,62 +130,38 @@ void HTMLLinkElement::parseMappedAttribute(MappedAttribute *attr)
}
}
-#ifdef ANDROID_PRELOAD_CHANGES
-void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& relStr, bool& styleSheet, bool& alternate, bool& icon)
+void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, bool& styleSheet, bool& alternate, bool& icon, bool& dnsPrefetch)
{
styleSheet = false;
icon = false;
alternate = false;
- String rel = relStr.domString().lower();
- if (rel == "stylesheet")
+ dnsPrefetch = false;
+ if (equalIgnoringCase(rel, "stylesheet"))
styleSheet = true;
- else if (rel == "icon" || rel == "shortcut icon")
+ else if (equalIgnoringCase(rel, "icon") || equalIgnoringCase(rel, "shortcut icon"))
icon = true;
- else if (rel == "alternate stylesheet" || rel == "stylesheet alternate") {
+ else if (equalIgnoringCase(rel, "dns-prefetch"))
+ dnsPrefetch = true;
+ else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
styleSheet = true;
alternate = true;
} else {
// Tokenize the rel attribute and set bits based on specific keywords that we find.
- rel.replace('\n', ' ');
- Vector<String> list = rel.split(' ');
+ String relString = rel.string();
+ relString.replace('\n', ' ');
+ Vector<String> list;
+ relString.split(' ', list);
Vector<String>::const_iterator end = list.end();
for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
- if (*it == "stylesheet")
+ if (equalIgnoringCase(*it, "stylesheet"))
styleSheet = true;
- else if (*it == "alternate")
+ else if (equalIgnoringCase(*it, "alternate"))
alternate = true;
- else if (*it == "icon")
+ else if (equalIgnoringCase(*it, "icon"))
icon = true;
}
}
}
-#else
-void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& relStr)
-{
- m_isStyleSheet = m_isIcon = m_alternate = false;
- String rel = relStr.domString().lower();
- if (rel == "stylesheet")
- m_isStyleSheet = true;
- else if (rel == "icon" || rel == "shortcut icon")
- m_isIcon = true;
- else if (rel == "alternate stylesheet" || rel == "stylesheet alternate")
- m_isStyleSheet = m_alternate = true;
- else {
- // Tokenize the rel attribute and set bits based on specific keywords that we find.
- rel.replace('\n', ' ');
- Vector<String> list = rel.split(' ');
- Vector<String>::const_iterator end = list.end();
- for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
- if (*it == "stylesheet")
- m_isStyleSheet = true;
- else if (*it == "alternate")
- m_alternate = true;
- else if (*it == "icon")
- m_isIcon = true;
- }
- }
-}
-#endif
void HTMLLinkElement::process()
{
@@ -198,16 +175,19 @@ void HTMLLinkElement::process()
if (m_isIcon && !m_url.isEmpty())
document()->setIconURL(m_url, type);
+ if (m_isDNSPrefetch && !m_url.isEmpty())
+ prefetchDNS(KURL(m_url).host());
+
// Stylesheet
// This was buggy and would incorrectly match <link rel="alternate">, which has a different specified meaning. -dwh
- if (m_disabledState != 2 && (type.contains("text/css") || m_isStyleSheet) && document()->frame()) {
+ if (m_disabledState != 2 && m_isStyleSheet && document()->frame()) {
// 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 = new MediaList((CSSStyleSheet*)0, m_media, 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
@@ -222,12 +202,12 @@ void HTMLLinkElement::process()
if (m_cachedSheet) {
if (m_loading)
document()->removePendingSheet();
- m_cachedSheet->deref(this);
+ m_cachedSheet->removeClient(this);
}
m_loading = true;
m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(m_url, chset);
if (m_cachedSheet)
- m_cachedSheet->ref(this);
+ m_cachedSheet->addClient(this);
else if (!isAlternate()) { // request may have been denied if stylesheet is local and document is remote.
m_loading = false;
document()->removePendingSheet();
@@ -243,22 +223,43 @@ void HTMLLinkElement::process()
void HTMLLinkElement::insertedIntoDocument()
{
HTMLElement::insertedIntoDocument();
+ document()->addStyleSheetCandidateNode(this, m_createdByParser);
process();
}
void HTMLLinkElement::removedFromDocument()
{
HTMLElement::removedFromDocument();
- process();
+
+ // FIXME: It's terrible to do a synchronous update of the style selector just because a <style> or <link> element got removed.
+ if (document()->renderer()) {
+ document()->removeStyleSheetCandidateNode(this);
+ document()->updateStyleSelector();
+ }
+}
+
+void HTMLLinkElement::finishParsingChildren()
+{
+ m_createdByParser = false;
+ HTMLElement::finishParsingChildren();
}
-void HTMLLinkElement::setCSSStyleSheet(const String& url, const String& charset, const String& sheetStr)
+void HTMLLinkElement::setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet* sheet)
{
- m_sheet = new CSSStyleSheet(this, url, charset);
- m_sheet->parseString(sheetStr, !document()->inCompatMode());
+ m_sheet = CSSStyleSheet::create(this, url, charset);
+
+ bool strictParsing = !document()->inCompatMode();
+ bool enforceMIMEType = strictParsing;
+
+ // Check to see if we should enforce the MIME type of the CSS resource in strict mode.
+ // Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748>
+ if (enforceMIMEType && document()->page() && !document()->page()->settings()->enforceCSSMIMETypeInStrictMode())
+ enforceMIMEType = false;
+
+ m_sheet->parseString(sheet->sheetText(enforceMIMEType), strictParsing);
m_sheet->setTitle(title());
- RefPtr<MediaList> media = new MediaList((CSSStyleSheet*)0, m_media, true);
+ RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media);
m_sheet->setMedia(media.get());
m_loading = false;
@@ -308,7 +309,7 @@ void HTMLLinkElement::setCharset(const String& value)
setAttribute(charsetAttr, value);
}
-String HTMLLinkElement::href() const
+KURL HTMLLinkElement::href() const
{
return document()->completeURL(getAttribute(hrefAttr));
}
@@ -378,4 +379,28 @@ void HTMLLinkElement::setType(const String& value)
setAttribute(typeAttr, value);
}
+void HTMLLinkElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ if (m_isIcon) {
+ urls.append(href().string());
+ return;
+ }
+
+ if (!m_isStyleSheet)
+ return;
+
+ // Append the URL of this link element.
+ urls.append(href().string());
+
+ // Walk the URLs linked by the linked-to stylesheet.
+ HashSet<String> styleURLs;
+ StyleSheet* styleSheet = const_cast<HTMLLinkElement*>(this)->sheet();
+ if (styleSheet)
+ styleSheet->addSubresourceURLStrings(styleURLs, href());
+
+ HashSet<String>::iterator end = styleURLs.end();
+ for (HashSet<String>::iterator i = styleURLs.begin(); i != end; ++i)
+ urls.append(*i);
+}
+
}
diff --git a/WebCore/html/HTMLLinkElement.h b/WebCore/html/HTMLLinkElement.h
index b9c31e6..2fcaaa8 100644
--- a/WebCore/html/HTMLLinkElement.h
+++ b/WebCore/html/HTMLLinkElement.h
@@ -1,9 +1,7 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 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
@@ -21,19 +19,21 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#ifndef HTMLLinkElement_h
#define HTMLLinkElement_h
-#include "HTMLElement.h"
-#include "CachedResourceClient.h"
#include "CSSStyleSheet.h"
+#include "CachedResourceClient.h"
+#include "CachedResourceHandle.h"
+#include "HTMLElement.h"
namespace WebCore {
class CachedCSSStyleSheet;
+class KURL;
-class HTMLLinkElement : public HTMLElement, public CachedResourceClient
-{
+class HTMLLinkElement : public HTMLElement, public CachedResourceClient {
public:
HTMLLinkElement(Document*);
~HTMLLinkElement();
@@ -47,7 +47,7 @@ public:
String charset() const;
void setCharset(const String&);
- String href() const;
+ KURL href() const;
void setHref(const String&);
String hreflang() const;
@@ -79,42 +79,40 @@ public:
virtual void removedFromDocument();
// from CachedResourceClient
- virtual void setCSSStyleSheet(const String &url, const String& charset, const String &sheet);
+ virtual void setCSSStyleSheet(const String &url, const String& charset, const CachedCSSStyleSheet* sheet);
bool isLoading() const;
virtual bool sheetLoaded();
bool isAlternate() const { return m_disabledState == 0 && m_alternate; }
bool isDisabled() const { return m_disabledState == 2; }
bool isEnabledViaScript() const { return m_disabledState == 1; }
-
+ bool isIcon() const { return m_isIcon; }
+
int disabledState() { return m_disabledState; }
void setDisabledState(bool _disabled);
virtual bool isURLAttribute(Attribute*) const;
-#ifdef ANDROID_PRELOAD_CHANGES
- static void tokenizeRelAttribute(const AtomicString& value, bool& stylesheet, bool& alternate, bool& icon);
-#else
- void tokenizeRelAttribute(const AtomicString& rel);
-#endif
+
+ static void tokenizeRelAttribute(const AtomicString& value, bool& stylesheet, bool& alternate, bool& icon, bool& dnsPrefetch);
+
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
+ void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; }
+ virtual void finishParsingChildren();
protected:
- CachedCSSStyleSheet* m_cachedSheet;
+ CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
RefPtr<CSSStyleSheet> m_sheet;
String m_url;
String m_type;
String m_media;
int m_disabledState; // 0=unset(default), 1=enabled via script, 2=disabled
-#ifdef ANDROID_PRELOAD_CHANGES
bool m_loading;
bool m_alternate;
bool m_isStyleSheet;
bool m_isIcon;
-#else
- bool m_loading : 1;
- bool m_alternate : 1;
- bool m_isStyleSheet : 1;
- bool m_isIcon : 1;
-#endif
+ bool m_isDNSPrefetch;
+ bool m_createdByParser;
};
} //namespace
diff --git a/WebCore/html/HTMLMapElement.cpp b/WebCore/html/HTMLMapElement.cpp
index 2fce481..891f560 100644
--- a/WebCore/html/HTMLMapElement.cpp
+++ b/WebCore/html/HTMLMapElement.cpp
@@ -80,14 +80,14 @@ void HTMLMapElement::parseMappedAttribute(MappedAttribute* attr)
if (attrName == idAttr) {
// Call base class so that hasID bit gets set.
HTMLElement::parseMappedAttribute(attr);
- if (doc->htmlMode() != Document::XHtml)
+ if (doc->isHTMLDocument())
return;
}
doc->removeImageMap(this);
String mapName = attr->value();
if (mapName[0] == '#')
mapName = mapName.substring(1);
- m_name = doc->htmlMode() == Document::XHtml ? mapName : mapName.lower();
+ m_name = doc->isHTMLDocument() ? mapName.lower() : mapName;
doc->addImageMap(this);
} else
HTMLElement::parseMappedAttribute(attr);
@@ -95,7 +95,7 @@ void HTMLMapElement::parseMappedAttribute(MappedAttribute* attr)
PassRefPtr<HTMLCollection> HTMLMapElement::areas()
{
- return new HTMLCollection(this, HTMLCollection::MapAreas);
+ return HTMLCollection::create(this, HTMLCollection::MapAreas);
}
String HTMLMapElement::name() const
diff --git a/WebCore/html/HTMLMarqueeElement.cpp b/WebCore/html/HTMLMarqueeElement.cpp
index 9fe1f4d..0fd8805 100644
--- a/WebCore/html/HTMLMarqueeElement.cpp
+++ b/WebCore/html/HTMLMarqueeElement.cpp
@@ -28,6 +28,7 @@
#include "CSSValueKeywords.h"
#include "HTMLNames.h"
#include "RenderLayer.h"
+#include "RenderMarquee.h"
namespace WebCore {
@@ -65,44 +66,44 @@ void HTMLMarqueeElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == widthAttr) {
if (!attr->value().isEmpty())
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
} else if (attr->name() == heightAttr) {
if (!attr->value().isEmpty())
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
} else if (attr->name() == bgcolorAttr) {
if (!attr->value().isEmpty())
- addCSSColor(attr, CSS_PROP_BACKGROUND_COLOR, attr->value());
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
} else if (attr->name() == vspaceAttr) {
if (!attr->value().isEmpty()) {
- addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
}
} else if (attr->name() == hspaceAttr) {
if (!attr->value().isEmpty()) {
- addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
}
} else if (attr->name() == scrollamountAttr) {
if (!attr->value().isEmpty())
- addCSSLength(attr, CSS_PROP__WEBKIT_MARQUEE_INCREMENT, attr->value());
+ addCSSLength(attr, CSSPropertyWebkitMarqueeIncrement, attr->value());
} else if (attr->name() == scrolldelayAttr) {
if (!attr->value().isEmpty())
- addCSSLength(attr, CSS_PROP__WEBKIT_MARQUEE_SPEED, attr->value());
+ addCSSLength(attr, CSSPropertyWebkitMarqueeSpeed, attr->value());
} else if (attr->name() == loopAttr) {
if (!attr->value().isEmpty()) {
if (attr->value() == "-1" || equalIgnoringCase(attr->value(), "infinite"))
- addCSSProperty(attr, CSS_PROP__WEBKIT_MARQUEE_REPETITION, CSS_VAL_INFINITE);
+ addCSSProperty(attr, CSSPropertyWebkitMarqueeRepetition, CSSValueInfinite);
else
- addCSSLength(attr, CSS_PROP__WEBKIT_MARQUEE_REPETITION, attr->value());
+ addCSSLength(attr, CSSPropertyWebkitMarqueeRepetition, attr->value());
}
} else if (attr->name() == behaviorAttr) {
if (!attr->value().isEmpty())
- addCSSProperty(attr, CSS_PROP__WEBKIT_MARQUEE_STYLE, attr->value());
+ addCSSProperty(attr, CSSPropertyWebkitMarqueeStyle, attr->value());
} else if (attr->name() == directionAttr) {
if (!attr->value().isEmpty())
- addCSSProperty(attr, CSS_PROP__WEBKIT_MARQUEE_DIRECTION, attr->value());
+ addCSSProperty(attr, CSSPropertyWebkitMarqueeDirection, attr->value());
} else if (attr->name() == truespeedAttr)
- m_minimumDelay = !attr->isNull() ? 0 : defaultMinimumDelay;
+ m_minimumDelay = !attr->isEmpty() ? 0 : defaultMinimumDelay;
else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index cccf0fd..f86c44d 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,7 +53,6 @@ using namespace std;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
@@ -68,7 +67,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_loadedFirstFrame(false)
, m_autoplaying(true)
, m_currentLoop(0)
- , m_volume(0.5f)
+ , m_volume(1.0f)
, m_muted(false)
, m_paused(true)
, m_seeking(false)
@@ -80,15 +79,15 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_loadNestingLevel(0)
, m_terminateLoadBelowNestingLevel(0)
, m_pausedInternal(false)
- , m_inPageCache(false)
+ , m_inActiveDocument(true)
, m_player(0)
{
- document()->registerForCacheCallbacks(this);
+ document()->registerForDocumentActivationCallbacks(this);
}
HTMLMediaElement::~HTMLMediaElement()
{
- document()->unregisterForCacheCallbacks(this);
+ document()->unregisterForDocumentActivationCallbacks(this);
}
bool HTMLMediaElement::checkDTD(const Node* newChild)
@@ -152,6 +151,14 @@ void HTMLMediaElement::attach()
renderer()->updateFromElement();
}
+void HTMLMediaElement::recalcStyle(StyleChange change)
+{
+ HTMLElement::recalcStyle(change);
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
void HTMLMediaElement::scheduleLoad()
{
m_loadTimer.startOneShot(0);
@@ -186,7 +193,7 @@ void HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*)
m_asyncEventsToDispatch.swap(asyncEventsToDispatch);
unsigned count = asyncEventsToDispatch.size();
for (unsigned n = 0; n < count; ++n)
- dispatchHTMLEvent(asyncEventsToDispatch[n], false, true);
+ dispatchEventForType(asyncEventsToDispatch[n], false, true);
}
String serializeTimeOffset(float time)
@@ -197,12 +204,16 @@ String serializeTimeOffset(float time)
return timeString;
}
-float parseTimeOffset(String timeString, bool* ok = 0)
+float parseTimeOffset(const String& timeString, bool* ok = 0)
{
- if (timeString.endsWith("s"))
- timeString = timeString.left(timeString.length() - 1);
+ const UChar* characters = timeString.characters();
+ unsigned length = timeString.length();
+
+ if (length && characters[length - 1] == 's')
+ length--;
+
// FIXME parse time offset values (format not specified yet)
- float val = (float)timeString.toDouble(ok);
+ float val = charactersToFloat(characters, length, ok);
return val;
}
@@ -226,7 +237,7 @@ PassRefPtr<MediaError> HTMLMediaElement::error() const
return m_error;
}
-String HTMLMediaElement::src() const
+KURL HTMLMediaElement::src() const
{
return document()->completeURL(getAttribute(srcAttr));
}
@@ -273,8 +284,8 @@ void HTMLMediaElement::load(ExceptionCode& ec)
// 2
if (m_begun) {
m_begun = false;
- m_error = new MediaError(MediaError::MEDIA_ERR_ABORTED);
- initAndDispatchProgressEvent(abortEvent);
+ m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
+ initAndDispatchProgressEvent(eventNames().abortEvent);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
goto end;
}
@@ -298,7 +309,7 @@ void HTMLMediaElement::load(ExceptionCode& ec)
m_player->seek(0);
}
m_currentLoop = 0;
- dispatchHTMLEvent(emptiedEvent, false, true);
+ dispatchEventForType(eventNames().emptiedEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
goto end;
}
@@ -318,7 +329,7 @@ void HTMLMediaElement::load(ExceptionCode& ec)
// 9
m_begun = true;
- dispatchProgressEvent(beginEvent, false, 0, 0); // progress event draft calls this loadstart
+ dispatchProgressEvent(eventNames().loadstartEvent, false, 0, 0);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
goto end;
@@ -359,12 +370,12 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
//delete m_player;
//m_player = 0;
// FIXME better error handling
- m_error = new MediaError(MediaError::MEDIA_ERR_NETWORK);
+ m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK);
m_begun = false;
m_progressEventTimer.stop();
m_bufferingRate = 0;
- initAndDispatchProgressEvent(errorEvent);
+ initAndDispatchProgressEvent(eventNames().errorEvent);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
@@ -373,7 +384,7 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
if (isVideo())
static_cast<HTMLVideoElement*>(this)->updatePosterImage();
- dispatchHTMLEvent(emptiedEvent, false, true);
+ dispatchEventForType(eventNames().emptiedEvent, false, true);
return;
}
@@ -384,11 +395,11 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
m_player->seek(effectiveStart());
m_networkState = LOADED_METADATA;
- dispatchHTMLEvent(durationchangeEvent, false, true);
+ dispatchEventForType(eventNames().durationchangeEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
- dispatchHTMLEvent(loadedmetadataEvent, false, true);
+ dispatchEventForType(eventNames().loadedmetadataEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
}
@@ -410,11 +421,11 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
static_cast<RenderVideo*>(renderer())->videoSizeChanged();
}
- dispatchHTMLEvent(loadedfirstframeEvent, false, true);
+ dispatchEventForType(eventNames().loadedfirstframeEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
- dispatchHTMLEvent(canshowcurrentframeEvent, false, true);
+ dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
}
@@ -425,7 +436,7 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
m_networkState = LOADED;
m_progressEventTimer.stop();
m_bufferingRate = 0;
- initAndDispatchProgressEvent(loadEvent);
+ initAndDispatchProgressEvent(eventNames().loadEvent);
}
}
@@ -451,25 +462,25 @@ void HTMLMediaElement::setReadyState(ReadyState state)
return;
if (state == DATA_UNAVAILABLE) {
- dispatchHTMLEvent(dataunavailableEvent, false, true);
+ dispatchEventForType(eventNames().dataunavailableEvent, false, true);
if (wasActivelyPlaying) {
- dispatchHTMLEvent(timeupdateEvent, false, true);
- dispatchHTMLEvent(waitingEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().waitingEvent, false, true);
}
} else if (state == CAN_SHOW_CURRENT_FRAME) {
if (m_loadedFirstFrame)
- dispatchHTMLEvent(canshowcurrentframeEvent, false, true);
+ dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true);
if (wasActivelyPlaying) {
- dispatchHTMLEvent(timeupdateEvent, false, true);
- dispatchHTMLEvent(waitingEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().waitingEvent, false, true);
}
} else if (state == CAN_PLAY) {
- dispatchHTMLEvent(canplayEvent, false, true);
+ dispatchEventForType(eventNames().canplayEvent, false, true);
} else if (state == CAN_PLAY_THROUGH) {
- dispatchHTMLEvent(canplaythroughEvent, false, true);
+ dispatchEventForType(eventNames().canplaythroughEvent, false, true);
if (m_autoplaying && m_paused && autoplay()) {
m_paused = false;
- dispatchHTMLEvent(playEvent, false, true);
+ dispatchEventForType(eventNames().playEvent, false, true);
}
}
updatePlayState();
@@ -487,11 +498,11 @@ void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
if (progress == m_previousProgress) {
if (timedelta > 3.0 && !m_sentStalledEvent) {
m_bufferingRate = 0;
- initAndDispatchProgressEvent(stalledEvent);
+ initAndDispatchProgressEvent(eventNames().stalledEvent);
m_sentStalledEvent = true;
}
} else {
- initAndDispatchProgressEvent(progressEvent);
+ initAndDispatchProgressEvent(eventNames().progressEvent);
m_previousProgress = progress;
m_previousProgressTime = time;
m_sentStalledEvent = false;
@@ -537,7 +548,7 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec)
m_seeking = true;
// 9
- dispatchHTMLEvent(timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
// 10
// As soon as the user agent has established whether or not the media data for the new playback position is available,
@@ -596,7 +607,7 @@ void HTMLMediaElement::setDefaultPlaybackRate(float rate, ExceptionCode& ec)
}
if (m_defaultPlaybackRate != rate) {
m_defaultPlaybackRate = rate;
- dispatchEventAsync(ratechangeEvent);
+ dispatchEventAsync(eventNames().ratechangeEvent);
}
}
@@ -613,7 +624,7 @@ void HTMLMediaElement::setPlaybackRate(float rate, ExceptionCode& ec)
}
if (m_player && m_player->rate() != rate) {
m_player->setRate(rate);
- dispatchEventAsync(ratechangeEvent);
+ dispatchEventAsync(eventNames().ratechangeEvent);
}
}
@@ -650,7 +661,7 @@ void HTMLMediaElement::play(ExceptionCode& ec)
if (m_paused) {
m_paused = false;
- dispatchEventAsync(playEvent);
+ dispatchEventAsync(eventNames().playEvent);
}
m_autoplaying = false;
@@ -670,8 +681,8 @@ void HTMLMediaElement::pause(ExceptionCode& ec)
if (!m_paused) {
m_paused = true;
- dispatchEventAsync(timeupdateEvent);
- dispatchEventAsync(pauseEvent);
+ dispatchEventAsync(eventNames().timeupdateEvent);
+ dispatchEventAsync(eventNames().pauseEvent);
}
m_autoplaying = false;
@@ -681,9 +692,9 @@ void HTMLMediaElement::pause(ExceptionCode& ec)
unsigned HTMLMediaElement::playCount() const
{
- String val = getAttribute(playcountAttr);
- int count = val.toInt();
- return max(count, 1);
+ bool ok;
+ unsigned count = getAttribute(playcountAttr).string().toUInt(&ok);
+ return (count > 0 && ok) ? count : 1;
}
void HTMLMediaElement::setPlayCount(unsigned count, ExceptionCode& ec)
@@ -720,7 +731,7 @@ void HTMLMediaElement::setEnd(float time)
float HTMLMediaElement::loopStart() const
{
- return getTimeOffsetAttribute(loopstartAttr, 0);
+ return getTimeOffsetAttribute(loopstartAttr, start());
}
void HTMLMediaElement::setLoopStart(float time)
@@ -731,7 +742,7 @@ void HTMLMediaElement::setLoopStart(float time)
float HTMLMediaElement::loopEnd() const
{
- return getTimeOffsetAttribute(loopendAttr, std::numeric_limits<float>::infinity());
+ return getTimeOffsetAttribute(loopendAttr, end());
}
void HTMLMediaElement::setLoopEnd(float time)
@@ -775,7 +786,7 @@ void HTMLMediaElement::setVolume(float vol, ExceptionCode& ec)
if (m_volume != vol) {
m_volume = vol;
updateVolume();
- dispatchEventAsync(volumechangeEvent);
+ dispatchEventAsync(eventNames().volumechangeEvent);
}
}
@@ -789,7 +800,7 @@ void HTMLMediaElement::setMuted(bool muted)
if (m_muted != muted) {
m_muted = muted;
updateVolume();
- dispatchEventAsync(volumechangeEvent);
+ dispatchEventAsync(eventNames().volumechangeEvent);
}
}
@@ -809,23 +820,29 @@ String HTMLMediaElement::pickMedia()
if (!source->hasAttribute(srcAttr))
continue;
if (source->hasAttribute(mediaAttr)) {
- MediaQueryEvaluator screenEval("screen", document()->page(), renderer() ? renderer()->style() : 0);
- RefPtr<MediaList> media = new MediaList((CSSStyleSheet*)0, source->media(), true);
+ MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
+ RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media());
if (!screenEval.eval(media.get()))
continue;
}
if (source->hasAttribute(typeAttr)) {
- String type = source->type();
+ String type = source->type().stripWhiteSpace();
+
+ // "type" can have parameters after a semi-colon, strip them before checking with the type registry
+ int semi = type.find(';');
+ if (semi != -1)
+ type = type.left(semi).stripWhiteSpace();
+
if (!MIMETypeRegistry::isSupportedMediaMIMEType(type))
continue;
}
- mediaSrc = source->src();
+ mediaSrc = source->src().string();
break;
}
}
}
if (!mediaSrc.isEmpty())
- mediaSrc = document()->completeURL(mediaSrc);
+ mediaSrc = document()->completeURL(mediaSrc).string();
return mediaSrc;
}
@@ -872,12 +889,12 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
ExceptionCode ec;
seek(effectiveLoopStart(), ec);
m_currentLoop++;
- dispatchHTMLEvent(timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
}
if (m_currentLoop == playCount() - 1 && currentTime() >= effectiveEnd()) {
- dispatchHTMLEvent(timeupdateEvent, false, true);
- dispatchHTMLEvent(endedEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().endedEvent, false, true);
}
updatePlayState();
@@ -893,22 +910,22 @@ PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
{
// FIXME real ranges support
if (!m_player || !m_player->maxTimeBuffered())
- return new TimeRanges;
- return new TimeRanges(0, m_player->maxTimeBuffered());
+ return TimeRanges::create();
+ return TimeRanges::create(0, m_player->maxTimeBuffered());
}
PassRefPtr<TimeRanges> HTMLMediaElement::played() const
{
// FIXME track played
- return new TimeRanges;
+ return TimeRanges::create();
}
PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
{
// FIXME real ranges support
if (!m_player || !m_player->maxTimeSeekable())
- return new TimeRanges;
- return new TimeRanges(0, m_player->maxTimeSeekable());
+ return TimeRanges::create();
+ return TimeRanges::create(0, m_player->maxTimeSeekable());
}
float HTMLMediaElement::effectiveStart() const
@@ -988,8 +1005,8 @@ void HTMLMediaElement::setPausedInternal(bool b)
m_pausedInternal = b;
updatePlayState();
}
-
-void HTMLMediaElement::willSaveToCache()
+
+void HTMLMediaElement::documentWillBecomeInactive()
{
// 3.14.9.4. Loading the media resource
// 14
@@ -998,26 +1015,26 @@ void HTMLMediaElement::willSaveToCache()
m_player.clear();
m_progressEventTimer.stop();
- m_error = new MediaError(MediaError::MEDIA_ERR_ABORTED);
+ m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
m_begun = false;
- initAndDispatchProgressEvent(abortEvent);
+ initAndDispatchProgressEvent(eventNames().abortEvent);
if (m_networkState >= LOADING) {
m_networkState = EMPTY;
- dispatchHTMLEvent(emptiedEvent, false, true);
+ m_readyState = DATA_UNAVAILABLE;
+ dispatchEventForType(eventNames().emptiedEvent, false, true);
}
}
- m_inPageCache = true;
+ m_inActiveDocument = false;
// Stop the playback without generating events
setPausedInternal(true);
- if (m_player)
- m_player->setVisible(false);
+
if (renderer())
renderer()->updateFromElement();
}
-void HTMLMediaElement::didRestoreFromCache()
+void HTMLMediaElement::documentDidBecomeActive()
{
- m_inPageCache = false;
+ m_inActiveDocument = true;
setPausedInternal(false);
if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED) {
@@ -1035,6 +1052,8 @@ void HTMLMediaElement::defaultEventHandler(Event* event)
{
if (renderer() && renderer()->isMedia())
static_cast<RenderMedia*>(renderer())->forwardEvent(event);
+ if (event->defaultHandled())
+ return;
HTMLElement::defaultEventHandler(event);
}
diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h
index 91520b0..27fac2f 100644
--- a/WebCore/html/HTMLMediaElement.h
+++ b/WebCore/html/HTMLMediaElement.h
@@ -37,6 +37,7 @@ namespace WebCore {
class MediaError;
class TimeRanges;
+class KURL;
class HTMLMediaElement : public HTMLElement, public MediaPlayerClient {
public:
@@ -52,6 +53,7 @@ public:
virtual void insertedIntoDocument();
virtual void removedFromDocument();
virtual void attach();
+ virtual void recalcStyle(StyleChange);
MediaPlayer* player() const { return m_player.get(); }
@@ -64,14 +66,14 @@ public:
// Pauses playback without changing any states or generating events
void setPausedInternal(bool);
- bool inPageCache() const { return m_inPageCache; }
+ bool inActiveDocument() const { return m_inActiveDocument; }
// DOM API
// error state
PassRefPtr<MediaError> error() const;
// network state
- String src() const;
+ KURL src() const;
void setSrc(const String&);
String currentSrc() const;
@@ -131,8 +133,8 @@ protected:
float getTimeOffsetAttribute(const QualifiedName&, float valueOnError) const;
void setTimeOffsetAttribute(const QualifiedName&, float value);
- virtual void willSaveToCache();
- virtual void didRestoreFromCache();
+ virtual void documentWillBecomeInactive();
+ virtual void documentDidBecomeActive();
void initAndDispatchProgressEvent(const AtomicString& eventName);
void dispatchEventAsync(const AtomicString& eventName);
@@ -198,7 +200,7 @@ protected:
unsigned m_terminateLoadBelowNestingLevel;
bool m_pausedInternal;
- bool m_inPageCache;
+ bool m_inActiveDocument;
OwnPtr<MediaPlayer> m_player;
};
diff --git a/WebCore/html/HTMLNameCollection.h b/WebCore/html/HTMLNameCollection.h
index 916cced..9add926 100644
--- a/WebCore/html/HTMLNameCollection.h
+++ b/WebCore/html/HTMLNameCollection.h
@@ -32,9 +32,14 @@ class Document;
class HTMLNameCollection : public HTMLCollection {
public:
- HTMLNameCollection(PassRefPtr<Document>, Type, const String& name);
+ static PassRefPtr<HTMLNameCollection> create(PassRefPtr<Document> document, Type type, const String& name)
+ {
+ return adoptRef(new HTMLNameCollection(document, type, name));
+ }
private:
+ HTMLNameCollection(PassRefPtr<Document>, Type, const String& name);
+
virtual Element* itemAfter(Element*) const;
String m_name;
diff --git a/WebCore/html/HTMLOListElement.cpp b/WebCore/html/HTMLOListElement.cpp
index 8da6930..a37d4ef 100644
--- a/WebCore/html/HTMLOListElement.cpp
+++ b/WebCore/html/HTMLOListElement.cpp
@@ -52,15 +52,15 @@ void HTMLOListElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == typeAttr) {
if (attr->value() == "a")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_LOWER_ALPHA);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueLowerAlpha);
else if (attr->value() == "A")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_UPPER_ALPHA);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueUpperAlpha);
else if (attr->value() == "i")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_LOWER_ROMAN);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueLowerRoman);
else if (attr->value() == "I")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_UPPER_ROMAN);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueUpperRoman);
else if (attr->value() == "1")
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, CSS_VAL_DECIMAL);
+ addCSSProperty(attr, CSSPropertyListStyleType, CSSValueDecimal);
} else if (attr->name() == startAttr) {
int s = !attr->isNull() ? attr->value().toInt() : 1;
if (s != m_start) {
diff --git a/WebCore/html/HTMLObjectElement.cpp b/WebCore/html/HTMLObjectElement.cpp
index 810496c..694f2d3 100644
--- a/WebCore/html/HTMLObjectElement.cpp
+++ b/WebCore/html/HTMLObjectElement.cpp
@@ -2,8 +2,8 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,30 +28,27 @@
#include "EventNames.h"
#include "ExceptionCode.h"
#include "Frame.h"
-#include "FrameLoader.h"
-#include "FrameLoaderClient.h"
-#include "FrameView.h"
#include "HTMLDocument.h"
#include "HTMLFormElement.h"
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
-#include "Image.h"
#include "MIMETypeRegistry.h"
#include "RenderImage.h"
#include "RenderPartObject.h"
#include "RenderWidget.h"
+#include "ScriptController.h"
#include "Text.h"
+
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
HTMLObjectElement::HTMLObjectElement(Document* doc, bool createdByParser)
- : HTMLPlugInElement(objectTag, doc)
+ : HTMLPlugInImageElement(objectTag, doc)
+ , m_docNamedItem(true)
, m_needWidgetUpdate(!createdByParser)
, m_useFallbackContent(false)
- , m_docNamedItem(true)
{
}
@@ -59,40 +56,24 @@ HTMLObjectElement::~HTMLObjectElement()
{
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
if (oldNameIdCount && document()->isHTMLDocument()) {
HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->removeDocExtraNamedItem(oldIdAttr);
+ doc->removeNamedItem(m_name);
+ doc->removeExtraNamedItem(m_id);
}
#endif
-#if USE(JAVASCRIPTCORE_BINDINGS)
- // m_instance should have been cleaned up in detach().
- ASSERT(!m_instance);
-#endif
}
-#if USE(JAVASCRIPTCORE_BINDINGS)
-KJS::Bindings::Instance *HTMLObjectElement::getInstance() const
+RenderWidget* HTMLObjectElement::renderWidgetForJSBindings() const
{
- Frame* frame = document()->frame();
- if (!frame)
- return 0;
-
- if (m_instance)
- return m_instance.get();
-
RenderWidget* renderWidget = (renderer() && renderer()->isWidget()) ? static_cast<RenderWidget*>(renderer()) : 0;
if (renderWidget && !renderWidget->widget()) {
document()->updateLayoutIgnorePendingStylesheets();
renderWidget = (renderer() && renderer()->isWidget()) ? static_cast<RenderWidget*>(renderer()) : 0;
- }
- if (renderWidget && renderWidget->widget())
- m_instance = frame->createScriptInstanceForWidget(renderWidget->widget());
-
- return m_instance.get();
+ }
+ return renderWidget;
}
-#endif
void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr)
{
@@ -121,25 +102,23 @@ void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr)
if (renderer())
m_needWidgetUpdate = true;
} else if (attr->name() == onloadAttr) {
- setHTMLEventListener(loadEvent, attr);
- } else if (attr->name() == onunloadAttr) {
- setHTMLEventListener(unloadEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
} else if (attr->name() == nameAttr) {
- String newNameAttr = attr->value();
- if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->addNamedItem(newNameAttr);
- }
- oldNameAttr = newNameAttr;
+ const AtomicString& newName = attr->value();
+ if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->addNamedItem(newName);
+ }
+ m_name = newName;
} else if (attr->name() == idAttr) {
- String newIdAttr = attr->value();
+ const AtomicString& newId = attr->value();
if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument*>(document());
- doc->removeDocExtraNamedItem(oldIdAttr);
- doc->addDocExtraNamedItem(newIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeExtraNamedItem(m_id);
+ document->addExtraNamedItem(newId);
}
- oldIdAttr = newIdAttr;
+ m_id = newId;
// also call superclass
HTMLPlugInElement::parseMappedAttribute(attr);
} else
@@ -180,15 +159,18 @@ void HTMLObjectElement::attach()
if (!m_imageLoader)
m_imageLoader.set(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
- if (renderer()) {
- RenderImage* imageObj = static_cast<RenderImage*>(renderer());
- imageObj->setCachedImage(m_imageLoader->image());
- }
+ // updateForElement() may have changed us to use fallback content and called detach() and attach().
+ if (m_useFallbackContent)
+ return;
+
+ if (renderer())
+ static_cast<RenderImage*>(renderer())->setCachedImage(m_imageLoader->image());
}
}
void HTMLObjectElement::updateWidget()
{
+ document()->updateRendering();
if (m_needWidgetUpdate && renderer() && !m_useFallbackContent && !isImageType())
static_cast<RenderPartObject*>(renderer())->updateWidget(true);
}
@@ -205,26 +187,21 @@ void HTMLObjectElement::finishParsingChildren()
void HTMLObjectElement::detach()
{
- if (attached() && renderer() && !m_useFallbackContent) {
+ if (attached() && renderer() && !m_useFallbackContent)
// Update the widget the next time we attach (detaching destroys the plugin).
m_needWidgetUpdate = true;
- }
-
-#if USE(JAVASCRIPTCORE_BINDINGS)
- m_instance = 0;
-#endif
HTMLPlugInElement::detach();
}
void HTMLObjectElement::insertedIntoDocument()
{
if (isDocNamedItem() && document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->addNamedItem(oldNameAttr);
- doc->addDocExtraNamedItem(oldIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->addNamedItem(m_name);
+ document->addExtraNamedItem(m_id);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
oldNameIdCount++;
#endif
}
@@ -235,12 +212,12 @@ void HTMLObjectElement::insertedIntoDocument()
void HTMLObjectElement::removedFromDocument()
{
if (isDocNamedItem() && document()->isHTMLDocument()) {
- HTMLDocument *doc = static_cast<HTMLDocument *>(document());
- doc->removeNamedItem(oldNameAttr);
- doc->removeDocExtraNamedItem(oldIdAttr);
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
+ document->removeNamedItem(m_name);
+ document->removeExtraNamedItem(m_id);
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name and m_id are removed from HTMLDocument's NameCountMap
oldNameIdCount--;
#endif
}
@@ -257,19 +234,19 @@ void HTMLObjectElement::recalcStyle(StyleChange ch)
HTMLPlugInElement::recalcStyle(ch);
}
-void HTMLObjectElement::childrenChanged(bool changedByParser)
+void HTMLObjectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
updateDocNamedItem();
if (inDocument() && !m_useFallbackContent) {
m_needWidgetUpdate = true;
setChanged();
}
- HTMLPlugInElement::childrenChanged(changedByParser);
+ HTMLPlugInElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
bool HTMLObjectElement::isURLAttribute(Attribute *attr) const
{
- return (attr->name() == dataAttr || (attr->name() == usemapAttr && attr->value().domString()[0] != '#'));
+ return (attr->name() == dataAttr || (attr->name() == usemapAttr && attr->value().string()[0] != '#'));
}
const QualifiedName& HTMLObjectElement::imageSourceAttributeName() const
@@ -277,34 +254,23 @@ const QualifiedName& HTMLObjectElement::imageSourceAttributeName() const
return dataAttr;
}
-bool HTMLObjectElement::isImageType()
-{
- if (m_serviceType.isEmpty() && m_url.startsWith("data:")) {
- // Extract the MIME type from the data URL.
- int index = m_url.find(';');
- if (index == -1)
- index = m_url.find(',');
- if (index != -1) {
- int len = index - 5;
- if (len > 0)
- m_serviceType = m_url.substring(5, len);
- else
- m_serviceType = "text/plain"; // Data URLs with no MIME type are considered text/plain.
- }
- }
- if (Frame* frame = document()->frame()) {
- KURL completedURL(frame->loader()->completeURL(m_url));
- return frame->loader()->client()->objectContentType(completedURL, m_serviceType) == ObjectContentImage;
- }
-
- return Image::supportsType(m_serviceType);
-}
-
void HTMLObjectElement::renderFallbackContent()
{
if (m_useFallbackContent)
return;
+ // Before we give up and use fallback content, check to see if this is a MIME type issue.
+ if (m_imageLoader && m_imageLoader->image()) {
+ m_serviceType = m_imageLoader->image()->response().mimeType();
+ if (!isImageType()) {
+ // If we don't think we have an image type anymore, then ditch the image loader.
+ m_imageLoader.clear();
+ detach();
+ attach();
+ return;
+ }
+ }
+
// Mark ourselves as using the fallback content.
m_useFallbackContent = true;
@@ -335,13 +301,13 @@ void HTMLObjectElement::updateDocNamedItem()
child = child->nextSibling();
}
if (isNamedItem != wasNamedItem && document()->isHTMLDocument()) {
- HTMLDocument* doc = static_cast<HTMLDocument*>(document());
+ HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
if (isNamedItem) {
- doc->addNamedItem(oldNameAttr);
- doc->addDocExtraNamedItem(oldIdAttr);
+ document->addNamedItem(m_name);
+ document->addExtraNamedItem(m_id);
} else {
- doc->removeNamedItem(oldNameAttr);
- doc->removeDocExtraNamedItem(oldIdAttr);
+ document->removeNamedItem(m_name);
+ document->removeExtraNamedItem(m_id);
}
}
m_docNamedItem = isNamedItem;
@@ -397,7 +363,7 @@ void HTMLObjectElement::setCodeType(const String& value)
setAttribute(codetypeAttr, value);
}
-String HTMLObjectElement::data() const
+KURL HTMLObjectElement::data() const
{
return document()->completeURL(getAttribute(dataAttr));
}
@@ -437,11 +403,6 @@ void HTMLObjectElement::setStandby(const String& value)
setAttribute(standbyAttr, value);
}
-void HTMLObjectElement::setTabIndex(int tabIndex)
-{
- setAttribute(tabindexAttr, String::number(tabIndex));
-}
-
String HTMLObjectElement::type() const
{
return getAttribute(typeAttr);
@@ -481,9 +442,7 @@ bool HTMLObjectElement::containsJavaApplet() const
while (child) {
if (child->isElementNode()) {
Element* e = static_cast<Element*>(child);
- if (e->hasTagName(paramTag) &&
- e->getAttribute(nameAttr).domString().lower() == "type" &&
- MIMETypeRegistry::isJavaAppletMIMEType(e->getAttribute(valueAttr).domString()))
+ if (e->hasTagName(paramTag) && equalIgnoringCase(e->getAttribute(nameAttr), "type") && MIMETypeRegistry::isJavaAppletMIMEType(e->getAttribute(valueAttr).string()))
return true;
else if (e->hasTagName(objectTag) && static_cast<HTMLObjectElement*>(e)->containsJavaApplet())
return true;
@@ -496,4 +455,11 @@ bool HTMLObjectElement::containsJavaApplet() const
return false;
}
+void HTMLObjectElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ urls.append(data().string());
+ if (useMap().startsWith("#"))
+ urls.append(useMap());
+}
+
}
diff --git a/WebCore/html/HTMLObjectElement.h b/WebCore/html/HTMLObjectElement.h
index 0a87b9f..859c73f 100644
--- a/WebCore/html/HTMLObjectElement.h
+++ b/WebCore/html/HTMLObjectElement.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 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
@@ -23,14 +23,13 @@
#ifndef HTMLObjectElement_h
#define HTMLObjectElement_h
-#include "HTMLPlugInElement.h"
-#include <wtf/OwnPtr.h>
+#include "HTMLPlugInImageElement.h"
namespace WebCore {
-class HTMLImageLoader;
+class KURL;
-class HTMLObjectElement : public HTMLPlugInElement {
+class HTMLObjectElement : public HTMLPlugInImageElement {
public:
HTMLObjectElement(Document*, bool createdByParser);
~HTMLObjectElement();
@@ -40,6 +39,7 @@ public:
virtual void parseMappedAttribute(MappedAttribute*);
virtual void attach();
+ virtual bool canLazyAttach() { return false; }
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual void finishParsingChildren();
@@ -48,7 +48,7 @@ public:
virtual void removedFromDocument();
virtual void recalcStyle(StyleChange);
- virtual void childrenChanged(bool changedByParser = false);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual bool isURLAttribute(Attribute*) const;
virtual const QualifiedName& imageSourceAttributeName() const;
@@ -56,13 +56,9 @@ public:
virtual void updateWidget();
void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
- bool isImageType();
-
void renderFallbackContent();
-#if USE(JAVASCRIPTCORE_BINDINGS)
- virtual KJS::Bindings::Instance* getInstance() const;
-#endif
+ virtual RenderWidget* renderWidgetForJSBindings() const;
String archive() const;
void setArchive(const String&);
@@ -79,7 +75,7 @@ public:
String codeType() const;
void setCodeType(const String&);
- String data() const;
+ KURL data() const;
void setData(const String&);
bool declare() const;
@@ -91,8 +87,6 @@ public:
String standby() const;
void setStandby(const String&);
- void setTabIndex(int);
-
String type() const;
void setType(const String&);
@@ -104,19 +98,20 @@ public:
bool isDocNamedItem() const { return m_docNamedItem; }
+ const String& classId() const { return m_classId; }
+
bool containsJavaApplet() const;
- String m_serviceType;
- String m_url;
- String m_classId;
- bool m_needWidgetUpdate : 1;
- bool m_useFallbackContent : 1;
- OwnPtr<HTMLImageLoader> m_imageLoader;
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
private:
void updateDocNamedItem();
- String oldIdAttr;
- bool m_docNamedItem;
+
+ AtomicString m_id;
+ String m_classId;
+ bool m_docNamedItem : 1;
+ bool m_needWidgetUpdate : 1;
+ bool m_useFallbackContent : 1;
};
}
diff --git a/WebCore/html/HTMLObjectElement.idl b/WebCore/html/HTMLObjectElement.idl
index a6fe7ac..c225238 100644
--- a/WebCore/html/HTMLObjectElement.idl
+++ b/WebCore/html/HTMLObjectElement.idl
@@ -42,7 +42,6 @@ module html {
attribute long hspace;
attribute [ConvertNullToNullString] DOMString name;
attribute [ConvertNullToNullString] DOMString standby;
- attribute long tabIndex;
attribute [ConvertNullToNullString] DOMString type;
attribute [ConvertNullToNullString] DOMString useMap;
attribute long vspace;
diff --git a/WebCore/html/HTMLOptGroupElement.cpp b/WebCore/html/HTMLOptGroupElement.cpp
index d317fc5..0465fb4 100644
--- a/WebCore/html/HTMLOptGroupElement.cpp
+++ b/WebCore/html/HTMLOptGroupElement.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 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
* This library is free software; you can redistribute it and/or
@@ -30,20 +30,21 @@
#include "HTMLNames.h"
#include "HTMLSelectElement.h"
#include "RenderMenuList.h"
+#include "NodeRenderStyle.h"
namespace WebCore {
using namespace HTMLNames;
HTMLOptGroupElement::HTMLOptGroupElement(Document* doc, HTMLFormElement* f)
- : HTMLGenericFormElement(optgroupTag, doc, f)
+ : HTMLFormControlElement(optgroupTag, doc, f)
, m_style(0)
{
}
bool HTMLOptGroupElement::isFocusable() const
{
- return false;
+ return HTMLElement::isFocusable();
}
const AtomicString& HTMLOptGroupElement::type() const
@@ -52,17 +53,17 @@ const AtomicString& HTMLOptGroupElement::type() const
return optgroup;
}
-bool HTMLOptGroupElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec)
+bool HTMLOptGroupElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
{
- bool result = HTMLGenericFormElement::insertBefore(newChild, refChild, ec);
+ bool result = HTMLFormControlElement::insertBefore(newChild, refChild, ec, shouldLazyAttach);
if (result)
recalcSelectOptions();
return result;
}
-bool HTMLOptGroupElement::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec)
+bool HTMLOptGroupElement::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
{
- bool result = HTMLGenericFormElement::replaceChild(newChild, oldChild, ec);
+ bool result = HTMLFormControlElement::replaceChild(newChild, oldChild, ec, shouldLazyAttach);
if (result)
recalcSelectOptions();
return result;
@@ -70,15 +71,15 @@ bool HTMLOptGroupElement::replaceChild(PassRefPtr<Node> newChild, Node* oldChild
bool HTMLOptGroupElement::removeChild(Node* oldChild, ExceptionCode& ec)
{
- bool result = HTMLGenericFormElement::removeChild(oldChild, ec);
+ bool result = HTMLFormControlElement::removeChild(oldChild, ec);
if (result)
recalcSelectOptions();
return result;
}
-bool HTMLOptGroupElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
+bool HTMLOptGroupElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
{
- bool result = HTMLGenericFormElement::appendChild(newChild, ec);
+ bool result = HTMLFormControlElement::appendChild(newChild, ec, shouldLazyAttach);
if (result)
recalcSelectOptions();
return result;
@@ -86,21 +87,21 @@ bool HTMLOptGroupElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode&
bool HTMLOptGroupElement::removeChildren()
{
- bool result = HTMLGenericFormElement::removeChildren();
+ bool result = HTMLFormControlElement::removeChildren();
if (result)
recalcSelectOptions();
return result;
}
-void HTMLOptGroupElement::childrenChanged(bool changedByParser)
+void HTMLOptGroupElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
recalcSelectOptions();
- HTMLGenericFormElement::childrenChanged(changedByParser);
+ HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
void HTMLOptGroupElement::parseMappedAttribute(MappedAttribute* attr)
{
- HTMLGenericFormElement::parseMappedAttribute(attr);
+ HTMLFormControlElement::parseMappedAttribute(attr);
recalcSelectOptions();
}
@@ -131,36 +132,30 @@ bool HTMLOptGroupElement::checkDTD(const Node* newChild)
void HTMLOptGroupElement::attach()
{
- if (parentNode()->renderStyle()) {
- RenderStyle* style = styleForRenderer(0);
- setRenderStyle(style);
- style->deref(document()->renderArena());
- }
- HTMLGenericFormElement::attach();
+ if (parentNode()->renderStyle())
+ setRenderStyle(styleForRenderer());
+ HTMLFormControlElement::attach();
}
void HTMLOptGroupElement::detach()
{
- if (m_style) {
- m_style->deref(document()->renderArena());
- m_style = 0;
- }
- HTMLGenericFormElement::detach();
+ m_style.clear();
+ HTMLFormControlElement::detach();
}
-void HTMLOptGroupElement::setRenderStyle(RenderStyle* newStyle)
+void HTMLOptGroupElement::setRenderStyle(PassRefPtr<RenderStyle> newStyle)
{
- RenderStyle* oldStyle = m_style;
m_style = newStyle;
- if (newStyle)
- newStyle->ref();
- if (oldStyle)
- oldStyle->deref(document()->renderArena());
+}
+
+RenderStyle* HTMLOptGroupElement::nonRendererRenderStyle() const
+{
+ return m_style.get();
}
String HTMLOptGroupElement::groupLabelText() const
{
- DeprecatedString itemText = getAttribute(labelAttr).deprecatedString();
+ String itemText = getAttribute(labelAttr);
itemText.replace('\\', document()->backslashAsCurrencySymbol());
// In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
@@ -170,5 +165,25 @@ String HTMLOptGroupElement::groupLabelText() const
return itemText;
}
-
+
+HTMLSelectElement* HTMLOptGroupElement::ownerSelectElement() const
+{
+ Node* select = parentNode();
+ while (select && !select->hasTagName(selectTag))
+ select = select->parentNode();
+
+ if (!select)
+ return 0;
+
+ return static_cast<HTMLSelectElement*>(select);
+}
+
+void HTMLOptGroupElement::accessKeyAction(bool sendToAnyElement)
+{
+ HTMLSelectElement* select = ownerSelectElement();
+ // send to the parent to bring focus to the list box
+ if (select && !select->focused())
+ select->accessKeyAction(false);
+}
+
} // namespace
diff --git a/WebCore/html/HTMLOptGroupElement.h b/WebCore/html/HTMLOptGroupElement.h
index 6127b19..85e789b 100644
--- a/WebCore/html/HTMLOptGroupElement.h
+++ b/WebCore/html/HTMLOptGroupElement.h
@@ -24,11 +24,13 @@
#ifndef HTMLOptGroupElement_h
#define HTMLOptGroupElement_h
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
namespace WebCore {
+
+class HTMLSelectElement;
-class HTMLOptGroupElement : public HTMLGenericFormElement {
+class HTMLOptGroupElement : public HTMLFormControlElement {
public:
HTMLOptGroupElement(Document*, HTMLFormElement* = 0);
@@ -39,25 +41,28 @@ public:
virtual bool rendererIsNeeded(RenderStyle*) { return false; }
virtual void attach();
virtual void detach();
- virtual RenderStyle* renderStyle() const { return m_style; }
- virtual void setRenderStyle(RenderStyle*);
+ virtual void setRenderStyle(PassRefPtr<RenderStyle>);
- virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&);
- virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&);
+ virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
+ virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
virtual bool removeChild(Node* child, ExceptionCode&);
- virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&);
+ virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
virtual bool removeChildren();
- virtual void childrenChanged(bool changedByParser = false);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
String label() const;
void setLabel(const String&);
String groupLabelText() const;
+ HTMLSelectElement* ownerSelectElement() const;
+ virtual void accessKeyAction(bool sendToAnyElement);
private:
+ virtual RenderStyle* nonRendererRenderStyle() const;
+
void recalcSelectOptions();
- RenderStyle* m_style;
+ RefPtr<RenderStyle> m_style;
};
} //namespace
diff --git a/WebCore/html/HTMLOptionElement.cpp b/WebCore/html/HTMLOptionElement.cpp
index db4f020..887a4e5 100644
--- a/WebCore/html/HTMLOptionElement.cpp
+++ b/WebCore/html/HTMLOptionElement.cpp
@@ -29,21 +29,20 @@
#include "CSSStyleSelector.h"
#include "Document.h"
-#include "EventNames.h"
#include "ExceptionCode.h"
#include "HTMLNames.h"
#include "HTMLSelectElement.h"
#include "RenderMenuList.h"
#include "Text.h"
+#include "NodeRenderStyle.h"
#include <wtf/Vector.h>
namespace WebCore {
using namespace HTMLNames;
-using namespace EventNames;
HTMLOptionElement::HTMLOptionElement(Document* doc, HTMLFormElement* f)
- : HTMLGenericFormElement(optionTag, doc, f)
+ : HTMLFormControlElement(optionTag, doc, f)
, m_selected(false)
, m_style(0)
{
@@ -56,26 +55,20 @@ bool HTMLOptionElement::checkDTD(const Node* newChild)
void HTMLOptionElement::attach()
{
- if (parentNode()->renderStyle()) {
- RenderStyle* style = styleForRenderer(0);
- setRenderStyle(style);
- style->deref(document()->renderArena());
- }
- HTMLGenericFormElement::attach();
+ if (parentNode()->renderStyle())
+ setRenderStyle(styleForRenderer());
+ HTMLFormControlElement::attach();
}
void HTMLOptionElement::detach()
{
- if (m_style) {
- m_style->deref(document()->renderArena());
- m_style = 0;
- }
- HTMLGenericFormElement::detach();
+ m_style.clear();
+ HTMLFormControlElement::detach();
}
bool HTMLOptionElement::isFocusable() const
{
- return false;
+ return HTMLElement::isFocusable();
}
const AtomicString& HTMLOptionElement::type() const
@@ -127,11 +120,18 @@ void HTMLOptionElement::setText(const String &text, ExceptionCode& ec)
appendChild(new Text(document(), text), ec);
}
+void HTMLOptionElement::accessKeyAction(bool sendToAnyElement)
+{
+ HTMLSelectElement* select = ownerSelectElement();
+ if (select)
+ select->accessKeySetSelectedIndex(index());
+}
+
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 = getSelect();
+ HTMLSelectElement* select = ownerSelectElement();
if (select) {
const Vector<HTMLElement*>& items = select->listItems();
int l = items.size();
@@ -154,7 +154,7 @@ void HTMLOptionElement::parseMappedAttribute(MappedAttribute *attr)
else if (attr->name() == valueAttr)
m_value = attr->value();
else
- HTMLGenericFormElement::parseMappedAttribute(attr);
+ HTMLFormControlElement::parseMappedAttribute(attr);
}
String HTMLOptionElement::value() const
@@ -174,7 +174,7 @@ void HTMLOptionElement::setSelected(bool selected)
{
if (m_selected == selected)
return;
- if (HTMLSelectElement* select = getSelect())
+ if (HTMLSelectElement* select = ownerSelectElement())
select->setSelectedIndex(selected ? index() : -1, false);
m_selected = selected;
}
@@ -187,19 +187,23 @@ void HTMLOptionElement::setSelectedState(bool selected)
setChanged();
}
-void HTMLOptionElement::childrenChanged(bool changedByParser)
+void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
- HTMLSelectElement *select = getSelect();
+ HTMLSelectElement* select = ownerSelectElement();
if (select)
select->childrenChanged(changedByParser);
- HTMLGenericFormElement::childrenChanged(changedByParser);
+ HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
-HTMLSelectElement* HTMLOptionElement::getSelect() const
+HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const
{
Node* select = parentNode();
while (select && !select->hasTagName(selectTag))
select = select->parentNode();
+
+ if (!select)
+ return 0;
+
return static_cast<HTMLSelectElement*>(select);
}
@@ -223,14 +227,14 @@ void HTMLOptionElement::setLabel(const String& value)
setAttribute(labelAttr, value);
}
-void HTMLOptionElement::setRenderStyle(RenderStyle* newStyle)
+void HTMLOptionElement::setRenderStyle(PassRefPtr<RenderStyle> newStyle)
{
- RenderStyle* oldStyle = m_style;
m_style = newStyle;
- if (newStyle)
- newStyle->ref();
- if (oldStyle)
- oldStyle->deref(document()->renderArena());
+}
+
+RenderStyle* HTMLOptionElement::nonRendererRenderStyle() const
+{
+ return m_style.get();
}
String HTMLOptionElement::optionText()
@@ -243,16 +247,16 @@ String HTMLOptionElement::optionText()
bool HTMLOptionElement::disabled() const
{
- return HTMLGenericFormElement::disabled() || (parentNode() && static_cast<HTMLGenericFormElement*>(parentNode())->disabled());
+ return HTMLFormControlElement::disabled() || (parentNode() && static_cast<HTMLFormControlElement*>(parentNode())->disabled());
}
void HTMLOptionElement::insertedIntoDocument()
{
HTMLSelectElement* select;
- if (selected() && (select = getSelect()))
+ if (selected() && (select = ownerSelectElement()))
select->scrollToSelection();
- HTMLGenericFormElement::insertedIntoDocument();
+ HTMLFormControlElement::insertedIntoDocument();
}
} // namespace
diff --git a/WebCore/html/HTMLOptionElement.h b/WebCore/html/HTMLOptionElement.h
index 635a7b3..58426eb 100644
--- a/WebCore/html/HTMLOptionElement.h
+++ b/WebCore/html/HTMLOptionElement.h
@@ -25,7 +25,7 @@
#ifndef HTMLOptionElement_h
#define HTMLOptionElement_h
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
namespace WebCore {
@@ -33,8 +33,7 @@ class HTMLSelectElement;
class HTMLFormElement;
class MappedAttribute;
-class HTMLOptionElement : public HTMLGenericFormElement
-{
+class HTMLOptionElement : public HTMLFormControlElement {
friend class HTMLSelectElement;
friend class RenderMenuList;
@@ -48,8 +47,7 @@ public:
virtual bool rendererIsNeeded(RenderStyle*) { return false; }
virtual void attach();
virtual void detach();
- virtual RenderStyle* renderStyle() const { return m_style; }
- virtual void setRenderStyle(RenderStyle*);
+ virtual void setRenderStyle(PassRefPtr<RenderStyle>);
virtual const AtomicString& type() const;
@@ -66,9 +64,9 @@ public:
void setSelected(bool);
void setSelectedState(bool);
- HTMLSelectElement* getSelect() const;
+ HTMLSelectElement* ownerSelectElement() const;
- virtual void childrenChanged(bool changedByParser = false);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
bool defaultSelected() const;
void setDefaultSelected(bool);
@@ -81,11 +79,14 @@ public:
virtual bool disabled() const;
virtual void insertedIntoDocument();
-
+ virtual void accessKeyAction(bool);
+
private:
+ virtual RenderStyle* nonRendererRenderStyle() const;
+
String m_value;
bool m_selected;
- RenderStyle* m_style;
+ RefPtr<RenderStyle> m_style;
};
} //namespace
diff --git a/WebCore/html/HTMLOptionElement.idl b/WebCore/html/HTMLOptionElement.idl
index 1f17033..34fa999 100644
--- a/WebCore/html/HTMLOptionElement.idl
+++ b/WebCore/html/HTMLOptionElement.idl
@@ -21,6 +21,7 @@
module html {
interface [
+ GenerateConstructor,
GenerateNativeConverter,
InterfaceUUID=74a7b64a-cf18-4da9-b3aa-e1f4d245d607,
ImplementationUUID=166915d5-2c93-404b-b076-af3fa5ccbd83
diff --git a/WebCore/html/HTMLOptionsCollection.cpp b/WebCore/html/HTMLOptionsCollection.cpp
index d5a1a7f..0b88183 100644
--- a/WebCore/html/HTMLOptionsCollection.cpp
+++ b/WebCore/html/HTMLOptionsCollection.cpp
@@ -34,6 +34,11 @@ HTMLOptionsCollection::HTMLOptionsCollection(PassRefPtr<HTMLSelectElement> selec
{
}
+PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(PassRefPtr<HTMLSelectElement> select)
+{
+ return adoptRef(new HTMLOptionsCollection(select));
+}
+
void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, ExceptionCode &ec)
{
add(element, length(), ec);
diff --git a/WebCore/html/HTMLOptionsCollection.h b/WebCore/html/HTMLOptionsCollection.h
index 9fb5bbf..a82749b 100644
--- a/WebCore/html/HTMLOptionsCollection.h
+++ b/WebCore/html/HTMLOptionsCollection.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, 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
@@ -35,7 +35,7 @@ typedef int ExceptionCode;
class HTMLOptionsCollection : public HTMLCollection {
public:
- HTMLOptionsCollection(PassRefPtr<HTMLSelectElement>);
+ static PassRefPtr<HTMLOptionsCollection> create(PassRefPtr<HTMLSelectElement>);
void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&);
void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionCode&);
@@ -45,6 +45,9 @@ public:
void setSelectedIndex(int);
void setLength(unsigned, ExceptionCode&);
+
+private:
+ HTMLOptionsCollection(PassRefPtr<HTMLSelectElement>);
};
} //namespace
diff --git a/WebCore/html/HTMLParagraphElement.cpp b/WebCore/html/HTMLParagraphElement.cpp
index 4cee789..1b5f054 100644
--- a/WebCore/html/HTMLParagraphElement.cpp
+++ b/WebCore/html/HTMLParagraphElement.cpp
@@ -57,13 +57,13 @@ void HTMLParagraphElement::parseMappedAttribute(MappedAttribute *attr)
if (attr->name() == alignAttr) {
String v = attr->value();
if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_CENTER);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitCenter);
else if (equalIgnoringCase(attr->value(), "left"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_LEFT);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitLeft);
else if (equalIgnoringCase(attr->value(), "right"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_RIGHT);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitRight);
else
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, v);
+ addCSSProperty(attr, CSSPropertyTextAlign, v);
} else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLParagraphElement.h b/WebCore/html/HTMLParagraphElement.h
index a6be6b4..9b5b4fa 100644
--- a/WebCore/html/HTMLParagraphElement.h
+++ b/WebCore/html/HTMLParagraphElement.h
@@ -32,7 +32,7 @@ class HTMLParagraphElement : public HTMLElement {
public:
HTMLParagraphElement(Document*);
- virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; }
+ virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
virtual int tagPriority() const { return 3; }
virtual bool checkDTD(const Node* newChild);
diff --git a/WebCore/html/HTMLParamElement.cpp b/WebCore/html/HTMLParamElement.cpp
index d1e2616..0c9d593 100644
--- a/WebCore/html/HTMLParamElement.cpp
+++ b/WebCore/html/HTMLParamElement.cpp
@@ -1,10 +1,8 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006, 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
@@ -21,6 +19,7 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLParamElement.h"
@@ -31,7 +30,7 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLParamElement::HTMLParamElement(Document *doc)
+HTMLParamElement::HTMLParamElement(Document* doc)
: HTMLElement(paramTag, doc)
{
}
@@ -40,12 +39,12 @@ HTMLParamElement::~HTMLParamElement()
{
}
-void HTMLParamElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLParamElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == idAttr) {
// Must call base class so that hasID bit gets set.
HTMLElement::parseMappedAttribute(attr);
- if (document()->htmlMode() != Document::XHtml)
+ if (document()->isHTMLDocument())
return;
m_name = attr->value();
} else if (attr->name() == nameAttr) {
@@ -56,20 +55,20 @@ void HTMLParamElement::parseMappedAttribute(MappedAttribute *attr)
HTMLElement::parseMappedAttribute(attr);
}
-bool HTMLParamElement::isURLAttribute(Attribute *attr) const
+bool HTMLParamElement::isURLAttribute(Attribute* attr) const
{
if (attr->name() == valueAttr) {
- Attribute *attr = attributes()->getAttributeItem(nameAttr);
+ Attribute* attr = attributes()->getAttributeItem(nameAttr);
if (attr) {
- String value = attr->value().domString().lower();
- if (value == "src" || value == "movie" || value == "data")
+ const AtomicString& value = attr->value();
+ if (equalIgnoringCase(value, "data") || equalIgnoringCase(value, "movie") || equalIgnoringCase(value, "src"))
return true;
}
}
return false;
}
-void HTMLParamElement::setName(const String &value)
+void HTMLParamElement::setName(const String& value)
{
setAttribute(nameAttr, value);
}
@@ -79,12 +78,12 @@ String HTMLParamElement::type() const
return getAttribute(typeAttr);
}
-void HTMLParamElement::setType(const String &value)
+void HTMLParamElement::setType(const String& value)
{
setAttribute(typeAttr, value);
}
-void HTMLParamElement::setValue(const String &value)
+void HTMLParamElement::setValue(const String& value)
{
setAttribute(valueAttr, value);
}
@@ -94,9 +93,19 @@ String HTMLParamElement::valueType() const
return getAttribute(valuetypeAttr);
}
-void HTMLParamElement::setValueType(const String &value)
+void HTMLParamElement::setValueType(const String& value)
{
setAttribute(valuetypeAttr, value);
}
+void HTMLParamElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ if (!equalIgnoringCase(name(), "data") &&
+ !equalIgnoringCase(name(), "movie") &&
+ !equalIgnoringCase(name(), "src"))
+ return;
+
+ urls.append(value());
+}
+
}
diff --git a/WebCore/html/HTMLParamElement.h b/WebCore/html/HTMLParamElement.h
index 3bc1fa1..5e31aed 100644
--- a/WebCore/html/HTMLParamElement.h
+++ b/WebCore/html/HTMLParamElement.h
@@ -55,6 +55,8 @@ public:
String valueType() const;
void setValueType(const String&);
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
protected:
AtomicString m_name;
AtomicString m_value;
diff --git a/WebCore/html/HTMLParser.cpp b/WebCore/html/HTMLParser.cpp
index 8102680..ba2220c 100644
--- a/WebCore/html/HTMLParser.cpp
+++ b/WebCore/html/HTMLParser.cpp
@@ -28,7 +28,10 @@
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "Comment.h"
+#include "Console.h"
+#include "DOMWindow.h"
#include "DocumentFragment.h"
+#include "DocumentType.h"
#include "Frame.h"
#include "HTMLBodyElement.h"
#include "HTMLDocument.h"
@@ -47,7 +50,6 @@
#include "HTMLTableSectionElement.h"
#include "HTMLTokenizer.h"
#include "LocalizedStrings.h"
-#include "Page.h"
#include "Settings.h"
#include "Text.h"
@@ -114,6 +116,7 @@ HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
, current(doc)
, didRefCurrent(false)
, blockStack(0)
+ , m_hasPElementInScope(NotInScope)
, head(0)
, inBody(false)
, haveContent(false)
@@ -130,6 +133,7 @@ HTMLParser::HTMLParser(DocumentFragment* frag)
, current(frag)
, didRefCurrent(true)
, blockStack(0)
+ , m_hasPElementInScope(NotInScope)
, head(0)
, inBody(true)
, haveContent(false)
@@ -207,10 +211,11 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
return 0;
}
- // ignore spaces, if we're not inside a paragraph or other inline code
- if (t->tagName == textAtom && t->text) {
- if (inBody && !skipMode() && current->localName() != styleTag && current->localName() != titleTag &&
- current->localName() != scriptTag && !t->text->containsOnlyWhitespace())
+ // Ignore spaces, if we're not inside a paragraph or other inline code.
+ // Do not alter the text if it is part of a scriptTag.
+ if (t->tagName == textAtom && t->text && current->localName() != scriptTag) {
+ if (inBody && !skipMode() && current->localName() != styleTag &&
+ current->localName() != titleTag && !t->text->containsOnlyWhitespace())
haveContent = true;
RefPtr<Node> n;
@@ -271,6 +276,16 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
return n;
}
+void HTMLParser::parseDoctypeToken(DoctypeToken* t)
+{
+ // Ignore any doctype after the first. Ignore doctypes in fragments.
+ if (document->doctype() || m_isParsingFragment || current != document)
+ return;
+
+ // Make a new doctype node and set it as our doctype.
+ document->addChild(DocumentType::create(document, String::adopt(t->m_name), String::adopt(t->m_publicID), String::adopt(t->m_systemID)));
+}
+
static bool isTableSection(Node* n)
{
return n->hasTagName(tbodyTag) || n->hasTagName(tfootTag) || n->hasTagName(theadTag);
@@ -287,6 +302,11 @@ static bool isTableRelated(Node* n)
return n->hasTagName(tableTag) || isTablePart(n);
}
+static bool isScopingTag(const AtomicString& tagName)
+{
+ return tagName == appletTag || tagName == captionTag || tagName == tdTag || tagName == thTag || tagName == buttonTag || tagName == marqueeTag || tagName == objectTag || tagName == tableTag || tagName == htmlTag;
+}
+
bool HTMLParser::insertNode(Node* n, bool flat)
{
RefPtr<Node> protectNode(n);
@@ -318,6 +338,7 @@ bool HTMLParser::insertNode(Node* n, bool flat)
// optimized version of setCurrent that takes advantage of that fact and also
// assumes that newNode is neither 0 nor a pointer to the document.
pushBlock(localName, tagPriority);
+ newNode->beginParsingChildren();
ASSERT(!didRefCurrent);
newNode->ref();
current = newNode;
@@ -374,7 +395,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
}
} else if (h->hasLocalName(htmlTag)) {
if (!current->isDocumentNode() ) {
- if (document->documentElement()->hasTagName(htmlTag)) {
+ if (document->documentElement() && document->documentElement()->hasTagName(htmlTag)) {
reportError(RedundantHTMLBodyError, &localName);
// we have another <HTML> element.... apply attributes to existing one
// make sure we don't overwrite already existing attributes
@@ -406,6 +427,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
reportError(MisplacedHeadContentError, &localName, &current->localName());
pushBlock(localName, tagPriority);
+ newNode->beginParsingChildren();
setCurrent(newNode);
if (!n->attached() && !m_isParsingFragment)
n->attach();
@@ -456,7 +478,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
// 2. Next we examine our currently active element to do some further error handling.
if (current->isHTMLElement()) {
HTMLElement* h = static_cast<HTMLElement*>(current);
- const AtomicString& currentTagName = current->localName();
+ const AtomicString& currentTagName = h->localName();
if (h->hasLocalName(htmlTag)) {
HTMLElement* elt = n->isHTMLElement() ? static_cast<HTMLElement*>(n) : 0;
if (elt && (elt->hasLocalName(scriptTag) || elt->hasLocalName(styleTag) ||
@@ -498,8 +520,8 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
} else
reportError(MisplacedFramesetContentError, &localName);
}
- } else if (h->hasLocalName(addressTag) || h->hasLocalName(dlTag) || h->hasLocalName(dtTag)
- || h->hasLocalName(fontTag) || h->hasLocalName(styleTag) || h->hasLocalName(titleTag)) {
+ } else if (h->hasLocalName(addressTag) || h->hasLocalName(fontTag)
+ || h->hasLocalName(styleTag) || h->hasLocalName(titleTag)) {
reportError(MisplacedContentRetryError, &localName, &currentTagName);
popBlock(currentTagName);
handled = true;
@@ -549,6 +571,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
!flat && static_cast<HTMLElement*>(n)->endTagRequirement() != TagStatusForbidden)
{
pushBlock(localName, tagPriority);
+ n->beginParsingChildren();
setCurrent(n);
inStrayTableContent++;
blockStack->strayTableContent = true;
@@ -591,6 +614,12 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
// IE treats a nested select as </select>. Let's do the same
popBlock(localName);
}
+ } else if (h->hasLocalName(selectTag)) {
+ if (localName == inputTag || localName == textareaTag) {
+ reportError(MisplacedContentRetryError, &localName, &currentTagName);
+ popBlock(currentTagName);
+ handled = true;
+ }
} else if (h->hasLocalName(colgroupTag)) {
popBlock(currentTagName);
handled = true;
@@ -677,13 +706,6 @@ bool HTMLParser::framesetCreateErrorCheck(Token* t, RefPtr<Node>& result)
return true;
}
-bool HTMLParser::iframeCreateErrorCheck(Token* t, RefPtr<Node>& result)
-{
- // a bit of a special case, since the frame is inlined
- setSkipMode(iframeTag);
- return true;
-}
-
bool HTMLParser::formCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
// Only create a new form if we're not already inside one.
@@ -691,6 +713,7 @@ bool HTMLParser::formCreateErrorCheck(Token* t, RefPtr<Node>& result)
if (!m_currentFormElement) {
m_currentFormElement = new HTMLFormElement(document);
result = m_currentFormElement;
+ pCloserCreateErrorCheck(t, result);
}
return false;
}
@@ -714,6 +737,7 @@ bool HTMLParser::selectCreateErrorCheck(Token* t, RefPtr<Node>& result)
bool HTMLParser::ddCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
+ pCloserCreateErrorCheck(t, result);
popBlock(dtTag);
popBlock(ddTag);
return true;
@@ -721,6 +745,7 @@ bool HTMLParser::ddCreateErrorCheck(Token* t, RefPtr<Node>& result)
bool HTMLParser::dtCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
+ pCloserCreateErrorCheck(t, result);
popBlock(ddTag);
popBlock(dtTag);
return true;
@@ -732,6 +757,13 @@ bool HTMLParser::nestedCreateErrorCheck(Token* t, RefPtr<Node>& result)
return true;
}
+bool HTMLParser::nestedPCloserCreateErrorCheck(Token* t, RefPtr<Node>& result)
+{
+ pCloserCreateErrorCheck(t, result);
+ popBlock(t->tagName);
+ return true;
+}
+
bool HTMLParser::nestedStyleCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
return allowNestedRedundantTag(t->tagName);
@@ -774,6 +806,22 @@ bool HTMLParser::noscriptCreateErrorCheck(Token* t, RefPtr<Node>& result)
return true;
}
+bool HTMLParser::pCloserCreateErrorCheck(Token* t, RefPtr<Node>& result)
+{
+ if (hasPElementInScope())
+ popBlock(pTag);
+ return true;
+}
+
+bool HTMLParser::pCloserStrictCreateErrorCheck(Token* t, RefPtr<Node>& result)
+{
+ if (document->inCompatMode())
+ return true;
+ if (hasPElementInScope())
+ popBlock(pTag);
+ return true;
+}
+
bool HTMLParser::mapCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
m_currentMapElement = new HTMLMapElement(document);
@@ -787,29 +835,49 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t)
static FunctionMap gFunctionMap;
if (gFunctionMap.isEmpty()) {
gFunctionMap.set(aTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
+ gFunctionMap.set(addressTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(bTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
gFunctionMap.set(bigTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
+ gFunctionMap.set(blockquoteTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(bodyTag.localName().impl(), &HTMLParser::bodyCreateErrorCheck);
gFunctionMap.set(buttonTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
+ gFunctionMap.set(centerTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(commentAtom.impl(), &HTMLParser::commentCreateErrorCheck);
gFunctionMap.set(ddTag.localName().impl(), &HTMLParser::ddCreateErrorCheck);
+ gFunctionMap.set(dirTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(divTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(dlTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(dtTag.localName().impl(), &HTMLParser::dtCreateErrorCheck);
gFunctionMap.set(formTag.localName().impl(), &HTMLParser::formCreateErrorCheck);
+ gFunctionMap.set(fieldsetTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(framesetTag.localName().impl(), &HTMLParser::framesetCreateErrorCheck);
+ gFunctionMap.set(h1Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(h2Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(h3Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(h4Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(h5Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(h6Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(headTag.localName().impl(), &HTMLParser::headCreateErrorCheck);
+ gFunctionMap.set(hrTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(iTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
- gFunctionMap.set(iframeTag.localName().impl(), &HTMLParser::iframeCreateErrorCheck);
gFunctionMap.set(isindexTag.localName().impl(), &HTMLParser::isindexCreateErrorCheck);
- gFunctionMap.set(liTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
+ gFunctionMap.set(liTag.localName().impl(), &HTMLParser::nestedPCloserCreateErrorCheck);
+ gFunctionMap.set(listingTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(mapTag.localName().impl(), &HTMLParser::mapCreateErrorCheck);
+ gFunctionMap.set(menuTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(nobrTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
gFunctionMap.set(noembedTag.localName().impl(), &HTMLParser::noembedCreateErrorCheck);
gFunctionMap.set(noframesTag.localName().impl(), &HTMLParser::noframesCreateErrorCheck);
gFunctionMap.set(noscriptTag.localName().impl(), &HTMLParser::noscriptCreateErrorCheck);
+ gFunctionMap.set(olTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(pTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(plaintextTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
+ gFunctionMap.set(preTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(sTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
gFunctionMap.set(selectTag.localName().impl(), &HTMLParser::selectCreateErrorCheck);
gFunctionMap.set(smallTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
gFunctionMap.set(strikeTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
+ gFunctionMap.set(tableTag.localName().impl(), &HTMLParser::pCloserStrictCreateErrorCheck);
gFunctionMap.set(tbodyTag.localName().impl(), &HTMLParser::tableSectionCreateErrorCheck);
gFunctionMap.set(tdTag.localName().impl(), &HTMLParser::tableCellCreateErrorCheck);
gFunctionMap.set(textAtom.impl(), &HTMLParser::textCreateErrorCheck);
@@ -819,6 +887,7 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t)
gFunctionMap.set(trTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
gFunctionMap.set(ttTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
gFunctionMap.set(uTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
+ gFunctionMap.set(ulTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
}
bool proceed = true;
@@ -1011,6 +1080,8 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
if (!parentElem->childAllowed(blockElem))
return;
+ m_hasPElementInScope = Unknown;
+
if (maxElem->node->parentNode() != elem->node) {
// Walk the stack and remove any elements that aren't residual style tags. These
// are basically just being closed up. Example:
@@ -1089,7 +1160,6 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
blockElem->parentNode()->removeChild(blockElem, ec);
Node* newNodePtr = 0;
- ASSERT(finished || blockElem->firstChild());
if (blockElem->firstChild()) {
// Step 2: Clone |residualElem|.
RefPtr<Node> newNode = residualElem->cloneNode(false); // Shallow clone. We don't pick up the same kids.
@@ -1109,7 +1179,8 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
// Step 4: Place |newNode| under |blockElem|. |blockElem| is still out of the document, so no
// attachment can occur yet.
blockElem->appendChild(newNode.release(), ec);
- }
+ } else
+ finished = true;
// Step 5: Reparent |blockElem|. Now the full attachment of the fixed up tree takes place.
if (isBlockStillInTree)
@@ -1157,10 +1228,11 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
HTMLStackElem* curr = blockStack;
HTMLStackElem* residualStyleStack = 0;
unsigned stackDepth = 1;
+ unsigned redundantStyleCount = 0;
while (curr && curr != maxElem) {
// We will actually schedule this tag for reopening
// after we complete the close of this entire block.
- if (isResidualStyleTag(curr->tagName) && stackDepth++ < cResidualStyleMaxDepth)
+ if (isResidualStyleTag(curr->tagName) && stackDepth++ < cResidualStyleMaxDepth) {
// We've overloaded the use of stack elements and are just reusing the
// struct with a slightly different meaning to the variables. Instead of chaining
// from innermost to outermost, we build up a list of all the tags we need to reopen
@@ -1169,8 +1241,16 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
// We also set curr->node to be the actual element that corresponds to the ID stored in
// curr->id rather than the node that you should pop to when the element gets pulled off
// the stack.
- moveOneBlockToStack(residualStyleStack);
- else
+ if (residualStyleStack && curr->tagName == residualStyleStack->tagName && curr->node->attributes()->mapsEquivalent(residualStyleStack->node->attributes()))
+ redundantStyleCount++;
+ else
+ redundantStyleCount = 0;
+
+ if (redundantStyleCount < cMaxRedundantTagDepth)
+ moveOneBlockToStack(residualStyleStack);
+ else
+ popOneBlock();
+ } else
popOneBlock();
curr = blockStack;
@@ -1200,6 +1280,7 @@ void HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTab
// Now push a new stack element for this node we just created.
pushBlock(elem->tagName, elem->level);
+ newNode->beginParsingChildren();
// Set our strayTableContent boolean if needed, so that the reopened tag also knows
// that it is inside a malformed table.
@@ -1223,9 +1304,12 @@ void HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTab
void HTMLParser::pushBlock(const AtomicString& tagName, int level)
{
- current->beginParsingChildren();
blockStack = new HTMLStackElem(tagName, level, current, didRefCurrent, blockStack);
didRefCurrent = false;
+ if (tagName == pTag)
+ m_hasPElementInScope = InScope;
+ else if (isScopingTag(tagName))
+ m_hasPElementInScope = NotInScope;
}
void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
@@ -1260,6 +1344,7 @@ void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
elem = blockStack;
unsigned stackDepth = 1;
+ unsigned redundantStyleCount = 0;
while (elem) {
if (elem->tagName == tagName) {
int strayTable = inStrayTableContent;
@@ -1286,7 +1371,7 @@ void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
// Schedule this tag for reopening
// after we complete the close of this entire block.
- if (isAffectedByStyle && isResidualStyleTag(elem->tagName) && stackDepth++ < cResidualStyleMaxDepth)
+ if (isAffectedByStyle && isResidualStyleTag(elem->tagName) && stackDepth++ < cResidualStyleMaxDepth) {
// We've overloaded the use of stack elements and are just reusing the
// struct with a slightly different meaning to the variables. Instead of chaining
// from innermost to outermost, we build up a list of all the tags we need to reopen
@@ -1295,8 +1380,16 @@ void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
// We also set elem->node to be the actual element that corresponds to the ID stored in
// elem->id rather than the node that you should pop to when the element gets pulled off
// the stack.
- moveOneBlockToStack(residualStyleStack);
- else
+ if (residualStyleStack && elem->tagName == residualStyleStack->tagName && elem->node->attributes()->mapsEquivalent(residualStyleStack->node->attributes()))
+ redundantStyleCount++;
+ else
+ redundantStyleCount = 0;
+
+ if (redundantStyleCount < cMaxRedundantTagDepth)
+ moveOneBlockToStack(residualStyleStack);
+ else
+ popOneBlock();
+ } else
popOneBlock();
elem = blockStack;
}
@@ -1321,6 +1414,11 @@ inline HTMLStackElem* HTMLParser::popOneBlockCommon()
if (elem->strayTableContent)
inStrayTableContent--;
+ if (elem->tagName == pTag)
+ m_hasPElementInScope = NotInScope;
+ else if (isScopingTag(elem->tagName))
+ m_hasPElementInScope = Unknown;
+
return elem;
}
@@ -1358,6 +1456,21 @@ void HTMLParser::moveOneBlockToStack(HTMLStackElem*& head)
head = elem;
}
+void HTMLParser::checkIfHasPElementInScope()
+{
+ m_hasPElementInScope = NotInScope;
+ HTMLStackElem* elem = blockStack;
+ while (elem) {
+ const AtomicString& tagName = elem->tagName;
+ if (tagName == pTag) {
+ m_hasPElementInScope = InScope;
+ return;
+ } else if (isScopingTag(tagName))
+ return;
+ elem = elem->next;
+ }
+}
+
void HTMLParser::popInlineBlocks()
{
while (blockStack && isInline(current))
@@ -1402,7 +1515,7 @@ PassRefPtr<Node> HTMLParser::handleIsindex(Token* t)
String text = searchableIndexIntroduction();
if (attrs) {
if (Attribute* a = attrs->getAttributeItem(promptAttr))
- text = a->value().domString() + " ";
+ text = a->value().string() + " ";
t->attrs = 0;
}
@@ -1448,10 +1561,6 @@ void HTMLParser::reportErrorToConsole(HTMLParserErrorCode errorCode, const Atomi
if (!frame)
return;
- Page* page = frame->page();
- if (!page)
- return;
-
HTMLTokenizer* htmlTokenizer = static_cast<HTMLTokenizer*>(document->tokenizer());
int lineNumber = htmlTokenizer->lineNumber() + 1;
@@ -1485,7 +1594,9 @@ void HTMLParser::reportErrorToConsole(HTMLParserErrorCode errorCode, const Atomi
message.replace("%tag1", tag1);
message.replace("%tag2", tag2);
- page->chrome()->addMessageToConsole(HTMLMessageSource, isWarning(errorCode) ? WarningMessageLevel: ErrorMessageLevel, message, lineNumber, document->url());
+ frame->domWindow()->console()->addMessage(HTMLMessageSource,
+ isWarning(errorCode) ? WarningMessageLevel : ErrorMessageLevel,
+ message, lineNumber, document->url().string());
}
}
diff --git a/WebCore/html/HTMLParser.h b/WebCore/html/HTMLParser.h
index 0c51a3f..3a5b437 100644
--- a/WebCore/html/HTMLParser.h
+++ b/WebCore/html/HTMLParser.h
@@ -31,6 +31,7 @@
namespace WebCore {
+class DoctypeToken;
class Document;
class DocumentFragment;
class HTMLDocument;
@@ -57,6 +58,9 @@ public:
*/
PassRefPtr<Node> parseToken(Token*);
+ // Parses a doctype token.
+ void parseDoctypeToken(DoctypeToken*);
+
/**
* tokenizer says it's not going to be sending us any more tokens
*/
@@ -88,11 +92,14 @@ private:
bool isindexCreateErrorCheck(Token*, RefPtr<Node>&);
bool mapCreateErrorCheck(Token*, RefPtr<Node>&);
bool nestedCreateErrorCheck(Token*, RefPtr<Node>&);
+ bool nestedPCloserCreateErrorCheck(Token*, RefPtr<Node>&);
bool nestedStyleCreateErrorCheck(Token*, RefPtr<Node>&);
bool noembedCreateErrorCheck(Token*, RefPtr<Node>&);
bool noframesCreateErrorCheck(Token*, RefPtr<Node>&);
bool nolayerCreateErrorCheck(Token*, RefPtr<Node>&);
bool noscriptCreateErrorCheck(Token*, RefPtr<Node>&);
+ bool pCloserCreateErrorCheck(Token*, RefPtr<Node>&);
+ bool pCloserStrictCreateErrorCheck(Token*, RefPtr<Node>&);
bool selectCreateErrorCheck(Token*, RefPtr<Node>&);
bool tableCellCreateErrorCheck(Token*, RefPtr<Node>&);
bool tableSectionCreateErrorCheck(Token*, RefPtr<Node>&);
@@ -130,6 +137,14 @@ private:
void startBody(); // inserts the isindex element
PassRefPtr<Node> handleIsindex(Token*);
+ void checkIfHasPElementInScope();
+ bool hasPElementInScope()
+ {
+ if (m_hasPElementInScope == Unknown)
+ checkIfHasPElementInScope();
+ return m_hasPElementInScope == InScope;
+ }
+
void reportError(HTMLParserErrorCode errorCode, const AtomicString* tagName1 = 0, const AtomicString* tagName2 = 0, bool closeTags = false)
{ if (!m_reportErrors) return; reportErrorToConsole(errorCode, tagName1, tagName2, closeTags); }
@@ -144,6 +159,9 @@ private:
HTMLStackElem* blockStack;
+ enum ElementInScopeState { NotInScope, InScope, Unknown };
+ ElementInScopeState m_hasPElementInScope;
+
RefPtr<HTMLFormElement> m_currentFormElement; // currently active form
RefPtr<HTMLMapElement> m_currentMapElement; // current map
HTMLHeadElement* head; // head element; needed for HTML which defines <base> after </head>
diff --git a/WebCore/html/HTMLPlugInElement.cpp b/WebCore/html/HTMLPlugInElement.cpp
index 223591a..5f585e7 100644
--- a/WebCore/html/HTMLPlugInElement.cpp
+++ b/WebCore/html/HTMLPlugInElement.cpp
@@ -34,19 +34,18 @@
#include "RenderWidget.h"
#include "Settings.h"
#include "Widget.h"
-#include "kjs_dom.h"
-#include "kjs_proxy.h"
+#include "ScriptController.h"
-#if USE(NPOBJECT)
-#include <bindings/NP_jsobject.h>
-#include <bindings/npruntime_impl.h>
-#include <bindings/runtime_root.h>
+#if USE(JSC)
+#include "runtime.h"
#endif
-using KJS::ExecState;
-using KJS::JSLock;
-using KJS::JSValue;
-using KJS::Bindings::RootObject;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+#include "JSNode.h"
+#include "NP_jsobject.h"
+#include "npruntime_impl.h"
+#include "runtime_root.h"
+#endif
namespace WebCore {
@@ -54,12 +53,12 @@ using namespace HTMLNames;
HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc)
: HTMLFrameOwnerElement(tagName, doc)
-#if USE(NPOBJECT)
+#if ENABLE(NETSCAPE_PLUGIN_API)
, m_NPObject(0)
#endif
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
-// ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+// ensure that m_name is removed from HTMLDocument's NameCountMap
, oldNameIdCount(0)
#endif
{
@@ -67,7 +66,11 @@ HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc
HTMLPlugInElement::~HTMLPlugInElement()
{
-#if USE(NPOBJECT)
+#if USE(JSC)
+ ASSERT(!m_instance); // cleared in detach()
+#endif
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
if (m_NPObject) {
_NPN_ReleaseObject(m_NPObject);
m_NPObject = 0;
@@ -75,6 +78,32 @@ HTMLPlugInElement::~HTMLPlugInElement()
#endif
}
+#if USE(JSC)
+void HTMLPlugInElement::detach()
+{
+ m_instance.clear();
+ HTMLFrameOwnerElement::detach();
+}
+
+JSC::Bindings::Instance* HTMLPlugInElement::getInstance() const
+{
+ Frame* frame = document()->frame();
+ if (!frame)
+ return 0;
+
+ // If the host dynamically turns off JavaScript (or Java) we will still return
+ // the cached allocated Bindings::Instance. Not supporting this edge-case is OK.
+ if (m_instance)
+ return m_instance.get();
+
+ RenderWidget* renderWidget = renderWidgetForJSBindings();
+ if (renderWidget && renderWidget->widget())
+ m_instance = frame->script()->createScriptInstanceForWidget(renderWidget->widget());
+
+ return m_instance.get();
+}
+#endif
+
String HTMLPlugInElement::align() const
{
return getAttribute(alignAttr);
@@ -136,20 +165,20 @@ bool HTMLPlugInElement::mapToEntry(const QualifiedName& attrName, MappedAttribut
void HTMLPlugInElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == widthAttr)
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
else if (attr->name() == heightAttr)
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
else if (attr->name() == vspaceAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
} else if (attr->name() == hspaceAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
} else if (attr->name() == alignAttr)
addHTMLAlignment(attr);
else
HTMLFrameOwnerElement::parseMappedAttribute(attr);
-}
+}
bool HTMLPlugInElement::checkDTD(const Node* newChild)
{
@@ -166,48 +195,17 @@ void HTMLPlugInElement::defaultEventHandler(Event* event)
widget->handleEvent(event);
}
-#if USE(NPOBJECT)
-
-NPObject* HTMLPlugInElement::createNPObject()
-{
- Frame* frame = document()->frame();
- if (!frame) {
- // This shouldn't ever happen, but might as well check anyway.
- ASSERT_NOT_REACHED();
- return _NPN_CreateNoScriptObject();
- }
-
- Settings* settings = frame->settings();
- if (!settings) {
- // This shouldn't ever happen, but might as well check anyway.
- ASSERT_NOT_REACHED();
- return _NPN_CreateNoScriptObject();
- }
-
- // Can't create NPObjects when JavaScript is disabled
- if (!frame->scriptProxy()->isEnabled())
- return _NPN_CreateNoScriptObject();
-
- // Create a JSObject bound to this element
- JSLock lock;
- ExecState *exec = frame->scriptProxy()->globalObject()->globalExec();
- JSValue* jsElementValue = toJS(exec, this);
- if (!jsElementValue || !jsElementValue->isObject())
- return _NPN_CreateNoScriptObject();
-
- // Wrap the JSObject in an NPObject
- RootObject* rootObject = frame->bindingRootObject();
- return _NPN_CreateScriptObject(0, jsElementValue->getObject(), rootObject);
-}
+#if ENABLE(NETSCAPE_PLUGIN_API)
NPObject* HTMLPlugInElement::getNPObject()
{
+ ASSERT(document()->frame());
if (!m_NPObject)
- m_NPObject = createNPObject();
+ m_NPObject = document()->frame()->script()->createScriptObjectForPluginElement(this);
return m_NPObject;
}
-#endif /* USE(NPOBJECT) */
+#endif /* ENABLE(NETSCAPE_PLUGIN_API) */
void HTMLPlugInElement::updateWidgetCallback(Node* n)
{
diff --git a/WebCore/html/HTMLPlugInElement.h b/WebCore/html/HTMLPlugInElement.h
index 5fad211..2b8c8ca 100644
--- a/WebCore/html/HTMLPlugInElement.h
+++ b/WebCore/html/HTMLPlugInElement.h
@@ -1,9 +1,7 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 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
@@ -27,16 +25,22 @@
#include "HTMLFrameOwnerElement.h"
-#if USE(JAVASCRIPTCORE_BINDINGS)
-#include <bindings/runtime.h>
+#if USE(JSC)
+namespace JSC {
+ namespace Bindings {
+ class Instance;
+ }
+}
#endif
-#if USE(NPOBJECT)
-#include <bindings/npruntime_internal.h>
+#if ENABLE(NETSCAPE_PLUGIN_API)
+struct NPObject;
#endif
namespace WebCore {
+class RenderWidget;
+
class HTMLPlugInElement : public HTMLFrameOwnerElement {
public:
HTMLPlugInElement(const QualifiedName& tagName, Document*);
@@ -62,32 +66,31 @@ public:
String width() const;
void setWidth(const String&);
-#if USE(JAVASCRIPTCORE_BINDINGS)
- virtual KJS::Bindings::Instance* getInstance() const = 0;
-#endif
-#if USE(NPOBJECT)
- virtual NPObject* getNPObject();
+ virtual void defaultEventHandler(Event*);
+
+ virtual RenderWidget* renderWidgetForJSBindings() const = 0;
+#if USE(JSC)
+ virtual void detach();
+ JSC::Bindings::Instance* getInstance() const;
#endif
- virtual void defaultEventHandler(Event*);
-private:
-#if USE(NPOBJECT)
- NPObject* createNPObject();
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ virtual NPObject* getNPObject();
#endif
protected:
static void updateWidgetCallback(Node*);
- String oldNameAttr;
-#if USE(JAVASCRIPTCORE_BINDINGS)
- mutable RefPtr<KJS::Bindings::Instance> m_instance;
+ AtomicString m_name;
+#if USE(JSC)
+ mutable RefPtr<JSC::Bindings::Instance> m_instance;
#endif
-#if USE(NPOBJECT)
+#if ENABLE(NETSCAPE_PLUGIN_API)
NPObject* m_NPObject;
#endif
#ifdef ANDROID_FIX
// addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512
- // ensure the oldNameAttr and oldIdAttr are removed from HTMLDocument's NameCountMap
+ // ensure that m_name is removed from HTMLDocument's NameCountMap
int oldNameIdCount;
#endif
};
diff --git a/WebCore/html/HTMLPlugInImageElement.cpp b/WebCore/html/HTMLPlugInImageElement.cpp
new file mode 100644
index 0000000..6dcd5fb
--- /dev/null
+++ b/WebCore/html/HTMLPlugInImageElement.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 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 "HTMLPlugInImageElement.h"
+
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "HTMLImageLoader.h"
+#include "Image.h"
+
+namespace WebCore {
+
+HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document)
+ : HTMLPlugInElement(tagName, document)
+{
+}
+
+HTMLPlugInImageElement::~HTMLPlugInImageElement()
+{
+}
+
+bool HTMLPlugInImageElement::isImageType()
+{
+ if (m_serviceType.isEmpty() && protocolIs(m_url, "data"))
+ m_serviceType = mimeTypeFromDataURL(m_url);
+
+ if (Frame* frame = document()->frame()) {
+ KURL completedURL = frame->loader()->completeURL(m_url);
+ return frame->loader()->client()->objectContentType(completedURL, m_serviceType) == ObjectContentImage;
+ }
+
+ return Image::supportsType(m_serviceType);
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/HTMLPlugInImageElement.h b/WebCore/html/HTMLPlugInImageElement.h
new file mode 100644
index 0000000..ec3b258
--- /dev/null
+++ b/WebCore/html/HTMLPlugInImageElement.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 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 HTMLPlugInImageElement_h
+#define HTMLPlugInImageElement_h
+
+#include "HTMLPlugInElement.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class HTMLImageLoader;
+
+class HTMLPlugInImageElement : public HTMLPlugInElement {
+public:
+ HTMLPlugInImageElement(const QualifiedName& tagName, Document*);
+ virtual ~HTMLPlugInImageElement();
+
+ bool isImageType();
+
+ const String& serviceType() const { return m_serviceType; }
+ const String& url() const { return m_url; }
+
+protected:
+ OwnPtr<HTMLImageLoader> m_imageLoader;
+ String m_serviceType;
+ String m_url;
+};
+
+} // namespace WebCore
+
+#endif // HTMLPlugInImageElement_h
diff --git a/WebCore/html/HTMLPreElement.cpp b/WebCore/html/HTMLPreElement.cpp
index 5597e7f..23ecaaa 100644
--- a/WebCore/html/HTMLPreElement.cpp
+++ b/WebCore/html/HTMLPreElement.cpp
@@ -55,7 +55,7 @@ void HTMLPreElement::parseMappedAttribute(MappedAttribute *attr)
// property.
} else if (attr->name() == wrapAttr) {
if (!attr->value().isNull())
- addCSSProperty(attr, CSS_PROP_WHITE_SPACE, CSS_VAL_PRE_WRAP);
+ addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValuePreWrap);
} else
return HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLScriptElement.cpp b/WebCore/html/HTMLScriptElement.cpp
index 9857c1f..ce334d7 100644
--- a/WebCore/html/HTMLScriptElement.cpp
+++ b/WebCore/html/HTMLScriptElement.cpp
@@ -1,10 +1,8 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc.
+ * 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
@@ -21,253 +19,98 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#include "config.h"
#include "HTMLScriptElement.h"
-#include "CachedScript.h"
-#include "DocLoader.h"
#include "Document.h"
#include "EventNames.h"
-#include "Frame.h"
-#include "FrameLoader.h"
#include "HTMLNames.h"
-#include "kjs_proxy.h"
-#include "MIMETypeRegistry.h"
#include "Text.h"
namespace WebCore {
using namespace HTMLNames;
-using namespace EventNames;
-HTMLScriptElement::HTMLScriptElement(Document *doc)
+HTMLScriptElement::HTMLScriptElement(Document* doc)
: HTMLElement(scriptTag, doc)
- , m_cachedScript(0)
- , m_createdByParser(false)
- , m_evaluated(false)
+ , m_data(this, this)
{
}
HTMLScriptElement::~HTMLScriptElement()
{
- if (m_cachedScript)
- m_cachedScript->deref(this);
}
-bool HTMLScriptElement::isURLAttribute(Attribute *attr) const
+bool HTMLScriptElement::isURLAttribute(Attribute* attr) const
+{
+ return attr->name() == sourceAttributeValue();
+}
+
+void HTMLScriptElement::setCreatedByParser(bool createdByParser)
{
- return attr->name() == srcAttr;
+ m_data.setCreatedByParser(createdByParser);
}
-void HTMLScriptElement::childrenChanged(bool changedByParser)
+bool HTMLScriptElement::shouldExecuteAsJavaScript() const
{
- // If a node is inserted as a child of the script element
- // and the script element has been inserted in the document
- // we evaluate the script.
- if (!m_createdByParser && inDocument() && firstChild())
- evaluateScript(document()->url(), text());
- HTMLElement::childrenChanged(changedByParser);
+ return m_data.shouldExecuteAsJavaScript();
}
-void HTMLScriptElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ ScriptElement::childrenChanged(m_data);
+ HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+}
+
+void HTMLScriptElement::parseMappedAttribute(MappedAttribute* attr)
{
const QualifiedName& attrName = attr->name();
- if (attrName == srcAttr) {
- if (m_evaluated || m_cachedScript || m_createdByParser || !inDocument())
- return;
-
- // FIXME: Evaluate scripts in viewless documents.
- // See http://bugs.webkit.org/show_bug.cgi?id=5727
- if (!document()->frame())
- return;
-
- const AtomicString& url = attr->value();
- if (!url.isEmpty()) {
- m_cachedScript = document()->docLoader()->requestScript(url, getAttribute(charsetAttr));
- if (m_cachedScript)
- m_cachedScript->ref(this);
- else
- dispatchHTMLEvent(errorEvent, true, false);
- }
- } else if (attrName == onloadAttr)
- setHTMLEventListener(loadEvent, attr);
+
+ if (attrName == srcAttr)
+ handleSourceAttribute(m_data, attr->value());
+ else if (attrName == onloadAttr)
+ setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr);
else
HTMLElement::parseMappedAttribute(attr);
}
void HTMLScriptElement::finishParsingChildren()
{
- // The parser just reached </script>. If we have no src and no text,
- // allow dynamic loading later.
- if (getAttribute(srcAttr).isEmpty() && text().isEmpty())
- setCreatedByParser(false);
+ ScriptElement::finishParsingChildren(m_data, sourceAttributeValue());
HTMLElement::finishParsingChildren();
}
void HTMLScriptElement::insertedIntoDocument()
{
HTMLElement::insertedIntoDocument();
-
- ASSERT(!m_cachedScript);
-
- if (m_createdByParser)
- return;
-
- // FIXME: Eventually we'd like to evaluate scripts which are inserted into a
- // viewless document but this'll do for now.
- // See http://bugs.webkit.org/show_bug.cgi?id=5727
- if (!document()->frame())
- return;
-
- const AtomicString& url = getAttribute(srcAttr);
- if (!url.isEmpty()) {
- String scriptSrcCharset = getAttribute(charsetAttr).domString().stripWhiteSpace();
- if (scriptSrcCharset.isEmpty()) {
- if (Frame* frame = document()->frame())
- scriptSrcCharset = frame->loader()->encoding();
- }
- m_cachedScript = document()->docLoader()->requestScript(url, scriptSrcCharset);
- if (m_cachedScript)
- m_cachedScript->ref(this);
- else
- dispatchHTMLEvent(errorEvent, true, false);
- return;
- }
-
- // If there's an empty script node, we shouldn't evaluate the script
- // because if a script is inserted afterwards (by setting text or innerText)
- // it should be evaluated, and evaluateScript only evaluates a script once.
- String scriptString = text();
- if (!scriptString.isEmpty())
- evaluateScript(document()->url(), scriptString);
+ ScriptElement::insertedIntoDocument(m_data, sourceAttributeValue());
}
void HTMLScriptElement::removedFromDocument()
{
HTMLElement::removedFromDocument();
-
- if (m_cachedScript) {
- m_cachedScript->deref(this);
- m_cachedScript = 0;
- }
-}
-
-void HTMLScriptElement::notifyFinished(CachedResource* o)
-{
- CachedScript *cs = static_cast<CachedScript *>(o);
-
- ASSERT(cs == m_cachedScript);
-
- // Evaluating the script could lead to a garbage collection which
- // can delete the script element so we need to protect it.
- RefPtr<HTMLScriptElement> protect(this);
-
- if (cs->errorOccurred())
- dispatchHTMLEvent(errorEvent, true, false);
- else {
- evaluateScript(cs->url(), cs->script());
- dispatchHTMLEvent(loadEvent, false, false);
- }
-
- // script evaluation may have dereffed it already
- if (m_cachedScript) {
- m_cachedScript->deref(this);
- m_cachedScript = 0;
- }
-}
-
-bool HTMLScriptElement::shouldExecuteAsJavaScript()
-{
- /*
- Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts only javascript1.1 - javascript1.3.
- Mozilla 1.8 and WinIE 7 both accept javascript and livescript.
- WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't.
- Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace.
- We want to accept all the values that either of these browsers accept, but not other values.
- */
- static const AtomicString validLanguages[] = {
- "javascript",
- "javascript1.0",
- "javascript1.1",
- "javascript1.2",
- "javascript1.3",
- "javascript1.4",
- "javascript1.5",
- "javascript1.6",
- "javascript1.7",
- "livescript",
- "ecmascript",
- "jscript"
- };
- static const unsigned validLanguagesCount = sizeof(validLanguages) / sizeof(validLanguages[0]);
-
- const AtomicString& type = getAttribute(typeAttr);
- if (!type.isEmpty()) {
- String lowerType = type.domString().stripWhiteSpace().lower();
- if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(lowerType))
- return true;
-
- return false;
- }
-
- const AtomicString& language = getAttribute(languageAttr);
- if (!language.isEmpty()) {
- String lowerLanguage = language.domString().lower();
- for (unsigned i = 0; i < validLanguagesCount; ++i)
- if (lowerLanguage == validLanguages[i])
- return true;
-
- return false;
- }
-
- // No type or language is specified, so we assume the script to be JavaScript
- return true;
-}
-
-void HTMLScriptElement::evaluateScript(const String& url, const String& script)
-{
- if (m_evaluated)
- return;
-
- if (!shouldExecuteAsJavaScript())
- return;
-
- Frame* frame = document()->frame();
- if (frame) {
- if (frame->scriptProxy()->isEnabled()) {
- m_evaluated = true;
- frame->scriptProxy()->evaluate(url, 0, script);
- Document::updateDocumentsRendering();
- }
- }
+ ScriptElement::removedFromDocument(m_data);
}
String HTMLScriptElement::text() const
{
- String val = "";
-
- for (Node *n = firstChild(); n; n = n->nextSibling()) {
- if (n->isTextNode())
- val += static_cast<Text *>(n)->data();
- }
-
- return val;
+ return m_data.scriptContent();
}
void HTMLScriptElement::setText(const String &value)
{
ExceptionCode ec = 0;
int numChildren = childNodeCount();
-
+
if (numChildren == 1 && firstChild()->isTextNode()) {
- static_cast<Text *>(firstChild())->setData(value, ec);
+ static_cast<Text*>(firstChild())->setData(value, ec);
return;
}
-
- if (numChildren > 0) {
+
+ if (numChildren > 0)
removeChildren();
- }
-
+
appendChild(document()->createTextNode(value.impl()), ec);
}
@@ -277,7 +120,7 @@ String HTMLScriptElement::htmlFor() const
return String();
}
-void HTMLScriptElement::setHtmlFor(const String &/*value*/)
+void HTMLScriptElement::setHtmlFor(const String&)
{
// DOM Level 1 says: reserved for future use.
}
@@ -288,14 +131,14 @@ String HTMLScriptElement::event() const
return String();
}
-void HTMLScriptElement::setEvent(const String &/*value*/)
+void HTMLScriptElement::setEvent(const String&)
{
// DOM Level 1 says: reserved for future use.
}
String HTMLScriptElement::charset() const
{
- return getAttribute(charsetAttr);
+ return charsetAttributeValue();
}
void HTMLScriptElement::setCharset(const String &value)
@@ -313,9 +156,9 @@ void HTMLScriptElement::setDefer(bool defer)
setAttribute(deferAttr, defer ? "" : 0);
}
-String HTMLScriptElement::src() const
+KURL HTMLScriptElement::src() const
{
- return document()->completeURL(getAttribute(srcAttr));
+ return document()->completeURL(sourceAttributeValue());
}
void HTMLScriptElement::setSrc(const String &value)
@@ -325,7 +168,7 @@ void HTMLScriptElement::setSrc(const String &value)
String HTMLScriptElement::type() const
{
- return getAttribute(typeAttr);
+ return typeAttributeValue();
}
void HTMLScriptElement::setType(const String &value)
@@ -333,4 +176,52 @@ void HTMLScriptElement::setType(const String &value)
setAttribute(typeAttr, value);
}
+String HTMLScriptElement::scriptCharset() const
+{
+ return m_data.scriptCharset();
+}
+
+String HTMLScriptElement::scriptContent() const
+{
+ return m_data.scriptContent();
+}
+
+void HTMLScriptElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ urls.append(src().string());
+}
+
+String HTMLScriptElement::sourceAttributeValue() const
+{
+ return getAttribute(srcAttr).string();
+}
+
+String HTMLScriptElement::charsetAttributeValue() const
+{
+ return getAttribute(charsetAttr).string();
+}
+
+String HTMLScriptElement::typeAttributeValue() const
+{
+ return getAttribute(typeAttr).string();
+}
+
+String HTMLScriptElement::languageAttributeValue() const
+{
+ return getAttribute(languageAttr).string();
+}
+
+void HTMLScriptElement::dispatchLoadEvent()
+{
+ ASSERT(!m_data.haveFiredLoadEvent());
+ m_data.setHaveFiredLoadEvent(true);
+
+ dispatchEventForType(eventNames().loadEvent, false, false);
+}
+
+void HTMLScriptElement::dispatchErrorEvent()
+{
+ dispatchEventForType(eventNames().errorEvent, true, false);
+}
+
}
diff --git a/WebCore/html/HTMLScriptElement.h b/WebCore/html/HTMLScriptElement.h
index 1bf7d7e..aa5b7d9 100644
--- a/WebCore/html/HTMLScriptElement.h
+++ b/WebCore/html/HTMLScriptElement.h
@@ -1,7 +1,8 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,18 +24,21 @@
#ifndef HTMLScriptElement_h
#define HTMLScriptElement_h
-#include "CachedResourceClient.h"
+#include "ScriptElement.h"
#include "HTMLElement.h"
namespace WebCore {
-class CachedScript;
-
-class HTMLScriptElement : public HTMLElement, public CachedResourceClient {
+class HTMLScriptElement : public HTMLElement
+ , public ScriptElement {
public:
HTMLScriptElement(Document*);
~HTMLScriptElement();
+ void setCreatedByParser(bool);
+ bool shouldExecuteAsJavaScript() const;
+ virtual String scriptContent() const;
+
virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
virtual int tagPriority() const { return 1; }
virtual bool checkDTD(const Node* newChild) { return newChild->isTextNode(); }
@@ -42,18 +46,11 @@ public:
virtual void parseMappedAttribute(MappedAttribute*);
virtual void insertedIntoDocument();
virtual void removedFromDocument();
- virtual void notifyFinished(CachedResource*);
-
- virtual void childrenChanged(bool changedByParser = false);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual bool isURLAttribute(Attribute*) const;
-
- void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; }
virtual void finishParsingChildren();
- bool shouldExecuteAsJavaScript();
- void evaluateScript(const String& url, const String& script);
-
String text() const;
void setText(const String&);
@@ -69,16 +66,27 @@ public:
bool defer() const;
void setDefer(bool);
- String src() const;
+ KURL src() const;
void setSrc(const String&);
String type() const;
void setType(const String&);
+ virtual String scriptCharset() const;
+
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
+protected:
+ virtual String sourceAttributeValue() const;
+ virtual String charsetAttributeValue() const;
+ virtual String typeAttributeValue() const;
+ virtual String languageAttributeValue() const;
+
+ virtual void dispatchLoadEvent();
+ virtual void dispatchErrorEvent();
+
private:
- CachedScript* m_cachedScript;
- bool m_createdByParser;
- bool m_evaluated;
+ ScriptElementData m_data;
};
} //namespace
diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp
index 115e473..44e7fe4 100644
--- a/WebCore/html/HTMLSelectElement.cpp
+++ b/WebCore/html/HTMLSelectElement.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "HTMLSelectElement.h"
+#include "AXObjectCache.h"
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "CharacterNames.h"
@@ -57,7 +58,6 @@ using namespace Unicode;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
static const DOMTimeStamp typeAheadTimeout = 1000;
@@ -301,17 +301,17 @@ void HTMLSelectElement::restoreState(const String& state)
setChanged();
}
-bool HTMLSelectElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec)
+bool HTMLSelectElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
{
- bool result = HTMLFormControlElementWithState::insertBefore(newChild, refChild, ec);
+ bool result = HTMLFormControlElementWithState::insertBefore(newChild, refChild, ec, shouldLazyAttach);
if (result)
setRecalcListItems();
return result;
}
-bool HTMLSelectElement::replaceChild(PassRefPtr<Node> newChild, Node *oldChild, ExceptionCode& ec)
+bool HTMLSelectElement::replaceChild(PassRefPtr<Node> newChild, Node *oldChild, ExceptionCode& ec, bool shouldLazyAttach)
{
- bool result = HTMLFormControlElementWithState::replaceChild(newChild, oldChild, ec);
+ bool result = HTMLFormControlElementWithState::replaceChild(newChild, oldChild, ec, shouldLazyAttach);
if (result)
setRecalcListItems();
return result;
@@ -325,9 +325,9 @@ bool HTMLSelectElement::removeChild(Node* oldChild, ExceptionCode& ec)
return result;
}
-bool HTMLSelectElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
+bool HTMLSelectElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
{
- bool result = HTMLFormControlElementWithState::appendChild(newChild, ec);
+ bool result = HTMLFormControlElementWithState::appendChild(newChild, ec, shouldLazyAttach);
if (result)
setRecalcListItems();
return result;
@@ -373,11 +373,11 @@ void HTMLSelectElement::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=12072
} else if (attr->name() == onfocusAttr) {
- setHTMLEventListener(focusEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
} else if (attr->name() == onblurAttr) {
- setHTMLEventListener(blurEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
} else if (attr->name() == onchangeAttr) {
- setHTMLEventListener(changeEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().changeEvent, attr);
} else
HTMLFormControlElementWithState::parseMappedAttribute(attr);
}
@@ -491,7 +491,7 @@ int HTMLSelectElement::listToOptionIndex(int listIndex) const
PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
{
- return new HTMLOptionsCollection(this);
+ return HTMLOptionsCollection::create(this);
}
void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
@@ -529,10 +529,13 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
m_recalcListItems = false;
}
-void HTMLSelectElement::childrenChanged(bool changedByParser)
+void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
setRecalcListItems();
- HTMLFormControlElementWithState::childrenChanged(changedByParser);
+ HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+
+ if (AXObjectCache::accessibilityEnabled() && renderer())
+ renderer()->document()->axObjectCache()->childrenChanged(renderer());
}
void HTMLSelectElement::setRecalcListItems()
@@ -605,7 +608,7 @@ void HTMLSelectElement::defaultEventHandler(Event* evt)
if (evt->defaultHandled())
return;
- if (evt->type() == keypressEvent && evt->isKeyboardEvent()) {
+ if (evt->type() == eventNames().keypressEvent && evt->isKeyboardEvent()) {
KeyboardEvent* keyboardEvent = static_cast<KeyboardEvent*>(evt);
if (!keyboardEvent->ctrlKey() && !keyboardEvent->altKey() && !keyboardEvent->metaKey() &&
@@ -623,7 +626,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
{
RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer());
- if (evt->type() == keydownEvent) {
+ if (evt->type() == eventNames().keydownEvent) {
if (!renderer() || !evt->isKeyboardEvent())
return;
String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
@@ -648,7 +651,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
int size = listItems().size();
for (listIndex += 1;
listIndex >= 0 && listIndex < size && (listItems()[listIndex]->disabled() || !listItems()[listIndex]->hasTagName(optionTag));
- ++listIndex);
+ ++listIndex) { }
if (listIndex >= 0 && listIndex < size)
setSelectedIndex(listToOptionIndex(listIndex));
@@ -657,7 +660,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
int size = listItems().size();
for (listIndex -= 1;
listIndex >= 0 && listIndex < size && (listItems()[listIndex]->disabled() || !listItems()[listIndex]->hasTagName(optionTag));
- --listIndex);
+ --listIndex) { }
if (listIndex >= 0 && listIndex < size)
setSelectedIndex(listToOptionIndex(listIndex));
@@ -670,7 +673,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
// 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() == keypressEvent) {
+ if (evt->type() == eventNames().keypressEvent) {
if (!renderer() || !evt->isKeyboardEvent())
return;
int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode();
@@ -702,7 +705,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
evt->setDefaultHandled();
}
- if (evt->type() == mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
+ if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
focus();
if (menuList->popupIsVisible())
menuList->hidePopup();
@@ -718,7 +721,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt)
{
- if (evt->type() == mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
+ if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
focus();
MouseEvent* mEvt = static_cast<MouseEvent*>(evt);
@@ -778,10 +781,10 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt)
evt->setDefaultHandled();
}
- } else if (evt->type() == mouseupEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer())
+ } 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() == keydownEvent) {
+ else if (evt->type() == eventNames().keydownEvent) {
if (!evt->isKeyboardEvent())
return;
String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
@@ -822,7 +825,7 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt)
listBoxOnChange();
evt->setDefaultHandled();
}
- } else if (evt->type() == keypressEvent) {
+ } else if (evt->type() == eventNames().keypressEvent) {
if (!evt->isKeyboardEvent())
return;
int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode();
@@ -981,13 +984,17 @@ void HTMLSelectElement::typeAheadFind(KeyboardEvent* event)
if (itemCount < 1)
return;
- int index = (optionToListIndex(selectedIndex()) + searchStartOffset) % itemCount;
+ 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;
if (stripLeadingWhiteSpace(static_cast<HTMLOptionElement*>(items[index])->optionText()).startsWith(prefix, false)) {
setSelectedIndex(listToOptionIndex(index));
+ if(!usesMenuList())
+ listBoxOnChange();
setChanged();
return;
}
@@ -1024,6 +1031,26 @@ void HTMLSelectElement::accessKeyAction(bool sendToAnyElement)
dispatchSimulatedClick(0, 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();
+}
+
void HTMLSelectElement::setMultiple(bool multiple)
{
setAttribute(multipleAttr, multiple ? "" : 0);
diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h
index ea8e990..0b438ab 100644
--- a/WebCore/html/HTMLSelectElement.h
+++ b/WebCore/html/HTMLSelectElement.h
@@ -26,7 +26,7 @@
#include "Event.h"
#include "HTMLCollection.h"
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
#include <wtf/Vector.h>
namespace WebCore {
@@ -82,12 +82,12 @@ public:
virtual bool saveState(String& value) const;
virtual void restoreState(const String&);
- virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&);
- virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&);
+ virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
+ virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
virtual bool removeChild(Node* child, ExceptionCode&);
- virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&);
+ virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
virtual bool removeChildren();
- virtual void childrenChanged(bool changedByParser = false);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual void parseMappedAttribute(MappedAttribute*);
@@ -113,6 +113,7 @@ public:
virtual void defaultEventHandler(Event*);
virtual void accessKeyAction(bool sendToAnyElement);
+ void accessKeySetSelectedIndex(int);
void setMultiple(bool);
diff --git a/WebCore/html/HTMLSelectElement.idl b/WebCore/html/HTMLSelectElement.idl
index e154ace..d3e85a8 100644
--- a/WebCore/html/HTMLSelectElement.idl
+++ b/WebCore/html/HTMLSelectElement.idl
@@ -41,15 +41,16 @@ module html {
#endif
readonly attribute HTMLFormElement form;
+ readonly attribute boolean willValidate;
// Modified in DOM Level 2:
readonly attribute HTMLOptionsCollection options;
attribute boolean disabled;
+ attribute boolean autofocus;
attribute boolean multiple;
attribute [ConvertNullToNullString] DOMString name;
attribute long size;
- attribute long tabIndex;
[OldStyleObjC] void add(in HTMLElement element,
in HTMLElement before)
@@ -61,8 +62,6 @@ module html {
#else
void remove(in long index);
#endif
- void blur();
- void focus();
// These methods are not in DOM Level 2 IDL, but are mentioned in the standard:
// "The contained options can be directly accessed through the select element as a collection."
diff --git a/WebCore/html/HTMLSourceElement.cpp b/WebCore/html/HTMLSourceElement.cpp
index 66f7305..86af4e4 100644
--- a/WebCore/html/HTMLSourceElement.cpp
+++ b/WebCore/html/HTMLSourceElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
#include "HTMLDocument.h"
#include "HTMLMediaElement.h"
+#include "HTMLNames.h"
using namespace std;
@@ -56,7 +57,7 @@ void HTMLSourceElement::insertedIntoDocument()
}
}
-String HTMLSourceElement::src() const
+KURL HTMLSourceElement::src() const
{
return document()->completeURL(getAttribute(srcAttr));
}
diff --git a/WebCore/html/HTMLSourceElement.h b/WebCore/html/HTMLSourceElement.h
index e47411a..8187877 100644
--- a/WebCore/html/HTMLSourceElement.h
+++ b/WebCore/html/HTMLSourceElement.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,15 +29,12 @@
#if ENABLE(VIDEO)
#include "HTMLElement.h"
-#include "HTMLNames.h"
#include <limits>
namespace WebCore {
-using namespace HTMLNames;
-
-class MediaError;
-
+class KURL;
+
class HTMLSourceElement : public HTMLElement {
public:
HTMLSourceElement(Document*);
@@ -48,7 +45,7 @@ public:
virtual void insertedIntoDocument();
- String src() const;
+ KURL src() const;
String media() const;
String type() const;
void setSrc(const String&);
diff --git a/WebCore/html/HTMLStyleElement.cpp b/WebCore/html/HTMLStyleElement.cpp
index 67eb1cc..dd00db6 100644
--- a/WebCore/html/HTMLStyleElement.cpp
+++ b/WebCore/html/HTMLStyleElement.cpp
@@ -43,7 +43,7 @@ HTMLStyleElement::HTMLStyleElement(Document* doc)
void HTMLStyleElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == mediaAttr)
- m_media = attr->value().domString().lower();
+ m_media = attr->value().string().lower();
else if (attr->name() == titleAttr && m_sheet)
m_sheet->setTitle(attr->value());
else
@@ -52,6 +52,7 @@ void HTMLStyleElement::parseMappedAttribute(MappedAttribute *attr)
void HTMLStyleElement::finishParsingChildren()
{
+ StyleElement::process(this);
StyleElement::sheet(this);
m_createdByParser = false;
HTMLElement::finishParsingChildren();
@@ -61,6 +62,7 @@ void HTMLStyleElement::insertedIntoDocument()
{
HTMLElement::insertedIntoDocument();
+ document()->addStyleSheetCandidateNode(this, m_createdByParser);
if (!m_createdByParser)
StyleElement::insertedIntoDocument(document(), this);
}
@@ -68,13 +70,16 @@ void HTMLStyleElement::insertedIntoDocument()
void HTMLStyleElement::removedFromDocument()
{
HTMLElement::removedFromDocument();
+ if (document()->renderer())
+ document()->removeStyleSheetCandidateNode(this);
StyleElement::removedFromDocument(document());
}
-void HTMLStyleElement::childrenChanged(bool changedByParser)
+void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
- StyleElement::process(this);
- HTMLElement::childrenChanged(changedByParser);
+ if (!changedByParser)
+ StyleElement::process(this);
+ HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
StyleSheet* HTMLStyleElement::sheet()
@@ -130,4 +135,16 @@ void HTMLStyleElement::setType(const AtomicString &value)
setAttribute(typeAttr, value);
}
+void HTMLStyleElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ HashSet<String> styleURLs;
+ StyleSheet* styleSheet = const_cast<HTMLStyleElement*>(this)->sheet();
+ if (styleSheet)
+ styleSheet->addSubresourceURLStrings(styleURLs, ownerDocument()->baseURL());
+
+ HashSet<String>::iterator end = styleURLs.end();
+ for (HashSet<String>::iterator i = styleURLs.begin(); i != end; ++i)
+ urls.append(*i);
+}
+
}
diff --git a/WebCore/html/HTMLStyleElement.h b/WebCore/html/HTMLStyleElement.h
index 05909d6..a85916f 100644
--- a/WebCore/html/HTMLStyleElement.h
+++ b/WebCore/html/HTMLStyleElement.h
@@ -43,7 +43,7 @@ public:
virtual void parseMappedAttribute(MappedAttribute*);
virtual void insertedIntoDocument();
virtual void removedFromDocument();
- virtual void childrenChanged(bool changedByParser = false);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; }
virtual void finishParsingChildren();
@@ -64,6 +64,8 @@ public:
virtual void setLoading(bool loading) { m_loading = loading; }
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
protected:
String m_media;
bool m_loading;
diff --git a/WebCore/html/HTMLTableCaptionElement.cpp b/WebCore/html/HTMLTableCaptionElement.cpp
index 7bc190e..b6c9c73 100644
--- a/WebCore/html/HTMLTableCaptionElement.cpp
+++ b/WebCore/html/HTMLTableCaptionElement.cpp
@@ -52,7 +52,7 @@ void HTMLTableCaptionElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == alignAttr) {
if (!attr->value().isEmpty())
- addCSSProperty(attr, CSS_PROP_CAPTION_SIDE, attr->value());
+ addCSSProperty(attr, CSSPropertyCaptionSide, attr->value());
} else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLTableCellElement.cpp b/WebCore/html/HTMLTableCellElement.cpp
index 29ec6c4..3395d23 100644
--- a/WebCore/html/HTMLTableCellElement.cpp
+++ b/WebCore/html/HTMLTableCellElement.cpp
@@ -106,18 +106,18 @@ void HTMLTableCellElement::parseMappedAttribute(MappedAttribute *attr)
if (!(document()->frame()) || document()->frame()->settings()->layoutAlgorithm() != Settings::kLayoutSSR)
#endif
if (!attr->isNull())
- addCSSProperty(attr, CSS_PROP_WHITE_SPACE, CSS_VAL__WEBKIT_NOWRAP);
+ addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValueWebkitNowrap);
} else if (attr->name() == widthAttr) {
if (!attr->value().isEmpty()) {
int widthInt = attr->value().toInt();
if (widthInt > 0) // width="0" is ignored for compatibility with WinIE.
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
}
} else if (attr->name() == heightAttr) {
if (!attr->value().isEmpty()) {
int heightInt = attr->value().toInt();
if (heightInt > 0) // height="0" is ignored for compatibility with WinIE.
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
}
} else
HTMLTablePartElement::parseMappedAttribute(attr);
@@ -269,4 +269,9 @@ void HTMLTableCellElement::setWidth(const String &value)
setAttribute(widthAttr, value);
}
+void HTMLTableCellElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ urls.append(getAttribute(HTMLNames::backgroundAttr).string());
+}
+
}
diff --git a/WebCore/html/HTMLTableCellElement.h b/WebCore/html/HTMLTableCellElement.h
index 1099857..6ac4b29 100644
--- a/WebCore/html/HTMLTableCellElement.h
+++ b/WebCore/html/HTMLTableCellElement.h
@@ -102,6 +102,8 @@ public:
String width() const;
void setWidth(const String&);
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
protected:
int _row;
int _col;
diff --git a/WebCore/html/HTMLTableColElement.cpp b/WebCore/html/HTMLTableColElement.cpp
index 6192ca2..11f6df6 100644
--- a/WebCore/html/HTMLTableColElement.cpp
+++ b/WebCore/html/HTMLTableColElement.cpp
@@ -80,7 +80,7 @@ void HTMLTableColElement::parseMappedAttribute(MappedAttribute *attr)
static_cast<RenderTableCol*>(renderer())->updateFromElement();
} else if (attr->name() == widthAttr) {
if (!attr->value().isEmpty())
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
} else
HTMLTablePartElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLTableElement.cpp b/WebCore/html/HTMLTableElement.cpp
index 92f2b54..ed5c577 100644
--- a/WebCore/html/HTMLTableElement.cpp
+++ b/WebCore/html/HTMLTableElement.cpp
@@ -320,13 +320,13 @@ void HTMLTableElement::parseMappedAttribute(MappedAttribute* attr)
unsigned short oldPadding = m_padding;
if (attr->name() == widthAttr)
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
else if (attr->name() == heightAttr)
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
else if (attr->name() == borderAttr) {
m_borderAttr = true;
if (attr->decl()) {
- RefPtr<CSSValue> val = attr->decl()->getPropertyCSSValue(CSS_PROP_BORDER_LEFT_WIDTH);
+ RefPtr<CSSValue> val = attr->decl()->getPropertyCSSValue(CSSPropertyBorderLeftWidth);
if (val && val->isPrimitiveValue()) {
CSSPrimitiveValue* primVal = static_cast<CSSPrimitiveValue*>(val.get());
m_borderAttr = primVal->getDoubleValue(CSSPrimitiveValue::CSS_NUMBER);
@@ -338,20 +338,20 @@ void HTMLTableElement::parseMappedAttribute(MappedAttribute* attr)
else
border = attr->value().toInt();
m_borderAttr = border;
- addCSSLength(attr, CSS_PROP_BORDER_WIDTH, String::number(border));
+ addCSSLength(attr, CSSPropertyBorderWidth, String::number(border));
}
} else if (attr->name() == bgcolorAttr)
- addCSSColor(attr, CSS_PROP_BACKGROUND_COLOR, attr->value());
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
else if (attr->name() == bordercolorAttr) {
m_borderColorAttr = attr->decl();
if (!attr->decl() && !attr->isEmpty()) {
- addCSSColor(attr, CSS_PROP_BORDER_COLOR, attr->value());
+ addCSSColor(attr, CSSPropertyBorderColor, attr->value());
m_borderColorAttr = true;
}
} else if (attr->name() == backgroundAttr) {
String url = parseURL(attr->value());
if (!url.isEmpty())
- addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, document()->completeURL(url));
+ addCSSImageProperty(attr, CSSPropertyBackgroundImage, document()->completeURL(url).string());
} else if (attr->name() == frameAttr) {
// Cache the value of "frame" so that the table can examine it later.
m_frameAttr = false;
@@ -392,14 +392,14 @@ void HTMLTableElement::parseMappedAttribute(MappedAttribute* attr)
// Now map in the border styles of solid and hidden respectively.
if (m_frameAttr) {
- addCSSProperty(attr, CSS_PROP_BORDER_TOP_WIDTH, CSS_VAL_THIN);
- addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_VAL_THIN);
- addCSSProperty(attr, CSS_PROP_BORDER_LEFT_WIDTH, CSS_VAL_THIN);
- addCSSProperty(attr, CSS_PROP_BORDER_RIGHT_WIDTH, CSS_VAL_THIN);
- addCSSProperty(attr, CSS_PROP_BORDER_TOP_STYLE, borders[cTop] ? CSS_VAL_SOLID : CSS_VAL_HIDDEN);
- addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_STYLE, borders[cBottom] ? CSS_VAL_SOLID : CSS_VAL_HIDDEN);
- addCSSProperty(attr, CSS_PROP_BORDER_LEFT_STYLE, borders[cLeft] ? CSS_VAL_SOLID : CSS_VAL_HIDDEN);
- addCSSProperty(attr, CSS_PROP_BORDER_RIGHT_STYLE, borders[cRight] ? CSS_VAL_SOLID : CSS_VAL_HIDDEN);
+ addCSSProperty(attr, CSSPropertyBorderTopWidth, CSSValueThin);
+ addCSSProperty(attr, CSSPropertyBorderBottomWidth, CSSValueThin);
+ addCSSProperty(attr, CSSPropertyBorderLeftWidth, CSSValueThin);
+ addCSSProperty(attr, CSSPropertyBorderRightWidth, CSSValueThin);
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, borders[cTop] ? CSSValueSolid : CSSValueHidden);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, borders[cBottom] ? CSSValueSolid : CSSValueHidden);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, borders[cLeft] ? CSSValueSolid : CSSValueHidden);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, borders[cRight] ? CSSValueSolid : CSSValueHidden);
}
} else if (attr->name() == rulesAttr) {
m_rulesAttr = UnsetRules;
@@ -416,10 +416,10 @@ void HTMLTableElement::parseMappedAttribute(MappedAttribute* attr)
// The presence of a valid rules attribute causes border collapsing to be enabled.
if (m_rulesAttr != UnsetRules)
- addCSSProperty(attr, CSS_PROP_BORDER_COLLAPSE, CSS_VAL_COLLAPSE);
+ addCSSProperty(attr, CSSPropertyBorderCollapse, CSSValueCollapse);
} else if (attr->name() == cellspacingAttr) {
if (!attr->value().isEmpty())
- addCSSLength(attr, CSS_PROP_BORDER_SPACING, attr->value());
+ addCSSLength(attr, CSSPropertyBorderSpacing, attr->value());
} else if (attr->name() == cellpaddingAttr) {
if (!attr->value().isEmpty())
m_padding = max(0, attr->value().toInt());
@@ -428,22 +428,22 @@ void HTMLTableElement::parseMappedAttribute(MappedAttribute* attr)
} else if (attr->name() == colsAttr) {
// ###
} else if (attr->name() == vspaceAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_TOP, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_BOTTOM, attr->value());
+ addCSSLength(attr, CSSPropertyMarginTop, attr->value());
+ addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
} else if (attr->name() == hspaceAttr) {
- addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value());
- addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
+ addCSSLength(attr, CSSPropertyMarginRight, attr->value());
} else if (attr->name() == alignAttr) {
if (!attr->value().isEmpty()) {
if (equalIgnoringCase(attr->value(), "center")) {
- addCSSProperty(attr, CSS_PROP_MARGIN_LEFT, CSS_VAL_AUTO);
- addCSSProperty(attr, CSS_PROP_MARGIN_RIGHT, CSS_VAL_AUTO);
+ addCSSProperty(attr, CSSPropertyMarginLeft, CSSValueAuto);
+ addCSSProperty(attr, CSSPropertyMarginRight, CSSValueAuto);
} else
- addCSSProperty(attr, CSS_PROP_FLOAT, attr->value());
+ addCSSProperty(attr, CSSPropertyFloat, attr->value());
}
} else if (attr->name() == valignAttr) {
if (!attr->value().isEmpty())
- addCSSProperty(attr, CSS_PROP_VERTICAL_ALIGN, attr->value());
+ addCSSProperty(attr, CSSPropertyVerticalAlign, attr->value());
} else
HTMLElement::parseMappedAttribute(attr);
@@ -462,27 +462,25 @@ void HTMLTableElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDecla
{
if ((!m_borderAttr && !m_borderColorAttr) || m_frameAttr)
return;
-
- MappedAttribute attr(tableborderAttr, m_borderColorAttr ? "solid" : "outset");
- CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, &attr);
+
+ AtomicString borderValue = m_borderColorAttr ? "solid" : "outset";
+ CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, tableborderAttr, borderValue);
if (!decl) {
- decl = new CSSMappedAttributeDeclaration(0);
+ decl = CSSMappedAttributeDeclaration::create().releaseRef(); // This single ref pins us in the table until the document dies.
decl->setParent(document()->elementSheet());
decl->setNode(this);
decl->setStrictParsing(false); // Mapped attributes are just always quirky.
- decl->ref(); // This single ref pins us in the table until the document dies.
-
- int v = m_borderColorAttr ? CSS_VAL_SOLID : CSS_VAL_OUTSET;
- decl->setProperty(CSS_PROP_BORDER_TOP_STYLE, v, false);
- decl->setProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v, false);
- decl->setProperty(CSS_PROP_BORDER_LEFT_STYLE, v, false);
- decl->setProperty(CSS_PROP_BORDER_RIGHT_STYLE, v, false);
+ int v = m_borderColorAttr ? CSSValueSolid : CSSValueOutset;
+ decl->setProperty(CSSPropertyBorderTopStyle, v, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, v, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, v, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, v, false);
- setMappedAttributeDecl(ePersistent, &attr, decl);
+ setMappedAttributeDecl(ePersistent, tableborderAttr, borderValue, decl);
decl->setParent(0);
decl->setNode(0);
- decl->setMappedState(ePersistent, attr.name(), attr.value());
+ decl->setMappedState(ePersistent, tableborderAttr, borderValue);
}
@@ -522,58 +520,55 @@ void HTMLTableElement::addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaratio
{
CellBorders borders = cellBorders();
- static AtomicString cellBorderNames[] = { "none", "solid", "inset", "solid-cols", "solid-rows" };
- MappedAttribute attr(cellborderAttr, cellBorderNames[borders]);
-
- CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, &attr);
+ static const AtomicString cellBorderNames[] = { "none", "solid", "inset", "solid-cols", "solid-rows" };
+ const AtomicString& cellborderValue = cellBorderNames[borders];
+ CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, cellborderAttr, cellborderValue);
if (!decl) {
- decl = new CSSMappedAttributeDeclaration(0);
+ decl = CSSMappedAttributeDeclaration::create().releaseRef(); // This single ref pins us in the table until the document dies.
decl->setParent(document()->elementSheet());
decl->setNode(this);
decl->setStrictParsing(false); // Mapped attributes are just always quirky.
- decl->ref(); // This single ref pins us in the table until the document dies.
-
switch (borders) {
case SolidBordersColsOnly:
- decl->setProperty(CSS_PROP_BORDER_LEFT_WIDTH, CSS_VAL_THIN, false);
- decl->setProperty(CSS_PROP_BORDER_RIGHT_WIDTH, CSS_VAL_THIN, false);
- decl->setProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_COLOR, "inherit", false);
+ decl->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderRightWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderColor, "inherit", false);
break;
case SolidBordersRowsOnly:
- decl->setProperty(CSS_PROP_BORDER_TOP_WIDTH, CSS_VAL_THIN, false);
- decl->setProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_VAL_THIN, false);
- decl->setProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_COLOR, "inherit", false);
+ decl->setProperty(CSSPropertyBorderTopWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderColor, "inherit", false);
break;
case SolidBorders:
- decl->setProperty(CSS_PROP_BORDER_WIDTH, "1px", false);
- decl->setProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_COLOR, "inherit", false);
+ decl->setProperty(CSSPropertyBorderWidth, "1px", false);
+ decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderColor, "inherit", false);
break;
case InsetBorders:
- decl->setProperty(CSS_PROP_BORDER_WIDTH, "1px", false);
- decl->setProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_INSET, false);
- decl->setProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_INSET, false);
- decl->setProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_INSET, false);
- decl->setProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_INSET, false);
- decl->setProperty(CSS_PROP_BORDER_COLOR, "inherit", false);
+ decl->setProperty(CSSPropertyBorderWidth, "1px", false);
+ decl->setProperty(CSSPropertyBorderTopStyle, CSSValueInset, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueInset, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueInset, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, CSSValueInset, false);
+ decl->setProperty(CSSPropertyBorderColor, "inherit", false);
break;
case NoBorders:
- decl->setProperty(CSS_PROP_BORDER_WIDTH, "0", false);
+ decl->setProperty(CSSPropertyBorderWidth, "0", false);
break;
}
- setMappedAttributeDecl(ePersistent, &attr, decl);
+ setMappedAttributeDecl(ePersistent, cellborderAttr, cellBorderNames[borders], decl);
decl->setParent(0);
decl->setNode(0);
- decl->setMappedState(ePersistent, attr.name(), attr.value());
+ decl->setMappedState(ePersistent, cellborderAttr, cellborderValue);
}
results.append(decl);
@@ -585,61 +580,57 @@ void HTMLTableElement::addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaratio
return;
if (!m_paddingDecl) {
- String numericStr = String::number(m_padding);
- MappedAttribute attr(cellpaddingAttr, numericStr);
- m_paddingDecl = getMappedAttributeDecl(eUniversal, &attr);
+ String paddingValue = String::number(m_padding);
+ m_paddingDecl = getMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue);
if (!m_paddingDecl) {
- m_paddingDecl = new CSSMappedAttributeDeclaration(0);
+ m_paddingDecl = CSSMappedAttributeDeclaration::create();
m_paddingDecl->setParent(document()->elementSheet());
m_paddingDecl->setNode(this);
m_paddingDecl->setStrictParsing(false); // Mapped attributes are just always quirky.
- m_paddingDecl->setProperty(CSS_PROP_PADDING_TOP, numericStr, false);
- m_paddingDecl->setProperty(CSS_PROP_PADDING_RIGHT, numericStr, false);
- m_paddingDecl->setProperty(CSS_PROP_PADDING_BOTTOM, numericStr, false);
- m_paddingDecl->setProperty(CSS_PROP_PADDING_LEFT, numericStr, false);
+ m_paddingDecl->setProperty(CSSPropertyPaddingTop, paddingValue, false);
+ m_paddingDecl->setProperty(CSSPropertyPaddingRight, paddingValue, false);
+ m_paddingDecl->setProperty(CSSPropertyPaddingBottom, paddingValue, false);
+ m_paddingDecl->setProperty(CSSPropertyPaddingLeft, paddingValue, false);
}
- setMappedAttributeDecl(eUniversal, &attr, m_paddingDecl.get());
+ setMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue, m_paddingDecl.get());
m_paddingDecl->setParent(0);
m_paddingDecl->setNode(0);
- m_paddingDecl->setMappedState(eUniversal, attr.name(), attr.value());
+ m_paddingDecl->setMappedState(eUniversal, cellpaddingAttr, paddingValue);
}
results.append(m_paddingDecl.get());
}
void HTMLTableElement::addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDeclaration*>& results)
-
{
if (m_rulesAttr != GroupsRules)
return;
- MappedAttribute attr(rulesAttr, rows ? "rowgroups" : "colgroups");
- CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, &attr);
+ AtomicString rulesValue = rows ? "rowgroups" : "colgroups";
+ CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, rulesAttr, rulesValue);
if (!decl) {
- decl = new CSSMappedAttributeDeclaration(0);
+ decl = CSSMappedAttributeDeclaration::create().releaseRef(); // This single ref pins us in the table until the document dies.
decl->setParent(document()->elementSheet());
decl->setNode(this);
decl->setStrictParsing(false); // Mapped attributes are just always quirky.
- decl->ref(); // This single ref pins us in the table until the document dies.
-
if (rows) {
- decl->setProperty(CSS_PROP_BORDER_TOP_WIDTH, CSS_VAL_THIN, false);
- decl->setProperty(CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_VAL_THIN, false);
- decl->setProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID, false);
+ decl->setProperty(CSSPropertyBorderTopWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
} else {
- decl->setProperty(CSS_PROP_BORDER_LEFT_WIDTH, CSS_VAL_THIN, false);
- decl->setProperty(CSS_PROP_BORDER_RIGHT_WIDTH, CSS_VAL_THIN, false);
- decl->setProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID, false);
- decl->setProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID, false);
+ decl->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderRightWidth, CSSValueThin, false);
+ decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
+ decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
}
- setMappedAttributeDecl(ePersistent, &attr, decl);
+ setMappedAttributeDecl(ePersistent, rulesAttr, rulesValue, decl);
decl->setParent(0);
decl->setNode(0);
- decl->setMappedState(ePersistent, attr.name(), attr.value());
+ decl->setMappedState(ePersistent, rulesAttr, rulesValue);
}
results.append(decl);
@@ -647,7 +638,7 @@ void HTMLTableElement::addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDecl
void HTMLTableElement::attach()
{
- ASSERT(!m_attached);
+ ASSERT(!attached());
HTMLElement::attach();
}
@@ -658,12 +649,12 @@ bool HTMLTableElement::isURLAttribute(Attribute *attr) const
PassRefPtr<HTMLCollection> HTMLTableElement::rows()
{
- return new HTMLTableRowsCollection(this);
+ return HTMLTableRowsCollection::create(this);
}
PassRefPtr<HTMLCollection> HTMLTableElement::tBodies()
{
- return new HTMLCollection(this, HTMLCollection::TableTBodies);
+ return HTMLCollection::create(this, HTMLCollection::TableTBodies);
}
String HTMLTableElement::align() const
@@ -756,4 +747,9 @@ void HTMLTableElement::setWidth(const String &value)
setAttribute(widthAttr, value);
}
+void HTMLTableElement::getSubresourceAttributeStrings(Vector<String>& urls) const
+{
+ urls.append(getAttribute(HTMLNames::backgroundAttr).string());
+}
+
}
diff --git a/WebCore/html/HTMLTableElement.h b/WebCore/html/HTMLTableElement.h
index 1a8df12..aced79e 100644
--- a/WebCore/html/HTMLTableElement.h
+++ b/WebCore/html/HTMLTableElement.h
@@ -103,6 +103,8 @@ public:
void addSharedCellDecls(Vector<CSSMutableStyleDeclaration*>&);
void addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDeclaration*>&);
+ virtual void getSubresourceAttributeStrings(Vector<String>&) const;
+
private:
void addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaration*>&);
void addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaration*>&);
diff --git a/WebCore/html/HTMLTablePartElement.cpp b/WebCore/html/HTMLTablePartElement.cpp
index 4070de9..6341197 100644
--- a/WebCore/html/HTMLTablePartElement.cpp
+++ b/WebCore/html/HTMLTablePartElement.cpp
@@ -62,37 +62,37 @@ bool HTMLTablePartElement::mapToEntry(const QualifiedName& attrName, MappedAttri
void HTMLTablePartElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == bgcolorAttr)
- addCSSColor(attr, CSS_PROP_BACKGROUND_COLOR, attr->value());
+ addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
else if (attr->name() == backgroundAttr) {
String url = parseURL(attr->value());
if (!url.isEmpty())
- addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, document()->completeURL(url));
+ addCSSImageProperty(attr, CSSPropertyBackgroundImage, document()->completeURL(url).string());
} else if (attr->name() == bordercolorAttr) {
if (!attr->value().isEmpty()) {
- addCSSColor(attr, CSS_PROP_BORDER_COLOR, attr->value());
- addCSSProperty(attr, CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
- addCSSProperty(attr, CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
+ addCSSColor(attr, CSSPropertyBorderColor, attr->value());
+ addCSSProperty(attr, CSSPropertyBorderTopStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderBottomStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderLeftStyle, CSSValueSolid);
+ addCSSProperty(attr, CSSPropertyBorderRightStyle, CSSValueSolid);
}
} else if (attr->name() == valignAttr) {
if (!attr->value().isEmpty())
- addCSSProperty(attr, CSS_PROP_VERTICAL_ALIGN, attr->value());
+ addCSSProperty(attr, CSSPropertyVerticalAlign, attr->value());
} else if (attr->name() == alignAttr) {
const AtomicString& v = attr->value();
if (equalIgnoringCase(v, "middle") || equalIgnoringCase(v, "center"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_CENTER);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitCenter);
else if (equalIgnoringCase(v, "absmiddle"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL_CENTER);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueCenter);
else if (equalIgnoringCase(v, "left"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_LEFT);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitLeft);
else if (equalIgnoringCase(v, "right"))
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, CSS_VAL__WEBKIT_RIGHT);
+ addCSSProperty(attr, CSSPropertyTextAlign, CSSValueWebkitRight);
else
- addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, v);
+ addCSSProperty(attr, CSSPropertyTextAlign, v);
} else if (attr->name() == heightAttr) {
if (!attr->value().isEmpty())
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
} else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLTableRowElement.cpp b/WebCore/html/HTMLTableRowElement.cpp
index a9558a0..da07594 100644
--- a/WebCore/html/HTMLTableRowElement.cpp
+++ b/WebCore/html/HTMLTableRowElement.cpp
@@ -167,7 +167,7 @@ void HTMLTableRowElement::deleteCell(int index, ExceptionCode& ec)
PassRefPtr<HTMLCollection> HTMLTableRowElement::cells()
{
- return new HTMLCollection(this, HTMLCollection::TRCells);
+ return HTMLCollection::create(this, HTMLCollection::TRCells);
}
void HTMLTableRowElement::setCells(HTMLCollection *, ExceptionCode& ec)
diff --git a/WebCore/html/HTMLTableRowsCollection.cpp b/WebCore/html/HTMLTableRowsCollection.cpp
index 3630fdc..7047576 100644
--- a/WebCore/html/HTMLTableRowsCollection.cpp
+++ b/WebCore/html/HTMLTableRowsCollection.cpp
@@ -149,10 +149,15 @@ HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
}
HTMLTableRowsCollection::HTMLTableRowsCollection(PassRefPtr<HTMLTableElement> table)
- : HTMLCollection(table, Other)
+ : HTMLCollection(table, Other, 0)
{
}
+PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(PassRefPtr<HTMLTableElement> table)
+{
+ return adoptRef(new HTMLTableRowsCollection(table));
+}
+
Element* HTMLTableRowsCollection::itemAfter(Element* previous) const
{
ASSERT(!previous || previous->hasLocalName(trTag));
diff --git a/WebCore/html/HTMLTableRowsCollection.h b/WebCore/html/HTMLTableRowsCollection.h
index 9acce69..f997e3c 100644
--- a/WebCore/html/HTMLTableRowsCollection.h
+++ b/WebCore/html/HTMLTableRowsCollection.h
@@ -38,12 +38,14 @@ class HTMLTableRowElement;
class HTMLTableRowsCollection : public HTMLCollection {
public:
- HTMLTableRowsCollection(PassRefPtr<HTMLTableElement>);
+ static PassRefPtr<HTMLTableRowsCollection> create(PassRefPtr<HTMLTableElement>);
static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
static HTMLTableRowElement* lastRow(HTMLTableElement*);
private:
+ HTMLTableRowsCollection(PassRefPtr<HTMLTableElement>);
+
virtual Element* itemAfter(Element*) const;
};
diff --git a/WebCore/html/HTMLTableSectionElement.cpp b/WebCore/html/HTMLTableSectionElement.cpp
index 15999e0..8190d93 100644
--- a/WebCore/html/HTMLTableSectionElement.cpp
+++ b/WebCore/html/HTMLTableSectionElement.cpp
@@ -169,7 +169,7 @@ void HTMLTableSectionElement::setVAlign(const String &value)
PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows()
{
- return new HTMLCollection(this, HTMLCollection::TSectionRows);
+ return HTMLCollection::create(this, HTMLCollection::TSectionRows);
}
}
diff --git a/WebCore/html/HTMLTagNames.in b/WebCore/html/HTMLTagNames.in
index 816f88d..6493c39 100644
--- a/WebCore/html/HTMLTagNames.in
+++ b/WebCore/html/HTMLTagNames.in
@@ -1,62 +1,68 @@
-a
+namespace="HTML"
+namespacePrefix="xhtml"
+namespaceURI="http://www.w3.org/1999/xhtml"
+
+a interfaceName=AnchorElement
abbr
acronym
address
applet
area
-audio
+#if ENABLE_VIDEO
+audio applyAudioHack=1
+#endif
b
base
-basefont
+basefont interfaceName=BaseFontElement
bdo
big
blockquote
body
-br
+br interfaceName=BRElement
button
canvas
-caption
+caption interfaceName=TableCaptionElement
center
cite
code
-col
+col interfaceName=TableColElement
colgroup
dd
-del
+del interfaceName=ModElement
dfn
-dir
+dir interfaceName=DirectoryElement
div
-dl
+dl interfaceName=DListElement
dt
em
embed
-fieldset
+fieldset interfaceName=FieldSetElement
font
form
frame
-frameset
+frameset interfaceName=FrameSetElement
head
-h1
+h1 interfaceName=HeadingElement
h2
h3
h4
h5
h6
-hr
+hr interfaceName=HRElement
html
i
-iframe
+iframe interfaceName=IFrameElement
image
-img
+img interfaceName=ImageElement
input
ins
-isindex
+isindex interfaceName=IsIndexElement
kbd
keygen
label
layer
legend
-li
+li interfaceName=LIElement
link
listing
map
@@ -69,20 +75,22 @@ noframes
nolayer
noscript
object
-ol
-optgroup
+ol interfaceName=OListElement
+optgroup interfaceName=OptGroupElement
option
-p
+p interfaceName=ParagraphElement
param
plaintext
pre
-q
+q interfaceName=QuoteElement
s
samp
script
select
small
-source
+#if ENABLE_VIDEO
+source applyAudioHack=1
+#endif
span
strike
strong
@@ -90,18 +98,20 @@ style
sub
sup
table
-tbody
-td
-textarea
+tbody interfaceName=TableSectionElement
+td interfaceName=TableCellElement
+textarea interfaceName=TextAreaElement
tfoot
th
thead
title
-tr
+tr interfaceName=TableRowElement
tt
u
-ul
+ul interfaceName=UListElement
var
-video
+#if ENABLE_VIDEO
+video applyAudioHack=1
+#endif
wbr
xmp
diff --git a/WebCore/html/HTMLTextAreaElement.cpp b/WebCore/html/HTMLTextAreaElement.cpp
index 4277f30..1882fe5 100644
--- a/WebCore/html/HTMLTextAreaElement.cpp
+++ b/WebCore/html/HTMLTextAreaElement.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 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
*
@@ -40,25 +40,23 @@
#include "Text.h"
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
-#include "FrameView.h"
-#include "WebCoreViewBridge.h"
+#include "WebViewCore.h"
#endif
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
static const int defaultRows = 2;
static const int defaultCols = 20;
-HTMLTextAreaElement::HTMLTextAreaElement(Document* doc, HTMLFormElement* f)
- : HTMLFormControlElementWithState(textareaTag, doc, f)
+HTMLTextAreaElement::HTMLTextAreaElement(Document* document, HTMLFormElement* form)
+ : HTMLFormControlElementWithState(textareaTag, document, form)
, m_rows(defaultRows)
, m_cols(defaultCols)
- , m_wrap(ta_Virtual)
- , cachedSelStart(-1)
- , cachedSelEnd(-1)
+ , m_wrap(SoftWrap)
+ , m_cachedSelectionStart(-1)
+ , m_cachedSelectionEnd(-1)
{
setValueMatchesRenderer();
}
@@ -82,55 +80,57 @@ void HTMLTextAreaElement::restoreState(const String& state)
int HTMLTextAreaElement::selectionStart()
{
- if (renderer()) {
- if (document()->focusedNode() != this && cachedSelStart != -1)
- return cachedSelStart;
- return static_cast<RenderTextControl *>(renderer())->selectionStart();
- }
- return 0;
+ if (!renderer())
+ return 0;
+ if (document()->focusedNode() != this && m_cachedSelectionStart >= 0)
+ return m_cachedSelectionStart;
+ return static_cast<RenderTextControl*>(renderer())->selectionStart();
}
int HTMLTextAreaElement::selectionEnd()
{
- if (renderer()) {
- if (document()->focusedNode() != this && cachedSelEnd != -1)
- return cachedSelEnd;
- return static_cast<RenderTextControl *>(renderer())->selectionEnd();
- }
- return 0;
+ if (!renderer())
+ return 0;
+ if (document()->focusedNode() != this && m_cachedSelectionEnd >= 0)
+ return m_cachedSelectionEnd;
+ return static_cast<RenderTextControl*>(renderer())->selectionEnd();
}
void HTMLTextAreaElement::setSelectionStart(int start)
{
- if (renderer())
- static_cast<RenderTextControl*>(renderer())->setSelectionStart(start);
+ if (!renderer())
+ return;
+ static_cast<RenderTextControl*>(renderer())->setSelectionStart(start);
}
void HTMLTextAreaElement::setSelectionEnd(int end)
{
- if (renderer())
- static_cast<RenderTextControl*>(renderer())->setSelectionEnd(end);
+ if (!renderer())
+ return;
+ static_cast<RenderTextControl*>(renderer())->setSelectionEnd(end);
}
void HTMLTextAreaElement::select()
{
- if (renderer())
- static_cast<RenderTextControl *>(renderer())->select();
+ if (!renderer())
+ return;
+ static_cast<RenderTextControl*>(renderer())->select();
}
void HTMLTextAreaElement::setSelectionRange(int start, int end)
{
- if (renderer())
- static_cast<RenderTextControl*>(renderer())->setSelectionRange(start, end);
+ if (!renderer())
+ return;
+ static_cast<RenderTextControl*>(renderer())->setSelectionRange(start, end);
}
-void HTMLTextAreaElement::childrenChanged(bool changedByParser)
+void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
setValue(defaultValue());
- HTMLElement::childrenChanged(changedByParser);
+ HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
-void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute* attr)
{
if (attr->name() == rowsAttr) {
int rows = attr->value().toInt();
@@ -151,36 +151,38 @@ void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute *attr)
renderer()->setNeedsLayoutAndPrefWidthsRecalc();
}
} else if (attr->name() == wrapAttr) {
- // virtual / physical is Netscape extension of HTML 3.0, now deprecated
- // soft/ hard / off is recommendation for HTML 4 extension by IE and NS 4
- if (equalIgnoringCase(attr->value(), "virtual") || equalIgnoringCase(attr->value(), "soft"))
- m_wrap = ta_Virtual;
- else if (equalIgnoringCase(attr->value(), "physical") || equalIgnoringCase(attr->value(), "hard"))
- m_wrap = ta_Physical;
- else if (equalIgnoringCase(attr->value(), "on" ))
- m_wrap = ta_Physical;
+ // The virtual/physical values were a Netscape extension of HTML 3.0, now deprecated.
+ // The soft/hard /off values are a recommendation for HTML 4 extension by IE and NS 4.
+ WrapMethod wrap;
+ if (equalIgnoringCase(attr->value(), "physical") || equalIgnoringCase(attr->value(), "hard") || equalIgnoringCase(attr->value(), "on"))
+ wrap = HardWrap;
else if (equalIgnoringCase(attr->value(), "off"))
- m_wrap = ta_NoWrap;
- if (renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ wrap = NoWrap;
+ else
+ wrap = SoftWrap;
+ if (wrap != m_wrap) {
+ m_wrap = wrap;
+ if (renderer())
+ renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ }
} else if (attr->name() == accesskeyAttr) {
// 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=7075
} else if (attr->name() == onfocusAttr)
- setHTMLEventListener(focusEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
else if (attr->name() == onblurAttr)
- setHTMLEventListener(blurEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
else if (attr->name() == onselectAttr)
- setHTMLEventListener(selectEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().selectEvent, attr);
else if (attr->name() == onchangeAttr)
- setHTMLEventListener(changeEvent, attr);
+ setInlineEventListenerForTypeAndAttribute(eventNames().changeEvent, attr);
else
HTMLFormControlElementWithState::parseMappedAttribute(attr);
}
-RenderObject* HTMLTextAreaElement::createRenderer(RenderArena* arena, RenderStyle* style)
+RenderObject* HTMLTextAreaElement::createRenderer(RenderArena* arena, RenderStyle*)
{
return new (arena) RenderTextControl(this, true);
}
@@ -189,10 +191,12 @@ bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool)
{
if (name().isEmpty())
return false;
-
- bool hardWrap = renderer() && wrap() == ta_Physical;
- String v = hardWrap ? static_cast<RenderTextControl*>(renderer())->textWithHardLineBreaks() : value();
- encoding.appendData(name(), v);
+
+ // FIXME: It's not acceptable to ignore the HardWrap setting when there is no renderer.
+ // While we have no evidence this has ever been a practical problem, it would be best to fix it some day.
+ RenderTextControl* control = static_cast<RenderTextControl*>(renderer());
+ const String& text = (m_wrap == HardWrap && control) ? control->textWithHardLineBreaks() : value();
+ encoding.appendData(name(), text);
return true;
}
@@ -203,42 +207,43 @@ void HTMLTextAreaElement::reset()
bool HTMLTextAreaElement::isKeyboardFocusable(KeyboardEvent*) const
{
- // If text areas can be focused, then they should always be keyboard focusable
- return HTMLFormControlElementWithState::isFocusable();
+ // If a given text area can be focused at all, then it will always be keyboard focusable.
+ return isFocusable();
}
bool HTMLTextAreaElement::isMouseFocusable() const
{
- return HTMLFormControlElementWithState::isFocusable();
+ return isFocusable();
}
void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection)
{
ASSERT(renderer());
- if (!restorePreviousSelection || cachedSelStart == -1) {
+ if (!restorePreviousSelection || m_cachedSelectionStart < 0) {
// If this is the first focus, set a caret at the beginning of the text.
- // This matches some browsers' behavior; see Bugzilla Bug 11746 Comment #15.
+ // This matches some browsers' behavior; see bug 11746 Comment #15.
// http://bugs.webkit.org/show_bug.cgi?id=11746#c15
setSelectionRange(0, 0);
#ifdef ANDROID_SELECT_TEXT_AREAS
// We need to select the entire text to match the platform text field.
select();
#endif
- } else
+ } else {
// Restore the cached selection. This matches other browsers' behavior.
- setSelectionRange(cachedSelStart, cachedSelEnd);
+ setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd);
+ }
if (document()->frame())
document()->frame()->revealSelection();
}
-void HTMLTextAreaElement::defaultEventHandler(Event *evt)
+void HTMLTextAreaElement::defaultEventHandler(Event* event)
{
- if (renderer() && (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent() || evt->type() == blurEvent))
- static_cast<RenderTextControl*>(renderer())->forwardEvent(evt);
+ if (renderer() && (event->isMouseEvent() || event->isDragEvent() || event->isWheelEvent() || event->type() == eventNames().blurEvent))
+ static_cast<RenderTextControl*>(renderer())->forwardEvent(event);
- HTMLFormControlElementWithState::defaultEventHandler(evt);
+ HTMLFormControlElementWithState::defaultEventHandler(event);
}
void HTMLTextAreaElement::rendererWillBeDestroyed()
@@ -248,11 +253,12 @@ void HTMLTextAreaElement::rendererWillBeDestroyed()
void HTMLTextAreaElement::updateValue() const
{
- if (!valueMatchesRenderer()) {
- ASSERT(renderer());
- m_value = static_cast<RenderTextControl*>(renderer())->text();
- setValueMatchesRenderer();
- }
+ if (valueMatchesRenderer())
+ return;
+
+ ASSERT(renderer());
+ m_value = static_cast<RenderTextControl*>(renderer())->text();
+ setValueMatchesRenderer();
}
String HTMLTextAreaElement::value() const
@@ -265,24 +271,21 @@ void HTMLTextAreaElement::setValue(const String& value)
{
// Code elsewhere normalizes line endings added by the user via the keyboard or pasting.
// We must normalize line endings coming from JS.
- DeprecatedString valueWithNormalizedLineEndings = value.deprecatedString();
- valueWithNormalizedLineEndings.replace("\r\n", "\n");
- valueWithNormalizedLineEndings.replace("\r", "\n");
-
- m_value = valueWithNormalizedLineEndings;
+ m_value = value;
+ m_value.replace("\r\n", "\n");
+ m_value.replace('\r', '\n');
+
setValueMatchesRenderer();
if (inDocument())
document()->updateRendering();
if (renderer())
renderer()->updateFromElement();
-
// Set the caret to the end of the text value.
if (document()->focusedNode() == this) {
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
// Make sure our UI side textfield changes to match the RenderTextControl
- WebCoreViewBridge* viewImpl = document()->frame()->view()->getWebCoreViewBridge();
- viewImpl->updateTextfield(this, false, value);
+ android::WebViewCore::getWebViewCore(document()->view())->updateTextfield(this, false, value);
#endif
unsigned endOfString = m_value.length();
setSelectionRange(endOfString, endOfString);
@@ -293,45 +296,57 @@ void HTMLTextAreaElement::setValue(const String& value)
String HTMLTextAreaElement::defaultValue() const
{
- String val = "";
+ String value = "";
// Since there may be comments, ignore nodes other than text nodes.
- for (Node* n = firstChild(); n; n = n->nextSibling())
+ for (Node* n = firstChild(); n; n = n->nextSibling()) {
if (n->isTextNode())
- val += static_cast<Text*>(n)->data();
+ value += static_cast<Text*>(n)->data();
+ }
- // FIXME: We should only drop the first carriage return for the default
- // value in the original source, not defaultValues set from JS. This code
- // will do both.
- if (val.length() >= 2 && val[0] == '\r' && val[1] == '\n')
- val.remove(0, 2);
- else if (val.length() >= 1 && (val[0] == '\r' || val[0] == '\n'))
- val.remove(0, 1);
+ UChar firstCharacter = value[0];
+ if (firstCharacter == '\r' && value[1] == '\n')
+ value.remove(0, 2);
+ else if (firstCharacter == '\r' || firstCharacter == '\n')
+ value.remove(0, 1);
- return val;
+ return value;
}
void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
{
- // To preserve comments, remove all the text nodes, then add a single one.
+ // To preserve comments, remove only the text nodes, then add a single text node.
+
Vector<RefPtr<Node> > textNodes;
- for (Node* n = firstChild(); n; n = n->nextSibling())
+ for (Node* n = firstChild(); n; n = n->nextSibling()) {
if (n->isTextNode())
textNodes.append(n);
- ExceptionCode ec = 0;
+ }
+ ExceptionCode ec;
size_t size = textNodes.size();
for (size_t i = 0; i < size; ++i)
removeChild(textNodes[i].get(), ec);
- insertBefore(document()->createTextNode(defaultValue), firstChild(), ec);
- setValue(defaultValue);
+
+ // Normalize line endings.
+ // Add an extra line break if the string starts with one, since
+ // the code to read default values from the DOM strips the leading one.
+ String value = defaultValue;
+ value.replace("\r\n", "\n");
+ value.replace('\r', '\n');
+ if (value[0] == '\n')
+ value = "\n" + value;
+
+ insertBefore(document()->createTextNode(value), firstChild(), ec);
+
+ setValue(value);
}
-void HTMLTextAreaElement::accessKeyAction(bool sendToAnyElement)
+void HTMLTextAreaElement::accessKeyAction(bool)
{
focus();
}
-String HTMLTextAreaElement::accessKey() const
+const AtomicString& HTMLTextAreaElement::accessKey() const
{
return getAttribute(accesskeyAttr);
}
@@ -353,9 +368,9 @@ void HTMLTextAreaElement::setRows(int rows)
Selection HTMLTextAreaElement::selection() const
{
- if (!renderer() || cachedSelStart == -1 || cachedSelEnd == -1)
+ if (!renderer() || m_cachedSelectionStart < 0 || m_cachedSelectionEnd < 0)
return Selection();
- return static_cast<RenderTextControl*>(renderer())->selection(cachedSelStart, cachedSelEnd);
+ return static_cast<RenderTextControl*>(renderer())->selection(m_cachedSelectionStart, m_cachedSelectionEnd);
}
bool HTMLTextAreaElement::shouldUseInputMethod() const
diff --git a/WebCore/html/HTMLTextAreaElement.h b/WebCore/html/HTMLTextAreaElement.h
index c4d712d..d5b06fa 100644
--- a/WebCore/html/HTMLTextAreaElement.h
+++ b/WebCore/html/HTMLTextAreaElement.h
@@ -24,7 +24,7 @@
#ifndef HTMLTextAreaElement_h
#define HTMLTextAreaElement_h
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
namespace WebCore {
@@ -32,8 +32,6 @@ class Selection;
class HTMLTextAreaElement : public HTMLFormControlElementWithState {
public:
- enum WrapMethod { ta_NoWrap, ta_Virtual, ta_Physical };
-
HTMLTextAreaElement(Document*, HTMLFormElement* = 0);
virtual bool checkDTD(const Node* newChild) { return newChild->isTextNode(); }
@@ -41,7 +39,7 @@ public:
int cols() const { return m_cols; }
int rows() const { return m_rows; }
- WrapMethod wrap() const { return m_wrap; }
+ bool shouldWrapText() const { return m_wrap != NoWrap; }
virtual bool isEnumeratable() const { return true; }
@@ -52,6 +50,8 @@ public:
bool readOnly() const { return isReadOnlyControl(); }
+ virtual bool isTextControl() const { return true; }
+
int selectionStart();
int selectionEnd();
@@ -61,7 +61,7 @@ public:
void select();
void setSelectionRange(int, int);
- virtual void childrenChanged(bool changedByParser = false);
+ 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);
@@ -80,25 +80,28 @@ public:
virtual void accessKeyAction(bool sendToAnyElement);
- String accessKey() const;
+ const AtomicString& accessKey() const;
void setAccessKey(const String&);
void setCols(int);
void setRows(int);
- void cacheSelection(int s, int e) { cachedSelStart = s; cachedSelEnd = e; };
+ void cacheSelection(int s, int e) { m_cachedSelectionStart = s; m_cachedSelectionEnd = e; };
Selection selection() const;
virtual bool shouldUseInputMethod() const;
+
private:
+ enum WrapMethod { NoWrap, SoftWrap, HardWrap };
+
void updateValue() const;
int m_rows;
int m_cols;
WrapMethod m_wrap;
mutable String m_value;
- int cachedSelStart;
- int cachedSelEnd;
+ int m_cachedSelectionStart;
+ int m_cachedSelectionEnd;
};
} //namespace
diff --git a/WebCore/html/HTMLTextAreaElement.idl b/WebCore/html/HTMLTextAreaElement.idl
index 40c3feb..c4f144b 100644
--- a/WebCore/html/HTMLTextAreaElement.idl
+++ b/WebCore/html/HTMLTextAreaElement.idl
@@ -30,17 +30,17 @@ module html {
attribute [ConvertNullToNullString] DOMString accessKey;
attribute long cols;
attribute boolean disabled;
+ attribute boolean autofocus;
attribute [ConvertNullToNullString] DOMString name;
attribute boolean readOnly;
attribute long rows;
- attribute long tabIndex;
readonly attribute DOMString type;
attribute [ConvertNullToNullString] DOMString value;
- void blur();
- void focus();
void select();
+ readonly attribute boolean willValidate;
+
// WinIE & FireFox extension:
attribute long selectionStart;
attribute long selectionEnd;
diff --git a/WebCore/html/HTMLTextFieldInnerElement.cpp b/WebCore/html/HTMLTextFieldInnerElement.cpp
deleted file mode 100644
index e6d5871..0000000
--- a/WebCore/html/HTMLTextFieldInnerElement.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "HTMLTextFieldInnerElement.h"
-
-#include "BeforeTextInsertedEvent.h"
-#include "Document.h"
-#include "EventHandler.h"
-#include "EventNames.h"
-#include "Frame.h"
-#include "HTMLInputElement.h"
-#include "HTMLTextAreaElement.h"
-#include "MouseEvent.h"
-#include "RenderTextControl.h"
-
-namespace WebCore {
-
-using namespace EventNames;
-
-HTMLTextFieldInnerElement::HTMLTextFieldInnerElement(Document* doc, Node* shadowParent)
- : HTMLDivElement(doc), m_shadowParent(shadowParent)
-{
-}
-
-HTMLTextFieldInnerTextElement::HTMLTextFieldInnerTextElement(Document* doc, Node* shadowParent)
- : HTMLTextFieldInnerElement(doc, shadowParent)
-{
-}
-
-void HTMLTextFieldInnerTextElement::defaultEventHandler(Event* evt)
-{
- // FIXME: In the future, we should add a way to have default event listeners. Then we would add one to the text field's inner div, and we wouldn't need this subclass.
- Node* shadowAncestor = shadowAncestorNode();
- if (shadowAncestor && shadowAncestor->renderer()) {
- ASSERT(shadowAncestor->renderer()->isTextField() || shadowAncestor->renderer()->isTextArea());
- if (evt->isBeforeTextInsertedEvent())
- if (shadowAncestor->renderer()->isTextField())
- static_cast<HTMLInputElement*>(shadowAncestor)->defaultEventHandler(evt);
- else
- static_cast<HTMLTextAreaElement*>(shadowAncestor)->defaultEventHandler(evt);
- if (evt->type() == webkitEditableContentChangedEvent)
- static_cast<RenderTextControl*>(shadowAncestor->renderer())->subtreeHasChanged();
- }
- if (!evt->defaultHandled())
- HTMLDivElement::defaultEventHandler(evt);
-}
-
-HTMLSearchFieldResultsButtonElement::HTMLSearchFieldResultsButtonElement(Document* doc)
- : HTMLTextFieldInnerElement(doc)
-{
-}
-
-void HTMLSearchFieldResultsButtonElement::defaultEventHandler(Event* evt)
-{
- // On mousedown, bring up a menu, if needed
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
- if (evt->type() == mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
- input->focus();
- input->select();
- if (input && input->renderer() && static_cast<RenderTextControl*>(input->renderer())->popupIsVisible())
- static_cast<RenderTextControl*>(input->renderer())->hidePopup();
- else if (input->maxResults() > 0)
- static_cast<RenderTextControl*>(input->renderer())->showPopup();
- evt->setDefaultHandled();
- }
- if (!evt->defaultHandled())
- HTMLDivElement::defaultEventHandler(evt);
-}
-
-HTMLSearchFieldCancelButtonElement::HTMLSearchFieldCancelButtonElement(Document* doc)
- : HTMLTextFieldInnerElement(doc)
- , m_capturing(false)
-{
-}
-
-void HTMLSearchFieldCancelButtonElement::defaultEventHandler(Event* evt)
-{
- // If the element is visible, on mouseup, clear the value, and set selection
- HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
- if (evt->type() == mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
- input->focus();
- input->select();
- evt->setDefaultHandled();
- if (Frame* frame = document()->frame())
- frame->eventHandler()->setCapturingMouseEventsNode(this);
- m_capturing = true;
- } else if (evt->type() == mouseupEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
- if (m_capturing && renderer() && renderer()->style()->visibility() == VISIBLE) {
- if (hovered()) {
- input->setValue("");
- input->onSearch();
- evt->setDefaultHandled();
- }
- if (Frame* frame = document()->frame())
- frame->eventHandler()->setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- }
- if (!evt->defaultHandled())
- HTMLDivElement::defaultEventHandler(evt);
-}
-
-}
diff --git a/WebCore/html/HTMLTextFieldInnerElement.h b/WebCore/html/HTMLTextFieldInnerElement.h
deleted file mode 100644
index c6fcb19..0000000
--- a/WebCore/html/HTMLTextFieldInnerElement.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLTextFieldInnerElement_h
-#define HTMLTextFieldInnerElement_h
-
-#include "HTMLDivElement.h"
-
-namespace WebCore {
-
-class String;
-
-class HTMLTextFieldInnerElement : public HTMLDivElement
-{
-public:
- HTMLTextFieldInnerElement(Document*, Node* shadowParent = 0);
-
- virtual bool isMouseFocusable() const { return false; }
- virtual bool isShadowNode() const { return m_shadowParent; }
- virtual Node* shadowParentNode() { return m_shadowParent; }
- void setShadowParentNode(Node* node) { m_shadowParent = node; }
-
-private:
- Node* m_shadowParent;
-};
-
-class HTMLTextFieldInnerTextElement : public HTMLTextFieldInnerElement {
-public:
- HTMLTextFieldInnerTextElement(Document*, Node* shadowParent);
- virtual void defaultEventHandler(Event*);
-};
-
-class HTMLSearchFieldResultsButtonElement : public HTMLTextFieldInnerElement {
-public:
- HTMLSearchFieldResultsButtonElement(Document*);
- virtual void defaultEventHandler(Event*);
-};
-
-class HTMLSearchFieldCancelButtonElement : public HTMLTextFieldInnerElement {
-public:
- HTMLSearchFieldCancelButtonElement(Document*);
- virtual void defaultEventHandler(Event*);
-private:
- bool m_capturing;
-};
-
-} //namespace
-
-#endif
diff --git a/WebCore/html/HTMLTitleElement.cpp b/WebCore/html/HTMLTitleElement.cpp
index 1f855e1..a75b1ee 100644
--- a/WebCore/html/HTMLTitleElement.cpp
+++ b/WebCore/html/HTMLTitleElement.cpp
@@ -54,7 +54,7 @@ void HTMLTitleElement::removedFromDocument()
document()->removeTitle(this);
}
-void HTMLTitleElement::childrenChanged(bool changedByParser)
+void HTMLTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
m_title = "";
for (Node* c = firstChild(); c != 0; c = c->nextSibling())
@@ -62,7 +62,7 @@ void HTMLTitleElement::childrenChanged(bool changedByParser)
m_title += c->nodeValue();
if (inDocument())
document()->setTitle(m_title, this);
- HTMLElement::childrenChanged(changedByParser);
+ HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
String HTMLTitleElement::text() const
diff --git a/WebCore/html/HTMLTitleElement.h b/WebCore/html/HTMLTitleElement.h
index 195305d..5bb05bc 100644
--- a/WebCore/html/HTMLTitleElement.h
+++ b/WebCore/html/HTMLTitleElement.h
@@ -38,7 +38,7 @@ public:
virtual void insertedIntoDocument();
virtual void removedFromDocument();
- virtual void childrenChanged(bool changedByParser = false);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
String text() const;
void setText(const String&);
diff --git a/WebCore/html/HTMLTokenizer.cpp b/WebCore/html/HTMLTokenizer.cpp
index 3481df0..bc0e215 100644
--- a/WebCore/html/HTMLTokenizer.cpp
+++ b/WebCore/html/HTMLTokenizer.cpp
@@ -23,6 +23,9 @@
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
+#ifdef ANDROID_INSTRUMENT
+#define LOG_TAG "WebCore"
+#endif
#include "config.h"
#include "HTMLTokenizer.h"
@@ -41,61 +44,54 @@
#include "HTMLParser.h"
#include "HTMLScriptElement.h"
#include "HTMLViewSourceDocument.h"
-#ifdef ANDROID_PRELOAD_CHANGES
+#include "Page.h"
#include "PreloadScanner.h"
-#endif
-#include "Settings.h"
+#include "ScriptController.h"
#include "SystemTime.h"
-#include "kjs_proxy.h"
#include <wtf/ASCIICType.h>
#include "HTMLEntityNames.c"
-#ifdef ANDROID_INSTRUMENT
-#undef LOG
-#include <utils/Log.h>
-#endif
-
-#ifdef ANDROID_PRELOAD_CHANGES
#define PRELOAD_SCANNER_ENABLED 1
-#endif
// #define INSTRUMENT_LAYOUT_SCHEDULING 1
-#if MOBILE
-// The mobile device needs to be responsive, as such the tokenizer chunk size is reduced.
-// This value is used to define how many characters the tokenizer will process before
-// yeilding control.
-#define TOKENIZER_CHUNK_SIZE 256
-#else
-#define TOKENIZER_CHUNK_SIZE 4096
-#endif
-
using namespace std;
using namespace WTF;
namespace WebCore {
using namespace HTMLNames;
-using namespace EventNames;
+
+#if MOBILE
+// The mobile device needs to be responsive, as such the tokenizer chunk size is reduced.
+// This value is used to define how many characters the tokenizer will process before
+// yeilding control.
+static const int defaultTokenizerChunkSize = 256;
+#else
+static const int defaultTokenizerChunkSize = 4096;
+#endif
#if MOBILE
// As the chunks are smaller (above), the tokenizer should not yield for as long a period, otherwise
// it will take way to long to load a page.
-const double tokenizerTimeDelay = 0.300;
-
+static const double defaultTokenizerTimeDelay = 0.300;
#else
// FIXME: We would like this constant to be 200ms.
// Yielding more aggressively results in increased responsiveness and better incremental rendering.
// It slows down overall page-load on slower machines, though, so for now we set a value of 500.
-const double tokenizerTimeDelay = 0.500;
+static const double defaultTokenizerTimeDelay = 0.500;
#endif
static const char commentStart [] = "<!--";
+static const char doctypeStart [] = "<!doctype";
+static const char publicStart [] = "public";
+static const char systemStart [] = "system";
static const char scriptEnd [] = "</script";
static const char xmpEnd [] = "</xmp";
static const char styleEnd [] = "</style";
static const char textareaEnd [] = "</textarea";
static const char titleEnd [] = "</title";
+static const char iframeEnd [] = "</iframe";
// Full support for MS Windows extensions to Latin-1.
// Technically these extensions should only be activated for pages
@@ -142,9 +138,11 @@ inline void Token::addAttribute(Document* doc, AtomicString& attrName, const Ato
{
if (!attrName.isEmpty()) {
ASSERT(!attrName.contains('/'));
- RefPtr<MappedAttribute> a = new MappedAttribute(attrName, v);
- if (!attrs)
- attrs = new NamedMappedAttrMap(0);
+ RefPtr<MappedAttribute> a = MappedAttribute::create(attrName, v);
+ if (!attrs) {
+ attrs = NamedMappedAttrMap::create();
+ attrs->reserveCapacity(10);
+ }
attrs->insertAttribute(a.release(), viewSourceMode);
}
@@ -166,8 +164,7 @@ void Frame::resetParsingTimeCounter()
void Frame::reportParsingTimeCounter()
{
- LOG(LOG_DEBUG, "WebCore",
- "*-* Total parsing time (may include calcStyle or Java callback): %d ms called %d times\n",
+ LOGD("*-* Total parsing time (may include calcStyle or Java callback): %d ms called %d times\n",
sTotalTimeUsed, sCounter);
}
#endif
@@ -233,9 +230,10 @@ void HTMLTokenizer::reset()
ASSERT(m_executingScript == 0);
while (!pendingScripts.isEmpty()) {
- CachedScript *cs = pendingScripts.dequeue();
- ASSERT(cache()->disabled() || cs->accessCount() > 0);
- cs->deref(this);
+ CachedScript *cs = pendingScripts.first().get();
+ pendingScripts.removeFirst();
+ ASSERT(cache()->disabled() || cs->accessCount() > 0);
+ cs->removeClient(this);
}
fastFree(buffer);
@@ -251,6 +249,9 @@ void HTMLTokenizer::reset()
m_state.setForceSynchronous(false);
currToken.reset();
+ m_doctypeToken.reset();
+ m_doctypeSearchCount = 0;
+ m_doctypeSecondarySearchCount = 0;
}
void HTMLTokenizer::begin()
@@ -276,6 +277,17 @@ void HTMLTokenizer::begin()
scriptStartLineno = 0;
tagStartLineno = 0;
m_state.setForceSynchronous(false);
+
+ Page* page = m_doc->page();
+ if (page && page->hasCustomHTMLTokenizerTimeDelay())
+ m_tokenizerTimeDelay = page->customHTMLTokenizerTimeDelay();
+ else
+ m_tokenizerTimeDelay = defaultTokenizerTimeDelay;
+
+ if (page && page->hasCustomHTMLTokenizerChunkSize())
+ m_tokenizerChunkSize = page->customHTMLTokenizerChunkSize();
+ else
+ m_tokenizerChunkSize = defaultTokenizerChunkSize;
}
void HTMLTokenizer::setForceSynchronous(bool force)
@@ -322,20 +334,24 @@ HTMLTokenizer::State HTMLTokenizer::processListing(SegmentedString list, State s
HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State state)
{
- ASSERT(state.inTextArea() || state.inTitle() || !state.hasEntityState());
+ ASSERT(state.inTextArea() || state.inTitle() || state.inIFrame() || !state.hasEntityState());
ASSERT(!state.hasTagState());
- ASSERT(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() == 1 );
- if (state.inScript())
- scriptStartLineno = m_lineNumber;
+ ASSERT(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() + state.inIFrame() == 1 );
+ if (state.inScript() && !scriptStartLineno)
+ scriptStartLineno = m_lineNumber + 1; // Script line numbers are 1 based.
if (state.inComment())
state = parseComment(src, state);
+ int lastDecodedEntityPosition = -1;
while ( !src.isEmpty() ) {
checkScriptBuffer();
UChar ch = *src;
- if (!scriptCodeResync && !brokenComments && !state.inTextArea() && !state.inXmp() && ch == '-' && scriptCodeSize >= 3 && !src.escaped() && scriptCode[scriptCodeSize-3] == '<' && scriptCode[scriptCodeSize-2] == '!' && scriptCode[scriptCodeSize-1] == '-') {
+ if (!scriptCodeResync && !brokenComments &&
+ !state.inXmp() && ch == '-' && scriptCodeSize >= 3 && !src.escaped() &&
+ scriptCode[scriptCodeSize-3] == '<' && scriptCode[scriptCodeSize-2] == '!' && scriptCode[scriptCodeSize-1] == '-' &&
+ (lastDecodedEntityPosition < scriptCodeSize - 3)) {
state.setInComment(true);
state = parseComment(src, state);
continue;
@@ -362,6 +378,9 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
} else if (state.inXmp()) {
currToken.tagName = xmpTag.localName();
currToken.beginTag = false;
+ } else if (state.inIFrame()) {
+ currToken.tagName = iframeTag.localName();
+ currToken.beginTag = false;
}
processToken();
state.setInStyle(false);
@@ -369,6 +388,7 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
state.setInTextArea(false);
state.setInTitle(false);
state.setInXmp(false);
+ state.setInIFrame(false);
tquote = NoQuote;
scriptCodeSize = scriptCodeResync = 0;
}
@@ -377,7 +397,8 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
// possible end of tagname, lets check.
if (!scriptCodeResync && !state.escaped() && !src.escaped() && (ch == '>' || ch == '/' || isASCIISpace(ch)) &&
scriptCodeSize >= searchStopperLen &&
- tagMatch( searchStopper, scriptCode+scriptCodeSize-searchStopperLen, searchStopperLen )) {
+ tagMatch(searchStopper, scriptCode + scriptCodeSize - searchStopperLen, searchStopperLen) &&
+ (lastDecodedEntityPosition < scriptCodeSize - searchStopperLen)) {
scriptCodeResync = scriptCodeSize-searchStopperLen+1;
tquote = NoQuote;
continue;
@@ -391,11 +412,14 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
tquote = NoQuote;
}
state.setEscaped(!state.escaped() && ch == '\\');
- if (!scriptCodeResync && (state.inTextArea() || state.inTitle()) && !src.escaped() && ch == '&') {
+ if (!scriptCodeResync && (state.inTextArea() || state.inTitle() || state.inIFrame()) && !src.escaped() && ch == '&') {
UChar* scriptCodeDest = scriptCode+scriptCodeSize;
src.advancePastNonNewline();
state = parseEntity(src, scriptCodeDest, state, m_cBufferPos, true, false);
- scriptCodeSize = scriptCodeDest - scriptCode;
+ if (scriptCodeDest == scriptCode + scriptCodeSize)
+ lastDecodedEntityPosition = scriptCodeSize;
+ else
+ scriptCodeSize = scriptCodeDest - scriptCode;
} else {
scriptCode[scriptCodeSize++] = ch;
src.advance(m_lineNumber);
@@ -409,6 +433,10 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
{
// We are inside a <script>
bool doScriptExec = false;
+ int startLine = scriptStartLineno;
+
+ // Reset scriptStartLineno to indicate that we've finished parsing the current script element
+ scriptStartLineno = 0;
// (Bugzilla 3837) Scripts following a frameset element should not execute or,
// in the case of extern scripts, even load.
@@ -427,18 +455,13 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
// The parser might have been stopped by for example a window.close call in an earlier script.
// If so, we don't want to load scripts.
if (!m_parserStopped && (cs = m_doc->docLoader()->requestScript(scriptSrc, scriptSrcCharset)))
- pendingScripts.enqueue(cs);
+ pendingScripts.append(cs);
else
scriptNode = 0;
} else
scriptNode = 0;
scriptSrc = String();
} else {
-#ifdef TOKEN_DEBUG
- kdDebug( 6036 ) << "---START SCRIPT---" << endl;
- kdDebug( 6036 ) << DeprecatedString(scriptCode, scriptCodeSize) << endl;
- kdDebug( 6036 ) << "---END SCRIPT---" << endl;
-#endif
// Parse scriptCode containing <script> info
#if USE(LOW_BANDWIDTH_DISPLAY)
if (m_doc->inLowBandwidthDisplay()) {
@@ -455,13 +478,14 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
}
state = processListing(SegmentedString(scriptCode, scriptCodeSize), state);
- String scriptCode(buffer, dest - buffer);
- processToken();
+ RefPtr<Node> node = processToken();
+ String scriptString = node ? node->textContent() : "";
currToken.tagName = scriptTag.localName();
currToken.beginTag = false;
processToken();
state.setInScript(false);
+ scriptCodeSize = scriptCodeResync = 0;
// FIXME: The script should be syntax highlighted.
if (inViewSourceMode())
@@ -470,7 +494,6 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
SegmentedString *savedPrependingSrc = currentPrependingSrc;
SegmentedString prependingSrc;
currentPrependingSrc = &prependingSrc;
- scriptCodeSize = scriptCodeResync = 0;
#ifdef ANDROID_INSTRUMENT
sTotalTimeUsed += get_thread_msec() - sCurrentTime;
@@ -489,7 +512,7 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
m_state = state;
bool savedRequestingScript = m_requestingScript;
m_requestingScript = true;
- cs->ref(this);
+ cs->addClient(this);
m_requestingScript = savedRequestingScript;
state = m_state;
// will be 0 if script was already loaded and ref() executed it
@@ -501,7 +524,7 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
else
prependingSrc = src;
setSrc(SegmentedString());
- state = scriptExecution(scriptCode, state, String(), scriptStartLineno);
+ state = scriptExecution(scriptString, state, String(), startLine);
}
}
@@ -520,7 +543,7 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
// we need to do this slightly modified bit of one of the write() cases
// because we want to prepend to pendingSrc rather than appending
// if there's no previous prependingSrc
- if (state.loadingExtScript()) {
+ if (!pendingScripts.isEmpty()) {
if (currentPrependingSrc) {
currentPrependingSrc->append(prependingSrc);
} else {
@@ -532,6 +555,7 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
state = m_state;
}
}
+
#if PRELOAD_SCANNER_ENABLED
if (!pendingScripts.isEmpty() && !m_executingScript) {
@@ -553,7 +577,7 @@ HTMLTokenizer::State HTMLTokenizer::scriptExecution(const String& str, State sta
if (m_fragment || !m_doc->frame())
return state;
m_executingScript++;
- DeprecatedString url = scriptURL.isNull() ? m_doc->frame()->document()->url() : scriptURL.deprecatedString();
+ String url = scriptURL.isNull() ? m_doc->frame()->document()->url().string() : scriptURL;
SegmentedString *savedPrependingSrc = currentPrependingSrc;
SegmentedString prependingSrc;
@@ -589,12 +613,12 @@ HTMLTokenizer::State HTMLTokenizer::scriptExecution(const String& str, State sta
// we need to do this slightly modified bit of one of the write() cases
// because we want to prepend to pendingSrc rather than appending
// if there's no previous prependingSrc
- if (state.loadingExtScript()) {
+ if (!pendingScripts.isEmpty()) {
if (currentPrependingSrc)
currentPrependingSrc->append(prependingSrc);
else
pendingSrc.prepend(prependingSrc);
-
+
#if PRELOAD_SCANNER_ENABLED
// We are stuck waiting for another script. Lets check the source that
// was just document.write()n for anything to load.
@@ -635,7 +659,7 @@ HTMLTokenizer::State HTMLTokenizer::parseComment(SegmentedString &src, State sta
}
if (handleBrokenComments || endCharsCount > 1) {
src.advancePastNonNewline();
- if (!(state.inTitle() || state.inScript() || state.inXmp() || state.inTextArea() || state.inStyle())) {
+ if (!(state.inTitle() || state.inScript() || state.inXmp() || state.inTextArea() || state.inStyle() || state.inIFrame())) {
checkScriptBuffer();
scriptCode[scriptCodeSize] = 0;
scriptCode[scriptCodeSize + 1] = 0;
@@ -901,6 +925,222 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString &src, UChar*& de
return state;
}
+HTMLTokenizer::State HTMLTokenizer::parseDoctype(SegmentedString& src, State state)
+{
+ ASSERT(state.inDoctype());
+ while (!src.isEmpty() && state.inDoctype()) {
+ UChar c = *src;
+ bool isWhitespace = c == '\r' || c == '\n' || c == '\t' || c == ' ';
+ switch (m_doctypeToken.state()) {
+ case DoctypeBegin: {
+ m_doctypeToken.setState(DoctypeBeforeName);
+ if (isWhitespace) {
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ }
+ break;
+ }
+ case DoctypeBeforeName: {
+ if (c == '>') {
+ // Malformed. Just exit.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ if (inViewSourceMode())
+ processDoctypeToken();
+ } else if (isWhitespace) {
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else
+ m_doctypeToken.setState(DoctypeName);
+ break;
+ }
+ case DoctypeName: {
+ if (c == '>') {
+ // Valid doctype. Emit it.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ processDoctypeToken();
+ } else if (isWhitespace) {
+ m_doctypeSearchCount = 0; // Used now to scan for PUBLIC
+ m_doctypeSecondarySearchCount = 0; // Used now to scan for SYSTEM
+ m_doctypeToken.setState(DoctypeAfterName);
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else {
+ src.advancePastNonNewline();
+ m_doctypeToken.m_name.append(c);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ }
+ break;
+ }
+ case DoctypeAfterName: {
+ if (c == '>') {
+ // Valid doctype. Emit it.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ processDoctypeToken();
+ } else if (!isWhitespace) {
+ src.advancePastNonNewline();
+ if (toASCIILower(c) == publicStart[m_doctypeSearchCount]) {
+ m_doctypeSearchCount++;
+ if (m_doctypeSearchCount == 6)
+ // Found 'PUBLIC' sequence
+ m_doctypeToken.setState(DoctypeBeforePublicID);
+ } else if (m_doctypeSearchCount > 0) {
+ m_doctypeSearchCount = 0;
+ m_doctypeToken.setState(DoctypeBogus);
+ } else if (toASCIILower(c) == systemStart[m_doctypeSecondarySearchCount]) {
+ m_doctypeSecondarySearchCount++;
+ if (m_doctypeSecondarySearchCount == 6)
+ // Found 'SYSTEM' sequence
+ m_doctypeToken.setState(DoctypeBeforeSystemID);
+ } else {
+ m_doctypeSecondarySearchCount = 0;
+ m_doctypeToken.setState(DoctypeBogus);
+ }
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else {
+ src.advance(m_lineNumber); // Whitespace keeps us in the after name state.
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ }
+ break;
+ }
+ case DoctypeBeforePublicID: {
+ if (c == '\"' || c == '\'') {
+ tquote = c == '\"' ? DoubleQuote : SingleQuote;
+ m_doctypeToken.setState(DoctypePublicID);
+ src.advancePastNonNewline();
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else if (c == '>') {
+ // Considered bogus. Don't process the doctype.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ if (inViewSourceMode())
+ processDoctypeToken();
+ } else if (isWhitespace) {
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else
+ m_doctypeToken.setState(DoctypeBogus);
+ break;
+ }
+ case DoctypePublicID: {
+ if ((c == '\"' && tquote == DoubleQuote) || (c == '\'' && tquote == SingleQuote)) {
+ src.advancePastNonNewline();
+ m_doctypeToken.setState(DoctypeAfterPublicID);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else if (c == '>') {
+ // Considered bogus. Don't process the doctype.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ if (inViewSourceMode())
+ processDoctypeToken();
+ } else {
+ m_doctypeToken.m_publicID.append(c);
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ }
+ break;
+ }
+ case DoctypeAfterPublicID:
+ if (c == '\"' || c == '\'') {
+ tquote = c == '\"' ? DoubleQuote : SingleQuote;
+ m_doctypeToken.setState(DoctypeSystemID);
+ src.advancePastNonNewline();
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else if (c == '>') {
+ // Valid doctype. Emit it now.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ processDoctypeToken();
+ } else if (isWhitespace) {
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else
+ m_doctypeToken.setState(DoctypeBogus);
+ break;
+ case DoctypeBeforeSystemID:
+ if (c == '\"' || c == '\'') {
+ tquote = c == '\"' ? DoubleQuote : SingleQuote;
+ m_doctypeToken.setState(DoctypeSystemID);
+ src.advancePastNonNewline();
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else if (c == '>') {
+ // Considered bogus. Don't process the doctype.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ } else if (isWhitespace) {
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else
+ m_doctypeToken.setState(DoctypeBogus);
+ break;
+ case DoctypeSystemID:
+ if ((c == '\"' && tquote == DoubleQuote) || (c == '\'' && tquote == SingleQuote)) {
+ src.advancePastNonNewline();
+ m_doctypeToken.setState(DoctypeAfterSystemID);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else if (c == '>') {
+ // Considered bogus. Don't process the doctype.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ if (inViewSourceMode())
+ processDoctypeToken();
+ } else {
+ m_doctypeToken.m_systemID.append(c);
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ }
+ break;
+ case DoctypeAfterSystemID:
+ if (c == '>') {
+ // Valid doctype. Emit it now.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ processDoctypeToken();
+ } else if (isWhitespace) {
+ src.advance(m_lineNumber);
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ } else
+ m_doctypeToken.setState(DoctypeBogus);
+ break;
+ case DoctypeBogus:
+ if (c == '>') {
+ // Done with the bogus doctype.
+ src.advancePastNonNewline();
+ state.setInDoctype(false);
+ if (inViewSourceMode())
+ processDoctypeToken();
+ } else {
+ src.advance(m_lineNumber); // Just keep scanning for '>'
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(c);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return state;
+}
+
HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
{
ASSERT(!state.hasEntityState());
@@ -919,19 +1159,14 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
}
case TagName:
{
-#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 1
- qDebug("TagName");
-#endif
- if (searchCount > 0)
- {
- if (*src == commentStart[searchCount])
- {
+ if (searchCount > 0) {
+ if (*src == commentStart[searchCount]) {
searchCount++;
- if (searchCount == 4)
- {
-#ifdef TOKEN_DEBUG
- kdDebug( 6036 ) << "Found comment" << endl;
-#endif
+ if (searchCount == 2)
+ m_doctypeSearchCount++; // A '!' is also part of a doctype, so we are moving through that still as well.
+ else
+ m_doctypeSearchCount = 0;
+ if (searchCount == 4) {
// Found '<!--' sequence
src.advancePastNonNewline();
dest = buffer; // ignore the previous part of this tag
@@ -942,12 +1177,11 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
// <!--> as a valid comment, since both mozilla and IE on windows
// can handle this case. Only do this in quirks mode. -dwh
if (!src.isEmpty() && *src == '>' && m_doc->inCompatMode()) {
- state.setInComment(false);
- src.advancePastNonNewline();
- if (!src.isEmpty())
- cBuffer[cBufferPos++] = *src;
- }
- else
+ state.setInComment(false);
+ src.advancePastNonNewline();
+ if (!src.isEmpty())
+ cBuffer[cBufferPos++] = *src;
+ } else
state = parseComment(src, state);
m_cBufferPos = cBufferPos;
@@ -956,10 +1190,30 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
cBuffer[cBufferPos++] = *src;
src.advancePastNonNewline();
break;
- }
- else
+ } else
searchCount = 0; // Stop looking for '<!--' sequence
}
+
+ if (m_doctypeSearchCount > 0) {
+ if (toASCIILower(*src) == doctypeStart[m_doctypeSearchCount]) {
+ m_doctypeSearchCount++;
+ cBuffer[cBufferPos++] = *src;
+ src.advancePastNonNewline();
+ if (m_doctypeSearchCount == 9) {
+ // Found '<!DOCTYPE' sequence
+ state.setInDoctype(true);
+ state.setTagState(NoTag);
+ m_doctypeToken.reset();
+ if (inViewSourceMode())
+ m_doctypeToken.m_source.append(cBuffer, cBufferPos);
+ state = parseDoctype(src, state);
+ m_cBufferPos = cBufferPos;
+ return state;
+ }
+ break;
+ } else
+ m_doctypeSearchCount = 0; // Stop looking for '<!DOCTYPE' sequence
+ }
bool finish = false;
unsigned int ll = min(src.length(), CBUFLEN - cBufferPos);
@@ -1153,7 +1407,8 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
while (dest > buffer + 1 && (dest[-1] == '\n' || dest[-1] == '\r'))
dest--; // remove trailing newlines
AtomicString v(buffer + 1, dest - buffer - 1);
- attrName = v; // Just make the name/value match. (FIXME: Is this some WinIE quirk?)
+ if (!v.contains('/'))
+ attrName = v; // Just make the name/value match. (FIXME: Is this some WinIE quirk?)
currToken.addAttribute(m_doc, attrName, v, inViewSourceMode());
if (inViewSourceMode())
currToken.addViewSourceChar('x');
@@ -1174,7 +1429,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
while (dest > buffer + 1 && (dest[-1] == '\n' || dest[-1] == '\r'))
dest--; // remove trailing newlines
AtomicString v(buffer + 1, dest - buffer - 1);
- if (attrName.isEmpty()) {
+ if (attrName.isEmpty() && !v.contains('/')) {
attrName = v; // Make the name match the value. (FIXME: Is this a WinIE quirk?)
if (inViewSourceMode())
currToken.addViewSourceChar('x');
@@ -1256,9 +1511,6 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
}
AtomicString tagName = currToken.tagName;
-#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 0
- kdDebug( 6036 ) << "appending Tag: " << tagName.deprecatedString() << endl;
-#endif
// Handle <script src="foo"/> like Mozilla/Opera. We have to do this now for Dashboard
// compatibility.
@@ -1269,26 +1521,24 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
scriptSrc = String();
scriptSrcCharset = String();
if (currToken.attrs && !m_fragment) {
- if (m_doc->frame() && m_doc->frame()->scriptProxy()->isEnabled()) {
+ if (m_doc->frame() && m_doc->frame()->script()->isEnabled()) {
if ((a = currToken.attrs->getAttributeItem(srcAttr)))
- scriptSrc = m_doc->completeURL(parseURL(a->value()));
- if ((a = currToken.attrs->getAttributeItem(charsetAttr)))
- scriptSrcCharset = a->value().domString().stripWhiteSpace();
- if (scriptSrcCharset.isEmpty())
- scriptSrcCharset = m_doc->frame()->loader()->encoding();
+ scriptSrc = m_doc->completeURL(parseURL(a->value())).string();
}
}
}
RefPtr<Node> n = processToken();
m_cBufferPos = cBufferPos;
- if (n) {
+ if (n || inViewSourceMode()) {
if ((tagName == preTag || tagName == listingTag) && !inViewSourceMode()) {
if (beginTag)
state.setDiscardLF(true); // Discard the first LF after we open a pre.
- } else if (tagName == scriptTag && n) {
+ } else if (tagName == scriptTag) {
ASSERT(!scriptNode);
scriptNode = n;
+ if (n)
+ scriptSrcCharset = static_cast<HTMLScriptElement*>(n.get())->scriptCharset();
if (beginTag) {
searchStopper = scriptEnd;
searchStopperLen = 8;
@@ -1342,6 +1592,13 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state)
state.setInXmp(true);
state = parseSpecial(src, state);
}
+ } else if (tagName == iframeTag) {
+ if (beginTag) {
+ searchStopper = iframeEnd;
+ searchStopperLen = 8;
+ state.setInIFrame(true);
+ state = parseSpecial(src, state);
+ }
}
}
if (tagName == plaintextTag)
@@ -1360,9 +1617,9 @@ inline bool HTMLTokenizer::continueProcessing(int& processedCount, double startT
// processed a certain number of characters.
bool allowedYield = state.allowYield();
state.setAllowYield(false);
- if (!state.loadingExtScript() && !state.forceSynchronous() && !m_executingScript && (processedCount > TOKENIZER_CHUNK_SIZE || allowedYield)) {
+ if (!state.loadingExtScript() && !state.forceSynchronous() && !m_executingScript && (processedCount > m_tokenizerChunkSize || allowedYield)) {
processedCount = 0;
- if (currentTime() - startTime > tokenizerTimeDelay) {
+ if (currentTime() - startTime > m_tokenizerTimeDelay) {
/* FIXME: We'd like to yield aggressively to give stylesheets the opportunity to
load, but this hurts overall performance on slower machines. For now turn this
off.
@@ -1371,7 +1628,7 @@ inline bool HTMLTokenizer::continueProcessing(int& processedCount, double startT
// Schedule the timer to keep processing as soon as possible.
m_timer.startOneShot(0);
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (currentTime() - startTime > tokenizerTimeDelay)
+ if (currentTime() - startTime > m_tokenizerTimeDelay)
printf("Deferring processing of data because 500ms elapsed away from event loop.\n");
#endif
return false;
@@ -1411,6 +1668,7 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
}
return false;
}
+
#if PRELOAD_SCANNER_ENABLED
if (m_preloadScanner && m_preloadScanner->inProgress() && appendData)
@@ -1469,6 +1727,8 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
state = parseSpecial(src, state);
else if (state.inComment())
state = parseComment(src, state);
+ else if (state.inDoctype())
+ state = parseDoctype(src, state);
else if (state.inServer())
state = parseServer(src, state);
else if (state.inProcessingInstruction())
@@ -1482,9 +1742,9 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
case '/':
break;
case '!': {
- // <!-- comment -->
- searchCount = 1; // Look for '<!--' sequence to start comment
-
+ // <!-- comment --> or <!DOCTYPE ...>
+ searchCount = 1; // Look for '<!--' sequence to start comment or '<!DOCTYPE' sequence to start doctype
+ m_doctypeSearchCount = 1;
break;
}
case '?': {
@@ -1531,6 +1791,7 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
tagStartLineno = m_lineNumber;
src.advancePastNonNewline();
state.setStartTag(true);
+ state.setDiscardLF(false);
} else if (cc == '\n' || cc == '\r') {
if (state.discardLF())
// Ignore this LF
@@ -1642,7 +1903,7 @@ void HTMLTokenizer::end()
void HTMLTokenizer::finish()
{
// do this as long as we don't find matching comment ends
- while((m_state.inComment() || m_state.inServer()) && scriptCode && scriptCodeSize) {
+ while ((m_state.inComment() || m_state.inServer()) && scriptCode && scriptCodeSize) {
// we've found an unmatched comment start
if (m_state.inComment())
brokenComments = true;
@@ -1653,13 +1914,13 @@ void HTMLTokenizer::finish()
scriptCode[scriptCodeSize + 1] = 0;
int pos;
String food;
- if (m_state.inScript() || m_state.inStyle())
+ if (m_state.inScript() || m_state.inStyle() || m_state.inTextArea())
food = String(scriptCode, scriptCodeSize);
else if (m_state.inServer()) {
food = "<";
- food.append(String(scriptCode, scriptCodeSize));
+ food.append(scriptCode, scriptCodeSize);
} else {
- pos = DeprecatedConstString(reinterpret_cast<DeprecatedChar*>(scriptCode), scriptCodeSize).string().find('>');
+ pos = find(scriptCode, scriptCodeSize, '>');
food = String(scriptCode + pos + 1, scriptCodeSize - pos - 1);
}
fastFree(scriptCode);
@@ -1679,55 +1940,27 @@ void HTMLTokenizer::finish()
PassRefPtr<Node> HTMLTokenizer::processToken()
{
- KJSProxy* jsProxy = (!m_fragment && m_doc->frame()) ? m_doc->frame()->scriptProxy() : 0;
- if (jsProxy && m_doc->frame()->scriptProxy()->isEnabled())
- jsProxy->setEventHandlerLineno(tagStartLineno);
+ ScriptController* jsProxy = (!m_fragment && m_doc->frame()) ? m_doc->frame()->script() : 0;
+ if (jsProxy && m_doc->frame()->script()->isEnabled())
+ jsProxy->setEventHandlerLineno(tagStartLineno + 1); // Script line numbers are 1 based.
if (dest > buffer) {
-#ifdef TOKEN_DEBUG
- if(currToken.tagName.length()) {
- qDebug( "unexpected token: %s, str: *%s*", currToken.tagName.deprecatedString().latin1(),DeprecatedConstString( buffer,dest-buffer ).deprecatedString().latin1() );
- ASSERT(0);
- }
-
-#endif
currToken.text = StringImpl::createStrippingNullCharacters(buffer, dest - buffer);
if (currToken.tagName != commentAtom)
currToken.tagName = textAtom;
} else if (currToken.tagName == nullAtom) {
currToken.reset();
if (jsProxy)
- jsProxy->setEventHandlerLineno(m_lineNumber);
+ jsProxy->setEventHandlerLineno(m_lineNumber + 1); // Script line numbers are 1 based.
return 0;
}
dest = buffer;
-#ifdef TOKEN_DEBUG
- DeprecatedString name = currToken.tagName.deprecatedString();
- DeprecatedString text;
- if(currToken.text)
- text = DeprecatedConstString(currToken.text->unicode(), currToken.text->length()).deprecatedString();
-
- kdDebug( 6036 ) << "Token --> " << name << endl;
- if (currToken.flat)
- kdDebug( 6036 ) << "Token is FLAT!" << endl;
- if(!text.isNull())
- kdDebug( 6036 ) << "text: \"" << text << "\"" << endl;
- unsigned l = currToken.attrs ? currToken.attrs->length() : 0;
- if(l) {
- kdDebug( 6036 ) << "Attributes: " << l << endl;
- for (unsigned i = 0; i < l; ++i) {
- Attribute* c = currToken.attrs->attributeItem(i);
- kdDebug( 6036 ) << " " << c->localName().deprecatedString()
- << "=\"" << c->value().deprecatedString() << "\"" << endl;
- }
- }
- kdDebug( 6036 ) << endl;
-#endif
-
RefPtr<Node> n;
if (!m_parserStopped) {
+ if (NamedMappedAttrMap* map = currToken.attrs.get())
+ map->shrinkToLength();
if (inViewSourceMode())
static_cast<HTMLViewSourceDocument*>(m_doc)->addViewSourceToken(&currToken);
else
@@ -1741,6 +1974,14 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
return n.release();
}
+void HTMLTokenizer::processDoctypeToken()
+{
+ if (inViewSourceMode())
+ static_cast<HTMLViewSourceDocument*>(m_doc)->addViewSourceDoctypeToken(&m_doctypeToken);
+ else
+ parser->parseDoctypeToken(&m_doctypeToken);
+}
+
HTMLTokenizer::~HTMLTokenizer()
{
ASSERT(!inWrite);
@@ -1782,33 +2023,26 @@ void HTMLTokenizer::notifyFinished(CachedResource*)
ASSERT(!pendingScripts.isEmpty());
- // Make scripts loaded from file URLs wait for stylesheets to match Tiger behavior where
- // file loads were serialized in lower level.
- // FIXME: this should really be done for all script loads or the same effect should be achieved by other
- // means, like javascript suspend/resume
- m_hasScriptsWaitingForStylesheets = !m_doc->haveStylesheetsLoaded() && pendingScripts.head()->url().startsWith("file:", false);
+ // Make external scripts wait for external stylesheets.
+ // FIXME: This needs to be done for inline scripts too.
+ m_hasScriptsWaitingForStylesheets = !m_doc->haveStylesheetsLoaded();
if (m_hasScriptsWaitingForStylesheets)
return;
bool finished = false;
- while (!finished && pendingScripts.head()->isLoaded()) {
-#ifdef TOKEN_DEBUG
- kdDebug( 6036 ) << "Finished loading an external script" << endl;
-#endif
- CachedScript* cs = pendingScripts.dequeue();
+ while (!finished && pendingScripts.first()->isLoaded()) {
+ CachedScript *cs = pendingScripts.first().get();
+ pendingScripts.removeFirst();
ASSERT(cache()->disabled() || cs->accessCount() > 0);
String scriptSource = cs->script();
-#ifdef TOKEN_DEBUG
- kdDebug( 6036 ) << "External script is:" << endl << scriptSource.deprecatedString() << endl;
-#endif
setSrc(SegmentedString());
// make sure we forget about the script before we execute the new one
// infinite recursion might happen otherwise
String cachedScriptUrl(cs->url());
bool errorOccurred = cs->errorOccurred();
- cs->deref(this);
+ cs->removeClient(this);
RefPtr<Node> n = scriptNode.release();
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -1817,11 +2051,11 @@ void HTMLTokenizer::notifyFinished(CachedResource*)
#endif
if (errorOccurred)
- EventTargetNodeCast(n.get())->dispatchHTMLEvent(errorEvent, true, false);
+ EventTargetNodeCast(n.get())->dispatchEventForType(eventNames().errorEvent, true, false);
else {
if (static_cast<HTMLScriptElement*>(n.get())->shouldExecuteAsJavaScript())
m_state = scriptExecution(scriptSource, m_state, cachedScriptUrl);
- EventTargetNodeCast(n.get())->dispatchHTMLEvent(loadEvent, false, false);
+ EventTargetNodeCast(n.get())->dispatchEventForType(eventNames().loadEvent, false, false);
}
// The state of pendingScripts.isEmpty() can change inside the scriptExecution()
diff --git a/WebCore/html/HTMLTokenizer.h b/WebCore/html/HTMLTokenizer.h
index 7657f95..0d175db 100644
--- a/WebCore/html/HTMLTokenizer.h
+++ b/WebCore/html/HTMLTokenizer.h
@@ -24,14 +24,15 @@
#ifndef HTMLTokenizer_h
#define HTMLTokenizer_h
-#include "DeprecatedPtrQueue.h"
+#include "CachedResourceClient.h"
+#include "CachedResourceHandle.h"
#include "NamedMappedAttrMap.h"
#include "SegmentedString.h"
#include "Timer.h"
#include "Tokenizer.h"
-#include "CachedResourceClient.h"
-#include <wtf/Vector.h>
+#include <wtf/Deque.h>
#include <wtf/OwnPtr.h>
+#include <wtf/Vector.h>
namespace WebCore {
@@ -43,9 +44,7 @@ class HTMLViewSourceDocument;
class FrameView;
class HTMLParser;
class Node;
-#ifdef ANDROID_PRELOAD_CHANGES
class PreloadScanner;
-#endif
/**
* @internal
@@ -86,6 +85,44 @@ public:
OwnPtr<Vector<UChar> > m_sourceInfo;
};
+enum DoctypeState {
+ DoctypeBegin,
+ DoctypeBeforeName,
+ DoctypeName,
+ DoctypeAfterName,
+ DoctypeBeforePublicID,
+ DoctypePublicID,
+ DoctypeAfterPublicID,
+ DoctypeBeforeSystemID,
+ DoctypeSystemID,
+ DoctypeAfterSystemID,
+ DoctypeBogus
+};
+
+class DoctypeToken {
+public:
+ DoctypeToken() {}
+
+ void reset()
+ {
+ m_name.clear();
+ m_publicID.clear();
+ m_systemID.clear();
+ m_state = DoctypeBegin;
+ m_source.clear();
+ }
+
+ DoctypeState state() { return m_state; }
+ void setState(DoctypeState s) { m_state = s; }
+
+ Vector<UChar> m_name;
+ Vector<UChar> m_publicID;
+ Vector<UChar> m_systemID;
+ DoctypeState m_state;
+
+ Vector<UChar> m_source;
+};
+
//-----------------------------------------------------------------------------
class HTMLTokenizer : public Tokenizer, public CachedResourceClient {
@@ -121,10 +158,13 @@ private:
void end();
void reset();
+
PassRefPtr<Node> processToken();
+ void processDoctypeToken();
State processListing(SegmentedString, State);
State parseComment(SegmentedString&, State);
+ State parseDoctype(SegmentedString&, State);
State parseServer(SegmentedString&, State);
State parseText(SegmentedString&, State);
State parseSpecial(SegmentedString&, State);
@@ -132,7 +172,7 @@ private:
State parseEntity(SegmentedString&, UChar*& dest, State, unsigned& _cBufferPos, bool start, bool parsingTag);
State parseProcessingInstruction(SegmentedString&, State);
State scriptHandler(State);
- State scriptExecution(const String& script, State, const String& scriptURL, int baseLine = 0);
+ State scriptExecution(const String& script, State, const String& scriptURL, int baseLine = 1);
void setSrc(const SegmentedString&);
// check if we have enough space in the buffer.
@@ -215,12 +255,16 @@ private:
void setInXmp(bool v) { setBit(InXmp, v); }
bool inTitle() const { return testBit(InTitle); }
void setInTitle(bool v) { setBit(InTitle, v); }
+ bool inIFrame() const { return testBit(InIFrame); }
+ void setInIFrame(bool v) { setBit(InIFrame, v); }
bool inPlainText() const { return testBit(InPlainText); }
void setInPlainText(bool v) { setBit(InPlainText, v); }
bool inProcessingInstruction() const { return testBit(InProcessingInstruction); }
void setInProcessingInstruction(bool v) { return setBit(InProcessingInstruction, v); }
bool inComment() const { return testBit(InComment); }
void setInComment(bool v) { setBit(InComment, v); }
+ bool inDoctype() const { return testBit(InDoctype); }
+ void setInDoctype(bool v) { setBit(InDoctype, v); }
bool inTextArea() const { return testBit(InTextArea); }
void setInTextArea(bool v) { setBit(InTextArea, v); }
bool escaped() const { return testBit(Escaped); }
@@ -240,11 +284,11 @@ private:
bool forceSynchronous() const { return testBit(ForceSynchronous); }
void setForceSynchronous(bool v) { setBit(ForceSynchronous, v); }
- bool inAnySpecial() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle); }
+ bool inAnySpecial() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle | InIFrame); }
bool hasTagState() const { return m_bits & TagMask; }
bool hasEntityState() const { return m_bits & EntityMask; }
- bool needsSpecialWriteHandling() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle | TagMask | EntityMask | InPlainText | InComment | InServer | InProcessingInstruction | StartTag); }
+ bool needsSpecialWriteHandling() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle | InIFrame | TagMask | EntityMask | InPlainText | InComment | InDoctype | InServer | InProcessingInstruction | StartTag); }
private:
static const int EntityShift = 4;
@@ -267,7 +311,9 @@ private:
DiscardLF = 1 << 20, // FIXME: should clarify difference between skip and discard
AllowYield = 1 << 21,
LoadingExtScript = 1 << 22,
- ForceSynchronous = 1 << 23
+ ForceSynchronous = 1 << 23,
+ InIFrame = 1 << 24,
+ InDoctype = 1 << 25
};
void setBit(StateBits bit, bool value)
@@ -283,13 +329,17 @@ private:
};
State m_state;
+
+ DoctypeToken m_doctypeToken;
+ int m_doctypeSearchCount;
+ int m_doctypeSecondarySearchCount;
bool brokenServer;
// Name of an attribute that we just scanned.
AtomicString attrName;
- // Used to store the code of a srcipting sequence
+ // Used to store the code of a scripting sequence
UChar* scriptCode;
// Size of the script sequenze stored in @ref #scriptCode
int scriptCodeSize;
@@ -300,14 +350,14 @@ private:
// Stores characters if we are scanning for a string like "</script>"
UChar searchBuffer[10];
+
// Counts where we are in the string we are scanning for
int searchCount;
- // The string we are searching for
- const UChar* searchFor;
// the stopper string
const char* searchStopper;
// the stopper len
int searchStopperLen;
+
// if no more data is coming, just parse what we have (including ext scripts that
// may be still downloading) and finish
bool noMoreData;
@@ -324,7 +374,7 @@ private:
// true if we are executing a script while parsing a document. This causes the parsing of
// the output of the script to be postponed until after the script has finished executing
int m_executingScript;
- DeprecatedPtrQueue<CachedScript> pendingScripts;
+ Deque<CachedResourceHandle<CachedScript> > pendingScripts;
RefPtr<Node> scriptNode;
bool m_requestingScript;
@@ -339,6 +389,9 @@ private:
int scriptStartLineno;
int tagStartLineno;
+ double m_tokenizerTimeDelay;
+ int m_tokenizerChunkSize;
+
// The timer for continued processing.
Timer<HTMLTokenizer> m_timer;
@@ -355,9 +408,7 @@ private:
bool inWrite;
bool m_fragment;
-#ifdef ANDROID_PRELOAD_CHANGES
OwnPtr<PreloadScanner> m_preloadScanner;
-#endif
};
void parseHTMLDocumentFragment(const String&, DocumentFragment*);
diff --git a/WebCore/html/HTMLUListElement.cpp b/WebCore/html/HTMLUListElement.cpp
index b1d1125..4557294 100644
--- a/WebCore/html/HTMLUListElement.cpp
+++ b/WebCore/html/HTMLUListElement.cpp
@@ -48,7 +48,7 @@ bool HTMLUListElement::mapToEntry(const QualifiedName& attrName, MappedAttribute
void HTMLUListElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == typeAttr)
- addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, attr->value());
+ addCSSProperty(attr, CSSPropertyListStyleType, attr->value());
else
HTMLElement::parseMappedAttribute(attr);
}
diff --git a/WebCore/html/HTMLVideoElement.cpp b/WebCore/html/HTMLVideoElement.cpp
index 4a2b2c9..2fb4a19 100644
--- a/WebCore/html/HTMLVideoElement.cpp
+++ b/WebCore/html/HTMLVideoElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -83,7 +83,7 @@ void HTMLVideoElement::detach()
m_imageLoader.clear();
}
-void HTMLVideoElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLVideoElement::parseMappedAttribute(MappedAttribute* attr)
{
const QualifiedName& attrName = attr->name();
@@ -95,52 +95,52 @@ void HTMLVideoElement::parseMappedAttribute(MappedAttribute *attr)
m_imageLoader->updateFromElement();
}
} else if (attrName == widthAttr)
- addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
+ addCSSLength(attr, CSSPropertyWidth, attr->value());
else if (attrName == heightAttr)
- addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
+ addCSSLength(attr, CSSPropertyHeight, attr->value());
else
HTMLMediaElement::parseMappedAttribute(attr);
}
-int HTMLVideoElement::videoWidth() const
+unsigned HTMLVideoElement::videoWidth() const
{
if (!m_player)
return 0;
return m_player->naturalSize().width();
}
-int HTMLVideoElement::videoHeight() const
+unsigned HTMLVideoElement::videoHeight() const
{
if (!m_player)
return 0;
return m_player->naturalSize().height();
}
-int HTMLVideoElement::width() const
+unsigned HTMLVideoElement::width() const
{
bool ok;
- int w = getAttribute(widthAttr).toInt(&ok);
+ unsigned w = getAttribute(widthAttr).string().toUInt(&ok);
return ok ? w : 0;
}
-void HTMLVideoElement::setWidth(int value)
+void HTMLVideoElement::setWidth(unsigned value)
{
setAttribute(widthAttr, String::number(value));
}
-int HTMLVideoElement::height() const
+unsigned HTMLVideoElement::height() const
{
bool ok;
- int h = getAttribute(heightAttr).toInt(&ok);
+ unsigned h = getAttribute(heightAttr).string().toUInt(&ok);
return ok ? h : 0;
}
-void HTMLVideoElement::setHeight(int value)
+void HTMLVideoElement::setHeight(unsigned value)
{
setAttribute(heightAttr, String::number(value));
}
-String HTMLVideoElement::poster() const
+KURL HTMLVideoElement::poster() const
{
return document()->completeURL(getAttribute(posterAttr));
}
@@ -150,7 +150,7 @@ void HTMLVideoElement::setPoster(const String& value)
setAttribute(posterAttr, value);
}
-bool HTMLVideoElement::isURLAttribute(Attribute *attr) const
+bool HTMLVideoElement::isURLAttribute(Attribute* attr) const
{
return attr->name() == posterAttr;
}
diff --git a/WebCore/html/HTMLVideoElement.h b/WebCore/html/HTMLVideoElement.h
index 8d9be2c..e424e3d 100644
--- a/WebCore/html/HTMLVideoElement.h
+++ b/WebCore/html/HTMLVideoElement.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,15 +50,15 @@ public:
virtual bool isURLAttribute(Attribute*) const;
virtual const QualifiedName& imageSourceAttributeName() const;
- int width() const;
- void setWidth(int);
- int height() const;
- void setHeight(int);
+ unsigned width() const;
+ void setWidth(unsigned);
+ unsigned height() const;
+ void setHeight(unsigned);
- int videoWidth() const;
- int videoHeight() const;
+ unsigned videoWidth() const;
+ unsigned videoHeight() const;
- String poster() const;
+ KURL poster() const;
void setPoster(const String&);
void updatePosterImage();
diff --git a/WebCore/html/HTMLVideoElement.idl b/WebCore/html/HTMLVideoElement.idl
index fa8aad0..c78594f 100644
--- a/WebCore/html/HTMLVideoElement.idl
+++ b/WebCore/html/HTMLVideoElement.idl
@@ -25,8 +25,8 @@
module html {
interface [GenerateConstructor, Conditional=VIDEO] HTMLVideoElement : HTMLMediaElement {
- attribute long width;
- attribute long height;
+ attribute unsigned long width;
+ attribute unsigned long height;
readonly attribute unsigned long videoWidth;
readonly attribute unsigned long videoHeight;
attribute [ConvertNullToNullString] DOMString poster;
diff --git a/WebCore/html/HTMLViewSourceDocument.cpp b/WebCore/html/HTMLViewSourceDocument.cpp
index 10c7a6d..7b141d1 100644
--- a/WebCore/html/HTMLViewSourceDocument.cpp
+++ b/WebCore/html/HTMLViewSourceDocument.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,8 +23,9 @@
*/
#include "config.h"
-#include "DOMImplementation.h"
#include "HTMLViewSourceDocument.h"
+
+#include "DOMImplementation.h"
#include "HTMLTokenizer.h"
#include "HTMLHtmlElement.h"
#include "HTMLAnchorElement.h"
@@ -38,13 +39,12 @@
#include "TextDocument.h"
#include "HTMLNames.h"
-namespace WebCore
-{
+namespace WebCore {
using namespace HTMLNames;
-HTMLViewSourceDocument::HTMLViewSourceDocument(DOMImplementation* implementation, Frame* frame, const String& mimeType)
- : HTMLDocument(implementation, frame)
+HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const String& mimeType)
+ : HTMLDocument(frame)
, m_type(mimeType)
, m_current(0)
, m_tbody(0)
@@ -55,30 +55,29 @@ HTMLViewSourceDocument::HTMLViewSourceDocument(DOMImplementation* implementation
Tokenizer* HTMLViewSourceDocument::createTokenizer()
{
if (implementation()->isTextMIMEType(m_type))
- return new TextTokenizer(this);
+ return createTextTokenizer(this);
return new HTMLTokenizer(this);
}
void HTMLViewSourceDocument::createContainingTable()
{
- Element* html = new HTMLHtmlElement(this);
+ RefPtr<Element> html = new HTMLHtmlElement(this);
addChild(html);
html->attach();
- Element* body = new HTMLBodyElement(this);
+ RefPtr<Element> body = new HTMLBodyElement(this);
html->addChild(body);
body->attach();
// Create a line gutter div that can be used to make sure the gutter extends down the height of the whole
// document.
- Element* div = new HTMLDivElement(this);
- Attribute* a = new MappedAttribute(classAttr, "webkit-line-gutter-backdrop");
- NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
- attrs->insertAttribute(a, true);
- div->setAttributeMap(attrs);
+ RefPtr<Element> div = new HTMLDivElement(this);
+ RefPtr<NamedMappedAttrMap> attrs = NamedMappedAttrMap::create();
+ attrs->insertAttribute(MappedAttribute::create(classAttr, "webkit-line-gutter-backdrop"), true);
+ div->setAttributeMap(attrs.release());
body->addChild(div);
div->attach();
- Element* table = new HTMLTableElement(this);
+ RefPtr<Element> table = new HTMLTableElement(this);
body->addChild(table);
table->attach();
m_tbody = new HTMLTableSectionElement(tbodyTag, this);
@@ -108,9 +107,7 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
}
} else {
// Handle the tag.
- bool doctype = token->tagName.startsWith("!DOCTYPE", false);
-
- String classNameStr = doctype ? "webkit-html-doctype" : "webkit-html-tag";
+ String classNameStr = "webkit-html-tag";
m_current = addSpanWithClassName(classNameStr);
String text = "<";
@@ -128,11 +125,11 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
unsigned size = guide->size();
unsigned begin = 0;
unsigned currAttr = 0;
- Attribute* attr = 0;
+ RefPtr<Attribute> attr = 0;
for (unsigned i = 0; i < size; i++) {
if (guide->at(i) == 'a' || guide->at(i) == 'x' || guide->at(i) == 'v') {
// Add in the string.
- addText(String((UChar*)(guide->data()) + begin, i - begin), classNameStr);
+ addText(String(static_cast<UChar*>(guide->data()) + begin, i - begin), classNameStr);
begin = i + 1;
@@ -145,28 +142,21 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
if (attr) {
if (guide->at(i) == 'a') {
String name = attr->name().toString();
- if (doctype)
- addText(name, "webkit-html-doctype");
- else {
- m_current = addSpanWithClassName("webkit-html-attribute-name");
- addText(name, "webkit-html-attribute-name");
- if (m_current != m_tbody)
- m_current = static_cast<Element*>(m_current->parent());
- }
+
+ m_current = addSpanWithClassName("webkit-html-attribute-name");
+ addText(name, "webkit-html-attribute-name");
+ if (m_current != m_tbody)
+ m_current = static_cast<Element*>(m_current->parent());
} else {
- String value = attr->value().domString();
- if (doctype)
- addText(value, "webkit-html-doctype");
- else {
- // 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"));
- else
- m_current = addSpanWithClassName("webkit-html-attribute-value");
- addText(value, "webkit-html-attribute-value");
- if (m_current != m_tbody)
- m_current = static_cast<Element*>(m_current->parent());
- }
+ const String& value = attr->value().string();
+ // 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"));
+ else
+ m_current = addSpanWithClassName("webkit-html-attribute-value");
+ addText(value, "webkit-html-attribute-value");
+ if (m_current != m_tbody)
+ m_current = static_cast<Element*>(m_current->parent());
}
}
}
@@ -174,7 +164,7 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
// Add in any string that might be left.
if (begin < size)
- addText(String((UChar*)(guide->data()) + begin, size - begin), classNameStr);
+ addText(String(static_cast<UChar*>(guide->data()) + begin, size - begin), classNameStr);
// Add in the end tag.
addText(">", classNameStr);
@@ -184,6 +174,17 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token)
}
}
+void HTMLViewSourceDocument::addViewSourceDoctypeToken(DoctypeToken* doctypeToken)
+{
+ if (!m_current)
+ createContainingTable();
+ m_current = addSpanWithClassName("webkit-html-doctype");
+ String text = "<";
+ text += String::adopt(doctypeToken->m_source);
+ text += ">";
+ addText(text, "webkit-html-doctype");
+}
+
Element* HTMLViewSourceDocument::addSpanWithClassName(const String& className)
{
if (m_current == m_tbody) {
@@ -192,10 +193,9 @@ Element* HTMLViewSourceDocument::addSpanWithClassName(const String& className)
}
Element* span = new HTMLElement(spanTag, this);
- Attribute* a = new MappedAttribute(classAttr, className);
- NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
- attrs->insertAttribute(a, true);
- span->setAttributeMap(attrs);
+ RefPtr<NamedMappedAttrMap> attrs = NamedMappedAttrMap::create();
+ attrs->insertAttribute(MappedAttribute::create(classAttr, className), true);
+ span->setAttributeMap(attrs.release());
m_current->addChild(span);
span->attach();
return span;
@@ -204,32 +204,29 @@ Element* HTMLViewSourceDocument::addSpanWithClassName(const String& className)
void HTMLViewSourceDocument::addLine(const String& className)
{
// Create a table row.
- Element* trow = new HTMLTableRowElement(this);
+ RefPtr<Element> trow = new HTMLTableRowElement(this);
m_tbody->addChild(trow);
trow->attach();
// Create a cell that will hold the line number (it is generated in the stylesheet using counters).
Element* td = new HTMLTableCellElement(tdTag, this);
- Attribute* classNameAttr = new MappedAttribute(classAttr, "webkit-line-number");
- NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
- attrs->insertAttribute(classNameAttr, true);
-
- td->setAttributeMap(attrs);
+ RefPtr<NamedMappedAttrMap> attrs = NamedMappedAttrMap::create();
+ attrs->insertAttribute(MappedAttribute::create(classAttr, "webkit-line-number"), true);
+ td->setAttributeMap(attrs.release());
trow->addChild(td);
td->attach();
// Create a second cell for the line contents
td = new HTMLTableCellElement(tdTag, this);
- classNameAttr = new MappedAttribute(classAttr, "webkit-line-content");
- attrs = new NamedMappedAttrMap(0);
- attrs->insertAttribute(classNameAttr, true);
- td->setAttributeMap(attrs);
+ attrs = NamedMappedAttrMap::create();
+ attrs->insertAttribute(MappedAttribute::create(classAttr, "webkit-line-content"), true);
+ td->setAttributeMap(attrs.release());
trow->addChild(td);
td->attach();
m_current = m_td = td;
#ifdef DEBUG_LINE_NUMBERS
- Text* lineNumberText = new Text(this, String::number(tokenizer()->lineNumber() + 1) + " ");
+ RefPtr<Text> lineNumberText = new Text(this, String::number(tokenizer()->lineNumber() + 1) + " ");
td->addChild(lineNumberText);
lineNumberText->attach();
#endif
@@ -248,7 +245,8 @@ void HTMLViewSourceDocument::addText(const String& text, const String& className
return;
// Add in the content, splitting on newlines.
- Vector<String> lines = text.split('\n', true);
+ Vector<String> lines;
+ text.split('\n', true, lines);
unsigned size = lines.size();
for (unsigned i = 0; i < size; i++) {
String substring = lines[i];
@@ -259,7 +257,7 @@ void HTMLViewSourceDocument::addText(const String& text, const String& className
}
if (m_current == m_tbody)
addLine(className);
- Text* t = new Text(this, substring);
+ RefPtr<Text> t = new Text(this, substring);
m_current->addChild(t);
t->attach();
if (i < size - 1)
@@ -278,19 +276,16 @@ Element* HTMLViewSourceDocument::addLink(const String& url, bool isAnchor)
// Now create a link for the attribute value instead of a span.
Element* anchor = new HTMLAnchorElement(aTag, this);
- NamedMappedAttrMap* attrs = new NamedMappedAttrMap(0);
- String classValueStr("webkit-html-attribute-value");
+ RefPtr<NamedMappedAttrMap> attrs = NamedMappedAttrMap::create();
+ const char* classValue;
if (isAnchor)
- classValueStr += " webkit-html-external-link";
+ classValue = "webkit-html-attribute-value webkit-html-external-link";
else
- classValueStr += " webkit-html-resource-link";
- Attribute* classAttribute = new MappedAttribute(classAttr, classValueStr);
- attrs->insertAttribute(classAttribute, true);
- Attribute* targetAttribute = new MappedAttribute(targetAttr, "_blank");
- attrs->insertAttribute(targetAttribute, true);
- Attribute* hrefAttribute = new MappedAttribute(hrefAttr, url);
- attrs->insertAttribute(hrefAttribute, true);
- anchor->setAttributeMap(attrs);
+ classValue = "webkit-html-attribute-value webkit-html-resource-link";
+ attrs->insertAttribute(MappedAttribute::create(classAttr, classValue), true);
+ attrs->insertAttribute(MappedAttribute::create(targetAttr, "_blank"), true);
+ attrs->insertAttribute(MappedAttribute::create(hrefAttr, url), true);
+ anchor->setAttributeMap(attrs.release());
m_current->addChild(anchor);
anchor->attach();
return anchor;
diff --git a/WebCore/html/HTMLViewSourceDocument.h b/WebCore/html/HTMLViewSourceDocument.h
index efbbf9e..99c1ee4 100644
--- a/WebCore/html/HTMLViewSourceDocument.h
+++ b/WebCore/html/HTMLViewSourceDocument.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -21,6 +21,7 @@
* (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 HTMLViewSourceDocument_h
#define HTMLViewSourceDocument_h
@@ -28,26 +29,31 @@
namespace WebCore {
+class DoctypeToken;
class Token;
-class HTMLViewSourceDocument : public HTMLDocument
-{
+class HTMLViewSourceDocument : public HTMLDocument {
public:
- HTMLViewSourceDocument(DOMImplementation*, Frame*, const String& mimeType);
+ static PassRefPtr<HTMLViewSourceDocument> create(Frame* frame, const String& mimeType)
+ {
+ return new HTMLViewSourceDocument(frame, mimeType);
+ }
virtual Tokenizer* createTokenizer();
void addViewSourceToken(Token*); // Used by the HTML tokenizer.
void addViewSourceText(const String&); // Used by the plaintext tokenizer.
-
+ void addViewSourceDoctypeToken(DoctypeToken*);
+
private:
+ HTMLViewSourceDocument(Frame*, const String& mimeType);
+
void createContainingTable();
Element* addSpanWithClassName(const String&);
void addLine(const String& className);
void addText(const String& text, const String& className);
Element* addLink(const String& url, bool isAnchor);
-private:
String m_type;
Element* m_current;
Element* m_tbody;
diff --git a/WebCore/html/ImageData.cpp b/WebCore/html/ImageData.cpp
new file mode 100644
index 0000000..3653031
--- /dev/null
+++ b/WebCore/html/ImageData.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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.
+ */
+
+#include "config.h"
+#include "ImageData.h"
+
+#include "CanvasPixelArray.h"
+
+namespace WebCore {
+
+PassRefPtr<ImageData> ImageData::create(unsigned width, unsigned height)
+{
+ return adoptRef(new ImageData(width, height));
+}
+
+ImageData::ImageData(unsigned width, unsigned height)
+ : m_width(width)
+ , m_height(height)
+ , m_data(CanvasPixelArray::create(width * height * 4))
+{
+}
+
+}
+
diff --git a/WebCore/html/ImageData.h b/WebCore/html/ImageData.h
new file mode 100644
index 0000000..21af1f9
--- /dev/null
+++ b/WebCore/html/ImageData.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 ImageData_h
+#define ImageData_h
+
+#include "CanvasPixelArray.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class ImageData : public RefCounted<ImageData> {
+ public:
+ static PassRefPtr<ImageData> create(unsigned width, unsigned height);
+
+ unsigned width() const { return m_width; }
+ unsigned height() const { return m_height; }
+ CanvasPixelArray* data() const { return m_data.get(); }
+
+ private:
+ ImageData(unsigned width, unsigned height);
+ unsigned m_width;
+ unsigned m_height;
+ RefPtr<CanvasPixelArray> m_data;
+ };
+
+} // namespace WebCore
+
+#endif // ImageData_h
diff --git a/WebCore/html/ImageData.idl b/WebCore/html/ImageData.idl
new file mode 100644
index 0000000..246632f
--- /dev/null
+++ b/WebCore/html/ImageData.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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.
+ */
+
+module html {
+
+ interface [
+ GenerateConstructor,
+ GenerateToJS
+ ] ImageData {
+ readonly attribute long width;
+ readonly attribute long height;
+ readonly attribute CanvasPixelArray data;
+ };
+
+}
diff --git a/WebCore/html/MediaError.h b/WebCore/html/MediaError.h
index 33a2a70..fbf375f 100644
--- a/WebCore/html/MediaError.h
+++ b/WebCore/html/MediaError.h
@@ -36,10 +36,13 @@ class MediaError : public RefCounted<MediaError> {
public:
enum Code { MEDIA_ERR_ABORTED = 1, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE };
- MediaError(Code code) { m_code = code; }
+ static PassRefPtr<MediaError> create(Code code) { return adoptRef(new MediaError(code)); }
+
Code code() const { return m_code; }
private:
+ MediaError(Code code) : m_code(code) { }
+
Code m_code;
};
diff --git a/WebCore/html/PreloadScanner.cpp b/WebCore/html/PreloadScanner.cpp
index f7fb27d..1580230 100644
--- a/WebCore/html/PreloadScanner.cpp
+++ b/WebCore/html/PreloadScanner.cpp
@@ -1,37 +1,32 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 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.
*
- * 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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.
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-#ifdef ANDROID_PRELOAD_CHANGES
#include "PreloadScanner.h"
#include "AtomicString.h"
-#include "Cache.h"
#include "CachedCSSStyleSheet.h"
#include "CachedImage.h"
#include "CachedResource.h"
@@ -46,6 +41,7 @@
#include "HTMLLinkElement.h"
#include "HTMLNames.h"
#include "SystemTime.h"
+#include <wtf/unicode/Unicode.h>
#ifdef __GNUC__
// The main tokenizer includes this too so we are getting two copies of the data. However, this way the code gets inlined.
@@ -61,6 +57,8 @@ const struct Entity* findEntity(register const char* str, register unsigned int
#define PRELOAD_DEBUG 0
+using namespace WTF;
+
namespace WebCore {
using namespace HTMLNames;
@@ -123,7 +121,7 @@ void PreloadScanner::reset()
m_cssRuleValue.clear();
}
-bool PreloadScanner::inBody() const
+bool PreloadScanner::scanningBody() const
{
return m_document->body() || m_bodySeen;
}
@@ -352,11 +350,13 @@ void PreloadScanner::tokenize(const SegmentedString& source)
m_state = CloseTagOpen;
else if (cc >= 'A' && cc <= 'Z') {
m_tagName.clear();
+ m_charset = String();
m_tagName.append(cc + 0x20);
m_closeTag = false;
m_state = TagName;
} else if (cc >= 'a' && cc <= 'z') {
m_tagName.clear();
+ m_charset = String();
m_tagName.append(cc);
m_closeTag = false;
m_state = TagName;
@@ -382,7 +382,7 @@ void PreloadScanner::tokenize(const SegmentedString& source)
UChar tmpChar = 0;
bool match = true;
for (unsigned n = 0; n < m_lastStartTag.length() + 1; n++) {
- tmpChar = u_tolower(*m_source);
+ tmpChar = Unicode::toLower(*m_source);
if (n < m_lastStartTag.length() && tmpChar != m_lastStartTag[n])
match = false;
tmpString.append(tmpChar);
@@ -396,11 +396,13 @@ void PreloadScanner::tokenize(const SegmentedString& source)
}
if (cc >= 'A' && cc <= 'Z') {
m_tagName.clear();
+ m_charset = String();
m_tagName.append(cc + 0x20);
m_closeTag = true;
m_state = TagName;
} else if (cc >= 'a' && cc <= 'z') {
m_tagName.clear();
+ m_charset = String();
m_tagName.append(cc);
m_closeTag = true;
m_state = TagName;
@@ -698,8 +700,9 @@ void PreloadScanner::processAttribute()
bool styleSheet = false;
bool alternate = false;
bool icon = false;
- HTMLLinkElement::tokenizeRelAttribute(value, styleSheet, alternate, icon);
- m_linkIsStyleSheet = styleSheet && !alternate && !icon;
+ bool dnsPrefetch = false;
+ HTMLLinkElement::tokenizeRelAttribute(value, styleSheet, alternate, icon, dnsPrefetch);
+ m_linkIsStyleSheet = styleSheet && !alternate && !icon && !dnsPrefetch;
} else if (attribute == charsetAttr)
m_charset = value;
}
@@ -823,11 +826,11 @@ void PreloadScanner::emitTag()
}
if (tag == scriptTag)
- m_document->docLoader()->preload(CachedResource::Script, m_urlToLoad, m_charset, inBody());
+ m_document->docLoader()->preload(CachedResource::Script, m_urlToLoad, m_charset, scanningBody());
else if (tag == imgTag)
- m_document->docLoader()->preload(CachedResource::ImageResource, m_urlToLoad, String(), inBody());
+ m_document->docLoader()->preload(CachedResource::ImageResource, m_urlToLoad, String(), scanningBody());
else if (tag == linkTag && m_linkIsStyleSheet)
- m_document->docLoader()->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, inBody());
+ m_document->docLoader()->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, scanningBody());
m_urlToLoad = String();
m_charset = String();
@@ -837,15 +840,14 @@ void PreloadScanner::emitTag()
void PreloadScanner::emitCSSRule()
{
String rule(m_cssRule.data(), m_cssRule.size());
- if (rule.lower() == "import" && !m_cssRuleValue.isEmpty()) {
+ if (equalIgnoringCase(rule, "import") && !m_cssRuleValue.isEmpty()) {
String value(m_cssRuleValue.data(), m_cssRuleValue.size());
String url = parseURL(value);
if (!url.isEmpty())
- m_document->docLoader()->preload(CachedResource::CSSStyleSheet, url, String(), inBody());
+ m_document->docLoader()->preload(CachedResource::CSSStyleSheet, url, String(), scanningBody());
}
m_cssRule.clear();
m_cssRuleValue.clear();
}
}
-#endif //ANDROID_PRELOAD_CHANGES
diff --git a/WebCore/html/PreloadScanner.h b/WebCore/html/PreloadScanner.h
index 8ef5d1a..b5908cf 100644
--- a/WebCore/html/PreloadScanner.h
+++ b/WebCore/html/PreloadScanner.h
@@ -1,32 +1,28 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 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.
*
- * 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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.
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#ifndef PreloadScanner_h
#define PreloadScanner_h
@@ -50,7 +46,7 @@ namespace WebCore {
void end();
bool inProgress() const { return m_inProgress; }
- bool inBody() const;
+ bool scanningBody() const;
static unsigned consumeEntity(SegmentedString&, bool& notEnoughCharacters);
diff --git a/WebCore/html/TextMetrics.h b/WebCore/html/TextMetrics.h
new file mode 100644
index 0000000..34a3378
--- /dev/null
+++ b/WebCore/html/TextMetrics.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 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 INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TextMetrics_h
+#define TextMetrics_h
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class TextMetrics : public RefCounted<TextMetrics> {
+public:
+ static PassRefPtr<TextMetrics> create() { return adoptRef(new TextMetrics); }
+
+ unsigned width() const { return m_width; }
+ void setWidth(float w) { m_width = w; }
+
+private:
+ TextMetrics()
+ : m_width(0)
+ { }
+
+ float m_width;
+};
+
+} // namespace WebCore
+
+#endif // TextMetrics_h
diff --git a/WebCore/html/TextMetrics.idl b/WebCore/html/TextMetrics.idl
new file mode 100644
index 0000000..dc88716
--- /dev/null
+++ b/WebCore/html/TextMetrics.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 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 INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ GenerateConstructor
+ ] TextMetrics {
+ readonly attribute float width;
+ };
+
+}
diff --git a/WebCore/html/TimeRanges.h b/WebCore/html/TimeRanges.h
index 16b0c25..eb54f6b 100644
--- a/WebCore/html/TimeRanges.h
+++ b/WebCore/html/TimeRanges.h
@@ -27,6 +27,7 @@
#define TimeRanges_h
#include "ExceptionCode.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
@@ -34,9 +35,15 @@ namespace WebCore {
class TimeRanges : public RefCounted<TimeRanges> {
public:
- TimeRanges() { }
- TimeRanges(float start, float end);
-
+ static PassRefPtr<TimeRanges> create()
+ {
+ return adoptRef(new TimeRanges);
+ }
+ static PassRefPtr<TimeRanges> create(float start, float end)
+ {
+ return adoptRef(new TimeRanges(start, end));
+ }
+
unsigned length() const { return m_ranges.size(); }
float start(unsigned index, ExceptionCode&) const;
float end(unsigned index, ExceptionCode&) const;
@@ -46,6 +53,9 @@ public:
bool contain(float time) const;
private:
+ TimeRanges() { }
+ TimeRanges(float start, float end);
+
struct Range {
Range() { }
Range(float start, float end) {
diff --git a/WebCore/html/VoidCallback.h b/WebCore/html/VoidCallback.h
index 478e2fc..c220411 100644
--- a/WebCore/html/VoidCallback.h
+++ b/WebCore/html/VoidCallback.h
@@ -32,10 +32,12 @@ namespace WebCore {
class VoidCallback : public RefCounted<VoidCallback> {
public:
- VoidCallback() { }
virtual ~VoidCallback() { }
virtual void handleEvent() = 0;
+
+protected:
+ VoidCallback() {}
};
} // namespace WebCore