diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 9364f22aed35e1a1e9d07c121510f80be3ab0502 (patch) | |
tree | d49911209b132da58d838efa852daf28d516df21 /WebCore/html | |
parent | 87eb0cb35bad8784770ebc807e6c982432e47107 (diff) | |
download | external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.zip external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.gz external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.bz2 |
Initial Contribution
Diffstat (limited to 'WebCore/html')
87 files changed, 2571 insertions, 1350 deletions
diff --git a/WebCore/html/CanvasGradient.cpp b/WebCore/html/CanvasGradient.cpp index bed5f01..e3e3726 100644 --- a/WebCore/html/CanvasGradient.cpp +++ b/WebCore/html/CanvasGradient.cpp @@ -37,23 +37,40 @@ #include <cairo.h> #endif +#ifdef ANDROID_CANVAS_IMPL +#include "GraphicsContext.h" +#include "SkColorShader.h" +#endif + namespace WebCore { CanvasGradient::CanvasGradient(const FloatPoint& p0, const FloatPoint& p1) - : RefCounted<CanvasGradient>(0) - , m_radial(false), m_p0(p0), m_p1(p1), m_stopsSorted(false), m_lastStop(0) -#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(CAIRO) + : 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 { } CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1) - : RefCounted<CanvasGradient>(0) - , m_radial(true), m_p0(p0), m_p1(p1), m_r0(r0), m_r1(r1), m_stopsSorted(false), m_lastStop(0) -#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(CAIRO) + : 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 { } @@ -66,6 +83,10 @@ CanvasGradient::~CanvasGradient() #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) @@ -244,4 +265,32 @@ int CanvasGradient::findStop(float value) const 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; +} +#endif + } //namespace diff --git a/WebCore/html/CanvasGradient.h b/WebCore/html/CanvasGradient.h index b6680a9..2648599 100644 --- a/WebCore/html/CanvasGradient.h +++ b/WebCore/html/CanvasGradient.h @@ -31,6 +31,10 @@ #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) @@ -53,6 +57,10 @@ namespace WebCore { 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) @@ -89,6 +97,10 @@ namespace WebCore { #elif PLATFORM(CAIRO) cairo_pattern_t* m_shading; #endif + +#ifdef ANDROID_CANVAS_IMPL + PlatformGradient* m_platformGradient; +#endif }; } //namespace diff --git a/WebCore/html/CanvasPattern.cpp b/WebCore/html/CanvasPattern.cpp index bc39d1a..585fc62 100644 --- a/WebCore/html/CanvasPattern.cpp +++ b/WebCore/html/CanvasPattern.cpp @@ -66,8 +66,7 @@ void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool& #if PLATFORM(CG) CanvasPattern::CanvasPattern(CGImageRef image, bool repeatX, bool repeatY) - : RefCounted<CanvasPattern>(0) - , m_platformImage(image) + : m_platformImage(image) , m_cachedImage(0) , m_repeatX(repeatX) , m_repeatY(repeatY) @@ -77,8 +76,7 @@ CanvasPattern::CanvasPattern(CGImageRef image, bool repeatX, bool repeatY) #elif PLATFORM(CAIRO) CanvasPattern::CanvasPattern(cairo_surface_t* surface, bool repeatX, bool repeatY) - : RefCounted<CanvasPattern>(0) - , m_platformImage(cairo_surface_reference(surface)) + : m_platformImage(cairo_surface_reference(surface)) , m_cachedImage(0) , m_repeatX(repeatX) , m_repeatY(repeatY) @@ -88,13 +86,17 @@ CanvasPattern::CanvasPattern(cairo_surface_t* surface, bool repeatX, bool repeat #endif CanvasPattern::CanvasPattern(CachedImage* cachedImage, bool repeatX, bool repeatY) - : RefCounted<CanvasPattern>(0) + : #if PLATFORM(CG) || PLATFORM(CAIRO) - , m_platformImage(0) + m_platformImage(0) + , #endif - , m_cachedImage(cachedImage) + m_cachedImage(cachedImage) , m_repeatX(repeatX) , m_repeatY(repeatY) +#ifdef ANDROID_CANVAS_IMPL + , m_platformPattern(NULL) +#endif { if (cachedImage) cachedImage->ref(this); @@ -102,6 +104,10 @@ CanvasPattern::CanvasPattern(CachedImage* cachedImage, bool repeatX, bool repeat 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); @@ -211,4 +217,25 @@ cairo_pattern_t* CanvasPattern::createPattern(const cairo_matrix_t& m) #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() +{ + 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 4990776..d74dc8a 100644 --- a/WebCore/html/CanvasPattern.h +++ b/WebCore/html/CanvasPattern.h @@ -29,6 +29,9 @@ #include "CachedResourceClient.h" #include <wtf/RefCounted.h> +#ifdef ANDROID_CANVAS_IMPL + #include "PlatformGraphics.h" +#endif #if PLATFORM(CG) #include <wtf/RetainPtr.h> #include <ApplicationServices/ApplicationServices.h> @@ -68,6 +71,10 @@ namespace WebCore { cairo_pattern_t* createPattern(const cairo_matrix_t&); #endif +#ifdef ANDROID_CANVAS_IMPL + PlatformPattern* platformPattern(); +#endif + private: #if PLATFORM(CG) const RetainPtr<CGImageRef> m_platformImage; @@ -77,8 +84,11 @@ namespace WebCore { CachedImage* const m_cachedImage; const bool m_repeatX; const bool m_repeatY; - }; +#ifdef ANDROID_CANVAS_IMPL + PlatformPattern* m_platformPattern; +#endif + }; } // namespace WebCore #endif diff --git a/WebCore/html/CanvasPixelArray.cpp b/WebCore/html/CanvasPixelArray.cpp deleted file mode 100644 index 82bc27b..0000000 --- a/WebCore/html/CanvasPixelArray.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 deleted file mode 100644 index 1a7e69b..0000000 --- a/WebCore/html/CanvasPixelArray.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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] = lround(value); - } - - 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 deleted file mode 100644 index e8f6342..0000000 --- a/WebCore/html/CanvasPixelArray.idl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 [ - HasCustomIndexGetter, - HasCustomIndexSetter, - GenerateToJS - ] CanvasPixelArray { - readonly attribute long length; - }; - -} diff --git a/WebCore/html/CanvasRenderingContext2D.cpp b/WebCore/html/CanvasRenderingContext2D.cpp index 26509ac..04cd1b5 100644 --- a/WebCore/html/CanvasRenderingContext2D.cpp +++ b/WebCore/html/CanvasRenderingContext2D.cpp @@ -33,7 +33,6 @@ #include "CachedImage.h" #include "CanvasGradient.h" #include "CanvasPattern.h" -#include "CanvasPixelArray.h" #include "CanvasStyle.h" #include "Document.h" #include "ExceptionCode.h" @@ -42,8 +41,6 @@ #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" #include "HTMLNames.h" -#include "ImageBuffer.h" -#include "ImageData.h" #include "NotImplemented.h" #include "RenderHTMLCanvas.h" #include "Settings.h" @@ -62,9 +59,21 @@ namespace WebCore { using namespace HTMLNames; +#ifdef ANDROID_CANVAS_IMPL +static PlatformGradient* extractGradient(CanvasStyle* style) +{ + CanvasGradient* grad = style->gradient(); + return grad ? grad->platformGradient() : NULL; +} +static PlatformPattern* extractPattern(CanvasStyle* style) +{ + CanvasPattern* pat = style->pattern(); + return pat ? pat->platformPattern() : NULL; +} +#endif + CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas) - : RefCounted<CanvasRenderingContext2D>(0) - , m_canvas(canvas) + : m_canvas(canvas) , m_stateStack(1) { } @@ -435,6 +444,7 @@ void CanvasRenderingContext2D::arcTo(float x0, float y0, float x1, float y1, flo 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); } @@ -471,13 +481,14 @@ 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()); - c->beginPath(); - c->addPath(state().m_path); if (!state().m_path.isEmpty()) - willDraw(state().m_path.boundingRect()); + willDraw(CGContextGetPathBoundingBox(c->platformContext())); -#if PLATFORM(CG) if (state().m_fillStyle->gradient()) { // Shading works on the entire clip region, so convert the current path to a clip. c->save(); @@ -489,9 +500,22 @@ void CanvasRenderingContext2D::fill() 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 { @@ -502,13 +526,15 @@ void CanvasRenderingContext2D::fill() #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); @@ -522,20 +548,18 @@ void CanvasRenderingContext2D::stroke() GraphicsContext* c = drawingContext(); if (!c) return; - c->beginPath(); - c->addPath(state().m_path); + // 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()) { - // FIXME: This is insufficient, need to use CGContextReplacePathWithStrokedPath to expand to required bounds float lineWidth = state().m_lineWidth; - float inset = lineWidth / 2; - FloatRect boundingRect = state().m_path.boundingRect(); - boundingRect.inflate(inset); + float inset = -lineWidth / 2; + CGRect boundingRect = CGRectInset(CGContextGetPathBoundingBox(c->platformContext()), inset, inset); willDraw(boundingRect); } - - // FIXME: Do this through platform-independent GraphicsContext API. -#if PLATFORM(CG) + if (state().m_strokeStyle->gradient()) { // Shading works on the entire clip region, so convert the current path to a clip. c->save(); @@ -548,9 +572,17 @@ void CanvasRenderingContext2D::stroke() 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())); @@ -564,6 +596,8 @@ void CanvasRenderingContext2D::stroke() #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); @@ -631,12 +665,12 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei GraphicsContext* c = drawingContext(); if (!c) return; + // FIXME: Do this through platform-independent GraphicsContext API. +#if PLATFORM(CG) + CGRect rect = CGRectMake(x, y, width, height); - FloatRect rect(x, y, width, height); willDraw(rect); - // FIXME: Do this through platform-independent GraphicsContext API. -#if PLATFORM(CG) if (state().m_fillStyle->gradient()) { // Shading works on the entire clip region, so convert the rect to a clip. c->save(); @@ -648,7 +682,14 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei 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()))); @@ -658,6 +699,8 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei 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()) { @@ -696,11 +739,16 @@ 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 } void CanvasRenderingContext2D::setShadow(float width, float height, float blur) @@ -881,6 +929,13 @@ 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) +{ + printf("----- %s [%g %g %g %g]\n", label, r.x(), r.y(), r.width(), r.height()); +} +#endif + void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode& ec) { @@ -909,7 +964,13 @@ void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRec FloatRect sourceRect = c->roundToDevicePixels(srcRect); FloatRect destRect = c->roundToDevicePixels(dstRect); willDraw(destRect); +#if defined(ANDROID_CANVAS_IMPL) + // 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); +#else c->drawImage(cachedImage->image(), destRect, sourceRect, state().m_globalComposite); +#endif } void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, float x, float y) @@ -951,12 +1012,68 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatR FloatRect destRect = c->roundToDevicePixels(dstRect); // FIXME: Do this through platform-independent GraphicsContext API. - ImageBuffer* buffer = canvas->buffer(); - if (!buffer) +#if PLATFORM(CG) + CGImageRef platformImage = canvas->createPlatformImage(); + if (!platformImage) return; - + willDraw(destRect); - c->drawImage(buffer, sourceRect, destRect); + + 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 } // FIXME: Why isn't this just another overload of drawImage? Why have a different name? @@ -1165,92 +1282,4 @@ void CanvasRenderingContext2D::applyFillPattern() state().m_appliedFillPattern = true; } -static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size) -{ - PassRefPtr<ImageData> data = ImageData::create(size.width(), size.height()); - memset(data->data()->data().data(), 0, data->data()->length()); - return data; -} - -PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh) const -{ - FloatSize unscaledSize(sw, sh); - IntSize scaledSize; - if (m_canvas) - scaledSize = m_canvas->convertLogicalToDevice(unscaledSize); - else - scaledSize = IntSize(ceilf(sw), ceilf(sh)); - if (scaledSize.width() < 1) - scaledSize.setWidth(1); - if (scaledSize.height() < 1) - scaledSize.setHeight(1); - - return createEmptyImageData(scaledSize); -} - -PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh) const -{ - FloatRect unscaledRect(sx, sy, sw, sh); - IntRect scaledRect = m_canvas ? m_canvas->convertLogicalToDevice(unscaledRect) : enclosingIntRect(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); -} - -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); -} - -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; - } - - ImageBuffer* buffer = m_canvas ? m_canvas->buffer() : 0; - if (!buffer) - return; - - if (dirtyWidth < 0) { - dirtyX += dirtyWidth; - dirtyWidth = -dirtyWidth; - } - - if (dirtyHeight < 0) { - dirtyY += dirtyHeight; - dirtyHeight = -dirtyHeight; - } - - 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); -} - } // namespace WebCore diff --git a/WebCore/html/CanvasRenderingContext2D.h b/WebCore/html/CanvasRenderingContext2D.h index 5f79d53..30f7a53 100644 --- a/WebCore/html/CanvasRenderingContext2D.h +++ b/WebCore/html/CanvasRenderingContext2D.h @@ -45,7 +45,6 @@ namespace WebCore { class GraphicsContext; class HTMLCanvasElement; class HTMLImageElement; - class ImageData; typedef int ExceptionCode; @@ -163,12 +162,7 @@ namespace WebCore { PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1); 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) 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; } diff --git a/WebCore/html/CanvasRenderingContext2D.idl b/WebCore/html/CanvasRenderingContext2D.idl index d4ea6e1..3d566d4 100644 --- a/WebCore/html/CanvasRenderingContext2D.idl +++ b/WebCore/html/CanvasRenderingContext2D.idl @@ -101,12 +101,7 @@ module html { [Custom] void createPattern(/* 2 */); attribute [Custom] custom strokeStyle; - 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); - [Custom] void putImageData(/* in ImageData imagedata, in float dx, in float dy [, in float dirtyX, in float dirtyY, in float dirtyWidth, in float dirtyHeight] */); + attribute [Custom] custom fillStyle; }; } diff --git a/WebCore/html/CanvasStyle.cpp b/WebCore/html/CanvasStyle.cpp index a3948c3..073fb35 100644 --- a/WebCore/html/CanvasStyle.cpp +++ b/WebCore/html/CanvasStyle.cpp @@ -34,6 +34,13 @@ #include "GraphicsContext.h" #include <wtf/PassRefPtr.h> +#ifdef ANDROID_CANVAS_IMPL +static int F2B(float unit) +{ + return (int)(unit * 255); +} +#endif + #if PLATFORM(QT) #include <QPainter> #include <QBrush> @@ -47,53 +54,42 @@ namespace WebCore { CanvasStyle::CanvasStyle(const String& color) - : RefCounted<CanvasStyle>(0) - , m_type(ColorString) - , m_color(color) + : m_type(ColorString), m_color(color) { } CanvasStyle::CanvasStyle(float grayLevel) - : RefCounted<CanvasStyle>(0) - , 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) - : RefCounted<CanvasStyle>(0) - , m_type(ColorStringWithAlpha), m_color(color), m_alpha(alpha) + : m_type(ColorStringWithAlpha), m_color(color), m_alpha(alpha) { } CanvasStyle::CanvasStyle(float grayLevel, float alpha) - : RefCounted<CanvasStyle>(0) - , m_type(GrayLevel), m_alpha(alpha), m_grayLevel(grayLevel) + : m_type(GrayLevel), m_alpha(alpha), m_grayLevel(grayLevel) { } CanvasStyle::CanvasStyle(float r, float g, float b, float a) - : RefCounted<CanvasStyle>(0) - , m_type(RGBA), m_alpha(a), m_red(r), m_green(g), m_blue(b) + : m_type(RGBA), m_alpha(a), m_red(r), m_green(g), m_blue(b) { } CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a) - : RefCounted<CanvasStyle>(0) - , m_type(CMYKA), m_alpha(a), m_cyan(c), m_magenta(m), m_yellow(y), m_black(k) + : m_type(CMYKA), m_alpha(a), m_cyan(c), m_magenta(m), m_yellow(y), m_black(k) { } CanvasStyle::CanvasStyle(PassRefPtr<CanvasGradient> gradient) - : RefCounted<CanvasStyle>(0) - , m_type(gradient ? Gradient : ColorString), m_gradient(gradient) + : m_type(gradient ? Gradient : ColorString), m_gradient(gradient) { } CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern) - : RefCounted<CanvasStyle>(0) - , m_type(pattern ? ImagePattern : ColorString), m_pattern(pattern) + : m_type(pattern ? ImagePattern : ColorString), m_pattern(pattern) { } @@ -117,6 +113,8 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context) ((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)))); @@ -141,6 +139,8 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context) ((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)); @@ -161,6 +161,11 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context) // 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(); @@ -176,6 +181,8 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context) // 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; @@ -230,6 +237,8 @@ void CanvasStyle::applyFillColor(GraphicsContext* context) ((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; @@ -249,6 +258,8 @@ void CanvasStyle::applyFillColor(GraphicsContext* context) ((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; @@ -263,6 +274,11 @@ void CanvasStyle::applyFillColor(GraphicsContext* context) // 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; @@ -276,6 +292,8 @@ void CanvasStyle::applyFillColor(GraphicsContext* context) // 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; diff --git a/WebCore/html/HTMLAnchorElement.cpp b/WebCore/html/HTMLAnchorElement.cpp index bd1e2fc..5daf2a0 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. * (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * This library is free software; you can redistribute it and/or @@ -197,9 +197,9 @@ void HTMLAnchorElement::defaultEventHandler(Event* evt) int x = e->pageX() - absx; int y = e->pageY() - absy; url += "?"; - url += String::number(x); + url += DeprecatedString::number(x); url += ","; - url += String::number(y); + url += DeprecatedString::number(y); } else { evt->setDefaultHandled(); HTMLElement::defaultEventHandler(evt); @@ -328,7 +328,7 @@ void HTMLAnchorElement::setCoords(const String &value) setAttribute(coordsAttr, value); } -KURL HTMLAnchorElement::href() const +String HTMLAnchorElement::href() const { return document()->completeURL(getAttribute(hrefAttr)); } @@ -415,40 +415,41 @@ void HTMLAnchorElement::setType(const String &value) String HTMLAnchorElement::hash() const { - return "#" + href().ref(); + return '#' + KURL(href().deprecatedString()).ref(); } String HTMLAnchorElement::host() const { - return href().host(); + return KURL(href().deprecatedString()).host(); } String HTMLAnchorElement::hostname() const { - KURL url(href()); - if (url.port() == 0) + KURL url(href().deprecatedString()); + if (url.port()==0) return url.host(); - return url.host() + ":" + String::number(url.port()); + else + return url.host() + ":" + String::number(url.port()); } String HTMLAnchorElement::pathname() const { - return href().path(); + return KURL(href().deprecatedString()).path(); } String HTMLAnchorElement::port() const { - return String::number(href().port()); + return DeprecatedString::number(KURL(href().deprecatedString()).port()); } String HTMLAnchorElement::protocol() const { - return href().protocol() + ":"; + return KURL(href().deprecatedString()).protocol() + ":"; } String HTMLAnchorElement::search() const { - return href().query(); + return KURL(href().deprecatedString()).query(); } String HTMLAnchorElement::text() const @@ -458,7 +459,7 @@ String HTMLAnchorElement::text() const String HTMLAnchorElement::toString() const { - return href().string(); + return href(); } bool HTMLAnchorElement::isLiveLink() const diff --git a/WebCore/html/HTMLAnchorElement.h b/WebCore/html/HTMLAnchorElement.h index 9edcb6a..98e37e0 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,6 +28,8 @@ namespace WebCore { +class String; + class HTMLAnchorElement : public HTMLElement { public: HTMLAnchorElement(Document*); @@ -58,7 +60,7 @@ public: String coords() const; void setCoords(const String&); - KURL href() const; + String href() const; void setHref(const String&); String hreflang() const; diff --git a/WebCore/html/HTMLAppletElement.cpp b/WebCore/html/HTMLAppletElement.cpp index 4e199ad..d5100d1 100644 --- a/WebCore/html/HTMLAppletElement.cpp +++ b/WebCore/html/HTMLAppletElement.cpp @@ -1,8 +1,10 @@ -/* +/** + * 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, 2008 Apple Inc. ALl rights reserved. + * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. * Copyright (C) 2007 Trolltech ASA * * This library is free software; you can redistribute it and/or @@ -20,7 +22,6 @@ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ - #include "config.h" #include "HTMLAppletElement.h" @@ -35,20 +36,30 @@ namespace WebCore { using namespace HTMLNames; -HTMLAppletElement::HTMLAppletElement(Document* doc) - : HTMLPlugInElement(appletTag, doc) +HTMLAppletElement::HTMLAppletElement(Document *doc) +: HTMLPlugInElement(appletTag, doc) { } 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 + if (oldNameIdCount && document()->isHTMLDocument()) { + HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + doc->removeNamedItem(oldNameAttr); + doc->removeDocExtraNamedItem(oldIdAttr); + } +#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 || @@ -60,7 +71,7 @@ void HTMLAppletElement::parseMappedAttribute(MappedAttribute* attr) } else if (attr->name() == nameAttr) { String newNameAttr = attr->value(); if (inDocument() && document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->removeNamedItem(oldNameAttr); doc->addNamedItem(newNameAttr); } @@ -68,7 +79,7 @@ void HTMLAppletElement::parseMappedAttribute(MappedAttribute* attr) } else if (attr->name() == idAttr) { String newIdAttr = attr->value(); if (inDocument() && document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->removeDocExtraNamedItem(oldIdAttr); doc->addDocExtraNamedItem(newIdAttr); } @@ -82,9 +93,14 @@ void HTMLAppletElement::parseMappedAttribute(MappedAttribute* attr) void HTMLAppletElement::insertedIntoDocument() { if (document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->addNamedItem(oldNameAttr); doc->addDocExtraNamedItem(oldIdAttr); +#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 + oldNameIdCount++; +#endif } HTMLPlugInElement::insertedIntoDocument(); @@ -93,20 +109,25 @@ void HTMLAppletElement::insertedIntoDocument() void HTMLAppletElement::removedFromDocument() { if (document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->removeNamedItem(oldNameAttr); doc->removeDocExtraNamedItem(oldIdAttr); +#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 + oldNameIdCount--; +#endif } 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(); @@ -117,14 +138,14 @@ RenderObject* HTMLAppletElement::createRenderer(RenderArena* arena, RenderStyle* const AtomicString& codeBase = getAttribute(codebaseAttr); if(!codeBase.isNull()) args.set("codeBase", codeBase); - const AtomicString& name = getAttribute(document()->isHTMLDocument() ? nameAttr : idAttr); + const AtomicString& name = getAttribute(document()->htmlMode() != Document::XHtml ? 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().string()); + args.set("baseURL", document()->baseURL()); const AtomicString& mayScript = getAttribute(mayscriptAttr); if (!mayScript.isNull()) @@ -139,7 +160,7 @@ RenderObject* HTMLAppletElement::createRenderer(RenderArena* arena, RenderStyle* } #if USE(JAVASCRIPTCORE_BINDINGS) -KJS::Bindings::Instance* HTMLAppletElement::getInstance() const +KJS::Bindings::Instance *HTMLAppletElement::getInstance() const { Settings* settings = document()->settings(); if (!settings || !settings->isJavaEnabled()) diff --git a/WebCore/html/HTMLAreaElement.cpp b/WebCore/html/HTMLAreaElement.cpp index 8eec391..09e1e30 100644 --- a/WebCore/html/HTMLAreaElement.cpp +++ b/WebCore/html/HTMLAreaElement.cpp @@ -1,4 +1,6 @@ -/* +/** + * 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. @@ -18,16 +20,19 @@ * 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 "FloatRect.h" #include "HTMLNames.h" +#include "FloatRect.h" #include "HitTestResult.h" #include "RenderObject.h" +#ifdef ANDROID_NAVIGATE_AREAMAPS +#include "RenderImage.h" +#endif + using namespace std; namespace WebCore { @@ -40,6 +45,9 @@ HTMLAreaElement::HTMLAreaElement(Document *doc) , m_coordsLen(0) , m_lastSize(-1, -1) , m_shape(Unknown) +#ifdef ANDROID_NAVIGATE_AREAMAPS + , m_map(0) +#endif { } @@ -178,7 +186,7 @@ void HTMLAreaElement::setCoords(const String& value) setAttribute(coordsAttr, value); } -KURL HTMLAreaElement::href() const +String HTMLAreaElement::href() const { return document()->completeURL(getAttribute(hrefAttr)); } @@ -223,4 +231,15 @@ void HTMLAreaElement::setTarget(const String& value) setAttribute(targetAttr, value); } +#ifdef ANDROID_NAVIGATE_AREAMAPS +IntRect HTMLAreaElement::getAreaRect() const +{ + if (m_map) { + if (isDefault()) + return m_map->absoluteBoundingBoxRect(); + return getRect(m_map); + } + return IntRect(); +} +#endif } diff --git a/WebCore/html/HTMLAreaElement.h b/WebCore/html/HTMLAreaElement.h index ff5aa55..98e10f5 100644 --- a/WebCore/html/HTMLAreaElement.h +++ b/WebCore/html/HTMLAreaElement.h @@ -1,7 +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) - * Copyright (C) 2004, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -29,10 +31,20 @@ namespace WebCore { +#ifdef ANDROID_NAVIGATE_AREAMAPS + // in android, we have no pointer, so we can't access area elements + // via mapMouseEvent. instead, we store the RenderImage here so we + // can use it to find its dimensions to focus on it and draw a ring + // around it + class RenderImage; +#endif + class HitTestResult; class HTMLAreaElement : public HTMLAnchorElement { public: + enum Shape { Default, Poly, Rect, Circle, Unknown }; + HTMLAreaElement(Document*); ~HTMLAreaElement(); @@ -56,7 +68,7 @@ public: String coords() const; void setCoords(const String&); - KURL href() const; + String href() const; void setHref(const String&); bool noHref() const; @@ -70,14 +82,21 @@ public: virtual String target() const; void setTarget(const String&); -private: - enum Shape { Default, Poly, Rect, Circle, Unknown }; +#ifdef ANDROID_NAVIGATE_AREAMAPS + IntRect getAreaRect() const; + void setMap(RenderImage* map) { m_map = map; } +#endif + +protected: Path getRegion(const IntSize&) const; Path region; Length* m_coords; int m_coordsLen; IntSize m_lastSize; Shape m_shape; +#ifdef ANDROID_NAVIGATE_AREAMAPS + RenderImage* m_map; +#endif }; } //namespace diff --git a/WebCore/html/HTMLBaseElement.cpp b/WebCore/html/HTMLBaseElement.cpp index 1ae6858..7a94c7b 100644 --- a/WebCore/html/HTMLBaseElement.cpp +++ b/WebCore/html/HTMLBaseElement.cpp @@ -1,8 +1,10 @@ -/* +/** + * 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -34,7 +36,7 @@ namespace WebCore { using namespace HTMLNames; -HTMLBaseElement::HTMLBaseElement(Document* doc) +HTMLBaseElement::HTMLBaseElement(Document *doc) : HTMLElement(baseTag, doc) { } @@ -43,7 +45,7 @@ HTMLBaseElement::~HTMLBaseElement() { } -void HTMLBaseElement::parseMappedAttribute(MappedAttribute* attr) +void HTMLBaseElement::parseMappedAttribute(MappedAttribute *attr) { if (attr->name() == hrefAttr) { m_href = parseURL(attr->value()); @@ -67,8 +69,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(KURL()); - document()->setBaseTarget(String()); + document()->setBaseURL(DeprecatedString::null); + document()->setBaseTarget(DeprecatedString::null); } void HTMLBaseElement::process() @@ -77,7 +79,7 @@ void HTMLBaseElement::process() return; if (!m_href.isEmpty() && document()->frame()) - document()->setBaseURL(KURL(document()->frame()->loader()->url(), m_href)); + document()->setBaseURL(KURL(document()->frame()->loader()->url(), m_href.deprecatedString()).deprecatedString()); if (!m_target.isEmpty()) document()->setBaseTarget(m_target); diff --git a/WebCore/html/HTMLBodyElement.cpp b/WebCore/html/HTMLBodyElement.cpp index ae7584c..6231fc2 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -88,7 +88,7 @@ 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).string()); + addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, document()->completeURL(url)); } else if (attr->name() == marginwidthAttr || attr->name() == leftmarginAttr) { addCSSLength(attr, CSS_PROP_MARGIN_RIGHT, attr->value()); addCSSLength(attr, CSS_PROP_MARGIN_LEFT, attr->value()); @@ -180,7 +180,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 +190,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 +200,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 +210,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 +220,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 +230,7 @@ String HTMLBodyElement::vLink() const return getAttribute(vlinkAttr); } -void HTMLBodyElement::setVLink(const String& value) +void HTMLBodyElement::setVLink(const String &value) { setAttribute(vlinkAttr, value); } @@ -241,6 +241,7 @@ int HTMLBodyElement::scrollLeft() const Document* doc = document(); doc->updateLayoutIgnorePendingStylesheets(); FrameView* view = doc->view(); + return view ? view->contentsX() : 0; } @@ -260,6 +261,7 @@ int HTMLBodyElement::scrollTop() const Document* doc = document(); doc->updateLayoutIgnorePendingStylesheets(); FrameView* view = doc->view(); + return view ? view->contentsY() : 0; } @@ -279,6 +281,7 @@ int HTMLBodyElement::scrollHeight() const Document* doc = document(); doc->updateLayoutIgnorePendingStylesheets(); FrameView* view = doc->view(); + return view ? view->contentsHeight() : 0; } @@ -288,6 +291,7 @@ int HTMLBodyElement::scrollWidth() const Document* doc = document(); doc->updateLayoutIgnorePendingStylesheets(); FrameView* view = doc->view(); + return view ? view->contentsWidth() : 0; } diff --git a/WebCore/html/HTMLButtonElement.cpp b/WebCore/html/HTMLButtonElement.cpp index a332c6f..6e57540 100644 --- a/WebCore/html/HTMLButtonElement.cpp +++ b/WebCore/html/HTMLButtonElement.cpp @@ -56,34 +56,18 @@ RenderObject* HTMLButtonElement::createRenderer(RenderArena* arena, RenderStyle* const AtomicString& HTMLButtonElement::type() const { - 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; + return getAttribute(typeAttr); } void HTMLButtonElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == typeAttr) { - if (equalIgnoringCase(attr->value(), "reset")) + if (equalIgnoringCase(attr->value(), "submit")) + m_type = SUBMIT; + else 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 diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp index 45895c7..8c3fc15 100644 --- a/WebCore/html/HTMLCanvasElement.cpp +++ b/WebCore/html/HTMLCanvasElement.cpp @@ -35,7 +35,6 @@ #include "Document.h" #include "Frame.h" #include "GraphicsContext.h" -#include "ImageBuffer.h" #include "HTMLNames.h" #include "Page.h" #include "RenderHTMLCanvas.h" @@ -60,12 +59,19 @@ 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. -const float HTMLCanvasElement::MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels +static const float maxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels HTMLCanvasElement::HTMLCanvasElement(Document* doc) : HTMLElement(canvasTag, doc) , m_size(defaultWidth, defaultHeight) - , m_createdImageBuffer(false) + , m_createdDrawingContext(false) + , m_data(0) +#if PLATFORM(QT) + , m_painter(0) +#elif PLATFORM(CAIRO) + , m_surface(0) +#endif + , m_drawingContext(0) { } @@ -73,6 +79,16 @@ 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; } HTMLTagStatus HTMLCanvasElement::endTagRequirement() const @@ -161,9 +177,22 @@ void HTMLCanvasElement::reset() IntSize oldSize = m_size; m_size = IntSize(w, h); - bool hadImageBuffer = m_createdImageBuffer; - m_createdImageBuffer = false; - m_imageBuffer.clear(); + 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; if (m_2DContext) m_2DContext->reset(); @@ -171,7 +200,7 @@ void HTMLCanvasElement::reset() if (m_rendererIsCanvas) { if (oldSize != m_size) static_cast<RenderHTMLCanvas*>(ro)->canvasSizeChanged(); - if (hadImageBuffer) + if (hadDrawingContext) ro->repaint(); } } @@ -180,60 +209,103 @@ void HTMLCanvasElement::paint(GraphicsContext* p, const IntRect& r) { if (p->paintingDisabled()) return; - - if (m_imageBuffer) - p->paintBuffer(m_imageBuffer.get(), r); -} - -IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const -{ - return IntRect(convertLogicalToDevice(logicalRect.location()), convertLogicalToDevice(logicalRect.size())); +#if PLATFORM(CG) + if (CGImageRef image = createPlatformImage()) { + CGContextDrawImage(p->platformContext(), p->roundToDevicePixels(r), image); + CGImageRelease(image); + } +#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 } -IntSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const +void HTMLCanvasElement::createDrawingContext() const { - float pageScaleFactor = document()->frame() ? document()->frame()->page()->chrome()->scaleFactor() : 1.0f; - float wf = ceilf(logicalSize.width() * pageScaleFactor); - float hf = ceilf(logicalSize.height() * pageScaleFactor); - - if (!(wf >= 1 && hf >= 1 && wf * hf <= MaxCanvasArea)) - return IntSize(); + ASSERT(!m_createdDrawingContext); + ASSERT(!m_data); - return IntSize(static_cast<unsigned>(wf), static_cast<unsigned>(hf)); -} + m_createdDrawingContext = true; -IntPoint HTMLCanvasElement::convertLogicalToDevice(const FloatPoint& logicalPos) const -{ + float unscaledWidth = width(); + float unscaledHeight = height(); 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)); -} + float wf = ceilf(unscaledWidth * pageScaleFactor); + float hf = ceilf(unscaledHeight * pageScaleFactor); -void HTMLCanvasElement::createImageBuffer() const -{ - ASSERT(!m_imageBuffer); + if (!(wf >= 1 && hf >= 1 && wf * hf <= maxCanvasArea)) + return; + + unsigned w = static_cast<unsigned>(wf); + unsigned h = static_cast<unsigned>(hf); - m_createdImageBuffer = true; - - FloatSize unscaledSize(width(), height()); - IntSize size = convertLogicalToDevice(unscaledSize); - if (!size.width() || !size.height()) +#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; - m_imageBuffer.set(ImageBuffer::create(size, false).release()); + 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 } GraphicsContext* HTMLCanvasElement::drawingContext() const { - return buffer() ? m_imageBuffer->context() : 0; -} - -ImageBuffer* HTMLCanvasElement::buffer() const -{ - if (!m_createdImageBuffer) - createImageBuffer(); - return m_imageBuffer.get(); + if (!m_createdDrawingContext) + createDrawingContext(); + return m_drawingContext; } #if PLATFORM(CG) @@ -255,27 +327,27 @@ CGImageRef HTMLCanvasElement::createPlatformImage() const #elif PLATFORM(QT) -QPixmap HTMLCanvasElement::createPlatformImage() const +QImage HTMLCanvasElement::createPlatformImage() const { - if (!m_imageBuffer) - return QPixmap(); - return *m_imageBuffer->pixmap(); + if (m_data) + return *m_data; + return QImage(); } #elif PLATFORM(CAIRO) cairo_surface_t* HTMLCanvasElement::createPlatformImage() const { - if (!m_imageBuffer) + 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_imageBuffer->surface()); - cairo_surface_reference(m_imageBuffer->surface()); - return m_imageBuffer->surface(); + cairo_surface_flush(m_surface); + cairo_surface_reference(m_surface); + return m_surface; } #endif diff --git a/WebCore/html/HTMLCanvasElement.h b/WebCore/html/HTMLCanvasElement.h index 2876be3..add1bf7 100644 --- a/WebCore/html/HTMLCanvasElement.h +++ b/WebCore/html/HTMLCanvasElement.h @@ -35,7 +35,7 @@ typedef struct CGContext* CGContextRef; typedef struct CGImage* CGImageRef; #elif PLATFORM(QT) -class QPixmap; +class QImage; class QPainter; #elif PLATFORM(CAIRO) typedef struct _cairo_surface cairo_surface_t; @@ -45,14 +45,8 @@ namespace WebCore { class CanvasRenderingContext2D; typedef CanvasRenderingContext2D CanvasRenderingContext; -class FloatPoint; class FloatRect; -class FloatSize; class GraphicsContext; -class ImageBuffer; -class IntPoint; -class InttRect; -class IntSize; class HTMLCanvasElement : public HTMLElement { public: @@ -80,21 +74,16 @@ public: GraphicsContext* drawingContext() const; - ImageBuffer* buffer() const; #if PLATFORM(CG) CGImageRef createPlatformImage() const; #elif PLATFORM(QT) - QPixmap createPlatformImage() const; + QImage createPlatformImage() const; #elif PLATFORM(CAIRO) cairo_surface_t* createPlatformImage() const; #endif - - IntRect convertLogicalToDevice(const FloatRect&) const; - IntSize convertLogicalToDevice(const FloatSize&) const; - IntPoint convertLogicalToDevice(const FloatPoint&) const; - static const float MaxCanvasArea; + private: - void createImageBuffer() const; + void createDrawingContext() const; void reset(); bool m_rendererIsCanvas; @@ -105,9 +94,19 @@ private: // 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. - // m_createdImageBuffer means we tried to malloc the buffer. We didn't necessarily get it. - mutable bool m_createdImageBuffer; - mutable OwnPtr<ImageBuffer> m_imageBuffer; + 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; }; } //namespace diff --git a/WebCore/html/HTMLCollection.cpp b/WebCore/html/HTMLCollection.cpp index 8214b07..474e6a6 100644 --- a/WebCore/html/HTMLCollection.cpp +++ b/WebCore/html/HTMLCollection.cpp @@ -36,8 +36,7 @@ namespace WebCore { using namespace HTMLNames; HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type) - : RefCounted<HTMLCollection>(0) - , m_idsDone(false) + : m_idsDone(false) , m_base(base) , m_type(type) , m_info(m_base->isDocumentNode() ? static_cast<Document*>(m_base.get())->collectionInfo(type) : 0) @@ -46,8 +45,7 @@ HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type) } HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type, CollectionInfo* info) - : RefCounted<HTMLCollection>(0) - , m_idsDone(false) + : m_idsDone(false) , m_base(base) , m_type(type) , m_info(info) @@ -301,7 +299,15 @@ Node* HTMLCollection::firstItem() const Node* HTMLCollection::nextItem() const { resetCollectionInfo(); - + +#ifdef ANDROID_FIX + // resetCollectionInfo() can set info->current to be 0. If this is the + // case, we need to go back to the firstItem. Otherwise traverseNextItem + // will crash. + if (!m_info->current) + return firstItem(); +#endif + // Look for the 'second' item. The first one is currentItem, already given back. Element* retval = itemAfter(m_info->current); m_info->current = retval; @@ -340,10 +346,10 @@ bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const S e->hasLocalName(selectTag))) return false; - return e->getAttribute(nameAttr).string().lower() == name.lower() && - e->getAttribute(idAttr).string().lower() != name.lower(); + return e->getAttribute(nameAttr).domString().lower() == name.lower() && + e->getAttribute(idAttr).domString().lower() != name.lower(); } else { - return e->getAttribute(idAttr).string().lower() == name.lower(); + return e->getAttribute(idAttr).domString().lower() == name.lower(); } } } diff --git a/WebCore/html/HTMLDocument.cpp b/WebCore/html/HTMLDocument.cpp index eb9eb4d..8db8422 100644 --- a/WebCore/html/HTMLDocument.cpp +++ b/WebCore/html/HTMLDocument.cpp @@ -74,6 +74,11 @@ #include "DocTypeStrings.cpp" +#ifdef ANDROID_META_SUPPORT +#include "FrameTree.h" +#include "Settings.h" +#endif + namespace WebCore { using namespace HTMLNames; @@ -82,7 +87,6 @@ HTMLDocument::HTMLDocument(DOMImplementation* implementation, Frame* frame) : Document(implementation, frame) { clearXMLVersion(); - setParseMode(Compat); } HTMLDocument::~HTMLDocument() @@ -274,7 +278,7 @@ Tokenizer *HTMLDocument::createTokenizer() bool HTMLDocument::childAllowed(Node *newChild) { - return newChild->hasTagName(htmlTag) || newChild->isCommentNode() || (newChild->nodeType() == DOCUMENT_TYPE_NODE && !doctype()); + return newChild->hasTagName(htmlTag) || newChild->isCommentNode(); } PassRefPtr<Element> HTMLDocument::createElement(const String &name, ExceptionCode& ec) @@ -347,62 +351,236 @@ bool HTMLDocument::hasDocExtraNamedItem(const String& name) return docExtraNamedItemCounts.get(name.impl()) != 0; } -void HTMLDocument::determineParseMode() +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) { - // FIXME: It's terrible that this code runs separately and isn't just built in to the - // HTML tokenizer/parser. + 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; + } + + 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. - 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(); - - // 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. + // 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); + } + 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. setParseMode(Strict); + setHTMLMode(Html4); + } else { - switch (docType->systemId().isEmpty() ? - doctypeEntry->mode_if_no_sysid : - doctypeEntry->mode_if_sysid) { + // 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) + { 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); } - } + } } - - if (inCompatMode() != wasInCompatMode) - updateStyleSelector(); + else { + // Malformed doctype implies quirks mode. + setParseMode(Compat); + setHTMLMode(Html3); + } + + styleSelector()->strictParsing = !inCompatMode(); + } } diff --git a/WebCore/html/HTMLDocument.h b/WebCore/html/HTMLDocument.h index 567d121..fefbdb7 100644 --- a/WebCore/html/HTMLDocument.h +++ b/WebCore/html/HTMLDocument.h @@ -69,6 +69,8 @@ public: virtual PassRefPtr<Element> createElement(const String& tagName, ExceptionCode&); + virtual void determineParseMode(const String&); + void addNamedItem(const String& name); void removeNamedItem(const String& name); bool hasNamedItem(const String& name); @@ -80,9 +82,6 @@ public: typedef HashMap<StringImpl*, int> NameCountMap; private: - virtual void determineParseMode(); - -private: NameCountMap namedItemCounts; NameCountMap docExtraNamedItemCounts; }; diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp index 2a19a9c..1f84e23 100644 --- a/WebCore/html/HTMLElement.cpp +++ b/WebCore/html/HTMLElement.cpp @@ -66,7 +66,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().string().upper(); + return tagQName().localName().domString().upper(); return Element::nodeName(); } @@ -220,6 +220,10 @@ void HTMLElement::parseMappedAttribute(MappedAttribute *attr) String HTMLElement::innerHTML() const { +#ifdef ANDROID_NO_BODY_INNER_HTML + if (id()==bodyTag || id()==htmlTag) + return "fastinnerhtml!"; +#endif return createMarkup(this, ChildrenOnly); } @@ -902,7 +906,7 @@ bool HTMLElement::checkDTD(const Node* newChild) void HTMLElement::setHTMLEventListener(const AtomicString& eventType, Attribute* attr) { Element::setHTMLEventListener(eventType, - document()->createHTMLEventListener(attr->localName().string(), attr->value(), this)); + document()->createHTMLEventListener(attr->localName().domString(), attr->value(), this)); } bool HTMLElement::rendererIsNeeded(RenderStyle *style) diff --git a/WebCore/html/HTMLEmbedElement.cpp b/WebCore/html/HTMLEmbedElement.cpp index ae65863..eb449fc 100644 --- a/WebCore/html/HTMLEmbedElement.cpp +++ b/WebCore/html/HTMLEmbedElement.cpp @@ -1,8 +1,10 @@ -/* +/** + * 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. * Copyright (C) 2007 Trolltech ASA * * This library is free software; you can redistribute it and/or @@ -20,7 +22,6 @@ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ - #include "config.h" #include "HTMLEmbedElement.h" @@ -45,6 +46,15 @@ HTMLEmbedElement::HTMLEmbedElement(Document* doc) 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 + if (oldNameIdCount && document()->isHTMLDocument()) { + HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + doc->removeNamedItem(oldNameAttr); + } +#endif + #if USE(JAVASCRIPTCORE_BINDINGS) // m_instance should have been cleaned up in detach(). ASSERT(!m_instance); @@ -63,7 +73,7 @@ static inline RenderWidget* findWidgetRenderer(const Node* n) ? static_cast<RenderWidget*>(n->renderer()) : 0; } -KJS::Bindings::Instance* HTMLEmbedElement::getInstance() const +KJS::Bindings::Instance *HTMLEmbedElement::getInstance() const { Frame* frame = document()->frame(); if (!frame) @@ -105,7 +115,7 @@ void HTMLEmbedElement::parseMappedAttribute(MappedAttribute* attr) if (pos != -1) m_serviceType = m_serviceType.left(pos); } else if (attr->name() == codeAttr || attr->name() == srcAttr) - m_url = parseURL(val); + url = parseURL(val).deprecatedString(); else if (attr->name() == pluginpageAttr || attr->name() == pluginspageAttr) m_pluginPage = val; else if (attr->name() == hiddenAttr) { @@ -126,13 +136,13 @@ void HTMLEmbedElement::parseMappedAttribute(MappedAttribute* attr) HTMLPlugInElement::parseMappedAttribute(attr); } -bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style) +bool HTMLEmbedElement::rendererIsNeeded(RenderStyle *style) { - Frame* frame = document()->frame(); + Frame *frame = document()->frame(); if (!frame) return false; - Node* p = parentNode(); + Node *p = parentNode(); if (p && p->hasTagName(objectTag)) { ASSERT(p->renderer()); return false; @@ -141,7 +151,7 @@ bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style) return true; } -RenderObject* HTMLEmbedElement::createRenderer(RenderArena* arena, RenderStyle* style) +RenderObject *HTMLEmbedElement::createRenderer(RenderArena *arena, RenderStyle *style) { return new (arena) RenderPartObject(this); } @@ -170,8 +180,13 @@ void HTMLEmbedElement::updateWidget() void HTMLEmbedElement::insertedIntoDocument() { if (document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->addNamedItem(oldNameAttr); +#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 + oldNameIdCount++; +#endif } String width = getAttribute(widthAttr); @@ -194,8 +209,13 @@ void HTMLEmbedElement::insertedIntoDocument() void HTMLEmbedElement::removedFromDocument() { if (document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->removeNamedItem(oldNameAttr); +#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 + oldNameIdCount--; +#endif } HTMLPlugInElement::removedFromDocument(); @@ -214,7 +234,7 @@ void HTMLEmbedElement::attributeChanged(Attribute* attr, bool preserveDecls) } } -bool HTMLEmbedElement::isURLAttribute(Attribute* attr) const +bool HTMLEmbedElement::isURLAttribute(Attribute *attr) const { return attr->name() == srcAttr; } diff --git a/WebCore/html/HTMLEmbedElement.h b/WebCore/html/HTMLEmbedElement.h index 1fc0ba5..8645489 100644 --- a/WebCore/html/HTMLEmbedElement.h +++ b/WebCore/html/HTMLEmbedElement.h @@ -1,7 +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) - * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -65,11 +67,7 @@ public: String type() const; void setType(const String&); - const String& url() const { return m_url; } - const String& serviceType() const { return m_serviceType; } - -private: - String m_url; + DeprecatedString url; String m_pluginPage; String m_serviceType; bool m_needWidgetUpdate; diff --git a/WebCore/html/HTMLFormCollection.cpp b/WebCore/html/HTMLFormCollection.cpp index fd2b836..fa69710 100644 --- a/WebCore/html/HTMLFormCollection.cpp +++ b/WebCore/html/HTMLFormCollection.cpp @@ -109,7 +109,7 @@ Element* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, con if (caseSensitive) found = e->getAttribute(attrName) == name; else - found = e->getAttribute(attrName).string().lower() == name.lower(); + found = e->getAttribute(attrName).domString().lower() == name.lower(); if (found) { foundInputElements = true; if (!duplicateNumber) @@ -126,7 +126,7 @@ Element* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, con if (caseSensitive) found = e->getAttribute(attrName) == name; else - found = e->getAttribute(attrName).string().lower() == name.lower(); + found = e->getAttribute(attrName).domString().lower() == name.lower(); if (found) { if (!duplicateNumber) return e; diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp index e2b0ea6..267c3bf 100644 --- a/WebCore/html/HTMLFormElement.cpp +++ b/WebCore/html/HTMLFormElement.cpp @@ -2,7 +2,7 @@ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. * (C) 2006 Alexey Proskuryakov (ap@nypop.com) * * This library is free software; you can redistribute it and/or @@ -25,7 +25,9 @@ #include "config.h" #include "HTMLFormElement.h" +#include "Base64.h" #include "CSSHelper.h" +#include "CString.h" #include "Event.h" #include "EventNames.h" #include "FormData.h" @@ -58,8 +60,6 @@ namespace WebCore { using namespace EventNames; using namespace HTMLNames; -static const char hexDigits[17] = "0123456789ABCDEF"; - HTMLFormElement::HTMLFormElement(Document* doc) : HTMLElement(formTag, doc) , m_elementAliases(0) @@ -72,11 +72,24 @@ HTMLFormElement::HTMLFormElement(Document* doc) , m_doingsubmit(false) , m_inreset(false) , 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 + , oldNameCount(0) +#endif { } 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 + if (oldNameCount && document()->isHTMLDocument()) { + HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + doc->removeNamedItem(oldNameAttr); + } +#endif delete m_elementAliases; delete collectionInfo; @@ -86,9 +99,12 @@ HTMLFormElement::~HTMLFormElement() imgElements[i]->m_form = 0; } -bool HTMLFormElement::formWouldHaveSecureSubmission(const String& url) +bool HTMLFormElement::formWouldHaveSecureSubmission(const String &url) { - return document()->completeURL(url).protocolIs("https"); + if (url.isNull()) { + return false; + } + return document()->completeURL(url.deprecatedString()).startsWith("https:", false); } void HTMLFormElement::attach() @@ -99,8 +115,13 @@ void HTMLFormElement::attach() void HTMLFormElement::insertedIntoDocument() { if (document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->addNamedItem(oldNameAttr); +#ifdef ANDROID_FIX + // addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512 + // ensure the oldNameAttr is removed from HTMLDocument's NameCountMap + oldNameCount++; +#endif } HTMLElement::insertedIntoDocument(); @@ -109,8 +130,13 @@ void HTMLFormElement::insertedIntoDocument() void HTMLFormElement::removedFromDocument() { if (document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->removeNamedItem(oldNameAttr); +#ifdef ANDROID_FIX + // addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512 + // ensure the oldNameAttr is removed from HTMLDocument's NameCountMap + oldNameCount--; +#endif } HTMLElement::removedFromDocument(); @@ -146,7 +172,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); @@ -158,40 +184,48 @@ void HTMLFormElement::submitClick(Event* event) prepareSubmit(event); } -static void appendString(Vector<char>& buffer, const char* string) +static DeprecatedCString encodeCString(const CString& cstr) { - buffer.append(string, strlen(string)); -} + DeprecatedCString e = cstr.deprecatedCString(); -static void appendString(Vector<char>& buffer, const CString& string) -{ - buffer.append(string.data(), string.length()); -} - -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 = "-._*"; + int elen = e.length(); + DeprecatedCString encoded((elen + e.contains('\n')) * 3 + 1); + int enclen = 0; + + for (int pos = 0; pos < elen; pos++) { + unsigned char c = e[pos]; - // 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)) - buffer.append(c); + encoded[enclen++] = c; else if (c == ' ') - 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++] = '+'; + 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; } } + encoded[enclen++] = '\0'; + encoded.truncate(enclen); + + return encoded; } -// FIXME: Move to platform directory? static int randomNumber() { static bool randomSeeded = false; @@ -211,9 +245,8 @@ static int randomNumber() #endif } -// FIXME: Move to platform directory? -// Warning: this helper doesn't currently have a reliable cross-platform behavior in -// certain edge cases (see basename(3) specification for examples). +// 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) { @@ -236,8 +269,7 @@ TextEncoding HTMLFormElement::dataEncoding() const TextEncoding encoding; String str = m_acceptcharset; str.replace(',', ' '); - Vector<String> charsets; - str.split(' ', charsets); + Vector<String> charsets = str.split(' '); Vector<String>::const_iterator end = charsets.end(); for (Vector<String>::const_iterator it = charsets.begin(); it != end; ++it) if ((encoding = TextEncoding(*it)).isValid()) @@ -249,69 +281,73 @@ TextEncoding HTMLFormElement::dataEncoding() const PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const { - Vector<char> encodedData; + DeprecatedCString enc_string = ""; TextEncoding encoding = dataEncoding(); - RefPtr<FormData> result = FormData::create(); + RefPtr<FormData> result = new FormData; for (unsigned i = 0; i < formElements.size(); ++i) { - HTMLGenericFormElement* control = formElements[i]; - FormDataList list(encoding); + HTMLGenericFormElement* current = formElements[i]; + FormDataList lst(encoding); - if (!control->disabled() && control->appendFormData(list, m_multipart)) { - size_t ln = list.list().size(); + 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 = list.list()[j]; + const FormDataListItem& item = lst.list()[j]; if (!m_multipart) { - // 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() && item.m_data == "isindex") - appendEncodedString(encodedData, list.list()[++j].m_data); - else { - if (!encodedData.isEmpty()) - encodedData.append('&'); - appendEncodedString(encodedData, item.m_data); - encodedData.append('='); - appendEncodedString(encodedData, list.list()[++j].m_data); + // 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; } - } else { - Vector<char> header; - appendString(header, "--"); - appendString(header, boundary); - appendString(header, "\r\n"); - appendString(header, "Content-Disposition: form-data; name=\""); - header.append(item.m_data.data(), item.m_data.length()); - header.append('"'); + } + else + { + DeprecatedCString hstr("--"); + hstr += boundary; + hstr += "\r\n"; + hstr += "Content-Disposition: form-data; name=\""; + hstr += item.m_data.data(); + hstr += "\""; // if the current type is FILE, then we also need to // include the filename - if (control->hasLocalName(inputTag) - && static_cast<HTMLInputElement*>(control)->inputType() == HTMLInputElement::FILE) { - String path = static_cast<HTMLInputElement*>(control)->value(); + if (current->hasLocalName(inputTag) && + static_cast<HTMLInputElement*>(current)->inputType() == HTMLInputElement::FILE) { + String path = static_cast<HTMLInputElement*>(current)->value(); String filename = pathGetFilename(path); // 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. - appendString(header, "; filename=\""); - appendString(header, encoding.encode(filename.characters(), filename.length(), true)); - header.append('"'); + hstr += "; filename=\""; + hstr += encoding.encode(reinterpret_cast<const UChar*>(filename.characters()), filename.length(), true).data(); + hstr += "\""; - if (!path.isEmpty()) { - String mimeType = MIMETypeRegistry::getMIMETypeForPath(path); + if (!static_cast<HTMLInputElement*>(current)->value().isEmpty()) { + DeprecatedString mimeType = MIMETypeRegistry::getMIMETypeForPath(path).deprecatedString(); if (!mimeType.isEmpty()) { - appendString(header, "\r\nContent-Type: "); - appendString(header, mimeType.latin1()); + hstr += "\r\nContent-Type: "; + hstr += mimeType.ascii(); } } } - appendString(header, "\r\n\r\n"); + hstr += "\r\n\r\n"; // append body - result->appendData(header.data(), header.size()); - const FormDataListItem& item = list.list()[j + 1]; + 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()) @@ -326,12 +362,12 @@ PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const if (m_multipart) { - appendString(encodedData, "--"); - appendString(encodedData, boundary); - appendString(encodedData, "--\r\n"); + enc_string = "--"; + enc_string += boundary; + enc_string += "--\r\n"; } - result->appendData(encodedData.data(), encodedData.size()); + result->appendData(enc_string.data(), enc_string.length()); return result; } @@ -351,7 +387,7 @@ void HTMLFormElement::parseEnctype(const String& type) bool HTMLFormElement::isMailtoForm() const { - return protocolIs(m_url, "mailto"); + return m_url.startsWith("mailto:", false); } bool HTMLFormElement::prepareSubmit(Event* event) @@ -431,8 +467,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; @@ -448,9 +484,9 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton) frame->loader()->clearRecordedFormValues(); for (unsigned i = 0; i < formElements.size(); ++i) { - HTMLGenericFormElement* control = formElements[i]; - if (control->hasLocalName(inputTag)) { - HTMLInputElement* input = static_cast<HTMLInputElement*>(control); + HTMLGenericFormElement* current = formElements[i]; + if (current->hasLocalName(inputTag)) { + HTMLInputElement* input = static_cast<HTMLInputElement*>(current); if (input->isTextField()) { frame->loader()->recordFormValue(input->name(), input->value(), this); if (input->isSearchField()) @@ -458,10 +494,10 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton) } } if (needButtonActivation) { - if (control->isActivatedSubmit()) + if (current->isActivatedSubmit()) needButtonActivation = false; - else if (firstSuccessfulSubmitButton == 0 && control->isSuccessfulSubmitButton()) - firstSuccessfulSubmitButton = control; + else if (firstSuccessfulSubmitButton == 0 && current->isSuccessfulSubmitButton()) + firstSuccessfulSubmitButton = current; } } @@ -469,7 +505,7 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton) firstSuccessfulSubmitButton->setActivatedSubmit(true); if (!m_url) - m_url = document()->url().string(); + m_url = document()->url(); if (m_post) { if (m_multipart && isMailtoForm()) { @@ -483,12 +519,9 @@ 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 = decodeURLEscapeSequences(body.replace('&', "\r\n").replace('+', ' ') + "\r\n"); + body = KURL::decode_string(body.replace('&', "\r\n").replace('+', ' ').deprecatedString() + "\r\n"); } - Vector<char> bodyData; - appendString(bodyData, "body="); - appendEncodedString(bodyData, body.utf8()); - data = FormData::create(String(bodyData.data(), bodyData.size()).replace('+', "%20").latin1()); + data = new FormData((String("body=") + encodeCString(body.utf8())).replace('+', "%20").latin1()); } frame->loader()->submitForm("POST", m_url, data, m_target, enctype(), String(), event); } else { @@ -509,7 +542,7 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton) void HTMLFormElement::reset() { - Frame* frame = document()->frame(); + Frame *frame = document()->frame(); if (m_inreset || !frame) return; @@ -528,7 +561,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()); @@ -556,7 +589,7 @@ void HTMLFormElement::parseMappedAttribute(MappedAttribute* attr) else if (attr->name() == nameAttr) { String newNameAttr = attr->value(); if (inDocument() && document()->isHTMLDocument()) { - HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->removeNamedItem(oldNameAttr); doc->addNamedItem(newNameAttr); } @@ -575,7 +608,7 @@ template<class T, size_t n> static void removeFromVector(Vector<T*, n> & vec, T* } } -unsigned HTMLFormElement::formElementIndex(HTMLGenericFormElement* e) +unsigned HTMLFormElement::formElementIndex(HTMLGenericFormElement *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 @@ -583,12 +616,12 @@ 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<HTMLGenericFormElement *>(node)->form() == this) ++i; } } @@ -608,17 +641,17 @@ void HTMLFormElement::removeFormElement(HTMLGenericFormElement* 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); } diff --git a/WebCore/html/HTMLFormElement.h b/WebCore/html/HTMLFormElement.h index 5a3eee5..73a4aba 100644 --- a/WebCore/html/HTMLFormElement.h +++ b/WebCore/html/HTMLFormElement.h @@ -150,6 +150,11 @@ private: bool m_inreset : 1; bool m_malformed : 1; String oldNameAttr; +#ifdef ANDROID_FIX + // addressing webkit bug, http://bugs.webkit.org/show_bug.cgi?id=16512 + // ensure the oldNameAttr is removed from HTMLDocument's NameCountMap + int oldNameCount; +#endif }; } // namespace WebCore diff --git a/WebCore/html/HTMLFrameElementBase.cpp b/WebCore/html/HTMLFrameElementBase.cpp index 037c755..6438f3c 100644 --- a/WebCore/html/HTMLFrameElementBase.cpp +++ b/WebCore/html/HTMLFrameElementBase.cpp @@ -1,9 +1,11 @@ -/* +/** + * 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,7 +22,6 @@ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ - #include "config.h" #include "HTMLFrameElementBase.h" @@ -60,25 +61,28 @@ bool HTMLFrameElementBase::isURLAllowed(const AtomicString& URLString) const if (URLString.isEmpty()) return true; - KURL completeURL(document()->completeURL(URLString)); + KURL completeURL(document()->completeURL(URLString.deprecatedString())); + completeURL.setRef(DeprecatedString::null); // 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 because WebKit has some + + // FIXME: This limit could be higher, but WebKit has some // algorithms that happen while loading which appear to be N^2 or - // worse in the number of frames, we'll keep it at 200 for now. - if (Frame* parentFrame = document()->frame()) { + // worse in the number of frames + 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()) { - if (equalIgnoringRef(frame->loader()->url(), completeURL)) { + KURL frameURL = frame->loader()->url(); + frameURL.setRef(DeprecatedString::null); + if (frameURL == completeURL) { if (foundSelfReference) return false; foundSelfReference = true; @@ -96,7 +100,7 @@ void HTMLFrameElementBase::openURL() return; if (m_URL.isEmpty()) - m_URL = blankURL().string(); + m_URL = "about:blank"; Frame* parentFrame = document()->frame(); if (!parentFrame) @@ -199,7 +203,7 @@ void HTMLFrameElementBase::attach() renderPart->setWidget(frame->view()); } -KURL HTMLFrameElementBase::location() const +String HTMLFrameElementBase::location() const { return src(); } @@ -298,7 +302,7 @@ void HTMLFrameElementBase::setScrolling(const String &value) setAttribute(scrollingAttr, value); } -KURL HTMLFrameElementBase::src() const +String HTMLFrameElementBase::src() const { return document()->completeURL(getAttribute(srcAttr)); } diff --git a/WebCore/html/HTMLFrameElementBase.h b/WebCore/html/HTMLFrameElementBase.h index e1d1397..bcb63ac 100644 --- a/WebCore/html/HTMLFrameElementBase.h +++ b/WebCore/html/HTMLFrameElementBase.h @@ -1,8 +1,10 @@ /* + * 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -38,7 +40,7 @@ public: virtual void attach(); - KURL location() const; + String location() const; void setLocation(const String&); virtual bool isFocusable() const; @@ -72,7 +74,7 @@ public: String scrolling() const; void setScrolling(const String&); - KURL src() const; + String src() const; void setSrc(const String&); int width() const; diff --git a/WebCore/html/HTMLFrameSetElement.cpp b/WebCore/html/HTMLFrameSetElement.cpp index 5e23672..c49b0f8 100644 --- a/WebCore/html/HTMLFrameSetElement.cpp +++ b/WebCore/html/HTMLFrameSetElement.cpp @@ -189,6 +189,9 @@ void HTMLFrameSetElement::recalcStyle(StyleChange ch) { if (changed() && renderer()) { renderer()->setNeedsLayout(true); +#ifdef FLATTEN_FRAMESET + static_cast<RenderFrameSet*>(renderer())->setGridNeedsLayout(); +#endif setChanged(NoStyleChange); } HTMLElement::recalcStyle(ch); diff --git a/WebCore/html/HTMLGenericFormElement.cpp b/WebCore/html/HTMLGenericFormElement.cpp index c40599c..2eab0a8 100644 --- a/WebCore/html/HTMLGenericFormElement.cpp +++ b/WebCore/html/HTMLGenericFormElement.cpp @@ -37,6 +37,10 @@ #include "RenderTheme.h" #include "Tokenizer.h" +#if USE(LOW_BANDWIDTH_DISPLAY) +#include "FrameLoader.h" +#endif + namespace WebCore { using namespace EventNames; @@ -258,4 +262,15 @@ 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/HTMLGenericFormElement.h index 7126235..ec18aa9 100644 --- a/WebCore/html/HTMLGenericFormElement.h +++ b/WebCore/html/HTMLGenericFormElement.h @@ -88,6 +88,10 @@ public: virtual bool isActivatedSubmit() const { return false; } virtual void setActivatedSubmit(bool flag) { } +#if USE(LOW_BANDWIDTH_DISPLAY) + virtual bool rendererIsNeeded(RenderStyle*); +#endif + void setTabIndex(int); void formDestroyed() { m_form = 0; } diff --git a/WebCore/html/HTMLImageElement.cpp b/WebCore/html/HTMLImageElement.cpp index 66728da..d2c74eb 100644 --- a/WebCore/html/HTMLImageElement.cpp +++ b/WebCore/html/HTMLImageElement.cpp @@ -44,6 +44,11 @@ HTMLImageElement::HTMLImageElement(Document* doc, HTMLFormElement* f) , ismap(false) , m_form(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 + , oldNameIdCount(0) +#endif { if (f) f->registerImgElement(this); @@ -55,11 +60,25 @@ HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* doc) , ismap(false) , m_form(0) , 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 + , oldNameIdCount(0) +#endif { } 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 + if (oldNameIdCount && document()->isHTMLDocument()) { + HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + doc->removeNamedItem(oldNameAttr); + doc->removeDocExtraNamedItem(oldIdAttr); + } +#endif if (m_form) m_form->removeImgElement(this); } @@ -113,10 +132,10 @@ void HTMLImageElement::parseMappedAttribute(MappedAttribute* attr) else if (attrName == valignAttr) addCSSProperty(attr, CSS_PROP_VERTICAL_ALIGN, attr->value()); else if (attrName == usemapAttr) { - if (attr->value().string()[0] == '#') + if (attr->value().domString()[0] == '#') usemap = attr->value(); else - usemap = document()->completeURL(parseURL(attr->value())).string(); + usemap = document()->completeURL(parseURL(attr->value())); m_isLink = !attr->isNull(); } else if (attrName == ismapAttr) ismap = true; @@ -191,6 +210,11 @@ void HTMLImageElement::insertedIntoDocument() doc->addNamedItem(oldNameAttr); doc->addDocExtraNamedItem(oldIdAttr); +#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 + oldNameIdCount++; +#endif } HTMLElement::insertedIntoDocument(); @@ -203,6 +227,11 @@ void HTMLImageElement::removedFromDocument() doc->removeNamedItem(oldNameAttr); doc->removeDocExtraNamedItem(oldIdAttr); +#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 + oldNameIdCount--; +#endif } HTMLElement::removedFromDocument(); @@ -273,7 +302,7 @@ bool HTMLImageElement::isURLAttribute(Attribute* attr) const return attr->name() == srcAttr || attr->name() == lowsrcAttr || attr->name() == longdescAttr - || (attr->name() == usemapAttr && attr->value().string()[0] != '#'); + || (attr->name() == usemapAttr && attr->value().domString()[0] != '#'); } String HTMLImageElement::name() const @@ -342,7 +371,7 @@ void HTMLImageElement::setIsMap(bool isMap) setAttribute(ismapAttr, isMap ? "" : 0); } -KURL HTMLImageElement::longDesc() const +String HTMLImageElement::longDesc() const { return document()->completeURL(getAttribute(longdescAttr)); } @@ -352,7 +381,7 @@ void HTMLImageElement::setLongDesc(const String& value) setAttribute(longdescAttr, value); } -KURL HTMLImageElement::lowsrc() const +String HTMLImageElement::lowsrc() const { return document()->completeURL(getAttribute(lowsrcAttr)); } @@ -362,7 +391,7 @@ void HTMLImageElement::setLowsrc(const String& value) setAttribute(lowsrcAttr, value); } -KURL HTMLImageElement::src() const +String HTMLImageElement::src() const { return document()->completeURL(getAttribute(srcAttr)); } diff --git a/WebCore/html/HTMLImageElement.h b/WebCore/html/HTMLImageElement.h index 5bf8afd..1ce3a74 100644 --- a/WebCore/html/HTMLImageElement.h +++ b/WebCore/html/HTMLImageElement.h @@ -1,7 +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) - * Copyright (C) 2004, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,13 +25,12 @@ #ifndef HTMLImageElement_h #define HTMLImageElement_h -#include "GraphicsTypes.h" #include "HTMLElement.h" +#include "GraphicsTypes.h" #include "HTMLImageLoader.h" namespace WebCore { - -class HTMLFormElement; + class HTMLFormElement; class HTMLImageElement : public HTMLElement { friend class HTMLFormElement; @@ -61,6 +62,8 @@ public: String altText() const; + String imageMap() const { return usemap; } + virtual bool isURLAttribute(Attribute*) const; CompositeOperator compositeOperator() const { return m_compositeOperator; } @@ -90,13 +93,13 @@ public: bool isMap() const; void setIsMap(bool); - KURL longDesc() const; + String longDesc() const; void setLongDesc(const String&); - KURL lowsrc() const; + String lowsrc() const; void setLowsrc(const String&); - KURL src() const; + String src() const; void setSrc(const String&); String useMap() const; @@ -113,8 +116,7 @@ public: bool complete() const; bool haveFiredLoadEvent() const { return m_imageLoader.haveFiredLoadEvent(); } - -private: +protected: HTMLImageLoader m_imageLoader; String usemap; bool ismap; @@ -122,6 +124,11 @@ private: String oldNameAttr; String oldIdAttr; 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 + int oldNameIdCount; +#endif }; } //namespace diff --git a/WebCore/html/HTMLImageLoader.cpp b/WebCore/html/HTMLImageLoader.cpp index 2565987..f7fecb6 100644 --- a/WebCore/html/HTMLImageLoader.cpp +++ b/WebCore/html/HTMLImageLoader.cpp @@ -29,7 +29,6 @@ #include "Element.h" #include "EventNames.h" #include "HTMLNames.h" -#include "HTMLObjectElement.h" #include "RenderImage.h" using namespace std; @@ -143,9 +142,6 @@ void HTMLImageLoader::notifyFinished(CachedResource *image) if (RenderObject* renderer = elem->renderer()) if (renderer->isImage()) static_cast<RenderImage*>(renderer)->setCachedImage(m_image); - - if (image->errorOccurred() && elem->hasTagName(objectTag)) - static_cast<HTMLObjectElement*>(elem)->renderFallbackContent(); } } diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp index d83235a..e9c2267 100644 --- a/WebCore/html/HTMLInputElement.cpp +++ b/WebCore/html/HTMLInputElement.cpp @@ -53,6 +53,14 @@ #include "SelectionController.h" #include "TextBreakIterator.h" #include "TextEvent.h" +#if USE(LOW_BANDWIDTH_DISPLAY) +#include "FrameLoader.h" +#endif +#ifdef ANDROID // multiple additions: see below +#include "FrameAndroid.h" +#include "FrameView.h" +#include "WebCoreViewBridge.h" +#endif #include "TextIterator.h" using namespace std; @@ -178,6 +186,7 @@ bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const if (name().isEmpty()) return false; +#ifndef ANDROID_KEYBOARD_NAVIGATION // Never allow keyboard tabbing to leave you in the same radio group. Always // skip any other elements in the group. Node* currentFocusedNode = document()->focusedNode(); @@ -187,6 +196,7 @@ bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const focusedInput->name() == name()) return false; } +#endif // Allow keyboard focus if we're checked or if nothing in the group is checked. return checked() || !checkedRadioButtons(this).checkedButtonForGroup(name()); @@ -262,7 +272,18 @@ void HTMLInputElement::setInputType(const String& t) InputType newType; if (equalIgnoringCase(t, "password")) +#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS + { + if (document()->focusedNode() == this) + { + WebCoreViewBridge* viewImpl = document()->frame()->view()->getWebCoreViewBridge(); + viewImpl->updateTextfield(this, true, String()); + } +#endif newType = PASSWORD; +#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS + } +#endif else if (equalIgnoringCase(t, "checkbox")) newType = CHECKBOX; else if (equalIgnoringCase(t, "radio")) @@ -670,6 +691,13 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr) bool HTMLInputElement::rendererIsNeeded(RenderStyle *style) { +#if USE(LOW_BANDWIDTH_DISPLAY) + if (document()->inLowBandwidthDisplay()) { + document()->frame()->loader()->needToSwitchOutLowBandwidthDisplay(); + return false; + } +#endif + switch (inputType()) { case BUTTON: case CHECKBOX: @@ -974,7 +1002,16 @@ void HTMLInputElement::setValue(const String& value) if (isTextField()) { unsigned max = m_value.length(); if (document()->focusedNode() == this) +#ifndef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS + setSelectionRange(max, max); +#else + { + // Make sure our UI side textfield changes to match the RenderTextControl + WebCoreViewBridge* viewImpl = document()->frame()->view()->getWebCoreViewBridge(); + viewImpl->updateTextfield(this, false, value); setSelectionRange(max, max); + } +#endif else { cachedSelStart = max; cachedSelEnd = max; @@ -1195,6 +1232,11 @@ void HTMLInputElement::defaultEventHandler(Event* evt) clickElement = true; break; case RADIO: +#ifdef ANDROID_KEYBOARD_NAVIGATION +// allow enter to change state of radio + if (!checked()) + clickElement = true; +#endif break; // Don't do anything for enter on a radio button. } } else if (charCode == ' ') { @@ -1241,6 +1283,8 @@ void HTMLInputElement::defaultEventHandler(Event* evt) } } +#ifndef ANDROID_KEYBOARD_NAVIGATION +// allow enter to change state of radio if (inputType() == RADIO && (key == "Up" || key == "Down" || key == "Left" || key == "Right")) { // Left and up mean "previous radio button". // Right and down mean "next radio button". @@ -1275,6 +1319,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt) } } } +#endif } if (evt->type() == keyupEvent && evt->isKeyboardEvent()) { @@ -1449,7 +1494,7 @@ void HTMLInputElement::setSize(unsigned _size) setAttribute(sizeAttr, String::number(_size)); } -KURL HTMLInputElement::src() const +String HTMLInputElement::src() const { return document()->completeURL(getAttribute(srcAttr)); } diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h index e50274b..410f2e1 100644 --- a/WebCore/html/HTMLInputElement.h +++ b/WebCore/html/HTMLInputElement.h @@ -30,7 +30,6 @@ namespace WebCore { class HTMLImageLoader; -class KURL; class Selection; class HTMLInputElement : public HTMLFormControlElementWithState { @@ -167,7 +166,7 @@ public: void setSize(unsigned); - KURL src() const; + String src() const; void setSrc(const String&); void setMaxLength(int); diff --git a/WebCore/html/HTMLLinkElement.cpp b/WebCore/html/HTMLLinkElement.cpp index cc719d5..b002a0c 100644 --- a/WebCore/html/HTMLLinkElement.cpp +++ b/WebCore/html/HTMLLinkElement.cpp @@ -1,8 +1,10 @@ -/* +/** + * 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,7 +21,6 @@ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ - #include "config.h" #include "HTMLLinkElement.h" @@ -104,16 +105,20 @@ 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 process(); } else if (attr->name() == hrefAttr) { - m_url = document()->completeURL(parseURL(attr->value())).string(); + m_url = document()->completeURL(parseURL(attr->value())); process(); } else if (attr->name() == typeAttr) { m_type = attr->value(); process(); } else if (attr->name() == mediaAttr) { - m_media = attr->value().string().lower(); + m_media = attr->value().domString().lower(); process(); } else if (attr->name() == disabledAttr) { setDisabledState(!attr->isNull()); @@ -124,10 +129,40 @@ void HTMLLinkElement::parseMappedAttribute(MappedAttribute *attr) } } +#ifdef ANDROID_PRELOAD_CHANGES +void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& relStr, bool& styleSheet, bool& alternate, bool& icon) +{ + styleSheet = false; + icon = false; + alternate = false; + String rel = relStr.domString().lower(); + if (rel == "stylesheet") + styleSheet = true; + else if (rel == "icon" || rel == "shortcut icon") + icon = true; + else if (rel == "alternate stylesheet" || 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(' '); + Vector<String>::const_iterator end = list.end(); + for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) { + if (*it == "stylesheet") + styleSheet = true; + else if (*it == "alternate") + alternate = true; + else if (*it == "icon") + icon = true; + } + } +} +#else void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& relStr) { m_isStyleSheet = m_isIcon = m_alternate = false; - String rel = relStr.string().lower(); + String rel = relStr.domString().lower(); if (rel == "stylesheet") m_isStyleSheet = true; else if (rel == "icon" || rel == "shortcut icon") @@ -137,8 +172,7 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& relStr) else { // Tokenize the rel attribute and set bits based on specific keywords that we find. rel.replace('\n', ' '); - Vector<String> list; - rel.split(' ', list); + 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") @@ -150,6 +184,7 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& relStr) } } } +#endif void HTMLLinkElement::process() { @@ -165,7 +200,7 @@ void HTMLLinkElement::process() // Stylesheet // This was buggy and would incorrectly match <link rel="alternate">, which has a different specified meaning. -dwh - if (m_disabledState != 2 && m_isStyleSheet && document()->frame()) { + if (m_disabledState != 2 && (type.contains("text/css") || 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 @@ -217,11 +252,10 @@ void HTMLLinkElement::removedFromDocument() process(); } -void HTMLLinkElement::setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet* sheet) +void HTMLLinkElement::setCSSStyleSheet(const String& url, const String& charset, const String& sheetStr) { - bool strict = !document()->inCompatMode(); m_sheet = new CSSStyleSheet(this, url, charset); - m_sheet->parseString(sheet->sheetText(strict), strict); + m_sheet->parseString(sheetStr, !document()->inCompatMode()); m_sheet->setTitle(title()); RefPtr<MediaList> media = new MediaList((CSSStyleSheet*)0, m_media, true); @@ -274,7 +308,7 @@ void HTMLLinkElement::setCharset(const String& value) setAttribute(charsetAttr, value); } -KURL HTMLLinkElement::href() const +String HTMLLinkElement::href() const { return document()->completeURL(getAttribute(hrefAttr)); } diff --git a/WebCore/html/HTMLLinkElement.h b/WebCore/html/HTMLLinkElement.h index 07a9228..b9c31e6 100644 --- a/WebCore/html/HTMLLinkElement.h +++ b/WebCore/html/HTMLLinkElement.h @@ -1,7 +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) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,20 +21,19 @@ * Boston, MA 02110-1301, USA. * */ - #ifndef HTMLLinkElement_h #define HTMLLinkElement_h -#include "CSSStyleSheet.h" -#include "CachedResourceClient.h" #include "HTMLElement.h" +#include "CachedResourceClient.h" +#include "CSSStyleSheet.h" namespace WebCore { class CachedCSSStyleSheet; -class KURL; -class HTMLLinkElement : public HTMLElement, public CachedResourceClient { +class HTMLLinkElement : public HTMLElement, public CachedResourceClient +{ public: HTMLLinkElement(Document*); ~HTMLLinkElement(); @@ -46,7 +47,7 @@ public: String charset() const; void setCharset(const String&); - KURL href() const; + String href() const; void setHref(const String&); String hreflang() const; @@ -78,7 +79,7 @@ public: virtual void removedFromDocument(); // from CachedResourceClient - virtual void setCSSStyleSheet(const String &url, const String& charset, const CachedCSSStyleSheet* sheet); + virtual void setCSSStyleSheet(const String &url, const String& charset, const String &sheet); bool isLoading() const; virtual bool sheetLoaded(); @@ -90,8 +91,11 @@ public: 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 protected: CachedCSSStyleSheet* m_cachedSheet; @@ -100,10 +104,17 @@ protected: 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 }; } //namespace diff --git a/WebCore/html/HTMLMapElement.cpp b/WebCore/html/HTMLMapElement.cpp index ef2673e..2fce481 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->isHTMLDocument()) + if (doc->htmlMode() != Document::XHtml) return; } doc->removeImageMap(this); String mapName = attr->value(); if (mapName[0] == '#') mapName = mapName.substring(1); - m_name = doc->isHTMLDocument() ? mapName.lower() : mapName; + m_name = doc->htmlMode() == Document::XHtml ? mapName : mapName.lower(); doc->addImageMap(this); } else HTMLElement::parseMappedAttribute(attr); diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp index bac3093..cccf0fd 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 @@ -226,7 +226,7 @@ PassRefPtr<MediaError> HTMLMediaElement::error() const return m_error; } -KURL HTMLMediaElement::src() const +String HTMLMediaElement::src() const { return document()->completeURL(getAttribute(srcAttr)); } @@ -809,7 +809,7 @@ String HTMLMediaElement::pickMedia() if (!source->hasAttribute(srcAttr)) continue; if (source->hasAttribute(mediaAttr)) { - MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0); + MediaQueryEvaluator screenEval("screen", document()->page(), renderer() ? renderer()->style() : 0); RefPtr<MediaList> media = new MediaList((CSSStyleSheet*)0, source->media(), true); if (!screenEval.eval(media.get())) continue; @@ -819,13 +819,13 @@ String HTMLMediaElement::pickMedia() if (!MIMETypeRegistry::isSupportedMediaMIMEType(type)) continue; } - mediaSrc = source->src().string(); + mediaSrc = source->src(); break; } } } if (!mediaSrc.isEmpty()) - mediaSrc = document()->completeURL(mediaSrc).string(); + mediaSrc = document()->completeURL(mediaSrc); return mediaSrc; } diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h index 6fd5de3..91520b0 100644 --- a/WebCore/html/HTMLMediaElement.h +++ b/WebCore/html/HTMLMediaElement.h @@ -37,7 +37,6 @@ namespace WebCore { class MediaError; class TimeRanges; -class KURL; class HTMLMediaElement : public HTMLElement, public MediaPlayerClient { public: @@ -72,7 +71,7 @@ public: PassRefPtr<MediaError> error() const; // network state - KURL src() const; + String src() const; void setSrc(const String&); String currentSrc() const; diff --git a/WebCore/html/HTMLMetaElement.cpp b/WebCore/html/HTMLMetaElement.cpp index f93770d..f2b5c4a 100644 --- a/WebCore/html/HTMLMetaElement.cpp +++ b/WebCore/html/HTMLMetaElement.cpp @@ -62,6 +62,12 @@ void HTMLMetaElement::insertedIntoDocument() void HTMLMetaElement::process() { +#ifdef ANDROID_META_SUPPORT + if (!inDocument() || m_content.isNull()) + return; + if (equalIgnoringCase(name(), "viewport") || equalIgnoringCase(name(), "format-detection")) + document()->processMetadataSettings(m_content); +#endif // Get the document to process the tag, but only if we're actually part of DOM tree (changing a meta tag while // it's not in the tree shouldn't have any effect on the document) if (inDocument() && !m_equiv.isNull() && !m_content.isNull()) diff --git a/WebCore/html/HTMLObjectElement.cpp b/WebCore/html/HTMLObjectElement.cpp index 436b641..810496c 100644 --- a/WebCore/html/HTMLObjectElement.cpp +++ b/WebCore/html/HTMLObjectElement.cpp @@ -2,7 +2,7 @@ * 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. * Copyright (C) 2007 Trolltech ASA * * This library is free software; you can redistribute it and/or @@ -57,6 +57,15 @@ HTMLObjectElement::HTMLObjectElement(Document* doc, bool createdByParser) 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 + if (oldNameIdCount && document()->isHTMLDocument()) { + HTMLDocument* doc = static_cast<HTMLDocument*>(document()); + doc->removeNamedItem(oldNameAttr); + doc->removeDocExtraNamedItem(oldIdAttr); + } +#endif #if USE(JAVASCRIPTCORE_BINDINGS) // m_instance should have been cleaned up in detach(). ASSERT(!m_instance); @@ -171,10 +180,6 @@ void HTMLObjectElement::attach() if (!m_imageLoader) m_imageLoader.set(new HTMLImageLoader(this)); m_imageLoader->updateFromElement(); - // updateForElement() may have changed us to use fallback content and called detach() and attach(). - if (m_useFallbackContent) - return; - if (renderer()) { RenderImage* imageObj = static_cast<RenderImage*>(renderer()); imageObj->setCachedImage(m_imageLoader->image()); @@ -217,6 +222,11 @@ void HTMLObjectElement::insertedIntoDocument() HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->addNamedItem(oldNameAttr); doc->addDocExtraNamedItem(oldIdAttr); +#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 + oldNameIdCount++; +#endif } HTMLPlugInElement::insertedIntoDocument(); @@ -228,6 +238,11 @@ void HTMLObjectElement::removedFromDocument() HTMLDocument *doc = static_cast<HTMLDocument *>(document()); doc->removeNamedItem(oldNameAttr); doc->removeDocExtraNamedItem(oldIdAttr); +#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 + oldNameIdCount--; +#endif } HTMLPlugInElement::removedFromDocument(); @@ -242,19 +257,19 @@ void HTMLObjectElement::recalcStyle(StyleChange ch) HTMLPlugInElement::recalcStyle(ch); } -void HTMLObjectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +void HTMLObjectElement::childrenChanged(bool changedByParser) { updateDocNamedItem(); if (inDocument() && !m_useFallbackContent) { m_needWidgetUpdate = true; setChanged(); } - HTMLPlugInElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + HTMLPlugInElement::childrenChanged(changedByParser); } bool HTMLObjectElement::isURLAttribute(Attribute *attr) const { - return (attr->name() == dataAttr || (attr->name() == usemapAttr && attr->value().string()[0] != '#')); + return (attr->name() == dataAttr || (attr->name() == usemapAttr && attr->value().domString()[0] != '#')); } const QualifiedName& HTMLObjectElement::imageSourceAttributeName() const @@ -264,7 +279,7 @@ const QualifiedName& HTMLObjectElement::imageSourceAttributeName() const bool HTMLObjectElement::isImageType() { - if (m_serviceType.isEmpty() && protocolIs(m_url, "data")) { + if (m_serviceType.isEmpty() && m_url.startsWith("data:")) { // Extract the MIME type from the data URL. int index = m_url.find(';'); if (index == -1) @@ -290,16 +305,6 @@ 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()) { - detach(); - attach(); - return; - } - } - // Mark ourselves as using the fallback content. m_useFallbackContent = true; @@ -392,7 +397,7 @@ void HTMLObjectElement::setCodeType(const String& value) setAttribute(codetypeAttr, value); } -KURL HTMLObjectElement::data() const +String HTMLObjectElement::data() const { return document()->completeURL(getAttribute(dataAttr)); } @@ -477,8 +482,8 @@ bool HTMLObjectElement::containsJavaApplet() const if (child->isElementNode()) { Element* e = static_cast<Element*>(child); if (e->hasTagName(paramTag) && - e->getAttribute(nameAttr).string().lower() == "type" && - MIMETypeRegistry::isJavaAppletMIMEType(e->getAttribute(valueAttr).string())) + e->getAttribute(nameAttr).domString().lower() == "type" && + MIMETypeRegistry::isJavaAppletMIMEType(e->getAttribute(valueAttr).domString())) return true; else if (e->hasTagName(objectTag) && static_cast<HTMLObjectElement*>(e)->containsJavaApplet()) return true; diff --git a/WebCore/html/HTMLObjectElement.h b/WebCore/html/HTMLObjectElement.h index 32c297c..0a87b9f 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -29,7 +29,6 @@ namespace WebCore { class HTMLImageLoader; -class KURL; class HTMLObjectElement : public HTMLPlugInElement { public: @@ -49,7 +48,7 @@ public: virtual void removedFromDocument(); virtual void recalcStyle(StyleChange); - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void childrenChanged(bool changedByParser = false); virtual bool isURLAttribute(Attribute*) const; virtual const QualifiedName& imageSourceAttributeName() const; @@ -80,7 +79,7 @@ public: String codeType() const; void setCodeType(const String&); - KURL data() const; + String data() const; void setData(const String&); bool declare() const; diff --git a/WebCore/html/HTMLOptGroupElement.cpp b/WebCore/html/HTMLOptGroupElement.cpp index 831e572..d317fc5 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. * (C) 2006 Alexey Proskuryakov (ap@nypop.com) * * This library is free software; you can redistribute it and/or @@ -92,10 +92,10 @@ bool HTMLOptGroupElement::removeChildren() return result; } -void HTMLOptGroupElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +void HTMLOptGroupElement::childrenChanged(bool changedByParser) { recalcSelectOptions(); - HTMLGenericFormElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + HTMLGenericFormElement::childrenChanged(changedByParser); } void HTMLOptGroupElement::parseMappedAttribute(MappedAttribute* attr) @@ -160,7 +160,7 @@ void HTMLOptGroupElement::setRenderStyle(RenderStyle* newStyle) String HTMLOptGroupElement::groupLabelText() const { - String itemText = getAttribute(labelAttr); + DeprecatedString itemText = getAttribute(labelAttr).deprecatedString(); itemText.replace('\\', document()->backslashAsCurrencySymbol()); // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior. diff --git a/WebCore/html/HTMLOptGroupElement.h b/WebCore/html/HTMLOptGroupElement.h index 751cf17..6127b19 100644 --- a/WebCore/html/HTMLOptGroupElement.h +++ b/WebCore/html/HTMLOptGroupElement.h @@ -47,7 +47,7 @@ public: virtual bool removeChild(Node* child, ExceptionCode&); virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&); virtual bool removeChildren(); - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void childrenChanged(bool changedByParser = false); String label() const; void setLabel(const String&); diff --git a/WebCore/html/HTMLOptionElement.cpp b/WebCore/html/HTMLOptionElement.cpp index e3944a8..db4f020 100644 --- a/WebCore/html/HTMLOptionElement.cpp +++ b/WebCore/html/HTMLOptionElement.cpp @@ -187,12 +187,12 @@ void HTMLOptionElement::setSelectedState(bool selected) setChanged(); } -void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +void HTMLOptionElement::childrenChanged(bool changedByParser) { HTMLSelectElement *select = getSelect(); if (select) select->childrenChanged(changedByParser); - HTMLGenericFormElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + HTMLGenericFormElement::childrenChanged(changedByParser); } HTMLSelectElement* HTMLOptionElement::getSelect() const diff --git a/WebCore/html/HTMLOptionElement.h b/WebCore/html/HTMLOptionElement.h index f585ff0..635a7b3 100644 --- a/WebCore/html/HTMLOptionElement.h +++ b/WebCore/html/HTMLOptionElement.h @@ -68,7 +68,7 @@ public: HTMLSelectElement* getSelect() const; - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void childrenChanged(bool changedByParser = false); bool defaultSelected() const; void setDefaultSelected(bool); diff --git a/WebCore/html/HTMLParamElement.cpp b/WebCore/html/HTMLParamElement.cpp index c716e9d..d1e2616 100644 --- a/WebCore/html/HTMLParamElement.cpp +++ b/WebCore/html/HTMLParamElement.cpp @@ -45,7 +45,7 @@ void HTMLParamElement::parseMappedAttribute(MappedAttribute *attr) if (attr->name() == idAttr) { // Must call base class so that hasID bit gets set. HTMLElement::parseMappedAttribute(attr); - if (document()->isHTMLDocument()) + if (document()->htmlMode() != Document::XHtml) return; m_name = attr->value(); } else if (attr->name() == nameAttr) { @@ -61,7 +61,7 @@ bool HTMLParamElement::isURLAttribute(Attribute *attr) const if (attr->name() == valueAttr) { Attribute *attr = attributes()->getAttributeItem(nameAttr); if (attr) { - String value = attr->value().string().lower(); + String value = attr->value().domString().lower(); if (value == "src" || value == "movie" || value == "data") return true; } diff --git a/WebCore/html/HTMLParser.cpp b/WebCore/html/HTMLParser.cpp index c7e444e..8102680 100644 --- a/WebCore/html/HTMLParser.cpp +++ b/WebCore/html/HTMLParser.cpp @@ -29,7 +29,6 @@ #include "CSSValueKeywords.h" #include "Comment.h" #include "DocumentFragment.h" -#include "DocumentType.h" #include "Frame.h" #include "HTMLBodyElement.h" #include "HTMLDocument.h" @@ -272,16 +271,6 @@ 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(new DocumentType(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); @@ -688,6 +677,13 @@ 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. @@ -802,6 +798,7 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t) gFunctionMap.set(framesetTag.localName().impl(), &HTMLParser::framesetCreateErrorCheck); gFunctionMap.set(headTag.localName().impl(), &HTMLParser::headCreateErrorCheck); 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(mapTag.localName().impl(), &HTMLParser::mapCreateErrorCheck); @@ -1405,7 +1402,7 @@ PassRefPtr<Node> HTMLParser::handleIsindex(Token* t) String text = searchableIndexIntroduction(); if (attrs) { if (Attribute* a = attrs->getAttributeItem(promptAttr)) - text = a->value().string() + " "; + text = a->value().domString() + " "; t->attrs = 0; } @@ -1488,9 +1485,7 @@ 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().string()); + page->chrome()->addMessageToConsole(HTMLMessageSource, isWarning(errorCode) ? WarningMessageLevel: ErrorMessageLevel, message, lineNumber, document->url()); } } diff --git a/WebCore/html/HTMLParser.h b/WebCore/html/HTMLParser.h index 7c6a022..0c51a3f 100644 --- a/WebCore/html/HTMLParser.h +++ b/WebCore/html/HTMLParser.h @@ -31,7 +31,6 @@ namespace WebCore { -class DoctypeToken; class Document; class DocumentFragment; class HTMLDocument; @@ -58,9 +57,6 @@ 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 */ diff --git a/WebCore/html/HTMLPlugInElement.cpp b/WebCore/html/HTMLPlugInElement.cpp index 93e1bf6..223591a 100644 --- a/WebCore/html/HTMLPlugInElement.cpp +++ b/WebCore/html/HTMLPlugInElement.cpp @@ -57,6 +57,11 @@ HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc #if USE(NPOBJECT) , 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 + , oldNameIdCount(0) +#endif { } diff --git a/WebCore/html/HTMLPlugInElement.h b/WebCore/html/HTMLPlugInElement.h index 2b9ed53..5fad211 100644 --- a/WebCore/html/HTMLPlugInElement.h +++ b/WebCore/html/HTMLPlugInElement.h @@ -85,6 +85,11 @@ protected: #if USE(NPOBJECT) 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 + int oldNameIdCount; +#endif }; } // namespace WebCore diff --git a/WebCore/html/HTMLScriptElement.cpp b/WebCore/html/HTMLScriptElement.cpp index 0d5209c..9857c1f 100644 --- a/WebCore/html/HTMLScriptElement.cpp +++ b/WebCore/html/HTMLScriptElement.cpp @@ -1,8 +1,10 @@ -/* +/** + * 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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,7 +21,6 @@ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ - #include "config.h" #include "HTMLScriptElement.h" @@ -39,7 +40,7 @@ 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) @@ -53,22 +54,22 @@ HTMLScriptElement::~HTMLScriptElement() m_cachedScript->deref(this); } -bool HTMLScriptElement::isURLAttribute(Attribute* attr) const +bool HTMLScriptElement::isURLAttribute(Attribute *attr) const { return attr->name() == srcAttr; } -void HTMLScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +void HTMLScriptElement::childrenChanged(bool changedByParser) { // 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().string(), text()); - HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + evaluateScript(document()->url(), text()); + HTMLElement::childrenChanged(changedByParser); } -void HTMLScriptElement::parseMappedAttribute(MappedAttribute* attr) +void HTMLScriptElement::parseMappedAttribute(MappedAttribute *attr) { const QualifiedName& attrName = attr->name(); if (attrName == srcAttr) { @@ -120,7 +121,7 @@ void HTMLScriptElement::insertedIntoDocument() const AtomicString& url = getAttribute(srcAttr); if (!url.isEmpty()) { - String scriptSrcCharset = getAttribute(charsetAttr).string().stripWhiteSpace(); + String scriptSrcCharset = getAttribute(charsetAttr).domString().stripWhiteSpace(); if (scriptSrcCharset.isEmpty()) { if (Frame* frame = document()->frame()) scriptSrcCharset = frame->loader()->encoding(); @@ -138,7 +139,7 @@ void HTMLScriptElement::insertedIntoDocument() // it should be evaluated, and evaluateScript only evaluates a script once. String scriptString = text(); if (!scriptString.isEmpty()) - evaluateScript(document()->url().string(), scriptString); + evaluateScript(document()->url(), scriptString); } void HTMLScriptElement::removedFromDocument() @@ -153,7 +154,7 @@ void HTMLScriptElement::removedFromDocument() void HTMLScriptElement::notifyFinished(CachedResource* o) { - CachedScript* cs = static_cast<CachedScript*>(o); + CachedScript *cs = static_cast<CachedScript *>(o); ASSERT(cs == m_cachedScript); @@ -202,7 +203,7 @@ bool HTMLScriptElement::shouldExecuteAsJavaScript() const AtomicString& type = getAttribute(typeAttr); if (!type.isEmpty()) { - String lowerType = type.string().stripWhiteSpace().lower(); + String lowerType = type.domString().stripWhiteSpace().lower(); if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(lowerType)) return true; @@ -211,7 +212,7 @@ bool HTMLScriptElement::shouldExecuteAsJavaScript() const AtomicString& language = getAttribute(languageAttr); if (!language.isEmpty()) { - String lowerLanguage = language.string().lower(); + String lowerLanguage = language.domString().lower(); for (unsigned i = 0; i < validLanguagesCount; ++i) if (lowerLanguage == validLanguages[i]) return true; @@ -243,14 +244,14 @@ void HTMLScriptElement::evaluateScript(const String& url, const String& script) String HTMLScriptElement::text() const { - Vector<UChar> val; + String val = ""; - for (Node* n = firstChild(); n; n = n->nextSibling()) { + for (Node *n = firstChild(); n; n = n->nextSibling()) { if (n->isTextNode()) - append(val, static_cast<Text*>(n)->data()); + val += static_cast<Text *>(n)->data(); } - return String::adopt(val); + return val; } void HTMLScriptElement::setText(const String &value) @@ -263,8 +264,9 @@ void HTMLScriptElement::setText(const String &value) return; } - if (numChildren > 0) + if (numChildren > 0) { removeChildren(); + } appendChild(document()->createTextNode(value.impl()), ec); } @@ -275,7 +277,7 @@ String HTMLScriptElement::htmlFor() const return String(); } -void HTMLScriptElement::setHtmlFor(const String& /*value*/) +void HTMLScriptElement::setHtmlFor(const String &/*value*/) { // DOM Level 1 says: reserved for future use. } @@ -286,7 +288,7 @@ String HTMLScriptElement::event() const return String(); } -void HTMLScriptElement::setEvent(const String& /*value*/) +void HTMLScriptElement::setEvent(const String &/*value*/) { // DOM Level 1 says: reserved for future use. } @@ -311,7 +313,7 @@ void HTMLScriptElement::setDefer(bool defer) setAttribute(deferAttr, defer ? "" : 0); } -KURL HTMLScriptElement::src() const +String HTMLScriptElement::src() const { return document()->completeURL(getAttribute(srcAttr)); } diff --git a/WebCore/html/HTMLScriptElement.h b/WebCore/html/HTMLScriptElement.h index 26935ae..1bf7d7e 100644 --- a/WebCore/html/HTMLScriptElement.h +++ b/WebCore/html/HTMLScriptElement.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, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -44,7 +44,7 @@ public: virtual void removedFromDocument(); virtual void notifyFinished(CachedResource*); - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void childrenChanged(bool changedByParser = false); virtual bool isURLAttribute(Attribute*) const; @@ -69,7 +69,7 @@ public: bool defer() const; void setDefer(bool); - KURL src() const; + String src() const; void setSrc(const String&); String type() const; diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp index e1ba0ff..115e473 100644 --- a/WebCore/html/HTMLSelectElement.cpp +++ b/WebCore/html/HTMLSelectElement.cpp @@ -529,10 +529,10 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const m_recalcListItems = false; } -void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +void HTMLSelectElement::childrenChanged(bool changedByParser) { setRecalcListItems(); - HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + HTMLFormControlElementWithState::childrenChanged(changedByParser); } void HTMLSelectElement::setRecalcListItems() @@ -583,10 +583,12 @@ void HTMLSelectElement::dispatchFocusEvent() void HTMLSelectElement::dispatchBlurEvent() { +#ifndef ANDROID_NAVIGATE_LISTBOX // We only need to fire onChange here for menu lists, because we fire onChange for list boxes whenever the selection change is actually made. // This matches other browsers' behavior. if (usesMenuList()) menuListOnChange(); +#endif HTMLFormControlElementWithState::dispatchBlurEvent(); } @@ -635,6 +637,11 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt) menuList->showPopup(); handled = true; } +#elif defined ANDROID_KEYBOARD_NAVIGATION + if ("Enter" == keyIdentifier && usesMenuList()) { + menuList->showPopup(); + handled = true; + } #else int listIndex = optionToListIndex(selectedIndex()); if (keyIdentifier == "Down" || keyIdentifier == "Right") { diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h index fba371c..ea8e990 100644 --- a/WebCore/html/HTMLSelectElement.h +++ b/WebCore/html/HTMLSelectElement.h @@ -87,7 +87,7 @@ public: virtual bool removeChild(Node* child, ExceptionCode&); virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&); virtual bool removeChildren(); - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void childrenChanged(bool changedByParser = false); virtual void parseMappedAttribute(MappedAttribute*); @@ -141,8 +141,18 @@ private: void recalcListItems(bool updateSelectedStates = true) const; void checkListItems() const; +#ifdef ANDROID_DESELECT_SELECT +public: +#endif void deselectItems(HTMLOptionElement* excludeElement = 0); +#ifdef ANDROID_DESELECT_SELECT +private: +#endif +#ifdef ANDROID_LISTBOX_USES_MENU_LIST + bool usesMenuList() const { return true; } +#else bool usesMenuList() const { return !m_multiple && m_size <= 1; } +#endif int nextSelectableListIndex(int startIndex); int previousSelectableListIndex(int startIndex); void menuListDefaultEventHandler(Event*); diff --git a/WebCore/html/HTMLSourceElement.cpp b/WebCore/html/HTMLSourceElement.cpp index 86af4e4..66f7305 100644 --- a/WebCore/html/HTMLSourceElement.cpp +++ b/WebCore/html/HTMLSourceElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 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,7 +30,6 @@ #include "HTMLDocument.h" #include "HTMLMediaElement.h" -#include "HTMLNames.h" using namespace std; @@ -57,7 +56,7 @@ void HTMLSourceElement::insertedIntoDocument() } } -KURL HTMLSourceElement::src() const +String HTMLSourceElement::src() const { return document()->completeURL(getAttribute(srcAttr)); } diff --git a/WebCore/html/HTMLSourceElement.h b/WebCore/html/HTMLSourceElement.h index 8187877..e47411a 100644 --- a/WebCore/html/HTMLSourceElement.h +++ b/WebCore/html/HTMLSourceElement.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 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,12 +29,15 @@ #if ENABLE(VIDEO) #include "HTMLElement.h" +#include "HTMLNames.h" #include <limits> namespace WebCore { -class KURL; - +using namespace HTMLNames; + +class MediaError; + class HTMLSourceElement : public HTMLElement { public: HTMLSourceElement(Document*); @@ -45,7 +48,7 @@ public: virtual void insertedIntoDocument(); - KURL src() const; + String 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 9403ace..67eb1cc 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().string().lower(); + m_media = attr->value().domString().lower(); else if (attr->name() == titleAttr && m_sheet) m_sheet->setTitle(attr->value()); else @@ -71,10 +71,10 @@ void HTMLStyleElement::removedFromDocument() StyleElement::removedFromDocument(document()); } -void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +void HTMLStyleElement::childrenChanged(bool changedByParser) { StyleElement::process(this); - HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + HTMLElement::childrenChanged(changedByParser); } StyleSheet* HTMLStyleElement::sheet() diff --git a/WebCore/html/HTMLStyleElement.h b/WebCore/html/HTMLStyleElement.h index 3ba1e18..05909d6 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, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void childrenChanged(bool changedByParser = false); void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; } virtual void finishParsingChildren(); diff --git a/WebCore/html/HTMLTableCellElement.cpp b/WebCore/html/HTMLTableCellElement.cpp index 65920ed..29ec6c4 100644 --- a/WebCore/html/HTMLTableCellElement.cpp +++ b/WebCore/html/HTMLTableCellElement.cpp @@ -31,6 +31,11 @@ #include "HTMLNames.h" #include "HTMLTableElement.h" #include "RenderTableCell.h" +#ifdef ANDROID_LAYOUT +#include "Document.h" +#include "Frame.h" +#include "Settings.h" +#endif using std::max; using std::min; @@ -97,6 +102,9 @@ void HTMLTableCellElement::parseMappedAttribute(MappedAttribute *attr) if (renderer() && renderer()->isTableCell()) static_cast<RenderTableCell*>(renderer())->updateFromElement(); } else if (attr->name() == nowrapAttr) { +#ifdef ANDROID_LAYOUT + if (!(document()->frame()) || document()->frame()->settings()->layoutAlgorithm() != Settings::kLayoutSSR) +#endif if (!attr->isNull()) addCSSProperty(attr, CSS_PROP_WHITE_SPACE, CSS_VAL__WEBKIT_NOWRAP); } else if (attr->name() == widthAttr) { diff --git a/WebCore/html/HTMLTableElement.cpp b/WebCore/html/HTMLTableElement.cpp index 82bc756..92f2b54 100644 --- a/WebCore/html/HTMLTableElement.cpp +++ b/WebCore/html/HTMLTableElement.cpp @@ -351,7 +351,7 @@ void HTMLTableElement::parseMappedAttribute(MappedAttribute* attr) } else if (attr->name() == backgroundAttr) { String url = parseURL(attr->value()); if (!url.isEmpty()) - addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, document()->completeURL(url).string()); + addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, document()->completeURL(url)); } else if (attr->name() == frameAttr) { // Cache the value of "frame" so that the table can examine it later. m_frameAttr = false; diff --git a/WebCore/html/HTMLTablePartElement.cpp b/WebCore/html/HTMLTablePartElement.cpp index 035f9ff..4070de9 100644 --- a/WebCore/html/HTMLTablePartElement.cpp +++ b/WebCore/html/HTMLTablePartElement.cpp @@ -66,7 +66,7 @@ void HTMLTablePartElement::parseMappedAttribute(MappedAttribute *attr) else if (attr->name() == backgroundAttr) { String url = parseURL(attr->value()); if (!url.isEmpty()) - addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, document()->completeURL(url).string()); + addCSSImageProperty(attr, CSS_PROP_BACKGROUND_IMAGE, document()->completeURL(url)); } else if (attr->name() == bordercolorAttr) { if (!attr->value().isEmpty()) { addCSSColor(attr, CSS_PROP_BORDER_COLOR, attr->value()); diff --git a/WebCore/html/HTMLTextAreaElement.cpp b/WebCore/html/HTMLTextAreaElement.cpp index 5f42a44..4277f30 100644 --- a/WebCore/html/HTMLTextAreaElement.cpp +++ b/WebCore/html/HTMLTextAreaElement.cpp @@ -39,6 +39,11 @@ #include "Selection.h" #include "Text.h" +#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS +#include "FrameView.h" +#include "WebCoreViewBridge.h" +#endif + namespace WebCore { using namespace EventNames; @@ -119,10 +124,10 @@ void HTMLTextAreaElement::setSelectionRange(int start, int end) static_cast<RenderTextControl*>(renderer())->setSelectionRange(start, end); } -void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +void HTMLTextAreaElement::childrenChanged(bool changedByParser) { setValue(defaultValue()); - HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + HTMLElement::childrenChanged(changedByParser); } void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute *attr) @@ -216,6 +221,10 @@ void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection) // This matches some browsers' behavior; see Bugzilla 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 // Restore the cached selection. This matches other browsers' behavior. setSelectionRange(cachedSelStart, cachedSelEnd); @@ -256,7 +265,7 @@ 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. - String valueWithNormalizedLineEndings = value; + DeprecatedString valueWithNormalizedLineEndings = value.deprecatedString(); valueWithNormalizedLineEndings.replace("\r\n", "\n"); valueWithNormalizedLineEndings.replace("\r", "\n"); @@ -267,8 +276,14 @@ void HTMLTextAreaElement::setValue(const String& value) 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); +#endif unsigned endOfString = m_value.length(); setSelectionRange(endOfString, endOfString); } diff --git a/WebCore/html/HTMLTextAreaElement.h b/WebCore/html/HTMLTextAreaElement.h index 7d1fe3f..c4d712d 100644 --- a/WebCore/html/HTMLTextAreaElement.h +++ b/WebCore/html/HTMLTextAreaElement.h @@ -61,7 +61,7 @@ public: void select(); void setSelectionRange(int, int); - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void childrenChanged(bool changedByParser = false); virtual void parseMappedAttribute(MappedAttribute*); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual bool appendFormData(FormDataList&, bool); diff --git a/WebCore/html/HTMLTitleElement.cpp b/WebCore/html/HTMLTitleElement.cpp index a75b1ee..1f855e1 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, Node* beforeChange, Node* afterChange, int childCountDelta) +void HTMLTitleElement::childrenChanged(bool changedByParser) { m_title = ""; for (Node* c = firstChild(); c != 0; c = c->nextSibling()) @@ -62,7 +62,7 @@ void HTMLTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, m_title += c->nodeValue(); if (inDocument()) document()->setTitle(m_title, this); - HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + HTMLElement::childrenChanged(changedByParser); } String HTMLTitleElement::text() const diff --git a/WebCore/html/HTMLTitleElement.h b/WebCore/html/HTMLTitleElement.h index 5bb05bc..195305d 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, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void childrenChanged(bool changedByParser = false); String text() const; void setText(const String&); diff --git a/WebCore/html/HTMLTokenizer.cpp b/WebCore/html/HTMLTokenizer.cpp index ee2d4bf..3481df0 100644 --- a/WebCore/html/HTMLTokenizer.cpp +++ b/WebCore/html/HTMLTokenizer.cpp @@ -41,6 +41,9 @@ #include "HTMLParser.h" #include "HTMLScriptElement.h" #include "HTMLViewSourceDocument.h" +#ifdef ANDROID_PRELOAD_CHANGES +#include "PreloadScanner.h" +#endif #include "Settings.h" #include "SystemTime.h" #include "kjs_proxy.h" @@ -48,6 +51,14 @@ #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 @@ -80,15 +91,11 @@ const double tokenizerTimeDelay = 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 @@ -146,6 +153,25 @@ inline void Token::addAttribute(Document* doc, AtomicString& attrName, const Ato // ---------------------------------------------------------------------------- +#ifdef ANDROID_INSTRUMENT +static uint32_t sTotalTimeUsed = 0; +static uint32_t sCurrentTime = 0; +static uint32_t sCounter = 0; + +void Frame::resetParsingTimeCounter() +{ + sTotalTimeUsed = 0; + sCounter = 0; +} + +void Frame::reportParsingTimeCounter() +{ + LOG(LOG_DEBUG, "WebCore", + "*-* Total parsing time (may include calcStyle or Java callback): %d ms called %d times\n", + sTotalTimeUsed, sCounter); +} +#endif + HTMLTokenizer::HTMLTokenizer(HTMLDocument* doc, bool reportErrors) : Tokenizer() , buffer(0) @@ -225,9 +251,6 @@ void HTMLTokenizer::reset() m_state.setForceSynchronous(false); currToken.reset(); - m_doctypeToken.reset(); - m_doctypeSearchCount = 0; - m_doctypeSecondarySearchCount = 0; } void HTMLTokenizer::begin() @@ -299,9 +322,9 @@ HTMLTokenizer::State HTMLTokenizer::processListing(SegmentedString list, State s HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State state) { - ASSERT(state.inTextArea() || state.inTitle() || state.inIFrame() || !state.hasEntityState()); + ASSERT(state.inTextArea() || state.inTitle() || !state.hasEntityState()); ASSERT(!state.hasTagState()); - ASSERT(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() + state.inIFrame() == 1 ); + ASSERT(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() == 1 ); if (state.inScript()) scriptStartLineno = m_lineNumber; @@ -339,9 +362,6 @@ 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); @@ -349,7 +369,6 @@ 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; } @@ -372,7 +391,7 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta tquote = NoQuote; } state.setEscaped(!state.escaped() && ch == '\\'); - if (!scriptCodeResync && (state.inTextArea() || state.inTitle() || state.inIFrame()) && !src.escaped() && ch == '&') { + if (!scriptCodeResync && (state.inTextArea() || state.inTitle()) && !src.escaped() && ch == '&') { UChar* scriptCodeDest = scriptCode+scriptCodeSize; src.advancePastNonNewline(); state = parseEntity(src, scriptCodeDest, state, m_cBufferPos, true, false); @@ -415,6 +434,11 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state) 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()) { @@ -448,6 +472,10 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state) currentPrependingSrc = &prependingSrc; scriptCodeSize = scriptCodeResync = 0; +#ifdef ANDROID_INSTRUMENT + sTotalTimeUsed += get_thread_msec() - sCurrentTime; +#endif + if (!parser->skipMode() && !followingFrameset) { if (cs) { if (savedPrependingSrc) @@ -477,6 +505,10 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state) } } +#ifdef ANDROID_INSTRUMENT + sCurrentTime = get_thread_msec(); +#endif + if (!m_executingScript && !state.loadingExtScript()) { src.append(pendingSrc); pendingSrc.clear(); @@ -488,7 +520,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 (!pendingScripts.isEmpty()) { + if (state.loadingExtScript()) { if (currentPrependingSrc) { currentPrependingSrc->append(prependingSrc); } else { @@ -501,6 +533,16 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state) } } +#if PRELOAD_SCANNER_ENABLED + if (!pendingScripts.isEmpty() && !m_executingScript) { + if (!m_preloadScanner) + m_preloadScanner.set(new PreloadScanner(m_doc)); + if (!m_preloadScanner->inProgress()) { + m_preloadScanner->begin(); + m_preloadScanner->write(pendingSrc); + } + } +#endif currentPrependingSrc = savedPrependingSrc; return state; @@ -511,7 +553,7 @@ HTMLTokenizer::State HTMLTokenizer::scriptExecution(const String& str, State sta if (m_fragment || !m_doc->frame()) return state; m_executingScript++; - String url = scriptURL.isNull() ? m_doc->frame()->document()->url().string() : scriptURL; + DeprecatedString url = scriptURL.isNull() ? m_doc->frame()->document()->url() : scriptURL.deprecatedString(); SegmentedString *savedPrependingSrc = currentPrependingSrc; SegmentedString prependingSrc; @@ -547,11 +589,20 @@ 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 (!pendingScripts.isEmpty()) { + if (state.loadingExtScript()) { 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. + PreloadScanner documentWritePreloadScanner(m_doc); + documentWritePreloadScanner.begin(); + documentWritePreloadScanner.write(prependingSrc); + documentWritePreloadScanner.end(); +#endif } else { m_state = state; write(prependingSrc, false); @@ -584,7 +635,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() || state.inIFrame())) { + if (!(state.inTitle() || state.inScript() || state.inXmp() || state.inTextArea() || state.inStyle())) { checkScriptBuffer(); scriptCode[scriptCodeSize] = 0; scriptCode[scriptCodeSize + 1] = 0; @@ -850,222 +901,6 @@ 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()); @@ -1084,14 +919,19 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state) } case TagName: { - if (searchCount > 0) { - if (*src == commentStart[searchCount]) { +#if defined(TOKEN_DEBUG) && TOKEN_DEBUG > 1 + qDebug("TagName"); +#endif + if (searchCount > 0) + { + if (*src == commentStart[searchCount]) + { searchCount++; - 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) { + if (searchCount == 4) + { +#ifdef TOKEN_DEBUG + kdDebug( 6036 ) << "Found comment" << endl; +#endif // Found '<!--' sequence src.advancePastNonNewline(); dest = buffer; // ignore the previous part of this tag @@ -1102,11 +942,12 @@ 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; @@ -1115,30 +956,10 @@ 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); @@ -1435,6 +1256,9 @@ 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. @@ -1447,9 +1271,9 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString &src, State state) if (currToken.attrs && !m_fragment) { if (m_doc->frame() && m_doc->frame()->scriptProxy()->isEnabled()) { if ((a = currToken.attrs->getAttributeItem(srcAttr))) - scriptSrc = m_doc->completeURL(parseURL(a->value())).string(); + scriptSrc = m_doc->completeURL(parseURL(a->value())); if ((a = currToken.attrs->getAttributeItem(charsetAttr))) - scriptSrcCharset = a->value().string().stripWhiteSpace(); + scriptSrcCharset = a->value().domString().stripWhiteSpace(); if (scriptSrcCharset.isEmpty()) scriptSrcCharset = m_doc->frame()->loader()->encoding(); } @@ -1518,13 +1342,6 @@ 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) @@ -1585,11 +1402,21 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData) // don't parse; we will do this later if (currentPrependingSrc) currentPrependingSrc->append(source); - else + else { pendingSrc.append(source); +#if PRELOAD_SCANNER_ENABLED + if (m_preloadScanner && m_preloadScanner->inProgress() && appendData) + m_preloadScanner->write(source); +#endif + } return false; } +#if PRELOAD_SCANNER_ENABLED + if (m_preloadScanner && m_preloadScanner->inProgress() && appendData) + m_preloadScanner->end(); +#endif + if (!src.isEmpty()) src.append(source); else @@ -1609,6 +1436,9 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData) int processedCount = 0; double startTime = currentTime(); +#ifdef ANDROID_INSTRUMENT + sCurrentTime = get_thread_msec(); +#endif Frame *frame = m_doc->frame(); @@ -1639,8 +1469,6 @@ 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()) @@ -1654,9 +1482,9 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData) case '/': break; case '!': { - // <!-- comment --> or <!DOCTYPE ...> - searchCount = 1; // Look for '<!--' sequence to start comment or '<!DOCTYPE' sequence to start doctype - m_doctypeSearchCount = 1; + // <!-- comment --> + searchCount = 1; // Look for '<!--' sequence to start comment + break; } case '?': { @@ -1734,6 +1562,14 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData) m_state = state; +#ifdef ANDROID_INSTRUMENT + uint32_t time = get_thread_msec() - sCurrentTime; + sTotalTimeUsed += time; + sCounter++; + if (time > 1000) + LOGW("***** HTMLTokenizer::write() used %d ms\n", time); +#endif + if (noMoreData && !inWrite && !state.loadingExtScript() && !m_executingScript && !m_timer.isActive()) { end(); // this actually causes us to be deleted return true; @@ -1764,7 +1600,11 @@ void HTMLTokenizer::timerFired(Timer<HTMLTokenizer>*) printf("Beginning timer write at time %d\n", m_doc->elapsedTime()); #endif +#ifdef ANDROID_MOBILE + if (m_doc->view() && m_doc->view()->layoutPending() && !m_doc->minimumLayoutDelay() && !m_doc->extraLayoutDelay()) { +#else if (m_doc->view() && m_doc->view()->layoutPending() && !m_doc->minimumLayoutDelay()) { +#endif // Restart the timer and let layout win. This is basically a way of ensuring that the layout // timer has higher priority than our timer. m_timer.startOneShot(0); @@ -1802,7 +1642,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; @@ -1817,9 +1657,9 @@ void HTMLTokenizer::finish() food = String(scriptCode, scriptCodeSize); else if (m_state.inServer()) { food = "<"; - food.append(scriptCode, scriptCodeSize); + food.append(String(scriptCode, scriptCodeSize)); } else { - pos = find(scriptCode, scriptCodeSize, '>'); + pos = DeprecatedConstString(reinterpret_cast<DeprecatedChar*>(scriptCode), scriptCodeSize).string().find('>'); food = String(scriptCode + pos + 1, scriptCodeSize - pos - 1); } fastFree(scriptCode); @@ -1843,6 +1683,13 @@ PassRefPtr<Node> HTMLTokenizer::processToken() if (jsProxy && m_doc->frame()->scriptProxy()->isEnabled()) jsProxy->setEventHandlerLineno(tagStartLineno); 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; @@ -1855,6 +1702,29 @@ PassRefPtr<Node> HTMLTokenizer::processToken() 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) { @@ -1871,14 +1741,6 @@ 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); @@ -1924,16 +1786,22 @@ void HTMLTokenizer::notifyFinished(CachedResource*) // 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() && protocolIs(pendingScripts.head()->url(), "file"); + m_hasScriptsWaitingForStylesheets = !m_doc->haveStylesheetsLoaded() && pendingScripts.head()->url().startsWith("file:", false); 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(); 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 diff --git a/WebCore/html/HTMLTokenizer.h b/WebCore/html/HTMLTokenizer.h index b0b71f6..7657f95 100644 --- a/WebCore/html/HTMLTokenizer.h +++ b/WebCore/html/HTMLTokenizer.h @@ -43,6 +43,9 @@ class HTMLViewSourceDocument; class FrameView; class HTMLParser; class Node; +#ifdef ANDROID_PRELOAD_CHANGES +class PreloadScanner; +#endif /** * @internal @@ -83,44 +86,6 @@ 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 { @@ -156,13 +121,10 @@ 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); @@ -253,16 +215,12 @@ 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); } @@ -282,11 +240,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 | InIFrame); } + bool inAnySpecial() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle); } 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 | InIFrame | TagMask | EntityMask | InPlainText | InComment | InDoctype | InServer | InProcessingInstruction | StartTag); } + bool needsSpecialWriteHandling() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle | TagMask | EntityMask | InPlainText | InComment | InServer | InProcessingInstruction | StartTag); } private: static const int EntityShift = 4; @@ -309,9 +267,7 @@ private: DiscardLF = 1 << 20, // FIXME: should clarify difference between skip and discard AllowYield = 1 << 21, LoadingExtScript = 1 << 22, - ForceSynchronous = 1 << 23, - InIFrame = 1 << 24, - InDoctype = 1 << 25 + ForceSynchronous = 1 << 23 }; void setBit(StateBits bit, bool value) @@ -327,10 +283,6 @@ private: }; State m_state; - - DoctypeToken m_doctypeToken; - int m_doctypeSearchCount; - int m_doctypeSecondarySearchCount; bool brokenServer; @@ -348,14 +300,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; @@ -402,6 +354,10 @@ private: HTMLParser* parser; bool inWrite; bool m_fragment; + +#ifdef ANDROID_PRELOAD_CHANGES + OwnPtr<PreloadScanner> m_preloadScanner; +#endif }; void parseHTMLDocumentFragment(const String&, DocumentFragment*); diff --git a/WebCore/html/HTMLVideoElement.cpp b/WebCore/html/HTMLVideoElement.cpp index 9b19c7f..4a2b2c9 100644 --- a/WebCore/html/HTMLVideoElement.cpp +++ b/WebCore/html/HTMLVideoElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 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(); @@ -140,7 +140,7 @@ void HTMLVideoElement::setHeight(int value) setAttribute(heightAttr, String::number(value)); } -KURL HTMLVideoElement::poster() const +String 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 e0d7a87..8d9be2c 100644 --- a/WebCore/html/HTMLVideoElement.h +++ b/WebCore/html/HTMLVideoElement.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -58,7 +58,7 @@ public: int videoWidth() const; int videoHeight() const; - KURL poster() const; + String poster() const; void setPoster(const String&); void updatePosterImage(); diff --git a/WebCore/html/HTMLViewSourceDocument.cpp b/WebCore/html/HTMLViewSourceDocument.cpp index 331c5ec..10c7a6d 100644 --- a/WebCore/html/HTMLViewSourceDocument.cpp +++ b/WebCore/html/HTMLViewSourceDocument.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * 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 @@ -23,9 +23,8 @@ */ #include "config.h" -#include "HTMLViewSourceDocument.h" - #include "DOMImplementation.h" +#include "HTMLViewSourceDocument.h" #include "HTMLTokenizer.h" #include "HTMLHtmlElement.h" #include "HTMLAnchorElement.h" @@ -39,7 +38,8 @@ #include "TextDocument.h" #include "HTMLNames.h" -namespace WebCore { +namespace WebCore +{ using namespace HTMLNames; @@ -108,7 +108,9 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token) } } else { // Handle the tag. - String classNameStr = "webkit-html-tag"; + bool doctype = token->tagName.startsWith("!DOCTYPE", false); + + String classNameStr = doctype ? "webkit-html-doctype" : "webkit-html-tag"; m_current = addSpanWithClassName(classNameStr); String text = "<"; @@ -143,21 +145,28 @@ void HTMLViewSourceDocument::addViewSourceToken(Token* token) if (attr) { if (guide->at(i) == 'a') { String name = attr->name().toString(); - - 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()); + 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()); + } } else { - 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()); + 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()); + } } } } @@ -175,17 +184,6 @@ 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) { @@ -250,8 +248,7 @@ void HTMLViewSourceDocument::addText(const String& text, const String& className return; // Add in the content, splitting on newlines. - Vector<String> lines; - text.split('\n', true, lines); + Vector<String> lines = text.split('\n', true); unsigned size = lines.size(); for (unsigned i = 0; i < size; i++) { String substring = lines[i]; diff --git a/WebCore/html/HTMLViewSourceDocument.h b/WebCore/html/HTMLViewSourceDocument.h index 4d83550..efbbf9e 100644 --- a/WebCore/html/HTMLViewSourceDocument.h +++ b/WebCore/html/HTMLViewSourceDocument.h @@ -28,7 +28,6 @@ namespace WebCore { -class DoctypeToken; class Token; class HTMLViewSourceDocument : public HTMLDocument @@ -40,8 +39,7 @@ public: void addViewSourceToken(Token*); // Used by the HTML tokenizer. void addViewSourceText(const String&); // Used by the plaintext tokenizer. - void addViewSourceDoctypeToken(DoctypeToken*); - + private: void createContainingTable(); Element* addSpanWithClassName(const String&); diff --git a/WebCore/html/ImageData.cpp b/WebCore/html/ImageData.cpp deleted file mode 100644 index 3653031..0000000 --- a/WebCore/html/ImageData.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 deleted file mode 100644 index 21af1f9..0000000 --- a/WebCore/html/ImageData.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 deleted file mode 100644 index 052f165..0000000 --- a/WebCore/html/ImageData.idl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 - ] 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 02b16da..33a2a70 100644 --- a/WebCore/html/MediaError.h +++ b/WebCore/html/MediaError.h @@ -36,8 +36,7 @@ class MediaError : public RefCounted<MediaError> { public: enum Code { MEDIA_ERR_ABORTED = 1, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE }; - MediaError(Code code) : RefCounted<MediaError>(0), m_code(code) { } - + MediaError(Code code) { m_code = code; } Code code() const { return m_code; } private: diff --git a/WebCore/html/PreloadScanner.cpp b/WebCore/html/PreloadScanner.cpp new file mode 100644 index 0000000..f7fb27d --- /dev/null +++ b/WebCore/html/PreloadScanner.cpp @@ -0,0 +1,851 @@ +/* + * 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" +#ifdef ANDROID_PRELOAD_CHANGES +#include "PreloadScanner.h" + +#include "AtomicString.h" +#include "Cache.h" +#include "CachedCSSStyleSheet.h" +#include "CachedImage.h" +#include "CachedResource.h" +#include "CachedResourceClient.h" +#include "CachedScript.h" +#include "CSSHelper.h" +#include "CString.h" +#include "DocLoader.h" +#include "Document.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "HTMLLinkElement.h" +#include "HTMLNames.h" +#include "SystemTime.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. +#include "HTMLEntityNames.c" +#else +// Not inlined for non-GCC compilers +struct Entity { + const char* name; + int code; +}; +const struct Entity* findEntity(register const char* str, register unsigned int len); +#endif + +#define PRELOAD_DEBUG 0 + +namespace WebCore { + +using namespace HTMLNames; + +PreloadScanner::PreloadScanner(Document* doc) + : m_inProgress(false) + , m_timeUsed(0) + , m_bodySeen(false) + , m_document(doc) +{ +#if PRELOAD_DEBUG + printf("CREATING PRELOAD SCANNER FOR %s\n", m_document->url().string().latin1().data()); +#endif +} + +PreloadScanner::~PreloadScanner() +{ +#if PRELOAD_DEBUG + printf("DELETING PRELOAD SCANNER FOR %s\n", m_document->url().string().latin1().data()); + printf("TOTAL TIME USED %.4fs\n", m_timeUsed); +#endif +} + +void PreloadScanner::begin() +{ + ASSERT(!m_inProgress); + reset(); + m_inProgress = true; +} + +void PreloadScanner::end() +{ + ASSERT(m_inProgress); + m_inProgress = false; +} + +void PreloadScanner::reset() +{ + m_source.clear(); + + m_state = Data; + m_escape = false; + m_contentModel = PCDATA; + m_commentPos = 0; + + m_closeTag = false; + m_tagName.clear(); + m_attributeName.clear(); + m_attributeValue.clear(); + m_lastStartTag = AtomicString(); + + m_urlToLoad = String(); + m_charset = String(); + m_linkIsStyleSheet = false; + m_lastCharacterIndex = 0; + clearLastCharacters(); + + m_cssState = CSSInitial; + m_cssRule.clear(); + m_cssRuleValue.clear(); +} + +bool PreloadScanner::inBody() const +{ + return m_document->body() || m_bodySeen; +} + +void PreloadScanner::write(const SegmentedString& source) +{ + double startTime = currentTime(); + tokenize(source); + m_timeUsed += currentTime() - startTime; +} + +static inline bool isWhitespace(UChar c) +{ + return c == ' ' || c == '\n' || c == '\r' || c == '\t'; +} + +inline void PreloadScanner::clearLastCharacters() +{ + memset(m_lastCharacters, 0, lastCharactersBufferSize * sizeof(UChar)); +} + +inline void PreloadScanner::rememberCharacter(UChar c) +{ + m_lastCharacterIndex = (m_lastCharacterIndex + 1) % lastCharactersBufferSize; + m_lastCharacters[m_lastCharacterIndex] = c; +} + +inline bool PreloadScanner::lastCharactersMatch(const char* chars, unsigned count) const +{ + unsigned pos = m_lastCharacterIndex; + while (count) { + if (chars[count - 1] != m_lastCharacters[pos]) + return false; + --count; + if (!pos) + pos = lastCharactersBufferSize; + --pos; + } + return true; +} + +static inline unsigned legalEntityFor(unsigned value) +{ + // FIXME There is a table for more exceptions in the HTML5 specification. + if (value == 0 || value > 0x10FFFF || (value >= 0xD800 && value <= 0xDFFF)) + return 0xFFFD; + return value; +} + +unsigned PreloadScanner::consumeEntity(SegmentedString& source, bool& notEnoughCharacters) +{ + enum EntityState { + Initial, + NumberType, + MaybeHex, + Hex, + Decimal, + Named + }; + EntityState entityState = Initial; + unsigned result = 0; + Vector<UChar, 10> seenChars; + Vector<char, 10> entityName; + + while (!source.isEmpty()) { + UChar cc = *source; + seenChars.append(cc); + switch (entityState) { + case Initial: + if (isWhitespace(cc) || cc == '<' || cc == '&') + return 0; + else if (cc == '#') + entityState = NumberType; + else if ((cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')) { + entityName.append(cc); + entityState = Named; + } else + return 0; + break; + case NumberType: + if (cc == 'x' || cc == 'X') + entityState = MaybeHex; + else if (cc >= '0' && cc <= '9') { + entityState = Decimal; + result = cc - '0'; + } else { + source.push('#'); + return 0; + } + break; + case MaybeHex: + if (cc >= '0' && cc <= '9') + result = cc - '0'; + else if (cc >= 'a' && cc <= 'f') + result = 10 + cc - 'a'; + else if (cc >= 'A' && cc <= 'F') + result = 10 + cc - 'A'; + else { + source.push(seenChars[1]); + source.push('#'); + return 0; + } + entityState = Hex; + break; + case Hex: + if (cc >= '0' && cc <= '9') + result = result * 16 + cc - '0'; + else if (cc >= 'a' && cc <= 'f') + result = result * 16 + 10 + cc - 'a'; + else if (cc >= 'A' && cc <= 'F') + result = result * 16 + 10 + cc - 'A'; + else if (cc == ';') { + source.advance(); + return legalEntityFor(result); + } else + return legalEntityFor(result); + break; + case Decimal: + if (cc >= '0' && cc <= '9') + result = result * 10 + cc - '0'; + else if (cc == ';') { + source.advance(); + return legalEntityFor(result); + } else + return legalEntityFor(result); + break; + case Named: + // This is the attribute only version, generic version matches somewhat differently + while (entityName.size() <= 8) { + if (cc == ';') { + const Entity* entity = findEntity(entityName.data(), entityName.size()); + if (entity) { + source.advance(); + return entity->code; + } + break; + } + if (!(cc >= 'a' && cc <= 'z') && !(cc >= 'A' && cc <= 'Z') && !(cc >= '0' && cc <= '9')) { + const Entity* entity = findEntity(entityName.data(), entityName.size()); + if (entity) + return entity->code; + break; + } + entityName.append(cc); + source.advance(); + if (source.isEmpty()) + goto outOfCharacters; + cc = *source; + seenChars.append(cc); + } + if (seenChars.size() == 2) + source.push(seenChars[0]); + else if (seenChars.size() == 3) { + source.push(seenChars[1]); + source.push(seenChars[0]); + } else + source.prepend(SegmentedString(String(seenChars.data(), seenChars.size() - 1))); + return 0; + } + source.advance(); + } +outOfCharacters: + notEnoughCharacters = true; + source.prepend(SegmentedString(String(seenChars.data(), seenChars.size()))); + return 0; +} + +void PreloadScanner::tokenize(const SegmentedString& source) +{ + ASSERT(m_inProgress); + + m_source.append(source); + + // This is a simplified HTML5 Tokenizer + // http://www.whatwg.org/specs/web-apps/current-work/#tokenisation0 + while (!m_source.isEmpty()) { + UChar cc = *m_source; + switch (m_state) { + case Data: + while (1) { + rememberCharacter(cc); + if (cc == '&') { + if (m_contentModel == PCDATA || m_contentModel == RCDATA) { + m_state = EntityData; + break; + } + } else if (cc == '-') { + if ((m_contentModel == RCDATA || m_contentModel == CDATA) && !m_escape) { + if (lastCharactersMatch("<!--", 4)) + m_escape = true; + } + } else if (cc == '<') { + if (m_contentModel == PCDATA || ((m_contentModel == RCDATA || m_contentModel == CDATA) && !m_escape)) { + m_state = TagOpen; + break; + } + } else if (cc == '>') { + if ((m_contentModel == RCDATA || m_contentModel == CDATA) && m_escape) { + if (lastCharactersMatch("-->", 3)) + m_escape = false; + } + } + emitCharacter(cc); + m_source.advance(); + if (m_source.isEmpty()) + return; + cc = *m_source; + } + break; + case EntityData: + // should try to consume the entity but we only care about entities in attributes + m_state = Data; + break; + case TagOpen: + if (m_contentModel == RCDATA || m_contentModel == CDATA) { + if (cc == '/') + m_state = CloseTagOpen; + else { + m_state = Data; + continue; + } + } else if (m_contentModel == PCDATA) { + if (cc == '!') + m_state = MarkupDeclarationOpen; + else if (cc == '/') + m_state = CloseTagOpen; + else if (cc >= 'A' && cc <= 'Z') { + m_tagName.clear(); + m_tagName.append(cc + 0x20); + m_closeTag = false; + m_state = TagName; + } else if (cc >= 'a' && cc <= 'z') { + m_tagName.clear(); + m_tagName.append(cc); + m_closeTag = false; + m_state = TagName; + } else if (cc == '>') { + m_state = Data; + } else if (cc == '?') { + m_state = BogusComment; + } else { + m_state = Data; + continue; + } + } + break; + case CloseTagOpen: + if (m_contentModel == RCDATA || m_contentModel == CDATA) { + if (!m_lastStartTag.length()) { + m_state = Data; + continue; + } + if (m_source.length() < m_lastStartTag.length() + 1) + return; + Vector<UChar> tmpString; + UChar tmpChar = 0; + bool match = true; + for (unsigned n = 0; n < m_lastStartTag.length() + 1; n++) { + tmpChar = u_tolower(*m_source); + if (n < m_lastStartTag.length() && tmpChar != m_lastStartTag[n]) + match = false; + tmpString.append(tmpChar); + m_source.advance(); + } + m_source.prepend(SegmentedString(String(tmpString.data(), tmpString.size()))); + if (!match || (!isWhitespace(tmpChar) && tmpChar != '>' && tmpChar != '/')) { + m_state = Data; + continue; + } + } + if (cc >= 'A' && cc <= 'Z') { + m_tagName.clear(); + m_tagName.append(cc + 0x20); + m_closeTag = true; + m_state = TagName; + } else if (cc >= 'a' && cc <= 'z') { + m_tagName.clear(); + m_tagName.append(cc); + m_closeTag = true; + m_state = TagName; + } else if (cc == '>') { + m_state = Data; + } else + m_state = BogusComment; + break; + case TagName: + while (1) { + if (isWhitespace(cc)) { + m_state = BeforeAttributeName; + break; + } + if (cc == '>') { + emitTag(); + m_state = Data; + break; + } + if (cc == '/') { + m_state = BeforeAttributeName; + break; + } + if (cc >= 'A' && cc <= 'Z') + m_tagName.append(cc + 0x20); + else + m_tagName.append(cc); + m_source.advance(); + if (m_source.isEmpty()) + return; + cc = *m_source; + } + break; + case BeforeAttributeName: + if (isWhitespace(cc)) + ; + else if (cc == '>') { + emitTag(); + m_state = Data; + } else if (cc >= 'A' && cc <= 'Z') { + m_attributeName.clear(); + m_attributeValue.clear(); + m_attributeName.append(cc + 0x20); + m_state = AttributeName; + } else if (cc == '/') + ; + else { + m_attributeName.clear(); + m_attributeValue.clear(); + m_attributeName.append(cc); + m_state = AttributeName; + } + break; + case AttributeName: + while (1) { + if (isWhitespace(cc)) { + m_state = AfterAttributeName; + break; + } + if (cc == '=') { + m_state = BeforeAttributeValue; + break; + } + if (cc == '>') { + emitTag(); + m_state = Data; + break; + } + if (cc == '/') { + m_state = BeforeAttributeName; + break; + } + if (cc >= 'A' && cc <= 'Z') + m_attributeName.append(cc + 0x20); + else + m_attributeName.append(cc); + m_source.advance(); + if (m_source.isEmpty()) + return; + cc = *m_source; + } + break; + case AfterAttributeName: + if (isWhitespace(cc)) + ; + else if (cc == '=') + m_state = BeforeAttributeValue; + else if (cc == '>') { + emitTag(); + m_state = Data; + } else if (cc >= 'A' && cc <= 'Z') { + m_attributeName.clear(); + m_attributeValue.clear(); + m_attributeName.append(cc + 0x20); + m_state = AttributeName; + } else if (cc == '/') + m_state = BeforeAttributeName; + else { + m_attributeName.clear(); + m_attributeValue.clear(); + m_attributeName.append(cc); + m_state = AttributeName; + } + break; + case BeforeAttributeValue: + if (isWhitespace(cc)) + ; + else if (cc == '"') + m_state = AttributeValueDoubleQuoted; + else if (cc == '&') { + m_state = AttributeValueUnquoted; + continue; + } else if (cc == '\'') + m_state = AttributeValueSingleQuoted; + else if (cc == '>') { + emitTag(); + m_state = Data; + } else { + m_attributeValue.append(cc); + m_state = AttributeValueUnquoted; + } + break; + case AttributeValueDoubleQuoted: + while (1) { + if (cc == '"') { + processAttribute(); + m_state = BeforeAttributeName; + break; + } + if (cc == '&') { + m_stateBeforeEntityInAttributeValue = m_state; + m_state = EntityInAttributeValue; + break; + } + m_attributeValue.append(cc); + m_source.advance(); + if (m_source.isEmpty()) + return; + cc = *m_source; + } + break; + case AttributeValueSingleQuoted: + while (1) { + if (cc == '\'') { + processAttribute(); + m_state = BeforeAttributeName; + break; + } + if (cc == '&') { + m_stateBeforeEntityInAttributeValue = m_state; + m_state = EntityInAttributeValue; + break; + } + m_attributeValue.append(cc); + m_source.advance(); + if (m_source.isEmpty()) + return; + cc = *m_source; + } + break; + case AttributeValueUnquoted: + while (1) { + if (isWhitespace(cc)) { + processAttribute(); + m_state = BeforeAttributeName; + break; + } + if (cc == '&') { + m_stateBeforeEntityInAttributeValue = m_state; + m_state = EntityInAttributeValue; + break; + } + if (cc == '>') { + processAttribute(); + emitTag(); + m_state = Data; + break; + } + m_attributeValue.append(cc); + m_source.advance(); + if (m_source.isEmpty()) + return; + cc = *m_source; + } + break; + case EntityInAttributeValue: + { + bool notEnoughCharacters = false; + unsigned entity = consumeEntity(m_source, notEnoughCharacters); + if (notEnoughCharacters) + return; + if (entity > 0xFFFF) { + m_attributeValue.append(U16_LEAD(entity)); + m_attributeValue.append(U16_TRAIL(entity)); + } else if (entity) + m_attributeValue.append(entity); + else + m_attributeValue.append('&'); + } + m_state = m_stateBeforeEntityInAttributeValue; + continue; + case BogusComment: + while (1) { + if (cc == '>') { + m_state = Data; + break; + } + m_source.advance(); + if (m_source.isEmpty()) + return; + cc = *m_source; + } + break; + case MarkupDeclarationOpen: { + if (cc == '-') { + if (m_source.length() < 2) + return; + m_source.advance(); + cc = *m_source; + if (cc == '-') + m_state = CommentStart; + else { + m_state = BogusComment; + continue; + } + // If we cared about the DOCTYPE we would test to enter those states here + } else { + m_state = BogusComment; + continue; + } + break; + } + case CommentStart: + if (cc == '-') + m_state = CommentStartDash; + else if (cc == '>') + m_state = Data; + else + m_state = Comment; + break; + case CommentStartDash: + if (cc == '-') + m_state = CommentEnd; + else if (cc == '>') + m_state = Data; + else + m_state = Comment; + break; + case Comment: + while (1) { + if (cc == '-') { + m_state = CommentEndDash; + break; + } + m_source.advance(); + if (m_source.isEmpty()) + return; + cc = *m_source; + } + break; + case CommentEndDash: + if (cc == '-') + m_state = CommentEnd; + else + m_state = Comment; + break; + case CommentEnd: + if (cc == '>') + m_state = Data; + else if (cc == '-') + ; + else + m_state = Comment; + break; + } + m_source.advance(); + } +} + +void PreloadScanner::processAttribute() +{ + AtomicString tag = AtomicString(m_tagName.data(), m_tagName.size()); + AtomicString attribute = AtomicString(m_attributeName.data(), m_attributeName.size()); + + String value(m_attributeValue.data(), m_attributeValue.size()); + if (tag == scriptTag || tag == imgTag) { + if (attribute == srcAttr && m_urlToLoad.isEmpty()) + m_urlToLoad = parseURL(value); + else if (attribute == charsetAttr) + m_charset = value; + } else if (tag == linkTag) { + if (attribute == hrefAttr && m_urlToLoad.isEmpty()) + m_urlToLoad = parseURL(value); + else if (attribute == relAttr) { + bool styleSheet = false; + bool alternate = false; + bool icon = false; + HTMLLinkElement::tokenizeRelAttribute(value, styleSheet, alternate, icon); + m_linkIsStyleSheet = styleSheet && !alternate && !icon; + } else if (attribute == charsetAttr) + m_charset = value; + } +} + +inline void PreloadScanner::emitCharacter(UChar c) +{ + if (m_contentModel == CDATA && m_lastStartTag == styleTag) + tokenizeCSS(c); +} + +inline void PreloadScanner::tokenizeCSS(UChar c) +{ + // We are just interested in @import rules, no need for real tokenization here + // Searching for other types of resources is probably low payoff + switch (m_cssState) { + case CSSInitial: + if (c == '@') + m_cssState = CSSRuleStart; + else if (c == '/') + m_cssState = CSSMaybeComment; + break; + case CSSMaybeComment: + if (c == '*') + m_cssState = CSSComment; + else + m_cssState = CSSInitial; + break; + case CSSComment: + if (c == '*') + m_cssState = CSSMaybeCommentEnd; + break; + case CSSMaybeCommentEnd: + if (c == '/') + m_cssState = CSSInitial; + else if (c == '*') + ; + else + m_cssState = CSSComment; + break; + case CSSRuleStart: + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { + m_cssRule.clear(); + m_cssRuleValue.clear(); + m_cssRule.append(c); + m_cssState = CSSRule; + } else + m_cssState = CSSInitial; + break; + case CSSRule: + if (isWhitespace(c)) + m_cssState = CSSAfterRule; + else if (c == ';') + m_cssState = CSSInitial; + else + m_cssRule.append(c); + break; + case CSSAfterRule: + if (isWhitespace(c)) + ; + else if (c == ';') + m_cssState = CSSInitial; + else { + m_cssState = CSSRuleValue; + m_cssRuleValue.append(c); + } + break; + case CSSRuleValue: + if (isWhitespace(c)) + m_cssState = CSSAferRuleValue; + else if (c == ';') { + emitCSSRule(); + m_cssState = CSSInitial; + } else + m_cssRuleValue.append(c); + break; + case CSSAferRuleValue: + if (isWhitespace(c)) + ; + else if (c == ';') { + emitCSSRule(); + m_cssState = CSSInitial; + } else { + // FIXME media rules + m_cssState = CSSInitial; + } + break; + } +} + +void PreloadScanner::emitTag() +{ + if (m_closeTag) { + m_contentModel = PCDATA; + m_cssState = CSSInitial; + clearLastCharacters(); + return; + } + + AtomicString tag(m_tagName.data(), m_tagName.size()); + m_lastStartTag = tag; + + if (tag == textareaTag || tag == titleTag) + m_contentModel = RCDATA; + else if (tag == styleTag || tag == xmpTag || tag == scriptTag || tag == iframeTag || tag == noembedTag || tag == noframesTag) + m_contentModel = CDATA; + else if (tag == noscriptTag) + // we wouldn't be here if scripts were disabled + m_contentModel = CDATA; + else if (tag == plaintextTag) + m_contentModel = PLAINTEXT; + else + m_contentModel = PCDATA; + + if (tag == bodyTag) + m_bodySeen = true; + + if (m_urlToLoad.isEmpty()) { + m_linkIsStyleSheet = false; + return; + } + + if (tag == scriptTag) + m_document->docLoader()->preload(CachedResource::Script, m_urlToLoad, m_charset, inBody()); + else if (tag == imgTag) + m_document->docLoader()->preload(CachedResource::ImageResource, m_urlToLoad, String(), inBody()); + else if (tag == linkTag && m_linkIsStyleSheet) + m_document->docLoader()->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, inBody()); + + m_urlToLoad = String(); + m_charset = String(); + m_linkIsStyleSheet = false; +} + +void PreloadScanner::emitCSSRule() +{ + String rule(m_cssRule.data(), m_cssRule.size()); + if (rule.lower() == "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_cssRule.clear(); + m_cssRuleValue.clear(); +} + +} +#endif //ANDROID_PRELOAD_CHANGES diff --git a/WebCore/html/PreloadScanner.h b/WebCore/html/PreloadScanner.h new file mode 100644 index 0000000..8ef5d1a --- /dev/null +++ b/WebCore/html/PreloadScanner.h @@ -0,0 +1,148 @@ +/* + * 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 PreloadScanner_h +#define PreloadScanner_h + +#include "AtomicString.h" +#include "SegmentedString.h" +#include <wtf/Noncopyable.h> +#include <wtf/Vector.h> + +namespace WebCore { + + class CachedResource; + class CachedResourceClient; + class Document; + + class PreloadScanner : Noncopyable { + public: + PreloadScanner(Document*); + ~PreloadScanner(); + void begin(); + void write(const SegmentedString&); + void end(); + bool inProgress() const { return m_inProgress; } + + bool inBody() const; + + static unsigned consumeEntity(SegmentedString&, bool& notEnoughCharacters); + + private: + void tokenize(const SegmentedString&); + void reset(); + + void emitTag(); + void emitCharacter(UChar); + + void tokenizeCSS(UChar); + void emitCSSRule(); + + void processAttribute(); + + + void clearLastCharacters(); + void rememberCharacter(UChar); + bool lastCharactersMatch(const char*, unsigned count) const; + + bool m_inProgress; + SegmentedString m_source; + + enum State { + Data, + EntityData, + TagOpen, + CloseTagOpen, + TagName, + BeforeAttributeName, + AttributeName, + AfterAttributeName, + BeforeAttributeValue, + AttributeValueDoubleQuoted, + AttributeValueSingleQuoted, + AttributeValueUnquoted, + EntityInAttributeValue, + BogusComment, + MarkupDeclarationOpen, + CommentStart, + CommentStartDash, + Comment, + CommentEndDash, + CommentEnd + }; + State m_state; + bool m_escape; + enum ContentModel { + PCDATA, + RCDATA, + CDATA, + PLAINTEXT + }; + ContentModel m_contentModel; + unsigned m_commentPos; + State m_stateBeforeEntityInAttributeValue; + + static const unsigned lastCharactersBufferSize = 8; + UChar m_lastCharacters[lastCharactersBufferSize]; + unsigned m_lastCharacterIndex; + + bool m_closeTag; + Vector<UChar, 32> m_tagName; + Vector<UChar, 32> m_attributeName; + Vector<UChar> m_attributeValue; + AtomicString m_lastStartTag; + + String m_urlToLoad; + String m_charset; + bool m_linkIsStyleSheet; + + enum CSSState { + CSSInitial, + CSSMaybeComment, + CSSComment, + CSSMaybeCommentEnd, + CSSRuleStart, + CSSRule, + CSSAfterRule, + CSSRuleValue, + CSSAferRuleValue + }; + CSSState m_cssState; + Vector<UChar, 16> m_cssRule; + Vector<UChar> m_cssRuleValue; + + double m_timeUsed; + + bool m_bodySeen; + Document* m_document; + }; + +} + +#endif diff --git a/WebCore/html/TimeRanges.cpp b/WebCore/html/TimeRanges.cpp index f27a75e..ad81ac8 100644 --- a/WebCore/html/TimeRanges.cpp +++ b/WebCore/html/TimeRanges.cpp @@ -30,7 +30,6 @@ using namespace WebCore; TimeRanges::TimeRanges(float start, float end) - : RefCounted<TimeRanges>(0) { add(start, end); } diff --git a/WebCore/html/TimeRanges.h b/WebCore/html/TimeRanges.h index 8de3d2a..16b0c25 100644 --- a/WebCore/html/TimeRanges.h +++ b/WebCore/html/TimeRanges.h @@ -34,7 +34,7 @@ namespace WebCore { class TimeRanges : public RefCounted<TimeRanges> { public: - TimeRanges() : RefCounted<TimeRanges>(0) { } + TimeRanges() { } TimeRanges(float start, float end); unsigned length() const { return m_ranges.size(); } diff --git a/WebCore/html/VoidCallback.h b/WebCore/html/VoidCallback.h index e1c9589..478e2fc 100644 --- a/WebCore/html/VoidCallback.h +++ b/WebCore/html/VoidCallback.h @@ -32,7 +32,7 @@ namespace WebCore { class VoidCallback : public RefCounted<VoidCallback> { public: - VoidCallback() : RefCounted<VoidCallback>(0) { } + VoidCallback() { } virtual ~VoidCallback() { } virtual void handleEvent() = 0; |