diff options
author | Steve Block <steveblock@google.com> | 2010-02-02 14:57:50 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-04 15:06:55 +0000 |
commit | d0825bca7fe65beaee391d30da42e937db621564 (patch) | |
tree | 7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/html | |
parent | 3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff) | |
download | external_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2 |
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'WebCore/html')
178 files changed, 2383 insertions, 871 deletions
diff --git a/WebCore/html/Blob.cpp b/WebCore/html/Blob.cpp new file mode 100644 index 0000000..0b677ea --- /dev/null +++ b/WebCore/html/Blob.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Blob.h" + +#include "FileSystem.h" + +namespace WebCore { + +Blob::Blob(const String& path) + : m_path(path) +{ +} + +unsigned long long Blob::size() const +{ + // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to + // come up with an exception to throw if file size is not represetable. + long long size; + if (!getFileSize(m_path, size)) + return 0; + return static_cast<unsigned long long>(size); +} + +} // namespace WebCore diff --git a/WebCore/html/Blob.h b/WebCore/html/Blob.h new file mode 100644 index 0000000..b910e8f --- /dev/null +++ b/WebCore/html/Blob.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Blob_h +#define Blob_h + +#include "ExceptionCode.h" +#include "PlatformString.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +class Blob : public RefCounted<Blob> { +public: + static PassRefPtr<Blob> create(const String& path) + { + return adoptRef(new Blob(path)); + } + + virtual ~Blob() { } + + const String& path() const { return m_path; } + unsigned long long size() const; + +protected: + Blob(const String& path); + +private: + String m_path; +}; + +} // namespace WebCore + +#endif // Blob_h diff --git a/WebCore/html/Blob.idl b/WebCore/html/Blob.idl new file mode 100644 index 0000000..573be35 --- /dev/null +++ b/WebCore/html/Blob.idl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module html { + + interface Blob { + readonly attribute unsigned long long size; + }; + +} diff --git a/WebCore/html/CollectionCache.cpp b/WebCore/html/CollectionCache.cpp index feecd96..745cf6e 100644 --- a/WebCore/html/CollectionCache.cpp +++ b/WebCore/html/CollectionCache.cpp @@ -85,4 +85,12 @@ void CollectionCache::reset() hasNameCache = false; } +#if !ASSERT_DISABLED +void CollectionCache::checkConsistency() +{ + idCache.checkConsistency(); + nameCache.checkConsistency(); +} +#endif + } // namespace WebCore diff --git a/WebCore/html/CollectionCache.h b/WebCore/html/CollectionCache.h index 0a49fb8..70a5af7 100644 --- a/WebCore/html/CollectionCache.h +++ b/WebCore/html/CollectionCache.h @@ -43,6 +43,8 @@ struct CollectionCache : FastAllocBase { void reset(); void swap(CollectionCache&); + void checkConsistency(); + typedef HashMap<AtomicStringImpl*, Vector<Element*>*> NodeCacheMap; unsigned version; @@ -59,6 +61,10 @@ private: static void copyCacheMap(NodeCacheMap&, const NodeCacheMap&); }; +#if ASSERT_DISABLED + inline void CollectionCache::checkConsistency() { } +#endif + } // namespace #endif diff --git a/WebCore/html/DataGridColumn.idl b/WebCore/html/DataGridColumn.idl index f566325..9214800 100644 --- a/WebCore/html/DataGridColumn.idl +++ b/WebCore/html/DataGridColumn.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, Conditional=DATAGRID ] DataGridColumn { attribute DOMString id; // The identifier for the column. diff --git a/WebCore/html/DataGridColumnList.idl b/WebCore/html/DataGridColumnList.idl index 1a59f43..9a8ea5c 100644 --- a/WebCore/html/DataGridColumnList.idl +++ b/WebCore/html/DataGridColumnList.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, HasIndexGetter, HasNameGetter, Conditional=DATAGRID diff --git a/WebCore/html/ISODateTime.cpp b/WebCore/html/DateComponents.cpp index 4c28ac0..9c62d30 100644 --- a/WebCore/html/ISODateTime.cpp +++ b/WebCore/html/DateComponents.cpp @@ -29,10 +29,15 @@ */ #include "config.h" -#include "ISODateTime.h" +#include "DateComponents.h" +#include "PlatformString.h" #include <limits.h> #include <wtf/ASCIICType.h> +#include <wtf/DateMath.h> +#include <wtf/MathExtras.h> + +using namespace std; namespace WebCore { @@ -54,7 +59,7 @@ static bool isLeapYear(int year) return true; } -// `month' is 0-based. +// 'month' is 0-based. static int maxDayOfMonth(int year, int month) { if (month != 1) // February? @@ -62,7 +67,7 @@ static int maxDayOfMonth(int year, int month) return isLeapYear(year) ? 29 : 28; } -// `month' is 0-based. +// 'month' is 0-based. static int dayOfWeek(int year, int month, int day) { int shiftedMonth = month + 2; @@ -82,7 +87,7 @@ static int dayOfWeek(int year, int month, int day) return result; } -int ISODateTime::maxWeekNumberInYear() const +int DateComponents::maxWeekNumberInYear() const { int day = dayOfWeek(m_year, 0, 1); // January 1. return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? 53 : 52; @@ -120,7 +125,7 @@ static bool toInt(const UChar* src, unsigned length, unsigned parseStart, unsign return true; } -bool ISODateTime::parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end) +bool DateComponents::parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end) { unsigned digitsLength = countDigits(src, length, start); // Needs at least 4 digits according to the standard. @@ -137,7 +142,14 @@ bool ISODateTime::parseYear(const UChar* src, unsigned length, unsigned start, u return true; } -bool ISODateTime::addDay(int dayDiff) +static bool beforeGregorianStartDate(int year, int month, int monthDay) +{ + return year < gregorianStartYear + || year == gregorianStartYear && month < gregorianStartMonth + || year == gregorianStartYear && month == gregorianStartMonth && monthDay < gregorianStartDay; +} + +bool DateComponents::addDay(int dayDiff) { ASSERT(m_monthDay); @@ -177,9 +189,7 @@ bool ISODateTime::addDay(int dayDiff) } day = maxDayOfMonth(year, month); } - if (year < gregorianStartYear - || (year == gregorianStartYear && month < gregorianStartMonth) - || (year == gregorianStartYear && month == gregorianStartMonth && day < gregorianStartDay)) + if (beforeGregorianStartDate(year, month, day)) return false; } m_year = year; @@ -189,7 +199,7 @@ bool ISODateTime::addDay(int dayDiff) return true; } -bool ISODateTime::addMinute(int minute) +bool DateComponents::addMinute(int minute) { int carry; // min can be negative or greater than 59. @@ -229,7 +239,7 @@ bool ISODateTime::addMinute(int minute) } // Parses a timezone part, and adjust year, month, monthDay, hour, minute, second, millisecond. -bool ISODateTime::parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end) +bool DateComponents::parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end) { if (start >= length) return false; @@ -274,7 +284,7 @@ bool ISODateTime::parseTimeZone(const UChar* src, unsigned length, unsigned star return true; } -bool ISODateTime::parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end) +bool DateComponents::parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end) { ASSERT(src); unsigned index; @@ -289,14 +299,15 @@ bool ISODateTime::parseMonth(const UChar* src, unsigned length, unsigned start, return false; --month; // No support for months before Gregorian calendar. - if (m_year == gregorianStartYear && month < gregorianStartMonth) + if (beforeGregorianStartDate(m_year, month, gregorianStartDay)) return false; m_month = month; end = index + 2; + m_type = Month; return true; } -bool ISODateTime::parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end) +bool DateComponents::parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end) { ASSERT(src); unsigned index; @@ -317,10 +328,11 @@ bool ISODateTime::parseDate(const UChar* src, unsigned length, unsigned start, u return false; m_monthDay = day; end = index + 2; + m_type = Date; return true; } -bool ISODateTime::parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end) +bool DateComponents::parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end) { ASSERT(src); unsigned index; @@ -345,10 +357,11 @@ bool ISODateTime::parseWeek(const UChar* src, unsigned length, unsigned start, u return false; m_week = week; end = index + 2; + m_type = Week; return true; } -bool ISODateTime::parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end) +bool DateComponents::parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end) { ASSERT(src); int hour; @@ -399,10 +412,11 @@ bool ISODateTime::parseTime(const UChar* src, unsigned length, unsigned start, u m_second = second; m_millisecond = millisecond; end = index; + m_type = Time; return true; } -bool ISODateTime::parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end) +bool DateComponents::parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end) { ASSERT(src); unsigned index; @@ -413,10 +427,13 @@ bool ISODateTime::parseDateTimeLocal(const UChar* src, unsigned length, unsigned if (src[index] != 'T') return false; ++index; - return parseTime(src, length, index, end); + if (!parseTime(src, length, index, end)) + return false; + m_type = DateTimeLocal; + return true; } -bool ISODateTime::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end) +bool DateComponents::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end) { ASSERT(src); unsigned index; @@ -429,7 +446,236 @@ bool ISODateTime::parseDateTime(const UChar* src, unsigned length, unsigned star ++index; if (!parseTime(src, length, index, index)) return false; - return parseTimeZone(src, length, index, end); + if (!parseTimeZone(src, length, index, end)) + return false; + m_type = DateTime; + return true; +} + +static inline double positiveFmod(double value, double divider) +{ + double remainder = fmod(value, divider); + return remainder < 0 ? remainder + divider : remainder; +} + +void DateComponents::setMillisecondsSinceMidnightInternal(double msInDay) +{ + ASSERT(msInDay >= 0 && msInDay < msPerDay); + m_millisecond = static_cast<int>(fmod(msInDay, msPerSecond)); + double value = floor(msInDay / msPerSecond); + m_second = static_cast<int>(fmod(value, secondsPerMinute)); + value = floor(value / secondsPerMinute); + m_minute = static_cast<int>(fmod(value, minutesPerHour)); + m_hour = static_cast<int>(value / minutesPerHour); +} + +bool DateComponents::setMillisecondsSinceEpochForDateInternal(double ms) +{ + m_year = msToYear(ms); + int yearDay = dayInYear(ms, m_year); + m_month = monthFromDayInYear(yearDay, isLeapYear(m_year)); + m_monthDay = dayInMonthFromDayInYear(yearDay, isLeapYear(m_year)); + return true; +} + +bool DateComponents::setMillisecondsSinceEpochForDate(double ms) +{ + m_type = Invalid; + if (!isfinite(ms)) + return false; + if (!setMillisecondsSinceEpochForDateInternal(round(ms))) + return false; + if (beforeGregorianStartDate(m_year, m_month, m_monthDay)) + return false; + m_type = Date; + return true; +} + +bool DateComponents::setMillisecondsSinceEpochForDateTime(double ms) +{ + m_type = Invalid; + if (!isfinite(ms)) + return false; + ms = round(ms); + setMillisecondsSinceMidnightInternal(positiveFmod(ms, msPerDay)); + if (!setMillisecondsSinceEpochForDateInternal(ms)) + return false; + if (beforeGregorianStartDate(m_year, m_month, m_monthDay)) + return false; + m_type = DateTime; + return true; +} + +bool DateComponents::setMillisecondsSinceEpochForDateTimeLocal(double ms) +{ + // Internal representation of DateTimeLocal is the same as DateTime except m_type. + if (!setMillisecondsSinceEpochForDateTime(ms)) + return false; + m_type = DateTimeLocal; + return true; +} + +bool DateComponents::setMillisecondsSinceEpochForMonth(double ms) +{ + m_type = Invalid; + if (!isfinite(ms)) + return false; + if (!setMillisecondsSinceEpochForDateInternal(round(ms))) + return false; + // Ignore m_monthDay updated by setMillisecondsSinceEpochForDateInternal(). + if (beforeGregorianStartDate(m_year, m_month, gregorianStartDay)) + return false; + m_type = Month; + return true; +} + +bool DateComponents::setMillisecondsSinceMidnight(double ms) +{ + m_type = Invalid; + if (!isfinite(ms)) + return false; + setMillisecondsSinceMidnightInternal(positiveFmod(round(ms), msPerDay)); + m_type = Time; + return true; +} + +bool DateComponents::setMonthsSinceEpoch(double months) +{ + if (!isfinite(months)) + return false; + months = round(months); + double doubleMonth = positiveFmod(months, 12); + double doubleYear = 1970 + (months - doubleMonth) / 12; + if (doubleYear < gregorianStartYear || numeric_limits<int>::max() < doubleYear) + return false; + int year = static_cast<int>(doubleYear); + int month = static_cast<int>(doubleMonth); + if (beforeGregorianStartDate(year, month, gregorianStartDay)) + return false; + m_year = year; + m_month = month; + m_type = Month; + return true; +} + +// Offset from January 1st to Monday of the ISO 8601's first week. +// ex. If January 1st is Friday, such Monday is 3 days later. Returns 3. +static int offsetTo1stWeekStart(int year) +{ + int offsetTo1stWeekStart = 1 - dayOfWeek(year, 0, 1); + if (offsetTo1stWeekStart <= -4) + offsetTo1stWeekStart += 7; + return offsetTo1stWeekStart; +} + +bool DateComponents::setMillisecondsSinceEpochForWeek(double ms) +{ + m_type = Invalid; + if (!isfinite(ms)) + return false; + ms = round(ms); + + m_year = msToYear(ms); + // We don't support gregorianStartYear. Week numbers are undefined in that year. + if (m_year <= gregorianStartYear) + return false; + + int yearDay = dayInYear(ms, m_year); + int offset = offsetTo1stWeekStart(m_year); + if (yearDay < offset) { + // The day belongs to the last week of the previous year. + m_year--; + if (m_year <= gregorianStartYear) + return false; + m_week = maxWeekNumberInYear(); + } else { + m_week = ((yearDay - offset) / 7) + 1; + if (m_week > maxWeekNumberInYear()) { + m_year++; + m_week = 1; + } + } + m_type = Week; + return true; +} + +double DateComponents::millisecondsSinceEpochForTime() const +{ + ASSERT(m_type == Time || m_type == DateTime || m_type == DateTimeLocal); + return ((m_hour * minutesPerHour + m_minute) * secondsPerMinute + m_second) * msPerSecond + m_millisecond; +} + +double DateComponents::millisecondsSinceEpoch() const +{ + switch (m_type) { + case Date: + return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay; + case DateTime: + case DateTimeLocal: + return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay + millisecondsSinceEpochForTime(); + case Month: + return dateToDaysFrom1970(m_year, m_month, 1) * msPerDay; + case Time: + return millisecondsSinceEpochForTime(); + case Week: + return (dateToDaysFrom1970(m_year, 0, 1) + offsetTo1stWeekStart(m_year) + (m_week - 1) * 7) * msPerDay; + case Invalid: + break; + } + ASSERT_NOT_REACHED(); + return invalidMilliseconds(); +} + +double DateComponents::monthsSinceEpoch() const +{ + ASSERT(m_type == Month); + return (m_year - 1970) * 12 + m_month; +} + +String DateComponents::toStringForTime(SecondFormat format) const +{ + ASSERT(m_type == DateTime || m_type == DateTimeLocal || m_type == Time); + SecondFormat effectiveFormat = format; + if (m_millisecond) + effectiveFormat = Millisecond; + else if (format == None && m_second) + effectiveFormat = Second; + + switch (effectiveFormat) { + default: + ASSERT_NOT_REACHED(); + // Fallback to None. + case None: + return String::format("%02d:%02d", m_hour, m_minute); + case Second: + return String::format("%02d:%02d:%02d", m_hour, m_minute, m_second); + case Millisecond: + return String::format("%02d:%02d:%02d.%03d", m_hour, m_minute, m_second, m_millisecond); + } +} + +String DateComponents::toString(SecondFormat format) const +{ + switch (m_type) { + case Date: + return String::format("%04d-%02d-%02d", m_year, m_month + 1, m_monthDay); + case DateTime: + return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay) + + toStringForTime(format) + String("Z"); + case DateTimeLocal: + return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay) + + toStringForTime(format); + case Month: + return String::format("%04d-%02d", m_year, m_month + 1); + case Time: + return toStringForTime(format); + case Week: + return String::format("%04d-W%02d", m_year, m_week); + case Invalid: + break; + } + ASSERT_NOT_REACHED(); + return String("(Invalid DateComponents)"); } } // namespace WebCore diff --git a/WebCore/html/ISODateTime.h b/WebCore/html/DateComponents.h index ee4cfb9..aff8855 100644 --- a/WebCore/html/ISODateTime.h +++ b/WebCore/html/DateComponents.h @@ -28,22 +28,25 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ISODateTime_h -#define ISODateTime_h +#ifndef DateComponents_h +#define DateComponents_h +#include <limits> #include <wtf/unicode/Unicode.h> namespace WebCore { -// An ISODateTime instance represents one of the following date and time combinations: -// * year-month -// * year-month-day -// * year-week -// * hour-minute-second-millisecond -// * year-month-day hour-minute-second-millisecond -class ISODateTime { +class String; + +// A DateComponents instance represents one of the following date and time combinations: +// * Month type: year-month +// * Date type: year-month-day +// * Week type: year-week +// * Time type: hour-minute-second-millisecond +// * DateTime or DateTimeLocal type: year-month-day hour-minute-second-millisecond +class DateComponents { public: - ISODateTime() + DateComponents() : m_millisecond(0) , m_second(0) , m_minute(0) @@ -52,6 +55,7 @@ public: , m_month(0) , m_year(0) , m_week(0) + , m_type(Invalid) { } @@ -64,12 +68,26 @@ public: int fullYear() const { return m_year; } int week() const { return m_week; } - // The following six functions parse the input `src' whose length is - // `length', and updates some fields of this instance. The parsing starts at + enum SecondFormat { + None, // Suppress the second part and the millisecond part if they are 0. + Second, // Always show the second part, and suppress the millisecond part if it is 0. + Millisecond // Always show the second part and the millisecond part. + }; + + // Returns an ISO 8601 representation for this instance. + // The format argument is valid for DateTime, DateTimeLocal, and Time types. + String toString(SecondFormat format = None) const; + + // parse*() and setMillisecondsSince*() functions are initializers for an + // DateComponents instance. If these functions return false, the instance + // might be invalid. + + // The following six functions parse the input 'src' whose length is + // 'length', and updates some fields of this instance. The parsing starts at // src[start] and examines characters before src[length]. - // `src' `date' must be non-null. The `src' string doesn't need to be + // 'src' must be non-null. The 'src' string doesn't need to be // null-terminated. - // The functions return true if the parsing succeeds, and set `end' to the + // The functions return true if the parsing succeeds, and set 'end' to the // next index after the last consumed. Extra leading characters cause parse // failures, and the trailing extra characters don't cause parse failures. @@ -86,14 +104,53 @@ public: // Sets year, month, monthDay, hour, minute, second and millisecond, and adjusts timezone. bool parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end); + // The following setMillisecondsSinceEpochFor*() functions take + // the number of milliseconds since 1970-01-01 00:00:00.000 UTC as + // the argument, and update all fields for the corresponding + // DateComponents type. The functions return true if it succeeds, and + // false if they fail. + + // For Date type. Updates m_year, m_month and m_monthDay. + bool setMillisecondsSinceEpochForDate(double ms); + // For DateTime type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond. + bool setMillisecondsSinceEpochForDateTime(double ms); + // For DateTimeLocal type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond. + bool setMillisecondsSinceEpochForDateTimeLocal(double ms); + // For Month type. Updates m_year and m_month. + bool setMillisecondsSinceEpochForMonth(double ms); + // For Week type. Updates m_year and m_week. + bool setMillisecondsSinceEpochForWeek(double ms); + + // For Time type. Updates m_hour, m_minute, m_second and m_millisecond. + bool setMillisecondsSinceMidnight(double ms); + + // Another initializer for Month type. Updates m_year and m_month. + bool setMonthsSinceEpoch(double months); + + // Returns the number of milliseconds from 1970-01-01 00:00:00 UTC. + // For a DateComponents initialized with parseDateTimeLocal(), + // millisecondsSinceEpoch() returns a value for UTC timezone. + double millisecondsSinceEpoch() const; + // Returns the number of months from 1970-01. + // Do not call this for types other than Month. + double monthsSinceEpoch() const; + static inline double invalidMilliseconds() { return std::numeric_limits<double>::quiet_NaN(); } + private: - // Returns the maximum week number in this ISODateTime's year. + // Returns the maximum week number in this DateComponents's year. // The result is either of 52 and 53. int maxWeekNumberInYear() const; bool parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end); bool addDay(int); bool addMinute(int); bool parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end); + // Helper for millisecondsSinceEpoch(). + double millisecondsSinceEpochForTime() const; + // Helpers for setMillisecondsSinceEpochFor*(). + bool setMillisecondsSinceEpochForDateInternal(double ms); + void setMillisecondsSinceMidnightInternal(double ms); + // Helper for toString(). + String toStringForTime(SecondFormat) const; // m_weekDay values enum { @@ -106,17 +163,28 @@ private: Saturday, }; - int m_millisecond; // 0 - 999 + int m_millisecond; // 0 - 999 int m_second; int m_minute; int m_hour; - int m_monthDay; // 1 - 31 - int m_month; // 0:January - 11:December - int m_year; // 1582 - - int m_week; // 1 - 53 + int m_monthDay; // 1 - 31 + int m_month; // 0:January - 11:December + int m_year; // 1582 - + int m_week; // 1 - 53 + + enum Type { + Invalid, + Date, + DateTime, + DateTimeLocal, + Month, + Time, + Week, + }; + Type m_type; }; } // namespace WebCore -#endif // ISODateTime_h +#endif // DateComponents_h diff --git a/WebCore/html/File.cpp b/WebCore/html/File.cpp index dbbbfa6..25e28e4 100644 --- a/WebCore/html/File.cpp +++ b/WebCore/html/File.cpp @@ -27,25 +27,13 @@ #include "File.h" #include "FileSystem.h" -#include "PlatformString.h" namespace WebCore { File::File(const String& path) - : m_path(path) - , m_fileName(pathGetFileName(path)) + : Blob(path) + , m_name(pathGetFileName(path)) { } -unsigned long long File::fileSize() -{ - // FIXME: Should we cache this? - // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to - // come up with an exception to throw if file size is not represetable. - long long size; - if (!getFileSize(m_path, size)) - return 0; - return size; -} - } // namespace WebCore diff --git a/WebCore/html/File.h b/WebCore/html/File.h index 7d79aa5..be53e30 100644 --- a/WebCore/html/File.h +++ b/WebCore/html/File.h @@ -26,30 +26,30 @@ #ifndef File_h #define File_h -#include "PlatformString.h" +#include "Blob.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> namespace WebCore { - class File : public RefCounted<File> { - public: - static PassRefPtr<File> create(const String& path) - { - return adoptRef(new File(path)); - } +class File : public Blob { +public: + static PassRefPtr<File> create(const String& path) + { + return adoptRef(new File(path)); + } - const String& fileName() const { return m_fileName; } - unsigned long long fileSize(); + const String& name() const { return m_name; } - const String& path() const { return m_path; } + // FIXME: obsolete attributes. To be removed. + const String& fileName() const { return m_name; } + unsigned long long fileSize() const { return size(); } - private: - File(const String& path); +private: + File(const String& path); - String m_path; - String m_fileName; - }; + String m_name; +}; } // namespace WebCore diff --git a/WebCore/html/File.idl b/WebCore/html/File.idl index ada9f0c..2632a4d 100644 --- a/WebCore/html/File.idl +++ b/WebCore/html/File.idl @@ -26,8 +26,12 @@ module html { interface [ - GenerateConstructor - ] File { + GenerateNativeConverter, + GenerateToJS + ] File : Blob { + readonly attribute DOMString name; + + // FIXME: obsolete attributes. To be removed. readonly attribute DOMString fileName; readonly attribute unsigned long long fileSize; }; diff --git a/WebCore/html/FileList.idl b/WebCore/html/FileList.idl index 01c286e..6baf3e1 100644 --- a/WebCore/html/FileList.idl +++ b/WebCore/html/FileList.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, HasIndexGetter ] FileList { readonly attribute unsigned long length; diff --git a/WebCore/html/HTMLAllCollection.idl b/WebCore/html/HTMLAllCollection.idl index d36f41e..3b65a0a 100644 --- a/WebCore/html/HTMLAllCollection.idl +++ b/WebCore/html/HTMLAllCollection.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, HasIndexGetter, HasNameGetter, CustomCall, diff --git a/WebCore/html/HTMLAnchorElement.cpp b/WebCore/html/HTMLAnchorElement.cpp index 1d5d569..f3b6ddd 100644 --- a/WebCore/html/HTMLAnchorElement.cpp +++ b/WebCore/html/HTMLAnchorElement.cpp @@ -497,20 +497,8 @@ String HTMLAnchorElement::protocol() const void HTMLAnchorElement::setProtocol(const String& value) { - int separator = value.find(':'); - - if (!separator) - return; - if (value.isEmpty()) - return; - KURL url = href(); - // Following Firefox 3.5.2 which removes anything after the first ":" - String newProtocol = value.substring(0, separator); - if (!isValidProtocol(newProtocol)) - return; - url.setProtocol(newProtocol); - + url.setProtocol(value); setHref(url.string()); } diff --git a/WebCore/html/HTMLAnchorElement.idl b/WebCore/html/HTMLAnchorElement.idl index e55bd86..03b3986 100644 --- a/WebCore/html/HTMLAnchorElement.idl +++ b/WebCore/html/HTMLAnchorElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=0c74cef8-b1f7-4b44-83a9-8deeb376a257, - ImplementationUUID=30f797d5-d145-498e-a126-d8e9ddeedea3 - ] HTMLAnchorElement : HTMLElement { + interface HTMLAnchorElement : HTMLElement { attribute [ConvertNullToNullString, Reflect=accesskey] DOMString accessKey; attribute [ConvertNullToNullString, Reflect] DOMString charset; attribute [ConvertNullToNullString, Reflect] DOMString coords; diff --git a/WebCore/html/HTMLAppletElement.cpp b/WebCore/html/HTMLAppletElement.cpp index f67e9dc..fb23b5c 100644 --- a/WebCore/html/HTMLAppletElement.cpp +++ b/WebCore/html/HTMLAppletElement.cpp @@ -63,7 +63,7 @@ void HTMLAppletElement::parseMappedAttribute(MappedAttribute* attr) document->addNamedItem(newName); } m_name = newName; - } else if (attr->name() == idAttr) { + } else if (attr->name() == idAttributeName()) { const AtomicString& newId = attr->value(); if (inDocument() && document()->isHTMLDocument()) { HTMLDocument* document = static_cast<HTMLDocument*>(this->document()); @@ -118,7 +118,7 @@ RenderObject* HTMLAppletElement::createRenderer(RenderArena*, RenderStyle* style if (!codeBase.isNull()) args.set("codeBase", codeBase); - const AtomicString& name = getAttribute(document()->isHTMLDocument() ? nameAttr : idAttr); + const AtomicString& name = getAttribute(document()->isHTMLDocument() ? nameAttr : idAttributeName()); if (!name.isNull()) args.set("name", name); const AtomicString& archive = getAttribute(archiveAttr); diff --git a/WebCore/html/HTMLAppletElement.idl b/WebCore/html/HTMLAppletElement.idl index cc923ca..8d6803e 100644 --- a/WebCore/html/HTMLAppletElement.idl +++ b/WebCore/html/HTMLAppletElement.idl @@ -21,13 +21,10 @@ module html { interface [ - GenerateConstructor, DelegatingPutFunction, DelegatingGetOwnPropertySlot, CustomCall, - HasOverridingNameGetter, - InterfaceUUID=9b5cb4a8-c156-4b55-afdb-c60938a4d1b1, - ImplementationUUID=56544372-675e-40dd-ba39-fa708a4c7678 + HasOverridingNameGetter ] HTMLAppletElement : HTMLElement { attribute [ConvertNullToNullString, Reflect] DOMString align; attribute [ConvertNullToNullString, Reflect] DOMString alt; diff --git a/WebCore/html/HTMLAreaElement.cpp b/WebCore/html/HTMLAreaElement.cpp index b202cae..b862f69 100644 --- a/WebCore/html/HTMLAreaElement.cpp +++ b/WebCore/html/HTMLAreaElement.cpp @@ -22,6 +22,8 @@ #include "config.h" #include "HTMLAreaElement.h" +#include "HTMLImageElement.h" +#include "HTMLMapElement.h" #include "HTMLNames.h" #include "HitTestResult.h" #include "MappedAttribute.h" @@ -82,13 +84,27 @@ bool HTMLAreaElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestRe return true; } -IntRect HTMLAreaElement::getRect(RenderObject* obj) const +Path HTMLAreaElement::getPath(RenderObject* obj) const { + if (!obj) + return Path(); + // FIXME: This doesn't work correctly with transforms. FloatPoint absPos = obj->localToAbsolute(); - Path p = getRegion(m_lastSize); + + // Default should default to the size of the containing object. + IntSize size = m_lastSize; + if (m_shape == Default) + size = obj->absoluteOutlineBounds().size(); + + Path p = getRegion(size); p.translate(absPos - FloatPoint()); - return enclosingIntRect(p.boundingRect()); + return p; +} + +IntRect HTMLAreaElement::getRect(RenderObject* obj) const +{ + return enclosingIntRect(getPath(obj).boundingRect()); } Path HTMLAreaElement::getRegion(const IntSize& size) const @@ -161,11 +177,58 @@ void HTMLAreaElement::setNoHref(bool noHref) { setAttribute(nohrefAttr, noHref ? "" : 0); } + +HTMLImageElement* HTMLAreaElement::imageElement() const +{ + Node* mapElement = parent(); + if (!mapElement->hasTagName(mapTag)) + return 0; + + return static_cast<HTMLMapElement*>(mapElement)->imageElement(); +} +bool HTMLAreaElement::isKeyboardFocusable(KeyboardEvent*) const +{ + return supportsFocus(); +} + +bool HTMLAreaElement::isFocusable() const +{ + return supportsFocus(); +} + +void HTMLAreaElement::dispatchBlurEvent() +{ + HTMLAnchorElement::dispatchBlurEvent(); + + // On a blur, we might need to remove our focus rings by repainting. + updateFocusAppearance(false); +} + +void HTMLAreaElement::updateFocusAppearance(bool restorePreviousSelection) +{ + Node* parent = parentNode(); + if (!parent || !parent->hasTagName(mapTag)) + return; + + HTMLImageElement* imageElement = static_cast<HTMLMapElement*>(parent)->imageElement(); + if (!imageElement) + return; + + // This will handle scrolling to the image if necessary. + imageElement->updateFocusAppearance(restorePreviousSelection); + + RenderObject* imageRenderer = imageElement->renderer(); + if (imageRenderer) + imageRenderer->setNeedsLayout(true); +} + bool HTMLAreaElement::supportsFocus() const { - // Skip HTMLAnchorElements isLink() check. - return HTMLElement::supportsFocus(); + // If the AREA element was a link, it should support focus. + // The inherited method is not used because it assumes that a render object must exist + // for the element to support focus. AREA elements do not have render objects. + return isLink(); } String HTMLAreaElement::target() const diff --git a/WebCore/html/HTMLAreaElement.h b/WebCore/html/HTMLAreaElement.h index 7b2497c..f8e2564 100644 --- a/WebCore/html/HTMLAreaElement.h +++ b/WebCore/html/HTMLAreaElement.h @@ -30,6 +30,7 @@ namespace WebCore { class HitTestResult; +class HTMLImageElement; class Path; class HTMLAreaElement : public HTMLAnchorElement { @@ -41,7 +42,11 @@ public: bool mapMouseEvent(int x, int y, const IntSize&, HitTestResult&); IntRect getRect(RenderObject*) const; - + Path getPath(RenderObject*) const; + + // Convenience method to get the parent map's image. + HTMLImageElement* imageElement() const; + KURL href() const; bool noHref() const; @@ -55,7 +60,11 @@ private: virtual void parseMappedAttribute(MappedAttribute*); virtual bool supportsFocus() const; virtual String target() const; - + virtual bool isKeyboardFocusable(KeyboardEvent*) const; + virtual bool isFocusable() const; + virtual void updateFocusAppearance(bool /*restorePreviousSelection*/); + virtual void dispatchBlurEvent(); + enum Shape { Default, Poly, Rect, Circle, Unknown }; Path getRegion(const IntSize&) const; diff --git a/WebCore/html/HTMLAreaElement.idl b/WebCore/html/HTMLAreaElement.idl index 53239c6..210d6e5 100644 --- a/WebCore/html/HTMLAreaElement.idl +++ b/WebCore/html/HTMLAreaElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=aac98729-47d3-4623-8c5b-004783af5bd6, - ImplementationUUID=f0631a41-5f55-40e5-a879-c09e663c26ba - ] HTMLAreaElement : HTMLElement { + interface HTMLAreaElement : HTMLElement { attribute [ConvertNullToNullString, Reflect=accesskey] DOMString accessKey; attribute [ConvertNullToNullString, Reflect] DOMString alt; attribute [ConvertNullToNullString, Reflect] DOMString coords; diff --git a/WebCore/html/HTMLAttributeNames.in b/WebCore/html/HTMLAttributeNames.in index 967b695..ad13070 100644 --- a/WebCore/html/HTMLAttributeNames.in +++ b/WebCore/html/HTMLAttributeNames.in @@ -13,6 +13,8 @@ alink alt archive aria-activedescendant +aria-atomic +aria-busy aria-checked aria-controls aria-describedby @@ -21,16 +23,19 @@ aria-dropeffect aria-expanded aria-flowto aria-grabbed +aria-haspopup aria-hidden aria-label aria-labeledby aria-labelledby aria-level +aria-live aria-multiselectable aria-orientation aria-owns aria-pressed aria-readonly +aria-relevant aria-required aria-selected aria-valuemax @@ -58,7 +63,7 @@ charset checked cellborder cite -class exportString +class classid clear code diff --git a/WebCore/html/HTMLAudioElement.idl b/WebCore/html/HTMLAudioElement.idl index f335d86..107b8b1 100644 --- a/WebCore/html/HTMLAudioElement.idl +++ b/WebCore/html/HTMLAudioElement.idl @@ -24,7 +24,7 @@ */ module html { - interface [GenerateConstructor, Conditional=VIDEO] HTMLAudioElement : HTMLMediaElement { + interface [Conditional=VIDEO] HTMLAudioElement : HTMLMediaElement { }; } diff --git a/WebCore/html/HTMLBRElement.idl b/WebCore/html/HTMLBRElement.idl index 6d626ff..4048911 100644 --- a/WebCore/html/HTMLBRElement.idl +++ b/WebCore/html/HTMLBRElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=e84b14bc-b0aa-431f-83c4-fcc297e354b0, - ImplementationUUID=c10d45a4-b042-45d0-b170-6ac7173ee823 - ] HTMLBRElement : HTMLElement { + interface HTMLBRElement : HTMLElement { attribute [ConvertNullToNullString, Reflect] DOMString clear; }; diff --git a/WebCore/html/HTMLBaseElement.idl b/WebCore/html/HTMLBaseElement.idl index b7385ec..087faca 100644 --- a/WebCore/html/HTMLBaseElement.idl +++ b/WebCore/html/HTMLBaseElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=e4112bea-13de-40f6-93d0-41e285ae1491, - ImplementationUUID=23cec074-660f-490a-996d-167d66c164d5 - ] HTMLBaseElement : HTMLElement { + interface HTMLBaseElement : HTMLElement { attribute [ConvertNullToNullString, Reflect] DOMString href; attribute [ConvertNullToNullString, Reflect] DOMString target; }; diff --git a/WebCore/html/HTMLBaseFontElement.idl b/WebCore/html/HTMLBaseFontElement.idl index 665f124..d55654e 100644 --- a/WebCore/html/HTMLBaseFontElement.idl +++ b/WebCore/html/HTMLBaseFontElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=434b1be5-408e-45b5-be83-c70e11e9bb37, - ImplementationUUID=1dc8508e-53c4-4e7e-93c0-16772372b2dc - ] HTMLBaseFontElement : HTMLElement { + interface HTMLBaseFontElement : HTMLElement { attribute [ConvertNullToNullString, Reflect] DOMString color; attribute [ConvertNullToNullString, Reflect] DOMString face; #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C diff --git a/WebCore/html/HTMLBlockquoteElement.idl b/WebCore/html/HTMLBlockquoteElement.idl index f6463dd..b819236 100644 --- a/WebCore/html/HTMLBlockquoteElement.idl +++ b/WebCore/html/HTMLBlockquoteElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=902d9011-c6d6-4363-b6fe-bd2d28ef553b, - ImplementationUUID=345db946-ba9c-44b9-87fd-06083aa472e4 - ] HTMLBlockquoteElement : HTMLElement { + interface HTMLBlockquoteElement : HTMLElement { attribute [ConvertNullToNullString, Reflect] DOMString cite; }; diff --git a/WebCore/html/HTMLBodyElement.idl b/WebCore/html/HTMLBodyElement.idl index b2f0c65..95140c7 100644 --- a/WebCore/html/HTMLBodyElement.idl +++ b/WebCore/html/HTMLBodyElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=4789afc6-2d9e-4f3b-8c27-12abc9d4a014, - ImplementationUUID=d2e16911-2f7e-4d58-a92c-94700d445b38 - ] HTMLBodyElement : HTMLElement { + interface HTMLBodyElement : HTMLElement { attribute [ConvertNullToNullString, Reflect=alink] DOMString aLink; attribute [ConvertNullToNullString, Reflect] DOMString background; attribute [ConvertNullToNullString, Reflect=bgcolor] DOMString bgColor; @@ -33,7 +29,6 @@ module html { attribute [ConvertNullToNullString, Reflect=vlink] DOMString vLink; #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM // Event handler attributes attribute [DontEnum] EventListener onbeforeunload; attribute [DontEnum] EventListener onhashchange; @@ -58,11 +53,9 @@ module html { // Not implemented yet. // attribute [DontEnum] EventListener onafterprint; // attribute [DontEnum] EventListener onbeforeprint; - // attribute [DontEnum] EventListener onpopstate; // attribute [DontEnum] EventListener onredo; // attribute [DontEnum] EventListener onundo; #endif -#endif }; } diff --git a/WebCore/html/HTMLButtonElement.idl b/WebCore/html/HTMLButtonElement.idl index cb9383d..73098fe 100644 --- a/WebCore/html/HTMLButtonElement.idl +++ b/WebCore/html/HTMLButtonElement.idl @@ -20,16 +20,10 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=b9715643-5591-442d-ab65-e05309607271, - ImplementationUUID=1be13b5f-40df-4550-b70e-8c805e546cad - ] HTMLButtonElement : HTMLElement { + interface HTMLButtonElement : HTMLElement { readonly attribute HTMLFormElement form; attribute boolean formNoValidate; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM readonly attribute ValidityState validity; -#endif attribute [ConvertNullToNullString] DOMString accessKey; attribute boolean disabled; attribute boolean autofocus; diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp index be0fa36..4cbbb65 100644 --- a/WebCore/html/HTMLCanvasElement.cpp +++ b/WebCore/html/HTMLCanvasElement.cpp @@ -27,10 +27,12 @@ #include "config.h" #include "HTMLCanvasElement.h" +#include "CanvasContextAttributes.h" #include "CanvasGradient.h" #include "CanvasPattern.h" #include "CanvasRenderingContext2D.h" #if ENABLE(3D_CANVAS) +#include "WebGLContextAttributes.h" #include "WebGLRenderingContext.h" #endif #include "CanvasStyle.h" @@ -147,7 +149,7 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, ExceptionCode& ec) return buffer()->toDataURL(mimeType); } -CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type) +CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, CanvasContextAttributes* attrs) { // A Canvas can either be "2D" or "webgl" but never both. If you request a 2D canvas and the existing // context is already 2D, just return that. If the existing context is WebGL, then destroy it @@ -174,7 +176,7 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type) if (m_context && !m_context->is3d()) return 0; if (!m_context) { - m_context = WebGLRenderingContext::create(this); + m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs)); if (m_context) { // Need to make sure a RenderLayer and compositing layer get created for the Canvas setNeedsStyleRecalc(SyntheticStyleChange); @@ -183,6 +185,8 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type) return m_context.get(); } } +#else + UNUSED_PARAM(attrs); #endif return 0; } @@ -223,6 +227,11 @@ void HTMLCanvasElement::reset() IntSize oldSize = m_size; m_size = IntSize(w, h); +#if ENABLE(3D_CANVAS) + if (m_context && m_context->is3d()) + static_cast<WebGLRenderingContext*>(m_context.get())->reshape(width(), height()); +#endif + bool hadImageBuffer = m_createdImageBuffer; m_createdImageBuffer = false; m_imageBuffer.clear(); @@ -251,7 +260,7 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r) return; #if ENABLE(3D_CANVAS) - WebGLRenderingContext* context3D = NULL; + WebGLRenderingContext* context3D = 0; if (m_context && m_context->is3d()) { context3D = static_cast<WebGLRenderingContext*>(m_context.get()); context3D->beginPaint(); @@ -265,10 +274,8 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r) } #if ENABLE(3D_CANVAS) - if (context3D != NULL) { - context3D->reshape(r.width(), r.height()); + if (context3D) context3D->endPaint(); - } #endif } diff --git a/WebCore/html/HTMLCanvasElement.h b/WebCore/html/HTMLCanvasElement.h index edae9e5..db80396 100644 --- a/WebCore/html/HTMLCanvasElement.h +++ b/WebCore/html/HTMLCanvasElement.h @@ -37,6 +37,7 @@ namespace WebCore { +class CanvasContextAttributes; class CanvasRenderingContext; class FloatPoint; class FloatRect; @@ -68,7 +69,7 @@ public: String toDataURL(const String& mimeType, ExceptionCode&); - CanvasRenderingContext* getContext(const String&); + CanvasRenderingContext* getContext(const String&, CanvasContextAttributes* attributes = 0); const IntSize& size() const { return m_size; } void setSize(const IntSize& size) diff --git a/WebCore/html/HTMLCanvasElement.idl b/WebCore/html/HTMLCanvasElement.idl index 4b1b057..ea7f982 100644 --- a/WebCore/html/HTMLCanvasElement.idl +++ b/WebCore/html/HTMLCanvasElement.idl @@ -26,10 +26,7 @@ module html { interface [ - CustomMarkFunction, - GenerateConstructor, - InterfaceUUID=a14d88c8-c6af-4e34-ad17-659700c77a10, - ImplementationUUID=7ae731bc-c264-4ee3-a4b4-5d4540af26c3 + CustomMarkFunction ] HTMLCanvasElement : HTMLElement { attribute long width; @@ -39,7 +36,8 @@ module html { raises(DOMException); #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C - [V8Custom] DOMObject getContext(in DOMString contextId); + // The custom binding is needed to handle context creation attributes. + [Custom] DOMObject getContext(in DOMString contextId); #endif }; diff --git a/WebCore/html/HTMLCollection.cpp b/WebCore/html/HTMLCollection.cpp index 2b29589..5e42d30 100644 --- a/WebCore/html/HTMLCollection.cpp +++ b/WebCore/html/HTMLCollection.cpp @@ -274,7 +274,7 @@ bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const A HTMLElement* e = static_cast<HTMLElement*>(element); if (!checkName) - return e->getAttribute(idAttr) == name; + return e->getAttribute(e->idAttributeName()) == name; // document.all returns only images, forms, applets, objects and embeds // by name (though everything by id) @@ -285,7 +285,7 @@ bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const A e->hasLocalName(selectTag))) return false; - return e->getAttribute(nameAttr) == name && e->getAttribute(idAttr) != name; + return e->getAttribute(nameAttr) == name && e->getAttribute(e->idAttributeName()) != name; } Node* HTMLCollection::namedItem(const AtomicString& name) const @@ -327,7 +327,7 @@ void HTMLCollection::updateNameCache() const if (!element->isHTMLElement()) continue; HTMLElement* e = static_cast<HTMLElement*>(element); - const AtomicString& idAttrVal = e->getAttribute(idAttr); + const AtomicString& idAttrVal = e->getAttribute(e->idAttributeName()); const AtomicString& nameAttrVal = e->getAttribute(nameAttr); if (!idAttrVal.isEmpty()) { // add to id cache @@ -366,7 +366,8 @@ void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& resetCollectionInfo(); updateNameCache(); - + m_info->checkConsistency(); + Vector<Element*>* idResults = m_info->idCache.get(name.impl()); Vector<Element*>* nameResults = m_info->nameCache.get(name.impl()); @@ -381,6 +382,7 @@ void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& Node* HTMLCollection::nextNamedItem(const AtomicString& name) const { resetCollectionInfo(); + m_info->checkConsistency(); for (Element* e = itemAfter(m_info->current); e; e = itemAfter(e)) { if (checkForNameMatch(e, m_idsDone, name)) { diff --git a/WebCore/html/HTMLCollection.idl b/WebCore/html/HTMLCollection.idl index 45d1127..a3e4332 100644 --- a/WebCore/html/HTMLCollection.idl +++ b/WebCore/html/HTMLCollection.idl @@ -21,14 +21,11 @@ module html { interface [ - GenerateConstructor, HasIndexGetter, HasNameGetter, CustomCall, CustomToJS, - Polymorphic, - InterfaceUUID=b0d215ff-6f9c-4d1f-86c3-f200a65a5134, - ImplementationUUID=8e81b17f-7f74-4121-8f2f-a339a7e66447 + Polymorphic ] HTMLCollection { readonly attribute unsigned long length; [Custom] Node item(in unsigned long index); diff --git a/WebCore/html/HTMLDListElement.idl b/WebCore/html/HTMLDListElement.idl index 1578dfd..57c5c57 100644 --- a/WebCore/html/HTMLDListElement.idl +++ b/WebCore/html/HTMLDListElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=5665c589-aea9-4322-844f-d3395fd5839e, - ImplementationUUID=99ac26a3-224b-4bc6-b287-89946a6de9a7 - ] HTMLDListElement : HTMLElement { + interface HTMLDListElement : HTMLElement { attribute boolean compact; }; diff --git a/WebCore/html/HTMLDataGridCellElement.idl b/WebCore/html/HTMLDataGridCellElement.idl index c7c51bc..1064cf7 100644 --- a/WebCore/html/HTMLDataGridCellElement.idl +++ b/WebCore/html/HTMLDataGridCellElement.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, Conditional=DATAGRID ] HTMLDataGridCellElement : HTMLElement { attribute DOMString label; // The text to display in the column, assuming the type supports text. diff --git a/WebCore/html/HTMLDataGridColElement.cpp b/WebCore/html/HTMLDataGridColElement.cpp index 8398545..935375e 100644 --- a/WebCore/html/HTMLDataGridColElement.cpp +++ b/WebCore/html/HTMLDataGridColElement.cpp @@ -55,7 +55,7 @@ void HTMLDataGridColElement::ensureColumn() { if (m_column) return; - m_column = DataGridColumn::create(getAttribute(idAttr), label(), type(), primary(), sortable()); + m_column = DataGridColumn::create(getAttribute(idAttributeName()), label(), type(), primary(), sortable()); } void HTMLDataGridColElement::insertedIntoTree(bool deep) @@ -162,8 +162,8 @@ void HTMLDataGridColElement::parseMappedAttribute(MappedAttribute* attr) column()->setSortable(sortable()); else if (attr->name() == sortdirectionAttr) column()->setSortDirection(sortDirection()); - else if (attr->name() == idAttr) - column()->setId(getAttribute(idAttr)); + else if (attr->name() == idAttributeName()) + column()->setId(getAttribute(idAttributeName())); } } // namespace WebCore diff --git a/WebCore/html/HTMLDataGridColElement.idl b/WebCore/html/HTMLDataGridColElement.idl index 5861039..7a67c7e 100644 --- a/WebCore/html/HTMLDataGridColElement.idl +++ b/WebCore/html/HTMLDataGridColElement.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, Conditional=DATAGRID ] HTMLDataGridColElement : HTMLElement { attribute DOMString label; // The text to display in the column. diff --git a/WebCore/html/HTMLDataGridElement.idl b/WebCore/html/HTMLDataGridElement.idl index c9e6d9d..e9a800b 100644 --- a/WebCore/html/HTMLDataGridElement.idl +++ b/WebCore/html/HTMLDataGridElement.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, Conditional=DATAGRID ] HTMLDataGridElement : HTMLElement { attribute [Custom] DataGridDataSource dataSource; diff --git a/WebCore/html/HTMLDataGridRowElement.idl b/WebCore/html/HTMLDataGridRowElement.idl index f6954af..7b3e68f 100644 --- a/WebCore/html/HTMLDataGridRowElement.idl +++ b/WebCore/html/HTMLDataGridRowElement.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, Conditional=DATAGRID ] HTMLDataGridRowElement : HTMLElement { attribute boolean selected; // Whether or not the row is currently selected. diff --git a/WebCore/html/HTMLDataListElement.idl b/WebCore/html/HTMLDataListElement.idl index 916c0a1..a971fa7 100644 --- a/WebCore/html/HTMLDataListElement.idl +++ b/WebCore/html/HTMLDataListElement.idl @@ -30,7 +30,6 @@ module html { interface [ - GenerateConstructor, Conditional=DATALIST ] HTMLDataListElement : HTMLElement { readonly attribute HTMLCollection options; diff --git a/WebCore/html/HTMLDirectoryElement.idl b/WebCore/html/HTMLDirectoryElement.idl index 308e30d..c88e2e0 100644 --- a/WebCore/html/HTMLDirectoryElement.idl +++ b/WebCore/html/HTMLDirectoryElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=49292c6b-2b2e-49cb-98b6-20d4cd806bd2, - ImplementationUUID=45749798-4afe-4884-a42a-a2c8b3d98795 - ] HTMLDirectoryElement : HTMLElement { + interface HTMLDirectoryElement : HTMLElement { attribute boolean compact; }; diff --git a/WebCore/html/HTMLDivElement.idl b/WebCore/html/HTMLDivElement.idl index 41cc327..9f0b581 100644 --- a/WebCore/html/HTMLDivElement.idl +++ b/WebCore/html/HTMLDivElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=46fb9095-b485-4925-b6fd-2622935fd8bf, - ImplementationUUID=5f8661b7-96ad-4a8b-864a-85d544319fd2 - ] HTMLDivElement : HTMLElement { + interface HTMLDivElement : HTMLElement { attribute [ConvertNullToNullString] DOMString align; }; diff --git a/WebCore/html/HTMLDocument.cpp b/WebCore/html/HTMLDocument.cpp index c04f73f..cf98755 100644 --- a/WebCore/html/HTMLDocument.cpp +++ b/WebCore/html/HTMLDocument.cpp @@ -80,7 +80,7 @@ namespace WebCore { using namespace HTMLNames; HTMLDocument::HTMLDocument(Frame* frame) - : Document(frame, false) + : Document(frame, false, true) { clearXMLVersion(); setParseMode(Compat); @@ -398,8 +398,11 @@ void HTMLDocument::determineParseMode() } } - if (inCompatMode() != wasInCompatMode) + if (inCompatMode() != wasInCompatMode) { + clearPageUserSheet(); + clearPageGroupUserSheets(); updateStyleSelector(); + } } void HTMLDocument::clear() diff --git a/WebCore/html/HTMLDocument.h b/WebCore/html/HTMLDocument.h index f4bdaec..4a8dd8b 100644 --- a/WebCore/html/HTMLDocument.h +++ b/WebCore/html/HTMLDocument.h @@ -95,7 +95,6 @@ private: virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&); - virtual bool isHTMLDocument() const { return true; } virtual bool isFrameSet() const; virtual Tokenizer* createTokenizer(); virtual void determineParseMode(); diff --git a/WebCore/html/HTMLDocument.idl b/WebCore/html/HTMLDocument.idl index d250741..a79b913 100644 --- a/WebCore/html/HTMLDocument.idl +++ b/WebCore/html/HTMLDocument.idl @@ -21,10 +21,7 @@ module html { interface [ - GenerateConstructor, - HasOverridingNameGetter, - InterfaceUUID=a183339c-8d74-412a-933d-6f6a4ad6266e, - ImplementationUUID=d0f7d966-033c-4cbf-847c-1461dacc2f6a + HasOverridingNameGetter ] HTMLDocument : Document { [Custom] void open(); void close(); diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp index a4fc52a..d3a7f22 100644 --- a/WebCore/html/HTMLElement.cpp +++ b/WebCore/html/HTMLElement.cpp @@ -82,19 +82,48 @@ HTMLTagStatus HTMLElement::endTagRequirement() const return TagStatusRequired; } -int HTMLElement::tagPriority() const +struct Empty1IntHashTraits : HashTraits<int> { + static const bool emptyValueIsZero = false; + static int emptyValue() { return 1; } +}; +typedef HashMap<AtomicStringImpl*, int, DefaultHash<AtomicStringImpl*>::Hash, HashTraits<AtomicStringImpl*>, Empty1IntHashTraits> TagPriorityMap; + +static const TagPriorityMap* createTagPriorityMap() { - if (hasLocalName(wbrTag)) - return 0; - if (hasLocalName(addressTag) || hasLocalName(ddTag) || hasLocalName(dtTag) || hasLocalName(noscriptTag) || hasLocalName(rpTag) || hasLocalName(rtTag)) - return 3; - if (hasLocalName(centerTag) || hasLocalName(nobrTag) || hasLocalName(rubyTag) || hasLocalName(navTag)) - return 5; - if (hasLocalName(noembedTag) || hasLocalName(noframesTag)) - return 10; + TagPriorityMap* map = new TagPriorityMap; + + map->add(wbrTag.localName().impl(), 0); + + map->add(addressTag.localName().impl(), 3); + map->add(ddTag.localName().impl(), 3); + map->add(dtTag.localName().impl(), 3); + map->add(noscriptTag.localName().impl(), 3); + map->add(rpTag.localName().impl(), 3); + map->add(rtTag.localName().impl(), 3); + + // 5 is same as <div>'s priority. + map->add(articleTag.localName().impl(), 5); + map->add(asideTag.localName().impl(), 5); + map->add(centerTag.localName().impl(), 5); + map->add(footerTag.localName().impl(), 5); + map->add(headerTag.localName().impl(), 5); + map->add(nobrTag.localName().impl(), 5); + map->add(rubyTag.localName().impl(), 5); + map->add(navTag.localName().impl(), 5); + map->add(sectionTag.localName().impl(), 5); + + map->add(noembedTag.localName().impl(), 10); + map->add(noframesTag.localName().impl(), 10); + + // TagPriorityMap returns 1 for unregistered tags. It's same as <span>. + // This way custom tag name elements will behave like inline spans. + return map; +} - // Same values as <span>. This way custom tag name elements will behave like inline spans. - return 1; +int HTMLElement::tagPriority() const +{ + static const TagPriorityMap* tagPriorityMap = createTagPriorityMap(); + return tagPriorityMap->get(localName().impl()); } bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const @@ -114,7 +143,7 @@ bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry void HTMLElement::parseMappedAttribute(MappedAttribute *attr) { - if (attr->name() == idAttr || attr->name() == classAttr || attr->name() == styleAttr) + if (attr->name() == idAttributeName() || attr->name() == classAttr || attr->name() == styleAttr) return StyledElement::parseMappedAttribute(attr); String indexstring; @@ -243,7 +272,7 @@ String HTMLElement::outerHTML() const return createMarkup(this); } -PassRefPtr<DocumentFragment> HTMLElement::createContextualFragment(const String &html) +PassRefPtr<DocumentFragment> HTMLElement::createContextualFragment(const String &html, FragmentScriptingPermission scriptingPermission) { // the following is in accordance with the definition as used by IE if (endTagRequirement() == TagStatusForbidden) @@ -256,9 +285,9 @@ PassRefPtr<DocumentFragment> HTMLElement::createContextualFragment(const String RefPtr<DocumentFragment> fragment = DocumentFragment::create(document()); if (document()->isHTMLDocument()) - parseHTMLDocumentFragment(html, fragment.get()); + parseHTMLDocumentFragment(html, fragment.get(), scriptingPermission); else { - if (!parseXMLDocumentFragment(html, fragment.get(), this)) + if (!parseXMLDocumentFragment(html, fragment.get(), this, scriptingPermission)) // FIXME: We should propagate a syntax error exception out here. return 0; } @@ -348,6 +377,13 @@ static void replaceChildrenWithText(HTMLElement* element, const String& text, Ex void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec) { + if (hasLocalName(scriptTag) || hasLocalName(styleTag)) { + // Script and CSS source shouldn't be parsed as HTML. + removeChildren(); + appendChild(document()->createTextNode(html), ec); + return; + } + RefPtr<DocumentFragment> fragment = createContextualFragment(html); if (!fragment) { ec = NO_MODIFICATION_ALLOWED_ERR; @@ -866,6 +902,8 @@ static HashSet<AtomicStringImpl*>* blockTagList() DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ()); if (tagList.isEmpty()) { tagList.add(addressTag.localName().impl()); + tagList.add(articleTag.localName().impl()); + tagList.add(asideTag.localName().impl()); tagList.add(blockquoteTag.localName().impl()); tagList.add(centerTag.localName().impl()); tagList.add(ddTag.localName().impl()); @@ -874,6 +912,7 @@ static HashSet<AtomicStringImpl*>* blockTagList() tagList.add(dlTag.localName().impl()); tagList.add(dtTag.localName().impl()); tagList.add(fieldsetTag.localName().impl()); + tagList.add(footerTag.localName().impl()); tagList.add(formTag.localName().impl()); tagList.add(h1Tag.localName().impl()); tagList.add(h2Tag.localName().impl()); @@ -881,6 +920,7 @@ static HashSet<AtomicStringImpl*>* blockTagList() tagList.add(h4Tag.localName().impl()); tagList.add(h5Tag.localName().impl()); tagList.add(h6Tag.localName().impl()); + tagList.add(headerTag.localName().impl()); tagList.add(hrTag.localName().impl()); tagList.add(isindexTag.localName().impl()); tagList.add(layerTag.localName().impl()); @@ -897,6 +937,7 @@ static HashSet<AtomicStringImpl*>* blockTagList() tagList.add(pTag.localName().impl()); tagList.add(plaintextTag.localName().impl()); tagList.add(preTag.localName().impl()); + tagList.add(sectionTag.localName().impl()); tagList.add(tableTag.localName().impl()); tagList.add(ulTag.localName().impl()); tagList.add(xmpTag.localName().impl()); diff --git a/WebCore/html/HTMLElement.h b/WebCore/html/HTMLElement.h index c6a384b..ccc9aa3 100644 --- a/WebCore/html/HTMLElement.h +++ b/WebCore/html/HTMLElement.h @@ -46,7 +46,7 @@ public: String innerHTML() const; String outerHTML() const; - PassRefPtr<DocumentFragment> createContextualFragment(const String&); + PassRefPtr<DocumentFragment> createContextualFragment(const String&, FragmentScriptingPermission = FragmentScriptingAllowed); void setInnerHTML(const String&, ExceptionCode&); void setOuterHTML(const String&, ExceptionCode&); void setInnerText(const String&, ExceptionCode&); @@ -116,6 +116,7 @@ private: inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document* document, ConstructionType type) : StyledElement(tagName, document, type) { + ASSERT(tagName.localName().impl()); } } // namespace WebCore diff --git a/WebCore/html/HTMLElement.idl b/WebCore/html/HTMLElement.idl index 6b9e1d0..627dda2 100644 --- a/WebCore/html/HTMLElement.idl +++ b/WebCore/html/HTMLElement.idl @@ -21,11 +21,8 @@ module html { interface [ - GenerateConstructor, GenerateNativeConverter, - CustomPushEventHandlerScope, - InterfaceUUID=b2f172f1-d209-446f-8143-5f21de678f95, - ImplementationUUID=c81b0e16-a2b9-448b-ad0a-81c9346d6f8a + CustomPushEventHandlerScope ] HTMLElement : Element { // iht.com relies on id returning the empty string when no id is present. // Other browsers do this as well. So we don't convert null to JS null. diff --git a/WebCore/html/HTMLEmbedElement.cpp b/WebCore/html/HTMLEmbedElement.cpp index 81b88a4..6c62848 100644 --- a/WebCore/html/HTMLEmbedElement.cpp +++ b/WebCore/html/HTMLEmbedElement.cpp @@ -32,8 +32,8 @@ #include "HTMLNames.h" #include "HTMLObjectElement.h" #include "MappedAttribute.h" +#include "RenderEmbeddedObject.h" #include "RenderImage.h" -#include "RenderPartObject.h" #include "RenderWidget.h" #include "ScriptController.h" #include "Settings.h" @@ -155,7 +155,7 @@ RenderObject* HTMLEmbedElement::createRenderer(RenderArena* arena, RenderStyle*) { if (isImageType()) return new (arena) RenderImage(this); - return new (arena) RenderPartObject(this); + return new (arena) RenderEmbeddedObject(this); } void HTMLEmbedElement::attach() @@ -183,7 +183,7 @@ void HTMLEmbedElement::updateWidget() { document()->updateStyleIfNeeded(); if (m_needWidgetUpdate && renderer() && !isImageType()) - toRenderPartObject(renderer())->updateWidget(true); + toRenderEmbeddedObject(renderer())->updateWidget(true); } void HTMLEmbedElement::insertedIntoDocument() diff --git a/WebCore/html/HTMLEmbedElement.idl b/WebCore/html/HTMLEmbedElement.idl index 05c10db..d491a0d 100644 --- a/WebCore/html/HTMLEmbedElement.idl +++ b/WebCore/html/HTMLEmbedElement.idl @@ -21,13 +21,10 @@ module html { interface [ - GenerateConstructor, DelegatingPutFunction, DelegatingGetOwnPropertySlot, CustomCall, - HasOverridingNameGetter, - InterfaceUUID=18f9bd58-6bb3-4b5c-aa30-6da13adfc91e, - ImplementationUUID=93e0407a-8380-4ff0-978d-f773f2dee6a3 + HasOverridingNameGetter ] HTMLEmbedElement : HTMLElement { attribute [ConvertNullToNullString, Reflect] DOMString align; #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT @@ -44,14 +41,12 @@ module html { attribute [ConvertFromString] long width; #endif -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM #if defined(ENABLE_SVG) && ENABLE_SVG #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS [SVGCheckSecurityDocument] SVGDocument getSVGDocument() raises(DOMException); #endif #endif -#endif }; } diff --git a/WebCore/html/HTMLFieldSetElement.idl b/WebCore/html/HTMLFieldSetElement.idl index c55e604..8cffe3d 100644 --- a/WebCore/html/HTMLFieldSetElement.idl +++ b/WebCore/html/HTMLFieldSetElement.idl @@ -19,15 +19,9 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=cf9e4c4c-a1c9-4740-ad6c-6e5ea94a51a5, - ImplementationUUID=93573758-96db-415d-9bdc-ee7238604094 - ] HTMLFieldSetElement : HTMLElement { + interface HTMLFieldSetElement : HTMLElement { readonly attribute HTMLFormElement form; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM readonly attribute ValidityState validity; -#endif readonly attribute boolean willValidate; readonly attribute DOMString validationMessage; boolean checkValidity(); diff --git a/WebCore/html/HTMLFontElement.idl b/WebCore/html/HTMLFontElement.idl index cb9cbbe..fa7d908 100644 --- a/WebCore/html/HTMLFontElement.idl +++ b/WebCore/html/HTMLFontElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=f6a11dbe-7f40-49dc-a304-7997b25b2cb9, - ImplementationUUID=a37453b9-f7ba-4896-8e91-37d1ecc5b7ce - ] HTMLFontElement : HTMLElement { + interface HTMLFontElement : HTMLElement { attribute [ConvertNullToNullString] DOMString color; attribute [ConvertNullToNullString] DOMString face; attribute [ConvertNullToNullString] DOMString size; diff --git a/WebCore/html/HTMLFormCollection.cpp b/WebCore/html/HTMLFormCollection.cpp index 812d98a..602f23b 100644 --- a/WebCore/html/HTMLFormCollection.cpp +++ b/WebCore/html/HTMLFormCollection.cpp @@ -40,6 +40,7 @@ inline CollectionCache* HTMLFormCollection::formCollectionInfo(HTMLFormElement* { if (!form->collectionInfo) form->collectionInfo = new CollectionCache; + form->collectionInfo->checkConsistency(); return form->collectionInfo; } @@ -110,7 +111,8 @@ Element* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, con bool foundInputElements = false; for (unsigned i = 0; i < form->formElements.size(); ++i) { HTMLFormControlElement* e = form->formElements[i]; - if (e->isEnumeratable() && e->getAttribute(attrName) == name) { + const QualifiedName& attributeName = (attrName == idAttr) ? e->idAttributeName() : attrName; + if (e->isEnumeratable() && e->getAttribute(attributeName) == name) { foundInputElements = true; if (!duplicateNumber) return e; @@ -121,7 +123,8 @@ Element* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, con if (!foundInputElements) { for (unsigned i = 0; i < form->imgElements.size(); ++i) { HTMLImageElement* e = form->imgElements[i]; - if (e->getAttribute(attrName) == name) { + const QualifiedName& attributeName = (attrName == idAttr) ? e->idAttributeName() : attrName; + if (e->getAttribute(attributeName) == name) { if (!duplicateNumber) return e; --duplicateNumber; @@ -171,10 +174,10 @@ Node* HTMLFormCollection::nextNamedItem(const AtomicString& name) const // The nextNamedItemInternal function can return the same item twice if it has // both an id and name that are equal to the name parameter. So this function // checks if we are on the nameAttr half of the iteration and skips over any - // that also have the same idAttr. + // that also have the same idAttributeName. Element* impl = nextNamedItemInternal(name); if (m_idsDone) - while (impl && impl->getAttribute(idAttr) == name) + while (impl && impl->getAttribute(impl->idAttributeName()) == name) impl = nextNamedItemInternal(name); return impl; } @@ -191,7 +194,7 @@ void HTMLFormCollection::updateNameCache() const for (unsigned i = 0; i < f->formElements.size(); ++i) { HTMLFormControlElement* e = f->formElements[i]; if (e->isEnumeratable()) { - const AtomicString& idAttrVal = e->getAttribute(idAttr); + const AtomicString& idAttrVal = e->getAttribute(e->idAttributeName()); const AtomicString& nameAttrVal = e->getAttribute(nameAttr); if (!idAttrVal.isEmpty()) { // add to id cache @@ -218,7 +221,7 @@ void HTMLFormCollection::updateNameCache() const for (unsigned i = 0; i < f->imgElements.size(); ++i) { HTMLImageElement* e = f->imgElements[i]; - const AtomicString& idAttrVal = e->getAttribute(idAttr); + const AtomicString& idAttrVal = e->getAttribute(e->idAttributeName()); const AtomicString& nameAttrVal = e->getAttribute(nameAttr); if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl())) { // add to id cache diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp index 2531c48..eb25c40 100644 --- a/WebCore/html/HTMLFormControlElement.cpp +++ b/WebCore/html/HTMLFormControlElement.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "HTMLFormControlElement.h" +#include "Chrome.h" #include "ChromeClient.h" #include "Document.h" #include "Event.h" @@ -233,12 +234,23 @@ void HTMLFormControlElement::setRequired(bool b) setAttribute(requiredAttr, b ? "required" : 0); } +static void updateFromElementCallback(Node* node) +{ + ASSERT_ARG(node, node->isElementNode()); + ASSERT_ARG(node, static_cast<Element*>(node)->isFormControlElement()); + ASSERT(node->renderer()); + if (RenderObject* renderer = node->renderer()) + renderer->updateFromElement(); +} + void HTMLFormControlElement::recalcStyle(StyleChange change) { HTMLElement::recalcStyle(change); + // updateFromElement() can cause the selection to change, and in turn + // trigger synchronous layout, so it must not be called during style recalc. if (renderer()) - renderer()->updateFromElement(); + queuePostAttachCallback(updateFromElementCallback, this); } bool HTMLFormControlElement::supportsFocus() const diff --git a/WebCore/html/HTMLFormControlElement.h b/WebCore/html/HTMLFormControlElement.h index 7105112..358546b 100644 --- a/WebCore/html/HTMLFormControlElement.h +++ b/WebCore/html/HTMLFormControlElement.h @@ -43,7 +43,7 @@ public: virtual int tagPriority() const { return 1; } HTMLFormElement* form() const { return m_form; } - virtual ValidityState* validity(); + ValidityState* validity(); bool formNoValidate() const; void setFormNoValidate(bool); @@ -129,7 +129,7 @@ private: virtual bool isValidFormControlElement(); HTMLFormElement* m_form; - RefPtr<ValidityState> m_validityState; + OwnPtr<ValidityState> m_validityState; bool m_disabled : 1; bool m_readOnly : 1; bool m_required : 1; diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp index ace0f2f..bf25bf6 100644 --- a/WebCore/html/HTMLFormElement.cpp +++ b/WebCore/html/HTMLFormElement.cpp @@ -26,6 +26,7 @@ #include "HTMLFormElement.h" #include "CSSHelper.h" +#include "Chrome.h" #include "ChromeClient.h" #include "Document.h" #include "Event.h" @@ -302,7 +303,7 @@ bool HTMLFormElement::prepareSubmit(Event* event) m_insubmit = false; if (m_doingsubmit) - submit(event, true); + submit(event, true, false, NotSubmittedByJavaScript); return m_doingsubmit; } @@ -329,7 +330,15 @@ static void transferMailtoPostFormDataToURL(RefPtr<FormData>& data, KURL& url, c url.setQuery(query); } -void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockHistory) +void HTMLFormElement::submit(Frame* javaScriptActiveFrame) +{ + if (javaScriptActiveFrame) + submit(0, false, !javaScriptActiveFrame->script()->anyPageIsProcessingUserGesture(), SubmittedByJavaScript); + else + submit(0, false, false, NotSubmittedByJavaScript); +} + +void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockHistory, FormSubmissionTrigger formSubmissionTrigger) { FrameView* view = document()->view(); Frame* frame = document()->frame(); @@ -366,7 +375,7 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool lockH } } - RefPtr<FormState> formState = FormState::create(this, formValues, frame); + RefPtr<FormState> formState = FormState::create(this, formValues, frame, formSubmissionTrigger); if (needButtonActivation && firstSuccessfulSubmitButton) firstSuccessfulSubmitButton->setActivatedSubmit(true); diff --git a/WebCore/html/HTMLFormElement.h b/WebCore/html/HTMLFormElement.h index a2e9585..c0ce3e3 100644 --- a/WebCore/html/HTMLFormElement.h +++ b/WebCore/html/HTMLFormElement.h @@ -26,6 +26,7 @@ #include "CheckedRadioButtons.h" #include "FormDataBuilder.h" +#include "FormState.h" #include "HTMLElement.h" #include <wtf/OwnPtr.h> @@ -78,7 +79,7 @@ public: void removeImgElement(HTMLImageElement*); bool prepareSubmit(Event*); - void submit(Event* = 0, bool activateSubmitButton = false, bool lockHistory = false); + void submit(Frame* javaScriptActiveFrame = 0); void reset(); // Used to indicate a malformed state to keep from applying the bottom margin of the form. @@ -130,6 +131,8 @@ protected: virtual void didMoveToNewOwnerDocument(); private: + void submit(Event*, bool activateSubmitButton, bool lockHistory, FormSubmissionTrigger); + bool isMailtoForm() const; TextEncoding dataEncoding() const; PassRefPtr<FormData> createFormData(const CString& boundary); diff --git a/WebCore/html/HTMLFormElement.idl b/WebCore/html/HTMLFormElement.idl index 3e846d6..d639c34 100644 --- a/WebCore/html/HTMLFormElement.idl +++ b/WebCore/html/HTMLFormElement.idl @@ -22,10 +22,7 @@ module html { interface [ HasIndexGetter, - HasOverridingNameGetter, - GenerateConstructor, - InterfaceUUID=c7e79252-3b6d-4636-9efb-0667192ca5c3, - ImplementationUUID=3561288f-5f67-4c45-9290-de4191d4c9c9 + HasOverridingNameGetter ] HTMLFormElement : HTMLElement { readonly attribute HTMLCollection elements; readonly attribute long length; diff --git a/WebCore/html/HTMLFrameElement.idl b/WebCore/html/HTMLFrameElement.idl index d0076eb..453de0a 100644 --- a/WebCore/html/HTMLFrameElement.idl +++ b/WebCore/html/HTMLFrameElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=0795de43-e0cb-429e-ae0b-d38dbb641fd7, - ImplementationUUID=38c9e3c8-3384-40b6-a484-cb845c48b67d - ] HTMLFrameElement : HTMLElement { + interface HTMLFrameElement : HTMLElement { attribute [ConvertNullToNullString, Reflect=frameborder] DOMString frameBorder; attribute [ConvertNullToNullString, Reflect=longdesc] DOMString longDesc; @@ -38,7 +34,6 @@ module html { // Introduced in DOM Level 2: readonly attribute [CheckFrameSecurity] Document contentDocument; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM // Extensions readonly attribute DOMWindow contentWindow; @@ -48,7 +43,6 @@ module html { raises(DOMException); #endif #endif -#endif attribute [ConvertNullToNullString, CustomSetter] DOMString location; readonly attribute long width; diff --git a/WebCore/html/HTMLFrameElementBase.cpp b/WebCore/html/HTMLFrameElementBase.cpp index 80df829..3890850 100644 --- a/WebCore/html/HTMLFrameElementBase.cpp +++ b/WebCore/html/HTMLFrameElementBase.cpp @@ -50,8 +50,10 @@ HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Documen , m_scrolling(ScrollbarAuto) , m_marginWidth(-1) , m_marginHeight(-1) + , m_checkAttachedTimer(this, &HTMLFrameElementBase::checkAttachedTimerFired) , m_viewSource(false) , m_shouldOpenURLAfterAttach(false) + , m_remainsAliveOnRemovalFromTree(false) { } @@ -111,7 +113,7 @@ void HTMLFrameElementBase::parseMappedAttribute(MappedAttribute *attr) { if (attr->name() == srcAttr) setLocation(deprecatedParseURL(attr->value())); - else if (attr->name() == idAttr) { + else if (attr->name() == idAttributeName()) { // Important to call through to base for the id attribute so the hasID bit gets set. HTMLFrameOwnerElement::parseMappedAttribute(attr); m_frameName = attr->value(); @@ -152,7 +154,7 @@ void HTMLFrameElementBase::setNameAndOpenURL() { m_frameName = getAttribute(nameAttr); if (m_frameName.isNull()) - m_frameName = getAttribute(idAttr); + m_frameName = getAttribute(idAttributeName()); if (Frame* parentFrame = document()->frame()) m_frameName = parentFrame->tree()->uniqueChildName(m_frameName); @@ -186,9 +188,12 @@ void HTMLFrameElementBase::attach() { if (m_shouldOpenURLAfterAttach) { m_shouldOpenURLAfterAttach = false; - queuePostAttachCallback(&HTMLFrameElementBase::setNameAndOpenURLCallback, this); + if (!m_remainsAliveOnRemovalFromTree) + queuePostAttachCallback(&HTMLFrameElementBase::setNameAndOpenURLCallback, this); } + setRemainsAliveOnRemovalFromTree(false); + HTMLFrameOwnerElement::attach(); if (RenderPart* renderPart = toRenderPart(renderer())) { @@ -249,4 +254,33 @@ int HTMLFrameElementBase::height() const return toRenderBox(renderer())->height(); } +void HTMLFrameElementBase::setRemainsAliveOnRemovalFromTree(bool value) +{ + m_remainsAliveOnRemovalFromTree = value; + + // There is a possibility that JS will do document.adoptNode() on this element but will not insert it into the tree. + // Start the async timer that is normally stopped by attach(). If it's not stopped and fires, it'll unload the frame. + if (value) + m_checkAttachedTimer.startOneShot(0); + else + m_checkAttachedTimer.stop(); +} + +void HTMLFrameElementBase::checkAttachedTimerFired(Timer<HTMLFrameElementBase>*) +{ + ASSERT(!attached()); + ASSERT(m_remainsAliveOnRemovalFromTree); + + m_remainsAliveOnRemovalFromTree = false; + willRemove(); +} + +void HTMLFrameElementBase::willRemove() +{ + if (m_remainsAliveOnRemovalFromTree) + return; + + HTMLFrameOwnerElement::willRemove(); +} + } // namespace WebCore diff --git a/WebCore/html/HTMLFrameElementBase.h b/WebCore/html/HTMLFrameElementBase.h index c211ba7..ea93ae7 100644 --- a/WebCore/html/HTMLFrameElementBase.h +++ b/WebCore/html/HTMLFrameElementBase.h @@ -42,6 +42,8 @@ public: int width() const; int height() const; + void setRemainsAliveOnRemovalFromTree(bool); + protected: HTMLFrameElementBase(const QualifiedName&, Document*); @@ -62,6 +64,9 @@ private: virtual bool isURLAttribute(Attribute*) const; + virtual void willRemove(); + void checkAttachedTimerFired(Timer<HTMLFrameElementBase>*); + bool viewSourceMode() const { return m_viewSource; } void setNameAndOpenURL(); @@ -77,9 +82,13 @@ private: int m_marginWidth; int m_marginHeight; + Timer<HTMLFrameElementBase> m_checkAttachedTimer; + bool m_viewSource; bool m_shouldOpenURLAfterAttach; + + bool m_remainsAliveOnRemovalFromTree; }; } // namespace WebCore diff --git a/WebCore/html/HTMLFrameOwnerElement.cpp b/WebCore/html/HTMLFrameOwnerElement.cpp index 7598da2..c3ae785 100644 --- a/WebCore/html/HTMLFrameOwnerElement.cpp +++ b/WebCore/html/HTMLFrameOwnerElement.cpp @@ -71,7 +71,7 @@ void HTMLFrameOwnerElement::setSandboxFlags(SandboxFlags flags) return; m_sandboxFlags = flags; - + if (Frame* frame = contentFrame()) frame->loader()->ownerElementSandboxFlagsChanged(); } diff --git a/WebCore/html/HTMLFrameOwnerElement.h b/WebCore/html/HTMLFrameOwnerElement.h index 308a100..4a56e45 100644 --- a/WebCore/html/HTMLFrameOwnerElement.h +++ b/WebCore/html/HTMLFrameOwnerElement.h @@ -48,19 +48,19 @@ public: virtual ScrollbarMode scrollingMode() const { return ScrollbarAuto; } SandboxFlags sandboxFlags() const { return m_sandboxFlags; } - + protected: HTMLFrameOwnerElement(const QualifiedName& tagName, Document*); void setSandboxFlags(SandboxFlags); - + + virtual void willRemove(); + private: friend class Frame; virtual bool isFrameOwnerElement() const { return true; } virtual bool isKeyboardFocusable(KeyboardEvent*) const { return m_contentFrame; } - - virtual void willRemove(); Frame* m_contentFrame; SandboxFlags m_sandboxFlags; diff --git a/WebCore/html/HTMLFrameSetElement.idl b/WebCore/html/HTMLFrameSetElement.idl index 6ab1a8b..3a761ae 100644 --- a/WebCore/html/HTMLFrameSetElement.idl +++ b/WebCore/html/HTMLFrameSetElement.idl @@ -21,16 +21,12 @@ module html { interface [ - GenerateConstructor, - HasOverridingNameGetter, - InterfaceUUID=5038a73d-c0db-4847-acb4-4c6d31f48790, - ImplementationUUID=450f7bf6-fdc0-4a0f-b7e1-baea7f7e5732 + HasOverridingNameGetter ] HTMLFrameSetElement : HTMLElement { attribute [ConvertNullToNullString] DOMString cols; attribute [ConvertNullToNullString] DOMString rows; #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM // Event handler attributes attribute [DontEnum] EventListener onbeforeunload; attribute [DontEnum] EventListener onhashchange; @@ -55,11 +51,9 @@ module html { // Not implemented yet. // attribute [DontEnum] EventListener onafterprint; // attribute [DontEnum] EventListener onbeforeprint; - // attribute [DontEnum] EventListener onpopstate; // attribute [DontEnum] EventListener onredo; // attribute [DontEnum] EventListener onundo; #endif -#endif }; } diff --git a/WebCore/html/HTMLHRElement.idl b/WebCore/html/HTMLHRElement.idl index e49932a..bb1fdcf 100644 --- a/WebCore/html/HTMLHRElement.idl +++ b/WebCore/html/HTMLHRElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=20477b34-ab22-47e3-b9aa-80c388d32975, - ImplementationUUID=6cfc8977-172d-48f6-8f08-c7671f02354c - ] HTMLHRElement : HTMLElement { + interface HTMLHRElement : HTMLElement { attribute [ConvertNullToNullString] DOMString align; attribute boolean noShade; attribute [ConvertNullToNullString] DOMString size; diff --git a/WebCore/html/HTMLHeadElement.idl b/WebCore/html/HTMLHeadElement.idl index 82ff796..8559dd3 100644 --- a/WebCore/html/HTMLHeadElement.idl +++ b/WebCore/html/HTMLHeadElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=47e0c1a2-39ca-4be8-a4ef-38af06462d2e, - ImplementationUUID=f56408fe-6987-4ece-b925-599f517bde50 - ] HTMLHeadElement : HTMLElement { + interface HTMLHeadElement : HTMLElement { attribute [ConvertNullToNullString] DOMString profile; }; diff --git a/WebCore/html/HTMLHeadingElement.idl b/WebCore/html/HTMLHeadingElement.idl index 7173252..486a5bd 100644 --- a/WebCore/html/HTMLHeadingElement.idl +++ b/WebCore/html/HTMLHeadingElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=91c029bb-aa3a-4877-8ab5-59f304525fd5, - ImplementationUUID=ab39e189-5d0c-465d-b518-f57bc920038b - ] HTMLHeadingElement : HTMLElement { + interface HTMLHeadingElement : HTMLElement { attribute [ConvertNullToNullString] DOMString align; }; diff --git a/WebCore/html/HTMLHtmlElement.idl b/WebCore/html/HTMLHtmlElement.idl index e9709bf..9cee000 100644 --- a/WebCore/html/HTMLHtmlElement.idl +++ b/WebCore/html/HTMLHtmlElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=162828a5-d4d9-4973-b5ca-00ccbb26ded9, - ImplementationUUID=362f4f5f-99c5-4bbf-91ba-9ae7f9a7b297 - ] HTMLHtmlElement : HTMLElement { + interface HTMLHtmlElement : HTMLElement { attribute [ConvertNullToNullString] DOMString version; diff --git a/WebCore/html/HTMLIFrameElement.cpp b/WebCore/html/HTMLIFrameElement.cpp index a2f287e..359bdb7 100644 --- a/WebCore/html/HTMLIFrameElement.cpp +++ b/WebCore/html/HTMLIFrameElement.cpp @@ -155,14 +155,6 @@ void HTMLIFrameElement::removedFromDocument() HTMLFrameElementBase::removedFromDocument(); } -void HTMLIFrameElement::attach() -{ - HTMLFrameElementBase::attach(); - - if (RenderPartObject* renderPartObject = toRenderPartObject(renderer())) - renderPartObject->updateWidget(false); -} - bool HTMLIFrameElement::isURLAttribute(Attribute* attr) const { return attr->name() == srcAttr; diff --git a/WebCore/html/HTMLIFrameElement.h b/WebCore/html/HTMLIFrameElement.h index f1c6a35..c708456 100644 --- a/WebCore/html/HTMLIFrameElement.h +++ b/WebCore/html/HTMLIFrameElement.h @@ -44,8 +44,6 @@ private: virtual void insertedIntoDocument(); virtual void removedFromDocument(); - virtual void attach(); - virtual bool rendererIsNeeded(RenderStyle*); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); diff --git a/WebCore/html/HTMLIFrameElement.idl b/WebCore/html/HTMLIFrameElement.idl index dad8416..e1aed03 100644 --- a/WebCore/html/HTMLIFrameElement.idl +++ b/WebCore/html/HTMLIFrameElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=32265f2e-79b1-4e4e-b0d1-86b050298883, - ImplementationUUID=370c6318-f804-49f9-bc8a-46b99cd87399 - ] HTMLIFrameElement : HTMLElement { + interface HTMLIFrameElement : HTMLElement { attribute [ConvertNullToNullString, Reflect] DOMString align; attribute [ConvertNullToNullString, Reflect=frameborder] DOMString frameBorder; @@ -41,7 +37,6 @@ module html { // Introduced in DOM Level 2: readonly attribute [CheckFrameSecurity] Document contentDocument; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM // Extensions readonly attribute DOMWindow contentWindow; @@ -51,7 +46,6 @@ module html { raises(DOMException); #endif #endif -#endif }; diff --git a/WebCore/html/HTMLImageElement.cpp b/WebCore/html/HTMLImageElement.cpp index d353073..34646ad 100644 --- a/WebCore/html/HTMLImageElement.cpp +++ b/WebCore/html/HTMLImageElement.cpp @@ -54,8 +54,6 @@ HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* doc, HTMLImageElement::~HTMLImageElement() { - if (m_form) - m_form->removeImgElement(this); } bool HTMLImageElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const @@ -131,7 +129,7 @@ void HTMLImageElement::parseMappedAttribute(MappedAttribute* attr) document->addNamedItem(newName); } m_name = newName; - } else if (attr->name() == idAttr) { + } else if (attr->name() == idAttributeName()) { const AtomicString& newId = attr->value(); if (inDocument() && document()->isHTMLDocument()) { HTMLDocument* document = static_cast<HTMLDocument*>(this->document()); @@ -209,6 +207,30 @@ void HTMLImageElement::removedFromDocument() HTMLElement::removedFromDocument(); } +void HTMLImageElement::insertedIntoTree(bool deep) +{ + if (!m_form) { + // m_form can be non-null if it was set in constructor. + for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { + if (ancestor->hasTagName(formTag)) { + m_form = static_cast<HTMLFormElement*>(ancestor); + m_form->registerImgElement(this); + break; + } + } + } + + HTMLElement::insertedIntoTree(deep); +} + +void HTMLImageElement::removedFromTree(bool deep) +{ + if (m_form) + m_form->removeImgElement(this); + m_form = 0; + HTMLElement::removedFromTree(deep); +} + int HTMLImageElement::width(bool ignorePendingStylesheets) const { if (!renderer()) { diff --git a/WebCore/html/HTMLImageElement.h b/WebCore/html/HTMLImageElement.h index f58574d..14e5fa3 100644 --- a/WebCore/html/HTMLImageElement.h +++ b/WebCore/html/HTMLImageElement.h @@ -45,8 +45,6 @@ public: virtual void attach(); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - virtual void insertedIntoDocument(); - virtual void removedFromDocument(); virtual bool canStartSelection() const { return false; } @@ -105,6 +103,11 @@ public: virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const; private: + virtual void insertedIntoDocument(); + virtual void removedFromDocument(); + virtual void insertedIntoTree(bool deep); + virtual void removedFromTree(bool deep); + HTMLImageLoader m_imageLoader; String usemap; bool ismap; diff --git a/WebCore/html/HTMLImageElement.idl b/WebCore/html/HTMLImageElement.idl index a90ae25..3862539 100644 --- a/WebCore/html/HTMLImageElement.idl +++ b/WebCore/html/HTMLImageElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=b21b8125-d00b-4bdf-b0e8-659678db3923, - ImplementationUUID=2121ca21-8118-4f1b-b9fe-4788a9050281 - ] HTMLImageElement : HTMLElement { + interface HTMLImageElement : HTMLElement { attribute [ConvertNullToNullString, Reflect] DOMString name; attribute [ConvertNullToNullString, Reflect] DOMString align; attribute [ConvertNullToNullString, Reflect] DOMString alt; diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp index acfe51f..5567fe2 100644 --- a/WebCore/html/HTMLInputElement.cpp +++ b/WebCore/html/HTMLInputElement.cpp @@ -29,6 +29,7 @@ #include "AXObjectCache.h" #include "CSSPropertyNames.h" #include "ChromeClient.h" +#include "DateComponents.h" #include "Document.h" #include "Editor.h" #include "Event.h" @@ -45,7 +46,6 @@ #include "HTMLImageLoader.h" #include "HTMLNames.h" #include "HTMLOptionElement.h" -#include "ISODateTime.h" #include "ScriptEventListener.h" #include "KeyboardEvent.h" #include "LocalizedStrings.h" @@ -82,9 +82,11 @@ const int maxSavedResults = 256; static const double numberDefaultStep = 1.0; static const double numberStepScaleFactor = 1.0; // Constant values for minimum(). +static const double dateDefaultMinimum = -12219292800000.0; // This means 1582-10-15T00:00Z. static const double numberDefaultMinimum = -DBL_MAX; static const double rangeDefaultMinimum = 0.0; // Constant values for maximum(). +static const double dateDefaultMaximum = DBL_MAX; static const double numberDefaultMaximum = DBL_MAX; static const double rangeDefaultMaximum = 100.0; @@ -269,46 +271,153 @@ bool HTMLInputElement::tooLong() const bool HTMLInputElement::rangeUnderflow() const { - if (inputType() == NUMBER || inputType() == RANGE) { - double doubleValue; - if (formStringToDouble(value(), &doubleValue)) - return doubleValue < minimum(); + const double nan = numeric_limits<double>::quiet_NaN(); + switch (inputType()) { + case DATE: + case NUMBER: + case RANGE: { + double doubleValue = parseToDouble(value(), nan); + return isfinite(doubleValue) && doubleValue < minimum(); + } + case BUTTON: + case CHECKBOX: + case COLOR: + case DATETIME: + case DATETIMELOCAL: + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case MONTH: + case PASSWORD: + case RADIO: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case TIME: + case URL: + case WEEK: + break; } return false; } bool HTMLInputElement::rangeOverflow() const { - if (inputType() == NUMBER || inputType() == RANGE) { - double doubleValue; - if (formStringToDouble(value(), &doubleValue)) - return doubleValue > maximum(); + const double nan = numeric_limits<double>::quiet_NaN(); + switch (inputType()) { + case DATE: + case NUMBER: + case RANGE: { + double doubleValue = parseToDouble(value(), nan); + return isfinite(doubleValue) && doubleValue > maximum(); + } + case BUTTON: + case CHECKBOX: + case COLOR: + case DATETIME: + case DATETIMELOCAL: + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case MONTH: + case PASSWORD: + case RADIO: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case TIME: + case URL: + case WEEK: + break; } return false; } double HTMLInputElement::minimum() const { - ASSERT(inputType() == NUMBER || inputType() == RANGE); - double min = inputType() == RANGE ? rangeDefaultMinimum : numberDefaultMinimum; - formStringToDouble(getAttribute(minAttr), &min); - return min; + switch (inputType()) { + case DATE: + return parseToDouble(getAttribute(minAttr), dateDefaultMinimum); + case NUMBER: + return parseToDouble(getAttribute(minAttr), numberDefaultMinimum); + case RANGE: + return parseToDouble(getAttribute(minAttr), rangeDefaultMinimum); + case BUTTON: + case CHECKBOX: + case COLOR: + case DATETIME: + case DATETIMELOCAL: + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case MONTH: + case PASSWORD: + case RADIO: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case TIME: + case URL: + case WEEK: + break; + } + ASSERT_NOT_REACHED(); + return 0; } double HTMLInputElement::maximum() const { - ASSERT(inputType() == NUMBER || inputType() == RANGE); - double defaultMaximum = inputType() == RANGE ? rangeDefaultMaximum : numberDefaultMaximum; - double max = defaultMaximum; - formStringToDouble(getAttribute(maxAttr), &max); - if (inputType() == RANGE) { + switch (inputType()) { + case DATE: + return parseToDouble(getAttribute(maxAttr), dateDefaultMaximum); + case NUMBER: + return parseToDouble(getAttribute(maxAttr), numberDefaultMaximum); + case RANGE: { + double max = parseToDouble(getAttribute(maxAttr), rangeDefaultMaximum); // A remedy for the inconsistent min/max values for RANGE. - // Sets the maxmimum to the default or the minimum value. + // Sets the maximum to the default or the minimum value. double min = minimum(); if (max < min) - max = std::max(min, defaultMaximum); + max = std::max(min, rangeDefaultMaximum); + return max; + } + case BUTTON: + case CHECKBOX: + case COLOR: + case DATETIME: + case DATETIMELOCAL: + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case MONTH: + case PASSWORD: + case RADIO: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case TIME: + case URL: + case WEEK: + break; } - return max; + ASSERT_NOT_REACHED(); + return 0; } double HTMLInputElement::stepBase() const @@ -1320,6 +1429,23 @@ void HTMLInputElement::setValueForUser(const String& value) setValue(value, true); } +const String& HTMLInputElement::suggestedValue() const +{ + return m_data.suggestedValue(); +} + +void HTMLInputElement::setSuggestedValue(const String& value) +{ + if (inputType() != TEXT) + return; + setFormControlValueMatchesRenderer(false); + m_data.setSuggestedValue(sanitizeValue(value)); + updatePlaceholderVisibility(false); + if (renderer()) + renderer()->updateFromElement(); + setNeedsStyleRecalc(); +} + void HTMLInputElement::setValue(const String& value, bool sendChangeEvent) { // For security reasons, we don't allow setting the filename, but we do allow clearing it. @@ -1356,6 +1482,7 @@ void HTMLInputElement::setValue(const String& value, bool sendChangeEvent) InputElement::updateSelectionRange(this, this, max, max); else cacheSelection(max, max); + m_data.setSuggestedValue(String()); } // Don't dispatch the change event when focused, it will be dispatched @@ -1367,6 +1494,255 @@ void HTMLInputElement::setValue(const String& value, bool sendChangeEvent) updateValidity(); } +double HTMLInputElement::parseToDouble(const String& src, double defaultValue) const +{ + switch (inputType()) { + case DATE: + case DATETIME: + case DATETIMELOCAL: + case TIME: + case WEEK: { + DateComponents date; + if (!formStringToDateComponents(inputType(), src, &date)) + return defaultValue; + double msec = date.millisecondsSinceEpoch(); + ASSERT(isfinite(msec)); + return msec; + } + case MONTH: { + DateComponents date; + if (!formStringToDateComponents(inputType(), src, &date)) + return defaultValue; + double months = date.monthsSinceEpoch(); + ASSERT(isfinite(months)); + return months; + } + case NUMBER: + case RANGE: { + double numberValue; + if (!formStringToDouble(src, &numberValue)) + return defaultValue; + ASSERT(isfinite(numberValue)); + return numberValue; + } + + case BUTTON: + case CHECKBOX: + case COLOR: + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case PASSWORD: + case RADIO: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case URL: + return defaultValue; + } + ASSERT_NOT_REACHED(); + return defaultValue; +} + +double HTMLInputElement::valueAsDate() const +{ + switch (inputType()) { + case DATE: + case DATETIME: + case TIME: + case WEEK: + return parseToDouble(value(), DateComponents::invalidMilliseconds()); + case MONTH: { + DateComponents date; + if (!formStringToDateComponents(inputType(), value(), &date)) + return DateComponents::invalidMilliseconds(); + double msec = date.millisecondsSinceEpoch(); + ASSERT(isfinite(msec)); + return msec; + } + + case BUTTON: + case CHECKBOX: + case COLOR: + case DATETIMELOCAL: // valueAsDate doesn't work for the DATETIMELOCAL type according to the standard. + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case NUMBER: + case PASSWORD: + case RADIO: + case RANGE: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case URL: + return DateComponents::invalidMilliseconds(); + } + ASSERT_NOT_REACHED(); + return DateComponents::invalidMilliseconds(); +} + +void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec) +{ + DateComponents date; + bool success; + switch (inputType()) { + case DATE: + success = date.setMillisecondsSinceEpochForDate(value); + break; + case DATETIME: + success = date.setMillisecondsSinceEpochForDateTime(value); + break; + case MONTH: + success = date.setMillisecondsSinceEpochForMonth(value); + break; + case TIME: + success = date.setMillisecondsSinceMidnight(value); + break; + case WEEK: + success = date.setMillisecondsSinceEpochForWeek(value); + break; + case BUTTON: + case CHECKBOX: + case COLOR: + case DATETIMELOCAL: // valueAsDate doesn't work for the DATETIMELOCAL type according to the standard. + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case NUMBER: + case PASSWORD: + case RADIO: + case RANGE: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case URL: + ec = INVALID_STATE_ERR; + return; + default: + ASSERT_NOT_REACHED(); + success = false; + } + if (!success) { + setValue(String()); + return; + } + // FIXME: We should specify SecondFormat. + // e.g. If the step value is 60, use SecondFormat::None. + // If the step value is 1, use SecondFormat::Second. + setValue(date.toString()); +} + +double HTMLInputElement::valueAsNumber() const +{ + const double nan = numeric_limits<double>::quiet_NaN(); + switch (inputType()) { + case DATE: + case DATETIME: + case DATETIMELOCAL: + case MONTH: + case NUMBER: + case RANGE: + case TIME: + case WEEK: + return parseToDouble(value(), nan); + + case BUTTON: + case CHECKBOX: + case COLOR: + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case PASSWORD: + case RADIO: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case URL: + return nan; + } + ASSERT_NOT_REACHED(); + return nan; +} + +void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec) +{ + if (!isfinite(newValue)) { + ec = NOT_SUPPORTED_ERR; + return; + } + switch (inputType()) { + case DATE: + case DATETIME: + case TIME: + case WEEK: + setValueAsDate(newValue, ec); + return; + case MONTH: { + DateComponents date; + if (!date.setMonthsSinceEpoch(newValue)) { + setValue(String()); + return; + } + setValue(date.toString()); + return; + } + case DATETIMELOCAL: { + DateComponents date; + if (!date.setMillisecondsSinceEpochForDateTimeLocal(newValue)) { + setValue(String()); + return; + } + // FIXME: We should specify SecondFormat. + // e.g. If the step value is 60, use SecondFormat::None. + // If the step value is 1, use SecondFormat::Second. + setValue(date.toString()); + return; + } + case NUMBER: + case RANGE: + setValue(formStringFromDouble(newValue)); + return; + + case BUTTON: + case CHECKBOX: + case COLOR: + case EMAIL: + case FILE: + case HIDDEN: + case IMAGE: + case ISINDEX: + case PASSWORD: + case RADIO: + case RESET: + case SEARCH: + case SUBMIT: + case TELEPHONE: + case TEXT: + case URL: + ec = INVALID_STATE_ERR; + return; + } + ASSERT_NOT_REACHED(); + return; +} + String HTMLInputElement::placeholder() const { return getAttribute(placeholderAttr).string(); @@ -1386,6 +1762,7 @@ void HTMLInputElement::setValueFromRenderer(const String& value) { // File upload controls will always use setFileListFromRenderer. ASSERT(inputType() != FILE); + m_data.setSuggestedValue(String()); updatePlaceholderVisibility(false); InputElement::setValueFromRenderer(m_data, this, this, value); updateValidity(); @@ -2095,16 +2472,21 @@ bool HTMLInputElement::formStringToDouble(const String& src, double* out) if (!valid) return false; // NaN and Infinity are not valid numbers according to the standard. - if (isnan(value) || isinf(value)) + if (!isfinite(value)) return false; + // -0 -> 0 + if (!value) + value = 0; if (out) *out = value; return true; } -bool HTMLInputElement::formStringToISODateTime(InputType type, const String& formString, ISODateTime* out) +bool HTMLInputElement::formStringToDateComponents(InputType type, const String& formString, DateComponents* out) { - ISODateTime ignoredResult; + if (formString.isEmpty()) + return false; + DateComponents ignoredResult; if (!out) out = &ignoredResult; const UChar* characters = formString.characters(); diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h index 8f00aeb..f35a1b1 100644 --- a/WebCore/html/HTMLInputElement.h +++ b/WebCore/html/HTMLInputElement.h @@ -30,11 +30,11 @@ namespace WebCore { +class DateComponents; class FileList; class HTMLDataListElement; class HTMLImageLoader; class HTMLOptionElement; -class ISODateTime; class KURL; class VisibleSelection; @@ -106,9 +106,9 @@ public: // For ValidityState bool rangeUnderflow() const; bool rangeOverflow() const; - // Returns the minimum value for type=number or range. Don't call this for other types. + // Returns the minimum value for type=date, number, or range. Don't call this for other types. double minimum() const; - // Returns the maximum value for type=number or range. Don't call this for other types. + // Returns the maximum value for type=date, number, or range. Don't call this for other types. // This always returns a value which is >= minimum(). double maximum() const; // Sets the "allowed value step" defined in the HTML spec to the specified double pointer. @@ -137,10 +137,19 @@ public: virtual const AtomicString& formControlType() const; void setType(const String&); + virtual const String& suggestedValue() const; + void setSuggestedValue(const String&); + virtual String value() const; virtual void setValue(const String&, bool sendChangeEvent = false); virtual void setValueForUser(const String&); + double valueAsDate() const; + void setValueAsDate(double, ExceptionCode&); + + double valueAsNumber() const; + void setValueAsNumber(double, ExceptionCode&); + virtual String placeholder() const; virtual void setPlaceholder(const String&); @@ -258,9 +267,9 @@ public: // HTML5's "algorithm to convert a number to a string" for NUMBER/RANGE types. static String formStringFromDouble(double); // Parses the specified string as the InputType, and returns true if it is successfully parsed. - // An instance pointed by the ISODateTime* parameter will have parsed values and be - // modified even if the parsing fails. The ISODateTime* parameter may be 0. - static bool formStringToISODateTime(InputType, const String&, ISODateTime*); + // An instance pointed by the DateComponents* parameter will have parsed values and be + // modified even if the parsing fails. The DateComponents* parameter may be 0. + static bool formStringToDateComponents(InputType, const String&, DateComponents*); protected: virtual void willMoveToNewOwnerDocument(); @@ -291,6 +300,12 @@ private: // Helper for applyStepForNumberOrRange(). double stepBase() const; + // Parses the specified string for the current type, and return + // the double value for the parsing result if the parsing + // succeeds; Returns defaultValue otherwise. This function can + // return NaN or Infinity only if defaultValue is NaN or Infinity. + double parseToDouble(const String&, double defaultValue) const; + #if ENABLE(DATALIST) HTMLDataListElement* dataList() const; #endif diff --git a/WebCore/html/HTMLInputElement.idl b/WebCore/html/HTMLInputElement.idl index 2ac6674..4563120 100644 --- a/WebCore/html/HTMLInputElement.idl +++ b/WebCore/html/HTMLInputElement.idl @@ -20,18 +20,12 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=8f388ea3-1c31-4cca-8edd-449d14e222e1, - ImplementationUUID=aeb56b87-a90e-4d9d-a4d5-7eec3687c338 - ] HTMLInputElement : HTMLElement { + interface HTMLInputElement : HTMLElement { attribute [ConvertNullToNullString] DOMString defaultValue; attribute boolean defaultChecked; readonly attribute HTMLFormElement form; attribute boolean formNoValidate; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM readonly attribute ValidityState validity; -#endif attribute [ConvertNullToNullString] DOMString accept; attribute [ConvertNullToNullString] DOMString accessKey; attribute [ConvertNullToNullString] DOMString align; @@ -42,14 +36,10 @@ module html { #if defined(ENABLE_DATALIST) && ENABLE_DATALIST readonly attribute HTMLElement list; #endif -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM attribute [ConvertNullToNullString, Reflect] DOMString max; -#endif attribute long maxLength setter raises(DOMException); -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM attribute [ConvertNullToNullString, Reflect] DOMString min; -#endif attribute boolean multiple; attribute [ConvertNullToNullString] DOMString name; attribute [ConvertNullToNullString, Reflect] DOMString pattern; @@ -67,6 +57,8 @@ module html { attribute [ConvertNullToNullString, JSCCustomGetter] DOMString type; // readonly dropped as part of DOM level 2 attribute [ConvertNullToNullString] DOMString useMap; attribute [ConvertNullToNullString] DOMString value; + attribute Date valueAsDate setter raises(DOMException); + attribute double valueAsNumber setter raises(DOMException); #if defined(ENABLE_DATALIST) && ENABLE_DATALIST readonly attribute HTMLOptionElement selectedOption; #endif @@ -102,9 +94,7 @@ module html { readonly attribute URL absoluteImageURL; #endif -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM readonly attribute FileList files; -#endif }; } diff --git a/WebCore/html/HTMLIsIndexElement.idl b/WebCore/html/HTMLIsIndexElement.idl index 1e978b2..d968fa7 100644 --- a/WebCore/html/HTMLIsIndexElement.idl +++ b/WebCore/html/HTMLIsIndexElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=94fc4e39-4d81-44e3-a37d-364553b23a37, - ImplementationUUID=b31d409b-8f68-495d-a0c2-b81520716974 - ] HTMLIsIndexElement : HTMLInputElement { + interface HTMLIsIndexElement : HTMLInputElement { readonly attribute HTMLFormElement form; attribute [ConvertNullToNullString] DOMString prompt; }; diff --git a/WebCore/html/HTMLLIElement.idl b/WebCore/html/HTMLLIElement.idl index 015454e..946ec18 100644 --- a/WebCore/html/HTMLLIElement.idl +++ b/WebCore/html/HTMLLIElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=83a4a75c-4427-4f53-b974-8107fedb4c2b, - ImplementationUUID=5747808d-8cbd-49c9-b89b-3fdc315c55fe - ] HTMLLIElement : HTMLElement { + interface HTMLLIElement : HTMLElement { attribute [ConvertNullToNullString] DOMString type; attribute long value; }; diff --git a/WebCore/html/HTMLLabelElement.idl b/WebCore/html/HTMLLabelElement.idl index 85b7ef3..3b25fa9 100644 --- a/WebCore/html/HTMLLabelElement.idl +++ b/WebCore/html/HTMLLabelElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=9978d8e6-1d27-4390-bd2f-56f0e72f16e3, - ImplementationUUID=165b7633-0377-4853-a647-2b9005f5aaec - ] HTMLLabelElement : HTMLElement { + interface HTMLLabelElement : HTMLElement { readonly attribute HTMLFormElement form; attribute [ConvertNullToNullString] DOMString accessKey; attribute [ConvertNullToNullString] DOMString htmlFor; diff --git a/WebCore/html/HTMLLegendElement.idl b/WebCore/html/HTMLLegendElement.idl index da00cc1..ee21e4c 100644 --- a/WebCore/html/HTMLLegendElement.idl +++ b/WebCore/html/HTMLLegendElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=a6eb4254-6066-465a-a1c0-b4732281c255, - ImplementationUUID=323e883c-edf8-4b13-a165-8604f4f06ae2 - ] HTMLLegendElement : HTMLElement { + interface HTMLLegendElement : HTMLElement { readonly attribute HTMLFormElement form; attribute [ConvertNullToNullString] DOMString accessKey; attribute [ConvertNullToNullString] DOMString align; diff --git a/WebCore/html/HTMLLinkElement.cpp b/WebCore/html/HTMLLinkElement.cpp index ab06544..5376611 100644 --- a/WebCore/html/HTMLLinkElement.cpp +++ b/WebCore/html/HTMLLinkElement.cpp @@ -40,6 +40,7 @@ #include "Page.h" #include "ScriptEventListener.h" #include "Settings.h" +#include <wtf/StdLibExtras.h> namespace WebCore { @@ -283,28 +284,50 @@ void HTMLLinkElement::finishParsingChildren() HTMLElement::finishParsingChildren(); } -void HTMLLinkElement::setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet* sheet) +void HTMLLinkElement::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet) { - m_sheet = CSSStyleSheet::create(this, url, charset); + m_sheet = CSSStyleSheet::create(this, href, baseURL, charset); bool strictParsing = !document()->inCompatMode(); bool enforceMIMEType = strictParsing; + bool crossOriginCSS = false; + bool validMIMEType = false; + bool needsSiteSpecificQuirks = document()->page() && document()->page()->settings()->needsSiteSpecificQuirks(); // Check to see if we should enforce the MIME type of the CSS resource in strict mode. // Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748> if (enforceMIMEType && document()->page() && !document()->page()->settings()->enforceCSSMIMETypeInStrictMode()) enforceMIMEType = false; - String sheetText = sheet->sheetText(enforceMIMEType); +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + if (enforceMIMEType && needsSiteSpecificQuirks) { + // Covers both http and https, with or without "www." + if (baseURL.string().contains("mcafee.com/japan/", false)) + enforceMIMEType = false; + } +#endif + + String sheetText = sheet->sheetText(enforceMIMEType, &validMIMEType); m_sheet->parseString(sheetText, strictParsing); - if (strictParsing && document()->settings() && document()->settings()->needsSiteSpecificQuirks()) { + // If we're loading a stylesheet cross-origin, and the MIME type is not + // standard, require the CSS to at least start with a syntactically + // valid CSS rule. + // This prevents an attacker playing games by injecting CSS strings into + // HTML, XML, JSON, etc. etc. + if (!document()->securityOrigin()->canRequest(baseURL)) + crossOriginCSS = true; + + if (crossOriginCSS && !validMIMEType && !m_sheet->hasSyntacticallyValidCSSHeader()) + m_sheet = CSSStyleSheet::create(this, href, baseURL, charset); + + if (strictParsing && needsSiteSpecificQuirks) { // Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>. DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css")); DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n")); // There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet, // while the other lacks the second trailing newline. - if (url.endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText) + if (baseURL.string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText) && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) { ASSERT(m_sheet->length() == 1); ExceptionCode ec; diff --git a/WebCore/html/HTMLLinkElement.h b/WebCore/html/HTMLLinkElement.h index e1b5171..324c244 100644 --- a/WebCore/html/HTMLLinkElement.h +++ b/WebCore/html/HTMLLinkElement.h @@ -79,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& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet); bool isLoading() const; virtual bool sheetLoaded(); diff --git a/WebCore/html/HTMLLinkElement.idl b/WebCore/html/HTMLLinkElement.idl index 98de809..dc700df 100644 --- a/WebCore/html/HTMLLinkElement.idl +++ b/WebCore/html/HTMLLinkElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=a9e9ef29-f20b-429d-848e-e5dadd32694a, - ImplementationUUID=2d9b944e-88e3-451a-8640-06c593c339a8 - ] HTMLLinkElement : HTMLElement { + interface HTMLLinkElement : HTMLElement { attribute boolean disabled; attribute [ConvertNullToNullString] DOMString charset; attribute [ConvertNullToNullString] DOMString href; @@ -35,10 +31,8 @@ module html { attribute [ConvertNullToNullString] DOMString target; attribute [ConvertNullToNullString] DOMString type; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM // DOM Level 2 Style readonly attribute StyleSheet sheet; -#endif #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C // Objective-C extension: diff --git a/WebCore/html/HTMLMapElement.cpp b/WebCore/html/HTMLMapElement.cpp index 90204e0..9617afc 100644 --- a/WebCore/html/HTMLMapElement.cpp +++ b/WebCore/html/HTMLMapElement.cpp @@ -25,10 +25,12 @@ #include "Document.h" #include "HTMLAreaElement.h" #include "HTMLCollection.h" +#include "HTMLImageElement.h" #include "HTMLNames.h" #include "HitTestResult.h" #include "IntSize.h" #include "MappedAttribute.h" +#include "RenderObject.h" using namespace std; @@ -75,12 +77,30 @@ bool HTMLMapElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestRes return defaultArea; } +HTMLImageElement* HTMLMapElement::imageElement() const +{ + RefPtr<HTMLCollection> coll = renderer()->document()->images(); + for (Node* curr = coll->firstItem(); curr; curr = coll->nextItem()) { + if (!curr->hasTagName(imgTag)) + continue; + + // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning, + // which has to be stripped off. + HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(curr); + String useMapName = imageElement->getAttribute(usemapAttr).string().substring(1); + if (equalIgnoringCase(useMapName, m_name)) + return imageElement; + } + + return 0; +} + void HTMLMapElement::parseMappedAttribute(MappedAttribute* attr) { const QualifiedName& attrName = attr->name(); - if (attrName == idAttr || attrName == nameAttr) { + if (attrName == idAttributeName() || attrName == nameAttr) { Document* doc = document(); - if (attrName == idAttr) { + if (attrName == idAttributeName()) { // Call base class so that hasID bit gets set. HTMLElement::parseMappedAttribute(attr); if (doc->isHTMLDocument()) diff --git a/WebCore/html/HTMLMapElement.h b/WebCore/html/HTMLMapElement.h index 2a6eb8d..f40e78e 100644 --- a/WebCore/html/HTMLMapElement.h +++ b/WebCore/html/HTMLMapElement.h @@ -29,7 +29,8 @@ namespace WebCore { class IntSize; class HitTestResult; - +class HTMLImageElement; + class HTMLMapElement : public HTMLElement { public: HTMLMapElement(const QualifiedName&, Document*); @@ -44,7 +45,8 @@ public: virtual void parseMappedAttribute(MappedAttribute*); bool mapMouseEvent(int x, int y, const IntSize&, HitTestResult&); - + + HTMLImageElement* imageElement() const; PassRefPtr<HTMLCollection> areas(); String name() const; diff --git a/WebCore/html/HTMLMapElement.idl b/WebCore/html/HTMLMapElement.idl index 9d5db47..1a760d1 100644 --- a/WebCore/html/HTMLMapElement.idl +++ b/WebCore/html/HTMLMapElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=8a660b48-4beb-4f9e-855b-e04131eb2519, - ImplementationUUID=7ad57e02-91e5-4761-a1ca-e967188e5e0d - ] HTMLMapElement : HTMLElement { + interface HTMLMapElement : HTMLElement { readonly attribute HTMLCollection areas; attribute [ConvertNullToNullString] DOMString name; }; diff --git a/WebCore/html/HTMLMarqueeElement.cpp b/WebCore/html/HTMLMarqueeElement.cpp index 0cb6501..7c16f16 100644 --- a/WebCore/html/HTMLMarqueeElement.cpp +++ b/WebCore/html/HTMLMarqueeElement.cpp @@ -112,14 +112,14 @@ void HTMLMarqueeElement::parseMappedAttribute(MappedAttribute *attr) void HTMLMarqueeElement::start() { - if (renderer() && renderer()->hasLayer() && renderBox()->layer()->marquee()) - renderBox()->layer()->marquee()->start(); + if (RenderMarquee* marqueeRenderer = renderMarquee()) + marqueeRenderer->start(); } void HTMLMarqueeElement::stop() { - if (renderer() && renderer()->hasLayer() && renderBox()->layer()->marquee()) - renderBox()->layer()->marquee()->stop(); + if (RenderMarquee* marqueeRenderer = renderMarquee()) + marqueeRenderer->stop(); } bool HTMLMarqueeElement::canSuspend() const @@ -129,14 +129,21 @@ bool HTMLMarqueeElement::canSuspend() const void HTMLMarqueeElement::suspend() { - if (renderer() && renderer()->hasLayer() && renderBox()->layer()->marquee()) - renderBox()->layer()->marquee()->suspend(); + if (RenderMarquee* marqueeRenderer = renderMarquee()) + marqueeRenderer->suspend(); } - + void HTMLMarqueeElement::resume() { - if (renderer() && renderer()->hasLayer() && renderBox()->layer()->marquee()) - renderBox()->layer()->marquee()->updateMarqueePosition(); + if (RenderMarquee* marqueeRenderer = renderMarquee()) + marqueeRenderer->updateMarqueePosition(); +} + +RenderMarquee* HTMLMarqueeElement::renderMarquee() const +{ + if (renderer() && renderer()->hasLayer()) + return renderBoxModelObject()->layer()->marquee(); + return 0; } } // namespace WebCore diff --git a/WebCore/html/HTMLMarqueeElement.h b/WebCore/html/HTMLMarqueeElement.h index 2423fc6..9100e8f 100644 --- a/WebCore/html/HTMLMarqueeElement.h +++ b/WebCore/html/HTMLMarqueeElement.h @@ -28,6 +28,8 @@ namespace WebCore { +class RenderMarquee; + class HTMLMarqueeElement : public HTMLElement, private ActiveDOMObject { public: HTMLMarqueeElement(const QualifiedName&, Document*); @@ -51,6 +53,8 @@ private: virtual void suspend(); virtual void resume(); + RenderMarquee* renderMarquee() const; + int m_minimumDelay; }; diff --git a/WebCore/html/HTMLMarqueeElement.idl b/WebCore/html/HTMLMarqueeElement.idl index eca53db..3659f81 100644 --- a/WebCore/html/HTMLMarqueeElement.idl +++ b/WebCore/html/HTMLMarqueeElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=100ca673-eb1e-40b6-8cba-a15abc4cd590, - ImplementationUUID=b9427505-1f10-4299-8b85-4e2891428988 - ] HTMLMarqueeElement : HTMLElement { + interface HTMLMarqueeElement : HTMLElement { void start(); void stop(); diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp index 30f762a..5cd0157 100644 --- a/WebCore/html/HTMLMediaElement.cpp +++ b/WebCore/html/HTMLMediaElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,9 +28,10 @@ #if ENABLE(VIDEO) #include "HTMLMediaElement.h" +#include "Chrome.h" +#include "ChromeClient.h" #include "ClientRect.h" #include "ClientRectList.h" -#include "ChromeClient.h" #include "CSSHelper.h" #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" @@ -55,7 +56,6 @@ #include "MediaPlayer.h" #include "MediaQueryEvaluator.h" #include "Page.h" -#include "ProgressEvent.h" #include "RenderVideo.h" #include "RenderView.h" #include "ScriptEventListener.h" @@ -132,6 +132,21 @@ HTMLMediaElement::~HTMLMediaElement() document()->unregisterForMediaVolumeCallbacks(this); } +void HTMLMediaElement::willMoveToNewOwnerDocument() +{ + document()->unregisterForDocumentActivationCallbacks(this); + document()->unregisterForMediaVolumeCallbacks(this); + HTMLElement::willMoveToNewOwnerDocument(); +} + +void HTMLMediaElement::didMoveToNewOwnerDocument() +{ + document()->registerForDocumentActivationCallbacks(this); + document()->registerForMediaVolumeCallbacks(this); + HTMLElement::didMoveToNewOwnerDocument(); +} + + bool HTMLMediaElement::checkDTD(const Node* newChild) { return newChild->hasTagName(sourceTag) || HTMLElement::checkDTD(newChild); @@ -239,7 +254,7 @@ bool HTMLMediaElement::rendererIsNeeded(RenderStyle* style) RenderObject* HTMLMediaElement::createRenderer(RenderArena* arena, RenderStyle*) { #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) - return new (arena) RenderPartObject(this); + return new (arena) RenderEmbeddedObject(this); #else return new (arena) RenderMedia(this); #endif @@ -299,12 +314,7 @@ void HTMLMediaElement::scheduleNextSourceChild() void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) { - enqueueEvent(Event::create(eventName, false, true)); -} - -void HTMLMediaElement::enqueueEvent(RefPtr<Event> event) -{ - m_pendingEvents.append(event); + m_pendingEvents.append(Event::create(eventName, false, true)); if (!m_asyncEventTimer.isActive()) m_asyncEventTimer.startOneShot(0); } @@ -439,38 +449,19 @@ void HTMLMediaElement::prepareForLoad() void HTMLMediaElement::loadInternal() { - // 1 - If the load() method for this element is already being invoked, then abort these steps. + // If the load() method for this element is already being invoked, then abort these steps. if (m_processingLoad) return; m_processingLoad = true; - // Steps 2 and 3 were done in prepareForLoad() - - // 4 - If the media element's networkState is set to NETWORK_LOADING or NETWORK_IDLE, set - // the error attribute to a new MediaError object whose code attribute is set to - // MEDIA_ERR_ABORTED, fire a progress event called abort at the media element, in the - // context of the fetching process that is in progress for the element. - if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) { - m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); - - // fire synchronous 'abort' - bool totalKnown = m_player && m_player->totalBytesKnown(); - unsigned loaded = m_player ? m_player->bytesLoaded() : 0; - unsigned total = m_player ? m_player->totalBytes() : 0; - dispatchEvent(ProgressEvent::create(eventNames().abortEvent, totalKnown, loaded, total)); - } + // Steps 1 and 2 were done in prepareForLoad() - // 5 - m_error = 0; - m_autoplaying = true; - m_playedTimeRanges = TimeRanges::create(); - m_lastSeekTime = 0; - m_closedCaptionsVisible = false; + // 3 - If the media element's networkState is set to NETWORK_LOADING or NETWORK_IDLE, queue + // a task to fire a simple event named abort at the media element. + if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) + scheduleEvent(eventNames().abortEvent); - // 6 - setPlaybackRate(defaultPlaybackRate()); - - // 7 + // 4 if (m_networkState != NETWORK_EMPTY) { m_networkState = NETWORK_EMPTY; m_readyState = HAVE_NOTHING; @@ -481,9 +472,21 @@ void HTMLMediaElement::loadInternal() m_playing = false; m_player->seek(0); } - dispatchEvent(Event::create(eventNames().emptiedEvent, false, true)); + scheduleEvent(eventNames().emptiedEvent); } + // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRate attribute. + setPlaybackRate(defaultPlaybackRate()); + + // 6 - Set the error attribute to null and the autoplaying flag to true. + m_error = 0; + m_autoplaying = true; + + m_playedTimeRanges = TimeRanges::create(); + m_lastSeekTime = 0; + m_closedCaptionsVisible = false; + + // 7 - Invoke the media element's resource selection algorithm. selectMediaResource(); m_processingLoad = false; } @@ -495,15 +498,24 @@ void HTMLMediaElement::selectMediaResource() // 2 - Asynchronously await a stable state. - // 3 - If the media element has neither a src attribute nor any source element children, run these substeps + // 3 - ... the media element has neither a src attribute ... String mediaSrc = getAttribute(srcAttr); - if (!mediaSrc && !havePotentialSourceChild()) { - m_loadState = WaitingForSource; + if (!mediaSrc) { + // ... nor a source element child: ... + Node* node; + for (node = firstChild(); node; node = node->nextSibling()) { + if (node->hasTagName(sourceTag)) + break; + } - // 1 - Set the networkState to NETWORK_EMPTY and abort these steps - m_networkState = NETWORK_EMPTY; - ASSERT(!m_delayingTheLoadEvent); - return; + if (!node) { + m_loadState = WaitingForSource; + + // ... set the networkState to NETWORK_EMPTY, and abort these steps + m_networkState = NETWORK_EMPTY; + ASSERT(!m_delayingTheLoadEvent); + return; + } } // 4 @@ -536,9 +548,7 @@ void HTMLMediaElement::loadNextSourceChild() ContentType contentType(""); KURL mediaURL = selectNextSourceChild(&contentType, Complain); if (!mediaURL.isValid()) { - // It seems wrong to fail silently when we give up because no suitable <source> - // element can be found and set the error attribute if the element's 'src' attribute - // fails, but that is what the spec says. + waitForSourceChange(); return; } @@ -576,6 +586,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content m_player = MediaPlayer::create(this); #endif + m_player->setAutobuffer(autobuffer()); m_player->setPreservesPitch(m_webkitPreservesPitch); updateVolume(); @@ -617,6 +628,18 @@ void HTMLMediaElement::startProgressEventTimer() m_progressEventTimer.startRepeating(0.350); } +void HTMLMediaElement::waitForSourceChange() +{ + stopPeriodicTimers(); + m_loadState = WaitingForSource; + + // 6.17 - Waiting: Set the element's networkState attribute to the NETWORK_NO_SOURCE value + m_networkState = NETWORK_NO_SOURCE; + + // 6.18 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event. + m_delayingTheLoadEvent = false; +} + void HTMLMediaElement::noneSupported() { stopPeriodicTimers(); @@ -707,6 +730,9 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state) m_currentSourceNode->scheduleErrorEvent(); if (havePotentialSourceChild()) scheduleNextSourceChild(); + else + waitForSourceChange(); + return; } @@ -818,6 +844,8 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) m_player->seek(0); } + bool shouldUpdatePosterImage = false; + // 4.8.10.7 says loadeddata is sent only when the new state *is* HAVE_CURRENT_DATA: "If the // previous ready state was HAVE_METADATA and the new ready state is HAVE_CURRENT_DATA", // but the event table at the end of the spec says it is sent when: "readyState newly @@ -825,6 +853,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) // We go with the later because it seems useful to count on getting this event if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData) { m_haveFiredLoadedData = true; + shouldUpdatePosterImage = true; scheduleEvent(eventNames().loadeddataEvent); } @@ -833,9 +862,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) scheduleEvent(eventNames().canplayEvent); if (isPotentiallyPlaying) scheduleEvent(eventNames().playingEvent); - - if (isVideo()) - static_cast<HTMLVideoElement*>(this)->updatePosterImage(); + shouldUpdatePosterImage = true; } if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA) { @@ -853,10 +880,12 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) scheduleEvent(eventNames().playingEvent); } - if (isVideo()) - static_cast<HTMLVideoElement*>(this)->updatePosterImage(); + shouldUpdatePosterImage = true; } + if (shouldUpdatePosterImage && isVideo()) + static_cast<HTMLVideoElement*>(this)->updatePosterImage(); + updatePlayState(); } @@ -1065,7 +1094,10 @@ void HTMLMediaElement::setWebkitPreservesPitch(bool preservesPitch) bool HTMLMediaElement::ended() const { - return endedPlayback(); + // 4.8.10.8 Playing the media resource + // The ended attribute must return true if the media element has ended + // playback and the direction of playback is forwards, and false otherwise. + return endedPlayback() && m_playbackRate > 0; } bool HTMLMediaElement::autoplay() const @@ -1164,7 +1196,7 @@ bool HTMLMediaElement::controls() const Frame* frame = document()->frame(); // always show controls when scripting is disabled - if (frame && !frame->script()->isEnabled()) + if (frame && !frame->script()->canExecuteScripts()) return true; return hasAttribute(controlsAttr); @@ -1379,10 +1411,14 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*) { beginProcessingMediaPlayerCallback(); + // Always call scheduleTimeupdateEvent when the media engine reports a time discontinuity, + // it will only queue a 'timeupdate' event if we haven't already posted one at the current + // movie time. + scheduleTimeupdateEvent(false); + // 4.8.10.10 step 12 & 13. Needed if no ReadyState change is associated with the seek. - if (m_readyState >= HAVE_CURRENT_DATA && m_seeking) { + if (m_readyState >= HAVE_CURRENT_DATA && m_seeking) finishSeek(); - } float now = currentTime(); float dur = duration(); @@ -1394,7 +1430,6 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*) } else { if (!m_sentEndEvent) { m_sentEndEvent = true; - scheduleTimeupdateEvent(false); scheduleEvent(eventNames().endedEvent); } } @@ -1525,11 +1560,29 @@ bool HTMLMediaElement::couldPlayIfEnoughData() const bool HTMLMediaElement::endedPlayback() const { - if (!m_player || m_readyState < HAVE_METADATA) + float dur = duration(); + if (!m_player || isnan(dur)) + return false; + + // 4.8.10.8 Playing the media resource + + // A media element is said to have ended playback when the element's + // readyState attribute is HAVE_METADATA or greater, + if (m_readyState < HAVE_METADATA) return false; - float dur = duration(); - return !isnan(dur) && currentTime() >= dur && !loop(); + // and the current playback position is the end of the media resource and the direction + // of playback is forwards and the media element does not have a loop attribute specified, + float now = currentTime(); + if (m_playbackRate > 0) + return now >= dur && !loop(); + + // or the current playback position is the earliest possible position and the direction + // of playback is backwards + if (m_playbackRate < 0) + return now <= 0; + + return false; } bool HTMLMediaElement::stoppedDueToErrors() const @@ -1777,7 +1830,7 @@ void HTMLMediaElement::finishParsingChildren() document()->updateStyleIfNeeded(); if (m_needWidgetUpdate && renderer()) - toRenderPartObject(renderer())->updateWidget(true); + toRenderEmbeddedObject(renderer())->updateWidget(true); } #endif diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h index bc39dd7..9ee2c25 100644 --- a/WebCore/html/HTMLMediaElement.h +++ b/WebCore/html/HTMLMediaElement.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -187,7 +187,10 @@ protected: void setReadyState(MediaPlayer::ReadyState); void setNetworkState(MediaPlayer::NetworkState); - + + virtual void willMoveToNewOwnerDocument(); + virtual void didMoveToNewOwnerDocument(); + private: // MediaPlayerClient virtual void mediaPlayerNetworkStateChanged(MediaPlayer*); virtual void mediaPlayerReadyStateChanged(MediaPlayer*); @@ -219,7 +222,6 @@ private: void scheduleTimeupdateEvent(bool periodicEvent); void scheduleEvent(const AtomicString& eventName); - void enqueueEvent(RefPtr<Event> event); // loading void selectMediaResource(); @@ -231,6 +233,7 @@ private: void noneSupported(); void mediaEngineError(PassRefPtr<MediaError> err); void cancelPendingEventsAndCallbacks(); + void waitForSourceChange(); enum InvalidSourceAction { DoNothing, Complain }; bool isSafeToLoadURL(const KURL&, InvalidSourceAction); diff --git a/WebCore/html/HTMLMediaElement.idl b/WebCore/html/HTMLMediaElement.idl index e418a63..1097e55 100644 --- a/WebCore/html/HTMLMediaElement.idl +++ b/WebCore/html/HTMLMediaElement.idl @@ -24,7 +24,7 @@ */ module html { -interface [GenerateConstructor, Conditional=VIDEO] HTMLMediaElement : HTMLElement { +interface [Conditional=VIDEO] HTMLMediaElement : HTMLElement { // error state readonly attribute MediaError error; diff --git a/WebCore/html/HTMLMenuElement.idl b/WebCore/html/HTMLMenuElement.idl index 4c2701a..238263a 100644 --- a/WebCore/html/HTMLMenuElement.idl +++ b/WebCore/html/HTMLMenuElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=fb353af6-4927-4512-ad43-4ad8191b5615, - ImplementationUUID=ec26257c-a2a4-43dc-b234-cf644d22b1fb - ] HTMLMenuElement : HTMLElement { + interface HTMLMenuElement : HTMLElement { attribute boolean compact; }; diff --git a/WebCore/html/HTMLMetaElement.idl b/WebCore/html/HTMLMetaElement.idl index 2c350c9..ef7e4ab 100644 --- a/WebCore/html/HTMLMetaElement.idl +++ b/WebCore/html/HTMLMetaElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=65e3374d-4789-4c81-983b-1b5a29d2c075, - ImplementationUUID=a9ac9c73-055d-4c00-bd02-1fa215ae32f1 - ] HTMLMetaElement : HTMLElement { + interface HTMLMetaElement : HTMLElement { attribute [ConvertNullToNullString] DOMString content; attribute [ConvertNullToNullString] DOMString httpEquiv; attribute [ConvertNullToNullString] DOMString name; diff --git a/WebCore/html/HTMLModElement.idl b/WebCore/html/HTMLModElement.idl index a22b7b4..a6e3a02 100644 --- a/WebCore/html/HTMLModElement.idl +++ b/WebCore/html/HTMLModElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=78c2bf89-c6e7-4d81-97df-429d07b91ff8, - ImplementationUUID=39e7c659-40be-4620-949b-15ec6a25bb90 - ] HTMLModElement : HTMLElement { + interface HTMLModElement : HTMLElement { attribute [ConvertNullToNullString] DOMString cite; attribute [ConvertNullToNullString] DOMString dateTime; }; diff --git a/WebCore/html/HTMLNameCollection.cpp b/WebCore/html/HTMLNameCollection.cpp index d5657da..eb88c02 100644 --- a/WebCore/html/HTMLNameCollection.cpp +++ b/WebCore/html/HTMLNameCollection.cpp @@ -63,7 +63,7 @@ Element* HTMLNameCollection::itemAfter(Element* previous) const e->hasTagName(objectTag)) if (e->getAttribute(nameAttr) == m_name) return e; - if (e->getAttribute(idAttr) == m_name) + if (e->getAttribute(e->idAttributeName()) == m_name) return e; break; case DocumentNamedItems: @@ -74,14 +74,14 @@ Element* HTMLNameCollection::itemAfter(Element* previous) const if (e->getAttribute(nameAttr) == m_name) return e; } else if (e->hasTagName(appletTag)) { - if (e->getAttribute(nameAttr) == m_name || e->getAttribute(idAttr) == m_name) + if (e->getAttribute(nameAttr) == m_name || e->getAttribute(e->idAttributeName()) == m_name) return e; } else if (e->hasTagName(objectTag)) { - if ((e->getAttribute(nameAttr) == m_name || e->getAttribute(idAttr) == m_name) + if ((e->getAttribute(nameAttr) == m_name || e->getAttribute(e->idAttributeName()) == m_name) && static_cast<HTMLObjectElement*>(e)->isDocNamedItem()) return e; } else if (e->hasTagName(imgTag)) { - if (e->getAttribute(nameAttr) == m_name || (e->getAttribute(idAttr) == m_name && e->hasAttribute(nameAttr))) + if (e->getAttribute(nameAttr) == m_name || (e->getAttribute(e->idAttributeName()) == m_name && e->hasAttribute(nameAttr))) return e; } break; diff --git a/WebCore/html/HTMLOListElement.idl b/WebCore/html/HTMLOListElement.idl index d787ee7..32d81f2 100644 --- a/WebCore/html/HTMLOListElement.idl +++ b/WebCore/html/HTMLOListElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=64165a4c-8889-4725-a149-abd13d5b4b61, - ImplementationUUID=a20e9b6a-e3a5-4276-aa43-0097e57df8d8 - ] HTMLOListElement : HTMLElement { + interface HTMLOListElement : HTMLElement { attribute boolean compact; attribute long start; attribute [ConvertNullToNullString] DOMString type; diff --git a/WebCore/html/HTMLObjectElement.cpp b/WebCore/html/HTMLObjectElement.cpp index d3ccfa4..80a5efa 100644 --- a/WebCore/html/HTMLObjectElement.cpp +++ b/WebCore/html/HTMLObjectElement.cpp @@ -35,8 +35,8 @@ #include "ScriptEventListener.h" #include "MIMETypeRegistry.h" #include "MappedAttribute.h" +#include "RenderEmbeddedObject.h" #include "RenderImage.h" -#include "RenderPartObject.h" #include "RenderWidget.h" #include "ScriptController.h" #include "Text.h" @@ -107,7 +107,7 @@ void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr) document->addNamedItem(newName); } m_name = newName; - } else if (attr->name() == idAttr) { + } else if (attr->name() == idAttributeName()) { const AtomicString& newId = attr->value(); if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) { HTMLDocument* document = static_cast<HTMLDocument*>(this->document()); @@ -140,7 +140,7 @@ RenderObject *HTMLObjectElement::createRenderer(RenderArena* arena, RenderStyle* return RenderObject::createObject(this, style); if (isImageType()) return new (arena) RenderImage(this); - return new (arena) RenderPartObject(this); + return new (arena) RenderEmbeddedObject(this); } void HTMLObjectElement::attach() @@ -169,7 +169,7 @@ void HTMLObjectElement::updateWidget() { document()->updateStyleIfNeeded(); if (m_needWidgetUpdate && renderer() && !m_useFallbackContent && !isImageType()) - toRenderPartObject(renderer())->updateWidget(true); + toRenderEmbeddedObject(renderer())->updateWidget(true); } void HTMLObjectElement::finishParsingChildren() diff --git a/WebCore/html/HTMLObjectElement.idl b/WebCore/html/HTMLObjectElement.idl index b51c568..8d975ba 100644 --- a/WebCore/html/HTMLObjectElement.idl +++ b/WebCore/html/HTMLObjectElement.idl @@ -21,13 +21,10 @@ module html { interface [ - GenerateConstructor, DelegatingPutFunction, DelegatingGetOwnPropertySlot, CustomCall, - HasOverridingNameGetter, - InterfaceUUID=9d04a3b8-9016-4b64-913a-3b00d548aca7, - ImplementationUUID=2dd24554-6784-4ef9-9713-179f3d37b2f9 + HasOverridingNameGetter ] HTMLObjectElement : HTMLElement { readonly attribute HTMLFormElement form; attribute [ConvertNullToNullString, Reflect] DOMString code; @@ -51,14 +48,12 @@ module html { // Introduced in DOM Level 2: readonly attribute [CheckFrameSecurity] Document contentDocument; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM #if defined(ENABLE_SVG) && ENABLE_SVG #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS [SVGCheckSecurityDocument] SVGDocument getSVGDocument() raises(DOMException); #endif #endif -#endif #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C // Objective-C extension: diff --git a/WebCore/html/HTMLOptGroupElement.idl b/WebCore/html/HTMLOptGroupElement.idl index 9f07c38..691bd13 100644 --- a/WebCore/html/HTMLOptGroupElement.idl +++ b/WebCore/html/HTMLOptGroupElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=18b0ea8c-d3ea-4b14-abd8-8e1d4269fffc, - ImplementationUUID=e26d8c4b-5181-4858-8231-f68ccbf819df - ] HTMLOptGroupElement : HTMLElement { + interface HTMLOptGroupElement : HTMLElement { attribute boolean disabled; attribute [ConvertNullToNullString] DOMString label; }; diff --git a/WebCore/html/HTMLOptionElement.cpp b/WebCore/html/HTMLOptionElement.cpp index 501615f..cab4e18 100644 --- a/WebCore/html/HTMLOptionElement.cpp +++ b/WebCore/html/HTMLOptionElement.cpp @@ -137,6 +137,8 @@ void HTMLOptionElement::setValue(const String& value) bool HTMLOptionElement::selected() const { + if (HTMLSelectElement* select = ownerSelectElement()) + select->recalcListItemsIfNeeded(); return m_data.selected(); } @@ -217,14 +219,15 @@ String HTMLOptionElement::textIndentedToRespectGroupLabel() const bool HTMLOptionElement::disabled() const { - return HTMLFormControlElement::disabled() || (parentNode() && static_cast<HTMLFormControlElement*>(parentNode())->disabled()); + return ownElementDisabled() || (parentNode() && static_cast<HTMLFormControlElement*>(parentNode())->disabled()); } void HTMLOptionElement::insertedIntoTree(bool deep) { if (HTMLSelectElement* select = ownerSelectElement()) { select->setRecalcListItems(); - if (selected()) + // Avoid our selected() getter since it will recalculate list items incorrectly for us. + if (m_data.selected()) select->setSelectedIndex(index(), false); select->scrollToSelection(); } diff --git a/WebCore/html/HTMLOptionElement.h b/WebCore/html/HTMLOptionElement.h index 843608f..7be9e9a 100644 --- a/WebCore/html/HTMLOptionElement.h +++ b/WebCore/html/HTMLOptionElement.h @@ -76,6 +76,7 @@ public: virtual String textIndentedToRespectGroupLabel() const; + bool ownElementDisabled() const { return HTMLFormControlElement::disabled(); } virtual bool disabled() const; virtual void insertedIntoTree(bool); diff --git a/WebCore/html/HTMLOptionElement.idl b/WebCore/html/HTMLOptionElement.idl index 612d459..c43132e 100644 --- a/WebCore/html/HTMLOptionElement.idl +++ b/WebCore/html/HTMLOptionElement.idl @@ -21,10 +21,7 @@ module html { interface [ - GenerateConstructor, - GenerateNativeConverter, - InterfaceUUID=74a7b64a-cf18-4da9-b3aa-e1f4d245d607, - ImplementationUUID=166915d5-2c93-404b-b076-af3fa5ccbd83 + GenerateNativeConverter ] HTMLOptionElement : HTMLElement { readonly attribute HTMLFormElement form; attribute boolean defaultSelected; diff --git a/WebCore/html/HTMLOptionsCollection.idl b/WebCore/html/HTMLOptionsCollection.idl index a7e191a..d9bfd45 100644 --- a/WebCore/html/HTMLOptionsCollection.idl +++ b/WebCore/html/HTMLOptionsCollection.idl @@ -23,9 +23,7 @@ module html { // FIXME: The W3C spec says that HTMLOptionsCollection should not have a parent class. interface [ GenerateNativeConverter, - HasCustomIndexSetter, - InterfaceUUID=a03aaeac-e47d-4bb3-acb4-f1897ae74237, - ImplementationUUID=99c11fde-6f9f-44a4-a041-49a894c52e70 + HasCustomIndexSetter ] HTMLOptionsCollection : HTMLCollection { attribute long selectedIndex; attribute [Custom] unsigned long length diff --git a/WebCore/html/HTMLParagraphElement.idl b/WebCore/html/HTMLParagraphElement.idl index b974ec2..cd3b940 100644 --- a/WebCore/html/HTMLParagraphElement.idl +++ b/WebCore/html/HTMLParagraphElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=dffe0809-f3f8-499d-8d5c-7d9893f23337, - ImplementationUUID=21d60b62-4ecb-4849-8729-0a40c64d12aa - ] HTMLParagraphElement : HTMLElement { + interface HTMLParagraphElement : HTMLElement { attribute [ConvertNullToNullString] DOMString align; }; diff --git a/WebCore/html/HTMLParamElement.cpp b/WebCore/html/HTMLParamElement.cpp index d5fc6e7..2b0637a 100644 --- a/WebCore/html/HTMLParamElement.cpp +++ b/WebCore/html/HTMLParamElement.cpp @@ -43,7 +43,7 @@ HTMLParamElement::~HTMLParamElement() void HTMLParamElement::parseMappedAttribute(MappedAttribute* attr) { - if (attr->name() == idAttr) { + if (attr->name() == idAttributeName()) { // Must call base class so that hasID bit gets set. HTMLElement::parseMappedAttribute(attr); if (document()->isHTMLDocument()) diff --git a/WebCore/html/HTMLParamElement.idl b/WebCore/html/HTMLParamElement.idl index 805d170..2473381 100644 --- a/WebCore/html/HTMLParamElement.idl +++ b/WebCore/html/HTMLParamElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=76e05eee-c30d-4d52-a356-271f17b31dbf, - ImplementationUUID=418d8a82-0a99-4c6f-a630-1e6071a74350 - ] HTMLParamElement : HTMLElement { + interface HTMLParamElement : HTMLElement { attribute [ConvertNullToNullString] DOMString name; attribute [ConvertNullToNullString] DOMString type; attribute [ConvertNullToNullString] DOMString value; diff --git a/WebCore/html/HTMLParser.cpp b/WebCore/html/HTMLParser.cpp index f13c19b..644f63e 100644 --- a/WebCore/html/HTMLParser.cpp +++ b/WebCore/html/HTMLParser.cpp @@ -28,6 +28,7 @@ #include "CharacterNames.h" #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" +#include "Chrome.h" #include "ChromeClient.h" #include "Comment.h" #include "Console.h" @@ -64,6 +65,8 @@ using namespace HTMLNames; static const unsigned cMaxRedundantTagDepth = 20; static const unsigned cResidualStyleMaxDepth = 200; +static const unsigned cResidualStyleIterationLimit = 5; + static const int minBlockLevelTagPriority = 3; @@ -137,11 +140,12 @@ HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors) , m_reportErrors(reportErrors) , m_handlingResidualStyleAcrossBlocks(false) , m_inStrayTableContent(0) + , m_scriptingPermission(FragmentScriptingAllowed) , m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0) { } -HTMLParser::HTMLParser(DocumentFragment* frag) +HTMLParser::HTMLParser(DocumentFragment* frag, FragmentScriptingPermission scriptingPermission) : m_document(frag->document()) , m_current(frag) , m_didRefCurrent(true) @@ -155,6 +159,7 @@ HTMLParser::HTMLParser(DocumentFragment* frag) , m_reportErrors(false) , m_handlingResidualStyleAcrossBlocks(false) , m_inStrayTableContent(0) + , m_scriptingPermission(scriptingPermission) , m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0) { if (frag) @@ -274,7 +279,8 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t) // set attributes if (n->isHTMLElement()) { HTMLElement* e = static_cast<HTMLElement*>(n.get()); - e->setAttributeMap(t->attrs.get()); + if (m_scriptingPermission == FragmentScriptingAllowed || t->tagName != scriptTag) + e->setAttributeMap(t->attrs.get(), m_scriptingPermission); // take care of optional close tags if (e->endTagRequirement() == TagStatusOptional) @@ -652,7 +658,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName, reportError(MisplacedContentRetryError, &localName, ¤tTagName); popBlock(objectTag); handled = true; - } else if (h->hasLocalName(pTag) || isHeaderTag(currentTagName)) { + } else if (h->hasLocalName(pTag) || isHeadingTag(currentTagName)) { if (!isInline(n)) { popBlock(currentTagName); handled = true; @@ -907,6 +913,8 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t) if (gFunctionMap.isEmpty()) { gFunctionMap.set(aTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck); gFunctionMap.set(addressTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); + gFunctionMap.set(articleTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); + gFunctionMap.set(asideTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(bTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck); gFunctionMap.set(bigTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck); gFunctionMap.set(blockquoteTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); @@ -921,6 +929,7 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t) gFunctionMap.set(dtTag.localName().impl(), &HTMLParser::dtCreateErrorCheck); gFunctionMap.set(formTag.localName().impl(), &HTMLParser::formCreateErrorCheck); gFunctionMap.set(fieldsetTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); + gFunctionMap.set(footerTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(framesetTag.localName().impl(), &HTMLParser::framesetCreateErrorCheck); gFunctionMap.set(h1Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(h2Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); @@ -929,6 +938,7 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t) gFunctionMap.set(h5Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(h6Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(headTag.localName().impl(), &HTMLParser::headCreateErrorCheck); + gFunctionMap.set(headerTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(hrTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(iTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck); gFunctionMap.set(isindexTag.localName().impl(), &HTMLParser::isindexCreateErrorCheck); @@ -940,9 +950,7 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t) gFunctionMap.set(nobrTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck); gFunctionMap.set(noembedTag.localName().impl(), &HTMLParser::noembedCreateErrorCheck); gFunctionMap.set(noframesTag.localName().impl(), &HTMLParser::noframesCreateErrorCheck); -#if !ENABLE(XHTMLMP) gFunctionMap.set(noscriptTag.localName().impl(), &HTMLParser::noscriptCreateErrorCheck); -#endif gFunctionMap.set(olTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(pTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(plaintextTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); @@ -950,6 +958,7 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t) gFunctionMap.set(rpTag.localName().impl(), &HTMLParser::rpCreateErrorCheck); gFunctionMap.set(rtTag.localName().impl(), &HTMLParser::rtCreateErrorCheck); gFunctionMap.set(sTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck); + gFunctionMap.set(sectionTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck); gFunctionMap.set(selectTag.localName().impl(), &HTMLParser::selectCreateErrorCheck); gFunctionMap.set(smallTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck); gFunctionMap.set(strikeTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck); @@ -1017,19 +1026,19 @@ void HTMLParser::processCloseTag(Token* t) } } -bool HTMLParser::isHeaderTag(const AtomicString& tagName) +bool HTMLParser::isHeadingTag(const AtomicString& tagName) { - DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, headerTags, ()); - if (headerTags.isEmpty()) { - headerTags.add(h1Tag.localName().impl()); - headerTags.add(h2Tag.localName().impl()); - headerTags.add(h3Tag.localName().impl()); - headerTags.add(h4Tag.localName().impl()); - headerTags.add(h5Tag.localName().impl()); - headerTags.add(h6Tag.localName().impl()); + DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, headingTags, ()); + if (headingTags.isEmpty()) { + headingTags.add(h1Tag.localName().impl()); + headingTags.add(h2Tag.localName().impl()); + headingTags.add(h3Tag.localName().impl()); + headingTags.add(h4Tag.localName().impl()); + headingTags.add(h5Tag.localName().impl()); + headingTags.add(h6Tag.localName().impl()); } - return headerTags.contains(tagName.impl()); + return headingTags.contains(tagName.impl()); } bool HTMLParser::isInline(Node* node) const @@ -1121,8 +1130,10 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem) bool finished = false; bool strayTableContent = elem->strayTableContent; + unsigned iterationCount = 0; + m_handlingResidualStyleAcrossBlocks = true; - while (!finished) { + while (!finished && (iterationCount++ < cResidualStyleIterationLimit)) { // Find the outermost element that crosses over to a higher level. If there exists another higher-level // element, we will do another pass, until we have corrected the innermost one. ExceptionCode ec = 0; @@ -1290,7 +1301,8 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem) prevMaxElem->next = elem; ASSERT(newNodePtr); prevMaxElem->node = newNodePtr; - prevMaxElem->didRefNode = false; + newNodePtr->ref(); + prevMaxElem->didRefNode = true; } else delete elem; } diff --git a/WebCore/html/HTMLParser.h b/WebCore/html/HTMLParser.h index f07b64b..acb6a6f 100644 --- a/WebCore/html/HTMLParser.h +++ b/WebCore/html/HTMLParser.h @@ -29,6 +29,7 @@ #include <wtf/OwnPtr.h> #include <wtf/RefPtr.h> #include "HTMLParserErrorCodes.h" +#include "MappedAttributeEntry.h" namespace WebCore { @@ -52,7 +53,7 @@ struct Token; class HTMLParser : public Noncopyable { public: HTMLParser(HTMLDocument*, bool reportErrors); - HTMLParser(DocumentFragment*); + HTMLParser(DocumentFragment*, FragmentScriptingPermission = FragmentScriptingAllowed); virtual ~HTMLParser(); /** @@ -136,8 +137,7 @@ private: bool allowNestedRedundantTag(const AtomicString& tagName); - static bool isHeaderTag(const AtomicString& tagName); - void popNestedHeaderTag(); + static bool isHeadingTag(const AtomicString& tagName); bool isInline(Node*) const; @@ -189,6 +189,7 @@ private: bool m_reportErrors; bool m_handlingResidualStyleAcrossBlocks; int m_inStrayTableContent; + FragmentScriptingPermission m_scriptingPermission; OwnPtr<HTMLParserQuirks> m_parserQuirks; }; diff --git a/WebCore/html/HTMLPlugInElement.cpp b/WebCore/html/HTMLPlugInElement.cpp index 9626c83..dafa8fb 100644 --- a/WebCore/html/HTMLPlugInElement.cpp +++ b/WebCore/html/HTMLPlugInElement.cpp @@ -45,7 +45,6 @@ namespace WebCore { using namespace HTMLNames; HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc) - // FIXME: Always passing false as createdByParser is odd (see bug22851). : HTMLFrameOwnerElement(tagName, doc) #if ENABLE(NETSCAPE_PLUGIN_API) , m_NPObject(0) diff --git a/WebCore/html/HTMLPreElement.idl b/WebCore/html/HTMLPreElement.idl index 5597d95..5dc0e9e 100644 --- a/WebCore/html/HTMLPreElement.idl +++ b/WebCore/html/HTMLPreElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=84050abc-45e6-4fd8-bdc3-29c7b4efb5cb, - ImplementationUUID=e6de0d19-883e-4e87-9569-fd068e5ee17d - ] HTMLPreElement : HTMLElement { + interface HTMLPreElement : HTMLElement { // FIXME: DOM spec says that width should be of type DOMString // see http://bugs.webkit.org/show_bug.cgi?id=8992 attribute long width; diff --git a/WebCore/html/HTMLQuoteElement.idl b/WebCore/html/HTMLQuoteElement.idl index 99047c4..f95dc20 100644 --- a/WebCore/html/HTMLQuoteElement.idl +++ b/WebCore/html/HTMLQuoteElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=a011e1a3-19ec-4999-a225-79ebdc64abdd, - ImplementationUUID=85c885ee-cc47-4d98-852c-fb907d573024 - ] HTMLQuoteElement : HTMLElement { + interface HTMLQuoteElement : HTMLElement { attribute [ConvertNullToNullString] DOMString cite; }; } diff --git a/WebCore/html/HTMLScriptElement.idl b/WebCore/html/HTMLScriptElement.idl index 4a19b8c..8985512 100644 --- a/WebCore/html/HTMLScriptElement.idl +++ b/WebCore/html/HTMLScriptElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=57ddf4da-1c9b-4005-87d7-eb9b2ed78e95, - ImplementationUUID=2edb1093-08f1-4e76-9728-df5dedb879fe - ] HTMLScriptElement : HTMLElement { + interface HTMLScriptElement : HTMLElement { attribute [ConvertNullToNullString] DOMString text; attribute [ConvertNullToNullString] DOMString htmlFor; attribute [ConvertNullToNullString] DOMString event; diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp index 2409f31..5f5c855 100644 --- a/WebCore/html/HTMLSelectElement.cpp +++ b/WebCore/html/HTMLSelectElement.cpp @@ -4,6 +4,7 @@ * (C) 2001 Dirk Mueller (mueller@kde.org) * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. * (C) 2006 Alexey Proskuryakov (ap@nypop.com) + * Copyright (C) 2010 Google 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 @@ -59,7 +60,6 @@ bool HTMLSelectElement::checkDTD(const Node* newChild) void HTMLSelectElement::recalcStyle(StyleChange change) { - SelectElement::recalcStyle(m_data, this); HTMLFormControlElementWithState::recalcStyle(change); } @@ -261,6 +261,12 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const SelectElement::recalcListItems(const_cast<SelectElementData&>(m_data), this, updateSelectedStates); } +void HTMLSelectElement::recalcListItemsIfNeeded() +{ + if (m_data.shouldRecalcListItems()) + recalcListItems(); +} + void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { setRecalcListItems(); diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h index 8f575d2..0a2050e 100644 --- a/WebCore/html/HTMLSelectElement.h +++ b/WebCore/html/HTMLSelectElement.h @@ -3,6 +3,7 @@ * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2010 Google 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 @@ -58,6 +59,7 @@ public: virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); void setRecalcListItems(); + void recalcListItemsIfNeeded(); virtual const Vector<Element*>& listItems() const { return m_data.listItems(this); } @@ -74,7 +76,7 @@ public: Node* namedItem(const AtomicString& name); Node* item(unsigned index); - CollectionCache* collectionInfo() { return &m_collectionInfo; } + CollectionCache* collectionInfo() { m_collectionInfo.checkConsistency(); return &m_collectionInfo; } void scrollToSelection(); diff --git a/WebCore/html/HTMLSelectElement.idl b/WebCore/html/HTMLSelectElement.idl index ae47896..d260fad 100644 --- a/WebCore/html/HTMLSelectElement.idl +++ b/WebCore/html/HTMLSelectElement.idl @@ -22,10 +22,7 @@ module html { interface [ HasIndexGetter, - HasCustomIndexSetter, - GenerateConstructor, - InterfaceUUID=99013cd3-d644-4bb5-86a3-2e743821383b, - ImplementationUUID=afe20462-588d-469a-9b4c-8879c4a461d5 + HasCustomIndexSetter ] HTMLSelectElement : HTMLElement { readonly attribute DOMString type; @@ -41,9 +38,7 @@ module html { #endif readonly attribute HTMLFormElement form; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM readonly attribute ValidityState validity; -#endif readonly attribute boolean willValidate; readonly attribute DOMString validationMessage; boolean checkValidity(); diff --git a/WebCore/html/HTMLSourceElement.idl b/WebCore/html/HTMLSourceElement.idl index 5a25c23..863e180 100644 --- a/WebCore/html/HTMLSourceElement.idl +++ b/WebCore/html/HTMLSourceElement.idl @@ -24,7 +24,7 @@ */ module html { -interface [GenerateConstructor, Conditional=VIDEO] HTMLSourceElement : HTMLElement { +interface [Conditional=VIDEO] HTMLSourceElement : HTMLElement { attribute DOMString src; attribute DOMString type; attribute DOMString media; diff --git a/WebCore/html/HTMLStyleElement.idl b/WebCore/html/HTMLStyleElement.idl index a1b86f8..562d01b 100644 --- a/WebCore/html/HTMLStyleElement.idl +++ b/WebCore/html/HTMLStyleElement.idl @@ -20,19 +20,13 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=3aaa334c-9660-48cf-b8e2-6d2b4ac0a1da, - ImplementationUUID=73024a55-b8a1-461b-ad85-befa4089f80d - ] HTMLStyleElement : HTMLElement { + interface HTMLStyleElement : HTMLElement { attribute boolean disabled; attribute [ConvertNullToNullString] DOMString media; attribute [ConvertNullToNullString] DOMString type; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM // DOM Level 2 Style readonly attribute StyleSheet sheet; -#endif }; } diff --git a/WebCore/html/HTMLTableCaptionElement.idl b/WebCore/html/HTMLTableCaptionElement.idl index 9424cd5..86a197f 100644 --- a/WebCore/html/HTMLTableCaptionElement.idl +++ b/WebCore/html/HTMLTableCaptionElement.idl @@ -21,10 +21,7 @@ module html { interface [ - GenerateNativeConverter, - GenerateConstructor, - InterfaceUUID=cd92752d-2f0e-44af-b68e-12c178e1f087, - ImplementationUUID=7c0e3749-0f81-4063-9760-8cec314a5b72 + GenerateNativeConverter ] HTMLTableCaptionElement : HTMLElement { attribute [ConvertNullToNullString] DOMString align; diff --git a/WebCore/html/HTMLTableCellElement.idl b/WebCore/html/HTMLTableCellElement.idl index c0d22ca..a89149f 100644 --- a/WebCore/html/HTMLTableCellElement.idl +++ b/WebCore/html/HTMLTableCellElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=3ad21d30-ce64-4a6f-9296-c07a16170783, - ImplementationUUID=36fe6075-c9c1-4f22-bbc2-dd440f21f7cf - ] HTMLTableCellElement : HTMLElement { + interface HTMLTableCellElement : HTMLElement { readonly attribute long cellIndex; attribute [ConvertNullToNullString] DOMString abbr; diff --git a/WebCore/html/HTMLTableColElement.idl b/WebCore/html/HTMLTableColElement.idl index 083e4a6..453ff3f 100644 --- a/WebCore/html/HTMLTableColElement.idl +++ b/WebCore/html/HTMLTableColElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=4e886641-910e-424a-995c-e525c09dcfd3, - ImplementationUUID=5f4cdf17-44f1-4b1d-9c68-206737085892 - ] HTMLTableColElement : HTMLElement { + interface HTMLTableColElement : HTMLElement { attribute [ConvertNullToNullString] DOMString align; attribute [ConvertNullToNullString] DOMString ch; diff --git a/WebCore/html/HTMLTableElement.idl b/WebCore/html/HTMLTableElement.idl index 7092be0..9cd72b0 100644 --- a/WebCore/html/HTMLTableElement.idl +++ b/WebCore/html/HTMLTableElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=3f9c6e17-ee0c-43de-94b0-2a21b19b612c, - ImplementationUUID=159bb8fe-ffee-4ff9-b507-76741118143f - ] HTMLTableElement : HTMLElement { + interface HTMLTableElement : HTMLElement { // could raise excepetions on setting. attribute HTMLTableCaptionElement caption diff --git a/WebCore/html/HTMLTableRowElement.idl b/WebCore/html/HTMLTableRowElement.idl index 3a76ca3..052b516 100644 --- a/WebCore/html/HTMLTableRowElement.idl +++ b/WebCore/html/HTMLTableRowElement.idl @@ -20,11 +20,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=f14ea3d9-8643-4cfd-a692-cefe6d5c65ea, - ImplementationUUID=0ce090da-33bb-4163-bb35-3ca8a2f6be47 - ] HTMLTableRowElement : HTMLElement { + interface HTMLTableRowElement : HTMLElement { readonly attribute long rowIndex; readonly attribute long sectionRowIndex; diff --git a/WebCore/html/HTMLTableSectionElement.idl b/WebCore/html/HTMLTableSectionElement.idl index 7078e33..57e4293 100644 --- a/WebCore/html/HTMLTableSectionElement.idl +++ b/WebCore/html/HTMLTableSectionElement.idl @@ -21,10 +21,7 @@ module html { interface [ - GenerateNativeConverter, - GenerateConstructor, - InterfaceUUID=e0cf6b6a-9ba1-400f-b523-dbb22819dfb6, - ImplementationUUID=85329cf4-1eae-4245-a971-1bddb212a9c5 + GenerateNativeConverter ] HTMLTableSectionElement : HTMLElement { attribute [ConvertNullToNullString] DOMString align; diff --git a/WebCore/html/HTMLTagNames.in b/WebCore/html/HTMLTagNames.in index 8842b23..1b77c5a 100644 --- a/WebCore/html/HTMLTagNames.in +++ b/WebCore/html/HTMLTagNames.in @@ -8,6 +8,8 @@ acronym interfaceName=HTMLElement address interfaceName=HTMLElement applet area +article interfaceName=HTMLElement +aside interfaceName=HTMLElement audio wrapperOnlyIfMediaIsAvailable, conditional=VIDEO, createWithNew b interfaceName=HTMLElement base createWithNew @@ -41,6 +43,7 @@ em interfaceName=HTMLElement embed fieldset interfaceName=HTMLFieldSetElement, constructorNeedsFormElement, createWithNew font createWithNew +footer interfaceName=HTMLElement form createWithNew frame frameset interfaceName=HTMLFrameSetElement, createWithNew @@ -51,6 +54,7 @@ h4 interfaceName=HTMLHeadingElement, createWithNew h5 interfaceName=HTMLHeadingElement, createWithNew h6 interfaceName=HTMLHeadingElement, createWithNew head createWithNew +header interfaceName=HTMLElement hr interfaceName=HTMLHRElement, createWithNew html createWithNew i interfaceName=HTMLElement @@ -92,6 +96,7 @@ ruby interfaceName=HTMLElement s interfaceName=HTMLElement samp interfaceName=HTMLElement script constructorNeedsCreatedByParser, createWithNew +section interfaceName=HTMLElement select constructorNeedsFormElement, createWithNew small interfaceName=HTMLElement source wrapperOnlyIfMediaIsAvailable, conditional=VIDEO, createWithNew diff --git a/WebCore/html/HTMLTextAreaElement.cpp b/WebCore/html/HTMLTextAreaElement.cpp index 0e8350c..7159cc7 100644 --- a/WebCore/html/HTMLTextAreaElement.cpp +++ b/WebCore/html/HTMLTextAreaElement.cpp @@ -27,6 +27,7 @@ #include "HTMLTextAreaElement.h" #include "BeforeTextInsertedEvent.h" +#include "Chrome.h" #include "ChromeClient.h" #include "CSSValueKeywords.h" #include "Document.h" diff --git a/WebCore/html/HTMLTextAreaElement.idl b/WebCore/html/HTMLTextAreaElement.idl index 107a1fe..2d82eed 100644 --- a/WebCore/html/HTMLTextAreaElement.idl +++ b/WebCore/html/HTMLTextAreaElement.idl @@ -20,16 +20,10 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=8b16bba6-efa9-4887-b863-308b4f9b9202, - ImplementationUUID=2414be6e-bae0-472d-b124-beed5ca82d3b - ] HTMLTextAreaElement : HTMLElement { + interface HTMLTextAreaElement : HTMLElement { attribute [ConvertNullToNullString] DOMString defaultValue; readonly attribute HTMLFormElement form; -#if !defined(LANGUAGE_COM) || !LANGUAGE_COM readonly attribute ValidityState validity; -#endif attribute [ConvertNullToNullString] DOMString accessKey; attribute long cols; attribute boolean disabled; diff --git a/WebCore/html/HTMLTitleElement.idl b/WebCore/html/HTMLTitleElement.idl index d0f27e7..de857e8 100644 --- a/WebCore/html/HTMLTitleElement.idl +++ b/WebCore/html/HTMLTitleElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=036211fb-c1e9-4265-aac5-c5874e4a499c, - ImplementationUUID=ff577152-4ea3-404f-912d-ed1d0b64e60e - ] HTMLTitleElement : HTMLElement { + interface HTMLTitleElement : HTMLElement { attribute [ConvertNullToNullString] DOMString text; }; diff --git a/WebCore/html/HTMLTokenizer.cpp b/WebCore/html/HTMLTokenizer.cpp index a552442..6fa3e20 100644 --- a/WebCore/html/HTMLTokenizer.cpp +++ b/WebCore/html/HTMLTokenizer.cpp @@ -171,10 +171,12 @@ HTMLTokenizer::HTMLTokenizer(HTMLDocument* doc, bool reportErrors) , m_requestingScript(false) , m_hasScriptsWaitingForStylesheets(false) , m_timer(this, &HTMLTokenizer::timerFired) + , m_externalScriptsTimer(this, &HTMLTokenizer::executeExternalScriptsTimerFired) , m_doc(doc) , m_parser(new HTMLParser(doc, reportErrors)) , m_inWrite(false) , m_fragment(false) + , m_scriptingPermission(FragmentScriptingAllowed) { begin(); } @@ -190,15 +192,17 @@ HTMLTokenizer::HTMLTokenizer(HTMLViewSourceDocument* doc) , m_requestingScript(false) , m_hasScriptsWaitingForStylesheets(false) , m_timer(this, &HTMLTokenizer::timerFired) + , m_externalScriptsTimer(this, &HTMLTokenizer::executeExternalScriptsTimerFired) , m_doc(doc) , m_parser(0) , m_inWrite(false) , m_fragment(false) + , m_scriptingPermission(FragmentScriptingAllowed) { begin(); } -HTMLTokenizer::HTMLTokenizer(DocumentFragment* frag) +HTMLTokenizer::HTMLTokenizer(DocumentFragment* frag, FragmentScriptingPermission scriptingPermission) : m_buffer(0) , m_scriptCode(0) , m_scriptCodeSize(0) @@ -208,10 +212,12 @@ HTMLTokenizer::HTMLTokenizer(DocumentFragment* frag) , m_requestingScript(false) , m_hasScriptsWaitingForStylesheets(false) , m_timer(this, &HTMLTokenizer::timerFired) + , m_externalScriptsTimer(this, &HTMLTokenizer::executeExternalScriptsTimerFired) , m_doc(frag->document()) - , m_parser(new HTMLParser(frag)) + , m_parser(new HTMLParser(frag, scriptingPermission)) , m_inWrite(false) , m_fragment(true) + , m_scriptingPermission(scriptingPermission) { begin(); } @@ -236,6 +242,8 @@ void HTMLTokenizer::reset() m_scriptCodeSize = m_scriptCodeCapacity = m_scriptCodeResync = 0; m_timer.stop(); + m_externalScriptsTimer.stop(); + m_state.setAllowYield(false); m_state.setForceSynchronous(false); @@ -467,6 +475,13 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state) state = processListing(SegmentedString(m_scriptCode, m_scriptCodeSize), state); RefPtr<Node> node = processToken(); + + if (node && m_scriptingPermission == FragmentScriptingNotAllowed) { + ExceptionCode ec; + node->remove(ec); + node = 0; + } + String scriptString = node ? node->textContent() : ""; m_currentToken.tagName = scriptTag.localName(); m_currentToken.beginTag = false; @@ -1508,7 +1523,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString& src, State state) m_scriptTagSrcAttrValue = String(); m_scriptTagCharsetAttrValue = String(); if (m_currentToken.attrs && !m_fragment) { - if (m_doc->frame() && m_doc->frame()->script()->isEnabled()) { + if (m_doc->frame() && m_doc->frame()->script()->canExecuteScripts()) { if ((a = m_currentToken.attrs->getAttributeItem(srcAttr))) m_scriptTagSrcAttrValue = m_doc->completeURL(deprecatedParseURL(a->value())).string(); } @@ -1682,7 +1697,7 @@ void HTMLTokenizer::write(const SegmentedString& str, bool appendData) #if ENABLE(INSPECTOR) if (InspectorTimelineAgent* timelineAgent = m_doc->inspectorTimelineAgent()) - timelineAgent->willWriteHTML(); + timelineAgent->willWriteHTML(source.length(), m_lineNumber); #endif Frame* frame = m_doc->frame(); @@ -1808,7 +1823,7 @@ void HTMLTokenizer::write(const SegmentedString& str, bool appendData) #if ENABLE(INSPECTOR) if (InspectorTimelineAgent* timelineAgent = m_doc->inspectorTimelineAgent()) - timelineAgent->didWriteHTML(); + timelineAgent->didWriteHTML(m_lineNumber); #endif m_inWrite = wasInWrite; @@ -1822,8 +1837,8 @@ void HTMLTokenizer::write(const SegmentedString& str, bool appendData) if (m_noMoreData && !m_inWrite && !state.loadingExtScript() && !m_executingScript && !m_timer.isActive()) end(); // this actually causes us to be deleted - // After parsing, go ahead and dispatch image beforeload/load events. - ImageLoader::dispatchPendingEvents(); + // After parsing, go ahead and dispatch image beforeload events. + ImageLoader::dispatchPendingBeforeLoadEvents(); } void HTMLTokenizer::stopParsing() @@ -1925,7 +1940,7 @@ void HTMLTokenizer::finish() PassRefPtr<Node> HTMLTokenizer::processToken() { ScriptController* scriptController = (!m_fragment && m_doc->frame()) ? m_doc->frame()->script() : 0; - if (scriptController && scriptController->isEnabled()) + if (scriptController && scriptController->canExecuteScripts()) // FIXME: Why isn't this m_currentScriptTagStartLineNumber? I suspect this is wrong. scriptController->setEventHandlerLineNumber(m_currentTagStartLineNumber + 1); // Script line numbers are 1 based. if (m_dest > m_buffer) { @@ -2026,6 +2041,11 @@ void HTMLTokenizer::executeScriptsWaitingForStylesheets() void HTMLTokenizer::notifyFinished(CachedResource*) { + executeExternalScriptsIfReady(); +} + +void HTMLTokenizer::executeExternalScriptsIfReady() +{ #ifdef INSTRUMENT_LAYOUT_SCHEDULING if (!m_doc->ownerElement()) printf("script loaded at %d\n", m_doc->elapsedTime()); @@ -2040,7 +2060,12 @@ void HTMLTokenizer::notifyFinished(CachedResource*) return; bool finished = false; + + double startTime = currentTime(); while (!finished && m_pendingScripts.first()->isLoaded()) { + if (!continueExecutingExternalScripts(startTime)) + break; + CachedScript* cs = m_pendingScripts.first().get(); m_pendingScripts.removeFirst(); ASSERT(cache()->disabled() || cs->accessCount() > 0); @@ -2100,6 +2125,31 @@ void HTMLTokenizer::notifyFinished(CachedResource*) } } +void HTMLTokenizer::executeExternalScriptsTimerFired(Timer<HTMLTokenizer>*) +{ + if (m_doc->view() && m_doc->view()->layoutPending() && !m_doc->minimumLayoutDelay()) { + // Restart the timer and do layout first. + m_externalScriptsTimer.startOneShot(0); + return; + } + + // Continue executing external scripts. + executeExternalScriptsIfReady(); +} + +bool HTMLTokenizer::continueExecutingExternalScripts(double startTime) +{ + if (m_externalScriptsTimer.isActive()) + return false; + + if (currentTime() - startTime > m_tokenizerTimeDelay) { + // Schedule the timer to keep processing as soon as possible. + m_externalScriptsTimer.startOneShot(0); + return false; + } + return true; +} + bool HTMLTokenizer::isWaitingForScripts() const { return m_state.loadingExtScript(); @@ -2110,9 +2160,9 @@ void HTMLTokenizer::setSrc(const SegmentedString& source) m_src = source; } -void parseHTMLDocumentFragment(const String& source, DocumentFragment* fragment) +void parseHTMLDocumentFragment(const String& source, DocumentFragment* fragment, FragmentScriptingPermission scriptingPermission) { - HTMLTokenizer tok(fragment); + HTMLTokenizer tok(fragment, scriptingPermission); tok.setForceSynchronous(true); tok.write(source, true); tok.finish(); diff --git a/WebCore/html/HTMLTokenizer.h b/WebCore/html/HTMLTokenizer.h index d731b2d..ef7cbfc 100644 --- a/WebCore/html/HTMLTokenizer.h +++ b/WebCore/html/HTMLTokenizer.h @@ -27,6 +27,7 @@ #include "CachedResourceClient.h" #include "CachedResourceHandle.h" #include "NamedMappedAttrMap.h" +#include "MappedAttributeEntry.h" #include "SegmentedString.h" #include "Timer.h" #include "Tokenizer.h" @@ -135,7 +136,7 @@ class HTMLTokenizer : public Tokenizer, public CachedResourceClient { public: HTMLTokenizer(HTMLDocument*, bool reportErrors); HTMLTokenizer(HTMLViewSourceDocument*); - HTMLTokenizer(DocumentFragment*); + HTMLTokenizer(DocumentFragment*, FragmentScriptingPermission = FragmentScriptingAllowed); virtual ~HTMLTokenizer(); virtual void write(const SegmentedString&, bool appendData); @@ -205,6 +206,10 @@ private: // from CachedResourceClient void notifyFinished(CachedResource*); + void executeExternalScriptsIfReady(); + void executeExternalScriptsTimerFired(Timer<HTMLTokenizer>*); + bool continueExecutingExternalScripts(double startTime); + // Internal buffers /////////////////// UChar* m_buffer; @@ -401,6 +406,9 @@ private: // The timer for continued processing. Timer<HTMLTokenizer> m_timer; + // The timer for continued executing external scripts. + Timer<HTMLTokenizer> m_externalScriptsTimer; + // This buffer can hold arbitrarily long user-defined attribute names, such as in EMBED tags. // So any fixed number might be too small, but rather than rewriting all usage of this buffer // we'll just make it large enough to handle all imaginable cases. @@ -413,11 +421,12 @@ private: OwnPtr<HTMLParser> m_parser; bool m_inWrite; bool m_fragment; + FragmentScriptingPermission m_scriptingPermission; OwnPtr<PreloadScanner> m_preloadScanner; }; -void parseHTMLDocumentFragment(const String&, DocumentFragment*); +void parseHTMLDocumentFragment(const String&, DocumentFragment*, FragmentScriptingPermission = FragmentScriptingAllowed); UChar decodeNamedEntity(const char*); diff --git a/WebCore/html/HTMLUListElement.idl b/WebCore/html/HTMLUListElement.idl index c49b058..38434f1 100644 --- a/WebCore/html/HTMLUListElement.idl +++ b/WebCore/html/HTMLUListElement.idl @@ -19,11 +19,7 @@ module html { - interface [ - GenerateConstructor, - InterfaceUUID=6877dee4-be67-4fb0-af8c-5023b108a1b0, - ImplementationUUID=23e9c21a-618e-42ac-a053-df85918118df - ] HTMLUListElement : HTMLElement { + interface HTMLUListElement : HTMLElement { attribute boolean compact; attribute [ConvertNullToNullString] DOMString type; }; diff --git a/WebCore/html/HTMLVideoElement.cpp b/WebCore/html/HTMLVideoElement.cpp index d0b1042..1fae354 100644 --- a/WebCore/html/HTMLVideoElement.cpp +++ b/WebCore/html/HTMLVideoElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,6 +28,7 @@ #if ENABLE(VIDEO) #include "HTMLVideoElement.h" +#include "Chrome.h" #include "ChromeClient.h" #include "CSSHelper.h" #include "CSSPropertyNames.h" @@ -45,11 +46,11 @@ using namespace HTMLNames; HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* doc) : HTMLMediaElement(tagName, doc) - , m_shouldShowPosterImage(false) + , m_shouldDisplayPosterImage(false) { ASSERT(hasTagName(videoTag)); } - + bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style) { return HTMLElement::rendererIsNeeded(style); @@ -58,8 +59,6 @@ bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style) #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*) { - if (m_shouldShowPosterImage) - return new (arena) RenderImage(this); return new (arena) RenderVideo(this); } #endif @@ -69,11 +68,12 @@ void HTMLVideoElement::attach() HTMLMediaElement::attach(); #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) - if (m_shouldShowPosterImage) { + updatePosterImage(); + if (m_shouldDisplayPosterImage) { if (!m_imageLoader) m_imageLoader.set(new HTMLImageLoader(this)); m_imageLoader->updateFromElement(); - if (renderer() && renderer()->isImage()) { + if (renderer()) { RenderImage* imageRenderer = toRenderImage(renderer()); imageRenderer->setCachedImage(m_imageLoader->image()); } @@ -85,7 +85,7 @@ void HTMLVideoElement::detach() { HTMLMediaElement::detach(); - if (!m_shouldShowPosterImage) + if (!m_shouldDisplayPosterImage) if (m_imageLoader) m_imageLoader.clear(); } @@ -95,8 +95,9 @@ void HTMLVideoElement::parseMappedAttribute(MappedAttribute* attr) const QualifiedName& attrName = attr->name(); if (attrName == posterAttr) { + m_posterURL = document()->completeURL(attr->value()); updatePosterImage(); - if (m_shouldShowPosterImage) { + if (m_shouldDisplayPosterImage) { #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) if (!m_imageLoader) m_imageLoader.set(new HTMLImageLoader(this)); @@ -165,11 +166,6 @@ void HTMLVideoElement::setHeight(unsigned value) setAttribute(heightAttr, String::number(value)); } -KURL HTMLVideoElement::poster() const -{ - return document()->completeURL(getAttribute(posterAttr)); -} - void HTMLVideoElement::setPoster(const String& value) { setAttribute(posterAttr, value); @@ -188,16 +184,14 @@ const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const void HTMLVideoElement::updatePosterImage() { #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) - bool oldShouldShowPosterImage = m_shouldShowPosterImage; + bool oldShouldShowPosterImage = m_shouldDisplayPosterImage; #endif - m_shouldShowPosterImage = !poster().isEmpty() && readyState() < HAVE_CURRENT_DATA; + m_shouldDisplayPosterImage = !poster().isEmpty() && !hasAvailableVideoFrame(); #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) - if (attached() && oldShouldShowPosterImage != m_shouldShowPosterImage) { - detach(); - attach(); - } + if (renderer() && oldShouldShowPosterImage != m_shouldDisplayPosterImage) + renderer()->updateFromElement(); #endif } @@ -225,5 +219,13 @@ void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, cons player->paintCurrentFrameInContext(context, destRect); } +bool HTMLVideoElement::hasAvailableVideoFrame() const +{ + if (!m_player) + return false; + + return m_player->hasAvailableVideoFrame(); +} + } #endif diff --git a/WebCore/html/HTMLVideoElement.h b/WebCore/html/HTMLVideoElement.h index 096eb53..834ec4c 100644 --- a/WebCore/html/HTMLVideoElement.h +++ b/WebCore/html/HTMLVideoElement.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,7 +38,7 @@ class HTMLImageLoader; class HTMLVideoElement : public HTMLMediaElement { public: HTMLVideoElement(const QualifiedName&, Document*); - + virtual int tagPriority() const { return 5; } virtual bool rendererIsNeeded(RenderStyle*); #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) @@ -61,18 +61,22 @@ public: unsigned videoWidth() const; unsigned videoHeight() const; - KURL poster() const; + const KURL& poster() const { return m_posterURL; } void setPoster(const String&); void updatePosterImage(); + bool shouldDisplayPosterImage() const { return m_shouldDisplayPosterImage; } void paint(GraphicsContext*, const IntRect&); // Used by canvas to gain raw pixel access void paintCurrentFrameInContext(GraphicsContext*, const IntRect&); private: + virtual bool hasAvailableVideoFrame() const; + OwnPtr<HTMLImageLoader> m_imageLoader; - bool m_shouldShowPosterImage; + KURL m_posterURL; + bool m_shouldDisplayPosterImage; }; } //namespace diff --git a/WebCore/html/HTMLVideoElement.idl b/WebCore/html/HTMLVideoElement.idl index c78594f..f43bf82 100644 --- a/WebCore/html/HTMLVideoElement.idl +++ b/WebCore/html/HTMLVideoElement.idl @@ -24,7 +24,7 @@ */ module html { - interface [GenerateConstructor, Conditional=VIDEO] HTMLVideoElement : HTMLMediaElement { + interface [Conditional=VIDEO] HTMLVideoElement : HTMLMediaElement { attribute unsigned long width; attribute unsigned long height; readonly attribute unsigned long videoWidth; diff --git a/WebCore/html/ImageData.idl b/WebCore/html/ImageData.idl index 8025de1..a5e2467 100644 --- a/WebCore/html/ImageData.idl +++ b/WebCore/html/ImageData.idl @@ -29,8 +29,7 @@ module html { interface [ - CustomToJS, - GenerateConstructor, + CustomToJS ] ImageData { readonly attribute long width; readonly attribute long height; diff --git a/WebCore/html/MediaError.idl b/WebCore/html/MediaError.idl index 4dcea7d..9d6f3bd 100644 --- a/WebCore/html/MediaError.idl +++ b/WebCore/html/MediaError.idl @@ -24,7 +24,7 @@ */ module html { - interface [GenerateConstructor, Conditional=VIDEO] MediaError { + interface [Conditional=VIDEO] MediaError { const unsigned short MEDIA_ERR_ABORTED = 1; const unsigned short MEDIA_ERR_NETWORK = 2; const unsigned short MEDIA_ERR_DECODE = 3; diff --git a/WebCore/html/TextMetrics.idl b/WebCore/html/TextMetrics.idl index dc88716..1a315ba 100644 --- a/WebCore/html/TextMetrics.idl +++ b/WebCore/html/TextMetrics.idl @@ -25,9 +25,7 @@ module html { - interface [ - GenerateConstructor - ] TextMetrics { + interface TextMetrics { readonly attribute float width; }; diff --git a/WebCore/html/TimeRanges.idl b/WebCore/html/TimeRanges.idl index d8686be..992b12a 100644 --- a/WebCore/html/TimeRanges.idl +++ b/WebCore/html/TimeRanges.idl @@ -25,7 +25,7 @@ module html { -interface [Conditional=VIDEO] TimeRanges { +interface [Conditional=VIDEO, OmitConstructor] TimeRanges { readonly attribute unsigned long length; float start(in unsigned long index) raises (DOMException); diff --git a/WebCore/html/ValidityState.cpp b/WebCore/html/ValidityState.cpp index e7df225..1e0a07b 100644 --- a/WebCore/html/ValidityState.cpp +++ b/WebCore/html/ValidityState.cpp @@ -2,6 +2,7 @@ * This file is part of the WebKit project. * * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com> + * Copyright (C) 2010 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -30,23 +31,18 @@ #include "RegularExpression.h" #include <wtf/StdLibExtras.h> -#define EMAIL_LOCALPART "[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" -#define EMAIL_DOMAINPART "[a-z0-9-]+(\\.[a-z0-9-]+)+" -#define EMAIL_PATTERN EMAIL_LOCALPART "@" EMAIL_DOMAINPART - namespace WebCore { using namespace HTMLNames; -ValidityState::ValidityState(HTMLFormControlElement* parent) - : m_control(parent) -{ - ASSERT(parent); -} +static const char emailPattern[] = + "[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part + "@" + "[a-z0-9-]+(\\.[a-z0-9-]+)+"; // domain part -String ValidityState::validationMessage() +String ValidityState::validationMessage() const { - if (!control()->willValidate()) + if (!m_control->willValidate()) return String(); if (customError()) @@ -69,12 +65,12 @@ String ValidityState::validationMessage() return String(); } -bool ValidityState::typeMismatch() +bool ValidityState::typeMismatch() const { - if (!control()->hasTagName(inputTag)) + if (!m_control->hasTagName(inputTag)) return false; - HTMLInputElement* input = static_cast<HTMLInputElement*>(control()); + HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control); String value = input->value(); if (value.isEmpty()) @@ -87,17 +83,15 @@ bool ValidityState::typeMismatch() return !HTMLInputElement::formStringToDouble(value, 0); case HTMLInputElement::URL: return !KURL(KURL(), value).isValid(); - case HTMLInputElement::EMAIL: - { + case HTMLInputElement::EMAIL: { if (!input->multiple()) return !isValidEmailAddress(value); - - Vector<String> email_list; - value.split(',', email_list); - for (unsigned i = 0; i < email_list.size(); ++i) - if (!isValidEmailAddress(email_list[i])) + Vector<String> addresses; + value.split(',', addresses); + for (unsigned i = 0; i < addresses.size(); ++i) { + if (!isValidEmailAddress(addresses[i])) return true; - + } return false; } case HTMLInputElement::DATE: @@ -106,38 +100,53 @@ bool ValidityState::typeMismatch() case HTMLInputElement::MONTH: case HTMLInputElement::TIME: case HTMLInputElement::WEEK: - return !HTMLInputElement::formStringToISODateTime(input->inputType(), value, 0); - default: + return !HTMLInputElement::formStringToDateComponents(input->inputType(), value, 0); + case HTMLInputElement::BUTTON: + case HTMLInputElement::CHECKBOX: + case HTMLInputElement::FILE: + case HTMLInputElement::HIDDEN: + case HTMLInputElement::IMAGE: + case HTMLInputElement::ISINDEX: + case HTMLInputElement::PASSWORD: + case HTMLInputElement::RADIO: + case HTMLInputElement::RANGE: + case HTMLInputElement::RESET: + case HTMLInputElement::SEARCH: + case HTMLInputElement::SUBMIT: + case HTMLInputElement::TELEPHONE: // FIXME: Is there validation for <input type=telephone>? + case HTMLInputElement::TEXT: return false; } + + ASSERT_NOT_REACHED(); + return false; } -bool ValidityState::rangeUnderflow() +bool ValidityState::rangeUnderflow() const { - if (!control()->hasTagName(inputTag)) + if (!m_control->hasTagName(inputTag)) return false; - return static_cast<HTMLInputElement*>(control())->rangeUnderflow(); + return static_cast<HTMLInputElement*>(m_control)->rangeUnderflow(); } -bool ValidityState::rangeOverflow() +bool ValidityState::rangeOverflow() const { - if (!control()->hasTagName(inputTag)) + if (!m_control->hasTagName(inputTag)) return false; - return static_cast<HTMLInputElement*>(control())->rangeOverflow(); + return static_cast<HTMLInputElement*>(m_control)->rangeOverflow(); } -bool ValidityState::stepMismatch() +bool ValidityState::stepMismatch() const { - if (!control()->hasTagName(inputTag)) + if (!m_control->hasTagName(inputTag)) return false; - return static_cast<HTMLInputElement*>(control())->stepMismatch(); + return static_cast<HTMLInputElement*>(m_control)->stepMismatch(); } -bool ValidityState::valid() +bool ValidityState::valid() const { - bool someError = typeMismatch() || stepMismatch() || rangeUnderflow() || rangeOverflow() || - tooLong() || patternMismatch() || valueMissing() || customError(); - + bool someError = typeMismatch() || stepMismatch() || rangeUnderflow() || rangeOverflow() + || tooLong() || patternMismatch() || valueMissing() || customError(); return !someError; } @@ -154,19 +163,18 @@ bool ValidityState::isValidColorString(const String& value) return color.isValid() && !color.hasAlpha(); } -bool ValidityState::isValidEmailAddress(const String& email) +bool ValidityState::isValidEmailAddress(const String& address) { - if (email.isEmpty()) + int addressLength = address.length(); + if (!addressLength) return false; - DEFINE_STATIC_LOCAL(AtomicString, emailPattern, (EMAIL_PATTERN)); - DEFINE_STATIC_LOCAL(RegularExpression, regExp, (emailPattern, TextCaseInsensitive)); + DEFINE_STATIC_LOCAL(const RegularExpression, regExp, (emailPattern, TextCaseInsensitive)); - int matchLength = 0; - int emailLength = email.length(); - int matchOffset = regExp.match(email, 0, &matchLength); + int matchLength; + int matchOffset = regExp.match(address, 0, &matchLength); - return matchOffset == 0 && matchLength == emailLength; + return matchOffset == 0 && matchLength == addressLength; } } // namespace diff --git a/WebCore/html/ValidityState.h b/WebCore/html/ValidityState.h index 7ae95d7..78238f1 100644 --- a/WebCore/html/ValidityState.h +++ b/WebCore/html/ValidityState.h @@ -2,6 +2,7 @@ * This file is part of the WebKit project. * * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com> + * Copyright (C) 2010 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,41 +25,43 @@ #define ValidityState_h #include "HTMLFormControlElement.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> +#include <wtf/PassOwnPtr.h> namespace WebCore { - class ValidityState : public RefCounted<ValidityState> { - public: - static PassRefPtr<ValidityState> create(HTMLFormControlElement* owner) - { - return adoptRef(new ValidityState(owner)); - } +class ValidityState : public Noncopyable { +public: + static PassOwnPtr<ValidityState> create(HTMLFormControlElement* control) + { + return new ValidityState(control); + } - HTMLFormControlElement* control() const { return m_control; } + void ref() { m_control->ref(); } + void deref() { m_control->deref(); } - String validationMessage(); - void setCustomErrorMessage(const String& message) { m_customErrorMessage = message; } + String validationMessage() const; - bool valueMissing() { return control()->valueMissing(); } - bool typeMismatch(); - bool patternMismatch() { return control()->patternMismatch(); } - bool tooLong() { return control()->tooLong(); } - bool rangeUnderflow(); - bool rangeOverflow(); - bool stepMismatch(); - bool customError() { return !m_customErrorMessage.isEmpty(); } - bool valid(); + void setCustomErrorMessage(const String& message) { m_customErrorMessage = message; } - private: - ValidityState(HTMLFormControlElement*); - HTMLFormControlElement* m_control; - String m_customErrorMessage; + bool valueMissing() const { return m_control->valueMissing(); } + bool typeMismatch() const; + bool patternMismatch() const { return m_control->patternMismatch(); } + bool tooLong() const { return m_control->tooLong(); } + bool rangeUnderflow() const; + bool rangeOverflow() const; + bool stepMismatch() const; + bool customError() const { return !m_customErrorMessage.isEmpty(); } + bool valid() const; - static bool isValidColorString(const String&); - bool isValidEmailAddress(const String&); - }; +private: + ValidityState(HTMLFormControlElement* control) : m_control(control) { } + + static bool isValidColorString(const String&); + static bool isValidEmailAddress(const String&); + + HTMLFormControlElement* m_control; + String m_customErrorMessage; +}; } // namespace WebCore diff --git a/WebCore/html/ValidityState.idl b/WebCore/html/ValidityState.idl index b926852..576fab4 100644 --- a/WebCore/html/ValidityState.idl +++ b/WebCore/html/ValidityState.idl @@ -22,7 +22,7 @@ module html { - interface ValidityState { + interface [OmitConstructor] ValidityState { readonly attribute boolean valueMissing; readonly attribute boolean typeMismatch; readonly attribute boolean patternMismatch; diff --git a/WebCore/html/VoidCallback.idl b/WebCore/html/VoidCallback.idl index 3682cf7..8a7cf19 100644 --- a/WebCore/html/VoidCallback.idl +++ b/WebCore/html/VoidCallback.idl @@ -24,7 +24,7 @@ */ module html { - interface [CustomNativeConverter] VoidCallback { + interface [CustomNativeConverter, OmitConstructor] VoidCallback { void handleEvent(); }; } diff --git a/WebCore/html/canvas/CanvasContextAttributes.cpp b/WebCore/html/canvas/CanvasContextAttributes.cpp new file mode 100644 index 0000000..d3d0398 --- /dev/null +++ b/WebCore/html/canvas/CanvasContextAttributes.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "CanvasContextAttributes.h" + +namespace WebCore { + +CanvasContextAttributes::CanvasContextAttributes() +{ +} + +CanvasContextAttributes::~CanvasContextAttributes() +{ +} + +} // namespace WebCore diff --git a/WebCore/html/canvas/CanvasContextAttributes.h b/WebCore/html/canvas/CanvasContextAttributes.h new file mode 100644 index 0000000..97483b3 --- /dev/null +++ b/WebCore/html/canvas/CanvasContextAttributes.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CanvasContextAttributes_h +#define CanvasContextAttributes_h + +#include <wtf/RefCounted.h> + +namespace WebCore { + +// A base class for any attributes that are needed which would affect +// the creation of the Canvas's rendering context. Currently only the +// WebGLRenderingContext uses this mechanism. + +class CanvasContextAttributes : public RefCounted<CanvasContextAttributes> { + public: + virtual ~CanvasContextAttributes(); + + protected: + CanvasContextAttributes(); +}; + +} // namespace WebCore + +#endif // CanvasContextAttributes_h diff --git a/WebCore/html/canvas/CanvasGradient.idl b/WebCore/html/canvas/CanvasGradient.idl index a925a26..32813bc 100644 --- a/WebCore/html/canvas/CanvasGradient.idl +++ b/WebCore/html/canvas/CanvasGradient.idl @@ -27,7 +27,8 @@ module html { interface [ InterfaceUUID=bb1108ea-6b8c-4a08-894a-218628630cdb, - ImplementationUUID=a2942ae6-2731-4286-98cc-9d5e79e20de1 + ImplementationUUID=a2942ae6-2731-4286-98cc-9d5e79e20de1, + OmitConstructor ] CanvasGradient { void addColorStop(in float offset, in DOMString color) diff --git a/WebCore/html/canvas/CanvasNumberArray.idl b/WebCore/html/canvas/CanvasNumberArray.idl index 56e807e..036d4ee 100644 --- a/WebCore/html/canvas/CanvasNumberArray.idl +++ b/WebCore/html/canvas/CanvasNumberArray.idl @@ -26,7 +26,6 @@ module html { interface [ Conditional=3D_CANVAS, - GenerateConstructor, HasCustomIndexGetter ] CanvasNumberArray { readonly attribute unsigned long length; diff --git a/WebCore/html/canvas/CanvasPattern.idl b/WebCore/html/canvas/CanvasPattern.idl index 1cac8f8..492c93f 100644 --- a/WebCore/html/canvas/CanvasPattern.idl +++ b/WebCore/html/canvas/CanvasPattern.idl @@ -27,7 +27,8 @@ module html { interface [ InterfaceUUID=c2131348-6d8c-47b5-86cc-d41aff34ce15, - ImplementationUUID=82f5d713-3d17-44dd-aa4a-7766fe345940 + ImplementationUUID=82f5d713-3d17-44dd-aa4a-7766fe345940, + OmitConstructor ] CanvasPattern { }; diff --git a/WebCore/html/canvas/CanvasPixelArray.idl b/WebCore/html/canvas/CanvasPixelArray.idl index 2295af6..60726cd 100644 --- a/WebCore/html/canvas/CanvasPixelArray.idl +++ b/WebCore/html/canvas/CanvasPixelArray.idl @@ -29,6 +29,7 @@ module html { #if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT || defined(V8_BINDING) && V8_BINDING interface [ + OmitConstructor, CustomHeader, HasNumericIndexGetter, HasCustomIndexSetter diff --git a/WebCore/html/canvas/CanvasRenderingContext.idl b/WebCore/html/canvas/CanvasRenderingContext.idl index 8701c80..a11aa75 100644 --- a/WebCore/html/canvas/CanvasRenderingContext.idl +++ b/WebCore/html/canvas/CanvasRenderingContext.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, CustomToJS, InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443, ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54 diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp index 1ae9f75..1e09534 100644 --- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -42,7 +42,6 @@ #include "Document.h" #include "ExceptionCode.h" #include "FloatConversion.h" -#include "Frame.h" #include "GraphicsContext.h" #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.idl b/WebCore/html/canvas/CanvasRenderingContext2D.idl index ef66d1a..f93a752 100644 --- a/WebCore/html/canvas/CanvasRenderingContext2D.idl +++ b/WebCore/html/canvas/CanvasRenderingContext2D.idl @@ -26,7 +26,6 @@ module html { interface [ - GenerateConstructor, InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443, ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54 ] CanvasRenderingContext2D : CanvasRenderingContext { diff --git a/WebCore/html/canvas/WebGLActiveInfo.idl b/WebCore/html/canvas/WebGLActiveInfo.idl index a3f79b8..17bb4d6 100644 --- a/WebCore/html/canvas/WebGLActiveInfo.idl +++ b/WebCore/html/canvas/WebGLActiveInfo.idl @@ -27,6 +27,7 @@ module html { interface [ Conditional=3D_CANVAS, + OmitConstructor ] WebGLActiveInfo { readonly attribute int size; readonly attribute unsigned int type; diff --git a/WebCore/html/canvas/WebGLArray.idl b/WebCore/html/canvas/WebGLArray.idl index 156ca5b..02e1f51 100644 --- a/WebCore/html/canvas/WebGLArray.idl +++ b/WebCore/html/canvas/WebGLArray.idl @@ -24,7 +24,7 @@ */ module html { - interface [Conditional=3D_CANVAS, CustomToJS] WebGLArray { + interface [Conditional=3D_CANVAS, CustomToJS, OmitConstructor] WebGLArray { readonly attribute WebGLArrayBuffer buffer; readonly attribute unsigned long byteOffset; readonly attribute unsigned long byteLength; diff --git a/WebCore/html/canvas/WebGLArrayBuffer.idl b/WebCore/html/canvas/WebGLArrayBuffer.idl index ec4a67a..3325210 100644 --- a/WebCore/html/canvas/WebGLArrayBuffer.idl +++ b/WebCore/html/canvas/WebGLArrayBuffer.idl @@ -24,7 +24,7 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLArrayBuffer { + interface [Conditional=3D_CANVAS, CustomConstructor] WebGLArrayBuffer { readonly attribute int byteLength; }; } diff --git a/WebCore/html/canvas/WebGLBuffer.cpp b/WebCore/html/canvas/WebGLBuffer.cpp index cbad6a0..958bedc 100644 --- a/WebCore/html/canvas/WebGLBuffer.cpp +++ b/WebCore/html/canvas/WebGLBuffer.cpp @@ -46,15 +46,18 @@ WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx) : CanvasObject(ctx) , m_elementArrayBufferByteLength(0) , m_arrayBufferByteLength(0) - , m_elementArrayBufferCloned(false) + , m_nextAvailableCacheEntry(0) { setObject(context()->graphicsContext3D()->createBuffer()); + clearCachedMaxIndices(); } WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx, Platform3DObject obj) : CanvasObject(ctx) + , m_nextAvailableCacheEntry(0) { setObject(obj, false); + clearCachedMaxIndices(); } void WebGLBuffer::_deleteObject(Platform3DObject object) @@ -83,9 +86,12 @@ bool WebGLBuffer::associateBufferData(unsigned long target, WebGLArray* array) return false; if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER) { + clearCachedMaxIndices(); m_elementArrayBufferByteLength = array->byteLength(); - m_elementArrayBuffer = array->buffer(); - m_elementArrayBufferCloned = false; + // We must always clone the incoming data because client-side + // modifications without calling bufferData or bufferSubData + // must never be able to change the validation results. + m_elementArrayBuffer = WebGLArrayBuffer::create(array->buffer().get()); return true; } @@ -103,6 +109,8 @@ bool WebGLBuffer::associateBufferSubData(unsigned long target, long offset, WebG return false; if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER) { + clearCachedMaxIndices(); + // We need to protect against integer overflow with these tests if (offset < 0) return false; @@ -111,12 +119,6 @@ bool WebGLBuffer::associateBufferSubData(unsigned long target, long offset, WebG if (uoffset > m_elementArrayBufferByteLength || array->byteLength() > m_elementArrayBufferByteLength - uoffset) return false; - // If we already have a buffer, we need to clone it and add the new data - if (m_elementArrayBuffer && !m_elementArrayBufferCloned) { - m_elementArrayBuffer = WebGLArrayBuffer::create(m_elementArrayBuffer.get()); - m_elementArrayBufferCloned = true; - } - memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()) + offset, array->baseAddress(), array->byteLength()); return true; } @@ -132,6 +134,33 @@ unsigned WebGLBuffer::byteLength(unsigned long target) const return (target == GraphicsContext3D::ARRAY_BUFFER) ? m_arrayBufferByteLength : m_elementArrayBufferByteLength; } +long WebGLBuffer::getCachedMaxIndex(unsigned long type) +{ + size_t numEntries = sizeof(m_maxIndexCache) / sizeof(MaxIndexCacheEntry); + for (size_t i = 0; i < numEntries; i++) + if (m_maxIndexCache[i].type == type) + return m_maxIndexCache[i].maxIndex; + return -1; +} + +void WebGLBuffer::setCachedMaxIndex(unsigned long type, long value) +{ + int numEntries = sizeof(m_maxIndexCache) / sizeof(MaxIndexCacheEntry); + for (int i = 0; i < numEntries; i++) + if (m_maxIndexCache[i].type == type) { + m_maxIndexCache[i].maxIndex = value; + return; + } + m_maxIndexCache[m_nextAvailableCacheEntry].type = type; + m_maxIndexCache[m_nextAvailableCacheEntry].maxIndex = value; + m_nextAvailableCacheEntry = (m_nextAvailableCacheEntry + 1) % numEntries; +} + +void WebGLBuffer::clearCachedMaxIndices() +{ + memset(m_maxIndexCache, 0, sizeof(m_maxIndexCache)); +} + } #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/html/canvas/WebGLBuffer.h b/WebCore/html/canvas/WebGLBuffer.h index cb953c6..bdb7052 100644 --- a/WebCore/html/canvas/WebGLBuffer.h +++ b/WebCore/html/canvas/WebGLBuffer.h @@ -51,6 +51,12 @@ namespace WebCore { unsigned byteLength(unsigned long target) const; const WebGLArrayBuffer* elementArrayBuffer() const { return m_elementArrayBuffer.get(); } + // Gets the cached max index for the given type. Returns -1 if + // none has been set. + long getCachedMaxIndex(unsigned long type); + // Sets the cached max index for the given type. + void setCachedMaxIndex(unsigned long type, long value); + protected: WebGLBuffer(WebGLRenderingContext*); WebGLBuffer(WebGLRenderingContext*, Platform3DObject obj); @@ -61,7 +67,26 @@ namespace WebCore { RefPtr<WebGLArrayBuffer> m_elementArrayBuffer; unsigned m_elementArrayBufferByteLength; unsigned m_arrayBufferByteLength; - bool m_elementArrayBufferCloned; + + // Optimization for index validation. For each type of index + // (i.e., UNSIGNED_SHORT), cache the maximum index in the + // entire buffer. + // + // This is sufficient to eliminate a lot of work upon each + // draw call as long as all bound array buffers are at least + // that size. + struct MaxIndexCacheEntry { + unsigned long type; + long maxIndex; + }; + // OpenGL ES 2.0 only has two valid index types (UNSIGNED_BYTE + // and UNSIGNED_SHORT), but might as well leave open the + // possibility of adding others. + MaxIndexCacheEntry m_maxIndexCache[4]; + unsigned m_nextAvailableCacheEntry; + + // Clears all of the cached max indices. + void clearCachedMaxIndices(); }; } // namespace WebCore diff --git a/WebCore/html/canvas/WebGLBuffer.idl b/WebCore/html/canvas/WebGLBuffer.idl index 30b7606..9dd97c0 100644 --- a/WebCore/html/canvas/WebGLBuffer.idl +++ b/WebCore/html/canvas/WebGLBuffer.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLBuffer { + interface [Conditional=3D_CANVAS, OmitConstructor] WebGLBuffer { }; } diff --git a/WebCore/html/canvas/WebGLByteArray.idl b/WebCore/html/canvas/WebGLByteArray.idl index 054a912..dbb3bb2 100644 --- a/WebCore/html/canvas/WebGLByteArray.idl +++ b/WebCore/html/canvas/WebGLByteArray.idl @@ -30,7 +30,7 @@ module html { HasNumericIndexGetter, HasCustomIndexSetter, GenerateNativeConverter, - GenerateCustomConstructor, + CustomConstructor, CustomToJS ] WebGLByteArray : WebGLArray { long get(in unsigned long index); diff --git a/WebCore/html/canvas/WebGLContextAttributes.cpp b/WebCore/html/canvas/WebGLContextAttributes.cpp new file mode 100644 index 0000000..a0725ca --- /dev/null +++ b/WebCore/html/canvas/WebGLContextAttributes.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(3D_CANVAS) + +#include "WebGLContextAttributes.h" + +namespace WebCore { + +PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create() +{ + return adoptRef(new WebGLContextAttributes()); +} + +PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create(GraphicsContext3D::Attributes attributes) +{ + return adoptRef(new WebGLContextAttributes(attributes)); +} + +WebGLContextAttributes::WebGLContextAttributes() + : CanvasContextAttributes() +{ +} + +WebGLContextAttributes::WebGLContextAttributes(GraphicsContext3D::Attributes attributes) + : CanvasContextAttributes() + , m_attrs(attributes) +{ +} + +WebGLContextAttributes::~WebGLContextAttributes() +{ +} + +bool WebGLContextAttributes::alpha() const +{ + return m_attrs.alpha; +} + +void WebGLContextAttributes::setAlpha(bool alpha) +{ + m_attrs.alpha = alpha; +} + +bool WebGLContextAttributes::depth() const +{ + return m_attrs.depth; +} + +void WebGLContextAttributes::setDepth(bool depth) +{ + m_attrs.depth = depth; +} + +bool WebGLContextAttributes::stencil() const +{ + return m_attrs.stencil; +} + +void WebGLContextAttributes::setStencil(bool stencil) +{ + m_attrs.stencil = stencil; +} + +bool WebGLContextAttributes::antialias() const +{ + return m_attrs.antialias; +} + +void WebGLContextAttributes::setAntialias(bool antialias) +{ + m_attrs.antialias = antialias; +} + +bool WebGLContextAttributes::premultipliedAlpha() const +{ + return m_attrs.premultipliedAlpha; +} + +void WebGLContextAttributes::setPremultipliedAlpha(bool premultipliedAlpha) +{ + m_attrs.premultipliedAlpha = premultipliedAlpha; +} + +GraphicsContext3D::Attributes WebGLContextAttributes::attributes() const +{ + return m_attrs; +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/html/canvas/WebGLContextAttributes.h b/WebCore/html/canvas/WebGLContextAttributes.h new file mode 100644 index 0000000..a108605 --- /dev/null +++ b/WebCore/html/canvas/WebGLContextAttributes.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebGLContextAttributes_h +#define WebGLContextAttributes_h + +#include "CanvasContextAttributes.h" +#include "GraphicsContext3D.h" +#include <wtf/PassRefPtr.h> + +namespace WebCore { + +class WebGLContextAttributes : public CanvasContextAttributes { + public: + virtual ~WebGLContextAttributes(); + + // Create a new attributes object + static PassRefPtr<WebGLContextAttributes> create(); + + // Create a new attributes object initialized with preexisting attributes + static PassRefPtr<WebGLContextAttributes> create(GraphicsContext3D::Attributes attributes); + + // Whether or not the drawing buffer has an alpha channel; default=true + bool alpha() const; + void setAlpha(bool alpha); + + // Whether or not the drawing buffer has a depth buffer; default=true + bool depth() const; + void setDepth(bool depth); + + // Whether or not the drawing buffer has a stencil buffer; default=true + bool stencil() const; + void setStencil(bool stencil); + + // Whether or not the drawing buffer is antialiased; default=true + bool antialias() const; + void setAntialias(bool antialias); + + // Whether or not to treat the values in the drawing buffer as + // though their alpha channel has already been multiplied into the + // color channels; default=true + bool premultipliedAlpha() const; + void setPremultipliedAlpha(bool premultipliedAlpha); + + // Fetches a copy of the attributes stored in this object in a + // form that can be used to initialize a GraphicsContext3D. + GraphicsContext3D::Attributes attributes() const; + + protected: + WebGLContextAttributes(); + WebGLContextAttributes(GraphicsContext3D::Attributes attributes); + + private: + GraphicsContext3D::Attributes m_attrs; +}; + +} // namespace WebCore + +#endif // WebGLContextAttributes_h diff --git a/WebCore/html/canvas/WebGLContextAttributes.idl b/WebCore/html/canvas/WebGLContextAttributes.idl new file mode 100644 index 0000000..be2b20c --- /dev/null +++ b/WebCore/html/canvas/WebGLContextAttributes.idl @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module html { + interface [ + Conditional=3D_CANVAS, + OmitConstructor + ] WebGLContextAttributes { + attribute boolean alpha; + attribute boolean depth; + attribute boolean stencil; + attribute boolean antialias; + attribute boolean premultipliedAlpha; + }; +} diff --git a/WebCore/html/canvas/WebGLFloatArray.idl b/WebCore/html/canvas/WebGLFloatArray.idl index 83479b3..e0a80f2 100644 --- a/WebCore/html/canvas/WebGLFloatArray.idl +++ b/WebCore/html/canvas/WebGLFloatArray.idl @@ -30,11 +30,11 @@ module html { HasNumericIndexGetter, HasCustomIndexSetter, GenerateNativeConverter, - GenerateCustomConstructor, + CustomConstructor, CustomToJS ] WebGLFloatArray : WebGLArray { - long get(in unsigned long index); - // void set(in unsigned long index, in long value); + float get(in unsigned long index); + // void set(in unsigned long index, in float value); // void set(in WebGLFloatArray array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); [Custom] void set(); diff --git a/WebCore/html/canvas/WebGLFramebuffer.idl b/WebCore/html/canvas/WebGLFramebuffer.idl index 8c1d9fd..f433352 100644 --- a/WebCore/html/canvas/WebGLFramebuffer.idl +++ b/WebCore/html/canvas/WebGLFramebuffer.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLFramebuffer { + interface [Conditional=3D_CANVAS, OmitConstructor] WebGLFramebuffer { }; } diff --git a/WebCore/html/canvas/WebGLIntArray.idl b/WebCore/html/canvas/WebGLIntArray.idl index 3bc037c..ef0d92f 100644 --- a/WebCore/html/canvas/WebGLIntArray.idl +++ b/WebCore/html/canvas/WebGLIntArray.idl @@ -30,7 +30,7 @@ module html { HasNumericIndexGetter, HasCustomIndexSetter, GenerateNativeConverter, - GenerateCustomConstructor, + CustomConstructor, CustomToJS ] WebGLIntArray : WebGLArray { long get(in unsigned long index); diff --git a/WebCore/html/canvas/WebGLProgram.idl b/WebCore/html/canvas/WebGLProgram.idl index 562fa3a..47e5cda 100644 --- a/WebCore/html/canvas/WebGLProgram.idl +++ b/WebCore/html/canvas/WebGLProgram.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLProgram { + interface [Conditional=3D_CANVAS, OmitConstructor] WebGLProgram { }; } diff --git a/WebCore/html/canvas/WebGLRenderbuffer.idl b/WebCore/html/canvas/WebGLRenderbuffer.idl index 2524433..6a4fc35 100644 --- a/WebCore/html/canvas/WebGLRenderbuffer.idl +++ b/WebCore/html/canvas/WebGLRenderbuffer.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLRenderbuffer { + interface [Conditional=3D_CANVAS, OmitConstructor] WebGLRenderbuffer { }; } diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp index 7a7215d..6cb3348 100644 --- a/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -29,8 +29,17 @@ #include "WebGLRenderingContext.h" +#include "CanvasPixelArray.h" +#include "HTMLCanvasElement.h" +#include "HTMLImageElement.h" +#include "ImageBuffer.h" +#include "ImageData.h" +#include "NotImplemented.h" +#include "RenderBox.h" +#include "RenderLayer.h" #include "WebGLActiveInfo.h" #include "WebGLBuffer.h" +#include "WebGLContextAttributes.h" #include "WebGLFramebuffer.h" #include "WebGLProgram.h" #include "WebGLRenderbuffer.h" @@ -44,6 +53,8 @@ #include "RenderBox.h" #include "RenderLayer.h" +#include <wtf/ByteArray.h> + namespace WebCore { class WebGLStateRestorer { @@ -65,9 +76,9 @@ private: bool m_changed; }; -PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas) +PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs) { - OwnPtr<GraphicsContext3D> context(GraphicsContext3D::create()); + OwnPtr<GraphicsContext3D> context(GraphicsContext3D::create(attrs->attributes())); if (!context) return 0; @@ -574,43 +585,98 @@ void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, Except cleanupAfterGraphicsCall(false); } -bool WebGLRenderingContext::validateIndexArray(unsigned long count, unsigned long type, long offset, long& numElements) +bool WebGLRenderingContext::validateElementArraySize(unsigned long count, unsigned long type, long offset) { - long lastIndex = -1; if (!m_boundElementArrayBuffer) return false; - + if (offset < 0) return false; - - // The GL spec says that count must be "greater - + unsigned long uoffset = static_cast<unsigned long>(offset); - + if (type == GraphicsContext3D::UNSIGNED_SHORT) { // For an unsigned short array, offset must be divisible by 2 for alignment reasons. if (uoffset & 1) return false; - + // Make uoffset an element offset. uoffset /= 2; - + unsigned long n = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER) / 2; if (uoffset > n || count > n - uoffset) return false; - - const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()); + } else if (type == GraphicsContext3D::UNSIGNED_BYTE) { + unsigned long n = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER); + if (uoffset > n || count > n - uoffset) + return false; + } + return true; +} + +bool WebGLRenderingContext::validateIndexArrayConservative(unsigned long type, long& numElementsRequired) +{ + // Performs conservative validation by caching a maximum index of + // the given type per element array buffer. If all of the bound + // array buffers have enough elements to satisfy that maximum + // index, skips the expensive per-draw-call iteration in + // validateIndexArrayPrecise. + + long maxIndex = m_boundElementArrayBuffer->getCachedMaxIndex(type); + if (maxIndex < 0) { + // Compute the maximum index in the entire buffer for the given type of index. + switch (type) { + case GraphicsContext3D::UNSIGNED_BYTE: { + unsigned numElements = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER); + const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()); + for (unsigned i = 0; i < numElements; i++) + maxIndex = max(maxIndex, static_cast<long>(p[i])); + break; + } + case GraphicsContext3D::UNSIGNED_SHORT: { + unsigned numElements = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER) / sizeof(unsigned short); + const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()); + for (unsigned i = 0; i < numElements; i++) + maxIndex = max(maxIndex, static_cast<long>(p[i])); + break; + } + default: + return false; + } + m_boundElementArrayBuffer->setCachedMaxIndex(type, maxIndex); + } + + if (maxIndex >= 0) { + // The number of required elements is one more than the maximum + // index that will be accessed. + numElementsRequired = maxIndex + 1; + return true; + } + + return false; +} + +bool WebGLRenderingContext::validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired) +{ + long lastIndex = -1; + + if (!m_boundElementArrayBuffer) + return false; + + unsigned long uoffset = static_cast<unsigned long>(offset); + unsigned long n = count; + + if (type == GraphicsContext3D::UNSIGNED_SHORT) { + // Make uoffset an element offset. + uoffset /= 2; + const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset; while (n-- > 0) { if (*p > lastIndex) lastIndex = *p; ++p; } } else if (type == GraphicsContext3D::UNSIGNED_BYTE) { - unsigned long n = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER); - if (uoffset > n || count > n - uoffset) - return false; - - const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()); + const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset; while (n-- > 0) { if (*p > lastIndex) lastIndex = *p; @@ -619,11 +685,11 @@ bool WebGLRenderingContext::validateIndexArray(unsigned long count, unsigned lon } // Then set the last index in the index array and make sure it is valid. - numElements = lastIndex + 1; - return numElements > 0; + numElementsRequired = lastIndex + 1; + return numElementsRequired > 0; } -bool WebGLRenderingContext::validateRenderingState(long numElements) +bool WebGLRenderingContext::validateRenderingState(long numElementsRequired) { // Look in each enabled vertex attrib and find the smallest buffer size long smallestNumElements = LONG_MAX; @@ -636,7 +702,7 @@ bool WebGLRenderingContext::validateRenderingState(long numElements) if (smallestNumElements == LONG_MAX) smallestNumElements = 0; - return numElements <= smallestNumElements; + return numElementsRequired <= smallestNumElements; } void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long count, ExceptionCode& ec) @@ -658,10 +724,16 @@ void WebGLRenderingContext::drawElements(unsigned long mode, unsigned long count // Ensure we have a valid rendering state long numElements; - if (offset < 0 || !validateIndexArray(count, type, offset, numElements) || !validateRenderingState(numElements)) { + if (offset < 0 || !validateElementArraySize(count, type, offset)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } + + if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) + if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } m_context->drawElements(mode, count, type, offset); cleanupAfterGraphicsCall(true); @@ -710,6 +782,13 @@ void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsign m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } + // Don't allow the default framebuffer to be mutated; all current + // implementations use an FBO internally in place of the default + // FBO. + if (!m_framebufferBinding || !m_framebufferBinding->object()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, buffer); cleanupAfterGraphicsCall(false); } @@ -721,6 +800,13 @@ void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } + // Don't allow the default framebuffer to be mutated; all current + // implementations use an FBO internally in place of the default + // FBO. + if (!m_framebufferBinding || !m_framebufferBinding->object()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } m_context->framebufferTexture2D(target, attachment, textarget, texture, level); cleanupAfterGraphicsCall(false); } @@ -792,6 +878,13 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, uns return WebGLGetInfo(static_cast<unsigned long>(value)); } +PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes() +{ + // We always need to return a new WebGLContextAttributes object to + // prevent the user from mutating any cached version. + return WebGLContextAttributes::create(m_context->getContextAttributes()); +} + unsigned long WebGLRenderingContext::getError() { return m_context->getError(); @@ -1530,25 +1623,28 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned unsigned format, unsigned type, WebGLArray* pixels, ExceptionCode& ec) { // FIXME: For now we ignore any errors returned + // FIXME: Need to make sure passed buffer has enough bytes to define the texture ec = 0; m_context->texImage2D(target, level, internalformat, width, height, - border, format, type, pixels); + border, format, type, pixels ? pixels->baseAddress() : 0); cleanupAfterGraphicsCall(false); } -void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat, - unsigned width, unsigned height, unsigned border, - unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec) +void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels, + bool flipY, bool premultiplyAlpha, ExceptionCode& ec) { // FIXME: For now we ignore any errors returned + // FIXME: Need a form of this call that can take both a pixel buffer and flipY and premultiplyAlpha flags + UNUSED_PARAM(flipY); + UNUSED_PARAM(premultiplyAlpha); ec = 0; - m_context->texImage2D(target, level, internalformat, width, height, - border, format, type, pixels); + m_context->texImage2D(target, level, GraphicsContext3D::RGBA, pixels->width(), pixels->height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels->data()->data()->data()); + //RLP: m_context->texImage2D(target, level, pixels, flipY, premultiplyAlpha); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image, - bool flipY, bool premultiplyAlpha, ExceptionCode& ec) + bool flipY, bool premultiplyAlpha, ExceptionCode& ec) { ec = 0; if (!image) { @@ -1590,9 +1686,14 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanv void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) { - // FIXME: For now we ignore any errors returned + // FIXME: Need implement this call + UNUSED_PARAM(target); + UNUSED_PARAM(level); + UNUSED_PARAM(video); + UNUSED_PARAM(flipY); + UNUSED_PARAM(premultiplyAlpha); + ec = 0; - m_context->texImage2D(target, level, video, flipY, premultiplyAlpha); cleanupAfterGraphicsCall(false); } @@ -1613,24 +1714,26 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig unsigned format, unsigned type, WebGLArray* pixels, ExceptionCode& ec) { // FIXME: For now we ignore any errors returned + // FIXME: Need to make sure passed buffer has enough bytes to define the texture ec = 0; - m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels ? pixels->baseAddress() : 0); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, - unsigned width, unsigned height, - unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec) + ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) { // FIXME: For now we ignore any errors returned + UNUSED_PARAM(flipY); + UNUSED_PARAM(premultiplyAlpha); ec = 0; - m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + m_context->texSubImage2D(target, level, xoffset, yoffset, pixels->width(), pixels->height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels->data()->data()->data()); + //RLP: m_context->texSubImage2D(target, level, xoffset, yoffset, pixels, flipY, premultiplyAlpha); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, - unsigned width, unsigned height, HTMLImageElement* image, - bool flipY, bool premultiplyAlpha, ExceptionCode& ec) + HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) { // FIXME: For now we ignore any errors returned ec = 0; @@ -1645,13 +1748,12 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig return; } - m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, cachedImage->image(), flipY, premultiplyAlpha); + m_context->texSubImage2D(target, level, xoffset, yoffset, cachedImage->image(), flipY, premultiplyAlpha); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, - unsigned width, unsigned height, HTMLCanvasElement* canvas, - bool flipY, bool premultiplyAlpha, ExceptionCode& ec) + HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) { ec = 0; if (!canvas) { @@ -1666,17 +1768,22 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig } // FIXME: For now we ignore any errors returned - m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, buffer->image(), flipY, premultiplyAlpha); + m_context->texSubImage2D(target, level, xoffset, yoffset, buffer->image(), flipY, premultiplyAlpha); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, - unsigned width, unsigned height, HTMLVideoElement* video, - bool flipY, bool premultiplyAlpha, ExceptionCode& ec) -{ - // FIXME: For now we ignore any errors returned + HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) +{ + // FIXME: Need to implement this call + UNUSED_PARAM(target); + UNUSED_PARAM(level); + UNUSED_PARAM(xoffset); + UNUSED_PARAM(yoffset); + UNUSED_PARAM(video); + UNUSED_PARAM(flipY); + UNUSED_PARAM(premultiplyAlpha); ec = 0; - m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, video, flipY, premultiplyAlpha); cleanupAfterGraphicsCall(false); } diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h index 3335eba..90d4fab 100644 --- a/WebCore/html/canvas/WebGLRenderingContext.h +++ b/WebCore/html/canvas/WebGLRenderingContext.h @@ -39,6 +39,7 @@ namespace WebCore { class WebGLActiveInfo; class WebGLBuffer; +class WebGLContextAttributes; class WebGLFramebuffer; class CanvasObject; class WebGLProgram; @@ -53,7 +54,7 @@ class WebKitCSSMatrix; class WebGLRenderingContext : public CanvasRenderingContext { public: - static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*); + static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*); virtual ~WebGLRenderingContext(); virtual bool is3d() const { return true; } @@ -134,6 +135,8 @@ class WebKitCSSMatrix; WebGLGetInfo getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode&); + PassRefPtr<WebGLContextAttributes> getContextAttributes(); + unsigned long getError(); WebGLGetInfo getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode&); @@ -196,9 +199,8 @@ class WebKitCSSMatrix; void texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, WebGLArray* pixels, ExceptionCode&); - void texImage2D(unsigned target, unsigned level, unsigned internalformat, - unsigned width, unsigned height, unsigned border, - unsigned format, unsigned type, ImageData* pixels, ExceptionCode&); + void texImage2D(unsigned target, unsigned level, ImageData* pixels, + bool flipY, bool premultiplyAlpha, ExceptionCode&); void texImage2D(unsigned target, unsigned level, HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode&); void texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas, @@ -213,17 +215,13 @@ class WebKitCSSMatrix; unsigned width, unsigned height, unsigned format, unsigned type, WebGLArray* pixels, ExceptionCode&); void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, - unsigned width, unsigned height, - unsigned format, unsigned type, ImageData* pixels, ExceptionCode&); + ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode&); void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, - unsigned width, unsigned height, HTMLImageElement* image, - bool flipY, bool premultiplyAlpha, ExceptionCode&); + HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode&); void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, - unsigned width, unsigned height, HTMLCanvasElement* canvas, - bool flipY, bool premultiplyAlpha, ExceptionCode&); + HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode&); void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, - unsigned width, unsigned height, HTMLVideoElement* video, - bool flipY, bool premultiplyAlpha, ExceptionCode&); + HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode&); void uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode&); void uniform1fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode&); @@ -301,7 +299,14 @@ class WebKitCSSMatrix; markContextChanged(); } - bool validateIndexArray(unsigned long count, unsigned long type, long offset, long& numElements); + // Basic validation of count and offset against number of elements in element array buffer + bool validateElementArraySize(unsigned long count, unsigned long type, long offset); + + // Conservative but quick index validation + bool validateIndexArrayConservative(unsigned long type, long& numElementsRequired); + + // Precise but slow index validation -- only done if conservative checks fail + bool validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired); bool validateRenderingState(long numElements); OwnPtr<GraphicsContext3D> m_context; diff --git a/WebCore/html/canvas/WebGLRenderingContext.idl b/WebCore/html/canvas/WebGLRenderingContext.idl index 78de8c8..ce01f43 100644 --- a/WebCore/html/canvas/WebGLRenderingContext.idl +++ b/WebCore/html/canvas/WebGLRenderingContext.idl @@ -27,7 +27,6 @@ module html { interface [ Conditional=3D_CANVAS, - GenerateConstructor, InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443, ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54 ] WebGLRenderingContext : CanvasRenderingContext { @@ -542,6 +541,8 @@ module html { // any getBufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException); [Custom] void getBufferParameter(); + WebGLContextAttributes getContextAttributes(); + unsigned long getError(); // any getFramebufferAttachmentParameter(in unsigned long target, in unsigned long attachment, in unsigned long pname) raises(DOMException); @@ -610,8 +611,8 @@ module html { // Supported forms: // void texImage2D(in GLenum target, in GLint level, in GLenum internalformat, in GLsizei width, in GLsizei height, // in GLint border, in GLenum format, in GLenum type, in WebGLArray pixels); - // void texImage2D(in GLenum target, in GLint level, in GLenum internalformat, in GLsizei width, in GLsizei height, - // in GLint border, in GLenum format, in GLenum type, in ImageData pixels); + // void texImage2D(in GLenum target, in GLint level, in ImageData pixels, + // [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha); // void texImage2D(in GLenum target, in GLint level, in HTMLImageElement image, // [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha); // void texImage2D(in GLenum target, in GLint level, in HTMLCanvasElement canvas, @@ -624,18 +625,14 @@ module html { // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, // in GLsizei width, in GLsizei height, // in GLenum format, in GLenum type, in WebGLArray pixels); + // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, + // in ImageData pixels, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, - // in GLsizei width, in GLsizei height, - // in GLenum format, in GLenum type, in ImageData pixels); - // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, - // in GLsizei width, in GLsizei height, in HTMLImageElement image, - // [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); + // in HTMLImageElement image, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, - // in GLsizei width, in GLsizei height, in HTMLCanvasElement canvas, - // [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); + // in HTMLCanvasElement canvas, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, - // in GLsizei width, in GLsizei height, in HTMLVideoElement video, - // [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); + // in HTMLVideoElement video, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); [Custom] void texSubImage2D(); void uniform1f(in WebGLUniformLocation location, in float x) raises(DOMException); diff --git a/WebCore/html/canvas/WebGLShader.idl b/WebCore/html/canvas/WebGLShader.idl index 45e7f54..2d79e49 100644 --- a/WebCore/html/canvas/WebGLShader.idl +++ b/WebCore/html/canvas/WebGLShader.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLShader { + interface [Conditional=3D_CANVAS, OmitConstructor] WebGLShader { }; } diff --git a/WebCore/html/canvas/WebGLShortArray.idl b/WebCore/html/canvas/WebGLShortArray.idl index bd8380f..59dce76 100644 --- a/WebCore/html/canvas/WebGLShortArray.idl +++ b/WebCore/html/canvas/WebGLShortArray.idl @@ -29,7 +29,7 @@ module html { HasNumericIndexGetter, HasCustomIndexSetter, GenerateNativeConverter, - GenerateCustomConstructor, + CustomConstructor, CustomToJS ] WebGLShortArray : WebGLArray { long get(in unsigned long index); diff --git a/WebCore/html/canvas/WebGLTexture.idl b/WebCore/html/canvas/WebGLTexture.idl index da7e066..0200e7e 100644 --- a/WebCore/html/canvas/WebGLTexture.idl +++ b/WebCore/html/canvas/WebGLTexture.idl @@ -24,6 +24,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLTexture { + interface [Conditional=3D_CANVAS, OmitConstructor] WebGLTexture { }; } diff --git a/WebCore/html/canvas/WebGLUniformLocation.idl b/WebCore/html/canvas/WebGLUniformLocation.idl index b080241..f25e834 100644 --- a/WebCore/html/canvas/WebGLUniformLocation.idl +++ b/WebCore/html/canvas/WebGLUniformLocation.idl @@ -25,6 +25,6 @@ */ module html { - interface [Conditional=3D_CANVAS] WebGLUniformLocation { + interface [Conditional=3D_CANVAS, OmitConstructor] WebGLUniformLocation { }; } diff --git a/WebCore/html/canvas/WebGLUnsignedByteArray.idl b/WebCore/html/canvas/WebGLUnsignedByteArray.idl index 57aa4ff..4de8b42 100644 --- a/WebCore/html/canvas/WebGLUnsignedByteArray.idl +++ b/WebCore/html/canvas/WebGLUnsignedByteArray.idl @@ -30,7 +30,7 @@ module html { HasNumericIndexGetter, HasCustomIndexSetter, GenerateNativeConverter, - GenerateCustomConstructor, + CustomConstructor, CustomToJS ] WebGLUnsignedByteArray : WebGLArray { long get(in unsigned long index); diff --git a/WebCore/html/canvas/WebGLUnsignedIntArray.idl b/WebCore/html/canvas/WebGLUnsignedIntArray.idl index 8697e70..75ff598 100644 --- a/WebCore/html/canvas/WebGLUnsignedIntArray.idl +++ b/WebCore/html/canvas/WebGLUnsignedIntArray.idl @@ -27,13 +27,13 @@ module html { interface [ Conditional=3D_CANVAS, + CustomConstructor, HasNumericIndexGetter, HasCustomIndexSetter, GenerateNativeConverter, - GenerateCustomConstructor, CustomToJS ] WebGLUnsignedIntArray : WebGLArray { - long get(in unsigned long index); + unsigned long get(in unsigned long index); // void set(in unsigned long index, in long value); // void set(in WebGLUnsignedIntArray array, [Optional] in unsigned long offset); // void set(in sequence<long> array, [Optional] in unsigned long offset); diff --git a/WebCore/html/canvas/WebGLUnsignedShortArray.idl b/WebCore/html/canvas/WebGLUnsignedShortArray.idl index d546444..fc53929 100644 --- a/WebCore/html/canvas/WebGLUnsignedShortArray.idl +++ b/WebCore/html/canvas/WebGLUnsignedShortArray.idl @@ -27,10 +27,10 @@ module html { interface [ Conditional=3D_CANVAS, + CustomConstructor, HasNumericIndexGetter, HasCustomIndexSetter, GenerateNativeConverter, - GenerateCustomConstructor, CustomToJS ] WebGLUnsignedShortArray : WebGLArray { long get(in unsigned long index); |