diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2010-11-10 15:31:59 -0800 |
---|---|---|
committer | Teng-Hui Zhu <ztenghui@google.com> | 2010-11-17 13:35:59 -0800 |
commit | 28040489d744e0c5d475a88663056c9040ed5320 (patch) | |
tree | c463676791e4a63e452a95f0a12b2a8519730693 | |
parent | eff9be92c41913c92fb1d3b7983c071f3e718678 (diff) | |
download | external_webkit-28040489d744e0c5d475a88663056c9040ed5320.zip external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.gz external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.bz2 |
Merge WebKit at r71558: Initial merge by git.
Change-Id: Ib345578fa29df7e4bc72b4f00e4a6fddcb754c4c
936 files changed, 32195 insertions, 13046 deletions
diff --git a/ANGLE/ANGLE.xcodeproj/project.pbxproj b/ANGLE/ANGLE.xcodeproj/project.pbxproj index 95f41c3..066a930 100644 --- a/ANGLE/ANGLE.xcodeproj/project.pbxproj +++ b/ANGLE/ANGLE.xcodeproj/project.pbxproj @@ -457,6 +457,7 @@ isa = PBXProject; buildConfigurationList = FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "ANGLE" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( English, diff --git a/ANGLE/ChangeLog b/ANGLE/ChangeLog index e886a42..78a4d12 100644 --- a/ANGLE/ChangeLog +++ b/ANGLE/ChangeLog @@ -1,3 +1,13 @@ +2010-11-03 Darin Adler <darin@apple.com> + + Updated Xcode projects by opening them with Xcode 3.2.4. + Updated svn:ignore for Xcode projects. + + * ANGLE.xcodeproj: Added property svn:ignore. + * ANGLE.xcodeproj/project.pbxproj: Updated with Xcode 3.2.4. + * src/build_angle.xcodeproj: Added property svn:ignore. + * src/build_angle.xcodeproj/project.pbxproj: Updated with Xcode 3.2.4. + 2010-09-01 Zhenyao Mo <zmo@google.com> Reviewed by Kenneth Russell. diff --git a/ANGLE/src/build_angle.xcodeproj/project.pbxproj b/ANGLE/src/build_angle.xcodeproj/project.pbxproj index 6c0e06b..f118435 100644 --- a/ANGLE/src/build_angle.xcodeproj/project.pbxproj +++ b/ANGLE/src/build_angle.xcodeproj/project.pbxproj @@ -373,7 +373,14 @@ }; buildConfigurationList = 0E59F8FE4A8099E8DDCA4CE7 /* Build configuration list for PBXProject "build_angle" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 5BBEFF9B91738297B95C568D; projectDirPath = ""; projectRoot = ""; diff --git a/JavaScriptCore/API/JSContextRef.cpp b/JavaScriptCore/API/JSContextRef.cpp index 926badc..ccab953 100644 --- a/JavaScriptCore/API/JSContextRef.cpp +++ b/JavaScriptCore/API/JSContextRef.cpp @@ -46,7 +46,7 @@ using namespace JSC; JSContextGroupRef JSContextGroupCreate() { initializeThreading(); - return toRef(JSGlobalData::createContextGroup(ThreadStackTypeSmall).releaseRef()); + return toRef(JSGlobalData::createContextGroup(ThreadStackTypeSmall).leakRef()); } JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp index 8bd33d6..4198ca8 100644 --- a/JavaScriptCore/API/JSObjectRef.cpp +++ b/JavaScriptCore/API/JSObjectRef.cpp @@ -59,7 +59,7 @@ JSClassRef JSClassCreate(const JSClassDefinition* definition) ? OpaqueJSClass::createNoAutomaticPrototype(definition) : OpaqueJSClass::create(definition); - return jsClass.release().releaseRef(); + return jsClass.release().leakRef(); } JSClassRef JSClassRetain(JSClassRef jsClass) @@ -507,7 +507,7 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o size_t size = array.size(); propertyNames->array.reserveInitialCapacity(size); for (size_t i = 0; i < size; ++i) - propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].ustring()).releaseRef())); + propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].ustring()).leakRef())); return JSPropertyNameArrayRetain(propertyNames); } diff --git a/JavaScriptCore/API/JSStringRef.cpp b/JavaScriptCore/API/JSStringRef.cpp index 8e236e4..ea31da6 100644 --- a/JavaScriptCore/API/JSStringRef.cpp +++ b/JavaScriptCore/API/JSStringRef.cpp @@ -36,7 +36,7 @@ using namespace WTF::Unicode; JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars) { initializeThreading(); - return OpaqueJSString::create(chars, numChars).releaseRef(); + return OpaqueJSString::create(chars, numChars).leakRef(); } JSStringRef JSStringCreateWithUTF8CString(const char* string) @@ -47,11 +47,11 @@ JSStringRef JSStringCreateWithUTF8CString(const char* string) Vector<UChar, 1024> buffer(length); UChar* p = buffer.data(); if (conversionOK == convertUTF8ToUTF16(&string, string + length, &p, p + length)) - return OpaqueJSString::create(buffer.data(), p - buffer.data()).releaseRef(); + return OpaqueJSString::create(buffer.data(), p - buffer.data()).leakRef(); } // Null string. - return OpaqueJSString::create().releaseRef(); + return OpaqueJSString::create().leakRef(); } JSStringRef JSStringRetain(JSStringRef string) diff --git a/JavaScriptCore/API/JSStringRefCF.cpp b/JavaScriptCore/API/JSStringRefCF.cpp index d1f6fe3..e0961d0 100644 --- a/JavaScriptCore/API/JSStringRefCF.cpp +++ b/JavaScriptCore/API/JSStringRefCF.cpp @@ -45,9 +45,9 @@ JSStringRef JSStringCreateWithCFString(CFStringRef string) OwnArrayPtr<UniChar> buffer(new UniChar[length]); CFStringGetCharacters(string, CFRangeMake(0, length), buffer.get()); COMPILE_ASSERT(sizeof(UniChar) == sizeof(UChar), unichar_and_uchar_must_be_same_size); - return OpaqueJSString::create(reinterpret_cast<UChar*>(buffer.get()), length).releaseRef(); + return OpaqueJSString::create(reinterpret_cast<UChar*>(buffer.get()), length).leakRef(); } else { - return OpaqueJSString::create(0, 0).releaseRef(); + return OpaqueJSString::create(0, 0).leakRef(); } } diff --git a/JavaScriptCore/API/JSValueRef.cpp b/JavaScriptCore/API/JSValueRef.cpp index b8dd7c6..faf4712 100644 --- a/JavaScriptCore/API/JSValueRef.cpp +++ b/JavaScriptCore/API/JSValueRef.cpp @@ -252,7 +252,7 @@ JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsig exec->clearException(); return 0; } - return OpaqueJSString::create(result).releaseRef(); + return OpaqueJSString::create(result).leakRef(); } bool JSValueToBoolean(JSContextRef ctx, JSValueRef value) @@ -295,7 +295,7 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exec->clearException(); stringRef.clear(); } - return stringRef.release().releaseRef(); + return stringRef.release().leakRef(); } JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception) diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index 7b935d4..8f663ff 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,229 @@ +2010-11-08 Adam Roben <aroben@apple.com> + + Roll out r71532 + + It broke the build for Cygwin 1.7 installs. Cygwin 1.7's default + .bashrc unsets %TEMP%, which broke copy-tools.cmd. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: + * JavaScriptCore.vcproj/JavaScriptCore/copy-tools.cmd: Removed. + * JavaScriptCore.vcproj/JavaScriptCore/show-alert.js: Removed. + +2010-11-08 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + >=webkitgtk-1.2.5: parallel build fails with libtool: link: cannot find the library `libwebkit-1.0.la' or unhandled argument `libwebkit-1.0.la' + https://bugs.webkit.org/show_bug.cgi?id=49128 + + r59042 introduced a C++-style comment in Platform.h, which is often + included in C source files. Change it to a C-style comment. + + * wtf/Platform.h: Fix the C++-style comment. + +2010-11-08 Adam Roben <aroben@apple.com> + + Show a message and cause the build to immediately fail when any + .vsprops files are copied + + When $WebKitLibrariesDir is set to a non-standard location, the + .vsprops files have to be copied from WebKitLibraries/win to + $WebKitLibrariesDir. When this happens, Visual Studio doesn't pick up + changes to the .vsprops files until the next time it opens the solution + file. Before this patch, the build would soldier on with the old + .vsprops files, leading to strange build failures. Now we detect that + the .vsprops files have been updated, display a message to the user + telling them what to do, and make the build fail immediately. + + Fixes <http://webkit.org/b/49181> Windows build fail mysteriously when + .vsprops files are updated + + Reviewed by Steve Falkenburg. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make: + Moved code to copy the tools directory to the new copy-tools.cmd + script. Moved that after the command that writes the buildfailed file + so the build will be considered a failure if copy-tools.cmd fails. + Changed to write the project name into buildfailed like all our other + projects do, so those other projects will know that the failure was due + to this project. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: + Added new scripts. + + * JavaScriptCore.vcproj/JavaScriptCore/copy-tools.cmd: Added. Copies + the tools directory to $WebKitLibrariesDir. If any files were copied, + we display a message to the user and exit with error code 1 to cause + the build to fail. In non-interactive builds, we just print the message + to the build log. In interactive builds, we show the message in an + alert. + + * JavaScriptCore.vcproj/JavaScriptCore/show-alert.js: Added. Uses + Windows Scripting Host to display a message in an alert. + +2010-11-07 Sam Magnuson <smagnuson@netflix.com> + + Reviewed by Andreas Kling. + + [Qt] make install does not cause JavaScriptCore to be built + https://bugs.webkit.org/show_bug.cgi?id=49114 + + * JavaScriptCore.pro: + +2010-11-05 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Website consistently crashing TOT in JIT::execute() on news.com.au + https://bugs.webkit.org/show_bug.cgi?id=48954 + + The problem here was the strict pass of this conversion was loading the + this structure into one register but doing the flags check off a different + register. This is clearly wrong. I have been unable to trigger the crash + with a reduction, but I've added an assertion to the this conversion to + attempt to make it more readily catchable in future. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_convert_this_strict): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_convert_this_strict): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + +2010-11-04 Xan Lopez <xlopez@igalia.com> + + Reviewed by Adam Barth. + + Use leakRef instead of releaseRef + https://bugs.webkit.org/show_bug.cgi?id=48974 + + Use leakRef instead of the deprecated releaseRef. This was renamed + some time ago because 'releaseRef' is too close to 'release', + which does something completely different. + +2010-11-04 Eric Seidel <eric@webkit.org> + + Reviewed by Gavin Barraclough. + + REGRESSION(49798): Crash in HTMLObjectElement::parseMappedAttribute + https://bugs.webkit.org/show_bug.cgi?id=48789 + + The contract for all String/AtomicString methods seems to be that it's + safe to call them, even when the String is null (impl() returns 0). + This contract was broken by r49798 (unintentionally) when optimizing + for dromeo. + This patch adds a null check to AtomicString::lower() fixing this + crash and preventing future confusion. + + * wtf/text/AtomicString.cpp: + (WTF::AtomicString::lower): + +2010-11-04 Adam Barth <abarth@webkit.org> + + Enabled ICCJPEG on Chromium Mac + https://bugs.webkit.org/show_bug.cgi?id=48977 + + * wtf/Platform.h: + +2010-11-03 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Crash in Function.prototype.call.apply + https://bugs.webkit.org/show_bug.cgi?id=48485 + + The problem here was op_load_varargs failing to ensure that + there was sufficient space for the entire callframe prior to + op_call_varargs. This meant that when we then re-entered the + VM it was possible to stomp over an earlier portion of the + stack, so causing sub-optimal behaviour. + + * bytecode/Opcode.h: + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitLoadVarargs): + * bytecompiler/BytecodeGenerator.h: + * bytecompiler/NodesCodegen.cpp: + (JSC::ApplyFunctionCallDotNode::emitBytecode): + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_load_varargs): + +2010-11-03 Kenneth Russell <kbr@google.com> + + Reviewed by Chris Marrin. + + Redesign extension mechanism in GraphicsContext3D + https://bugs.webkit.org/show_bug.cgi?id=46894 + + * JavaScriptCore.exp: + - Exposed String::split(const String&, Vector<String>). + +2010-11-03 Adam Roben <aroben@apple.com> + + Bring WTF.vcproj up to date + + * JavaScriptCore.vcproj/WTF/WTF.vcproj: Added filters for the text and + unicode directories, added new files, removed old files. + +2010-11-03 Gabor Loki <loki@webkit.org> + + Reviewed by Andreas Kling. + + Remove unused initializeWeakRandomNumberGenerator + https://bugs.webkit.org/show_bug.cgi?id=48899 + + WeakRandom class is used instead of weakRandomNumber and its initializer. + + * wtf/RandomNumberSeed.h: + +2010-11-03 Gabor Loki <loki@webkit.org> + + Reviewed by Geoffrey Garen. + + Unused class: JSFastMath with JSValue64 + https://bugs.webkit.org/show_bug.cgi?id=48835 + + Remove unused JSFastMath class. + + * runtime/JSImmediate.h: + +2010-11-02 Adam Roben <aroben@apple.com> + + Windows build fix after r71127 + + MSVC isn't smart enough to figure out that the definition of the global + nullptr variable isn't needed, so we provide one for it. + + Fixes <http://webkit.org/b/48862> Windows build is broken due to + undefined symbol nullptr + + Reviewed by Anders Carlsson. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export nullptr. + + * JavaScriptCore.vcproj/WTF/WTF.vcproj: Added NullPtr.cpp and let VS + resort the files. + + * wtf/NullPtr.cpp: Added. + +2010-11-02 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + Remove special handling of HashTableDeletedValue in PlatformRefPtr and manually manage memory that cannot be controlled by HashTraits + https://bugs.webkit.org/show_bug.cgi?id=48841 + + Remove special handling of HashTableDeletedValue in PlatformRefPtr. + This is better handled on a case-by-case basis, when HashTraits + cannot account for it. + + * wtf/PlatformRefPtr.h: + (WTF::PlatformRefPtr::~PlatformRefPtr): + (WTF::PlatformRefPtr::clear): + (WTF::::operator): + 2010-10-29 Oliver Hunt <oliver@apple.com> Reviewed by Gavin Barraclough. @@ -6259,7 +6485,7 @@ once. Added a clear function. * wtf/PassRefPtr.h: Changed all uses of releaseRef to leakRef. - +n * wtf/RefPtr.h: Changed all uses of "template <...>" to instead do "template<...>". Tidied up declarations and comments a bit. Changed all uses of releaseRef to leakRef. diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig index 35ae251..8cdcafc 100644 --- a/JavaScriptCore/Configurations/Version.xcconfig +++ b/JavaScriptCore/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 534; -MINOR_VERSION = 11; +MINOR_VERSION = 12; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp index 6ef8ead..3715a43 100644 --- a/JavaScriptCore/JavaScriptCore.exp +++ b/JavaScriptCore/JavaScriptCore.exp @@ -563,6 +563,7 @@ __ZNK3WTF6String19characterStartingAtEj __ZNK3WTF6String4utf8Eb __ZNK3WTF6String5asciiEv __ZNK3WTF6String5lowerEv +__ZNK3WTF6String5splitERKS0_RNS_6VectorIS0_Lm0EEE __ZNK3WTF6String5splitERKS0_bRNS_6VectorIS0_Lm0EEE __ZNK3WTF6String5splitEtRNS_6VectorIS0_Lm0EEE __ZNK3WTF6String5splitEtbRNS_6VectorIS0_Lm0EEE diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro index f83bf4c..531b22c 100644 --- a/JavaScriptCore/JavaScriptCore.pro +++ b/JavaScriptCore/JavaScriptCore.pro @@ -68,6 +68,8 @@ wince* { include(pcre/pcre.pri) include(wtf/wtf.pri) +INSTALLDEPS += all + SOURCES += \ API/JSBase.cpp \ API/JSCallbackConstructor.cpp \ diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index 779b0bc..aa9d529 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -228,6 +228,7 @@ EXPORTS ?name@JSFunction@JSC@@QAEABVUString@2@PAVExecState@2@@Z ?newUninitialized@CString@WTF@@SA?AV12@IAAPAD@Z ?nonInlineNaN@JSC@@YANXZ + ?nullptr@@3Vnullptr_t@std@@A ?number@UString@JSC@@SA?AV12@H@Z ?number@UString@JSC@@SA?AV12@I@Z ?number@UString@JSC@@SA?AV12@N@Z diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj index 3a53070..c0ecd45 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj @@ -244,6 +244,114 @@ >
</File>
</Filter>
+ <Filter
+ Name="unicode"
+ >
+ <File
+ RelativePath="..\..\wtf\unicode\Collator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\unicode\Unicode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\unicode\UnicodeMacrosFromICU.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\unicode\UTF8.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\unicode\UTF8.h"
+ >
+ </File>
+ <Filter
+ Name="icu"
+ >
+ <File
+ RelativePath="..\..\wtf\unicode\icu\CollatorICU.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\unicode\icu\UnicodeIcu.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="text"
+ >
+ <File
+ RelativePath="..\..\wtf\text\AtomicString.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\AtomicString.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\AtomicStringHash.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\AtomicStringImpl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\CString.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\CString.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringBuffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringBuilder.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringBuilder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringConcatenate.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringHash.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringImpl.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringImpl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringImplBase.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringStatics.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\WTFString.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\WTFString.h"
+ >
+ </File>
+ </Filter>
<File
RelativePath="..\..\wtf\AlwaysInline.h"
>
@@ -265,23 +373,27 @@ >
</File>
<File
- RelativePath="..\..\wtf\ByteArray.cpp"
+ RelativePath="..\..\wtf\AVLTree.h"
>
</File>
<File
- RelativePath="..\..\wtf\ByteArray.h"
+ RelativePath="..\..\wtf\Bitmap.h"
>
</File>
<File
- RelativePath="..\..\wtf\unicode\Collator.h"
+ RelativePath="..\..\wtf\BumpPointerAllocator.h"
>
</File>
<File
- RelativePath="..\..\wtf\unicode\CollatorDefault.cpp"
+ RelativePath="..\..\wtf\ByteArray.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\unicode\icu\CollatorICU.cpp"
+ RelativePath="..\..\wtf\ByteArray.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\Complex.h"
>
</File>
<File
@@ -297,23 +409,27 @@ >
</File>
<File
- RelativePath="..\..\wtf\Deque.h"
+ RelativePath="..\..\wtf\DecimalNumber.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\dtoa.cpp"
+ RelativePath="..\..\wtf\DecimalNumber.h"
>
</File>
<File
- RelativePath="..\..\wtf\dtoa.h"
+ RelativePath="..\..\wtf\Deque.h"
>
</File>
<File
- RelativePath="..\..\wtf\DecimalNumber.cpp"
+ RelativePath="..\..\wtf\DisallowCType.h"
>
</File>
<File
- RelativePath="..\..\wtf\DecimalNumber.h"
+ RelativePath="..\..\wtf\dtoa.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa.h"
>
</File>
<File
@@ -337,7 +453,7 @@ >
</File>
<File
- RelativePath="..\..\wtf\FastMallocInternal.h"
+ RelativePath="..\..\wtf\FixedArray.h"
>
</File>
<File
@@ -357,6 +473,10 @@ >
</File>
<File
+ RelativePath="..\..\wtf\HashIterators.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\HashMap.h"
>
</File>
@@ -389,31 +509,31 @@ >
</File>
<File
- RelativePath="..\..\wtf\MD5.cpp"
+ RelativePath="..\..\wtf\MainThread.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\MD5.h"
+ RelativePath="..\..\wtf\MainThread.h"
>
</File>
<File
- RelativePath="..\..\wtf\MainThread.cpp"
+ RelativePath="..\..\wtf\MallocZoneSupport.h"
>
</File>
<File
- RelativePath="..\..\wtf\MainThread.h"
+ RelativePath="..\..\wtf\MathExtras.h"
>
</File>
<File
- RelativePath="..\..\wtf\MathExtras.h"
+ RelativePath="..\..\wtf\MD5.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\MessageQueue.h"
+ RelativePath="..\..\wtf\MD5.h"
>
</File>
<File
- RelativePath="..\..\wtf\NonCopyingSort.h"
+ RelativePath="..\..\wtf\MessageQueue.h"
>
</File>
<File
@@ -421,19 +541,23 @@ >
</File>
<File
+ RelativePath="..\..\wtf\NonCopyingSort.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\NotFound.h"
>
</File>
<File
- RelativePath="..\..\wtf\OwnArrayPtr.h"
+ RelativePath="..\..\wtf\NullPtr.cpp"
>
</File>
<File
- RelativePath="..\..\wtf\OwnFastMallocPtr.h"
+ RelativePath="..\..\wtf\NullPtr.h"
>
</File>
<File
- RelativePath="..\..\wtf\OwnPtr.h"
+ RelativePath="..\..\wtf\OwnArrayPtr.h"
>
</File>
<File
@@ -441,6 +565,14 @@ >
</File>
<File
+ RelativePath="..\..\wtf\OwnFastMallocPtr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\OwnPtr.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\OwnPtrCommon.h"
>
</File>
@@ -473,7 +605,11 @@ >
</File>
<File
- RelativePath="..\..\wtf\PtrAndFlags.h"
+ RelativePath="..\..\wtf\PlatformRefPtr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\PossiblyNull.h"
>
</File>
<File
@@ -497,6 +633,10 @@ >
</File>
<File
+ RelativePath="..\..\wtf\RefCountedLeakCounter.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\RefPtr.h"
>
</File>
@@ -513,14 +653,30 @@ >
</File>
<File
+ RelativePath="..\..\wtf\SizeLimits.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\StaticConstructors.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\StdLibExtras.h"
>
</File>
<File
+ RelativePath="..\..\wtf\StringExtras.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\StringExtras.h"
>
</File>
<File
+ RelativePath="..\..\wtf\StringHasher.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\TCPackedCache.h"
>
</File>
@@ -549,6 +705,10 @@ >
</File>
<File
+ RelativePath="..\..\wtf\ThreadingNone.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\ThreadingPrimitives.h"
>
</File>
@@ -577,103 +737,27 @@ >
</File>
<File
- RelativePath="..\..\wtf\unicode\Unicode.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\unicode\icu\UnicodeIcu.h"
+ RelativePath="..\..\wtf\UnusedParam.h"
>
</File>
<File
- RelativePath="..\..\wtf\UnusedParam.h"
+ RelativePath="..\..\wtf\ValueCheck.h"
>
</File>
<File
- RelativePath="..\..\wtf\text\AtomicString.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\AtomicString.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\AtomicStringHash.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\AtomicStringImpl.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\CString.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\CString.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\StringStatics.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\StringBuffer.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\StringBuilder.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\StringBuilder.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\StringConcatenate.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\StringHash.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\StringImpl.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\StringImpl.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\TextPosition.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\WTFString.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\text\WTFString.h"
- >
- </File>
- <File
- RelativePath="..\..\wtf\unicode\UTF8.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\unicode\UTF8.h"
+ RelativePath="..\..\wtf\Vector.h"
>
</File>
<File
- RelativePath="..\..\wtf\ValueCheck.h"
+ RelativePath="..\..\wtf\Vector3.h"
>
</File>
<File
- RelativePath="..\..\wtf\Vector.h"
+ RelativePath="..\..\wtf\VectorTraits.h"
>
</File>
<File
- RelativePath="..\..\wtf\VectorTraits.h"
+ RelativePath="..\..\wtf\VMTags.h"
>
</File>
<File
diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h index e4ebeb8..68acae4 100644 --- a/JavaScriptCore/bytecode/CodeBlock.h +++ b/JavaScriptCore/bytecode/CodeBlock.h @@ -678,7 +678,7 @@ namespace JSC { // symbol table, so we just pass as a raw pointer with a ref count of 1. We then manually deref // in the destructor. FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, bool isConstructor) - : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, SharedSymbolTable::create().releaseRef(), isConstructor) + : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, SharedSymbolTable::create().leakRef(), isConstructor) { } ~FunctionCodeBlock() diff --git a/JavaScriptCore/bytecode/Opcode.h b/JavaScriptCore/bytecode/Opcode.h index e1ef01e..8ee82e7 100644 --- a/JavaScriptCore/bytecode/Opcode.h +++ b/JavaScriptCore/bytecode/Opcode.h @@ -162,7 +162,7 @@ namespace JSC { macro(op_call, 4) \ macro(op_call_eval, 4) \ macro(op_call_varargs, 4) \ - macro(op_load_varargs, 3) \ + macro(op_load_varargs, 4) \ macro(op_tear_off_activation, 3) \ macro(op_tear_off_arguments, 2) \ macro(op_ret, 2) \ diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 87f0beb..7538314 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -1674,12 +1674,13 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi return dst; } -RegisterID* BytecodeGenerator::emitLoadVarargs(RegisterID* argCountDst, RegisterID* arguments) +RegisterID* BytecodeGenerator::emitLoadVarargs(RegisterID* argCountDst, RegisterID* thisRegister, RegisterID* arguments) { ASSERT(argCountDst->index() < arguments->index()); emitOpcode(op_load_varargs); instructions().append(argCountDst->index()); instructions().append(arguments->index()); + instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset return argCountDst; } diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h index d0e4a6b..b189565 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -350,7 +350,7 @@ namespace JSC { RegisterID* emitCall(RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset); RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset); RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCount, unsigned divot, unsigned startOffset, unsigned endOffset); - RegisterID* emitLoadVarargs(RegisterID* argCountDst, RegisterID* args); + RegisterID* emitLoadVarargs(RegisterID* argCountDst, RegisterID* thisRegister, RegisterID* args); RegisterID* emitReturn(RegisterID* src); RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); } diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp index f282542..47129d5 100644 --- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp +++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp @@ -536,7 +536,7 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, while ((args = args->m_next)) generator.emitNode(args->m_expr); - generator.emitLoadVarargs(argsCountRegister.get(), argsRegister.get()); + generator.emitLoadVarargs(argsCountRegister.get(), thisRegister.get(), argsRegister.get()); generator.emitCallVarargs(finalDestinationOrIgnored.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset()); } generator.emitJump(end.get()); diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp index 0eabdf5..e5be43b 100644 --- a/JavaScriptCore/jit/JIT.cpp +++ b/JavaScriptCore/jit/JIT.cpp @@ -477,8 +477,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck) emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock); addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1); - registerFileCheck = branchPtr(Below, AbsoluteAddress(&m_globalData->interpreter->registerFile(). - m_end), regT1); + registerFileCheck = branchPtr(Below, AbsoluteAddress(&m_globalData->interpreter->registerFile().m_end), regT1); } Label functionBody = label(); diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp index 1528b76..74170c1 100644 --- a/JavaScriptCore/jit/JITOpcodes.cpp +++ b/JavaScriptCore/jit/JITOpcodes.cpp @@ -1266,7 +1266,7 @@ void JIT::emit_op_convert_this_strict(Instruction* currentInstruction) notNull.link(this); Jump isImmediate = emitJumpIfNotJSCell(regT0); loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1); - Jump notAnObject = branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); + Jump notAnObject = branch8(NotEqual, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion))); isImmediate.link(this); notAnObject.link(this); @@ -1666,6 +1666,9 @@ void JIT::emit_op_load_varargs(Instruction* currentInstruction) { int argCountDst = currentInstruction[1].u.operand; int argsOffset = currentInstruction[2].u.operand; + int registerOffset = currentInstruction[3].u.operand; + ASSERT(argsOffset <= registerOffset); + int expectedParams = m_codeBlock->m_numParameters - 1; // Don't do inline copying if we aren't guaranteed to have a single stream // of arguments @@ -1695,6 +1698,7 @@ void JIT::emit_op_load_varargs(Instruction* currentInstruction) // Bounds check the registerfile addPtr(regT2, regT3); + addPtr(Imm32((registerOffset - argsOffset) * sizeof(Register)), regT3); addSlowCase(branchPtr(Below, AbsoluteAddress(&m_globalData->interpreter->registerFile().m_end), regT3)); sub32(Imm32(1), regT0); diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp index 0a3d69d..8e0226d 100644 --- a/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -1574,7 +1574,7 @@ void JIT::emit_op_convert_this_strict(Instruction* currentInstruction) notNull.link(this); Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); - Jump notAnObject = branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); + Jump notAnObject = branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); addSlowCase(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion))); isImmediate.link(this); notAnObject.link(this); diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp index c69a828..896b93d 100644 --- a/JavaScriptCore/jit/JITStubs.cpp +++ b/JavaScriptCore/jit/JITStubs.cpp @@ -1304,7 +1304,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this_strict) JSValue v1 = stackFrame.args[0].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - + ASSERT(v1.asCell()->structure()->typeInfo().needsThisConversion()); JSValue result = v1.toStrictThisObject(callFrame); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp index 16647ec..00581e5 100644 --- a/JavaScriptCore/jsc.cpp +++ b/JavaScriptCore/jsc.cpp @@ -343,7 +343,7 @@ int main(int argc, char** argv) // We can't use destructors in the following code because it uses Windows // Structured Exception Handling int res = 0; - JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge).releaseRef(); + JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge).leakRef(); TRY res = jscmain(argc, argv, globalData); EXCEPT(res = 3) diff --git a/JavaScriptCore/runtime/Identifier.cpp b/JavaScriptCore/runtime/Identifier.cpp index d375eff..d4069ba 100644 --- a/JavaScriptCore/runtime/Identifier.cpp +++ b/JavaScriptCore/runtime/Identifier.cpp @@ -101,7 +101,7 @@ struct IdentifierCStringTranslator { { size_t length = strlen(c); UChar* d; - StringImpl* r = StringImpl::createUninitialized(length, d).releaseRef(); + StringImpl* r = StringImpl::createUninitialized(length, d).leakRef(); for (size_t i = 0; i != length; i++) d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend r->setHash(hash); @@ -160,7 +160,7 @@ struct IdentifierUCharBufferTranslator { static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash) { UChar* d; - StringImpl* r = StringImpl::createUninitialized(buf.length, d).releaseRef(); + StringImpl* r = StringImpl::createUninitialized(buf.length, d).leakRef(); for (unsigned i = 0; i != buf.length; i++) d[i] = buf.s[i]; r->setHash(hash); diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h index ffa446e..68ba75c 100644 --- a/JavaScriptCore/runtime/JSImmediate.h +++ b/JavaScriptCore/runtime/JSImmediate.h @@ -39,7 +39,6 @@ namespace JSC { class ExecState; class JSCell; - class JSFastMath; class JSGlobalData; class JSObject; class UString; @@ -133,7 +132,6 @@ namespace JSC { private: friend class JIT; friend class JSValue; - friend class JSFastMath; friend class JSInterfaceJIT; friend class SpecializedThunkJIT; friend JSValue jsNumber(ExecState* exec, double d); @@ -563,98 +561,6 @@ namespace JSC { return JSImmediate::getTruncatedUInt32(asValue()); } - class JSFastMath { - public: - static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValue v1, JSValue v2) - { - return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); - } - - static ALWAYS_INLINE JSValue equal(JSValue v1, JSValue v2) - { - ASSERT(canDoFastBitwiseOperations(v1, v2)); - return jsBoolean(v1 == v2); - } - - static ALWAYS_INLINE JSValue notEqual(JSValue v1, JSValue v2) - { - ASSERT(canDoFastBitwiseOperations(v1, v2)); - return jsBoolean(v1 != v2); - } - - static ALWAYS_INLINE JSValue andImmediateNumbers(JSValue v1, JSValue v2) - { - ASSERT(canDoFastBitwiseOperations(v1, v2)); - return JSImmediate::makeValue(JSImmediate::rawValue(v1) & JSImmediate::rawValue(v2)); - } - - static ALWAYS_INLINE JSValue xorImmediateNumbers(JSValue v1, JSValue v2) - { - ASSERT(canDoFastBitwiseOperations(v1, v2)); - return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagTypeNumber); - } - - static ALWAYS_INLINE JSValue orImmediateNumbers(JSValue v1, JSValue v2) - { - ASSERT(canDoFastBitwiseOperations(v1, v2)); - return JSImmediate::makeValue(JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2)); - } - - static ALWAYS_INLINE bool canDoFastRshift(JSValue v1, JSValue v2) - { - return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); - } - - static ALWAYS_INLINE bool canDoFastUrshift(JSValue v1, JSValue v2) - { - return JSImmediate::areBothImmediateIntegerNumbers(v1, v2) && !(JSImmediate::rawValue(v1) & JSImmediate::signBit); - } - - static ALWAYS_INLINE JSValue rightShiftImmediateNumbers(JSValue val, JSValue shift) - { - ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift)); - return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber); - } - - static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue v) - { - // Number is non-negative and an operation involving two of these can't overflow. - // Checking for allowed negative numbers takes more time than it's worth on SunSpider. - return (JSImmediate::rawValue(v) & (JSImmediate::TagTypeNumber + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeNumber; - } - - static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue v1, JSValue v2) - { - // Number is non-negative and an operation involving two of these can't overflow. - // Checking for allowed negative numbers takes more time than it's worth on SunSpider. - return canDoFastAdditiveOperations(v1) && canDoFastAdditiveOperations(v2); - } - - static ALWAYS_INLINE JSValue addImmediateNumbers(JSValue v1, JSValue v2) - { - ASSERT(canDoFastAdditiveOperations(v1, v2)); - return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagTypeNumber); - } - - static ALWAYS_INLINE JSValue subImmediateNumbers(JSValue v1, JSValue v2) - { - ASSERT(canDoFastAdditiveOperations(v1, v2)); - return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagTypeNumber); - } - - static ALWAYS_INLINE JSValue incImmediateNumber(JSValue v) - { - ASSERT(canDoFastAdditiveOperations(v)); - return JSImmediate::makeValue(JSImmediate::rawValue(v) + (1 << JSImmediate::IntegerPayloadShift)); - } - - static ALWAYS_INLINE JSValue decImmediateNumber(JSValue v) - { - ASSERT(canDoFastAdditiveOperations(v)); - return JSImmediate::makeValue(JSImmediate::rawValue(v) - (1 << JSImmediate::IntegerPayloadShift)); - } - }; - } // namespace JSC #endif // USE(JSVALUE64) diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h index 8981469..f484ce4 100644 --- a/JavaScriptCore/runtime/JSObject.h +++ b/JavaScriptCore/runtime/JSObject.h @@ -340,7 +340,7 @@ inline void JSObject::setPrototype(JSValue prototype) inline void JSObject::setStructure(NonNullPassRefPtr<Structure> structure) { m_structure->deref(); - m_structure = structure.releaseRef(); // ~JSObject balances this ref() + m_structure = structure.leakRef(); // ~JSObject balances this ref() } inline Structure* JSObject::inheritorID() diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h index 4d81a2f..51b9f2d 100644 --- a/JavaScriptCore/runtime/JSString.h +++ b/JavaScriptCore/runtime/JSString.h @@ -216,7 +216,7 @@ namespace JSC { , m_length(rope->length()) , m_fiberCount(1) { - m_other.m_fibers[0] = rope.releaseRef(); + m_other.m_fibers[0] = rope.leakRef(); } // This constructor constructs a new string by concatenating s1 & s2. // This should only be called with fiberCount <= 3. diff --git a/JavaScriptCore/runtime/JSZombie.cpp b/JavaScriptCore/runtime/JSZombie.cpp index 22aabb9..8a36bda 100644 --- a/JavaScriptCore/runtime/JSZombie.cpp +++ b/JavaScriptCore/runtime/JSZombie.cpp @@ -37,7 +37,7 @@ Structure* JSZombie::leakedZombieStructure() { static Structure* structure = 0; if (!structure) { Structure::startIgnoringLeaks(); - structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType), 0).releaseRef(); + structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType), 0).leakRef(); Structure::stopIgnoringLeaks(); } return structure; diff --git a/JavaScriptCore/runtime/Lookup.cpp b/JavaScriptCore/runtime/Lookup.cpp index 07416af..dac1c94 100644 --- a/JavaScriptCore/runtime/Lookup.cpp +++ b/JavaScriptCore/runtime/Lookup.cpp @@ -34,7 +34,7 @@ void HashTable::createTable(JSGlobalData* globalData) const for (int i = 0; i < compactSize; ++i) entries[i].setKey(0); for (int i = 0; values[i].key; ++i) { - StringImpl* identifier = Identifier::add(globalData, values[i].key).releaseRef(); + StringImpl* identifier = Identifier::add(globalData, values[i].key).leakRef(); int hashIndex = identifier->existingHash() & compactHashSizeMask; HashEntry* entry = &entries[hashIndex]; diff --git a/JavaScriptCore/wtf/NullPtr.cpp b/JavaScriptCore/wtf/NullPtr.cpp new file mode 100644 index 0000000..e7d94b2 --- /dev/null +++ b/JavaScriptCore/wtf/NullPtr.cpp @@ -0,0 +1,33 @@ +/* + +Copyright (C) 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 +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "NullPtr.h" + +#if !__has_feature(cxx_nullptr) + +std::nullptr_t nullptr; + +#endif diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 1877917..cb732f3 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -526,6 +526,7 @@ #define WTF_PLATFORM_CI 1 #define WTF_USE_ATSUI 1 #define WTF_USE_CORE_TEXT 1 +#define WTF_USE_ICCJPEG 1 #else #define WTF_PLATFORM_SKIA 1 #endif @@ -814,7 +815,7 @@ /* ENABLE macro defaults */ #if PLATFORM(QT) -// We must not customize the global operator new and delete for the Qt port. +/* We must not customize the global operator new and delete for the Qt port. */ #define ENABLE_GLOBAL_FASTMALLOC_NEW 0 #endif diff --git a/JavaScriptCore/wtf/PlatformRefPtr.h b/JavaScriptCore/wtf/PlatformRefPtr.h index f99ec9b..8ac16cb 100644 --- a/JavaScriptCore/wtf/PlatformRefPtr.h +++ b/JavaScriptCore/wtf/PlatformRefPtr.h @@ -62,8 +62,7 @@ public: ~PlatformRefPtr() { - T* ptr = m_ptr; - if (ptr && ptr != hashTableDeletedValue()) + if (T* ptr = m_ptr) derefPlatformPtr(ptr); } @@ -71,7 +70,7 @@ public: { T* ptr = m_ptr; m_ptr = 0; - if (ptr && ptr != hashTableDeletedValue()) + if (ptr) derefPlatformPtr(ptr); } @@ -111,7 +110,7 @@ template <typename T> inline PlatformRefPtr<T>& PlatformRefPtr<T>::operator=(con refPlatformPtr(optr); T* ptr = m_ptr; m_ptr = optr; - if (ptr && ptr != hashTableDeletedValue()) + if (ptr) derefPlatformPtr(ptr); return *this; } @@ -122,7 +121,7 @@ template <typename T> inline PlatformRefPtr<T>& PlatformRefPtr<T>::operator=(T* if (optr) refPlatformPtr(optr); m_ptr = optr; - if (ptr && ptr != hashTableDeletedValue()) + if (ptr) derefPlatformPtr(ptr); return *this; } diff --git a/JavaScriptCore/wtf/RandomNumberSeed.h b/JavaScriptCore/wtf/RandomNumberSeed.h index 1f1c00e..b53b506 100644 --- a/JavaScriptCore/wtf/RandomNumberSeed.h +++ b/JavaScriptCore/wtf/RandomNumberSeed.h @@ -76,15 +76,6 @@ inline void initializeRandomNumberGenerator() #endif } -inline void initializeWeakRandomNumberGenerator() -{ -#if COMPILER(MSVC) && defined(_CRT_RAND_S) - // We need to initialise windows rand() explicitly for Math.random - unsigned seed = 0; - rand_s(&seed); - srand(seed); -#endif -} } #endif diff --git a/JavaScriptCore/wtf/text/AtomicString.cpp b/JavaScriptCore/wtf/text/AtomicString.cpp index c8140d6..c49a837 100644 --- a/JavaScriptCore/wtf/text/AtomicString.cpp +++ b/JavaScriptCore/wtf/text/AtomicString.cpp @@ -90,7 +90,7 @@ struct CStringTranslator { static void translate(StringImpl*& location, const char* const& c, unsigned hash) { - location = StringImpl::create(c).releaseRef(); + location = StringImpl::create(c).leakRef(); location->setHash(hash); location->setIsAtomic(true); } @@ -174,7 +174,7 @@ struct UCharBufferTranslator { static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash) { - location = StringImpl::create(buf.s, buf.length).releaseRef(); + location = StringImpl::create(buf.s, buf.length).leakRef(); location->setHash(hash); location->setIsAtomic(true); } @@ -200,7 +200,7 @@ struct HashAndCharactersTranslator { static void translate(StringImpl*& location, const HashAndCharacters& buffer, unsigned hash) { - location = StringImpl::create(buffer.characters, buffer.length).releaseRef(); + location = StringImpl::create(buffer.characters, buffer.length).leakRef(); location->setHash(hash); location->setIsAtomic(true); } @@ -295,6 +295,8 @@ AtomicString AtomicString::lower() const { // Note: This is a hot function in the Dromaeo benchmark. StringImpl* impl = this->impl(); + if (UNLIKELY(!impl)) + return *this; RefPtr<StringImpl> newImpl = impl->lower(); if (LIKELY(newImpl == impl)) return *this; diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp index e1e08ee..f4b2f05 100644 --- a/JavaScriptCore/wtf/text/StringImpl.cpp +++ b/JavaScriptCore/wtf/text/StringImpl.cpp @@ -144,7 +144,7 @@ SharedUChar* StringImpl::sharedBuffer() return m_substringBuffer->sharedBuffer(); if (ownership == BufferOwned) { ASSERT(!m_sharedBuffer); - m_sharedBuffer = SharedUChar::create(new SharableUChar(m_data)).releaseRef(); + m_sharedBuffer = SharedUChar::create(new SharableUChar(m_data)).leakRef(); m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared; } diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h index 897751d..8f0af52 100644 --- a/JavaScriptCore/wtf/text/StringImpl.h +++ b/JavaScriptCore/wtf/text/StringImpl.h @@ -110,7 +110,7 @@ private: StringImpl(const UChar* characters, unsigned length, PassRefPtr<StringImpl> base) : StringImplBase(length, BufferSubstring) , m_data(characters) - , m_substringBuffer(base.releaseRef()) + , m_substringBuffer(base.leakRef()) , m_hash(0) { ASSERT(m_data); @@ -122,7 +122,7 @@ private: StringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) : StringImplBase(length, BufferShared) , m_data(characters) - , m_sharedBuffer(sharedBuffer.releaseRef()) + , m_sharedBuffer(sharedBuffer.leakRef()) , m_hash(0) { ASSERT(m_data); diff --git a/JavaScriptGlue/Configurations/Version.xcconfig b/JavaScriptGlue/Configurations/Version.xcconfig index 35ae251..8cdcafc 100644 --- a/JavaScriptGlue/Configurations/Version.xcconfig +++ b/JavaScriptGlue/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 534; -MINOR_VERSION = 11; +MINOR_VERSION = 12; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/LayoutTests/http/tests/appcache/fallback.html b/LayoutTests/http/tests/appcache/fallback.html index aaf7a82..ed641e0 100644 --- a/LayoutTests/http/tests/appcache/fallback.html +++ b/LayoutTests/http/tests/appcache/fallback.html @@ -29,18 +29,6 @@ function setNetworkEnabled(state) } } -function canLoad(url) -{ - try { - var req = new XMLHttpRequest(); - req.open("GET", url, false); - req.send(""); - return true; - } catch (e) { - return false; - } -} - function load(url) { try { @@ -49,8 +37,9 @@ function load(url) req.send(""); return req.responseText; } catch (ex) { - alert("Unexpected error loading " + url + ": " + ex); + log("FAIL: Cannot load " + url + ", ex = " + ex); hadError = true; + return ""; // This value should not be expected as the responseText for a url presented to this function. } } @@ -65,17 +54,17 @@ function test() setNetworkEnabled(true); - if (!canLoad(testURL) || !/not in the cache/.test(load(testURL))) { + if (!/not in the cache/.test(load(testURL))) { log("FAIL: Cannot load an URL from fallback namespace when network is enabled"); hadError = true; } - if (!canLoad(nonexistentURL) || load(nonexistentURL) != "Hello, World!") { + if (load(nonexistentURL) != "Hello, World!") { log("FAIL: Fallback resource wasn't used for a 404 response"); hadError = true; } - if (!canLoad(redirectURL) || load(redirectURL) != "Hello, World!") { + if (load(redirectURL) != "Hello, World!") { log("FAIL: Fallback resource wasn't used for a redirect to a resource with another origin"); hadError = true; } @@ -147,10 +136,7 @@ function test6() { setNetworkEnabled(false); - if (!canLoad(testURL)) { - log("FAIL: Cannot load an URL from fallback namespace when network is disabled"); - hadError = true; - } else if (load(testURL) != load("resources/simple.txt")) { + if (load(testURL) != load("resources/simple.txt")) { log("FAIL: Loading an URL from fallback namespace when network is disabled returned unexpected response"); hadError = true; } diff --git a/LayoutTests/http/tests/appcache/resources/offline-access-frame.html b/LayoutTests/http/tests/appcache/resources/offline-access-frame.html index 68ef274..43015ae 100644 --- a/LayoutTests/http/tests/appcache/resources/offline-access-frame.html +++ b/LayoutTests/http/tests/appcache/resources/offline-access-frame.html @@ -17,14 +17,5 @@ applicationCache.onobsolete = function() { log("obsolete") } applicationCache.oncached = function() { log("cached"); test() } applicationCache.onnoupdate = function() { log("noupdate"); test() } applicationCache.onerror = function() { log("error"); test() } - -if (applicationCache.status == applicationCache.IDLE) { - // Update finished while we were waiting for offline-access.js to load. - applicationCache.oncached = function() { log("cached") } - applicationCache.onnoupdate = function() { log("noupdate") } - applicationCache.onerror = function() { log("error") } - test(); -} - </script> </html> diff --git a/LayoutTests/http/tests/resources/network-simulator.php b/LayoutTests/http/tests/resources/network-simulator.php index 4860028..ccfcf5c 100644 --- a/LayoutTests/http/tests/resources/network-simulator.php +++ b/LayoutTests/http/tests/resources/network-simulator.php @@ -2,7 +2,7 @@ require_once 'portabilityLayer.php'; // This script acts as a stateful proxy for retrieving files. When the state is set to -// offline, it simulates a network error by redirecting to itself. +// offline, it simulates a network error with a nonsense response. if (!sys_get_temp_dir()) { echo "FAIL: No temp dir was returned.\n"; @@ -59,9 +59,12 @@ function generateResponse($path) global $stateFile; $state = getState($stateFile); if ($state == "Offline") { + # Simulate a network error by replying with a nonsense response. header('HTTP/1.1 307 Temporary Redirect'); - # Simulate a network error by redirecting to self. - header('Location: ' . $_SERVER['REQUEST_URI']); + header('Location: ' . $_SERVER['REQUEST_URI']); # Redirect to self. + header('Content-Length: 1'); + header('Content-Length: 5', false); # Multiple content-length headers, some network stacks can detect this condition faster. + echo "Intentionally incorrect response."; } else { // A little securuty checking can't hurt. if (strstr($path, "..")) @@ -70,7 +73,7 @@ function generateResponse($path) if ($path[0] == '/') $path = '..' . $path; - generateNoCacheHTTPHeader(); + generateNoCacheHTTPHeader(); if (file_exists($path)) { header("Last-Modified: " . gmdate("D, d M Y H:i:s T", filemtime($path))); diff --git a/LayoutTests/storage/indexeddb/tutorial-expected.txt b/LayoutTests/storage/indexeddb/tutorial-expected.txt index 1e424ef..f9175b7 100644 --- a/LayoutTests/storage/indexeddb/tutorial-expected.txt +++ b/LayoutTests/storage/indexeddb/tutorial-expected.txt @@ -1,2 +1,4 @@ -All done! +Please view source for more information on what this is doing and why... + +Everything worked! diff --git a/LayoutTests/storage/indexeddb/tutorial.html b/LayoutTests/storage/indexeddb/tutorial.html index 2e7e41f..db9f2fa 100644 --- a/LayoutTests/storage/indexeddb/tutorial.html +++ b/LayoutTests/storage/indexeddb/tutorial.html @@ -24,8 +24,10 @@ // goal of teaching people IndexedDB. That said, it does have a good amount of coverage and // serves as a living document describing what's expected to work and how within WebKit so it // seems well worth having checked in. -if (window.layoutTestController) - layoutTestController.dumpAsText(true); +if (window.layoutTestController) { + layoutTestController.dumpAsText(); + layoutTestController.waitUntilDone(); +} function setup() @@ -51,7 +53,7 @@ function setup() function log(txt) { - document.write(txt + "<br>"); + document.getElementById("logger").innerHTML += txt + "<br>"; } function logError(txt) @@ -394,6 +396,7 @@ function onIndexGetSuccess() function onAllDone() { log("Everything worked!"); + layoutTestController.notifyDone(); } // The way setVersion is supposed to work: @@ -429,5 +432,6 @@ function onAllDone() </script> <body onload="start()"> Please view source for more information on what this is doing and why...<br><br> +<div id="logger"></div> </body> </html> diff --git a/WebCore/Android.derived.jscbindings.mk b/WebCore/Android.derived.jscbindings.mk index db414ab..7461ece 100644 --- a/WebCore/Android.derived.jscbindings.mk +++ b/WebCore/Android.derived.jscbindings.mk @@ -261,6 +261,7 @@ GEN := \ $(intermediates)/html/JSHTMLOptGroupElement.h \ $(intermediates)/html/JSHTMLOptionElement.h \ $(intermediates)/html/JSHTMLOptionsCollection.h \ + $(intermediates)/html/JSHTMLOutputElement.h \ $(intermediates)/html/JSHTMLParagraphElement.h \ $(intermediates)/html/JSHTMLParamElement.h \ $(intermediates)/html/JSHTMLPreElement.h \ diff --git a/WebCore/Android.derived.v8bindings.mk b/WebCore/Android.derived.v8bindings.mk index ba2b8db..02d7b3b 100644 --- a/WebCore/Android.derived.v8bindings.mk +++ b/WebCore/Android.derived.v8bindings.mk @@ -245,6 +245,7 @@ GEN := \ $(intermediates)/bindings/V8HTMLOptGroupElement.h \ $(intermediates)/bindings/V8HTMLOptionElement.h \ $(intermediates)/bindings/V8HTMLOptionsCollection.h \ + $(intermediates)/bindings/V8HTMLOutputElement.h \ $(intermediates)/bindings/V8HTMLParagraphElement.h \ $(intermediates)/bindings/V8HTMLParamElement.h \ $(intermediates)/bindings/V8HTMLPreElement.h \ @@ -580,7 +581,6 @@ GEN += \ $(intermediates)/bindings/V8SVGAnimatedLengthList.h \ $(intermediates)/bindings/V8SVGAnimatedNumber.h \ $(intermediates)/bindings/V8SVGAnimatedNumberList.h \ - $(intermediates)/bindings/V8SVGAnimatedPoints.h \ $(intermediates)/bindings/V8SVGAnimatedPreserveAspectRatio.h \ $(intermediates)/bindings/V8SVGAnimatedRect.h \ $(intermediates)/bindings/V8SVGAnimatedString.h \ diff --git a/WebCore/Android.jscbindings.mk b/WebCore/Android.jscbindings.mk index dfc7b9f..bc8a494 100644 --- a/WebCore/Android.jscbindings.mk +++ b/WebCore/Android.jscbindings.mk @@ -127,6 +127,7 @@ LOCAL_SRC_FILES += \ bindings/js/JSHTMLInputElementCustom.cpp \ bindings/js/JSHTMLObjectElementCustom.cpp \ bindings/js/JSHTMLOptionsCollectionCustom.cpp \ + bindings/js/JSHTMLOutputElementCustom.cpp \ bindings/js/JSHTMLSelectElementCustom.cpp \ bindings/js/JSHistoryCustom.cpp \ bindings/js/JSIDBAnyCustom.cpp \ @@ -182,8 +183,7 @@ LOCAL_SRC_FILES += \ bindings/js/JSXSLTProcessorCustom.cpp \ bindings/js/ScheduledAction.cpp \ bindings/js/ScriptCachedFrameData.cpp \ - bindings/js/ScriptCallFrame.cpp \ - bindings/js/ScriptCallStack.cpp \ + bindings/js/ScriptCallStackFactory.cpp \ bindings/js/ScriptController.cpp \ bindings/js/ScriptControllerAndroid.cpp \ bindings/js/ScriptEventListener.cpp \ diff --git a/WebCore/Android.mk b/WebCore/Android.mk index 84cbf7a..a18edab 100644 --- a/WebCore/Android.mk +++ b/WebCore/Android.mk @@ -314,6 +314,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ html/HTMLImageLoader.cpp \ html/HTMLNameCollection.cpp \ html/HTMLOptionsCollection.cpp \ + html/HTMLOutputElement.cpp \ html/HTMLParserErrorCodes.cpp \ html/HTMLTableRowsCollection.cpp \ html/HTMLViewSourceDocument.cpp \ @@ -343,6 +344,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ html/TimeInputType.cpp \ html/TimeRanges.cpp \ html/URLInputType.cpp \ + html/ValidationMessage.cpp \ html/ValidityState.cpp \ html/WeekInputType.cpp \ \ @@ -379,17 +381,16 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ html/parser/TextDocumentParser.cpp \ html/parser/TextViewSourceParser.cpp \ \ - loader/Cache.cpp \ - loader/CachedCSSStyleSheet.cpp \ - loader/CachedFont.cpp \ - loader/CachedImage.cpp \ - loader/CachedResource.cpp \ - loader/CachedResourceClientWalker.cpp \ - loader/CachedResourceHandle.cpp \ - loader/CachedScript.cpp \ + loader/cache/CachedCSSStyleSheet.cpp \ + loader/cache/CachedFont.cpp \ + loader/cache/CachedImage.cpp \ + loader/cache/CachedResource.cpp \ + loader/cache/CachedResourceClientWalker.cpp \ + loader/cache/CachedResourceHandle.cpp \ + loader/cache/CachedScript.cpp \ loader/CrossOriginAccessControl.cpp \ loader/CrossOriginPreflightResultCache.cpp \ - loader/CachedResourceLoader.cpp \ + loader/cache/CachedResourceLoader.cpp \ loader/DocumentLoader.cpp \ loader/DocumentThreadableLoader.cpp \ loader/DocumentWriter.cpp \ @@ -425,6 +426,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ loader/appcache/DOMApplicationCache.cpp \ loader/appcache/ManifestParser.cpp \ \ + loader/cache/MemoryCache.cpp \ + \ loader/icon/IconDatabase.cpp \ loader/icon/IconLoader.cpp \ loader/icon/IconRecord.cpp \ @@ -529,6 +532,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/android/GeolocationServiceAndroid.cpp \ platform/android/GeolocationServiceBridge.cpp \ platform/android/KeyEventAndroid.cpp \ + platform/android/LanguageAndroid.cpp \ platform/android/LocalizedStringsAndroid.cpp \ platform/android/PlatformTouchEventAndroid.cpp \ platform/android/PlatformTouchPointAndroid.cpp \ @@ -970,7 +974,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ svg/SVGAnimateMotionElement.cpp \ svg/SVGAnimateTransformElement.cpp \ svg/SVGAnimatedPathData.cpp \ - svg/SVGAnimatedPoints.cpp \ svg/SVGAnimationElement.cpp \ svg/SVGCircleElement.cpp \ svg/SVGClipPathElement.cpp \ diff --git a/WebCore/Android.v8bindings.mk b/WebCore/Android.v8bindings.mk index fc74a30..30d7487 100644 --- a/WebCore/Android.v8bindings.mk +++ b/WebCore/Android.v8bindings.mk @@ -54,9 +54,14 @@ LOCAL_SRC_FILES += \ bindings/v8/NPV8Object.cpp \ bindings/v8/ScheduledAction.cpp \ bindings/v8/ScopedDOMDataStore.cpp \ +<<<<<<< HEAD bindings/v8/ScriptCachedFrameData.cpp \ bindings/v8/ScriptCallFrame.cpp \ bindings/v8/ScriptCallStack.cpp \ +======= + bindings/v8/ScriptArray.cpp \ + bindings/v8/ScriptCallStackFactory.cpp \ +>>>>>>> webkit.org at r71558 bindings/v8/ScriptController.cpp \ bindings/v8/ScriptEventListener.cpp \ bindings/v8/ScriptFunctionCall.cpp \ @@ -145,6 +150,7 @@ LOCAL_SRC_FILES += \ bindings/v8/custom/V8HTMLInputElementCustom.cpp \ bindings/v8/custom/V8HTMLOptionElementConstructor.cpp \ bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp \ + bindings/v8/custom/V8HTMLOutputElementCustom.cpp \ bindings/v8/custom/V8HTMLPlugInElementCustom.cpp \ bindings/v8/custom/V8HTMLSelectElementCustom.cpp \ bindings/v8/custom/V8Int16ArrayCustom.cpp \ diff --git a/WebCore/CMakeLists.txt b/WebCore/CMakeLists.txt index 30fd99d..e7e741a 100644 --- a/WebCore/CMakeLists.txt +++ b/WebCore/CMakeLists.txt @@ -22,6 +22,7 @@ SET(WebCore_INCLUDE_DIRECTORIES "${WEBCORE_DIR}/loader" "${WEBCORE_DIR}/loader/appcache" "${WEBCORE_DIR}/loader/archive" + "${WEBCORE_DIR}/loader/cache" "${WEBCORE_DIR}/loader/icon" "${WEBCORE_DIR}/mathml" "${WEBCORE_DIR}/notifications" @@ -99,7 +100,6 @@ SET(WebCore_IDL_INCLUDES SET(WebCore_IDL_PURE_FILES svg/ElementTimeControl.idl svg/SVGAnimatedPathData.idl - svg/SVGAnimatedPoints.idl svg/SVGExternalResourcesRequired.idl svg/SVGFilterPrimitiveStandardAttributes.idl svg/SVGFitToViewBox.idl @@ -262,6 +262,7 @@ SET(WebCore_IDL_FILES html/HTMLOptGroupElement.idl html/HTMLOptionElement.idl html/HTMLOptionsCollection.idl + html/HTMLOutputElement.idl html/HTMLParagraphElement.idl html/HTMLParamElement.idl html/HTMLPreElement.idl @@ -639,6 +640,7 @@ SET(WebCore_SOURCES bindings/js/JSHTMLInputElementCustom.cpp bindings/js/JSHTMLObjectElementCustom.cpp bindings/js/JSHTMLOptionsCollectionCustom.cpp + bindings/js/JSHTMLOutputElementCustom.cpp bindings/js/JSHTMLSelectElementCustom.cpp bindings/js/JSImageConstructor.cpp bindings/js/JSImageDataCustom.cpp @@ -688,8 +690,7 @@ SET(WebCore_SOURCES bindings/js/JSXSLTProcessorCustom.cpp bindings/js/ScheduledAction.cpp bindings/js/ScriptCachedFrameData.cpp - bindings/js/ScriptCallFrame.cpp - bindings/js/ScriptCallStack.cpp + bindings/js/ScriptCallStackFactory.cpp bindings/js/ScriptController.cpp bindings/js/ScriptDebugServer.cpp bindings/js/ScriptEventListener.cpp @@ -898,6 +899,7 @@ SET(WebCore_SOURCES editing/DeleteFromTextNodeCommand.cpp editing/DeleteSelectionCommand.cpp editing/EditCommand.cpp + editing/EditingStyle.cpp editing/Editor.cpp editing/EditorCommand.cpp editing/FormatBlockCommand.cpp @@ -1033,6 +1035,7 @@ SET(WebCore_SOURCES html/HTMLOptGroupElement.cpp html/HTMLOptionElement.cpp html/HTMLOptionsCollection.cpp + html/HTMLOutputElement.cpp html/HTMLParagraphElement.cpp html/HTMLParamElement.cpp html/HTMLParserErrorCodes.cpp @@ -1081,6 +1084,7 @@ SET(WebCore_SOURCES html/TextInputType.cpp html/TimeInputType.cpp html/URLInputType.cpp + html/ValidationMessage.cpp html/ValidityState.cpp html/WeekInputType.cpp html/canvas/CanvasGradient.cpp @@ -1119,32 +1123,34 @@ SET(WebCore_SOURCES inspector/InspectorDOMStorageResource.cpp inspector/InspectorDatabaseResource.cpp inspector/InspectorDebuggerAgent.cpp + inspector/InspectorFileSystemAgent.cpp inspector/InspectorFrontendClientLocal.cpp inspector/InspectorFrontendHost.cpp inspector/InspectorInstrumentation.cpp inspector/InspectorProfilerAgent.cpp - inspector/InspectorResource.cpp inspector/InspectorResourceAgent.cpp inspector/InspectorStyleSheet.cpp inspector/InspectorValues.cpp inspector/InspectorState.cpp inspector/InspectorStorageAgent.cpp inspector/InspectorTimelineAgent.cpp + inspector/ScriptArguments.cpp inspector/ScriptBreakpoint.cpp + inspector/ScriptCallFrame.cpp + inspector/ScriptCallStack.cpp inspector/TimelineRecordFactory.cpp - loader/Cache.cpp - loader/CachedCSSStyleSheet.cpp - loader/CachedFont.cpp - loader/CachedImage.cpp - loader/CachedResource.cpp - loader/CachedResourceClientWalker.cpp - loader/CachedResourceHandle.cpp - loader/CachedScript.cpp - loader/CachedXSLStyleSheet.cpp + loader/cache/CachedCSSStyleSheet.cpp + loader/cache/CachedFont.cpp + loader/cache/CachedImage.cpp + loader/cache/CachedResource.cpp + loader/cache/CachedResourceClientWalker.cpp + loader/cache/CachedResourceHandle.cpp + loader/cache/CachedScript.cpp + loader/cache/CachedXSLStyleSheet.cpp loader/CrossOriginAccessControl.cpp loader/CrossOriginPreflightResultCache.cpp - loader/CachedResourceLoader.cpp + loader/cache/CachedResourceLoader.cpp loader/DocumentLoader.cpp loader/DocumentThreadableLoader.cpp loader/DocumentWriter.cpp @@ -1186,6 +1192,8 @@ SET(WebCore_SOURCES loader/archive/ArchiveResource.cpp loader/archive/ArchiveResourceCollection.cpp + loader/cache/MemoryCache.cpp + loader/icon/IconDatabase.cpp loader/icon/IconLoader.cpp loader/icon/IconRecord.cpp @@ -1771,7 +1779,6 @@ IF (ENABLE_SVG) svg/SVGAnimateMotionElement.cpp svg/SVGAnimateTransformElement.cpp svg/SVGAnimatedPathData.cpp - svg/SVGAnimatedPoints.cpp svg/SVGAnimationElement.cpp svg/SVGCircleElement.cpp svg/SVGClipPathElement.cpp diff --git a/WebCore/CMakeListsEfl.txt b/WebCore/CMakeListsEfl.txt index 3397bc2..18fedc3 100644 --- a/WebCore/CMakeListsEfl.txt +++ b/WebCore/CMakeListsEfl.txt @@ -81,7 +81,7 @@ IF (WTF_PLATFORM_CAIRO) platform/graphics/cairo/OwnPtrCairo.cpp platform/graphics/cairo/PathCairo.cpp platform/graphics/cairo/PatternCairo.cpp - platform/graphics/cairo/PlatformRefPtrCairo.cpp + platform/graphics/cairo/RefPtrCairo.cpp platform/graphics/cairo/SimpleFontDataCairo.cpp platform/graphics/cairo/TransformationMatrixCairo.cpp diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog index 44714b7..6bf8f3c 100644 --- a/WebCore/ChangeLog +++ b/WebCore/ChangeLog @@ -1,3 +1,6324 @@ +2010-11-08 Ryosuke Niwa <rniwa@webkit.org> + + Reviewed by Darin Adler. + + Remove the remaining editing-style functions from ApplyStyleCommand + https://bugs.webkit.org/show_bug.cgi?id=49155 + + Replaced removeNonEditingProperties, editingStyleAtPosition, prepareEditingStyleToApplyAt, + and removeStylesAddedByNode in ApplyStyleCommand.cpp by removeNonEditingProperties, EditingStyle::create, + prepareToApplyAt, and removeStyleAddedByNode in EditingStyle.cpp. + + Also removed unnecessary header includes from various cpp files. + + No tests are added since this is a cleanup. + + * editing/ApplyStyleCommand.cpp: Removed removeNonEditingProperties, editingStyleAtPosition, + prepareEditingStyleToApplyAt, and removeStylesAddedByNode. + * editing/ApplyStyleCommand.h: Ditto. + * editing/DeleteSelectionCommand.cpp: Removed removeEnclosingAnchorStyle. + (WebCore::DeleteSelectionCommand::saveTypingStyleState): Calls removeStylesAddedByNode instead. + * editing/EditingStyle.cpp: + (WebCore::copyEditingProperties): Moved and renamed ApplyStyleCommand::removeNonEditingProperties. + (WebCore::editingStyleFromComputedStyle): Calls copyEditingProperties. Changed the argument to PassRefPtr + as supposed to a raw pointer for convenience. + (WebCore::EditingStyle::init): Calls editingStyleFromComputedStyle. + (WebCore::EditingStyle::removeStyleAddedByNode): Added. + (WebCore::EditingStyle::removeStyleConflictingWithStyleOfNode): Added. + (WebCore::EditingStyle::removeNonEditingProperties): Added. + (WebCore::editingStyleIncludingTypingStyle): Calls copyEditingProperties. + * editing/EditingStyle.h: Added prototypes. + * editing/Editor.cpp: + (WebCore::Editor::selectionComputedStyle): Uses EditingStyle. + * editing/InsertParagraphSeparatorCommand.cpp: + (WebCore::InsertParagraphSeparatorCommand::calculateStyleBeforeInsertion): Ditto. + (WebCore::InsertParagraphSeparatorCommand::applyStyleAfterInsertion): Ditto. + * editing/InsertParagraphSeparatorCommand.h: + * editing/RemoveFormatCommand.cpp: + (WebCore::RemoveFormatCommand::doApply): Ditto. + * editing/ReplaceSelectionCommand.cpp: + (WebCore::handleStyleSpansBeforeInsertion): Ditto. + (WebCore::ReplaceSelectionCommand::handleStyleSpans): Ditto. + (WebCore::ReplaceSelectionCommand::doApply): Ditto. + (WebCore::ReplaceSelectionCommand::completeHTMLReplacement): Ditto. + * editing/ReplaceSelectionCommand.h: + * editing/markup.cpp: Removed removeEnclosingMailBlockquoteStyle and removeDefaultStyles. + (WebCore::createMarkup): Uses EditingStyle. + +2010-11-08 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dan Bernstein. + + Media objects in nested iframes showing above everything else in TinyMCE + https://bugs.webkit.org/show_bug.cgi?id=44877 + + Tests: compositing/iframes/become-composited-nested-iframes.html + compositing/iframes/overlapped-nested-iframes.html + + The overlap testing logic that connects compositing across iframe boundaries + needed to be educated about nestd iframes, for platforms (i.e. Mac) where iframes + are allowed to be independently composited. + + Also fix a bug that could cause iframes (and possibly other elements) that share + style to fail to become composited. + + * css/CSSStyleSelector.cpp: + (WebCore::CSSStyleSelector::canShareStyleWithElement): Disable style sharing for elements + that force synethetic style updates in order to gain RenderLayers, so they can become + composited. This is tested by become-composited-nested-iframes.html, though it is very + timing-dependent. + + * page/FrameView.h: + * page/FrameView.cpp: + (WebCore::FrameView::hasCompositedContentIncludingDescendants): New method that + is a "deep" version of hasCompositedContent() on platforms where that is necessary to ask. + + (WebCore::FrameView::hasCompositingAncestor): New method. + (WebCore::FrameView::setIsOverlapped): If we can have independently composited iframes, + we need to force all descendant iframes to update so that compositing gets hooked up across + nested iframes. + + (WebCore::FrameView::isOverlappedIncludingAncestors): New method, only called on platforms + where allowsIndependentlyCompositedIFrames() is true. + + * rendering/RenderLayerCompositor.h: + * rendering/RenderLayerCompositor.cpp: + (WebCore::RenderLayerCompositor::allowsIndependentlyCompositedIFrames): Utility method that + returns true if an iframe can be a compositing root. + + (WebCore::RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame): Make use of + allowsIndependentlyCompositedIFrames(). + + (WebCore::RenderLayerCompositor::notifyIFramesOfCompositingChange): We need to notify all + descendant frames, not just children. + + * rendering/RenderObject.cpp: + (WebCore::RenderObject::setStyle): Add assert to ensure that we don't do style sharing + for elements that play tricks with synthetic style changes. + + * rendering/RenderWidget.cpp: + (WebCore::RenderWidget::paint): Run overlap testing if a frame has any composited + descendants. + +2010-11-08 Darin Adler <darin@apple.com> + + Reviewed by Alexey Proskuryakov. + + Incorrect image map used when multiple maps have the same name + https://bugs.webkit.org/show_bug.cgi?id=49086 + + Tests: fast/images/image-map-multiple.html + fast/images/image-map-multiple-xhtml.xhtml + + Factored out the code used to look up elements by id and reused it + to look up maps by name. It handles multiple elements efficiently. + + * dom/Document.cpp: + (WebCore::Document::DocumentOrderedMap::clear): Added. + (WebCore::Document::DocumentOrderedMap::add): Added. Has code that + was formerly in addElementById. + (WebCore::Document::DocumentOrderedMap::remove): Added. Has code that + was formerly in removeElementById. + (WebCore::Document::DocumentOrderedMap::get): Added. Has code that + was formerly in getElementById. + (WebCore::keyMatchesId): Added. + (WebCore::Document::getElementById): Use DocumentOrderedMap::get. + (WebCore::Document::addElementById): Use DocumentOrderedMap::add. + (WebCore::Document::removeElementById): Use DocumentOrderedMap::remove. + (WebCore::Document::addImageMap): Use DocumentOrderedMap::add. + (WebCore::Document::removeImageMap): Use DocumentOrderedMap::remove. + (WebCore::keyMatchesMapName): Added. + (WebCore::keyMatchesLowercasedMapName): Added. + (WebCore::Document::getImageMap): Use DocumentOrderedMap::get. + + * dom/Document.h: Added DocumentOrderedMap class, used inside the + Document class. Changed m_imageMapsByName to be a DocumentOrderedMap. + Changed m_elementsById to be a DocumentOrderedMap. Eliminated + m_duplicateIds, since DocumentOrderedMap now has that internally. + +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + * WebCore.xcodeproj/project.pbxproj: Adding developmentRegion back. + + * loader/EmptyClients.h: (WebCore::EmptyChromeClient::focusedFrameChanged): + * page/Chrome.cpp: (WebCore::Chrome::focusedFrameChanged): + * page/Chrome.h: + * page/ChromeClient.h: + Added a new Chrome client notification. + + * page/FocusController.cpp: (WebCore::FocusController::setFocusedFrame): Notify chrome. + +2010-11-08 Anders Carlsson <andersca@apple.com> + + Reviewed by Adam Roben. + + Remove use of HIGetScaleFactor + https://bugs.webkit.org/show_bug.cgi?id=49186 + <rdar://problem/8618410> + + Scale factors can vary on a display-by-display basis and it doesn't make sense + to compute scale factor event coordinates like this. + + * plugins/mac/PluginViewMac.mm: + (WebCore::PluginView::globalMousePosForPlugin): + +2010-11-08 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Texmap] [Qt] Texture mapper initial implementation + https://bugs.webkit.org/show_bug.cgi?id=47070 + + Make the necessary changes in TextureMapperNode in preparation of making it possible to paint it + from a different thread. + The main problematic part was the cache, which made it so that textures can become invalid and have to + be rerendered from content during paint. This is solved here by creating a pack/unpack function for + textures, which lets a texture archive its data away from video memory, or do whatever the platform + thinks is right for freeing memory without needing to re-render again from content (which cannot be + made thread safe). + + After this change, TextureMapperNode moved to its own file, and has 2 entry points: paint and syncCompositingState. + The idea is that syncCompositingState has to be called in the UI thread, paint can be called from a different + thread, and they should block each other. + + The new test tests the cache code-path, to show that the pack/unpack technique works for cases where it + kicks in. + + Test: compositing/layer-creation/many-layers.html + + * WebCore.pro: + * platform/graphics/opengl/TextureMapperGL.cpp: + (WebCore::BitmapTextureGL::~BitmapTextureGL): + (WebCore::BitmapTextureGL::BitmapTextureGL): + (WebCore::TextureMapperGL::TextureMapperGL): + (WebCore::TextureMapperGL::drawTexture): + * platform/graphics/opengl/TextureMapperGL.h: + (WebCore::TextureMapperGL::create): + * platform/graphics/qt/TextureMapperQt.cpp: + (WebCore::BitmapTextureQt::pack): + (WebCore::BitmapTextureQt::unpack): + (WebCore::TextureMapper::create): + (WebCore::BitmapTextureQt::BitmapTextureQt): + * platform/graphics/qt/TextureMapperQt.h: Added. + +2010-11-08 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Sam Weinig. + + Allow applets to participate in accelerated compositing + https://bugs.webkit.org/show_bug.cgi?id=49117 + <rdar://problem/8625819> + + Add RenderApplet to the list of renderers that can optionally get RenderLayers, + and be composited for some reason. + + Not currently testable. + + * rendering/RenderApplet.h: Outdented the class declaration. + + * rendering/RenderApplet.cpp: + (WebCore::RenderApplet::requiresLayer): Return true if the underlying widget + has a platform layer. + (WebCore::RenderApplet::allowsAcceleratedCompositing): Check the widget to see + if it has a platform layer. + + * rendering/RenderLayer.cpp: + (WebCore::RenderLayer::shouldBeNormalFlowOnly): Reformat, and add isApplet(). + (WebCore::RenderLayer::isSelfPaintingLayer): Reformat, and add isApplet(). + * rendering/RenderLayerBacking.cpp: + (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Use 'renderer' local variable + for efficiency. Now check for embedded objects and applets. + * rendering/RenderLayerCompositor.cpp: + (WebCore::RenderLayerCompositor::requiresCompositingForPlugin): Check for embedded objects and applets. + +2010-11-08 Xan Lopez <xlopez@igalia.com> + + Reviewed by Martin Robinson. + + * GNUmakefile.am: add missing files to fix distcheck. + +2010-11-08 Alexander Pavlov <apavlov@chromium.org> + + Reviewed by David Hyatt. + + getPropertyValue("background") causes crash + https://bugs.webkit.org/show_bug.cgi?id=49055 + + Test: fast/css/background-norepeat-crash.html + + * css/CSSMutableStyleDeclaration.cpp: + (WebCore::CSSMutableStyleDeclaration::getLayeredShorthandValue): + +2010-11-08 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [GTK] Wrapped DOM bindings GObjects do not disconnect event listeners when they die + https://bugs.webkit.org/show_bug.cgi?id=49136 + + When GObjects are finalized and freed, disconnect their event listeners, so that + WebCore does not try to fire signals on dead GObjects. We do this by holding a weak + reference to the GObject in the signal listener. When the weak reference notification + callback is executed, we disconnect the event listener. + + No new tests; this fix is proved by prevention of crashes in soon to be + landed editing delegate signals, which are covered by the layout tests. + + * bindings/gobject/GObjectEventListener.cpp: + (WebCore::GObjectEventListener::GObjectEventListener): Updated the constructor. + (WebCore::GObjectEventListener::~GObjectEventListener): Disconnect the weak reference + if the GObject is still alive. + (WebCore::GObjectEventListener::gobjectDestroyed): When the GObject is destroyed, + disconnect the appropriate event listener. + (WebCore::GObjectEventListener::handleEvent): Changes to reflect use of CString + instead of WebCore string. + * bindings/gobject/GObjectEventListener.h: + (WebCore::GObjectEventListener::addEventListener): Changed create to addEventListener, + so that the connection and disconnection is an internal contract to the class. + (WebCore::GObjectEventListener::gobjectDestroyedCallback): Added. + * bindings/scripts/CodeGeneratorGObject.pm: Modified the code generate to use + GObjectEventListener::addEventListener and no longer call addEventListener on + its own. + +2010-11-08 Adam Roben <aroben@apple.com> + + Windows Release build fix after r71514 + + The build was failing due to an alignment error. Strangely, depending + on the order of SVGStaticPropertyTearOff's members, the build will + either fail in Release (as it does before this change), or Debug (as it + did before r71514), but not both. + + * svg/properties/SVGStaticPropertyTearOff.h: + (WebCore::SVGStaticPropertyTearOff::SVGStaticPropertyTearOff): Copied + the #pragma pack trick from JSSVGPODTypeWrapper.h, which has similar + issues. + +2010-11-08 Yury Semikhatsky <yurys@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: decouple ScriptArguments from ScriptCallStack + https://bugs.webkit.org/show_bug.cgi?id=48058 + + ScriptCallFrame and ScriptCallStack are now the same for both JSC and V8. + The factory functions that allow to create ScriptCallStack from VM-specific + objects are defined in ScriptCallStackFactory.cpp. + + ScriptArguments class is used for passing arguments from JS code to the native + part. + + No new tests. This refactoring is covered with existing Console tests. + + * Android.jscbindings.mk: + * Android.v8bindings.mk: + * CMakeLists.txt: + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * bindings/js/JSBindingsAllInOne.cpp: + * bindings/js/JSConsoleCustom.cpp: + (WebCore::JSConsole::profile): + (WebCore::JSConsole::profileEnd): + * bindings/js/ScriptCallStackFactory.cpp: Renamed from WebCore/bindings/js/ScriptCallStack.cpp. + (WebCore::createScriptCallStack): + (WebCore::createScriptArguments): + (WebCore::ScriptCallStack::stackTrace): + * bindings/js/ScriptCallStackFactory.h: Copied from WebCore/bindings/js/ScriptCallFrame.cpp. + * bindings/js/ScriptState.cpp: + (WebCore::ScriptStateProtectedPtr::~ScriptStateProtectedPtr): + (WebCore::ScriptStateProtectedPtr::ScriptStateProtectedPtr): + (WebCore::ScriptStateProtectedPtr::get): + * bindings/js/ScriptState.h: + * bindings/scripts/CodeGeneratorJS.pm: + * bindings/scripts/CodeGeneratorV8.pm: + * bindings/scripts/test/JS/JSTestObj.cpp: + (WebCore::jsTestObjPrototypeFunctionCustomArgsAndException): + * bindings/scripts/test/V8/V8TestObj.cpp: + (WebCore::TestObjInternal::customArgsAndExceptionCallback): + * bindings/v8/ScriptCallFrame.h: Removed. + * bindings/v8/ScriptCallStack.h: Removed. + * bindings/v8/ScriptCallStackFactory.cpp: Renamed from WebCore/bindings/v8/ScriptCallStack.cpp. + (WebCore::toScriptCallFrame): + (WebCore::toScriptCallFramesVector): + (WebCore::createScriptCallStack): + (WebCore::createScriptArguments): + (WebCore::ScriptCallStack::stackTrace): + * bindings/v8/ScriptCallStackFactory.h: Copied from WebCore/bindings/js/ScriptCallFrame.cpp. + * bindings/v8/ScriptController.cpp: + (WebCore::ScriptController::setCaptureCallStackForUncaughtExceptions): + * bindings/v8/ScriptState.h: + (WebCore::ScriptStateProtectedPtr::get): + * bindings/v8/V8ConsoleMessage.cpp: + (WebCore::V8ConsoleMessage::handler): + (WebCore::V8ConsoleMessage::dispatchNow): + * bindings/v8/V8ConsoleMessage.h: + * bindings/v8/custom/V8ConsoleCustom.cpp: + (WebCore::V8Console::traceCallback): + (WebCore::V8Console::assertCallback): + (WebCore::V8Console::profileCallback): + (WebCore::V8Console::profileEndCallback): + * dom/NodeFilter.h: + * inspector/ConsoleMessage.cpp: + (WebCore::ConsoleMessage::ConsoleMessage): + (WebCore::ConsoleMessage::addToFrontend): + (WebCore::ConsoleMessage::updateRepeatCountInConsole): + (WebCore::ConsoleMessage::isEqual): + * inspector/ConsoleMessage.h: + * inspector/InspectorController.cpp: + (WebCore::InspectorController::addMessageToConsole): + (WebCore::InspectorController::startGroup): + * inspector/InspectorController.h: + * inspector/ScriptArguments.cpp: Copied from WebCore/bindings/v8/ScriptCallFrame.cpp. + (WebCore::ScriptArguments::ScriptArguments): + (WebCore::ScriptArguments::~ScriptArguments): + (WebCore::ScriptArguments::argumentAt): + (WebCore::ScriptArguments::globalState): + (WebCore::ScriptArguments::getFirstArgumentAsString): + (WebCore::ScriptArguments::isEqual): + * inspector/ScriptArguments.h: Copied from WebCore/bindings/js/ScriptCallFrame.h. + (WebCore::ScriptArguments::argumentCount): + * inspector/ScriptCallFrame.cpp: Renamed from WebCore/bindings/v8/ScriptCallFrame.cpp. + (WebCore::ScriptCallFrame::ScriptCallFrame): + (WebCore::ScriptCallFrame::~ScriptCallFrame): + (WebCore::ScriptCallFrame::isEqual): + (WebCore::ScriptCallFrame::buildInspectorObject): + * inspector/ScriptCallFrame.h: Renamed from WebCore/bindings/js/ScriptCallFrame.h. + (WebCore::ScriptCallFrame::functionName): + (WebCore::ScriptCallFrame::sourceURL): + (WebCore::ScriptCallFrame::lineNumber): + * inspector/ScriptCallStack.cpp: Renamed from WebCore/bindings/js/ScriptCallFrame.cpp. + (WebCore::ScriptCallStack::ScriptCallStack): + (WebCore::ScriptCallStack::~ScriptCallStack): + (WebCore::ScriptCallStack::at): + (WebCore::ScriptCallStack::size): + (WebCore::ScriptCallStack::isEqual): + (WebCore::ScriptCallStack::buildInspectorObject): + * inspector/ScriptCallStack.h: Renamed from WebCore/bindings/js/ScriptCallStack.h. + * page/Console.cpp: + (WebCore::Console::addMessage): + (WebCore::Console::debug): + (WebCore::Console::error): + (WebCore::Console::info): + (WebCore::Console::log): + (WebCore::Console::dir): + (WebCore::Console::dirxml): + (WebCore::Console::trace): + (WebCore::Console::assertCondition): + (WebCore::Console::count): + (WebCore::Console::markTimeline): + (WebCore::Console::profile): + (WebCore::Console::profileEnd): + (WebCore::Console::timeEnd): + (WebCore::Console::group): + (WebCore::Console::groupCollapsed): + (WebCore::Console::shouldCaptureFullStackTrace): + (WebCore::Console::warn): + * page/Console.h: + (WebCore::Console::profiles): + * page/Console.idl: + +2010-11-08 Nikolas Zimmermann <nzimmermann@rim.com> + + Not reviewed. Build fix. + + Attempt to fix windows builds after r71512. Swap order of members to avoid warning C4121. + + * svg/properties/SVGStaticPropertyTearOff.h: + (WebCore::SVGStaticPropertyTearOff::SVGStaticPropertyTearOff): + +2010-11-08 Mikhail Naganov <mnaganov@chromium.org> + + Unreviewed. Fix Qt build after r71511. + + * inspector/InspectorController.cpp: + (WebCore::InspectorController::restoreInspectorStateFromCookie): + +2010-11-08 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Dirk Schulze. + + Convert SVGPoint/SVGPointList to the new SVGPropertyTearOff concept + https://bugs.webkit.org/show_bug.cgi?id=49067 + + Remove SVGAnimatedPoints interface, not reachable through bindings anyway, it was just another MI interface, that + now has been integrated into SVGPolylineElement/SVGPolygonElement, simplfying the generation and avoiding virtual + calls in SVGPolylineElement/SVGPolygonElement. + + Remove the need to use manual XML <-> SVG DOM synchronization. The points/animatedPoints methods now create + SVGListPropertyTearOffs, thus using the same synchronization/expose-to-bindings concept like all other + animated properties. + + Convert SVGPoint/SVGPointList to use the new SVGPropertyTearOff concept, adapted all code, as SVGPointList + is now a plain Vector<FloatPoint>. Enable StrictTypeChecking for SVGPoint. + + Test: svg/dom/SVGPoint.html + + * Android.derived.v8bindings.mk: Remove SVGAnimatedPoints (and IDL generation). + * Android.mk: Ditto. + * CMakeLists.txt: Ditto. + * DerivedSources.make: Ditto. + * GNUmakefile.am: Ditto. Add SVGStaticPropertyTearOff.h to build. + * WebCore.gypi: Ditto. + * WebCore.order: Remove SVGAnimatedPoints symbols. + * WebCore.pro: Remove SVGAnimatedPoints (and IDL generation). Add SVGStaticPropertyTearOff.h to build. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * bindings/objc/DOMSVG.h: Remove DOMSVGAnimatedPoints include. + * bindings/scripts/CodeGenerator.pm: Adapt code converting SVGPoint/SVGPointList to use the new SVGPropertyTearOff concepts. + * bindings/scripts/CodeGeneratorJS.pm: Ditto. + * bindings/scripts/CodeGeneratorObjC.pm: Ditto. + * bindings/scripts/CodeGeneratorV8.pm: Ditto. + * rendering/SVGRenderTreeAsText.cpp: Adapt for SVGPolyElement API change, use pointList() instead of points() (which is only used for bindings now). + (WebCore::operator<<): + * svg/SVGAllInOne.cpp: Remove SVGAnimatedPoints.cpp. + * svg/SVGAnimateElement.cpp: Adapt for SVGPointList API change, it's not refcounted anymore. + (WebCore::SVGAnimateElement::calculateAnimatedValue): + (WebCore::SVGAnimateElement::calculateFromAndToValues): + (WebCore::SVGAnimateElement::applyResultsToTarget): + * svg/SVGAnimateElement.h: Ditto. + * svg/SVGAnimatedPoints.cpp: Removed. + * svg/SVGAnimatedPoints.h: Removed. + * svg/SVGAnimatedPoints.idl: Removed. + * svg/SVGParserUtilities.cpp: Adapt for SVGPointList API change, it's not refcounted anymore. + (WebCore::pointsListFromSVGData): + * svg/SVGParserUtilities.h: Ditto. + * svg/SVGPoint.idl: Remove PODType marker, and add StrictTypeChecking for x/y attributes. + * svg/SVGPointList.cpp: SVGPointList is now a plain Vector<FloatPoint>, rewrite. + (WebCore::SVGPointList::valueAsString): + (WebCore::SVGPointList::createAnimated): + * svg/SVGPointList.h: Ditto. + (WebCore::SVGPointList::SVGPointList): + * svg/SVGPolyElement.cpp: Remove manual SVG <-> XML DOM synchronization. Now handles through the SVGAnimatedPropertyTearOff concept. + (WebCore::SVGPolyElement::parseMappedAttribute): + (WebCore::SVGPolyElement::svgAttributeChanged): + (WebCore::SVGPolyElement::synchronizeProperty): + (WebCore::SVGPolyElement::synchronizePoints): + (WebCore::SVGPolyElement::points): + (WebCore::SVGPolyElement::animatedPoints): + * svg/SVGPolyElement.h: Reindented. + (WebCore::SVGPolyElement::pointList): + (WebCore::SVGPolyElement::isValid): + (WebCore::SVGPolyElement::supportsMarkers): + * svg/SVGPolygonElement.cpp: Adapt for SVGPointList API change. + (WebCore::SVGPolygonElement::toPathData): + * svg/SVGPolygonElement.idl: Remove SVGAnimatedPoints inheritance. + * svg/SVGPolylineElement.cpp: Adapt for SVGPointList API change. + (WebCore::SVGPolylineElement::toPathData): + * svg/SVGPolylineElement.idl: Remove SVGAnimatedPoints inheritance. + * svg/SVGSVGElement.cpp: + (WebCore::SVGSVGElement::setCurrentTranslate): Use updateCurrentTranslate(). + (WebCore::SVGSVGElement::updateCurrentTranslate): Added, only used by the bindings, after changing a value of SVGStaticPropertyTearOff object. + * svg/SVGSVGElement.h: + (WebCore::SVGSVGElement::currentTranslate): Return reference to m_translation. + * svg/properties/SVGPropertyTearOff.h: Made constructors protected, as SVGStaticPropertyTearOff inherits from it. + (WebCore::SVGPropertyTearOff::commitChange): + * svg/properties/SVGPropertyTraits.h: Add SVGPointList handing. + * svg/properties/SVGStaticPropertyTearOff.h: Added. Used for SVGProperty types returned by attributes, that are not associated with a SVGAnimatedProperty. (SVGSVGElement::currentTranslate). + (WebCore::SVGStaticPropertyTearOff::create): + (WebCore::SVGStaticPropertyTearOff::commitChange): + (WebCore::SVGStaticPropertyTearOff::SVGStaticPropertyTearOff): + +2010-11-08 Mikhail Naganov <mnaganov@chromium.org> + + Reviewed by Adam Barth. + + Web Inspector [Chromium]: Make CPU profiling to survive navigation. + + https://bugs.webkit.org/show_bug.cgi?id=48843 + + * inspector/Inspector.idl: + * inspector/InspectorController.cpp: + (WebCore::InspectorController::restoreInspectorStateFromCookie): + (WebCore::InspectorController::reuseFrontend): + (WebCore::InspectorController::disconnectFrontend): + (WebCore::InspectorController::populateScriptObjects): + (WebCore::InspectorController::restoreProfiler): + (WebCore::InspectorController::didCommitLoad): + (WebCore::InspectorController::startUserInitiatedProfiling): + (WebCore::InspectorController::stopUserInitiatedProfiling): + * inspector/InspectorController.h: + (WebCore::InspectorController::startProfiling): + (WebCore::InspectorController::stopProfiling): + * inspector/InspectorProfilerAgent.cpp: + (WebCore::InspectorProfilerAgent::startUserInitiatedProfiling): + (WebCore::InspectorProfilerAgent::stopUserInitiatedProfiling): + * inspector/InspectorProfilerAgent.h: + * inspector/InspectorState.cpp: + (WebCore::InspectorState::InspectorState): + * inspector/InspectorState.h: + * inspector/front-end/ProfilesPanel.js: + (WebInspector.ProfilesPanel.prototype.hasTemporaryProfile): + (WebInspector.ProfilesPanel.prototype.hasProfile): + * inspector/front-end/inspector.js: + (WebInspector.setRecordingProfile): + +2010-11-08 Renata Hodovan <reni@webkit.org> + + Reviewed by Nikolas Zimmermann. + + SVGFEConvolveMatrixElement doesn't support dynamic invalidation + https://bugs.webkit.org/show_bug.cgi?id=47660 + + Wrap orderX and orderY into the common order property according to the w3 standard and remove them from svnattrs.in. + The patch implements the orderXIdentifier and orderYIdentifier getter functions to reach + properly the orderX and orderY components of order property from SVG DOM. + + Tests: svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-bias-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-divisor-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-edgeMode-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-in-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-kernelMatrix-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-kernelUnitLength-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-order-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-preserveAlpha-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-targetX-prop.html + svg/dynamic-updates/SVGFEConvolveMatrixElement-svgdom-targetY-prop.html + + * svg/SVGFEConvolveMatrixElement.cpp: + (WebCore::SVGFEConvolveMatrixElement::orderXIdentifier): + (WebCore::SVGFEConvolveMatrixElement::orderYIdentifier): + * svg/SVGFEConvolveMatrixElement.h: + * svg/svgattrs.in: + +2010-11-08 Adam Barth <abarth@webkit.org> + + Reviewed by Antti Koivisto. + + Rename CachedResourceLoader::m_doc to CachedResourceLoader::m_document + https://bugs.webkit.org/show_bug.cgi?id=49163 + + The usual convention is to use "document", not "doc" to refer to the + document. + + * css/CSSCursorImageValue.cpp: + (WebCore::CSSCursorImageValue::cachedImage): + * dom/XMLDocumentParserLibxml2.cpp: + (WebCore::shouldAllowExternalLoad): + * loader/cache/CachedResourceLoader.cpp: + (WebCore::CachedResourceLoader::CachedResourceLoader): + (WebCore::CachedResourceLoader::frame): + (WebCore::CachedResourceLoader::requestImage): + (WebCore::CachedResourceLoader::canRequest): + (WebCore::CachedResourceLoader::requestResource): + (WebCore::CachedResourceLoader::printAccessDeniedMessage): + (WebCore::CachedResourceLoader::preload): + (WebCore::CachedResourceLoader::checkForPendingPreloads): + (WebCore::CachedResourceLoader::requestPreload): + * loader/cache/CachedResourceLoader.h: + (WebCore::CachedResourceLoader::document): + * loader/cache/MemoryCache.cpp: + (WebCore::MemoryCache::requestResource): + * loader/loader.cpp: + (WebCore::Loader::load): + (WebCore::Loader::Host::servePendingRequests): + (WebCore::Loader::Host::didFinishLoading): + (WebCore::Loader::Host::didFail): + * xml/XSLTProcessorLibxslt.cpp: + (WebCore::docLoaderFunc): + +2010-11-07 Adam Barth <abarth@webkit.org> + + Unreviewed. Remove some unneeded includes. + + * loader/FrameLoader.cpp: + * loader/PlaceholderDocument.cpp: + +2010-11-07 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Rename Cache to MemoryCache + https://bugs.webkit.org/show_bug.cgi?id=49159 + + So sayeth the diagram. + + * Android.mk: + * CMakeLists.txt: + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * css/CSSImageValue.cpp: + * dom/ContainerNode.cpp: + * history/PageCache.cpp: + * inspector/InspectorCSSStore.h: + * inspector/InspectorResourceAgent.cpp: + * loader/FrameLoader.cpp: + * loader/archive/cf/LegacyWebArchive.cpp: + * loader/cache/Cache.cpp: Removed. + * loader/cache/Cache.h: Removed. + * loader/cache/CachedCSSStyleSheet.cpp: + (WebCore::CachedCSSStyleSheet::allClientsRemoved): + * loader/cache/CachedFont.cpp: + * loader/cache/CachedFont.h: + * loader/cache/CachedImage.cpp: + (WebCore::CachedImage::destroyDecodedData): + * loader/cache/CachedImage.h: + * loader/cache/CachedResource.cpp: + * loader/cache/CachedResource.h: + * loader/cache/CachedResourceLoader.cpp: + * loader/cache/CachedResourceLoader.h: + * loader/cache/CachedScript.cpp: + (WebCore::CachedScript::destroyDecodedData): + * loader/cache/MemoryCache.cpp: Copied from WebCore/loader/cache/Cache.cpp. + (WebCore::cache): + (WebCore::MemoryCache::MemoryCache): + (WebCore::MemoryCache::requestResource): + (WebCore::MemoryCache::requestUserCSSStyleSheet): + (WebCore::MemoryCache::revalidateResource): + (WebCore::MemoryCache::revalidationSucceeded): + (WebCore::MemoryCache::revalidationFailed): + (WebCore::MemoryCache::resourceForURL): + (WebCore::MemoryCache::deadCapacity): + (WebCore::MemoryCache::liveCapacity): + (WebCore::MemoryCache::pruneLiveResources): + (WebCore::MemoryCache::pruneDeadResources): + (WebCore::MemoryCache::setCapacities): + (WebCore::MemoryCache::makeResourcePurgeable): + (WebCore::MemoryCache::evict): + (WebCore::MemoryCache::addCachedResourceLoader): + (WebCore::MemoryCache::removeCachedResourceLoader): + (WebCore::MemoryCache::lruListFor): + (WebCore::MemoryCache::removeFromLRUList): + (WebCore::MemoryCache::insertInLRUList): + (WebCore::MemoryCache::resourceAccessed): + (WebCore::MemoryCache::removeFromLiveDecodedResourcesList): + (WebCore::MemoryCache::insertInLiveDecodedResourcesList): + (WebCore::MemoryCache::addToLiveResourcesSize): + (WebCore::MemoryCache::removeFromLiveResourcesSize): + (WebCore::MemoryCache::adjustSize): + (WebCore::MemoryCache::TypeStatistic::addResource): + (WebCore::MemoryCache::getStatistics): + (WebCore::MemoryCache::setDisabled): + (WebCore::MemoryCache::dumpStats): + (WebCore::MemoryCache::dumpLRULists): + * loader/cache/MemoryCache.h: Copied from WebCore/loader/cache/Cache.h. + (WebCore::MemoryCache::shouldMakeResourcePurgeableOnEviction): + * loader/loader.cpp: + * page/EventSource.cpp: + * page/Settings.h: + * xml/XMLHttpRequest.cpp: + (WebCore::XMLHttpRequest::createRequest): + +2010-11-07 Eric Seidel <eric@webkit.org> + + Unreviewed. Attempt to fix the windows build. + + Move the rest of the cache-related files into loader/cache + https://bugs.webkit.org/show_bug.cgi?id=49156 + + * WebCore.vcproj/WebCoreCommon.vsprops: + * WebCore.vcproj/copyForwardingHeaders.cmd: + +2010-11-07 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + Move the rest of the cache-related files into loader/cache + https://bugs.webkit.org/show_bug.cgi?id=49156 + + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * loader/CachePolicy.h: Removed. + * loader/CachedCSSStyleSheet.cpp: Removed. + * loader/CachedCSSStyleSheet.h: Removed. + * loader/CachedFont.cpp: Removed. + * loader/CachedFont.h: Removed. + * loader/CachedImage.cpp: Removed. + * loader/CachedImage.h: Removed. + * loader/CachedResource.cpp: Removed. + * loader/CachedResource.h: Removed. + * loader/CachedResourceClient.h: Removed. + * loader/CachedResourceClientWalker.cpp: Removed. + * loader/CachedResourceClientWalker.h: Removed. + * loader/CachedResourceHandle.cpp: Removed. + * loader/CachedResourceHandle.h: Removed. + * loader/CachedResourceLoader.cpp: Removed. + * loader/CachedResourceLoader.h: Removed. + * loader/CachedScript.cpp: Removed. + * loader/CachedScript.h: Removed. + * loader/CachedXSLStyleSheet.cpp: Removed. + * loader/CachedXSLStyleSheet.h: Removed. + * loader/cache/CachePolicy.h: Copied from WebCore/loader/CachePolicy.h. + * loader/cache/CachedCSSStyleSheet.cpp: Copied from WebCore/loader/CachedCSSStyleSheet.cpp. + * loader/cache/CachedCSSStyleSheet.h: Copied from WebCore/loader/CachedCSSStyleSheet.h. + * loader/cache/CachedFont.cpp: Copied from WebCore/loader/CachedFont.cpp. + * loader/cache/CachedFont.h: Copied from WebCore/loader/CachedFont.h. + * loader/cache/CachedImage.cpp: Copied from WebCore/loader/CachedImage.cpp. + * loader/cache/CachedImage.h: Copied from WebCore/loader/CachedImage.h. + * loader/cache/CachedResource.cpp: Copied from WebCore/loader/CachedResource.cpp. + * loader/cache/CachedResource.h: Copied from WebCore/loader/CachedResource.h. + * loader/cache/CachedResourceClient.h: Copied from WebCore/loader/CachedResourceClient.h. + * loader/cache/CachedResourceClientWalker.cpp: Copied from WebCore/loader/CachedResourceClientWalker.cpp. + * loader/cache/CachedResourceClientWalker.h: Copied from WebCore/loader/CachedResourceClientWalker.h. + * loader/cache/CachedResourceHandle.cpp: Copied from WebCore/loader/CachedResourceHandle.cpp. + * loader/cache/CachedResourceHandle.h: Copied from WebCore/loader/CachedResourceHandle.h. + * loader/cache/CachedResourceLoader.cpp: Copied from WebCore/loader/CachedResourceLoader.cpp. + * loader/cache/CachedResourceLoader.h: Copied from WebCore/loader/CachedResourceLoader.h. + * loader/cache/CachedScript.cpp: Copied from WebCore/loader/CachedScript.cpp. + * loader/cache/CachedScript.h: Copied from WebCore/loader/CachedScript.h. + * loader/cache/CachedXSLStyleSheet.cpp: Copied from WebCore/loader/CachedXSLStyleSheet.cpp. + * loader/cache/CachedXSLStyleSheet.h: Copied from WebCore/loader/CachedXSLStyleSheet.h. + +2010-11-07 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Rename X-Purpose to Purpose + https://bugs.webkit.org/show_bug.cgi?id=47802 + + As requested by IETF HTTP WG. This patch is part of a larger movement + in the HTTP community to move away from X- headers. Various senior + folks at the IETF believe they're a failed experiment: + + http://tools.ietf.org/html/draft-saintandre-xdash-considered-harmful + + * loader/loader.cpp: + (WebCore::Loader::Host::servePendingRequests): + +2010-11-07 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + Assert that a non-null PassRefPtr<Document> has a non-null frame in Frame::setDocument() + https://bugs.webkit.org/show_bug.cgi?id=49152 + + Add an ASSERT to ensure that a non-null Document has a non-null Frame + in Frame::setDocument(). + + Currently, whenever Frame::setDocument() is called with a non-null + Document the Document has a non-null Frame. We should assert this + invariant. + + * page/Frame.cpp: + (WebCore::Frame::setDocument): + +2010-11-07 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + Move Cache.* into loader/cache in as a start to cleaning up loader/ + https://bugs.webkit.org/show_bug.cgi?id=49153 + + * Android.mk: + * CMakeLists.txt: + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * loader/cache/Cache.cpp: Renamed from WebCore/loader/Cache.cpp. + (WebCore::cache): + (WebCore::Cache::Cache): + (WebCore::createResource): + (WebCore::Cache::requestResource): + (WebCore::Cache::requestUserCSSStyleSheet): + (WebCore::Cache::revalidateResource): + (WebCore::Cache::revalidationSucceeded): + (WebCore::Cache::revalidationFailed): + (WebCore::Cache::resourceForURL): + (WebCore::Cache::deadCapacity): + (WebCore::Cache::liveCapacity): + (WebCore::Cache::pruneLiveResources): + (WebCore::Cache::pruneDeadResources): + (WebCore::Cache::setCapacities): + (WebCore::Cache::makeResourcePurgeable): + (WebCore::Cache::evict): + (WebCore::Cache::addCachedResourceLoader): + (WebCore::Cache::removeCachedResourceLoader): + (WebCore::fastLog2): + (WebCore::Cache::lruListFor): + (WebCore::Cache::removeFromLRUList): + (WebCore::Cache::insertInLRUList): + (WebCore::Cache::resourceAccessed): + (WebCore::Cache::removeFromLiveDecodedResourcesList): + (WebCore::Cache::insertInLiveDecodedResourcesList): + (WebCore::Cache::addToLiveResourcesSize): + (WebCore::Cache::removeFromLiveResourcesSize): + (WebCore::Cache::adjustSize): + (WebCore::Cache::TypeStatistic::addResource): + (WebCore::Cache::getStatistics): + (WebCore::Cache::setDisabled): + (WebCore::Cache::dumpStats): + (WebCore::Cache::dumpLRULists): + * loader/cache/Cache.h: Renamed from WebCore/loader/Cache.h. + (WebCore::Cache::LRUList::LRUList): + (WebCore::Cache::TypeStatistic::TypeStatistic): + (WebCore::Cache::loader): + (WebCore::Cache::disabled): + (WebCore::Cache::setPruneEnabled): + (WebCore::Cache::prune): + (WebCore::Cache::setDeadDecodedDataDeletionInterval): + (WebCore::Cache::deadDecodedDataDeletionInterval): + (WebCore::Cache::remove): + (WebCore::Cache::shouldMakeResourcePurgeableOnEviction): + +2010-11-05 Helder Correia <helder@sencha.com> + + Reviewed by Andreas Kling. + + [Qt] box-shadow does not blur (is solid) when using border-radius + https://bugs.webkit.org/show_bug.cgi?id=46327 + + Implement blurred box-shadow when styling with border-radius. + This change is related to https://bugs.webkit.org/show_bug.cgi?id=44488 + + * platform/graphics/qt/GraphicsContextQt.cpp: + (WebCore::GraphicsContext::fillRoundedRect): + +2010-11-07 John Reck <jreck@google.com> + + Reviewed by Steve Block. + + Implements navigator.language for Android + https://bugs.webkit.org/show_bug.cgi?id=49099 + + Android was previously hardcoding the value for WebCore::platformDefaultLanguage(). + This patch removes the hardcoding and calls into the PlatformBridge to get the + correct language based off of the user's settings. + + No new tests needed, this is already covered + + * Android.mk: + * platform/android/LanguageAndroid.cpp: Added. + (WebCore::platformDefaultLanguage): + * platform/android/PlatformBridge.h: + * platform/android/TemporaryLinkStubs.cpp: + +2010-11-07 Robert Hogan <robert@webkit.org> + + Reviewed by Andreas Kling. + + [qt] screenDepthPerComponent returns the wrong value + + Return best estimate of the number of bits per color + rather than screen depth. + + Add a layout test to sanity check screenDepthPerComponent. + + https://bugs.webkit.org/show_bug.cgi?id=20289 + + Test: fast/css/media-rule-screenDepthPerComponent.html + + * platform/qt/PlatformScreenQt.cpp: + (WebCore::screenDepthPerComponent): + +2010-11-07 Chang Shu <chang.shu@nokia.com> + + Reviewed by Antonio Gomes. + + Add a helper function to avoid duplicated code. + https://bugs.webkit.org/show_bug.cgi?id=49085 + + * dom/SelectElement.cpp: + * editing/SelectionController.cpp: + (WebCore::SelectionController::modify): + * html/HTMLInputElement.cpp: + (WebCore::HTMLInputElement::isKeyboardFocusable): + * page/EventHandler.cpp: + (WebCore::EventHandler::defaultArrowEventHandler): + * page/SpatialNavigation.cpp: + (WebCore::isSpatialNavigationEnabled): + * page/SpatialNavigation.h: + +2010-11-06 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Simon Fraser. + + Web Inspector: Some image resources don't display the image when selected in the Resources panel. + https://bugs.webkit.org/show_bug.cgi?id=48935 + + Marked resources loaded from memory cache as finished. + + * inspector/front-end/ResourceManager.js: + (WebInspector.ResourceManager.prototype.didLoadResourceFromMemoryCache): + +2010-11-06 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: XHR logging is not checked in context menu after browser restart. + https://bugs.webkit.org/show_bug.cgi?id=49133 + + * inspector/InspectorState.cpp: + (WebCore::InspectorState::InspectorState): + +2010-11-06 Ryosuke Niwa <rniwa@webkit.org> + + Unreviewed Windows build fix. + + * editing/EditingAllInOne.cpp: Added EditingStyle.cpp + +2010-11-04 Ryosuke Niwa <rniwa@webkit.org> + + Reviewed by Darin Adler. + + Bug 46335 - Add EditingStyle + https://bugs.webkit.org/show_bug.cgi?id=46335 + + Added EditingStyle to WebCore/editing. This class is intended to encapsulate getPropertiesNotIn, removeNonEditingProperties, + editingStyleAtPosition, and prepareEditingStyleToApplyAt in ApplyStyleCommand.cpp once deployed everywhere. + Deployed it in typing styles. + + No new tests are added since this is a refactoring in progress. + + * CMakeLists.txt: Added EditingStyle.cpp + * GNUmakefile.am: Added EditingStyle.cpp and EditingStyle.h + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * editing/CompositeEditCommand.cpp: + (WebCore::CompositeEditCommand::moveParagraphs): Calls editingStyleIncludingTypingStyle. + (WebCore::CompositeEditCommand::breakOutOfEmptyListItem): Uses EditingStyle. + * editing/DeleteSelectionCommand.cpp: + (WebCore::DeleteSelectionCommand::saveTypingStyleState): Ditto. + (WebCore::DeleteSelectionCommand::calculateTypingStyleAfterDelete): Ditto. + * editing/DeleteSelectionCommand.h: + * editing/EditingStyle.cpp: Added. + (WebCore::editingStyleFromComputedStyle): Added. + (WebCore::EditingStyle::EditingStyle): Added. + (WebCore::EditingStyle::init): Added; a clone of ApplyStyleCommand::editingStyleAtPosition. + (WebCore::EditingStyle::removeTextFillAndStrokeColorsIfNeeded): Extracted from init. + (WebCore::EditingStyle::replaceFontSizeByKeywordIfPossible): Extracted from init. + (WebCore::EditingStyle::isEmpty): Added. + (WebCore::EditingStyle::setStyle): Added. + (WebCore::EditingStyle::clear): Added. + (WebCore::EditingStyle::removeBlockProperties): Added. + (WebCore::EditingStyle::prepareToApplyAt): Added. + (WebCore::editingStyleIncludingTypingStyle): Added. + * editing/EditingStyle.h: Added. + (WebCore::EditingStyle::create): Added. + (WebCore::EditingStyle::style): Added. + * editing/RemoveFormatCommand.cpp: + (WebCore::RemoveFormatCommand::doApply): Uses EditingStyle. + * editing/SelectionController.h: + (WebCore::SelectionController::typingStyle): Uses EditingStyle. + (WebCore::SelectionController::clearTypingStyle): Uses EditingStyle. + (WebCore::SelectionController::setTypingStyle): Uses EditingStyle. + * rendering/style/RenderStyle.h: Added EditingStyle as a friend. + +2010-11-05 David Hyatt <hyatt@apple.com> + + Reviewed by Dan Bernstein and Simon Fraser. + + https://bugs.webkit.org/show_bug.cgi?id=47237 + + Make selection work with vertical text. This patch fixes a bug in the computation of lineTop. For lines + with positive leading, lineTop was incorrectly including the top leading. Since the flipping of lines + for "lr" and "bt" writing modes involved flipping using lineTop and lineBottom, an incorrect lineTop meant + that those modes were mis-rendering. This is why the Japanese "lr" text examples have the first line smushed + too far against the border. + + Fixing lineTop to no longer incorrectly include top leading has implications for editing. I ended up + rewriting positionForPoint to exactly match selection, since that seemed to be the most intuitive + behavior. I got rid of the verticalClickFudgeFactor and now just use selectionTop and selectionBottom + instead of lineTop and lineBottom. I am pretty sure the code used selectionTop in a previous incarnation + anyway and that I moved away from it when I implemented lineTop and lineBottom. The code then grew + more complicated from people trying to work with lineTop and lineBottom, but going back to selectionTop + and selectionBottom is the right behavior I think. One editing test has been updated after this change + (editing/selection/after-line-break.html), and one DOM test has been changed to not hit test past the + bottom of a line (fast/dom/Document/CaretRangeFromPoint/basic.html). + + I patched selection painting of InlineTextBoxes so that the leading going up to the next line box is used + for "lr" and "bt" modes instead of the previous box. This makes sense for English text, but we may want + a different policy for Japanese text eventually (possibly just splitting the difference instead). Leaving it + this way for now, and we can collect feedback on the design. + + I rewrote all of the selection gap painting code to be writing-mode aware. During the course of rewriting this + code I noticed a bug in the logicalLeftSelectionOffset and logicalRightSelectionOffset functions where there + was a coordinate space mismatch on a comparison. Fixing this improves the repaint/selection-clear.html test. + + Added new tests in fast/blockflow/. + + * rendering/InlineFlowBox.cpp: + (WebCore::InlineFlowBox::placeBoxesInBlockDirection): + * rendering/InlineFlowBox.h: + * rendering/InlineTextBox.cpp: + (WebCore::InlineTextBox::selectionBottom): + (WebCore::InlineTextBox::paintSelection): + (WebCore::InlineTextBox::paintCompositionBackground): + (WebCore::InlineTextBox::paintSpellingOrGrammarMarker): + (WebCore::InlineTextBox::paintTextMatchMarker): + * rendering/InlineTextBox.h: + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::selectionGapRectsForRepaint): + (WebCore::RenderBlock::paintSelection): + (WebCore::clipOutPositionedObjects): + (WebCore::blockDirectionOffset): + (WebCore::inlineDirectionOffset): + (WebCore::RenderBlock::logicalRectToPhysicalRect): + (WebCore::RenderBlock::selectionGaps): + (WebCore::RenderBlock::inlineSelectionGaps): + (WebCore::RenderBlock::blockSelectionGaps): + (WebCore::RenderBlock::blockSelectionGap): + (WebCore::RenderBlock::logicalLeftSelectionGap): + (WebCore::RenderBlock::logicalRightSelectionGap): + (WebCore::RenderBlock::logicalLeftSelectionOffset): + (WebCore::RenderBlock::logicalRightSelectionOffset): + * rendering/RenderBlock.h: + * rendering/RenderBox.cpp: + (WebCore::RenderBox::flipForWritingMode): + * rendering/RenderBox.h: + (WebCore::RenderBox::logicalBottom): + * rendering/RootInlineBox.cpp: + (WebCore::RootInlineBox::alignBoxesInBlockDirection): + (WebCore::RootInlineBox::lineSelectionGap): + (WebCore::RootInlineBox::selectionTop): + (WebCore::RootInlineBox::selectionBottom): + * rendering/RootInlineBox.h: + +2010-11-05 Simon Fraser <simon.fraser@apple.com> + + Just put things back the way they were. Too many mysterious linker errors. + +2010-11-05 Simon Fraser <simon.fraser@apple.com> + + Undo most of the previous commit since the compiler seems to have trouble + with an inlined operator++ in debug builds. + + * platform/DeprecatedPtrListImpl.cpp: + (WebCore::DeprecatedPtrListImplIterator::operator++): + * platform/DeprecatedPtrListImpl.h: + +2010-11-05 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dave Hyatt. + + Inline some DeprecatedPtrListImplIterator methods for performance + https://bugs.webkit.org/show_bug.cgi?id=49124 + + This is a ~4% performance improvement on some Peacekeepr "Community" tests. + + * platform/DeprecatedPtrListImpl.cpp: + * platform/DeprecatedPtrListImpl.h: + (WebCore::DeprecatedListNode::DeprecatedListNode): + (WebCore::DeprecatedPtrListImplIterator::current): + (WebCore::DeprecatedPtrListImplIterator::operator++): + +2010-11-05 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Gray-scale PNGs with color profiles don't decode properly on Chromium Mac + https://bugs.webkit.org/show_bug.cgi?id=49110 + + Applying the color profile from this PNG was causing the image to + triple in width. This seems to be because both the PNG decoder and + CoreGraphics were trying to expand the gray-scale image to RGB. To fix + this issue, I've disabled color profile support for gray-scale PNGs. + + Test: fast/images/gray-scale-png-with-color-profile.html + + * platform/image-decoders/png/PNGImageDecoder.cpp: + (WebCore::PNGImageDecoder::headerAvailable): + +2010-11-05 Jian Li <jianli@chromium.org> + + Reviewed by Dmitry Titov. + + Need to check if page is detached in Frame::transferChildFrameToNewDocument to avoid occasional crash + https://bugs.webkit.org/show_bug.cgi?id=49116 + + The fix is to add the check. + + * page/Frame.cpp: + (WebCore::Frame::transferChildFrameToNewDocument): + +2010-11-04 Enrica Casucci <enrica@apple.com> + + Reviewed by Adele Peterson. + + Pasting large amounts of plain text in a text area is very slow + https://bugs.webkit.org/show_bug.cgi?id=49040 + <rdar://problem/7640912> + + The optimization consists in skipping the ApplyStyle command when + pasting into a text area or into an element that has -webkit-user-modify: read-write-plaintext-only. + The biggest performance hit comes from iterating through + a large number of paragraph when no style change is needed. + A further step will be to improve the paragraph iteration when it + can't be avoided. + + * editing/ReplaceSelectionCommand.cpp: + (WebCore::ReplaceSelectionCommand::doApply): Check if the selection + is in a text form control or in an element that has -webkit-user-modify: read-write-plaintext-only + and force no style matching. + +2010-11-05 Ryosuke Niwa <rniwa@webkit.org> + + Reviewed by David Levin. + + JSCallbackData::invokeCallback triggers layout from a worker thread + https://bugs.webkit.org/show_bug.cgi?id=49096 + + Fixed the bug by only calling updateStyleForAllDocuments when the context is document in + JSCallbackData::invokeCallback. + + No new tests are added since many of existing workers tests hit the added assertion in debug builds. + + * bindings/js/JSCallbackData.cpp: + (WebCore::JSCallbackData::invokeCallback): No longer calls updateStyleForAllDocuments unconditionally. + * dom/Document.cpp: + (WebCore::Document::updateStyleIfNeeded): Added ASSERT(isMainThread()). + (WebCore::Document::updateStyleForAllDocuments): Ditto. + (WebCore::Document::updateLayout): Ditto. + +2010-11-05 Ilya Sherman <isherman@chromium.org> + + Reviewed by Simon Fraser. + + Querying selection start and end should be const + https://bugs.webkit.org/show_bug.cgi?id=48786 + + * rendering/RenderTextControl.cpp: + (WebCore::RenderTextControl::selectionStart): + (WebCore::RenderTextControl::selectionEnd): + (WebCore::RenderTextControl::visiblePositionForIndex): + (WebCore::RenderTextControl::indexForVisiblePosition): + * rendering/RenderTextControl.h: + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Move resumeAnimations/suspendAnimations from Frame to AnimationController. + https://bugs.webkit.org/show_bug.cgi?id=49073 + + Changed the name of suspendAnimations/resumeAnimations to + suspendAnimationsInDocument/resumeAnimationsInDocument. These are no + longer exported, but have the same functionality as before. I then + added new suspendAnimations/resumeAnimations function which take + no params and suspend/resume on the frame owning the animation + controller and all its child frames. These are the functions that + are now exported. I then changed all the platform specific WebKit + code to use these functions. + + * WebCore.exp.in: + * page/Frame.cpp: + * page/Frame.h: + * page/animation/AnimationController.cpp: + (WebCore::AnimationControllerPrivate::suspendAnimations): + (WebCore::AnimationControllerPrivate::resumeAnimations): + +2010-11-04 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + Need to simulate DEPTH_STENCIL in framebufferRenderbuffer / getFramebufferAttachmentParameter + https://bugs.webkit.org/show_bug.cgi?id=49020 + + * html/canvas/WebGLFramebuffer.cpp: + (WebCore::WebGLFramebuffer::getAttachment): Return the attached renderbuffer/texture. + (WebCore::WebGLFramebuffer::isIncomplete): Add an extra parameter deciding whether we should check internal format matching the attachment point or not. + (WebCore::WebGLFramebuffer::onAccess): Pass extra parameter in isIncomplete. + * html/canvas/WebGLFramebuffer.h: + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::checkFramebufferStatus): Pass extra parameter in isIncomplete. + (WebCore::WebGLRenderingContext::framebufferRenderbuffer): Emulate DEPTH_STENCIL_ATTACHMENT; re-attach previously conflicted buffers upon detachment. + (WebCore::WebGLRenderingContext::getFramebufferAttachmentParameter): Throw an error when conflicted attachments exist. + (WebCore::WebGLRenderingContext::renderbufferStorage): Map DEPTH_STENCIL to DEPTH24_STENCIL8. + * platform/graphics/Extensions3D.h: Add DEPTH24_STENCIL8 enum and update the documentation. + * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp: + (WebCore::GraphicsContext3D::framebufferRenderbuffer): Remove emulation code at this level. + +2010-11-05 Chris Guillory <chris.guillory@google.com> + + Reviewed by Chris Fleizach. + + Keep a reference to the scrollbar in accessibility scrollbar. + https://bugs.webkit.org/show_bug.cgi?id=48896 + + * accessibility/AccessibilityScrollbar.h: + (WebCore::AccessibilityScrollbar::scrollbar): + +2010-11-05 Chang Shu <chang.shu@nokia.com> + + Reviewed by Antonio Gomes. + + Add support for <select> element in single selection mode. We use space to + trigger arrow key handling for selection change or spatial navigation. + https://bugs.webkit.org/show_bug.cgi?id=48937 + + * dom/SelectElement.cpp: + (WebCore::isSpatialNavigationEnabled): + (WebCore::SelectElement::menuListDefaultEventHandler): + (WebCore::SelectElement::listBoxDefaultEventHandler): + +2010-11-05 Charlie Reis <creis@chromium.org> + + Reviewed by Darin Fisher. + + Need to expose HistoryController::previousItem() for Chromium WebKit API. + https://bugs.webkit.org/show_bug.cgi?id=48809 + + * loader/HistoryController.h: + +2010-11-05 Ryosuke Niwa <rniwa@webkit.org> + + Reviewed by Darin Adler. + + Crash in ApplyStyleCommand::surroundNodeRangeWithElement + https://bugs.webkit.org/show_bug.cgi?id=48581 + + The crash was caused by a false assertion that we can always recover selection in + ApplyStyleCommand::removeInlineStyle. Fixed the crash by removing the assertion + and adding an early exit to the call site. Also converted raw pointers to RefPtr + in surroundNodeRangeWithElement and addInlineStyleIfNeeded. + + Test (non-Mac platforms): editing/style/iframe-onload-crash.html + + * editing/ApplyStyleCommand.cpp: + (WebCore::ApplyStyleCommand::applyInlineStyle): + (WebCore::ApplyStyleCommand::removeInlineStyle): + (WebCore::ApplyStyleCommand::surroundNodeRangeWithElement): + (WebCore::ApplyStyleCommand::addInlineStyleIfNeeded): + * editing/ApplyStyleCommand.h: + +2010-11-04 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=49008 + <rdar://problem/7906226> Frequent crashes on mail.yahoo.co.jp + + Instance::m_runtimeObject used to be zeroed out by RuntimeObject destructor. But the + destructor may not be called immediately - GC first marks an object as dead, and only + destroys it when its cell is overwritten. So, m_runtimeObject would keep pointing to a dead + object. + + Functions in JSPluginElementFunctions.cpp put the RuntimeObject on stack for later use, + but if it's already dead, it can be overwritten before use. + + The solution is of course to use WeakGCPtr, which returns 0 for dead objects. + + * bridge/jsc/BridgeJSC.cpp: + (JSC::Bindings::Instance::Instance): + (JSC::Bindings::Instance::~Instance): + (JSC::Bindings::Instance::createRuntimeObject): + (JSC::Bindings::Instance::willDestroyRuntimeObject): + (JSC::Bindings::Instance::willInvalidateRuntimeObject): + * bridge/jsc/BridgeJSC.h: + * bridge/runtime_object.cpp: + (JSC::Bindings::RuntimeObject::~RuntimeObject): + (JSC::Bindings::RuntimeObject::invalidate): + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Make suspendAnimations/resumeAnimations and setCSSAnimations traverse through subframes and remember state + https://bugs.webkit.org/show_bug.cgi?id=46945 + + Add new funtions to suspend and resume animations. The go through all subframes and suspend or resume them + recursively. + + Test: animations/stop-animation-on-suspend.html + + * WebCore.exp.in: + * page/Frame.cpp: + (WebCore::Frame::suspendAnimations): + (WebCore::Frame::resumeAnimations): + * page/Frame.h: + +2010-11-05 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: Crash in InspectorDOMAgent::innerParentNode. + https://bugs.webkit.org/show_bug.cgi?id=49054 + + * inspector/InspectorDOMAgent.cpp: + (WebCore::InspectorDOMAgent::setOuterHTML): + +2010-11-05 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: XHR logging in console should give complete view of resource. + https://bugs.webkit.org/show_bug.cgi?id=48998 + + Drive-by fixes: linkify line number to scripts panel, fall back to resources; + enable multiline console entry on shift modifier as well. + + * inspector/front-end/NetworkPanel.js: + (WebInspector.NetworkPanel): + (WebInspector.NetworkPanel.prototype._reset): + (WebInspector.NetworkPanel.prototype.refreshResource): + (WebInspector.NetworkPanel.prototype.canShowSourceLine): + (WebInspector.NetworkPanel.prototype.showSourceLine): + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel.prototype.show): + (WebInspector.StoragePanel.prototype.showSourceLine): + * inspector/front-end/inspector.js: + (WebInspector.showPanel): + (WebInspector.linkifyStringAsFragment): + +2010-10-27 Jeremy Orlow <jorlow@chromium.org> + + Reviewed by Steve Block. + + Clean up IDBTransactionBackend/Coordinator + https://bugs.webkit.org/show_bug.cgi?id=48425 + + Get rid of obsolete id and thus we don't need the factory method + on IDBTransactionCoordinator that creates IDBTransactionBackends. + + Add an assert to IDBTransactionBackend to make sure we're not in + the coordinator and then remove the coordinators ref counting link + to the transaction. + + Have the transaction backend zero out refs to the database when its + done using it. + + Existing tests provide coverage for this refactoring. + + * storage/IDBDatabaseBackendImpl.cpp: + (WebCore::IDBDatabaseBackendImpl::setVersion): + (WebCore::IDBDatabaseBackendImpl::transaction): + * storage/IDBTransactionBackendImpl.cpp: + (WebCore::IDBTransactionBackendImpl::create): + (WebCore::IDBTransactionBackendImpl::IDBTransactionBackendImpl): + (WebCore::IDBTransactionBackendImpl::~IDBTransactionBackendImpl): + (WebCore::IDBTransactionBackendImpl::abort): + (WebCore::IDBTransactionBackendImpl::commit): + * storage/IDBTransactionBackendImpl.h: + * storage/IDBTransactionBackendInterface.h: + * storage/IDBTransactionCoordinator.cpp: + (WebCore::IDBTransactionCoordinator::didStartTransaction): + (WebCore::IDBTransactionCoordinator::didFinishTransaction): + (WebCore::IDBTransactionCoordinator::isActive): + (WebCore::IDBTransactionCoordinator::processStartedTransactions): + * storage/IDBTransactionCoordinator.h: + +2010-10-27 Jeremy Orlow <jorlow@chromium.org> + + Reviewed by Steve Block. + + IDBFactoryBackend's reference to IDBDatabaseBackend should be weak + https://bugs.webkit.org/show_bug.cgi?id=48416 + + The factory's lifetime is that of the application, so without making + this weak, IDBDatabaseBackend's will never be closed until the app + terminates. + + * storage/IDBDatabaseBackendImpl.cpp: + (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl): + (WebCore::IDBDatabaseBackendImpl::~IDBDatabaseBackendImpl): + * storage/IDBDatabaseBackendImpl.h: + (WebCore::IDBDatabaseBackendImpl::create): + * storage/IDBFactoryBackendImpl.cpp: + (WebCore::IDBFactoryBackendImpl::removeIDBDatabaseBackend): + (WebCore::IDBFactoryBackendImpl::removeSQLiteDatabase): + (WebCore::IDBFactoryBackendImpl::open): + * storage/IDBFactoryBackendImpl.h: + +2010-10-27 Jeremy Orlow <jorlow@chromium.org> + + Reviewed by Steve Block. + + IDBObjectStoreBackend and IDBIndexBackend should not depend on IDBDatabaseBackend + https://bugs.webkit.org/show_bug.cgi?id=48410 + + Break dependency cyles between IDBDatabaseBackend and the other classes listed. + This was causing memory leaks. + + * storage/IDBCursorBackendImpl.cpp: + (WebCore::IDBCursorBackendImpl::IDBCursorBackendImpl): + (WebCore::IDBCursorBackendImpl::updateInternal): + (WebCore::IDBCursorBackendImpl::removeInternal): + (WebCore::IDBCursorBackendImpl::database): + * storage/IDBCursorBackendImpl.h: + (WebCore::IDBCursorBackendImpl::create): + * storage/IDBDatabaseBackendImpl.cpp: + (WebCore::IDBDatabaseBackendImpl::createObjectStore): + (WebCore::IDBDatabaseBackendImpl::loadObjectStores): + * storage/IDBIndexBackendImpl.cpp: + (WebCore::IDBIndexBackendImpl::IDBIndexBackendImpl): + (WebCore::IDBIndexBackendImpl::openCursorInternal): + (WebCore::IDBIndexBackendImpl::sqliteDatabase): + * storage/IDBIndexBackendImpl.h: + (WebCore::IDBIndexBackendImpl::create): + (WebCore::IDBIndexBackendImpl::storeName): + * storage/IDBObjectStoreBackendImpl.cpp: + (WebCore::IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl): + (WebCore::IDBObjectStoreBackendImpl::createIndex): + (WebCore::IDBObjectStoreBackendImpl::openCursorInternal): + (WebCore::IDBObjectStoreBackendImpl::loadIndexes): + (WebCore::IDBObjectStoreBackendImpl::sqliteDatabase): + * storage/IDBObjectStoreBackendImpl.h: + (WebCore::IDBObjectStoreBackendImpl::create): + +2010-11-05 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: inspector lags on large resources with numerous <script> tags. + https://bugs.webkit.org/show_bug.cgi?id=49060 + + * inspector/front-end/ScriptsPanel.js: + (WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu): + +2010-11-05 Patrick Gansterer <paroga@webkit.org> + + Reviewed by David Kilzer. + + Replace ARRAYSIZE with WTF_ARRAY_LENGTH + https://bugs.webkit.org/show_bug.cgi?id=48903 + + * platform/UUID.cpp: + (WebCore::createCanonicalUUIDString): + * platform/graphics/chromium/FontCacheChromiumWin.cpp: + (WebCore::FontCache::getFontDataForCharacters): + * platform/graphics/win/FontCacheWin.cpp: + (WebCore::FontCache::getLastResortFallbackFont): + * platform/graphics/win/IconWin.cpp: + (WebCore::Icon::createIconForFiles): + * platform/win/ClipboardUtilitiesWin.cpp: + (WebCore::getWebLocData): + * platform/win/ClipboardWin.cpp: + (WebCore::createGlobalHDropContent): + (WebCore::createGlobalImageFileDescriptor): + (WebCore::ClipboardWin::files): + (WebCore::ClipboardWin::writeURL): + * platform/win/DragDataWin.cpp: + (WebCore::DragData::asFilenames): + * platform/win/FileSystemWin.cpp: + (WebCore::safeCreateFile): + +2010-11-05 Roland Steiner <rolandsteiner@chromium.org> + + Reviewed by Dirk Schulze. + + Bug 48979 - [Chromium] SVGListPropertyTearOff.h: function commitChange ASSERTs on Win & Mac + https://bugs.webkit.org/show_bug.cgi?id=48979 + + Function removeItemValuesAndWrappers(): Move code out of 'if' statement so that + 'wrappers' and 'values' stay synced. + + test: svg/dom/baseVal-animVal-crash.html doesn't ASSERT + + * svg/properties/SVGListProperty.h: + (WebCore::SVGListProperty::removeItemValuesAndWrappers): + +2010-11-05 John Reck <jreck@google.com> + + Reviewed by Nikolas Zimmermann. + + The change to SVGPropertyTearOff by CodeGeneratorV8.pm caused two build failures + for Android. One was a missing SVGPropertyTearOff.h include, the other was a + missing forward declaration of FloatRect. Seems to be the result of: + https://bugs.webkit.org/show_bug.cgi?id=48204 + + Bug: https://bugs.webkit.org/show_bug.cgi?id=49025 + + No tests needed, fixes build issue. + + * bindings/scripts/CodeGeneratorV8.pm: + +2010-11-05 Rob Buis <rwlbuis@gmail.com> + + Reviewed by David Hyatt. + + CSSRule#parentRule always null + https://bugs.webkit.org/show_bug.cgi?id=46228 + + Ensure MediaList child rules have the MediaList set as parent + in order to correct their parentRule correctness. + + Test: fast/dom/css-mediarule-parentRule.html + + * css/CSSMediaRule.cpp: + (WebCore::CSSMediaRule::CSSMediaRule): + +2010-11-04 Xan Lopez <xlopez@igalia.com> + + Fix the GTK+ build. + + * GNUmakefile.am: + +2010-10-20 Chang Shu <chang.shu@nokia.com>, Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Fraser. + + [Qt] Makes <input type=text> and <textarea> functional with + Spatial Navigation enabled. Before this patch, the focus cannot + move away from input box once it is in. This patch allows focus + move to neighbor nodes when the caret reaches the edge of the texts. + This patch does not support yet cases where the focused <input> + has a JS handler for the arrow keys. + https://bugs.webkit.org/show_bug.cgi?id=37153 + + Tests: fast/events/spatial-navigation/snav-input.html + fast/events/spatial-navigation/snav-textarea.html + + * editing/EditorCommand.cpp: + (WebCore::executeMoveDown): + (WebCore::executeMoveLeft): + (WebCore::executeMoveRight): + (WebCore::executeMoveUp): + * editing/SelectionController.cpp: + (WebCore::SelectionController::modify): + +2010-11-04 Dan Bernstein <mitz@apple.com> + + Build fix. + + * editing/Editor.cpp: + (WebCore::Editor::dismissCorrectionPanel): + +2010-11-04 Jia Pu <jpu@apple.com> + + Reviewed by Dan Bernstein. + + reversion bubble in WebViews + https://bugs.webkit.org/show_bug.cgi?id=47630 + <rdar://problem/8530960> + + Added manual test: + manual-tests/autocorrection/continue-typing-to-dismiss-reversion.html + manual-tests/autocorrection/delete-to-dismiss-reversion.html + manual-tests/autocorrection/delete-to-end-of-word-to-show-reversion.html + manual-tests/autocorrection/move-to-end-of-word-to-show-reversion.html + manual-tests/autocorrection/type-whitespace-to-dismiss-reversion.html + + We can only manully test this feature for two reasons: + 1. On Mac OS X, the result of spell checking is partly determined by past user usage. We can't + realiably generating test cases until we can disable user custom data during spell checking. + 2. To exerciese this feature, we need a minimum of 0.3 second delay using WebCore timer. + + This patch is to add reversion to correction panel. It consists of following major code changes: + 1. Collected all autocorrection related member variables in Editor into a CorrectionPanelInfo + class to improve readability. + 2. Changed signature of Editor::startCorrectionPanelTimer() to allow caller to specify the + type of correction panel--regular correction or reversion. + 3. Made necessary changes to adopt reversion API in AppKit. + 4. Use SUPPORT_CORRECTION_PANEL macro to improve readability. + + * GNUmakefile.am: Added CorrectionPanelInfo.h. + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * WebCore.xcodeproj/project.pbxproj: + * editing/CorrectionPanelInfo.h: Added. + * editing/Editor.cpp: + (WebCore::Editor::respondToChangedSelection): Start correction panel timer for reversion when + the new selection is a caret selection at end of a previously corrected word. + (WebCore::Editor::appliedEditing): Stop timer at the beginning of the method instead of at the end. + (WebCore::Editor::~Editor): Adopted new method dismissCorrectionPanel(). + (WebCore::Editor::markMisspellingsAfterTypingToPosition): Adopted new method applyCorrectionPanelInfo(). + (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): Code change for new m_correctionPanelInfo + member variable. + (WebCore::Editor::correctionPanelTimerFired): Change to handle reversion panel type. + (WebCore::Editor::handleRejectedCorrection): Ditto. + (WebCore::Editor::startCorrectionPanelTimer): Changed signature to allow passing in panel type. + (WebCore::Editor::stopCorrectionPanelTimer): Adopted macro SUPPORT_CORRECTION_PANEL. + (WebCore::Editor::handleCancelOperation): Ditto. + (WebCore::Editor::isShowingCorrectionPanel): Ditto. + (WebCore::Editor::dismissCorrectionPanel): Update m_correctionPanelInfo when correction panel + is dismissed. + (WebCore::Editor::applyCorrectionPanelInfo): Factored out code that applies autocorrection. + (WebCore::Editor::changeSelectionAfterCommand): Adopt macro SUPPORT_CORRECTION_PANEL. + * editing/Editor.h: Adopted CorrectionPanelInfo and add new member methods. + * editing/EditorCommand.cpp: Adopted macro SUPPORT_CORRECTION_PANEL + (WebCore::createCommandMap): + * editing/TypingCommand.cpp: Adopted macro SUPPORT_CORRECTION_PANEL and new signature of + startCorrectionPanelTimer(). + (WebCore::TypingCommand::markMisspellingsAfterTyping): + * loader/EmptyClients.h: + (WebCore::EmptyEditorClient::showCorrectionPanel): Adopted new signature of base class method. + (WebCore::EmptyEditorClient::dismissCorrectionPanel): Ditto. + * manual-tests/autocorrection/continue-typing-to-dismiss-reversion.html: Added. + * manual-tests/autocorrection/delete-to-dismiss-reversion.html: Added. + * manual-tests/autocorrection/delete-to-end-of-word-to-show-reversion.html: Added. + * manual-tests/autocorrection/move-to-end-of-word-to-show-reversion.html: Added. + * manual-tests/autocorrection/type-whitespace-to-dismiss-reversion.html: Added. + * page/EditorClient.h: Changed signature of showCorrectionPanel() and dismissCorrectionPanel(). + * platform/graphics/mac/GraphicsContextMac.mm: Added comment to improve readability. + (WebCore::GraphicsContext::drawLineForTextChecking): + +2010-11-04 Dan Bernstein <mitz@apple.com> + + Reviewed by Dave Hyatt. + + Made table layout and painting work with all writing modes. Hit-testing, repainting, tables + where some elements have their own layers, and cells whose writing mode differs from the + table’s are not supported yet. + + Make tables work with vertical text + https://bugs.webkit.org/show_bug.cgi?id=46417 + + Tests: fast/table/027-vertical.html + fast/table/028-vertical.html + fast/table/035-vertical.html + fast/table/038-vertical.html + fast/table/040-vertical.html + fast/table/auto-with-percent-height-vertical.html + fast/table/border-collapsing/001-vertical.html + fast/table/border-collapsing/002-vertical.html + fast/table/border-collapsing/003-vertical.html + fast/table/border-collapsing/004-vertical.html + fast/table/border-collapsing/border-collapsing-head-foot-vertical.html + fast/table/border-collapsing/equal-precedence-resolution-vertical.html + fast/table/border-collapsing/rtl-border-collapsing-vertical.html + fast/table/colspanMinWidth-vertical.html + fast/table/fixed-with-auto-with-colspan-vertical.html + fast/table/growCellForImageQuirk-vertical.html + fast/table/height-percent-test-vertical.html + fast/table/percent-widths-stretch-vertical.html + fast/table/rowspan-paint-order-vertical.html + fast/table/table-display-types-vertical.html + + * css/CSSStyleSelector.cpp: + (WebCore::CSSStyleSelector::adjustRenderStyle): Changed to allow all writing modes for tables, + make row groups, rows, column groups and columns inherit the table’s writing mode. For now, + make cells do this too. + * html/HTMLTableElement.cpp: + (WebCore::HTMLTableElement::parseMappedAttribute): Map align=center using logical properties. + * rendering/RenderTable.cpp: + (WebCore::RenderTable::RenderTable): Initialize m_borderStart and m_borderEnd. + (WebCore::RenderTable::styleDidChange): Changed the rule for when to use auto layout to look + at the logical width instead of the width. + (WebCore::RenderTable::computeLogicalWidth): Uses logical widths and works with perpendicular + containing blocks. + (WebCore::RenderTable::layout): Use logical lengths. + (WebCore::RenderTable::setCellLogicalWidths): Renamed setCellWidths() to this and updated for + the renaming of RenderTableSection::setCellWidths(). + (WebCore::RenderTable::paintObject): Account for flipped modes. + (WebCore::RenderTable::subtractCaptionRect): Added this helper method the considers writing modes. + (WebCore::RenderTable::paintBoxDecorations): Adopted subtractCaptionRect(). + (WebCore::RenderTable::paintMask): Ditto. + (WebCore::RenderTable::computePreferredLogicalWidths): Updated for the renaming of + recalcHorizontalBorders(). + (WebCore::RenderTable::calcBorderStart): Renamed calcBorderLeft() to this and changed it to use + borderStart(). Splits odd number of pixels based on the physical side. + (WebCore::RenderTable::calcBorderEnd): Similar. + (WebCore::RenderTable::recalcBordersInRowDirection): Renamed recalcHorizontalBorders() to this + and updated for other renames. + (WebCore::RenderTable::borderBefore): Replaced borderTop() with this. + (WebCore::RenderTable::borderAfter): Similar. + (WebCore::RenderTable::outerBorderBefore): Similar. + (WebCore::RenderTable::outerBorderAfter): Similar. + (WebCore::RenderTable::outerBorderStart): Similar. + (WebCore::RenderTable::outerBorderEnd): Similar. + (WebCore::RenderTable::firstLineBoxBaseline): Changed to use logical heights. + (WebCore::RenderTable::overflowClipRect): Account for writing modes. + * rendering/RenderTable.h: + (WebCore::RenderTable::borderStart): + (WebCore::RenderTable::borderEnd): + (WebCore::RenderTable::borderLeft): + (WebCore::RenderTable::borderRight): + (WebCore::RenderTable::borderTop): + (WebCore::RenderTable::borderBottom): + (WebCore::RenderTable::outerBorderLeft): + (WebCore::RenderTable::outerBorderRight): + (WebCore::RenderTable::outerBorderTop): + (WebCore::RenderTable::outerBorderBottom): + (WebCore::RenderTable::bordersPaddingAndSpacingInRowDirection): Changed to match its name. + * rendering/RenderTableRow.cpp: + (WebCore::RenderTableRow::styleWillChange): Changed to detect changes to logical height. + * rendering/RenderTableSection.cpp: + (WebCore::setRowLogicalHeightToRowStyleLogicalHeightIfNotRelative): Renamed and changed to use + logical heights. + (WebCore::RenderTableSection::RenderTableSection): Updated initializers for new member variables. + (WebCore::RenderTableSection::addChild): Updated for rename. + (WebCore::RenderTableSection::ensureRows): Ditto. + (WebCore::RenderTableSection::addCell): Ditto. Also use logical heights. + (WebCore::RenderTableSection::setCellLogicalWidths): Renamed setCellWidths() to this, changed + to use logical widths. + (WebCore::RenderTableSection::calcRowLogicalHeight): Added “logical” to the name. Updated with + logical heights. + (WebCore::RenderTableSection::layoutRows): + (WebCore::RenderTableSection::calcOuterBorderBefore): + (WebCore::RenderTableSection::calcOuterBorderAfter): + (WebCore::RenderTableSection::calcOuterBorderStart): + (WebCore::RenderTableSection::calcOuterBorderEnd): + (WebCore::RenderTableSection::recalcOuterBorder): + (WebCore::RenderTableSection::firstLineBoxBaseline): + (WebCore::RenderTableSection::paintCell): + (WebCore::RenderTableSection::recalcCells): + * rendering/RenderTableSection.h: + (WebCore::RenderTableSection::outerBorderBefore): + (WebCore::RenderTableSection::outerBorderAfter): + (WebCore::RenderTableSection::outerBorderStart): + (WebCore::RenderTableSection::outerBorderEnd): + +2010-11-04 Kent Tamura <tkent@chromium.org> + + Unreviewed, trivial test fix. + + Fix GTK build for http://trac.webkit.org/changeset/71373 . + + * GNUmakefile.am: Add HTMLOutputElement.{cpp,h} + +2010-11-04 MORITA Hajime <morrita@google.com> + + Reviewed by Kent Tamura. + + Stale reference to RenderObject held as FrameView layoutRoot + https://bugs.webkit.org/show_bug.cgi?id=48019 + + <progress> and <meter> shouldn't have children of its RenderObject, + which caused unexpected result. + This change suppresses child creation to prevent it. + + Tests: fast/dom/HTMLMeterElement/meter-element-with-child-crash.html + fast/dom/HTMLProgressElement/progress-element-with-child-crash.html + + * rendering/RenderIndicator.h: + (WebCore::RenderIndicator::canHaveChildren): + +2010-11-04 Kenichi Ishibashi <bashi@google.com> + + Reviewed by Kent Tamura. + + [HTML5][Forms] Support for <output> element + https://bugs.webkit.org/show_bug.cgi?id=29363 + + Support for <output> element. + + Tests: fast/dom/HTMLOutputElement/dom-settable-token-list.html + fast/dom/HTMLOutputElement/htmloutputelement-reset-event.html + fast/dom/HTMLOutputElement/htmloutputelement-validity.html + fast/dom/HTMLOutputElement/htmloutputelement-value.html + fast/dom/HTMLOutputElement/htmloutputelement.html + + * Android.derived.jscbindings.mk: Added JSHTMLOutputElement.h. + * Android.derived.v8bindings.mk: Added V8HTMLOutputElement.h. + * Android.jscbindings.mk: Added JSHTMLOutputElementCustom.cpp. + * Android.mk: Added HTMLOutputElement.cpp. + * Android.v8bindings.mk: Added V8HTMLOutputElementCustom.cpp. + * CMakeLists.txt: Added HTMLOutputElement.{idl,cpp} and JSHTMLOutputElementCustom.cpp. + * DerivedSources.cpp: Added JSHTMLOutputElement.cpp. + * DerivedSources.make: Added HTMLOutputElement entry. + * GNUmakefile.am: Added JSHTMLOutputElement.{cpp,h} + * WebCore.gypi: Added HTMLOutputElement.{idl,cpp,h}, JSHTMLOutputElementCustom.cpp and V8HTMLOutputElementCustom.cpp + * WebCore.pri: Added HTMLOutputElement.idl. + * WebCore.pro: Added V8HTMLOutputElementCustom.cpp, JSHTMLOutputElementCustom.cpp and HTMLOutputElement.cpp. + * WebCore.vcproj/WebCore.vcproj: Added entries for JSHTMLOutputElement.{cpp,h} and JSHTMLOutputElementCustom.cpp. + * WebCore.xcodeproj/project.pbxproj: Added entries for JSHTMLOutputElementCustom.cpp, HTMLOutputElement.{cpp,h,idl}, JSHTMLOutputElement.{cpp,h} + * bindings/js/JSBindingsAllInOne.cpp: Added JSHTMLOutputElementCustom.cpp. + * bindings/js/JSHTMLOutputElementCustom.cpp: Added. + (WebCore::JSHTMLOutputElement::htmlFor): + (WebCore::JSHTMLOutputElement::setHtmlFor): + * bindings/v8/custom/V8DOMSettableTokenListCustom.cpp: Modified. + (WebCore::V8DOMSettableTokenList::indexedPropertyGetter): Returns null if the index is out of range. + * bindings/v8/custom/V8HTMLOutputElementCustom.cpp: Added. + (WebCore::V8HTMLOutputElement::htmlForAccessorGetter): + (WebCore::V8HTMLOutputElement::htmlForAccessorSetter): + * css/html.css: Added a default style of output element. + (output): + * html/DOMSettableTokenList.cpp: Fix bugs. + (WebCore::DOMSettableTokenList::item): Returns null string if the index is out of range. + (WebCore::DOMSettableTokenList::addInternal): Added check m_tokens.isNull(). + (WebCore::DOMSettableTokenList::setValue): Set the value case sensitive. + * html/HTMLOutputElement.cpp: Added. + (WebCore::HTMLOutputElement::HTMLOutputElement): + (WebCore::HTMLOutputElement::create): + (WebCore::HTMLOutputElement::formControlType): + (WebCore::HTMLOutputElement::parseMappedAttribute): + (WebCore::HTMLOutputElement::htmlFor): + (WebCore::HTMLOutputElement::setFor): + (WebCore::HTMLOutputElement::setForm): + (WebCore::HTMLOutputElement::childrenChanged): + (WebCore::HTMLOutputElement::reset): + (WebCore::HTMLOutputElement::value): + (WebCore::HTMLOutputElement::setValue): + (WebCore::HTMLOutputElement::defaultValue): + (WebCore::HTMLOutputElement::setDefaultValue): + (WebCore::HTMLOutputElement::setTextContentInternal): + * html/HTMLOutputElement.h: Added. + (WebCore::HTMLOutputElement::isEnumeratable): + (WebCore::HTMLOutputElement::willValidate): + * html/HTMLOutputElement.idl: Added. + * html/HTMLTagNames.in: Added "output". + * page/DOMWindow.idl: Added an attribute for HTMLOutputElement. + +2010-11-04 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + Remove IMPLEMENTATION_COLOR_READ_FORMAT and TYPE + https://bugs.webkit.org/show_bug.cgi?id=48938 + + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::initializeNewContext): + (WebCore::WebGLRenderingContext::getParameter): + (WebCore::WebGLRenderingContext::readPixels): + * html/canvas/WebGLRenderingContext.h: + * html/canvas/WebGLRenderingContext.idl: + * platform/graphics/GraphicsContext3D.h: + * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp: + (WebCore::GraphicsContext3D::getIntegerv): + +2010-11-04 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + TypedArray should throw exception if length not a multiple of element size + https://bugs.webkit.org/show_bug.cgi?id=45487 + + * bindings/js/JSArrayBufferViewHelper.h: + (WebCore::constructArrayBufferView): + * bindings/v8/custom/V8ArrayBufferViewCustom.h: + (WebCore::constructWebGLArray): + +2010-11-04 Kenneth Russell <kbr@google.com> + + Reviewed by Adam Barth. + + [chromium] Mac: WebGL: all textured content is blue + https://bugs.webkit.org/show_bug.cgi?id=49021 + + Added support for 8-bit, little-endian CGImages. The previous + image decode path used the default byte order, which is apparently + big-endian. + + Tested with various WebGL content and layout tests in Chromium. + Ran layout tests in WebKit and tested various WebGL content in + Safari. Was not able to run layout tests with Chromium port of + DumpRenderTree due to build failures currently in the tree. + + * platform/graphics/GraphicsContext3D.cpp: + (WebCore::doPacking): + * platform/graphics/GraphicsContext3D.h: + * platform/graphics/cg/GraphicsContext3DCG.cpp: + (WebCore::getSourceDataFormat): + (WebCore::GraphicsContext3D::getImageData): + +2010-11-03 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + renderbufferStorage(DEPTH_STENCIL) shouldn't generate an error + https://bugs.webkit.org/show_bug.cgi?id=48891 + + * html/canvas/WebGLFramebuffer.cpp: + (WebCore::WebGLFramebuffer::isIncomplete): Considering the case where DEPTH_STENCIL is not supported. + * html/canvas/WebGLRenderbuffer.cpp: + (WebCore::WebGLRenderbuffer::WebGLRenderbuffer): Init added members. + * html/canvas/WebGLRenderbuffer.h: Add members and accessor functions. + (WebCore::WebGLRenderbuffer::setInternalFormat): + (WebCore::WebGLRenderbuffer::setSize): + (WebCore::WebGLRenderbuffer::getWidth): + (WebCore::WebGLRenderbuffer::getHeight): + (WebCore::WebGLRenderbuffer::setIsValid): + (WebCore::WebGLRenderbuffer::isValid): + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::initializeNewContext): Check if packed_depth_stencil extension exists. + (WebCore::WebGLRenderingContext::getRenderbufferParameter): Simulate the case for DEPTH_STENCIL where packed_depth_stencil is not supported. + (WebCore::WebGLRenderingContext::renderbufferStorage): Bypass the call if packed_depth_stencil is not supported. + * html/canvas/WebGLRenderingContext.h: + +2010-11-04 Kavita Kanetkar <kkanetkar@chromium.org> + + Reviewed by Adam Barth. + + Web Inspector: Enable files ystem UI for chromium + https://bugs.webkit.org/show_bug.cgi?id=48963 + + * inspector/Inspector.idl: + * inspector/InspectorFileSystemAgent.cpp: + (WebCore::InspectorFileSystemAgent::getFileSystemPathAsync): + * inspector/InspectorFileSystemAgent.h: + * inspector/front-end/FileSystemView.js: + (WebInspector.FileSystemView): + (WebInspector.FileSystemView.prototype.setFileSystemDisabled): + (WebInspector.FileSystemView.prototype._createTextAndButton): + (WebInspector.FileSystemView.prototype.refreshFileSystem): + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel.prototype.setFileSystemDisabled): + * inspector/front-end/inspector.js: + (WebInspector.didGetFileSystemDisabled): + (WebInspector.reset): + +2010-11-04 Robert Hogan <robert@webkit.org> + + Reviewed by Darin Adler. + + Stale reference to JSDOMWindow in ScriptController::m_cacheableBindingObject + + After bug 37725 we need to update the globalObject() (i.e. JSDOMWindow) + associated with the m_cacheablebindingRootObject every time we clear the + frame and load a new page. This allows the runtime objects + (e.g. LayoutTestController etc.) to persist between navigations as + before but also ensures that when qt_runtime, or any other bridge, + looks at the root->globalObject() of a cacheable binding object + it gets the DOMWindow of the current page rather than the DOMWindow + that was in place when m_cacheableBindingRootObject was created. + + Fixes fast/dom/nodesFromRect-basic.html on Qt. + + https://bugs.webkit.org/show_bug.cgi?id=48758 + + * bindings/js/ScriptController.cpp: + (WebCore::ScriptController::clearWindowShell): + * bridge/runtime_root.cpp: + (JSC::Bindings::RootObject::updateGlobalObject): + * bridge/runtime_root.h: + +2010-11-04 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by David Hyatt. + + Delegate scrolling via a separate method + https://bugs.webkit.org/show_bug.cgi?id=48988 + + Add a delegatedScrollRequested method to HostWindow for delegating + scrolling to the view. This is only used in conjunction with tiling, + and is ifdef'ed. + + * page/Chrome.cpp: + (WebCore::Chrome::delegatedScrollRequested): + * page/Chrome.h: + * page/ChromeClient.h: + * platform/HostWindow.h: + * platform/ScrollView.cpp: + (WebCore::ScrollView::setScrollPosition): + +2010-11-04 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: Need better way of switching back to the Timeline view of the Network tab. + https://bugs.webkit.org/show_bug.cgi?id=48995 + + - Moved close button to the left, preceding tab headers; + - Auto-adjusting summary bar width when switching to the preview mode + - Auto-scrolling network log if it was scrolled to bottom. + + * inspector/front-end/DataGrid.js: + (WebInspector.DataGrid): + (WebInspector.DataGrid.prototype.isScrolledToLastRow): + (WebInspector.DataGrid.prototype.scrollToLastRow): + * inspector/front-end/NetworkPanel.js: + (WebInspector.NetworkPanel): + (WebInspector.NetworkPanel.prototype.updateSidebarWidth): + (WebInspector.NetworkPanel.prototype._positionSummaryBar): + (WebInspector.NetworkPanel.prototype.refresh): + (WebInspector.NetworkPanel.prototype._reset): + (WebInspector.NetworkPanel.prototype._toggleGridMode): + * inspector/front-end/inspector.css: + (.tabbed-pane-header li): + * inspector/front-end/networkPanel.css: + (.network-summary-bar): + (#network-close-button): + (#network-views.small #network-close-button): + (#network-views .resource-view .tabbed-pane-header): + (#network-views.small .resource-view .tabbed-pane-header): + +2010-11-04 Erik Arvidsson <arv@chromium.org> + + Reviewed by Dimitri Glazkov. + + Support box-sizing without the vendor prefix + https://bugs.webkit.org/show_bug.cgi?id=36713 + + Based on patch by Peter Beverloo <peter@lvp-media.com> + + Test: fast/css/box-sizing-backwards-compat-prefix.html + + * css/CSSComputedStyleDeclaration.cpp: + (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): + * css/CSSParser.cpp: + (WebCore::CSSParser::parseValue): + (WebCore::cssPropertyID): This handles -webkit-box-sizing and maps it to box-sizing. + * css/CSSPropertyNames.in: + * css/CSSStyleSelector.cpp: + (WebCore::CSSStyleSelector::applyProperty): + * css/quirks.css: Change -webkit-box-sizing to box-sizing. + (input:not([type=image]), textarea): + * css/view-source.css: Ditto. + (.webkit-line-gutter-backdrop, .webkit-line-number): + * css/wml.css: Ditto. + (do): + (select): + +2010-11-04 John Reck <jreck@google.com> + + Reviewed by Steve Block. + + Fix a linker failure when building for Android + https://bugs.webkit.org/show_bug.cgi?id=48964 + + The Android stub for setCookieStoragePrivateBrowsingEnabled(bool) wasn't in the WebCore namespace, which caused + a linker failure when building for Android. Moved the stub to the WebCore namespace. This was caused by + http://trac.webkit.org/changeset/70400 + + No new tests, build fix only + + * platform/android/TemporaryLinkStubs.cpp: + +2010-11-04 Joseph Pecoraro <joepeck@webkit.org> + + Reviewed by Andreas Kling. + + Request.h getters can be made const + https://bugs.webkit.org/show_bug.cgi?id=49003 + + Added the const qualifier to some getters that don't mutate the object. + + * loader/Request.h: + (WebCore::Request::cachedResource): + (WebCore::Request::cachedResourceLoader): + (WebCore::Request::isIncremental): + (WebCore::Request::isMultipart): + +2010-11-03 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Brady Eidson. + + User scripts shouldn't be injected in a frame's empty initial document. + https://bugs.webkit.org/show_bug.cgi?id=48970 + <rdar://problem/8618164> + <rdar://problem/8082122> + + When a frame loads, it first creates an empty initial document, then navigates to the correct URL. Our + current policy with user scripts is to inject them into both the initial empty document, and then inject + them again. + + This causes developers to think their scripts have been injected twice into all iframes, and there is a timing + issue between WebKit1 and WebKit2 that causes start scripts to be injected into the initial empty document + of the main frame when a new tab or window is created. + + The fix for this is to not inject user scripts when the frame is creating its initial empty document before loading + the correct source. + + * page/Frame.cpp: + (WebCore::Frame::injectUserScripts): + +2010-11-04 Andreas Kling <kling@webkit.org> + + Reviewed by Nikolas Zimmermann. + + GraphicsContext: Don't do full save/restore when painting with low quality scaling + https://bugs.webkit.org/show_bug.cgi?id=48738 + + Stash the imageInterpolationQuality() in a local and reset it after painting. + + * platform/graphics/GraphicsContext.cpp: + (WebCore::GraphicsContext::drawImage): + (WebCore::GraphicsContext::drawTiledImage): + (WebCore::GraphicsContext::drawImageBuffer): + * platform/graphics/haiku/GraphicsContextHaiku.cpp: + (WebCore::GraphicsContext::imageInterpolationQuality): + * platform/graphics/skia/GraphicsContextSkia.cpp: + (WebCore::GraphicsContext::imageInterpolationQuality): + * platform/graphics/wince/GraphicsContextWinCE.cpp: + (WebCore::GraphicsContext::imageInterpolationQuality): + +2010-11-04 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Andreas Kling. + + Refactor SVGStringListPropertyTearOff/SVGListPropertyTearOff to use a common base class + https://bugs.webkit.org/show_bug.cgi?id=48990 + + Introduce SVGListProperty as common base class between static lists (SVGStringListPropertyTearOff) and dynamic lists (SVGListPropertyTearOff). + This is a preparation for the addition of the next static list type: SVGPointList. + + * GNUmakefile.am: Add new files to build. + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * bindings/scripts/CodeGenerator.pm: s/SVGStringListPropertyTearOff/SVGStaticListPropertyTearOff/. + * bindings/scripts/CodeGeneratorJS.pm: Ditto. + * bindings/scripts/CodeGeneratorObjC.pm: Ditto. + * bindings/scripts/CodeGeneratorV8.pm: Ditto. + * svg/properties/SVGAnimatedListPropertyTearOff.h: Include SVGStaticListPropertyTearOff.h here, to avoid special dependencies in CodeGenerator*.pm + * svg/properties/SVGListProperty.h: Added. + * svg/properties/SVGListPropertyTearOff.h: Use SVGList API implementation from SVGListProperty base class. + * svg/properties/SVGStaticListPropertyTearOff.h: Added. Use SVGList API implementation from SVGListProperty base class. + * svg/properties/SVGStringListPropertyTearOff.h: Removed. + +2010-11-04 Ryosuke Niwa <rniwa@webkit.org> + + Unreviewed. Fixed WebCore.xcodeproject + + * WebCore.xcodeproj/project.pbxproj: + +2010-11-04 Pratik Solanki <psolanki@apple.com> + + Reviewed by Darin Adler. + + Should make use of purge priorities for different resource types + https://bugs.webkit.org/show_bug.cgi?id=48684 + + Assign purge priorities to CachedResource objects. JavaScript and CSS stylesheets are more + important than images so hint to the kernel to purge them last. We do this by repurposing + the previously unused function, PurgeableBuffer::setPurgePriority(). It now just sets the + priority field and does not have side-effects like calling makePurgeable(true). + + Also, remove unusued PurgeableBuffer::create(const Vector<char>&) function and move the + purgeable memory size threshold from CachedResource to PurgeableBuffer. + + * WebCore.xcodeproj/project.pbxproj: Add new PurgePriority.h header and mark it as private + header. + * loader/CachedCSSStyleSheet.h: + (WebCore::CachedCSSStyleSheet::purgePriority): + * loader/CachedImage.h: + (WebCore::CachedImage::purgePriority): + * loader/CachedResource.cpp: + (WebCore::CachedResource::makePurgeable): Set the purge priority on the PurgeableBffer. + Also, move the check for purgeable size threshold to PurgeableBuffer. + * loader/CachedResource.h: + (WebCore::CachedResource::purgePriority): Added. New virtual method that lets the class + specify its purge priority. + * loader/CachedScript.h: + (WebCore::CachedScript::purgePriority): + * platform/PurgePriority.h: Added. Move the PurgePriority enum from PurgeableBuffer class to + its own header file. + (WebCore::): + * platform/PurgeableBuffer.h: + (WebCore::PurgeableBuffer::setPurgePriority): Update this previously unused function to just + set the priority and not call makePurgeable(true). + * platform/mac/PurgeableBufferMac.cpp: Update size threshold to 16KB which is what + CachedResource was using. + +2010-11-04 Chris Guillory <chris.guillory@google.com> + + Reviewed by Chris Fleizach. + + Ignore static text children of text field controls in the accessibility tree. + https://bugs.webkit.org/show_bug.cgi?id=48944 + + * accessibility/AccessibilityRenderObject.cpp: + (WebCore::AccessibilityRenderObject::accessibilityIsIgnored): + +2010-11-04 Erik Arvidsson <arv@chromium.org> + + Reviewed by Tony Chang. + + Computed style is not correct for negative values in the presence of zooming + https://bugs.webkit.org/show_bug.cgi?id=48855 + + * rendering/style/RenderStyle.h: + (WebCore::adjustForAbsoluteZoom): When the value is less than zero we need to decrement instead of increment. + +2010-11-04 Shane Stephens <shanestephens@google.com> + + Reviewed by Tony Chang. + + SVGStyledTransformableElement supplemental transforms pre-multiplied + but should be post-multiplied. + https://bugs.webkit.org/show_bug.cgi?id=48026 + + Test: svg/animations/animate-path-nested-transforms.svg + + * svg/SVGStyledTransformableElement.cpp: + (WebCore::SVGStyledTransformableElement::animatedLocalTransform): + + Switched order of multiplication. Note that due to a bug in + AffineTransform's operator* implementation the order of arguments is + reversed (see http://bugs.webkit.org/show_bug.cgi?id=48031). + +2010-11-04 James Simonsen <simonjam@chromium.org> + + Reviewed by Darin Fisher. + + [Web Timing] Implement dom* timing marks + https://bugs.webkit.org/show_bug.cgi?id=46301 + + Test: fast/dom/webtiming-document-open.html + + * GNUmakefile.am: Added DocumentTiming.h + * WebCore.gypi: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * dom/Document.cpp: + (WebCore::Document::setReadyState): Set DOM WebTiming marks. + (WebCore::Document::finishedParsing): Set DOM WebTiming marks. + * dom/Document.h: + (WebCore::Document::timing): Added. + * dom/DocumentTiming.h: Added. + (WebCore::DocumentTiming::DocumentTiming): + * page/Timing.cpp: Added DOM timing. + (WebCore::Timing::domLoading): Ditto. + (WebCore::Timing::domInteractive): Ditto. + (WebCore::Timing::domContentLoaded): Ditto. + (WebCore::Timing::domComplete): Ditto. + (WebCore::Timing::documentTiming): Ditto. + * page/Timing.h: Ditto. + * page/Timing.idl: Ditto. + +2010-11-04 Carlos Garcia Campos <cgarcia@igalia.com> + + Reviewed by Martin Robinson. + + [GTK] Implement unencodable characters handling in TextCodecGtk::encode() + https://bugs.webkit.org/show_bug.cgi?id=48902 + + Fixes a crash in test fast/encoding/char-encoding.html. + + * platform/text/gtk/TextCodecGtk.cpp: + (WebCore::TextCodecGtk::encode): + +2010-11-04 Adam Barth <abarth@webkit.org> + + Enabled ICCJPEG on Chromium Mac + https://bugs.webkit.org/show_bug.cgi?id=48977 + + Add iccjpeg as a dependency. + + * WebCore.gyp/WebCore.gyp: + +2010-11-03 Kent Tamura <tkent@chromium.org> + + Reviewed by Dimitri Glazkov. + + Framework to show form validation message for invalid controls + https://bugs.webkit.org/show_bug.cgi?id=31718 + + HTMLFormElement::validateInteractively() shows a validation message for + an invalid control by HTMLFormControlElement::updateVisibleValidationMessage(), + and the message is hidden when the invalid control looses focus, becomes + valid, detached, or the form is submitted again. + + Introduce ValidationMessage class to manage visible form validation + message. It has no implementation to show/hide a message yet. + + No new tests. New behavior is disabled by default, and is timing-dependent. + + * Android.mk: Add ValidationMessage. + * CMakeLists.txt: ditto. + * GNUmakefile.am: ditto. + * WebCore.gypi: ditto. + * WebCore.pro: ditto. + * WebCore.vcproj/WebCore.vcproj: ditto. + * WebCore.xcodeproj/project.pbxproj: ditto. + * html/HTMLFormControlElement.cpp: + (WebCore::HTMLFormControlElement::detach): Hides a validation message. + (WebCore::HTMLFormControlElement::setNeedsWillValidateCheck): + Hides a validation message if validation is not needed. + (WebCore::HTMLFormControlElement::updateVisibleValidationMessage): + (WebCore::HTMLFormControlElement::hideVisibleValidationMessage): + (WebCore::HTMLFormControlElement::setNeedsValidityCheck): + Hides a validation message or updates the validation message. + (WebCore::HTMLFormControlElement::dispatchBlurEvent): + Hides a validation message. + (WebCore::HTMLFormControlElement::visibleValidationMessage): + * html/HTMLFormControlElement.h: + * html/HTMLFormElement.cpp: + (WebCore::HTMLFormElement::validateInteractively): + - Hide existing validation messages before showing new message. + - Show new validation message. + * html/ValidationMessage.cpp: Added. + (WebCore::ValidationMessage::ValidationMessage): + (WebCore::ValidationMessage::~ValidationMessage): + (WebCore::ValidationMessage::create): + (WebCore::ValidationMessage::setMessage): + (WebCore::ValidationMessage::hideMessage): + * html/ValidationMessage.h: Added. + (WebCore::ValidationMessage::message): + +2010-11-03 Patrick Gansterer <paroga@webkit.org> + + Reviewed by Adam Roben. + + Port WCDataObject.cpp to WinCE + https://bugs.webkit.org/show_bug.cgi?id=48921 + + OleDuplicateData is not supported on WinCE. + + * platform/win/WCDataObject.cpp: + (WebCore::WCDataObject::CopyMedium): + +2010-11-03 Patrick Gansterer <paroga@webkit.org> + + Reviewed by Adam Roben. + + Port ClipboardWin.cpp to WinCE + https://bugs.webkit.org/show_bug.cgi?id=48412 + + * platform/win/ClipboardWin.cpp: + (WebCore::writeFileToDataObject): + +2010-11-03 Patrick Gansterer <paroga@webkit.org> + + Reviewed by Adam Roben. + + Port ClipboardWin.cpp to WinCE + https://bugs.webkit.org/show_bug.cgi?id=48412 + + * platform/win/ClipboardWin.cpp: + (WebCore::filesystemPathFromUrlOrTitle): + (WebCore::createGlobalHDropContent): + (WebCore::ClipboardWin::files): + +2010-11-03 Vincent Scheib <scheib@chromium.org> + + Reviewed by James Robinson. + + [chromium] GraphicsContext3D creation attributes include canRecoverFromContextLoss option + https://bugs.webkit.org/show_bug.cgi?id=48850 + + Implementations of GraphicsContext3D may respect the creation attribute + canRecoverFromContextLoss being false, and then only succeeding initialization if + the context can satisfy that request of never being lost. DX9 on XP can not satisfy + such a request. + + Test by use of accelerated canvas 2d in Chromium with ANGLE on XP machines. + + * platform/graphics/GraphicsContext3D.h: + (WebCore::GraphicsContext3D::Attributes::Attributes): + * platform/graphics/gpu/SharedGraphicsContext3D.cpp: + (WebCore::SharedGraphicsContext3D::create): + +2010-11-03 Carlos Garcia Campos <cgarcia@igalia.com> + + Reviewed by Martin Robinson. + + [GTK] Use sentence boundaries instead of start/end sentence + https://bugs.webkit.org/show_bug.cgi?id=48422 + + Using sentence boundaries all intersentence + whitespace/control/format characters are assigned to a + sentence. This is what ICU does, so we have to do the same in + order to get the same results with glib unicode backend. It fixes + the sentence tests cases in test fast/dom/Range/range-expand.html. + + * platform/text/gtk/TextBreakIteratorGtk.cpp: + (WebCore::textBreakNext): + (WebCore::textBreakPrevious): + +2010-11-03 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + depthRange should generate INVALID_OPERATION if zNear is greater than zFar + https://bugs.webkit.org/show_bug.cgi?id=48676 + + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::depthRange): + +2010-11-03 Adrienne Walker <enne@google.com> + + Reviewed by Kenneth Russell. + + Properly return empty strings instead of null when using invalid + objects for some WebGL calls. This fixes issues caused by r71274. + https://bugs.webkit.org/show_bug.cgi?id=48962 + + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::getProgramInfoLog): + (WebCore::WebGLRenderingContext::getShaderInfoLog): + (WebCore::WebGLRenderingContext::getShaderSource): + +2010-11-01 Ryosuke Niwa <rniwa@webkit.org> + + Reviewed by Darin Adler. + + Crash in ApplyStyleCommand::removeStyleFromRunBeforeApplyingStyle + https://bugs.webkit.org/show_bug.cgi?id=48581 + + The crash was caused by RemoveNodePreservingChildrenCommand's calling removeNode + on m_node without checking that m_node has a parent and it's still in the document. + Fixed the crash by adding an early exit in CompositeEditCommand::removeNode and + deploying RefPtr in several places of ApplyStyleCommand.cpp. + + Test: editing/style/iframe-onload-crash.html + + * editing/ApplyStyleCommand.cpp: + (WebCore::ApplyStyleCommand::applyInlineStyleToNodeRange): + (WebCore::ApplyStyleCommand::removeStyleFromRunBeforeApplyingStyle): + (WebCore::ApplyStyleCommand::removeInlineStyleFromElement): + * editing/ApplyStyleCommand.h: + * editing/CompositeEditCommand.cpp: + (WebCore::CompositeEditCommand::removeNode): + +2010-11-03 Jia Pu <jpu@apple.com> + + Reviewed by Darin Adler. + + Crashes in WebCore::DocumentMarkerController::removeMarkersFromMarkerMapVectorPair() when deleting multiple lines of text. + https://bugs.webkit.org/show_bug.cgi?id=48918 + <rdar://problem/8620602> + + I haven't been able to found a reliable way to reproduce the bug. However, whenever it happens, + the crash is caused by a null node pointer returned by TextIterator. So it seems to be a + safe fix to guard against that. + + * editing/Editor.cpp: (WebCore::Editor::removeSpellAndCorrectionMarkersFromWordsToBeEdited): + +2010-11-02 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + A different mask or reference value in stencil operations should generate INVALID_OPERATION + https://bugs.webkit.org/show_bug.cgi?id=48669 + + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::WebGLRenderingContext): Init stencil func ref/mask and stencil mask to default. + (WebCore::WebGLRenderingContext::stencilFunc): Cache ref/mask value. + (WebCore::WebGLRenderingContext::stencilFuncSeparate): Generate error if front/back values differ. + (WebCore::WebGLRenderingContext::stencilMask): Cache mask value. + (WebCore::WebGLRenderingContext::stencilMaskSeparate): Generate error if front/back values differ. + (WebCore::WebGLRenderingContext::validateFace): Validate face parameter. + (WebCore::WebGLRenderingContext::validateStencilFunc): Validate stencil func parameter. + * html/canvas/WebGLRenderingContext.h: Add members to track stencil func ref/mask and stencil mask. + +2010-11-03 Dimitri Glazkov <dglazkov@chromium.org> + + Reverting r71244, r71248 and r71250. Broke default event handling inside text fields. + https://bugs.webkit.org/show_bug.cgi?id=46015 + + * Android.mk: + * CMakeLists.txt: + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * dom/ContainerNode.cpp: + (WebCore::notifyChildInserted): + * dom/DOMAllInOne.cpp: + * dom/EventContext.cpp: Removed. + * dom/EventContext.h: Removed. + * dom/Node.cpp: + (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): + (WebCore::Node::createRendererIfNeeded): + (WebCore::Node::eventParentNode): + (WebCore::Node::enclosingLinkEventParentOrSelf): + (WebCore::eventTargetAsSVGElementInstance): + (WebCore::eventTargetRespectingSVGTargetRules): + (WebCore::Node::eventAncestors): + (WebCore::Node::dispatchGenericEvent): + * dom/Node.h: + * dom/Text.cpp: + (WebCore::Text::createRenderer): + * dom/WindowEventContext.cpp: Removed. + * dom/WindowEventContext.h: Removed. + * inspector/InspectorDOMAgent.cpp: + (WebCore::InspectorDOMAgent::getEventListenersForNode): + * inspector/InspectorInstrumentation.cpp: + (WebCore::eventHasListeners): + (WebCore::InspectorInstrumentation::willDispatchEventImpl): + * inspector/InspectorInstrumentation.h: + (WebCore::InspectorInstrumentation::willDispatchEvent): + * page/EventHandler.cpp: + (WebCore::EventHandler::updateMouseEventTargetNode): + * rendering/ShadowElement.h: + (WebCore::ShadowElement::shadowParent): + (WebCore::ShadowElement::shadowParentNode): + * svg/SVGElement.cpp: + (WebCore::SVGElement::eventParentNode): + * svg/SVGElement.h: + +2010-11-03 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + CG use of WebKit image decoders crashes on some animated GIFs + https://bugs.webkit.org/show_bug.cgi?id=48955 + + It turns out CFDataGetMutableBytePtr isn't safe call on a null pointer. + + Test: fast/images/dont-crash-with-null-gif-frames.html + + * platform/image-decoders/cg/ImageDecoderCG.cpp: + (WebCore::RGBA32Buffer::copyReferenceToBitmapData): + (WebCore::RGBA32Buffer::copyBitmapData): + +2010-11-03 Adrienne Walker <enne@google.com> + + Reviewed by Kenneth Russell. + + Implement lost, restored, and creation failure context events for + WebGLRenderingContext. The lost and restored functions are not hooked + up yet, but the context now acts according to the spec as it should + during a lost context. Tested manually, as there's no programmatic + way to lose a context yet. + https://bugs.webkit.org/show_bug.cgi?id=35626 + + * WebCore.gypi: + * WebCore.xcodeproj/project.pbxproj: + * bindings/js/JSWebGLRenderingContextCustom.cpp: + (WebCore::JSWebGLRenderingContext::getAttachedShaders): + * bindings/v8/custom/V8WebGLRenderingContextCustom.cpp: + (WebCore::V8WebGLRenderingContext::getAttachedShadersCallback): + * dom/EventNames.h: + * html/canvas/WebGLContextEvent.cpp: Added. + (WebCore::WebGLContextEvent::WebGLContextEvent): + (WebCore::WebGLContextEvent::~WebGLContextEvent): + (WebCore::WebGLContextEvent::initEvent): + * html/canvas/WebGLContextEvent.h: Added. + (WebCore::WebGLContextEvent::create): + (WebCore::WebGLContextEvent::statusMessage): + * html/canvas/WebGLContextEvent.idl: Added. + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::create): + (WebCore::WebGLRenderingContext::WebGLRenderingContext): + (WebCore::WebGLRenderingContext::initializeNewContext): + (WebCore::WebGLRenderingContext::activeTexture): + (WebCore::WebGLRenderingContext::attachShader): + (WebCore::WebGLRenderingContext::bindAttribLocation): + (WebCore::WebGLRenderingContext::bindBuffer): + (WebCore::WebGLRenderingContext::bindFramebuffer): + (WebCore::WebGLRenderingContext::bindRenderbuffer): + (WebCore::WebGLRenderingContext::bindTexture): + (WebCore::WebGLRenderingContext::blendColor): + (WebCore::WebGLRenderingContext::blendEquation): + (WebCore::WebGLRenderingContext::blendEquationSeparate): + (WebCore::WebGLRenderingContext::blendFunc): + (WebCore::WebGLRenderingContext::blendFuncSeparate): + (WebCore::WebGLRenderingContext::bufferData): + (WebCore::WebGLRenderingContext::bufferSubData): + (WebCore::WebGLRenderingContext::checkFramebufferStatus): + (WebCore::WebGLRenderingContext::clear): + (WebCore::WebGLRenderingContext::clearColor): + (WebCore::WebGLRenderingContext::clearDepth): + (WebCore::WebGLRenderingContext::clearStencil): + (WebCore::WebGLRenderingContext::colorMask): + (WebCore::WebGLRenderingContext::compileShader): + (WebCore::WebGLRenderingContext::copyTexImage2D): + (WebCore::WebGLRenderingContext::copyTexSubImage2D): + (WebCore::WebGLRenderingContext::createBuffer): + (WebCore::WebGLRenderingContext::createFramebuffer): + (WebCore::WebGLRenderingContext::createTexture): + (WebCore::WebGLRenderingContext::createProgram): + (WebCore::WebGLRenderingContext::createRenderbuffer): + (WebCore::WebGLRenderingContext::createShader): + (WebCore::WebGLRenderingContext::cullFace): + (WebCore::WebGLRenderingContext::deleteBuffer): + (WebCore::WebGLRenderingContext::deleteFramebuffer): + (WebCore::WebGLRenderingContext::deleteProgram): + (WebCore::WebGLRenderingContext::deleteRenderbuffer): + (WebCore::WebGLRenderingContext::deleteShader): + (WebCore::WebGLRenderingContext::deleteTexture): + (WebCore::WebGLRenderingContext::depthFunc): + (WebCore::WebGLRenderingContext::depthMask): + (WebCore::WebGLRenderingContext::depthRange): + (WebCore::WebGLRenderingContext::detachShader): + (WebCore::WebGLRenderingContext::disable): + (WebCore::WebGLRenderingContext::disableVertexAttribArray): + (WebCore::WebGLRenderingContext::drawArrays): + (WebCore::WebGLRenderingContext::drawElements): + (WebCore::WebGLRenderingContext::enable): + (WebCore::WebGLRenderingContext::enableVertexAttribArray): + (WebCore::WebGLRenderingContext::finish): + (WebCore::WebGLRenderingContext::flush): + (WebCore::WebGLRenderingContext::framebufferRenderbuffer): + (WebCore::WebGLRenderingContext::framebufferTexture2D): + (WebCore::WebGLRenderingContext::frontFace): + (WebCore::WebGLRenderingContext::generateMipmap): + (WebCore::WebGLRenderingContext::getActiveAttrib): + (WebCore::WebGLRenderingContext::getActiveUniform): + (WebCore::WebGLRenderingContext::getAttachedShaders): + (WebCore::WebGLRenderingContext::getAttribLocation): + (WebCore::WebGLRenderingContext::getBufferParameter): + (WebCore::WebGLRenderingContext::getContextAttributes): + (WebCore::WebGLRenderingContext::getFramebufferAttachmentParameter): + (WebCore::WebGLRenderingContext::getParameter): + (WebCore::WebGLRenderingContext::getProgramParameter): + (WebCore::WebGLRenderingContext::getProgramInfoLog): + (WebCore::WebGLRenderingContext::getRenderbufferParameter): + (WebCore::WebGLRenderingContext::getShaderParameter): + (WebCore::WebGLRenderingContext::getShaderInfoLog): + (WebCore::WebGLRenderingContext::getShaderSource): + (WebCore::WebGLRenderingContext::getTexParameter): + (WebCore::WebGLRenderingContext::getUniform): + (WebCore::WebGLRenderingContext::getUniformLocation): + (WebCore::WebGLRenderingContext::getVertexAttrib): + (WebCore::WebGLRenderingContext::getVertexAttribOffset): + (WebCore::WebGLRenderingContext::hint): + (WebCore::WebGLRenderingContext::isBuffer): + (WebCore::WebGLRenderingContext::isContextLost): + (WebCore::WebGLRenderingContext::isEnabled): + (WebCore::WebGLRenderingContext::isFramebuffer): + (WebCore::WebGLRenderingContext::isProgram): + (WebCore::WebGLRenderingContext::isRenderbuffer): + (WebCore::WebGLRenderingContext::isShader): + (WebCore::WebGLRenderingContext::isTexture): + (WebCore::WebGLRenderingContext::lineWidth): + (WebCore::WebGLRenderingContext::linkProgram): + (WebCore::WebGLRenderingContext::pixelStorei): + (WebCore::WebGLRenderingContext::polygonOffset): + (WebCore::WebGLRenderingContext::readPixels): + (WebCore::WebGLRenderingContext::releaseShaderCompiler): + (WebCore::WebGLRenderingContext::renderbufferStorage): + (WebCore::WebGLRenderingContext::sampleCoverage): + (WebCore::WebGLRenderingContext::scissor): + (WebCore::WebGLRenderingContext::shaderSource): + (WebCore::WebGLRenderingContext::stencilFunc): + (WebCore::WebGLRenderingContext::stencilFuncSeparate): + (WebCore::WebGLRenderingContext::stencilMask): + (WebCore::WebGLRenderingContext::stencilMaskSeparate): + (WebCore::WebGLRenderingContext::stencilOp): + (WebCore::WebGLRenderingContext::stencilOpSeparate): + (WebCore::WebGLRenderingContext::texImage2D): + (WebCore::WebGLRenderingContext::texParameter): + (WebCore::WebGLRenderingContext::texSubImage2DBase): + (WebCore::WebGLRenderingContext::texSubImage2DImpl): + (WebCore::WebGLRenderingContext::texSubImage2D): + (WebCore::WebGLRenderingContext::uniform1f): + (WebCore::WebGLRenderingContext::uniform1fv): + (WebCore::WebGLRenderingContext::uniform1i): + (WebCore::WebGLRenderingContext::uniform1iv): + (WebCore::WebGLRenderingContext::uniform2f): + (WebCore::WebGLRenderingContext::uniform2fv): + (WebCore::WebGLRenderingContext::uniform2i): + (WebCore::WebGLRenderingContext::uniform2iv): + (WebCore::WebGLRenderingContext::uniform3f): + (WebCore::WebGLRenderingContext::uniform3fv): + (WebCore::WebGLRenderingContext::uniform3i): + (WebCore::WebGLRenderingContext::uniform3iv): + (WebCore::WebGLRenderingContext::uniform4f): + (WebCore::WebGLRenderingContext::uniform4fv): + (WebCore::WebGLRenderingContext::uniform4i): + (WebCore::WebGLRenderingContext::uniform4iv): + (WebCore::WebGLRenderingContext::uniformMatrix2fv): + (WebCore::WebGLRenderingContext::uniformMatrix3fv): + (WebCore::WebGLRenderingContext::uniformMatrix4fv): + (WebCore::WebGLRenderingContext::useProgram): + (WebCore::WebGLRenderingContext::validateProgram): + (WebCore::WebGLRenderingContext::vertexAttribPointer): + (WebCore::WebGLRenderingContext::viewport): + (WebCore::WebGLRenderingContext::loseContext): + (WebCore::WebGLRenderingContext::restoreContext): + (WebCore::WebGLRenderingContext::addObject): + (WebCore::WebGLRenderingContext::vertexAttribfImpl): + (WebCore::WebGLRenderingContext::vertexAttribfvImpl): + * html/canvas/WebGLRenderingContext.h: + * html/canvas/WebGLRenderingContext.idl: + * platform/graphics/GraphicsContext3D.h: + +2010-11-03 Kenneth Russell <kbr@google.com> + + Reviewed by Chris Marrin. + + Redesign extension mechanism in GraphicsContext3D + https://bugs.webkit.org/show_bug.cgi?id=46894 + + Upon request, factored out extension support from GraphicsContext3D + into a new Extensions3D class. (The plural was chosen because the + class and subclasses hold multiple extensions.) + + Unlike GraphicsContext3D, Extensions3D contains only pure virtual + methods. This was done because Extensions3D's inheritance diagram + and usage pattern is very different from that of GraphicsContext3D, + and the concrete subclasses need to decide how to implement the + various entry points. Requiring them to be placed at the + Extensions3D level will cause implementation details to leak into + the base class, which is highly undesirable. Any virtual call + overhead to these entry points will be negligible. + + Changed call sites utilizing these extensions to call through the + Extensions3D object or its subclasses. + + Tested: + - Chromium on Linux with accelerated 2D canvas and HTML5 video + - Chromium on Mac OS X with WebGL and CSS 3D content + - Safari on Mac OS X with WebGL and CSS 3D content + + No new tests. Covered by existing tests. + + * WebCore.gypi: + * WebCore.pro: + * WebCore.xcodeproj/project.pbxproj: + * platform/graphics/Extensions3D.h: Added. + (WebCore::Extensions3D::~Extensions3D): + * platform/graphics/GraphicsContext3D.cpp: + * platform/graphics/GraphicsContext3D.h: + * platform/graphics/chromium/DrawingBufferChromium.cpp: + (WebCore::DrawingBuffer::DrawingBuffer): + (WebCore::DrawingBuffer::publishToPlatformLayer): + * platform/graphics/chromium/Extensions3DChromium.h: Added. + * platform/graphics/chromium/VideoLayerChromium.cpp: + (WebCore::VideoLayerChromium::updateTexture): + * platform/graphics/gpu/SharedGraphicsContext3D.cpp: + (WebCore::SharedGraphicsContext3D::supportsBGRA): + * platform/graphics/gpu/SharedGraphicsContext3D.h: + * platform/graphics/gpu/Texture.cpp: + (WebCore::convertFormat): + * platform/graphics/mac/GraphicsContext3DMac.mm: + * platform/graphics/opengl/Extensions3DOpenGL.cpp: Added. + (WebCore::Extensions3DOpenGL::Extensions3DOpenGL): + (WebCore::Extensions3DOpenGL::~Extensions3DOpenGL): + (WebCore::Extensions3DOpenGL::supports): + (WebCore::Extensions3DOpenGL::getGraphicsResetStatusARB): + * platform/graphics/opengl/Extensions3DOpenGL.h: Added. + * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp: + (WebCore::GraphicsContext3D::getExtensions): + * platform/graphics/qt/Extensions3DQt.cpp: Added. + (WebCore::Extensions3DQt::Extensions3DQt): + (WebCore::Extensions3DQt::~Extensions3DQt): + (WebCore::Extensions3DQt::supports): + (WebCore::Extensions3DQt::getGraphicsResetStatusARB): + * platform/graphics/qt/Extensions3DQt.h: Added. + * platform/graphics/qt/GraphicsContext3DQt.cpp: + (WebCore::GraphicsContext3D::getExtensions): + * platform/graphics/skia/PlatformContextSkia.cpp: + (WebCore::PlatformContextSkia::readbackHardwareToSoftware): + +2010-11-03 Mike Thole <mthole@apple.com> + + Reviewed by Darin Adler. + + Tweak coding style (follow-up to r71264). + + * platform/mac/Language.mm: + (WebCore::createHTTPStyleLanguageCode): Style tweaks. + +2010-11-03 Darin Adler <darin@apple.com> + + Updated Xcode projects by opening them with Xcode 3.2.4. + Updated svn:ignore for Xcode projects. + + * manual-tests/NPN_Invoke/NPN_Invoke.xcodeproj: Added property svn:ignore. + * manual-tests/NPN_Invoke/NPN_Invoke.xcodeproj/project.pbxproj: Updated with Xcode 3.2.4. + +2010-11-03 Matthew Delaney <mdelaney@apple.com> + + Reviewed by Darin Adler. + + Fix canvas/philip/tests/2d.pattern.image.undefined.html + https://bugs.webkit.org/show_bug.cgi?id=48894 + + * bindings/js/JSCanvasRenderingContext2DCustom.cpp: Changed error thrown to match the spec. + +2010-11-03 Simon Fraser <simon.fraser@apple.com> + + Reviewed by John Sullivan. + + Crash when setting context font to bad value + https://bugs.webkit.org/show_bug.cgi?id=48948 + + Null-check the CSSValue passed to CSSStyleSelector::applyPropertyToStyle(), + since it may be null if the style declaration does not contain a value + for the 'font' property. + + Test: fast/canvas/invalid-set-font-crash.html + + * css/CSSStyleSelector.cpp: + (WebCore::CSSStyleSelector::applyPropertyToStyle): + +2010-11-03 Mike Thole <mthole@apple.com> + + Reviewed by Alexey Proskuryakov. + + Crash under WebCore::platformDefaultLanguage() when using Arabic language + https://bugs.webkit.org/show_bug.cgi?id=48946 + + * platform/mac/Language.mm: + (WebCore::createHTTPStyleLanguageCode): + Retain the lowercaseLanguageCode string before returning it. This was the code path that + would lead to a crash. Also removed early return to prevent a leak of preferredLanguageCode. + +2010-11-03 Dan Bernstein <mitz@apple.com> + + Reviewed by Dave Hyatt. + + Made table column width allocation algorithms use logical widths. + + Part of: Make tables work with vertical text + https://bugs.webkit.org/show_bug.cgi?id=46417 + + No new tests since tables don’t support different block flows yet. + + * rendering/AutoTableLayout.cpp: + (WebCore::AutoTableLayout::AutoTableLayout): + (WebCore::AutoTableLayout::recalcColumn): + (WebCore::AutoTableLayout::fullRecalc): + (WebCore::AutoTableLayout::computePreferredLogicalWidths): + (WebCore::AutoTableLayout::calcEffectiveLogicalWidth): + (WebCore::AutoTableLayout::insertSpanCell): + (WebCore::AutoTableLayout::layout): + * rendering/AutoTableLayout.h: + (WebCore::AutoTableLayout::Layout::Layout): + * rendering/FixedTableLayout.cpp: + (WebCore::FixedTableLayout::calcWidthArray): + (WebCore::FixedTableLayout::computePreferredLogicalWidths): + (WebCore::FixedTableLayout::layout): + * rendering/FixedTableLayout.h: + * rendering/RenderTable.h: + (WebCore::RenderTable::bordersPaddingAndSpacingInRowDirection): Renamed, but not changed yet. + +2010-11-03 No'am Rosenthal <noam.rosenthal@nokia.com> + + Unreviewed build fix for r71253 + + #endif for TILED_BACKING_STORE was at the wrong place. + + * platform/graphics/qt/GraphicsLayerQt.cpp: + (WebCore::GraphicsLayerQtImpl::tiledBackingStoreBackgroundColor): + +2010-11-03 David Hyatt <hyatt@apple.com> + + Reviewed by Dan Bernstein. + + https://bugs.webkit.org/show_bug.cgi?id=48945 + + Patch logicalLeftSelectionOffset and logicalRightSelectionOffset to be directionally abstract. + + Also make sure writing mode roots are also selection painting roots. + + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::isSelectionRoot): + (WebCore::RenderBlock::logicalLeftSelectionOffset): + (WebCore::RenderBlock::logicalRightSelectionOffset): + * rendering/RenderBlock.h: + +2010-11-03 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: main resource is being re-assigned upon iframe's commit load. + https://bugs.webkit.org/show_bug.cgi?id=48940 + + * inspector/front-end/ResourceManager.js: + (WebInspector.ResourceManager.prototype.identifierForInitialRequest): + (WebInspector.ResourceManager.prototype.didCommitLoadForFrame): + +2010-11-03 Nate Chapin <japhet@chromium.org> + + Reviewed by Alexey Proskuryakov. + + Wait to stop all loads for a frame being detached until after its + chidlren have been detached. This ensures that any loads started + by a child's unload event handler will be properly cancelled. + https://bugs.webkit.org/show_bug.cgi?id=46579 + + Tests: fast/loader/ping-error.html + http/tests/navigation/image-load-in-subframe-unload-handler.html + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::detachFromParent): + +2010-11-03 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Simon Fraser. + + Web Inspector: show proper image size for cached resources. + https://bugs.webkit.org/show_bug.cgi?id=48915 + + * inspector/front-end/ExtensionServer.js: + (WebInspector.ExtensionServer.prototype._onGetResourceContent): + * inspector/front-end/ImageView.js: + (WebInspector.ImageView.prototype.contentTabSelected.onImageLoad): + (WebInspector.ImageView.prototype.contentTabSelected): + (WebInspector.ImageView.prototype._base64ToSize): + * inspector/front-end/NetworkPanel.js: + (WebInspector.NetworkDataGridNode.prototype._refreshNameCell): + * inspector/front-end/Resource.js: + (WebInspector.Resource.prototype.set finished): + (WebInspector.Resource.prototype.get content): + (WebInspector.Resource.prototype.requestContent): + (WebInspector.Resource.prototype._innerRequestContent): + * inspector/front-end/ResourceManager.js: + (WebInspector.ResourceManager.requestContent): + * inspector/front-end/SourceView.js: + (WebInspector.SourceView.prototype.setupSourceFrameIfNeeded): + +2010-11-03 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] GraphicsLayer: support tiling + https://bugs.webkit.org/show_bug.cgi?id=39691 + + Add support for TiledBackingStore in GraphicsLayerQt, when a layer is too large. + + No new tests. Tests in LayoutTests/compositing/tiling now work with OpenGL enabled. + + * platform/graphics/qt/GraphicsLayerQt.cpp: + (WebCore::GraphicsLayerQtImpl::GraphicsLayerQtImpl): + (WebCore::GraphicsLayerQtImpl::~GraphicsLayerQtImpl): + (WebCore::GraphicsLayerQtImpl::recache): + (WebCore::GraphicsLayerQtImpl::paint): + (WebCore::GraphicsLayerQtImpl::tiledBackingStorePaintBegin): + (WebCore::GraphicsLayerQtImpl::tiledBackingStorePaint): + (WebCore::GraphicsLayerQtImpl::tiledBackingStorePaintEnd): + (WebCore::GraphicsLayerQtImpl::tiledBackingStoreContentsRect): + (WebCore::GraphicsLayerQtImpl::tiledBackingStoreBackgroundColor): + (WebCore::GraphicsLayerQtImpl::tiledBackingStoreVisibleRect): + +2010-11-03 Tony Chang <tony@chromium.org> + + Reviewed by Ojan Vafai. + + Undo r54932 which inappropriately adjusts font sizes on zoomed pages + https://bugs.webkit.org/show_bug.cgi?id=48890 + + Test: editing/inserting/page-zoom-font-size.html + + * editing/ReplaceSelectionCommand.cpp: + (WebCore::ReplaceSelectionCommand::negateStyleRulesThatAffectAppearance): + +2010-11-03 Dan Bernstein <mitz@apple.com> + + Reviewed by Dave Hyatt. + + Make collapsed borders in tables work with different block flows + https://bugs.webkit.org/show_bug.cgi?id=46191 + + No new tests since tables don’t support different block flows yet. + + This change still doesn’t support cells whose block flow differs from the table’s. + + * rendering/AutoTableLayout.cpp: + (WebCore::AutoTableLayout::recalcColumn): Updated for the renaming of styleOrColWidth(). + (WebCore::AutoTableLayout::calcEffectiveWidth): Ditto. + * rendering/FixedTableLayout.cpp: + (WebCore::FixedTableLayout::calcWidthArray): Ditto. + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::computePreferredLogicalWidths): Ditto. + * rendering/RenderTableCell.cpp: + (WebCore::RenderTableCell::styleOrColLogicalWidth): Renamed styleOrColWidth() to this and + changed to use logical widths. + (WebCore::RenderTableCell::computePreferredLogicalWidths): Updated for the above rename. + (WebCore::RenderTableCell::updateLogicalWidth): Renamed updateWidth() to this and changed + to set the logical width. + (WebCore::RenderTableCell::collapsedStartBorder): Changed collapsedLeftBorder() into this. + Note that “start” here will refer to the table’s block flow, not the cell’s, once we allow + the two to differ. + (WebCore::RenderTableCell::collapsedEndBorder): Similar. + (WebCore::RenderTableCell::collapsedBeforeBorder): Similar. + (WebCore::RenderTableCell::collapsedAfterBorder): Similar. + (WebCore::RenderTableCell::collapsedLeftBorder): Resolves “left” to a logical side using + the table’s block flow. + (WebCore::RenderTableCell::collapsedRightBorder): Similar. + (WebCore::RenderTableCell::collapsedTopBorder): Similar. + (WebCore::RenderTableCell::collapsedBottomBorder): Similar. + (WebCore::RenderTableCell::borderStart): Use borderHalfStart(). + (WebCore::RenderTableCell::borderEnd): Similar. + (WebCore::RenderTableCell::borderBefore): Similar. + (WebCore::RenderTableCell::borderAfter): Similar. + (WebCore::RenderTableCell::borderHalfLeft): Resolves “left” to a logical side using the + table’s block flow. + (WebCore::RenderTableCell::borderHalfRight): Similar. + (WebCore::RenderTableCell::borderHalfTop): Similar. + (WebCore::RenderTableCell::borderHalfBottom): Similar. + (WebCore::RenderTableCell::borderHalfStart): Added. Uses collapsedStartBorder(). Splits odd + widths based on physical side. + (WebCore::RenderTableCell::borderHalfEnd): Similar. + (WebCore::RenderTableCell::borderHalfBefore): Similar. + (WebCore::RenderTableCell::borderHalfAfter): Similar. + (WebCore::RenderTableCell::collectBorderStyles): Use logical methods. + (WebCore::RenderTableCell::paintCollapsedBorder): Updated. + * rendering/RenderTableCell.h: + * rendering/RenderTableSection.cpp: + (WebCore::RenderTableSection::setCellWidths): Updated for the renaming of updateWidth(). + * rendering/style/RenderStyle.cpp: + (WebCore::RenderStyle::borderBefore): Added. + (WebCore::RenderStyle::borderAfter): Added. + (WebCore::RenderStyle::borderStart): Added. + (WebCore::RenderStyle::borderEnd): Adeed. + * rendering/style/RenderStyle.h: + +2010-11-03 Dimitri Glazkov <dglazkov@chromium.org> + + Fix Win build correctly after r71244 and r71248 + + * WebCore.vcproj/WebCore.vcproj: Added XML gobbledygook back. + * dom/DOMAllInOne.cpp: Added files to build into a combined file. + +2010-11-03 Dimitri Glazkov <dglazkov@chromium.org> + + Fix Qt, Win builds after r71244. + + * WebCore.vcproj/WebCore.vcproj: Removed XML gobbledygook that prevents files from building. + * dom/Text.cpp: + (WebCore::Text::createRenderer): Moved parentOrHost inside ENABLE(SVG) guard. + +2010-11-03 David Hyatt <hyatt@apple.com> + + Reviewed by Dan Bernstein. + + https://bugs.webkit.org/show_bug.cgi?id=48928 + + Rename all the selection gap functions to not be directionally specific. Left and Right turn into LogicalLeft and + LogicalRight. Horizontal becomes Line. Vertical becomes Block. + + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::selectionGapRectsForRepaint): + (WebCore::RenderBlock::paintSelection): + (WebCore::RenderBlock::fillSelectionGaps): + (WebCore::RenderBlock::fillInlineSelectionGaps): + (WebCore::RenderBlock::fillBlockSelectionGaps): + (WebCore::RenderBlock::fillLineSelectionGap): + (WebCore::RenderBlock::fillBlockSelectionGap): + (WebCore::RenderBlock::fillLogicalLeftSelectionGap): + (WebCore::RenderBlock::fillLogicalRightSelectionGap): + (WebCore::RenderBlock::getSelectionGapInfo): + (WebCore::RenderBlock::logicalLeftSelectionOffset): + (WebCore::RenderBlock::logicalRightSelectionOffset): + * rendering/RenderBlock.h: + * rendering/RootInlineBox.cpp: + (WebCore::RootInlineBox::fillLineSelectionGap): + +2010-11-03 Dimitri Glazkov <dglazkov@chromium.org> + + Reviewed by Darin Adler. + + Implement shadow DOM-aware event targeting and introduce EventContext to track the context of each event dispatch. + https://bugs.webkit.org/show_bug.cgi?id=46015 + + This patch adds the notion of EventContext (and a very similar-acting WindowEventContext, specifically + for DOMWindow), an abstraction that carries information around dispatching an event for any given Node. + + This abstraction is necessary to ensure that events, fired from shadow DOM nodes are properly retargeted to + appear as if they are coming from their host, thus never exposing the shadow DOM nodes to the world outside. + + * Android.mk: Added EventContext, WindowEventContext files. + * CMakeLists.txt: Ditto. + * GNUmakefile.am: Ditto. + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * dom/ContainerNode.cpp: + (WebCore::notifyChildInserted): Changed to be shadow DOM-aware. + * dom/EventContext.cpp: Added. + * dom/EventContext.h: Added. + * dom/Node.cpp: + (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Changed to be shadow DOM-aware. + (WebCore::Node::createRendererIfNeeded): Ditto. + (WebCore::Node::parentOrHostNode): Added new helper method. + (WebCore::Node::enclosingLinkEventParentOrSelf): Changed to be shadow DOM-aware. + (WebCore::eventTargetRespectingSVGTargetRules): Collapsed two helper methods into one. + (WebCore::Node::eventAncestors): Refactored to collect a vector of EventContexts. + (WebCore::Node::topEventContext): Added. + (WebCore::eventHasListeners): Changed to use EventContexts. + (WebCore::Node::dispatchGenericEvent): Ditto. + * dom/Node.h: Removed eventParentNode that's no longer needed, added parentOrHostNode decl, + and changed signature of eventAncestors to use EventContexts. + * dom/Text.cpp: + (WebCore::Text::createRenderer): Changed to be shadow DOM-aware. + * inspector/InspectorDOMAgent.cpp: + (WebCore::InspectorDOMAgent::getEventListenersForNode): Changed to use EventContexts. + * page/EventHandler.cpp: + (WebCore::EventHandler::updateMouseEventTargetNode): Removed code that's no longer necessary. + * rendering/ShadowElement.h: Made m_shadowParent a RefPtr to avoid stale references when parent + is deleted. + * svg/SVGElement.cpp: Removed eventParentNode that's no longer needed. + * svg/SVGElement.h: Ditto. + * dom/WindowEventContext.cpp: Added. + * dom/WindowEventContext.h: Added. + +2010-11-02 Mikhail Naganov <mnaganov@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: Fix console messages about starting and finishing profiling. + + https://bugs.webkit.org/show_bug.cgi?id=48825 + + * inspector/InspectorProfilerAgent.cpp: + (WebCore::InspectorProfilerAgent::addStartProfilingMessageToConsole): + * inspector/front-end/ProfilesPanel.js: + (WebInspector.ProfilesPanel.prototype.displayTitleForProfileLink): + +2010-11-03 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Andreas Kling. + + chrome.dll!WebCore::SVGLength::SVGLength ... + https://bugs.webkit.org/show_bug.cgi?id=48831 + + Test: svg/dom/baseVal-animVal-crash.html + + * svg/properties/SVGListPropertyTearOff.h: + (WebCore::SVGListPropertyTearOff::initialize): Renamed removeItemFromListIfNeeded to processIncomingListItem, to reflect its new job. + (WebCore::SVGListPropertyTearOff::insertItemBefore): Ditto. + (WebCore::SVGListPropertyTearOff::replaceItem): Ditto. + (WebCore::SVGListPropertyTearOff::appendItem): Ditto. + (WebCore::SVGListPropertyTearOff::processIncomingListItem): Copy incoming item, if necessary, see inline comments. + * svg/properties/SVGPropertyTearOff.h: + (WebCore::SVGPropertyTearOff::detachWrapper): Remove association with SVGAnimatedProperty, when wrapper is detached. + +2010-11-03 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Andreas Kling. + + Make it possible to delegate scrolling to the UI + https://bugs.webkit.org/show_bug.cgi?id=48907 + + Add a WebCore setting for delegating scrolling to the actual + WebKit view, which means that setScrollPosition will call + scrollContents directly without going though the scrollbar + code. + + * page/FrameView.cpp: + (WebCore::FrameView::delegatesScrolling): + * page/FrameView.h: + * page/Settings.cpp: + (WebCore::Settings::Settings): + (WebCore::Settings::setShouldDelegateScrolling): + * page/Settings.h: + (WebCore::Settings::shouldDelegateScrolling): + * platform/ScrollView.cpp: + (WebCore::ScrollView::setScrollPosition): + * platform/ScrollView.h: + (WebCore::ScrollView::delegatesScrolling): + +2010-11-03 Patrick Gansterer <paroga@webkit.org> + + Reviewed by Adam Roben. + + [WINCE] Add SharedBitmap + https://bugs.webkit.org/show_bug.cgi?id=28272 + + SharedBitmap is a helper class used as NativeImagePtr for WinCE. + It's wide used by WinCE graphics files as a replacement of HBITMAP. + + Originally written by Yong Li <yong.li@torchmobile.com>. + + * platform/graphics/wince/GraphicsContextWinCE.cpp: + (WebCore::TransparentLayerDC::TransparentLayerDC): + (WebCore::TransparentLayerDC::~TransparentLayerDC): + (WebCore::ScopeDCProvider::ScopeDCProvider): + (WebCore::ScopeDCProvider::~ScopeDCProvider): + (WebCore::GraphicsContext::drawText): + * platform/graphics/wince/SharedBitmap.cpp: Added. + (WebCore::SharedBitmap::create): + (WebCore::SharedBitmap::SharedBitmap): + (WebCore::SharedBitmap::~SharedBitmap): + (WebCore::SharedBitmap::resetPixels): + (WebCore::convert32To16): + (WebCore::SharedBitmap::to16bit): + (WebCore::SharedBitmap::freeMemory): + (WebCore::SharedBitmap::createHandle): + (WebCore::SharedBitmap::ensureHandle): + (WebCore::SharedBitmap::draw): + (WebCore::SharedBitmap::clipBitmap): + (WebCore::drawPatternSimple): + (WebCore::normalizePhase): + (WebCore::SharedBitmap::drawPattern): + (WebCore::SharedBitmap::DCProvider::getDC): + (WebCore::SharedBitmap::DCProvider::releaseDC): + (WebCore::SharedBitmap::clearPixels): + * platform/graphics/wince/SharedBitmap.h: Added. + (WebCore::DCProvider::getDC): + (WebCore::DCProvider::releaseDC): + (WebCore::DCProvider::DCHolder::DCHolder): + (WebCore::DCProvider::DCHolder::~DCHolder): + (WebCore::DCProvider::DCHolder::set): + (WebCore::DCProvider::DCHolder::get): + (WebCore::DCProvider::DCHolder::clearInternal): + (WebCore::DCProvider::DCHolder::setInternal): + +2010-11-03 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Dirk Schulze. + + chrome.dll!WebCore::SVGListPropertyTearOff<...>::getItem ReadAV@NULL (578c0f7f21ca517ba29a4eafb7099c1b) + https://bugs.webkit.org/show_bug.cgi?id=48829 + + Share SVGPropertyTearOff wrapper cache between SVGAnimatedListPropertyTearOff::baseVal/animVal. + When modifying the list through baseVal, and then grabbing the animVal list an assertion was fired, + as the wrapper cache was out of sync with the underlying SVG*List vector. + + Test: svg/dom/baseVal-animVal-list-crash.html + + * svg/properties/SVGAnimatedListPropertyTearOff.h: + (WebCore::SVGAnimatedListPropertyTearOff::baseVal): + (WebCore::SVGAnimatedListPropertyTearOff::animVal): + (WebCore::SVGAnimatedListPropertyTearOff::removeItemFromList): + (WebCore::SVGAnimatedListPropertyTearOff::detachListWrappers): + (WebCore::SVGAnimatedListPropertyTearOff::values): + (WebCore::SVGAnimatedListPropertyTearOff::wrappers): + (WebCore::SVGAnimatedListPropertyTearOff::create): + (WebCore::SVGAnimatedListPropertyTearOff::SVGAnimatedListPropertyTearOff): + * svg/properties/SVGListPropertyTearOff.h: + (WebCore::SVGListPropertyTearOff::create): + (WebCore::SVGListPropertyTearOff::removeItemFromList): + (WebCore::SVGListPropertyTearOff::clear): + (WebCore::SVGListPropertyTearOff::numberOfItems): + (WebCore::SVGListPropertyTearOff::initialize): + (WebCore::SVGListPropertyTearOff::getItem): + (WebCore::SVGListPropertyTearOff::insertItemBefore): + (WebCore::SVGListPropertyTearOff::replaceItem): + (WebCore::SVGListPropertyTearOff::removeItem): + (WebCore::SVGListPropertyTearOff::appendItem): + (WebCore::SVGListPropertyTearOff::SVGListPropertyTearOff): + (WebCore::SVGListPropertyTearOff::commitChange): + +2010-11-02 Ilya Tikhonovsky <loislo@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: Remove obsolete code. + It is not required to push onload and DOMContentLoaded events times to the fresh instance of Inspector. + Network Panel is showing the markers only after reloading the inspected page. + https://bugs.webkit.org/show_bug.cgi?id=48854 + + * inspector/InspectorController.cpp: + (WebCore::InspectorController::InspectorController): + (WebCore::InspectorController::populateScriptObjects): + (WebCore::InspectorController::mainResourceFiredDOMContentEvent): + (WebCore::InspectorController::mainResourceFiredLoadEvent): + * inspector/InspectorController.h: + +2010-11-03 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Jeremy Orlow. + + Web Inspector: brush up breakpoints UI and UX. + https://bugs.webkit.org/show_bug.cgi?id=48901 + + * inspector/front-end/BreakpointManager.js: + (WebInspector.DOMBreakpoint.prototype.populateLabelElement): + (WebInspector.XHRBreakpoint.prototype.populateLabelElement): + * inspector/front-end/BreakpointsSidebarPane.js: + (WebInspector.BreakpointsSidebarPane.prototype.addBreakpointItem): + (WebInspector.XHRBreakpointsSidebarPane.prototype.addBreakpointItem): + (WebInspector.XHRBreakpointsSidebarPane.prototype._hideEditBreakpointDialog): + (WebInspector.BreakpointItem): + * inspector/front-end/ElementsTreeOutline.js: + (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu.handlerFunction): + (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu): + * inspector/front-end/PropertiesSection.js: + (WebInspector.PropertiesSection): + * inspector/front-end/inspector.css: + (.monospace): + (body.platform-mac.platform-mac-snowleopard .source-code): + (body.platform-windows .monospace, body.platform-windows .source-code): + (body.platform-linux .monospace, body.platform-linux .source-code): + (.source-code): + (.section .header): + (.section .header::before): + (.section .header .title, .event-bar .header .title): + (.section .header .subtitle, .event-bar .header .subtitle): + (.section.expanded .properties, .event-bar.expanded .event-properties): + (.event-listener-breakpoints .event-category): + (.event-listener-breakpoints.properties-tree .children li): + (.event-listener-breakpoints .checkbox-elem): + (.event-bar): + (.event-bars .event-bar .header .title): + (.event-bars .event-bar .header::before): + (.pane > .body .info): + (.pane > .body .placard + .info): + (ol.breakpoint-list): + (.breakpoint-list li): + (.pane .breakpoint-hit): + (.cursor-pointer): + (.cursor-auto): + +2010-11-03 Nikolas Zimmermann <nzimmermann@rim.com> + + Not reviewed. + + Convert SVGAnimatedString/SVGStringList to the new SVG*PropertyTearOff concept + https://bugs.webkit.org/show_bug.cgi?id=48898 + + Fix Chromium/V8 build for real, verified using a local ToT Chromium build. + + * bindings/scripts/CodeGeneratorV8.pm: + +2010-11-03 Nikolas Zimmermann <nzimmermann@rim.com> + + Not reviewed. + + Convert SVGAnimatedString/SVGStringList to the new SVG*PropertyTearOff concept + https://bugs.webkit.org/show_bug.cgi?id=48898 + + Next attempt to fix the Chromium/V8 builds - a class forward in the headers was still missing. + + * bindings/scripts/CodeGeneratorV8.pm: Add SVGStringListPropertyTearOff in the V8SVGStringList header. + +2010-11-03 Nikolas Zimmermann <nzimmermann@rim.com> + + Not reviewed. + + Convert SVGAnimatedString/SVGStringList to the new SVG*PropertyTearOff concept + https://bugs.webkit.org/show_bug.cgi?id=48898 + + Attempt to fix the Chromium/V8 builds. + + * bindings/scripts/CodeGeneratorV8.pm: Add missing "SVGStringListPropertyTearOff.h" include, also replaces some commas by semicolons (no idea why it worked before, Perl is not strict...) + +2010-11-03 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Dirk Schulze. + + Convert SVGAnimatedString/SVGStringList to the new SVG*PropertyTearOff concept + https://bugs.webkit.org/show_bug.cgi?id=48898 + + Convert SVGAnimatedString/SVGStringList to the new svg animated type concept. + SVGStringList is special compared to all other SVG*Lists, as it returns non-live elements. + That means myStringList.getItem(0) = 'foobar' doesn't take effect. + + When appending an item to a SVGStringList, that has been taken from another list, it's not removed from the list origin. + That demanded a new SVGStringListPropertyTearOff which does just that. + + Tests: svg/W3C-SVG-1.1-SE/types-dom-06-f.svg + svg/dom/SVGStringList.html + + * GNUmakefile.am: Add SVGAnimatedString.h / SVGStringListPropertyTearOff.h to build. + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * bindings/scripts/CodeGenerator.pm: Recognize SVGAnimatedString as new style svg animated type. Map SVGStringList to SVGStringListPropertyTearOff. + * bindings/scripts/CodeGeneratorJS.pm: Handle SVGStringListPropertyTearOff in GetSVGPropertyTypes. + * bindings/scripts/CodeGeneratorObjC.pm: Ditto. + * bindings/scripts/CodeGeneratorV8.pm: Ditto. + * svg/DeprecatedSVGAnimatedPropertyTraits.h: Remove SVGAnimatedString handling. + * svg/DeprecatedSVGAnimatedTemplate.h: Ditto. + * svg/SVGAElement.cpp: Renamed target to svgTarget() to avoid clashes with Element::target(), adjust the bindings to call svgTarget() instead of target(), when processing SVGAElement. + (WebCore::SVGAElement::parseMappedAttribute): + (WebCore::SVGAElement::synchronizeProperty): + * svg/SVGAElement.h: + * svg/SVGAltGlyphElement.h: s/DECLARE_ANIMATED_PROPERTY/DECLARED_ANIMATED_STATIC_PROPERTY_NEW/ + * svg/SVGAnimatedString.h: Added. + * svg/SVGCursorElement.h: Ditto. + * svg/SVGFEBlendElement.h: Ditto. + * svg/SVGFEColorMatrixElement.h: Ditto. + * svg/SVGFEComponentTransferElement.h: Ditto. + * svg/SVGFECompositeElement.h: Ditto. + * svg/SVGFEConvolveMatrixElement.h: Ditto. + * svg/SVGFEDiffuseLightingElement.h: Ditto. + * svg/SVGFEDisplacementMapElement.h: Ditto. + * svg/SVGFEGaussianBlurElement.h: Ditto. + * svg/SVGFEImageElement.h: Ditto. + * svg/SVGFEMergeNodeElement.h: Ditto. + * svg/SVGFEMorphologyElement.h: Ditto. + * svg/SVGFEOffsetElement.h: Ditto. + * svg/SVGFESpecularLightingElement.h: Ditto. + * svg/SVGFETileElement.h: Ditto. + * svg/SVGFilterElement.h: Ditto. + * svg/SVGFilterPrimitiveStandardAttributes.h: Ditto. + * svg/SVGForeignObjectElement.h: Ditto. + * svg/SVGGradientElement.h: Ditto. + * svg/SVGImageElement.h: Ditto. + * svg/SVGLengthList.idl: Remove leftover SVGListProperty marker. + * svg/SVGMPathElement.h: s/DECLARE_ANIMATED_PROPERTY/DECLARED_ANIMATED_STATIC_PROPERTY_NEW/ + * svg/SVGPatternElement.h: Ditto. + * svg/SVGScriptElement.h: Ditto. + * svg/SVGStringList.cpp: Make SVGStringList a plain Vector<String>. + (WebCore::SVGStringList::commitChange): React to SVGStringList changes. + (WebCore::SVGStringList::reset): + (WebCore::SVGStringList::parse): + * svg/SVGStringList.h: + (WebCore::SVGStringList::SVGStringList): + * svg/SVGStyledElement.h: s/DECLARE_ANIMATED_PROPERTY/DECLARED_ANIMATED_STATIC_PROPERTY_NEW/ + * svg/SVGTRefElement.h: Ditto. + * svg/SVGTests.cpp: Adapt to SVGStringList API changes. + (WebCore::SVGTests::SVGTests): + (WebCore::SVGTests::hasExtension): + (WebCore::SVGTests::isValid): + (WebCore::SVGTests::parseMappedAttribute): + (WebCore::SVGTests::isKnownAttribute): + * svg/SVGTests.h: Ditto. + (WebCore::SVGTests::requiredFeatures): + (WebCore::SVGTests::requiredExtensions): + (WebCore::SVGTests::systemLanguage): + * svg/SVGTextPathElement.h: s/DECLARE_ANIMATED_PROPERTY/DECLARED_ANIMATED_STATIC_PROPERTY_NEW/ + * svg/SVGURIReference.h: Adapt to SVGStringList API changes. + (WebCore::SVGURIReference::~SVGURIReference): + * svg/SVGUseElement.h: s/DECLARE_ANIMATED_PROPERTY/DECLARED_ANIMATED_STATIC_PROPERTY_NEW/ + * svg/SVGViewElement.cpp: Adapt to SVGStringList API changes. + (WebCore::SVGViewElement::SVGViewElement): + (WebCore::SVGViewElement::parseMappedAttribute): + * svg/SVGViewElement.h: Ditto. + (WebCore::SVGViewElement::viewTarget): + * svg/properties/SVGAnimatedPropertyMacros.h: Moved GetOwnerElementForType heleprs from SVGAnimatedPropertySynchronizer into this file. + * svg/properties/SVGAnimatedPropertySynchronizer.h: + * svg/properties/SVGPropertyTraits.h: Handle SVGStringList. + * svg/properties/SVGStringListPropertyTearOff.h: Added. This is a simplified version of SVGListPropertyTearOff, tied to SVGStringList and its special demands. + (WebCore::SVGStringListPropertyTearOff::create): + (WebCore::SVGStringListPropertyTearOff::clear): + (WebCore::SVGStringListPropertyTearOff::numberOfItems): + (WebCore::SVGStringListPropertyTearOff::initialize): + (WebCore::SVGStringListPropertyTearOff::getItem): + (WebCore::SVGStringListPropertyTearOff::insertItemBefore): + (WebCore::SVGStringListPropertyTearOff::replaceItem): + (WebCore::SVGStringListPropertyTearOff::removeItem): + (WebCore::SVGStringListPropertyTearOff::appendItem): + (WebCore::SVGStringListPropertyTearOff::SVGStringListPropertyTearOff): + +2010-11-03 Zoltan Herczeg <zherczeg@webkit.org> + + Reviewed by Dirk Schulze. + + SVG FELighting performance issues + https://bugs.webkit.org/show_bug.cgi?id=48212 + + This patch speeds-up FELighting filter painting by 40% + It reduces the number of floating point operations and + empolys faster pixel manipulation (both for read and + write). Furthermore the length() member of FloatPoint3D + is made inline to speed up vector length calculations. + + The lighting filter pixels tests are cover this patch. + + * platform/graphics/FloatPoint3D.cpp: + * platform/graphics/FloatPoint3D.h: + (WebCore::FloatPoint3D::length): + * platform/graphics/filters/FELighting.cpp: + (WebCore::FELighting::LightingData::topLeft): + (WebCore::FELighting::LightingData::topRow): + (WebCore::FELighting::LightingData::topRight): + (WebCore::FELighting::LightingData::leftColumn): + (WebCore::FELighting::LightingData::interior): + (WebCore::FELighting::LightingData::rightColumn): + (WebCore::FELighting::LightingData::bottomLeft): + (WebCore::FELighting::LightingData::bottomRow): + (WebCore::FELighting::LightingData::bottomRight): + (WebCore::FELighting::inlineSetPixel): + (WebCore::FELighting::setPixel): + (WebCore::FELighting::drawLighting): + (WebCore::FELighting::apply): + * platform/graphics/filters/FELighting.h: + * platform/graphics/filters/LightSource.cpp: + (WebCore::PointLightSource::updatePaintingData): + (WebCore::SpotLightSource::updatePaintingData): + (WebCore::DistantLightSource::initPaintingData): + * platform/graphics/filters/LightSource.h: + +2010-11-03 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 2 of 2. + + Fixes an issue where the window.name of an unnamed frame returns + a unique generated name that is used internally to identify the + frame. Instead, we should return an empty string as implied by + section 5.1.6 of the HTML5 spec. (http://www.w3.org/TR/html5/browsers.html#browsing-context-names). + This section describes that a browsing context can have no name or be + the empty string. + + * html/HTMLFrameElementBase.cpp: + (WebCore::HTMLFrameElementBase::openURL): Removed ASSERT for empty + frame name since this is valid as per the HTML5 spec. + (WebCore::HTMLFrameElementBase::setName): Removed the call to FrameTree::uniqueChildName() + since the loader code no longer depends on the frame name being unique. + * page/DOMWindow.cpp: + (WebCore::DOMWindow::name): Modified to call FrameTree::name(). + * page/FrameTree.cpp: + (WebCore::FrameTree::setName): + (WebCore::FrameTree::clearName): + * page/FrameTree.h: + (WebCore::FrameTree::name): Re-added; returns the DOM-specified name of the + frame. Previously, this method returned the internal frame name. + +2010-11-03 takano takumi <takano1@asia.apple.com> + + Reviewed by Dan Bernstein. + + Add text-combine property to our property list. Reflect the setting to a RenderStyle object. + https://bugs.webkit.org/show_bug.cgi?id=48608 + + Test: fast/text/international/text-combine-parser-test.html + + * css/CSSComputedStyleDeclaration.cpp: Added text-combine property support. + (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): + * css/CSSParser.cpp: Added text-combine property support. + (WebCore::CSSParser::parseValue): + * css/CSSPrimitiveValueMappings.h: Added a primitive value mapper for text-combine + (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): + (WebCore::CSSPrimitiveValue::operator TextCombine): + * css/CSSPropertyNames.in: Added "text-combine". + * css/CSSStyleSelector.cpp: Added text-combine property support. + (WebCore::CSSStyleSelector::applyProperty): + * css/CSSValueKeywords.in: Added values for text-combine. + * rendering/style/RenderStyle.cpp: + (WebCore::RenderStyle::diff): Added check of text-combine value. + * rendering/style/RenderStyle.h: Added accessors for text-combine. + (WebCore::InheritedFlags::textCombine): + (WebCore::InheritedFlags::setTextCombine): + (WebCore::InheritedFlags::initialTextCombine): + * rendering/style/RenderStyleConstants.h: + * rendering/style/StyleRareNonInheritedData.cpp: Added text-combine property support. + (WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData): + (WebCore::StyleRareNonInheritedData::operator==): + * rendering/style/StyleRareNonInheritedData.h: Added text-combine entry for RenderStyle object here. + +2010-11-02 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 1 of 2. + + Towards fixing bug #6751, rename FrameTree::name() to FrameTree::uniqueName(), + which is more descriptive of its purpose. A follow up patch will re-add + FrameTree::name() which will return the DOM-specified name of the frame. + + We will also take this opportunity to verify that we have found all the + call sites of FrameTree::name(). + + * loader/DocumentLoader.cpp: + (WebCore::DocumentLoader::mainResource): Use FrameTree::uniqueName(). + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::loadURLIntoChildFrame): Ditto. + (WebCore::FrameLoader::commitProvisionalLoad): Ditto. + * loader/HistoryController.cpp: + (WebCore::HistoryController::saveDocumentState): Ditto. + (WebCore::HistoryController::restoreDocumentState): Ditto. + (WebCore::HistoryController::createItem): Ditto. + (WebCore::HistoryController::currentFramesMatchItem): Ditto. + * loader/ProgressTracker.cpp: + (WebCore::ProgressTracker::progressStarted): Ditto. + (WebCore::ProgressTracker::progressCompleted): Ditto. + * loader/archive/cf/LegacyWebArchive.cpp: + (WebCore::LegacyWebArchive::create): Ditto. + * page/DOMWindow.cpp: + (WebCore::DOMWindow::name): Ditto. + * page/FrameTree.cpp: + (WebCore::FrameTree::setName): Ditto. + (WebCore::FrameTree::clearName): Ditto. + (WebCore::FrameTree::uniqueChildName): Ditto. + (WebCore::FrameTree::child): Ditto. + (WebCore::FrameTree::find): Ditto. + * page/FrameTree.h: + (WebCore::FrameTree::uniqueName): Renamed (formerly FrameTree::name()). + +2010-11-02 Chris Rogers <crogers@google.com> + + Reviewed by James Robinson. + + Add AudioProcessingEvent files + https://bugs.webkit.org/show_bug.cgi?id=48884 + + No new tests since audio API is not yet implemented. + + * webaudio/AudioProcessingEvent.cpp: Added. + (WebCore::AudioProcessingEvent::create): + (WebCore::AudioProcessingEvent::AudioProcessingEvent): + (WebCore::AudioProcessingEvent::~AudioProcessingEvent): + (WebCore::AudioProcessingEvent::isAudioProcessingEvent): + * webaudio/AudioProcessingEvent.h: Added. + (WebCore::AudioProcessingEvent::inputBuffer): + (WebCore::AudioProcessingEvent::outputBuffer): + * webaudio/AudioProcessingEvent.idl: Added. + +2010-11-02 Al Patrick <apatrick@chromium.org> + + Reviewed by Kenneth Russell. + + Added PluginLayerChromium, which composites plugin instances that have an associated OpenGL backing texture. + + https://bugs.webkit.org/show_bug.cgi?id=48032 + + * WebCore.gypi: + * loader/SubframeLoader.cpp + (WebCore::SubframeLoader::loadPlugin): + * platform/graphics/chromium/LayerChromium.cpp: + (WebCore::LayerChromium::setNeedsDisplay): + * platform/graphics/chromium/LayerRendererChromium.cpp: + (WebCore::LayerRendererChromium::initializeSharedObjects): + (WebCore::LayerRendererChromium::cleanupSharedObjects): + * platform/graphics/chromium/LayerRendererChromium.h: + (WebCore::LayerRendererChromium::pluginLayerSharedValues): + * platform/graphics/chromium/PluginLayerChromium.cpp: Added. + (WebCore::PluginLayerChromium::SharedValues::SharedValues): + (WebCore::PluginLayerChromium::SharedValues::~SharedValues): + (WebCore::PluginLayerChromium::create): + (WebCore::PluginLayerChromium::PluginLayerChromium): + (WebCore::PluginLayerChromium::updateContents): + (WebCore::PluginLayerChromium::draw): + * platform/graphics/chromium/PluginLayerChromium.h: Added. + (WebCore::PluginLayerChromium::drawsContent): + (WebCore::PluginLayerChromium::setTextureId): + (WebCore::PluginLayerChromium::SharedValues::shaderProgram): + (WebCore::PluginLayerChromium::SharedValues::shaderSamplerLocation): + (WebCore::PluginLayerChromium::SharedValues::shaderMatrixLocation): + (WebCore::PluginLayerChromium::SharedValues::shaderAlphaLocation): + (WebCore::PluginLayerChromium::SharedValues::initialized): + +2010-11-02 James Simonsen <simonjam@chromium.org> + + Reviewed by Adam Barth. + + mathml in html sometimes incorrectly parsed + https://bugs.webkit.org/show_bug.cgi?id=48105 + + * html/parser/HTMLTreeBuilder.cpp: + (WebCore::HTMLTreeBuilder::processEndTag): Fixed to match HTML5 spec. + +2010-11-02 Chris Guillory <chris.guillory@google.com> + + Reviewed by Dmitry Titov. + + Null check obj in AXObjectCache::postPlatformNotification. + https://bugs.webkit.org/show_bug.cgi?id=48896 + + * accessibility/chromium/AXObjectCacheChromium.cpp: + (WebCore::AXObjectCache::postPlatformNotification): + +2010-11-02 Kavita Kanetkar <kkanetkar@chromium.org> + + Reviewed by Dumitru Daniliuc. + + [FileSystem] Support not creating directories when queried by inspector. + https://bugs.webkit.org/show_bug.cgi?id=48169 + + * fileapi/LocalFileSystem.cpp: + (WebCore::openFileSystem): + (WebCore::LocalFileSystem::readFileSystem): + (WebCore::LocalFileSystem::requestFileSystem): + * fileapi/LocalFileSystem.h: + * platform/AsyncFileSystem.cpp: + (WebCore::AsyncFileSystem::openFileSystem): + * platform/AsyncFileSystem.h: + +2010-11-02 Chris Rogers <crogers@google.com> + + Reviewed by Kenneth Russell. + + Add AudioBufferSourceNode files + https://bugs.webkit.org/show_bug.cgi?id=48012 + + No new tests since audio API is not yet implemented. + + * webaudio/AudioBufferSourceNode.cpp: Added. + (WebCore::AudioBufferSourceNode::create): + (WebCore::AudioBufferSourceNode::AudioBufferSourceNode): + (WebCore::AudioBufferSourceNode::~AudioBufferSourceNode): + (WebCore::AudioBufferSourceNode::process): + (WebCore::AudioBufferSourceNode::provideInput): + (WebCore::AudioBufferSourceNode::readFromBuffer): + (WebCore::AudioBufferSourceNode::readFromBufferWithGrainEnvelope): + (WebCore::AudioBufferSourceNode::reset): + (WebCore::AudioBufferSourceNode::setBuffer): + (WebCore::AudioBufferSourceNode::numberOfChannels): + (WebCore::AudioBufferSourceNode::noteOn): + (WebCore::AudioBufferSourceNode::noteGrainOn): + (WebCore::AudioBufferSourceNode::noteOff): + (WebCore::AudioBufferSourceNode::totalPitchRate): + * webaudio/AudioBufferSourceNode.h: Added. + (WebCore::AudioBufferSourceNode::buffer): + (WebCore::AudioBufferSourceNode::looping): + (WebCore::AudioBufferSourceNode::setLooping): + (WebCore::AudioBufferSourceNode::gain): + (WebCore::AudioBufferSourceNode::playbackRate): + (WebCore::AudioBufferSourceNode::setPannerNode): + * webaudio/AudioBufferSourceNode.idl: Added. + +2010-11-02 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Adam Barth. + + [Cairo] Remove PlatformRefPtrCairo + https://bugs.webkit.org/show_bug.cgi?id=48192 + + Replace PlatformRefPtrCairo with a RefPtr specialization for Cairo and + Fontconfig types. This is the first step toward removing PlatformRefPtr, + whose job is better handled by RefPtr. + + * CMakeListsEfl.txt: Update the sources list to include RefPtrCairo + instead of PlatformRefPtrCairo. + * GNUmakefile.am: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * platform/graphics/GraphicsContext.h: Replace PlatformRefPtrCairo with + RefPtrCairo. + * platform/graphics/cairo/CairoUtilities.cpp: Ditto. + (WebCore::drawPatternToCairoContext): Ditto. + * platform/graphics/cairo/FontCacheFreeType.cpp: Ditto. + (WebCore::FontCache::getFontDataForCharacters): Ditto. + (WebCore::FontCache::createFontPlatformData): Ditto. + * platform/graphics/cairo/FontPlatformDataFreeType.cpp: Ditto. + (WebCore::FontPlatformData::FontPlatformData): Ditto. + (WebCore::FontPlatformData::initializeWithFontFace): Ditto. + * platform/graphics/cairo/FontPlatformDataFreeType.h: Ditto. + * platform/graphics/cairo/GraphicsContextCairo.cpp: Ditto. + * platform/graphics/cairo/ImageCairo.cpp: Ditto. + * platform/graphics/cairo/RefPtrCairo.cpp: Renamed from WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp. + (WTF::refIfNotNull): Added. + (WTF::derefIfNotNull): Added. + * platform/graphics/cairo/RefPtrCairo.h: Renamed from WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h. + * platform/gtk/CursorGtk.cpp: Replace PlatformRefPtrCairo with + RefPtrCairo. + (WebCore::createNamedCursor): Ditto. + * platform/gtk/DragImageGtk.cpp: Ditto. + (WebCore::scaleDragImage): Ditto. + (WebCore::dissolveDragImageToFraction): Ditto. + * plugins/gtk/PluginViewGtk.cpp: Ditto. + (WebCore::PluginView::paint): Ditto. + +2010-11-02 Chris Rogers <crogers@google.com> + + Reviewed by Kenneth Russell. + + Simple followup changes to files affected by AudioNodeInput thread safety + https://bugs.webkit.org/show_bug.cgi?id=48661 + + No new tests since audio API is not yet implemented. + + * webaudio/AudioBasicProcessorNode.cpp: + (WebCore::AudioBasicProcessorNode::checkNumberOfChannelsForInput): + * webaudio/AudioChannelSplitter.cpp: + (WebCore::AudioChannelSplitter::process): + * webaudio/AudioDestinationNode.cpp: + (WebCore::AudioDestinationNode::initialize): + (WebCore::AudioDestinationNode::uninitialize): + (WebCore::AudioDestinationNode::provideInput): + * webaudio/AudioGainNode.cpp: + (WebCore::AudioGainNode::checkNumberOfChannelsForInput): + * webaudio/AudioPannerNode.cpp: + (WebCore::AudioPannerNode::notifyAudioSourcesConnectedToNode): + +2010-11-02 Chris Guillory <chris.guillory@google.com> + + Reviewed by Chris Fleizach. + + Chromium: Propagate a document value changed notification on scroll. + https://bugs.webkit.org/show_bug.cgi?id=48817 + + * accessibility/AccessibilityObject.h: + (WebCore::AccessibilityObject::isAccessibilityScrollbar): + * accessibility/AccessibilityScrollbar.h: + (WebCore::AccessibilityScrollbar::scrollbar): + (WebCore::AccessibilityScrollbar::isAccessibilityScrollbar): + * accessibility/chromium/AXObjectCacheChromium.cpp: + (WebCore::AXObjectCache::postPlatformNotification): + +2010-11-02 Chris Rogers <crogers@google.com> + + Reviewed by Kenneth Russell. + + Add ConvolverNode files + https://bugs.webkit.org/show_bug.cgi?id=47941 + + No new tests since audio API is not yet implemented. + + * webaudio/ConvolverNode.cpp: Added. + (WebCore::ConvolverNode::ConvolverNode): + (WebCore::ConvolverNode::~ConvolverNode): + (WebCore::ConvolverNode::process): + (WebCore::ConvolverNode::reset): + (WebCore::ConvolverNode::initialize): + (WebCore::ConvolverNode::uninitialize): + (WebCore::ConvolverNode::setBuffer): + (WebCore::ConvolverNode::buffer): + * webaudio/ConvolverNode.h: Added. + (WebCore::ConvolverNode::create): + * webaudio/ConvolverNode.idl: Added. + +2010-11-02 Chris Rogers <crogers@google.com> + + Reviewed by Kenneth Russell. + + Add RealtimeAnalyser files + https://bugs.webkit.org/show_bug.cgi?id=48810 + + No new tests since audio API is not yet implemented. + + * webaudio/RealtimeAnalyser.cpp: Added. + (WebCore::RealtimeAnalyser::RealtimeAnalyser): + (WebCore::RealtimeAnalyser::~RealtimeAnalyser): + (WebCore::RealtimeAnalyser::reset): + (WebCore::RealtimeAnalyser::setFftSize): + (WebCore::RealtimeAnalyser::writeInput): + (WebCore::RealtimeAnalyser::doFFTAnalysis): + (WebCore::RealtimeAnalyser::getFloatFrequencyData): + (WebCore::RealtimeAnalyser::getByteFrequencyData): + (WebCore::RealtimeAnalyser::getByteTimeDomainData): + * webaudio/RealtimeAnalyser.h: Added. + (WebCore::RealtimeAnalyser::fftSize): + (WebCore::RealtimeAnalyser::frequencyBinCount): + (WebCore::RealtimeAnalyser::setMinDecibels): + (WebCore::RealtimeAnalyser::minDecibels): + (WebCore::RealtimeAnalyser::setMaxDecibels): + (WebCore::RealtimeAnalyser::maxDecibels): + (WebCore::RealtimeAnalyser::setSmoothingTimeConstant): + (WebCore::RealtimeAnalyser::smoothingTimeConstant): + (WebCore::RealtimeAnalyser::magnitudeBuffer): + +2010-11-02 Ilya Sherman <isherman@chromium.org> + + Reviewed by Kent Tamura. + + Avoid overlapping label text in autofill popup with icon. + Updates the menu width computation to take the icon width into account. + https://bugs.webkit.org/show_bug.cgi?id=48497 + + * platform/chromium/PopupMenuChromium.cpp: + (WebCore::PopupListBox::paintRow): + (WebCore::PopupListBox::layout): + +2010-10-28 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + Perform framebuffer attachment checking upon draw call rather than attachment + https://bugs.webkit.org/show_bug.cgi?id=46318 + + * html/canvas/WebGLFramebuffer.cpp: + (WebCore::getInternalFormat): Helper function to get an attachment's internal format. + (WebCore::isUninitialized): Helper function to decide if an attachment is initialized or not. + (WebCore::setInitialized): Helper funtion to set an attachment as being initialized. + (WebCore::WebGLFramebuffer::setAttachment): No longer perform buffer initialization at this point. + (WebCore::WebGLFramebuffer::removeAttachment): Ditto. + (WebCore::WebGLFramebuffer::getColorBufferFormat): Make it const. + (WebCore::WebGLFramebuffer::isIncomplete): Attachments conflict check. + (WebCore::WebGLFramebuffer::onAccess): Check atatchment conflicts and buffer initialization if necessary. + (WebCore::WebGLFramebuffer::initializeRenderbuffers): Return a boolean whether the framebuffer is complete or not. + * html/canvas/WebGLFramebuffer.h: Add new function declaration and remove some outdated functions. + (WebCore::WebGLFramebuffer::isColorAttached): + (WebCore::WebGLFramebuffer::isDepthAttached): Make this private. + (WebCore::WebGLFramebuffer::isStencilAttached): Ditto. + (WebCore::WebGLFramebuffer::isDepthStencilAttached): Ditto. + * html/canvas/WebGLRenderbuffer.h: + (WebCore::WebGLRenderbuffer::setInternalFormat): Also set the renderbuffer as uninitialized. + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::bindFramebuffer): No longer perform framebuffer initialization at this point. + (WebCore::WebGLRenderingContext::checkFramebufferStatus): Check WebGL specific attachment conflicts. + (WebCore::WebGLRenderingContext::clear): Call WebGLFramebuffer::onAccess. + (WebCore::WebGLRenderingContext::copyTexImage2D): Ditto. + (WebCore::WebGLRenderingContext::copyTexSubImage2D): Ditto. + (WebCore::WebGLRenderingContext::drawArrays): Ditto. + (WebCore::WebGLRenderingContext::drawElements): Ditto. + (WebCore::WebGLRenderingContext::framebufferRenderbuffer): No longer perform framebuffer initialization at this point. + (WebCore::WebGLRenderingContext::readPixels): Call WebGLFramebuffer::onAccess. + (WebCore::WebGLRenderingContext::renderbufferStorage): No longer perform framebuffer initialization at this point. + (WebCore::WebGLRenderingContext::texImage2DBase): Ditto. + +2010-11-01 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + blendFunc should generate INVALID_OPERATION if constant color and constant alpha are together as source and destination factors + https://bugs.webkit.org/show_bug.cgi?id=48674 + + Test: fast/canvas/webgl/webgl-specific.html + + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::blendFunc): + (WebCore::WebGLRenderingContext::blendFuncSeparate): + * html/canvas/WebGLRenderingContext.h: + (WebCore::WebGLRenderingContext::validateBlendFuncFactors): Helper function to do the checking. + +2010-11-02 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dan Bernstein. + + Overlapped nested iframes show smearing when scrolled + https://bugs.webkit.org/show_bug.cgi?id=48873 + + A FrameView goes into slow scrolling mode (not blitting) when told that it is + overlapped. However, a nested iframe could still try to use fast scrolling + when its parent is overlapped, which could result in bad rendering. + + Fixed by making useSlowRepaints() and useSlowRepaintsIfNotOverlapped() + walk up their parent chain, asking if their parents also use slow + repaints. + + All the places that call setCanBlitOnScroll() now call + updateCanBlitOnScrollRecursively() to ensure that the canBlitOnScroll + flag is updated correctly on subframes. + + Repaint tests do not work on nested iframes, so added manual test. + + * manual-tests/frames/nested-iframe-blit-on-scroll.html: Added. + * manual-tests/frames/resources/blit-on-scroll-subframe.html: Added. + * manual-tests/frames/resources/blit-on-scroll-subsubframe.html: Added. + * page/FrameView.cpp: + (WebCore::FrameView::layout): + (WebCore::FrameView::useSlowRepaints): + (WebCore::FrameView::useSlowRepaintsIfNotOverlapped): + (WebCore::FrameView::updateCanBlitOnScrollRecursively): + (WebCore::FrameView::setUseSlowRepaints): + (WebCore::FrameView::addSlowRepaintObject): + (WebCore::FrameView::removeSlowRepaintObject): + (WebCore::FrameView::addFixedObject): + (WebCore::FrameView::removeFixedObject): + (WebCore::FrameView::setIsOverlapped): + (WebCore::FrameView::setContentIsOpaque): + * page/FrameView.h: + +2010-11-02 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dan Bernstein. + + Iframes nested inside a compositing layer don't repaint correctly + https://bugs.webkit.org/show_bug.cgi?id=48880 + <rdar://problem/8194698> + + The isEnclosedInCompositingLayer() is used to modify the behavior of + -[WebClipView visibleRect:] in WebKit, so that scrolling-related repaints + are correct in composited iframes. Previously it only asked whether the + frame's renderer was in a compositing layer, but we actually need to + consult all ancestors. + + Test: compositing/iframes/nested-iframe-scrolling.html + + * page/FrameView.cpp: + (WebCore::FrameView::isEnclosedInCompositingLayer): + +2010-11-02 David Hyatt <hyatt@apple.com> + + Reviewed by Dan Bernstein. + + https://bugs.webkit.org/show_bug.cgi?id=48672 + + Make vertical glyph offset hit testing work with inline boxes. This allows selection to paint + properly for vertical text (although gap-filling is still broken). + + Refactored and cleaned up the writing mode flipping functions, and also did some cleanup to + better share code between hit testing and painting. + + * rendering/InlineBox.cpp: + (WebCore::InlineBox::locationIncludingFlipping): + (WebCore::InlineBox::flipForWritingMode): + * rendering/InlineBox.h: + * rendering/InlineFlowBox.cpp: + (WebCore::InlineFlowBox::nodeAtPoint): + (WebCore::InlineFlowBox::paint): + (WebCore::InlineFlowBox::paintBoxDecorations): + (WebCore::InlineFlowBox::paintMask): + * rendering/InlineTextBox.cpp: + (WebCore::InlineTextBox::selectionRect): + (WebCore::InlineTextBox::nodeAtPoint): + (WebCore::InlineTextBox::paint): + (WebCore::InlineTextBox::textPos): + (WebCore::InlineTextBox::offsetForPosition): + (WebCore::InlineTextBox::positionForOffset): + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::paintChildren): + (WebCore::RenderBlock::paintFloats): + (WebCore::RenderBlock::hitTestFloats): + (WebCore::RenderBlock::hitTestContents): + * rendering/RenderBox.cpp: + (WebCore::RenderBox::computeRectForRepaint): + (WebCore::RenderBox::flipForWritingMode): + (WebCore::RenderBox::locationOffsetIncludingFlipping): + * rendering/RenderBox.h: + * rendering/RenderInline.cpp: + (WebCore::RenderInline::clippedOverflowRectForRepaint): + * rendering/RenderLineBoxList.cpp: + (WebCore::RenderLineBoxList::rangeIntersectsRect): + (WebCore::RenderLineBoxList::anyLineIntersectsRect): + (WebCore::RenderLineBoxList::lineIntersectsDirtyRect): + (WebCore::RenderLineBoxList::paint): + (WebCore::RenderLineBoxList::hitTest): + * rendering/RenderLineBoxList.h: + * rendering/RenderText.cpp: + (WebCore::RenderText::positionForPoint): + +2010-11-02 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + JPEG decoders should understand color profiles + https://bugs.webkit.org/show_bug.cgi?id=48819 + + This patch is currently a no-op because no one defines USE(ICCJPEG). + We'll enable this for Chromium Mac once we have ICCJPEG landed in + Chromium's third_party directory. + + * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: + (WebCore::readColorProfile): + (WebCore::JPEGImageReader::JPEGImageReader): + (WebCore::JPEGImageReader::decode): + (WebCore::JPEGImageDecoder::outputScanlines): + * platform/image-decoders/jpeg/JPEGImageDecoder.h: + (WebCore::JPEGImageDecoder::setColorProfile): + +2010-11-02 Mihai Parparita <mihaip@chromium.org> + + Reviewed by Adam Barth. + + [Chromium] Crash when encountering history.back() call during Page::goToItem execution + https://bugs.webkit.org/show_bug.cgi?id=48477 + + For the Chromium port, BackForwardList::itemAtIndex synthesizes a + HistoryItem and saves a pointer to it in m_pendingItem. During + Page::goToItem we call FrameLoader::stopAllLoaders, which can trigger + onload handlers (if a subframe was not considered committed by the frame + loader). If one of those handlers calls calls history.back() or another + operation that ends up in NavigationScheduler::scheduleHistoryNavigation, + we would call BackForwardList::itemAtIndex, which means that we would + lose the m_pendingItem RefPtr that pointed to the item being navigated + to, causing its ref count to go to 0*, and thus for the HistoryItem to + be deleted before we were done navigating to it. + + This is fixed in two ways: + - Add a protector RefPtr in Page::goToItem to make sure that the item is + still around for when we pass it to HistoryController:goToItem. + - Change NavigationScheduler::scheduleHistoryNavigation to not use + BackForwardList::itemAtIndex and instead look at the + forward/backListCount() (since it doesn't actually care about the + returned HistoryItem). + + * Full annotated stack trace of this is at http://crbug.com/59554#c9. + + Test: http/tests/history/back-during-onload-triggered-by-back.html + + * loader/NavigationScheduler.cpp: + (WebCore::NavigationScheduler::scheduleHistoryNavigation): + * page/Page.cpp: + (WebCore::Page::goToItem): + +2010-10-28 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + Update getUniform for bvec[234] to return boolean[] rather than Uint8Array + https://bugs.webkit.org/show_bug.cgi?id=47568 + + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::getUniform): + +2010-11-02 Chris Rogers <crogers@google.com> + + Reviewed by Kenneth Russell. + + Add RealtimeAnalyserNode files + https://bugs.webkit.org/show_bug.cgi?id=48798 + + No new tests since audio API is not yet implemented. + + * webaudio/RealtimeAnalyserNode.cpp: Added. + (WebCore::RealtimeAnalyserNode::RealtimeAnalyserNode): + (WebCore::RealtimeAnalyserNode::~RealtimeAnalyserNode): + (WebCore::RealtimeAnalyserNode::process): + (WebCore::RealtimeAnalyserNode::pullInputs): + (WebCore::RealtimeAnalyserNode::reset): + * webaudio/RealtimeAnalyserNode.h: Added. + (WebCore::RealtimeAnalyserNode::create): + (WebCore::RealtimeAnalyserNode::fftSize): + (WebCore::RealtimeAnalyserNode::setFftSize): + (WebCore::RealtimeAnalyserNode::frequencyBinCount): + (WebCore::RealtimeAnalyserNode::setMinDecibels): + (WebCore::RealtimeAnalyserNode::minDecibels): + (WebCore::RealtimeAnalyserNode::setMaxDecibels): + (WebCore::RealtimeAnalyserNode::maxDecibels): + (WebCore::RealtimeAnalyserNode::setSmoothingTimeConstant): + (WebCore::RealtimeAnalyserNode::smoothingTimeConstant): + (WebCore::RealtimeAnalyserNode::getFloatFrequencyData): + (WebCore::RealtimeAnalyserNode::getByteFrequencyData): + (WebCore::RealtimeAnalyserNode::getByteTimeDomainData): + * webaudio/RealtimeAnalyserNode.idl: Added. + +2010-11-02 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r71152. + http://trac.webkit.org/changeset/71152 + https://bugs.webkit.org/show_bug.cgi?id=48866 + + Causes lots and lots of crashes (Requested by jamesr_ on + #webkit). + + * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: + (WebCore::JPEGImageReader::JPEGImageReader): + (WebCore::JPEGImageReader::decode): + (WebCore::JPEGImageDecoder::outputScanlines): + * platform/image-decoders/jpeg/JPEGImageDecoder.h: + +2010-11-02 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Timothy Hatcher. + + https://bugs.webkit.org/show_bug.cgi?id=48813 + <rdar://problem/8602552> REGRESSION (r63622): DNS prefetching for <link> tags doesn't work + in non-HTTP documents + + Cannot test DNS prefetching. + + * html/HTMLLinkElement.cpp: (WebCore::HTMLLinkElement::process): We should be looking at + preferences, not at whether this document has prefetching enabled. + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Not reviewed: Web Inspector: follow up to r71139. Fixed Mac monospace + height style. + + * inspector/front-end/PropertiesSection.js: + (WebInspector.PropertiesSection): + * inspector/front-end/inspector.css: + +2010-11-02 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + JPEG decoders should understand color profiles + https://bugs.webkit.org/show_bug.cgi?id=48819 + + This patch is currently a no-op because no one defines USE(ICCJPEG). + We'll enable this for Chromium Mac once we have ICCJPEG landed in + Chromium's third_party directory. + + * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: + (WebCore::readColorProfile): + (WebCore::JPEGImageReader::JPEGImageReader): + (WebCore::JPEGImageReader::decode): + (WebCore::JPEGImageDecoder::outputScanlines): + * platform/image-decoders/jpeg/JPEGImageDecoder.h: + (WebCore::JPEGImageDecoder::setColorProfile): + +2010-11-02 Ilya Sherman <isherman@chromium.org> + + Reviewed by Simon Fraser. + + Marks selectionStart() and selectionEnd() as const. + https://bugs.webkit.org/show_bug.cgi?id=48786 + + * html/HTMLFormControlElement.cpp: + (WebCore::HTMLTextFormControlElement::selectionStart): + (WebCore::HTMLTextFormControlElement::selectionEnd): + * html/HTMLFormControlElement.h: + +2010-11-02 Chris Rogers <crogers@google.com> + + Reviewed by Kenneth Russell. + + Fix license for audio files + https://bugs.webkit.org/show_bug.cgi?id=48859 + + * webaudio/AudioChannelSplitter.cpp: + * webaudio/AudioChannelSplitter.h: + * webaudio/AudioDestinationNode.cpp: + * webaudio/AudioDestinationNode.h: + * webaudio/AudioGainNode.cpp: + * webaudio/AudioGainNode.h: + * webaudio/AudioPannerNode.cpp: + * webaudio/AudioPannerNode.h: + * webaudio/AudioPannerNode.idl: + +2010-11-02 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + Remove special handling of HashTableDeletedValue in PlatformRefPtr and manually manage memory that cannot be controlled by HashTraits + https://bugs.webkit.org/show_bug.cgi?id=48841 + + Switch to manually managing the memory in FontPlatformDataFreeType. This + is necessary because smart pointers do not know how to deal with a pointer + value of -1 (HashTableDeletedValue) and HashTraits can only manage the type + contained in the HashMap. + + No new tests as this should not change functionality. + + * platform/graphics/cairo/FontPlatformDataFreeType.cpp: + (WebCore::FontPlatformData::FontPlatformData): + (WebCore::FontPlatformData::operator=): + (WebCore::FontPlatformData::~FontPlatformData): + (WebCore::FontPlatformData::operator==): + (WebCore::FontPlatformData::initializeWithFontFace): + * platform/graphics/cairo/FontPlatformDataFreeType.h: + (WebCore::FontPlatformData::FontPlatformData): + (WebCore::FontPlatformData::scaledFont): + (WebCore::FontPlatformData::hash): + (WebCore::FontPlatformData::isHashTableDeletedValue): + (WebCore::FontPlatformData::hashTableDeletedFontValue): + * platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp: + (WebCore::GlyphPage::fill): + * platform/graphics/cairo/SimpleFontDataCairo.cpp: + (WebCore::SimpleFontData::platformInit): + (WebCore::SimpleFontData::containsCharacters): + (WebCore::SimpleFontData::platformWidthForGlyph): + +2010-11-02 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + querySelectorAll('body>:last-child') does not work unless HTML file ends with 'new-line'. + https://bugs.webkit.org/show_bug.cgi?id=47166 + + We need to pop all the open elements when we end the document in the + AfterAfterBody state. + + Test: fast/parser/pop-all-after-after-body.html + + * html/parser/HTMLTreeBuilder.cpp: + (WebCore::HTMLTreeBuilder::processEndOfFile): + +2010-11-02 Patrick Gansterer <paroga@webkit.org> + + Reviewed by Adam Roben. + + Cleanup createGlobalImageFileDescriptor in ClipboardWin + https://bugs.webkit.org/show_bug.cgi?id=48189 + + * platform/win/ClipboardWin.cpp: + (WebCore::ClipboardWin::writeURL): + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: display frame names in the resources panel. + https://bugs.webkit.org/show_bug.cgi?id=48839 + + * inspector/Inspector.idl: + * inspector/InspectorResourceAgent.cpp: + (WebCore::frameId): + (WebCore::buildObjectForDocumentLoader): + (WebCore::buildObjectForFrame): + (WebCore::buildObjectForFrameTree): + (WebCore::InspectorResourceAgent::didCommitLoad): + (WebCore::InspectorResourceAgent::frameDetachedFromParent): + (WebCore::InspectorResourceAgent::frameForId): + (WebCore::InspectorResourceAgent::resourceContent): + * inspector/InspectorResourceAgent.h: + * inspector/front-end/ResourceManager.js: + (WebInspector.ResourceManager.prototype.didCommitLoadForFrame): + (WebInspector.ResourceManager.prototype._processCachedResources): + (WebInspector.ResourceManager.prototype._addFramesRecursively): + (WebInspector.ResourceTreeModel.prototype.addOrUpdateFrame): + (WebInspector.ResourceTreeModel.prototype.didCommitLoadForFrame): + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel.prototype.addOrUpdateFrame): + (WebInspector.BaseStorageTreeElement.prototype.get titleText): + (WebInspector.FrameTreeElement): + (WebInspector.FrameTreeElement.prototype.onattach): + (WebInspector.FrameTreeElement.prototype.get nameForSorting): + (WebInspector.FrameTreeElement.prototype.setTitles): + (WebInspector.FrameTreeElement.prototype.set hovered): + * inspector/front-end/inspector.css: + (li.selected .base-storage-tree-element-subtitle): + (.base-storage-tree-element-subtitle): + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Not reviewed. Follow up to r71139: removing unused images. + https://bugs.webkit.org/show_bug.cgi?id=48827 + + * WebCore.gypi: + * inspector/front-end/Images/grayConnectorPoint.png: Removed. + * inspector/front-end/Images/whiteConnectorPoint.png: Removed. + * inspector/front-end/WebKit.qrc: + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: make properties and event listeners look consistent with the styles section. + https://bugs.webkit.org/show_bug.cgi?id=48827 + + * inspector/front-end/EventListenersSidebarPane.js: + * inspector/front-end/PropertiesSection.js: + (WebInspector.PropertiesSection): + * inspector/front-end/PropertiesSidebarPane.js: + (WebInspector.PropertiesSidebarPane.prototype.update.callback): + (WebInspector.PropertiesSidebarPane.prototype.update): + * inspector/front-end/inspector.css: + (.events-pane .section:not(:nth-of-type(1))): + (.event-bar:first-child): + (.section .header): + (.section .header::before): + (.section.expanded .header::before): + (.section .header .title, .event-bar .header .title): + (.section .header .subtitle, .event-bar .header .subtitle): + (.section.expanded .properties, .event-bar.expanded .event-properties): + (.properties-tree): + (.event-bar): + (.event-bars .event-bar .header): + (.event-bars .event-bar .header .title): + (.event-bars .event-bar .header::before): + +2010-11-02 Dan Bernstein <mitz@apple.com> + + Reviewed by Anders Carlsson. + + Remove unused methods and member variables from AutoTableLayout. + + * rendering/AutoTableLayout.cpp: + (WebCore::AutoTableLayout::AutoTableLayout): Removed initialization of m_percentagesDirty + and m_totalPercent. + (WebCore::AutoTableLayout::fullRecalc): Removed setting of m_percentagesDirty. + (WebCore::AutoTableLayout::calcPercentages): Removed. + * rendering/AutoTableLayout.h: Removed totalPercent(), m_percentagesDirty, and m_totalPercent. + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: clear / hide timing information for cached resources. + https://bugs.webkit.org/show_bug.cgi?id=48848 + + * inspector/front-end/Resource.js: + (WebInspector.Resource.prototype.set cached): + (WebInspector.Resource.prototype.get timing): + (WebInspector.Resource.prototype.set timing): + * inspector/front-end/ResourceManager.js: + (WebInspector.ResourceManager.prototype.markResourceAsCached): + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: improve network's 'preview close' usability. + https://bugs.webkit.org/show_bug.cgi?id=48846 + + * inspector/front-end/networkPanel.css: + (#network-close-button:hover): + (#network-close-button:active): + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: Image heights are displayed as 0. + https://bugs.webkit.org/show_bug.cgi?id=40817 + + * inspector/front-end/ImageView.js: + (WebInspector.ImageView.prototype.contentTabSelected): + (WebInspector.ImageView.prototype.contentTabSelected.onImageLoad): + + 2010-10-31 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Texmap] [Qt] Texture mapper initial implementation + https://bugs.webkit.org/show_bug.cgi?id=47070 + + Some refactor for texmap to enable WebKit2: remove globals, and allow TextureMapper to exist without a GraphicsContext. + This will allow rendering the TextureMapperNode tree without an active QPainter, into the current GL context. + Most of the changes simply move the globas in TextureMapperGL into members of that class. + + No new tests. Old tests in LayoutTests/compositing cover this. + + * platform/graphics/opengl/TextureMapperGL.cpp: + (WebCore::TextureMapperGLData::ShaderInfo::getUniformLocation): + (WebCore::TextureMapperGLData::ShaderInfo::createShaderProgram): + (WebCore::TextureMapperGLData::DirectlyCompositedImageRepository::findOrCreate): + (WebCore::TextureMapperGLData::DirectlyCompositedImageRepository::deref): + (WebCore::TextureMapperGLData::DirectlyCompositedImageRepository::DirectlyCompositedImageRepository): + (WebCore::TextureMapperGLData::DirectlyCompositedImageRepository::~DirectlyCompositedImageRepository): + (WebCore::TextureMapperGLData::TextureMapperGLData): + (WebCore::TextureMapperGL::TextureMapperGL): + (WebCore::TextureMapperGL::drawTexture): + (WebCore::BitmapTextureGL::setContentsToImage): + (WebCore::BitmapTextureGL::destroy): + (WebCore::TextureMapperGL::~TextureMapperGL): + (WebCore::TextureMapperGL::makeContextCurrent): + (WebCore::TextureMapperGL::obtainCurrentContext): + (WebCore::TextureMapperGL::bindSurface): + (WebCore::TextureMapperGL::paintToTarget): + (WebCore::TextureMapperGL::createTexture): + * platform/graphics/opengl/TextureMapperGL.h: + (WebCore::TextureMapperGL::data): + * platform/graphics/qt/TextureMapperQt.cpp: + (WebCore::TextureMapperQt::TextureMapperQt): + (WebCore::TextureMapperQt::setGraphicsContext): + (WebCore::TextureMapper::create): + * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp: + (WebCore::TextureMapperNode::paint): + (WebCore::TextureMapperNode::uploadTextureFromContent): + * platform/graphics/texmap/TextureMapper.h: + (WebCore::TextureMapper::setGraphicsContext): + (WebCore::TextureMapper::setImageInterpolationQuality): + (WebCore::TextureMapper::setTextDrawingMode): + (WebCore::TextureMapper::imageInterpolationQuality): + (WebCore::TextureMapper::textDrawingMode): + (WebCore::TextureMapper::TextureMapper): + * platform/graphics/texmap/TextureMapperPlatformLayer.h: + (WebCore::TextureMapperContentLayer::paint): + + 2010-11-02 Adele Peterson <adele@apple.com> + + Reviewed by Kent Tamura. + + Fix for https://bugs.webkit.org/show_bug.cgi?id=48814 + <rdar://problem/8546143> Attempting to redo typing in apple.com/startpage search field causes infinite recursion in TextControlInnerTextElement::defaultEventHandler + + Test: editing/undo/redo-after-detach.html + + * rendering/TextControlInnerElements.cpp: (WebCore::TextControlInnerTextElement::defaultEventHandler): + A TextControlInnerTextElement will almost always have a shadowAncestorNode, the HTMLInputElement. In this case, + after the renderer was destroyed, this shadow node was kept alive by the EditCommand, even though its not hooked up + anymore to the shadow DOM. EditCommands can sometimes operate on stale selections and are expected to fail silently. + So here we prevent the infinite loop during event dispatch, and the rest of the redo operation will fail silently. + +2010-11-02 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + When animations are paused, play-state can cause them to be unpaused. + https://bugs.webkit.org/show_bug.cgi?id=46525 + + I Changed updatePlayState() to only unpause when both play-state is + "running" and not suspended. Likewise I pause animation when either + play-state is "paused" or suspended. + + Test: animations/play-state-suspend.html + + * page/animation/AnimationBase.cpp: + (WebCore::AnimationBase::updatePlayState): + +2010-11-02 Chris Marrin <cmarrin@apple.com> + + Reviewed by Adam Roben. + + Make RenderStyle::playState() return typed value and cleanup naming in Animation code + https://bugs.webkit.org/show_bug.cgi?id=48844 + + playState() function was returning unsigned value, but there is a EAnimPlayState + enum type which has the legal playState values. This type is now used everywhere. + I also changed the naming of the m_isSuspended to m_suspended to match the style + elsewhere in the code. + + * page/animation/AnimationBase.cpp: + (WebCore::AnimationBase::updatePlayState): + * page/animation/AnimationBase.h: + * page/animation/AnimationController.cpp: + (WebCore::AnimationControllerPrivate::clear): + (WebCore::AnimationControllerPrivate::updateAnimationTimer): + * page/animation/CompositeAnimation.cpp: + (WebCore::CompositeAnimation::updateKeyframeAnimations): + (WebCore::CompositeAnimation::suspendAnimations): + (WebCore::CompositeAnimation::resumeAnimations): + * page/animation/CompositeAnimation.h: + (WebCore::CompositeAnimation::suspended): + (WebCore::CompositeAnimation::CompositeAnimation): + * platform/animation/Animation.h: + (WebCore::Animation::playState): + (WebCore::Animation::setPlayState): + (WebCore::Animation::initialAnimationPlayState): + +2010-11-01 Zhenyao Mo <zmo@google.com> + + Reviewed by Andreas Kling. + + vertexAttribPointer should generate INVALID_VALUE if the stride exceeds 255 + https://bugs.webkit.org/show_bug.cgi?id=48677 + + Test: fast/canvas/webgl/gl-vertexattribpointer.html + + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::vertexAttribPointer): Generate INVALID_VALUE if stride > 255. + +2010-11-01 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [Soup] Random crashes in http/tests/websocket/tests/workers/worker-handshake-challenge-randomness.html + https://bugs.webkit.org/show_bug.cgi?id=48805 + + Track active WebSocket handles via a sequential id. This ensures + that when a handle is reallocated into a recently used segment of + memory, it doesn't trigger a false positive in the code which ensures + the original handle is active. + + No new tests. This test should stop crashing on the bots, proving the fix. + + * platform/network/soup/SocketStreamHandle.h: + (WebCore::SocketStreamHandle::id): Added an m_id member and accessor + to SocketStreamHandle. + * platform/network/soup/SocketStreamHandleSoup.cpp: + (WebCore::getHandleFromId): Updated to work with HashMap of handle ids to + SocketStreamHandle*. + (WebCore::deactivateHandle): Ditto. + (WebCore::activateHandle): Ditto. + (WebCore::SocketStreamHandle::SocketStreamHandle): Ditto. + (WebCore::SocketStreamHandle::connected): Ditto. + (WebCore::SocketStreamHandle::readBytes): Ditto. + (WebCore::SocketStreamHandle::beginWaitingForSocketWritability): Ditto. + (WebCore::connectedCallback): Ditto. + (WebCore::readReadyCallback): Ditto. + (WebCore::writeReadyCallback): Ditto. + +2010-11-02 Csaba Osztrogonác <ossy@webkit.org> + + Unreviewed trivial fix. + + * WebCore.pro: Remove inspector/InspectorResource.h after r71035. + +2010-11-02 Pavel Podivilov <podivilov@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: make xhr breakpoints editable + https://bugs.webkit.org/show_bug.cgi?id=48830 + + * inspector/front-end/BreakpointManager.js: + (WebInspector.Breakpoint.prototype.set sourceText): + (WebInspector.Breakpoint.prototype.click): + (WebInspector.Breakpoint.prototype.populateLabelElement): + (WebInspector.XHRBreakpoint.prototype.populateEditElement): + * inspector/front-end/BreakpointsSidebarPane.js: + (WebInspector.BreakpointsSidebarPane.prototype.addBreakpointItem): + (WebInspector.BreakpointsSidebarPane.prototype._breakpointItemClicked): + (WebInspector.BreakpointsSidebarPane.prototype._contextMenuEventFired): + (WebInspector.BreakpointsSidebarPane.prototype._addListElement): + (WebInspector.BreakpointsSidebarPane.prototype._removeListElement): + (WebInspector.XHRBreakpointsSidebarPane.addButtonClicked): + (WebInspector.XHRBreakpointsSidebarPane): + (WebInspector.XHRBreakpointsSidebarPane.prototype._startEditingBreakpoint): + (WebInspector.XHRBreakpointsSidebarPane.prototype._hideEditBreakpointDialog): + (WebInspector.XHRBreakpointsSidebarPane.prototype._breakpointItemClicked): + (WebInspector.BreakpointItem): + (WebInspector.BreakpointItem.prototype.get element): + (WebInspector.BreakpointItem.prototype.click): + (WebInspector.BreakpointItem.prototype.populateEditElement): + (WebInspector.BreakpointItem.prototype.remove): + (WebInspector.BreakpointItem.prototype._hitStateChanged): + (WebInspector.BreakpointItem.prototype._labelChanged): + (WebInspector.BreakpointItem.prototype._createLabelElement): + * inspector/front-end/inspector.js: + (WebInspector.createJSBreakpointsSidebarPane.breakpointAdded): + (WebInspector.createJSBreakpointsSidebarPane): + (WebInspector.createDOMBreakpointsSidebarPane.breakpointAdded): + (WebInspector.createDOMBreakpointsSidebarPane): + (WebInspector.createXHRBreakpointsSidebarPane.breakpointAdded): + (WebInspector.createXHRBreakpointsSidebarPane): + +2010-11-02 Pavel Podivilov <podivilov@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: fix for breakpoints not restored on live edit bug + https://bugs.webkit.org/show_bug.cgi?id=48833 + + * inspector/front-end/ScriptsPanel.js: + (WebInspector.ScriptsPanel.prototype.debuggerPaused): + * inspector/front-end/inspector.js: + (WebInspector.pausedScript): + +2010-11-02 Alexander Pavlov <apavlov@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: [REGRESSION] Rule addition/selector editing result in unusable rules + https://bugs.webkit.org/show_bug.cgi?id=48826 + + * inspector/front-end/CSSStyleModel.js: + (WebInspector.CSSStyleModel.prototype.setRuleSelector): + (WebInspector.CSSStyleModel.prototype.addRule): + * inspector/front-end/StylesSidebarPane.js: + (WebInspector.BlankStylePropertiesSection.prototype.editingSelectorCommitted.successCallback): + (WebInspector.BlankStylePropertiesSection.prototype.editingSelectorCommitted): + +2010-11-02 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Andreas Kling. + + [Qt] Don't include Objective-C sources in SOURCES + + * WebCore.pro: + +2010-11-02 Pavel Podivilov <podivilov@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: persist native breakpoints in localStorage + https://bugs.webkit.org/show_bug.cgi?id=48711 + + * inspector/InspectorController.cpp: + (WebCore::InspectorController::disconnectFrontend): + (WebCore::InspectorController::didCommitLoad): + (WebCore::InspectorController::clearNativeBreakpoints): + * inspector/InspectorController.h: + * inspector/front-end/BreakpointManager.js: + (WebInspector.BreakpointManager): + (WebInspector.DOMBreakpoint): + (WebInspector.EventListenerBreakpoint): + (WebInspector.EventListenerBreakpoint.eventNameForUI): + (WebInspector.EventListenerBreakpoint.prototype._uiEventName): + (WebInspector.XHRBreakpoint): + (WebInspector.XHRBreakpoint.prototype.populateStatusMessageElement): + * inspector/front-end/BreakpointsSidebarPane.js: + (WebInspector.BreakpointsSidebarPane.prototype.addBreakpoint): + (WebInspector.BreakpointsSidebarPane.prototype._breakpointHit): + (WebInspector.BreakpointItem.prototype._hitStateChanged): + (WebInspector.EventListenerBreakpointsSidebarPane): + * inspector/front-end/ConsoleView.js: + * inspector/front-end/EventListenersSidebarPane.js: + * inspector/front-end/NetworkPanel.js: + * inspector/front-end/Panel.js: + * inspector/front-end/ResourceView.js: + * inspector/front-end/ScriptsPanel.js: + * inspector/front-end/Settings.js: + (WebInspector.Settings): + (WebInspector.Settings.prototype.inspectedURLChanged): + (WebInspector.Settings.prototype._formatProjectKey): + * inspector/front-end/StoragePanel.js: + * inspector/front-end/StylesSidebarPane.js: + * inspector/front-end/WatchExpressionsSidebarPane.js: + * inspector/front-end/inspector.css: + (.pane .breakpoint-hit): + * inspector/front-end/inspector.js: + (WebInspector.set currentPanel): + (WebInspector.doLoadedDone.onPopulateScriptObjects): + (WebInspector.doLoadedDone): + (WebInspector.reset): + (WebInspector.inspectedURLChanged): + +2010-11-01 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Joseph Pecoraro. + + Web Inspector: use mimeType from cached resource + in case response data contains none. + https://bugs.webkit.org/show_bug.cgi?id=48773 + + * inspector/InspectorResourceAgent.cpp: + (WebCore::InspectorResourceAgent::didReceiveResponse): + * inspector/front-end/NetworkPanel.js: + (WebInspector.NetworkPanel.prototype._createTable): + +2010-11-01 Andrey Kosyakov <caseq@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: [Extensions API] expose API to create properties watch sidebar panes + https://bugs.webkit.org/show_bug.cgi?id=48761 + + * inspector/front-end/ExtensionAPI.js: + (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createSidebarPane): + (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createWatchExpressionSidebarPane.callbackWrapper): + (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createWatchExpressionSidebarPane): + (WebInspector.injectedExtensionAPI): + (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl): + (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl.prototype.setExpression): + (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl.prototype.setObject): + * inspector/front-end/ExtensionPanel.js: Added ExtensionWatchSidebarPane + (WebInspector.ExtensionWatchSidebarPane): + (WebInspector.ExtensionWatchSidebarPane.prototype.setObject): + (WebInspector.ExtensionWatchSidebarPane.prototype.setExpression): + (WebInspector.ExtensionWatchSidebarPane.prototype._onEvaluate): + (WebInspector.ExtensionWatchSidebarPane.prototype._setObject): + * inspector/front-end/ExtensionServer.js: + (WebInspector.ExtensionServer): + (WebInspector.ExtensionServer.prototype.notifyExtensionWatchSidebarUpdated): + (WebInspector.ExtensionServer.prototype._onCreateSidebar): + (WebInspector.ExtensionServer.prototype._onCreateWatchExpressionSidebarPane): + (WebInspector.ExtensionServer.prototype._createSidebar): + (WebInspector.ExtensionServer.prototype._onSetWatchSidebarContent): + * inspector/front-end/InjectedScript.js: + (injectedScriptConstructor.): + * inspector/front-end/RemoteObject.js: Added a wrapper for local JSON object to simulate RemoteObject interface. + (WebInspector.RemoteObject.fromLocalObject): + (WebInspector.LocalJSONObject): + (WebInspector.LocalJSONObject.prototype.get description): + (WebInspector.LocalJSONObject.prototype.get type): + (WebInspector.LocalJSONObject.prototype.get hasChildren): + (WebInspector.LocalJSONObject.prototype.getOwnProperties): + (WebInspector.LocalJSONObject.prototype.getProperties): + (WebInspector.LocalJSONObject.prototype.isError): + +2010-11-02 Ryuan Choi <ryuan.choi@samsung.com> + + Unreviewed build fix for EFL build with libcurl + + [EFL] remove multiple definition with libcurl + https://bugs.webkit.org/show_bug.cgi?id=48499 + + Add macro to isolate setCookieStoragePrivateBrowsingEnabled from EFL + build because it was duplicated. + + * platform/network/curl/CookieJarCurl.cpp: + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Joseph Pecoraro. + + Web Inspector: highlight frame on hover in resources panel. + https://bugs.webkit.org/show_bug.cgi?id=48760 + + * inspector/Inspector.idl: + * inspector/InspectorController.cpp: + (WebCore::InspectorController::highlightFrame): + * inspector/InspectorController.h: + (WebCore::InspectorController::hideFrameHighlight): + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel): + (WebInspector.StoragePanel.prototype.showView): + (WebInspector.StoragePanel.prototype._onmousemove): + (WebInspector.StoragePanel.prototype._onmouseout): + (WebInspector.FrameTreeElement.prototype.onselect): + (WebInspector.FrameTreeElement.prototype.ondeselect): + (WebInspector.FrameTreeElement.prototype.set displayName): + (WebInspector.FrameTreeElement.prototype.set hovered): + * inspector/front-end/inspector.css: + (.storage.panel .sidebar li.selected .selection): + (.storage.panel .sidebar :focus li.selected .selection): + (body.inactive .storage.panel .sidebar li.selected .selection): + +2010-11-02 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Rob Buis. + + Convert SVGPreserveAspectRatio to the new SVGPropertyTearOff concept + https://bugs.webkit.org/show_bug.cgi?id=48822 + + Convert the next type to use the SVGPropertyTearOffConcept. Just SVGAnimatedTransformList/SVGTransform/SVGStringList are missing. + + Tests: svg/dom/SVGAnimatedPreserveAspectRatio.html + svg/dom/SVGPreserveAspectRatio.html + + * GNUmakefile.am: Add SVGAnimatedPreserveAspectRatio.h to build. + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * bindings/scripts/CodeGenerator.pm: Recognize SVGAnimatedPreserveAspectRatio as new style animated type. + * bindings/scripts/CodeGeneratorJS.pm: Remove special SVGPreserveAspectRatio handling. + * bindings/scripts/CodeGeneratorObjC.pm: Always include the type wrapped by SVGPropertyTearOff<> - this was missing before, and now become visible as missing include. + * bindings/scripts/CodeGeneratorV8.pm: Remove special SVGPreserveAspectRatio handling. + * svg/DeprecatedSVGAnimatedPropertyTraits.h: Remove SVGPreserveAspectRatio handling. + * svg/DeprecatedSVGAnimatedTemplate.h: Ditto. + * svg/SVGAnimatedPreserveAspectRatio.h: Added. + * svg/SVGFEImageElement.h: s/DECLARE_ANIMATED_PROPERTY/DECLARE_ANIMATED_PROPERTY_NEW/ where SVGPreserveAspectRatio is used. + * svg/SVGFitToViewBox.cpp: + (WebCore::SVGFitToViewBox::viewBoxToViewTransform): SVGPreserveAspectRatio::getCTM doesn't need x/y parameters, they were not used anywhere, remove them. + * svg/SVGFitToViewBox.h: Replace includes by class forwards. + * svg/SVGImageElement.h: s/DECLARE_ANIMATED_PROPERTY/DECLARE_ANIMATED_PROPERTY_NEW/ where SVGPreserveAspectRatio is used. + * svg/SVGLocatable.cpp: Add SVGNames.h include, to allow Qt to build (thanks ews!). + * svg/SVGMarkerElement.h: Ditto. + * svg/SVGPatternElement.h: Ditto. + * svg/SVGPreserveAspectRatio.cpp: Modernize code, add error handling for align/meetOrSlice covered by the new tests. + (WebCore::SVGPreserveAspectRatio::SVGPreserveAspectRatio): + (WebCore::SVGPreserveAspectRatio::setAlign): + (WebCore::SVGPreserveAspectRatio::setMeetOrSlice): + (WebCore::SVGPreserveAspectRatio::parsePreserveAspectRatio): + (WebCore::SVGPreserveAspectRatio::transformRect): + (WebCore::SVGPreserveAspectRatio::getCTM): + (WebCore::SVGPreserveAspectRatio::valueAsString): + * svg/SVGPreserveAspectRatio.h: Reindented header. + (WebCore::SVGPreserveAspectRatio::align): Inlined. + (WebCore::SVGPreserveAspectRatio::meetOrSlice): Inlined. + * svg/SVGPreserveAspectRatio.idl: Enable StrictTypeChecking for the align/meetOrSlice properties. + * svg/SVGSVGElement.h: s/DECLARE_ANIMATED_PROPERTY/DECLARE_ANIMATED_PROPERTY_NEW/ where SVGPreserveAspectRatio is used. + * svg/SVGStyledTransformableElement.h: Add SVGAnimatedPropertyMacros.h include, needed by efl to build (thanks ews!). + * svg/SVGSymbolElement.h: Ditto. + * svg/SVGViewElement.h: Ditto. + * svg/SVGViewSpec.h: Ditto. + +2010-11-01 MORITA Hajime <morrita@google.com> + + Reviewed by Kent Tamura. + + @spellcheck attribute at the child of contentEditable node is ignored. + https://bugs.webkit.org/show_bug.cgi?id=48418 + + Changed to check spellcheck availability against a node under the + selection (caret) instead of the focus. For shadow elements, the + check now refers its host node. Note that the original code didn't + care shadows because focus is never set on them. + + Test: editing/spelling/spelling-attribute-at-child.html + + * dom/Element.h: + * editing/Editor.cpp: + (WebCore::Editor::markMisspellingsOrBadGrammar): + (WebCore::Editor::isSpellCheckingEnabledFor): + (WebCore::Editor::isSpellCheckingEnabledInFocusedNode): Now just calling isSpellCheckingEnabledFor() + (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): + * editing/Editor.h: + * platform/ContextMenu.cpp: + (WebCore::ContextMenu::populate): + * rendering/TextControlInnerElements.cpp: + (WebCore::TextControlInnerElement::isSpellCheckingEnabled): Added. + * rendering/TextControlInnerElements.h: + +2010-11-01 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Daniel Bates. + + [GTK] PopupMenuGtk has a very confusing if-else block + https://bugs.webkit.org/show_bug.cgi?id=48816 + + Small code cleanup for PopupMenuGtk. + + * platform/gtk/PopupMenuGtk.cpp: + (WebCore::PopupMenuGtk::show): + +2010-11-01 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + [Chromium] Add ICC support for PNG on Mac + https://bugs.webkit.org/show_bug.cgi?id=48170 + + This just pipes the ICC profile from libpng to CoreGraphics. This + patch would have been a lot prettier on Snow Leopard, but we have to + use a somewhat ugly API to get this to work on Leopard. + + This is covered by about infinite tests. + + * platform/image-decoders/ImageDecoder.cpp: + (WebCore::RGBA32Buffer::setColorProfile): + * platform/image-decoders/ImageDecoder.h: + * platform/image-decoders/cg/ImageDecoderCG.cpp: + (WebCore::RGBA32Buffer::asNewNativeImage): + * platform/image-decoders/png/PNGImageDecoder.cpp: + (WebCore::PNGImageDecoder::headerAvailable): + (WebCore::PNGImageDecoder::rowAvailable): + * platform/image-decoders/qt/RGBA32BufferQt.cpp: + (WebCore::RGBA32Buffer::setColorProfile): + * platform/image-decoders/skia/ImageDecoderSkia.cpp: + (WebCore::RGBA32Buffer::setColorProfile): + +2010-11-01 Chang Shu <chang.shu@nokia.com> + + Reviewed by Antonio Gomes. + + Leave SelectElement key handling without setting event default + handled when the selection reaches the boundary so focus can + move to neighbor nodes in spatial navigation. + https://bugs.webkit.org/show_bug.cgi?id=48145 + + * dom/SelectElement.cpp: + (WebCore::SelectElement::listBoxDefaultEventHandler): + +2010-11-01 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r71080. + http://trac.webkit.org/changeset/71080 + https://bugs.webkit.org/show_bug.cgi?id=48815 + + This change caused many crashes on the debug bot. (Requested + by mrobinson on #webkit). + + * platform/network/soup/SocketStreamHandle.h: + * platform/network/soup/SocketStreamHandleSoup.cpp: + (WebCore::isActiveHandle): + (WebCore::deactivateHandle): + (WebCore::SocketStreamHandle::SocketStreamHandle): + (WebCore::SocketStreamHandle::connected): + (WebCore::SocketStreamHandle::readBytes): + (WebCore::SocketStreamHandle::beginWaitingForSocketWritability): + (WebCore::connectedCallback): + (WebCore::readReadyCallback): + (WebCore::writeReadyCallback): + +2010-11-01 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [Soup] Random crashes in http/tests/websocket/tests/workers/worker-handshake-challenge-randomness.html + https://bugs.webkit.org/show_bug.cgi?id=48805 + + Track active WebSocket handles via a sequential id. This ensures + that when a handle is reallocated into a recently used segment of + memory, it doesn't trigger a false positive in the code which ensures + the original handle is active. + + No new tests. This test should stop crashing on the bots, proving the fix. + + * platform/network/soup/SocketStreamHandle.h: + (WebCore::SocketStreamHandle::id): Added an m_id member and accessor + to SocketStreamHandle. + * platform/network/soup/SocketStreamHandleSoup.cpp: + (WebCore::getHandleFromId): Updated to work with HashMap of handle ids to + SocketStreamHandle*. + (WebCore::deactivateHandle): Ditto. + (WebCore::activateHandle): Ditto. + (WebCore::SocketStreamHandle::SocketStreamHandle): Ditto. + (WebCore::SocketStreamHandle::connected): Ditto. + (WebCore::SocketStreamHandle::readBytes): Ditto. + (WebCore::SocketStreamHandle::beginWaitingForSocketWritability): Ditto. + (WebCore::connectedCallback): Ditto. + (WebCore::readReadyCallback): Ditto. + (WebCore::writeReadyCallback): Ditto. + +2010-11-01 Kent Tamura <tkent@chromium.org> + + Unreviewed. Run sort-Xcode-project-file. + + * WebCore.xcodeproj/project.pbxproj: + +2010-11-01 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dan Bernstein. + + Assertion failure in FrameView::layout when clicking on a YouTube video on youtube.com front page + https://bugs.webkit.org/show_bug.cgi?id=44287 + + When removing subframes, it's possible for layout() to get called on a FrameView + for a Frame that has been removed from the frame tree. This can happen if the parent + document happens to do a layout() while RenderView still has a reference to the widget + for the removed frame; updateWidgetPosition() will try to force a layout() on the + subframe. + + Fix by checking that the FrameView's Frame still has a reference to the page before + calling layout() on the subframe. + + Test: fast/frames/layout-after-destruction.html + + * rendering/RenderWidget.cpp: + (WebCore::RenderWidget::updateWidgetPosition): + +2010-11-01 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r71065. + http://trac.webkit.org/changeset/71065 + https://bugs.webkit.org/show_bug.cgi?id=48801 + + Seem to breake a lot of tests on Chromium bots (Requested by + dimich on #webkit). + + * platform/image-decoders/ImageDecoder.cpp: + * platform/image-decoders/ImageDecoder.h: + * platform/image-decoders/cg/ImageDecoderCG.cpp: + (WebCore::RGBA32Buffer::asNewNativeImage): + * platform/image-decoders/png/PNGImageDecoder.cpp: + (WebCore::PNGImageDecoder::headerAvailable): + (WebCore::PNGImageDecoder::rowAvailable): + * platform/image-decoders/qt/RGBA32BufferQt.cpp: + * platform/image-decoders/skia/ImageDecoderSkia.cpp: + +2010-11-01 Matthew Delaney <mdelaney@apple.com> + + Reviewed by Simon Fraser. + + Setting attr repeatDur=0 on SVG element causes hang + https://bugs.webkit.org/show_bug.cgi?id=48785 + + Test: svg/animations/repeatDur-zero.xhtml + + * svg/animation/SVGSMILElement.cpp: Fixing bound checking for legal repeatDur values. + +2010-10-31 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + [Chromium] Add ICC support for PNG on Mac + https://bugs.webkit.org/show_bug.cgi?id=48170 + + This just pipes the ICC profile from libpng to CoreGraphics. This + patch would have been a lot prettier on Snow Leopard, but we have to + use a somewhat ugly API to get this to work on Leopard. + + This is covered by about infinite tests. + + * platform/image-decoders/ImageDecoder.cpp: + (WebCore::RGBA32Buffer::setColorProfile): + * platform/image-decoders/ImageDecoder.h: + * platform/image-decoders/cg/ImageDecoderCG.cpp: + (WebCore::RGBA32Buffer::asNewNativeImage): + * platform/image-decoders/png/PNGImageDecoder.cpp: + (WebCore::PNGImageDecoder::headerAvailable): + (WebCore::PNGImageDecoder::rowAvailable): + * platform/image-decoders/qt/RGBA32BufferQt.cpp: + (WebCore::RGBA32Buffer::setColorProfile): + * platform/image-decoders/skia/ImageDecoderSkia.cpp: + (WebCore::RGBA32Buffer::setColorProfile): + +2010-11-01 David Hyatt <hyatt@apple.com> + + Reviewed by Dan Bernstein. + + https://bugs.webkit.org/show_bug.cgi?id=48776 + + Change isVertical() on InlineBox to isHorizontal() instead. This makes the horizontal code path come + first if you branch on isHorizontal() and makes the code read better (since that's the more common code + path). + + * rendering/InlineBox.cpp: + (WebCore::InlineBox::logicalHeight): + * rendering/InlineBox.h: + (WebCore::InlineBox::InlineBox): + (WebCore::InlineBox::isHorizontal): + (WebCore::InlineBox::setIsHorizontal): + (WebCore::InlineBox::width): + (WebCore::InlineBox::height): + (WebCore::InlineBox::logicalLeft): + (WebCore::InlineBox::setLogicalLeft): + (WebCore::InlineBox::logicalTop): + (WebCore::InlineBox::setLogicalTop): + (WebCore::InlineBox::baselinePosition): + (WebCore::InlineBox::lineHeight): + * rendering/InlineFlowBox.cpp: + (WebCore::InlineFlowBox::addToLine): + (WebCore::InlineFlowBox::placeBoxesInInlineDirection): + (WebCore::InlineFlowBox::computeBlockDirectionOverflow): + (WebCore::InlineFlowBox::paintFillLayer): + (WebCore::InlineFlowBox::paintBoxDecorations): + (WebCore::InlineFlowBox::paintMask): + * rendering/InlineFlowBox.h: + (WebCore::InlineFlowBox::marginLogicalLeft): + (WebCore::InlineFlowBox::marginLogicalRight): + (WebCore::InlineFlowBox::borderLogicalLeft): + (WebCore::InlineFlowBox::borderLogicalRight): + (WebCore::InlineFlowBox::paddingLogicalLeft): + (WebCore::InlineFlowBox::paddingLogicalRight): + (WebCore::InlineFlowBox::setInlineDirectionOverflowPositions): + (WebCore::InlineFlowBox::setBlockDirectionOverflowPositions): + * rendering/InlineTextBox.cpp: + (WebCore::InlineTextBox::selectionRect): + (WebCore::InlineTextBox::applyShadowToGraphicsContext): + (WebCore::paintTextWithShadows): + (WebCore::InlineTextBox::paint): + (WebCore::InlineTextBox::paintDecoration): + * rendering/InlineTextBox.h: + * rendering/RenderBlockLineLayout.cpp: + (WebCore::RenderBlock::createLineBoxes): + * rendering/RenderBox.cpp: + (WebCore::RenderBox::blockDirectionOverflow): + * rendering/RenderBox.h: + * rendering/RenderBoxModelObject.cpp: + (WebCore::RenderBoxModelObject::paintFillLayerExtended): + * rendering/RenderLineBoxList.cpp: + (WebCore::RenderLineBoxList::hitTest): + * rendering/RootInlineBox.cpp: + (WebCore::RootInlineBox::RootInlineBox): + (WebCore::RootInlineBox::placeEllipsis): + * rendering/RootInlineBox.h: + (WebCore::RootInlineBox::baselinePosition): + (WebCore::RootInlineBox::lineHeight): + +2010-11-01 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Dave Hyatt. + + Multiple background properties are not retrievable via DOM method getComputedStyle + https://bugs.webkit.org/show_bug.cgi?id=23203 + + Return lists of values from getComputedStyle() for multiple backgrounds, + and multiple masks. + + Test: fast/backgrounds/multiple-backgrounds-computed-style.html + + * css/CSSComputedStyleDeclaration.cpp: + (WebCore::fillSizeToCSSValue): + (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): + +2010-11-01 David Hyatt <hyatt@apple.com> + + Reviewed by Dan Bernstein. + + https://bugs.webkit.org/show_bug.cgi?id=48663 + + Make repaint invalidation work with vertical lines. Rewrite linesBoundingBox for RenderText and + RenderInline to give the correct rectangle back for vertical lines. Also patch linesVisibleOverflowBoundingBox + to give back the correct rectangle for vertical lines. + + Fix bugs in the overflow accessors of InlineFlowBox when m_overflow was 0. + + Patch hit testing to also account for "rt" and "bt" blocks. + + * rendering/InlineBox.cpp: + (WebCore::InlineBox::adjustForFlippedBlocksWritingMode): + * rendering/InlineFlowBox.cpp: + (WebCore::InlineFlowBox::nodeAtPoint): + * rendering/InlineFlowBox.h: + (WebCore::InlineFlowBox::logicalLeftVisibleOverflow): + (WebCore::InlineFlowBox::logicalRightVisibleOverflow): + (WebCore::InlineFlowBox::bottomLayoutOverflow): + (WebCore::InlineFlowBox::rightLayoutOverflow): + (WebCore::InlineFlowBox::bottomVisualOverflow): + (WebCore::InlineFlowBox::rightVisualOverflow): + * rendering/InlineTextBox.cpp: + (WebCore::InlineTextBox::nodeAtPoint): + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::hitTestFloats): + (WebCore::RenderBlock::hitTestContents): + * rendering/RenderBox.cpp: + (WebCore::RenderBox::computeRectForRepaint): + (WebCore::RenderBox::adjustForFlippedBlocksWritingMode): + * rendering/RenderBox.h: + * rendering/RenderInline.cpp: + (WebCore::RenderInline::linesBoundingBox): + (WebCore::RenderInline::linesVisibleOverflowBoundingBox): + (WebCore::RenderInline::clippedOverflowRectForRepaint): + * rendering/RenderText.cpp: + (WebCore::RenderText::linesBoundingBox): + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + Add a "showContextMenu" call to Chrome/ChromeClient: + * loader/EmptyClients.h: + (WebCore::EmptyChromeClient::showContextMenu): + * page/Chrome.cpp: + (WebCore::Chrome::showContextMenu): + * page/Chrome.h: + * page/ChromeClient.h: + + Add a "platform description to ContextMenuItem" creator, will be needed by WebKit2 + * platform/ContextMenu.h: + * platform/mac/ContextMenuMac.mm: + (WebCore::contextMenuItemVector): + + * platform/mac/ContextMenuItemMac.mm: + (WebCore::ContextMenuItem::checked): WebKit2 ports now need this implemented. + + Stub these out to keep their WK2 ports building: + * platform/qt/ContextMenuItemQt.cpp: + (WebCore::ContextMenuItem::checked): + * platform/qt/ContextMenuQt.cpp: + (WebCore::contextMenuItemVector): + * platform/win/ContextMenuItemWin.cpp: + (WebCore::ContextMenuItem::checked): + * platform/win/ContextMenuWin.cpp: + (WebCore::contextMenuItemVector): + +2010-11-01 Eric Carlson <eric.carlson@apple.com> + + Reviewed by Adam Roben. + + Seeking by very small increment doesn't generate 'seeked' event + https://bugs.webkit.org/show_bug.cgi?id=48530 + + Test: media/video-seek-by-small-increment.html + + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::seek): Ask the media engine for its closest time value so we can + avoid asking it to seek to the current time. + + * platform/graphics/MediaPlayer.cpp: + (WebCore::MediaPlayer::mediaTimeForTimeValue): New. + * platform/graphics/MediaPlayer.h: + * platform/graphics/MediaPlayerPrivate.h: + (WebCore::MediaPlayerPrivateInterface::mediaTimeForTimeValue): Ditto. + + * platform/graphics/mac/MediaPlayerPrivateQTKit.h: + * platform/graphics/mac/MediaPlayerPrivateQTKit.mm: + (WebCore::MediaPlayerPrivate::mediaTimeForTimeValue): Return the closest value in the movie's time scale. + + * platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp: + (WebCore::MediaPlayerPrivateQuickTimeVisualContext::mediaTimeForTimeValue): Ditto + * platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h: + + * platform/graphics/win/QTMovie.cpp: + (QTMovie::timeScale): Return the movie's time scale. + * platform/graphics/win/QTMovie.h: + +2010-11-01 Pavel Feldman <pfeldman@chromium.org> + + Not reviewed: Chromium build fix. Adding missing transitive dependency. + + * inspector/InspectorResourceAgent.cpp: + +2010-11-01 Pavel Feldman <pfeldman@chromium.org> + + Not reviewed. Removing references to removed file from project files. + + * WebCore.gypi: + * inspector/front-end/WebKit.qrc: + * inspector/front-end/inspector.css: + +2010-11-01 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: remove old resources panel. + https://bugs.webkit.org/show_bug.cgi?id=45657 + + * CMakeLists.txt: + * English.lproj/localizedStrings.js: + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * bindings/js/JSInjectedScriptHostCustom.cpp: + * inspector/InjectedScriptHost.cpp: + * inspector/Inspector.idl: + * inspector/InspectorCSSStore.cpp: + * inspector/InspectorController.cpp: + (WebCore::InspectorController::~InspectorController): + (WebCore::InspectorController::connectFrontend): + (WebCore::InspectorController::releaseFrontendLifetimeAgents): + (WebCore::InspectorController::populateScriptObjects): + (WebCore::InspectorController::unbindAllResources): + (WebCore::InspectorController::didCommitLoad): + (WebCore::InspectorController::frameDetachedFromParent): + (WebCore::InspectorController::didLoadResourceFromMemoryCache): + (WebCore::InspectorController::identifierForInitialRequest): + (WebCore::InspectorController::willSendRequest): + (WebCore::InspectorController::markResourceAsCached): + (WebCore::InspectorController::didReceiveResponse): + (WebCore::InspectorController::didReceiveContentLength): + (WebCore::InspectorController::didFinishLoading): + (WebCore::InspectorController::didFailLoading): + (WebCore::InspectorController::resourceRetrievedByXMLHttpRequest): + (WebCore::InspectorController::scriptImported): + (WebCore::InspectorController::didCreateWebSocket): + (WebCore::InspectorController::willSendWebSocketHandshakeRequest): + (WebCore::InspectorController::didReceiveWebSocketHandshakeResponse): + (WebCore::InspectorController::didCloseWebSocket): + * inspector/InspectorController.h: + * inspector/InspectorFrontendHost.cpp: + * inspector/InspectorResource.cpp: Removed. + * inspector/InspectorResource.h: Removed. + * inspector/InspectorResourceAgent.cpp: + (WebCore::InspectorResourceAgent::setOverrideContent): + * inspector/InspectorResourceAgent.h: + * inspector/front-end/ConsoleView.js: + (WebInspector.ConsoleView.prototype.addMessage): + (WebInspector.ConsoleView.prototype.clearMessages): + * inspector/front-end/ExtensionServer.js: + (WebInspector.ExtensionServer.prototype._onRevealAndSelectResource): + * inspector/front-end/Images/resourcesSilhouette.png: Removed. + * inspector/front-end/Resource.js: + * inspector/front-end/ResourceManager.js: + (WebInspector.ResourceManager.getContent): + * inspector/front-end/ResourcesPanel.js: Removed. + * inspector/front-end/Settings.js: + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel): + (WebInspector.StoragePanel.prototype.get toolbarItemLabel): + * inspector/front-end/WebKit.qrc: + * inspector/front-end/inspector.html: + * inspector/front-end/inspector.js: + (WebInspector._createPanels): + (WebInspector.get networkResources): + (WebInspector.forAllResources): + (WebInspector.resourceForURL): + (WebInspector.doLoadedDone.populateInspectorState): + (WebInspector.openResource): + (WebInspector.domContentEventFired): + (WebInspector.loadEventFired): + (WebInspector.reset): + (WebInspector._choosePanelToShowSourceLine): + +2010-10-28 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + Fix enum naming style violation in GraphicsContext3D + https://bugs.webkit.org/show_bug.cgi?id=48441 + + * platform/graphics/GraphicsContext3D.cpp: + (WebCore::GraphicsContext3D::extractImageData): + (WebCore::GraphicsContext3D::extractTextureData): + (WebCore::doPacking): + (WebCore::GraphicsContext3D::packPixels): + * platform/graphics/GraphicsContext3D.h: + * platform/graphics/cg/GraphicsContext3DCG.cpp: + (WebCore::getSourceDataFormat): + (WebCore::GraphicsContext3D::getImageData): + * platform/graphics/skia/GraphicsContext3DSkia.cpp: + (WebCore::GraphicsContext3D::getImageData): + +2010-11-01 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [GTK] Pasting markup into Thunderbird compose window produces no text + https://bugs.webkit.org/show_bug.cgi?id=43737 + + Include a content-type meta tag prefix on all clipboard markup. Programs like + Thunderbird expect this meta tag and will not paste anything unless it is there. + + This is covered by changes to WebKit/gtk/tests/testcopyandpaste.c. This patch was + written in such a way as to not affect layout test results, otherwise there + would be many new GTK+-specific results that say "FAIL"). + + * platform/gtk/PasteboardHelper.cpp: + (WebCore::removeMarkupPrefix): Added this helper which removes the prefix + when found on incoming clipboard and drag-and-drop text. + (WebCore::PasteboardHelper::getClipboardContents): Remove the meta tag prefix. + (WebCore::PasteboardHelper::fillSelectionData): Add the meta tag prefix. + (WebCore::PasteboardHelper::fillDataObjectFromDropData): Remove the meta tag prefix + +2010-11-01 Justin Schuh <jschuh@chromium.org> + + Reviewed by Dirk Schulze. + + Check for NULL node in SVGUseElement::associateInstancesWithShadowTreeElements loop + https://bugs.webkit.org/show_bug.cgi?id=48741 + + Test: svg/custom/use-on-use-with-child-and-empty-target.svg + + * svg/SVGUseElement.cpp: + (WebCore::SVGUseElement::associateInstancesWithShadowTreeElements): + +2010-11-01 Mario Sanchez Prada <msanchez@igalia.com> + + Reviewed by Martin Robinson. + + [Gtk] AtkHyperlink needs to be implemented + https://bugs.webkit.org/show_bug.cgi?id=33785 + + Implemented the AtkHyperlink/AtkHypertext stuff in the GTK port. + + Even thought these kind of tasks are usually about implementing an + interface, in this case it was needed to implement some more + things due to the fact that AtkHyperlink is neither an interface + nor an AtkObject, but just an abstract class child of GObject that + needs to be redefined in a specific subclass of that one. On top + of that, it was needed to implement the AtkAction interface as + well for that new class, so exposed hyperlinks can work as + expected with Assistive Technologies based on ATK. + + Furthermore, as there's no mechanism to get an instance of that + AtkHyperlink other than doing it through an AtkObject implementing + the AtkHypertext interface, it was needed to also add the code to + implement that one, so it makes possible to ask for the + 'hyperlinks' under an 'hypertext' accessible object. + + Finally, to complete the implementation of all this stuff and make + it all consistent, it was needed as well to implement the + AtkHyperlinkImpl interface (providing just one method only) so + that allows retrieving the AtkHyperlink object associated to an + AtkObject implementing such an interface. + + * GNUmakefile.am: Add the new WebKitAccessibleHyperlink.[h|cpp] + files to the sources list for the GTK port. + + * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: + (core): New function to return the core accessibility object + related to an AtkObject implementing the AtkHypertext interface. + (webkitAccessibleHypertextGetLink): New, part of the + implementation of the AtkHypertext interface. + (webkitAccessibleHypertextGetNLinks): New, likewise. + (webkitAccessibleHypertextGetLinkIndex): New, likewise. + (atkHypertextInterfaceInit): New, initialize the AtkHypertext + interface. + (webkitAccessibleHyperlinkImplGetHyperlink): New, part of the + implementation of the AtkHyperlinkImpl interface. + (atkHyperlinkImplInterfaceInit): New, initialize the + AtkHyperlinkImpl interface. + (GetAtkInterfaceTypeFromWAIType): Add ATK_TYPE_HYPERTEXT and + ATK_TYPE_HYPERLINK_IMPL to the list of recognized types. + (getInterfaceMaskFromObject): Decide when it's needed to add + WAI_HYPERTEXT and WAI_HYPERLINK to the interface mask. + + * accessibility/gtk/WebKitAccessibleHyperlink.h: Added. + * accessibility/gtk/WebKitAccessibleHyperlink.cpp: Added. + (returnString): Return (const char*) from String variables. + (core): Return the associated AccessibilityObject. + (webkitAccessibleHyperlinkActionDoAction): Part of the + implementation of the AtkAction interface. + (webkitAccessibleHyperlinkActionGetNActions): Likewise. + (webkitAccessibleHyperlinkActionGetDescription): Likewise. + (webkitAccessibleHyperlinkActionGetKeybinding): Likewise. + (webkitAccessibleHyperlinkActionGetName): Likewise. + (atkActionInterfaceInit): Initialize the AtkAction interface. + (getRangeLengthForObject): Returns the length for a given Range, + considering special cases (e.g. List item markers). + (webkitAccessibleHyperlinkGetURI): Implementation of one of the + methods in the AtkHyperlink abstract class. + (webkitAccessibleHyperlinkGetObject): Likewise. + (webkitAccessibleHyperlinkGetStartIndex): Likewise. + (webkitAccessibleHyperlinkGetEndIndex): Likewise. + (webkitAccessibleHyperlinkIsValid): Likewise. + (webkitAccessibleHyperlinkGetNAnchors): Likewise. + (webkitAccessibleHyperlinkIsSelectedLink): Likewise. + (webkitAccessibleHyperlinkGetProperty): Getter method. + (webkitAccessibleHyperlinkSetProperty): Setter method. + (webkitAccessibleHyperlinkFinalize): Finalize method. + (webkitAccessibleHyperlinkClassInit): Initialize the + WebKitAccessibleHyperlink class. + (webkitAccessibleHyperlinkInit): Initialize the + WebKitAccessibleHyperlink instance. + (webkitAccessibleHyperlinkGetType): Implementation of the + get_type() function for the WebKitAccessibleHyperlink class. + (webkitAccessibleHyperlinkNew): Returns an instance of the class + associated to a given AtkHyperlinkImpl object. + (webkitAccessibleHyperlinkGetAccessibilityObject): Public function + returning the AccessibilityObject associated to the instance of + the WebKitAccessibleHyperlink class. + +2010-11-01 Pavel Feldman <pfeldman@chromium.org> + + Not reviewed: simplify inspector styles test to make all bots happy. + (drive-by fix for overriden inspector styles in network panel). + + * inspector/InspectorController.h: + * inspector/front-end/networkPanel.css: + +2010-11-01 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Rob Buis. + + Enable StrictTypeChecking for all types using SVG(Animated)PropertyTearOff + https://bugs.webkit.org/show_bug.cgi?id=48715 + + Enable StrictTypeChecking for all readwrite attributes and function calls of all types using the new SVG(Animated)PropertyTearOff concept. + Also enable RequiresAllArguments=Raise for all function calls of these new types. Cover this functionality by tests for each of them. + + When testing SVGLength it became obvious that quite a lot of functionality was missing. + Conversion from relative arguments (percentage, ems, exs) to user specified units was missing, added that functionality and tested it. + User units to pt conversion was wrong, fixed that. + + Tests: svg/dom/SVGAnimatedAngle.html + svg/dom/SVGAnimatedBoolean.html + svg/dom/SVGAnimatedEnumeration.html + svg/dom/SVGAnimatedInteger.html + svg/dom/SVGAnimatedLength.html + svg/dom/SVGAnimatedLengthList.html + svg/dom/SVGAnimatedRect.html + svg/dom/SVGLength-px-with-context.html + svg/dom/SVGLength-px.html + svg/dom/SVGLength.html + + * bindings/js/JSSVGLengthCustom.cpp: These SVGLength methods now take an ExceptionCode parameter, adapt to that. + (WebCore::JSSVGLength::value): + (WebCore::JSSVGLength::setValue): + (WebCore::JSSVGLength::convertToSpecifiedUnits): + * bindings/scripts/CodeGeneratorObjC.pm: Remove FIXMEs, pass real context instead off null pointer. DOMSVGLength::value is functional now. + * bindings/v8/custom/V8SVGLengthCustom.cpp: These SVGLength methods now take an ExceptionCode parameter, adapt to that. + (WebCore::V8SVGLength::valueAccessorGetter): + (WebCore::V8SVGLength::valueAccessorSetter): + (WebCore::V8SVGLength::convertToSpecifiedUnitsCallback): + * rendering/style/SVGRenderStyle.h: Adapt to SVGLength API changes. + (WebCore::SVGRenderStyle::initialBaselineShiftValue): + (WebCore::SVGRenderStyle::initialKerning): + (WebCore::SVGRenderStyle::initialStrokeDashOffset): + (WebCore::SVGRenderStyle::initialStrokeWidth): + * svg/SVGAngle.idl: Add StrictTypeChecking, RequiresAllArguments=Raise to all methods. + * svg/SVGAnimatedBoolean.idl: Remove StrictTypeChecking from animVal, it's readonly so this is useless. + * svg/SVGAnimatedEnumeration.idl: Add StrictTypeChecking to all attributes. + * svg/SVGAnimatedInteger.idl: Ditto. + * svg/SVGLength.cpp: Implement all missing features of SVGLength. Conform to our style guide (s/.0f// etc) + (WebCore::lengthTypeToString): + (WebCore::SVGLength::SVGLength): + (WebCore::SVGLength::value): Throw NOT_SUPPORTED_ERR when trying to obtain to relative units, when no context is given (SVGLength created by createSVGLength()). + (WebCore::SVGLength::setValue): Ditto, for the setter. + (WebCore::SVGLength::valueAsPercentage): Use m_valueInSpecifiedUnits instead of valueInSpecifiedUnits(). + (WebCore::SVGLength::setValueAsString): Throw SYNTAX_ERR if parsing failed. + (WebCore::SVGLength::valueAsString): Use makeString() instead of String and operator+. + (WebCore::SVGLength::newValueSpecifiedUnits): Add ExceptionCode parameter, throw NOT_SUPPORTED_ERR, if the given unit type is invalid. + (WebCore::SVGLength::convertToSpecifiedUnits): Ditto. + (WebCore::SVGLength::determineViewport): Added helper function used by convertValue*Percentage*. + (WebCore::SVGLength::convertValueFromUserUnitsToPercentage): Add new helper functions, used by value/setValue. + (WebCore::SVGLength::convertValueFromPercentageToUserUnits): Ditto. + (WebCore::SVGLength::convertValueFromUserUnitsToEMS): Ditto. + (WebCore::SVGLength::convertValueFromEMSToUserUnits): Ditto. + (WebCore::SVGLength::convertValueFromUserUnitsToEXS): Ditto. + (WebCore::SVGLength::convertValueFromEXSToUserUnits): Ditto. + (WebCore::SVGLength::fromCSSPrimitiveValue): Adapt to newValueSpecifiedUnits API change. + (WebCore::SVGLength::toCSSPrimitiveValue): Remove default switch case. + * svg/SVGLength.h: + (WebCore::SVGLength::valueInSpecifiedUnits): Inlined. + (WebCore::SVGLength::setValueInSpecifiedUnits): Ditto. + (WebCore::SVGLength::isRelative): + * svg/SVGLength.idl: Add StrictTypeChecking for all attributes/functions and RequiresAllArguments=Raise for all functions. + * svg/SVGLengthList.cpp: Adapt to SVGLength API changes. + (WebCore::SVGLengthList::parse): + +2010-10-31 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: unhide new network and resources panels. + https://bugs.webkit.org/show_bug.cgi?id=48725 + + * English.lproj/localizedStrings.js: + * inspector/InspectorController.h: + * inspector/front-end/NetworkPanel.js: + (WebInspector.NetworkPanel): + * inspector/front-end/Settings.js: + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel): + (WebInspector.StoragePanel.prototype.reset): + (WebInspector.StoragePanel.prototype.addResourceToFrame): + (WebInspector.StoragePanel.prototype.addDocumentURL): + (WebInspector.StoragePanel.prototype.showFileSystem): + (WebInspector.FileSystemTreeElement): + (WebInspector.FileSystemTreeElement.prototype.get itemURL): + (WebInspector.FileSystemTreeElement.prototype.onselect): + * inspector/front-end/inspector.js: + (WebInspector.updateResource): + * inspector/front-end/networkPanel.css: + (#network-close-button): + (.network.panel.viewing-resource #network-close-button): + +2010-10-26 MORITA Hajime <morrita@google.com> + + Reviewed by Kent Tamura. + + Refactoring: Spellchecking related static functions could form a class + https://bugs.webkit.org/show_bug.cgi?id=48287 + + Extracted spellcheck related static functions to TextCheckingHelper class, + which has EditorClient and Range as its member. + + No new tests. Just a refactoring. + + * CMakeLists.txt: + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * editing/EditingAllInOne.cpp + * editing/Editor.cpp: + (WebCore::Editor::advanceToNextMisspelling): + (WebCore::Editor::isSelectionUngrammatical): + (WebCore::Editor::guessesForUngrammaticalSelection): + (WebCore::Editor::guessesForMisspelledOrUngrammaticalSelection): + (WebCore::Editor::markMisspellingsAfterTypingToPosition): + (WebCore::Editor::markMisspellingsOrBadGrammar): + (WebCore::Editor::markMisspellings): + (WebCore::Editor::markBadGrammar): + (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): + (WebCore::Editor::changeBackToReplacedString): + * editing/Editor.h: + * editing/TextCheckingHelper.cpp: Added. + (WebCore::TextCheckingHelper::TextCheckingHelper): + (WebCore::TextCheckingHelper::~TextCheckingHelper): + (WebCore::TextCheckingHelper::paragraphAlignedRange): + (WebCore::TextCheckingHelper::findFirstMisspelling): + (WebCore::TextCheckingHelper::findFirstMisspellingOrBadGrammar): + (WebCore::TextCheckingHelper::findFirstGrammarDetail): + (WebCore::TextCheckingHelper::findFirstBadGrammar): + (WebCore::TextCheckingHelper::isUngrammatical): + (WebCore::TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange): + (WebCore::TextCheckingHelper::markAllMisspellings): + (WebCore::TextCheckingHelper::markAllBadGrammar): + * editing/TextCheckingHelper.h: Added. + +2010-10-31 Xan Lopez <xlopez@igalia.com> + + Try to fix the GTK+ build. + + Do not use broken/deprecated functions that won't be available + with G_DISABLE_DEPRECATED (used in debug builds). + + * plugins/gtk/PluginPackageGtk.cpp: + (WebCore::PluginPackage::fetchInfo): + +2010-10-31 Kenichi Ishibashi <bashi@google.com> + + Reviewed by Adam Barth. + + V8 binding for DOMSettableTokenList + https://bugs.webkit.org/show_bug.cgi?id=47812 + + Tests for this change will be included in the change for supporting + the <output> element. + See https://bugs.webkit.org/show_bug.cgi?id=29363. + + * bindings/v8/custom/V8DOMSettableTokenListCustom.cpp: Implemented. + (WebCore::V8DOMSettableTokenList::indexedPropertyGetter): Just calls DOMSettableTokenList::item(index). + +2010-10-31 Robert Hogan <robert@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] [Gtk] Plug-ins having upper case in mime type are failing to load + + Qt and Gtk are case-sensitive when storing the declared mime-type + of plugins. Since plugin mime-types are lowercased prior to searching + for them in the plugin database, ensure they are loaded with the + mime-type in lower case too. + + https://bugs.webkit.org/show_bug.cgi?id=36815 + + * plugins/gtk/PluginPackageGtk.cpp: + (WebCore::PluginPackage::fetchInfo): + * plugins/qt/PluginPackageQt.cpp: + (WebCore::PluginPackage::setMIMEDescription): + +2010-10-31 Robert Hogan <robert@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] Support nodesFromRect in DRT + + Pass a Document object as a QWebElement. + + https://bugs.webkit.org/show_bug.cgi?id=48716 + + * bridge/qt/qt_runtime.cpp: + (JSC::Bindings::convertValueToQVariant): + +2010-10-31 Peter Kasting <pkasting@google.com> + + Reviewed by Adam Barth. + + Treat GIFs with no loop count as "loop once". + https://bugs.webkit.org/show_bug.cgi?id=47302 + + Test: fast/images/gif-loop-count.html + + * platform/image-decoders/gif/GIFImageDecoder.cpp: + (WebCore::GIFImageDecoder::repetitionCount): + (WebCore::GIFImageDecoder::gifComplete): + +2010-10-31 No'am Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Andreas Kling. + + [Texmap] [Qt] Texture mapper initial implementation + https://bugs.webkit.org/show_bug.cgi?id=47070 + + Build fix for X11. + + No new tests; build fix. + + * plugins/qt/PluginViewQt.cpp: + (WebCore::PluginView::invalidateRect): + (WebCore::PluginView::platformStart): + +2010-10-31 Andreas Kling <kling@webkit.org> + + Reviewed by Dirk Schulze. + + Remove the unused GraphicsContext::clipOutEllipseInRect(IntRect) + https://bugs.webkit.org/show_bug.cgi?id=48727 + + This function was added in <http://trac.webkit.org/changeset/18654> for CSS3 box-shadows. + All use of the function was removed in <http://trac.webkit.org/changeset/21601> + + * platform/graphics/GraphicsContext.h: + * platform/graphics/cairo/GraphicsContextCairo.cpp: + * platform/graphics/cg/GraphicsContextCG.cpp: + * platform/graphics/haiku/GraphicsContextHaiku.cpp: + (WebCore::GraphicsContext::clipOut): + * platform/graphics/openvg/GraphicsContextOpenVG.cpp: + * platform/graphics/qt/GraphicsContextQt.cpp: + * platform/graphics/skia/GraphicsContextSkia.cpp: + (WebCore::GraphicsContext::clipOut): + * platform/graphics/wince/GraphicsContextWinCE.cpp: + * platform/graphics/wx/GraphicsContextWx.cpp: + +2010-10-31 Andreas Kling <kling@webkit.org> + + Reviewed by Dirk Schulze. + + [Qt] Respect the "antialiased" argument in clipConvexPolygon() + https://bugs.webkit.org/show_bug.cgi?id=48734 + + Set (or unset) the QPainter::Antialiased render hint for antialiased + clipping based on the "antialiased" argument. + + No test since Qt doesn't have pixel tests yet. + + * platform/graphics/qt/GraphicsContextQt.cpp: + (WebCore::GraphicsContext::clipConvexPolygon): + +2010-10-31 Andreas Kling <kling@webkit.org> + + Reviewed by Dirk Schulze. + + Remove the unused GraphicsContext::strokeRect(FloatRect) + https://bugs.webkit.org/show_bug.cgi?id=48726 + + This function was only implemented by GraphicsContextOpenVG and not + called from anywhere. + + * platform/graphics/GraphicsContext.h: + * platform/graphics/openvg/GraphicsContextOpenVG.cpp: + +2010-10-31 Andreas Kling <kling@webkit.org> + + Reviewed by Dirk Schulze. + + Remove the unused GraphicsContext::origin() + https://bugs.webkit.org/show_bug.cgi?id=48732 + + This method was not called from anywhere. + + * platform/graphics/GraphicsContext.h: + * platform/graphics/cairo/GraphicsContextCairo.cpp: + * platform/graphics/haiku/GraphicsContextHaiku.cpp: + * platform/graphics/openvg/GraphicsContextOpenVG.cpp: + * platform/graphics/qt/GraphicsContextQt.cpp: + * platform/graphics/wince/GraphicsContextWinCE.cpp: + +2010-10-31 Andreas Kling <kling@webkit.org> + + Reviewed by Dirk Schulze. + + [Qt] Remove GraphicsContext::pen() + https://bugs.webkit.org/show_bug.cgi?id=48733 + + Have PathQt obtain the pen() through the platformContext() instead. + + * platform/graphics/GraphicsContext.h: + * platform/graphics/qt/GraphicsContextQt.cpp: + * platform/graphics/qt/PathQt.cpp: + (WebCore::Path::strokeContains): + (WebCore::Path::strokeBoundingRect): + +2010-10-31 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r70959. + http://trac.webkit.org/changeset/70959 + https://bugs.webkit.org/show_bug.cgi?id=48731 + + It broke fast/events/spatial-navigation tests (Requested by + Ossy on #webkit). + + * WebCore.xcodeproj/project.pbxproj: + * rendering/InlineBox.cpp: + (WebCore::InlineBox::adjustForFlippedBlocksWritingMode): + * rendering/InlineFlowBox.h: + (WebCore::InlineFlowBox::bottomLayoutOverflow): + (WebCore::InlineFlowBox::rightLayoutOverflow): + (WebCore::InlineFlowBox::bottomVisualOverflow): + (WebCore::InlineFlowBox::rightVisualOverflow): + * rendering/RenderBox.cpp: + * rendering/RenderBox.h: + * rendering/RenderInline.cpp: + (WebCore::RenderInline::linesBoundingBox): + (WebCore::RenderInline::linesVisibleOverflowBoundingBox): + (WebCore::RenderInline::clippedOverflowRectForRepaint): + * rendering/RenderText.cpp: + (WebCore::RenderText::linesBoundingBox): + +2010-10-30 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: new resources and network panel usability improvements. + https://bugs.webkit.org/show_bug.cgi?id=48680 + + By default, navigation clears network log, added 'preserve log' button, + that prevents log from being cleared. + + Storing expanded state of all group items, restoring last selected item, + fall back to main frame's main resource by default. + Do not list XHRs and redirects in resources. + + * English.lproj/localizedStrings.js: + * inspector/InspectorController.cpp: + (WebCore::InspectorController::didLoadResourceFromMemoryCache): + (WebCore::InspectorController::identifierForInitialRequest): + * inspector/front-end/NetworkPanel.js: + (WebInspector.NetworkPanel.prototype.get statusBarItems): + (WebInspector.NetworkPanel.prototype._positionSummaryBar): + (WebInspector.NetworkPanel.prototype._updateFilter): + (WebInspector.NetworkPanel.prototype._createStatusbarButtons): + (WebInspector.NetworkPanel.prototype._onPreserveLogClicked): + (WebInspector.NetworkPanel.prototype.reset): + (WebInspector.NetworkPanel.prototype.refreshResource): + * inspector/front-end/ResourceManager.js: + (WebInspector.ResourceManager.prototype.identifierForInitialRequest): + (WebInspector.ResourceManager.prototype.willSendRequest): + (WebInspector.ResourceManager.prototype.didLoadResourceFromMemoryCache): + (WebInspector.ResourceManager.prototype.setOverrideContent): + (WebInspector.ResourceManager.prototype.didCreateWebSocket): + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel): + (WebInspector.StoragePanel.prototype.show): + (WebInspector.StoragePanel.prototype._initDefaultSelection): + (WebInspector.StoragePanel.prototype.reset): + (WebInspector.StoragePanel.prototype.addResourceToFrame): + (WebInspector.StoragePanel.prototype.refreshResource): + (WebInspector.StoragePanel.prototype.showDatabase): + (WebInspector.BaseStorageTreeElement.prototype.onselect): + (WebInspector.StorageCategoryTreeElement): + (WebInspector.StorageCategoryTreeElement.prototype.get itemURL): + (WebInspector.StorageCategoryTreeElement.prototype.onselect): + (WebInspector.StorageCategoryTreeElement.prototype.onattach): + (WebInspector.StorageCategoryTreeElement.prototype.onexpand): + (WebInspector.StorageCategoryTreeElement.prototype.oncollapse): + (WebInspector.FrameTreeElement.prototype.get itemURL): + (WebInspector.FrameTreeElement.prototype.onselect): + (WebInspector.FrameResourceTreeElement.prototype.get itemURL): + (WebInspector.FrameResourceTreeElement.prototype.onselect): + (WebInspector.DatabaseTreeElement.prototype.get itemURL): + (WebInspector.DatabaseTreeElement.prototype.onselect): + (WebInspector.DatabaseTableTreeElement.prototype.get itemURL): + (WebInspector.DatabaseTableTreeElement.prototype.onselect): + (WebInspector.DOMStorageTreeElement.prototype.get itemURL): + (WebInspector.DOMStorageTreeElement.prototype.onselect): + (WebInspector.CookieTreeElement.prototype.get itemURL): + (WebInspector.CookieTreeElement.prototype.onselect): + (WebInspector.ApplicationCacheTreeElement.prototype.get itemURL): + (WebInspector.ApplicationCacheTreeElement.prototype.onselect): + +2010-10-30 Patrick Gansterer <paroga@webkit.org> + + Unreviewed, build fix after r70846. + + * platform/graphics/wince/ImageWinCE.cpp: + (WebCore::RGBA32Buffer::asNewNativeImage): + +2010-10-30 Dimitri Glazkov <dglazkov@chromium.org> + + Unreviewed, rolling out r70984. + http://trac.webkit.org/changeset/70984 + https://bugs.webkit.org/show_bug.cgi?id=46015 + + Made media/audio-delete-while-slider-thumb-clicked.html crash. + + * Android.mk: + * CMakeLists.txt: + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.xcodeproj/project.pbxproj: + * dom/ContainerNode.cpp: + (WebCore::notifyChildInserted): + * dom/EventContext.cpp: Removed. + * dom/EventContext.h: Removed. + * dom/Node.cpp: + (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): + (WebCore::Node::createRendererIfNeeded): + (WebCore::Node::eventParentNode): + (WebCore::Node::enclosingLinkEventParentOrSelf): + (WebCore::eventTargetAsSVGElementInstance): + (WebCore::eventTargetRespectingSVGTargetRules): + (WebCore::Node::eventAncestors): + (WebCore::Node::dispatchGenericEvent): + * dom/Node.h: + * dom/Text.cpp: + (WebCore::Text::createRenderer): + * dom/WindowEventContext.cpp: Removed. + * dom/WindowEventContext.h: Removed. + * inspector/InspectorDOMAgent.cpp: + (WebCore::InspectorDOMAgent::getEventListenersForNode): + * inspector/InspectorInstrumentation.cpp: + (WebCore::eventHasListeners): + (WebCore::InspectorInstrumentation::willDispatchEventImpl): + * inspector/InspectorInstrumentation.h: + (WebCore::InspectorInstrumentation::willDispatchEvent): + * page/EventHandler.cpp: + (WebCore::EventHandler::updateMouseEventTargetNode): + * svg/SVGElement.cpp: + (WebCore::SVGElement::eventParentNode): + * svg/SVGElement.h: + +2010-10-30 Dimitri Glazkov <dglazkov@chromium.org> + + Reviewed by Darin Adler. + + Implement shadow DOM-aware event targeting and introduce EventContext to track the context of each event dispatch. + https://bugs.webkit.org/show_bug.cgi?id=46015 + + This patch adds the notion of EventContext (and a very similar-acting WindowEventContext, specifically + for DOMWindow), an abstraction that carries information around dispatching an event for any given Node. + + This abstraction is necessary to ensure that events, fired from shadow DOM nodes are properly retargeted to + appear as if they are coming from their host, thus never exposing the shadow DOM nodes to the world outside. + + * Android.mk: Added EventContext, WindowEventContext files. + * CMakeLists.txt: Ditto. + * GNUmakefile.am: Ditto. + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * dom/ContainerNode.cpp: + (WebCore::notifyChildInserted): Changed to be shadow DOM-aware. + * dom/EventContext.cpp: Added. + * dom/EventContext.h: Added. + * dom/Node.cpp: + (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Changed to be shadow DOM-aware. + (WebCore::Node::createRendererIfNeeded): Ditto. + (WebCore::Node::parentOrHostNode): Added new helper method. + (WebCore::Node::enclosingLinkEventParentOrSelf): Changed to be shadow DOM-aware. + (WebCore::eventTargetRespectingSVGTargetRules): Collapsed two helper methods into one. + (WebCore::Node::eventAncestors): Refactored to collect a vector of EventContexts. + (WebCore::Node::topEventContext): Added. + (WebCore::eventHasListeners): Changed to use EventContexts. + (WebCore::Node::dispatchGenericEvent): Ditto. + * dom/Node.h: Removed eventParentNode that's no longer needed, added parentOrHostNode decl, + and changed signature of eventAncestors to use EventContexts. + * dom/Text.cpp: + (WebCore::Text::createRenderer): Changed to be shadow DOM-aware. + * inspector/InspectorDOMAgent.cpp: + (WebCore::InspectorDOMAgent::getEventListenersForNode): Changed to use EventContexts. + * page/EventHandler.cpp: + (WebCore::EventHandler::updateMouseEventTargetNode): Removed code that's no longer necessary. + * svg/SVGElement.cpp: Removed eventParentNode that's no longer needed. + * svg/SVGElement.h: Ditto. + * dom/WindowEventContext.cpp: Added. + * dom/WindowEventContext.h: Added. + +2010-10-30 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Rob Buis. + + Convert SVGAnimatedNumber/SVGAnimatedNumberList to the new SVGAnimatedPropertyTearOff concept + https://bugs.webkit.org/show_bug.cgi?id=48686 + + Convert the next set of primitives to use the new SVG(Animated)PropertyTearOff concept. + + Tests: svg/dom/SVGAnimatedNumber.html + svg/dom/SVGAnimatedNumberList.html + svg/dom/SVGNumber.html + + * GNUmakefile.am: Add SVGAnimatedNumber.h / SVGAnimatedNumberList.h to build. + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + * bindings/scripts/CodeGenerator.pm: Recognize SVGAnimatedNumber/SVGAnimatedNumberList as new style SVG animated properties. Remove SVGNumber from PODType hash. + * bindings/scripts/CodeGeneratorJS.pm: Remove special SVGNumber handing, it's obsolete now. + * bindings/scripts/CodeGeneratorObjC.pm: Add special SVGNumber handling, as it's the first of the converted dynamic SVGAnimatedProperty types that's not in WebCore namespace. + * bindings/scripts/CodeGeneratorV8.pm: Use AvoidInclusionOfType method from CodeGenerator.pm, remove special SVGNumber handling, that's obsolete now. + * rendering/svg/SVGTextLayoutAttributesBuilder.cpp: + (WebCore::extractFloatValuesFromSVGNumberList): Adapt to SVGNumberList change, which is a plain Vector<float> now. + * svg/DeprecatedSVGAnimatedPropertyTraits.h: Remove SVGAnimatedNumber/SVGAnimatedNumberList handling. + * svg/DeprecatedSVGAnimatedTemplate.h: Ditto. + * svg/SVGAnimatedNumber.h: Added. + * svg/SVGAnimatedNumber.idl: Enable StrictTypeChecking. + * svg/SVGAnimatedNumberList.h: Added. + * svg/SVGAnimatedNumberList.idl: Ditto. + * svg/SVGComponentTransferFunctionElement.cpp: Switch animated float properties to the new SVGAnimatedNumber(List). + (WebCore::SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement): + (WebCore::SVGComponentTransferFunctionElement::parseMappedAttribute): + (WebCore::SVGComponentTransferFunctionElement::transferFunction): + * svg/SVGComponentTransferFunctionElement.h: + * svg/SVGFEColorMatrixElement.cpp: Ditto. + (WebCore::SVGFEColorMatrixElement::SVGFEColorMatrixElement): + (WebCore::SVGFEColorMatrixElement::parseMappedAttribute): + (WebCore::SVGFEColorMatrixElement::build): + * svg/SVGFEColorMatrixElement.h: + * svg/SVGFECompositeElement.h: Ditto. + * svg/SVGFEConvolveMatrixElement.cpp: Ditto. + (WebCore::SVGFEConvolveMatrixElement::SVGFEConvolveMatrixElement): + (WebCore::SVGFEConvolveMatrixElement::kernelUnitLengthXIdentifier): Added, replacing char[] hack by a static atomic string. + (WebCore::SVGFEConvolveMatrixElement::kernelUnitLengthYIdentifier): Ditto. + (WebCore::SVGFEConvolveMatrixElement::parseMappedAttribute): + (WebCore::SVGFEConvolveMatrixElement::build): + * svg/SVGFEConvolveMatrixElement.h: Switch animated float properties to the new SVGAnimatedNumber(List). + * svg/SVGFEDiffuseLightingElement.cpp: Ditto. + (WebCore::SVGFEDiffuseLightingElement::kernelUnitLengthXIdentifier): Remove trailing whitespace. + (WebCore::SVGFEDiffuseLightingElement::kernelUnitLengthYIdentifier): Ditto. + * svg/SVGFEDiffuseLightingElement.h: Switch animated float properties to the new SVGAnimatedNumber(List). + * svg/SVGFEDisplacementMapElement.h: Ditto. + * svg/SVGFEGaussianBlurElement.cpp: Ditto. + (WebCore::SVGFEGaussianBlurElement::stdDeviationXIdentifier): Remove trailing whitespace. + (WebCore::SVGFEGaussianBlurElement::stdDeviationYIdentifier): Ditto. + * svg/SVGFEGaussianBlurElement.h: Switch animated float properties to the new SVGAnimatedNumber(List). + * svg/SVGFELightElement.h: Ditto. + * svg/SVGFEMorphologyElement.cpp: + (WebCore::SVGFEMorphologyElement::radiusXIdentifier): Added, replacing char[] hack by a static atomic string. + (WebCore::SVGFEMorphologyElement::radiusYIdentifier): Ditto. + * svg/SVGFEMorphologyElement.h: Switch animated float properties to the new SVGAnimatedNumber(List). + * svg/SVGFEOffsetElement.h: Ditto. + * svg/SVGFESpecularLightingElement.cpp: + (WebCore::SVGFESpecularLightingElement::kernelUnitLengthXIdentifier): Remove trailing whitespace. + (WebCore::SVGFESpecularLightingElement::kernelUnitLengthYIdentifier): Ditto. + * svg/SVGFESpecularLightingElement.h: Switch animated float properties to the new SVGAnimatedNumber(List). + * svg/SVGFETurbulenceElement.cpp: + (WebCore::SVGFETurbulenceElement::baseFrequencyXIdentifier): Remove trailing whitespace. + (WebCore::SVGFETurbulenceElement::baseFrequencyYIdentifier): Ditto. + * svg/SVGFETurbulenceElement.h: Switch animated float properties to the new SVGAnimatedNumber(List). + * svg/SVGFilterElement.cpp: + (WebCore::SVGFilterElement::filterResXIdentifier): Remove trailing whitespace. + (WebCore::SVGFilterElement::filterResYIdentifier): Ditto. + * svg/SVGLengthList.idl: Remove leftover [SVGListProperty] marker. + * svg/SVGMarkerElement.cpp: + (WebCore::SVGMarkerElement::orientTypeIdentifier): Remove trailing whitespace. + (WebCore::SVGMarkerElement::orientAngleIdentifier): Ditto. + * svg/SVGNumber.idl: Remove [PODType] marker, add StrictTypeChecking. + * svg/SVGNumberList.cpp: Convert from SVGPODList<RefPtr<SVGPODListItem<float> > > to plain Vector<float>, just like it has been done for SVGLengthList before. + (WebCore::SVGNumberList::parse): + (WebCore::SVGNumberList::valueAsString): + * svg/SVGNumberList.h: + (WebCore::SVGNumberList::SVGNumberList): + * svg/SVGPathElement.h: Switch animated float properties to the new SVGAnimatedNumber(List). + * svg/SVGStopElement.h: Ditto. + * svg/SVGTextPositioningElement.cpp: Switch animated float properties to the new SVGAnimatedNumber(List). + (WebCore::SVGTextPositioningElement::SVGTextPositioningElement): + (WebCore::SVGTextPositioningElement::parseMappedAttribute): + * svg/SVGTextPositioningElement.h: Ditto. + * svg/properties/SVGPropertyTraits.h: Add SVGNumberList handling. + +2010-10-29 Daniel Bates <dbates@rim.com> + + No review, rolling out 70971. + http://trac.webkit.org/changeset/70971 + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Rolling out changeset 70971 <http://trac.webkit.org/changeset/70971> since + it caused layout test failures on all bots. In particular, the + child count in a generated frame name differs after this patch. We need + to look into this further. + + Test: fast/frames/iframe-set-inner-html.html + + * html/HTMLFrameElementBase.cpp: + (WebCore::HTMLFrameElementBase::openURL): + (WebCore::HTMLFrameElementBase::setName): + * html/HTMLFrameElementBase.h: + * loader/DocumentLoader.cpp: + (WebCore::DocumentLoader::mainResource): + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::loadURLIntoChildFrame): + (WebCore::FrameLoader::commitProvisionalLoad): + * loader/HistoryController.cpp: + (WebCore::HistoryController::saveDocumentState): + (WebCore::HistoryController::restoreDocumentState): + (WebCore::HistoryController::createItem): + (WebCore::HistoryController::currentFramesMatchItem): + * loader/ProgressTracker.cpp: + (WebCore::ProgressTracker::progressStarted): + (WebCore::ProgressTracker::progressCompleted): + * loader/archive/cf/LegacyWebArchive.cpp: + (WebCore::LegacyWebArchive::create): + * page/FrameTree.cpp: + (WebCore::FrameTree::setName): + (WebCore::FrameTree::clearName): + (WebCore::FrameTree::uniqueChildName): + (WebCore::FrameTree::child): + (WebCore::FrameTree::find): + * page/FrameTree.h: + (WebCore::FrameTree::name): + +2010-10-28 Antonio Gomes <agomes@rim.com> + + Reviewed by Ojan Vafai. + + Needs a "LinuxEditingBehavior", perhaps with a better name + https://bugs.webkit.org/show_bug.cgi?id=36627 + + Added EditingUnixBehavior editing type aim to cover the cases when + neither Mac or Windows behaviors are appropriated. + + It was decided to name it Unix not Linux. + + No new tests. The current editing tests that involve platform specific + bahaviors are coded so that they go through all editing behavior + types possible. There will be a follow up bug where all of them will + be updated to include the new editing behavior ("unix"). + + * editing/EditingBehaviorTypes.h: + * page/Settings.cpp: + (WebCore::editingBehaviorTypeForPlatform): + (WebCore::Settings::Settings): + +2010-10-29 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Fixes an issue where the window.name of an unnamed frame returns + a unique generated name that is used internally to identify the + frame. Instead, we should return an empty string as implied by + section 5.1.6 of the HTML5 spec. (http://www.w3.org/TR/html5/browsers.html#browsing-context-names). + This section describes that a browsing context can have no name or be + the empty string. + + * html/HTMLFrameElementBase.cpp: + (WebCore::HTMLFrameElementBase::openURL): Removed ASSERT for empty + frame name since this is valid as per the HTML5 spec. + (WebCore::HTMLFrameElementBase::setName): Removed the call to FrameTree::uniqueChildName() + since the loader code no longer depends on the frame name being unique. + * html/HTMLFrameElementBase.h: + * loader/DocumentLoader.cpp: + (WebCore::DocumentLoader::mainResource): Use FrameTree::uniqueName(). + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::loadURLIntoChildFrame): Ditto. + (WebCore::FrameLoader::commitProvisionalLoad): Ditto. + * loader/HistoryController.cpp: + (WebCore::HistoryController::saveDocumentState): Ditto. + (WebCore::HistoryController::restoreDocumentState): Ditto. + (WebCore::HistoryController::createItem): + (WebCore::HistoryController::currentFramesMatchItem): Ditto. + * loader/ProgressTracker.cpp: + (WebCore::ProgressTracker::progressStarted): Ditto. + (WebCore::ProgressTracker::progressCompleted): Ditto. + * loader/archive/cf/LegacyWebArchive.cpp: + (WebCore::LegacyWebArchive::create): Ditto. + * page/FrameTree.cpp: + (WebCore::FrameTree::setName): Modified to store the DOM-specified + name of the frame. + (WebCore::FrameTree::clearName): + (WebCore::FrameTree::uniqueChildName): Use FrameTree::uniqueName(). + (WebCore::FrameTree::child): Ditto. + (WebCore::FrameTree::find): Ditto. + * page/FrameTree.h: + (WebCore::FrameTree::uniqueName): Added. + +2010-10-29 Darin Adler <darin@apple.com> + + Try to fix build. + + * page/ContextMenuController.cpp: Added include of BackForwardController.h. + * page/DOMWindow.cpp: Ditto. + * page/History.cpp: Ditto. + * platform/ContextMenu.cpp: Ditto. + +2010-10-29 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + More back/forward refactoring + + * WebCore.exp.in: Updated. + + * GNUmakefile.am: Removed BackForwardControllerClient.h. + * WebCore.gypi: Ditto. + * WebCore.pro: Ditto. + * WebCore.vcproj/WebCore.vcproj: Ditto. + * WebCore.xcodeproj/project.pbxproj: Ditto. + + * history/BackForwardControllerClient.h: Removed. + + * history/BackForwardController.cpp: + (WebCore::BackForwardController::BackForwardController): + Set up just m_client. + (WebCore::BackForwardController::~BackForwardController): + Removed call to backForwardControllerDestroyed. + (WebCore::BackForwardController::canGoBackOrForward): Added. + (WebCore::BackForwardController::goBackOrForward): Added. + (WebCore::BackForwardController::goBack): Added. + (WebCore::BackForwardController::goForward): Added. + (WebCore::BackForwardController::addItem): Added. + (WebCore::BackForwardController::setCurrentItem): Added. + (WebCore::BackForwardController::count): Added. + (WebCore::BackForwardController::backCount): Added. + (WebCore::BackForwardController::forwardCount): Added. + (WebCore::BackForwardController::itemAtIndex): Added. + (WebCore::BackForwardController::isActive): Added. + (WebCore::BackForwardController::close): Added. + + * history/BackForwardController.h: Added functions from Page + and BackForwardList that should be called here instead. + Note that BackForwardList is to be renamed BackForwardClient soon. + + * history/BackForwardList.h: Removed many now-unneeded + virtual functions. + + * history/BackForwardListImpl.h: Moved BackForwardListClient + in here. + + * history/PageCache.cpp: + (WebCore::logCanCachePageDecision): Use backForward(). + (WebCore::PageCache::canCache): Ditto. + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::transitionToCommitted): Removed unneeded + null check of backFowardList, which is never null. + (WebCore::FrameLoader::checkLoadCompleteForThisFrame): Use backForward. + (WebCore::FrameLoader::didFirstLayout): Ditto. + (WebCore::FrameLoader::continueLoadAfterNavigationPolicy): Ditto. + (WebCore::FrameLoader::checkDidPerformFirstNavigation): Ditto. + * loader/HistoryController.cpp: + (WebCore::HistoryController::goToItem): Ditto. + (WebCore::HistoryController::updateForStandardLoad): Ditto. + (WebCore::HistoryController::updateForRedirectWithLockedBackForwardList): Ditto. + (WebCore::HistoryController::updateBackForwardListClippedAtTarget): Ditto. + (WebCore::HistoryController::pushState): Ditto. + * loader/NavigationScheduler.cpp: + (WebCore::ScheduledHistoryNavigation::fire): Ditto. + (WebCore::NavigationScheduler::scheduleHistoryNavigation): Ditto. + * page/ContextMenuController.cpp: + (WebCore::ContextMenuController::contextMenuItemSelected): Ditto. + * page/DOMWindow.cpp: + (WebCore::DOMWindow::close): Ditto. + * page/History.cpp: + (WebCore::History::length): Ditto. + + * page/Page.cpp: + (WebCore::Page::Page): Use more adoptPtr. Use backForwardClient instead of + backForwardControllerClient. + (WebCore::Page::~Page): Use backForward. + (WebCore::Page::backForwardList): Ditto. + (WebCore::Page::goBack): Ditto. + (WebCore::Page::goForward): Ditto. + (WebCore::Page::canGoBackOrForward): Ditto. + (WebCore::Page::goBackOrForward): Ditto. + (WebCore::Page::getHistoryLength): Ditto. + (WebCore::Page::PageClients::PageClients): Made non-inline. + (WebCore::Page::PageClients::~PageClients): Ditto. + + * page/Page.h: Made PageClients constructor and destructor non-inline. + Added backForward function. Marked old functions as deprecated. + + * page/Settings.cpp: + (WebCore::Settings::setUsesPageCache): Use backForward. + * platform/ContextMenu.cpp: + (WebCore::ContextMenu::populate): Ditto. + (WebCore::ContextMenu::checkOrEnableIfNeeded): Ditto. + * wml/WMLDoElement.cpp: + (WebCore::WMLDoElement::defaultEventHandler): Ditto. + * wml/WMLDocument.cpp: + (WebCore::WMLDocument::finishedParsing): Ditto. + * wml/WMLPageState.cpp: + (WebCore::WMLPageState::reset): Ditto. + (WebCore::tryAccessHistoryURLs): Ditto. + * wml/WMLPrevElement.cpp: + (WebCore::WMLPrevElement::executeTask): Ditto. + +2010-10-29 David Hyatt <hyatt@apple.com> + + Reviewed by Sam Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=48663 + + Make repaint invalidation work with vertical lines. Rewrite linesBoundingBox for RenderText and + RenderInline to give the correct rectangle back for vertical lines. Also patch linesVisibleOverflowBoundingBox + to give back the correct rectangle for vertical lines. + + Fix bugs in the overflow accessors of InlineFlowBox when m_overflow was 0. + + Added fast/repaint/inline-vertical-lr-overflow.html + + * rendering/InlineBox.cpp: + (WebCore::InlineBox::adjustForFlippedBlocksWritingMode): + * rendering/InlineFlowBox.h: + (WebCore::InlineFlowBox::logicalLeftVisibleOverflow): + (WebCore::InlineFlowBox::logicalRightVisibleOverflow): + (WebCore::InlineFlowBox::bottomLayoutOverflow): + (WebCore::InlineFlowBox::rightLayoutOverflow): + (WebCore::InlineFlowBox::bottomVisualOverflow): + (WebCore::InlineFlowBox::rightVisualOverflow): + * rendering/RenderBox.cpp: + (WebCore::RenderBox::adjustForFlippedBlocksWritingMode): + * rendering/RenderBox.h: + * rendering/RenderInline.cpp: + (WebCore::RenderInline::linesBoundingBox): + (WebCore::RenderInline::linesVisibleOverflowBoundingBox): + (WebCore::RenderInline::clippedOverflowRectForRepaint): + * rendering/RenderText.cpp: + (WebCore::RenderText::linesBoundingBox): + +2010-10-29 Mike Lawther <mikelawther@chromium.org> + + Reviewed by James Robinson. + + Fix canvas/philip/tests/2d.imageData.get.source.negative + https://bugs.webkit.org/show_bug.cgi?id=48277 + + Handle negative width/height. + See http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#pixel-manipulation + + * html/canvas/CanvasRenderingContext2D.cpp: + (WebCore::CanvasRenderingContext2D::getImageData): + +2010-10-29 Kavita Kanetkar <kkanetkar@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: FileSystem integration + https://bugs.webkit.org/show_bug.cgi?id=45982 + + Adding filesystem support for Inspector under storage tab. This fetches root paths for + temporary and persistent filesystems and allows "reveal folder in OS" option that + launches native file browser. Currently this feature is disabled for non-chromium platforms. + + * CMakeLists.txt: + * English.lproj/localizedStrings.js: + * GNUmakefile.am: + * WebCore.gypi: + * WebCore.pro: + * WebCore.vcproj/WebCore.vcproj: + * inspector/CodeGeneratorInspector.pm: + * inspector/Inspector.idl: + * inspector/InspectorController.cpp: + (WebCore::InspectorController::connectFrontend): + (WebCore::InspectorController::releaseFrontendLifetimeAgents): + * inspector/InspectorController.h: + (WebCore::InspectorController::fileSystemAgent): + * inspector/InspectorFileSystemAgent.cpp: Added. + * inspector/InspectorFileSystemAgent.h: Added. + * inspector/front-end/FileSystemView.js: Added. + * inspector/front-end/Settings.js: + * inspector/front-end/StoragePanel.js: + (WebInspector.StoragePanel): + (WebInspector.StoragePanel.prototype.reset): + (WebInspector.StoragePanel.prototype.addFileSystem): + (WebInspector.StoragePanel.prototype.showFileSystem): + (WebInspector.StoragePanel.prototype.updateFileSystemPath): + (WebInspector.StoragePanel.prototype.updateFileSystemError): + (WebInspector.FileSystemTreeElement): + (WebInspector.FileSystemTreeElement.prototype.onselect): + * inspector/front-end/WebKit.qrc: + * inspector/front-end/inspector.css: + (.file-system-storage-tree-item .icon): + * inspector/front-end/inspector.html: + * inspector/front-end/inspector.js: + (WebInspector.updateResource): + (WebInspector._addFileSystemOrigin): + (WebInspector.didGetFileSystemPath): + (WebInspector.didGetFileSystemError): + (WebInspector.reset): + * platform/AsyncFileSystem.h: + (WebCore::AsyncFileSystem::root): + * platform/FileSystem.h: + * platform/chromium/ChromiumBridge.h: + * platform/chromium/FileSystemChromium.cpp: + (WebCore::revealFolderInOS): + 2010-10-29 Ryosuke Niwa <rniwa@webkit.org> Reviewed by Darin Adler. @@ -6287,6 +12608,116 @@ 2010-10-21 Yury Semikhatsky <yurys@chromium.org> + Reviewed by Pavel Feldman. + + Web Inspector: decouple ScriptArguments from ScriptCallStack + https://bugs.webkit.org/show_bug.cgi?id=48058 + + ScriptCallFrame and ScriptCallStack are now the same for both JSC and V8. + The factory functions that allow to create ScriptCallStack from VM-specific + objects are defined in ScriptCallStackFactory.cpp. + + ScriptArguments class is used for passing arguments from JS code to the native + part. + + No new tests. This refactoring is covered with existing Console tests. + + * WebCore.gypi: + * WebCore.xcodeproj/project.pbxproj: + * bindings/js/ScriptCallFrame.cpp: Removed. + * bindings/js/ScriptCallFrame.h: Removed. + * bindings/js/ScriptCallStack.cpp: Removed. + * bindings/js/ScriptCallStack.h: Removed. + * bindings/js/ScriptCallStackFactory.cpp: Added. + (WebCore::createScriptCallStack): + (WebCore::createScriptArguments): + (WebCore::ScriptCallStack::stackTrace): + * bindings/js/ScriptCallStackFactory.h: Added. + * bindings/js/ScriptState.h: + (WebCore::ScriptStateProtectedPtr::get): + * bindings/scripts/CodeGeneratorJS.pm: + * bindings/scripts/CodeGeneratorV8.pm: + * bindings/v8/ScriptCallFrame.cpp: Removed. + * bindings/v8/ScriptCallFrame.h: Removed. + * bindings/v8/ScriptCallStack.cpp: Removed. + * bindings/v8/ScriptCallStack.h: Removed. + * bindings/v8/ScriptCallStackFactory.cpp: Added. + (WebCore::toScriptCallFrame): + (WebCore::toScriptCallFramesVector): + (WebCore::createScriptCallStack): + (WebCore::createScriptArguments): + (WebCore::ScriptCallStack::stackTrace): + * bindings/v8/ScriptCallStackFactory.h: Added. + * bindings/v8/ScriptController.cpp: + (WebCore::ScriptController::setCaptureCallStackForUncaughtExceptions): + * bindings/v8/ScriptState.h: + (WebCore::ScriptStateProtectedPtr::get): + * bindings/v8/V8ConsoleMessage.cpp: + (WebCore::V8ConsoleMessage::handler): + (WebCore::V8ConsoleMessage::dispatchNow): + * bindings/v8/V8ConsoleMessage.h: + * bindings/v8/custom/V8ConsoleCustom.cpp: + (WebCore::V8Console::traceCallback): + (WebCore::V8Console::assertCallback): + * inspector/ConsoleMessage.cpp: + (WebCore::ConsoleMessage::ConsoleMessage): + (WebCore::ConsoleMessage::addToFrontend): + (WebCore::ConsoleMessage::updateRepeatCountInConsole): + (WebCore::ConsoleMessage::isEqual): + * inspector/ConsoleMessage.h: + * inspector/InspectorController.cpp: + (WebCore::InspectorController::addMessageToConsole): + (WebCore::InspectorController::startGroup): + * inspector/InspectorController.h: + * inspector/ScriptArguments.cpp: Added. + (WebCore::ScriptArguments::ScriptArguments): + (WebCore::ScriptArguments::~ScriptArguments): + (WebCore::ScriptArguments::argumentAt): + (WebCore::ScriptArguments::globalState): + (WebCore::ScriptArguments::getFirstArgumentAsString): + (WebCore::ScriptArguments::isEqual): + * inspector/ScriptArguments.h: Added. + (WebCore::ScriptArguments::argumentCount): + * inspector/ScriptCallFrame.cpp: Added. + (WebCore::ScriptCallFrame::ScriptCallFrame): + (WebCore::ScriptCallFrame::~ScriptCallFrame): + (WebCore::ScriptCallFrame::isEqual): + (WebCore::ScriptCallFrame::buildInspectorObject): + * inspector/ScriptCallFrame.h: Added. + (WebCore::ScriptCallFrame::functionName): + (WebCore::ScriptCallFrame::sourceURL): + (WebCore::ScriptCallFrame::lineNumber): + * inspector/ScriptCallStack.cpp: Added. + (WebCore::ScriptCallStack::ScriptCallStack): + (WebCore::ScriptCallStack::~ScriptCallStack): + (WebCore::ScriptCallStack::at): + (WebCore::ScriptCallStack::size): + (WebCore::ScriptCallStack::isEqual): + (WebCore::ScriptCallStack::buildInspectorObject): + * inspector/ScriptCallStack.h: Added. + * page/Console.cpp: + (WebCore::Console::addMessage): + (WebCore::Console::debug): + (WebCore::Console::error): + (WebCore::Console::info): + (WebCore::Console::log): + (WebCore::Console::dir): + (WebCore::Console::dirxml): + (WebCore::Console::trace): + (WebCore::Console::assertCondition): + (WebCore::Console::count): + (WebCore::Console::markTimeline): + (WebCore::Console::profile): + (WebCore::Console::profileEnd): + (WebCore::Console::timeEnd): + (WebCore::Console::group): + (WebCore::Console::groupCollapsed): + (WebCore::Console::shouldCaptureFullStackTrace): + (WebCore::Console::warn): + * page/Console.h: + +2010-10-21 Yury Semikhatsky <yurys@chromium.org> + Unreviewed. Revert r70232. Chromium compilation failure. 2010-10-21 Yury Semikhatsky <yurys@chromium.org> @@ -80395,7 +86826,7 @@ Reviewed by Gustavo Noronha Silva. - Bug 41340 - [GStreamer] Subtle race condition during seeks + Bug 41340 - [GStreamer] Subtle race condition during seeks https://bugs.webkit.org/show_bug.cgi?id=41340 * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp: diff --git a/WebCore/Configurations/Version.xcconfig b/WebCore/Configurations/Version.xcconfig index c8846df..0a75fe6 100644 --- a/WebCore/Configurations/Version.xcconfig +++ b/WebCore/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 534; -MINOR_VERSION = 11; +MINOR_VERSION = 12; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/WebCore/DerivedSources.cpp b/WebCore/DerivedSources.cpp index 80c1304..dcd0e22 100644 --- a/WebCore/DerivedSources.cpp +++ b/WebCore/DerivedSources.cpp @@ -182,6 +182,7 @@ #include "JSHTMLOptGroupElement.cpp" #include "JSHTMLOptionElement.cpp" #include "JSHTMLOptionsCollection.cpp" +#include "JSHTMLOutputElement.cpp" #include "JSHTMLParagraphElement.cpp" #include "JSHTMLParamElement.cpp" #include "JSHTMLPreElement.cpp" diff --git a/WebCore/DerivedSources.make b/WebCore/DerivedSources.make index 4e732de..ef22c83 100644 --- a/WebCore/DerivedSources.make +++ b/WebCore/DerivedSources.make @@ -227,6 +227,7 @@ DOM_CLASSES = \ HTMLOptGroupElement \ HTMLOptionElement \ HTMLOptionsCollection \ + HTMLOutputElement \ HTMLParagraphElement \ HTMLParamElement \ HTMLPreElement \ @@ -329,7 +330,6 @@ DOM_CLASSES = \ SVGAnimatedNumber \ SVGAnimatedNumberList \ SVGAnimatedPathData \ - SVGAnimatedPoints \ SVGAnimatedPreserveAspectRatio \ SVGAnimatedRect \ SVGAnimatedString \ diff --git a/WebCore/English.lproj/localizedStrings.js b/WebCore/English.lproj/localizedStrings.js Binary files differindex 7403b22..02e2143 100644 --- a/WebCore/English.lproj/localizedStrings.js +++ b/WebCore/English.lproj/localizedStrings.js diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am index 6c1bc35..63d0455 100644 --- a/WebCore/GNUmakefile.am +++ b/WebCore/GNUmakefile.am @@ -28,6 +28,7 @@ webcore_cppflags += \ -I$(srcdir)/WebCore/loader \ -I$(srcdir)/WebCore/loader/appcache \ -I$(srcdir)/WebCore/loader/archive \ + -I$(srcdir)/WebCore/loader/cache \ -I$(srcdir)/WebCore/loader/icon \ -I$(srcdir)/WebCore/mathml \ -I$(srcdir)/WebCore/notifications \ @@ -370,6 +371,8 @@ webcore_built_sources += \ DerivedSources/WebCore/JSHTMLOptionElement.h \ DerivedSources/WebCore/JSHTMLOptionsCollection.cpp \ DerivedSources/WebCore/JSHTMLOptionsCollection.h \ + DerivedSources/WebCore/JSHTMLOutputElement.cpp \ + DerivedSources/WebCore/JSHTMLOutputElement.h \ DerivedSources/WebCore/JSHTMLParagraphElement.cpp \ DerivedSources/WebCore/JSHTMLParagraphElement.h \ DerivedSources/WebCore/JSHTMLParamElement.cpp \ @@ -750,6 +753,7 @@ webcore_sources += \ WebCore/bindings/js/JSHTMLObjectElementCustom.cpp \ WebCore/bindings/js/JSHTMLObjectElementCustom.h \ WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp \ + WebCore/bindings/js/JSHTMLOutputElementCustom.cpp \ WebCore/bindings/js/JSHTMLSelectElementCustom.cpp \ WebCore/bindings/js/JSHTMLSelectElementCustom.h \ WebCore/bindings/js/JSImageConstructor.cpp \ @@ -819,10 +823,8 @@ webcore_sources += \ WebCore/bindings/js/ScheduledAction.h \ WebCore/bindings/js/ScriptCachedFrameData.cpp \ WebCore/bindings/js/ScriptCachedFrameData.h \ - WebCore/bindings/js/ScriptCallFrame.cpp \ - WebCore/bindings/js/ScriptCallFrame.h \ - WebCore/bindings/js/ScriptCallStack.cpp \ - WebCore/bindings/js/ScriptCallStack.h \ + WebCore/bindings/js/ScriptCallStackFactory.cpp \ + WebCore/bindings/js/ScriptCallStackFactory.h \ WebCore/bindings/js/ScriptController.cpp \ WebCore/bindings/js/ScriptController.h \ WebCore/bindings/js/ScriptDebugServer.cpp \ @@ -1109,6 +1111,7 @@ webcore_sources += \ WebCore/dom/DocumentMarker.h \ WebCore/dom/DocumentParser.cpp \ WebCore/dom/DocumentParser.h \ + WebCore/dom/DocumentTiming.h \ WebCore/dom/DocumentType.cpp \ WebCore/dom/DocumentType.h \ WebCore/dom/DOMCoreException.h \ @@ -1278,6 +1281,7 @@ webcore_sources += \ WebCore/editing/CompositeEditCommand.h \ WebCore/editing/CreateLinkCommand.cpp \ WebCore/editing/CreateLinkCommand.h \ + WebCore/editing/CorrectionPanelInfo.h \ WebCore/editing/DeleteButtonController.cpp \ WebCore/editing/DeleteButtonController.h \ WebCore/editing/DeleteButton.cpp \ @@ -1291,6 +1295,8 @@ webcore_sources += \ WebCore/editing/EditCommand.h \ WebCore/editing/EditingBehavior.h \ WebCore/editing/EditingBehaviorTypes.h \ + WebCore/editing/EditingStyle.cpp \ + WebCore/editing/EditingStyle.h \ WebCore/editing/EditorCommand.cpp \ WebCore/editing/Editor.cpp \ WebCore/editing/EditorDeleteAction.h \ @@ -1444,7 +1450,6 @@ webcore_sources += \ WebCore/fileapi/Metadata.h \ WebCore/fileapi/ThreadableBlobRegistry.cpp \ WebCore/fileapi/ThreadableBlobRegistry.h \ - WebCore/history/BackForwardControllerClient.h \ WebCore/history/BackForwardController.cpp \ WebCore/history/BackForwardController.h \ WebCore/history/BackForwardList.h \ @@ -1471,6 +1476,7 @@ webcore_sources += \ WebCore/html/BaseTextInputType.h \ WebCore/html/ButtonInputType.cpp \ WebCore/html/ButtonInputType.h \ + WebCore/html/canvas/ArrayBuffer.h \ WebCore/html/canvas/CanvasContextAttributes.h \ WebCore/html/canvas/CanvasGradient.cpp \ WebCore/html/canvas/CanvasGradient.h \ @@ -1644,6 +1650,8 @@ webcore_sources += \ WebCore/html/HTMLOptionElement.h \ WebCore/html/HTMLOptionsCollection.cpp \ WebCore/html/HTMLOptionsCollection.h \ + WebCore/html/HTMLOutputElement.cpp \ + WebCore/html/HTMLOutputElement.h \ WebCore/html/HTMLParagraphElement.cpp \ WebCore/html/HTMLParagraphElement.h \ WebCore/html/HTMLParamElement.cpp \ @@ -1786,6 +1794,8 @@ webcore_sources += \ WebCore/html/TimeRanges.h \ WebCore/html/URLInputType.cpp \ WebCore/html/URLInputType.h \ + WebCore/html/ValidationMessage.cpp \ + WebCore/html/ValidationMessage.h \ WebCore/html/ValidityState.cpp \ WebCore/html/ValidityState.h \ WebCore/html/VoidCallback.h \ @@ -1844,6 +1854,8 @@ webcore_sources += \ WebCore/inspector/InspectorDOMAgent.h \ WebCore/inspector/InspectorDOMStorageResource.cpp \ WebCore/inspector/InspectorDOMStorageResource.h \ + WebCore/inspector/InspectorFileSystemAgent.cpp \ + WebCore/inspector/InspectorFileSystemAgent.h \ WebCore/inspector/InspectorFrontendClient.h \ WebCore/inspector/InspectorFrontendClientLocal.cpp \ WebCore/inspector/InspectorFrontendClientLocal.h \ @@ -1853,8 +1865,6 @@ webcore_sources += \ WebCore/inspector/InspectorInstrumentation.h \ WebCore/inspector/InspectorProfilerAgent.cpp \ WebCore/inspector/InspectorProfilerAgent.h \ - WebCore/inspector/InspectorResource.cpp \ - WebCore/inspector/InspectorResource.h \ WebCore/inspector/InspectorResourceAgent.cpp \ WebCore/inspector/InspectorResourceAgent.h \ WebCore/inspector/InspectorState.cpp \ @@ -1868,8 +1878,14 @@ webcore_sources += \ WebCore/inspector/InspectorValues.cpp \ WebCore/inspector/InspectorValues.h \ WebCore/inspector/InspectorWorkerResource.h \ + WebCore/inspector/ScriptArguments.cpp \ + WebCore/inspector/ScriptArguments.h \ WebCore/inspector/ScriptBreakpoint.cpp \ WebCore/inspector/ScriptBreakpoint.h \ + WebCore/inspector/ScriptCallFrame.cpp \ + WebCore/inspector/ScriptCallFrame.h \ + WebCore/inspector/ScriptCallStack.cpp \ + WebCore/inspector/ScriptCallStack.h \ WebCore/inspector/ScriptDebugListener.h \ WebCore/inspector/ScriptGCEventListener.h \ WebCore/inspector/TimelineRecordFactory.cpp \ @@ -1895,29 +1911,29 @@ webcore_sources += \ WebCore/loader/archive/ArchiveResourceCollection.h \ WebCore/loader/archive/ArchiveResource.cpp \ WebCore/loader/archive/ArchiveResource.h \ - WebCore/loader/Cache.cpp \ - WebCore/loader/CachedCSSStyleSheet.cpp \ - WebCore/loader/CachedCSSStyleSheet.h \ - WebCore/loader/CachedFont.cpp \ - WebCore/loader/CachedFont.h \ - WebCore/loader/CachedImage.cpp \ - WebCore/loader/CachedImage.h \ + WebCore/loader/cache/MemoryCache.cpp \ + WebCore/loader/cache/CachedCSSStyleSheet.cpp \ + WebCore/loader/cache/CachedCSSStyleSheet.h \ + WebCore/loader/cache/CachedFont.cpp \ + WebCore/loader/cache/CachedFont.h \ + WebCore/loader/cache/CachedImage.cpp \ + WebCore/loader/cache/CachedImage.h \ + WebCore/loader/cache/CachedResourceClient.h \ + WebCore/loader/cache/CachedResourceClientWalker.cpp \ + WebCore/loader/cache/CachedResourceClientWalker.h \ + WebCore/loader/cache/CachedResource.cpp \ + WebCore/loader/cache/CachedResource.h \ + WebCore/loader/cache/CachedResourceHandle.cpp \ + WebCore/loader/cache/CachedResourceHandle.h \ + WebCore/loader/cache/CachedResourceLoader.cpp \ + WebCore/loader/cache/CachedResourceLoader.h \ + WebCore/loader/cache/CachedScript.cpp \ + WebCore/loader/cache/CachedScript.h \ + WebCore/loader/cache/CachedXSLStyleSheet.cpp \ + WebCore/loader/cache/CachedXSLStyleSheet.h \ + WebCore/loader/cache/MemoryCache.h \ + WebCore/loader/cache/CachePolicy.h \ WebCore/loader/CachedMetadata.h \ - WebCore/loader/CachedResourceClient.h \ - WebCore/loader/CachedResourceClientWalker.cpp \ - WebCore/loader/CachedResourceClientWalker.h \ - WebCore/loader/CachedResource.cpp \ - WebCore/loader/CachedResource.h \ - WebCore/loader/CachedResourceHandle.cpp \ - WebCore/loader/CachedResourceHandle.h \ - WebCore/loader/CachedResourceLoader.cpp \ - WebCore/loader/CachedResourceLoader.h \ - WebCore/loader/CachedScript.cpp \ - WebCore/loader/CachedScript.h \ - WebCore/loader/CachedXSLStyleSheet.cpp \ - WebCore/loader/CachedXSLStyleSheet.h \ - WebCore/loader/Cache.h \ - WebCore/loader/CachePolicy.h \ WebCore/loader/CrossOriginAccessControl.cpp \ WebCore/loader/CrossOriginAccessControl.h \ WebCore/loader/CrossOriginPreflightResultCache.cpp \ @@ -2276,6 +2292,7 @@ webcore_sources += \ WebCore/platform/graphics/FontFamily.h \ WebCore/platform/graphics/FontFastPath.cpp \ WebCore/platform/graphics/Font.h \ + WebCore/platform/graphics/FontOrientation.h \ WebCore/platform/graphics/FontRenderingMode.h \ WebCore/platform/graphics/FontSelector.h \ WebCore/platform/graphics/FontSmoothingMode.h \ @@ -2438,6 +2455,7 @@ webcore_sources += \ WebCore/platform/PopupMenu.h \ WebCore/platform/PopupMenuStyle.h \ WebCore/platform/PurgeableBuffer.h \ + WebCore/platform/PurgePriority.h \ WebCore/platform/SchemeRegistry.cpp \ WebCore/platform/SchemeRegistry.h \ WebCore/platform/ScrollAnimator.cpp \ @@ -2949,6 +2967,8 @@ webcore_sources += \ WebCore/storage/IDBObjectStore.h \ WebCore/storage/IDBRequest.cpp \ WebCore/storage/IDBRequest.h \ + WebCore/storage/IDBSQLiteDatabase.cpp \ + WebCore/storage/IDBSQLiteDatabase.h \ WebCore/storage/IDBSuccessEvent.cpp \ WebCore/storage/IDBSuccessEvent.h \ WebCore/storage/IDBTransactionBackendInterface.h \ @@ -3035,10 +3055,13 @@ webcore_sources += \ WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h \ WebCore/svg/properties/SVGAnimatedPropertyTearOff.h \ WebCore/svg/properties/SVGAnimatedStaticPropertyTearOff.h \ + WebCore/svg/properties/SVGListProperty.h \ WebCore/svg/properties/SVGListPropertyTearOff.h \ WebCore/svg/properties/SVGProperty.h \ WebCore/svg/properties/SVGPropertyTearOff.h \ WebCore/svg/properties/SVGPropertyTraits.h \ + WebCore/svg/properties/SVGStaticListPropertyTearOff.h \ + WebCore/svg/properties/SVGStaticPropertyTearOff.h \ WebCore/svg/RadialGradientAttributes.h \ WebCore/svg/SVGAElement.cpp \ WebCore/svg/SVGAElement.h \ @@ -3054,11 +3077,13 @@ webcore_sources += \ WebCore/svg/SVGAnimatedInteger.h \ WebCore/svg/SVGAnimatedLength.h \ WebCore/svg/SVGAnimatedLengthList.h \ + WebCore/svg/SVGAnimatedNumber.h \ + WebCore/svg/SVGAnimatedNumberList.h \ WebCore/svg/SVGAnimatedPathData.cpp \ WebCore/svg/SVGAnimatedPathData.h \ - WebCore/svg/SVGAnimatedPoints.cpp \ - WebCore/svg/SVGAnimatedPoints.h \ + WebCore/svg/SVGAnimatedPreserveAspectRatio.h \ WebCore/svg/SVGAnimatedRect.h \ + WebCore/svg/SVGAnimatedString.h \ WebCore/svg/SVGAnimateElement.cpp \ WebCore/svg/SVGAnimateElement.h \ WebCore/svg/SVGAnimateMotionElement.cpp \ @@ -3493,6 +3518,8 @@ webcoregtk_sources += \ WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp \ WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.h \ WebCore/accessibility/gtk/AXObjectCacheAtk.cpp \ + WebCore/accessibility/gtk/WebKitAccessibleHyperlink.h \ + WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp \ WebCore/bindings/js/ScriptControllerGtk.cpp \ WebCore/page/gtk/DragControllerGtk.cpp \ WebCore/page/gtk/EventHandlerGtk.cpp \ @@ -3515,8 +3542,8 @@ webcoregtk_sources += \ WebCore/platform/graphics/cairo/OwnPtrCairo.h \ WebCore/platform/graphics/cairo/PathCairo.cpp \ WebCore/platform/graphics/cairo/PatternCairo.cpp \ - WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp \ - WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h \ + WebCore/platform/graphics/cairo/RefPtrCairo.cpp \ + WebCore/platform/graphics/cairo/RefPtrCairo.h \ WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp \ WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp \ WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h \ @@ -4162,7 +4189,6 @@ webcore_built_sources += \ DerivedSources/WebCore/JSSVGAnimatedNumberList.cpp \ DerivedSources/WebCore/JSSVGAnimatedNumberList.h \ DerivedSources/WebCore/JSSVGAnimatedPathData.h \ - DerivedSources/WebCore/JSSVGAnimatedPoints.h \ DerivedSources/WebCore/JSSVGAnimatedPreserveAspectRatio.cpp \ DerivedSources/WebCore/JSSVGAnimatedPreserveAspectRatio.h \ DerivedSources/WebCore/JSSVGAnimatedRect.cpp \ diff --git a/WebCore/WebCore.exp.in b/WebCore/WebCore.exp.in index 66dc594..217f328 100644 --- a/WebCore/WebCore.exp.in +++ b/WebCore/WebCore.exp.in @@ -200,6 +200,9 @@ __ZN7WebCore11HistoryItemC1ERKN3WTF6StringES4_d __ZN7WebCore11HistoryItemC1ERKNS_4KURLERKN3WTF6StringES7_S7_ __ZN7WebCore11HistoryItemC1Ev __ZN7WebCore11HistoryItemD1Ev +__ZN7WebCore11MemoryCache13getStatisticsEv +__ZN7WebCore11MemoryCache11setDisabledEb +__ZN7WebCore11MemoryCache13setCapacitiesEjjj __ZN7WebCore11RenderLayer19scrollRectToVisibleERKNS_7IntRectEbRKNS_15ScrollAlignmentES6_ __ZN7WebCore11globalPointERK8_NSPointP8NSWindow __ZN7WebCore11toUserSpaceERK7_NSRectP8NSWindow @@ -431,13 +434,25 @@ __ZN7WebCore18SearchPopupMenuMacC1EPNS_15PopupMenuClientE __ZN7WebCore18isStartOfParagraphERKNS_15VisiblePositionENS_8Position27EditingBoundaryCrossingRuleE __ZN7WebCore18pluginScriptObjectEPN3JSC9ExecStateEPNS_13JSHTMLElementE __ZN7WebCore18proxyServersForURLERKNS_4KURLEPKNS_17NetworkingContextE -__ZN7WebCore19AnimationController16resumeAnimationsEPNS_8DocumentE -__ZN7WebCore19AnimationController17suspendAnimationsEPNS_8DocumentE +__ZN7WebCore19AnimationController16resumeAnimationsEv +__ZN7WebCore19AnimationController17suspendAnimationsEv __ZN7WebCore19AnimationController20pauseAnimationAtTimeEPNS_12RenderObjectERKN3WTF6StringEd __ZN7WebCore19AnimationController21pauseTransitionAtTimeEPNS_12RenderObjectERKN3WTF6StringEd +__ZN7WebCore19BackForwardListImpl10removeItemEPNS_11HistoryItemE +__ZN7WebCore19BackForwardListImpl10setEnabledEb __ZN7WebCore19BackForwardListImpl11currentItemEv __ZN7WebCore19BackForwardListImpl11forwardItemEv +__ZN7WebCore19BackForwardListImpl11setCapacityEi +__ZN7WebCore19BackForwardListImpl12containsItemEPNS_11HistoryItemE +__ZN7WebCore19BackForwardListImpl17backListWithLimitEiRN3WTF6VectorINS1_6RefPtrINS_11HistoryItemEEELm0EEE +__ZN7WebCore19BackForwardListImpl20forwardListWithLimitEiRN3WTF6VectorINS1_6RefPtrINS_11HistoryItemEEELm0EEE +__ZN7WebCore19BackForwardListImpl6closedEv +__ZN7WebCore19BackForwardListImpl6goBackEv +__ZN7WebCore19BackForwardListImpl7enabledEv +__ZN7WebCore19BackForwardListImpl7entriesEv __ZN7WebCore19BackForwardListImpl8backItemEv +__ZN7WebCore19BackForwardListImpl8capacityEv +__ZN7WebCore19BackForwardListImpl9goForwardEv __ZN7WebCore19BackForwardListImplC1EPNS_4PageE __ZN7WebCore19CSSStyleDeclaration11setPropertyERKN3WTF6StringES4_Ri __ZN7WebCore19ResourceRequestBase11setHTTPBodyEN3WTF10PassRefPtrINS_8FormDataEEE @@ -463,6 +478,7 @@ __ZN7WebCore20ResourceResponseBase24setExpectedContentLengthEx __ZN7WebCore20ResourceResponseBaseC2Ev __ZN7WebCore20SpaceSplitStringData12createVectorEv __ZN7WebCore20protocolIsJavaScriptERKN3WTF6StringE +__ZN7WebCore21BackForwardController11itemAtIndexEi __ZN7WebCore21PlatformKeyboardEvent24disambiguateKeyDownEventENS0_4TypeEb __ZN7WebCore21PlatformKeyboardEventC1EP7NSEvent __ZN7WebCore21SVGDocumentExtensions21sampleAnimationAtTimeERKN3WTF6StringEPNS_14SVGSMILElementEd @@ -581,6 +597,8 @@ __ZN7WebCore4Node17stopIgnoringLeaksEv __ZN7WebCore4Node18startIgnoringLeaksEv __ZN7WebCore4Node19setNeedsStyleRecalcENS_15StyleChangeTypeE __ZN7WebCore4Page10findStringERKN3WTF6StringENS1_19TextCaseSensitivityENS_13FindDirectionEb +__ZN7WebCore4Page11PageClientsC1Ev +__ZN7WebCore4Page11PageClientsD1Ev __ZN7WebCore4Page12setGroupNameERKN3WTF6StringE __ZN7WebCore4Page13didStopPluginEPNS_14HaltablePluginE __ZN7WebCore4Page14didStartPluginEPNS_14HaltablePluginE @@ -614,9 +632,6 @@ __ZN7WebCore4coreEP20NSURLProtectionSpace __ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_19CSSStyleDeclarationE __ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_5RangeE __ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_8NodeListE -__ZN7WebCore5Cache11setDisabledEb -__ZN7WebCore5Cache13getStatisticsEv -__ZN7WebCore5Cache13setCapacitiesEjjj __ZN7WebCore5Frame10createViewERKNS_7IntSizeERKNS_5ColorEbS3_bNS_13ScrollbarModeEbS7_b __ZN7WebCore5Frame14frameForWidgetEPKNS_6WidgetE __ZN7WebCore5Frame17setPageZoomFactorEf @@ -1023,6 +1038,8 @@ __ZNK7WebCore20ResourceResponseBase21expectedContentLengthEv __ZNK7WebCore20ResourceResponseBase3urlEv __ZNK7WebCore20ResourceResponseBase6isHTTPEv __ZNK7WebCore20ResourceResponseBase8mimeTypeEv +__ZNK7WebCore21BackForwardController12forwardCountEv +__ZNK7WebCore21BackForwardController9backCountEv __ZNK7WebCore21UserContentURLPattern7matchesERKNS_4KURLE __ZNK7WebCore23FrameLoaderStateMachine15firstLayoutDoneEv __ZNK7WebCore23FrameLoaderStateMachine23committingFirstRealLoadEv @@ -1208,9 +1225,22 @@ __ZNK7WebCore18RenderLayerBacking20compositingLayerTypeEv #if ENABLE(CONTEXT_MENUS) __ZN7WebCore11ContextMenu22setPlatformDescriptionEP14NSMutableArray __ZN7WebCore12EventHandler20sendContextMenuEventEP7NSEvent +__ZN7WebCore12EventHandler20sendContextMenuEventERKNS_18PlatformMouseEventE __ZN7WebCore15ContextMenuItem26releasePlatformDescriptionEv +__ZN7WebCore15ContextMenuItemC1ENS_19ContextMenuItemTypeENS_17ContextMenuActionERKN3WTF6StringEPNS_11ContextMenuE +__ZN7WebCore15ContextMenuItemD1Ev __ZN7WebCore21ContextMenuController16clearContextMenuEv +__ZN7WebCore21ContextMenuController23contextMenuItemSelectedEPNS_15ContextMenuItemE +__ZN7WebCore21contextMenuItemVectorEP14NSMutableArray +__ZN7WebCore6Chrome15showContextMenuEv __ZNK7WebCore11ContextMenu19platformDescriptionEv +__ZNK7WebCore11ContextMenu21checkOrEnableIfNeededERNS_15ContextMenuItemE +__ZNK7WebCore15ContextMenuItem15platformSubMenuEv +__ZNK7WebCore15ContextMenuItem4typeEv +__ZNK7WebCore15ContextMenuItem5titleEv +__ZNK7WebCore15ContextMenuItem6actionEv +__ZNK7WebCore15ContextMenuItem7checkedEv +__ZNK7WebCore15ContextMenuItem7enabledEv #endif #if ENABLE(DASHBOARD_SUPPORT) diff --git a/WebCore/WebCore.gyp/WebCore.gyp b/WebCore/WebCore.gyp/WebCore.gyp index ce77c8f..4792a2a 100644 --- a/WebCore/WebCore.gyp/WebCore.gyp +++ b/WebCore/WebCore.gyp/WebCore.gyp @@ -134,6 +134,7 @@ '../loader', '../loader/appcache', '../loader/archive', + '../loader/cache', '../loader/icon', '../mathml', '../notifications', @@ -720,6 +721,7 @@ '../../JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp:wtf', '<(chromium_src_dir)/build/temp_gyp/googleurl.gyp:googleurl', '<(chromium_src_dir)/skia/skia.gyp:skia', + '<(chromium_src_dir)/third_party/iccjpeg/iccjpeg.gyp:iccjpeg', '<(chromium_src_dir)/third_party/libjpeg/libjpeg.gyp:libjpeg', '<(chromium_src_dir)/third_party/libpng/libpng.gyp:libpng', '<(chromium_src_dir)/third_party/libxml/libxml.gyp:libxml', @@ -831,6 +833,7 @@ '../../JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp:wtf', '<(chromium_src_dir)/build/temp_gyp/googleurl.gyp:googleurl', '<(chromium_src_dir)/skia/skia.gyp:skia', + '<(chromium_src_dir)/third_party/iccjpeg/iccjpeg.gyp:iccjpeg', '<(chromium_src_dir)/third_party/libjpeg/libjpeg.gyp:libjpeg', '<(chromium_src_dir)/third_party/libwebp/libwebp.gyp:libwebp', '<(chromium_src_dir)/third_party/libpng/libpng.gyp:libpng', @@ -847,6 +850,7 @@ '../../JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp:wtf', '<(chromium_src_dir)/build/temp_gyp/googleurl.gyp:googleurl', '<(chromium_src_dir)/skia/skia.gyp:skia', + '<(chromium_src_dir)/third_party/iccjpeg/iccjpeg.gyp:iccjpeg', '<(chromium_src_dir)/third_party/libjpeg/libjpeg.gyp:libjpeg', '<(chromium_src_dir)/third_party/libwebp/libwebp.gyp:libwebp', '<(chromium_src_dir)/third_party/libpng/libpng.gyp:libpng', diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi index 934db17..faa339a 100644 --- a/WebCore/WebCore.gypi +++ b/WebCore/WebCore.gypi @@ -174,6 +174,7 @@ 'html/HTMLOptGroupElement.idl', 'html/HTMLOptionElement.idl', 'html/HTMLOptionsCollection.idl', + 'html/HTMLOutputElement.idl', 'html/HTMLParagraphElement.idl', 'html/HTMLParamElement.idl', 'html/HTMLPreElement.idl', @@ -216,6 +217,7 @@ 'html/canvas/WebGLActiveInfo.idl', 'html/canvas/WebGLBuffer.idl', 'html/canvas/WebGLContextAttributes.idl', + 'html/canvas/WebGLContextEvent.idl', 'html/canvas/WebGLFramebuffer.idl', 'html/canvas/WebGLProgram.idl', 'html/canvas/WebGLRenderbuffer.idl', @@ -324,7 +326,6 @@ 'svg/SVGAnimatedNumber.idl', 'svg/SVGAnimatedNumberList.idl', 'svg/SVGAnimatedPathData.idl', - 'svg/SVGAnimatedPoints.idl', 'svg/SVGAnimatedPreserveAspectRatio.idl', 'svg/SVGAnimatedRect.idl', 'svg/SVGAnimatedString.idl', @@ -624,6 +625,7 @@ 'bindings/js/JSHTMLObjectElementCustom.cpp', 'bindings/js/JSHTMLObjectElementCustom.h', 'bindings/js/JSHTMLOptionsCollectionCustom.cpp', + 'bindings/js/JSHTMLOutputElementCustom.cpp', 'bindings/js/JSHTMLSelectElementCustom.cpp', 'bindings/js/JSHTMLSelectElementCustom.h', 'bindings/js/JSImageConstructor.cpp', @@ -701,10 +703,6 @@ 'bindings/js/ScheduledAction.h', 'bindings/js/ScriptCachedFrameData.cpp', 'bindings/js/ScriptCachedFrameData.h', - 'bindings/js/ScriptCallFrame.cpp', - 'bindings/js/ScriptCallFrame.h', - 'bindings/js/ScriptCallStack.cpp', - 'bindings/js/ScriptCallStack.h', 'bindings/js/ScriptController.cpp', 'bindings/js/ScriptController.h', 'bindings/js/ScriptControllerGtk.cpp', @@ -808,6 +806,7 @@ 'bindings/v8/custom/V8HTMLOptionElementConstructor.cpp', 'bindings/v8/custom/V8HTMLOptionElementConstructor.h', 'bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp', + 'bindings/v8/custom/V8HTMLOutputElementCustom.cpp', 'bindings/v8/custom/V8HTMLPlugInElementCustom.cpp', 'bindings/v8/custom/V8HTMLSelectElementCustom.cpp', 'bindings/v8/custom/V8HTMLSelectElementCustom.h', @@ -872,10 +871,8 @@ 'bindings/v8/ScopedDOMDataStore.cpp', 'bindings/v8/ScopedDOMDataStore.h', 'bindings/v8/ScriptCachedFrameData.h', - 'bindings/v8/ScriptCallFrame.cpp', - 'bindings/v8/ScriptCallFrame.h', - 'bindings/v8/ScriptCallStack.cpp', - 'bindings/v8/ScriptCallStack.h', + 'bindings/v8/ScriptCallStackFactory.cpp', + 'bindings/v8/ScriptCallStackFactory.h', 'bindings/v8/ScriptController.cpp', 'bindings/v8/ScriptController.h', 'bindings/v8/ScriptDebugServer.cpp', @@ -1187,6 +1184,7 @@ 'dom/DocumentMarkerController.h', 'dom/DocumentParser.cpp', 'dom/DocumentParser.h', + 'dom/DocumentTiming.h', 'dom/DocumentType.cpp', 'dom/DocumentType.h', 'dom/DynamicNodeList.cpp', @@ -1362,6 +1360,7 @@ 'editing/BreakBlockquoteCommand.h', 'editing/CompositeEditCommand.cpp', 'editing/CompositeEditCommand.h', + 'editing/CorrectionPanelInfo.h', 'editing/CreateLinkCommand.cpp', 'editing/CreateLinkCommand.h', 'editing/DeleteButton.cpp', @@ -1377,6 +1376,8 @@ 'editing/EditCommand.h', 'editing/EditingBehavior.h', 'editing/EditingBehaviorTypes.h', + 'editing/EditingStyle.cpp', + 'editing/EditingStyle.h', 'editing/Editor.cpp', 'editing/Editor.h', 'editing/EditorCommand.cpp', @@ -1535,7 +1536,6 @@ 'history/mac/HistoryItemMac.mm', 'history/BackForwardController.cpp', 'history/BackForwardController.h', - 'history/BackForwardControllerClient.h', 'history/BackForwardList.h', 'history/BackForwardListImpl.cpp', 'history/BackForwardListImpl.h', @@ -1718,6 +1718,8 @@ 'html/HTMLOptionElement.h', 'html/HTMLOptionsCollection.cpp', 'html/HTMLOptionsCollection.h', + 'html/HTMLOutputElement.cpp', + 'html/HTMLOutputElement.h', 'html/HTMLParagraphElement.cpp', 'html/HTMLParagraphElement.h', 'html/HTMLParamElement.cpp', @@ -1822,6 +1824,8 @@ 'html/TimeRanges.h', 'html/URLInputType.cpp', 'html/URLInputType.h', + 'html/ValidationMessage.cpp', + 'html/ValidationMessage.h', 'html/ValidityState.cpp', 'html/ValidityState.h', 'html/VoidCallback.h', @@ -1866,6 +1870,8 @@ 'html/canvas/WebGLBuffer.h', 'html/canvas/WebGLContextAttributes.cpp', 'html/canvas/WebGLContextAttributes.h', + 'html/canvas/WebGLContextEvent.cpp', + 'html/canvas/WebGLContextEvent.h', 'html/canvas/WebGLFramebuffer.cpp', 'html/canvas/WebGLFramebuffer.h', 'html/canvas/WebGLGetInfo.cpp', @@ -1946,6 +1952,8 @@ 'inspector/InspectorDOMAgent.h', 'inspector/InspectorDOMStorageResource.cpp', 'inspector/InspectorDOMStorageResource.h', + 'inspector/InspectorFileSystemAgent.cpp', + 'inspector/InspectorFileSystemAgent.h', 'inspector/InspectorFrontendClient.h', 'inspector/InspectorFrontendHost.cpp', 'inspector/InspectorFrontendHost.h', @@ -1953,8 +1961,6 @@ 'inspector/InspectorInstrumentation.h', 'inspector/InspectorProfilerAgent.cpp', 'inspector/InspectorProfilerAgent.h', - 'inspector/InspectorResource.cpp', - 'inspector/InspectorResource.h', 'inspector/InspectorResourceAgent.cpp', 'inspector/InspectorResourceAgent.h', 'inspector/InspectorState.cpp', @@ -1970,6 +1976,12 @@ 'inspector/InspectorWorkerResource.h', 'inspector/ScriptBreakpoint.cpp', 'inspector/ScriptBreakpoint.h', + 'inspector/ScriptArguments.cpp', + 'inspector/ScriptArguments.h', + 'inspector/ScriptCallFrame.cpp', + 'inspector/ScriptCallFrame.h', + 'inspector/ScriptCallStack.cpp', + 'inspector/ScriptCallStack.h', 'inspector/ScriptDebugListener.h', 'inspector/ScriptGCEventListener.h', 'inspector/TimelineRecordFactory.cpp', @@ -1998,6 +2010,28 @@ 'loader/archive/ArchiveResource.h', 'loader/archive/ArchiveResourceCollection.cpp', 'loader/archive/ArchiveResourceCollection.h', + 'loader/cache/MemoryCache.cpp', + 'loader/cache/MemoryCache.h', + 'loader/cache/CachedCSSStyleSheet.cpp', + 'loader/cache/CachedCSSStyleSheet.h', + 'loader/cache/CachedFont.cpp', + 'loader/cache/CachedFont.h', + 'loader/cache/CachedImage.cpp', + 'loader/cache/CachedImage.h', + 'loader/cache/CachedResource.cpp', + 'loader/cache/CachedResource.h', + 'loader/cache/CachedResourceClient.h', + 'loader/cache/CachedResourceClientWalker.cpp', + 'loader/cache/CachedResourceClientWalker.h', + 'loader/cache/CachedResourceHandle.cpp', + 'loader/cache/CachedResourceHandle.h', + 'loader/cache/CachedResourceLoader.cpp', + 'loader/cache/CachedResourceLoader.h', + 'loader/cache/CachedScript.cpp', + 'loader/cache/CachedScript.h', + 'loader/cache/CachedXSLStyleSheet.cpp', + 'loader/cache/CachedXSLStyleSheet.h', + 'loader/cache/CachePolicy.h', 'loader/icon/IconDatabase.cpp', 'loader/icon/IconDatabase.h', 'loader/icon/IconDatabaseClient.h', @@ -2014,33 +2048,11 @@ 'loader/mac/ResourceLoaderMac.mm', 'loader/win/DocumentLoaderWin.cpp', 'loader/win/FrameLoaderWin.cpp', - 'loader/Cache.cpp', - 'loader/Cache.h', 'loader/CachedMetadata.h', - 'loader/CachePolicy.h', - 'loader/CachedCSSStyleSheet.cpp', - 'loader/CachedCSSStyleSheet.h', - 'loader/CachedFont.cpp', - 'loader/CachedFont.h', - 'loader/CachedImage.cpp', - 'loader/CachedImage.h', - 'loader/CachedResource.cpp', - 'loader/CachedResource.h', - 'loader/CachedResourceClient.h', - 'loader/CachedResourceClientWalker.cpp', - 'loader/CachedResourceClientWalker.h', - 'loader/CachedResourceHandle.cpp', - 'loader/CachedResourceHandle.h', - 'loader/CachedScript.cpp', - 'loader/CachedScript.h', - 'loader/CachedXSLStyleSheet.cpp', - 'loader/CachedXSLStyleSheet.h', 'loader/CrossOriginAccessControl.cpp', 'loader/CrossOriginAccessControl.h', 'loader/CrossOriginPreflightResultCache.cpp', 'loader/CrossOriginPreflightResultCache.h', - 'loader/CachedResourceLoader.cpp', - 'loader/CachedResourceLoader.h', 'loader/DocumentLoadTiming.h', 'loader/DocumentLoader.cpp', 'loader/DocumentLoader.h', @@ -2420,6 +2432,7 @@ 'platform/graphics/chromium/CanvasLayerChromium.cpp', 'platform/graphics/chromium/CanvasLayerChromium.h', 'platform/graphics/chromium/DrawingBufferChromium.cpp', + 'platform/graphics/chromium/Extensions3DChromium.h', 'platform/graphics/chromium/ContentLayerChromium.cpp', 'platform/graphics/chromium/ContentLayerChromium.h', 'platform/graphics/chromium/CrossProcessFontLoading.h', @@ -2456,6 +2469,8 @@ 'platform/graphics/chromium/LayerRendererChromium.h', 'platform/graphics/chromium/MediaPlayerPrivateChromium.h', 'platform/graphics/chromium/PlatformIcon.h', + 'platform/graphics/chromium/PluginLayerChromium.cpp', + 'platform/graphics/chromium/PluginLayerChromium.h', 'platform/graphics/chromium/SimpleFontDataChromiumWin.cpp', 'platform/graphics/chromium/SimpleFontDataLinux.cpp', 'platform/graphics/chromium/TransparencyWin.cpp', @@ -2735,6 +2750,7 @@ 'platform/graphics/Color.cpp', 'platform/graphics/Color.h', 'platform/graphics/DashArray.h', + 'platform/graphics/Extensions3D.h', 'platform/graphics/FloatPoint.cpp', 'platform/graphics/FloatPoint.h', 'platform/graphics/FloatPoint3D.cpp', @@ -3952,10 +3968,13 @@ 'svg/properties/SVGAnimatedPropertySynchronizer.h', 'svg/properties/SVGAnimatedPropertyTearOff.h', 'svg/properties/SVGAnimatedStaticPropertyTearOff.h', + 'svg/properties/SVGListProperty.h', 'svg/properties/SVGListPropertyTearOff.h', 'svg/properties/SVGProperty.h', 'svg/properties/SVGPropertyTearOff.h', 'svg/properties/SVGPropertyTraits.h', + 'svg/properties/SVGStaticListPropertyTearOff.h', + 'svg/properties/SVGStaticPropertyTearOff.h', 'svg/ColorDistance.cpp', 'svg/ColorDistance.h', 'svg/DeprecatedSVGAnimatedProperty.h', @@ -3987,11 +4006,13 @@ 'svg/SVGAnimatedInteger.h', 'svg/SVGAnimatedLength.h', 'svg/SVGAnimatedLengthList.h', + 'svg/SVGAnimatedNumber.h', + 'svg/SVGAnimatedNumberList.h', 'svg/SVGAnimatedPathData.cpp', 'svg/SVGAnimatedPathData.h', - 'svg/SVGAnimatedPoints.cpp', - 'svg/SVGAnimatedPoints.h', + 'svg/SVGAnimatedPreserveAspectRatio.h', 'svg/SVGAnimatedRect.h', + 'svg/SVGAnimatedString.h', 'svg/SVGAnimationElement.cpp', 'svg/SVGAnimationElement.h', 'svg/SVGCircleElement.cpp', @@ -4419,6 +4440,7 @@ 'inspector/front-end/ExtensionPanel.js', 'inspector/front-end/ExtensionRegistryStub.js', 'inspector/front-end/ExtensionServer.js', + 'inspector/front-end/FileSystemView.js', 'inspector/front-end/FontView.js', 'inspector/front-end/GoToLineDialog.js', 'inspector/front-end/HAREntry.js', @@ -4448,7 +4470,6 @@ 'inspector/front-end/Resource.js', 'inspector/front-end/ResourceCategory.js', 'inspector/front-end/ResourceManager.js', - 'inspector/front-end/ResourcesPanel.js', 'inspector/front-end/ResourceView.js', 'inspector/front-end/ScopeChainSidebarPane.js', 'inspector/front-end/Script.js', @@ -4547,7 +4568,6 @@ 'inspector/front-end/Images/goArrow.png', 'inspector/front-end/Images/graphLabelCalloutLeft.png', 'inspector/front-end/Images/graphLabelCalloutRight.png', - 'inspector/front-end/Images/grayConnectorPoint.png', 'inspector/front-end/Images/largerResourcesButtonGlyph.png', 'inspector/front-end/Images/localStorage.png', 'inspector/front-end/Images/networkIcon.png', @@ -4578,7 +4598,6 @@ 'inspector/front-end/Images/resourcePlainIcon.png', 'inspector/front-end/Images/resourcePlainIconSmall.png', 'inspector/front-end/Images/resourcesIcon.png', - 'inspector/front-end/Images/resourcesSilhouette.png', 'inspector/front-end/Images/resourcesSizeGraphIcon.png', 'inspector/front-end/Images/resourcesTimeGraphIcon.png', 'inspector/front-end/Images/scriptsIcon.png', @@ -4652,8 +4671,7 @@ 'inspector/front-end/Images/warningIcon.png', 'inspector/front-end/Images/warningOrangeDot.png', 'inspector/front-end/Images/warningMediumIcon.png', - 'inspector/front-end/Images/warningsErrors.png', - 'inspector/front-end/Images/whiteConnectorPoint.png' + 'inspector/front-end/Images/warningsErrors.png' ], } } diff --git a/WebCore/WebCore.order b/WebCore/WebCore.order index 06dfb3d..0c852e1 100644 --- a/WebCore/WebCore.order +++ b/WebCore/WebCore.order @@ -26499,7 +26499,6 @@ __ZN7WebCoreL16transformListForEPNS_10SVGElementE __ZN7WebCoreL19polylineConstructorERKNS_13QualifiedNameEPNS_8DocumentEb __ZN7WebCore18SVGPolylineElementC1ERKNS_13QualifiedNameEPNS_8DocumentE __ZN7WebCore14SVGPolyElementC2ERKNS_13QualifiedNameEPNS_8DocumentE -__ZN7WebCore17SVGAnimatedPointsC2Ev __ZN7WebCore14SVGPolyElement19svgAttributeChangedERKNS_13QualifiedNameE __ZN7WebCore14SVGPolyElement20parseMappedAttributeEPNS_15MappedAttributeE __ZNK7WebCore14SVGPolyElement6pointsEv @@ -26655,7 +26654,6 @@ __ZN7WebCore18SVGPolylineElementD0Ev __ZN7WebCore14SVGPolyElementD2Ev __ZN7WebCore12SVGPointListD0Ev __ZN3WTF6VectorINS_6RefPtrIN7WebCore14SVGPODListItemINS2_10FloatPointEEEEELm0EE6shrinkEm -__ZN7WebCore17SVGAnimatedPointsD2Ev __ZThn8_N7WebCore17SVGPolygonElementD0Ev __ZN7WebCore17SVGPolygonElementD0Ev __ZThn8_N7WebCore15SVGImageElementD0Ev diff --git a/WebCore/WebCore.pri b/WebCore/WebCore.pri index 3b38a45..9d9906a 100644 --- a/WebCore/WebCore.pri +++ b/WebCore/WebCore.pri @@ -262,6 +262,7 @@ IDL_BINDINGS += \ html/HTMLOptGroupElement.idl \ html/HTMLOptionElement.idl \ html/HTMLOptionsCollection.idl \ + html/HTMLOutputElement.idl \ html/HTMLParagraphElement.idl \ html/HTMLParamElement.idl \ html/HTMLPreElement.idl \ diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro index 132d36d..7a98a1f 100644 --- a/WebCore/WebCore.pro +++ b/WebCore/WebCore.pro @@ -231,6 +231,7 @@ WEBCORE_INCLUDEPATH = \ $$PWD/loader \ $$PWD/loader/appcache \ $$PWD/loader/archive \ + $$PWD/loader/cache \ $$PWD/loader/icon \ $$PWD/mathml \ $$PWD/notifications \ @@ -351,8 +352,7 @@ v8 { bindings/v8/ScopedDOMDataStore.cpp \ # bindings/v8/ScriptArray.cpp \ bindings/v8/ScriptCachedFrameData.cpp \ - bindings/v8/ScriptCallFrame.cpp \ - bindings/v8/ScriptCallStack.cpp \ + bindings/v8/ScriptCallStackFactory.cpp \ bindings/ScriptControllerBase.cpp \ bindings/v8/ScriptController.cpp \ bindings/v8/ScriptEventListener.cpp \ @@ -442,6 +442,7 @@ v8 { bindings/v8/custom/V8HTMLInputElementCustom.cpp \ bindings/v8/custom/V8HTMLOptionElementConstructor.cpp \ bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp \ + bindings/v8/custom/V8HTMLOutputElementCustom.cpp \ bindings/v8/custom/V8HTMLPlugInElementCustom.cpp \ bindings/v8/custom/V8HTMLSelectElementCustom.cpp \ bindings/v8/custom/V8LocationCustom.cpp \ @@ -537,6 +538,7 @@ v8 { bindings/js/JSHTMLInputElementCustom.cpp \ bindings/js/JSHTMLObjectElementCustom.cpp \ bindings/js/JSHTMLOptionsCollectionCustom.cpp \ + bindings/js/JSHTMLOutputElementCustom.cpp \ bindings/js/JSHTMLSelectElementCustom.cpp \ bindings/js/JSImageConstructor.cpp \ bindings/js/JSImageDataCustom.cpp \ @@ -577,8 +579,7 @@ v8 { bindings/js/JSPopStateEventCustom.cpp \ bindings/js/JSWorkerContextErrorHandler.cpp \ bindings/js/ScriptCachedFrameData.cpp \ - bindings/js/ScriptCallFrame.cpp \ - bindings/js/ScriptCallStack.cpp \ + bindings/js/ScriptCallStackFactory.cpp \ bindings/js/ScriptController.cpp \ bindings/js/ScriptDebugServer.cpp \ bindings/js/ScriptEventListener.cpp \ @@ -787,6 +788,7 @@ SOURCES += \ editing/DeleteFromTextNodeCommand.cpp \ editing/DeleteSelectionCommand.cpp \ editing/EditCommand.cpp \ + editing/EditingStyle.cpp \ editing/Editor.cpp \ editing/EditorCommand.cpp \ editing/FormatBlockCommand.cpp \ @@ -925,6 +927,7 @@ SOURCES += \ html/HTMLOptGroupElement.cpp \ html/HTMLOptionElement.cpp \ html/HTMLOptionsCollection.cpp \ + html/HTMLOutputElement.cpp \ html/HTMLParagraphElement.cpp \ html/HTMLParamElement.cpp \ html/HTMLParserErrorCodes.cpp \ @@ -973,6 +976,7 @@ SOURCES += \ html/TextInputType.cpp \ html/TimeInputType.cpp \ html/URLInputType.cpp \ + html/ValidationMessage.cpp \ html/ValidityState.cpp \ html/WeekInputType.cpp \ html/canvas/CanvasGradient.cpp \ @@ -1010,34 +1014,37 @@ SOURCES += \ inspector/InspectorDebuggerAgent.cpp \ inspector/InspectorDOMAgent.cpp \ inspector/InspectorDOMStorageResource.cpp \ + inspector/InspectorFileSystemAgent.cpp \ inspector/InspectorFrontendClientLocal.cpp \ inspector/InspectorFrontendHost.cpp \ inspector/InspectorInstrumentation.cpp \ inspector/InspectorProfilerAgent.cpp \ - inspector/InspectorResource.cpp \ inspector/InspectorResourceAgent.cpp \ inspector/InspectorState.cpp \ inspector/InspectorStorageAgent.cpp \ inspector/InspectorStyleSheet.cpp \ inspector/InspectorTimelineAgent.cpp \ inspector/InspectorValues.cpp \ + inspector/ScriptArguments.cpp \ inspector/ScriptBreakpoint.cpp \ + inspector/ScriptCallFrame.cpp \ + inspector/ScriptCallStack.cpp \ inspector/TimelineRecordFactory.cpp \ loader/archive/ArchiveFactory.cpp \ loader/archive/ArchiveResource.cpp \ loader/archive/ArchiveResourceCollection.cpp \ - loader/Cache.cpp \ - loader/CachedCSSStyleSheet.cpp \ - loader/CachedFont.cpp \ - loader/CachedImage.cpp \ - loader/CachedResourceClientWalker.cpp \ - loader/CachedResourceHandle.cpp \ - loader/CachedResource.cpp \ - loader/CachedScript.cpp \ - loader/CachedXSLStyleSheet.cpp \ + loader/cache/MemoryCache.cpp \ + loader/cache/CachedCSSStyleSheet.cpp \ + loader/cache/CachedFont.cpp \ + loader/cache/CachedImage.cpp \ + loader/cache/CachedResourceClientWalker.cpp \ + loader/cache/CachedResourceHandle.cpp \ + loader/cache/CachedResource.cpp \ + loader/cache/CachedScript.cpp \ + loader/cache/CachedXSLStyleSheet.cpp \ loader/CrossOriginAccessControl.cpp \ loader/CrossOriginPreflightResultCache.cpp \ - loader/CachedResourceLoader.cpp \ + loader/cache/CachedResourceLoader.cpp \ loader/DocumentLoader.cpp \ loader/DocumentThreadableLoader.cpp \ loader/DocumentWriter.cpp \ @@ -1397,8 +1404,6 @@ v8 { bindings/v8/ScopedDOMDataStore.h \ # bindings/v8/ScriptArray.h \ bindings/v8/ScriptCachedFrameData.h \ - bindings/v8/ScriptCallFrame.h \ - bindings/v8/ScriptCallStack.h \ bindings/v8/ScriptController.h \ bindings/v8/ScriptEventListener.h \ bindings/v8/ScriptFunctionCall.h \ @@ -1481,8 +1486,6 @@ v8 { bindings/js/JavaScriptCallFrame.h \ bindings/js/ScheduledAction.h \ bindings/js/ScriptCachedFrameData.h \ - bindings/js/ScriptCallFrame.h \ - bindings/js/ScriptCallStack.h \ bindings/js/ScriptController.h \ bindings/js/ScriptEventListener.h \ bindings/js/ScriptFunctionCall.h \ @@ -1689,12 +1692,14 @@ HEADERS += \ editing/ApplyStyleCommand.h \ editing/BreakBlockquoteCommand.h \ editing/CompositeEditCommand.h \ + editing/CorrectionPanelInfo.h \ editing/CreateLinkCommand.h \ editing/DeleteButtonController.h \ editing/DeleteButton.h \ editing/DeleteFromTextNodeCommand.h \ editing/DeleteSelectionCommand.h \ editing/EditCommand.h \ + editing/EditingStyle.h \ editing/EditingBehavior.h \ editing/Editor.h \ editing/FormatBlockCommand.h \ @@ -1746,7 +1751,6 @@ HEADERS += \ fileapi/FileThread.h \ fileapi/FileThreadTask.h \ history/BackForwardController.h \ - history/BackForwardControllerClient.h \ history/BackForwardListImpl.h \ history/BackForwardList.h \ history/CachedFrame.h \ @@ -1831,6 +1835,7 @@ HEADERS += \ html/HTMLOptGroupElement.h \ html/HTMLOptionElement.h \ html/HTMLOptionsCollection.h \ + html/HTMLOutputElement.h \ html/HTMLParagraphElement.h \ html/HTMLParamElement.h \ html/HTMLParserErrorCodes.h \ @@ -1892,12 +1897,12 @@ HEADERS += \ inspector/InspectorDatabaseResource.h \ inspector/InspectorDebuggerAgent.h \ inspector/InspectorDOMStorageResource.h \ + inspector/InspectorFileSystemAgent.h \ inspector/InspectorFrontendClient.h \ inspector/InspectorFrontendClientLocal.h \ inspector/InspectorFrontendHost.h \ inspector/InspectorInstrumentation.h \ inspector/InspectorProfilerAgent.h \ - inspector/InspectorResource.h \ inspector/InspectorResourceAgent.h \ inspector/InspectorState.h \ inspector/InspectorStorageAgent.h \ @@ -1915,18 +1920,18 @@ HEADERS += \ loader/archive/ArchiveFactory.h \ loader/archive/ArchiveResourceCollection.h \ loader/archive/ArchiveResource.h \ - loader/CachedCSSStyleSheet.h \ - loader/CachedFont.h \ - loader/CachedImage.h \ - loader/CachedResourceClientWalker.h \ - loader/CachedResource.h \ - loader/CachedResourceHandle.h \ - loader/CachedScript.h \ - loader/CachedXSLStyleSheet.h \ - loader/Cache.h \ + loader/cache/CachedCSSStyleSheet.h \ + loader/cache/CachedFont.h \ + loader/cache/CachedImage.h \ + loader/cache/CachedResourceClientWalker.h \ + loader/cache/CachedResource.h \ + loader/cache/CachedResourceHandle.h \ + loader/cache/CachedScript.h \ + loader/cache/CachedXSLStyleSheet.h \ + loader/cache/MemoryCache.h \ loader/CrossOriginAccessControl.h \ loader/CrossOriginPreflightResultCache.h \ - loader/CachedResourceLoader.h \ + loader/cache/CachedResourceLoader.h \ loader/DocumentLoader.h \ loader/DocumentThreadableLoader.h \ loader/FormState.h \ @@ -2364,10 +2369,13 @@ HEADERS += \ svg/properties/SVGAnimatedPropertySynchronizer.h \ svg/properties/SVGAnimatedPropertyTearOff.h \ svg/properties/SVGAnimatedStaticPropertyTearOff.h \ + svg/properties/SVGListProperty.h \ svg/properties/SVGListPropertyTearOff.h \ svg/properties/SVGProperty.h \ svg/properties/SVGPropertyTearOff.h \ svg/properties/SVGPropertyTraits.h \ + svg/properties/SVGStaticListPropertyTearOff.h \ + svg/properties/SVGStaticPropertyTearOff.h \ svg/SVGAElement.h \ svg/SVGAltGlyphElement.h \ svg/SVGAngle.h \ @@ -2378,9 +2386,12 @@ HEADERS += \ svg/SVGAnimatedInteger.h \ svg/SVGAnimatedLength.h \ svg/SVGAnimatedLengthList.h \ + svg/SVGAnimatedNumber.h \ + svg/SVGAnimatedNumberList.h \ svg/SVGAnimatedPathData.h \ - svg/SVGAnimatedPoints.h \ + svg/SVGAnimatedPreserveAspectRatio.h \ svg/SVGAnimatedRect.h \ + svg/SVGAnimatedString.h \ svg/SVGAnimateElement.h \ svg/SVGAnimateMotionElement.h \ svg/SVGAnimateTransformElement.h \ @@ -2777,11 +2788,11 @@ contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=1) { mac { SOURCES += \ - plugins/mac/PluginPackageMac.cpp \ - plugins/mac/PluginViewMac.mm + plugins/mac/PluginPackageMac.cpp OBJECTIVE_SOURCES += \ platform/text/mac/StringImplMac.mm \ - platform/mac/WebCoreNSStringExtras.mm + platform/mac/WebCoreNSStringExtras.mm \ + plugins/mac/PluginViewMac.mm INCLUDEPATH += platform/mac # Note: XP_MACOSX is defined in npapi.h } else { @@ -3392,7 +3403,6 @@ contains(DEFINES, ENABLE_SVG=1) { svg/SVGAngle.cpp \ svg/SVGAnimateColorElement.cpp \ svg/SVGAnimatedPathData.cpp \ - svg/SVGAnimatedPoints.cpp \ svg/SVGAnimateElement.cpp \ svg/SVGAnimateMotionElement.cpp \ svg/SVGAnimateTransformElement.cpp \ @@ -3671,7 +3681,9 @@ HEADERS += \ html/canvas/Uint8Array.h \ html/canvas/Uint32Array.h \ html/canvas/Uint16Array.h \ - platform/graphics/GraphicsContext3D.h + platform/graphics/Extensions3D.h \ + platform/graphics/GraphicsContext3D.h \ + platform/graphics/qt/Extensions3DQt.h !v8 { SOURCES += \ @@ -3709,6 +3721,7 @@ SOURCES += \ html/canvas/Uint32Array.cpp \ html/canvas/Uint16Array.cpp \ platform/graphics/GraphicsContext3D.cpp \ + platform/graphics/qt/Extensions3DQt.cpp \ platform/graphics/qt/GraphicsContext3DQt.cpp } @@ -3844,11 +3857,15 @@ win32:!win32-g++*:contains(QMAKE_HOST.arch, x86_64):{ contains(CONFIG, texmap) { DEFINES += WTF_USE_TEXTURE_MAPPER=1 HEADERS += \ + platform/graphics/qt/TextureMapperQt.h \ + platform/graphics/texmap/GraphicsLayerTextureMapper.h \ platform/graphics/texmap/TextureMapper.h \ + platform/graphics/texmap/TextureMapperNode.h \ platform/graphics/texmap/TextureMapperPlatformLayer.h SOURCES += \ platform/graphics/qt/TextureMapperQt.cpp \ + platform/graphics/texmap/TextureMapperNode.cpp \ platform/graphics/texmap/GraphicsLayerTextureMapper.cpp contains(QT_CONFIG, opengl) { diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj index 8cb84a7..4dd2c30 100644 --- a/WebCore/WebCore.vcproj/WebCore.vcproj +++ b/WebCore/WebCore.vcproj/WebCore.vcproj @@ -8564,6 +8564,62 @@ >
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSHTMLOutputElement.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSHTMLOutputElement.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSHTMLParagraphElement.cpp"
>
<FileConfiguration
@@ -23672,94 +23728,6 @@ Name="loader"
>
<File
- RelativePath="..\loader\Cache.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\Cache.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedCSSStyleSheet.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedCSSStyleSheet.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedFont.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedFont.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedImage.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedImage.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResource.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResource.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResourceClient.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResourceClientWalker.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResourceClientWalker.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResourceHandle.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResourceHandle.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResourceLoader.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedResourceLoader.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedScript.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedScript.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachedXSLStyleSheet.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\CachedXSLStyleSheet.h"
- >
- </File>
- <File
- RelativePath="..\loader\CachePolicy.h"
- >
- </File>
- <File
RelativePath="..\loader\CrossOriginAccessControl.cpp"
>
</File>
@@ -24211,6 +24179,98 @@ </File>
</Filter>
</Filter>
+ <Filter
+ Name="cache"
+ >
+ <File
+ RelativePath="..\loader\cache\MemoryCache.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\MemoryCache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedCSSStyleSheet.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedCSSStyleSheet.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedFont.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedFont.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedImage.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedImage.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResource.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResourceClient.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResourceClientWalker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResourceClientWalker.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResourceHandle.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResourceHandle.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResourceLoader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedResourceLoader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedScript.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedScript.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedXSLStyleSheet.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachedXSLStyleSheet.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\cache\CachePolicy.h"
+ >
+ </File>
+ </Filter>
</Filter>
<Filter
Name="platform"
@@ -27446,7 +27506,7 @@ </FileConfiguration>
</File>
<File
- RelativePath="..\platform\graphics\cairo\PlatformRefPtrCairo.cpp"
+ RelativePath="..\platform\graphics\cairo\RefPtrCairo.cpp"
>
<FileConfiguration
Name="Debug|Win32"
@@ -27482,7 +27542,7 @@ </FileConfiguration>
</File>
<File
- RelativePath="..\platform\graphics\cairo\PlatformRefPtrCairo.h"
+ RelativePath="..\platform\graphics\cairo\RefPtrCairo.h"
>
<FileConfiguration
Name="Debug|Win32"
@@ -41648,6 +41708,10 @@ >
</File>
<File
+ RelativePath="..\dom\DocumentTiming.h"
+ >
+ </File>
+ <File
RelativePath="..\dom\DocumentType.cpp"
>
<FileConfiguration
@@ -45872,6 +45936,10 @@ >
</File>
<File
+ RelativePath="..\editing\CorrectionPanelInfo.h"
+ >
+ </File>
+ <File
RelativePath="..\editing\CreateLinkCommand.cpp"
>
<FileConfiguration
@@ -46224,6 +46292,62 @@ >
</File>
<File
+ RelativePath="..\editing\EditingStyle.h"
+ >
+ </File>
+ <File
+ RelativePath="..\editing\EditingStyle.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath="..\editing\Editor.cpp"
>
<FileConfiguration
@@ -52044,6 +52168,14 @@ >
</File>
<File
+ RelativePath="..\html\HTMLOutputElement.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\HTMLOutputElement.h"
+ >
+ </File>
+ <File
RelativePath="..\html\HTMLParagraphElement.cpp"
>
<FileConfiguration
@@ -53524,6 +53656,14 @@ >
</File>
<File
+ RelativePath="..\html\ValidationMessage.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\ValidationMessage.h"
+ >
+ </File>
+ <File
RelativePath="..\html\ValidityState.cpp"
>
</File>
@@ -57251,6 +57391,58 @@ </FileConfiguration>
</File>
<File
+ RelativePath="..\bindings\js\JSHTMLOutputElementCustom.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath="..\bindings\js\JSHTMLSelectElementCustom.cpp"
>
<FileConfiguration
@@ -60859,63 +61051,7 @@ >
</File>
<File
- RelativePath="..\bindings\js\ScriptCallFrame.cpp"
- >
- <FileConfiguration
- Name="Debug|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Cairo|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_All|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\bindings\js\ScriptCallFrame.h"
- >
- </File>
- <File
- RelativePath="..\bindings\js\ScriptCallStack.cpp"
+ RelativePath="..\bindings\js\ScriptCallStackFactory.cpp"
>
<FileConfiguration
Name="Debug|Win32"
@@ -60967,7 +61103,7 @@ </FileConfiguration>
</File>
<File
- RelativePath="..\bindings\js\ScriptCallStack.h"
+ RelativePath="..\bindings\js\ScriptCallStackFactory.h"
>
</File>
<File
@@ -61668,11 +61804,19 @@ >
</File>
<File
+ RelativePath="..\svg\SVGAnimatedNumber.h"
+ >
+ </File>
+ <File
+ RelativePath="..\svg\SVGAnimatedNumberList.h"
+ >
+ </File>
+ <File
RelativePath="..\svg\SVGAnimatedPathData.h"
>
</File>
<File
- RelativePath="..\svg\SVGAnimatedPoints.h"
+ RelativePath="..\svg\SVGAnimatedPreserveAspectRatio.h"
>
</File>
<File
@@ -61680,6 +61824,10 @@ >
</File>
<File
+ RelativePath="..\svg\SVGAnimatedString.h"
+ >
+ </File>
+ <File
RelativePath="..\svg\SVGAnimateElement.h"
>
</File>
@@ -62727,6 +62875,10 @@ >
</File>
<File
+ RelativePath="..\svg\properties\SVGListProperty.h"
+ >
+ </File>
+ <File
RelativePath="..\svg\properties\SVGListPropertyTearOff.h"
>
</File>
@@ -62742,6 +62894,14 @@ RelativePath="..\svg\properties\SVGPropertyTraits.h"
>
</File>
+ <File
+ RelativePath="..\svg\properties\SVGStaticListPropertyTearOff.h"
+ >
+ </File>
+ <File
+ RelativePath="..\svg\properties\SVGStaticPropertyTearOff.h"
+ >
+ </File>
</Filter>
</Filter>
<Filter
@@ -63012,10 +63172,6 @@ >
</File>
<File
- RelativePath="..\history\BackForwardControllerClient.h"
- >
- </File>
- <File
RelativePath="..\history\BackForwardList.h"
>
</File>
@@ -63788,6 +63944,14 @@ >
</File>
<File
+ RelativePath="..\inspector\InspectorFileSystemAgent.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\InspectorFileSystemAgent.cpp"
+ >
+ </File>
+ <File
RelativePath="..\inspector\InspectorFrontendClient.h"
>
</File>
@@ -63824,14 +63988,6 @@ >
</File>
<File
- RelativePath="..\inspector\InspectorResource.cpp"
- >
- </File>
- <File
- RelativePath="..\inspector\InspectorResource.h"
- >
- </File>
- <File
RelativePath="..\inspector\InspectorResourceAgent.cpp"
>
</File>
@@ -63884,6 +64040,14 @@ >
</File>
<File
+ RelativePath="..\inspector\ScriptArguments.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\ScriptArguments.h"
+ >
+ </File>
+ <File
RelativePath="..\inspector\ScriptBreakpoint.cpp"
>
</File>
@@ -63892,6 +64056,22 @@ >
</File>
<File
+ RelativePath="..\inspector\ScriptCallFrame.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\ScriptCallFrame.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\ScriptCallStack.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\ScriptCallStack.h"
+ >
+ </File>
+ <File
RelativePath="..\inspector\ScriptDebugListener.h"
>
</File>
@@ -64067,6 +64247,10 @@ >
</File>
<File
+ RelativePath="..\inspector\front-end\FileSystemView.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\FontView.js"
>
</File>
@@ -64207,10 +64391,6 @@ >
</File>
<File
- RelativePath="..\inspector\front-end\ResourcesPanel.js"
- >
- </File>
- <File
RelativePath="..\inspector\front-end\ResourceView.js"
>
</File>
diff --git a/WebCore/WebCore.vcproj/WebCoreCommon.vsprops b/WebCore/WebCore.vcproj/WebCoreCommon.vsprops index c8c4e94..d9929d9 100644 --- a/WebCore/WebCore.vcproj/WebCoreCommon.vsprops +++ b/WebCore/WebCore.vcproj/WebCoreCommon.vsprops @@ -7,7 +7,7 @@ >
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(ProjectDir)..";"$(ProjectDir)..\accessibility";"$(ProjectDir)..\accessibility\win";"$(ProjectDir)..\bridge";"$(ProjectDir)..\bridge\c";"$(ProjectDir)..\bridge\jsc";"$(ProjectDir)..\css";"$(ProjectDir)..\editing";"$(ProjectDir)..\fileapi";"$(ProjectDir)..\rendering";"$(ProjectDir)..\rendering\style";"$(ProjectDir)..\rendering\svg";"$(ProjectDir)..\bindings";"$(ProjectDir)..\bindings\generic";"$(ProjectDir)..\bindings\js";"$(ProjectDir)..\bindings\js\specialization";"$(ProjectDir)..\dom";"$(ProjectDir)..\dom\default";"$(ProjectDir)..\history";"$(ProjectDir)..\html";"$(ProjectDir)..\html\canvas";"$(ProjectDir)..\html\parser";"$(ProjectDir)..\inspector";"$(ProjectDir)..\loader";"$(ProjectDir)..\loader\appcache";"$(ProjectDir)..\loader\archive";"$(ProjectDir)..\loader\archive\cf";"$(ProjectDir)..\loader\icon";"$(ProjectDir)..\mathml";"$(ProjectDir)..\notifications";"$(ProjectDir)..\page";"$(ProjectDir)..\page\animation";"$(ProjectDir)..\page\win";"$(ProjectDir)..\platform";"$(ProjectDir)..\platform\animation";"$(ProjectDir)..\platform\mock";"$(ProjectDir)..\platform\sql";"$(ProjectDir)..\platform\win";"$(ProjectDir)..\platform\network";"$(ProjectDir)..\platform\network\win";"$(ProjectDir)..\platform\cf";"$(ProjectDir)..\platform\graphics";"$(ProjectDir)..\platform\graphics\filters";"$(ProjectDir)..\platform\graphics\opentype";"$(ProjectDir)..\platform\graphics\transforms";"$(ProjectDir)..\platform\text";"$(ProjectDir)..\platform\text\transcoder";"$(ProjectDir)..\platform\graphics\win";"$(ProjectDir)..\xml";"$(WebKitOutputDir)\obj\WebCore\DerivedSources";"$(ProjectDir)..\plugins";"$(ProjectDir)..\plugins\win";"$(ProjectDir)..\svg\animation";"$(ProjectDir)..\svg\graphics";"$(ProjectDir)..\svg\properties";"$(ProjectDir)..\svg\graphics\filters";"$(ProjectDir)..\svg";"$(ProjectDir)..\wml";"$(ProjectDir)..\storage";"$(ProjectDir)..\websockets";"$(ProjectDir)..\workers";"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitOutputDir)\include\private\JavaScriptCore";"$(ProjectDir)..\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitLibrariesDir)\include\private\JavaScriptCore";"$(WebKitLibrariesDir)\include\pthreads";"$(WebKitLibrariesDir)\include\sqlite";"$(WebKitLibrariesDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\include\zlib""
+ AdditionalIncludeDirectories=""$(ProjectDir)..";"$(ProjectDir)..\accessibility";"$(ProjectDir)..\accessibility\win";"$(ProjectDir)..\bridge";"$(ProjectDir)..\bridge\c";"$(ProjectDir)..\bridge\jsc";"$(ProjectDir)..\css";"$(ProjectDir)..\editing";"$(ProjectDir)..\fileapi";"$(ProjectDir)..\rendering";"$(ProjectDir)..\rendering\style";"$(ProjectDir)..\rendering\svg";"$(ProjectDir)..\bindings";"$(ProjectDir)..\bindings\generic";"$(ProjectDir)..\bindings\js";"$(ProjectDir)..\bindings\js\specialization";"$(ProjectDir)..\dom";"$(ProjectDir)..\dom\default";"$(ProjectDir)..\history";"$(ProjectDir)..\html";"$(ProjectDir)..\html\canvas";"$(ProjectDir)..\html\parser";"$(ProjectDir)..\inspector";"$(ProjectDir)..\loader";"$(ProjectDir)..\loader\appcache";"$(ProjectDir)..\loader\archive";"$(ProjectDir)..\loader\archive\cf";"$(ProjectDir)..\loader\cache";"$(ProjectDir)..\loader\icon";"$(ProjectDir)..\mathml";"$(ProjectDir)..\notifications";"$(ProjectDir)..\page";"$(ProjectDir)..\page\animation";"$(ProjectDir)..\page\win";"$(ProjectDir)..\platform";"$(ProjectDir)..\platform\animation";"$(ProjectDir)..\platform\mock";"$(ProjectDir)..\platform\sql";"$(ProjectDir)..\platform\win";"$(ProjectDir)..\platform\network";"$(ProjectDir)..\platform\network\win";"$(ProjectDir)..\platform\cf";"$(ProjectDir)..\platform\graphics";"$(ProjectDir)..\platform\graphics\filters";"$(ProjectDir)..\platform\graphics\opentype";"$(ProjectDir)..\platform\graphics\transforms";"$(ProjectDir)..\platform\text";"$(ProjectDir)..\platform\text\transcoder";"$(ProjectDir)..\platform\graphics\win";"$(ProjectDir)..\xml";"$(WebKitOutputDir)\obj\WebCore\DerivedSources";"$(ProjectDir)..\plugins";"$(ProjectDir)..\plugins\win";"$(ProjectDir)..\svg\animation";"$(ProjectDir)..\svg\graphics";"$(ProjectDir)..\svg\properties";"$(ProjectDir)..\svg\graphics\filters";"$(ProjectDir)..\svg";"$(ProjectDir)..\wml";"$(ProjectDir)..\storage";"$(ProjectDir)..\websockets";"$(ProjectDir)..\workers";"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitOutputDir)\include\private\JavaScriptCore";"$(ProjectDir)..\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitLibrariesDir)\include\private\JavaScriptCore";"$(WebKitLibrariesDir)\include\pthreads";"$(WebKitLibrariesDir)\include\sqlite";"$(WebKitLibrariesDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\include\zlib""
PreprocessorDefinitions="__WIN32__;DISABLE_3D_RENDERING;WEBCORE_CONTEXT_MENUS"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="WebCorePrefix.h"
diff --git a/WebCore/WebCore.vcproj/copyForwardingHeaders.cmd b/WebCore/WebCore.vcproj/copyForwardingHeaders.cmd index 3885487..d9d45b5 100755 --- a/WebCore/WebCore.vcproj/copyForwardingHeaders.cmd +++ b/WebCore/WebCore.vcproj/copyForwardingHeaders.cmd @@ -24,6 +24,7 @@ xcopy /y /d "%ProjectDir%..\loader\*.h" "%WebKitOutputDir%\include\WebCore" xcopy /y /d "%ProjectDir%..\loader\appcache\*.h" "%WebKitOutputDir%\include\WebCore" xcopy /y /d "%ProjectDir%..\loader\archive\*.h" "%WebKitOutputDir%\include\WebCore" xcopy /y /d "%ProjectDir%..\loader\archive\cf\*.h" "%WebKitOutputDir%\include\WebCore" +xcopy /y /d "%ProjectDir%..\loader\cache\*.h" "%WebKitOutputDir%\include\WebCore" xcopy /y /d "%ProjectDir%..\loader\icon\*.h" "%WebKitOutputDir%\include\WebCore" xcopy /y /d "%ProjectDir%..\history\*.h" "%WebKitOutputDir%\include\WebCore" xcopy /y /d "%ProjectDir%..\history\cf\*.h" "%WebKitOutputDir%\include\WebCore" diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj index 6bc2e36..b7e5d48 100644 --- a/WebCore/WebCore.xcodeproj/project.pbxproj +++ b/WebCore/WebCore.xcodeproj/project.pbxproj @@ -70,8 +70,10 @@ 080E49281255F3BD00EFCA27 /* SVGTextLayoutEngineSpacing.h in Headers */ = {isa = PBXBuildFile; fileRef = 080E49241255F3BD00EFCA27 /* SVGTextLayoutEngineSpacing.h */; }; 080FAE1A0EEEBDA800AACDE9 /* WMLTemplateElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 080FAE180EEEBDA800AACDE9 /* WMLTemplateElement.cpp */; }; 080FAE1B0EEEBDA800AACDE9 /* WMLTemplateElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 080FAE190EEEBDA800AACDE9 /* WMLTemplateElement.h */; }; + 0810764412828556007C63BA /* SVGListProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 0810764312828556007C63BA /* SVGListProperty.h */; settings = {ATTRIBUTES = (Private, ); }; }; 081093DB1255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 081093D91255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.cpp */; }; 081093DC1255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 081093DA1255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.h */; }; + 0813A4EA1284132600992511 /* SVGStaticPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 0813A4E91284132600992511 /* SVGStaticPropertyTearOff.h */; settings = {ATTRIBUTES = (Private, ); }; }; 081668D3125603BF006F25DE /* SVGTextChunkBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 081668D1125603BF006F25DE /* SVGTextChunkBuilder.cpp */; }; 081668D4125603BF006F25DE /* SVGTextChunkBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 081668D2125603BF006F25DE /* SVGTextChunkBuilder.h */; }; 081668D9125603D5006F25DE /* SVGTextLayoutEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 081668D7125603D5006F25DE /* SVGTextLayoutEngine.cpp */; }; @@ -113,6 +115,7 @@ 084D0E3D11F5816100081E1A /* SVGResources.h in Headers */ = {isa = PBXBuildFile; fileRef = 084D0E3911F5816100081E1A /* SVGResources.h */; settings = {ATTRIBUTES = (Private, ); }; }; 084D0E3E11F5816100081E1A /* SVGResourcesCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 084D0E3A11F5816100081E1A /* SVGResourcesCache.cpp */; }; 084D0E3F11F5816100081E1A /* SVGResourcesCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 084D0E3B11F5816100081E1A /* SVGResourcesCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 084DB59B128008CC002A6D64 /* SVGAnimatedString.h in Headers */ = {isa = PBXBuildFile; fileRef = 084DB59A128008CC002A6D64 /* SVGAnimatedString.h */; settings = {ATTRIBUTES = (Private, ); }; }; 084DBAA10ED39D360038C226 /* WMLVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 084DBA9D0ED39D350038C226 /* WMLVariables.cpp */; }; 084DBAA20ED39D360038C226 /* WMLVariables.h in Headers */ = {isa = PBXBuildFile; fileRef = 084DBA9E0ED39D360038C226 /* WMLVariables.h */; }; 08525E631278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 08525E621278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -171,6 +174,7 @@ 08807B7F0ED709AB003F6975 /* WMLRefreshElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08807B730ED709AB003F6975 /* WMLRefreshElement.h */; }; 08807B800ED709AB003F6975 /* WMLSetvarElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08807B740ED709AB003F6975 /* WMLSetvarElement.cpp */; }; 08807B810ED709AB003F6975 /* WMLSetvarElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08807B750ED709AB003F6975 /* WMLSetvarElement.h */; }; + 0880F70E1282B46D00948505 /* SVGStaticListPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 0880F70D1282B46D00948505 /* SVGStaticListPropertyTearOff.h */; settings = {ATTRIBUTES = (Private, ); }; }; 08820BDE0EF5D381009099A8 /* WMLTableElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08820BDC0EF5D381009099A8 /* WMLTableElement.cpp */; }; 08820BDF0EF5D381009099A8 /* WMLTableElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08820BDD0EF5D381009099A8 /* WMLTableElement.h */; }; 088451150F267B63007F139E /* WMLInputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 088451130F267B62007F139E /* WMLInputElement.cpp */; }; @@ -213,6 +217,8 @@ 08A484770E5272C500C3FE76 /* ScriptElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08A484750E5272C500C3FE76 /* ScriptElement.cpp */; }; 08A484780E5272C500C3FE76 /* ScriptElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08A484760E5272C500C3FE76 /* ScriptElement.h */; }; 08A48A6E0E86CF6D00E225DD /* JSSVGElementInstanceCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08A48A6D0E86CF6D00E225DD /* JSSVGElementInstanceCustom.cpp */; }; + 08B35B13127B6A7C005314DD /* SVGAnimatedNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 08B35B12127B6A7C005314DD /* SVGAnimatedNumber.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 08B35B17127B6A88005314DD /* SVGAnimatedNumberList.h in Headers */ = {isa = PBXBuildFile; fileRef = 08B35B16127B6A88005314DD /* SVGAnimatedNumberList.h */; settings = {ATTRIBUTES = (Private, ); }; }; 08C34AF51179C057002D7456 /* RenderSVGResourceGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08C34AF11179C056002D7456 /* RenderSVGResourceGradient.cpp */; }; 08C34AF61179C057002D7456 /* RenderSVGResourceGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 08C34AF21179C057002D7456 /* RenderSVGResourceGradient.h */; }; 08C34AF71179C057002D7456 /* RenderSVGResourceLinearGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08C34AF31179C057002D7456 /* RenderSVGResourceLinearGradient.cpp */; }; @@ -252,6 +258,7 @@ 08F0BFC61255C53C00075185 /* SVGTextMetrics.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F0BFC11255C53C00075185 /* SVGTextMetrics.h */; }; 08F2F0091213E61700DCEC48 /* RenderImageResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08F2F0071213E61700DCEC48 /* RenderImageResource.cpp */; }; 08F2F00A1213E61700DCEC48 /* RenderImageResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F2F0081213E61700DCEC48 /* RenderImageResource.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 08FE0BC5127E2AC1000C4FB5 /* SVGAnimatedPreserveAspectRatio.h in Headers */ = {isa = PBXBuildFile; fileRef = 08FE0BC4127E2AC1000C4FB5 /* SVGAnimatedPreserveAspectRatio.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0A4844990CA44CB200B7BD48 /* SoftLinking.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A4844980CA44CB200B7BD48 /* SoftLinking.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0AFDAC3D10F5448C00E1F3D2 /* PluginViewBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AFDAC3C10F5448C00E1F3D2 /* PluginViewBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0B8C56D40F28627F000502E1 /* HTTPHeaderMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B8C56D30F28627F000502E1 /* HTTPHeaderMap.cpp */; }; @@ -932,8 +939,6 @@ 41F061750F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F061730F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp */; }; 41F0618E0F5F069800A07EAC /* ConsoleMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F0618C0F5F069800A07EAC /* ConsoleMessage.h */; }; 41F0618F0F5F069800A07EAC /* ConsoleMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F0618D0F5F069800A07EAC /* ConsoleMessage.cpp */; }; - 41F062010F5F0B6600A07EAC /* InspectorResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F061FF0F5F0B6600A07EAC /* InspectorResource.h */; }; - 41F062020F5F0B6600A07EAC /* InspectorResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F062000F5F0B6600A07EAC /* InspectorResource.cpp */; }; 41F062140F5F192600A07EAC /* InspectorDatabaseResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */; }; 41F062150F5F192600A07EAC /* InspectorDatabaseResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */; }; 41F066E40F64BCF600A07EAC /* ScriptObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F066E20F64BCF600A07EAC /* ScriptObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -1136,6 +1141,11 @@ 4ACBC0C412713CCA0094F9B2 /* DOMSettableTokenList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4ACBC0C112713CCA0094F9B2 /* DOMSettableTokenList.h */; }; 4ACBC0CA12713D0A0094F9B2 /* JSDOMSettableTokenList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4ACBC0C812713D0A0094F9B2 /* JSDOMSettableTokenList.cpp */; }; 4ACBC0CB12713D0A0094F9B2 /* JSDOMSettableTokenList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4ACBC0C912713D0A0094F9B2 /* JSDOMSettableTokenList.h */; }; + 4AD01000127E63100015035F /* JSHTMLOutputElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AD00FFF127E63100015035F /* JSHTMLOutputElementCustom.cpp */; }; + 4AD01008127E642A0015035F /* HTMLOutputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AD01005127E642A0015035F /* HTMLOutputElement.cpp */; }; + 4AD01009127E642A0015035F /* HTMLOutputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AD01006127E642A0015035F /* HTMLOutputElement.h */; }; + 4AD0173C127E82860015035F /* JSHTMLOutputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AD0173A127E82860015035F /* JSHTMLOutputElement.cpp */; }; + 4AD0173D127E82860015035F /* JSHTMLOutputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AD0173B127E82860015035F /* JSHTMLOutputElement.h */; }; 4B2708C70AF19EE40065127F /* Pasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2708C50AF19EE40065127F /* Pasteboard.h */; }; 4B2709830AF2E5E00065127F /* PasteboardMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2709810AF2E5E00065127F /* PasteboardMac.mm */; }; 4B3043C70AE0370300A82647 /* Sound.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3043C60AE0370300A82647 /* Sound.h */; }; @@ -1473,6 +1483,9 @@ 6E4E91AD10F7FB3100A2779C /* CanvasContextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E4E91A810F7FB3100A2779C /* CanvasContextAttributes.h */; }; 6E4E91AE10F7FB3100A2779C /* WebGLContextAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E4E91A910F7FB3100A2779C /* WebGLContextAttributes.cpp */; }; 6E4E91AF10F7FB3100A2779C /* WebGLContextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E4E91AA10F7FB3100A2779C /* WebGLContextAttributes.h */; }; + 6E67D2A61280E8A4008758F7 /* Extensions3DOpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E67D2A41280E8A4008758F7 /* Extensions3DOpenGL.cpp */; }; + 6E67D2A71280E8A4008758F7 /* Extensions3DOpenGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E67D2A51280E8A4008758F7 /* Extensions3DOpenGL.h */; }; + 6E67D2A91280E8BD008758F7 /* Extensions3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E67D2A81280E8BD008758F7 /* Extensions3D.h */; }; 6E96BB1C11986EE2007D94CD /* IntegralTypedArrayBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E96BB1A11986EE1007D94CD /* IntegralTypedArrayBase.h */; }; 6E96BB1D11986EE2007D94CD /* TypedArrayBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E96BB1B11986EE1007D94CD /* TypedArrayBase.h */; }; 6EE8A77210F803F3005A4A24 /* JSWebGLContextAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6EE8A77010F803F3005A4A24 /* JSWebGLContextAttributes.cpp */; }; @@ -1546,6 +1559,7 @@ 7ADE722610CBBB9B006B3B3A /* ContextMenuProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */; }; 7AFD4A8B1131C2760035B883 /* ScriptBreakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AFD4A8A1131C2760035B883 /* ScriptBreakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; }; 7AFD4FF4113277B60035B883 /* ScriptDebugListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AFD4FF3113277B60035B883 /* ScriptDebugListener.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 7E33CD01127F340D00BE8F17 /* PurgePriority.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E33CD00127F340D00BE8F17 /* PurgePriority.h */; settings = {ATTRIBUTES = (Private, ); }; }; 81A7325E1210189B00FC0D9E /* IDBCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 81A7325D1210189B00FC0D9E /* IDBCursor.h */; }; 81A73260121018A400FC0D9E /* IDBCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81A7325F121018A400FC0D9E /* IDBCursor.cpp */; }; 81A73278121019E100FC0D9E /* IDBCursorBackendImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 81A73277121019E100FC0D9E /* IDBCursorBackendImpl.h */; }; @@ -2131,7 +2145,6 @@ 85ACABB00A9CAF8000671E90 /* DOMDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 85ACABAE0A9CAF8000671E90 /* DOMDocument.h */; settings = {ATTRIBUTES = (); }; }; 85ACABB10A9CAF8000671E90 /* DOMDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 85ACABAF0A9CAF8000671E90 /* DOMDocument.mm */; }; 85ACEF0C0ACDCCCF001214FF /* DOMSVGAnimatedPathData.h in Headers */ = {isa = PBXBuildFile; fileRef = 85ACEF060ACDCCCF001214FF /* DOMSVGAnimatedPathData.h */; }; - 85ACEF0D0ACDCCCF001214FF /* DOMSVGAnimatedPoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 85ACEF070ACDCCCF001214FF /* DOMSVGAnimatedPoints.h */; }; 85ACEF0E0ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.h in Headers */ = {isa = PBXBuildFile; fileRef = 85ACEF080ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.h */; }; 85ACEF0F0ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.mm in Sources */ = {isa = PBXBuildFile; fileRef = 85ACEF090ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.mm */; }; 85ACEF100ACDCCCF001214FF /* DOMSVGPreserveAspectRatio.h in Headers */ = {isa = PBXBuildFile; fileRef = 85ACEF0A0ACDCCCF001214FF /* DOMSVGPreserveAspectRatio.h */; }; @@ -2504,6 +2517,7 @@ 85FF315A0AAFBFCB00374F38 /* DOMKeyboardEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 85FF31580AAFBFCB00374F38 /* DOMKeyboardEvent.h */; }; 85FF315B0AAFBFCB00374F38 /* DOMKeyboardEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 85FF31590AAFBFCB00374F38 /* DOMKeyboardEvent.mm */; }; 86243D0111BC31F700CC006A /* JSArrayBufferViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */; }; + 86D982F7125C154000AD9E3D /* DocumentTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D982F6125C154000AD9E3D /* DocumentTiming.h */; settings = {ATTRIBUTES = (Private, ); }; }; 890AE0E11256A07900F5968C /* DirectoryReaderBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 890AE0E01256A07900F5968C /* DirectoryReaderBase.h */; }; 893C47A71238908B002B3D86 /* FileCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 893C47A51238908B002B3D86 /* FileCallback.h */; }; 893C47A81238908B002B3D86 /* FileWriterCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 893C47A61238908B002B3D86 /* FileWriterCallback.h */; }; @@ -2874,6 +2888,8 @@ 93F19B1508245E59001E9ABC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5C2869502846DCD018635CA /* Cocoa.framework */; }; 93F19B1608245E59001E9ABC /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8216299029F4FB501000131 /* JavaScriptCore.framework */; }; 93F19B1708245E59001E9ABC /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 93F1D31A0558CC5C00821BC0 /* libicucore.dylib */; }; + 93F6F1ED127F70B10055CB06 /* WebGLContextEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F6F1EA127F70B10055CB06 /* WebGLContextEvent.cpp */; }; + 93F6F1EE127F70B10055CB06 /* WebGLContextEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F6F1EB127F70B10055CB06 /* WebGLContextEvent.h */; }; 93F925430F7EF5B8007E37C9 /* CheckedRadioButtons.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F925410F7EF5B8007E37C9 /* CheckedRadioButtons.h */; settings = {ATTRIBUTES = (Private, ); }; }; 93F925440F7EF5B8007E37C9 /* CheckedRadioButtons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F925420F7EF5B8007E37C9 /* CheckedRadioButtons.cpp */; }; 93F9B6570BA0F35E00854064 /* DOMHTMLCanvasElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93F9B6540BA0F35E00854064 /* DOMHTMLCanvasElement.mm */; }; @@ -2972,6 +2988,8 @@ 97EF7DFE107E55B700D7C49C /* ScriptControllerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */; }; 9B417064125662B3006B28FC /* ApplyBlockElementCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B417062125662B3006B28FC /* ApplyBlockElementCommand.h */; settings = {ATTRIBUTES = (Private, ); }; }; 9B417065125662B3006B28FC /* ApplyBlockElementCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B417063125662B3006B28FC /* ApplyBlockElementCommand.cpp */; }; + 9BAB6C6C12550631001626D4 /* EditingStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BAB6C6A12550631001626D4 /* EditingStyle.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 9BAB6C6D12550631001626D4 /* EditingStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BAB6C6B12550631001626D4 /* EditingStyle.cpp */; }; 9F0D6B2E121BFEBA006C0288 /* InspectorProfilerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */; }; 9F0D6B2F121BFEBA006C0288 /* InspectorProfilerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */; }; 9F3B947E12241758005304E7 /* ScriptHeapSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F3B947D12241758005304E7 /* ScriptHeapSnapshot.h */; }; @@ -3151,7 +3169,6 @@ A80E7E9F0A1A83E3007FB8C5 /* JSHTMLButtonElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E7E950A1A83E3007FB8C5 /* JSHTMLButtonElement.h */; }; A80E7EA00A1A83E3007FB8C5 /* JSHTMLButtonElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A80E7E960A1A83E3007FB8C5 /* JSHTMLButtonElement.cpp */; }; A80F3A500CCDA2A2002DD990 /* DOMSVGFETurbulenceElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 8502AB3E0AD438C000378540 /* DOMSVGFETurbulenceElement.h */; }; - A80F3A5A0CCDA2ED002DD990 /* DOMSVGAnimatedPoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 85ACEF070ACDCCCF001214FF /* DOMSVGAnimatedPoints.h */; }; A80F3A640CCDA2FC002DD990 /* DOMSVGLineElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 85C9A2FD0AD7E94200FBFF1E /* DOMSVGLineElement.h */; }; A80F3A6B0CCDA30A002DD990 /* DOMSVGPathSegLinetoAbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 85CE1A2D0ADAC473003BBDEA /* DOMSVGPathSegLinetoAbs.h */; }; A80F3A750CCDA318002DD990 /* DOMSVGPathSegCurvetoQuadraticAbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 85CE1A250ADAC473003BBDEA /* DOMSVGPathSegCurvetoQuadraticAbs.h */; }; @@ -3260,7 +3277,6 @@ A80F3B910CCDCE24002DD990 /* DOMSVGFEGaussianBlurElement.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 8502AB2C0AD438C000378540 /* DOMSVGFEGaussianBlurElement.h */; }; A80F3B920CCDCE24002DD990 /* DOMSVGPaintInternal.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = A8E544400CA9D1C10097D09B /* DOMSVGPaintInternal.h */; }; A80F3B930CCDCE24002DD990 /* DOMSVGPathSegCurvetoQuadraticAbsInternal.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = A8E544200CA9D1C10097D09B /* DOMSVGPathSegCurvetoQuadraticAbsInternal.h */; }; - A80F3B940CCDCE24002DD990 /* DOMSVGAnimatedPoints.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85ACEF070ACDCCCF001214FF /* DOMSVGAnimatedPoints.h */; }; A80F3B950CCDCE24002DD990 /* DOMSVGPathSegLinetoAbs.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85CE1A2D0ADAC473003BBDEA /* DOMSVGPathSegLinetoAbs.h */; }; A80F3B960CCDCE24002DD990 /* DOMSVGNumberInternal.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = A8E544330CA9D1C10097D09B /* DOMSVGNumberInternal.h */; }; A80F3B970CCDCE24002DD990 /* DOMSVGAnimatedAngleInternal.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = A8E544BF0CA9D1C20097D09B /* DOMSVGAnimatedAngleInternal.h */; }; @@ -3952,8 +3968,6 @@ B222797A0D00BF220071B782 /* SVGAnimateColorElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277E40D00BF1F0071B782 /* SVGAnimateColorElement.h */; }; B22279840D00BF220071B782 /* SVGAnimatedPathData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22277EE0D00BF1F0071B782 /* SVGAnimatedPathData.cpp */; }; B22279850D00BF220071B782 /* SVGAnimatedPathData.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277EF0D00BF1F0071B782 /* SVGAnimatedPathData.h */; }; - B22279870D00BF220071B782 /* SVGAnimatedPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22277F10D00BF1F0071B782 /* SVGAnimatedPoints.cpp */; }; - B22279880D00BF220071B782 /* SVGAnimatedPoints.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277F20D00BF1F0071B782 /* SVGAnimatedPoints.h */; }; B222798F0D00BF220071B782 /* SVGAnimateElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22277F90D00BF1F0071B782 /* SVGAnimateElement.cpp */; }; B22279900D00BF220071B782 /* SVGAnimateElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277FA0D00BF1F0071B782 /* SVGAnimateElement.h */; }; B22279920D00BF220071B782 /* SVGAnimateMotionElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22277FC0D00BF1F0071B782 /* SVGAnimateMotionElement.cpp */; }; @@ -4659,6 +4673,7 @@ B776D43D1104527500BEB0EC /* PrintContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B776D43C1104527500BEB0EC /* PrintContext.cpp */; }; B885E8D411E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B885E8D211E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp */; }; B885E8D511E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = B885E8D311E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h */; settings = {ATTRIBUTES = (); }; }; + B8A6A6D5127B338D008673BA /* CorrectionPanelInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = B8A6A6D4127B338D008673BA /* CorrectionPanelInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC00F0040E0A185500FD04E3 /* DOMFile.h in Headers */ = {isa = PBXBuildFile; fileRef = BC00EFFE0E0A185500FD04E3 /* DOMFile.h */; }; BC00F0050E0A185500FD04E3 /* DOMFile.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC00EFFF0E0A185500FD04E3 /* DOMFile.mm */; }; BC00F0060E0A185500FD04E3 /* DOMFileInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = BC00F0000E0A185500FD04E3 /* DOMFileInternal.h */; }; @@ -5008,7 +5023,6 @@ BCA85A100C3AEAF4006F8308 /* DOMSVGNumberInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA85A0F0C3AEAF4006F8308 /* DOMSVGNumberInternal.h */; }; BCA8C81E11E3D36900812FB7 /* BackForwardController.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA8C81C11E3D36900812FB7 /* BackForwardController.h */; settings = {ATTRIBUTES = (Private, ); }; }; BCA8C81F11E3D36900812FB7 /* BackForwardController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA8C81D11E3D36900812FB7 /* BackForwardController.cpp */; }; - BCA8C83111E3D53200812FB7 /* BackForwardControllerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA8C83011E3D53200812FB7 /* BackForwardControllerClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; BCA8CA5F11E4E6D100812FB7 /* BackForwardListImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA8CA5D11E4E6D100812FB7 /* BackForwardListImpl.cpp */; }; BCA8CA6011E4E6D100812FB7 /* BackForwardListImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA8CA5E11E4E6D100812FB7 /* BackForwardListImpl.h */; settings = {ATTRIBUTES = (Private, ); }; }; BCA979171215D055005C485C /* ImageBufferData.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA979161215D055005C485C /* ImageBufferData.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -5016,8 +5030,8 @@ BCACF3BC1072921A00C0C8A3 /* UserContentURLPattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCACF3BA1072921A00C0C8A3 /* UserContentURLPattern.cpp */; }; BCACF3BD1072921A00C0C8A3 /* UserContentURLPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = BCACF3BB1072921A00C0C8A3 /* UserContentURLPattern.h */; settings = {ATTRIBUTES = (Private, ); }; }; BCAEFCAE1016CE4A0040D34E /* DOMRGBColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCAEFCAD1016CE4A0040D34E /* DOMRGBColor.mm */; }; - BCB16C170979C3BD00467741 /* Cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16BFE0979C3BD00467741 /* Cache.cpp */; }; - BCB16C180979C3BD00467741 /* Cache.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16BFF0979C3BD00467741 /* Cache.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BCB16C170979C3BD00467741 /* MemoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16BFE0979C3BD00467741 /* MemoryCache.cpp */; }; + BCB16C180979C3BD00467741 /* MemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16BFF0979C3BD00467741 /* MemoryCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; BCB16C190979C3BD00467741 /* CachedCSSStyleSheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C000979C3BD00467741 /* CachedCSSStyleSheet.cpp */; }; BCB16C1A0979C3BD00467741 /* CachedCSSStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C010979C3BD00467741 /* CachedCSSStyleSheet.h */; }; BCB16C1B0979C3BD00467741 /* CachedImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C020979C3BD00467741 /* CachedImage.cpp */; }; @@ -5486,6 +5500,10 @@ F3644AFF1119805900E0D537 /* InjectedScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F3644AFD1119805900E0D537 /* InjectedScript.cpp */; }; F3644B001119805900E0D537 /* InjectedScript.h in Headers */ = {isa = PBXBuildFile; fileRef = F3644AFE1119805900E0D537 /* InjectedScript.h */; }; F375CC071150D300008DDB81 /* InspectorWorkerResource.h in Headers */ = {isa = PBXBuildFile; fileRef = F375CC061150D300008DDB81 /* InspectorWorkerResource.h */; }; + F392249C126F11AE00A926D9 /* ScriptCallStackFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F392249A126F11AE00A926D9 /* ScriptCallStackFactory.cpp */; }; + F392249D126F11AE00A926D9 /* ScriptCallStackFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = F392249B126F11AE00A926D9 /* ScriptCallStackFactory.h */; }; + F39BE95B12673BF400E0A674 /* ScriptArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F39BE95912673BF400E0A674 /* ScriptArguments.cpp */; }; + F39BE95C12673BF400E0A674 /* ScriptArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = F39BE95A12673BF400E0A674 /* ScriptArguments.h */; }; F3D461481161D53200CA0D09 /* JSWorkerContextErrorHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F3D461461161D53200CA0D09 /* JSWorkerContextErrorHandler.cpp */; }; F3D461491161D53200CA0D09 /* JSWorkerContextErrorHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F3D461471161D53200CA0D09 /* JSWorkerContextErrorHandler.h */; }; F4EAF4AE10C742B1009100D3 /* OpenTypeSanitizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4EAF4AC10C742B1009100D3 /* OpenTypeSanitizer.cpp */; }; @@ -5544,6 +5562,8 @@ F55B3DE01251F12D003EF269 /* WeekInputType.h in Headers */ = {isa = PBXBuildFile; fileRef = F55B3DAC1251F12D003EF269 /* WeekInputType.h */; }; F59C95FF1255B23F000623C0 /* BaseDateAndTimeInputType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F59C95FD1255B23F000623C0 /* BaseDateAndTimeInputType.cpp */; }; F59C96001255B23F000623C0 /* BaseDateAndTimeInputType.h in Headers */ = {isa = PBXBuildFile; fileRef = F59C95FE1255B23F000623C0 /* BaseDateAndTimeInputType.h */; }; + F5A154271279534D00D0B0C0 /* ValidationMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A154251279534D00D0B0C0 /* ValidationMessage.cpp */; }; + F5A154281279534D00D0B0C0 /* ValidationMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A154261279534D00D0B0C0 /* ValidationMessage.h */; }; F5C041DA0FFCA7CE00839D4A /* HTMLDataListElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5C041D70FFCA7CE00839D4A /* HTMLDataListElement.cpp */; }; F5C041DB0FFCA7CE00839D4A /* HTMLDataListElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5C041D80FFCA7CE00839D4A /* HTMLDataListElement.h */; }; F5C041E30FFCA96D00839D4A /* DOMHTMLDataListElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5C041DE0FFCA96D00839D4A /* DOMHTMLDataListElement.h */; }; @@ -5795,7 +5815,6 @@ A8F46AAF0CB20A9D003A9670 /* DOMSVGAnimatedNumberList.h in Copy Generated Headers */, A80F3B700CCDCE24002DD990 /* DOMSVGAnimatedNumberListInternal.h in Copy Generated Headers */, A8F46A900CB20A9D003A9670 /* DOMSVGAnimatedPathData.h in Copy Generated Headers */, - A80F3B940CCDCE24002DD990 /* DOMSVGAnimatedPoints.h in Copy Generated Headers */, A8F46B2E0CB20A9D003A9670 /* DOMSVGAnimatedPreserveAspectRatio.h in Copy Generated Headers */, A80F3B7E0CCDCE24002DD990 /* DOMSVGAnimatedPreserveAspectRatioInternal.h in Copy Generated Headers */, A8F46B1B0CB20A9D003A9670 /* DOMSVGAnimatedRect.h in Copy Generated Headers */, @@ -6095,8 +6114,10 @@ 080E49241255F3BD00EFCA27 /* SVGTextLayoutEngineSpacing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextLayoutEngineSpacing.h; sourceTree = "<group>"; }; 080FAE180EEEBDA800AACDE9 /* WMLTemplateElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLTemplateElement.cpp; sourceTree = "<group>"; }; 080FAE190EEEBDA800AACDE9 /* WMLTemplateElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLTemplateElement.h; sourceTree = "<group>"; }; + 0810764312828556007C63BA /* SVGListProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGListProperty.h; sourceTree = "<group>"; }; 081093D91255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextLayoutAttributesBuilder.cpp; sourceTree = "<group>"; }; 081093DA1255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextLayoutAttributesBuilder.h; sourceTree = "<group>"; }; + 0813A4E91284132600992511 /* SVGStaticPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGStaticPropertyTearOff.h; sourceTree = "<group>"; }; 081668D1125603BF006F25DE /* SVGTextChunkBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextChunkBuilder.cpp; sourceTree = "<group>"; }; 081668D2125603BF006F25DE /* SVGTextChunkBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextChunkBuilder.h; sourceTree = "<group>"; }; 081668D7125603D5006F25DE /* SVGTextLayoutEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextLayoutEngine.cpp; sourceTree = "<group>"; }; @@ -6136,6 +6157,7 @@ 084D0E3911F5816100081E1A /* SVGResources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGResources.h; sourceTree = "<group>"; }; 084D0E3A11F5816100081E1A /* SVGResourcesCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGResourcesCache.cpp; sourceTree = "<group>"; }; 084D0E3B11F5816100081E1A /* SVGResourcesCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGResourcesCache.h; sourceTree = "<group>"; }; + 084DB59A128008CC002A6D64 /* SVGAnimatedString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedString.h; sourceTree = "<group>"; }; 084DBA9D0ED39D350038C226 /* WMLVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLVariables.cpp; sourceTree = "<group>"; }; 084DBA9E0ED39D360038C226 /* WMLVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLVariables.h; sourceTree = "<group>"; }; 08525E621278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedStaticPropertyTearOff.h; sourceTree = "<group>"; }; @@ -6194,6 +6216,7 @@ 08807B730ED709AB003F6975 /* WMLRefreshElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLRefreshElement.h; sourceTree = "<group>"; }; 08807B740ED709AB003F6975 /* WMLSetvarElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLSetvarElement.cpp; sourceTree = "<group>"; }; 08807B750ED709AB003F6975 /* WMLSetvarElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLSetvarElement.h; sourceTree = "<group>"; }; + 0880F70D1282B46D00948505 /* SVGStaticListPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGStaticListPropertyTearOff.h; sourceTree = "<group>"; }; 08820BDC0EF5D381009099A8 /* WMLTableElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLTableElement.cpp; sourceTree = "<group>"; }; 08820BDD0EF5D381009099A8 /* WMLTableElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLTableElement.h; sourceTree = "<group>"; }; 088451130F267B62007F139E /* WMLInputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLInputElement.cpp; sourceTree = "<group>"; }; @@ -6224,6 +6247,8 @@ 08A484750E5272C500C3FE76 /* ScriptElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptElement.cpp; sourceTree = "<group>"; }; 08A484760E5272C500C3FE76 /* ScriptElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptElement.h; sourceTree = "<group>"; }; 08A48A6D0E86CF6D00E225DD /* JSSVGElementInstanceCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGElementInstanceCustom.cpp; sourceTree = "<group>"; }; + 08B35B12127B6A7C005314DD /* SVGAnimatedNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedNumber.h; sourceTree = "<group>"; }; + 08B35B16127B6A88005314DD /* SVGAnimatedNumberList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedNumberList.h; sourceTree = "<group>"; }; 08C34AF11179C056002D7456 /* RenderSVGResourceGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGResourceGradient.cpp; sourceTree = "<group>"; }; 08C34AF21179C057002D7456 /* RenderSVGResourceGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGResourceGradient.h; sourceTree = "<group>"; }; 08C34AF31179C057002D7456 /* RenderSVGResourceLinearGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGResourceLinearGradient.cpp; sourceTree = "<group>"; }; @@ -6264,6 +6289,7 @@ 08F2F0081213E61700DCEC48 /* RenderImageResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderImageResource.h; sourceTree = "<group>"; }; 08FB84B00ECE373300DC064E /* WMLElementFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLElementFactory.cpp; sourceTree = "<group>"; }; 08FB84B10ECE373300DC064E /* WMLElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLElementFactory.h; sourceTree = "<group>"; }; + 08FE0BC4127E2AC1000C4FB5 /* SVGAnimatedPreserveAspectRatio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedPreserveAspectRatio.h; sourceTree = "<group>"; }; 0A4844980CA44CB200B7BD48 /* SoftLinking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoftLinking.h; sourceTree = "<group>"; }; 0AFDAC3C10F5448C00E1F3D2 /* PluginViewBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginViewBase.h; sourceTree = "<group>"; }; 0B8C56D30F28627F000502E1 /* HTTPHeaderMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPHeaderMap.cpp; sourceTree = "<group>"; }; @@ -7001,8 +7027,6 @@ 41F061730F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDOMStorageResource.cpp; sourceTree = "<group>"; }; 41F0618C0F5F069800A07EAC /* ConsoleMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleMessage.h; sourceTree = "<group>"; }; 41F0618D0F5F069800A07EAC /* ConsoleMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleMessage.cpp; sourceTree = "<group>"; }; - 41F061FF0F5F0B6600A07EAC /* InspectorResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorResource.h; sourceTree = "<group>"; }; - 41F062000F5F0B6600A07EAC /* InspectorResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorResource.cpp; sourceTree = "<group>"; }; 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDatabaseResource.h; sourceTree = "<group>"; }; 41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseResource.cpp; sourceTree = "<group>"; }; 41F066E20F64BCF600A07EAC /* ScriptObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptObject.h; sourceTree = "<group>"; }; @@ -7231,6 +7255,12 @@ 4ACBC0C212713CCA0094F9B2 /* DOMSettableTokenList.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DOMSettableTokenList.idl; sourceTree = "<group>"; }; 4ACBC0C812713D0A0094F9B2 /* JSDOMSettableTokenList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMSettableTokenList.cpp; sourceTree = "<group>"; }; 4ACBC0C912713D0A0094F9B2 /* JSDOMSettableTokenList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMSettableTokenList.h; sourceTree = "<group>"; }; + 4AD00FFF127E63100015035F /* JSHTMLOutputElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLOutputElementCustom.cpp; sourceTree = "<group>"; }; + 4AD01005127E642A0015035F /* HTMLOutputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLOutputElement.cpp; sourceTree = "<group>"; }; + 4AD01006127E642A0015035F /* HTMLOutputElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLOutputElement.h; sourceTree = "<group>"; }; + 4AD01007127E642A0015035F /* HTMLOutputElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLOutputElement.idl; sourceTree = "<group>"; }; + 4AD0173A127E82860015035F /* JSHTMLOutputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLOutputElement.cpp; sourceTree = "<group>"; }; + 4AD0173B127E82860015035F /* JSHTMLOutputElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSHTMLOutputElement.h; sourceTree = "<group>"; }; 4B2708C50AF19EE40065127F /* Pasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pasteboard.h; sourceTree = "<group>"; }; 4B2709810AF2E5E00065127F /* PasteboardMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteboardMac.mm; sourceTree = "<group>"; }; 4B3043C60AE0370300A82647 /* Sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Sound.h; sourceTree = "<group>"; }; @@ -7607,6 +7637,9 @@ 6E4E91A910F7FB3100A2779C /* WebGLContextAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebGLContextAttributes.cpp; path = canvas/WebGLContextAttributes.cpp; sourceTree = "<group>"; }; 6E4E91AA10F7FB3100A2779C /* WebGLContextAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLContextAttributes.h; path = canvas/WebGLContextAttributes.h; sourceTree = "<group>"; }; 6E4E91AB10F7FB3100A2779C /* WebGLContextAttributes.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WebGLContextAttributes.idl; path = canvas/WebGLContextAttributes.idl; sourceTree = "<group>"; }; + 6E67D2A41280E8A4008758F7 /* Extensions3DOpenGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Extensions3DOpenGL.cpp; sourceTree = "<group>"; }; + 6E67D2A51280E8A4008758F7 /* Extensions3DOpenGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Extensions3DOpenGL.h; sourceTree = "<group>"; }; + 6E67D2A81280E8BD008758F7 /* Extensions3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Extensions3D.h; sourceTree = "<group>"; }; 6E96BB1A11986EE1007D94CD /* IntegralTypedArrayBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IntegralTypedArrayBase.h; path = canvas/IntegralTypedArrayBase.h; sourceTree = "<group>"; }; 6E96BB1B11986EE1007D94CD /* TypedArrayBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TypedArrayBase.h; path = canvas/TypedArrayBase.h; sourceTree = "<group>"; }; 6EE8A77010F803F3005A4A24 /* JSWebGLContextAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebGLContextAttributes.cpp; sourceTree = "<group>"; }; @@ -7686,6 +7719,7 @@ 7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuProvider.h; sourceTree = "<group>"; }; 7AFD4A8A1131C2760035B883 /* ScriptBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptBreakpoint.h; sourceTree = "<group>"; }; 7AFD4FF3113277B60035B883 /* ScriptDebugListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptDebugListener.h; sourceTree = "<group>"; }; + 7E33CD00127F340D00BE8F17 /* PurgePriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PurgePriority.h; sourceTree = "<group>"; }; 81A7325D1210189B00FC0D9E /* IDBCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBCursor.h; sourceTree = "<group>"; }; 81A7325F121018A400FC0D9E /* IDBCursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBCursor.cpp; sourceTree = "<group>"; }; 81A73277121019E100FC0D9E /* IDBCursorBackendImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBCursorBackendImpl.h; sourceTree = "<group>"; }; @@ -8265,7 +8299,6 @@ 85ACABAE0A9CAF8000671E90 /* DOMDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMDocument.h; sourceTree = "<group>"; }; 85ACABAF0A9CAF8000671E90 /* DOMDocument.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMDocument.mm; sourceTree = "<group>"; }; 85ACEF060ACDCCCF001214FF /* DOMSVGAnimatedPathData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGAnimatedPathData.h; sourceTree = "<group>"; }; - 85ACEF070ACDCCCF001214FF /* DOMSVGAnimatedPoints.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGAnimatedPoints.h; sourceTree = "<group>"; }; 85ACEF080ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGAnimatedPreserveAspectRatio.h; sourceTree = "<group>"; }; 85ACEF090ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMSVGAnimatedPreserveAspectRatio.mm; sourceTree = "<group>"; }; 85ACEF0A0ACDCCCF001214FF /* DOMSVGPreserveAspectRatio.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGPreserveAspectRatio.h; sourceTree = "<group>"; }; @@ -8595,6 +8628,7 @@ 85FF31580AAFBFCB00374F38 /* DOMKeyboardEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMKeyboardEvent.h; sourceTree = "<group>"; }; 85FF31590AAFBFCB00374F38 /* DOMKeyboardEvent.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMKeyboardEvent.mm; sourceTree = "<group>"; }; 86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayBufferViewHelper.h; sourceTree = "<group>"; }; + 86D982F6125C154000AD9E3D /* DocumentTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentTiming.h; sourceTree = "<group>"; }; 890AE0E01256A07900F5968C /* DirectoryReaderBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DirectoryReaderBase.h; path = fileapi/DirectoryReaderBase.h; sourceTree = "<group>"; }; 893C47A51238908B002B3D86 /* FileCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileCallback.h; path = fileapi/FileCallback.h; sourceTree = "<group>"; }; 893C47A61238908B002B3D86 /* FileWriterCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileWriterCallback.h; path = fileapi/FileWriterCallback.h; sourceTree = "<group>"; }; @@ -8949,6 +8983,9 @@ 93F19B1908245E59001E9ABC /* Info.plist */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; 93F19B1A08245E5A001E9ABC /* WebCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WebCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 93F1D31A0558CC5C00821BC0 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = /usr/lib/libicucore.dylib; sourceTree = "<absolute>"; }; + 93F6F1EA127F70B10055CB06 /* WebGLContextEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebGLContextEvent.cpp; path = canvas/WebGLContextEvent.cpp; sourceTree = "<group>"; }; + 93F6F1EB127F70B10055CB06 /* WebGLContextEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLContextEvent.h; path = canvas/WebGLContextEvent.h; sourceTree = "<group>"; }; + 93F6F1EC127F70B10055CB06 /* WebGLContextEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WebGLContextEvent.idl; path = canvas/WebGLContextEvent.idl; sourceTree = "<group>"; }; 93F8B3050A300FE100F61AB8 /* CodeGenerator.pm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = CodeGenerator.pm; path = scripts/CodeGenerator.pm; sourceTree = "<group>"; }; 93F8B3060A300FEA00F61AB8 /* CodeGeneratorJS.pm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = CodeGeneratorJS.pm; path = ../scripts/CodeGeneratorJS.pm; sourceTree = "<group>"; wrapsLines = 0; }; 93F8B3070A300FEA00F61AB8 /* generate-bindings.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = "generate-bindings.pl"; path = "scripts/generate-bindings.pl"; sourceTree = "<group>"; }; @@ -9053,6 +9090,8 @@ 97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptControllerBase.cpp; sourceTree = "<group>"; }; 9B417062125662B3006B28FC /* ApplyBlockElementCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplyBlockElementCommand.h; sourceTree = "<group>"; }; 9B417063125662B3006B28FC /* ApplyBlockElementCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApplyBlockElementCommand.cpp; sourceTree = "<group>"; }; + 9BAB6C6A12550631001626D4 /* EditingStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditingStyle.h; sourceTree = "<group>"; }; + 9BAB6C6B12550631001626D4 /* EditingStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditingStyle.cpp; sourceTree = "<group>"; }; 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorProfilerAgent.cpp; sourceTree = "<group>"; }; 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorProfilerAgent.h; sourceTree = "<group>"; }; 9F3B947D12241758005304E7 /* ScriptHeapSnapshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptHeapSnapshot.h; sourceTree = "<group>"; }; @@ -9796,9 +9835,6 @@ B22277EE0D00BF1F0071B782 /* SVGAnimatedPathData.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedPathData.cpp; sourceTree = "<group>"; }; B22277EF0D00BF1F0071B782 /* SVGAnimatedPathData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedPathData.h; sourceTree = "<group>"; }; B22277F00D00BF1F0071B782 /* SVGAnimatedPathData.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SVGAnimatedPathData.idl; sourceTree = "<group>"; }; - B22277F10D00BF1F0071B782 /* SVGAnimatedPoints.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedPoints.cpp; sourceTree = "<group>"; }; - B22277F20D00BF1F0071B782 /* SVGAnimatedPoints.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedPoints.h; sourceTree = "<group>"; }; - B22277F30D00BF1F0071B782 /* SVGAnimatedPoints.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SVGAnimatedPoints.idl; sourceTree = "<group>"; }; B22277F40D00BF1F0071B782 /* SVGAnimatedPreserveAspectRatio.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SVGAnimatedPreserveAspectRatio.idl; sourceTree = "<group>"; }; B22277F50D00BF1F0071B782 /* SVGAnimatedRect.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SVGAnimatedRect.idl; sourceTree = "<group>"; }; B22277F60D00BF1F0071B782 /* SVGAnimatedString.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SVGAnimatedString.idl; sourceTree = "<group>"; }; @@ -10649,6 +10685,7 @@ B776D43C1104527500BEB0EC /* PrintContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrintContext.cpp; sourceTree = "<group>"; }; B885E8D211E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorApplicationCacheAgent.cpp; sourceTree = "<group>"; }; B885E8D311E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorApplicationCacheAgent.h; sourceTree = "<group>"; }; + B8A6A6D4127B338D008673BA /* CorrectionPanelInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CorrectionPanelInfo.h; sourceTree = "<group>"; }; BC00EFFE0E0A185500FD04E3 /* DOMFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFile.h; sourceTree = "<group>"; }; BC00EFFF0E0A185500FD04E3 /* DOMFile.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMFile.mm; sourceTree = "<group>"; }; BC00F0000E0A185500FD04E3 /* DOMFileInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFileInternal.h; sourceTree = "<group>"; }; @@ -11021,7 +11058,6 @@ BCA85A0F0C3AEAF4006F8308 /* DOMSVGNumberInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGNumberInternal.h; sourceTree = "<group>"; }; BCA8C81C11E3D36900812FB7 /* BackForwardController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardController.h; sourceTree = "<group>"; }; BCA8C81D11E3D36900812FB7 /* BackForwardController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackForwardController.cpp; sourceTree = "<group>"; }; - BCA8C83011E3D53200812FB7 /* BackForwardControllerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardControllerClient.h; sourceTree = "<group>"; }; BCA8CA5D11E4E6D100812FB7 /* BackForwardListImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackForwardListImpl.cpp; sourceTree = "<group>"; }; BCA8CA5E11E4E6D100812FB7 /* BackForwardListImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardListImpl.h; sourceTree = "<group>"; }; BCA979161215D055005C485C /* ImageBufferData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferData.h; sourceTree = "<group>"; }; @@ -11029,8 +11065,8 @@ BCACF3BA1072921A00C0C8A3 /* UserContentURLPattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserContentURLPattern.cpp; sourceTree = "<group>"; }; BCACF3BB1072921A00C0C8A3 /* UserContentURLPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserContentURLPattern.h; sourceTree = "<group>"; }; BCAEFCAD1016CE4A0040D34E /* DOMRGBColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMRGBColor.mm; sourceTree = "<group>"; }; - BCB16BFE0979C3BD00467741 /* Cache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Cache.cpp; sourceTree = "<group>"; }; - BCB16BFF0979C3BD00467741 /* Cache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Cache.h; sourceTree = "<group>"; }; + BCB16BFE0979C3BD00467741 /* MemoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryCache.cpp; sourceTree = "<group>"; }; + BCB16BFF0979C3BD00467741 /* MemoryCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MemoryCache.h; sourceTree = "<group>"; }; BCB16C000979C3BD00467741 /* CachedCSSStyleSheet.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CachedCSSStyleSheet.cpp; sourceTree = "<group>"; }; BCB16C010979C3BD00467741 /* CachedCSSStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedCSSStyleSheet.h; sourceTree = "<group>"; }; BCB16C020979C3BD00467741 /* CachedImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CachedImage.cpp; sourceTree = "<group>"; }; @@ -11491,7 +11527,6 @@ E44614120CD6826900FADA75 /* JSTimeRanges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTimeRanges.cpp; sourceTree = "<group>"; }; E44614130CD6826900FADA75 /* JSTimeRanges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTimeRanges.h; sourceTree = "<group>"; }; E462A4A0113E71BE004A4220 /* IntPointHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntPointHash.h; sourceTree = "<group>"; }; - E472053A0E5A053A0006BB4D /* CachedResourceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedResourceHandle.h; sourceTree = "<group>"; }; E4778B7D115A581A00B5D372 /* JSCustomEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomEvent.cpp; sourceTree = "<group>"; }; E4778B7E115A581A00B5D372 /* JSCustomEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomEvent.h; sourceTree = "<group>"; }; E47B4BE60E71241600038854 /* CachedResourceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedResourceHandle.h; sourceTree = "<group>"; }; @@ -11542,6 +11577,10 @@ F3644AFD1119805900E0D537 /* InjectedScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedScript.cpp; sourceTree = "<group>"; }; F3644AFE1119805900E0D537 /* InjectedScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedScript.h; sourceTree = "<group>"; }; F375CC061150D300008DDB81 /* InspectorWorkerResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorWorkerResource.h; sourceTree = "<group>"; }; + F392249A126F11AE00A926D9 /* ScriptCallStackFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptCallStackFactory.cpp; sourceTree = "<group>"; }; + F392249B126F11AE00A926D9 /* ScriptCallStackFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptCallStackFactory.h; sourceTree = "<group>"; }; + F39BE95912673BF400E0A674 /* ScriptArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptArguments.cpp; sourceTree = "<group>"; }; + F39BE95A12673BF400E0A674 /* ScriptArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptArguments.h; sourceTree = "<group>"; }; F3D461461161D53200CA0D09 /* JSWorkerContextErrorHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerContextErrorHandler.cpp; sourceTree = "<group>"; }; F3D461471161D53200CA0D09 /* JSWorkerContextErrorHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWorkerContextErrorHandler.h; sourceTree = "<group>"; }; F4EAF4AC10C742B1009100D3 /* OpenTypeSanitizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenTypeSanitizer.cpp; path = opentype/OpenTypeSanitizer.cpp; sourceTree = "<group>"; }; @@ -11621,6 +11660,8 @@ F587869902DE3B8601EA4122 /* DeprecatedPtrList.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = DeprecatedPtrList.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; F59C95FD1255B23F000623C0 /* BaseDateAndTimeInputType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BaseDateAndTimeInputType.cpp; sourceTree = "<group>"; }; F59C95FE1255B23F000623C0 /* BaseDateAndTimeInputType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseDateAndTimeInputType.h; sourceTree = "<group>"; }; + F5A154251279534D00D0B0C0 /* ValidationMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ValidationMessage.cpp; sourceTree = "<group>"; }; + F5A154261279534D00D0B0C0 /* ValidationMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidationMessage.h; sourceTree = "<group>"; }; F5C041D70FFCA7CE00839D4A /* HTMLDataListElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLDataListElement.cpp; sourceTree = "<group>"; }; F5C041D80FFCA7CE00839D4A /* HTMLDataListElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLDataListElement.h; sourceTree = "<group>"; }; F5C041D90FFCA7CE00839D4A /* HTMLDataListElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLDataListElement.idl; sourceTree = "<group>"; }; @@ -11750,10 +11791,13 @@ 081CDFBE126ECFE800D215CA /* SVGAnimatedPropertySynchronizer.h */, 088A0DFF126EF1DB00978F7A /* SVGAnimatedPropertyTearOff.h */, 08525E621278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h */, + 0810764312828556007C63BA /* SVGListProperty.h */, 088A0E00126EF1DB00978F7A /* SVGListPropertyTearOff.h */, 088A0E01126EF1DB00978F7A /* SVGProperty.h */, 088A0E02126EF1DB00978F7A /* SVGPropertyTearOff.h */, 088A0E03126EF1DB00978F7A /* SVGPropertyTraits.h */, + 0880F70D1282B46D00948505 /* SVGStaticListPropertyTearOff.h */, + 0813A4E91284132600992511 /* SVGStaticPropertyTearOff.h */, ); path = properties; sourceTree = "<group>"; @@ -12298,8 +12342,6 @@ 20D629251253690B00081543 /* InspectorInstrumentation.h */, 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */, 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */, - 41F062000F5F0B6600A07EAC /* InspectorResource.cpp */, - 41F061FF0F5F0B6600A07EAC /* InspectorResource.h */, 82AB1771125C826700C5069D /* InspectorResourceAgent.cpp */, 82AB1772125C826700C5069D /* InspectorResourceAgent.h */, 4FA3B908125CD12100300BAD /* InspectorState.cpp */, @@ -12315,8 +12357,14 @@ F375CC061150D300008DDB81 /* InspectorWorkerResource.h */, 1C81BA050E97348300266E07 /* JavaScriptCallFrame.idl */, BCC64F5F0DCFB84E0081EF3B /* localizedStrings.js */, + F39BE95912673BF400E0A674 /* ScriptArguments.cpp */, + F39BE95A12673BF400E0A674 /* ScriptArguments.h */, 200B190811C277D900DCCD3A /* ScriptBreakpoint.cpp */, 7AFD4A8A1131C2760035B883 /* ScriptBreakpoint.h */, + 416E75CA0EDF90C700360E1D /* ScriptCallFrame.cpp */, + 416E75C90EDF90C700360E1D /* ScriptCallFrame.h */, + 416E75BD0EDF8FD700360E1D /* ScriptCallStack.cpp */, + 416E75BC0EDF8FD700360E1D /* ScriptCallStack.h */, 7AFD4FF3113277B60035B883 /* ScriptDebugListener.h */, 9FA37EEF1172FD4100C4CD55 /* ScriptProfile.idl */, 9FA37EF01172FD4100C4CD55 /* ScriptProfileNode.idl */, @@ -12566,6 +12614,9 @@ 6E4E91A910F7FB3100A2779C /* WebGLContextAttributes.cpp */, 6E4E91AA10F7FB3100A2779C /* WebGLContextAttributes.h */, 6E4E91AB10F7FB3100A2779C /* WebGLContextAttributes.idl */, + 93F6F1EA127F70B10055CB06 /* WebGLContextEvent.cpp */, + 93F6F1EB127F70B10055CB06 /* WebGLContextEvent.h */, + 93F6F1EC127F70B10055CB06 /* WebGLContextEvent.idl */, 49C7B9AE1042D32E0009D447 /* WebGLFramebuffer.cpp */, 49C7B9AF1042D32E0009D447 /* WebGLFramebuffer.h */, 49C7B9B01042D32E0009D447 /* WebGLFramebuffer.idl */, @@ -12824,7 +12875,6 @@ 5160F4920B0AA71500C1D2AF /* mac */, BCA8C81D11E3D36900812FB7 /* BackForwardController.cpp */, BCA8C81C11E3D36900812FB7 /* BackForwardController.h */, - BCA8C83011E3D53200812FB7 /* BackForwardControllerClient.h */, 51741D0B0B07259A00ED442C /* BackForwardList.h */, BCA8CA5D11E4E6D100812FB7 /* BackForwardListImpl.cpp */, BCA8CA5E11E4E6D100812FB7 /* BackForwardListImpl.h */, @@ -13509,7 +13559,6 @@ A8E544B10CA9D1C20097D09B /* DOMSVGAnimatedNumberListInternal.h */, A8E544B00CA9D1C20097D09B /* DOMSVGAnimatedPathData.h */, 85ACEF060ACDCCCF001214FF /* DOMSVGAnimatedPathData.h */, - 85ACEF070ACDCCCF001214FF /* DOMSVGAnimatedPoints.h */, 85ACEF080ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.h */, 85ACEF090ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.mm */, A8E544AD0CA9D1C20097D09B /* DOMSVGAnimatedPreserveAspectRatioInternal.h */, @@ -14470,6 +14519,7 @@ 93309D8C099E64910056E581 /* BreakBlockquoteCommand.h */, 93309D8D099E64910056E581 /* CompositeEditCommand.cpp */, 93309D8E099E64910056E581 /* CompositeEditCommand.h */, + B8A6A6D4127B338D008673BA /* CorrectionPanelInfo.h */, D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */, D0B0556609C6700100307E43 /* CreateLinkCommand.h */, 1C4C8F630AD8655D009475CE /* DeleteButton.cpp */, @@ -14485,6 +14535,8 @@ 93309D95099E64910056E581 /* EditCommand.h */, 4F1534DD11B532EC0021FD86 /* EditingBehavior.h */, 4F1534DF11B533020021FD86 /* EditingBehaviorTypes.h */, + 9BAB6C6A12550631001626D4 /* EditingStyle.h */, + 9BAB6C6B12550631001626D4 /* EditingStyle.cpp */, 4B3043CA0AE0373B00A82647 /* Editor.cpp */, 4B3043CB0AE0373B00A82647 /* Editor.h */, 93A38B4A0D0E5808006872C2 /* EditorCommand.cpp */, @@ -14845,6 +14897,9 @@ 9327A94109968D1A0068A546 /* HTMLOptionsCollection.cpp */, A81369BE097374F500D74463 /* HTMLOptionsCollection.h */, 85DF2F920AA3C9B600AD64C5 /* HTMLOptionsCollection.idl */, + 4AD01005127E642A0015035F /* HTMLOutputElement.cpp */, + 4AD01006127E642A0015035F /* HTMLOutputElement.h */, + 4AD01007127E642A0015035F /* HTMLOutputElement.idl */, A8EA7CA40A192B9C00A8EF5F /* HTMLParagraphElement.cpp */, A8EA7CA70A192B9C00A8EF5F /* HTMLParagraphElement.h */, 1AE2AB610A1CE7CA00B42B25 /* HTMLParagraphElement.idl */, @@ -14972,6 +15027,8 @@ E446139F0CD6331000FADA75 /* TimeRanges.idl */, F55B3DA91251F12D003EF269 /* URLInputType.cpp */, F55B3DAA1251F12D003EF269 /* URLInputType.h */, + F5A154251279534D00D0B0C0 /* ValidationMessage.cpp */, + F5A154261279534D00D0B0C0 /* ValidationMessage.h */, 15C7708B100D3C6A005BA267 /* ValidityState.cpp */, 15C7708A100D3C6A005BA267 /* ValidityState.h */, 15C77089100D3C6A005BA267 /* ValidityState.idl */, @@ -15322,6 +15379,8 @@ A80E7E8F0A1A83E3007FB8C5 /* JSHTMLOptionElement.h */, 448A29BE0A46D9CB0030759F /* JSHTMLOptionsCollection.cpp */, 448A29BD0A46D9CB0030759F /* JSHTMLOptionsCollection.h */, + 4AD0173A127E82860015035F /* JSHTMLOutputElement.cpp */, + 4AD0173B127E82860015035F /* JSHTMLOutputElement.h */, 1AE2AB9E0A1CE90500B42B25 /* JSHTMLParagraphElement.cpp */, 1AE2AB9F0A1CE90500B42B25 /* JSHTMLParagraphElement.h */, 1AE2ABA00A1CE90500B42B25 /* JSHTMLParamElement.cpp */, @@ -15967,6 +16026,35 @@ name = XML; sourceTree = "<group>"; }; + A8D2B2521287A56000AF4DDA /* cache */ = { + isa = PBXGroup; + children = ( + BCB16C000979C3BD00467741 /* CachedCSSStyleSheet.cpp */, + BCB16C010979C3BD00467741 /* CachedCSSStyleSheet.h */, + BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */, + BC64B4CA0CB4295D005F2B62 /* CachedFont.h */, + BCB16C020979C3BD00467741 /* CachedImage.cpp */, + BCB16C030979C3BD00467741 /* CachedImage.h */, + BCB16C060979C3BD00467741 /* CachedResource.cpp */, + BCB16C070979C3BD00467741 /* CachedResource.h */, + BCFB2E5D0979E46400BA703D /* CachedResourceClient.h */, + BCB16C080979C3BD00467741 /* CachedResourceClientWalker.cpp */, + BCB16C090979C3BD00467741 /* CachedResourceClientWalker.h */, + E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */, + E47B4BE60E71241600038854 /* CachedResourceHandle.h */, + BCB16C100979C3BD00467741 /* CachedResourceLoader.cpp */, + BCB16C110979C3BD00467741 /* CachedResourceLoader.h */, + BCB16C0A0979C3BD00467741 /* CachedScript.cpp */, + BCB16C0B0979C3BD00467741 /* CachedScript.h */, + BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */, + BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */, + F587864902DE3A9A01EA4122 /* CachePolicy.h */, + BCB16BFE0979C3BD00467741 /* MemoryCache.cpp */, + BCB16BFF0979C3BD00467741 /* MemoryCache.h */, + ); + path = cache; + sourceTree = "<group>"; + }; A9D247F90D757E4100FDF959 /* Plugins */ = { isa = PBXGroup; children = ( @@ -16023,17 +16111,18 @@ B22277EA0D00BF1F0071B782 /* SVGAnimatedLength.idl */, 089021AC126EF5E90092D5EA /* SVGAnimatedLengthList.h */, B22277EB0D00BF1F0071B782 /* SVGAnimatedLengthList.idl */, + 08B35B12127B6A7C005314DD /* SVGAnimatedNumber.h */, B22277EC0D00BF1F0071B782 /* SVGAnimatedNumber.idl */, + 08B35B16127B6A88005314DD /* SVGAnimatedNumberList.h */, B22277ED0D00BF1F0071B782 /* SVGAnimatedNumberList.idl */, B22277EE0D00BF1F0071B782 /* SVGAnimatedPathData.cpp */, B22277EF0D00BF1F0071B782 /* SVGAnimatedPathData.h */, B22277F00D00BF1F0071B782 /* SVGAnimatedPathData.idl */, - B22277F10D00BF1F0071B782 /* SVGAnimatedPoints.cpp */, - B22277F20D00BF1F0071B782 /* SVGAnimatedPoints.h */, - B22277F30D00BF1F0071B782 /* SVGAnimatedPoints.idl */, + 08FE0BC4127E2AC1000C4FB5 /* SVGAnimatedPreserveAspectRatio.h */, B22277F40D00BF1F0071B782 /* SVGAnimatedPreserveAspectRatio.idl */, 08C859BF1274575300A5728D /* SVGAnimatedRect.h */, B22277F50D00BF1F0071B782 /* SVGAnimatedRect.idl */, + 084DB59A128008CC002A6D64 /* SVGAnimatedString.h */, B22277F60D00BF1F0071B782 /* SVGAnimatedString.idl */, B22277F80D00BF1F0071B782 /* SVGAnimatedTransformList.idl */, B22277F90D00BF1F0071B782 /* SVGAnimateElement.cpp */, @@ -16573,6 +16662,7 @@ B27535390B053814002CE64F /* Color.h */, 9382DF5710A8D5C900925652 /* ColorSpace.h */, A8CB41020E85B8A50032C4F0 /* DashArray.h */, + 6E67D2A81280E8BD008758F7 /* Extensions3D.h */, B275353A0B053814002CE64F /* FloatPoint.cpp */, B275353B0B053814002CE64F /* FloatPoint.h */, B2E27C9D0B0F2B0900F17C7B /* FloatPoint3D.cpp */, @@ -16859,10 +16949,8 @@ BCA378BB0D15F64200B793D6 /* ScheduledAction.h */, 41F1D21E0EF35C2A00DA8753 /* ScriptCachedFrameData.cpp */, 41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */, - 416E75CA0EDF90C700360E1D /* ScriptCallFrame.cpp */, - 416E75C90EDF90C700360E1D /* ScriptCallFrame.h */, - 416E75BD0EDF8FD700360E1D /* ScriptCallStack.cpp */, - 416E75BC0EDF8FD700360E1D /* ScriptCallStack.h */, + F392249A126F11AE00A926D9 /* ScriptCallStackFactory.cpp */, + F392249B126F11AE00A926D9 /* ScriptCallStackFactory.h */, 93B70D5309EB0C7C009D8468 /* ScriptController.cpp */, 93B70D5409EB0C7C009D8468 /* ScriptController.h */, A83E1C720E49042B00140B9C /* ScriptControllerMac.mm */, @@ -17002,6 +17090,7 @@ BCC438770E886CC700533DD5 /* JSHTMLInputElementCustom.cpp */, BC305CA30C0781BB00CD20F0 /* JSHTMLObjectElementCustom.cpp */, 448AD27A0A4813790023D179 /* JSHTMLOptionsCollectionCustom.cpp */, + 4AD00FFF127E63100015035F /* JSHTMLOutputElementCustom.cpp */, BC17F9650B64EBB8004A65CB /* JSHTMLSelectElementCustom.cpp */, AB4CB4EA0B8BDA3D009F40B0 /* JSHTMLSelectElementCustom.h */, C585A65C11D4FAB2004C3E4B /* JSIDBAnyCustom.cpp */, @@ -17184,33 +17273,11 @@ BCB16BFB0979C38700467741 /* loader */ = { isa = PBXGroup; children = ( + A8D2B2521287A56000AF4DDA /* cache */, 1A8F6BB00DB55CDC001DB794 /* appcache */, 512DD8E80D91E691000F89EE /* archive */, 5126E6B60A2E3AEF005C29FA /* icon */, 93A1EAA20A5634D8006960A0 /* mac */, - BCB16BFE0979C3BD00467741 /* Cache.cpp */, - BCB16BFF0979C3BD00467741 /* Cache.h */, - BCB16C000979C3BD00467741 /* CachedCSSStyleSheet.cpp */, - BCB16C010979C3BD00467741 /* CachedCSSStyleSheet.h */, - BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */, - BC64B4CA0CB4295D005F2B62 /* CachedFont.h */, - BCB16C020979C3BD00467741 /* CachedImage.cpp */, - BCB16C030979C3BD00467741 /* CachedImage.h */, - BCB16C060979C3BD00467741 /* CachedResource.cpp */, - BCB16C070979C3BD00467741 /* CachedResource.h */, - BCFB2E5D0979E46400BA703D /* CachedResourceClient.h */, - BCB16C080979C3BD00467741 /* CachedResourceClientWalker.cpp */, - BCB16C090979C3BD00467741 /* CachedResourceClientWalker.h */, - E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */, - E47B4BE60E71241600038854 /* CachedResourceHandle.h */, - E472053A0E5A053A0006BB4D /* CachedResourceHandle.h */, - BCB16C100979C3BD00467741 /* CachedResourceLoader.cpp */, - BCB16C110979C3BD00467741 /* CachedResourceLoader.h */, - BCB16C0A0979C3BD00467741 /* CachedScript.cpp */, - BCB16C0B0979C3BD00467741 /* CachedScript.h */, - BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */, - BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */, - F587864902DE3A9A01EA4122 /* CachePolicy.h */, E1C416160F6563180092D2FB /* CrossOriginAccessControl.cpp */, E1C416110F6562FD0092D2FB /* CrossOriginAccessControl.h */, E1C415DD0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp */, @@ -17417,6 +17484,7 @@ ABC128760B33AA6D00C693D5 /* PopupMenuClient.h */, BC3BE12A0E98092F00835588 /* PopupMenuStyle.h */, E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */, + 7E33CD00127F340D00BE8F17 /* PurgePriority.h */, 1C63A2460F71646600C09D5A /* RunLoopTimer.h */, 5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */, 5162C7F311F77EFB00612EFE /* SchemeRegistry.h */, @@ -18132,6 +18200,7 @@ CE057FA41220731100A476D5 /* DocumentMarkerController.h */, A8C2280D11D4A59700D5A7D3 /* DocumentParser.cpp */, BCCFBAE70B5152ED0001F1D7 /* DocumentParser.h */, + 86D982F6125C154000AD9E3D /* DocumentTiming.h */, A8185F3209765765005826D9 /* DocumentType.cpp */, A8185F3109765765005826D9 /* DocumentType.h */, 93EEC1E809C2877700C515D1 /* DocumentType.idl */, @@ -18377,6 +18446,8 @@ FBC220DD1237FBEB00BCF788 /* opengl */ = { isa = PBXGroup; children = ( + 6E67D2A41280E8A4008758F7 /* Extensions3DOpenGL.cpp */, + 6E67D2A51280E8A4008758F7 /* Extensions3DOpenGL.h */, FBC220DE1237FBEB00BCF788 /* GraphicsContext3DOpenGL.cpp */, ); path = opengl; @@ -18454,7 +18525,6 @@ A8CFF04E0A154F09000A4234 /* AutoTableLayout.h in Headers */, 29A812380FBB9C1D00510293 /* AXObjectCache.h in Headers */, BCA8C81E11E3D36900812FB7 /* BackForwardController.h in Headers */, - BCA8C83111E3D53200812FB7 /* BackForwardControllerClient.h in Headers */, 51741D0F0B07259A00ED442C /* BackForwardList.h in Headers */, BCA8CA6011E4E6D100812FB7 /* BackForwardListImpl.h in Headers */, BC124EE80C2641CD009E2349 /* BarInfo.h in Headers */, @@ -18495,7 +18565,7 @@ 1A569CFA0D7E2B82007C3983 /* c_instance.h in Headers */, 1A569CFC0D7E2B82007C3983 /* c_runtime.h in Headers */, 1A569CFE0D7E2B82007C3983 /* c_utility.h in Headers */, - BCB16C180979C3BD00467741 /* Cache.h in Headers */, + BCB16C180979C3BD00467741 /* MemoryCache.h in Headers */, BCB16C1A0979C3BD00467741 /* CachedCSSStyleSheet.h in Headers */, BC64B4CC0CB4295D005F2B62 /* CachedFont.h in Headers */, 51C0AA390F2AA10A001648C2 /* CachedFrame.h in Headers */, @@ -18567,6 +18637,7 @@ D8B6152F1032495100C8554A /* Cookie.h in Headers */, 9352088209BD45E900F2038D /* CookieJar.h in Headers */, FE6FD4880F676E5700092873 /* Coordinates.h in Headers */, + B8A6A6D5127B338D008673BA /* CorrectionPanelInfo.h in Headers */, A80E6D040A1989CA007FB8C5 /* Counter.h in Headers */, BC5EB9790E82069200B25965 /* CounterContent.h in Headers */, BC5EB9510E82056B00B25965 /* CounterDirectives.h in Headers */, @@ -18695,6 +18766,7 @@ CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */, BCCFBAE80B5152ED0001F1D7 /* DocumentParser.h in Headers */, 0B90561A0F2578BF0095FF6A /* DocumentThreadableLoader.h in Headers */, + 86D982F7125C154000AD9E3D /* DocumentTiming.h in Headers */, A8185F3909765766005826D9 /* DocumentType.h in Headers */, 973889A1116EA9DC00ADF313 /* DocumentWriter.h in Headers */, BC1A37AD097C715F0019F3D8 /* DOM.h in Headers */, @@ -19010,8 +19082,6 @@ A8E545AF0CA9D1C20097D09B /* DOMSVGAnimatedNumberListInternal.h in Headers */, 85ACEF0C0ACDCCCF001214FF /* DOMSVGAnimatedPathData.h in Headers */, A8E545AE0CA9D1C20097D09B /* DOMSVGAnimatedPathData.h in Headers */, - 85ACEF0D0ACDCCCF001214FF /* DOMSVGAnimatedPoints.h in Headers */, - A80F3A5A0CCDA2ED002DD990 /* DOMSVGAnimatedPoints.h in Headers */, 85ACEF0E0ACDCCCF001214FF /* DOMSVGAnimatedPreserveAspectRatio.h in Headers */, 85ACEF180ACDCD1A001214FF /* DOMSVGAnimatedPreserveAspectRatioInternal.h in Headers */, A8E545AB0CA9D1C20097D09B /* DOMSVGAnimatedPreserveAspectRatioInternal.h in Headers */, @@ -19466,6 +19536,7 @@ 93309DE4099E64920056E581 /* EditCommand.h in Headers */, 4F1534DE11B532EC0021FD86 /* EditingBehavior.h in Headers */, 4F1534E011B533020021FD86 /* EditingBehaviorTypes.h in Headers */, + 9BAB6C6C12550631001626D4 /* EditingStyle.h in Headers */, 6550B6A4099DF0270090D781 /* EditingText.h in Headers */, 4B3043CD0AE0373B00A82647 /* Editor.h in Headers */, 1AF326790D78B9440068F0C4 /* EditorClient.h in Headers */, @@ -19500,6 +19571,8 @@ BC60D8F30D2A11E000B9918F /* ExceptionBase.h in Headers */, 935FBCF209BA143B00E230B1 /* ExceptionCode.h in Headers */, 148AFDA50AF58360008CC700 /* ExceptionHandlers.h in Headers */, + 6E67D2A91280E8BD008758F7 /* Extensions3D.h in Headers */, + 6E67D2A71280E8A4008758F7 /* Extensions3DOpenGL.h in Headers */, A75E8B890E1DE2D6007F2481 /* FEBlend.h in Headers */, A75E8B8B0E1DE2D6007F2481 /* FEColorMatrix.h in Headers */, A75E8B8D0E1DE2D6007F2481 /* FEComponentTransfer.h in Headers */, @@ -19700,6 +19773,7 @@ A81369DE097374F600D74463 /* HTMLOptGroupElement.h in Headers */, A81369DC097374F600D74463 /* HTMLOptionElement.h in Headers */, A81369DA097374F600D74463 /* HTMLOptionsCollection.h in Headers */, + 4AD01009127E642A0015035F /* HTMLOutputElement.h in Headers */, A8EA7CB50A192B9C00A8EF5F /* HTMLParagraphElement.h in Headers */, A871D4580A127CBC00B12A68 /* HTMLParamElement.h in Headers */, BC588AF00BFA6CF900EE679E /* HTMLParserErrorCodes.h in Headers */, @@ -19817,7 +19891,6 @@ 7A0E770F10C00A8800A0276E /* InspectorFrontendHost.h in Headers */, 20D629271253690B00081543 /* InspectorInstrumentation.h in Headers */, 9F0D6B2F121BFEBA006C0288 /* InspectorProfilerAgent.h in Headers */, - 41F062010F5F0B6600A07EAC /* InspectorResource.h in Headers */, 82AB1776125C826700C5069D /* InspectorResourceAgent.h in Headers */, 4FA3B90B125CD12200300BAD /* InspectorState.h in Headers */, 7AB0B1C11211A62200A76940 /* InspectorStorageAgent.h in Headers */, @@ -20022,6 +20095,7 @@ A80E7E9B0A1A83E3007FB8C5 /* JSHTMLOptGroupElement.h in Headers */, A80E7E990A1A83E3007FB8C5 /* JSHTMLOptionElement.h in Headers */, 448A29BF0A46D9CB0030759F /* JSHTMLOptionsCollection.h in Headers */, + 4AD0173D127E82860015035F /* JSHTMLOutputElement.h in Headers */, 1AE2ABA70A1CE90500B42B25 /* JSHTMLParagraphElement.h in Headers */, 1AE2ABA90A1CE90500B42B25 /* JSHTMLParamElement.h in Headers */, 1AE2ABAB0A1CE90500B42B25 /* JSHTMLPreElement.h in Headers */, @@ -20499,6 +20573,7 @@ 51A052561058874000CC9E95 /* ProtectionSpaceHash.h in Headers */, 1AF8E11A1256592600230FF7 /* ProxyServer.h in Headers */, E4D687790ED7AE4F006EA978 /* PurgeableBuffer.h in Headers */, + 7E33CD01127F340D00BE8F17 /* PurgePriority.h in Headers */, 550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */, B22279720D00BF220071B782 /* RadialGradientAttributes.h in Headers */, F55B3DCC1251F12D003EF269 /* RadioInputType.h in Headers */, @@ -20655,11 +20730,13 @@ 1CEFC9B90D78DC8C007D2579 /* SchedulePair.h in Headers */, 5162C7F511F77EFB00612EFE /* SchemeRegistry.h in Headers */, BCEC01BE0C274DAC009F4EC9 /* Screen.h in Headers */, + F39BE95C12673BF400E0A674 /* ScriptArguments.h in Headers */, A84D82C111D3474800972990 /* ScriptableDocumentParser.h in Headers */, 7AFD4A8B1131C2760035B883 /* ScriptBreakpoint.h in Headers */, 41F1D21F0EF35C2A00DA8753 /* ScriptCachedFrameData.h in Headers */, 416E75CB0EDF90C700360E1D /* ScriptCallFrame.h in Headers */, 416E75BE0EDF8FD700360E1D /* ScriptCallStack.h in Headers */, + F392249D126F11AE00A926D9 /* ScriptCallStackFactory.h in Headers */, 93B70D7009EB0C7C009D8468 /* ScriptController.h in Headers */, CE02F0C411E83ADD00C6684A /* ScriptControllerBase.h in Headers */, 7AFD4FF4113277B60035B883 /* ScriptDebugListener.h in Headers */, @@ -20814,17 +20891,24 @@ B22279770D00BF220071B782 /* SVGAngle.h in Headers */, B222797A0D00BF220071B782 /* SVGAnimateColorElement.h in Headers */, 087B84961272CEC800A14417 /* SVGAnimatedAngle.h in Headers */, + 085797091278394C00A8EC5F /* SVGAnimatedBoolean.h in Headers */, + 08D46CE3127AD5FC0089694B /* SVGAnimatedEnumeration.h in Headers */, + 0823D159127AD6AC000EBC95 /* SVGAnimatedInteger.h in Headers */, 089021A9126EF5DE0092D5EA /* SVGAnimatedLength.h in Headers */, 089021AD126EF5E90092D5EA /* SVGAnimatedLengthList.h in Headers */, 088A0E04126EF1DB00978F7A /* SVGAnimatedListPropertyTearOff.h in Headers */, + 08B35B13127B6A7C005314DD /* SVGAnimatedNumber.h in Headers */, + 08B35B17127B6A88005314DD /* SVGAnimatedNumberList.h in Headers */, B22279850D00BF220071B782 /* SVGAnimatedPathData.h in Headers */, - B22279880D00BF220071B782 /* SVGAnimatedPoints.h in Headers */, + 08FE0BC5127E2AC1000C4FB5 /* SVGAnimatedPreserveAspectRatio.h in Headers */, 088A0E05126EF1DB00978F7A /* SVGAnimatedProperty.h in Headers */, 088A0E06126EF1DB00978F7A /* SVGAnimatedPropertyDescription.h in Headers */, 088A0E07126EF1DB00978F7A /* SVGAnimatedPropertyMacros.h in Headers */, 081CDFBF126ECFE800D215CA /* SVGAnimatedPropertySynchronizer.h in Headers */, 088A0E08126EF1DB00978F7A /* SVGAnimatedPropertyTearOff.h in Headers */, 08C859C01274575400A5728D /* SVGAnimatedRect.h in Headers */, + 08525E631278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h in Headers */, + 084DB59B128008CC002A6D64 /* SVGAnimatedString.h in Headers */, B22279900D00BF220071B782 /* SVGAnimateElement.h in Headers */, B22279930D00BF220071B782 /* SVGAnimateMotionElement.h in Headers */, B22279950D00BF220071B782 /* SVGAnimateTransformElement.h in Headers */, @@ -20902,6 +20986,7 @@ B2227A390D00BF220071B782 /* SVGLinearGradientElement.h in Headers */, B2227A3C0D00BF220071B782 /* SVGLineElement.h in Headers */, B2227A3E0D00BF220071B782 /* SVGList.h in Headers */, + 0810764412828556007C63BA /* SVGListProperty.h in Headers */, 088A0E09126EF1DB00978F7A /* SVGListPropertyTearOff.h in Headers */, B2227A3F0D00BF220071B782 /* SVGListTraits.h in Headers */, B2227A410D00BF220071B782 /* SVGLocatable.h in Headers */, @@ -20966,6 +21051,8 @@ B2227AA60D00BF220071B782 /* SVGSetElement.h in Headers */, 08DAB9C31103D9C1003E7ABA /* SVGShadowTreeElements.h in Headers */, E4AFD0100DAF335500F5F55C /* SVGSMILElement.h in Headers */, + 0880F70E1282B46D00948505 /* SVGStaticListPropertyTearOff.h in Headers */, + 0813A4EA1284132600992511 /* SVGStaticPropertyTearOff.h in Headers */, B2227AA90D00BF220071B782 /* SVGStopElement.h in Headers */, B2227AAC0D00BF220071B782 /* SVGStringList.h in Headers */, B2227AAF0D00BF220071B782 /* SVGStylable.h in Headers */, @@ -21092,6 +21179,7 @@ BC8BF15A1058141800A40A07 /* UserStyleSheetTypes.h in Headers */, BCDF317C11F8D683003C5BF8 /* UserTypingGestureIndicator.h in Headers */, 2E3BBF081162DA1100B9409A /* UUID.h in Headers */, + F5A154281279534D00D0B0C0 /* ValidationMessage.h in Headers */, 15C7708D100D3C6B005BA267 /* ValidityState.h in Headers */, CEF418CF1179678C009D112C /* ViewportArguments.h in Headers */, 93309E1E099E64920056E581 /* visible_units.h in Headers */, @@ -21114,6 +21202,7 @@ A7D20F6D107F438B00A80392 /* WebGLActiveInfo.h in Headers */, 49C7B9C91042D32F0009D447 /* WebGLBuffer.h in Headers */, 6E4E91AF10F7FB3100A2779C /* WebGLContextAttributes.h in Headers */, + 93F6F1EE127F70B10055CB06 /* WebGLContextEvent.h in Headers */, 49C7B9CF1042D32F0009D447 /* WebGLFramebuffer.h in Headers */, 6E47E66110B7944B00B186C8 /* WebGLGetInfo.h in Headers */, 49FFBF3F11C93EE3006A7118 /* WebGLLayer.h in Headers */, @@ -21238,10 +21327,6 @@ 93F199ED08245E59001E9ABC /* XSLTProcessor.h in Headers */, E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */, 97DD4D870FDF4D6E00ECF9A4 /* XSSAuditor.h in Headers */, - 085797091278394C00A8EC5F /* SVGAnimatedBoolean.h in Headers */, - 08525E631278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h in Headers */, - 08D46CE3127AD5FC0089694B /* SVGAnimatedEnumeration.h in Headers */, - 0823D159127AD6AC000EBC95 /* SVGAnimatedInteger.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -21301,6 +21386,7 @@ isa = PBXProject; buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, @@ -21629,7 +21715,7 @@ 1A569CF90D7E2B82007C3983 /* c_instance.cpp in Sources */, 1A569CFB0D7E2B82007C3983 /* c_runtime.cpp in Sources */, 1A569CFD0D7E2B82007C3983 /* c_utility.cpp in Sources */, - BCB16C170979C3BD00467741 /* Cache.cpp in Sources */, + BCB16C170979C3BD00467741 /* MemoryCache.cpp in Sources */, BCB16C190979C3BD00467741 /* CachedCSSStyleSheet.cpp in Sources */, BC64B4CB0CB4295D005F2B62 /* CachedFont.cpp in Sources */, 51C0AA410F2AA15E001648C2 /* CachedFrame.cpp in Sources */, @@ -22103,6 +22189,7 @@ 498771531243F9FA002226BA /* DrawingBufferMac.mm in Sources */, BC7FA6200D1F0CBD00DB22A9 /* DynamicNodeList.cpp in Sources */, 93309DE3099E64920056E581 /* EditCommand.cpp in Sources */, + 9BAB6C6D12550631001626D4 /* EditingStyle.cpp in Sources */, 6550B6A3099DF0270090D781 /* EditingText.cpp in Sources */, 4B3043CC0AE0373B00A82647 /* Editor.cpp in Sources */, 93A38B4B0D0E5808006872C2 /* EditorCommand.cpp in Sources */, @@ -22127,6 +22214,7 @@ BC60D8F20D2A11E000B9918F /* ExceptionBase.cpp in Sources */, 93831B570D087D6000E5C984 /* ExceptionCode.cpp in Sources */, 148AFDA60AF58360008CC700 /* ExceptionHandlers.mm in Sources */, + 6E67D2A61280E8A4008758F7 /* Extensions3DOpenGL.cpp in Sources */, A75E8B880E1DE2D6007F2481 /* FEBlend.cpp in Sources */, A75E8B8A0E1DE2D6007F2481 /* FEColorMatrix.cpp in Sources */, A75E8B8C0E1DE2D6007F2481 /* FEComponentTransfer.cpp in Sources */, @@ -22307,6 +22395,7 @@ A81369DF097374F600D74463 /* HTMLOptGroupElement.cpp in Sources */, A81369DD097374F600D74463 /* HTMLOptionElement.cpp in Sources */, 9327A94209968D1A0068A546 /* HTMLOptionsCollection.cpp in Sources */, + 4AD01008127E642A0015035F /* HTMLOutputElement.cpp in Sources */, A8EA7CB20A192B9C00A8EF5F /* HTMLParagraphElement.cpp in Sources */, A871D4590A127CBC00B12A68 /* HTMLParamElement.cpp in Sources */, BC588B4B0BFA723C00EE679E /* HTMLParserErrorCodes.cpp in Sources */, @@ -22411,7 +22500,6 @@ 7A0E770E10C00A8800A0276E /* InspectorFrontendHost.cpp in Sources */, 20D629261253690B00081543 /* InspectorInstrumentation.cpp in Sources */, 9F0D6B2E121BFEBA006C0288 /* InspectorProfilerAgent.cpp in Sources */, - 41F062020F5F0B6600A07EAC /* InspectorResource.cpp in Sources */, 82AB1775125C826700C5069D /* InspectorResourceAgent.cpp in Sources */, 4FA3B90A125CD12200300BAD /* InspectorState.cpp in Sources */, 7AB0B1C01211A62200A76940 /* InspectorStorageAgent.cpp in Sources */, @@ -22666,6 +22754,8 @@ A80E7E9A0A1A83E3007FB8C5 /* JSHTMLOptionElement.cpp in Sources */, 448A29C00A46D9CB0030759F /* JSHTMLOptionsCollection.cpp in Sources */, 448AD27C0A48137A0023D179 /* JSHTMLOptionsCollectionCustom.cpp in Sources */, + 4AD0173C127E82860015035F /* JSHTMLOutputElement.cpp in Sources */, + 4AD01000127E63100015035F /* JSHTMLOutputElementCustom.cpp in Sources */, 1AE2ABA60A1CE90500B42B25 /* JSHTMLParagraphElement.cpp in Sources */, 1AE2ABA80A1CE90500B42B25 /* JSHTMLParamElement.cpp in Sources */, 1AE2ABAA0A1CE90500B42B25 /* JSHTMLPreElement.cpp in Sources */, @@ -23297,10 +23387,12 @@ 5162C7F411F77EFB00612EFE /* SchemeRegistry.cpp in Sources */, BCEC01BD0C274DAC009F4EC9 /* Screen.cpp in Sources */, A84D82C211D3474800972990 /* ScriptableDocumentParser.cpp in Sources */, + F39BE95B12673BF400E0A674 /* ScriptArguments.cpp in Sources */, 200B190911C277D900DCCD3A /* ScriptBreakpoint.cpp in Sources */, 41F1D2200EF35C2A00DA8753 /* ScriptCachedFrameData.cpp in Sources */, 416E75CC0EDF90C700360E1D /* ScriptCallFrame.cpp in Sources */, 416E75BF0EDF8FD700360E1D /* ScriptCallStack.cpp in Sources */, + F392249C126F11AE00A926D9 /* ScriptCallStackFactory.cpp in Sources */, 93B70D6F09EB0C7C009D8468 /* ScriptController.cpp in Sources */, 97EF7DFE107E55B700D7C49C /* ScriptControllerBase.cpp in Sources */, A83E1C740E49042C00140B9C /* ScriptControllerMac.mm in Sources */, @@ -23437,7 +23529,6 @@ B22279760D00BF220071B782 /* SVGAngle.cpp in Sources */, B22279790D00BF220071B782 /* SVGAnimateColorElement.cpp in Sources */, B22279840D00BF220071B782 /* SVGAnimatedPathData.cpp in Sources */, - B22279870D00BF220071B782 /* SVGAnimatedPoints.cpp in Sources */, B222798F0D00BF220071B782 /* SVGAnimateElement.cpp in Sources */, B22279920D00BF220071B782 /* SVGAnimateMotionElement.cpp in Sources */, B22279940D00BF220071B782 /* SVGAnimateTransformElement.cpp in Sources */, @@ -23673,6 +23764,7 @@ 2542F4DA1166C25A00E89A86 /* UserGestureIndicator.cpp in Sources */, BCDF317B11F8D683003C5BF8 /* UserTypingGestureIndicator.cpp in Sources */, 2E3BBF071162DA1100B9409A /* UUID.cpp in Sources */, + F5A154271279534D00D0B0C0 /* ValidationMessage.cpp in Sources */, 15C7708E100D3C6B005BA267 /* ValidityState.cpp in Sources */, CEF418CE1179678C009D112C /* ViewportArguments.cpp in Sources */, 93309E1D099E64920056E581 /* visible_units.cpp in Sources */, @@ -23688,6 +23780,7 @@ BC6DADFA0A19602B00E5CD14 /* WebFontCache.mm in Sources */, 49C7B9C81042D32F0009D447 /* WebGLBuffer.cpp in Sources */, 6E4E91AE10F7FB3100A2779C /* WebGLContextAttributes.cpp in Sources */, + 93F6F1ED127F70B10055CB06 /* WebGLContextEvent.cpp in Sources */, 49C7B9CE1042D32F0009D447 /* WebGLFramebuffer.cpp in Sources */, 6E47E66010B7944B00B186C8 /* WebGLGetInfo.cpp in Sources */, 49FFBF4011C93EE3006A7118 /* WebGLLayer.mm in Sources */, diff --git a/WebCore/accessibility/AccessibilityObject.h b/WebCore/accessibility/AccessibilityObject.h index 66424ea..85f3e27 100644 --- a/WebCore/accessibility/AccessibilityObject.h +++ b/WebCore/accessibility/AccessibilityObject.h @@ -259,6 +259,7 @@ public: typedef Vector<RefPtr<AccessibilityObject> > AccessibilityChildrenVector; virtual bool isAccessibilityRenderObject() const { return false; } + virtual bool isAccessibilityScrollbar() const { return false; } virtual bool isAnchor() const { return false; } virtual bool isAttachment() const { return false; } virtual bool isHeading() const { return false; } diff --git a/WebCore/accessibility/AccessibilityRenderObject.cpp b/WebCore/accessibility/AccessibilityRenderObject.cpp index efa2036..ef42272 100644 --- a/WebCore/accessibility/AccessibilityRenderObject.cpp +++ b/WebCore/accessibility/AccessibilityRenderObject.cpp @@ -1773,7 +1773,13 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const RenderText* renderText = toRenderText(m_renderer); if (m_renderer->isBR() || !renderText->firstTextBox()) return true; - + + // static text beneath TextControls is reported along with the text control text so it's ignored. + for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) { + if (parent->roleValue() == TextFieldRole) + return true; + } + // text elements that are just empty whitespace should not be returned return renderText->text()->containsOnlyWhitespace(); } diff --git a/WebCore/accessibility/AccessibilityScrollbar.h b/WebCore/accessibility/AccessibilityScrollbar.h index d75e60c..7d78b52 100644 --- a/WebCore/accessibility/AccessibilityScrollbar.h +++ b/WebCore/accessibility/AccessibilityScrollbar.h @@ -41,6 +41,10 @@ public: void setScrollbar(Scrollbar* scrollbar) { m_scrollbar = scrollbar; } + Scrollbar* scrollbar() const { return m_scrollbar.get(); } + + virtual bool isAccessibilityScrollbar() const { return true; } + virtual AccessibilityRole roleValue() const { return ScrollBarRole; } virtual float valueForRange() const; @@ -56,7 +60,7 @@ private: virtual IntRect elementRect() const { ASSERT_NOT_REACHED(); return IntRect(); } virtual AccessibilityObject* parentObject() const { ASSERT_NOT_REACHED(); return 0; } - Scrollbar* m_scrollbar; + RefPtr<Scrollbar> m_scrollbar; }; } // namespace WebCore diff --git a/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp b/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp index b02fe00..9a1dcaf 100644 --- a/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp +++ b/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp @@ -27,9 +27,11 @@ #include "config.h" #include "AXObjectCache.h" #include "AccessibilityObject.h" +#include "AccessibilityScrollbar.h" #include "Chrome.h" #include "ChromeClient.h" #include "FrameView.h" +#include "Scrollbar.h" namespace WebCore { @@ -47,6 +49,17 @@ void AXObjectCache::attachWrapper(AccessibilityObject*) void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotification notification) { + if (obj && obj->isAccessibilityScrollbar() && notification == AXValueChanged) { + // Send document value changed on scrollbar value changed notification. + Scrollbar* scrollBar = static_cast<AccessibilityScrollbar*>(obj)->scrollbar(); + if (!scrollBar || !scrollBar->parent() || !scrollBar->parent()->isFrameView()) + return; + Document* document = static_cast<FrameView*>(scrollBar->parent())->frame()->document(); + if (document != document->topDocument()) + return; + obj = get(document->renderer()); + } + if (!obj || !obj->document() || !obj->documentFrameView() || !obj->documentFrameView()->frame() || !obj->documentFrameView()->frame()->page()) return; diff --git a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp index 283b2de..726cdb1 100644 --- a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp +++ b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp @@ -60,14 +60,15 @@ #include "RenderText.h" #include "TextEncoding.h" #include "TextIterator.h" -#include <wtf/text/CString.h> -#include <wtf/text/AtomicString.h> +#include "WebKitAccessibleHyperlink.h" #include <atk/atk.h> #include <glib.h> #include <glib/gprintf.h> #include <libgail-util/gail-util.h> #include <pango/pango.h> +#include <wtf/text/AtomicString.h> +#include <wtf/text/CString.h> using namespace WebCore; @@ -143,6 +144,11 @@ static AccessibilityObject* core(AtkTable* table) return core(ATK_OBJECT(table)); } +static AccessibilityObject* core(AtkHypertext* hypertext) +{ + return core(ATK_OBJECT(hypertext)); +} + static AccessibilityObject* core(AtkDocument* document) { return core(ATK_OBJECT(document)); @@ -1954,6 +1960,89 @@ static void atk_table_interface_init(AtkTableIface* iface) iface->get_row_description = webkit_accessible_table_get_row_description; } +static AtkHyperlink* webkitAccessibleHypertextGetLink(AtkHypertext* hypertext, gint index) +{ + AccessibilityObject::AccessibilityChildrenVector children = core(hypertext)->children(); + if (index < 0 || static_cast<unsigned>(index) >= children.size()) + return 0; + + gint currentLink = -1; + for (unsigned i = 0; i < children.size(); i++) { + AccessibilityObject* coreChild = children.at(i).get(); + if (!coreChild->accessibilityIsIgnored() && coreChild->isLink()) { + currentLink++; + if (index != currentLink) + continue; + + AtkObject* axObject = coreChild->wrapper(); + if (!axObject || !ATK_IS_HYPERLINK_IMPL(axObject)) + return 0; + + return atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(axObject)); + } + } + + return 0; +} + +static gint webkitAccessibleHypertextGetNLinks(AtkHypertext* hypertext) +{ + AccessibilityObject::AccessibilityChildrenVector children = core(hypertext)->children(); + if (!children.size()) + return 0; + + gint linksFound = 0; + for (size_t i = 0; i < children.size(); i++) { + AccessibilityObject* coreChild = children.at(i).get(); + if (!coreChild->accessibilityIsIgnored() && coreChild->isLink()) + linksFound++; + } + + return linksFound; +} + +static gint webkitAccessibleHypertextGetLinkIndex(AtkHypertext* hypertext, gint charIndex) +{ + size_t linksCount = webkitAccessibleHypertextGetNLinks(hypertext); + if (!linksCount) + return -1; + + for (size_t i = 0; i < linksCount; i++) { + AtkHyperlink* hyperlink = ATK_HYPERLINK(webkitAccessibleHypertextGetLink(hypertext, i)); + gint startIndex = atk_hyperlink_get_start_index(hyperlink); + gint endIndex = atk_hyperlink_get_end_index(hyperlink); + + // Check if the char index in the link's offset range + if (startIndex <= charIndex && charIndex < endIndex) + return i; + } + + // Not found if reached + return -1; +} + +static void atkHypertextInterfaceInit(AtkHypertextIface* iface) +{ + iface->get_link = webkitAccessibleHypertextGetLink; + iface->get_n_links = webkitAccessibleHypertextGetNLinks; + iface->get_link_index = webkitAccessibleHypertextGetLinkIndex; +} + +static AtkHyperlink* webkitAccessibleHyperlinkImplGetHyperlink(AtkHyperlinkImpl* hyperlink) +{ + AtkHyperlink* hyperlinkObject = ATK_HYPERLINK(g_object_get_data(G_OBJECT(hyperlink), "hyperlink-object")); + if (!hyperlinkObject) { + hyperlinkObject = ATK_HYPERLINK(webkitAccessibleHyperlinkNew(hyperlink)); + g_object_set_data(G_OBJECT(hyperlink), "hyperlink-object", hyperlinkObject); + } + return hyperlinkObject; +} + +static void atkHyperlinkImplInterfaceInit(AtkHyperlinkImplIface* iface) +{ + iface->get_hyperlink = webkitAccessibleHyperlinkImplGetHyperlink; +} + static const gchar* documentAttributeValue(AtkDocument* document, const gchar* attribute) { Document* coreDocument = core(document)->document(); @@ -2025,6 +2114,10 @@ static const GInterfaceInfo AtkInterfacesInitFunctions[] = { (GInterfaceFinalizeFunc) 0, 0}, {(GInterfaceInitFunc)atk_table_interface_init, (GInterfaceFinalizeFunc) 0, 0}, + {(GInterfaceInitFunc)atkHypertextInterfaceInit, + (GInterfaceFinalizeFunc) 0, 0}, + {(GInterfaceInitFunc)atkHyperlinkImplInterfaceInit, + (GInterfaceFinalizeFunc) 0, 0}, {(GInterfaceInitFunc)atk_document_interface_init, (GInterfaceFinalizeFunc) 0, 0} }; @@ -2037,31 +2130,37 @@ enum WAIType { WAI_COMPONENT, WAI_IMAGE, WAI_TABLE, + WAI_HYPERTEXT, + WAI_HYPERLINK, WAI_DOCUMENT }; static GType GetAtkInterfaceTypeFromWAIType(WAIType type) { - switch (type) { - case WAI_ACTION: - return ATK_TYPE_ACTION; - case WAI_SELECTION: - return ATK_TYPE_SELECTION; - case WAI_EDITABLE_TEXT: - return ATK_TYPE_EDITABLE_TEXT; - case WAI_TEXT: - return ATK_TYPE_TEXT; - case WAI_COMPONENT: - return ATK_TYPE_COMPONENT; - case WAI_IMAGE: - return ATK_TYPE_IMAGE; - case WAI_TABLE: - return ATK_TYPE_TABLE; - case WAI_DOCUMENT: - return ATK_TYPE_DOCUMENT; - } - - return G_TYPE_INVALID; + switch (type) { + case WAI_ACTION: + return ATK_TYPE_ACTION; + case WAI_SELECTION: + return ATK_TYPE_SELECTION; + case WAI_EDITABLE_TEXT: + return ATK_TYPE_EDITABLE_TEXT; + case WAI_TEXT: + return ATK_TYPE_TEXT; + case WAI_COMPONENT: + return ATK_TYPE_COMPONENT; + case WAI_IMAGE: + return ATK_TYPE_IMAGE; + case WAI_TABLE: + return ATK_TYPE_TABLE; + case WAI_HYPERTEXT: + return ATK_TYPE_HYPERTEXT; + case WAI_HYPERLINK: + return ATK_TYPE_HYPERLINK_IMPL; + case WAI_DOCUMENT: + return ATK_TYPE_DOCUMENT; + } + + return G_TYPE_INVALID; } static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject) @@ -2071,20 +2170,24 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject) // Component interface is always supported interfaceMask |= 1 << WAI_COMPONENT; + AccessibilityRole role = coreObject->roleValue(); + // Action - if (!coreObject->actionVerb().isEmpty()) + if (!coreObject->actionVerb().isEmpty()) { interfaceMask |= 1 << WAI_ACTION; + if (!coreObject->accessibilityIsIgnored() && coreObject->isLink()) + interfaceMask |= 1 << WAI_HYPERLINK; + } + // Selection if (coreObject->isListBox()) interfaceMask |= 1 << WAI_SELECTION; // Text & Editable Text - AccessibilityRole role = coreObject->roleValue(); - if (role == StaticTextRole) interfaceMask |= 1 << WAI_TEXT; - else if (coreObject->isAccessibilityRenderObject()) + else if (coreObject->isAccessibilityRenderObject()) { if (coreObject->isTextControl()) { interfaceMask |= 1 << WAI_TEXT; if (!coreObject->isReadOnly()) @@ -2092,11 +2195,15 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject) } else { AccessibilityRenderObject* axRenderObject = static_cast<AccessibilityRenderObject*>(coreObject); RenderObject* renderer = axRenderObject->renderer(); - if (role != TableRole && renderer && renderer->childrenInline()) - interfaceMask |= 1 << WAI_TEXT; - else if (role == ListItemRole) { - // Add the TEXT interface for list items whose - // first accessible child has a text renderer + if (role != TableRole) { + interfaceMask |= 1 << WAI_HYPERTEXT; + if (renderer && renderer->childrenInline()) + interfaceMask |= 1 << WAI_TEXT; + } + + // Add the TEXT interface for list items whose + // first accessible child has a text renderer + if (role == ListItemRole) { AccessibilityObject::AccessibilityChildrenVector children = axRenderObject->children(); if (children.size()) { AccessibilityObject* axRenderChild = children.at(0).get(); @@ -2104,6 +2211,7 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject) } } } + } // Image if (coreObject->isImage()) diff --git a/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp b/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp new file mode 100644 index 0000000..5927430 --- /dev/null +++ b/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitAccessibleHyperlink.h" + +#if HAVE(ACCESSIBILITY) + +#include "AXObjectCache.h" +#include "AccessibilityObject.h" +#include "AccessibilityObjectWrapperAtk.h" +#include "AccessibilityRenderObject.h" +#include "NotImplemented.h" +#include "Position.h" +#include "Range.h" +#include "RenderListMarker.h" +#include "RenderObject.h" +#include "TextIterator.h" + +#include <atk/atk.h> +#include <glib.h> + +using namespace WebCore; + +struct _WebKitAccessibleHyperlinkPrivate { + WebKitAccessible* hyperlinkImpl; +}; + +#define WEBKIT_ACCESSIBLE_HYPERLINK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlinkPrivate)) + +enum { + PROP_0, + + PROP_HYPERLINK_IMPL +}; + +static gpointer webkitAccessibleHyperlinkParentClass = 0; + +// Used to provide const char* returns. +static const char* returnString(const String& str) +{ + static CString returnedString; + returnedString = str.utf8(); + return returnedString.data(); +} + +static AccessibilityObject* core(WebKitAccessible* accessible) +{ + if (!accessible || !WEBKIT_IS_ACCESSIBLE(accessible)) + return 0; + + return webkit_accessible_get_accessibility_object(accessible); +} + +static AccessibilityObject* core(WebKitAccessibleHyperlink* link) +{ + if (!link) + return 0; + + return core(link->priv->hyperlinkImpl); +} + +static AccessibilityObject* core(AtkHyperlink* link) +{ + if (!WEBKIT_IS_ACCESSIBLE_HYPERLINK(link)) + return 0; + + return core(WEBKIT_ACCESSIBLE_HYPERLINK(link)); +} + +static AccessibilityObject* core(AtkAction* action) +{ + return core(WEBKIT_ACCESSIBLE_HYPERLINK(action)); +} + + +static gboolean webkitAccessibleHyperlinkActionDoAction(AtkAction* action, gint index) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), FALSE); + g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, FALSE); + g_return_val_if_fail(!index, FALSE); + + if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl)) + return FALSE; + + AccessibilityObject* coreObject = core(action); + if (!coreObject) + return FALSE; + + return coreObject->performDefaultAction(); +} + +static gint webkitAccessibleHyperlinkActionGetNActions(AtkAction* action) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0); + g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0); + + if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl)) + return 0; + + return 1; +} + +static const gchar* webkitAccessibleHyperlinkActionGetDescription(AtkAction* action, gint index) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0); + g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0); + g_return_val_if_fail(!index, 0); + + // TODO: Need a way to provide/localize action descriptions. + notImplemented(); + return ""; +} + +static const gchar* webkitAccessibleHyperlinkActionGetKeybinding(AtkAction* action, gint index) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0); + g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0); + g_return_val_if_fail(!index, 0); + + if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl)) + return 0; + + AccessibilityObject* coreObject = core(action); + if (!coreObject) + return 0; + + return returnString(coreObject->accessKey().string()); +} + +static const gchar* webkitAccessibleHyperlinkActionGetName(AtkAction* action, gint index) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0); + g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0); + g_return_val_if_fail(!index, 0); + + if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl)) + return 0; + + AccessibilityObject* coreObject = core(action); + if (!coreObject) + return 0; + + return returnString(coreObject->actionVerb()); +} + +static void atkActionInterfaceInit(AtkActionIface* iface) +{ + iface->do_action = webkitAccessibleHyperlinkActionDoAction; + iface->get_n_actions = webkitAccessibleHyperlinkActionGetNActions; + iface->get_description = webkitAccessibleHyperlinkActionGetDescription; + iface->get_keybinding = webkitAccessibleHyperlinkActionGetKeybinding; + iface->get_name = webkitAccessibleHyperlinkActionGetName; +} + +static gchar* webkitAccessibleHyperlinkGetURI(AtkHyperlink* link, gint index) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0); + // FIXME: Do NOT support more than one instance of an AtkObject + // implementing AtkHyperlinkImpl in every instance of AtkHyperLink + g_return_val_if_fail(!index, 0); + + AccessibilityObject* coreObject = core(link); + if (!coreObject || coreObject->url().isNull()) + return 0; + + return g_strdup(returnString(coreObject->url().string())); +} + +static AtkObject* webkitAccessibleHyperlinkGetObject(AtkHyperlink* link, gint index) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0); + g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0); + + // FIXME: Do NOT support more than one instance of an AtkObject + // implementing AtkHyperlinkImpl in every instance of AtkHyperLink + g_return_val_if_fail(!index, 0); + + return ATK_OBJECT(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl); +} + +static gint getRangeLengthForObject(AccessibilityObject* obj, Range* range) +{ + // This is going to be the actual length in most of the cases + int baseLength = TextIterator::rangeLength(range); + + // Check whether the current hyperlink belongs to a list item. + // If so, we need to consider the length of the item's marker + AccessibilityObject* parent = obj->parentObjectUnignored(); + if (!parent || !parent->isAccessibilityRenderObject() || !parent->isListItem()) + return baseLength; + + // Even if we don't expose list markers to Assistive + // Technologies, we need to have a way to measure their length + // for those cases when it's needed to take it into account + // separately (as in getAccessibilityObjectForOffset) + AccessibilityObject* markerObj = parent->firstChild(); + if (!markerObj) + return baseLength; + + RenderObject* renderer = static_cast<const AccessibilityRenderObject*>(markerObj)->renderer(); + if (!renderer || !renderer->isListMarker()) + return baseLength; + + RenderListMarker* marker = toRenderListMarker(renderer); + return baseLength + marker->text().length() + marker->suffix().length(); +} + +static gint webkitAccessibleHyperlinkGetStartIndex(AtkHyperlink* link) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0); + + AccessibilityObject* coreObject = core(link); + if (!coreObject) + return 0; + + Node* node = coreObject->node(); + if (!node) + return 0; + + RefPtr<Range> range = Range::create(node->document(), firstPositionInNode(node->parentNode()), firstPositionInNode(node)); + return getRangeLengthForObject(coreObject, range.get()); +} + +static gint webkitAccessibleHyperlinkGetEndIndex(AtkHyperlink* link) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0); + + AccessibilityObject* coreObject = core(link); + if (!coreObject) + return 0; + + Node* node = coreObject->node(); + if (!node) + return 0; + + RefPtr<Range> range = Range::create(node->document(), firstPositionInNode(node->parentNode()), lastPositionInNode(node)); + return getRangeLengthForObject(coreObject, range.get()); +} + +static gboolean webkitAccessibleHyperlinkIsValid(AtkHyperlink* link) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0); + g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, FALSE); + + // Link is valid for the whole object's lifetime + return TRUE; +} + +static gint webkitAccessibleHyperlinkGetNAnchors(AtkHyperlink* link) +{ + // FIXME Do NOT support more than one instance of an AtkObject + // implementing AtkHyperlinkImpl in every instance of AtkHyperLink + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0); + g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0); + return 1; +} + +static gboolean webkitAccessibleHyperlinkIsSelectedLink(AtkHyperlink* link) +{ + // Not implemented: this function is deprecated in ATK now + notImplemented(); + return FALSE; +} + +static void webkitAccessibleHyperlinkGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* pspec) +{ + switch (propId) { + case PROP_HYPERLINK_IMPL: + g_value_set_object(value, WEBKIT_ACCESSIBLE_HYPERLINK(object)->priv->hyperlinkImpl); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec); + } +} + +static void webkitAccessibleHyperlinkSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* pspec) +{ + WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(object)->priv; + + switch (propId) { + case PROP_HYPERLINK_IMPL: + // No need to check and unref previous values of + // priv->hyperlinkImpl as this is a CONSTRUCT ONLY property + priv->hyperlinkImpl = WEBKIT_ACCESSIBLE(g_value_get_object(value)); + g_object_weak_ref(G_OBJECT(priv->hyperlinkImpl), (GWeakNotify)g_object_unref, object); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec); + } +} + +static void webkitAccessibleHyperlinkFinalize(GObject* object) +{ + G_OBJECT_CLASS(webkitAccessibleHyperlinkParentClass)->finalize(object); +} + +static void webkitAccessibleHyperlinkClassInit(AtkHyperlinkClass* klass) +{ + GObjectClass* gobjectClass = G_OBJECT_CLASS(klass); + + webkitAccessibleHyperlinkParentClass = g_type_class_peek_parent(klass); + + gobjectClass->finalize = webkitAccessibleHyperlinkFinalize; + gobjectClass->set_property = webkitAccessibleHyperlinkSetProperty; + gobjectClass->get_property = webkitAccessibleHyperlinkGetProperty; + + klass->get_uri = webkitAccessibleHyperlinkGetURI; + klass->get_object = webkitAccessibleHyperlinkGetObject; + klass->get_start_index = webkitAccessibleHyperlinkGetStartIndex; + klass->get_end_index = webkitAccessibleHyperlinkGetEndIndex; + klass->is_valid = webkitAccessibleHyperlinkIsValid; + klass->get_n_anchors = webkitAccessibleHyperlinkGetNAnchors; + klass->is_selected_link = webkitAccessibleHyperlinkIsSelectedLink; + + g_object_class_install_property(gobjectClass, PROP_HYPERLINK_IMPL, + g_param_spec_object("hyperlink-impl", + "Hyperlink implementation", + "The associated WebKitAccessible instance.", + WEBKIT_TYPE_ACCESSIBLE, + (GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS))); + + g_type_class_add_private(gobjectClass, sizeof(WebKitAccessibleHyperlinkPrivate)); +} + +static void webkitAccessibleHyperlinkInit(AtkHyperlink* link) +{ + WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv = WEBKIT_ACCESSIBLE_HYPERLINK_GET_PRIVATE(link); + WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl = 0; +} + +GType webkitAccessibleHyperlinkGetType() +{ + static volatile gsize typeVolatile = 0; + + if (g_once_init_enter(&typeVolatile)) { + static const GTypeInfo tinfo = { + sizeof(WebKitAccessibleHyperlinkClass), + (GBaseInitFunc) 0, + (GBaseFinalizeFunc) 0, + (GClassInitFunc) webkitAccessibleHyperlinkClassInit, + (GClassFinalizeFunc) 0, + 0, /* class data */ + sizeof(WebKitAccessibleHyperlink), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) webkitAccessibleHyperlinkInit, + 0 /* value table */ + }; + + static const GInterfaceInfo actionInfo = { + (GInterfaceInitFunc)(GInterfaceInitFunc)atkActionInterfaceInit, + (GInterfaceFinalizeFunc) 0, 0 + }; + + GType type = g_type_register_static(ATK_TYPE_HYPERLINK, "WebKitAccessibleHyperlink", &tinfo, GTypeFlags(0)); + g_type_add_interface_static(type, ATK_TYPE_ACTION, &actionInfo); + + g_once_init_leave(&typeVolatile, type); + } + + return typeVolatile; +} + +WebKitAccessibleHyperlink* webkitAccessibleHyperlinkNew(AtkHyperlinkImpl* hyperlinkImpl) +{ + g_return_val_if_fail(ATK_IS_HYPERLINK_IMPL(hyperlinkImpl), 0); + return WEBKIT_ACCESSIBLE_HYPERLINK(g_object_new(WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, "hyperlink-impl", hyperlinkImpl, 0)); +} + +WebCore::AccessibilityObject* webkitAccessibleHyperlinkGetAccessibilityObject(WebKitAccessibleHyperlink* link) +{ + g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0); + return core(link); +} + +#endif // HAVE(ACCESSIBILITY) diff --git a/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.h b/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.h new file mode 100644 index 0000000..9df819d --- /dev/null +++ b/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitAccessibleHyperlink_h +#define WebKitAccessibleHyperlink_h + +#include "AccessibilityObjectWrapperAtk.h" + +#include <atk/atk.h> + +namespace WebCore { +class AccessibilityObject; +} + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_ACCESSIBLE_HYPERLINK (webkitAccessibleHyperlinkGetType ()) +#define WEBKIT_ACCESSIBLE_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlink)) +#define WEBKIT_ACCESSIBLE_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlinkClass)) +#define WEBKIT_IS_ACCESSIBLE_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK)) +#define WEBKIT_IS_ACCESSIBLE_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK)) +#define WEBKIT_ACCESSIBLE_HYPERLINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlinkClass)) + +typedef struct _WebKitAccessibleHyperlink WebKitAccessibleHyperlink; +typedef struct _WebKitAccessibleHyperlinkClass WebKitAccessibleHyperlinkClass; +typedef struct _WebKitAccessibleHyperlinkPrivate WebKitAccessibleHyperlinkPrivate; + +struct _WebKitAccessibleHyperlink { + AtkHyperlink parent; + + // private + WebKitAccessibleHyperlinkPrivate *priv; +}; + +struct _WebKitAccessibleHyperlinkClass { + AtkObjectClass parentClass; +}; + +GType webkitAccessibleHyperlinkGetType(void) G_GNUC_CONST; + +WebKitAccessibleHyperlink* webkitAccessibleHyperlinkNew(AtkHyperlinkImpl* hyperlinkImpl); + +WebCore::AccessibilityObject* webkitAccessibleHyperlinkGetAccessibilityObject(WebKitAccessibleHyperlink* link); + +G_END_DECLS + +#endif // WebKitAccessibleHyperlink_h diff --git a/WebCore/bindings/gobject/GObjectEventListener.cpp b/WebCore/bindings/gobject/GObjectEventListener.cpp index 3ce8461..553d717 100644 --- a/WebCore/bindings/gobject/GObjectEventListener.cpp +++ b/WebCore/bindings/gobject/GObjectEventListener.cpp @@ -19,20 +19,63 @@ #include "config.h" #include "GObjectEventListener.h" +#include "DOMWindow.h" #include "Event.h" #include "EventListener.h" +#include "Node.h" #include "webkit/WebKitDOMEvent.h" #include "webkit/WebKitDOMEventPrivate.h" +#include <glib-object.h> +#include <glib.h> #include <wtf/HashMap.h> -#include <wtf/text/CString.h> namespace WebCore { +GObjectEventListener::GObjectEventListener(GObject* object, DOMWindow* window, Node* node, const char* domEventName, const char* signalName) + : EventListener(GObjectEventListenerType) + , m_object(object) + , m_coreNode(node) + , m_coreWindow(window) + , m_domEventName(domEventName) + , m_signalName(signalName) +{ + ASSERT(!m_coreWindow || !m_coreNode); + if (m_coreWindow) + m_coreWindow->addEventListener(domEventName, this, false); + if (m_coreNode) + m_coreNode->addEventListener(domEventName, this, false); + g_object_weak_ref(object, reinterpret_cast<GWeakNotify>(GObjectEventListener::gobjectDestroyedCallback), this); +} + +GObjectEventListener::~GObjectEventListener() +{ + if (!m_coreWindow && !m_coreNode) + return; + g_object_weak_unref(m_object, reinterpret_cast<GWeakNotify>(GObjectEventListener::gobjectDestroyedCallback), this); +} + +void GObjectEventListener::gobjectDestroyed() +{ + ASSERT(!m_coreWindow || !m_coreNode); + + // We must set m_coreWindow and m_coreNode to null, because removeEventListener may call the + // destructor as a side effect and we must be in the proper state to prevent g_object_weak_unref. + if (DOMWindow* window = m_coreWindow) { + m_coreWindow = 0; + window->removeEventListener(m_domEventName.data(), this, false); + return; + } + + Node* node = m_coreNode; + m_coreNode = 0; // See above. + node->removeEventListener(m_domEventName.data(), this, false); +} + void GObjectEventListener::handleEvent(ScriptExecutionContext*, Event* event) { gboolean handled = FALSE; WebKitDOMEvent* gobjectEvent = WEBKIT_DOM_EVENT(WebKit::kit(event)); - g_signal_emit_by_name(m_object, m_signalName.utf8().data(), gobjectEvent, &handled); + g_signal_emit_by_name(m_object, m_signalName.data(), gobjectEvent, &handled); } bool GObjectEventListener::operator==(const EventListener& listener) diff --git a/WebCore/bindings/gobject/GObjectEventListener.h b/WebCore/bindings/gobject/GObjectEventListener.h index 7ca2cc7..e5ad2e5 100644 --- a/WebCore/bindings/gobject/GObjectEventListener.h +++ b/WebCore/bindings/gobject/GObjectEventListener.h @@ -21,15 +21,34 @@ #include "EventListener.h" -#include "PlatformString.h" -#include <glib-object.h> -#include <glib.h> -#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/text/CString.h> + +typedef struct _GObject GObject; namespace WebCore { + +class DOMWindow; +class Node; + class GObjectEventListener : public EventListener { public: - static PassRefPtr<GObjectEventListener> create(GObject* object, const char* signalName) { return adoptRef(new GObjectEventListener(object, signalName)); } + + static void addEventListener(GObject* object, DOMWindow* window, const char* domEventName, const char* signalName) + { + RefPtr<GObjectEventListener> listener(adoptRef(new GObjectEventListener(object, window, 0, domEventName, signalName))); + } + + static void addEventListener(GObject* object, Node* node, const char* domEventName, const char* signalName) + { + RefPtr<GObjectEventListener> listener(adoptRef(new GObjectEventListener(object, 0, node, domEventName, signalName))); + } + + static void gobjectDestroyedCallback(GObjectEventListener* listener, GObject*) + { + listener->gobjectDestroyed(); + } + static const GObjectEventListener* cast(const EventListener* listener) { return listener->type() == GObjectEventListenerType @@ -40,17 +59,20 @@ public: virtual bool operator==(const EventListener& other); private: - GObjectEventListener(GObject* object, const char* signalName) - : EventListener(GObjectEventListenerType) - , m_object(object) - , m_signalName(signalName) - { - } + GObjectEventListener(GObject*, DOMWindow*, Node*, const char* domEventName, const char* signalName); + ~GObjectEventListener(); + void gobjectDestroyed(); virtual void handleEvent(ScriptExecutionContext*, Event*); GObject* m_object; - String m_signalName; + + // We do not need to keep a reference to these WebCore objects, because + // we only use them when the GObject and thus the WebCore object is alive. + Node* m_coreNode; + DOMWindow* m_coreWindow; + CString m_domEventName; + CString m_signalName; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSArrayBufferViewHelper.h b/WebCore/bindings/js/JSArrayBufferViewHelper.h index 27a9a98..ba712c6 100644 --- a/WebCore/bindings/js/JSArrayBufferViewHelper.h +++ b/WebCore/bindings/js/JSArrayBufferViewHelper.h @@ -115,6 +115,8 @@ PassRefPtr<ArrayBufferView> constructArrayBufferView(JSC::ExecState* exec) RefPtr<ArrayBuffer> buffer = toArrayBuffer(exec->argument(0)); if (buffer) { unsigned offset = (exec->argumentCount() > 1) ? exec->argument(1).toUInt32(exec) : 0; + if ((buffer->byteLength() - offset) % sizeof(T)) + throwError(exec, createRangeError(exec, "ArrayBuffer length minus the byteOffset is not a multiple of the element size.")); unsigned int length = (buffer->byteLength() - offset) / sizeof(T); if (exec->argumentCount() > 2) length = exec->argument(2).toUInt32(exec); diff --git a/WebCore/bindings/js/JSBindingsAllInOne.cpp b/WebCore/bindings/js/JSBindingsAllInOne.cpp index cf08ca9..b786431 100644 --- a/WebCore/bindings/js/JSBindingsAllInOne.cpp +++ b/WebCore/bindings/js/JSBindingsAllInOne.cpp @@ -84,6 +84,7 @@ #include "JSHTMLInputElementCustom.cpp" #include "JSHTMLObjectElementCustom.cpp" #include "JSHTMLOptionsCollectionCustom.cpp" +#include "JSHTMLOutputElementCustom.cpp" #include "JSHTMLSelectElementCustom.cpp" #include "JSHistoryCustom.cpp" #include "JSImageConstructor.cpp" @@ -141,8 +142,7 @@ #include "MemoryInfo.cpp" #include "ScheduledAction.cpp" #include "ScriptCachedFrameData.cpp" -#include "ScriptCallFrame.cpp" -#include "ScriptCallStack.cpp" +#include "ScriptCallStackFactory.cpp" #include "ScriptController.cpp" #include "ScriptControllerWin.cpp" #include "ScriptDebugServer.cpp" diff --git a/WebCore/bindings/js/JSCallbackData.cpp b/WebCore/bindings/js/JSCallbackData.cpp index f39c53c..204c348 100644 --- a/WebCore/bindings/js/JSCallbackData.cpp +++ b/WebCore/bindings/js/JSCallbackData.cpp @@ -65,12 +65,14 @@ JSValue JSCallbackData::invokeCallback(MarkedArgumentBuffer& args, bool* raisedE if (!context) return JSValue(); - JSValue result = context->isDocument() + bool contextIsDocument = context->isDocument(); + JSValue result = contextIsDocument ? JSMainThreadExecState::call(exec, function, callType, callData, callback(), args) : JSC::call(exec, function, callType, callData, callback(), args); globalObject()->globalData().timeoutChecker.stop(); - Document::updateStyleForAllDocuments(); + if (contextIsDocument) + Document::updateStyleForAllDocuments(); if (exec->hadException()) { reportCurrentException(exec); diff --git a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp index 532b38b..e3f5a4e 100644 --- a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp +++ b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp @@ -343,8 +343,10 @@ JSValue JSCanvasRenderingContext2D::createPattern(ExecState* exec) CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(impl()); JSValue value = exec->argument(0); - if (!value.isObject()) - return throwTypeError(exec); + if (!value.isObject()) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } JSObject* o = asObject(value); if (o->inherits(&JSHTMLImageElement::s_info)) { diff --git a/WebCore/bindings/js/JSConsoleCustom.cpp b/WebCore/bindings/js/JSConsoleCustom.cpp index f0419c7..6df88f6 100644 --- a/WebCore/bindings/js/JSConsoleCustom.cpp +++ b/WebCore/bindings/js/JSConsoleCustom.cpp @@ -29,8 +29,11 @@ #include "Console.h" #include "JSScriptProfile.h" +#include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" #include "ScriptProfile.h" #include <runtime/JSArray.h> +#include <wtf/OwnPtr.h> using namespace JSC; @@ -52,6 +55,28 @@ JSValue JSConsole::profiles(ExecState* exec) const return constructArray(exec, list); } +JSValue JSConsole::profile(ExecState* exec) +{ + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(exec, 1)); + const String& title = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)); + if (exec->hadException()) + return jsUndefined(); + + impl()->profile(title, exec, callStack.release()); + return jsUndefined(); +} + +JSValue JSConsole::profileEnd(ExecState* exec) +{ + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(exec, 1)); + const String& title = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)); + if (exec->hadException()) + return jsUndefined(); + + impl()->profileEnd(title, exec, callStack.release()); + return jsUndefined(); +} + #endif } // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLOutputElementCustom.cpp b/WebCore/bindings/js/JSHTMLOutputElementCustom.cpp new file mode 100644 index 0000000..248a08e --- /dev/null +++ b/WebCore/bindings/js/JSHTMLOutputElementCustom.cpp @@ -0,0 +1,51 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLOutputElement.h" + +#include "HTMLOutputElement.h" +#include "JSDOMBinding.h" +#include "JSDOMSettableTokenList.h" +#include <wtf/GetPtr.h> + +using namespace JSC; + +namespace WebCore { + +JSValue JSHTMLOutputElement::htmlFor(ExecState* exec) const +{ + HTMLOutputElement* output = static_cast<HTMLOutputElement*>(impl()); + JSValue result = toJS(exec, globalObject(), WTF::getPtr(output->htmlFor())); + return result; +} + +void JSHTMLOutputElement::setHtmlFor(ExecState* exec, JSValue value) +{ + HTMLOutputElement* output = static_cast<HTMLOutputElement*>(impl()); + output->setFor(valueToStringWithNullCheck(exec, value)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp index 818d549..9cf4604 100644 --- a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp +++ b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp @@ -47,7 +47,6 @@ #include "InjectedScript.h" #include "InjectedScriptHost.h" #include "InspectorController.h" -#include "InspectorResource.h" #include "InspectorValues.h" #include "JSDOMWindow.h" #include "JSDOMWindowCustom.h" diff --git a/WebCore/bindings/js/JSSVGLengthCustom.cpp b/WebCore/bindings/js/JSSVGLengthCustom.cpp index 0cc7c6d..9a9138c 100644 --- a/WebCore/bindings/js/JSSVGLengthCustom.cpp +++ b/WebCore/bindings/js/JSSVGLengthCustom.cpp @@ -22,22 +22,64 @@ #if ENABLE(SVG) #include "JSSVGLength.h" +#include <runtime/Error.h> #include "SVGAnimatedProperty.h" +#include "SVGException.h" using namespace JSC; namespace WebCore { -JSValue JSSVGLength::value(ExecState*) const +JSValue JSSVGLength::value(ExecState* exec) const { SVGLength& podImp = impl()->propertyReference(); - return jsNumber(podImp.value(impl()->contextElement())); + ExceptionCode ec = 0; + float value = podImp.value(impl()->contextElement(), ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + + return jsNumber(value); +} + +void JSSVGLength::setValue(ExecState* exec, JSValue value) +{ + if (!value.isUndefinedOrNull() && !value.isNumber() && !value.isBoolean()) { + throwVMTypeError(exec); + return; + } + + SVGLength& podImp = impl()->propertyReference(); + + ExceptionCode ec = 0; + podImp.setValue(value.toFloat(exec), impl()->contextElement(), ec); + if (ec) { + setDOMException(exec, ec); + return; + } + + impl()->commitChange(); } JSValue JSSVGLength::convertToSpecifiedUnits(ExecState* exec) { SVGLength& podImp = impl()->propertyReference(); - podImp.convertToSpecifiedUnits(exec->argument(0).toInt32(exec), impl()->contextElement()); + + // Mimic the behaviour of RequiresAllArguments=Raise. + if (exec->argumentCount() < 1) + return throwError(exec, createSyntaxError(exec, "Not enough arguments")); + + unsigned short unitType = exec->argument(0).toUInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + ExceptionCode ec = 0; + podImp.convertToSpecifiedUnits(unitType, impl()->contextElement(), ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } impl()->commitChange(); return jsUndefined(); diff --git a/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp b/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp index 643ce64..e414278 100644 --- a/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp +++ b/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp @@ -171,15 +171,15 @@ JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec) return throwTypeError(exec); WebGLProgram* program = toWebGLProgram(exec->argument(0)); if (exec->hadException()) - return jsUndefined(); + return jsNull(); Vector<WebGLShader*> shaders; bool succeed = context->getAttachedShaders(program, shaders, ec); if (ec) { setDOMException(exec, ec); - return jsUndefined(); + return jsNull(); } if (!succeed) - return jsUndefined(); + return jsNull(); MarkedArgumentBuffer list; for (size_t ii = 0; ii < shaders.size(); ++ii) list.append(toJS(exec, globalObject(), shaders[ii])); diff --git a/WebCore/bindings/js/ScriptCallStack.cpp b/WebCore/bindings/js/ScriptCallStackFactory.cpp index de61b07..25fabdd 100644 --- a/WebCore/bindings/js/ScriptCallStack.cpp +++ b/WebCore/bindings/js/ScriptCallStackFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Google Inc. All rights reserved. + * 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 @@ -29,85 +29,62 @@ */ #include "config.h" -#include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" +#include "JSDOMBinding.h" +#include "ScriptArguments.h" +#include "ScriptCallFrame.h" +#include "ScriptCallStack.h" +#include "ScriptValue.h" #include <interpreter/CallFrame.h> #include <interpreter/Interpreter.h> +#include <runtime/ArgList.h> #include <runtime/JSFunction.h> +#include <runtime/JSGlobalData.h> #include <runtime/JSValue.h> #include <runtime/UString.h> -#include <runtime/JSGlobalData.h> using namespace JSC; namespace WebCore { -ScriptCallStack::ScriptCallStack(ExecState* exec, unsigned skipArgumentCount) - : m_initialized(false) - , m_exec(exec) - , m_caller(0) -{ - int signedLineNumber; - intptr_t sourceID; - UString urlString; - JSValue function; - - exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, urlString, function); - - unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; - - if (function) { - m_caller = asFunction(function); - m_frames.append(ScriptCallFrame(m_caller->name(m_exec), urlString, lineNumber, m_exec, skipArgumentCount)); - } else { - // Caller is unknown, but we should still add the frame, because - // something called us, and gave us arguments. - m_frames.append(ScriptCallFrame(UString(), urlString, lineNumber, m_exec, skipArgumentCount)); - } -} - -ScriptCallStack::~ScriptCallStack() -{ -} - -const ScriptCallFrame &ScriptCallStack::at(unsigned index) +PassOwnPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize) { - // First frame is pre-populated in constructor, so don't trigger - // initialization unless looking beyond the first frame. - if (index > 0) - initialize(); - ASSERT(m_frames.size() > index); - return m_frames[index]; -} - -unsigned ScriptCallStack::size() -{ - initialize(); - return m_frames.size(); -} - -void ScriptCallStack::initialize() -{ - if (!m_caller || m_initialized) - return; - - int signedLineNumber; - intptr_t sourceID; - UString urlString; - JSValue function; - // callFrame must exist if m_caller is not null. - CallFrame* callFrame = m_exec->callerFrame(); + Vector<ScriptCallFrame> frames; + CallFrame* callFrame = exec; while (true) { ASSERT(callFrame); - m_exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function); - if (!function) - break; - JSFunction* jsFunction = asFunction(function); + int signedLineNumber; + intptr_t sourceID; + UString urlString; + JSValue function; + + exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function); + UString functionName; + if (function) + functionName = asFunction(function)->name(exec); + else { + // Caller is unknown, but if frames is empty we should still add the frame, because + // something called us, and gave us arguments. + if (!frames.isEmpty()) + break; + } unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; - m_frames.append(ScriptCallFrame(jsFunction->name(m_exec), urlString, lineNumber, m_exec, 0)); + frames.append(ScriptCallFrame(ustringToString(functionName), ustringToString(urlString), lineNumber)); + if (!function || frames.size() == maxStackSize) + break; callFrame = callFrame->callerFrame(); } - m_initialized = true; + return new ScriptCallStack(frames); +} + +PassOwnPtr<ScriptArguments> createScriptArguments(JSC::ExecState* exec, unsigned skipArgumentCount) +{ + Vector<ScriptValue> arguments; + size_t argumentCount = exec->argumentCount(); + for (size_t i = skipArgumentCount; i < argumentCount; ++i) + arguments.append(ScriptValue(exec->argument(i))); + return new ScriptArguments(exec, arguments); } bool ScriptCallStack::stackTrace(int, const RefPtr<InspectorArray>&) diff --git a/WebCore/bindings/js/ScriptCallStackFactory.h b/WebCore/bindings/js/ScriptCallStackFactory.h new file mode 100644 index 0000000..744d88d --- /dev/null +++ b/WebCore/bindings/js/ScriptCallStackFactory.h @@ -0,0 +1,50 @@ +/* + * 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 ScriptCallStackFactory_h +#define ScriptCallStackFactory_h + +#include <wtf/PassOwnPtr.h> + +namespace JSC { +class ExecState; +} + +namespace WebCore { + +class ScriptArguments; +class ScriptCallStack; + +PassOwnPtr<ScriptCallStack> createScriptCallStack(JSC::ExecState*, size_t maxStackSize); +PassOwnPtr<ScriptArguments> createScriptArguments(JSC::ExecState*, unsigned skipArgumentCount); + +} // namespace WebCore + +#endif // ScriptCallStackFactory_h diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp index e03c822..cf55080 100644 --- a/WebCore/bindings/js/ScriptController.cpp +++ b/WebCore/bindings/js/ScriptController.cpp @@ -197,6 +197,11 @@ void ScriptController::clearWindowShell(bool goingIntoPageCache) windowShell->window()->willRemoveFromWindowShell(); windowShell->setWindow(m_frame->domWindow()); + // An m_cacheableBindingRootObject persists between page navigations + // so needs to know about the new JSDOMWindow. + if (m_cacheableBindingRootObject) + m_cacheableBindingRootObject->updateGlobalObject(windowShell->window()); + if (Page* page = m_frame->page()) { attachDebugger(windowShell, page->debugger()); windowShell->window()->setProfileGroup(page->group().identifier()); diff --git a/WebCore/bindings/js/ScriptState.cpp b/WebCore/bindings/js/ScriptState.cpp index 3edd1bd..d6699f6 100644 --- a/WebCore/bindings/js/ScriptState.cpp +++ b/WebCore/bindings/js/ScriptState.cpp @@ -35,9 +35,28 @@ #include "JSDOMWindowBase.h" #include "Node.h" #include "Page.h" +#include <interpreter/CallFrame.h> +#include <runtime/JSGlobalObject.h> namespace WebCore { +ScriptStateProtectedPtr::~ScriptStateProtectedPtr() +{ +} + +ScriptStateProtectedPtr::ScriptStateProtectedPtr(ScriptState* scriptState) + : m_globalObject(scriptState->lexicalGlobalObject()) +{ +} + +ScriptState* ScriptStateProtectedPtr::get() const +{ + if (m_globalObject) + return m_globalObject->globalExec(); + return 0; +} + + ScriptState* mainWorldScriptState(Frame* frame) { JSDOMWindowShell* shell = frame->script()->windowShell(mainThreadNormalWorld()); diff --git a/WebCore/bindings/js/ScriptState.h b/WebCore/bindings/js/ScriptState.h index 6bef4f7..0c08611 100644 --- a/WebCore/bindings/js/ScriptState.h +++ b/WebCore/bindings/js/ScriptState.h @@ -32,10 +32,14 @@ #ifndef ScriptState_h #define ScriptState_h -#include "JSDOMBinding.h" #include <runtime/Protect.h> #include <wtf/Noncopyable.h> +namespace JSC { +class ExecState; +class JSGlobalObject; +} + namespace WebCore { class DOMWrapperWorld; class Frame; @@ -50,14 +54,9 @@ typedef JSC::ExecState ScriptState; class ScriptStateProtectedPtr : public Noncopyable { public: - ScriptStateProtectedPtr() { } - ScriptStateProtectedPtr(ScriptState* scriptState) : m_globalObject(scriptState->lexicalGlobalObject()) { } - ScriptState* get() - { - if (m_globalObject) - return m_globalObject->globalExec(); - return 0; - } + explicit ScriptStateProtectedPtr(ScriptState*); + ~ScriptStateProtectedPtr(); + ScriptState* get() const; private: JSC::ProtectedPtr<JSC::JSGlobalObject> m_globalObject; }; diff --git a/WebCore/bindings/objc/DOMSVG.h b/WebCore/bindings/objc/DOMSVG.h index eda705e..1fdab9a 100644 --- a/WebCore/bindings/objc/DOMSVG.h +++ b/WebCore/bindings/objc/DOMSVG.h @@ -39,7 +39,6 @@ #import <WebCore/DOMSVGAnimatedNumber.h> #import <WebCore/DOMSVGAnimatedNumberList.h> #import <WebCore/DOMSVGAnimatedPathData.h> -#import <WebCore/DOMSVGAnimatedPoints.h> #import <WebCore/DOMSVGAnimatedPreserveAspectRatio.h> #import <WebCore/DOMSVGAnimatedRect.h> #import <WebCore/DOMSVGAnimatedString.h> diff --git a/WebCore/bindings/scripts/CodeGenerator.pm b/WebCore/bindings/scripts/CodeGenerator.pm index c4f87f0..d439c19 100644 --- a/WebCore/bindings/scripts/CodeGenerator.pm +++ b/WebCore/bindings/scripts/CodeGenerator.pm @@ -50,8 +50,8 @@ my %numericTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1, my %primitiveTypeHash = ( "boolean" => 1, "void" => 1, "Date" => 1); -my %podTypeHash = ("SVGNumber" => 1, "SVGTransform" => 1); -my %podTypesWithWritablePropertiesHash = ("SVGMatrix" => 1, "SVGPoint" => 1, "SVGPreserveAspectRatio" => 1); +my %podTypeHash = ("SVGTransform" => 1); +my %podTypesWithWritablePropertiesHash = ("SVGMatrix" => 1); my %stringTypeHash = ("DOMString" => 1, "AtomicString" => 1); my %nonPointerTypeHash = ("DOMTimeStamp" => 1, "CompareHow" => 1, "SVGPaintType" => 1); @@ -59,7 +59,9 @@ my %nonPointerTypeHash = ("DOMTimeStamp" => 1, "CompareHow" => 1, "SVGPaintType" my %svgNewStyleAnimatedTypeHash = ("SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1, "SVGAnimatedEnumeration" => 1, "SVGAnimatedInteger" => 1, "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1, - "SVGAnimatedRect" => 1); + "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1, + "SVGAnimatedPreserveAspectRatio" => 1, "SVGAnimatedRect" => 1, + "SVGAnimatedString" => 1); my %svgAnimatedTypeHash = ("SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1, "SVGAnimatedEnumeration" => 1, "SVGAnimatedInteger" => 1, @@ -75,11 +77,21 @@ my %svgAttributesInHTMLHash = ("class" => 1, "id" => 1, "onabort" => 1, "onclick "onmouseup" => 1, "onresize" => 1, "onscroll" => 1, "onunload" => 1); -my %svgNativeType = ( +my %svgTypeNeedingTearOff = ( "SVGAngle" => "SVGPropertyTearOff<SVGAngle>", "SVGLength" => "SVGPropertyTearOff<SVGLength>", "SVGLengthList" => "SVGListPropertyTearOff<SVGLengthList>", - "SVGRect" => "SVGPropertyTearOff<FloatRect>" + "SVGNumber" => "SVGPropertyTearOff<float>", + "SVGNumberList" => "SVGListPropertyTearOff<SVGNumberList>", + "SVGPoint" => "SVGPropertyTearOff<FloatPoint>", + "SVGPointList" => "SVGListPropertyTearOff<SVGPointList>", + "SVGPreserveAspectRatio" => "SVGPropertyTearOff<SVGPreserveAspectRatio>", + "SVGRect" => "SVGPropertyTearOff<FloatRect>", + "SVGStringList" => "SVGStaticListPropertyTearOff<SVGStringList>" +); + +my %svgTypeWithWritablePropertiesNeedingTearOff = ( + "SVGPoint" => 1 ); # Cache of IDL file pathnames. @@ -367,7 +379,16 @@ sub IsSVGTypeNeedingTearOff my $object = shift; my $type = shift; - return 1 if exists $svgNativeType{$type}; + return 1 if exists $svgTypeNeedingTearOff{$type}; + return 0; +} + +sub IsSVGTypeWithWritablePropertiesNeedingTearOff +{ + my $object = shift; + my $type = shift; + + return 1 if $svgTypeWithWritablePropertiesNeedingTearOff{$type}; return 0; } @@ -376,7 +397,7 @@ sub GetSVGTypeNeedingTearOff my $object = shift; my $type = shift; - return $svgNativeType{$type} if exists $svgNativeType{$type}; + return $svgTypeNeedingTearOff{$type} if exists $svgTypeNeedingTearOff{$type}; return undef; } @@ -385,16 +406,19 @@ sub GetSVGWrappedTypeNeedingTearOff my $object = shift; my $type = shift; - my $svgNativeType = $object->GetSVGTypeNeedingTearOff($type); - return $svgNativeType if not $svgNativeType; + my $svgTypeNeedingTearOff = $object->GetSVGTypeNeedingTearOff($type); + return $svgTypeNeedingTearOff if not $svgTypeNeedingTearOff; - if ($svgNativeType =~ /SVGPropertyTearOff/) { - $svgNativeType =~ s/SVGPropertyTearOff<//; - } elsif ($svgNativeType =~ /SVGListPropertyTearOff/) { - $svgNativeType =~ s/SVGListPropertyTearOff<//; + if ($svgTypeNeedingTearOff =~ /SVGPropertyTearOff/) { + $svgTypeNeedingTearOff =~ s/SVGPropertyTearOff<//; + } elsif ($svgTypeNeedingTearOff =~ /SVGListPropertyTearOff/) { + $svgTypeNeedingTearOff =~ s/SVGListPropertyTearOff<//; + } elsif ($svgTypeNeedingTearOff =~ /SVGStaticListPropertyTearOff/) { + $svgTypeNeedingTearOff =~ s/SVGStaticListPropertyTearOff<//; } - $svgNativeType =~ s/>//; - return $svgNativeType; + + $svgTypeNeedingTearOff =~ s/>//; + return $svgTypeNeedingTearOff; } # FIXME: This method will go away once all SVG animated properties are converted to the new scheme. @@ -476,13 +500,18 @@ sub AttributeNameForGetterAndSetter my ($generator, $attribute) = @_; my $attributeName = $attribute->signature->name; + my $attributeType = $generator->StripModule($attribute->signature->type); # Avoid clash with C++ keyword. $attributeName = "_operator" if $attributeName eq "operator"; + # SVGAElement defines a non-virtual "String& target() const" method which clashes with "virtual String target() const" in Element. + # To solve this issue the SVGAElement method was renamed to "svgTarget", take care of that when calling this method. + $attributeName = "svgTarget" if $attributeName eq "target" and $attributeType eq "SVGAnimatedString"; + # SVG animated types need to use a special attribute name. # The rest of the special casing for SVG animated types is handled in the language-specific code generators. - $attributeName .= "Animated" if $generator->IsSVGAnimatedType($generator->StripModule($attribute->signature->type)); + $attributeName .= "Animated" if $generator->IsSVGAnimatedType($attributeType); return $attributeName; } diff --git a/WebCore/bindings/scripts/CodeGeneratorGObject.pm b/WebCore/bindings/scripts/CodeGeneratorGObject.pm index dd9e3c7..6c450ad 100644 --- a/WebCore/bindings/scripts/CodeGeneratorGObject.pm +++ b/WebCore/bindings/scripts/CodeGeneratorGObject.pm @@ -501,8 +501,7 @@ EOF my ${listenerName} = $name . "Listener"; my $txtInstallEventListener = << "EOF"; - RefPtr<WebCore::GObjectEventListener> ${listenerName} = WebCore::GObjectEventListener::create(reinterpret_cast<GObject*>(object), "${gobjectSignalName}"); - coreObject->addEventListener("${name}", ${listenerName}, false); + WebCore::GObjectEventListener::addEventListener(object, coreObject, "${name}", "${gobjectSignalName}"); EOF push(@txtInstallEventListeners, $txtInstallEventListener); diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm index 9244bc6..b18e57e 100644 --- a/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -1983,8 +1983,12 @@ sub GenerateImplementation my $hasOptionalArguments = 0; if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { - push(@implContent, " ScriptCallStack callStack(exec, $numParameters);\n"); + push(@implContent, " OwnPtr<ScriptArguments> scriptArguments(createScriptArguments(exec, $numParameters));\n"); + push(@implContent, " size_t maxStackSize = imp->shouldCaptureFullStackTrace() ? ScriptCallStack::maxCallStackSizeToCapture : 1;\n"); + push(@implContent, " OwnPtr<ScriptCallStack> callStack(createScriptCallStack(exec, maxStackSize));\n"); + $implIncludes{"ScriptArguments.h"} = 1; $implIncludes{"ScriptCallStack.h"} = 1; + $implIncludes{"ScriptCallStackFactory.h"} = 1; } my $callWith = $function->signature->extendedAttributes->{"CallWith"}; @@ -2389,8 +2393,8 @@ sub GenerateImplementationFunctionCall() if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { $functionString .= ", " if $paramIndex; - ++$paramIndex; - $functionString .= "&callStack"; + $paramIndex += 2; + $functionString .= "scriptArguments.release(), callStack.release()"; } if (@{$function->raisesExceptions}) { @@ -2455,11 +2459,7 @@ my %nativeType = ( "SerializedScriptValue" => "RefPtr<SerializedScriptValue>", "IDBKey" => "RefPtr<IDBKey>", "SVGMatrix" => "AffineTransform", - "SVGNumber" => "float", "SVGPaintType" => "SVGPaint::SVGPaintType", - "SVGPreserveAspectRatio" => "SVGPreserveAspectRatio", - "SVGPoint" => "FloatPoint", - "SVGRect" => "FloatRect", "SVGTransform" => "SVGTransform", "boolean" => "bool", "double" => "double", @@ -2504,7 +2504,7 @@ sub GetSVGPropertyTypes $svgPropertyType = $svgWrappedNativeType; $headerIncludes{"$svgWrappedNativeType.h"} = 1; $headerIncludes{"SVGAnimatedPropertyTearOff.h"} = 1; - } elsif ($svgNativeType =~ /SVGListPropertyTearOff/) { + } elsif ($svgNativeType =~ /SVGListPropertyTearOff/ or $svgNativeType =~ /SVGStaticListPropertyTearOff/) { $svgListPropertyType = $svgWrappedNativeType; $headerIncludes{"$svgWrappedNativeType.h"} = 1; $headerIncludes{"SVGAnimatedListPropertyTearOff.h"} = 1; @@ -2528,7 +2528,7 @@ sub JSValueToNative return "$value.toBoolean(exec)" if $type eq "boolean"; return "$value.toNumber(exec)" if $type eq "double"; - return "$value.toFloat(exec)" if $type eq "float" or $type eq "SVGNumber"; + return "$value.toFloat(exec)" if $type eq "float"; return "$value.toInt32(exec)" if $type eq "long"; return "$value.toUInt32(exec)" if $type eq "unsigned long" or $type eq "unsigned short"; return "static_cast<$type>($value.toInteger(exec))" if $type eq "long long" or $type eq "unsigned long long"; @@ -2558,8 +2558,6 @@ sub JSValueToNative return "createIDBKeyFromValue(exec, $value)"; } - $implIncludes{"FloatPoint.h"} = 1 if $type eq "SVGPoint"; - $implIncludes{"FloatRect.h"} = 1 if $type eq "SVGRect"; $implIncludes{"HTMLOptionElement.h"} = 1 if $type eq "HTMLOptionElement"; $implIncludes{"JSCustomVoidCallback.h"} = 1 if $type eq "VoidCallback"; $implIncludes{"Event.h"} = 1 if $type eq "Event"; @@ -2681,7 +2679,22 @@ sub NativeToJSValue # Convert from abstract SVGProperty to real type, so the right toJS() method can be invoked. $value = "static_cast<" . GetNativeType($type) . ">($value)"; } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($type) and not $implClassName =~ /List$/) { - $value = $codeGenerator->GetSVGTypeNeedingTearOff($type) . "::create($value)"; + my $tearOffType = $codeGenerator->GetSVGTypeNeedingTearOff($type); + if ($codeGenerator->IsSVGTypeWithWritablePropertiesNeedingTearOff($type) and $inFunctionCall eq 0 and not defined $signature->extendedAttributes->{"Immutable"}) { + $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyTearOff<$implClassName, /; + $implIncludes{"SVGStaticPropertyTearOff.h"} = 1; + + my $getter = $value; + $getter =~ s/imp->//; + $getter =~ s/\(\)//; + my $updater = "update" . $codeGenerator->WK_ucfirst($getter); + $value = "${tearOffType}::create(imp, $value, &${implClassName}::$updater)"; + } elsif ($tearOffType =~ /SVGStaticListPropertyTearOff/) { + my $extraImp = "GetOwnerElementForType<$implClassName, IsDerivedFromSVGElement<$implClassName>::value>::ownerElement(imp), "; + $value = "${tearOffType}::create($extraImp$value)"; + } elsif (not $tearOffType =~ /SVGPointList/) { + $value = "${tearOffType}::create($value)"; + } } return "toJS(exec, $globalObject, WTF::getPtr($value))"; diff --git a/WebCore/bindings/scripts/CodeGeneratorObjC.pm b/WebCore/bindings/scripts/CodeGeneratorObjC.pm index 8351c87..69e24a9 100644 --- a/WebCore/bindings/scripts/CodeGeneratorObjC.pm +++ b/WebCore/bindings/scripts/CodeGeneratorObjC.pm @@ -1,4 +1,4 @@ -# +# # Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> # Copyright (C) 2006 Anders Carlsson <andersca@mac.com> # Copyright (C) 2006, 2007 Samuel Weinig <sam@webkit.org> @@ -59,8 +59,7 @@ my @depsContent = (); my %protocolTypeHash = ("XPathNSResolver" => 1, "EventListener" => 1, "EventTarget" => 1, "NodeFilter" => 1, "SVGLocatable" => 1, "SVGTransformable" => 1, "SVGStylable" => 1, "SVGFilterPrimitiveStandardAttributes" => 1, "SVGTests" => 1, "SVGLangSpace" => 1, "SVGExternalResourcesRequired" => 1, "SVGURIReference" => 1, - "SVGZoomAndPan" => 1, "SVGFitToViewBox" => 1, "SVGAnimatedPathData" => 1, "SVGAnimatedPoints" => 1, - "ElementTimeControl" => 1); + "SVGZoomAndPan" => 1, "SVGFitToViewBox" => 1, "SVGAnimatedPathData" => 1, "ElementTimeControl" => 1); my %nativeObjCTypeHash = ("URL" => 1, "Color" => 1); # FIXME: this should be replaced with a function that recurses up the tree @@ -71,7 +70,7 @@ my %baseTypeHash = ("Object" => 1, "Node" => 1, "NodeList" => 1, "NamedNodeMap" "NodeIterator" => 1, "TreeWalker" => 1, "AbstractView" => 1, "Blob" => 1, "SVGAngle" => 1, "SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1, "SVGAnimatedEnumeration" => 1, "SVGAnimatedInteger" => 1, "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1, - "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1, "SVGAnimatedPoints" => 1, + "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1, "SVGAnimatedPreserveAspectRatio" => 1, "SVGAnimatedRect" => 1, "SVGAnimatedString" => 1, "SVGAnimatedTransformList" => 1, "SVGLength" => 1, "SVGLengthList" => 1, "SVGMatrix" => 1, "SVGNumber" => 1, "SVGNumberList" => 1, "SVGPathSeg" => 1, "SVGPathSegList" => 1, "SVGPoint" => 1, @@ -600,12 +599,6 @@ sub AddIncludesForType return; } - if ($type eq "SVGPoint") { - $implIncludes{"FloatPoint.h"} = 1; - $implIncludes{"DOMSVGPointInternal.h"} = 1; - return; - } - if ($type eq "SVGMatrix") { $implIncludes{"AffineTransform.h"} = 1; $implIncludes{"DOMSVGMatrixInternal.h"} = 1; @@ -613,11 +606,6 @@ sub AddIncludesForType return; } - if ($type eq "SVGNumber") { - $implIncludes{"DOMSVGNumberInternal.h"} = 1; - return; - } - if ($type =~ /(\w+)(Abs|Rel)$/) { $implIncludes{"$1.h"} = 1; $implIncludes{"DOM${type}Internal.h"} = 1; @@ -656,6 +644,16 @@ sub AddIncludesForType $implIncludes{"DOM${type}Internal.h"} = 1; } +sub GetSVGTypeWithNamespace +{ + my $type = shift; + my $typeWithNamespace = "WebCore::" . $codeGenerator->GetSVGTypeNeedingTearOff($type); + + # Special case for DOMSVGNumber + $typeWithNamespace =~ s/</\<WebCore::/ unless $type eq "SVGNumber"; + return $typeWithNamespace; +} + sub GetSVGPropertyTypes { my $implType = shift; @@ -671,13 +669,18 @@ sub GetSVGPropertyTypes # Append space to avoid compilation errors when using PassRefPtr<$svgNativeType> $svgNativeType = "WebCore::$svgNativeType "; - $svgNativeType =~ s/</\<WebCore::/; + $svgNativeType =~ s/</\<WebCore::/ if not $svgNativeType =~ /float/; my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implType); if ($svgNativeType =~ /SVGPropertyTearOff/) { - $svgPropertyType = "WebCore::$svgWrappedNativeType"; - $svgPropertyType =~ s/</\<WebCore::/; - } elsif ($svgNativeType =~ /SVGListPropertyTearOff/) { + if ($svgWrappedNativeType eq "float") { + # Special case for DOMSVGNumber + $svgPropertyType = $svgWrappedNativeType; + } else { + $svgPropertyType = "WebCore::$svgWrappedNativeType"; + $svgPropertyType =~ s/</\<WebCore::/; + } + } elsif ($svgNativeType =~ /SVGListPropertyTearOff/ or $svgNativeType =~ /SVGStaticListPropertyTearOff/) { $svgListPropertyType = "WebCore::$svgWrappedNativeType"; $svgListPropertyType =~ s/</\<WebCore::/; } @@ -1127,7 +1130,12 @@ sub GenerateImplementation $implIncludes{"$1.h"} = 1; } else { if (!$podType) { - $implIncludes{"$implClassName.h"} = 1 if not $codeGenerator->AvoidInclusionOfType($implClassName); + if (!$codeGenerator->AvoidInclusionOfType($implClassName)) { + $implIncludes{"$implClassName.h"} = 1 ; + } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($implClassName)) { + my $includeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implClassName); + $implIncludes{"${includeType}.h"} = 1; + } } else { $implIncludes{"$podType.h"} = 1 unless $podType eq "float"; } @@ -1236,13 +1244,7 @@ sub GenerateImplementation # TODO: Handle special case for DOMSVGLength. We do need Custom code support for this. if ($svgPropertyType eq "WebCore::SVGLength" and $attributeName eq "value") { - $getterContentHead = "value(0 /* FIXME */"; - } - } else { - # Special case for DOMSVGNumber - if ($podType and $podType eq "float") { - $getterContentHead = "*IMPL"; - $getterContentTail = ""; + $getterContentHead = "value(IMPL->contextElement(), "; } } @@ -1287,10 +1289,15 @@ sub GenerateImplementation $getterContentHead = "kit($getterContentHead"; $getterContentTail .= ")"; } elsif ($svgPropertyType) { - $getterContentHead = "IMPL->propertyReference().$getterContentHead"; + # Special case for DOMSVGNumber + if ($svgPropertyType eq "float") { + # Intentional leave out closing brace, it's already contained in getterContentTail + $getterContentHead = "IMPL->propertyReference("; + } else { + $getterContentHead = "IMPL->propertyReference().$getterContentHead"; + } } elsif ($codeGenerator->IsSVGNewStyleAnimatedType($implClassName) and $codeGenerator->IsSVGTypeNeedingTearOff($idlType)) { - my $idlTypeWithNamespace = "WebCore::" . $codeGenerator->GetSVGTypeNeedingTearOff($idlType); - $idlTypeWithNamespace =~ s/</\<WebCore::/; + my $idlTypeWithNamespace = GetSVGTypeWithNamespace($idlType); $getterContentHead = "kit(static_cast<$idlTypeWithNamespace*>($getterContentHead)"; $getterContentTail .= ")"; } elsif (IsProtocolType($idlType) and $idlType ne "EventTarget") { @@ -1303,12 +1310,30 @@ sub GenerateImplementation $getterContentHead = "$getterContentHead"; $getterContentTail .= "->toString()"; } elsif (ConversionNeeded($attribute->signature->type)) { - if ($codeGenerator->IsSVGTypeNeedingTearOff($attribute->signature->type) and not $implClassName =~ /List$/) { - my $idlType = $attribute->signature->type; - my $idlTypeWithNamespace = "WebCore::" . $codeGenerator->GetSVGTypeNeedingTearOff($idlType); - $idlTypeWithNamespace =~ s/</\<WebCore::/; - $getterContentHead = "kit(WTF::getPtr(${idlTypeWithNamespace}::create($getterContentHead"; - $getterContentTail .= ")))"; + my $type = $attribute->signature->type; + if ($codeGenerator->IsSVGTypeNeedingTearOff($type) and not $implClassName =~ /List$/) { + my $idlTypeWithNamespace = GetSVGTypeWithNamespace($type); + if ($codeGenerator->IsSVGTypeWithWritablePropertiesNeedingTearOff($type) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) { + $idlTypeWithNamespace =~ s/SVGPropertyTearOff</SVGStaticPropertyTearOff<$implClassNameWithNamespace, /; + $implIncludes{"SVGStaticPropertyTearOff.h"} = 1; + + my $getter = $getterContentHead; + $getter =~ s/IMPL->//; + $getter =~ s/\(//; + my $updater = "update" . $codeGenerator->WK_ucfirst($getter); + $getterContentHead = "kit(WTF::getPtr(${idlTypeWithNamespace}::create(IMPL, $getterContentHead$getterContentTail, &${implClassNameWithNamespace}::$updater"; + $getterContentTail .= "))"; + } elsif ($idlTypeWithNamespace =~ /SVGStaticListPropertyTearOff/) { + my $extraImp = "WebCore::GetOwnerElementForType<$implClassNameWithNamespace, WebCore::IsDerivedFromSVGElement<$implClassNameWithNamespace>::value>::ownerElement(IMPL), "; + $getterContentHead = "kit(WTF::getPtr(${idlTypeWithNamespace}::create($extraImp$getterContentHead"; + $getterContentTail .= ")))"; + } elsif ($idlTypeWithNamespace =~ /SVGPointList/) { + $getterContentHead = "kit(WTF::getPtr($getterContentHead"; + $getterContentTail .= "))"; + } else { + $getterContentHead = "kit(WTF::getPtr(${idlTypeWithNamespace}::create($getterContentHead"; + $getterContentTail .= ")))"; + } } else { $getterContentHead = "kit(WTF::getPtr($getterContentHead"; $getterContentTail .= "))"; @@ -1381,24 +1406,31 @@ sub GenerateImplementation push(@implContent, " $svgPropertyType& podImpl = IMPL->propertyReference();\n"); my $ec = $hasSetterException ? ", ec" : ""; push(@implContent, " $exceptionInit\n") if $hasSetterException; - push(@implContent, " podImpl.$coreSetterName($arg$ec);\n"); + + # Special case for DOMSVGNumber + if ($svgPropertyType eq "float") { + push(@implContent, " podImpl = $arg;\n"); + } else { + # FIXME: Special case for DOMSVGLength. We do need Custom code support for this. + if ($svgPropertyType eq "WebCore::SVGLength" and $attributeName eq "value") { + push(@implContent, " podImpl.$coreSetterName($arg, IMPL->contextElement()$ec);\n"); + } else { + push(@implContent, " podImpl.$coreSetterName($arg$ec);\n"); + } + } + if ($hasSetterException) { push(@implContent, " if (!ec)\n"); push(@implContent, " IMPL->commitChange();\n"); push(@implContent, " $exceptionRaiseOnError\n"); } else { - push(@implContent, " IMPL->commitChange();\n"); + push(@implContent, " IMPL->commitChange();\n"); } } elsif ($svgListPropertyType) { $getterContentHead = "$getterExpressionPrefix"; push(@implContent, " IMPL->$coreSetterName($arg);\n"); } elsif ($podType) { - # Special case for DOMSVGNumber - if ($podType eq "float") { - push(@implContent, " *IMPL = $arg;\n"); - } else { - push(@implContent, " IMPL->$coreSetterName($arg);\n"); - } + push(@implContent, " IMPL->$coreSetterName($arg);\n"); } else { my $setterExpressionPrefix = $codeGenerator->SetterExpressionPrefix(\%implIncludes, $interfaceName, $attribute); my $ec = $hasSetterException ? ", ec" : ""; @@ -1519,8 +1551,8 @@ sub GenerateImplementation my $svgMatrixInverse = ($podType and $podType eq "AffineTransform" and $functionName eq "inverse"); my $svgLengthConvertToSpecifiedUnits = ($svgPropertyType and $svgPropertyType eq "WebCore::SVGLength" and $functionName eq "convertToSpecifiedUnits"); + push(@parameterNames, "IMPL->contextElement()") if $svgLengthConvertToSpecifiedUnits; push(@parameterNames, "ec") if $raisesExceptions and !($svgMatrixRotateFromVector || $svgMatrixInverse); - push(@parameterNames, "0 /* FIXME */") if $svgLengthConvertToSpecifiedUnits; # Handle arguments that are 'SVGProperty' based (SVGAngle/SVGLength). We need to convert from SVGPropertyTearOff<Type>* to Type, # to be able to call the desired WebCore function. If the conversion fails, we can't extract Type and need to raise an exception. @@ -1533,8 +1565,7 @@ sub GenerateImplementation next if not $codeGenerator->IsSVGTypeNeedingTearOff($idlType) or $implClassName =~ /List$/; my $implGetter = GetObjCTypeGetter($paramName, $idlType); - my $idlTypeWithNamespace = "WebCore::" . $codeGenerator->GetSVGTypeNeedingTearOff($idlType); - $idlTypeWithNamespace =~ s/</\<WebCore::/; + my $idlTypeWithNamespace = GetSVGTypeWithNamespace($idlType); push(@functionContent, " $idlTypeWithNamespace* ${paramName}Core = $implGetter;\n"); push(@functionContent, " if (!${paramName}Core) {\n"); @@ -1555,7 +1586,7 @@ sub GenerateImplementation if ($svgPropertyType) { push(@functionContent, " $svgPropertyType& podImpl = IMPL->propertyReference();\n"); - $content = "podImpl.$content;\n IMPL->commitChange()"; + $content = "podImpl.$content"; } else { $content = $caller . "->$content"; } @@ -1579,9 +1610,14 @@ sub GenerateImplementation if ($raisesExceptions) { push(@functionContent, " $exceptionInit\n"); push(@functionContent, " $content;\n"); + if ($svgPropertyType) { + push(@functionContent, " if (!ec)\n"); + push(@functionContent, " IMPL->commitChange();\n"); + } push(@functionContent, " $exceptionRaiseOnError\n"); } else { push(@functionContent, " $content;\n"); + push(@functionContent, " IMPL->commitChange()\n") if $svgPropertyType; } } elsif (defined $needsCustom{"NodeToReturn"}) { # Special case the insertBefore, replaceChild, removeChild @@ -1603,9 +1639,7 @@ sub GenerateImplementation } else { if (ConversionNeeded($function->signature->type)) { if ($codeGenerator->IsSVGTypeNeedingTearOff($function->signature->type) and not $implClassName =~ /List$/) { - my $idlType = $function->signature->type; - my $idlTypeWithNamespace = "WebCore::" . $codeGenerator->GetSVGTypeNeedingTearOff($idlType); - $idlTypeWithNamespace =~ s/</\<WebCore::/; + my $idlTypeWithNamespace = GetSVGTypeWithNamespace($function->signature->type); $content = "kit(WTF::getPtr(${idlTypeWithNamespace}::create($content)))"; } elsif ($codeGenerator->IsPodType($function->signature->type)) { $content = "kit($content)"; diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm index cfb8a6d..2a76692 100644 --- a/WebCore/bindings/scripts/CodeGeneratorV8.pm +++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm @@ -130,22 +130,13 @@ sub GenerateModule $module = $dataNode->module; } -sub AvoidInclusionOfType -{ - my $type = shift; - - # Special case: SVGRect.h / SVGPoint.h / SVGNumber.h / SVGMatrix.h do not exist. - return 1 if $type eq "SVGRect" or $type eq "SVGPoint" or $type eq "SVGNumber" or $type eq "SVGMatrix"; - return 0; -} - sub AddIncludesForType { my $type = $codeGenerator->StripModule(shift); # When we're finished with the one-file-per-class # reorganization, we won't need these special cases. - if (!$codeGenerator->IsPrimitiveType($type) and !AvoidInclusionOfType($type) and $type ne "Date") { + if (!$codeGenerator->IsPrimitiveType($type) and !$codeGenerator->AvoidInclusionOfType($type) and $type ne "Date") { # default, include the same named file $implIncludes{GetV8HeaderName(${type})} = 1; @@ -231,12 +222,13 @@ sub GetSVGPropertyTypes my $svgWrappedNativeType = $codeGenerator->GetSVGWrappedTypeNeedingTearOff($implType); if ($svgNativeType =~ /SVGPropertyTearOff/) { $svgPropertyType = $svgWrappedNativeType; - $implIncludes{"SVGAnimatedPropertyTearOff.h"} = 1, - } elsif ($svgNativeType =~ /SVGListPropertyTearOff/) { + $implIncludes{"SVGAnimatedPropertyTearOff.h"} = 1; + } elsif ($svgNativeType =~ /SVGListPropertyTearOff/ or $svgNativeType =~ /SVGStaticListPropertyTearOff/) { $svgListPropertyType = $svgWrappedNativeType; - $implIncludes{"SVGAnimatedListPropertyTearOff.h"} = 1, + $implIncludes{"SVGAnimatedListPropertyTearOff.h"} = 1; } + $svgPropertyType = "SVGPoint" if $svgPropertyType eq "FloatPoint"; return ($svgPropertyType, $svgListPropertyType, $svgNativeType); } @@ -280,7 +272,17 @@ sub GenerateHeader push(@headerContent, "\nnamespace WebCore {\n"); push(@headerContent, "\ntemplate<typename PODType> class V8SVGPODTypeWrapper;\n") if $podType; push(@headerContent, "\ntemplate<typename PropertyType> class SVGPropertyTearOff;\n") if $svgPropertyType; +<<<<<<< HEAD push(@headerContent, "\ntemplate<typename PropertyType> class SVGListPropertyTearOff;\n") if $svgListPropertyType; +======= + if ($svgListPropertyType) { + if ($svgListPropertyType =~ /SVGStaticListPropertyTearOff/) { + push(@headerContent, "\ntemplate<typename PropertyType> class SVGStaticListPropertyTearOff;\n"); + } else { + push(@headerContent, "\ntemplate<typename PropertyType> class SVGListPropertyTearOff;\n"); + } + } +>>>>>>> webkit.org at r71558 push(@headerContent, "\nclass FloatRect;\n") if $svgPropertyType && $svgPropertyType eq "FloatRect"; push(@headerContent, "\nclass $className {\n"); @@ -479,7 +481,7 @@ sub GetHeaderClassInclude if ($className =~ /SVGPathSeg/) { $className =~ s/Abs|Rel//; } - return "" if (AvoidInclusionOfType($className)); + return "" if ($codeGenerator->AvoidInclusionOfType($className)); return "DeprecatedSVGAnimatedTemplate.h" if $codeGenerator->IsSVGAnimatedType($className) and !$codeGenerator->IsSVGNewStyleAnimatedType($className); return "${className}.h"; } @@ -728,7 +730,7 @@ sub GenerateNormalAttrGetter $attrIsPodType = 0; } - my $getterStringUsesImp = $implClassName ne "float"; + my $getterStringUsesImp = $implClassName ne "SVGNumber"; my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($implClassName); # Getter @@ -761,8 +763,12 @@ END push(@implContentDecls, <<END); $svgNativeType* wrapper = V8${implClassName}::toNative(info.Holder()); $svgWrappedNativeType& impInstance = wrapper->propertyReference(); +END + if ($getterStringUsesImp) { + push(@implContentDecls, <<END); $svgWrappedNativeType* imp = &impInstance; END + } } } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) { if ($interfaceName eq "DOMWindow") { @@ -928,8 +934,29 @@ END } elsif ($codeGenerator->IsSVGTypeNeedingTearOff($attrType) and not $implClassName =~ /List$/) { $implIncludes{"V8$attrType.h"} = 1; $implIncludes{"SVGPropertyTearOff.h"} = 1; +<<<<<<< HEAD my $svgNativeType = $codeGenerator->GetSVGTypeNeedingTearOff($attrType); push(@implContentDecls, " return toV8(WTF::getPtr(${svgNativeType}::create($result)));\n"); +======= + my $tearOffType = $codeGenerator->GetSVGTypeNeedingTearOff($attrType); + if ($codeGenerator->IsSVGTypeWithWritablePropertiesNeedingTearOff($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) { + $tearOffType =~ s/SVGPropertyTearOff</SVGStaticPropertyTearOff<$implClassName, /; + $implIncludes{"SVGStaticPropertyTearOff.h"} = 1; + + my $getter = $result; + $getter =~ s/imp->//; + $getter =~ s/\(\)//; + my $updater = "update" . $codeGenerator->WK_ucfirst($getter); + push(@implContentDecls, " return toV8(WTF::getPtr(${tearOffType}::create(imp, $result, &${implClassName}::$updater)));\n"); + } elsif ($tearOffType =~ /SVGStaticListPropertyTearOff/) { + my $extraImp = "GetOwnerElementForType<$implClassName, IsDerivedFromSVGElement<$implClassName>::value>::ownerElement(imp), "; + push(@implContentDecls, " return toV8(WTF::getPtr(${tearOffType}::create($extraImp$result)));\n"); + } elsif ($tearOffType =~ /SVGPointList/) { + push(@implContentDecls, " return toV8(WTF::getPtr($result));\n"); + } else { + push(@implContentDecls, " return toV8(WTF::getPtr(${tearOffType}::create($result)));\n"); + } +>>>>>>> webkit.org at r71558 } elsif ($attrIsPodType) { $implIncludes{"V8${attrType}.h"} = 1; push(@implContentDecls, " return toV8(wrapper.release().get());\n"); @@ -1071,7 +1098,7 @@ END push(@implContentDecls, " ExceptionCode ec = 0;\n"); } - if ($implClassName eq "float") { + if ($implClassName eq "SVGNumber") { push(@implContentDecls, " *imp = $result;\n"); } else { if ($attribute->signature->type eq "EventListener") { @@ -1361,11 +1388,15 @@ END if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { push(@implContentDecls, <<END); - OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, $numParameters)); + OwnPtr<ScriptArguments> scriptArguments(createScriptArguments(args, $numParameters)); + size_t maxStackSize = imp->shouldCaptureFullStackTrace() ? ScriptCallStack::maxCallStackSizeToCapture : 1; + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(maxStackSize)); if (!callStack) return v8::Undefined(); END + $implIncludes{"ScriptArguments.h"} = 1; $implIncludes{"ScriptCallStack.h"} = 1; + $implIncludes{"ScriptCallStackFactory.h"} = 1; } if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) { push(@implContentDecls, <<END); @@ -2673,9 +2704,7 @@ sub GetNativeTypeForConversions my $dataNode = shift; my $type = shift; - $type = "FloatPoint" if $type eq "SVGPoint"; $type = "AffineTransform" if $type eq "SVGMatrix"; - $type = "float" if $type eq "SVGNumber"; $type = "V8SVGPODTypeWrapper<$type>" if $dataNode->extendedAttributes->{"PODType"}; $type = $codeGenerator->GetSVGTypeNeedingTearOff($type) if $codeGenerator->IsSVGTypeNeedingTearOff($type); return $type; @@ -2788,8 +2817,8 @@ sub GenerateFunctionCallString() if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) { $functionString .= ", " if $index; - $functionString .= "callStack.get()"; - $index++; + $functionString .= "scriptArguments.release(), callStack.release()"; + $index += 2; } if ($function->signature->extendedAttributes->{"NeedsUserGestureCheck"}) { @@ -2944,7 +2973,6 @@ sub IsRefPtrType return 0 if $type eq "unsigned"; return 0 if $type eq "unsigned long"; return 0 if $type eq "unsigned short"; - return 0 if $type eq "SVGAnimatedPoints"; return 1; } @@ -2977,11 +3005,8 @@ sub GetNativeType return "bool" if $type eq "boolean"; return "String" if $type eq "DOMString"; return "Range::CompareHow" if $type eq "CompareHow"; - return "FloatPoint" if $type eq "SVGPoint"; return "AffineTransform" if $type eq "SVGMatrix"; return "SVGTransform" if $type eq "SVGTransform"; - return "float" if $type eq "SVGNumber"; - return "SVGPreserveAspectRatio" if $type eq "SVGPreserveAspectRatio"; return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType"; return "DOMTimeStamp" if $type eq "DOMTimeStamp"; return "unsigned" if $type eq "unsigned int"; @@ -3032,8 +3057,6 @@ sub BasicTypeCanFailConversion my $type = GetTypeFromSignature($signature); return 1 if $type eq "SVGMatrix"; - return 1 if $type eq "SVGPoint"; - return 1 if $type eq "SVGPreserveAspectRatio"; return 1 if $type eq "SVGTransform"; return 0; } @@ -3063,7 +3086,6 @@ sub JSValueToNative return "$value" if $type eq "JSObject"; return "$value->BooleanValue()" if $type eq "boolean"; return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $type eq "double"; - return "$value->NumberValue()" if $type eq "SVGNumber"; return "toInt32($value${maybeOkParam})" if $type eq "long"; return "toUInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short"; @@ -3097,10 +3119,6 @@ sub JSValueToNative $implIncludes{"FloatRect.h"} = 1; } - if ($type eq "SVGPoint") { - $implIncludes{"FloatPoint.h"} = 1; - } - # Default, assume autogenerated type conversion routines if ($type eq "EventTarget") { $implIncludes{"V8Node.h"} = 1; @@ -3492,7 +3510,6 @@ sub IsSVGListTypeNeedingSpecialHandling { my $className = shift; - return 1 if $className eq "SVGPointList"; return 1 if $className eq "SVGTransformList"; return 0; diff --git a/WebCore/bindings/scripts/test/JS/JSTestObj.cpp b/WebCore/bindings/scripts/test/JS/JSTestObj.cpp index 5236267..7e06068 100644 --- a/WebCore/bindings/scripts/test/JS/JSTestObj.cpp +++ b/WebCore/bindings/scripts/test/JS/JSTestObj.cpp @@ -31,7 +31,9 @@ #include "JSTestObj.h" #include "JSlog.h" #include "KURL.h" +#include "ScriptArguments.h" #include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" #include "SerializedScriptValue.h" #include "TestObj.h" #include <runtime/Error.h> @@ -994,12 +996,14 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionCustomArgsAndException(Ex JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue)); TestObj* imp = static_cast<TestObj*>(castedThis->impl()); ExceptionCode ec = 0; - ScriptCallStack callStack(exec, 1); + OwnPtr<ScriptArguments> scriptArguments(createScriptArguments(exec, 1)); + size_t maxStackSize = imp->shouldCaptureFullStackTrace() ? ScriptCallStack::maxCallStackSizeToCapture : 1; + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(exec, maxStackSize)); log* intArg = tolog(exec->argument(0)); if (exec->hadException()) return JSValue::encode(jsUndefined()); - imp->customArgsAndException(intArg, &callStack, ec); + imp->customArgsAndException(intArg, scriptArguments.release(), callStack.release(), ec); setDOMException(exec, ec); return JSValue::encode(jsUndefined()); } diff --git a/WebCore/bindings/scripts/test/V8/V8TestObj.cpp b/WebCore/bindings/scripts/test/V8/V8TestObj.cpp index 4be1177..4c921bb 100644 --- a/WebCore/bindings/scripts/test/V8/V8TestObj.cpp +++ b/WebCore/bindings/scripts/test/V8/V8TestObj.cpp @@ -26,7 +26,9 @@ #include "IDBBindingUtilities.h" #include "IDBKey.h" #include "RuntimeEnabledFeatures.h" +#include "ScriptArguments.h" #include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" #include "SerializedScriptValue.h" #include "V8Binding.h" #include "V8BindingMacros.h" @@ -715,11 +717,13 @@ static v8::Handle<v8::Value> customArgsAndExceptionCallback(const v8::Arguments& TestObj* imp = V8TestObj::toNative(args.Holder()); ExceptionCode ec = 0; { - OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, 1)); + OwnPtr<ScriptArguments> scriptArguments(createScriptArguments(args, 1)); + size_t maxStackSize = imp->shouldCaptureFullStackTrace() ? ScriptCallStack::maxCallStackSizeToCapture : 1; + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(maxStackSize)); if (!callStack) return v8::Undefined(); EXCEPTION_BLOCK(log*, intArg, V8log::HasInstance(args[0]) ? V8log::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0); - imp->customArgsAndException(intArg, callStack.get(), ec); + imp->customArgsAndException(intArg, scriptArguments.release(), callStack.release(), ec); if (UNLIKELY(ec)) goto fail; return v8::Handle<v8::Value>(); diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h deleted file mode 100644 index 98e5195..0000000 --- a/WebCore/bindings/v8/ScriptCallStack.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ScriptCallStack_h -#define ScriptCallStack_h - -#include "ScriptCallFrame.h" -#include "ScriptState.h" -#include "ScriptValue.h" -#include <wtf/Noncopyable.h> -#include <wtf/RefPtr.h> - -namespace v8 { - class Arguments; -} - -namespace WebCore { - -class InspectorArray; - -class ScriptCallStack : public Noncopyable { -public: - static const int maxCallStackSizeToCapture; - static const v8::StackTrace::StackTraceOptions stackTraceOptions; - - static PassOwnPtr<ScriptCallStack> create(const v8::Arguments&, unsigned skipArgumentCount = 0, int framCountLimit = 1); - static PassOwnPtr<ScriptCallStack> create(ScriptState*, v8::Handle<v8::StackTrace>); - ~ScriptCallStack(); - - // Returns false if there is no running JavaScript or if fetching the stack failed. - // Sets stackTrace to be an array of stack frame objects. - // A stack frame object looks like: - // { - // scriptName: <file name for the associated script resource> - // functionName: <name of the JavaScript function> - // lineNumber: <1 based line number> - // column: <1 based column offset on the line> - // } - static bool stackTrace(int frameLimit, const RefPtr<InspectorArray>& stackTrace); - - const ScriptCallFrame& at(unsigned); - unsigned size(); - - ScriptState* state() const { return m_scriptState; } - ScriptState* globalState() const { return m_scriptState; } - -private: - ScriptCallStack(ScriptState* scriptState, PassOwnPtr<ScriptCallFrame> topFrame, Vector<OwnPtr<ScriptCallFrame> >& scriptCallFrames); - ScriptCallStack(ScriptState* scriptState, v8::Handle<v8::StackTrace> stackTrace); - - OwnPtr<ScriptCallFrame> m_topFrame; - ScriptState* m_scriptState; - Vector<OwnPtr<ScriptCallFrame> > m_scriptCallFrames; -}; - -} // namespace WebCore - -#endif // ScriptCallStack_h diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStackFactory.cpp index 3e29c7a..62fbeef 100644 --- a/WebCore/bindings/v8/ScriptCallStack.cpp +++ b/WebCore/bindings/v8/ScriptCallStackFactory.cpp @@ -1,10 +1,10 @@ /* - * Copyright (C) 2008, 2009 Google Inc. All rights reserved. - * + * 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 @@ -29,131 +29,88 @@ */ #include "config.h" -#include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" #include "InspectorValues.h" -#include "ScriptController.h" -#include "ScriptDebugServer.h" +#include "ScriptArguments.h" +#include "ScriptCallFrame.h" +#include "ScriptCallStack.h" #include "ScriptScope.h" +#include "ScriptValue.h" #include "V8Binding.h" #include <v8-debug.h> namespace WebCore { -static void getFrameLocation(v8::Handle<v8::StackFrame> frame, String* sourceName, int* sourceLineNumber, String* functionName) +static ScriptCallFrame toScriptCallFrame(v8::Handle<v8::StackFrame> frame) { - ASSERT(!frame.IsEmpty()); + String sourceName; v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL()); - v8::Local<v8::String> functionNameValue(frame->GetFunctionName()); - *sourceName = sourceNameValue.IsEmpty() ? "" : toWebCoreString(sourceNameValue); - *functionName = functionNameValue.IsEmpty() ? "" : toWebCoreString(functionNameValue); - *sourceLineNumber = frame->GetLineNumber(); -} - -static void getTopFrameLocation(v8::Handle<v8::StackTrace> stackTrace, String* sourceName, int* sourceLineNumber, String* functionName) -{ - if (stackTrace->GetFrameCount() <= 0) { - // Successfully grabbed stack trace, but there are no frames. It may happen in case of a syntax error for example. - // Fallback to setting lineNumber to 0, and source and function name to "undefined". - *sourceName = "undefined"; - *sourceLineNumber = 0; - *functionName = "undefined"; - } else { - v8::Handle<v8::StackFrame> frame = stackTrace->GetFrame(0); - getFrameLocation(frame, sourceName, sourceLineNumber, functionName); - } -} + if (!sourceNameValue.IsEmpty()) + sourceName = toWebCoreString(sourceNameValue); -static PassOwnPtr<ScriptCallFrame> toScriptCallFrame(v8::Handle<v8::StackFrame> frame) -{ - String sourceName; - int sourceLineNumber; String functionName; - getFrameLocation(frame, &sourceName, &sourceLineNumber, &functionName); - return new ScriptCallFrame(functionName, sourceName, sourceLineNumber); + v8::Local<v8::String> functionNameValue(frame->GetFunctionName()); + if (!functionNameValue.IsEmpty()) + functionName = toWebCoreString(functionNameValue); + + int sourceLineNumber = frame->GetLineNumber(); + return ScriptCallFrame(functionName, sourceName, sourceLineNumber); } -static void toScriptCallFramesVector(v8::Local<v8::Context> context, v8::Handle<v8::StackTrace> stackTrace, Vector<OwnPtr<ScriptCallFrame> >& scriptCallFrames) +static void toScriptCallFramesVector(v8::Local<v8::Context> context, v8::Handle<v8::StackTrace> stackTrace, Vector<ScriptCallFrame>& scriptCallFrames, size_t maxStackSize) { + // TODO(yurys): remove this??? v8::Context::Scope contextScope(context); int frameCount = stackTrace->GetFrameCount(); + if (frameCount > static_cast<int>(maxStackSize)) + frameCount = maxStackSize; for (int i = 0; i < frameCount; i++) { v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i); scriptCallFrames.append(toScriptCallFrame(stackFrame)); } + + if (!frameCount) { + // Successfully grabbed stack trace, but there are no frames. It may happen in case of a syntax error for example. + // Fallback to setting lineNumber to 0, and source and function name to "undefined". + scriptCallFrames.append(ScriptCallFrame("undefined", "undefined", 0)); + } } -const int ScriptCallStack::maxCallStackSizeToCapture = 200; -const v8::StackTrace::StackTraceOptions ScriptCallStack::stackTraceOptions = static_cast<v8::StackTrace::StackTraceOptions>( - v8::StackTrace::kLineNumber - | v8::StackTrace::kColumnOffset - | v8::StackTrace::kScriptNameOrSourceURL - | v8::StackTrace::kFunctionName); - - -PassOwnPtr<ScriptCallStack> ScriptCallStack::create(const v8::Arguments& arguments, unsigned skipArgumentCount, int framCountLimit) +PassOwnPtr<ScriptCallStack> createScriptCallStack(v8::Local<v8::Context> context, v8::Handle<v8::StackTrace> stackTrace, size_t maxStackSize) { v8::HandleScope scope; - v8::Local<v8::Context> context = v8::Context::GetCurrent(); v8::Context::Scope contextScope(context); - v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(framCountLimit, ScriptCallStack::stackTraceOptions)); - - if (stackTrace.IsEmpty()) - return 0; - - String sourceName; - int sourceLineNumber; - String functionName; - getTopFrameLocation(stackTrace, &sourceName, &sourceLineNumber, &functionName); - - Vector<OwnPtr<ScriptCallFrame> > scriptCallFrames; - if (framCountLimit > 1) - toScriptCallFramesVector(context, stackTrace, scriptCallFrames); - return new ScriptCallStack(ScriptState::forContext(context), new ScriptCallFrame(functionName, sourceName, sourceLineNumber, arguments, skipArgumentCount), scriptCallFrames); + Vector<ScriptCallFrame> scriptCallFrames; + toScriptCallFramesVector(context, stackTrace, scriptCallFrames, maxStackSize); + return new ScriptCallStack(scriptCallFrames); } -PassOwnPtr<ScriptCallStack> ScriptCallStack::create(ScriptState* state, v8::Handle<v8::StackTrace> stackTrace) +PassOwnPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize) { v8::HandleScope scope; - Vector<OwnPtr<ScriptCallFrame> > scriptCallFrames; - toScriptCallFramesVector(state->context(), stackTrace, scriptCallFrames); - - String sourceName; - int sourceLineNumber; - String functionName; - getTopFrameLocation(stackTrace, &sourceName, &sourceLineNumber, &functionName); - - return new ScriptCallStack(state, new ScriptCallFrame(functionName, sourceName, sourceLineNumber), scriptCallFrames); -} - -ScriptCallStack::ScriptCallStack(ScriptState* scriptState, PassOwnPtr<ScriptCallFrame> topFrame, Vector<OwnPtr<ScriptCallFrame> >& scriptCallFrames) - : m_topFrame(topFrame) - , m_scriptState(scriptState) -{ - m_scriptCallFrames.swap(scriptCallFrames); + v8::Local<v8::Context> context = v8::Context::GetCurrent(); + // TODO(yurys): remove? + v8::Context::Scope contextScope(context); + v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(maxStackSize, stackTraceOptions)); + return createScriptCallStack(context, stackTrace, maxStackSize); } -ScriptCallStack::~ScriptCallStack() +PassOwnPtr<ScriptArguments> createScriptArguments(const v8::Arguments& v8arguments, unsigned skipArgumentCount) { -} + v8::HandleScope scope; + v8::Local<v8::Context> context = v8::Context::GetCurrent(); + ScriptState* state = ScriptState::forContext(context); -const ScriptCallFrame& ScriptCallStack::at(unsigned index) -{ - if (!index && m_topFrame) - return *m_topFrame; - return *m_scriptCallFrames.at(index); -} + Vector<ScriptValue> arguments; + for (int i = skipArgumentCount; i < v8arguments.Length(); ++i) + arguments.append(ScriptValue(v8arguments[i])); -unsigned ScriptCallStack::size() -{ - if (m_scriptCallFrames.isEmpty()) - return 1; - return m_scriptCallFrames.size(); + return new ScriptArguments(state, arguments); } - bool ScriptCallStack::stackTrace(int frameLimit, const RefPtr<InspectorArray>& stackTrace) { #if ENABLE(INSPECTOR) diff --git a/WebCore/bindings/v8/ScriptCallStackFactory.h b/WebCore/bindings/v8/ScriptCallStackFactory.h new file mode 100644 index 0000000..613af7b --- /dev/null +++ b/WebCore/bindings/v8/ScriptCallStackFactory.h @@ -0,0 +1,56 @@ +/* + * 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 ScriptCallStackFactory_h +#define ScriptCallStackFactory_h + +#include <v8.h> +#include <wtf/PassOwnPtr.h> + +namespace WebCore { + +class ScriptState; + +const v8::StackTrace::StackTraceOptions stackTraceOptions = static_cast<v8::StackTrace::StackTraceOptions>( + v8::StackTrace::kLineNumber + | v8::StackTrace::kColumnOffset + | v8::StackTrace::kScriptNameOrSourceURL + | v8::StackTrace::kFunctionName); + +class ScriptArguments; +class ScriptCallStack; + +PassOwnPtr<ScriptCallStack> createScriptCallStack(v8::Local<v8::Context>, v8::Handle<v8::StackTrace>, size_t maxStackSize); +PassOwnPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize); +PassOwnPtr<ScriptArguments> createScriptArguments(const v8::Arguments& v8arguments, unsigned skipArgumentCount); + +} // namespace WebCore + +#endif // ScriptCallStackFactory_h diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp index 913a892..648ae98 100644 --- a/WebCore/bindings/v8/ScriptController.cpp +++ b/WebCore/bindings/v8/ScriptController.cpp @@ -35,6 +35,7 @@ #include "PlatformBridge.h" #include "Document.h" #include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" #include "ScriptableDocumentParser.h" #include "DOMWindow.h" #include "Event.h" @@ -481,7 +482,7 @@ void ScriptController::clearWindowShell(bool) #if ENABLE(INSPECTOR) void ScriptController::setCaptureCallStackForUncaughtExceptions(bool value) { - v8::V8::SetCaptureStackTraceForUncaughtExceptions(value, ScriptCallStack::maxCallStackSizeToCapture, ScriptCallStack::stackTraceOptions); + v8::V8::SetCaptureStackTraceForUncaughtExceptions(value, ScriptCallStack::maxCallStackSizeToCapture, stackTraceOptions); } #endif diff --git a/WebCore/bindings/v8/ScriptState.h b/WebCore/bindings/v8/ScriptState.h index ce350da..11813b0 100644 --- a/WebCore/bindings/v8/ScriptState.h +++ b/WebCore/bindings/v8/ScriptState.h @@ -95,7 +95,7 @@ public: m_context.Clear(); } } - ScriptState* get() { return m_scriptState; } + ScriptState* get() const { return m_scriptState; } private: ScriptState* m_scriptState; v8::Persistent<v8::Context> m_context; diff --git a/WebCore/bindings/v8/V8ConsoleMessage.cpp b/WebCore/bindings/v8/V8ConsoleMessage.cpp index 8b6bb17..40f9a7a 100644 --- a/WebCore/bindings/v8/V8ConsoleMessage.cpp +++ b/WebCore/bindings/v8/V8ConsoleMessage.cpp @@ -37,6 +37,7 @@ #include "OwnPtr.h" #include "Page.h" #include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" #include "V8Binding.h" #include "V8Proxy.h" @@ -117,18 +118,17 @@ void V8ConsoleMessage::handler(v8::Handle<v8::Message> message, v8::Handle<v8::V // Currently stack trace is only collected when inspector is open. if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) { v8::Local<v8::Context> context = v8::Context::GetEntered(); - ScriptState* scriptState = ScriptState::forContext(context); - callStack = ScriptCallStack::create(scriptState, stackTrace); + callStack = createScriptCallStack(context, stackTrace, ScriptCallStack::maxCallStackSizeToCapture); } v8::Handle<v8::Value> resourceName = message->GetScriptResourceName(); bool useURL = resourceName.IsEmpty() || !resourceName->IsString(); String resourceNameString = useURL ? frame->document()->url() : toWebCoreString(resourceName); V8ConsoleMessage consoleMessage(errorMessage, resourceNameString, message->GetLineNumber()); - consoleMessage.dispatchNow(page, callStack.get()); + consoleMessage.dispatchNow(page, callStack.release()); } -void V8ConsoleMessage::dispatchNow(Page* page, ScriptCallStack* callStack) +void V8ConsoleMessage::dispatchNow(Page* page, PassOwnPtr<ScriptCallStack> callStack) { ASSERT(page); diff --git a/WebCore/bindings/v8/V8ConsoleMessage.h b/WebCore/bindings/v8/V8ConsoleMessage.h index 387b5ee..6b892dd 100644 --- a/WebCore/bindings/v8/V8ConsoleMessage.h +++ b/WebCore/bindings/v8/V8ConsoleMessage.h @@ -33,6 +33,7 @@ #include "PlatformString.h" #include <v8.h> +#include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> namespace WebCore { @@ -81,7 +82,7 @@ namespace WebCore { const String m_sourceID; const unsigned m_lineNumber; - void dispatchNow(Page*, ScriptCallStack*); + void dispatchNow(Page*, PassOwnPtr<ScriptCallStack>); // All delayed messages are stored in this vector. If the vector // is 0, there are no delayed messages. diff --git a/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h b/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h index ffea07c..2566b67 100644 --- a/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h +++ b/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h @@ -94,6 +94,8 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args, WrapperType if (!ok) return throwError("Could not convert argument 1 to a number"); } + if ((buf->byteLength() - offset) % sizeof(ElementType)) + return throwError("ArrayBuffer length minus the byteOffset is not a multiple of the element size.", V8Proxy::RangeError); uint32_t length = (buf->byteLength() - offset) / sizeof(ElementType); if (argLen > 2) { length = toUInt32(args[2], ok); diff --git a/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp index fc83b61..b17b8e9 100644 --- a/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp +++ b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp @@ -33,9 +33,12 @@ #include "V8Console.h" #include "Console.h" +#include "ScriptArguments.h" #include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" #include "ScriptProfile.h" #include "V8Binding.h" +#include "V8BindingMacros.h" #include "V8Proxy.h" #include "V8ScriptProfile.h" @@ -62,11 +65,9 @@ v8::Handle<v8::Value> V8Console::traceCallback(const v8::Arguments& args) { INC_STATS("DOM.Console.traceCallback"); Console* imp = V8Console::toNative(args.Holder()); - v8::HandleScope handleScope; - ScriptState* scriptState = ScriptState::current(); - v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(ScriptCallStack::maxCallStackSizeToCapture, ScriptCallStack::stackTraceOptions); - OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(scriptState, stackTrace)); - imp->trace(callStack.get()); + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture)); + OwnPtr<ScriptArguments> scriptArguments(createScriptArguments(args, 0)); + imp->trace(scriptArguments.release(), callStack.release()); return v8::Handle<v8::Value>(); } @@ -74,9 +75,34 @@ v8::Handle<v8::Value> V8Console::assertCallback(const v8::Arguments& args) { INC_STATS("DOM.Console.assertCallback"); Console* imp = V8Console::toNative(args.Holder()); - OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(args, 1, ScriptCallStack::maxCallStackSizeToCapture)); + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture)); bool condition = args[0]->BooleanValue(); - imp->assertCondition(condition, callStack.get()); + OwnPtr<ScriptArguments> scriptArguments(createScriptArguments(args, 1)); + imp->assertCondition(condition, scriptArguments.release(), callStack.release()); + return v8::Handle<v8::Value>(); +} + +v8::Handle<v8::Value> V8Console::profileCallback(const v8::Arguments& args) +{ + INC_STATS("DOM.Console.profile"); + Console* imp = V8Console::toNative(args.Holder()); + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(1)); + if (!callStack) + return v8::Undefined(); + STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, title, args[0]); + imp->profile(title, ScriptState::current(), callStack.release()); + return v8::Handle<v8::Value>(); +} + +v8::Handle<v8::Value> V8Console::profileEndCallback(const v8::Arguments& args) +{ + INC_STATS("DOM.Console.profileEnd"); + Console* imp = V8Console::toNative(args.Holder()); + OwnPtr<ScriptCallStack> callStack(createScriptCallStack(1)); + if (!callStack) + return v8::Undefined(); + STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<WithUndefinedOrNullCheck>, title, args[0]); + imp->profileEnd(title, ScriptState::current(), callStack.release()); return v8::Handle<v8::Value>(); } diff --git a/WebCore/bindings/v8/custom/V8DOMSettableTokenListCustom.cpp b/WebCore/bindings/v8/custom/V8DOMSettableTokenListCustom.cpp index 4eeb1e0..e1c9be4 100644 --- a/WebCore/bindings/v8/custom/V8DOMSettableTokenListCustom.cpp +++ b/WebCore/bindings/v8/custom/V8DOMSettableTokenListCustom.cpp @@ -34,8 +34,9 @@ namespace WebCore { v8::Handle<v8::Value> V8DOMSettableTokenList::indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) { - // FIXME: Implement this function. - return v8String(""); + INC_STATS("DOM.DOMSettableTokenList.IndexedPropertyGetter"); + DOMSettableTokenList* list = V8DOMSettableTokenList::toNative(info.Holder()); + return v8StringOrNull(list->item(index)); } } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptCallFrame.cpp b/WebCore/bindings/v8/custom/V8HTMLOutputElementCustom.cpp index 2f74b96..ad86dd2 100644 --- a/WebCore/bindings/js/ScriptCallFrame.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLOutputElementCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Google Inc. All rights reserved. + * 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 @@ -29,35 +29,27 @@ */ #include "config.h" -#include "ScriptCallFrame.h" +#include "V8HTMLOutputElement.h" -#include <runtime/ArgList.h> -#include <runtime/UString.h> - -using namespace JSC; +#include "HTMLOutputElement.h" +#include "V8Binding.h" +#include "V8DOMSettableTokenList.h" +#include "V8Proxy.h" namespace WebCore { -ScriptCallFrame::ScriptCallFrame(const UString& functionName, const UString& urlString, int lineNumber, ExecState* exec, unsigned skipArgumentCount) - : m_functionName(ustringToString(functionName)) - , m_sourceURL(ustringToString(urlString)) - , m_lineNumber(lineNumber) -{ - if (!exec) - return; - size_t argumentCount = exec->argumentCount(); - for (size_t i = skipArgumentCount; i < argumentCount; ++i) - m_arguments.append(ScriptValue(exec->argument(i))); -} - -ScriptCallFrame::~ScriptCallFrame() +v8::Handle<v8::Value> V8HTMLOutputElement::htmlForAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { + INC_STATS("DOM.HTMLOutputElement.htmlFor._get"); + HTMLOutputElement* imp = V8HTMLOutputElement::toNative(info.Holder()); + return toV8(imp->htmlFor()); } -const ScriptValue &ScriptCallFrame::argumentAt(unsigned index) const +void V8HTMLOutputElement::htmlForAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { - ASSERT(m_arguments.size() > index); - return m_arguments[index]; + INC_STATS("DOM.HTMLOutputElement.htmlFor._set"); + HTMLOutputElement* imp = V8HTMLOutputElement::toNative(info.Holder()); + imp->setFor(toWebCoreString(value)); } } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp b/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp index 3582a36..ec6324d 100644 --- a/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp +++ b/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp @@ -35,25 +35,58 @@ #include "SVGPropertyTearOff.h" #include "V8Binding.h" +#include "V8BindingMacros.h" namespace WebCore { v8::Handle<v8::Value> V8SVGLength::valueAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { - INC_STATS("DOM.SVGLength.value"); + INC_STATS("DOM.SVGLength.value._get"); SVGPropertyTearOff<SVGLength>* wrapper = V8SVGLength::toNative(info.Holder()); SVGLength& imp = wrapper->propertyReference(); - return v8::Number::New(imp.value(wrapper->contextElement())); + ExceptionCode ec = 0; + float value = imp.value(wrapper->contextElement(), ec); + if (UNLIKELY(ec)) { + V8Proxy::setDOMException(ec); + return v8::Handle<v8::Value>(); + } + return v8::Number::New(value); +} + +void V8SVGLength::valueAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) +{ + INC_STATS("DOM.SVGLength.value._set"); + if (!isUndefinedOrNull(value) && !value->IsNumber() && !value->IsBoolean()) { + V8Proxy::throwTypeError(); + return; + } + + SVGPropertyTearOff<SVGLength>* wrapper = V8SVGLength::toNative(info.Holder()); + SVGLength& imp = wrapper->propertyReference(); + ExceptionCode ec = 0; + imp.setValue(static_cast<float>(value->NumberValue()), wrapper->contextElement(), ec); + if (UNLIKELY(ec)) + V8Proxy::setDOMException(ec); + else + wrapper->commitChange(); } v8::Handle<v8::Value> V8SVGLength::convertToSpecifiedUnitsCallback(const v8::Arguments& args) { INC_STATS("DOM.SVGLength.convertToSpecifiedUnits"); + if (args.Length() < 1) + return throwError("Not enough arguments", V8Proxy::SyntaxError); + SVGPropertyTearOff<SVGLength>* wrapper = V8SVGLength::toNative(args.Holder()); SVGLength& imp = wrapper->propertyReference(); - imp.convertToSpecifiedUnits(toInt32(args[0]), wrapper->contextElement()); - wrapper->commitChange(); - return v8::Undefined(); + ExceptionCode ec = 0; + EXCEPTION_BLOCK(int, unitType, toUInt32(args[0])); + imp.convertToSpecifiedUnits(unitType, wrapper->contextElement(), ec); + if (UNLIKELY(ec)) + V8Proxy::setDOMException(ec); + else + wrapper->commitChange(); + return v8::Handle<v8::Value>(); } } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp index 9346a05..b2240ed 100644 --- a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp @@ -236,10 +236,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getAttachedShadersCallback(const bool succeed = context->getAttachedShaders(program, shaders, ec); if (ec) { V8Proxy::setDOMException(ec); - return v8::Undefined(); + return v8::Null(); } if (!succeed) - return v8::Undefined(); + return v8::Null(); v8::Local<v8::Array> array = v8::Array::New(shaders.size()); for (size_t ii = 0; ii < shaders.size(); ++ii) array->Set(v8::Integer::New(ii), toV8(shaders[ii])); diff --git a/WebCore/bridge/jsc/BridgeJSC.cpp b/WebCore/bridge/jsc/BridgeJSC.cpp index 9b3af25..49ffb2a 100644 --- a/WebCore/bridge/jsc/BridgeJSC.cpp +++ b/WebCore/bridge/jsc/BridgeJSC.cpp @@ -51,7 +51,6 @@ Array::~Array() Instance::Instance(PassRefPtr<RootObject> rootObject) : m_rootObject(rootObject) - , m_runtimeObject(0) { ASSERT(m_rootObject); } @@ -59,6 +58,7 @@ Instance::Instance(PassRefPtr<RootObject> rootObject) Instance::~Instance() { ASSERT(!m_runtimeObject); + ASSERT(!m_runtimeObject.hasDeadObject()); } static KJSDidExecuteFunctionPtr s_didExecuteFunction; @@ -87,12 +87,14 @@ JSObject* Instance::createRuntimeObject(ExecState* exec) { ASSERT(m_rootObject); ASSERT(m_rootObject->isValid()); - if (m_runtimeObject) - return m_runtimeObject; + if (RuntimeObject* existingObject = m_runtimeObject.get()) + return existingObject; + JSLock lock(SilenceAssertionsOnly); - m_runtimeObject = newRuntimeObject(exec); - m_rootObject->addRuntimeObject(m_runtimeObject); - return m_runtimeObject; + RuntimeObject* newObject = newRuntimeObject(exec); + m_runtimeObject = newObject; + m_rootObject->addRuntimeObject(newObject); + return newObject; } RuntimeObject* Instance::newRuntimeObject(ExecState* exec) @@ -101,19 +103,18 @@ RuntimeObject* Instance::newRuntimeObject(ExecState* exec) return new (exec)RuntimeObject(exec, exec->lexicalGlobalObject(), this); } -void Instance::willDestroyRuntimeObject() +void Instance::willDestroyRuntimeObject(RuntimeObject* object) { ASSERT(m_rootObject); ASSERT(m_rootObject->isValid()); - ASSERT(m_runtimeObject); - m_rootObject->removeRuntimeObject(m_runtimeObject); - m_runtimeObject = 0; + m_rootObject->removeRuntimeObject(object); + m_runtimeObject.clear(object); } -void Instance::willInvalidateRuntimeObject() +void Instance::willInvalidateRuntimeObject(RuntimeObject* object) { - ASSERT(m_runtimeObject); - m_runtimeObject = 0; + ASSERT(object); + m_runtimeObject.clear(object); } RootObject* Instance::rootObject() const diff --git a/WebCore/bridge/jsc/BridgeJSC.h b/WebCore/bridge/jsc/BridgeJSC.h index 9cc9140..96974d9 100644 --- a/WebCore/bridge/jsc/BridgeJSC.h +++ b/WebCore/bridge/jsc/BridgeJSC.h @@ -85,8 +85,8 @@ public: virtual Class* getClass() const = 0; JSObject* createRuntimeObject(ExecState*); - void willInvalidateRuntimeObject(); - void willDestroyRuntimeObject(); + void willInvalidateRuntimeObject(RuntimeObject*); + void willDestroyRuntimeObject(RuntimeObject*); // Returns false if the value was not set successfully. virtual bool setValueOfUndefinedField(ExecState*, const Identifier&, JSValue) { return false; } @@ -122,7 +122,7 @@ protected: RefPtr<RootObject> m_rootObject; private: - RuntimeObject* m_runtimeObject; + WeakGCPtr<RuntimeObject> m_runtimeObject; }; class Array : public Noncopyable { diff --git a/WebCore/bridge/qt/qt_runtime.cpp b/WebCore/bridge/qt/qt_runtime.cpp index 96851fa..6595b84 100644 --- a/WebCore/bridge/qt/qt_runtime.cpp +++ b/WebCore/bridge/qt/qt_runtime.cpp @@ -28,6 +28,7 @@ #include "Interpreter.h" #include "JSArray.h" #include "JSByteArray.h" +#include "JSDocument.h" #include "JSDOMBinding.h" #include "JSDOMWindow.h" #include <JSFunction.h> @@ -747,6 +748,8 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type } else if (hint == (QMetaType::Type) qMetaTypeId<QWebElement>()) { if (object && object->inherits(&JSHTMLElement::s_info)) ret = QVariant::fromValue<QWebElement>(QtWebElementRuntime::create((static_cast<JSHTMLElement*>(object))->impl())); + else if (object && object->inherits(&JSDocument::s_info)) + ret = QVariant::fromValue<QWebElement>(QtWebElementRuntime::create((static_cast<JSDocument*>(object))->impl()->documentElement())); else ret = QVariant::fromValue<QWebElement>(QWebElement()); } else if (hint == (QMetaType::Type) qMetaTypeId<QVariant>()) { diff --git a/WebCore/bridge/runtime_object.cpp b/WebCore/bridge/runtime_object.cpp index 9c5d7b6..368f7b0 100644 --- a/WebCore/bridge/runtime_object.cpp +++ b/WebCore/bridge/runtime_object.cpp @@ -55,14 +55,14 @@ RuntimeObject::RuntimeObject(ExecState*, JSGlobalObject* globalObject, NonNullPa RuntimeObject::~RuntimeObject() { if (m_instance) - m_instance->willDestroyRuntimeObject(); + m_instance->willDestroyRuntimeObject(this); } void RuntimeObject::invalidate() { ASSERT(m_instance); if (m_instance) - m_instance->willInvalidateRuntimeObject(); + m_instance->willInvalidateRuntimeObject(this); m_instance = 0; } diff --git a/WebCore/bridge/runtime_root.cpp b/WebCore/bridge/runtime_root.cpp index 09fd43b..796354f 100644 --- a/WebCore/bridge/runtime_root.cpp +++ b/WebCore/bridge/runtime_root.cpp @@ -168,6 +168,11 @@ JSGlobalObject* RootObject::globalObject() const return m_globalObject; } +void RootObject::updateGlobalObject(JSGlobalObject* globalObject) +{ + m_globalObject = globalObject; +} + void RootObject::addRuntimeObject(RuntimeObject* object) { ASSERT(m_isValid); diff --git a/WebCore/bridge/runtime_root.h b/WebCore/bridge/runtime_root.h index 04f382a..babd7ad 100644 --- a/WebCore/bridge/runtime_root.h +++ b/WebCore/bridge/runtime_root.h @@ -69,6 +69,7 @@ public: const void* nativeHandle() const; JSGlobalObject* globalObject() const; + void updateGlobalObject(JSGlobalObject*); void addRuntimeObject(RuntimeObject*); void removeRuntimeObject(RuntimeObject*); diff --git a/WebCore/css/CSSComputedStyleDeclaration.cpp b/WebCore/css/CSSComputedStyleDeclaration.cpp index 3f6aa4a..35a0b4a 100644 --- a/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -80,6 +80,7 @@ static const int computedProperties[] = { CSSPropertyBorderTopStyle, CSSPropertyBorderTopWidth, CSSPropertyBottom, + CSSPropertyBoxSizing, CSSPropertyCaptionSide, CSSPropertyClear, CSSPropertyClip, @@ -177,7 +178,6 @@ static const int computedProperties[] = { CSSPropertyWebkitBoxPack, CSSPropertyWebkitBoxReflect, CSSPropertyWebkitBoxShadow, - CSSPropertyWebkitBoxSizing, CSSPropertyWebkitColorCorrection, CSSPropertyWebkitColumnBreakAfter, CSSPropertyWebkitColumnBreakBefore, @@ -215,6 +215,7 @@ static const int computedProperties[] = { CSSPropertyWebkitPerspective, CSSPropertyWebkitPerspectiveOrigin, CSSPropertyWebkitRtlOrdering, + CSSPropertyWebkitTextCombine, CSSPropertyWebkitTextDecorationsInEffect, CSSPropertyWebkitTextFillColor, CSSPropertyWebkitTextSecurity, @@ -720,6 +721,20 @@ static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepea return list.release(); } +static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize) +{ + if (fillSize.type == Contain) + return CSSPrimitiveValue::createIdentifier(CSSValueContain); + + if (fillSize.type == Cover) + return CSSPrimitiveValue::createIdentifier(CSSValueCover); + + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(CSSPrimitiveValue::create(fillSize.size.width())); + list->append(CSSPrimitiveValue::create(fillSize.size.height())); + return list.release(); +} + static void logUnimplementedPropertyID(int propertyID) { DEFINE_STATIC_LOCAL(HashSet<int>, propertyIDSet, ()); @@ -766,47 +781,141 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyBackgroundColor: return CSSPrimitiveValue::createColor(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb()); case CSSPropertyBackgroundImage: - // FIXME: Broken for multiple backgrounds. https://bugs.webkit.org/show_bug.cgi?id=44853 - if (style->backgroundImage()) - return style->backgroundImage()->cssValue(); - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + case CSSPropertyWebkitMaskImage: { + const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers(); + if (!layers) + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + + if (!layers->next()) { + if (layers->image()) + return layers->image()->cssValue(); + + return CSSPrimitiveValue::createIdentifier(CSSValueNone); + } + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { + if (currLayer->image()) + list->append(currLayer->image()->cssValue()); + else + list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone)); + } + return list.release(); + } case CSSPropertyBackgroundSize: - case CSSPropertyWebkitBackgroundSize: { - EFillSizeType size = style->backgroundSizeType(); - if (size == Contain) - return CSSPrimitiveValue::createIdentifier(CSSValueContain); - if (size == Cover) - return CSSPrimitiveValue::createIdentifier(CSSValueCover); - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(CSSPrimitiveValue::create(style->backgroundSizeLength().width())); - list->append(CSSPrimitiveValue::create(style->backgroundSizeLength().height())); + case CSSPropertyWebkitBackgroundSize: + case CSSPropertyWebkitMaskSize: { + const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers(); + if (!layers->next()) + return fillSizeToCSSValue(layers->size()); + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) + list->append(fillSizeToCSSValue(currLayer->size())); + return list.release(); - } + } case CSSPropertyBackgroundRepeat: - return fillRepeatToCSSValue(style->backgroundRepeatX(), style->backgroundRepeatY()); + case CSSPropertyWebkitMaskRepeat: { + const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers(); + if (!layers->next()) + return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY()); + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) + list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY())); + + return list.release(); + } case CSSPropertyWebkitBackgroundComposite: - return CSSPrimitiveValue::create(style->backgroundComposite()); + case CSSPropertyWebkitMaskComposite: { + const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers(); + if (!layers->next()) + return CSSPrimitiveValue::create(layers->composite()); + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) + list->append(CSSPrimitiveValue::create(currLayer->composite())); + + return list.release(); + } case CSSPropertyBackgroundAttachment: - return CSSPrimitiveValue::create(style->backgroundAttachment()); + case CSSPropertyWebkitMaskAttachment: { + const FillLayer* layers = propertyID == CSSPropertyWebkitMaskAttachment ? style->maskLayers() : style->backgroundLayers(); + if (!layers->next()) + return CSSPrimitiveValue::create(layers->attachment()); + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) + list->append(CSSPrimitiveValue::create(currLayer->attachment())); + + return list.release(); + } case CSSPropertyBackgroundClip: case CSSPropertyBackgroundOrigin: case CSSPropertyWebkitBackgroundClip: - case CSSPropertyWebkitBackgroundOrigin: { - EFillBox box = (propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyBackgroundClip) ? style->backgroundClip() : style->backgroundOrigin(); - return CSSPrimitiveValue::create(box); + case CSSPropertyWebkitBackgroundOrigin: + case CSSPropertyWebkitMaskClip: + case CSSPropertyWebkitMaskOrigin: { + const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers(); + bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip; + if (!layers->next()) { + EFillBox box = isClip ? layers->clip() : layers->origin(); + return CSSPrimitiveValue::create(box); + } + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { + EFillBox box = isClip ? currLayer->clip() : currLayer->origin(); + list->append(CSSPrimitiveValue::create(box)); + } + + return list.release(); } - case CSSPropertyBackgroundPosition: { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + case CSSPropertyBackgroundPosition: + case CSSPropertyWebkitMaskPosition: { + const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers(); + if (!layers->next()) { + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(CSSPrimitiveValue::create(layers->xPosition())); + list->append(CSSPrimitiveValue::create(layers->yPosition())); + return list.release(); + } - list->append(CSSPrimitiveValue::create(style->backgroundXPosition())); - list->append(CSSPrimitiveValue::create(style->backgroundYPosition())); + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { + RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated(); + positionList->append(CSSPrimitiveValue::create(currLayer->xPosition())); + positionList->append(CSSPrimitiveValue::create(currLayer->yPosition())); + list->append(positionList); + } return list.release(); } case CSSPropertyBackgroundPositionX: - return CSSPrimitiveValue::create(style->backgroundXPosition()); + case CSSPropertyWebkitMaskPositionX: { + const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers(); + if (!layers->next()) + return CSSPrimitiveValue::create(layers->xPosition()); + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) + list->append(CSSPrimitiveValue::create(currLayer->xPosition())); + + return list.release(); + } case CSSPropertyBackgroundPositionY: - return CSSPrimitiveValue::create(style->backgroundYPosition()); + case CSSPropertyWebkitMaskPositionY: { + const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers(); + if (!layers->next()) + return CSSPrimitiveValue::create(layers->yPosition()); + + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) + list->append(CSSPrimitiveValue::create(currLayer->yPosition())); + + return list.release(); + } case CSSPropertyBorderCollapse: if (style->borderCollapse()) return CSSPrimitiveValue::createIdentifier(CSSValueCollapse); @@ -1059,44 +1168,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper return CSSPrimitiveValue::create(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitMarqueeStyle: return CSSPrimitiveValue::create(style->marqueeBehavior()); - case CSSPropertyWebkitMaskImage: - if (style->maskImage()) - return style->maskImage()->cssValue(); - return CSSPrimitiveValue::createIdentifier(CSSValueNone); - case CSSPropertyWebkitMaskSize: { - EFillSizeType size = style->maskSizeType(); - if (size == Contain) - return CSSPrimitiveValue::createIdentifier(CSSValueContain); - if (size == Cover) - return CSSPrimitiveValue::createIdentifier(CSSValueCover); - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(CSSPrimitiveValue::create(style->maskSizeLength().width())); - list->append(CSSPrimitiveValue::create(style->maskSizeLength().height())); - return list.release(); - } - case CSSPropertyWebkitMaskRepeat: - return fillRepeatToCSSValue(style->maskRepeatX(), style->maskRepeatY()); - case CSSPropertyWebkitMaskAttachment: - return CSSPrimitiveValue::create(style->maskAttachment()); - case CSSPropertyWebkitMaskComposite: - return CSSPrimitiveValue::create(style->maskComposite()); - case CSSPropertyWebkitMaskClip: - case CSSPropertyWebkitMaskOrigin: { - EFillBox box = (propertyID == CSSPropertyWebkitMaskClip ? style->maskClip() : style->maskOrigin()); - return CSSPrimitiveValue::create(box); - } - case CSSPropertyWebkitMaskPosition: { - RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - - list->append(CSSPrimitiveValue::create(style->maskXPosition())); - list->append(CSSPrimitiveValue::create(style->maskYPosition())); - - return list.release(); - } - case CSSPropertyWebkitMaskPositionX: - return CSSPrimitiveValue::create(style->maskXPosition()); - case CSSPropertyWebkitMaskPositionY: - return CSSPrimitiveValue::create(style->maskYPosition()); case CSSPropertyWebkitUserModify: return CSSPrimitiveValue::create(style->userModify()); case CSSPropertyMaxHeight: { @@ -1284,7 +1355,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper return CSSPrimitiveValue::create(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyZoom: return CSSPrimitiveValue::create(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); - case CSSPropertyWebkitBoxSizing: + case CSSPropertyBoxSizing: if (style->boxSizing() == CONTENT_BOX) return CSSPrimitiveValue::createIdentifier(CSSValueContentBox); return CSSPrimitiveValue::createIdentifier(CSSValueBorderBox); @@ -1381,9 +1452,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); if (t) { - for (size_t i = 0; i < t->size(); ++i) { + for (size_t i = 0; i < t->size(); ++i) list->append(CSSPrimitiveValue::create(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING)); - } } else list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone)); return list.release(); @@ -1518,6 +1588,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper return CSSPrimitiveValue::create(style->colorSpace()); case CSSPropertyWebkitWritingMode: return CSSPrimitiveValue::create(style->writingMode()); + case CSSPropertyWebkitTextCombine: + return CSSPrimitiveValue::create(style->textCombine()); /* Shorthand properties, currently not supported see bug 13658*/ case CSSPropertyBackground: diff --git a/WebCore/css/CSSCursorImageValue.cpp b/WebCore/css/CSSCursorImageValue.cpp index 2b09ab3..b0dda58 100644 --- a/WebCore/css/CSSCursorImageValue.cpp +++ b/WebCore/css/CSSCursorImageValue.cpp @@ -116,8 +116,8 @@ StyleCachedImage* CSSCursorImageValue::cachedImage(CachedResourceLoader* loader) String url = getStringValue(); #if ENABLE(SVG) - if (isSVGCursorIdentifier(url) && loader && loader->doc()) { - if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, loader->doc())) + if (isSVGCursorIdentifier(url) && loader && loader->document()) { + if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, loader->document())) url = cursorElement->href(); } #endif diff --git a/WebCore/css/CSSImageValue.cpp b/WebCore/css/CSSImageValue.cpp index e657fcc..f09a35f 100644 --- a/WebCore/css/CSSImageValue.cpp +++ b/WebCore/css/CSSImageValue.cpp @@ -22,7 +22,7 @@ #include "CSSImageValue.h" #include "CSSValueKeywords.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedImage.h" #include "CachedResourceLoader.h" #include "StyleCachedImage.h" diff --git a/WebCore/css/CSSMediaRule.cpp b/WebCore/css/CSSMediaRule.cpp index d1c220b..6348762 100644 --- a/WebCore/css/CSSMediaRule.cpp +++ b/WebCore/css/CSSMediaRule.cpp @@ -33,6 +33,9 @@ CSSMediaRule::CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList> media, P , m_lstMedia(media) , m_lstCSSRules(rules) { + int length = m_lstCSSRules->length(); + for (int i = 0; i < length; i++) + m_lstCSSRules->item(i)->setParent(this); } CSSMediaRule::~CSSMediaRule() diff --git a/WebCore/css/CSSMutableStyleDeclaration.cpp b/WebCore/css/CSSMutableStyleDeclaration.cpp index 708e2eb..38aee50 100644 --- a/WebCore/css/CSSMutableStyleDeclaration.cpp +++ b/WebCore/css/CSSMutableStyleDeclaration.cpp @@ -350,7 +350,9 @@ String CSSMutableStyleDeclaration::getLayeredShorthandValue(const int* propertie // then it was written with only one value. Here we figure out which value that was so we can // report back correctly. if (properties[j] == CSSPropertyBackgroundRepeatX && isPropertyImplicit(properties[j])) { - if (j < number - 1 && properties[j + 1] == CSSPropertyBackgroundRepeatY) { + + // BUG 49055: make sure the value was not reset in the layer check just above. + if (j < number - 1 && properties[j + 1] == CSSPropertyBackgroundRepeatY && value) { RefPtr<CSSValue> yValue; RefPtr<CSSValue> nextValue = values[j + 1]; if (nextValue->isValueList()) diff --git a/WebCore/css/CSSParser.cpp b/WebCore/css/CSSParser.cpp index e75e017..f98036f 100644 --- a/WebCore/css/CSSParser.cpp +++ b/WebCore/css/CSSParser.cpp @@ -1330,7 +1330,7 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitBoxOrdinalGroup: validPrimitive = validUnit(value, FInteger | FNonNeg, true); break; - case CSSPropertyWebkitBoxSizing: + case CSSPropertyBoxSizing: validPrimitive = id == CSSValueBorderBox || id == CSSValueContentBox; break; case CSSPropertyWebkitColorCorrection: @@ -1840,6 +1840,7 @@ bool CSSParser::parseValue(int propId, bool important) validPrimitive = true; break; +<<<<<<< HEAD #ifdef ANDROID_CSS_RING case CSSPropertyWebkitRing: { @@ -1877,6 +1878,12 @@ bool CSSParser::parseValue(int propId, bool important) m_valueList->next(); break; #endif +======= + case CSSPropertyWebkitTextCombine: + if (id == CSSValueNone || id == CSSValueCluster || id == CSSValueUpright) + validPrimitive = true; + break; +>>>>>>> webkit.org at r71558 #if ENABLE(SVG) default: @@ -5928,7 +5935,12 @@ static int cssPropertyID(const UChar* propertyName, unsigned length) } if (hasPrefix(buffer, length, "-webkit")) { - if (strcmp(buffer, "-webkit-opacity") == 0) { + if (!strcmp(buffer, "-webkit-box-sizing")) { + // -webkit-box-sizing worked in Safari 4 and earlier. + const char* const boxSizing = "box-sizing"; + name = boxSizing; + length = strlen(boxSizing); + } else if (!strcmp(buffer, "-webkit-opacity")) { // Honor -webkit-opacity as a synonym for opacity. // This was the only syntax that worked in Safari 1.1, and may be in use on some websites and widgets. const char* const opacity = "opacity"; diff --git a/WebCore/css/CSSPrimitiveValueMappings.h b/WebCore/css/CSSPrimitiveValueMappings.h index a57a882..c055875 100644 --- a/WebCore/css/CSSPrimitiveValueMappings.h +++ b/WebCore/css/CSSPrimitiveValueMappings.h @@ -2040,6 +2040,38 @@ template<> inline CSSPrimitiveValue::operator WritingMode() const } } +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextCombine e) + : m_type(CSS_IDENT) + , m_hasCachedCSSText(false) +{ + switch (e) { + case TextCombineNone: + m_value.ident = CSSValueNone; + break; + case TextCombineCluster: + m_value.ident = CSSValueCluster; + break; + case TextCombineUpright: + m_value.ident = CSSValueUpright; + break; + } +} + +template<> inline CSSPrimitiveValue::operator TextCombine() const +{ + switch (m_value.ident) { + case CSSValueNone: + return TextCombineNone; + case CSSValueCluster: + return TextCombineCluster; + case CSSValueUpright: + return TextCombineUpright; + default: + ASSERT_NOT_REACHED(); + return TextCombineNone; + } +} + template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EPointerEvents e) : m_type(CSS_IDENT) , m_hasCachedCSSText(false) diff --git a/WebCore/css/CSSPropertyNames.in b/WebCore/css/CSSPropertyNames.in index 9fd2d2c..ab75404 100644 --- a/WebCore/css/CSSPropertyNames.in +++ b/WebCore/css/CSSPropertyNames.in @@ -70,6 +70,7 @@ border-top-style border-top-width border-width bottom +box-sizing caption-side clear clip @@ -209,7 +210,6 @@ z-index -webkit-box-pack -webkit-box-reflect -webkit-box-shadow --webkit-box-sizing -webkit-color-correction -webkit-column-break-after -webkit-column-break-before @@ -276,6 +276,7 @@ z-index -webkit-perspective-origin-x -webkit-perspective-origin-y -webkit-rtl-ordering +-webkit-text-combine -webkit-text-decorations-in-effect -webkit-text-fill-color -webkit-text-security diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp index b0201a3..ec56916 100644 --- a/WebCore/css/CSSStyleSelector.cpp +++ b/WebCore/css/CSSStyleSelector.cpp @@ -1034,6 +1034,13 @@ bool CSSStyleSelector::canShareStyleWithElement(Node* n) if (style->transitions() || style->animations()) return false; +#if USE(ACCELERATED_COMPOSITING) + // Turn off style sharing for elements that can gain layers for reasons outside of the style system. + // See comments in RenderObject::setStyle(). + if (s->hasTagName(iframeTag) || s->hasTagName(embedTag) || s->hasTagName(objectTag) || s->hasTagName(appletTag)) + return false; +#endif + bool classesMatch = true; if (s->hasClass()) { const AtomicString& class1 = m_element->fastGetAttribute(classAttr); @@ -1753,15 +1760,18 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_CELL) && style->position() == RelativePosition) style->setPosition(StaticPosition); - - // FIXME: Since we don't support block-flow on either tables or flexible boxes yet, disallow setting + + // writing-mode does not apply to table row groups, table column groups, table rows, and table columns. + // FIXME: Table cells should be allowed to be perpendicular or flipped with respect to the table, though. + if (style->display() == TABLE_COLUMN || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_FOOTER_GROUP + || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_ROW_GROUP + || style->display() == TABLE_CELL) + style->setWritingMode(parentStyle->writingMode()); + + // FIXME: Since we don't support block-flow on flexible boxes yet, disallow setting // of block-flow to anything other than TopToBottomWritingMode. - // https://bugs.webkit.org/show_bug.cgi?id=46417 - Tables support // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support. - if (style->writingMode() != TopToBottomWritingMode && (style->display() == TABLE || style->display() == INLINE_TABLE - || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP - || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_CELL - || style->display() == BOX || style->display() == INLINE_BOX)) + if (style->writingMode() != TopToBottomWritingMode && (style->display() == BOX || style->display() == INLINE_BOX)) style->setWritingMode(TopToBottomWritingMode); } @@ -3093,7 +3103,8 @@ void CSSStyleSelector::applyPropertyToStyle(int id, CSSValue *value, RenderStyle initElement(0); initForStyleResolve(0, style); m_style = style; - applyProperty(id, value); + if (value) + applyProperty(id, value); } inline bool isValidVisitedLinkProperty(int id) @@ -4970,7 +4981,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; // Error case. m_style->setBoxOrdinalGroup((unsigned int)(primitiveValue->getDoubleValue())); return; - case CSSPropertyWebkitBoxSizing: + case CSSPropertyBoxSizing: HANDLE_INHERIT_AND_INITIAL(boxSizing, BoxSizing) if (!primitiveValue) return; @@ -5605,6 +5616,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; } +<<<<<<< HEAD #ifdef ANDROID_CSS_RING case CSSPropertyWebkitRing: if (valueType != CSSValue::CSS_INHERIT || !m_parentNode) return; @@ -5748,6 +5760,11 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; } #endif +======= + case CSSPropertyWebkitTextCombine: + HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textCombine, TextCombine) + return; +>>>>>>> webkit.org at r71558 #if ENABLE(SVG) default: diff --git a/WebCore/css/CSSValueKeywords.in b/WebCore/css/CSSValueKeywords.in index fa0a214..cd37519 100644 --- a/WebCore/css/CSSValueKeywords.in +++ b/WebCore/css/CSSValueKeywords.in @@ -764,3 +764,7 @@ horizontal-tb vertical-rl vertical-lr horizontal-bt + +# -webkit-text-combine +cluster +upright diff --git a/WebCore/css/html.css b/WebCore/css/html.css index 02fa620..a201adc 100644 --- a/WebCore/css/html.css +++ b/WebCore/css/html.css @@ -530,6 +530,10 @@ option { font-weight: normal; } +output { + display: inline; +} + /* meter */ meter { diff --git a/WebCore/css/quirks.css b/WebCore/css/quirks.css index 4477708..52d07e6 100644 --- a/WebCore/css/quirks.css +++ b/WebCore/css/quirks.css @@ -44,7 +44,7 @@ table { /* This will apply only to text fields, since all other inputs already use border box sizing */ input:not([type=image]), textarea { - -webkit-box-sizing: border-box; + box-sizing: border-box; } /* Set margin-bottom for form element in quirks mode. */ diff --git a/WebCore/css/view-source.css b/WebCore/css/view-source.css index 60467b9..afceef5 100644 --- a/WebCore/css/view-source.css +++ b/WebCore/css/view-source.css @@ -44,7 +44,7 @@ td { .webkit-line-gutter-backdrop, .webkit-line-number { /* Keep this in sync with inspector.css (.webkit-line-gutter-backdrop) */ - -webkit-box-sizing: border-box; + box-sizing: border-box; padding: 0 4px !important; width: 31px; background-color: rgb(240, 240, 240); diff --git a/WebCore/css/wml.css b/WebCore/css/wml.css index 54e5a97..4bcf08f 100644 --- a/WebCore/css/wml.css +++ b/WebCore/css/wml.css @@ -109,7 +109,7 @@ do { padding: 2px 6px 3px 6px; border: 2px outset ButtonFace; background-color: ButtonFace; - -webkit-box-sizing: border-box + box-sizing: border-box } input, select, do { @@ -163,7 +163,7 @@ do:active:disabled { select { -webkit-appearance: menulist; - -webkit-box-sizing: border-box; + box-sizing: border-box; -webkit-box-align: center; border: 1px solid; -webkit-border-radius: 5px; diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp index fc33519..79d233a 100644 --- a/WebCore/dom/ContainerNode.cpp +++ b/WebCore/dom/ContainerNode.cpp @@ -24,7 +24,7 @@ #include "ContainerNode.h" #include "BeforeLoadEvent.h" -#include "Cache.h" +#include "MemoryCache.h" #include "ContainerNodeAlgorithms.h" #include "DeleteButtonController.h" #include "EventNames.h" diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp index 272387d..978ca44 100644 --- a/WebCore/dom/Document.cpp +++ b/WebCore/dom/Document.cpp @@ -226,8 +226,10 @@ using namespace HTMLNames; // for dual G5s. :) static const int cLayoutScheduleThreshold = 250; -// Use 1 to represent the document's default form. -static HTMLFormElement* const defaultForm = reinterpret_cast<HTMLFormElement*>(1); +// These functions can't have internal linkage because they are used as template arguments. +bool keyMatchesId(AtomicStringImpl*, Element*); +bool keyMatchesMapName(AtomicStringImpl*, Element*); +bool keyMatchesLowercasedMapName(AtomicStringImpl*, Element*); // DOM Level 2 says (letters added): // @@ -500,6 +502,12 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML, con #endif } +inline void Document::DocumentOrderedMap::clear() +{ + m_map.clear(); + m_duplicateCounts.clear(); +} + void Document::removedLastRef() { ASSERT(!m_deletionHasBegun); @@ -967,34 +975,89 @@ PassRefPtr<Element> Document::createElementNS(const String& namespaceURI, const return createElement(qName, false); } -Element* Document::getElementById(const AtomicString& elementId) const +inline void Document::DocumentOrderedMap::add(AtomicStringImpl* key, Element* element) { - if (elementId.isEmpty()) - return 0; + ASSERT(key); + ASSERT(element); + + if (!m_duplicateCounts.contains(key)) { + // Fast path. The key is not already in m_duplicateCounts, so we assume that it's + // also not already in m_map and try to add it. If that add succeeds, we're done. + pair<Map::iterator, bool> addResult = m_map.add(key, element); + if (addResult.second) + return; + + // The add failed, so this key was already cached in m_map. + // There are multiple elements with this key. Remove the m_map + // cache for this key so get searches for it next time it is called. + m_map.remove(addResult.first); + m_duplicateCounts.add(key); + } else { + // There are multiple elements with this key. Remove the m_map + // cache for this key so get will search for it next time it is called. + Map::iterator cachedItem = m_map.find(key); + if (cachedItem != m_map.end()) { + m_map.remove(cachedItem); + m_duplicateCounts.add(key); + } + } - m_elementsById.checkConsistency(); + m_duplicateCounts.add(key); +} - Element* element = m_elementsById.get(elementId.impl()); +inline void Document::DocumentOrderedMap::remove(AtomicStringImpl* key, Element* element) +{ + ASSERT(key); + ASSERT(element); + + m_map.checkConsistency(); + Map::iterator cachedItem = m_map.find(key); + if (cachedItem != m_map.end() && cachedItem->second == element) + m_map.remove(cachedItem); + else + m_duplicateCounts.remove(key); +} + +template<bool keyMatches(AtomicStringImpl*, Element*)> inline Element* Document::DocumentOrderedMap::get(AtomicStringImpl* key, const Document* document) const +{ + ASSERT(key); + + m_map.checkConsistency(); + + Element* element = m_map.get(key); if (element) return element; - if (m_duplicateIds.contains(elementId.impl())) { - // We know there's at least one node with this id, but we don't know what the first one is. - for (Node* n = traverseNextNode(); n; n = n->traverseNextNode()) { - if (n->isElementNode()) { - element = static_cast<Element*>(n); - if (element->hasID() && element->getIdAttribute() == elementId) { - m_duplicateIds.remove(elementId.impl()); - m_elementsById.set(elementId.impl(), element); - return element; - } - } + if (m_duplicateCounts.contains(key)) { + // We know there's at least one node that matches; iterate to find the first one. + for (Node* node = document->firstChild(); node; node = node->traverseNextNode()) { + if (!node->isElementNode()) + continue; + element = static_cast<Element*>(node); + if (!keyMatches(key, element)) + continue; + m_duplicateCounts.remove(key); + m_map.set(key, element); + return element; } ASSERT_NOT_REACHED(); } + return 0; } +inline bool keyMatchesId(AtomicStringImpl* key, Element* element) +{ + return element->hasID() && element->getIdAttribute().impl() == key; +} + +Element* Document::getElementById(const AtomicString& elementId) const +{ + if (elementId.isEmpty()) + return 0; + return m_elementsById.get<keyMatchesId>(elementId.impl(), this); +} + String Document::readyState() const { DEFINE_STATIC_LOCAL(const String, loading, ("loading")); @@ -1018,6 +1081,22 @@ void Document::setReadyState(ReadyState readyState) { if (readyState == m_readyState) return; + + switch (readyState) { + case Loading: + if (!m_documentTiming.domLoading) + m_documentTiming.domLoading = currentTime(); + break; + case Interactive: + if (!m_documentTiming.domInteractive) + m_documentTiming.domInteractive = currentTime(); + break; + case Complete: + if (!m_documentTiming.domComplete) + m_documentTiming.domComplete = currentTime(); + break; + } + m_readyState = readyState; dispatchEvent(Event::create(eventNames().readystatechangeEvent, false, false)); } @@ -1211,40 +1290,12 @@ PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y) void Document::addElementById(const AtomicString& elementId, Element* element) { - typedef HashMap<AtomicStringImpl*, Element*>::iterator iterator; - if (!m_duplicateIds.contains(elementId.impl())) { - // Fast path. The ID is not already in m_duplicateIds, so we assume that it's - // also not already in m_elementsById and do an add. If that add succeeds, we're done. - pair<iterator, bool> addResult = m_elementsById.add(elementId.impl(), element); - if (addResult.second) - return; - // The add failed, so this ID was already cached in m_elementsById. - // There are multiple elements with this ID. Remove the m_elementsById - // cache for this ID so getElementById searches for it next time it is called. - m_elementsById.remove(addResult.first); - m_duplicateIds.add(elementId.impl()); - } else { - // There are multiple elements with this ID. If it exists, remove the m_elementsById - // cache for this ID so getElementById searches for it next time it is called. - iterator cachedItem = m_elementsById.find(elementId.impl()); - if (cachedItem != m_elementsById.end()) { - m_elementsById.remove(cachedItem); - m_duplicateIds.add(elementId.impl()); - } - } - m_duplicateIds.add(elementId.impl()); + m_elementsById.add(elementId.impl(), element); } void Document::removeElementById(const AtomicString& elementId, Element* element) { - m_elementsById.checkConsistency(); - - if (m_elementsById.get(elementId.impl()) == element) - m_elementsById.remove(elementId.impl()); - else { - ASSERT(m_inRemovedLastRefFunction || m_duplicateIds.contains(elementId.impl())); - m_duplicateIds.remove(elementId.impl()); - } + m_elementsById.remove(elementId.impl(), element); } Element* Document::getElementByAccessKey(const String& key) const @@ -1562,6 +1613,7 @@ bail_out: void Document::updateStyleIfNeeded() { + ASSERT(isMainThread()); ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting())); if ((!m_pendingStyleRecalcShouldForce && !childNeedsStyleRecalc()) || inPageCache()) @@ -1579,6 +1631,7 @@ void Document::updateStyleIfNeeded() void Document::updateStyleForAllDocuments() { + ASSERT(isMainThread()); if (!documentsThatNeedStyleRecalc) return; @@ -1592,6 +1645,7 @@ void Document::updateStyleForAllDocuments() void Document::updateLayout() { + ASSERT(isMainThread()); if (Element* oe = ownerElement()) oe->document()->updateLayout(); @@ -2066,7 +2120,7 @@ void Document::implicitClose() // Resume the animations (or start them) if (f) - f->animation()->resumeAnimations(this); + f->animation()->resumeAnimationsForDocument(this); ImageLoader::dispatchPendingBeforeLoadEvents(); ImageLoader::dispatchPendingLoadEvents(); @@ -3822,30 +3876,28 @@ bool Document::parseQualifiedName(const String& qualifiedName, String& prefix, S void Document::addImageMap(HTMLMapElement* imageMap) { - const AtomicString& name = imageMap->getName(); - if (!name.impl()) + AtomicStringImpl* name = imageMap->getName().impl(); + if (!name) return; - - // Add the image map, unless there's already another with that name. - // "First map wins" is the rule other browsers seem to implement. - m_imageMapsByName.add(name.impl(), imageMap); + m_imageMapsByName.add(name, imageMap); } void Document::removeImageMap(HTMLMapElement* imageMap) { - // Remove the image map by name. - // But don't remove some other image map that just happens to have the same name. - // FIXME: Use a HashCountedSet as we do for IDs to find the first remaining map - // once a map has been removed. - const AtomicString& name = imageMap->getName(); - if (!name.impl()) + AtomicStringImpl* name = imageMap->getName().impl(); + if (!name) return; + m_imageMapsByName.remove(name, imageMap); +} - m_imageMapsByName.checkConsistency(); +inline bool keyMatchesMapName(AtomicStringImpl* key, Element* element) +{ + return element->hasTagName(mapTag) && static_cast<HTMLMapElement*>(element)->getName().impl() == key; +} - ImageMapsByName::iterator it = m_imageMapsByName.find(name.impl()); - if (it != m_imageMapsByName.end() && it->second == imageMap) - m_imageMapsByName.remove(it); +inline bool keyMatchesLowercasedMapName(AtomicStringImpl* key, Element* element) +{ + return element->hasTagName(mapTag) && static_cast<HTMLMapElement*>(element)->getName().lower().impl() == key; } HTMLMapElement* Document::getImageMap(const String& url) const @@ -3854,9 +3906,9 @@ HTMLMapElement* Document::getImageMap(const String& url) const return 0; size_t hashPos = url.find('#'); String name = (hashPos == notFound ? url : url.substring(hashPos + 1)).impl(); - AtomicString mapName = isHTMLDocument() ? name.lower() : name; - m_imageMapsByName.checkConsistency(); - return m_imageMapsByName.get(mapName.impl()); + if (isHTMLDocument()) + return static_cast<HTMLMapElement*>(m_imageMapsByName.get<keyMatchesLowercasedMapName>(AtomicString(name.lower()).impl(), this)); + return static_cast<HTMLMapElement*>(m_imageMapsByName.get<keyMatchesMapName>(AtomicString(name).impl(), this)); } void Document::setDecoder(PassRefPtr<TextResourceDecoder> decoder) @@ -4201,6 +4253,8 @@ void Document::finishedParsing() ASSERT(!scriptableDocumentParser() || !m_parser->isParsing()); ASSERT(!scriptableDocumentParser() || m_readyState != Loading); setParsing(false); + if (!m_documentTiming.domContentLoaded) + m_documentTiming.domContentLoaded = currentTime(); dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false)); if (Frame* f = frame()) { diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h index 2d169e7..b4af55d 100644 --- a/WebCore/dom/Document.h +++ b/WebCore/dom/Document.h @@ -33,6 +33,7 @@ #include "Color.h" #include "ContainerNode.h" #include "DocumentMarkerController.h" +#include "DocumentTiming.h" #include "QualifiedName.h" #include "ScriptExecutionContext.h" #include "Timer.h" @@ -310,7 +311,7 @@ public: PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser); Element* getElementById(const AtomicString&) const; bool hasElementWithId(AtomicStringImpl* id) const; - bool containsMultipleElementsWithId(const AtomicString& elementId) { return m_duplicateIds.contains(elementId.impl()); } + bool containsMultipleElementsWithId(const AtomicString& id) const; /** * Retrieve all nodes that intersect a rect in the window's document, until it is fully enclosed by @@ -1058,6 +1059,8 @@ public: PassRefPtr<TouchList> createTouchList(ExceptionCode&) const; #endif + const DocumentTiming* timing() const { return &m_documentTiming; } + protected: Document(Frame*, const KURL& url, bool isXHTML, bool isHTML, const KURL& baseURL = KURL()); @@ -1065,6 +1068,28 @@ protected: private: + class DocumentOrderedMap { + public: + void add(AtomicStringImpl*, Element*); + void remove(AtomicStringImpl*, Element*); + void clear(); + + bool contains(AtomicStringImpl*) const; + bool containsMultiple(AtomicStringImpl*) const; + template<bool keyMatches(AtomicStringImpl*, Element*)> Element* get(AtomicStringImpl*, const Document*) const; + + void checkConsistency() const; + + private: + typedef HashMap<AtomicStringImpl*, Element*> Map; + + // We maintain the invariant that m_duplicateCounts is the count of all elements with a given key + // excluding the one referenced in m_map, if any. This means it one less than the total count + // when the first node with a given key is cached, otherwise the same as the total count. + mutable Map m_map; + mutable HashCountedSet<AtomicStringImpl*> m_duplicateCounts; + }; + friend class IgnoreDestructiveWriteCountIncrementer; void detachParser(); @@ -1259,8 +1284,7 @@ private: RefPtr<Document> m_transformSourceDocument; #endif - typedef HashMap<AtomicStringImpl*, HTMLMapElement*> ImageMapsByName; - ImageMapsByName m_imageMapsByName; + DocumentOrderedMap m_imageMapsByName; int m_docID; // A unique document identifier used for things like document-specific mapped attributes. @@ -1278,11 +1302,7 @@ private: RefPtr<TextResourceDecoder> m_decoder; - // We maintain the invariant that m_duplicateIds is the count of all elements with a given ID - // excluding the one referenced in m_elementsById, if any. This means it one less than the total count - // when the first node with a given ID is cached, otherwise the same as the total count. - mutable HashMap<AtomicStringImpl*, Element*> m_elementsById; - mutable HashCountedSet<AtomicStringImpl*> m_duplicateIds; + DocumentOrderedMap m_elementsById; mutable HashMap<StringImpl*, Element*, CaseFoldingHash> m_elementsByAccessKey; @@ -1357,15 +1377,32 @@ private: Timer<Document> m_loadEventDelayTimer; ViewportArguments m_viewportArguments; - + bool m_directionSetOnDocumentElement; bool m_writingModeSetOnDocumentElement; + + DocumentTiming m_documentTiming; }; +inline bool Document::DocumentOrderedMap::contains(AtomicStringImpl* id) const +{ + return m_map.contains(id) || m_duplicateCounts.contains(id); +} + +inline bool Document::DocumentOrderedMap::containsMultiple(AtomicStringImpl* id) const +{ + return m_duplicateCounts.contains(id); +} + inline bool Document::hasElementWithId(AtomicStringImpl* id) const { ASSERT(id); - return m_elementsById.contains(id) || m_duplicateIds.contains(id); + return m_elementsById.contains(id); +} + +inline bool Document::containsMultipleElementsWithId(const AtomicString& id) const +{ + return m_elementsById.containsMultiple(id.impl()); } inline bool Node::isDocumentNode() const diff --git a/WebCore/svg/SVGAnimatedPoints.idl b/WebCore/dom/DocumentTiming.h index 11314df..a0bbb8c 100644 --- a/WebCore/svg/SVGAnimatedPoints.idl +++ b/WebCore/dom/DocumentTiming.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Inc. All rights reserved. + * 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 @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -23,11 +23,26 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module svg { +#ifndef DocumentTiming_h +#define DocumentTiming_h - interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGAnimatedPoints { - readonly attribute SVGPointList points; - readonly attribute SVGPointList animatedPoints; - }; +namespace WebCore { + +struct DocumentTiming { + DocumentTiming() + : domLoading(0.0) + , domInteractive(0.0) + , domContentLoaded(0.0) + , domComplete(0.0) + { + } + + double domLoading; + double domInteractive; + double domContentLoaded; + double domComplete; +}; } + +#endif diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h index 67887cc..1a85650 100644 --- a/WebCore/dom/Element.h +++ b/WebCore/dom/Element.h @@ -326,7 +326,7 @@ public: void webkitRequestFullScreen(unsigned short flags); #endif - bool isSpellCheckingEnabled() const; + virtual bool isSpellCheckingEnabled() const; protected: Element(const QualifiedName& tagName, Document* document, ConstructionType type) diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h index c91c136..4d39acf 100644 --- a/WebCore/dom/EventNames.h +++ b/WebCore/dom/EventNames.h @@ -172,7 +172,11 @@ namespace WebCore { \ macro(webkitfullscreenchange) \ \ - macro(webkitspeechchange) + macro(webkitspeechchange) \ + \ + macro(webglcontextlost) \ + macro(webglcontextrestored) \ + macro(webglcontextcreationerror) \ \ // end of DOM_EVENT_NAMES_FOR_EACH diff --git a/WebCore/dom/NodeFilter.h b/WebCore/dom/NodeFilter.h index d2022bc..5ce2866 100644 --- a/WebCore/dom/NodeFilter.h +++ b/WebCore/dom/NodeFilter.h @@ -25,6 +25,7 @@ #ifndef NodeFilter_h #define NodeFilter_h +#include "DOMWrapperWorld.h" #include "NodeFilterCondition.h" #include <wtf/RefPtr.h> diff --git a/WebCore/dom/SelectElement.cpp b/WebCore/dom/SelectElement.cpp index 57fb277..886eee7 100644 --- a/WebCore/dom/SelectElement.cpp +++ b/WebCore/dom/SelectElement.cpp @@ -41,7 +41,7 @@ #include "Page.h" #include "RenderListBox.h" #include "RenderMenuList.h" -#include "Settings.h" +#include "SpatialNavigation.h" #include <wtf/Assertions.h> #if ENABLE(WML) @@ -561,10 +561,9 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element #else // When using spatial navigation, we want to be able to navigate away from the select element // when the user hits any of the arrow keys, instead of changing the selection. - if (Frame* frame = element->document()->frame()) { - if (frame->settings() && frame->settings()->isSpatialNavigationEnabled()) + if (isSpatialNavigationEnabled(element->document()->frame())) + if (!data.activeSelectionState()) return; - } UNUSED_PARAM(htmlForm); const Vector<Element*>& listItems = data.listItems(element); @@ -645,6 +644,10 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element // listIndex should already be selected, but this will fire the onchange handler. setSelectedIndex(data, element, listToOptionIndex(data, element, listIndex), true, true); handled = true; + } else if (keyCode == ' ' && isSpatialNavigationEnabled(element->document()->frame())) { + // Use space to trigger arrow key handling for selection change or spatial navigation. + data.setActiveSelectionState(!data.activeSelectionState()); + handled = true; } #endif if (handled) @@ -762,7 +765,12 @@ void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* else if (keyIdentifier == "Up") endIndex = previousSelectableListIndex(data, element, data.activeSelectionEndIndex()); } - + + if (isSpatialNavigationEnabled(element->document()->frame())) + // Check if the selection moves to the boundary. + if (keyIdentifier == "Left" || keyIdentifier == "Right" || ((keyIdentifier == "Down" || keyIdentifier == "Up") && endIndex == data.activeSelectionEndIndex())) + return; + if (keyIdentifier == "Down" || keyIdentifier == "Up") { // Save the selection so it can be compared to the new selection when dispatching change events immediately after making the new selection. saveLastSelection(data, element); diff --git a/WebCore/dom/XMLDocumentParserLibxml2.cpp b/WebCore/dom/XMLDocumentParserLibxml2.cpp index 5b5ac89..77b0af6 100644 --- a/WebCore/dom/XMLDocumentParserLibxml2.cpp +++ b/WebCore/dom/XMLDocumentParserLibxml2.cpp @@ -403,7 +403,7 @@ static bool shouldAllowExternalLoad(const KURL& url) // retrieved content. If we had more context, we could potentially allow // the parser to load a DTD. As things stand, we take the conservative // route and allow same-origin requests only. - if (!XMLDocumentParserScope::currentCachedResourceLoader->doc()->securityOrigin()->canRequest(url)) { + if (!XMLDocumentParserScope::currentCachedResourceLoader->document()->securityOrigin()->canRequest(url)) { XMLDocumentParserScope::currentCachedResourceLoader->printAccessDeniedMessage(url); return false; } diff --git a/WebCore/editing/ApplyStyleCommand.cpp b/WebCore/editing/ApplyStyleCommand.cpp index 8862da7..4e1c733 100644 --- a/WebCore/editing/ApplyStyleCommand.cpp +++ b/WebCore/editing/ApplyStyleCommand.cpp @@ -36,7 +36,6 @@ #include "Document.h" #include "Editor.h" #include "Frame.h" -#include "HTMLElement.h" #include "HTMLFontElement.h" #include "HTMLInterchange.h" #include "HTMLNames.h" @@ -430,104 +429,6 @@ RefPtr<CSSMutableStyleDeclaration> getPropertiesNotIn(CSSStyleDeclaration* style return result; } -// Editing style properties must be preserved during editing operation. -// e.g. when a user inserts a new paragraph, all properties listed here must be copied to the new paragraph. -// FIXME: The current editingStyleProperties contains all inheritableProperties but we may not need to preserve all inheritable properties -static const int editingStyleProperties[] = { - // CSS inheritable properties - CSSPropertyBorderCollapse, - CSSPropertyColor, - CSSPropertyFontFamily, - CSSPropertyFontSize, - CSSPropertyFontStyle, - CSSPropertyFontVariant, - CSSPropertyFontWeight, - CSSPropertyLetterSpacing, - CSSPropertyLineHeight, - CSSPropertyOrphans, - CSSPropertyTextAlign, - CSSPropertyTextIndent, - CSSPropertyTextTransform, - CSSPropertyWhiteSpace, - CSSPropertyWidows, - CSSPropertyWordSpacing, - CSSPropertyWebkitBorderHorizontalSpacing, - CSSPropertyWebkitBorderVerticalSpacing, - CSSPropertyWebkitTextDecorationsInEffect, - CSSPropertyWebkitTextFillColor, - CSSPropertyWebkitTextSizeAdjust, - CSSPropertyWebkitTextStrokeColor, - CSSPropertyWebkitTextStrokeWidth, -}; -size_t numEditingStyleProperties = sizeof(editingStyleProperties)/sizeof(editingStyleProperties[0]); - -RefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::removeNonEditingProperties(CSSStyleDeclaration* style) -{ - return style->copyPropertiesInSet(editingStyleProperties, numEditingStyleProperties); -} - -PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::editingStyleAtPosition(Position pos, ShouldIncludeTypingStyle shouldIncludeTypingStyle) -{ - RefPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = pos.computedStyle(); - RefPtr<CSSMutableStyleDeclaration> style; - if (!computedStyleAtPosition) - style = CSSMutableStyleDeclaration::create(); - else - style = removeNonEditingProperties(computedStyleAtPosition.get()); - - if (style && pos.node() && pos.node()->computedStyle()) { - RenderStyle* renderStyle = pos.node()->computedStyle(); - // If a node's text fill color is invalid, then its children use - // their font-color as their text fill color (they don't - // inherit it). Likewise for stroke color. - ExceptionCode ec = 0; - if (!renderStyle->textFillColor().isValid()) - style->removeProperty(CSSPropertyWebkitTextFillColor, ec); - if (!renderStyle->textStrokeColor().isValid()) - style->removeProperty(CSSPropertyWebkitTextStrokeColor, ec); - ASSERT(ec == 0); - if (renderStyle->fontDescription().keywordSize()) - style->setProperty(CSSPropertyFontSize, computedStyleAtPosition->getFontSizeCSSValuePreferringKeyword()->cssText()); - } - - if (shouldIncludeTypingStyle == IncludeTypingStyle) { - CSSMutableStyleDeclaration* typingStyle = pos.node()->document()->frame()->selection()->typingStyle(); - if (typingStyle) - style->merge(typingStyle); - } - - return style.release(); -} - -void prepareEditingStyleToApplyAt(CSSMutableStyleDeclaration* editingStyle, Position pos) -{ - // ReplaceSelectionCommand::handleStyleSpans() requires that this function only removes the editing style. - // If this function was modified in the future to delete all redundant properties, then add a boolean value to indicate - // which one of editingStyleAtPosition or computedStyle is called. - RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(pos); - style->diff(editingStyle); - - // if alpha value is zero, we don't add the background color. - RefPtr<CSSValue> backgroundColor = editingStyle->getPropertyCSSValue(CSSPropertyBackgroundColor); - if (backgroundColor && backgroundColor->isPrimitiveValue()) { - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(backgroundColor.get()); - Color color = Color(primitiveValue->getRGBA32Value()); - ExceptionCode ec; - if (color.alpha() == 0) - editingStyle->removeProperty(CSSPropertyBackgroundColor, ec); - } -} - -void removeStylesAddedByNode(CSSMutableStyleDeclaration* editingStyle, Node* node) -{ - ASSERT(node); - ASSERT(node->parentNode()); - RefPtr<CSSMutableStyleDeclaration> parentStyle = ApplyStyleCommand::editingStyleAtPosition(Position(node->parentNode(), 0)); - RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(Position(node, 0)); - parentStyle->diff(style.get()); - style->diff(editingStyle); -} - ApplyStyleCommand::ApplyStyleCommand(Document* document, CSSStyleDeclaration* style, EditAction editingAction, EPropertyLevel propertyLevel) : CompositeEditCommand(document) , m_style(style->makeMutable()) @@ -1046,6 +947,8 @@ void ApplyStyleCommand::applyInlineStyle(CSSMutableStyleDeclaration *style) removeInlineStyle(styleWithoutEmbedding ? styleWithoutEmbedding.get() : style, removeStart, end); start = startPosition(); end = endPosition(); + if (start.isNull() || start.isOrphan() || end.isNull() || end.isOrphan()) + return; if (splitStart) { if (mergeStartWithPreviousIfIdentical(start, end)) { @@ -1150,9 +1053,9 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(CSSMutableStyleDeclaration* if (m_removeOnly) return; - for (Node* next; node && node != pastEndNode; node = next) { + for (RefPtr<Node> next; node && node != pastEndNode; node = next.get()) { next = node->traverseNextNode(); - + if (!node->renderer() || !node->isContentEditable()) continue; @@ -1183,7 +1086,8 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(CSSMutableStyleDeclaration* } } - Node* runEnd = node; + RefPtr<Node> runStart = node; + RefPtr<Node> runEnd = node; Node* sibling = node->nextSibling(); while (sibling && sibling != pastEndNode && !sibling->contains(pastEndNode) && (!isBlock(sibling) || sibling->hasTagName(brTag)) @@ -1193,9 +1097,9 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(CSSMutableStyleDeclaration* } next = runEnd->traverseNextSibling(); - if (!removeStyleFromRunBeforeApplyingStyle(style, node, runEnd)) + if (!removeStyleFromRunBeforeApplyingStyle(style, runStart, runEnd)) continue; - addInlineStyleIfNeeded(style, node, runEnd, AddStyledElement); + addInlineStyleIfNeeded(style, runStart.get(), runEnd.get(), AddStyledElement); } } @@ -1205,12 +1109,12 @@ bool ApplyStyleCommand::isStyledInlineElementToRemove(Element* element) const || (m_isInlineElementToRemoveFunction && m_isInlineElementToRemoveFunction(element)); } -bool ApplyStyleCommand::removeStyleFromRunBeforeApplyingStyle(CSSMutableStyleDeclaration* style, Node*& runStart, Node*& runEnd) +bool ApplyStyleCommand::removeStyleFromRunBeforeApplyingStyle(CSSMutableStyleDeclaration* style, RefPtr<Node>& runStart, RefPtr<Node>& runEnd) { ASSERT(runStart && runEnd && runStart->parentNode() == runEnd->parentNode()); - Node* pastEndNode = runEnd->traverseNextSibling(); + RefPtr<Node> pastEndNode = runEnd->traverseNextSibling(); bool needToApplyStyle = false; - for (Node* node = runStart; node && node != pastEndNode; node = node->traverseNextNode()) { + for (Node* node = runStart.get(); node && node != pastEndNode.get(); node = node->traverseNextNode()) { if (node->childNodeCount()) continue; // We don't consider m_isInlineElementToRemoveFunction here because we never apply style when m_isInlineElementToRemoveFunction is specified @@ -1223,16 +1127,16 @@ bool ApplyStyleCommand::removeStyleFromRunBeforeApplyingStyle(CSSMutableStyleDec if (!needToApplyStyle) return false; - Node* next; - for (Node* node = runStart; node && node != pastEndNode; node = next) { + RefPtr<Node> next = runStart; + for (RefPtr<Node> node = next; node && node->inDocument() && node != pastEndNode; node = next) { next = node->traverseNextNode(); if (!node->isHTMLElement()) continue; - - Node* previousSibling = node->previousSibling(); - Node* nextSibling = node->nextSibling(); - ContainerNode* parent = node->parentNode(); - removeInlineStyleFromElement(style, static_cast<HTMLElement*>(node), RemoveAlways); + + RefPtr<Node> previousSibling = node->previousSibling(); + RefPtr<Node> nextSibling = node->nextSibling(); + RefPtr<ContainerNode> parent = node->parentNode(); + removeInlineStyleFromElement(style, static_cast<HTMLElement*>(node.get()), RemoveAlways); if (!node->inDocument()) { // FIXME: We might need to update the start and the end of current selection here but need a test. if (runStart == node) @@ -1245,7 +1149,7 @@ bool ApplyStyleCommand::removeStyleFromRunBeforeApplyingStyle(CSSMutableStyleDec return true; } -bool ApplyStyleCommand::removeInlineStyleFromElement(CSSMutableStyleDeclaration* style, HTMLElement* element, InlineStyleRemovalMode mode, CSSMutableStyleDeclaration* extractedStyle) +bool ApplyStyleCommand::removeInlineStyleFromElement(CSSMutableStyleDeclaration* style, PassRefPtr<HTMLElement> element, InlineStyleRemovalMode mode, CSSMutableStyleDeclaration* extractedStyle) { ASSERT(style); ASSERT(element); @@ -1253,7 +1157,7 @@ bool ApplyStyleCommand::removeInlineStyleFromElement(CSSMutableStyleDeclaration* if (!element->parentNode() || !element->parentNode()->isContentEditable()) return false; - if (isStyledInlineElementToRemove(element)) { + if (isStyledInlineElementToRemove(element.get())) { if (mode == RemoveNone) return true; ASSERT(extractedStyle); @@ -1264,7 +1168,7 @@ bool ApplyStyleCommand::removeInlineStyleFromElement(CSSMutableStyleDeclaration* } bool removed = false; - if (removeImplicitlyStyledElement(style, element, mode, extractedStyle)) + if (removeImplicitlyStyledElement(style, element.get(), mode, extractedStyle)) removed = true; if (!element->inDocument()) @@ -1272,7 +1176,7 @@ bool ApplyStyleCommand::removeInlineStyleFromElement(CSSMutableStyleDeclaration* // If the node was converted to a span, the span may still contain relevant // styles which must be removed (e.g. <b style='font-weight: bold'>) - if (removeCSSStyle(style, element, mode, extractedStyle)) + if (removeCSSStyle(style, element.get(), mode, extractedStyle)) removed = true; return removed; @@ -1658,9 +1562,7 @@ void ApplyStyleCommand::removeInlineStyle(PassRefPtr<CSSMutableStyleDeclaration> break; node = next.get(); } - - ASSERT(s.node()->inDocument()); - ASSERT(e.node()->inDocument()); + updateStartEnd(s, e); } @@ -1859,18 +1761,19 @@ bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position &start, const return false; } -void ApplyStyleCommand::surroundNodeRangeWithElement(Node* startNode, Node* endNode, PassRefPtr<Element> elementToInsert) +void ApplyStyleCommand::surroundNodeRangeWithElement(PassRefPtr<Node> passedStartNode, PassRefPtr<Node> endNode, PassRefPtr<Element> elementToInsert) { - ASSERT(startNode); + ASSERT(passedStartNode); ASSERT(endNode); ASSERT(elementToInsert); + RefPtr<Node> startNode = passedStartNode; RefPtr<Element> element = elementToInsert; insertNodeBefore(element, startNode); - - Node* node = startNode; - while (1) { - Node* next = node->nextSibling(); + + RefPtr<Node> node = startNode; + while (node) { + RefPtr<Node> next = node->nextSibling(); removeNode(node); appendNode(node, element); if (node == endNode) @@ -1878,17 +1781,17 @@ void ApplyStyleCommand::surroundNodeRangeWithElement(Node* startNode, Node* endN node = next; } - Node* nextSibling = element->nextSibling(); - Node* previousSibling = element->previousSibling(); + RefPtr<Node> nextSibling = element->nextSibling(); + RefPtr<Node> previousSibling = element->previousSibling(); if (nextSibling && nextSibling->isElementNode() && nextSibling->isContentEditable() - && areIdenticalElements(element.get(), static_cast<Element*>(nextSibling))) - mergeIdenticalElements(element, static_cast<Element*>(nextSibling)); + && areIdenticalElements(element.get(), static_cast<Element*>(nextSibling.get()))) + mergeIdenticalElements(element.get(), static_cast<Element*>(nextSibling.get())); if (previousSibling && previousSibling->isElementNode() && previousSibling->isContentEditable()) { Node* mergedElement = previousSibling->nextSibling(); if (mergedElement->isElementNode() && mergedElement->isContentEditable() - && areIdenticalElements(static_cast<Element*>(previousSibling), static_cast<Element*>(mergedElement))) - mergeIdenticalElements(static_cast<Element*>(previousSibling), static_cast<Element*>(mergedElement)); + && areIdenticalElements(static_cast<Element*>(previousSibling.get()), static_cast<Element*>(mergedElement))) + mergeIdenticalElements(static_cast<Element*>(previousSibling.get()), static_cast<Element*>(mergedElement)); } // FIXME: We should probably call updateStartEnd if the start or end was in the node @@ -1910,17 +1813,22 @@ void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, HTMLElemen setNodeAttribute(block, styleAttr, cssText); } -void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style, Node *startNode, Node *endNode, EAddStyledElement addStyledElement) +void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style, PassRefPtr<Node> passedStart, PassRefPtr<Node> passedEnd, EAddStyledElement addStyledElement) { + if (!passedStart || !passedEnd || !passedStart->inDocument() || !passedEnd->inDocument()) + return; + RefPtr<Node> startNode = passedStart; + RefPtr<Node> endNode = passedEnd; + // It's okay to obtain the style at the startNode because we've removed all relevant styles from the current run. RefPtr<HTMLElement> dummyElement; Position positionForStyleComparison; if (!startNode->isElementNode()) { dummyElement = createStyleSpanElement(document()); - insertNodeAt(dummyElement, positionBeforeNode(startNode)); + insertNodeAt(dummyElement, positionBeforeNode(startNode.get())); positionForStyleComparison = positionBeforeNode(dummyElement.get()); } else - positionForStyleComparison = firstPositionInNode(startNode); + positionForStyleComparison = firstPositionInNode(startNode.get()); StyleChange styleChange(style, positionForStyleComparison); @@ -1930,7 +1838,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style // Find appropriate font and span elements top-down. HTMLElement* fontContainer = 0; HTMLElement* styleContainer = 0; - for (Node* container = startNode; container && startNode == endNode; container = container->firstChild()) { + for (Node* container = startNode.get(); container && startNode == endNode; container = container->firstChild()) { if (container->isHTMLElement() && container->hasTagName(fontTag)) fontContainer = static_cast<HTMLElement*>(container); bool styleContainerIsNotSpan = !styleContainer || !styleContainer->hasTagName(spanTag); diff --git a/WebCore/editing/ApplyStyleCommand.h b/WebCore/editing/ApplyStyleCommand.h index 16c5b68..018148f 100644 --- a/WebCore/editing/ApplyStyleCommand.h +++ b/WebCore/editing/ApplyStyleCommand.h @@ -27,6 +27,7 @@ #define ApplyStyleCommand_h #include "CompositeEditCommand.h" +#include "HTMLElement.h" namespace WebCore { @@ -63,9 +64,6 @@ public: return adoptRef(new ApplyStyleCommand(document, style, isInlineElementToRemoveFunction, action)); } - static RefPtr<CSSMutableStyleDeclaration> removeNonEditingProperties(CSSStyleDeclaration* style); - static PassRefPtr<CSSMutableStyleDeclaration> editingStyleAtPosition(Position pos, ShouldIncludeTypingStyle shouldIncludeTypingStyle = IgnoreTypingStyle); - private: ApplyStyleCommand(Document*, CSSStyleDeclaration*, EditAction, EPropertyLevel); ApplyStyleCommand(Document*, CSSStyleDeclaration*, const Position& start, const Position& end, EditAction, EPropertyLevel); @@ -79,8 +77,8 @@ private: // style-removal helpers bool isStyledInlineElementToRemove(Element*) const; - bool removeStyleFromRunBeforeApplyingStyle(CSSMutableStyleDeclaration* style, Node*& runStart, Node*& runEnd); - bool removeInlineStyleFromElement(CSSMutableStyleDeclaration*, HTMLElement*, InlineStyleRemovalMode = RemoveIfNeeded, CSSMutableStyleDeclaration* extractedStyle = 0); + bool removeStyleFromRunBeforeApplyingStyle(CSSMutableStyleDeclaration* style, RefPtr<Node>& runStart, RefPtr<Node>& runEnd); + bool removeInlineStyleFromElement(CSSMutableStyleDeclaration*, PassRefPtr<HTMLElement>, InlineStyleRemovalMode = RemoveIfNeeded, CSSMutableStyleDeclaration* extractedStyle = 0); inline bool shouldRemoveInlineStyleFromElement(CSSMutableStyleDeclaration* style, HTMLElement* element) {return removeInlineStyleFromElement(style, element, RemoveNone);} bool removeImplicitlyStyledElement(CSSMutableStyleDeclaration*, HTMLElement*, InlineStyleRemovalMode, CSSMutableStyleDeclaration* extractedStyle); void replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement*&); @@ -99,7 +97,7 @@ private: void fixRangeAndApplyInlineStyle(CSSMutableStyleDeclaration*, const Position& start, const Position& end); void applyInlineStyleToNodeRange(CSSMutableStyleDeclaration*, Node* startNode, Node* pastEndNode); void addBlockStyle(const StyleChange&, HTMLElement*); - void addInlineStyleIfNeeded(CSSMutableStyleDeclaration*, Node* start, Node* end, EAddStyledElement addStyledElement = AddStyledElement); + void addInlineStyleIfNeeded(CSSMutableStyleDeclaration*, PassRefPtr<Node> start, PassRefPtr<Node> end, EAddStyledElement addStyledElement = AddStyledElement); void splitTextAtStart(const Position& start, const Position& end); void splitTextAtEnd(const Position& start, const Position& end); void splitTextElementAtStart(const Position& start, const Position& end); @@ -110,7 +108,7 @@ private: bool mergeEndWithNextIfIdentical(const Position& start, const Position& end); void cleanupUnstyledAppleStyleSpans(Node* dummySpanAncestor); - void surroundNodeRangeWithElement(Node* start, Node* end, PassRefPtr<Element>); + void surroundNodeRangeWithElement(PassRefPtr<Node> start, PassRefPtr<Node> end, PassRefPtr<Element>); float computedFontSize(const Node*); void joinChildTextNodes(Node*, const Position& start, const Position& end); @@ -136,9 +134,6 @@ bool isStyleSpan(const Node*); PassRefPtr<HTMLElement> createStyleSpanElement(Document*); RefPtr<CSSMutableStyleDeclaration> getPropertiesNotIn(CSSStyleDeclaration* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle); -void prepareEditingStyleToApplyAt(CSSMutableStyleDeclaration*, Position); -void removeStylesAddedByNode(CSSMutableStyleDeclaration*, Node*); - } // namespace WebCore #endif diff --git a/WebCore/editing/CompositeEditCommand.cpp b/WebCore/editing/CompositeEditCommand.cpp index 6f47fb4..5579b25 100644 --- a/WebCore/editing/CompositeEditCommand.cpp +++ b/WebCore/editing/CompositeEditCommand.cpp @@ -206,6 +206,8 @@ void CompositeEditCommand::removeChildrenInRange(PassRefPtr<Node> node, unsigned void CompositeEditCommand::removeNode(PassRefPtr<Node> node) { + if (!node || !node->parentNode()) + return; applyCommandToComposite(RemoveNodeCommand::create(node)); } @@ -935,9 +937,9 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap // A non-empty paragraph's style is moved when we copy and move it. We don't move // anything if we're given an empty paragraph, but an empty paragraph can have style // too, <div><b><br></b></div> for example. Save it so that we can preserve it later. - RefPtr<CSSMutableStyleDeclaration> styleInEmptyParagraph; + RefPtr<EditingStyle> styleInEmptyParagraph; if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) { - styleInEmptyParagraph = ApplyStyleCommand::editingStyleAtPosition(startOfParagraphToMove.deepEquivalent(), IncludeTypingStyle); + styleInEmptyParagraph = editingStyleIncludingTypingStyle(startOfParagraphToMove.deepEquivalent()); // The moved paragraph should assume the block style of the destination. styleInEmptyParagraph->removeBlockProperties(); } @@ -981,8 +983,8 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap // If the selection is in an empty paragraph, restore styles from the old empty paragraph to the new empty paragraph. bool selectionIsEmptyParagraph = endingSelection().isCaret() && isStartOfParagraph(endingSelection().visibleStart()) && isEndOfParagraph(endingSelection().visibleStart()); if (styleInEmptyParagraph && selectionIsEmptyParagraph) - applyStyle(styleInEmptyParagraph.get()); - + applyStyle(styleInEmptyParagraph->style()); + if (preserveSelection && startIndex != -1) { // Fragment creation (using createMarkup) incorrectly uses regular // spaces instead of nbsps for some spaces that were rendered (11475), which @@ -1003,7 +1005,7 @@ bool CompositeEditCommand::breakOutOfEmptyListItem() if (!emptyListItem) return false; - RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(endingSelection().start(), IncludeTypingStyle); + RefPtr<EditingStyle> style = editingStyleIncludingTypingStyle(endingSelection().start()); ContainerNode* listNode = emptyListItem->parentNode(); // FIXME: Can't we do something better when the immediate parent wasn't a list node? @@ -1052,10 +1054,10 @@ bool CompositeEditCommand::breakOutOfEmptyListItem() appendBlockPlaceholder(newBlock); setEndingSelection(VisibleSelection(Position(newBlock.get(), 0), DOWNSTREAM)); - prepareEditingStyleToApplyAt(style.get(), endingSelection().start()); - if (style->length()) - applyStyle(style.get()); - + style->prepareToApplyAt(endingSelection().start()); + if (!style->isEmpty()) + applyStyle(style->style()); + return true; } diff --git a/WebCore/editing/CorrectionPanelInfo.h b/WebCore/editing/CorrectionPanelInfo.h new file mode 100644 index 0000000..2caac17 --- /dev/null +++ b/WebCore/editing/CorrectionPanelInfo.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CorrectionPanelInfo_h +#define CorrectionPanelInfo_h + +#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +// Some platforms provide UI for suggesting autocorrection. +#define SUPPORT_AUTOCORRECTION_PANEL 1 +// Some platforms use spelling and autocorrection markers to provide visual cue. +// On such platform, if word with marker is edited, we need to remove the marker. +#define REMOVE_MARKERS_UPON_EDITING 1 +#else +#define SUPPORT_AUTOCORRECTION_PANEL 0 +#define REMOVE_MARKERS_UPON_EDITING 0 +#endif // #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + +#include "Range.h" + +namespace WebCore { + +struct CorrectionPanelInfo { + enum PanelType { + PanelTypeCorrection = 0, + PanelTypeReversion + }; + + RefPtr<Range> m_rangeToBeReplaced; + String m_replacedString; + String m_replacementString; + PanelType m_panelType; + bool m_isActive; +}; + +enum CorrectionWasRejectedOrNot { CorrectionWasNotRejected, CorrectionWasRejected }; + +} // namespace WebCore + +#endif // CorrectionPanelInfo_h diff --git a/WebCore/editing/DeleteSelectionCommand.cpp b/WebCore/editing/DeleteSelectionCommand.cpp index 1f56da7..56deac3 100644 --- a/WebCore/editing/DeleteSelectionCommand.cpp +++ b/WebCore/editing/DeleteSelectionCommand.cpp @@ -26,25 +26,18 @@ #include "config.h" #include "DeleteSelectionCommand.h" -#include "CSSMutableStyleDeclaration.h" #include "Document.h" #include "DocumentFragment.h" #include "Editor.h" #include "EditorClient.h" #include "Element.h" #include "Frame.h" -#include "Logging.h" -#include "CSSComputedStyleDeclaration.h" #include "htmlediting.h" #include "HTMLInputElement.h" #include "HTMLNames.h" -#include "markup.h" #include "RenderTableCell.h" -#include "ReplaceSelectionCommand.h" #include "Text.h" -#include "TextIterator.h" #include "visible_units.h" -#include "ApplyStyleCommand.h" namespace WebCore { @@ -272,15 +265,6 @@ void DeleteSelectionCommand::initializePositionData() m_endBlock = enclosingNodeOfType(rangeCompliantEquivalent(m_upstreamEnd), &isBlock, false); } -static void removeEnclosingAnchorStyle(CSSMutableStyleDeclaration* style, const Position& position) -{ - Node* enclosingAnchor = enclosingAnchorElement(position); - if (!enclosingAnchor || !enclosingAnchor->parentNode()) - return; - - removeStylesAddedByNode(style, enclosingAnchor); -} - void DeleteSelectionCommand::saveTypingStyleState() { // A common case is deleting characters that are all from the same text node. In @@ -294,14 +278,13 @@ void DeleteSelectionCommand::saveTypingStyleState() return; // Figure out the typing style in effect before the delete is done. - m_typingStyle = ApplyStyleCommand::editingStyleAtPosition(positionBeforeTabSpan(m_selectionToDelete.start())); - - removeEnclosingAnchorStyle(m_typingStyle.get(), m_selectionToDelete.start()); + m_typingStyle = EditingStyle::create(positionBeforeTabSpan(m_selectionToDelete.start())); + m_typingStyle->removeStyleAddedByNode(enclosingAnchorElement(m_selectionToDelete.start())); // If we're deleting into a Mail blockquote, save the style at end() instead of start() // We'll use this later in computeTypingStyleAfterDelete if we end up outside of a Mail blockquote if (nearestMailBlockquote(m_selectionToDelete.start().node())) - m_deleteIntoBlockquoteStyle = ApplyStyleCommand::editingStyleAtPosition(m_selectionToDelete.end()); + m_deleteIntoBlockquoteStyle = EditingStyle::create(m_selectionToDelete.end()); else m_deleteIntoBlockquoteStyle = 0; } @@ -693,8 +676,8 @@ void DeleteSelectionCommand::calculateTypingStyleAfterDelete() m_typingStyle = m_deleteIntoBlockquoteStyle; m_deleteIntoBlockquoteStyle = 0; - prepareEditingStyleToApplyAt(m_typingStyle.get(), m_endingPosition); - if (!m_typingStyle->length()) + m_typingStyle->prepareToApplyAt(m_endingPosition); + if (m_typingStyle->isEmpty()) m_typingStyle = 0; VisiblePosition visibleEnd(m_endingPosition); if (m_typingStyle && @@ -707,7 +690,7 @@ void DeleteSelectionCommand::calculateTypingStyleAfterDelete() // then move it back (which will clear typing style). setEndingSelection(visibleEnd); - applyStyle(m_typingStyle.get(), EditActionUnspecified); + applyStyle(m_typingStyle->style(), EditActionUnspecified); // applyStyle can destroy the placeholder that was at m_endingPosition if it needs to // move it, but it will set an endingSelection() at [movedPlaceholder, 0] if it does so. m_endingPosition = endingSelection().start(); diff --git a/WebCore/editing/DeleteSelectionCommand.h b/WebCore/editing/DeleteSelectionCommand.h index 20f52f4..7b46935 100644 --- a/WebCore/editing/DeleteSelectionCommand.h +++ b/WebCore/editing/DeleteSelectionCommand.h @@ -30,6 +30,8 @@ namespace WebCore { +class EditingStyle; + class DeleteSelectionCommand : public CompositeEditCommand { public: static PassRefPtr<DeleteSelectionCommand> create(Document* document, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = false) @@ -86,8 +88,8 @@ private: Position m_trailingWhitespace; RefPtr<Node> m_startBlock; RefPtr<Node> m_endBlock; - RefPtr<CSSMutableStyleDeclaration> m_typingStyle; - RefPtr<CSSMutableStyleDeclaration> m_deleteIntoBlockquoteStyle; + RefPtr<EditingStyle> m_typingStyle; + RefPtr<EditingStyle> m_deleteIntoBlockquoteStyle; RefPtr<Node> m_startRoot; RefPtr<Node> m_endRoot; RefPtr<Node> m_startTableRow; diff --git a/WebCore/editing/EditingAllInOne.cpp b/WebCore/editing/EditingAllInOne.cpp index 81483f8..e93840a 100644 --- a/WebCore/editing/EditingAllInOne.cpp +++ b/WebCore/editing/EditingAllInOne.cpp @@ -36,6 +36,7 @@ #include <DeleteFromTextNodeCommand.cpp> #include <DeleteSelectionCommand.cpp> #include <EditCommand.cpp> +#include <EditingStyle.cpp> #include <Editor.cpp> #include <EditorCommand.cpp> #include <FormatBlockCommand.cpp> diff --git a/WebCore/editing/EditingBehaviorTypes.h b/WebCore/editing/EditingBehaviorTypes.h index 26ba18e..11345da 100644 --- a/WebCore/editing/EditingBehaviorTypes.h +++ b/WebCore/editing/EditingBehaviorTypes.h @@ -38,7 +38,8 @@ namespace WebCore { // if possible in the future. enum EditingBehaviorType { EditingMacBehavior, - EditingWindowsBehavior + EditingWindowsBehavior, + EditingUnixBehavior }; } // WebCore namespace diff --git a/WebCore/editing/EditingStyle.cpp b/WebCore/editing/EditingStyle.cpp new file mode 100644 index 0000000..9da337f --- /dev/null +++ b/WebCore/editing/EditingStyle.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2007, 2008, 2009 Apple Computer, Inc. + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY 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 "EditingStyle.h" + +#include "ApplyStyleCommand.h" +#include "CSSComputedStyleDeclaration.h" +#include "CSSMutableStyleDeclaration.h" +#include "Frame.h" +#include "RenderStyle.h" +#include "SelectionController.h" + +namespace WebCore { + +// Editing style properties must be preserved during editing operation. +// e.g. when a user inserts a new paragraph, all properties listed here must be copied to the new paragraph. +// FIXME: The current editingStyleProperties contains all inheritableProperties but we may not need to preserve all inheritable properties +static const int editingStyleProperties[] = { + // CSS inheritable properties + CSSPropertyBorderCollapse, + CSSPropertyColor, + CSSPropertyFontFamily, + CSSPropertyFontSize, + CSSPropertyFontStyle, + CSSPropertyFontVariant, + CSSPropertyFontWeight, + CSSPropertyLetterSpacing, + CSSPropertyLineHeight, + CSSPropertyOrphans, + CSSPropertyTextAlign, + CSSPropertyTextIndent, + CSSPropertyTextTransform, + CSSPropertyWhiteSpace, + CSSPropertyWidows, + CSSPropertyWordSpacing, + CSSPropertyWebkitBorderHorizontalSpacing, + CSSPropertyWebkitBorderVerticalSpacing, + CSSPropertyWebkitTextDecorationsInEffect, + CSSPropertyWebkitTextFillColor, + CSSPropertyWebkitTextSizeAdjust, + CSSPropertyWebkitTextStrokeColor, + CSSPropertyWebkitTextStrokeWidth, +}; +size_t numEditingStyleProperties = sizeof(editingStyleProperties) / sizeof(editingStyleProperties[0]); + +static PassRefPtr<CSSMutableStyleDeclaration> copyEditingProperties(CSSStyleDeclaration* style) +{ + return style->copyPropertiesInSet(editingStyleProperties, numEditingStyleProperties); +} + +static PassRefPtr<CSSMutableStyleDeclaration> editingStyleFromComputedStyle(PassRefPtr<CSSComputedStyleDeclaration> style) +{ + if (!style) + return CSSMutableStyleDeclaration::create(); + return copyEditingProperties(style.get()); +} + +EditingStyle::EditingStyle() + : m_shouldUseFixedDefaultFontSize(false) +{ +} + +EditingStyle::EditingStyle(Node* node) + : m_shouldUseFixedDefaultFontSize(false) +{ + init(node); +} + +EditingStyle::EditingStyle(const Position& position) + : m_shouldUseFixedDefaultFontSize(false) +{ + init(position.node()); +} + +EditingStyle::EditingStyle(const CSSStyleDeclaration* style) + : m_mutableStyle(style->copy()) + , m_shouldUseFixedDefaultFontSize(false) +{ +} + +void EditingStyle::init(Node* node) +{ + RefPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = computedStyle(node); + m_mutableStyle = editingStyleFromComputedStyle(computedStyleAtPosition); + + if (node && node->computedStyle()) { + RenderStyle* renderStyle = node->computedStyle(); + removeTextFillAndStrokeColorsIfNeeded(renderStyle); + replaceFontSizeByKeywordIfPossible(renderStyle, computedStyleAtPosition.get()); + } + + m_shouldUseFixedDefaultFontSize = computedStyleAtPosition->useFixedFontDefaultSize(); +} + +void EditingStyle::removeTextFillAndStrokeColorsIfNeeded(RenderStyle* renderStyle) +{ + // If a node's text fill color is invalid, then its children use + // their font-color as their text fill color (they don't + // inherit it). Likewise for stroke color. + ExceptionCode ec = 0; + if (!renderStyle->textFillColor().isValid()) + m_mutableStyle->removeProperty(CSSPropertyWebkitTextFillColor, ec); + if (!renderStyle->textStrokeColor().isValid()) + m_mutableStyle->removeProperty(CSSPropertyWebkitTextStrokeColor, ec); + ASSERT(!ec); +} + +void EditingStyle::replaceFontSizeByKeywordIfPossible(RenderStyle* renderStyle, CSSComputedStyleDeclaration* computedStyle) +{ + ASSERT(renderStyle); + if (renderStyle->fontDescription().keywordSize()) + m_mutableStyle->setProperty(CSSPropertyFontSize, computedStyle->getFontSizeCSSValuePreferringKeyword()->cssText()); +} + +bool EditingStyle::isEmpty() const +{ + return !m_mutableStyle || m_mutableStyle->isEmpty(); +} + +void EditingStyle::setStyle(PassRefPtr<CSSMutableStyleDeclaration> style) +{ + m_mutableStyle = style; + // FIXME: We should be able to figure out whether or not font is fixed width for mutable style. + // We need to check font-family is monospace as in FontDescription but we don't want to duplicate code here. + m_shouldUseFixedDefaultFontSize = false; +} + +void EditingStyle::clear() +{ + m_mutableStyle.clear(); + m_shouldUseFixedDefaultFontSize = false; +} + +void EditingStyle::removeBlockProperties() +{ + if (!m_mutableStyle) + return; + + m_mutableStyle->removeBlockProperties(); +} + +void EditingStyle::removeStyleAddedByNode(Node* node) +{ + if (!node || !node->parentNode()) + return; + RefPtr<CSSMutableStyleDeclaration> parentStyle = editingStyleFromComputedStyle(computedStyle(node->parentNode())); + RefPtr<CSSMutableStyleDeclaration> nodeStyle = editingStyleFromComputedStyle(computedStyle(node)); + parentStyle->diff(nodeStyle.get()); + nodeStyle->diff(m_mutableStyle.get()); +} + +void EditingStyle::removeStyleConflictingWithStyleOfNode(Node* node) +{ + if (!node || !node->parentNode()) + return; + RefPtr<CSSMutableStyleDeclaration> parentStyle = editingStyleFromComputedStyle(computedStyle(node->parentNode())); + RefPtr<CSSMutableStyleDeclaration> nodeStyle = editingStyleFromComputedStyle(computedStyle(node)); + parentStyle->diff(nodeStyle.get()); + + CSSMutableStyleDeclaration::const_iterator end = nodeStyle->end(); + for (CSSMutableStyleDeclaration::const_iterator it = nodeStyle->begin(); it != end; ++it) + m_mutableStyle->removeProperty(it->id()); +} + +void EditingStyle::removeNonEditingProperties() +{ + if (m_mutableStyle) + m_mutableStyle = copyEditingProperties(m_mutableStyle.get()); +} + +void EditingStyle::prepareToApplyAt(const Position& position) +{ + // ReplaceSelectionCommand::handleStyleSpans() requires that this function only removes the editing style. + // If this function was modified in the future to delete all redundant properties, then add a boolean value to indicate + // which one of editingStyleAtPosition or computedStyle is called. + RefPtr<EditingStyle> style = EditingStyle::create(position); + style->m_mutableStyle->diff(m_mutableStyle.get()); + + // if alpha value is zero, we don't add the background color. + RefPtr<CSSValue> backgroundColor = m_mutableStyle->getPropertyCSSValue(CSSPropertyBackgroundColor); + if (backgroundColor && backgroundColor->isPrimitiveValue() + && !alphaChannel(static_cast<CSSPrimitiveValue*>(backgroundColor.get())->getRGBA32Value())) { + ExceptionCode ec; + m_mutableStyle->removeProperty(CSSPropertyBackgroundColor, ec); + } +} + +PassRefPtr<EditingStyle> editingStyleIncludingTypingStyle(const Position& position) +{ + RefPtr<EditingStyle> editingStyle = EditingStyle::create(position); + RefPtr<CSSMutableStyleDeclaration> typingStyle = position.node()->document()->frame()->selection()->typingStyle(); + if (typingStyle) + editingStyle->style()->merge(copyEditingProperties(typingStyle.get()).get()); + return editingStyle; +} + +} diff --git a/WebCore/editing/EditingStyle.h b/WebCore/editing/EditingStyle.h new file mode 100644 index 0000000..6b4c60c --- /dev/null +++ b/WebCore/editing/EditingStyle.h @@ -0,0 +1,93 @@ +/* + * 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 EditingStyle_h +#define EditingStyle_h + +#include "CSSMutableStyleDeclaration.h" +#include "Document.h" +#include "Position.h" + +namespace WebCore { + +class CSSStyleDeclaration; +class CSSComputedStyleDeclaration; + +class EditingStyle : public RefCounted<EditingStyle> { +public: + + static PassRefPtr<EditingStyle> create() + { + return adoptRef(new EditingStyle()); + } + + static PassRefPtr<EditingStyle> create(Node* node) + { + return adoptRef(new EditingStyle(node)); + } + + static PassRefPtr<EditingStyle> create(const Position& position) + { + return adoptRef(new EditingStyle(position)); + } + + static PassRefPtr<EditingStyle> create(const CSSStyleDeclaration* style) + { + return adoptRef(new EditingStyle(style)); + } + + CSSMutableStyleDeclaration* style() { return m_mutableStyle.get(); } + bool isEmpty() const; + void setStyle(PassRefPtr<CSSMutableStyleDeclaration>); + void clear(); + void removeBlockProperties(); + void removeStyleAddedByNode(Node* node); + void removeStyleConflictingWithStyleOfNode(Node* node); + void removeNonEditingProperties(); + void prepareToApplyAt(const Position&); + +private: + EditingStyle(); + EditingStyle(Node*); + EditingStyle(const Position&); + EditingStyle(const CSSStyleDeclaration*); + void init(Node*); + void removeTextFillAndStrokeColorsIfNeeded(RenderStyle*); + void replaceFontSizeByKeywordIfPossible(RenderStyle*, CSSComputedStyleDeclaration*); + + RefPtr<CSSMutableStyleDeclaration> m_mutableStyle; + bool m_shouldUseFixedDefaultFontSize; +}; + +PassRefPtr<EditingStyle> editingStyleIncludingTypingStyle(const Position&); + +} // namespace WebCore + +#endif // EditingStyle_h diff --git a/WebCore/editing/Editor.cpp b/WebCore/editing/Editor.cpp index c74d765..327aa5f 100644 --- a/WebCore/editing/Editor.cpp +++ b/WebCore/editing/Editor.cpp @@ -457,9 +457,53 @@ bool Editor::shouldShowDeleteInterface(HTMLElement* element) const void Editor::respondToChangedSelection(const VisibleSelection& oldSelection) { +#if SUPPORT_AUTOCORRECTION_PANEL + VisibleSelection currentSelection(frame()->selection()->selection()); + if (currentSelection != oldSelection) { + stopCorrectionPanelTimer(); + dismissCorrectionPanel(CorrectionWasNotRejected); + } +#endif // SUPPORT_AUTOCORRECTION_PANEL + if (client()) client()->respondToChangedSelection(); m_deleteButtonController->respondToChangedSelection(oldSelection); + +#if SUPPORT_AUTOCORRECTION_PANEL + // When user moves caret to the end of autocorrected word and pauses, we show the panel + // containing the original pre-correction word so that user can quickly revert the + // undesired autocorrection. Here, we start correction panel timer once we confirm that + // the new caret position is at the end of a word. + if (!currentSelection.isCaret() || currentSelection == oldSelection) + return; + + VisiblePosition selectionPosition = currentSelection.start(); + VisiblePosition endPositionOfWord = endOfWord(selectionPosition, LeftWordIfOnBoundary); + if (selectionPosition != endPositionOfWord) + return; + + Position position = endPositionOfWord.deepEquivalent(); + if (position.anchorType() != Position::PositionIsOffsetInAnchor) + return; + + Node* node = position.containerNode(); + int endOffset = position.offsetInContainerNode(); + Vector<DocumentMarker> markers = node->document()->markers()->markersForNode(node); + size_t markerCount = markers.size(); + for (size_t i = 0; i < markerCount; ++i) { + const DocumentMarker& marker = markers[i]; + if (marker.type == DocumentMarker::CorrectionIndicator && static_cast<int>(marker.endOffset) == endOffset) { + RefPtr<Range> wordRange = Range::create(frame()->document(), node, marker.startOffset, node, marker.endOffset); + String currentWord = plainText(wordRange.get()); + if (currentWord.length() > 0 && marker.description.length() > 0) { + m_correctionPanelInfo.m_rangeToBeReplaced = wordRange; + m_correctionPanelInfo.m_replacementString = marker.description; + startCorrectionPanelTimer(CorrectionPanelInfo::PanelTypeReversion); + } + break; + } + } +#endif // SUPPORT_AUTOCORRECTION_PANEL } void Editor::respondToChangedContents(const VisibleSelection& endingSelection) @@ -564,7 +608,8 @@ WritingDirection Editor::textDirectionForSelection(bool& hasNestedOrMultipleEmbe } if (m_frame->selection()->isCaret()) { - if (CSSMutableStyleDeclaration* typingStyle = m_frame->selection()->typingStyle()) { + RefPtr<CSSMutableStyleDeclaration> typingStyle = m_frame->selection()->typingStyle(); + if (typingStyle) { RefPtr<CSSValue> unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi); if (unicodeBidi) { ASSERT(unicodeBidi->isPrimitiveValue()); @@ -998,10 +1043,13 @@ static void dispatchEditableContentChangedEvents(const EditCommand& command) void Editor::appliedEditing(PassRefPtr<EditCommand> cmd) { + // We may start reversion panel timer in respondToChangedSelection(). + // So we stop the timer for current panel before calling changeSelectionAfterCommand() later in this method. + stopCorrectionPanelTimer(); m_frame->document()->updateLayout(); - + dispatchEditableContentChangedEvents(*cmd); - + VisibleSelection newSelection(cmd->endingSelection()); // Don't clear the typing style with this selection change. We do those things elsewhere if necessary. changeSelectionAfterCommand(newSelection, false, false); @@ -1020,7 +1068,6 @@ void Editor::appliedEditing(PassRefPtr<EditCommand> cmd) client()->registerCommandForUndo(m_lastEditCommand); } respondToChangedContents(newSelection); - stopCorrectionPanelTimer(); } void Editor::unappliedEditing(PassRefPtr<EditCommand> cmd) @@ -1068,9 +1115,8 @@ Editor::Editor(Frame* frame) Editor::~Editor() { -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - if (client()) - client()->dismissCorrectionPanel(true); +#if SUPPORT_AUTOCORRECTION_PANEL + dismissCorrectionPanel(CorrectionWasNotRejected); #endif } @@ -1671,7 +1717,6 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) // repeated "check spelling" commands work. VisibleSelection selection(frame()->selection()->selection()); RefPtr<Range> spellingSearchRange(rangeOfContents(frame()->document())); - TextCheckingHelper checker(client(), spellingSearchRange); bool startedWithSelection = false; if (selection.start().node()) { @@ -1738,7 +1783,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) bool isSpelling = true; int foundOffset = 0; GrammarDetail grammarDetail; - String foundItem = checker.findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail); + String foundItem = TextCheckingHelper(client(), spellingSearchRange).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail); if (isSpelling) { misspelledWord = foundItem; misspellingOffset = foundOffset; @@ -1748,7 +1793,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) } #else RefPtr<Range> firstMisspellingRange; - String misspelledWord = checker.findFirstMisspelling(misspellingOffset, false, firstMisspellingRange); + String misspelledWord = TextCheckingHelper(client(), spellingSearchRange).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange); String badGrammarPhrase; #ifndef BUILDING_ON_TIGER @@ -1765,7 +1810,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) } if (isGrammarCheckingEnabled()) - badGrammarPhrase = checker.findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); + badGrammarPhrase = TextCheckingHelper(client(), grammarSearchRange).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); #endif #endif @@ -1778,7 +1823,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) grammarSearchRange = spellingSearchRange->cloneRange(ec); - foundItem = checker.findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail); + foundItem = TextCheckingHelper(client(), spellingSearchRange).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail); if (isSpelling) { misspelledWord = foundItem; misspellingOffset = foundOffset; @@ -1787,7 +1832,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) grammarPhraseOffset = foundOffset; } #else - misspelledWord = checker.findFirstMisspelling(misspellingOffset, false, firstMisspellingRange); + misspelledWord = TextCheckingHelper(client(), spellingSearchRange).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange); #ifndef BUILDING_ON_TIGER grammarSearchRange = spellingSearchRange->cloneRange(ec); @@ -1797,8 +1842,9 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) chars.advance(misspellingOffset); grammarSearchRange->setEnd(chars.range()->startContainer(ec), chars.range()->startOffset(ec), ec); } + if (isGrammarCheckingEnabled()) - badGrammarPhrase = checker.findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); + badGrammarPhrase = TextCheckingHelper(client(), grammarSearchRange).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); #endif #endif } @@ -1967,47 +2013,10 @@ void Editor::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelecti void Editor::markMisspellingsAfterTypingToPosition(const VisiblePosition &p) { #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) -#if !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL // Apply pending autocorrection before next round of spell checking. - bool didApplyCorrection = false; - if (m_rangeToBeReplacedByCorrection) { - ExceptionCode ec = 0; - RefPtr<Range> paragraphRangeContainingCorrection = m_rangeToBeReplacedByCorrection->cloneRange(ec); - if (!ec) { - setStart(paragraphRangeContainingCorrection.get(), startOfParagraph(m_rangeToBeReplacedByCorrection->startPosition())); - setEnd(paragraphRangeContainingCorrection.get(), endOfParagraph(m_rangeToBeReplacedByCorrection->endPosition())); - // After we replace the word at range m_rangeToBeReplacedByCorrection, we need to add - // autocorrection underline at that range. However, once the replacement took place, the - // value of m_rangeToBeReplacedByCorrection is not valid anymore. So before we carry out - // the replacement, we need to store the start position of m_rangeToBeReplacedByCorrection - // relative to the start position of the containing paragraph. We use correctionStartOffsetInParagraph - // to store this value. In order to obtain this offset, we need to first create a range - // which spans from the start of paragraph to the start position of m_rangeToBeReplacedByCorrection. - RefPtr<Range> correctionStartOffsetInParagraphAsRange = Range::create(paragraphRangeContainingCorrection->startContainer(ec)->document(), paragraphRangeContainingCorrection->startPosition(), paragraphRangeContainingCorrection->startPosition()); - if (!ec) { - Position startPositionOfRangeToBeReplaced = m_rangeToBeReplacedByCorrection->startPosition(); - correctionStartOffsetInParagraphAsRange->setEnd(startPositionOfRangeToBeReplaced.containerNode(), startPositionOfRangeToBeReplaced.computeOffsetInContainerNode(), ec); - if (!ec) { - // Take note of the location of autocorrection so that we can add marker after the replacement took place. - int correctionStartOffsetInParagraph = TextIterator::rangeLength(correctionStartOffsetInParagraphAsRange.get()); - Position caretPosition = m_frame->selection()->selection().end(); - RefPtr<Range> rangeToBeReplaced = m_rangeToBeReplacedByCorrection->cloneRange(ec); - VisibleSelection selectionToReplace(rangeToBeReplaced.get(), DOWNSTREAM); - if (m_frame->selection()->shouldChangeSelection(selectionToReplace)) { - m_frame->selection()->setSelection(selectionToReplace); - replaceSelectionWithText(m_correctionReplacementString, false, false); - caretPosition.moveToOffset(caretPosition.offsetInContainerNode() + m_correctionReplacementString.length() - m_stringToBeReplacedByCorrection.length()); - RefPtr<Range> replacementRange = TextIterator::subrange(paragraphRangeContainingCorrection.get(), correctionStartOffsetInParagraph, m_correctionReplacementString.length()); - replacementRange->startContainer()->document()->markers()->addMarker(replacementRange.get(), DocumentMarker::Replacement, m_correctionReplacementString); - replacementRange->startContainer()->document()->markers()->addMarker(replacementRange.get(), DocumentMarker::CorrectionIndicator); - m_frame->selection()->moveTo(caretPosition, false); - didApplyCorrection = true; - } - } - } - } - m_rangeToBeReplacedByCorrection.clear(); - } + applyCorrectionPanelInfo(true); + m_correctionPanelInfo.m_rangeToBeReplaced.clear(); #endif TextCheckingOptions textCheckingOptions = 0; @@ -2095,7 +2104,7 @@ void Editor::markMisspellingsOrBadGrammar(const VisibleSelection& selection, boo if (!editableNode || !editableNode->isContentEditable()) return; - if (!isSpellCheckingEnabledInFocusedNode()) + if (!isSpellCheckingEnabledFor(editableNode)) return; // Get the spell checker if it is available @@ -2115,11 +2124,8 @@ void Editor::markMisspellingsOrBadGrammar(const VisibleSelection& selection, boo } } -bool Editor::isSpellCheckingEnabledInFocusedNode() const +bool Editor::isSpellCheckingEnabledFor(Node* node) const { - // Ascend the DOM tree to find a "spellcheck" attribute. - // When we find a "spellcheck" attribute, retrieve its value and return false if its value is "false". - const Node* node = frame()->document()->focusedNode(); if (!node) return false; const Element* focusedElement = node->isElementNode() ? toElement(node) : node->parentElement(); @@ -2128,6 +2134,11 @@ bool Editor::isSpellCheckingEnabledInFocusedNode() const return focusedElement->isSpellCheckingEnabled(); } +bool Editor::isSpellCheckingEnabledInFocusedNode() const +{ + return isSpellCheckingEnabledFor(m_frame->selection()->start().node()); +} + void Editor::markMisspellings(const VisibleSelection& selection, RefPtr<Range>& firstMisspellingRange) { markMisspellingsOrBadGrammar(selection, true, firstMisspellingRange); @@ -2170,7 +2181,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions textCh if (!editableNode || !editableNode->isContentEditable()) return; - if (!isSpellCheckingEnabledInFocusedNode()) + if (!isSpellCheckingEnabledFor(editableNode)) return; // Expand the range to encompass entire paragraphs, since text checking needs that much context. @@ -2187,16 +2198,15 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions textCh bool adjustSelectionForParagraphBoundaries = false; String paragraphString; RefPtr<Range> paragraphRange; - TextCheckingHelper checker(client(), grammarRange); if (shouldMarkGrammar) { // The spelling range should be contained in the paragraph-aligned extension of the grammar range. - paragraphRange = checker.paragraphAlignedRange(grammarRangeStartOffset, paragraphString); + paragraphRange = TextCheckingHelper(client(), grammarRange).paragraphAlignedRange(grammarRangeStartOffset, paragraphString); RefPtr<Range> offsetAsRange = Range::create(paragraphRange->startContainer(ec)->document(), paragraphRange->startPosition(), spellingRange->startPosition()); spellingRangeStartOffset = TextIterator::rangeLength(offsetAsRange.get()); grammarRangeEndOffset = grammarRangeStartOffset + TextIterator::rangeLength(grammarRange); } else { - paragraphRange = checker.paragraphAlignedRange(spellingRangeStartOffset, paragraphString); + paragraphRange = TextCheckingHelper(client(), spellingRange).paragraphAlignedRange(spellingRangeStartOffset, paragraphString); } spellingRangeEndOffset = spellingRangeStartOffset + TextIterator::rangeLength(spellingRange); paragraphLength = paragraphString.length(); @@ -2242,7 +2252,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions textCh } client()->checkTextOfParagraph(paragraphString.characters(), paragraphLength, checkingTypes, results); -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL // If this checking is only for showing correction panel, we shouldn't bother to mark misspellings. if (shouldShowCorrectionPanel) shouldMarkSpelling = false; @@ -2327,7 +2337,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions textCh } else if (canEdit() && shouldInsertText(result->replacement, rangeToReplace.get(), EditorInsertActionTyped)) { if (result->type == TextCheckingTypeCorrection) replacedString = plainText(rangeToReplace.get()); -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL if (shouldShowCorrectionPanel && resultLocation + resultLength == spellingRangeEndOffset && result->type == TextCheckingTypeCorrection) { // We only show the correction panel on the last word. Vector<FloatQuad> textQuads; @@ -2336,10 +2346,11 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions textCh FloatRect totalBoundingBox; for (Vector<FloatQuad>::const_iterator it = textQuads.begin(); it < end; ++it) totalBoundingBox.unite(it->boundingBox()); - m_rangeToBeReplacedByCorrection = rangeToReplace; - m_stringToBeReplacedByCorrection = replacedString; - m_correctionReplacementString = result->replacement; - client()->showCorrectionPanel(totalBoundingBox, m_stringToBeReplacedByCorrection, result->replacement, this); + m_correctionPanelInfo.m_rangeToBeReplaced = rangeToReplace; + m_correctionPanelInfo.m_replacedString = replacedString; + m_correctionPanelInfo.m_replacementString = result->replacement; + m_correctionPanelInfo.m_isActive = true; + client()->showCorrectionPanel(m_correctionPanelInfo.m_panelType, totalBoundingBox, m_correctionPanelInfo.m_replacedString, result->replacement, this); doReplacement = false; } #endif @@ -2353,7 +2364,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions textCh // Add a marker so that corrections can easily be undone and won't be re-corrected. RefPtr<Range> replacedRange = TextIterator::subrange(paragraphRange.get(), resultLocation, replacementLength); replacedRange->startContainer()->document()->markers()->addMarker(replacedRange.get(), DocumentMarker::Replacement, replacedString); - replacedRange->startContainer()->document()->markers()->addMarker(replacedRange.get(), DocumentMarker::CorrectionIndicator); + replacedRange->startContainer()->document()->markers()->addMarker(replacedRange.get(), DocumentMarker::CorrectionIndicator, replacedString); } } } @@ -2416,60 +2427,99 @@ void Editor::markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelec void Editor::correctionPanelTimerFired(Timer<Editor>*) { -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) - VisibleSelection selection(frame()->selection()->selection()); - VisiblePosition start(selection.start(), selection.affinity()); - VisiblePosition p = startOfWord(start, LeftWordIfOnBoundary); - VisibleSelection adjacentWords = VisibleSelection(p, start); - markAllMisspellingsAndBadGrammarInRanges(MarkSpelling | ShowCorrectionPanel, adjacentWords.toNormalizedRange().get(), 0); +#if SUPPORT_AUTOCORRECTION_PANEL + if (m_correctionPanelInfo.m_panelType == CorrectionPanelInfo::PanelTypeCorrection) { + VisibleSelection selection(frame()->selection()->selection()); + VisiblePosition start(selection.start(), selection.affinity()); + VisiblePosition p = startOfWord(start, LeftWordIfOnBoundary); + VisibleSelection adjacentWords = VisibleSelection(p, start); + markAllMisspellingsAndBadGrammarInRanges(MarkSpelling | ShowCorrectionPanel, adjacentWords.toNormalizedRange().get(), 0); + } else { + String currentWord = plainText(m_correctionPanelInfo.m_rangeToBeReplaced.get()); + Vector<FloatQuad> textQuads; + m_correctionPanelInfo.m_rangeToBeReplaced->getBorderAndTextQuads(textQuads); + Vector<FloatQuad>::const_iterator end = textQuads.end(); + FloatRect totalBoundingBox; + for (Vector<FloatQuad>::const_iterator it = textQuads.begin(); it < end; ++it) + totalBoundingBox.unite(it->boundingBox()); + m_correctionPanelInfo.m_isActive = true; + m_correctionPanelInfo.m_replacedString = currentWord; + client()->showCorrectionPanel(m_correctionPanelInfo.m_panelType, totalBoundingBox, m_correctionPanelInfo.m_replacedString, m_correctionPanelInfo.m_replacementString, this); + } #endif } void Editor::handleRejectedCorrection() { - Range* replacedRange = m_rangeToBeReplacedByCorrection.get(); + Range* replacedRange = m_correctionPanelInfo.m_rangeToBeReplaced.get(); if (!replacedRange || m_frame->document() != replacedRange->ownerDocument()) return; - replacedRange->startContainer()->document()->markers()->addMarker(replacedRange, DocumentMarker::RejectedCorrection, m_stringToBeReplacedByCorrection); - m_rangeToBeReplacedByCorrection.clear(); + if (m_correctionPanelInfo.m_panelType == CorrectionPanelInfo::PanelTypeCorrection) + replacedRange->startContainer()->document()->markers()->addMarker(replacedRange, DocumentMarker::RejectedCorrection, m_correctionPanelInfo.m_replacedString); + else { + m_correctionPanelInfo.m_isActive = false; + applyCorrectionPanelInfo(false); + } + m_correctionPanelInfo.m_rangeToBeReplaced.clear(); } -void Editor::startCorrectionPanelTimer() +void Editor::startCorrectionPanelTimer(CorrectionPanelInfo::PanelType type) { -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - static const double correctionPanelTimerInterval = 0.3; +#if SUPPORT_AUTOCORRECTION_PANEL + const double correctionPanelTimerInterval = 0.3; if (isAutomaticSpellingCorrectionEnabled()) { - m_rangeToBeReplacedByCorrection.clear(); + if (type == CorrectionPanelInfo::PanelTypeCorrection) + // If type is PanelTypeReversion, then the new range has been set. So we shouldn't clear it. + m_correctionPanelInfo.m_rangeToBeReplaced.clear(); + m_correctionPanelInfo.m_panelType = type; m_correctionPanelTimer.startOneShot(correctionPanelTimerInterval); } +#else + UNUSED_PARAM(type); #endif } void Editor::stopCorrectionPanelTimer() { -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL m_correctionPanelTimer.stop(); #endif } void Editor::handleCancelOperation() { -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL + if (!m_correctionPanelInfo.m_isActive) + return; + m_correctionPanelInfo.m_isActive = false; if (client()) - client()->dismissCorrectionPanel(false); + client()->dismissCorrectionPanel(CorrectionWasRejected); #endif } bool Editor::isShowingCorrectionPanel() { -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL if (client()) return client()->isShowingCorrectionPanel(); #endif return false; } +void Editor::dismissCorrectionPanel(CorrectionWasRejectedOrNot correctionWasRejectedOrNot) +{ +#if SUPPORT_AUTOCORRECTION_PANEL + if (!m_correctionPanelInfo.m_isActive) + return; + m_correctionPanelInfo.m_isActive = false; + m_correctionPanelInfo.m_rangeToBeReplaced.clear(); + if (client()) + client()->dismissCorrectionPanel(correctionWasRejectedOrNot); +#else + UNUSED_PARAM(correctionWasRejectedOrNot); +#endif +} void Editor::removeSpellAndCorrectionMarkersFromWordsToBeEdited(bool doNotRemoveIfSelectionAtWordBoundary) { // We want to remove the markers from a word if an editing command will change the word. This can happen in one of @@ -2536,6 +2586,8 @@ void Editor::removeSpellAndCorrectionMarkersFromWordsToBeEdited(bool doNotRemove Vector<RangeMarkerPair, 16> markersToRemove; for (TextIterator textIterator(wordRange.get()); !textIterator.atEnd(); textIterator.advance()) { Node* node = textIterator.node(); + if (!node) + continue; if (node == startOfFirstWord.deepEquivalent().containerNode() || node == endOfLastWord.deepEquivalent().containerNode()) { // First word and last word can belong to the same node bool processFirstWord = node == startOfFirstWord.deepEquivalent().containerNode() && document->markers()->hasMarkers(rangeOfFirstWord.get(), DocumentMarker::Spelling | DocumentMarker::CorrectionIndicator); @@ -2565,6 +2617,54 @@ void Editor::removeSpellAndCorrectionMarkersFromWordsToBeEdited(bool doNotRemove document->markers()->removeMarkers(pairIterator->first.get(), pairIterator->second); } +void Editor::applyCorrectionPanelInfo(bool addCorrectionIndicatorMarker) +{ + if (!m_correctionPanelInfo.m_rangeToBeReplaced) + return; + + ExceptionCode ec = 0; + RefPtr<Range> paragraphRangeContainingCorrection = m_correctionPanelInfo.m_rangeToBeReplaced->cloneRange(ec); + if (ec) + return; + + setStart(paragraphRangeContainingCorrection.get(), startOfParagraph(m_correctionPanelInfo.m_rangeToBeReplaced->startPosition())); + setEnd(paragraphRangeContainingCorrection.get(), endOfParagraph(m_correctionPanelInfo.m_rangeToBeReplaced->endPosition())); + + // After we replace the word at range m_rangeToBeReplaced, we need to add markers to that range. + // However, once the replacement took place, the value of m_rangeToBeReplaced is not valid anymore. + // So before we carry out the replacement, we need to store the start position of m_rangeToBeReplaced + // relative to the start position of the containing paragraph. We use correctionStartOffsetInParagraph + // to store this value. In order to obtain this offset, we need to first create a range + // which spans from the start of paragraph to the start position of m_rangeToBeReplaced. + RefPtr<Range> correctionStartOffsetInParagraphAsRange = Range::create(paragraphRangeContainingCorrection->startContainer(ec)->document(), paragraphRangeContainingCorrection->startPosition(), paragraphRangeContainingCorrection->startPosition()); + if (ec) + return; + + Position startPositionOfRangeToBeReplaced = m_correctionPanelInfo.m_rangeToBeReplaced->startPosition(); + correctionStartOffsetInParagraphAsRange->setEnd(startPositionOfRangeToBeReplaced.containerNode(), startPositionOfRangeToBeReplaced.computeOffsetInContainerNode(), ec); + if (ec) + return; + + // Take note of the location of autocorrection so that we can add marker after the replacement took place. + int correctionStartOffsetInParagraph = TextIterator::rangeLength(correctionStartOffsetInParagraphAsRange.get()); + Position caretPosition = m_frame->selection()->selection().end(); + + // Clone the range, since the caller of this method may want to keep the original range around. + RefPtr<Range> rangeToBeReplaced = m_correctionPanelInfo.m_rangeToBeReplaced->cloneRange(ec); + VisibleSelection selectionToReplace(rangeToBeReplaced.get(), DOWNSTREAM); + if (m_frame->selection()->shouldChangeSelection(selectionToReplace)) { + m_frame->selection()->setSelection(selectionToReplace); + replaceSelectionWithText(m_correctionPanelInfo.m_replacementString, false, false); + caretPosition.moveToOffset(caretPosition.offsetInContainerNode() + m_correctionPanelInfo.m_replacementString.length() - m_correctionPanelInfo.m_replacedString.length()); + setEnd(paragraphRangeContainingCorrection.get(), endOfParagraph(caretPosition)); + RefPtr<Range> replacementRange = TextIterator::subrange(paragraphRangeContainingCorrection.get(), correctionStartOffsetInParagraph, m_correctionPanelInfo.m_replacementString.length()); + replacementRange->startContainer()->document()->markers()->addMarker(replacementRange.get(), DocumentMarker::Replacement, m_correctionPanelInfo.m_replacementString); + if (addCorrectionIndicatorMarker) + replacementRange->startContainer()->document()->markers()->addMarker(replacementRange.get(), DocumentMarker::CorrectionIndicator, m_correctionPanelInfo.m_replacedString); + m_frame->selection()->moveTo(caretPosition, false); + } +} + PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint) { Document* document = m_frame->documentAtPoint(windowPoint); @@ -2831,7 +2931,7 @@ void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, b if (newSelection.start().isOrphan() || newSelection.end().isOrphan()) return; -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL // Check to see if the command introduced paragraph separator. If it did, we remove existing autocorrection underlines. // This is in consistency with the behavior in AppKit if (!inSameParagraph(m_frame->selection()->selection().visibleStart(), newSelection.visibleEnd())) @@ -2954,7 +3054,7 @@ void Editor::computeAndSetTypingStyle(CSSStyleDeclaration* style, EditAction edi applyCommand(ApplyStyleCommand::create(m_frame->document(), blockStyle.get(), editingAction)); // Set the remaining style as the typing style. - m_frame->selection()->setTypingStyle(mutableStyle.release()); + m_frame->selection()->setTypingStyle(EditingStyle::create(mutableStyle.get())); } PassRefPtr<CSSMutableStyleDeclaration> Editor::selectionComputedStyle(bool& shouldUseFixedFontDefaultSize) const @@ -2985,10 +3085,10 @@ PassRefPtr<CSSMutableStyleDeclaration> Editor::selectionComputedStyle(bool& shou if (!m_frame->selection()->typingStyle()) return mutableStyle; - RefPtr<CSSMutableStyleDeclaration> typingStyle = m_frame->selection()->typingStyle()->copy(); - ApplyStyleCommand::removeNonEditingProperties(typingStyle.get()); - prepareEditingStyleToApplyAt(typingStyle.get(), position); - mutableStyle->merge(typingStyle.get()); + RefPtr<EditingStyle> typingStyle = EditingStyle::create(m_frame->selection()->typingStyle()); + typingStyle->removeNonEditingProperties(); + typingStyle->prepareToApplyAt(position); + mutableStyle->merge(typingStyle->style()); return mutableStyle; } diff --git a/WebCore/editing/Editor.h b/WebCore/editing/Editor.h index 110e3f9..24cdaf1 100644 --- a/WebCore/editing/Editor.h +++ b/WebCore/editing/Editor.h @@ -28,23 +28,13 @@ #include "ClipboardAccessPolicy.h" #include "Color.h" +#include "CorrectionPanelInfo.h" #include "EditAction.h" #include "EditingBehavior.h" #include "EditorDeleteAction.h" #include "EditorInsertAction.h" #include "SelectionController.h" -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) -// Some platforms provide UI for suggesting autocorrection. -#define SUPPORT_AUTOCORRECTION_PANEL 1 -// Some platforms use spelling and autocorrection markers to provide visual cue. -// On such platform, if word with marker is edited, we need to remove the marker. -#define REMOVE_MARKERS_UPON_EDITING 1 -#else -#define SUPPORT_AUTOCORRECTION_PANEL 0 -#define REMOVE_MARKERS_UPON_EDITING 0 -#endif /* #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) */ - #if PLATFORM(MAC) && !defined(__OBJC__) class NSDictionary; typedef int NSWritingDirection; @@ -219,6 +209,7 @@ public: Vector<String> guessesForUngrammaticalSelection(); Vector<String> guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical); bool isSpellCheckingEnabledInFocusedNode() const; + bool isSpellCheckingEnabledFor(Node*) const; void markMisspellingsAfterTypingToPosition(const VisiblePosition&); void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange); void markBadGrammar(const VisibleSelection&); @@ -322,7 +313,7 @@ public: void addToKillRing(Range*, bool prepend); void handleCancelOperation(); - void startCorrectionPanelTimer(); + void startCorrectionPanelTimer(CorrectionPanelInfo::PanelType); void handleRejectedCorrection(); bool isShowingCorrectionPanel(); @@ -388,9 +379,7 @@ private: bool m_shouldStartNewKillRingSequence; bool m_shouldStyleWithCSS; OwnPtr<KillRing> m_killRing; - RefPtr<Range> m_rangeToBeReplacedByCorrection; - String m_stringToBeReplacedByCorrection; - String m_correctionReplacementString; + CorrectionPanelInfo m_correctionPanelInfo; Timer<Editor> m_correctionPanelTimer; VisibleSelection m_mark; bool m_areMarkedTextMatchesHighlighted; @@ -417,6 +406,8 @@ private: void correctionPanelTimerFired(Timer<Editor>*); Node* findEventTargetFromSelection() const; void stopCorrectionPanelTimer(); + void dismissCorrectionPanel(CorrectionWasRejectedOrNot); + void applyCorrectionPanelInfo(bool addCorrectionIndicatorMarker); }; inline void Editor::setStartNewKillRingSequence(bool flag) diff --git a/WebCore/editing/EditorCommand.cpp b/WebCore/editing/EditorCommand.cpp index 85becd5..e3ea37e 100644 --- a/WebCore/editing/EditorCommand.cpp +++ b/WebCore/editing/EditorCommand.cpp @@ -618,8 +618,7 @@ static bool executeMoveBackwardAndModifySelection(Frame* frame, Event*, EditorCo static bool executeMoveDown(Frame* frame, Event*, EditorCommandSource, const String&) { - frame->selection()->modify(SelectionController::AlterationMove, SelectionController::DirectionForward, LineGranularity, true); - return true; + return frame->selection()->modify(SelectionController::AlterationMove, SelectionController::DirectionForward, LineGranularity, true); } static bool executeMoveDownAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&) @@ -642,8 +641,7 @@ static bool executeMoveForwardAndModifySelection(Frame* frame, Event*, EditorCom static bool executeMoveLeft(Frame* frame, Event*, EditorCommandSource, const String&) { - frame->selection()->modify(SelectionController::AlterationMove, SelectionController::DirectionLeft, CharacterGranularity, true); - return true; + return frame->selection()->modify(SelectionController::AlterationMove, SelectionController::DirectionLeft, CharacterGranularity, true); } static bool executeMoveLeftAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&) @@ -686,8 +684,7 @@ static bool executeMovePageUpAndModifySelection(Frame* frame, Event*, EditorComm static bool executeMoveRight(Frame* frame, Event*, EditorCommandSource, const String&) { - frame->selection()->modify(SelectionController::AlterationMove, SelectionController::DirectionRight, CharacterGranularity, true); - return true; + return frame->selection()->modify(SelectionController::AlterationMove, SelectionController::DirectionRight, CharacterGranularity, true); } static bool executeMoveRightAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&) @@ -806,8 +803,7 @@ static bool executeMoveParagraphForwardAndModifySelection(Frame* frame, Event*, static bool executeMoveUp(Frame* frame, Event*, EditorCommandSource, const String&) { - frame->selection()->modify(SelectionController::AlterationMove, SelectionController::DirectionBackward, LineGranularity, true); - return true; + return frame->selection()->modify(SelectionController::AlterationMove, SelectionController::DirectionBackward, LineGranularity, true); } static bool executeMoveUpAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&) @@ -1074,7 +1070,7 @@ static bool executeYankAndSelect(Frame* frame, Event*, EditorCommandSource, cons return true; } -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL static bool executeCancelOperation(Frame* frame, Event*, EditorCommandSource, const String&) { frame->editor()->handleCancelOperation(); @@ -1124,7 +1120,7 @@ static bool supportedPaste(Frame* frame, EditorCommandSource source) return false; } -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL static bool supportedDismissCorrectionPanel(Frame* frame, EditorCommandSource source) { return supportedFromMenuOrKeyBinding(frame, source) && frame->editor()->isShowingCorrectionPanel(); @@ -1506,7 +1502,7 @@ static const CommandMap& createCommandMap() { "Unselect", { executeUnselect, supported, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } }, { "Yank", { executeYank, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } }, { "YankAndSelect", { executeYankAndSelect, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } }, -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL { "CancelOperation", { executeCancelOperation, supportedDismissCorrectionPanel, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } }, #endif }; diff --git a/WebCore/editing/InsertLineBreakCommand.cpp b/WebCore/editing/InsertLineBreakCommand.cpp index 8ac1167..5588326 100644 --- a/WebCore/editing/InsertLineBreakCommand.cpp +++ b/WebCore/editing/InsertLineBreakCommand.cpp @@ -165,14 +165,14 @@ void InsertLineBreakCommand::doApply() // Handle the case where there is a typing style. - CSSMutableStyleDeclaration* typingStyle = document()->frame()->selection()->typingStyle(); + RefPtr<CSSMutableStyleDeclaration> typingStyle = document()->frame()->selection()->typingStyle(); if (typingStyle && typingStyle->length() > 0) { // Apply the typing style to the inserted line break, so that if the selection // leaves and then comes back, new input will have the right style. // FIXME: We shouldn't always apply the typing style to the line break here, // see <rdar://problem/5794462>. - applyStyle(typingStyle, firstDeepEditingPositionForNode(nodeToInsert.get()), lastDeepEditingPositionForNode(nodeToInsert.get())); + applyStyle(typingStyle.get(), firstDeepEditingPositionForNode(nodeToInsert.get()), lastDeepEditingPositionForNode(nodeToInsert.get())); // Even though this applyStyle operates on a Range, it still sets an endingSelection(). // It tries to set a VisibleSelection around the content it operated on. So, that VisibleSelection // will either (a) select the line break we inserted, or it will (b) be a caret just diff --git a/WebCore/editing/InsertParagraphSeparatorCommand.cpp b/WebCore/editing/InsertParagraphSeparatorCommand.cpp index 1804bf4..abd744c 100644 --- a/WebCore/editing/InsertParagraphSeparatorCommand.cpp +++ b/WebCore/editing/InsertParagraphSeparatorCommand.cpp @@ -26,19 +26,16 @@ #include "config.h" #include "InsertParagraphSeparatorCommand.h" -#include "CSSComputedStyleDeclaration.h" -#include "CSSMutableStyleDeclaration.h" #include "CSSPropertyNames.h" #include "Document.h" +#include "EditingStyle.h" #include "HTMLElement.h" #include "HTMLNames.h" #include "InsertLineBreakCommand.h" -#include "Logging.h" #include "RenderObject.h" #include "Text.h" #include "htmlediting.h" #include "visible_units.h" -#include "ApplyStyleCommand.h" namespace WebCore { @@ -82,7 +79,7 @@ void InsertParagraphSeparatorCommand::calculateStyleBeforeInsertion(const Positi if (!isStartOfParagraph(visiblePos) && !isEndOfParagraph(visiblePos)) return; - m_style = ApplyStyleCommand::editingStyleAtPosition(pos, IncludeTypingStyle); + m_style = editingStyleIncludingTypingStyle(pos); } void InsertParagraphSeparatorCommand::applyStyleAfterInsertion(Node* originalEnclosingBlock) @@ -95,14 +92,13 @@ void InsertParagraphSeparatorCommand::applyStyleAfterInsertion(Node* originalEnc originalEnclosingBlock->hasTagName(h4Tag) || originalEnclosingBlock->hasTagName(h5Tag)) return; - + if (!m_style) return; - - prepareEditingStyleToApplyAt(m_style.get(), endingSelection().start()); - if (m_style->length() > 0) - applyStyle(m_style.get()); + m_style->prepareToApplyAt(endingSelection().start()); + if (!m_style->isEmpty()) + applyStyle(m_style->style()); } bool InsertParagraphSeparatorCommand::shouldUseDefaultParagraphElement(Node* enclosingBlock) const diff --git a/WebCore/editing/InsertParagraphSeparatorCommand.h b/WebCore/editing/InsertParagraphSeparatorCommand.h index 23ee51c..2eae77d 100644 --- a/WebCore/editing/InsertParagraphSeparatorCommand.h +++ b/WebCore/editing/InsertParagraphSeparatorCommand.h @@ -30,6 +30,8 @@ namespace WebCore { +class EditingStyle; + class InsertParagraphSeparatorCommand : public CompositeEditCommand { public: static PassRefPtr<InsertParagraphSeparatorCommand> create(Document* document, bool useDefaultParagraphElement = false) @@ -46,13 +48,13 @@ private: void applyStyleAfterInsertion(Node* originalEnclosingBlock); void getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, Vector<Element*>& ancestors); PassRefPtr<Element> cloneHierarchyUnderNewBlock(const Vector<Element*>& ancestors, PassRefPtr<Element> blockToInsert); - + bool shouldUseDefaultParagraphElement(Node*) const; virtual bool preservesTypingStyle() const; - RefPtr<CSSMutableStyleDeclaration> m_style; - + RefPtr<EditingStyle> m_style; + bool m_mustUseDefaultParagraphElement; }; diff --git a/WebCore/editing/InsertTextCommand.cpp b/WebCore/editing/InsertTextCommand.cpp index b6c8236..87a695d 100644 --- a/WebCore/editing/InsertTextCommand.cpp +++ b/WebCore/editing/InsertTextCommand.cpp @@ -190,7 +190,7 @@ void InsertTextCommand::input(const String& text, bool selectInsertedText) setEndingSelection(forcedEndingSelection); // Handle the case where there is a typing style. - CSSMutableStyleDeclaration* typingStyle = document()->frame()->selection()->typingStyle(); + RefPtr<CSSMutableStyleDeclaration> typingStyle = document()->frame()->selection()->typingStyle(); RefPtr<CSSComputedStyleDeclaration> endingStyle = endPosition.computedStyle(); RefPtr<CSSValue> unicodeBidi; RefPtr<CSSValue> direction; @@ -198,7 +198,7 @@ void InsertTextCommand::input(const String& text, bool selectInsertedText) unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi); direction = typingStyle->getPropertyCSSValue(CSSPropertyDirection); } - endingStyle->diff(typingStyle); + endingStyle->diff(typingStyle.get()); if (typingStyle && unicodeBidi) { ASSERT(unicodeBidi->isPrimitiveValue()); typingStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent()); @@ -209,7 +209,7 @@ void InsertTextCommand::input(const String& text, bool selectInsertedText) } if (typingStyle && typingStyle->length()) - applyStyle(typingStyle); + applyStyle(typingStyle.get()); if (!selectInsertedText) setEndingSelection(VisibleSelection(endingSelection().end(), endingSelection().affinity())); diff --git a/WebCore/editing/RemoveFormatCommand.cpp b/WebCore/editing/RemoveFormatCommand.cpp index f8807e2..42833cb 100644 --- a/WebCore/editing/RemoveFormatCommand.cpp +++ b/WebCore/editing/RemoveFormatCommand.cpp @@ -28,18 +28,11 @@ #include "RemoveFormatCommand.h" #include "ApplyStyleCommand.h" -#include "CSSComputedStyleDeclaration.h" -#include "CSSMutableStyleDeclaration.h" -#include "CSSValueKeywords.h" -#include "Editor.h" +#include "EditingStyle.h" +#include "Element.h" #include "Frame.h" -#include "HTMLElement.h" #include "HTMLNames.h" -#include "VisibleSelection.h" #include "SelectionController.h" -#include "TextIterator.h" -#include "TypingCommand.h" -#include "htmlediting.h" namespace WebCore { @@ -92,9 +85,9 @@ void RemoveFormatCommand::doApply() // Get the default style for this editable root, it's the style that we'll give the // content that we're operating on. Node* root = frame->selection()->rootEditableElement(); - RefPtr<CSSMutableStyleDeclaration> defaultStyle = ApplyStyleCommand::editingStyleAtPosition(Position(root, 0)); + RefPtr<EditingStyle> defaultStyle = EditingStyle::create(root); - applyCommandToComposite(ApplyStyleCommand::create(document(), defaultStyle.get(), isElementForRemoveFormatCommand, editingAction())); + applyCommandToComposite(ApplyStyleCommand::create(document(), defaultStyle->style(), isElementForRemoveFormatCommand, editingAction())); } } diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp index 056ab70..fb52e56 100644 --- a/WebCore/editing/ReplaceSelectionCommand.cpp +++ b/WebCore/editing/ReplaceSelectionCommand.cpp @@ -31,7 +31,6 @@ #include "BreakBlockquoteCommand.h" #include "CSSComputedStyleDeclaration.h" #include "CSSMutableStyleDeclaration.h" -#include "CSSProperty.h" #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" #include "Document.h" @@ -484,17 +483,6 @@ void ReplaceSelectionCommand::negateStyleRulesThatAffectAppearance() e->getInlineStyleDecl()->setProperty(CSSPropertyDisplay, CSSValueInline); if (e->renderer() && e->renderer()->style()->floating() != FNONE) e->getInlineStyleDecl()->setProperty(CSSPropertyFloat, CSSValueNone); - - // Undo the effects of page zoom if we have an absolute font size. When we copy, we - // compute the new font size as an absolute size so pasting will cause the zoom to be - // applied twice. - if (e->renderer() && e->renderer()->style() && e->renderer()->style()->effectiveZoom() != 1.0 - && e->renderer()->style()->fontDescription().isAbsoluteSize()) { - float newSize = e->renderer()->style()->fontDescription().specifiedSize() / e->renderer()->style()->effectiveZoom(); - ExceptionCode ec = 0; - e->style()->setProperty(CSSPropertyFontSize, String::number(newSize), false, ec); - ASSERT(!ec); - } } if (node == m_lastLeafInserted) break; @@ -563,35 +551,36 @@ VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent() static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const Position& insertionPos) { Node* topNode = fragment.firstChild(); - + // Handling the case where we are doing Paste as Quotation or pasting into quoted content is more complicated (see handleStyleSpans) // and doesn't receive the optimization. if (isMailPasteAsQuotationNode(topNode) || nearestMailBlockquote(topNode)) return false; - + // Either there are no style spans in the fragment or a WebKit client has added content to the fragment // before inserting it. Look for and handle style spans after insertion. if (!isStyleSpan(topNode)) return false; - + Node* sourceDocumentStyleSpan = topNode; RefPtr<Node> copiedRangeStyleSpan = sourceDocumentStyleSpan->firstChild(); - RefPtr<CSSMutableStyleDeclaration> styleAtInsertionPos = ApplyStyleCommand::editingStyleAtPosition(rangeCompliantEquivalent(insertionPos)); + RefPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create(rangeCompliantEquivalent(insertionPos)); + String styleText = styleAtInsertionPos->style()->cssText(); - String styleText = styleAtInsertionPos->cssText(); - + // FIXME: This string comparison is a naive way of comparing two styles. + // We should be taking the diff and check that the diff is empty. if (styleText == static_cast<Element*>(sourceDocumentStyleSpan)->getAttribute(styleAttr)) { fragment.removeNodePreservingChildren(sourceDocumentStyleSpan); if (!isStyleSpan(copiedRangeStyleSpan.get())) return true; } - + if (isStyleSpan(copiedRangeStyleSpan.get()) && styleText == static_cast<Element*>(copiedRangeStyleSpan.get())->getAttribute(styleAttr)) { fragment.removeNodePreservingChildren(copiedRangeStyleSpan.get()); return true; } - + return false; } @@ -626,29 +615,20 @@ void ReplaceSelectionCommand::handleStyleSpans() // we are here because of a document.execCommand("InsertHTML", ...) call. if (!sourceDocumentStyleSpan) return; - - RefPtr<CSSMutableStyleDeclaration> sourceDocumentStyle = static_cast<HTMLElement*>(sourceDocumentStyleSpan)->getInlineStyleDecl()->copy(); + + RefPtr<EditingStyle> sourceDocumentStyle = EditingStyle::create(static_cast<HTMLElement*>(sourceDocumentStyleSpan)->getInlineStyleDecl()); ContainerNode* context = sourceDocumentStyleSpan->parentNode(); - + // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region, // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>. Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : nearestMailBlockquote(context); if (blockquoteNode) { - RefPtr<CSSMutableStyleDeclaration> blockquoteStyle = ApplyStyleCommand::editingStyleAtPosition(Position(blockquoteNode, 0)); - RefPtr<CSSMutableStyleDeclaration> parentStyle = ApplyStyleCommand::editingStyleAtPosition(Position(blockquoteNode->parentNode(), 0)); - parentStyle->diff(blockquoteStyle.get()); - - CSSMutableStyleDeclaration::const_iterator end = blockquoteStyle->end(); - for (CSSMutableStyleDeclaration::const_iterator it = blockquoteStyle->begin(); it != end; ++it) { - const CSSProperty& property = *it; - sourceDocumentStyle->removeProperty(property.id()); - } - + sourceDocumentStyle->removeStyleConflictingWithStyleOfNode(blockquoteNode); context = blockquoteNode->parentNode(); } // This operation requires that only editing styles to be removed from sourceDocumentStyle. - prepareEditingStyleToApplyAt(sourceDocumentStyle.get(), Position(context, 0)); + sourceDocumentStyle->prepareToApplyAt(firstPositionInNode(context)); // Remove block properties in the span's style. This prevents properties that probably have no effect // currently from affecting blocks later if the style is cloned for a new block element during a future @@ -656,49 +636,44 @@ void ReplaceSelectionCommand::handleStyleSpans() // FIXME: They *can* have an effect currently if blocks beneath the style span aren't individually marked // with block styles by the editing engine used to style them. WebKit doesn't do this, but others might. sourceDocumentStyle->removeBlockProperties(); - + // The styles on sourceDocumentStyleSpan are all redundant, and there is no copiedRangeStyleSpan // to consider. We're finished. - if (sourceDocumentStyle->length() == 0 && !copiedRangeStyleSpan) { + if (sourceDocumentStyle->isEmpty() && !copiedRangeStyleSpan) { removeNodePreservingChildren(sourceDocumentStyleSpan); return; } - + // There are non-redundant styles on sourceDocumentStyleSpan, but there is no // copiedRangeStyleSpan. Remove the span, because it could be surrounding block elements, // and apply the styles to its children. - if (sourceDocumentStyle->length() > 0 && !copiedRangeStyleSpan) { - copyStyleToChildren(sourceDocumentStyleSpan, sourceDocumentStyle.get()); + if (!sourceDocumentStyle->isEmpty() && !copiedRangeStyleSpan) { + copyStyleToChildren(sourceDocumentStyleSpan, sourceDocumentStyle->style()); removeNodePreservingChildren(sourceDocumentStyleSpan); return; } - RefPtr<CSSMutableStyleDeclaration> copiedRangeStyle = static_cast<HTMLElement*>(copiedRangeStyleSpan)->getInlineStyleDecl()->copy(); - + RefPtr<EditingStyle> copiedRangeStyle = EditingStyle::create(static_cast<HTMLElement*>(copiedRangeStyleSpan)->getInlineStyleDecl()); + // We're going to put sourceDocumentStyleSpan's non-redundant styles onto copiedRangeStyleSpan, // as long as they aren't overridden by ones on copiedRangeStyleSpan. - sourceDocumentStyle->merge(copiedRangeStyle.get(), true); - copiedRangeStyle = sourceDocumentStyle; - + copiedRangeStyle->style()->merge(sourceDocumentStyle->style(), false); + removeNodePreservingChildren(sourceDocumentStyleSpan); - + // Remove redundant styles. context = copiedRangeStyleSpan->parentNode(); - prepareEditingStyleToApplyAt(copiedRangeStyle.get(), Position(context, 0)); - - // See the comments above about removing block properties. + copiedRangeStyle->prepareToApplyAt(firstPositionInNode(context)); copiedRangeStyle->removeBlockProperties(); - - // All the styles on copiedRangeStyleSpan are redundant, remove it. - if (copiedRangeStyle->length() == 0) { + if (copiedRangeStyle->isEmpty()) { removeNodePreservingChildren(copiedRangeStyleSpan); return; } - + // Clear the redundant styles from the span's style attribute. // FIXME: If font-family:-webkit-monospace is non-redundant, then the font-size should stay, even if it // appears redundant. - setNodeAttribute(static_cast<Element*>(copiedRangeStyleSpan), styleAttr, copiedRangeStyle->cssText()); + setNodeAttribute(static_cast<Element*>(copiedRangeStyleSpan), styleAttr, copiedRangeStyle->style()->cssText()); } // Take the style attribute of a span and apply it to it's children instead. This allows us to @@ -810,9 +785,14 @@ void ReplaceSelectionCommand::doApply() if (performTrivialReplace(fragment)) return; - if (m_matchStyle) - m_insertionStyle = ApplyStyleCommand::editingStyleAtPosition(selection.start(), IncludeTypingStyle); + // We can skip matching the style if the selection is plain text. + if ((selection.start().node()->renderer() && selection.start().node()->renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY) && + (selection.end().node()->renderer() && selection.end().node()->renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY)) + m_matchStyle = false; + if (m_matchStyle) + m_insertionStyle = editingStyleIncludingTypingStyle(selection.start()); + VisiblePosition visibleStart = selection.visibleStart(); VisiblePosition visibleEnd = selection.visibleEnd(); @@ -1163,7 +1143,7 @@ void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi if (m_matchStyle) { ASSERT(m_insertionStyle); - applyStyle(m_insertionStyle.get(), start, end); + applyStyle(m_insertionStyle->style(), start, end); } if (lastPositionToSelect.isNotNull()) diff --git a/WebCore/editing/ReplaceSelectionCommand.h b/WebCore/editing/ReplaceSelectionCommand.h index e995e79..9fc4a49 100644 --- a/WebCore/editing/ReplaceSelectionCommand.h +++ b/WebCore/editing/ReplaceSelectionCommand.h @@ -31,6 +31,7 @@ namespace WebCore { class DocumentFragment; +class EditingStyle; class ReplacementFragment; class ReplaceSelectionCommand : public CompositeEditCommand { @@ -82,7 +83,7 @@ private: RefPtr<Node> m_firstNodeInserted; RefPtr<Node> m_lastLeafInserted; - RefPtr<CSSMutableStyleDeclaration> m_insertionStyle; + RefPtr<EditingStyle> m_insertionStyle; bool m_selectReplacement; bool m_smartReplace; bool m_matchStyle; diff --git a/WebCore/editing/SelectionController.cpp b/WebCore/editing/SelectionController.cpp index 6f25c86..bb42662 100644 --- a/WebCore/editing/SelectionController.cpp +++ b/WebCore/editing/SelectionController.cpp @@ -642,6 +642,8 @@ bool SelectionController::modify(EAlteration alter, EDirection direction, TextGr willBeModified(alter, direction); + bool wasRange = m_selection.isRange(); + Position originalStartPosition = m_selection.start(); VisiblePosition position; switch (direction) { case DirectionRight: @@ -673,6 +675,10 @@ bool SelectionController::modify(EAlteration alter, EDirection direction, TextGr if (position.isNull()) return false; + if (isSpatialNavigationEnabled(m_frame)) + if (!wasRange && alter == AlterationMove && position == originalStartPosition) + return false; + // Some of the above operations set an xPosForVerticalArrowNavigation. // Setting a selection will clear it, so save it to possibly restore later. // Note: the START position type is arbitrary because it is unused, it would be diff --git a/WebCore/editing/SelectionController.h b/WebCore/editing/SelectionController.h index e5fe71b..2edad0a 100644 --- a/WebCore/editing/SelectionController.h +++ b/WebCore/editing/SelectionController.h @@ -26,7 +26,7 @@ #ifndef SelectionController_h #define SelectionController_h -#include "CSSMutableStyleDeclaration.h" +#include "EditingStyle.h" #include "IntRect.h" #include "Range.h" #include "ScrollBehavior.h" @@ -37,6 +37,7 @@ namespace WebCore { class Frame; +class CSSMutableStyleDeclaration; class GraphicsContext; class HTMLFormElement; class RenderObject; @@ -160,7 +161,7 @@ public: void paintDragCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const; CSSMutableStyleDeclaration* typingStyle() const; - void setTypingStyle(PassRefPtr<CSSMutableStyleDeclaration>); + void setTypingStyle(PassRefPtr<EditingStyle>); void clearTypingStyle(); FloatRect bounds(bool clipToVisibleContent = true) const; @@ -214,7 +215,7 @@ private: VisibleSelection m_selection; TextGranularity m_granularity; - RefPtr<CSSMutableStyleDeclaration> m_typingStyle; + RefPtr<EditingStyle> m_typingStyle; Timer<SelectionController> m_caretBlinkTimer; @@ -234,7 +235,7 @@ private: inline CSSMutableStyleDeclaration* SelectionController::typingStyle() const { - return m_typingStyle.get(); + return m_typingStyle ? m_typingStyle->style() : 0; } inline void SelectionController::clearTypingStyle() @@ -242,7 +243,7 @@ inline void SelectionController::clearTypingStyle() m_typingStyle.clear(); } -inline void SelectionController::setTypingStyle(PassRefPtr<CSSMutableStyleDeclaration> style) +inline void SelectionController::setTypingStyle(PassRefPtr<EditingStyle> style) { m_typingStyle = style; } diff --git a/WebCore/editing/TypingCommand.cpp b/WebCore/editing/TypingCommand.cpp index d78708b..9165a3e 100644 --- a/WebCore/editing/TypingCommand.cpp +++ b/WebCore/editing/TypingCommand.cpp @@ -311,9 +311,9 @@ void TypingCommand::markMisspellingsAfterTyping(ETypingCommand commandType) VisiblePosition p2 = startOfWord(start, LeftWordIfOnBoundary); if (p1 != p2) document()->frame()->editor()->markMisspellingsAfterTypingToPosition(p1); -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if SUPPORT_AUTOCORRECTION_PANEL else if (commandType == TypingCommand::InsertText) - document()->frame()->editor()->startCorrectionPanelTimer(); + document()->frame()->editor()->startCorrectionPanelTimer(CorrectionPanelInfo::PanelTypeCorrection); #else UNUSED_PARAM(commandType); #endif diff --git a/WebCore/editing/markup.cpp b/WebCore/editing/markup.cpp index 75d567e..417de71 100644 --- a/WebCore/editing/markup.cpp +++ b/WebCore/editing/markup.cpp @@ -26,10 +26,8 @@ #include "config.h" #include "markup.h" -#include "ApplyStyleCommand.h" #include "CDATASection.h" #include "CharacterNames.h" -#include "Comment.h" #include "CSSComputedStyleDeclaration.h" #include "CSSMutableStyleDeclaration.h" #include "CSSPrimitiveValue.h" @@ -49,11 +47,8 @@ #include "HTMLBodyElement.h" #include "HTMLElement.h" #include "HTMLNames.h" -#include "InlineTextBox.h" #include "KURL.h" -#include "Logging.h" #include "MarkupAccumulator.h" -#include "ProcessingInstruction.h" #include "Range.h" #include "TextIterator.h" #include "VisibleSelection.h" @@ -525,23 +520,6 @@ static Node* highestAncestorToWrapMarkup(const Range* range, Node* fullySelected return specialCommonAncestor; } -static void removeEnclosingMailBlockquoteStyle(CSSMutableStyleDeclaration* style, Node* node) -{ - Node* blockquote = nearestMailBlockquote(node); - if (!blockquote || !blockquote->parentNode()) - return; - - removeStylesAddedByNode(style, blockquote); -} - -static void removeDefaultStyles(CSSMutableStyleDeclaration* style, Document* document) -{ - if (!document || !document->documentElement()) - return; - - prepareEditingStyleToApplyAt(style, Position(document->documentElement(), 0)); -} - // FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange? // FIXME: At least, annotation and style info should probably not be included in range.markupString() String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs) @@ -650,34 +628,34 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc // Add a wrapper span with the styles that all of the nodes in the markup inherit. ContainerNode* parentOfLastClosed = lastClosed ? lastClosed->parentNode() : 0; if (parentOfLastClosed && parentOfLastClosed->renderer()) { - RefPtr<CSSMutableStyleDeclaration> style = ApplyStyleCommand::editingStyleAtPosition(Position(parentOfLastClosed, 0)); + RefPtr<EditingStyle> style = EditingStyle::create(parentOfLastClosed); // Styles that Mail blockquotes contribute should only be placed on the Mail blockquote, to help // us differentiate those styles from ones that the user has applied. This helps us // get the color of content pasted into blockquotes right. - removeEnclosingMailBlockquoteStyle(style.get(), parentOfLastClosed); - + style->removeStyleAddedByNode(nearestMailBlockquote(parentOfLastClosed)); + // Document default styles will be added on another wrapper span. - removeDefaultStyles(style.get(), document); - + if (document && document->documentElement()) + style->prepareToApplyAt(firstPositionInNode(document->documentElement())); + // Since we are converting blocks to inlines, remove any inherited block properties that are in the style. // This cuts out meaningless properties and prevents properties from magically affecting blocks later // if the style is cloned for a new block element during a future editing operation. if (convertBlocksToInlines) style->removeBlockProperties(); - if (style->length() > 0) - accumulator.wrapWithStyleNode(style.get(), document); + if (!style->isEmpty()) + accumulator.wrapWithStyleNode(style->style(), document); } if (lastClosed && lastClosed != document->documentElement()) { // Add a style span with the document's default styles. We add these in a separate // span so that at paste time we can differentiate between document defaults and user // applied styles. - RefPtr<CSSMutableStyleDeclaration> defaultStyle = ApplyStyleCommand::editingStyleAtPosition(Position(document->documentElement(), 0)); - - if (defaultStyle->length() > 0) - accumulator.wrapWithStyleNode(defaultStyle.get(), document); + RefPtr<EditingStyle> defaultStyle = EditingStyle::create(document->documentElement()); + if (!defaultStyle->isEmpty()) + accumulator.wrapWithStyleNode(defaultStyle->style(), document); } // FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally. diff --git a/WebCore/fileapi/LocalFileSystem.cpp b/WebCore/fileapi/LocalFileSystem.cpp index c7347b8..721fdf5 100644 --- a/WebCore/fileapi/LocalFileSystem.cpp +++ b/WebCore/fileapi/LocalFileSystem.cpp @@ -76,15 +76,21 @@ String LocalFileSystem::fileSystemBasePath() const return m_basePath; } -static void openFileSystem(ScriptExecutionContext*, const String& basePath, const String& identifier, AsyncFileSystem::Type type, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) +static void openFileSystem(ScriptExecutionContext*, const String& basePath, const String& identifier, AsyncFileSystem::Type type, bool create, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) { - AsyncFileSystem::openFileSystem(basePath, identifier, type, callbacks); + AsyncFileSystem::openFileSystem(basePath, identifier, type, create, callbacks); +} + +void LocalFileSystem::readFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) +{ + // AsyncFileSystem::openFileSystem calls callbacks synchronously, so the method needs to be called asynchronously. + context->postTask(createCallbackTask(&openFileSystem, fileSystemBasePath(), context->securityOrigin()->databaseIdentifier(), type, false, callbacks)); } void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long, PassOwnPtr<AsyncFileSystemCallbacks> callbacks, bool) { // AsyncFileSystem::openFileSystem calls callbacks synchronously, so the method needs to be called asynchronously. - context->postTask(createCallbackTask(&openFileSystem, fileSystemBasePath(), context->securityOrigin()->databaseIdentifier(), type, callbacks)); + context->postTask(createCallbackTask(&openFileSystem, fileSystemBasePath(), context->securityOrigin()->databaseIdentifier(), type, true, callbacks)); } } // namespace diff --git a/WebCore/fileapi/LocalFileSystem.h b/WebCore/fileapi/LocalFileSystem.h index 9d8ae65..b779a5f 100644 --- a/WebCore/fileapi/LocalFileSystem.h +++ b/WebCore/fileapi/LocalFileSystem.h @@ -52,6 +52,9 @@ public: // calling this one. static LocalFileSystem& localFileSystem(); + // Does not create the root path for file system, just reads it if available. + void readFileSystem(ScriptExecutionContext*, AsyncFileSystem::Type, long long size, PassOwnPtr<AsyncFileSystemCallbacks>); + void requestFileSystem(ScriptExecutionContext*, AsyncFileSystem::Type, long long size, PassOwnPtr<AsyncFileSystemCallbacks>, bool synchronous = false); #if !PLATFORM(CHROMIUM) diff --git a/WebCore/history/BackForwardController.cpp b/WebCore/history/BackForwardController.cpp index 9f557ac..d388f19 100644 --- a/WebCore/history/BackForwardController.cpp +++ b/WebCore/history/BackForwardController.cpp @@ -26,26 +26,82 @@ #include "config.h" #include "BackForwardController.h" -#include "BackForwardControllerClient.h" -#include "BackForwardList.h" #include "BackForwardListImpl.h" +#include "HistoryItem.h" +#include "Page.h" namespace WebCore { -BackForwardController::BackForwardController(Page* page, BackForwardControllerClient* client) +BackForwardController::BackForwardController(Page* page, PassRefPtr<BackForwardList> client) : m_page(page) , m_client(client) { if (!m_client) - m_list = BackForwardListImpl::create(page); - else - m_list = m_client->createBackForwardList(page); + m_client = BackForwardListImpl::create(page); } BackForwardController::~BackForwardController() { - if (m_client) - m_client->backForwardControllerDestroyed(); +} + +bool BackForwardController::canGoBackOrForward(int distance) const +{ + return m_page->canGoBackOrForward(distance); +} + +void BackForwardController::goBackOrForward(int distance) +{ + m_page->goBackOrForward(distance); +} + +bool BackForwardController::goBack() +{ + return m_page->goBack(); +} + +bool BackForwardController::goForward() +{ + return m_page->goForward(); +} + +void BackForwardController::addItem(PassRefPtr<HistoryItem> item) +{ + m_client->addItem(item); +} + +void BackForwardController::setCurrentItem(HistoryItem* item) +{ + m_client->goToItem(item); +} + +int BackForwardController::count() const +{ + return m_page->getHistoryLength(); +} + +int BackForwardController::backCount() const +{ + return m_client->backListCount(); +} + +int BackForwardController::forwardCount() const +{ + return m_client->forwardListCount(); +} + +HistoryItem* BackForwardController::itemAtIndex(int i) +{ + return m_client->itemAtIndex(i); +} + +bool BackForwardController::isActive() +{ + return m_client->isActive(); +} + +void BackForwardController::close() +{ + m_client->close(); } } // namespace WebCore diff --git a/WebCore/history/BackForwardController.h b/WebCore/history/BackForwardController.h index 02c13a1..e89e32b 100644 --- a/WebCore/history/BackForwardController.h +++ b/WebCore/history/BackForwardController.h @@ -26,27 +26,49 @@ #ifndef BackForwardController_h #define BackForwardController_h -#include "BackForwardList.h" #include <wtf/Noncopyable.h> +#include <wtf/Forward.h> #include <wtf/RefPtr.h> namespace WebCore { +class BackForwardList; +class HistoryItem; class Page; -class BackForwardControllerClient; class BackForwardController : public Noncopyable { public: - BackForwardController(Page*, BackForwardControllerClient*); + BackForwardController(Page*, PassRefPtr<BackForwardList>); ~BackForwardController(); - BackForwardControllerClient* client() const { return m_client; } - BackForwardList* list() const { return m_list.get(); } + BackForwardList* client() const { return m_client.get(); } + + bool canGoBackOrForward(int distance) const; + void goBackOrForward(int distance); + + bool goBack(); + bool goForward(); + + void addItem(PassRefPtr<HistoryItem>); + void setCurrentItem(HistoryItem*); + + int count() const; + int backCount() const; + int forwardCount() const; + + HistoryItem* itemAtIndex(int); + + bool isActive(); + + void close(); + + HistoryItem* backItem() { return itemAtIndex(-1); } + HistoryItem* currentItem() { return itemAtIndex(0); } + HistoryItem* forwardItem() { return itemAtIndex(1); } private: Page* m_page; - BackForwardControllerClient* m_client; - RefPtr<BackForwardList> m_list; + RefPtr<BackForwardList> m_client; }; } // namespace WebCore diff --git a/WebCore/history/BackForwardList.h b/WebCore/history/BackForwardList.h index b622a9d..212eadd 100644 --- a/WebCore/history/BackForwardList.h +++ b/WebCore/history/BackForwardList.h @@ -28,39 +28,13 @@ #ifndef BackForwardList_h #define BackForwardList_h +#include <wtf/Forward.h> #include <wtf/RefCounted.h> -#include <wtf/PassRefPtr.h> -#include <wtf/Vector.h> namespace WebCore { class HistoryItem; -// FIXME: Remove this and rely on the typedef in BackForwardListImpl -// instead, after removing the virtual functions at the bottom -// of this class. -typedef Vector<RefPtr<HistoryItem> > HistoryItemVector; - -// FIXME: Move this class out of this file and into BackForwardListImpl. -// FIXME: Consider replacing this BackForwardListClient concept with a -// function that creates a BackForwardList object. The functions in -// BackForwardList are now almost identical to this, and there is no -// need for the extra level of indirection. -#if PLATFORM(CHROMIUM) -// In the Chromium port, the back/forward list is managed externally. -// See BackForwardListChromium.cpp -class BackForwardListClient { -public: - virtual ~BackForwardListClient() {} - virtual void addItem(PassRefPtr<HistoryItem>) = 0; - virtual void goToItem(HistoryItem*) = 0; - virtual HistoryItem* itemAtIndex(int) = 0; - virtual int backListCount() = 0; - virtual int forwardListCount() = 0; - virtual void close() = 0; -}; -#endif - // FIXME: Rename this class to BackForwardClient, and rename the // getter in Page accordingly. class BackForwardList : public RefCounted<BackForwardList> { @@ -69,13 +43,6 @@ public: { } - // FIXME: Move this function to BackForwardListImpl, or eliminate - // it (see comment at definition of BackForwardListClient class). -#if PLATFORM(CHROMIUM) - // Must be called before any other methods. - virtual void setClient(BackForwardListClient*) = 0; -#endif - virtual void addItem(PassRefPtr<HistoryItem>) = 0; virtual void goToItem(HistoryItem*) = 0; @@ -88,42 +55,21 @@ public: virtual void close() = 0; +#if ENABLE(WML) // FIXME: Rename this to just "clear" and change it so it's not // WML-specific. This is the same operation as clearBackForwardList // in the layout test controller; it would be reasonable to have it // here even though HTML DOM interfaces don't require it. -#if ENABLE(WML) virtual void clearWMLPageHistory() = 0; #endif + // FIXME: Delete these once all callers are using BackForwardController + // instead of calling this directly. HistoryItem* backItem() { return itemAtIndex(-1); } HistoryItem* currentItem() { return itemAtIndex(0); } HistoryItem* forwardItem() { return itemAtIndex(1); } - - // FIXME: Remove these functions once all call sites are calling them - // directly on BackForwardListImpl instead of on BackForwardList. - // There is no need for any of these to be virtual functions and no - // need to implement them in classes other than BackForwardListImpl. - // Also remove the HistoryItemVector typedef in this file once this is done. - virtual void goBack() { } - virtual void goForward() { } - virtual void backListWithLimit(int, HistoryItemVector&) { } - virtual void forwardListWithLimit(int, HistoryItemVector&) { } - virtual int capacity() { return 0; } - virtual void setCapacity(int) { } - virtual bool enabled() { return false; } - virtual void setEnabled(bool) { } - virtual bool containsItem(HistoryItem*) { return false; } - virtual bool closed() { return false; } - virtual void removeItem(HistoryItem*) { } - virtual HistoryItemVector& entries() { HistoryItemVector* bogus = 0; return *bogus; } - -protected: - BackForwardList() - { - } }; - + } // namespace WebCore #endif // BackForwardList_h diff --git a/WebCore/history/BackForwardListImpl.h b/WebCore/history/BackForwardListImpl.h index 2f08cfe..30043fa 100644 --- a/WebCore/history/BackForwardListImpl.h +++ b/WebCore/history/BackForwardListImpl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * Copyright (C) 2009 Google, Inc. All rights reserved. * @@ -30,6 +30,7 @@ #include "BackForwardList.h" #include <wtf/HashSet.h> +#include <wtf/Vector.h> namespace WebCore { @@ -38,6 +39,25 @@ class Page; typedef Vector<RefPtr<HistoryItem> > HistoryItemVector; typedef HashSet<RefPtr<HistoryItem> > HistoryItemHashSet; +// FIXME: Change Chromium to use its own BackForwardList implementation +// and not use BackForwardListImpl at all, then remove this +// BackForwardListClient feature entirely and just don't use this +// class on Chromium. +#if PLATFORM(CHROMIUM) +// In the Chromium port, the back/forward list is managed externally. +// See BackForwardListChromium.cpp +class BackForwardListClient { +public: + virtual ~BackForwardListClient() { } + virtual void addItem(PassRefPtr<HistoryItem>) = 0; + virtual void goToItem(HistoryItem*) = 0; + virtual HistoryItem* itemAtIndex(int) = 0; + virtual int backListCount() = 0; + virtual int forwardListCount() = 0; + virtual void close() = 0; +}; +#endif + // FIXME: After renaming BackForwardList to BackForwardClient, // rename this to BackForwardList. class BackForwardListImpl : public BackForwardList { @@ -47,7 +67,7 @@ public: #if PLATFORM(CHROMIUM) // Must be called before any other methods. - virtual void setClient(BackForwardListClient* client) { m_client = client; } + void setClient(BackForwardListClient* client) { m_client = client; } #endif Page* page() { return m_page; } diff --git a/WebCore/history/CachedFrame.cpp b/WebCore/history/CachedFrame.cpp index a3ef401..f2ce27d 100644 --- a/WebCore/history/CachedFrame.cpp +++ b/WebCore/history/CachedFrame.cpp @@ -90,7 +90,7 @@ void CachedFrameBase::restore() m_document->accessSVGExtensions()->unpauseAnimations(); #endif - frame->animation()->resumeAnimations(m_document.get()); + frame->animation()->resumeAnimationsForDocument(m_document.get()); frame->eventHandler()->setMousePressNode(m_mousePressNode.get()); m_document->resumeActiveDOMObjects(); diff --git a/WebCore/history/PageCache.cpp b/WebCore/history/PageCache.cpp index 30c3b42..7375a9c 100644 --- a/WebCore/history/PageCache.cpp +++ b/WebCore/history/PageCache.cpp @@ -27,8 +27,8 @@ #include "PageCache.h" #include "ApplicationCacheHost.h" -#include "BackForwardList.h" -#include "Cache.h" +#include "BackForwardController.h" +#include "MemoryCache.h" #include "CachedPage.h" #include "DOMWindow.h" #include "DeviceMotionController.h" @@ -192,7 +192,7 @@ static void logCanCachePageDecision(Page* page) bool cannotCache = !logCanCacheFrameDecision(page->mainFrame(), 1); FrameLoadType loadType = page->mainFrame()->loader()->loadType(); - if (!page->backForwardList()->isActive()) { + if (!page->backForward()->isActive()) { PCLOG(" -The back/forward list is disabled or has 0 capacity"); cannotCache = true; } @@ -303,7 +303,7 @@ bool PageCache::canCache(Page* page) FrameLoadType loadType = page->mainFrame()->loader()->loadType(); return canCachePageContainingThisFrame(page->mainFrame()) - && page->backForwardList()->isActive() + && page->backForward()->isActive() && page->settings()->usesPageCache() #if ENABLE(DEVICE_ORIENTATION) && !(page->deviceMotionController() && page->deviceMotionController()->isActive()) diff --git a/WebCore/html/DOMSettableTokenList.cpp b/WebCore/html/DOMSettableTokenList.cpp index 2636bd3..3a86e9c 100644 --- a/WebCore/html/DOMSettableTokenList.cpp +++ b/WebCore/html/DOMSettableTokenList.cpp @@ -40,7 +40,7 @@ DOMSettableTokenList::~DOMSettableTokenList() const AtomicString DOMSettableTokenList::item(unsigned index) const { if (index >= length()) - return AtomicString(""); + return AtomicString(); return m_tokens[index]; } @@ -61,7 +61,10 @@ void DOMSettableTokenList::add(const AtomicString& token, ExceptionCode& ec) void DOMSettableTokenList::addInternal(const AtomicString& token) { m_value = addToken(m_value, token); - m_tokens.add(token); + if (m_tokens.isNull()) + m_tokens.set(token, false); + else + m_tokens.add(token); } void DOMSettableTokenList::remove(const AtomicString& token, ExceptionCode& ec) @@ -92,7 +95,7 @@ bool DOMSettableTokenList::toggle(const AtomicString& token, ExceptionCode& ec) void DOMSettableTokenList::setValue(const String& value) { m_value = value; - m_tokens.set(value, true); + m_tokens.set(value, false); } } // namespace WebCore diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp index 710cda1..8fa000f 100644 --- a/WebCore/html/HTMLFormControlElement.cpp +++ b/WebCore/html/HTMLFormControlElement.cpp @@ -45,6 +45,7 @@ #include "RenderTextControl.h" #include "RenderTheme.h" #include "ScriptEventListener.h" +#include "ValidationMessage.h" #include "ValidityState.h" #include <limits> #include <wtf/Vector.h> @@ -77,6 +78,12 @@ HTMLFormControlElement::~HTMLFormControlElement() m_form->removeFormElement(this); } +void HTMLFormControlElement::detach() +{ + hideVisibleValidationMessage(); + HTMLElement::detach(); +} + bool HTMLFormControlElement::formNoValidate() const { return !getAttribute(formnovalidateAttr).isNull(); @@ -301,7 +308,8 @@ void HTMLFormControlElement::setNeedsWillValidateCheck() m_willValidateInitialized = true; m_willValidate = newWillValidate; setNeedsStyleRecalc(); - // FIXME: Show/hide a validation message. + if (!m_willValidate) + hideVisibleValidationMessage(); } String HTMLFormControlElement::validationMessage() @@ -309,6 +317,42 @@ String HTMLFormControlElement::validationMessage() return validity()->validationMessage(); } +void HTMLFormControlElement::updateVisibleValidationMessage() +{ + Page* page = document()->page(); + if (!page) + return; + String message; + if (renderer() && willValidate()) { + message = validationMessage().stripWhiteSpace(); + // HTML5 specification doesn't ask UA to show the title attribute value + // with the validationMessage. However, this behavior is same as Opera + // and the specification describes such behavior as an example. + const AtomicString& title = getAttribute(titleAttr); + if (!message.isEmpty() && !title.isEmpty()) { + message.append('\n'); + message.append(title); + } + } + if (!m_validationMessage) { + m_validationMessage = ValidationMessage::create(this); + m_validationMessage->setMessage(message); + } else if (message.isEmpty()) + hideVisibleValidationMessage(); + else if (m_validationMessage->message() != message) + m_validationMessage->setMessage(message); +} + +void HTMLFormControlElement::hideVisibleValidationMessage() +{ + m_validationMessage = 0; +} + +String HTMLFormControlElement::visibleValidationMessage() const +{ + return m_validationMessage ? m_validationMessage->message() : String(); +} + bool HTMLFormControlElement::checkValidity(Vector<RefPtr<HTMLFormControlElement> >* unhandledInvalidControls) { if (!willValidate() || isValidFormControlElement()) @@ -338,7 +382,13 @@ void HTMLFormControlElement::setNeedsValidityCheck() setNeedsStyleRecalc(); } m_isValid = newIsValid; - // FIXME: show/hide a validation message. + + // Updates only if this control already has a validtion message. + if (!visibleValidationMessage().isEmpty()) { + // Calls updateVisibleValidationMessage() even if m_isValid is not + // changed because a validation message can be chagned. + updateVisibleValidationMessage(); + } } void HTMLFormControlElement::setCustomValidity(const String& error) @@ -360,6 +410,7 @@ void HTMLFormControlElement::dispatchBlurEvent() document()->page()->chrome()->client()->formDidBlur(this); HTMLElement::dispatchBlurEvent(); + hideVisibleValidationMessage(); } HTMLFormElement* HTMLFormControlElement::virtualForm() const @@ -568,7 +619,7 @@ void HTMLTextFormControlElement::setSelectionRange(int start, int end) WebCore::setSelectionRange(this, start, end); } -int HTMLTextFormControlElement::selectionStart() +int HTMLTextFormControlElement::selectionStart() const { if (!isTextFormControl()) return 0; @@ -579,7 +630,7 @@ int HTMLTextFormControlElement::selectionStart() return toRenderTextControl(renderer())->selectionStart(); } -int HTMLTextFormControlElement::selectionEnd() +int HTMLTextFormControlElement::selectionEnd() const { if (!isTextFormControl()) return 0; diff --git a/WebCore/html/HTMLFormControlElement.h b/WebCore/html/HTMLFormControlElement.h index 8b721d8..1960fc3 100644 --- a/WebCore/html/HTMLFormControlElement.h +++ b/WebCore/html/HTMLFormControlElement.h @@ -31,6 +31,7 @@ namespace WebCore { class FormDataList; class HTMLFormElement; class RenderTextControl; +class ValidationMessage; class ValidityState; class VisibleSelection; @@ -84,6 +85,8 @@ public: virtual bool willValidate() const; String validationMessage(); + void updateVisibleValidationMessage(); + void hideVisibleValidationMessage(); bool checkValidity(Vector<RefPtr<HTMLFormControlElement> >* unhandledInvalidControls = 0); // This must be called when a validation constraint or control value is changed. void setNeedsValidityCheck(); @@ -111,6 +114,7 @@ protected: virtual void dispatchFocusEvent(); virtual void dispatchBlurEvent(); + virtual void detach(); void removeFromForm(); @@ -131,9 +135,11 @@ private: virtual HTMLFormElement* virtualForm() const; virtual bool isDefaultButtonForForm() const; virtual bool isValidFormControlElement(); + String visibleValidationMessage() const; HTMLFormElement* m_form; OwnPtr<ValidityState> m_validityState; + OwnPtr<ValidationMessage> m_validationMessage; bool m_disabled : 1; bool m_readOnly : 1; bool m_required : 1; @@ -182,8 +188,8 @@ public: String strippedPlaceholder() const; bool placeholderShouldBeVisible() const; - int selectionStart(); - int selectionEnd(); + int selectionStart() const; + int selectionEnd() const; void setSelectionStart(int); void setSelectionEnd(int); void select(); diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp index 31a72bd..da388d5 100644 --- a/WebCore/html/HTMLFormElement.cpp +++ b/WebCore/html/HTMLFormElement.cpp @@ -205,6 +205,9 @@ bool HTMLFormElement::validateInteractively(Event* event) if (submitElement && submitElement->formNoValidate()) return true; + for (unsigned i = 0; i < m_associatedElements.size(); ++i) + m_associatedElements[i]->hideVisibleValidationMessage(); + Vector<RefPtr<HTMLFormControlElement> > unhandledInvalidControls; collectUnhandledInvalidControls(unhandledInvalidControls); if (unhandledInvalidControls.isEmpty()) @@ -212,7 +215,7 @@ bool HTMLFormElement::validateInteractively(Event* event) // If the form has invalid controls, abort submission. RefPtr<HTMLFormElement> protector(this); - // Focus on the first focusable control. + // Focus on the first focusable control and show a validation message. for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) { HTMLFormControlElement* unhandled = unhandledInvalidControls[i].get(); if (unhandled->isFocusable() && unhandled->inDocument()) { @@ -223,6 +226,7 @@ bool HTMLFormElement::validateInteractively(Event* event) // moved to another document. if (unhandled->isFocusable() && unhandled->inDocument() && originalDocument == unhandled->document()) { unhandled->focus(); + unhandled->updateVisibleValidationMessage(); break; } } diff --git a/WebCore/html/HTMLFrameElementBase.cpp b/WebCore/html/HTMLFrameElementBase.cpp index d153845..cba82a2 100644 --- a/WebCore/html/HTMLFrameElementBase.cpp +++ b/WebCore/html/HTMLFrameElementBase.cpp @@ -92,8 +92,6 @@ bool HTMLFrameElementBase::isURLAllowed() const void HTMLFrameElementBase::openURL(bool lockHistory, bool lockBackForwardList) { - ASSERT(!m_frameName.isEmpty()); - if (!isURLAllowed()) return; @@ -155,9 +153,6 @@ void HTMLFrameElementBase::setName() m_frameName = getAttribute(nameAttr); if (m_frameName.isNull()) m_frameName = getIdAttribute(); - - if (Frame* parentFrame = document()->frame()) - m_frameName = parentFrame->tree()->uniqueChildName(m_frameName); } void HTMLFrameElementBase::setNameAndOpenURL() diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp index cd826bf..b7b05b1 100644 --- a/WebCore/html/HTMLInputElement.cpp +++ b/WebCore/html/HTMLInputElement.cpp @@ -338,7 +338,7 @@ bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const if (deprecatedInputType() == RADIO) { // When using Spatial Navigation, every radio button should be focusable. - if (document()->frame() && document()->frame()->settings() && document()->frame()->settings()->isSpatialNavigationEnabled()) + if (isSpatialNavigationEnabled(document()->frame())) return true; // Never allow keyboard tabbing to leave you in the same radio group. Always diff --git a/WebCore/html/HTMLLinkElement.cpp b/WebCore/html/HTMLLinkElement.cpp index 6a5c2f6..9303076 100644 --- a/WebCore/html/HTMLLinkElement.cpp +++ b/WebCore/html/HTMLLinkElement.cpp @@ -199,6 +199,7 @@ void HTMLLinkElement::process() if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty()) document()->setIconURL(m_url.string(), type); +<<<<<<< HEAD #ifdef ANDROID_APPLE_TOUCH_ICON if ((m_relAttribute.m_isTouchIcon || m_relAttribute.m_isPrecomposedTouchIcon) && m_url.isValid() && !m_url.isEmpty() && document()->frame()) @@ -209,6 +210,15 @@ void HTMLLinkElement::process() if (m_relAttribute.m_isDNSPrefetch && document()->isDNSPrefetchEnabled() && m_url.isValid() && !m_url.isEmpty()) ResourceHandle::prepareForURL(m_url); +======= + if (m_relAttribute.m_isDNSPrefetch) { + Settings* settings = document()->settings(); + // FIXME: The href attribute of the link element can be in "//hostname" form, and we shouldn't attempt + // to complete that as URL <https://bugs.webkit.org/show_bug.cgi?id=48857>. + if (settings && settings->dnsPrefetchingEnabled() && m_url.isValid() && !m_url.isEmpty()) + ResourceHandle::prepareForURL(m_url); + } +>>>>>>> webkit.org at r71558 #if ENABLE(LINK_PREFETCH) if (m_relAttribute.m_isLinkPrefetch && m_url.isValid() && document()->frame()) diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp index 3f6c286..5b75dde 100644 --- a/WebCore/html/HTMLMediaElement.cpp +++ b/WebCore/html/HTMLMediaElement.cpp @@ -1119,6 +1119,18 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec) float earliestTime = m_player->startTime(); time = max(time, earliestTime); + // Ask the media engine for the time value in the movie's time scale before comparing with current time. This + // is necessary because if the seek time is not equal to currentTime but the delta is less than the movie's + // time scale, we will ask the media engine to "seek" to the current movie time, which may be a noop and + // not generate a timechanged callback. This means m_seeking will never be cleared and we will never + // fire a 'seeked' event. +#if !LOG_DISABLED + float mediaTime = m_player->mediaTimeForTimeValue(time); + if (time != mediaTime) + LOG(Media, "HTMLMediaElement::seek(%f) - media timeline equivalent is %f", time, mediaTime); +#endif + time = m_player->mediaTimeForTimeValue(time); + // 7 - If the (possibly now changed) new playback position is not in one of the ranges given in the // seekable attribute, then let it be the position in one of the ranges given in the seekable attribute // that is the nearest to the new playback position. ... If there are no ranges given in the seekable diff --git a/WebCore/html/HTMLOutputElement.cpp b/WebCore/html/HTMLOutputElement.cpp new file mode 100644 index 0000000..dee21ae --- /dev/null +++ b/WebCore/html/HTMLOutputElement.cpp @@ -0,0 +1,137 @@ +/* + * 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 "HTMLOutputElement.h" + +#include "HTMLFormElement.h" +#include "HTMLNames.h" + +namespace WebCore { + +inline HTMLOutputElement::HTMLOutputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) + : HTMLFormControlElement(tagName, document, form) + , m_isDefaultValueMode(true) + , m_isSetTextContentInProgress(false) + , m_defaultValue() + , m_tokens(DOMSettableTokenList::create()) +{ +} + +PassRefPtr<HTMLOutputElement> HTMLOutputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form) +{ + return adoptRef(new HTMLOutputElement(tagName, document, form)); +} + +const AtomicString& HTMLOutputElement::formControlType() const +{ + DEFINE_STATIC_LOCAL(const AtomicString, output, ("output")); + return output; +} + +void HTMLOutputElement::parseMappedAttribute(Attribute* attr) +{ + // FIXME: Should handle the 'form' attribute here. + if (attr->name() == HTMLNames::forAttr) + setFor(attr->value()); + else + HTMLFormControlElement::parseMappedAttribute(attr); +} + +DOMSettableTokenList* HTMLOutputElement::htmlFor() const +{ + return m_tokens.get(); +} + +void HTMLOutputElement::setFor(const String& value) +{ + m_tokens->setValue(value); +} + +void HTMLOutputElement::setForm(const String& /*id*/) +{ + // FIXME: Implement this function. +} + +void HTMLOutputElement::childrenChanged(bool createdByParser, Node*, Node*, int) +{ + if (createdByParser || m_isSetTextContentInProgress) { + m_isSetTextContentInProgress = false; + return; + } + + if (m_isDefaultValueMode) + m_defaultValue = textContent(); +} + +void HTMLOutputElement::reset() +{ + // The reset algorithm for output elements is to set the element's + // value mode flag to "default" and then to set the element's textContent + // attribute to the default value. + m_isDefaultValueMode = true; + setTextContentInternal(m_defaultValue); +} + +String HTMLOutputElement::value() const +{ + return textContent(); +} + +void HTMLOutputElement::setValue(const String& value) +{ + // The value mode flag set to "value" when the value attribute is set. + m_isDefaultValueMode = false; + setTextContentInternal(value); +} + +String HTMLOutputElement::defaultValue() const +{ + return m_defaultValue; +} + +void HTMLOutputElement::setDefaultValue(const String& value) +{ + m_defaultValue = value; + // The spec requires the value attribute set to the default value + // when the element's value mode flag to "default". + if (m_isDefaultValueMode) + setTextContentInternal(value); +} + +void HTMLOutputElement::setTextContentInternal(const String& value) +{ + ASSERT(!m_isSetTextContentInProgress); + ExceptionCode ec; + m_isSetTextContentInProgress = true; + setTextContent(value, ec); +} + +} // namespace diff --git a/WebCore/html/HTMLOutputElement.h b/WebCore/html/HTMLOutputElement.h new file mode 100644 index 0000000..df807fb --- /dev/null +++ b/WebCore/html/HTMLOutputElement.h @@ -0,0 +1,73 @@ +/* + * 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 HTMLOutputElement_h +#define HTMLOutputElement_h + +#include "DOMSettableTokenList.h" +#include "HTMLFormControlElement.h" +#include <wtf/OwnPtr.h> + +namespace WebCore { + +class HTMLOutputElement : public HTMLFormControlElement { +public: + static PassRefPtr<HTMLOutputElement> create(const QualifiedName&, Document*, HTMLFormElement*); + + virtual bool willValidate() const { return false; } + + void setForm(const String&); + String value() const; + void setValue(const String&); + String defaultValue() const; + void setDefaultValue(const String&); + void setFor(const String&); + DOMSettableTokenList* htmlFor() const; + +private: + HTMLOutputElement(const QualifiedName&, Document*, HTMLFormElement*); + + virtual void parseMappedAttribute(Attribute*); + virtual const AtomicString& formControlType() const; + virtual bool isEnumeratable() const { return true; } + virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + virtual void reset(); + + void setTextContentInternal(const String&); + + bool m_isDefaultValueMode; + bool m_isSetTextContentInProgress; + String m_defaultValue; + RefPtr<DOMSettableTokenList> m_tokens; +}; + +} // namespace + +#endif diff --git a/WebCore/html/HTMLOutputElement.idl b/WebCore/html/HTMLOutputElement.idl new file mode 100644 index 0000000..4e6cbfb --- /dev/null +++ b/WebCore/html/HTMLOutputElement.idl @@ -0,0 +1,43 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module html { + interface HTMLOutputElement : HTMLElement { + attribute [Custom] DOMSettableTokenList htmlFor; + readonly attribute HTMLFormElement form; + attribute [Reflect] DOMString name; + + readonly attribute DOMString type; + attribute [ConvertNullToNullString] DOMString defaultValue; + attribute [ConvertNullToNullString] DOMString value; + + readonly attribute boolean willValidate; + readonly attribute ValidityState validity; + readonly attribute DOMString validationMessage; + boolean checkValidity(); + void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error); + + readonly attribute NodeList labels; + }; +} diff --git a/WebCore/html/HTMLTableElement.cpp b/WebCore/html/HTMLTableElement.cpp index fe823ea..f6344d4 100644 --- a/WebCore/html/HTMLTableElement.cpp +++ b/WebCore/html/HTMLTableElement.cpp @@ -424,8 +424,8 @@ void HTMLTableElement::parseMappedAttribute(Attribute* attr) } else if (attr->name() == alignAttr) { if (!attr->value().isEmpty()) { if (equalIgnoringCase(attr->value(), "center")) { - addCSSProperty(attr, CSSPropertyMarginLeft, CSSValueAuto); - addCSSProperty(attr, CSSPropertyMarginRight, CSSValueAuto); + addCSSProperty(attr, CSSPropertyWebkitMarginStart, CSSValueAuto); + addCSSProperty(attr, CSSPropertyWebkitMarginEnd, CSSValueAuto); } else addCSSProperty(attr, CSSPropertyFloat, attr->value()); } diff --git a/WebCore/html/HTMLTagNames.in b/WebCore/html/HTMLTagNames.in index 209636d..2b2c1fe 100644 --- a/WebCore/html/HTMLTagNames.in +++ b/WebCore/html/HTMLTagNames.in @@ -93,6 +93,7 @@ object constructorNeedsCreatedByParser ol interfaceName=HTMLOListElement optgroup interfaceName=HTMLOptGroupElement, constructorNeedsFormElement option constructorNeedsFormElement +output constructorNeedsFormElement p interfaceName=HTMLParagraphElement param plaintext interfaceName=HTMLElement diff --git a/WebCore/html/ValidationMessage.cpp b/WebCore/html/ValidationMessage.cpp new file mode 100644 index 0000000..d32917e --- /dev/null +++ b/WebCore/html/ValidationMessage.cpp @@ -0,0 +1,70 @@ +/* + * 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 "ValidationMessage.h" + +#include <wtf/PassOwnPtr.h> + +namespace WebCore { + +ALWAYS_INLINE ValidationMessage::ValidationMessage(HTMLFormControlElement* element) + : m_element(element) +{ +} + +ValidationMessage::~ValidationMessage() +{ + hideMessage(); +} + +PassOwnPtr<ValidationMessage> ValidationMessage::create(HTMLFormControlElement* element) +{ + return adoptPtr(new ValidationMessage(element)); +} + +void ValidationMessage::setMessage(const String& message) +{ + // FIXME: Construct validation message UI if m_message is empty. + + m_message = message; + + m_timer.set(new Timer<ValidationMessage>(this, &ValidationMessage::hideMessage)); + m_timer->startOneShot(6.0); // FIXME: should be <message length> * something. +} + +void ValidationMessage::hideMessage(Timer<ValidationMessage>*) +{ + // FIXME: Implement. + + m_message = String(); +} + +} // namespace WebCore diff --git a/WebCore/html/ValidationMessage.h b/WebCore/html/ValidationMessage.h new file mode 100644 index 0000000..fe18b6b --- /dev/null +++ b/WebCore/html/ValidationMessage.h @@ -0,0 +1,61 @@ +/* + * 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 ValidationMessage_h +#define ValidationMessage_h + +#include "Timer.h" +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class HTMLFormControlElement; + +class ValidationMessage : public Noncopyable { +public: + static PassOwnPtr<ValidationMessage> create(HTMLFormControlElement*); + ~ValidationMessage(); + String message() const { return m_message; } + void setMessage(const String&); + +private: + ValidationMessage(HTMLFormControlElement*); + void hideMessage(Timer<ValidationMessage>* = 0); + + HTMLFormControlElement* m_element; + String m_message; + OwnPtr<Timer<ValidationMessage> > m_timer; +}; + +} // namespace WebCore + +#endif // ValidationMessage_h diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp index b1d7b23..a2d9e98 100644 --- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -1582,6 +1582,15 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, return 0; } + if (sw < 0) { + sx += sw; + sw = -sw; + } + if (sh < 0) { + sy += sh; + sh = -sh; + } + FloatRect unscaledRect(sx, sy, sw, sh); IntRect scaledRect = canvas()->convertLogicalToDevice(unscaledRect); if (scaledRect.width() < 1) diff --git a/WebCore/html/canvas/WebGLContextEvent.cpp b/WebCore/html/canvas/WebGLContextEvent.cpp new file mode 100644 index 0000000..b7a277f --- /dev/null +++ b/WebCore/html/canvas/WebGLContextEvent.cpp @@ -0,0 +1,54 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebGLContextEvent.h" + +namespace WebCore { + +WebGLContextEvent::WebGLContextEvent() +{ +} + +WebGLContextEvent::WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage) + : Event(type, canBubble, cancelable) + , m_statusMessage(statusMessage) +{ +} + +WebGLContextEvent::~WebGLContextEvent() +{ +} + +void WebGLContextEvent::initEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage) +{ + if (dispatched()) + return; + + Event::initEvent(type, canBubble, cancelable); + m_statusMessage = statusMessage; +} + +} // namespace WebCore diff --git a/WebCore/html/canvas/WebGLContextEvent.h b/WebCore/html/canvas/WebGLContextEvent.h new file mode 100644 index 0000000..348769b --- /dev/null +++ b/WebCore/html/canvas/WebGLContextEvent.h @@ -0,0 +1,58 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebGLContextEvent_h +#define WebGLContextEvent_h + +#include "Event.h" + +namespace WebCore { + +class WebGLContextEvent : public Event { +public: + static PassRefPtr<WebGLContextEvent> create() + { + return adoptRef(new WebGLContextEvent); + } + static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage) + { + return adoptRef(new WebGLContextEvent(type, canBubble, cancelable, statusMessage)); + } + virtual ~WebGLContextEvent(); + + void initEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage); + + const String& statusMessage() const { return m_statusMessage; } + +private: + WebGLContextEvent(); + WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage); + + String m_statusMessage; +}; + +} // namespace WebCore + +#endif // WebGLContextEvent_h diff --git a/WebCore/html/canvas/WebGLContextEvent.idl b/WebCore/html/canvas/WebGLContextEvent.idl new file mode 100644 index 0000000..30973a9 --- /dev/null +++ b/WebCore/html/canvas/WebGLContextEvent.idl @@ -0,0 +1,36 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module html { + interface [ + Conditional=3D_CANVAS, + ] WebGLContextEvent : Event { + readonly attribute DOMString statusMessage; + [StrictTypeChecking] void initEvent(in DOMString eventTypeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in DOMString statusMessageArg); + }; +} diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp index 0fdcb99..5bf3779 100644 --- a/WebCore/html/canvas/WebGLFramebuffer.cpp +++ b/WebCore/html/canvas/WebGLFramebuffer.cpp @@ -32,7 +32,42 @@ #include "WebGLRenderingContext.h" namespace WebCore { - + +namespace { + + // This function is only for depth/stencil/depth_stencil attachment. + // Currently we assume these attachments are all renderbuffers. + unsigned long getInternalFormat(WebGLObject* buffer) + { + ASSERT(buffer && buffer->isRenderbuffer()); + return (reinterpret_cast<WebGLRenderbuffer*>(buffer))->getInternalFormat(); + } + + bool isUninitialized(WebGLObject* attachedObject) + { + if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer() + && !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized()) + return true; + return false; + } + + void setInitialized(WebGLObject* attachedObject) + { + if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()) + (reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized(); + } + + bool isValid(WebGLObject* attachedObject) + { + if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()) { + if (!(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isValid()) + return false; + } + return true; + } + +} // anonymous namespace + PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx) { return adoptRef(new WebGLFramebuffer(ctx)); @@ -66,7 +101,24 @@ void WebGLFramebuffer::setAttachment(unsigned long attachment, WebGLObject* atta default: return; } - initializeRenderbuffers(); +} + +WebGLObject* WebGLFramebuffer::getAttachment(unsigned long attachment) const +{ + if (!object()) + return 0; + switch (attachment) { + case GraphicsContext3D::COLOR_ATTACHMENT0: + return m_colorAttachment.get(); + case GraphicsContext3D::DEPTH_ATTACHMENT: + return m_depthAttachment.get(); + case GraphicsContext3D::STENCIL_ATTACHMENT: + return m_stencilAttachment.get(); + case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT: + return m_depthStencilAttachment.get(); + default: + return 0; + } } void WebGLFramebuffer::removeAttachment(WebGLObject* attachment) @@ -83,25 +135,9 @@ void WebGLFramebuffer::removeAttachment(WebGLObject* attachment) m_depthStencilAttachment = 0; else return; - initializeRenderbuffers(); -} - -void WebGLFramebuffer::onBind() -{ - initializeRenderbuffers(); } -void WebGLFramebuffer::onAttachedObjectChange(WebGLObject* object) -{ - // Currently object == 0 is not considered, but this might change if the - // lifespan of WebGLObject changes. - if (object - && (object == m_colorAttachment.get() || object == m_depthAttachment.get() - || object == m_stencilAttachment.get() || object == m_depthStencilAttachment.get())) - initializeRenderbuffers(); -} - -unsigned long WebGLFramebuffer::getColorBufferFormat() +unsigned long WebGLFramebuffer::getColorBufferFormat() const { if (object() && m_colorAttachment && m_colorAttachment->object()) { if (m_colorAttachment->isRenderbuffer()) { @@ -119,6 +155,38 @@ unsigned long WebGLFramebuffer::getColorBufferFormat() return 0; } +bool WebGLFramebuffer::isIncomplete(bool checkInternalFormat) const +{ + unsigned int count = 0; + if (isDepthAttached()) { + if (checkInternalFormat && getInternalFormat(m_depthAttachment.get()) != GraphicsContext3D::DEPTH_COMPONENT16) + return true; + count++; + } + if (isStencilAttached()) { + if (checkInternalFormat && getInternalFormat(m_stencilAttachment.get()) != GraphicsContext3D::STENCIL_INDEX8) + return true; + count++; + } + if (isDepthStencilAttached()) { + if (checkInternalFormat && getInternalFormat(m_depthStencilAttachment.get()) != GraphicsContext3D::DEPTH_STENCIL) + return true; + if (!isValid(m_depthStencilAttachment.get())) + return true; + count++; + } + if (count > 1) + return true; + return false; +} + +bool WebGLFramebuffer::onAccess() +{ + if (isIncomplete(true)) + return false; + return initializeRenderbuffers(); +} + void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object) { if (!isDeleted()) @@ -129,24 +197,11 @@ void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object) m_depthStencilAttachment = 0; } -bool WebGLFramebuffer::isUninitialized(WebGLObject* attachedObject) +bool WebGLFramebuffer::initializeRenderbuffers() { - if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer() - && !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized()) - return true; - return false; -} - -void WebGLFramebuffer::setInitialized(WebGLObject* attachedObject) -{ - if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()) - (reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized(); -} - -void WebGLFramebuffer::initializeRenderbuffers() -{ - if (!object()) - return; + ASSERT(object()); + if (!isColorAttached()) + return false; bool initColor = false, initDepth = false, initStencil = false; unsigned long mask = 0; if (isUninitialized(m_colorAttachment.get())) { @@ -167,13 +222,13 @@ void WebGLFramebuffer::initializeRenderbuffers() mask |= (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT); } if (!initColor && !initDepth && !initStencil) - return; + return true; // We only clear un-initialized renderbuffers when they are ready to be // read, i.e., when the framebuffer is complete. GraphicsContext3D* g3d = context()->graphicsContext3D(); if (g3d->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) - return; + return false; float colorClearValue[] = {0, 0, 0, 0}, depthClearValue = 0; int stencilClearValue = 0; @@ -237,6 +292,7 @@ void WebGLFramebuffer::initializeRenderbuffers() if (initStencil) setInitialized(m_stencilAttachment.get()); } + return true; } } diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h index 1892694..394b770 100644 --- a/WebCore/html/canvas/WebGLFramebuffer.h +++ b/WebCore/html/canvas/WebGLFramebuffer.h @@ -39,27 +39,22 @@ public: static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*); - bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); } - bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); } - bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); } - void setAttachment(unsigned long, WebGLObject*); // If an object is attached to the framebuffer, remove it. void removeAttachment(WebGLObject*); + WebGLObject* getAttachment(unsigned long) const; - // This function is called right after a framebuffer is bound. - // Because renderbuffers and textures attached to the framebuffer might - // have changed and the framebuffer might have become complete when it - // isn't bound, so we need to clear un-initialized renderbuffers. - void onBind(); + unsigned long getColorBufferFormat() const; - // When a texture or a renderbuffer changes, we need to check the - // current bound framebuffer; if the newly changed object is attached - // to the framebuffer and the framebuffer becomes complete, we need to - // clear un-initialized renderbuffers. - void onAttachedObjectChange(WebGLObject*); + // This should always be called before drawArray, drawElements, clear, + // readPixels, copyTexImage2D, copyTexSubImage2D if this framebuffer is + // currently bound. + // Return false if the framebuffer is incomplete; otherwise initialize + // the buffers if they haven't been initialized. + bool onAccess(); - unsigned long getColorBufferFormat(); + // Return false does not mean COMPLETE, might still be INCOMPLETE. + bool isIncomplete(bool checkInternalFormat) const; protected: WebGLFramebuffer(WebGLRenderingContext*); @@ -69,9 +64,13 @@ protected: private: virtual bool isFramebuffer() const { return true; } - bool isUninitialized(WebGLObject*); - void setInitialized(WebGLObject*); - void initializeRenderbuffers(); + // Return false if framebuffer is incomplete. + bool initializeRenderbuffers(); + + bool isColorAttached() const { return (m_colorAttachment && m_colorAttachment->object()); } + bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); } + bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); } + bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); } RefPtr<WebGLObject> m_colorAttachment; RefPtr<WebGLObject> m_depthAttachment; diff --git a/WebCore/html/canvas/WebGLRenderbuffer.cpp b/WebCore/html/canvas/WebGLRenderbuffer.cpp index 4772873..b9efd47 100644 --- a/WebCore/html/canvas/WebGLRenderbuffer.cpp +++ b/WebCore/html/canvas/WebGLRenderbuffer.cpp @@ -42,6 +42,9 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx) : WebGLObject(ctx) , m_internalFormat(GraphicsContext3D::RGBA4) , m_initialized(false) + , m_width(0) + , m_height(0) + , m_isValid(true) { setObject(context()->graphicsContext3D()->createRenderbuffer()); } diff --git a/WebCore/html/canvas/WebGLRenderbuffer.h b/WebCore/html/canvas/WebGLRenderbuffer.h index 5765061..9a23ca5 100644 --- a/WebCore/html/canvas/WebGLRenderbuffer.h +++ b/WebCore/html/canvas/WebGLRenderbuffer.h @@ -39,9 +39,24 @@ public: static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*); - void setInternalFormat(unsigned long internalformat) { m_internalFormat = internalformat; } + void setInternalFormat(unsigned long internalformat) + { + m_internalFormat = internalformat; + m_initialized = false; + } unsigned long getInternalFormat() const { return m_internalFormat; } + void setSize(unsigned long width, unsigned long height) + { + m_width = width; + m_height = height; + } + unsigned long getWidth() const { return m_width; } + unsigned long getHeight() const { return m_height; } + + void setIsValid(bool isValid) { m_isValid = isValid; } + bool isValid() const { return m_isValid; } + bool isInitialized() const { return m_initialized; } void setInitialized() { m_initialized = true; } @@ -55,6 +70,8 @@ private: unsigned long m_internalFormat; bool m_initialized; + unsigned long m_width, m_height; + bool m_isValid; // This is only false if internalFormat is DEPTH_STENCIL and packed_depth_stencil is not supported. }; } // namespace WebCore diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp index 0b89cce..94dac10 100644 --- a/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -34,6 +34,7 @@ #include "CheckedInt.h" #include "Console.h" #include "DOMWindow.h" +#include "Extensions3D.h" #include "FrameView.h" #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" @@ -48,6 +49,7 @@ #include "WebGLActiveInfo.h" #include "WebGLBuffer.h" #include "WebGLContextAttributes.h" +#include "WebGLContextEvent.h" #include "WebGLFramebuffer.h" #include "WebGLProgram.h" #include "WebGLRenderbuffer.h" @@ -90,8 +92,10 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen GraphicsContext3D::Attributes emptyAttributes; RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attrs ? attrs->attributes() : emptyAttributes, hostWindow)); - if (!context) + if (!context) { + canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context.")); return 0; + } return new WebGLRenderingContext(canvas, context); } @@ -99,32 +103,41 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context) : CanvasRenderingContext(passedCanvas) , m_context(context) - , m_needsUpdate(true) - , m_markedCanvasDirty(false) - , m_activeTextureUnit(0) , m_videoCache(4) - , m_packAlignment(4) - , m_unpackAlignment(4) - , m_unpackFlipY(false) - , m_unpackPremultiplyAlpha(false) + , m_contextLost(false) + , m_stencilMask(0xFFFFFFFF) + , m_stencilFuncRef(0) + , m_stencilFuncMask(0xFFFFFFFF) { ASSERT(m_context); + initializeNewContext(); +} + +void WebGLRenderingContext::initializeNewContext() +{ + m_needsUpdate = true; + m_markedCanvasDirty = false; + m_activeTextureUnit = 0; + m_packAlignment = 4; + m_unpackAlignment = 4; + m_unpackFlipY = false; + m_unpackPremultiplyAlpha = false; + m_boundArrayBuffer = 0; + m_boundElementArrayBuffer = 0; + m_currentProgram = 0; + m_framebufferBinding = 0; + m_renderbufferBinding = 0; + m_vertexAttribState.clear(); int numCombinedTextureImageUnits = 0; m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits); + m_textureUnits.clear(); m_textureUnits.resize(numCombinedTextureImageUnits); int numVertexAttribs = 0; m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs); m_maxVertexAttribs = numVertexAttribs; - int implementationColorReadFormat = GraphicsContext3D::RGBA; - m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT, &implementationColorReadFormat); - m_implementationColorReadFormat = implementationColorReadFormat; - int implementationColorReadType = GraphicsContext3D::UNSIGNED_BYTE; - m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE, &implementationColorReadType); - m_implementationColorReadType = implementationColorReadType; - m_maxTextureSize = 0; m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize); m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize); @@ -136,6 +149,12 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa createFallbackBlackTextures1x1(); if (!isGLES2Compliant()) initVertexAttrib0(); + + if (isGLES2Compliant()) + m_isDepthStencilSupported = m_context->getExtensions()->supports("GL_OES_packed_depth_stencil"); + else + m_isDepthStencilSupported = m_context->getExtensions()->supports("GL_EXT_packed_depth_stencil"); + m_context->reshape(canvas()->width(), canvas()->height()); m_context->viewport(0, 0, canvas()->width(), canvas()->height()); } @@ -199,6 +218,8 @@ int WebGLRenderingContext::sizeInBytes(int type) void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return; @@ -211,7 +232,7 @@ void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(program) || !validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader)) return; if (!program->attachShader(shader)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); @@ -225,7 +246,7 @@ void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* sha void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return; m_context->bindAttribLocation(objectOrZero(program), index, name); cleanupAfterGraphicsCall(false); @@ -234,6 +255,8 @@ void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned l void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (buffer && buffer->context() != this) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; @@ -262,6 +285,8 @@ void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (buffer && buffer->context() != this) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; @@ -272,14 +297,14 @@ void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuff } m_framebufferBinding = buffer; m_context->bindFramebuffer(target, objectOrZero(buffer)); - if (m_framebufferBinding) - m_framebufferBinding->onBind(); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (renderBuffer && renderBuffer->context() != this) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; @@ -297,6 +322,8 @@ void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbu void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (texture && texture->context() != this) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; @@ -330,13 +357,15 @@ void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* text void WebGLRenderingContext::blendColor(double red, double green, double blue, double alpha) { + if (isContextLost()) + return; m_context->blendColor(red, green, blue, alpha); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::blendEquation(unsigned long mode) { - if (!validateBlendEquation(mode)) + if (isContextLost() || !validateBlendEquation(mode)) return; m_context->blendEquation(mode); cleanupAfterGraphicsCall(false); @@ -344,7 +373,7 @@ void WebGLRenderingContext::blendEquation(unsigned long mode) void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha) { - if (!validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha)) + if (isContextLost() || !validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha)) return; m_context->blendEquationSeparate(modeRGB, modeAlpha); cleanupAfterGraphicsCall(false); @@ -353,12 +382,16 @@ void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigne void WebGLRenderingContext::blendFunc(unsigned long sfactor, unsigned long dfactor) { + if (isContextLost() || !validateBlendFuncFactors(sfactor, dfactor)) + return; m_context->blendFunc(sfactor, dfactor); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha) { + if (isContextLost() || !validateBlendFuncFactors(srcRGB, dstRGB)) + return; m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); cleanupAfterGraphicsCall(false); } @@ -366,6 +399,8 @@ void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned lon void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; WebGLBuffer* buffer = validateBufferDataParameters(target, usage); if (!buffer) return; @@ -383,6 +418,8 @@ void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; WebGLBuffer* buffer = validateBufferDataParameters(target, usage); if (!buffer) return; @@ -400,6 +437,8 @@ void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data, void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; WebGLBuffer* buffer = validateBufferDataParameters(target, usage); if (!buffer) return; @@ -417,6 +456,8 @@ void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* da void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBuffer* data, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW); if (!buffer) return; @@ -434,6 +475,8 @@ void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, Arr void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW); if (!buffer) return; @@ -450,28 +493,40 @@ void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, Arr unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target) { + if (isContextLost()) + return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED; if (target != GraphicsContext3D::FRAMEBUFFER) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return 0; } if (!m_framebufferBinding || !m_framebufferBinding->object()) return GraphicsContext3D::FRAMEBUFFER_COMPLETE; + if (m_framebufferBinding->isIncomplete(true)) + return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED; return m_context->checkFramebufferStatus(target); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::clear(unsigned long mask) { + if (isContextLost()) + return; if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; } + if (m_framebufferBinding && !m_framebufferBinding->onAccess()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + return; + } m_context->clear(mask); cleanupAfterGraphicsCall(true); } void WebGLRenderingContext::clearColor(double r, double g, double b, double a) { + if (isContextLost()) + return; if (isnan(r)) r = 0; if (isnan(g)) @@ -486,18 +541,24 @@ void WebGLRenderingContext::clearColor(double r, double g, double b, double a) void WebGLRenderingContext::clearDepth(double depth) { + if (isContextLost()) + return; m_context->clearDepth(depth); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::clearStencil(long s) { + if (isContextLost()) + return; m_context->clearStencil(s); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alpha) { + if (isContextLost()) + return; m_context->colorMask(red, green, blue, alpha); cleanupAfterGraphicsCall(false); } @@ -505,7 +566,7 @@ void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alph void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject(shader)) return; m_context->compileShader(objectOrZero(shader)); cleanupAfterGraphicsCall(false); @@ -513,6 +574,8 @@ void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border) { + if (isContextLost()) + return; if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE)) return; WebGLTexture* tex = validateTextureBinding(target, true); @@ -530,16 +593,20 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; } + if (m_framebufferBinding && !m_framebufferBinding->onAccess()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + return; + } m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); // FIXME: if the framebuffer is not complete, none of the below should be executed. tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE); - if (m_framebufferBinding) - m_framebufferBinding->onAttachedObjectChange(tex); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height) { + if (isContextLost()) + return; WebGLTexture* tex = validateTextureBinding(target, true); if (!tex) return; @@ -551,12 +618,18 @@ void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level, return; } } + if (m_framebufferBinding && !m_framebufferBinding->onAccess()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + return; + } m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); cleanupAfterGraphicsCall(false); } PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer() { + if (isContextLost()) + return 0; RefPtr<WebGLBuffer> o = WebGLBuffer::create(this); addObject(o.get()); return o; @@ -564,6 +637,8 @@ PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer() PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer() { + if (isContextLost()) + return 0; RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this); addObject(o.get()); return o; @@ -571,6 +646,8 @@ PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer() PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture() { + if (isContextLost()) + return 0; RefPtr<WebGLTexture> o = WebGLTexture::create(this); addObject(o.get()); return o; @@ -578,6 +655,8 @@ PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture() PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram() { + if (isContextLost()) + return 0; RefPtr<WebGLProgram> o = WebGLProgram::create(this); addObject(o.get()); return o; @@ -585,6 +664,8 @@ PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram() PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer() { + if (isContextLost()) + return 0; RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this); addObject(o.get()); return o; @@ -593,6 +674,8 @@ PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer() PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return 0; if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return 0; @@ -605,13 +688,15 @@ PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, void WebGLRenderingContext::cullFace(unsigned long mode) { + if (isContextLost()) + return; m_context->cullFace(mode); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer) { - if (!buffer) + if (isContextLost() || !buffer) return; buffer->deleteObject(); @@ -633,7 +718,7 @@ void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer) void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer) { - if (!framebuffer) + if (isContextLost() || !framebuffer) return; if (framebuffer == m_framebufferBinding) { m_framebufferBinding = 0; @@ -645,7 +730,7 @@ void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer) void WebGLRenderingContext::deleteProgram(WebGLProgram* program) { - if (!program) + if (isContextLost() || !program) return; if (program->context() != this) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); @@ -658,7 +743,7 @@ void WebGLRenderingContext::deleteProgram(WebGLProgram* program) void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer) { - if (!renderbuffer) + if (isContextLost() || !renderbuffer) return; if (renderbuffer == m_renderbufferBinding) m_renderbufferBinding = 0; @@ -669,7 +754,7 @@ void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer) void WebGLRenderingContext::deleteShader(WebGLShader* shader) { - if (!shader) + if (isContextLost() || !shader) return; shader->deleteObject(); @@ -677,7 +762,7 @@ void WebGLRenderingContext::deleteShader(WebGLShader* shader) void WebGLRenderingContext::deleteTexture(WebGLTexture* texture) { - if (!texture) + if (isContextLost() || !texture) return; texture->deleteObject(); @@ -687,18 +772,28 @@ void WebGLRenderingContext::deleteTexture(WebGLTexture* texture) void WebGLRenderingContext::depthFunc(unsigned long func) { + if (isContextLost()) + return; m_context->depthFunc(func); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::depthMask(bool flag) { + if (isContextLost()) + return; m_context->depthMask(flag); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::depthRange(double zNear, double zFar) { + if (isContextLost()) + return; + if (zNear > zFar) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } m_context->depthRange(zNear, zFar); cleanupAfterGraphicsCall(false); } @@ -706,7 +801,7 @@ void WebGLRenderingContext::depthRange(double zNear, double zFar) void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(program) || !validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader)) return; if (!program->detachShader(shader)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); @@ -720,7 +815,7 @@ void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* sha void WebGLRenderingContext::disable(unsigned long cap) { - if (!validateCapability(cap)) + if (isContextLost() || !validateCapability(cap)) return; m_context->disable(cap); cleanupAfterGraphicsCall(false); @@ -729,6 +824,8 @@ void WebGLRenderingContext::disable(unsigned long cap) void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (index >= m_maxVertexAttribs) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; @@ -925,7 +1022,7 @@ void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long coun { UNUSED_PARAM(ec); - if (!validateDrawMode(mode)) + if (isContextLost() || !validateDrawMode(mode)) return; if (first < 0 || count < 0) { @@ -952,6 +1049,11 @@ void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long coun } } + if (m_framebufferBinding && !m_framebufferBinding->onAccess()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + return; + } + bool vertexAttrib0Simulated = false; if (!isGLES2Compliant()) vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1); @@ -969,7 +1071,7 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne { UNUSED_PARAM(ec); - if (!validateDrawMode(mode)) + if (isContextLost() || !validateDrawMode(mode)) return; switch (type) { @@ -1011,6 +1113,11 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne } } + if (m_framebufferBinding && !m_framebufferBinding->onAccess()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + return; + } + bool vertexAttrib0Simulated = false; if (!isGLES2Compliant()) { if (!numElements) @@ -1029,7 +1136,7 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne void WebGLRenderingContext::enable(unsigned long cap) { - if (!validateCapability(cap)) + if (isContextLost() || !validateCapability(cap)) return; m_context->enable(cap); cleanupAfterGraphicsCall(false); @@ -1038,6 +1145,8 @@ void WebGLRenderingContext::enable(unsigned long cap) void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (index >= m_maxVertexAttribs) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; @@ -1054,6 +1163,8 @@ void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, Excepti void WebGLRenderingContext::finish() { + if (isContextLost()) + return; m_context->finish(); cleanupAfterGraphicsCall(true); } @@ -1061,6 +1172,8 @@ void WebGLRenderingContext::finish() void WebGLRenderingContext::flush() { + if (isContextLost()) + return; m_context->flush(); cleanupAfterGraphicsCall(true); } @@ -1068,7 +1181,7 @@ void WebGLRenderingContext::flush() void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateFramebufferFuncParameters(target, attachment)) + if (isContextLost() || !validateFramebufferFuncParameters(target, attachment)) return; if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); @@ -1085,42 +1198,61 @@ void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsign m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } - if (buffer && buffer->object()) { - bool isConflicted = false; - switch (attachment) { - case GraphicsContext3D::DEPTH_ATTACHMENT: - if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isStencilAttached()) - isConflicted = true; - if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16) - isConflicted = true; - break; - case GraphicsContext3D::STENCIL_ATTACHMENT: - if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isDepthAttached()) - isConflicted = true; - if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8) - isConflicted = true; - break; - case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT: - if (m_framebufferBinding->isDepthAttached() || m_framebufferBinding->isStencilAttached()) - isConflicted = true; - if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL) - isConflicted = true; - break; - } - if (isConflicted) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); - return; + Platform3DObject bufferObject = objectOrZero(buffer); + bool reattachDepth = false; + bool reattachStencil = false; + bool reattachDepthStencilDepth = false; + bool reattachDepthStencilStencil = false; + switch (attachment) { + case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT: + m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, bufferObject); + m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, bufferObject); + if (!bufferObject) { + reattachDepth = true; + reattachStencil = true; } + break; + case GraphicsContext3D::DEPTH_ATTACHMENT: + m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer)); + if (!bufferObject) + reattachDepthStencilDepth = true; + break; + case GraphicsContext3D::STENCIL_ATTACHMENT: + m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer)); + if (!bufferObject) + reattachDepthStencilStencil = true; + break; + default: + m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer)); } - m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer)); m_framebufferBinding->setAttachment(attachment, buffer); + if (reattachDepth) { + Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_ATTACHMENT)); + if (object) + m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, object); + } + if (reattachStencil) { + Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::STENCIL_ATTACHMENT)); + if (object) + m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, object); + } + if (reattachDepthStencilDepth) { + Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT)); + if (object) + m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, object); + } + if (reattachDepthStencilStencil) { + Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT)); + if (object) + m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, object); + } cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateFramebufferFuncParameters(target, attachment)) + if (isContextLost() || !validateFramebufferFuncParameters(target, attachment)) return; if (level) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); @@ -1144,12 +1276,16 @@ void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned void WebGLRenderingContext::frontFace(unsigned long mode) { + if (isContextLost()) + return; m_context->frontFace(mode); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::generateMipmap(unsigned long target) { + if (isContextLost()) + return; WebGLTexture* tex = validateTextureBinding(target, false); if (!tex) return; @@ -1178,9 +1314,9 @@ void WebGLRenderingContext::generateMipmap(unsigned long target) PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, unsigned long index, ExceptionCode& ec) { UNUSED_PARAM(ec); - ActiveInfo info; - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return 0; + ActiveInfo info; if (!m_context->getActiveAttrib(objectOrZero(program), index, info)) return 0; return WebGLActiveInfo::create(info.name, info.type, info.size); @@ -1189,9 +1325,9 @@ PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec) { UNUSED_PARAM(ec); - ActiveInfo info; - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return 0; + ActiveInfo info; if (!m_context->getActiveUniform(objectOrZero(program), index, info)) return 0; if (!isGLES2Compliant()) @@ -1204,7 +1340,7 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Web { UNUSED_PARAM(ec); shaderObjects.clear(); - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return false; int numShaders = 0; m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::ATTACHED_SHADERS, &numShaders); @@ -1229,12 +1365,16 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Web int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name) { + if (isContextLost()) + return -1; return m_context->getAttribLocation(objectOrZero(program), name); } WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return WebGLGetInfo(); if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); @@ -1255,6 +1395,8 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, uns PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes() { + if (isContextLost()) + return 0; // We always need to return a new WebGLContextAttributes object to // prevent the user from mutating any cached version. return WebGLContextAttributes::create(m_context->getContextAttributes()); @@ -1268,7 +1410,7 @@ unsigned long WebGLRenderingContext::getError() WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateFramebufferFuncParameters(target, attachment)) + if (isContextLost() || !validateFramebufferFuncParameters(target, attachment)) return WebGLGetInfo(); switch (pname) { case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: @@ -1281,7 +1423,7 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned l return WebGLGetInfo(); } - if (!m_framebufferBinding || !m_framebufferBinding->object()) { + if (!m_framebufferBinding || !m_framebufferBinding->object() || m_framebufferBinding->isIncomplete(false)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return WebGLGetInfo(); } @@ -1316,6 +1458,8 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned l WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return WebGLGetInfo(); WebGLStateRestorer(this, false); switch (pname) { case GraphicsContext3D::ACTIVE_TEXTURE: @@ -1383,10 +1527,6 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC return getUnsignedLongParameter(pname); case GraphicsContext3D::GREEN_BITS: return getLongParameter(pname); - case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT: - return getLongParameter(pname); - case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE: - return getLongParameter(pname); case GraphicsContext3D::LINE_WIDTH: return getFloatParameter(pname); case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS: @@ -1507,7 +1647,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return WebGLGetInfo(); WebGLStateRestorer(this, false); @@ -1536,6 +1676,8 @@ WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, u String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return String(); if (!validateWebGLObject(program)) return ""; WebGLStateRestorer(this, false); @@ -1545,10 +1687,48 @@ String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, Exception WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return WebGLGetInfo(); if (target != GraphicsContext3D::RENDERBUFFER) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return WebGLGetInfo(); } + if (!m_renderbufferBinding || !m_renderbufferBinding->object()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return WebGLGetInfo(); + } + + if (m_renderbufferBinding->getInternalFormat() == GraphicsContext3D::DEPTH_STENCIL + && !m_renderbufferBinding->isValid()) { + ASSERT(!m_isDepthStencilSupported); + long value = 0; + switch (pname) { + case GraphicsContext3D::RENDERBUFFER_WIDTH: + value = static_cast<long>(m_renderbufferBinding->getWidth()); + break; + case GraphicsContext3D::RENDERBUFFER_HEIGHT: + value = static_cast<long>(m_renderbufferBinding->getHeight()); + break; + case GraphicsContext3D::RENDERBUFFER_RED_SIZE: + case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE: + case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE: + case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE: + value = 0; + break; + case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE: + value = 24; + break; + case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE: + value = 8; + break; + case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT: + return WebGLGetInfo(m_renderbufferBinding->getInternalFormat()); + default: + m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + return WebGLGetInfo(); + } + return WebGLGetInfo(value); + } WebGLStateRestorer(this, false); int value = 0; @@ -1564,10 +1744,6 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long targe m_context->getRenderbufferParameteriv(target, pname, &value); return WebGLGetInfo(static_cast<long>(value)); case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT: - if (!m_renderbufferBinding) { - m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); - return WebGLGetInfo(); - } return WebGLGetInfo(m_renderbufferBinding->getInternalFormat()); default: m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); @@ -1578,7 +1754,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long targe WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject(shader)) return WebGLGetInfo(); WebGLStateRestorer(this, false); int value = 0; @@ -1603,6 +1779,8 @@ WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsi String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return String(); if (!validateWebGLObject(shader)) return ""; WebGLStateRestorer(this, false); @@ -1612,6 +1790,8 @@ String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCod String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return String(); if (!validateWebGLObject(shader)) return ""; WebGLStateRestorer(this, false); @@ -1621,6 +1801,8 @@ String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return WebGLGetInfo(); WebGLTexture* tex = validateTextureBinding(target, false); if (!tex) return WebGLGetInfo(); @@ -1642,7 +1824,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsign WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return WebGLGetInfo(); if (!uniformLocation) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); @@ -1755,20 +1937,20 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG return WebGLGetInfo(Float32Array::create(value, length)); } case GraphicsContext3D::INT: { - int value[16] = {0}; + int value[4] = {0}; m_context->getUniformiv(objectOrZero(program), location, value); if (length == 1) return WebGLGetInfo(static_cast<long>(value[0])); return WebGLGetInfo(Int32Array::create(value, length)); } case GraphicsContext3D::BOOL: { - int value[16] = {0}; + int value[4] = {0}; m_context->getUniformiv(objectOrZero(program), location, value); if (length > 1) { - unsigned char boolValue[16] = {0}; + bool boolValue[16] = {0}; for (unsigned j = 0; j < length; j++) boolValue[j] = static_cast<bool>(value[j]); - return WebGLGetInfo(Uint8Array::create(boolValue, length)); + return WebGLGetInfo(boolValue, length); } return WebGLGetInfo(static_cast<bool>(value[0])); } @@ -1786,7 +1968,7 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return 0; WebGLStateRestorer(this, false); long uniformLocation = m_context->getUniformLocation(objectOrZero(program), name); @@ -1798,6 +1980,8 @@ PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGL WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return WebGLGetInfo(); WebGLStateRestorer(this, false); if (index >= m_maxVertexAttribs) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); @@ -1845,6 +2029,8 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigne long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname) { + if (isContextLost()) + return 0; long result = m_context->getVertexAttribOffset(index, pname); cleanupAfterGraphicsCall(false); return result; @@ -1852,6 +2038,8 @@ long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned void WebGLRenderingContext::hint(unsigned long target, unsigned long mode) { + if (isContextLost()) + return; if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); return; @@ -1862,22 +2050,27 @@ void WebGLRenderingContext::hint(unsigned long target, unsigned long mode) bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer) { - if (!buffer) + if (!buffer || isContextLost()) return false; return m_context->isBuffer(buffer->object()); } +bool WebGLRenderingContext::isContextLost() const +{ + return m_contextLost; +} + bool WebGLRenderingContext::isEnabled(unsigned long cap) { - if (!validateCapability(cap)) + if (!validateCapability(cap) || isContextLost()) return false; return m_context->isEnabled(cap); } bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer) { - if (!framebuffer) + if (!framebuffer || isContextLost()) return false; return m_context->isFramebuffer(framebuffer->object()); @@ -1885,7 +2078,7 @@ bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer) bool WebGLRenderingContext::isProgram(WebGLProgram* program) { - if (!program) + if (!program || isContextLost()) return false; return m_context->isProgram(program->object()); @@ -1893,7 +2086,7 @@ bool WebGLRenderingContext::isProgram(WebGLProgram* program) bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer) { - if (!renderbuffer) + if (!renderbuffer || isContextLost()) return false; return m_context->isRenderbuffer(renderbuffer->object()); @@ -1901,7 +2094,7 @@ bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer) bool WebGLRenderingContext::isShader(WebGLShader* shader) { - if (!shader) + if (!shader || isContextLost()) return false; return m_context->isShader(shader->object()); @@ -1909,7 +2102,7 @@ bool WebGLRenderingContext::isShader(WebGLShader* shader) bool WebGLRenderingContext::isTexture(WebGLTexture* texture) { - if (!texture) + if (!texture || isContextLost()) return false; return m_context->isTexture(texture->object()); @@ -1917,6 +2110,8 @@ bool WebGLRenderingContext::isTexture(WebGLTexture* texture) void WebGLRenderingContext::lineWidth(double width) { + if (isContextLost()) + return; m_context->lineWidth((float) width); cleanupAfterGraphicsCall(false); } @@ -1924,7 +2119,7 @@ void WebGLRenderingContext::lineWidth(double width) void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return; if (!isGLES2Compliant()) { if (!program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER) || !program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER)) { @@ -1944,6 +2139,8 @@ void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec void WebGLRenderingContext::pixelStorei(unsigned long pname, long param) { + if (isContextLost()) + return; switch (pname) { case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL: m_unpackFlipY = param; @@ -1970,12 +2167,16 @@ void WebGLRenderingContext::pixelStorei(unsigned long pname, long param) void WebGLRenderingContext::polygonOffset(double factor, double units) { + if (isContextLost()) + return; m_context->polygonOffset((float) factor, (float) units); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels, ExceptionCode& ec) { + if (isContextLost()) + return; if (!canvas()->originClean()) { ec = SECURITY_ERR; return; @@ -1994,7 +2195,7 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height, m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; } - if (!((format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE) || (format == m_implementationColorReadFormat && type == m_implementationColorReadType))) { + if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } @@ -2004,6 +2205,10 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height, m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } + if (m_framebufferBinding && !m_framebufferBinding->onAccess()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION); + return; + } // Calculate array size, taking into consideration of PACK_ALIGNMENT. unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width; unsigned long padding = 0; @@ -2043,27 +2248,44 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height, void WebGLRenderingContext::releaseShaderCompiler() { + if (isContextLost()) + return; m_context->releaseShaderCompiler(); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height) { + if (isContextLost()) + return; + if (target != GraphicsContext3D::RENDERBUFFER) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + return; + } + if (!m_renderbufferBinding || !m_renderbufferBinding->object()) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } switch (internalformat) { case GraphicsContext3D::DEPTH_COMPONENT16: case GraphicsContext3D::RGBA4: case GraphicsContext3D::RGB5_A1: case GraphicsContext3D::RGB565: case GraphicsContext3D::STENCIL_INDEX8: - case GraphicsContext3D::DEPTH_STENCIL: m_context->renderbufferStorage(target, internalformat, width, height); - if (m_renderbufferBinding) { - m_renderbufferBinding->setInternalFormat(internalformat); - if (m_framebufferBinding) - m_framebufferBinding->onAttachedObjectChange(m_renderbufferBinding.get()); - } + m_renderbufferBinding->setInternalFormat(internalformat); + m_renderbufferBinding->setIsValid(true); cleanupAfterGraphicsCall(false); break; + case GraphicsContext3D::DEPTH_STENCIL: + if (m_isDepthStencilSupported) { + m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height); + cleanupAfterGraphicsCall(false); + } else + m_renderbufferBinding->setSize(width, height); + m_renderbufferBinding->setIsValid(m_isDepthStencilSupported); + m_renderbufferBinding->setInternalFormat(internalformat); + break; default: m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); } @@ -2071,12 +2293,16 @@ void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned l void WebGLRenderingContext::sampleCoverage(double value, bool invert) { + if (isContextLost()) + return; m_context->sampleCoverage((float) value, invert); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigned long height) { + if (isContextLost()) + return; m_context->scissor(x, y, width, height); cleanupAfterGraphicsCall(false); } @@ -2084,7 +2310,7 @@ void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigne void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(shader)) + if (isContextLost() || !validateWebGLObject(shader)) return; m_context->shaderSource(objectOrZero(shader), string); cleanupAfterGraphicsCall(false); @@ -2092,36 +2318,72 @@ void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& stri void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask) { + if (isContextLost()) + return; + if (!validateStencilFunc(func)) + return; + m_stencilFuncRef = ref; + m_stencilFuncMask = mask; m_context->stencilFunc(func, ref, mask); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask) { + if (isContextLost()) + return; + if (!validateFace(face) || !validateStencilFunc(func)) + return; + if (face == GraphicsContext3D::FRONT_AND_BACK) { + m_stencilFuncRef = ref; + m_stencilFuncMask = mask; + } else if (m_stencilFuncRef != ref || m_stencilFuncMask != mask) { + // for ref value, we generate an error if user specify a different value + // for front/back faces even if they clamp to the same value internally. + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } m_context->stencilFuncSeparate(face, func, ref, mask); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::stencilMask(unsigned long mask) { + if (isContextLost()) + return; + m_stencilMask = mask; m_context->stencilMask(mask); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long mask) { + if (isContextLost()) + return; + if (!validateFace(face)) + return; + if (face == GraphicsContext3D::FRONT_AND_BACK) + m_stencilMask = mask; + else if (m_stencilMask != mask) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return; + } m_context->stencilMaskSeparate(face, mask); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass) { + if (isContextLost()) + return; m_context->stencilOp(fail, zfail, zpass); cleanupAfterGraphicsCall(false); } void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass) { + if (isContextLost()) + return; m_context->stencilOpSeparate(face, fail, zfail, zpass); cleanupAfterGraphicsCall(false); } @@ -2146,8 +2408,6 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi m_context->texImage2D(target, level, internalformat, width, height, border, format, type, pixels); tex->setLevelInfo(target, level, internalformat, width, height, type); - if (m_framebufferBinding) - m_framebufferBinding->onAttachedObjectChange(tex); cleanupAfterGraphicsCall(false); } @@ -2173,7 +2433,7 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec) { - if (!validateTexFuncData(width, height, format, type, pixels)) + if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels)) return; void* data = pixels ? pixels->baseAddress() : 0; Vector<uint8_t> tempData; @@ -2200,6 +2460,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; Vector<uint8_t> data; if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); @@ -2217,6 +2479,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; if (!image || !image->cachedImage()) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; @@ -2230,6 +2494,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; if (!canvas || !canvas->buffer()) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; @@ -2262,6 +2528,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; RefPtr<Image> image = videoFrameToImage(video); if (!video) return; @@ -2270,6 +2538,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat) { + if (isContextLost()) + return; WebGLTexture* tex = validateTextureBinding(target, false); if (!tex) return; @@ -2315,6 +2585,8 @@ void WebGLRenderingContext::texSubImage2DBase(unsigned target, unsigned level, u { // FIXME: For now we ignore any errors returned ec = 0; + if (isContextLost()) + return; if (!validateTexFuncFormatAndType(format, type)) return; if (!validateTextureBinding(target, true)) @@ -2328,6 +2600,8 @@ void WebGLRenderingContext::texSubImage2DImpl(unsigned target, unsigned level, u Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; Vector<uint8_t> data; if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); @@ -2341,7 +2615,7 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig unsigned width, unsigned height, unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec) { - if (!validateTexFuncData(width, height, format, type, pixels)) + if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels)) return; void* data = pixels ? pixels->baseAddress() : 0; Vector<uint8_t> tempData; @@ -2367,6 +2641,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; Vector<uint8_t> data; if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); @@ -2380,6 +2656,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; if (!image || !image->cachedImage()) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; @@ -2393,6 +2671,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; if (!canvas || !canvas->buffer()) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; @@ -2406,6 +2686,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec) { ec = 0; + if (isContextLost()) + return; RefPtr<Image> image = videoFrameToImage(video); if (!video) return; @@ -2415,7 +2697,7 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!location) + if (isContextLost() || !location) return; if (location->program() != m_currentProgram) { @@ -2430,7 +2712,7 @@ void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, floa void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, 1)) + if (isContextLost() || !validateUniformParameters(location, v, 1)) return; m_context->uniform1fv(location->location(), v->data(), v->length()); @@ -2440,7 +2722,7 @@ void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Flo void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, size, 1)) + if (isContextLost() || !validateUniformParameters(location, v, size, 1)) return; m_context->uniform1fv(location->location(), v, size); @@ -2450,7 +2732,7 @@ void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, flo void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!location) + if (isContextLost() || !location) return; if (location->program() != m_currentProgram) { @@ -2465,7 +2747,7 @@ void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, 1)) + if (isContextLost() || !validateUniformParameters(location, v, 1)) return; m_context->uniform1iv(location->location(), v->data(), v->length()); @@ -2475,7 +2757,7 @@ void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, size, 1)) + if (isContextLost() || !validateUniformParameters(location, v, size, 1)) return; m_context->uniform1iv(location->location(), v, size); @@ -2485,7 +2767,7 @@ void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!location) + if (isContextLost() || !location) return; if (location->program() != m_currentProgram) { @@ -2500,7 +2782,7 @@ void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, floa void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, 2)) + if (isContextLost() || !validateUniformParameters(location, v, 2)) return; m_context->uniform2fv(location->location(), v->data(), v->length() / 2); @@ -2510,7 +2792,7 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Flo void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, size, 2)) + if (isContextLost() || !validateUniformParameters(location, v, size, 2)) return; m_context->uniform2fv(location->location(), v, size / 2); @@ -2520,7 +2802,7 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, flo void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!location) + if (isContextLost() || !location) return; if (location->program() != m_currentProgram) { @@ -2535,7 +2817,7 @@ void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, 2)) + if (isContextLost() || !validateUniformParameters(location, v, 2)) return; m_context->uniform2iv(location->location(), v->data(), v->length() / 2); @@ -2545,7 +2827,7 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, size, 2)) + if (isContextLost() || !validateUniformParameters(location, v, size, 2)) return; m_context->uniform2iv(location->location(), v, size / 2); @@ -2555,7 +2837,7 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!location) + if (isContextLost() || !location) return; if (location->program() != m_currentProgram) { @@ -2570,7 +2852,7 @@ void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, floa void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, 3)) + if (isContextLost() || !validateUniformParameters(location, v, 3)) return; m_context->uniform3fv(location->location(), v->data(), v->length() / 3); @@ -2580,7 +2862,7 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Flo void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, size, 3)) + if (isContextLost() || !validateUniformParameters(location, v, size, 3)) return; m_context->uniform3fv(location->location(), v, size / 3); @@ -2590,7 +2872,7 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, flo void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!location) + if (isContextLost() || !location) return; if (location->program() != m_currentProgram) { @@ -2605,7 +2887,7 @@ void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, 3)) + if (isContextLost() || !validateUniformParameters(location, v, 3)) return; m_context->uniform3iv(location->location(), v->data(), v->length() / 3); @@ -2615,7 +2897,7 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, size, 3)) + if (isContextLost() || !validateUniformParameters(location, v, size, 3)) return; m_context->uniform3iv(location->location(), v, size / 3); @@ -2625,7 +2907,7 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!location) + if (isContextLost() || !location) return; if (location->program() != m_currentProgram) { @@ -2640,7 +2922,7 @@ void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, floa void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, 4)) + if (isContextLost() || !validateUniformParameters(location, v, 4)) return; m_context->uniform4fv(location->location(), v->data(), v->length() / 4); @@ -2650,7 +2932,7 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Flo void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, size, 4)) + if (isContextLost() || !validateUniformParameters(location, v, size, 4)) return; m_context->uniform4fv(location->location(), v, size / 4); @@ -2660,7 +2942,7 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, flo void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!location) + if (isContextLost() || !location) return; if (location->program() != m_currentProgram) { @@ -2675,7 +2957,7 @@ void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, 4)) + if (isContextLost() || !validateUniformParameters(location, v, 4)) return; m_context->uniform4iv(location->location(), v->data(), v->length() / 4); @@ -2685,7 +2967,7 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformParameters(location, v, size, 4)) + if (isContextLost() || !validateUniformParameters(location, v, size, 4)) return; m_context->uniform4iv(location->location(), v, size / 4); @@ -2695,7 +2977,7 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformMatrixParameters(location, transpose, v, 4)) + if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 4)) return; m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4); cleanupAfterGraphicsCall(false); @@ -2704,7 +2986,7 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformMatrixParameters(location, transpose, v, size, 4)) + if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 4)) return; m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4); cleanupAfterGraphicsCall(false); @@ -2713,7 +2995,7 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformMatrixParameters(location, transpose, v, 9)) + if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 9)) return; m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9); cleanupAfterGraphicsCall(false); @@ -2722,7 +3004,7 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformMatrixParameters(location, transpose, v, size, 9)) + if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 9)) return; m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9); cleanupAfterGraphicsCall(false); @@ -2731,7 +3013,7 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformMatrixParameters(location, transpose, v, 16)) + if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 16)) return; m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16); cleanupAfterGraphicsCall(false); @@ -2740,7 +3022,7 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateUniformMatrixParameters(location, transpose, v, size, 16)) + if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 16)) return; m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16); cleanupAfterGraphicsCall(false); @@ -2749,6 +3031,8 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (program && program->context() != this) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; @@ -2772,7 +3056,7 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec) void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec) { UNUSED_PARAM(ec); - if (!validateWebGLObject(program)) + if (isContextLost() || !validateWebGLObject(program)) return; m_context->validateProgram(objectOrZero(program)); cleanupAfterGraphicsCall(false); @@ -2841,11 +3125,13 @@ void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, float* v, int s void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size, unsigned long type, bool normalized, long stride, long offset, ExceptionCode& ec) { UNUSED_PARAM(ec); + if (isContextLost()) + return; if (index >= m_maxVertexAttribs) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; } - if (size < 1 || size > 4 || stride < 0 || offset < 0) { + if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; } @@ -2885,6 +3171,8 @@ void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size, void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsigned long height) { + if (isContextLost()) + return; if (isnan(x)) x = 0; if (isnan(y)) @@ -2897,6 +3185,44 @@ void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsign cleanupAfterGraphicsCall(false); } +void WebGLRenderingContext::loseContext() +{ + if (isContextLost()) + return; + + m_contextLost = true; + + detachAndRemoveAllObjects(); + + // There is no direct way to clear errors from a GL implementation and + // looping until getError() becomes NO_ERROR might cause an infinite loop if + // the driver or context implementation had a bug. So, loop a reasonably + // large number of times to clear any existing errors. + for (int i = 0; i < 100; ++i) { + if (m_context->getError() == GraphicsContext3D::NO_ERROR) + break; + } + m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL); + + canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, "")); +} + +void WebGLRenderingContext::restoreContext() +{ + if (!isContextLost()) + return; + + // The rendering context is not restored if there is no handler for + // the context restored event. + if (!canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent)) + return; + + m_contextLost = false; + initializeNewContext(); + + canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, "")); +} + void WebGLRenderingContext::removeObject(WebGLObject* object) { m_canvasObjects.remove(object); @@ -2904,6 +3230,7 @@ void WebGLRenderingContext::removeObject(WebGLObject* object) void WebGLRenderingContext::addObject(WebGLObject* object) { + ASSERT(!isContextLost()); removeObject(object); m_canvasObjects.add(object); } @@ -3355,6 +3682,37 @@ bool WebGLRenderingContext::validateDrawMode(unsigned long mode) } } +bool WebGLRenderingContext::validateFace(unsigned long face) +{ + switch (face) { + case GraphicsContext3D::FRONT: + case GraphicsContext3D::BACK: + case GraphicsContext3D::FRONT_AND_BACK: + return true; + default: + m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + return false; + } +} + +bool WebGLRenderingContext::validateStencilFunc(unsigned long func) +{ + switch (func) { + case GraphicsContext3D::NEVER: + case GraphicsContext3D::LESS: + case GraphicsContext3D::LEQUAL: + case GraphicsContext3D::GREATER: + case GraphicsContext3D::GEQUAL: + case GraphicsContext3D::EQUAL: + case GraphicsContext3D::NOTEQUAL: + case GraphicsContext3D::ALWAYS: + return true; + default: + m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); + return false; + } +} + void WebGLRenderingContext::printWarningToConsole(const String& message) { canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, @@ -3393,6 +3751,18 @@ bool WebGLRenderingContext::validateBlendEquation(unsigned long mode) } } +bool WebGLRenderingContext::validateBlendFuncFactors(unsigned long src, unsigned long dst) +{ + if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR) + && (dst == GraphicsContext3D::CONSTANT_ALPHA || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA)) + || ((dst == GraphicsContext3D::CONSTANT_COLOR || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR) + && (src == GraphicsContext3D::CONSTANT_ALPHA || src == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))) { + m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); + return false; + } + return true; +} + bool WebGLRenderingContext::validateCapability(unsigned long cap) { switch (cap) { @@ -3497,6 +3867,8 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(unsigned long t void WebGLRenderingContext::vertexAttribfImpl(unsigned long index, int expectedSize, float v0, float v1, float v2, float v3) { + if (isContextLost()) + return; if (index >= m_maxVertexAttribs) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; @@ -3529,6 +3901,8 @@ void WebGLRenderingContext::vertexAttribfImpl(unsigned long index, int expectedS void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, Float32Array* v, int expectedSize) { + if (isContextLost()) + return; if (!v) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; @@ -3538,6 +3912,8 @@ void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, Float32Array void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, float* v, int size, int expectedSize) { + if (isContextLost()) + return; if (!v) { m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return; diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h index ce66f6a..5f66248 100644 --- a/WebCore/html/canvas/WebGLRenderingContext.h +++ b/WebCore/html/canvas/WebGLRenderingContext.h @@ -176,6 +176,7 @@ public: void hint(unsigned long target, unsigned long mode); bool isBuffer(WebGLBuffer*); + bool isContextLost() const; bool isEnabled(unsigned long cap); bool isFramebuffer(WebGLFramebuffer*); bool isProgram(WebGLProgram*); @@ -277,6 +278,9 @@ public: void viewport(long x, long y, unsigned long width, unsigned long height); + void loseContext(); + void restoreContext(); + GraphicsContext3D* graphicsContext3D() const { return m_context.get(); } #if USE(ACCELERATED_COMPOSITING) virtual PlatformLayer* platformLayer() const { return m_context->platformLayer(); } @@ -292,6 +296,7 @@ public: friend class WebGLObject; WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>); + void initializeNewContext(); void addObject(WebGLObject*); void detachAndRemoveAllObjects(); @@ -333,8 +338,6 @@ public: RefPtr<GraphicsContext3D> m_context; bool m_needsUpdate; bool m_markedCanvasDirty; - // FIXME: I think this is broken -- it does not increment any - // reference counts, so may refer to destroyed objects. HashSet<RefPtr<WebGLObject> > m_canvasObjects; // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER @@ -417,10 +420,16 @@ public: int m_packAlignment; int m_unpackAlignment; - unsigned long m_implementationColorReadFormat; - unsigned long m_implementationColorReadType; bool m_unpackFlipY; bool m_unpackPremultiplyAlpha; + bool m_contextLost; + + long m_stencilBits; + unsigned long m_stencilMask; + long m_stencilFuncRef; // Note that this is the user specified value, not the internal clamped value. + unsigned long m_stencilFuncMask; + + bool m_isDepthStencilSupported; // Helpers for getParameter and others WebGLGetInfo getBooleanParameter(unsigned long pname); @@ -481,6 +490,12 @@ public: // Helper function to validate mode for draw{Arrays/Elements}. bool validateDrawMode(unsigned long); + // Helper function to validate face. + bool validateFace(unsigned long); + + // Helper function to validate stencil func. + bool validateStencilFunc(unsigned long); + // Helper function for texParameterf and texParameteri. void texParameter(unsigned long target, unsigned long pname, float parami, int paramf, bool isFloat); @@ -495,6 +510,9 @@ public: // Helper function to validate blend equation mode. bool validateBlendEquation(unsigned long); + // Helper function to validate blend func factors. + bool validateBlendFuncFactors(unsigned long src, unsigned long dst); + // Helper function to validate a GL capability. bool validateCapability(unsigned long); diff --git a/WebCore/html/canvas/WebGLRenderingContext.idl b/WebCore/html/canvas/WebGLRenderingContext.idl index f76646d..4d41b78 100644 --- a/WebCore/html/canvas/WebGLRenderingContext.idl +++ b/WebCore/html/canvas/WebGLRenderingContext.idl @@ -392,10 +392,6 @@ module html { const unsigned int VERTEX_ATTRIB_ARRAY_POINTER = 0x8645; const unsigned int VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F; - /* Read Format */ - const unsigned int IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A; - const unsigned int IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B; - /* Shader Source */ const unsigned int COMPILE_STATUS = 0x8B81; const unsigned int INFO_LOG_LENGTH = 0x8B84; @@ -463,6 +459,7 @@ module html { /* WebGL-specific enums */ const unsigned int UNPACK_FLIP_Y_WEBGL = 0x9240; const unsigned int UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; + const unsigned int CONTEXT_LOST_WEBGL = 0x9242; [StrictTypeChecking] void activeTexture(in unsigned long texture) raises(DOMException); [StrictTypeChecking] void attachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException); @@ -551,18 +548,18 @@ module html { [StrictTypeChecking, Custom] void getParameter(); // any getProgramParameter(in WebGLProgram program, in unsigned long pname) raises(DOMException); [StrictTypeChecking, Custom] void getProgramParameter(); - [StrictTypeChecking] DOMString getProgramInfoLog(in WebGLProgram program) raises(DOMException); + [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getProgramInfoLog(in WebGLProgram program) raises(DOMException); // any getRenderbufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException); [StrictTypeChecking, Custom] void getRenderbufferParameter(); // any getShaderParameter(in WebGLShader shader, in unsigned long pname) raises(DOMException); [StrictTypeChecking, Custom] void getShaderParameter() raises(DOMException); - [StrictTypeChecking] DOMString getShaderInfoLog(in WebGLShader shader) raises(DOMException); + [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getShaderInfoLog(in WebGLShader shader) raises(DOMException); // TBD // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); - [StrictTypeChecking] DOMString getShaderSource(in WebGLShader shader) raises(DOMException); + [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getShaderSource(in WebGLShader shader) raises(DOMException); // any getTexParameter(in unsigned long target, in unsigned long pname) raises(DOMException); [StrictTypeChecking, Custom] void getTexParameter(); @@ -579,6 +576,7 @@ module html { [StrictTypeChecking] void hint(in unsigned long target, in unsigned long mode); [StrictTypeChecking] boolean isBuffer(in WebGLBuffer buffer); + [StrictTypeChecking] boolean isContextLost(); [StrictTypeChecking] boolean isEnabled(in unsigned long cap); [StrictTypeChecking] boolean isFramebuffer(in WebGLFramebuffer framebuffer); [StrictTypeChecking] boolean isProgram(in WebGLProgram program); diff --git a/WebCore/html/parser/HTMLTreeBuilder.cpp b/WebCore/html/parser/HTMLTreeBuilder.cpp index 310ff60..6134607 100644 --- a/WebCore/html/parser/HTMLTreeBuilder.cpp +++ b/WebCore/html/parser/HTMLTreeBuilder.cpp @@ -2295,7 +2295,8 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token) while (1) { if (nodeRecord->element()->hasLocalName(token.name())) { m_tree.openElements()->popUntilPopped(nodeRecord->element()); - break; + resetForeignInsertionMode(); + return; } nodeRecord = nodeRecord->next(); if (nodeRecord->element()->namespaceURI() == xhtmlNamespaceURI) @@ -2580,7 +2581,7 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token) case AfterBodyMode: case AfterAfterBodyMode: ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode); - return; + break; case InHeadNoscriptMode: ASSERT(insertionMode() == InHeadNoscriptMode); defaultForInHeadNoscript(); @@ -2602,11 +2603,11 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token) case InColumnGroupMode: if (m_tree.currentElement() == m_tree.openElements()->htmlElement()) { ASSERT(isParsingFragment()); - return; + return; // FIXME: Should we break here instead of returning? } if (!processColgroupEndTagForInColumnGroup()) { ASSERT(isParsingFragment()); - return; + return; // FIXME: Should we break here instead of returning? } prepareToReprocessToken(); processEndOfFile(token); diff --git a/WebCore/inspector/CodeGeneratorInspector.pm b/WebCore/inspector/CodeGeneratorInspector.pm index a566576..3a8a6cb 100644 --- a/WebCore/inspector/CodeGeneratorInspector.pm +++ b/WebCore/inspector/CodeGeneratorInspector.pm @@ -43,6 +43,11 @@ $typeTransform{"ApplicationCache"} = { "header" => "InspectorApplicationCacheAgent.h", "domainAccessor" => "m_inspectorController->applicationCacheAgent()", }; +$typeTransform{"FileSystem"} = { + "forward" => "InspectorFileSystemAgent", + "header" => "InspectorFileSystemAgent.h", + "domainAccessor" => "m_inspectorController->fileSystemAgent()", +}; $typeTransform{"Profiler"} = { "forward" => "InspectorProfilerAgent", "header" => "InspectorProfilerAgent.h", diff --git a/WebCore/inspector/ConsoleMessage.cpp b/WebCore/inspector/ConsoleMessage.cpp index 67930cd..03283bf 100644 --- a/WebCore/inspector/ConsoleMessage.cpp +++ b/WebCore/inspector/ConsoleMessage.cpp @@ -33,46 +33,15 @@ #include "InjectedScript.h" #include "InjectedScriptHost.h" +#include "InspectorFrontend.h" #include "InspectorValues.h" +#include "ScriptArguments.h" #include "ScriptCallStack.h" #include "ScriptValue.h" - -#if ENABLE(INSPECTOR) -#include "InspectorFrontend.h" -#endif +#include <wtf/PassOwnPtr.h> namespace WebCore { -ConsoleMessage::CallFrame::CallFrame(const ScriptCallFrame& frame) - : m_functionName(frame.functionName()) - , m_sourceURL(frame.sourceURL()) - , m_lineNumber(frame.lineNumber()) -{ -} - -ConsoleMessage::CallFrame::CallFrame() - : m_lineNumber(0) -{ -} - -bool ConsoleMessage::CallFrame::isEqual(const ConsoleMessage::CallFrame& o) const -{ - return m_functionName == o.m_functionName - && m_sourceURL == o.m_sourceURL - && m_lineNumber == o.m_lineNumber; -} - -#if ENABLE(INSPECTOR) -PassRefPtr<InspectorObject> ConsoleMessage::CallFrame::buildInspectorObject() const -{ - RefPtr<InspectorObject> frame = InspectorObject::create(); - frame->setString("functionName", m_functionName); - frame->setString("sourceURL", m_sourceURL); - frame->setNumber("lineNumber", m_lineNumber); - return frame; -} -#endif - ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g) : m_source(s) , m_type(t) @@ -85,35 +54,26 @@ ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, c { } -ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, ScriptCallStack* callStack, unsigned g, bool storeTrace) +ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack, unsigned g) : m_source(s) , m_type(t) , m_level(l) , m_message(m) -#if ENABLE(INSPECTOR) - , m_arguments(callStack->at(0).argumentCount()) - , m_scriptState(callStack->globalState()) -#endif - , m_frames(storeTrace ? callStack->size() : 0) + , m_arguments(arguments) + , m_callStack(callStack) , m_groupLevel(g) , m_repeatCount(1) { - const ScriptCallFrame& lastCaller = callStack->at(0); + const ScriptCallFrame& lastCaller = m_callStack->at(0); m_line = lastCaller.lineNumber(); m_url = lastCaller.sourceURL(); - if (storeTrace) { - for (unsigned i = 0; i < callStack->size(); ++i) - m_frames[i] = ConsoleMessage::CallFrame(callStack->at(i)); - } -#if ENABLE(INSPECTOR) - for (unsigned i = 0; i < lastCaller.argumentCount(); ++i) - m_arguments[i] = lastCaller.argumentAt(i); -#endif + bool storeTrace = (t == TraceMessageType || t == UncaughtExceptionMessageType || t == AssertMessageType); + if (!storeTrace) + m_callStack.clear(); } -#if ENABLE(INSPECTOR) void ConsoleMessage::addToFrontend(InspectorFrontend* frontend, InjectedScriptHost* injectedScriptHost) { RefPtr<InspectorObject> jsonObj = InspectorObject::create(); @@ -125,12 +85,12 @@ void ConsoleMessage::addToFrontend(InspectorFrontend* frontend, InjectedScriptHo jsonObj->setNumber("groupLevel", static_cast<int>(m_groupLevel)); jsonObj->setNumber("repeatCount", static_cast<int>(m_repeatCount)); jsonObj->setString("message", m_message); - if (!m_arguments.isEmpty()) { - InjectedScript injectedScript = injectedScriptHost->injectedScriptFor(m_scriptState.get()); + if (m_arguments && m_arguments->argumentCount()) { + InjectedScript injectedScript = injectedScriptHost->injectedScriptFor(m_arguments->globalState()); if (!injectedScript.hasNoValue()) { RefPtr<InspectorArray> jsonArgs = InspectorArray::create(); - for (unsigned i = 0; i < m_arguments.size(); ++i) { - RefPtr<InspectorValue> inspectorValue = injectedScript.wrapForConsole(m_arguments[i]); + for (unsigned i = 0; i < m_arguments->argumentCount(); ++i) { + RefPtr<InspectorValue> inspectorValue = injectedScript.wrapForConsole(m_arguments->argumentAt(i)); if (!inspectorValue) { ASSERT_NOT_REACHED(); return; @@ -140,12 +100,8 @@ void ConsoleMessage::addToFrontend(InspectorFrontend* frontend, InjectedScriptHo jsonObj->setArray("parameters", jsonArgs); } } - if (!m_frames.isEmpty()) { - RefPtr<InspectorArray> frames = InspectorArray::create(); - for (unsigned i = 0; i < m_frames.size(); i++) - frames->pushObject(m_frames.at(i).buildInspectorObject()); - jsonObj->setArray("stackTrace", frames); - } + if (m_callStack) + jsonObj->setArray("stackTrace", m_callStack->buildInspectorObject()); frontend->addConsoleMessage(jsonObj); } @@ -153,32 +109,20 @@ void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend* frontend) { frontend->updateConsoleMessageRepeatCount(m_repeatCount); } -#endif // ENABLE(INSPECTOR) bool ConsoleMessage::isEqual(ConsoleMessage* msg) const { -#if ENABLE(INSPECTOR) - if (msg->m_arguments.size() != m_arguments.size()) - return false; - if (!msg->m_scriptState.get() && msg->m_arguments.size()) { - ASSERT_NOT_REACHED(); - return false; - } - - for (size_t i = 0; i < m_arguments.size(); ++i) { - if (!m_arguments[i].isEqual(msg->m_scriptState.get(), msg->m_arguments[i])) + if (m_arguments) { + if (!m_arguments->isEqual(msg->m_arguments.get())) return false; - } -#endif // ENABLE(INSPECTOR) - - size_t frameCount = msg->m_frames.size(); - if (frameCount != m_frames.size()) + } else if (msg->m_arguments) return false; - for (size_t i = 0; i < frameCount; ++i) { - if (!m_frames[i].isEqual(msg->m_frames[i])) + if (m_callStack) { + if (!m_callStack->isEqual(msg->m_callStack.get())) return false; - } + } else if (msg->m_callStack) + return false; return msg->m_source == m_source && msg->m_type == m_type diff --git a/WebCore/inspector/ConsoleMessage.h b/WebCore/inspector/ConsoleMessage.h index 6c3f2c7..4e88bec 100644 --- a/WebCore/inspector/ConsoleMessage.h +++ b/WebCore/inspector/ConsoleMessage.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2009, 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 @@ -32,15 +32,16 @@ #define ConsoleMessage_h #include "Console.h" -#include "KURL.h" #include "ScriptState.h" +#include <wtf/Forward.h> #include <wtf/Vector.h> namespace WebCore { class InjectedScriptHost; class InspectorFrontend; class InspectorObject; +class ScriptArguments; class ScriptCallFrame; class ScriptCallStack; class ScriptValue; @@ -48,12 +49,10 @@ class ScriptValue; class ConsoleMessage : public Noncopyable { public: ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, unsigned li, const String& u, unsigned g); - ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, ScriptCallStack*, unsigned g, bool storeTrace = false); + ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>, unsigned g); -#if ENABLE(INSPECTOR) void addToFrontend(InspectorFrontend*, InjectedScriptHost*); void updateRepeatCountInConsole(InspectorFrontend* frontend); -#endif void incrementCount() { ++m_repeatCount; } bool isEqual(ConsoleMessage* msg) const; @@ -61,30 +60,12 @@ public: const String& message() const { return m_message; } private: - class CallFrame { - public: - explicit CallFrame(const ScriptCallFrame& frame); - CallFrame(); - bool isEqual(const CallFrame& o) const; -#if ENABLE(INSPECTOR) - PassRefPtr<InspectorObject> buildInspectorObject() const; -#endif - - private: - String m_functionName; - String m_sourceURL; - unsigned m_lineNumber; - }; - MessageSource m_source; MessageType m_type; MessageLevel m_level; String m_message; -#if ENABLE(INSPECTOR) - Vector<ScriptValue> m_arguments; - ScriptStateProtectedPtr m_scriptState; -#endif - Vector<CallFrame> m_frames; + OwnPtr<ScriptArguments> m_arguments; + OwnPtr<ScriptCallStack> m_callStack; unsigned m_line; String m_url; unsigned m_groupLevel; diff --git a/WebCore/inspector/InjectedScriptHost.cpp b/WebCore/inspector/InjectedScriptHost.cpp index 06b25fe..415a2e5 100644 --- a/WebCore/inspector/InjectedScriptHost.cpp +++ b/WebCore/inspector/InjectedScriptHost.cpp @@ -43,7 +43,6 @@ #include "InspectorController.h" #include "InspectorDOMAgent.h" #include "InspectorFrontend.h" -#include "InspectorResource.h" #include "Pasteboard.h" #if ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl index 331e504..93d5396 100644 --- a/WebCore/inspector/Inspector.idl +++ b/WebCore/inspector/Inspector.idl @@ -46,7 +46,6 @@ module core { [notify] void domContentEventFired(out double time); [notify] void inspectedURLChanged(out String url); [notify] void loadEventFired(out double time); - [notify] void removeResource(out unsigned long identifier); [notify] void reset(); [notify] void resetProfilesPanel(); [notify] void setChildNodes(out long parentId, out Array nodes); @@ -56,7 +55,6 @@ module core { [notify] void timelineProfilerWasStarted(); [notify] void timelineProfilerWasStopped(); [notify] void updateFocusedNode(out long nodeId); - [notify] void updateResource(out Value resource); #if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER [notify] void addProfileHeader(out Object header); @@ -100,8 +98,6 @@ module core { [handler=Controller] void setMonitoringXHREnabled(in boolean enable, out boolean newState); - [handler=Controller] void setResourceTrackingEnabled(in boolean enabled, in boolean always, out boolean newState); - [handler=Controller] void getResourceContent(in unsigned long identifier, in boolean encode, out String content); [handler=Controller] void reloadPage(); [handler=Controller] void startTimelineProfiler(); @@ -118,7 +114,7 @@ module core { [notify] void didFailLoading(out long identifier, out double time, out String localizedDescription); [notify] void didLoadResourceFromMemoryCache(out double time, out Object resource); [notify] void setOverrideContent(out long identifier, out String sourceString, out String type); - [notify] void didCommitLoadForFrame(out unsigned long parentFrameId, out Object loader); + [notify] void didCommitLoadForFrame(out Object frame, out Object loader); [notify] void frameDetachedFromParent(out unsigned long frameId); [notify] void didCreateWebSocket(out unsigned long identifier, out String requestURL); @@ -153,8 +149,8 @@ module core { [handler=Controller] void enableProfiler(in boolean always); [handler=Controller] void disableProfiler(in boolean always); - [handler=Profiler] void startProfiling(); - [handler=Profiler] void stopProfiling(); + [handler=Controller] void startProfiling(); + [handler=Controller] void stopProfiling(); [handler=Profiler] void getProfileHeaders(out Array headers); [handler=Profiler] void getProfile(in String type, in unsigned long uid, out Object profile); @@ -196,6 +192,9 @@ module core { [handler=Controller] void hideDOMNodeHighlight(); [handler=Controller] void openInInspectedWindow(in String url); + [handler=Controller] void highlightFrame(in unsigned long frameId); + [handler=Controller] void hideFrameHighlight(); + [handler=DOM] void getStyles(in long nodeId, in boolean authOnly, out Value styles); [handler=DOM] void getAllStyles(out Array styles); [handler=DOM] void getInlineStyle(in long nodeId, out Value style); @@ -217,6 +216,14 @@ module core { [handler=ApplicationCache] void getApplicationCaches(out Value applicationCaches); #endif +#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM + [handler=FileSystem] void getFileSystemPathAsync(in unsigned int type, in String origin); + [handler=FileSystem] void revealFolderInOS(in String path); + [notify] void didGetFileSystemPath(out String root, out int type, out String origin); + [notify] void didGetFileSystemError(out int type, out String origin); + [notify] void didGetFileSystemDisabled(); +#endif + [handler=Backend] void releaseWrapperObjectGroup(in long injectedScriptId, in String objectGroup); [handler=Controller] void didEvaluateForTestInFrontend(in long testCallId, in String jsonResult); diff --git a/WebCore/inspector/InspectorCSSStore.cpp b/WebCore/inspector/InspectorCSSStore.cpp index b75f11b..08634cb 100644 --- a/WebCore/inspector/InspectorCSSStore.cpp +++ b/WebCore/inspector/InspectorCSSStore.cpp @@ -43,7 +43,6 @@ #include "Frame.h" #include "HTMLHeadElement.h" #include "InspectorController.h" -#include "InspectorResource.h" #include "InspectorResourceAgent.h" #include "Node.h" #include "PlatformString.h" diff --git a/WebCore/inspector/InspectorCSSStore.h b/WebCore/inspector/InspectorCSSStore.h index 25a9d15..0414b58 100644 --- a/WebCore/inspector/InspectorCSSStore.h +++ b/WebCore/inspector/InspectorCSSStore.h @@ -30,7 +30,7 @@ #define InspectorCSSStore_h #include "CSSPropertySourceData.h" -#include "Cache.h" +#include "MemoryCache.h" #include <wtf/Forward.h> #include <wtf/HashMap.h> diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp index 956ef7e..c34130e 100644 --- a/WebCore/inspector/InspectorController.cpp +++ b/WebCore/inspector/InspectorController.cpp @@ -81,6 +81,7 @@ #include "RenderInline.h" #include "ResourceRequest.h" #include "ResourceResponse.h" +#include "ScriptArguments.h" #include "ScriptCallStack.h" #include "ScriptFunctionCall.h" #include "ScriptObject.h" @@ -102,10 +103,6 @@ #include <wtf/StdLibExtras.h> #include <wtf/UnusedParam.h> -#if LEGACY_RESOURCE_TRACKING_ENABLED -#include "InspectorResource.h" -#endif - #if ENABLE(DATABASE) #include "Database.h" #endif @@ -114,6 +111,10 @@ #include "InspectorApplicationCacheAgent.h" #endif +#if ENABLE(FILE_SYSTEM) +#include "InspectorFileSystemAgent.h" +#endif + #if ENABLE(DOM_STORAGE) #include "Storage.h" #include "StorageArea.h" @@ -143,8 +144,6 @@ InspectorController::InspectorController(Page* page, InspectorClient* client) , m_openingFrontend(false) , m_cssStore(new InspectorCSSStore(this)) , m_mainResourceIdentifier(0) - , m_loadEventTime(-1.0) - , m_domContentEventTime(-1.0) , m_expiredConsoleMessageCount(0) , m_groupLevel(0) , m_previousMessage(0) @@ -170,10 +169,6 @@ InspectorController::~InspectorController() ASSERT(!m_inspectedPage); ASSERT(!m_highlightedNode); -#if LEGACY_RESOURCE_TRACKING_ENABLED - deleteAllValues(m_frameResources); -#endif - releaseFrontendLifetimeAgents(); m_inspectorBackend->disconnectController(); @@ -229,13 +224,6 @@ bool InspectorController::searchingForNodeInPage() const return m_state->getBoolean(InspectorState::searchingForNode); } -#if LEGACY_RESOURCE_TRACKING_ENABLED -bool InspectorController::resourceTrackingEnabled() const -{ - return m_state->getBoolean(InspectorState::resourceTrackingEnabled); -} -#endif - void InspectorController::getInspectorState(RefPtr<InspectorObject>* state) { #if ENABLE(JAVASCRIPT_DEBUGGER) @@ -250,6 +238,10 @@ void InspectorController::restoreInspectorStateFromCookie(const String& inspecto m_state->restoreFromInspectorCookie(inspectorStateCookie); if (m_state->getBoolean(InspectorState::timelineProfilerEnabled)) startTimelineProfiler(); +#if ENABLE(JAVASCRIPT_DEBUGGER) + if (m_state->getBoolean(InspectorState::userInitiatedProfiling)) + startUserInitiatedProfiling(); +#endif } void InspectorController::inspect(Node* node) @@ -298,6 +290,17 @@ void InspectorController::highlightDOMNode(long nodeId) highlight(node); } +void InspectorController::highlightFrame(unsigned long frameId) +{ + Frame* mainFrame = m_inspectedPage->mainFrame(); + for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext(mainFrame)) { + if (reinterpret_cast<uintptr_t>(frame) == frameId && frame->ownerElement()) { + highlight(frame->ownerElement()); + return; + } + } +} + void InspectorController::hideHighlight() { if (!enabled()) @@ -325,13 +328,12 @@ void InspectorController::setConsoleMessagesEnabled(bool enabled) m_consoleMessages[i]->addToFrontend(m_frontend.get(), m_injectedScriptHost.get()); } -void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, ScriptCallStack* callStack, const String& message) +void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { if (!enabled()) return; - bool storeStackTrace = type == TraceMessageType || type == UncaughtExceptionMessageType || type == AssertMessageType; - addConsoleMessage(new ConsoleMessage(source, type, level, message, callStack, m_groupLevel, storeStackTrace)); + addConsoleMessage(new ConsoleMessage(source, type, level, message, arguments, callStack, m_groupLevel)); } void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID) @@ -377,11 +379,11 @@ void InspectorController::clearConsoleMessages() m_frontend->consoleMessagesCleared(); } -void InspectorController::startGroup(MessageSource source, ScriptCallStack* callStack, bool collapsed) +void InspectorController::startGroup(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack, bool collapsed) { ++m_groupLevel; - addConsoleMessage(new ConsoleMessage(source, collapsed ? StartGroupCollapsedMessageType : StartGroupMessageType, LogMessageLevel, String(), callStack, m_groupLevel)); + addConsoleMessage(new ConsoleMessage(JSMessageSource, collapsed ? StartGroupCollapsedMessageType : StartGroupMessageType, LogMessageLevel, "", arguments, callStack, m_groupLevel)); } void InspectorController::endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL) @@ -481,10 +483,7 @@ void InspectorController::connectFrontend() releaseFrontendLifetimeAgents(); m_frontend = new InspectorFrontend(m_client); m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), m_frontend.get()); - -#if !LEGACY_RESOURCE_TRACKING_ENABLED m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_frontend.get()); -#endif #if ENABLE(DATABASE) m_storageAgent = InspectorStorageAgent::create(m_frontend.get()); @@ -500,6 +499,10 @@ void InspectorController::connectFrontend() m_applicationCacheAgent = new InspectorApplicationCacheAgent(this, m_frontend.get()); #endif +#if ENABLE(FILE_SYSTEM) + m_fileSystemAgent = InspectorFileSystemAgent::create(this, m_frontend.get()); +#endif + if (!InspectorInstrumentation::hasFrontends()) ScriptController::setCaptureCallStackForUncaughtExceptions(true); InspectorInstrumentation::frontendCreated(); @@ -509,7 +512,7 @@ void InspectorController::reuseFrontend() { connectFrontend(); restoreDebugger(); - restoreProfiler(); + restoreProfiler(ProfilerRestoreResetAgent); } void InspectorController::show() @@ -568,6 +571,7 @@ void InspectorController::disconnectFrontend() bool debuggerWasEnabled = debuggerEnabled(); disableDebugger(); m_attachDebuggerWhenShown = debuggerWasEnabled; + clearNativeBreakpoints(); #endif setSearchingForNode(false); unbindAllResources(); @@ -577,7 +581,7 @@ void InspectorController::disconnectFrontend() #if ENABLE(JAVASCRIPT_DEBUGGER) m_profilerAgent->setFrontend(0); - m_profilerAgent->stopUserInitiatedProfiling(); + m_profilerAgent->stopUserInitiatedProfiling(true); #endif releaseFrontendLifetimeAgents(); @@ -586,9 +590,7 @@ void InspectorController::disconnectFrontend() void InspectorController::releaseFrontendLifetimeAgents() { -#if !LEGACY_RESOURCE_TRACKING_ENABLED m_resourceAgent.clear(); -#endif // m_domAgent is RefPtr. Remove DOM listeners first to ensure that there are // no references to the DOM agent from the DOM tree. @@ -605,6 +607,12 @@ void InspectorController::releaseFrontendLifetimeAgents() #if ENABLE(OFFLINE_WEB_APPLICATIONS) m_applicationCacheAgent.clear(); #endif + +#if ENABLE(FILE_SYSTEM) + if (m_fileSystemAgent) + m_fileSystemAgent->stop(); + m_fileSystemAgent.clear(); +#endif } void InspectorController::populateScriptObjects() @@ -623,17 +631,6 @@ void InspectorController::populateScriptObjects() m_frontend->profilerWasEnabled(); #endif -#if LEGACY_RESOURCE_TRACKING_ENABLED - ResourcesMap::iterator resourcesEnd = m_resources.end(); - for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) - it->second->updateScriptObject(m_frontend.get()); -#endif - - if (m_domContentEventTime != -1.0) - m_frontend->domContentEventFired(m_domContentEventTime); - if (m_loadEventTime != -1.0) - m_frontend->loadEventFired(m_loadEventTime); - m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); if (m_nodeToFocus) @@ -663,7 +660,7 @@ void InspectorController::populateScriptObjects() m_pendingEvaluateTestCommands.clear(); restoreDebugger(); - restoreProfiler(); + restoreProfiler(ProfilerRestoreNoAction); } void InspectorController::restoreDebugger() @@ -679,24 +676,20 @@ void InspectorController::restoreDebugger() #endif } -void InspectorController::restoreProfiler() +void InspectorController::restoreProfiler(ProfilerRestoreAction action) { ASSERT(m_frontend); #if ENABLE(JAVASCRIPT_DEBUGGER) m_profilerAgent->setFrontend(m_frontend.get()); if (!ScriptProfiler::isProfilerAlwaysEnabled() && m_state->getBoolean(InspectorState::profilerAlwaysEnabled)) enableProfiler(); + if (action == ProfilerRestoreResetAgent) + m_profilerAgent->resetState(); #endif } void InspectorController::unbindAllResources() { -#if LEGACY_RESOURCE_TRACKING_ENABLED - ResourcesMap::iterator resourcesEnd = m_resources.end(); - for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) - it->second->releaseScriptObject(0); -#endif - #if ENABLE(DATABASE) DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end(); for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) @@ -711,36 +704,13 @@ void InspectorController::unbindAllResources() m_timelineAgent->reset(); } -#if LEGACY_RESOURCE_TRACKING_ENABLED -void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoader* loaderToKeep) -{ - ASSERT_ARG(resourceMap, resourceMap); - - ResourcesMap mapCopy(*resourceMap); - ResourcesMap::iterator end = mapCopy.end(); - for (ResourcesMap::iterator it = mapCopy.begin(); it != end; ++it) { - InspectorResource* resource = (*it).second.get(); - if (resource == m_mainResource) - continue; - - if (!loaderToKeep || !resource->isSameLoader(loaderToKeep)) { - removeResource(resource); - if (m_frontend) - resource->releaseScriptObject(m_frontend.get()); - } - } -} -#endif - void InspectorController::didCommitLoad(DocumentLoader* loader) { if (!enabled()) return; -#if !LEGACY_RESOURCE_TRACKING_ENABLED if (m_resourceAgent) m_resourceAgent->didCommitLoad(loader); -#endif ASSERT(m_inspectedPage); @@ -758,13 +728,11 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) if (m_debuggerAgent) m_debuggerAgent->clearForPageNavigation(); - m_nativeBreakpoints.clear(); - m_eventListenerBreakpoints.clear(); - m_XHRBreakpoints.clear(); - m_lastBreakpointId = 0; + clearNativeBreakpoints(); #endif #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) + m_profilerAgent->stopUserInitiatedProfiling(true); m_profilerAgent->resetState(); #endif @@ -788,32 +756,11 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) #endif if (m_frontend) { -#if LEGACY_RESOURCE_TRACKING_ENABLED - if (!loader->frameLoader()->isLoadingFromCachedPage()) { - ASSERT(m_mainResource && m_mainResource->isSameLoader(loader)); - // We don't add the main resource until its load is committed. This is - // needed to keep the load for a user-entered URL from showing up in the - // list of resources for the page they are navigating away from. - m_mainResource->updateScriptObject(m_frontend.get()); - } else { - // Pages loaded from the page cache are committed before - // m_mainResource is the right resource for this load, so we - // clear it here. It will be re-assigned in - // identifierForInitialRequest. - m_mainResource = 0; - } -#endif m_mainResourceIdentifier = 0; m_frontend->didCommitLoad(); m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); } } - -#if LEGACY_RESOURCE_TRACKING_ENABLED - for (Frame* frame = loader->frame(); frame; frame = frame->tree()->traverseNext(loader->frame())) - if (ResourcesMap* resourceMap = m_frameResources.get(frame)) - pruneResources(resourceMap, loader); -#endif } void InspectorController::frameDetachedFromParent(Frame* rootFrame) @@ -821,105 +768,19 @@ void InspectorController::frameDetachedFromParent(Frame* rootFrame) if (!enabled()) return; -#if LEGACY_RESOURCE_TRACKING_ENABLED - for (Frame* frame = rootFrame; frame; frame = frame->tree()->traverseNext(rootFrame)) - if (ResourcesMap* resourceMap = m_frameResources.get(frame)) - removeAllResources(resourceMap); -#else if (m_resourceAgent) m_resourceAgent->frameDetachedFromParent(rootFrame); -#endif -} - -#if LEGACY_RESOURCE_TRACKING_ENABLED -void InspectorController::addResource(InspectorResource* resource) -{ - m_resources.set(resource->identifier(), resource); - m_knownResources.add(resource->requestURL()); - - Frame* frame = resource->frame(); - if (!frame) - return; - ResourcesMap* resourceMap = m_frameResources.get(frame); - if (resourceMap) - resourceMap->set(resource->identifier(), resource); - else { - resourceMap = new ResourcesMap; - resourceMap->set(resource->identifier(), resource); - m_frameResources.set(frame, resourceMap); - } -} - -void InspectorController::removeResource(InspectorResource* resource) -{ - m_resources.remove(resource->identifier()); - String requestURL = resource->requestURL(); - if (!requestURL.isNull()) - m_knownResources.remove(requestURL); - - Frame* frame = resource->frame(); - if (!frame) - return; - ResourcesMap* resourceMap = m_frameResources.get(frame); - if (!resourceMap) { - ASSERT_NOT_REACHED(); - return; - } - - resourceMap->remove(resource->identifier()); - if (resourceMap->isEmpty()) { - m_frameResources.remove(frame); - delete resourceMap; - } } -InspectorResource* InspectorController::getTrackedResource(unsigned long identifier) -{ - if (!enabled()) - return 0; - - if (resourceTrackingEnabled()) - return m_resources.get(identifier).get(); - - bool isMainResource = m_mainResource && m_mainResource->identifier() == identifier; - if (isMainResource) - return m_mainResource.get(); - - return 0; -} -#endif - void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, const CachedResource* cachedResource) { if (!enabled()) return; -#if LEGACY_RESOURCE_TRACKING_ENABLED - // If the resource URL is already known, we don't need to add it again since this is just a cached load. - if (m_knownResources.contains(cachedResource->url())) - return; - - ASSERT(m_inspectedPage); - bool isMainResource = isMainResourceLoader(loader, KURL(ParsedURLString, cachedResource->url())); ensureSettingsLoaded(); - if (!isMainResource && !resourceTrackingEnabled()) - return; - - RefPtr<InspectorResource> resource = InspectorResource::createCached(m_inspectedPage->progress()->createUniqueIdentifier(), loader, cachedResource); - - if (isMainResource) { - m_mainResource = resource; - resource->markMainResource(); - } - - addResource(resource.get()); - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->didLoadResourceFromMemoryCache(loader, cachedResource); -#endif } void InspectorController::identifierForInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) @@ -932,27 +793,10 @@ void InspectorController::identifierForInitialRequest(unsigned long identifier, if (isMainResource) m_mainResourceIdentifier = identifier; -#if LEGACY_RESOURCE_TRACKING_ENABLED - ensureSettingsLoaded(); - if (!isMainResource && !resourceTrackingEnabled()) - return; - - RefPtr<InspectorResource> resource = InspectorResource::create(identifier, loader, request.url()); - if (isMainResource) { - m_mainResource = resource; - resource->markMainResource(); - } - - addResource(resource.get()); - - if (m_frontend && loader->frameLoader()->isLoadingFromCachedPage() && resource == m_mainResource) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->identifierForInitialRequest(identifier, request.url(), loader); -#endif } void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loader, const KURL& url) @@ -960,11 +804,10 @@ void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loade if (!enabled() || !isMainResourceLoader(loader, url)) return; - m_domContentEventTime = currentTime(); if (m_timelineAgent) m_timelineAgent->didMarkDOMContentEvent(); if (m_frontend) - m_frontend->domContentEventFired(m_domContentEventTime); + m_frontend->domContentEventFired(currentTime()); } void InspectorController::mainResourceFiredLoadEvent(DocumentLoader* loader, const KURL& url) @@ -972,11 +815,10 @@ void InspectorController::mainResourceFiredLoadEvent(DocumentLoader* loader, con if (!enabled() || !isMainResourceLoader(loader, url)) return; - m_loadEventTime = currentTime(); if (m_timelineAgent) m_timelineAgent->didMarkLoadEvent(); if (m_frontend) - m_frontend->loadEventFired(m_loadEventTime); + m_frontend->loadEventFired(currentTime()); } bool InspectorController::isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl) @@ -1000,40 +842,8 @@ void InspectorController::willSendRequest(unsigned long identifier, ResourceRequ if (m_timelineAgent) m_timelineAgent->willSendResourceRequest(identifier, isMainResource, request); -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = getTrackedResource(identifier); - if (!resource) - return; - - if (!redirectResponse.isNull()) { - // Redirect may have empty URL and we'd like to not crash with invalid HashMap entry. - // See http/tests/misc/will-send-request-returns-null-on-redirect.html - if (!request.url().isEmpty()) { - resource->endTiming(0); - resource->updateResponse(redirectResponse); - - // We always store last redirect by the original id key. Rest of the redirects are stored within the last one. - unsigned long id = m_inspectedPage->progress()->createUniqueIdentifier(); - RefPtr<InspectorResource> withRedirect = resource->appendRedirect(id, request.url()); - removeResource(resource.get()); - addResource(withRedirect.get()); - if (isMainResource) { - m_mainResource = withRedirect; - withRedirect->markMainResource(); - } - resource = withRedirect; - } - } - - resource->startTiming(); - resource->updateRequest(request); - - if (resource != m_mainResource && m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->willSendRequest(identifier, request, redirectResponse); -#endif } void InspectorController::markResourceAsCached(unsigned long identifier) @@ -1041,13 +851,8 @@ void InspectorController::markResourceAsCached(unsigned long identifier) if (!enabled()) return; -#if LEGACY_RESOURCE_TRACKING_ENABLED - if (RefPtr<InspectorResource> resource = getTrackedResource(identifier)) - resource->markAsCached(); -#else if (m_resourceAgent) m_resourceAgent->markResourceAsCached(identifier); -#endif } void InspectorController::didReceiveResponse(unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response) @@ -1055,18 +860,8 @@ void InspectorController::didReceiveResponse(unsigned long identifier, DocumentL if (!enabled()) return; -#if LEGACY_RESOURCE_TRACKING_ENABLED - if (RefPtr<InspectorResource> resource = getTrackedResource(identifier)) { - resource->updateResponse(response); - - if (resource != m_mainResource && m_frontend) - resource->updateScriptObject(m_frontend.get()); - } - UNUSED_PARAM(loader); -#else if (m_resourceAgent) m_resourceAgent->didReceiveResponse(identifier, loader, response); -#endif if (response.httpStatusCode() >= 400) { String message = makeString("Failed to load resource: the server responded with a status of ", String::number(response.httpStatusCode()), " (", response.httpStatusText(), ')'); @@ -1079,19 +874,8 @@ void InspectorController::didReceiveContentLength(unsigned long identifier, int if (!enabled()) return; -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = getTrackedResource(identifier); - if (!resource) - return; - - resource->addLength(lengthReceived); - - if (resource != m_mainResource && m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->didReceiveContentLength(identifier, lengthReceived); -#endif } void InspectorController::didFinishLoading(unsigned long identifier, double finishTime) @@ -1102,20 +886,8 @@ void InspectorController::didFinishLoading(unsigned long identifier, double fini if (m_timelineAgent) m_timelineAgent->didFinishLoadingResource(identifier, false, finishTime); -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = getTrackedResource(identifier); - if (!resource) - return; - - resource->endTiming(finishTime); - - // No need to mute this event for main resource since it happens after did commit load. - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->didFinishLoading(identifier, finishTime); -#endif } void InspectorController::didFailLoading(unsigned long identifier, const ResourceError& error) @@ -1131,21 +903,8 @@ void InspectorController::didFailLoading(unsigned long identifier, const Resourc message += ": " + error.localizedDescription(); addMessageToConsole(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 0, error.failingURL()); -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = getTrackedResource(identifier); - if (!resource) - return; - - resource->markFailed(error.localizedDescription()); - resource->endTiming(0); - - // No need to mute this event for main resource since it happens after did commit load. - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->didFailLoading(identifier, error); -#endif } void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber) @@ -1156,22 +915,8 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi if (m_state->getBoolean(InspectorState::monitoringXHR)) addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, "XHR finished loading: \"" + url + "\".", sendLineNumber, sendURL); -#if LEGACY_RESOURCE_TRACKING_ENABLED - if (!resourceTrackingEnabled()) - return; - - InspectorResource* resource = m_resources.get(identifier).get(); - if (!resource) - return; - - resource->setOverrideContent(sourceString, InspectorResource::XHR); - - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) - m_resourceAgent->setOverrideContent(identifier, sourceString, InspectorResource::XHR); -#endif + m_resourceAgent->setOverrideContent(identifier, sourceString, "XHR"); } void InspectorController::scriptImported(unsigned long identifier, const String& sourceString) @@ -1179,56 +924,8 @@ void InspectorController::scriptImported(unsigned long identifier, const String& if (!enabled()) return; -#if LEGACY_RESOURCE_TRACKING_ENABLED - if (!resourceTrackingEnabled()) - return; - - InspectorResource* resource = m_resources.get(identifier).get(); - if (!resource) - return; - - resource->setOverrideContent(sourceString, InspectorResource::Script); - - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) - m_resourceAgent->setOverrideContent(identifier, sourceString, InspectorResource::Script); -#endif -} - -#if LEGACY_RESOURCE_TRACKING_ENABLED -void InspectorController::setResourceTrackingEnabled(bool enable) -{ - if (!enabled()) - return; - - ASSERT(m_inspectedPage); - m_state->setBoolean(InspectorState::resourceTrackingEnabled, enable); -} -#endif - -void InspectorController::setResourceTrackingEnabled(bool enable, bool always, bool* newState) -{ -#if LEGACY_RESOURCE_TRACKING_ENABLED - *newState = enable; - - if (always) - m_state->setBoolean(InspectorState::resourceTrackingAlwaysEnabled, enable); - - if (resourceTrackingEnabled() == enable) - return; - - ASSERT(m_inspectedPage); - m_state->setBoolean(InspectorState::resourceTrackingEnabled, enable); - - if (enable) - reloadPage(); -#else - UNUSED_PARAM(enable); - UNUSED_PARAM(always); - UNUSED_PARAM(newState); -#endif + m_resourceAgent->setOverrideContent(identifier, sourceString, "Script"); } void InspectorController::ensureSettingsLoaded() @@ -1238,9 +935,6 @@ void InspectorController::ensureSettingsLoaded() m_settingsLoaded = true; m_state->loadFromSettings(); - - if (m_state->getBoolean(InspectorState::resourceTrackingAlwaysEnabled)) - m_state->setBoolean(InspectorState::resourceTrackingEnabled, true); } void InspectorController::startTimelineProfiler() @@ -1553,67 +1247,27 @@ void InspectorController::didCreateWebSocket(unsigned long identifier, const KUR return; ASSERT(m_inspectedPage); -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = InspectorResource::createWebSocket(identifier, requestURL, documentURL); - addResource(resource.get()); - - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->didCreateWebSocket(identifier, requestURL); UNUSED_PARAM(documentURL); -#endif } void InspectorController::willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest& request) { -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = getTrackedResource(identifier); - if (!resource) - return; - resource->startTiming(); - resource->updateWebSocketRequest(request); - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->willSendWebSocketHandshakeRequest(identifier, request); -#endif } void InspectorController::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse& response) { -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = getTrackedResource(identifier); - if (!resource) - return; - // Calling resource->markResponseReceivedTime() here makes resources bar chart confusing, because - // we cannot apply the "latency + download" model of regular resources to WebSocket connections. - // FIXME: Design a new UI for bar charts of WebSocket resources, and record timing here. - resource->updateWebSocketResponse(response); - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->didReceiveWebSocketHandshakeResponse(identifier, response); -#endif } void InspectorController::didCloseWebSocket(unsigned long identifier) { -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = getTrackedResource(identifier); - if (!resource) - return; - - resource->endTiming(0); - if (m_frontend) - resource->updateScriptObject(m_frontend.get()); -#else if (m_resourceAgent) m_resourceAgent->didCloseWebSocket(identifier); -#endif } #endif // ENABLE(WEB_SOCKETS) @@ -1651,6 +1305,7 @@ void InspectorController::startUserInitiatedProfiling() if (!enabled()) return; m_profilerAgent->startUserInitiatedProfiling(); + m_state->setBoolean(InspectorState::userInitiatedProfiling, true); } void InspectorController::stopUserInitiatedProfiling() @@ -1658,6 +1313,7 @@ void InspectorController::stopUserInitiatedProfiling() if (!enabled()) return; m_profilerAgent->stopUserInitiatedProfiling(); + m_state->setBoolean(InspectorState::userInitiatedProfiling, false); } bool InspectorController::profilerEnabled() const @@ -1802,6 +1458,14 @@ String InspectorController::findXHRBreakpoint(const String& url) } return ""; } + +void InspectorController::clearNativeBreakpoints() +{ + m_nativeBreakpoints.clear(); + m_eventListenerBreakpoints.clear(); + m_XHRBreakpoints.clear(); + m_lastBreakpointId = 0; +} #endif void InspectorController::evaluateForTestInFrontend(long callId, const String& script) @@ -2157,22 +1821,6 @@ void InspectorController::setInspectorExtensionAPI(const String& source) m_inspectorExtensionAPI = source; } -void InspectorController::getResourceContent(unsigned long identifier, bool encode, String* content) -{ -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> resource = m_resources.get(identifier); - if (!resource) { - *content = String(); - return; - } - *content = encode ? resource->sourceBytes() : resource->sourceString(); -#else - UNUSED_PARAM(identifier); - UNUSED_PARAM(encode); - UNUSED_PARAM(content); -#endif -} - void InspectorController::reloadPage() { // FIXME: Why do we set the user gesture indicator here? diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h index 80d094f..7dadaa9 100644 --- a/WebCore/inspector/InspectorController.h +++ b/WebCore/inspector/InspectorController.h @@ -80,22 +80,21 @@ class Page; class ResourceRequest; class ResourceResponse; class ResourceError; +class ScriptArguments; class ScriptCallStack; class ScriptProfile; class SharedBuffer; class Storage; class StorageArea; -#define LEGACY_RESOURCE_TRACKING_ENABLED 1 - -#if LEGACY_RESOURCE_TRACKING_ENABLED -class InspectorResource; -#endif - #if ENABLE(OFFLINE_WEB_APPLICATIONS) class InspectorApplicationCacheAgent; #endif +#if ENABLE(FILE_SYSTEM) +class InspectorFileSystemAgent; +#endif + #if ENABLE(WEB_SOCKETS) class WebSocketHandshakeRequest; class WebSocketHandshakeResponse; @@ -103,10 +102,6 @@ class WebSocketHandshakeResponse; class InspectorController : public Noncopyable { public: -#if LEGACY_RESOURCE_TRACKING_ENABLED - typedef HashMap<unsigned long, RefPtr<InspectorResource> > ResourcesMap; - typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap; -#endif typedef HashMap<int, RefPtr<InspectorDatabaseResource> > DatabaseResourcesMap; typedef HashMap<int, RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesMap; @@ -138,6 +133,9 @@ public: void highlightDOMNode(long nodeId); void hideDOMNodeHighlight() { hideHighlight(); } + void highlightFrame(unsigned long frameId); + void hideFrameHighlight() { hideHighlight(); } + void show(); void showPanel(const String&); void close(); @@ -147,8 +145,8 @@ public: void disconnectFrontend(); void setConsoleMessagesEnabled(bool enabled, bool* newState); - void addMessageToConsole(MessageSource, MessageType, MessageLevel, ScriptCallStack*, const String& message); - void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID); + void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack>); + void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String&); void clearConsoleMessages(); const Vector<OwnPtr<ConsoleMessage> >& consoleMessages() const { return m_consoleMessages; } @@ -175,12 +173,6 @@ public: void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber); void scriptImported(unsigned long identifier, const String& sourceString); - void setResourceTrackingEnabled(bool enabled, bool always, bool* newState); -#if LEGACY_RESOURCE_TRACKING_ENABLED - void setResourceTrackingEnabled(bool enabled); - bool resourceTrackingEnabled() const; -#endif - void ensureSettingsLoaded(); void startTimelineProfiler(); @@ -194,6 +186,10 @@ public: InspectorApplicationCacheAgent* applicationCacheAgent() { return m_applicationCacheAgent.get(); } #endif +#if ENABLE(FILE_SYSTEM) + InspectorFileSystemAgent* fileSystemAgent() { return m_fileSystemAgent.get(); } +#endif + void mainResourceFiredLoadEvent(DocumentLoader*, const KURL&); void mainResourceFiredDOMContentEvent(DocumentLoader*, const KURL&); @@ -222,10 +218,6 @@ public: void didCloseWebSocket(unsigned long identifier); #endif -#if LEGACY_RESOURCE_TRACKING_ENABLED - const ResourcesMap& resources() const { return m_resources; } -#endif - bool hasFrontend() const { return m_frontend; } void drawNodeHighlight(GraphicsContext&) const; @@ -237,7 +229,7 @@ public: void startTiming(const String& title); bool stopTiming(const String& title, double& elapsed); - void startGroup(MessageSource source, ScriptCallStack* callFrame, bool collapsed = false); + void startGroup(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack> callFrame, bool collapsed = false); void endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL); void markTimeline(const String& message); @@ -248,7 +240,9 @@ public: void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL); bool isRecordingUserInitiatedProfile() const; String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false); + void startProfiling() { startUserInitiatedProfiling(); } void startUserInitiatedProfiling(); + void stopProfiling() { stopUserInitiatedProfiling(); } void stopUserInitiatedProfiling(); void enableProfiler(bool always = false, bool skipRecompile = false); void disableProfiler(bool always = false); @@ -289,9 +283,14 @@ private: friend class InspectorInstrumentation; friend class InjectedScriptHost; + enum ProfilerRestoreAction { + ProfilerRestoreNoAction = 0, + ProfilerRestoreResetAgent = 1 + }; + void populateScriptObjects(); void restoreDebugger(); - void restoreProfiler(); + void restoreProfiler(ProfilerRestoreAction action); void unbindAllResources(); void setSearchingForNode(bool enabled); @@ -308,6 +307,7 @@ private: String findEventListenerBreakpoint(const String& eventName); String findXHRBreakpoint(const String& url); + void clearNativeBreakpoints(); #endif #if ENABLE(DATABASE) void selectDatabase(Database* database); @@ -324,15 +324,6 @@ private: void addConsoleMessage(PassOwnPtr<ConsoleMessage>); -#if LEGACY_RESOURCE_TRACKING_ENABLED - void addResource(InspectorResource*); - void removeResource(InspectorResource*); - InspectorResource* getTrackedResource(unsigned long identifier); - void pruneResources(ResourcesMap*, DocumentLoader* loaderToKeep = 0); - void removeAllResources(ResourcesMap* map) { pruneResources(map); } -#endif - void getResourceContent(unsigned long identifier, bool encode, String* content); - bool isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl); void didEvaluateForTestInFrontend(long callId, const String& jsonResult); @@ -358,17 +349,14 @@ private: #if ENABLE(OFFLINE_WEB_APPLICATIONS) OwnPtr<InspectorApplicationCacheAgent> m_applicationCacheAgent; #endif + +#if ENABLE(FILE_SYSTEM) + RefPtr<InspectorFileSystemAgent> m_fileSystemAgent; +#endif + RefPtr<Node> m_nodeToFocus; -#if LEGACY_RESOURCE_TRACKING_ENABLED - RefPtr<InspectorResource> m_mainResource; - ResourcesMap m_resources; - HashSet<String> m_knownResources; - FrameResourcesMap m_frameResources; -#endif RefPtr<InspectorResourceAgent> m_resourceAgent; unsigned long m_mainResourceIdentifier; - double m_loadEventTime; - double m_domContentEventTime; Vector<OwnPtr<ConsoleMessage> > m_consoleMessages; unsigned m_expiredConsoleMessageCount; HashMap<String, double> m_times; diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp index cfb55fc..9316296 100644 --- a/WebCore/inspector/InspectorDOMAgent.cpp +++ b/WebCore/inspector/InspectorDOMAgent.cpp @@ -568,6 +568,12 @@ void InspectorDOMAgent::setOuterHTML(long nodeId, const String& outerHTML, long* } Node* newNode = previousSibling ? previousSibling->nextSibling() : parentNode->firstChild(); + if (!newNode) { + // The only child node has been deleted. + *newId = 0; + return; + } + *newId = pushNodePathToFrontend(newNode); if (childrenRequested) pushChildNodesToFrontend(*newId); diff --git a/WebCore/inspector/InspectorFileSystemAgent.cpp b/WebCore/inspector/InspectorFileSystemAgent.cpp new file mode 100644 index 0000000..2192fd1 --- /dev/null +++ b/WebCore/inspector/InspectorFileSystemAgent.cpp @@ -0,0 +1,162 @@ +/* + * 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 "InspectorFileSystemAgent.h" + +#if ENABLE(INSPECTOR) && ENABLE(FILE_SYSTEM) + +#include "AsyncFileWriter.h" +#include "Document.h" +#include "FileSystem.h" +#include "FileSystemCallbacks.h" +#include "Frame.h" +#include "FrameTree.h" +#include "InspectorController.h" +#include "InspectorFrontend.h" +#include "LocalFileSystem.h" +#include "Page.h" +#include "RuntimeEnabledFeatures.h" + +namespace WebCore { + +class InspectorFileSystemAgentCallbacks : public AsyncFileSystemCallbacks { +public: + InspectorFileSystemAgentCallbacks(InspectorFileSystemAgent* agent, AsyncFileSystem::Type type, const String& origin) + : m_agent(agent) + , m_type(type) + , m_origin(origin) + { + } + + ~InspectorFileSystemAgentCallbacks() + { + } + + // FileSystemCallbacks is only used for getting filesystem. All other methods are irrelevant and will not be called. + void didSucceed() + { + ASSERT_NOT_REACHED(); + } + + void didOpenFileSystem(const String& name, PassOwnPtr<AsyncFileSystem> fileSystem) + { + // Agent will be alive even if InspectorController is destroyed until callback is run. + m_agent->didGetFileSystemPath(fileSystem->root(), m_type, m_origin); + } + + void didReadMetadata(const FileMetadata&) + { + ASSERT_NOT_REACHED(); + } + + void didReadDirectoryEntry(const String& name, bool isDirectory) + { + ASSERT_NOT_REACHED(); + } + + void didReadDirectoryEntries(bool hasMore) + { + ASSERT_NOT_REACHED(); + } + + void didCreateFileWriter(PassOwnPtr<AsyncFileWriter> writer, long long length) + { + ASSERT_NOT_REACHED(); + } + + void didFail(int code) + { + // FIXME: Is it useful to give back the code to Inspector UI? + m_agent->didGetFileSystemError(m_type, m_origin); + } + +private: + RefPtr<InspectorFileSystemAgent> m_agent; + AsyncFileSystem::Type m_type; + String m_origin; +}; + +InspectorFileSystemAgent::InspectorFileSystemAgent(InspectorController* inspectorController, InspectorFrontend* frontend) + : m_inspectorController(inspectorController) + , m_frontend(frontend) +{ +} + +InspectorFileSystemAgent::~InspectorFileSystemAgent() { } + +void InspectorFileSystemAgent::stop() +{ + m_inspectorController = 0; +} + +void InspectorFileSystemAgent::revealFolderInOS(const String& path) +{ + WebCore::revealFolderInOS(path); +} + +void InspectorFileSystemAgent::getFileSystemPathAsync(unsigned int type, const String& origin) +{ + if (!RuntimeEnabledFeatures::fileSystemEnabled()) { + m_frontend->didGetFileSystemDisabled(); + return; + } + + AsyncFileSystem::Type asyncFileSystemType = static_cast<AsyncFileSystem::Type>(type); + Frame* mainFrame = m_inspectorController->inspectedPage()->mainFrame(); + for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) { + Document* document = frame->document(); + if (document && document->securityOrigin()->toString() == origin) { + LocalFileSystem::localFileSystem().readFileSystem(document, asyncFileSystemType, 0, new InspectorFileSystemAgentCallbacks(this, asyncFileSystemType, origin)); + return; + } + } +} + +void InspectorFileSystemAgent::didGetFileSystemPath(const String& root, AsyncFileSystem::Type type, const String& origin) +{ + // When controller is being destroyed, this is set to 0. Agent can live even after m_inspectorController is destroyed. + if (!m_inspectorController) + return; + + m_frontend->didGetFileSystemPath(root, static_cast<unsigned int>(type), origin); +} + +void InspectorFileSystemAgent::didGetFileSystemError(AsyncFileSystem::Type type, const String& origin) +{ + // When controller is being destroyed, this is set to 0. Agent can live even after m_inspectorController is destroyed. + if (!m_inspectorController) + return; + m_frontend->didGetFileSystemError(static_cast<unsigned int>(type), origin); +} + +} // namespace WebCore + +#endif // ENABLE(INSPECTOR) && ENABLE(FILE_SYSTEM) diff --git a/WebCore/bindings/v8/ScriptCallFrame.h b/WebCore/inspector/InspectorFileSystemAgent.h index ff77d4a..a85ad0f 100644 --- a/WebCore/bindings/v8/ScriptCallFrame.h +++ b/WebCore/inspector/InspectorFileSystemAgent.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Google Inc. All rights reserved. + * 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 @@ -14,7 +14,7 @@ * * 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 @@ -28,46 +28,50 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ScriptCallFrame_h -#define ScriptCallFrame_h - -#include "KURL.h" +#ifndef InspectorFileSystemAgent_h +#define InspectorFileSystemAgent_h -#include <wtf/Vector.h> +#if ENABLE(INSPECTOR) && ENABLE(FILE_SYSTEM) -namespace v8 { - class Arguments; -} +#include "AsyncFileSystem.h" +#include "AsyncFileSystemCallbacks.h" +#include <wtf/PassRefPtr.h> namespace WebCore { - class ScriptValue; - // FIXME: Implement retrieving line number and source URL and storing here - // for all call frames, not just the first one. - // See <https://bugs.webkit.org/show_bug.cgi?id=22556> and - // <https://bugs.webkit.org/show_bug.cgi?id=21180> - class ScriptCallFrame { - public: - ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber, const v8::Arguments&, unsigned skipArgumentCount); - ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber); - ~ScriptCallFrame(); +class Document; +class InspectorController; +class InspectorFrontend; +class LocalFileSystem; + +class InspectorFileSystemAgent : public RefCounted<InspectorFileSystemAgent> { +public: + static PassRefPtr<InspectorFileSystemAgent> create(InspectorController* inspectorController, InspectorFrontend* frontend) + { + return adoptRef(new InspectorFileSystemAgent(inspectorController, frontend)); + } + + ~InspectorFileSystemAgent(); + void stop(); - const String& functionName() const { return m_functionName; } - const String& sourceURL() const { return m_sourceURL; } - unsigned lineNumber() const { return m_lineNumber; } + // From Frontend + void getFileSystemPathAsync(unsigned int type, const String& origin); + void revealFolderInOS(const String& path); - // argument retrieval methods - const ScriptValue& argumentAt(unsigned) const; - unsigned argumentCount() const { return m_arguments.size(); } + // Backend to Frontend + void didGetFileSystemPath(const String&, AsyncFileSystem::Type, const String& origin); + void didGetFileSystemError(AsyncFileSystem::Type, const String& origin); + void didGetFileSystemDisabled(); - private: - String m_functionName; - String m_sourceURL; - unsigned m_lineNumber; +private: + InspectorFileSystemAgent(InspectorController*, InspectorFrontend*); + void getFileSystemRoot(AsyncFileSystem::Type); - Vector<ScriptValue> m_arguments; - }; + InspectorController* m_inspectorController; + InspectorFrontend* m_frontend; +}; } // namespace WebCore -#endif // ScriptCallFrame_h +#endif // ENABLE(INSPECTOR) && ENABLE(FILE_SYSTEM) +#endif // InspectorFileSystemAgent_h diff --git a/WebCore/inspector/InspectorFrontendHost.cpp b/WebCore/inspector/InspectorFrontendHost.cpp index bc529ea..4b7e13f 100644 --- a/WebCore/inspector/InspectorFrontendHost.cpp +++ b/WebCore/inspector/InspectorFrontendHost.cpp @@ -42,7 +42,6 @@ #include "HitTestResult.h" #include "HTMLFrameOwnerElement.h" #include "InspectorFrontendClient.h" -#include "InspectorResource.h" #include "Page.h" #include "Pasteboard.h" #include "ScriptFunctionCall.h" diff --git a/WebCore/inspector/InspectorProfilerAgent.cpp b/WebCore/inspector/InspectorProfilerAgent.cpp index 71c7231..3f107d6 100644 --- a/WebCore/inspector/InspectorProfilerAgent.cpp +++ b/WebCore/inspector/InspectorProfilerAgent.cpp @@ -95,7 +95,7 @@ void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<Scrip void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL) { - String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), "#0 \" started."); + String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), "#0\" started."); m_inspectorController->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); } @@ -197,6 +197,8 @@ void InspectorProfilerAgent::resetState() void InspectorProfilerAgent::startUserInitiatedProfiling() { + if (m_recordingUserInitiatedProfile) + return; if (!enabled()) { enable(false); ScriptDebugServer::shared().recompileAllJSFunctions(); @@ -213,8 +215,10 @@ void InspectorProfilerAgent::startUserInitiatedProfiling() toggleRecordButton(true); } -void InspectorProfilerAgent::stopUserInitiatedProfiling() +void InspectorProfilerAgent::stopUserInitiatedProfiling(bool ignoreProfile) { + if (!m_recordingUserInitiatedProfile) + return; m_recordingUserInitiatedProfile = false; String title = getCurrentUserInitiatedProfileName(); #if USE(JSC) @@ -225,8 +229,12 @@ void InspectorProfilerAgent::stopUserInitiatedProfiling() ScriptState* scriptState = 0; #endif RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title); - if (profile) - addProfile(profile, 0, String()); + if (profile) { + if (!ignoreProfile) + addProfile(profile, 0, String()); + else + addProfileFinishedMessageToConsole(profile, 0, String()); + } toggleRecordButton(false); } diff --git a/WebCore/inspector/InspectorProfilerAgent.h b/WebCore/inspector/InspectorProfilerAgent.h index 421efb0..c1f5db1 100644 --- a/WebCore/inspector/InspectorProfilerAgent.h +++ b/WebCore/inspector/InspectorProfilerAgent.h @@ -66,10 +66,8 @@ public: void removeProfile(const String& type, unsigned uid); void resetState(); void setFrontend(InspectorFrontend* frontend) { m_frontend = frontend; } - void startProfiling() { startUserInitiatedProfiling(); } void startUserInitiatedProfiling(); - void stopProfiling() { stopUserInitiatedProfiling(); } - void stopUserInitiatedProfiling(); + void stopUserInitiatedProfiling(bool ignoreProfile = false); void takeHeapSnapshot(); void toggleRecordButton(bool isProfiling); diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp deleted file mode 100644 index 9b3f95d..0000000 --- a/WebCore/inspector/InspectorResource.cpp +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "InspectorResource.h" - -#if ENABLE(INSPECTOR) - -#include "Base64.h" -#include "Cache.h" -#include "CachedResource.h" -#include "CachedResourceLoader.h" -#include "DocumentLoader.h" -#include "Frame.h" -#include "InspectorFrontend.h" -#include "InspectorResourceAgent.h" -#include "InspectorValues.h" -#include "ResourceLoadTiming.h" -#include "ResourceRequest.h" -#include "ResourceResponse.h" -#include "TextEncoding.h" -#include "WebSocketHandshakeRequest.h" -#include "WebSocketHandshakeResponse.h" - -#include <wtf/Assertions.h> -#include <wtf/text/StringBuffer.h> - -namespace WebCore { - -#if ENABLE(WEB_SOCKETS) -// Create human-readable binary representation, like "01:23:45:67:89:AB:CD:EF". -static String createReadableStringFromBinary(const unsigned char* value, size_t length) -{ - ASSERT(length > 0); - static const char hexDigits[17] = "0123456789ABCDEF"; - size_t bufferSize = length * 3 - 1; - StringBuffer buffer(bufferSize); - size_t index = 0; - for (size_t i = 0; i < length; ++i) { - if (i > 0) - buffer[index++] = ':'; - buffer[index++] = hexDigits[value[i] >> 4]; - buffer[index++] = hexDigits[value[i] & 0xF]; - } - ASSERT(index == bufferSize); - return String::adopt(buffer); -} -#endif - -InspectorResource::InspectorResource(unsigned long identifier, DocumentLoader* loader, const KURL& requestURL) - : m_identifier(identifier) - , m_loader(loader) - , m_frame(loader ? loader->frame() : 0) - , m_requestURL(requestURL) - , m_expectedContentLength(0) - , m_cached(false) - , m_finished(false) - , m_failed(false) - , m_length(0) - , m_responseStatusCode(0) - , m_startTime(-1.0) - , m_responseReceivedTime(-1.0) - , m_endTime(-1.0) - , m_connectionID(0) - , m_connectionReused(false) - , m_isMainResource(false) -#if ENABLE(WEB_SOCKETS) - , m_isWebSocket(false) -#endif -{ -} - -InspectorResource::~InspectorResource() -{ -} - -PassRefPtr<InspectorResource> InspectorResource::appendRedirect(unsigned long identifier, const KURL& redirectURL) -{ - // Last redirect is always a container of all previous ones. Pass this container here. - RefPtr<InspectorResource> redirect = InspectorResource::create(m_identifier, m_loader.get(), redirectURL); - redirect->m_redirects = m_redirects; - redirect->m_redirects.append(this); - redirect->m_changes.set(RedirectsChange); - - m_identifier = identifier; - // Re-send request info with new id. - m_changes.set(RequestChange); - m_redirects.clear(); - return redirect; -} - -PassRefPtr<InspectorResource> InspectorResource::create(unsigned long identifier, DocumentLoader* loader, const KURL& requestURL) -{ - ASSERT(loader); - return adoptRef(new InspectorResource(identifier, loader, requestURL)); -} - -PassRefPtr<InspectorResource> InspectorResource::createCached(unsigned long identifier, DocumentLoader* loader, const CachedResource* cachedResource) -{ - PassRefPtr<InspectorResource> resource = create(identifier, loader, KURL(ParsedURLString, cachedResource->url())); - - resource->m_finished = true; - - resource->updateResponse(cachedResource->response()); - - resource->m_length = cachedResource->encodedSize(); - resource->m_cached = true; - resource->m_startTime = currentTime(); - resource->m_responseReceivedTime = resource->m_startTime; - resource->m_endTime = resource->m_startTime; - - resource->m_changes.setAll(); - - return resource; -} - -#if ENABLE(WEB_SOCKETS) -PassRefPtr<InspectorResource> InspectorResource::createWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL) -{ - RefPtr<InspectorResource> resource = adoptRef(new InspectorResource(identifier, 0, requestURL)); - resource->markWebSocket(); - resource->m_documentURL = documentURL; - resource->m_changes.setAll(); - return resource.release(); -} -#endif - -void InspectorResource::updateRequest(const ResourceRequest& request) -{ - m_requestHeaderFields = request.httpHeaderFields(); - m_requestMethod = request.httpMethod(); - if (request.httpBody() && !request.httpBody()->isEmpty()) - m_requestFormData = request.httpBody()->flattenToString(); - - m_changes.set(RequestChange); -} - -void InspectorResource::markAsCached() -{ - m_cached = true; -} - -void InspectorResource::updateResponse(const ResourceResponse& response) -{ - m_expectedContentLength = response.expectedContentLength(); - m_mimeType = response.mimeType(); - if (m_mimeType.isEmpty() && response.httpStatusCode() == 304) { - CachedResource* cachedResource = cache()->resourceForURL(response.url().string()); - if (cachedResource) - m_mimeType = cachedResource->response().mimeType(); - } - if (ResourceRawHeaders* headers = response.resourceRawHeaders().get()) { - m_requestHeaderFields = headers->requestHeaders; - m_responseHeaderFields = headers->responseHeaders; - m_changes.set(RequestChange); - } else - m_responseHeaderFields = response.httpHeaderFields(); - m_responseStatusCode = response.httpStatusCode(); - m_responseStatusText = response.httpStatusText(); - m_suggestedFilename = response.suggestedFilename(); - - m_connectionID = response.connectionID(); - m_connectionReused = response.connectionReused(); - m_loadTiming = response.resourceLoadTiming(); - m_cached = m_cached || response.wasCached(); - m_responseReceivedTime = currentTime(); - m_changes.set(TimingChange); - m_changes.set(ResponseChange); - m_changes.set(TypeChange); -} - -#if ENABLE(WEB_SOCKETS) -void InspectorResource::updateWebSocketRequest(const WebSocketHandshakeRequest& request) -{ - m_requestHeaderFields = request.headerFields(); - m_requestMethod = "GET"; // Currently we always use "GET" to request handshake. - m_webSocketRequestKey3.set(new WebSocketHandshakeRequest::Key3(request.key3())); - m_changes.set(RequestChange); - m_changes.set(TypeChange); -} - -void InspectorResource::updateWebSocketResponse(const WebSocketHandshakeResponse& response) -{ - m_responseStatusCode = response.statusCode(); - m_responseStatusText = response.statusText(); - m_responseHeaderFields = response.headerFields(); - m_webSocketChallengeResponse.set(new WebSocketHandshakeResponse::ChallengeResponse(response.challengeResponse())); - m_changes.set(ResponseChange); - m_changes.set(TypeChange); -} -#endif // ENABLE(WEB_SOCKETS) - -static PassRefPtr<InspectorObject> buildHeadersObject(const HTTPHeaderMap& headers) -{ - RefPtr<InspectorObject> object = InspectorObject::create(); - HTTPHeaderMap::const_iterator end = headers.end(); - for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it) { - object->setString(it->first.string(), it->second); - } - return object; -} - -static PassRefPtr<InspectorObject> buildObjectForTiming(ResourceLoadTiming* timing) -{ - RefPtr<InspectorObject> jsonObject = InspectorObject::create(); - jsonObject->setNumber("requestTime", timing->requestTime); - jsonObject->setNumber("proxyStart", timing->proxyStart); - jsonObject->setNumber("proxyEnd", timing->proxyEnd); - jsonObject->setNumber("dnsStart", timing->dnsStart); - jsonObject->setNumber("dnsEnd", timing->dnsEnd); - jsonObject->setNumber("connectStart", timing->connectStart); - jsonObject->setNumber("connectEnd", timing->connectEnd); - jsonObject->setNumber("sslStart", timing->sslStart); - jsonObject->setNumber("sslEnd", timing->sslEnd); - jsonObject->setNumber("sendStart", timing->sendStart); - jsonObject->setNumber("sendEnd", timing->sendEnd); - jsonObject->setNumber("receiveHeadersEnd", timing->receiveHeadersEnd); - return jsonObject; -} - - -void InspectorResource::updateScriptObject(InspectorFrontend* frontend) -{ - if (m_changes.hasChange(NoChange)) - return; - - RefPtr<InspectorObject> jsonObject = InspectorObject::create(); - jsonObject->setNumber("id", m_identifier); - if (m_changes.hasChange(RequestChange)) { - if (m_frame) - m_documentURL = m_frame->document()->url(); - jsonObject->setString("url", m_requestURL.string()); - jsonObject->setString("documentURL", m_documentURL.string()); - RefPtr<InspectorObject> requestHeaders = buildHeadersObject(m_requestHeaderFields); - jsonObject->setObject("requestHeaders", requestHeaders); - jsonObject->setBoolean("mainResource", m_isMainResource); - jsonObject->setString("requestMethod", m_requestMethod); - jsonObject->setString("requestFormData", m_requestFormData); - jsonObject->setBoolean("didRequestChange", true); -#if ENABLE(WEB_SOCKETS) - if (m_webSocketRequestKey3) - jsonObject->setString("webSocketRequestKey3", createReadableStringFromBinary(m_webSocketRequestKey3->value, sizeof(m_webSocketRequestKey3->value))); -#endif - } - - if (m_changes.hasChange(ResponseChange)) { - jsonObject->setString("mimeType", m_mimeType); - jsonObject->setString("suggestedFilename", m_suggestedFilename); - jsonObject->setNumber("expectedContentLength", m_expectedContentLength); - jsonObject->setNumber("statusCode", m_responseStatusCode); - jsonObject->setString("statusText", m_responseStatusText); - RefPtr<InspectorObject> responseHeaders = buildHeadersObject(m_responseHeaderFields); - jsonObject->setObject("responseHeaders", responseHeaders); - jsonObject->setNumber("connectionID", m_connectionID); - jsonObject->setBoolean("connectionReused", m_connectionReused); - jsonObject->setBoolean("cached", m_cached); - if (m_loadTiming && !m_cached) - jsonObject->setObject("timing", buildObjectForTiming(m_loadTiming.get())); -#if ENABLE(WEB_SOCKETS) - if (m_webSocketChallengeResponse) - jsonObject->setString("webSocketChallengeResponse", createReadableStringFromBinary(m_webSocketChallengeResponse->value, sizeof(m_webSocketChallengeResponse->value))); -#endif - jsonObject->setBoolean("didResponseChange", true); - } - - if (m_changes.hasChange(TypeChange)) { - jsonObject->setNumber("type", static_cast<int>(type())); - jsonObject->setBoolean("didTypeChange", true); - } - - if (m_changes.hasChange(LengthChange)) { - jsonObject->setNumber("resourceSize", m_length); - jsonObject->setBoolean("didLengthChange", true); - } - - if (m_changes.hasChange(CompletionChange)) { - jsonObject->setBoolean("failed", m_failed); - jsonObject->setString("localizedFailDescription", m_localizedFailDescription); - jsonObject->setBoolean("finished", m_finished); - jsonObject->setBoolean("didCompletionChange", true); - } - - if (m_changes.hasChange(TimingChange)) { - if (m_startTime > 0) - jsonObject->setNumber("startTime", m_startTime); - if (m_responseReceivedTime > 0) - jsonObject->setNumber("responseReceivedTime", m_responseReceivedTime); - if (m_endTime > 0) - jsonObject->setNumber("endTime", m_endTime); - jsonObject->setBoolean("didTimingChange", true); - } - - if (m_changes.hasChange(RedirectsChange)) { - for (size_t i = 0; i < m_redirects.size(); ++i) - m_redirects[i]->updateScriptObject(frontend); - } - - frontend->updateResource(jsonObject); - m_changes.clearAll(); -} - -void InspectorResource::releaseScriptObject(InspectorFrontend* frontend) -{ - m_changes.setAll(); - - for (size_t i = 0; i < m_redirects.size(); ++i) - m_redirects[i]->releaseScriptObject(frontend); - - if (frontend) - frontend->removeResource(m_identifier); -} - -static InspectorResource::Type cachedResourceType(CachedResource* cachedResource) -{ - if (!cachedResource) - return InspectorResource::Other; - - switch (cachedResource->type()) { - case CachedResource::ImageResource: - return InspectorResource::Image; - case CachedResource::FontResource: - return InspectorResource::Font; - case CachedResource::CSSStyleSheet: -#if ENABLE(XSLT) - case CachedResource::XSLStyleSheet: -#endif - return InspectorResource::Stylesheet; - case CachedResource::Script: - return InspectorResource::Script; - default: - return InspectorResource::Other; - } -} - -InspectorResource::Type InspectorResource::type() const -{ - if (!m_overrideContent.isNull()) - return m_overrideContentType; - -#if ENABLE(WEB_SOCKETS) - if (m_isWebSocket) - return WebSocket; -#endif - - ASSERT(m_loader); - - if (m_loader->frameLoader() && equalIgnoringFragmentIdentifier(m_requestURL, m_loader->frameLoader()->iconURL())) - return Image; - - if (!m_frame) - return Other; - - InspectorResource::Type resourceType = cachedResourceType(InspectorResourceAgent::cachedResource(m_frame.get(), m_requestURL)); - if (equalIgnoringFragmentIdentifier(m_requestURL, m_loader->requestURL()) && resourceType == Other) - return Doc; - - return resourceType; -} - -void InspectorResource::setOverrideContent(const String& data, Type type) -{ - m_overrideContent = data; - m_overrideContentType = type; - m_changes.set(TypeChange); -} - -String InspectorResource::sourceString() const -{ - if (!m_overrideContent.isNull()) - return String(m_overrideContent); - - String result; - if (!InspectorResourceAgent::resourceContent(m_frame.get(), m_requestURL, &result)) - return String(); - return result; -} - -String InspectorResource::sourceBytes() const -{ - Vector<char> out; - if (!m_overrideContent.isNull()) { - Vector<char> data; - String overrideContent = m_overrideContent; - data.append(overrideContent.characters(), overrideContent.length()); - base64Encode(data, out); - return String(out.data(), out.size()); - } - - String result; - if (!InspectorResourceAgent::resourceContentBase64(m_frame.get(), m_requestURL, &result)) - return String(); - return result; -} - -void InspectorResource::startTiming() -{ - m_startTime = currentTime(); - m_changes.set(TimingChange); -} - -void InspectorResource::endTiming(double actualEndTime) -{ - if (actualEndTime) - m_endTime = actualEndTime; - else - m_endTime = currentTime(); - - m_finished = true; - m_changes.set(TimingChange); - m_changes.set(CompletionChange); -} - -void InspectorResource::markFailed(const String& localizedDescription) -{ - m_failed = true; - m_localizedFailDescription = localizedDescription; - m_changes.set(CompletionChange); -} - -void InspectorResource::addLength(int lengthReceived) -{ - m_length += lengthReceived; - m_changes.set(LengthChange); - - // Update load time, otherwise the resource will - // have start time == end time and 0 load duration - // until its loading is completed. - m_endTime = currentTime(); - m_changes.set(TimingChange); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/WebCore/inspector/InspectorResource.h b/WebCore/inspector/InspectorResource.h deleted file mode 100644 index aa4c3b1..0000000 --- a/WebCore/inspector/InspectorResource.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorResource_h -#define InspectorResource_h - -#include "HTTPHeaderMap.h" -#include "KURL.h" -#include "WebSocketHandshakeRequest.h" -#include "WebSocketHandshakeResponse.h" - -#include <wtf/CurrentTime.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> - -namespace WebCore { - - class CachedResource; - class DocumentLoader; - class Frame; - class InspectorFrontend; - class ResourceLoadTiming; - class ResourceRequest; - class ResourceResponse; - -#if ENABLE(WEB_SOCKETS) - class WebSocketHandshakeRequest; - class WebSocketHandshakeResponse; -#endif - - class InspectorResource : public RefCounted<InspectorResource> { - public: - - // Keep these in sync with WebInspector.Resource.Type - enum Type { - Doc, - Stylesheet, - Image, - Font, - Script, - XHR, - Media, - WebSocket, - Other - }; - - static PassRefPtr<InspectorResource> create(unsigned long identifier, DocumentLoader* loader, const KURL& requestURL); - - static PassRefPtr<InspectorResource> createCached(unsigned long identifier, DocumentLoader*, const CachedResource*); - -#if ENABLE(WEB_SOCKETS) - // WebSocket resource doesn't have its loader. For WebSocket resources, m_loader and m_frame will become null. - static PassRefPtr<InspectorResource> createWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL); -#endif - - ~InspectorResource(); - - PassRefPtr<InspectorResource> appendRedirect(unsigned long identifier, const KURL& redirectURL); - void updateScriptObject(InspectorFrontend* frontend); - void releaseScriptObject(InspectorFrontend* frontend); - - void updateRequest(const ResourceRequest&); - void markAsCached(); - void updateResponse(const ResourceResponse&); - -#if ENABLE(WEB_SOCKETS) - void updateWebSocketRequest(const WebSocketHandshakeRequest&); - void updateWebSocketResponse(const WebSocketHandshakeResponse&); -#endif - - void setOverrideContent(const String& data, Type); - String sourceString() const; - String sourceBytes() const; - - bool isSameLoader(DocumentLoader* loader) const { return loader == m_loader; } - void markMainResource() { m_isMainResource = true; } - unsigned long identifier() const { return m_identifier; } - KURL requestURL() const { return m_requestURL; } - Frame* frame() const { return m_frame.get(); } - const String& mimeType() const { return m_mimeType; } - const HTTPHeaderMap& requestHeaderFields() const { return m_requestHeaderFields; } - const HTTPHeaderMap& responseHeaderFields() const { return m_responseHeaderFields; } - int responseStatusCode() const { return m_responseStatusCode; } - String requestMethod() const { return m_requestMethod; } - String requestFormData() const { return m_requestFormData; } - - void startTiming(); - void endTiming(double actualEndTime); - - void markFailed(const String& localizedDescription); - void addLength(int lengthReceived); - - private: - enum ChangeType { - NoChange = 0, - RequestChange = 1, - ResponseChange = 2, - TypeChange = 4, - LengthChange = 8, - CompletionChange = 16, - TimingChange = 32, - RedirectsChange = 64 - }; - - class Changes { - public: - Changes() : m_change(NoChange) {} - - inline bool hasChange(ChangeType change) - { - return m_change & change || (m_change == NoChange && change == NoChange); - } - inline void set(ChangeType change) - { - m_change = static_cast<ChangeType>(static_cast<unsigned>(m_change) | static_cast<unsigned>(change)); - } - inline void clear(ChangeType change) - { - m_change = static_cast<ChangeType>(static_cast<unsigned>(m_change) & ~static_cast<unsigned>(change)); - } - - inline void setAll() { m_change = static_cast<ChangeType>(127); } - inline void clearAll() { m_change = NoChange; } - - private: - ChangeType m_change; - }; - - InspectorResource(unsigned long identifier, DocumentLoader*, const KURL& requestURL); - Type type() const; - -#if ENABLE(WEB_SOCKETS) - void markWebSocket() { m_isWebSocket = true; } -#endif - - unsigned long m_identifier; - RefPtr<DocumentLoader> m_loader; - RefPtr<Frame> m_frame; - KURL m_requestURL; - KURL m_documentURL; - HTTPHeaderMap m_requestHeaderFields; - HTTPHeaderMap m_responseHeaderFields; - String m_mimeType; - String m_suggestedFilename; - long long m_expectedContentLength; - bool m_cached; - bool m_finished; - bool m_failed; - String m_localizedFailDescription; - int m_length; - int m_responseStatusCode; - String m_responseStatusText; - double m_startTime; - double m_responseReceivedTime; - double m_endTime; - unsigned m_connectionID; - bool m_connectionReused; - RefPtr<ResourceLoadTiming> m_loadTiming; - String m_overrideContent; - Type m_overrideContentType; - Changes m_changes; - bool m_isMainResource; - String m_requestMethod; - String m_requestFormData; - Vector<RefPtr<InspectorResource> > m_redirects; - -#if ENABLE(WEB_SOCKETS) - bool m_isWebSocket; - - // The following fields are not used for resources other than WebSocket. - // We allocate them dynamically to reduce memory consumption for regular resources. - OwnPtr<WebSocketHandshakeRequest::Key3> m_webSocketRequestKey3; - OwnPtr<WebSocketHandshakeResponse::ChallengeResponse> m_webSocketChallengeResponse; -#endif - }; - -} // namespace WebCore - -#endif // InspectorResource_h diff --git a/WebCore/inspector/InspectorResourceAgent.cpp b/WebCore/inspector/InspectorResourceAgent.cpp index 2e965b6..0ed6cba 100644 --- a/WebCore/inspector/InspectorResourceAgent.cpp +++ b/WebCore/inspector/InspectorResourceAgent.cpp @@ -32,13 +32,15 @@ #include "InspectorResourceAgent.h" #include "Base64.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedResource.h" #include "CachedResourceLoader.h" #include "Document.h" #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoader.h" +#include "HTMLFrameOwnerElement.h" +#include "HTMLNames.h" #include "HTTPHeaderMap.h" #include "InspectorFrontend.h" #include "InspectorValues.h" @@ -53,6 +55,7 @@ #include "WebSocketHandshakeRequest.h" #include "WebSocketHandshakeResponse.h" +#include <wtf/CurrentTime.h> #include <wtf/ListHashSet.h> #include <wtf/RefPtr.h> #include <wtf/text/StringBuffer.h> @@ -199,10 +202,15 @@ static PassRefPtr<InspectorObject> buildObjectForResourceResponse(const Resource return responseObject; } +static unsigned long frameId(Frame* frame) +{ + return reinterpret_cast<uintptr_t>(frame); +} + static PassRefPtr<InspectorObject> buildObjectForDocumentLoader(DocumentLoader* loader) { RefPtr<InspectorObject> documentLoaderObject = InspectorObject::create(); - documentLoaderObject->setNumber("frameId", reinterpret_cast<uintptr_t>(loader->frame())); + documentLoaderObject->setNumber("frameId", frameId(loader->frame())); documentLoaderObject->setNumber("loaderId", reinterpret_cast<uintptr_t>(loader)); documentLoaderObject->setString("url", loader->requestURL().string()); return documentLoaderObject; @@ -290,6 +298,7 @@ void InspectorResourceAgent::markResourceAsCached(unsigned long identifier) void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response) { + RefPtr<InspectorObject> resourceResponse = buildObjectForResourceResponse(response); String type = "Other"; if (loader) { if (equalIgnoringFragmentIdentifier(response.url(), loader->frameLoader()->iconURL())) @@ -301,9 +310,13 @@ void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, Docume if (equalIgnoringFragmentIdentifier(response.url(), loader->url()) && type == "Other") type = "Document"; + + // Use mime type from cached resource in case the one in response is empty. + if (response.mimeType().isEmpty() && cachedResource) + resourceResponse->setString("mimeType", cachedResource->response().mimeType()); } } - m_frontend->didReceiveResponse(identifier, currentTime(), type, buildObjectForResourceResponse(response)); + m_frontend->didReceiveResponse(identifier, currentTime(), type, resourceResponse); } void InspectorResourceAgent::didReceiveContentLength(unsigned long identifier, int lengthReceived) @@ -329,28 +342,30 @@ void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* load m_frontend->didLoadResourceFromMemoryCache(currentTime(), buildObjectForCachedResource(loader, *resource)); } -void InspectorResourceAgent::setOverrideContent(unsigned long identifier, const String& sourceString, InspectorResource::Type type) +void InspectorResourceAgent::setOverrideContent(unsigned long identifier, const String& sourceString, const String& type) { - String typeString; - switch (type) { - case InspectorResource::XHR: - typeString = "XHR"; - break; - case InspectorResource::Script: - typeString = "Script"; - break; - default: - typeString = "Other"; - } + m_frontend->setOverrideContent(identifier, sourceString, type); +} - m_frontend->setOverrideContent(identifier, sourceString, typeString); +static PassRefPtr<InspectorObject> buildObjectForFrame(Frame* frame) +{ + RefPtr<InspectorObject> frameObject = InspectorObject::create(); + frameObject->setNumber("id", frameId(frame)); + frameObject->setNumber("parentId", frameId(frame->tree()->parent())); + if (frame->ownerElement()) { + String name = frame->ownerElement()->getAttribute(HTMLNames::nameAttr); + if (name.isEmpty()) + name = frame->ownerElement()->getAttribute(HTMLNames::idAttr); + frameObject->setString("name", name); + } + frameObject->setString("url", frame->loader()->url().string()); + return frameObject; } static PassRefPtr<InspectorObject> buildObjectForFrameTree(Frame* frame, bool dumpResources) { - RefPtr<InspectorObject> frameObject = InspectorObject::create(); - frameObject->setNumber("parentId", reinterpret_cast<uintptr_t>(frame->tree()->parent())); - frameObject->setNumber("id", reinterpret_cast<uintptr_t>(frame)); + RefPtr<InspectorObject> frameObject = buildObjectForFrame(frame); + if (dumpResources) populateObjectWithFrameResources(frame, frameObject); RefPtr<InspectorArray> childrenArray; @@ -366,13 +381,12 @@ static PassRefPtr<InspectorObject> buildObjectForFrameTree(Frame* frame, bool du void InspectorResourceAgent::didCommitLoad(DocumentLoader* loader) { - Frame* parentFrame = loader->frame()->tree()->parent(); - m_frontend->didCommitLoadForFrame(reinterpret_cast<uintptr_t>(parentFrame), buildObjectForDocumentLoader(loader)); + m_frontend->didCommitLoadForFrame(buildObjectForFrame(loader->frame()), buildObjectForDocumentLoader(loader)); } void InspectorResourceAgent::frameDetachedFromParent(Frame* frame) { - m_frontend->frameDetachedFromParent(reinterpret_cast<uintptr_t>(frame)); + m_frontend->frameDetachedFromParent(frameId(frame)); } #if ENABLE(WEB_SOCKETS) @@ -425,15 +439,25 @@ void InspectorResourceAgent::didCloseWebSocket(unsigned long identifier) } #endif // ENABLE(WEB_SOCKETS) +Frame* InspectorResourceAgent::frameForId(unsigned long frameId) +{ + Frame* mainFrame = m_page->mainFrame(); + for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext(mainFrame)) { + if (reinterpret_cast<uintptr_t>(frame) == frameId) + return frame; + } + return 0; +} + void InspectorResourceAgent::cachedResources(RefPtr<InspectorObject>* object) { *object = buildObjectForFrameTree(m_page->mainFrame(), true); } -void InspectorResourceAgent::resourceContent(unsigned long frameId, const String& url, bool base64Encode, String* content) +void InspectorResourceAgent::resourceContent(unsigned long id, const String& url, bool base64Encode, String* content) { for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext(m_page->mainFrame())) { - if (reinterpret_cast<uintptr_t>(frame) != frameId) + if (frameId(frame) != id) continue; if (base64Encode) InspectorResourceAgent::resourceContentBase64(frame, KURL(ParsedURLString, url), content); diff --git a/WebCore/inspector/InspectorResourceAgent.h b/WebCore/inspector/InspectorResourceAgent.h index 1cdd292..e3153bf 100644 --- a/WebCore/inspector/InspectorResourceAgent.h +++ b/WebCore/inspector/InspectorResourceAgent.h @@ -31,7 +31,6 @@ #ifndef InspectorResourceAgent_h #define InspectorResourceAgent_h -#include "InspectorResource.h" #include "PlatformString.h" #include <wtf/PassRefPtr.h> @@ -48,6 +47,7 @@ namespace WebCore { class CachedResource; class Document; class DocumentLoader; +class Frame; class InspectorArray; class InspectorObject; class InspectorFrontend; @@ -85,7 +85,7 @@ public: void didFinishLoading(unsigned long identifier, double finishTime); void didFailLoading(unsigned long identifier, const ResourceError&); void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*); - void setOverrideContent(unsigned long identifier, const String& sourceString, InspectorResource::Type); + void setOverrideContent(unsigned long identifier, const String& sourceString, const String& type); void didCommitLoad(DocumentLoader*); void frameDetachedFromParent(Frame*); @@ -96,6 +96,8 @@ public: void didCloseWebSocket(unsigned long identifier); #endif + Frame* frameForId(unsigned long); + // Called from frontend void cachedResources(RefPtr<InspectorObject>*); void resourceContent(unsigned long frameID, const String& url, bool base64Encode, String* content); diff --git a/WebCore/inspector/InspectorState.cpp b/WebCore/inspector/InspectorState.cpp index e6d3044..df939ba 100644 --- a/WebCore/inspector/InspectorState.cpp +++ b/WebCore/inspector/InspectorState.cpp @@ -39,9 +39,7 @@ namespace WebCore { InspectorState::InspectorState(InspectorClient* client) : m_client(client) { - registerBoolean(monitoringXHR, false, "monitoringXHR", "xhrMonitor"); - registerBoolean(resourceTrackingEnabled, false, "resourceTrackingEnabled", (const char*)0); - registerBoolean(resourceTrackingAlwaysEnabled, false, (const char*)0, "resourceTrackingEnabled"); + registerBoolean(monitoringXHR, false, "monitoringXHREnabled", "xhrMonitor"); registerBoolean(timelineProfilerEnabled, false, "timelineProfilerEnabled", (const char*)0); registerBoolean(searchingForNode, false, "searchingForNodeEnabled", (const char*)0); registerBoolean(profilerAlwaysEnabled, false, (const char*)0, "profilerEnabled"); @@ -50,6 +48,7 @@ InspectorState::InspectorState(InspectorClient* client) registerLong(inspectorAttachedHeight, InspectorController::defaultAttachedHeight, (const char*)0, "inspectorAttachedHeight"); registerLong(pauseOnExceptionsState, 0, "pauseOnExceptionsState", (const char*)0); registerBoolean(consoleMessagesEnabled, false, "consoleMessagesEnabled", (const char*)0); + registerBoolean(userInitiatedProfiling, false, "userInitiatedProfiling", (const char*)0); } void InspectorState::restoreFromInspectorCookie(const String& json) diff --git a/WebCore/inspector/InspectorState.h b/WebCore/inspector/InspectorState.h index 387f3c7..aa2f1ec 100644 --- a/WebCore/inspector/InspectorState.h +++ b/WebCore/inspector/InspectorState.h @@ -45,8 +45,6 @@ class InspectorState { public: enum InspectorPropertyId { monitoringXHR = 1, - resourceTrackingEnabled, - resourceTrackingAlwaysEnabled, timelineProfilerEnabled, searchingForNode, profilerAlwaysEnabled, @@ -56,6 +54,7 @@ public: inspectorAttachedHeight, pauseOnExceptionsState, consoleMessagesEnabled, + userInitiatedProfiling, lastPropertyId }; diff --git a/WebCore/inspector/ScriptArguments.cpp b/WebCore/inspector/ScriptArguments.cpp new file mode 100644 index 0000000..e30e135 --- /dev/null +++ b/WebCore/inspector/ScriptArguments.cpp @@ -0,0 +1,94 @@ +/* + * 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 "ScriptArguments.h" + +#include "ScriptValue.h" + +namespace WebCore { + +ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>& arguments) + : m_scriptState(scriptState) +{ + m_arguments.swap(arguments); +} + +ScriptArguments::~ScriptArguments() +{ +} + +const ScriptValue &ScriptArguments::argumentAt(size_t index) const +{ + ASSERT(m_arguments.size() > index); + return m_arguments[index]; +} + +ScriptState* ScriptArguments::globalState() const +{ + return m_scriptState.get(); +} + +bool ScriptArguments::getFirstArgumentAsString(String& result, bool checkForNullOrUndefined) +{ + if (!argumentCount()) + return false; + + const ScriptValue& value = argumentAt(0); + if (checkForNullOrUndefined && (value.isNull() || value.isUndefined())) + return false; + + if (!globalState()) { + ASSERT_NOT_REACHED(); + return false; + } + + result = value.toString(globalState()); + return true; +} + +bool ScriptArguments::isEqual(ScriptArguments* other) const +{ + if (!other) + return false; + + if (m_arguments.size() != other->m_arguments.size()) + return false; + if (!globalState() && m_arguments.size()) + return false; + + for (size_t i = 0; i < m_arguments.size(); ++i) { + if (!m_arguments[i].isEqual(other->globalState(), other->m_arguments[i])) + return false; + } + return true; +} + +} // namespace WebCore diff --git a/WebCore/inspector/ScriptArguments.h b/WebCore/inspector/ScriptArguments.h new file mode 100644 index 0000000..fdf05ab --- /dev/null +++ b/WebCore/inspector/ScriptArguments.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 ScriptArguments_h +#define ScriptArguments_h + +#include "PlatformString.h" +#include "ScriptState.h" +#include <wtf/Vector.h> + +namespace WebCore { + +class ScriptValue; + +class ScriptArguments { +public: + ScriptArguments(ScriptState*, Vector<ScriptValue>& arguments); + ~ScriptArguments(); + + const ScriptValue& argumentAt(size_t) const; + size_t argumentCount() const { return m_arguments.size(); } + + ScriptState* globalState() const; + + bool getFirstArgumentAsString(WTF::String& result, bool checkForNullOrUndefined = false); + bool isEqual(ScriptArguments*) const; + +private: + ScriptStateProtectedPtr m_scriptState; + Vector<ScriptValue> m_arguments; +}; + +} // namespace WebCore + +#endif // ScriptArguments_h diff --git a/WebCore/bindings/v8/ScriptCallFrame.cpp b/WebCore/inspector/ScriptCallFrame.cpp index f0c7343..5455d25 100644 --- a/WebCore/bindings/v8/ScriptCallFrame.cpp +++ b/WebCore/inspector/ScriptCallFrame.cpp @@ -1,10 +1,10 @@ /* - * Copyright (C) 2008, 2009 Google Inc. All rights reserved. - * + * 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 @@ -31,39 +31,36 @@ #include "config.h" #include "ScriptCallFrame.h" -#include <v8.h> - -#include "PlatformString.h" -#include "V8Binding.h" -#include "V8Proxy.h" -#include "ScriptValue.h" +#include "InspectorValues.h" +#include <wtf/RefPtr.h> namespace WebCore { -ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber, const v8::Arguments& arguments, unsigned skipArgumentCount) +ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& urlString, unsigned lineNumber) : m_functionName(functionName) , m_sourceURL(urlString) , m_lineNumber(lineNumber) { - for (int i = skipArgumentCount; i < arguments.Length(); ++i) - m_arguments.append(ScriptValue(arguments[i])); } -ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber) - : m_functionName(functionName) - , m_sourceURL(urlString) - , m_lineNumber(lineNumber) +ScriptCallFrame::~ScriptCallFrame() { } -ScriptCallFrame::~ScriptCallFrame() +bool ScriptCallFrame::isEqual(const ScriptCallFrame& o) const { + return m_functionName == o.m_functionName + && m_sourceURL == o.m_sourceURL + && m_lineNumber == o.m_lineNumber; } -const ScriptValue& ScriptCallFrame::argumentAt(unsigned index) const +PassRefPtr<InspectorObject> ScriptCallFrame::buildInspectorObject() const { - ASSERT(m_arguments.size() > index); - return m_arguments[index]; + RefPtr<InspectorObject> frame = InspectorObject::create(); + frame->setString("functionName", m_functionName); + frame->setString("sourceURL", m_sourceURL); + frame->setNumber("lineNumber", m_lineNumber); + return frame; } } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptCallFrame.h b/WebCore/inspector/ScriptCallFrame.h index 31aec7e..60d77e1 100644 --- a/WebCore/bindings/js/ScriptCallFrame.h +++ b/WebCore/inspector/ScriptCallFrame.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Google Inc. All rights reserved. + * 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 @@ -32,35 +32,28 @@ #define ScriptCallFrame_h #include "PlatformString.h" -#include "ScriptValue.h" -#include <wtf/Vector.h> - -namespace JSC { -class ExecState; -class UString; -} +#include <wtf/PassRefPtr.h> namespace WebCore { +class InspectorObject; + class ScriptCallFrame { public: - ScriptCallFrame(const JSC::UString& functionName, const JSC::UString& urlString, int lineNumber, JSC::ExecState*, unsigned skipArgumentCount); + ScriptCallFrame(const String& functionName, const String& urlString, unsigned lineNumber); ~ScriptCallFrame(); const String& functionName() const { return m_functionName; } const String& sourceURL() const { return m_sourceURL; } unsigned lineNumber() const { return m_lineNumber; } - // argument retrieval methods - const ScriptValue& argumentAt(unsigned) const; - unsigned argumentCount() const { return m_arguments.size(); } + bool isEqual(const ScriptCallFrame&) const; + PassRefPtr<InspectorObject> buildInspectorObject() const; private: String m_functionName; String m_sourceURL; unsigned m_lineNumber; - - Vector<ScriptValue> m_arguments; }; } // namespace WebCore diff --git a/WebCore/inspector/ScriptCallStack.cpp b/WebCore/inspector/ScriptCallStack.cpp new file mode 100644 index 0000000..8d010bb --- /dev/null +++ b/WebCore/inspector/ScriptCallStack.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2008, 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 "ScriptCallStack.h" + +#include "InspectorValues.h" + +namespace WebCore { + +ScriptCallStack::ScriptCallStack(Vector<ScriptCallFrame>& frames) +{ + m_frames.swap(frames); +} + +ScriptCallStack::~ScriptCallStack() +{ +} + +const ScriptCallFrame &ScriptCallStack::at(size_t index) +{ + ASSERT(m_frames.size() > index); + return m_frames[index]; +} + +size_t ScriptCallStack::size() +{ + return m_frames.size(); +} + +bool ScriptCallStack::isEqual(ScriptCallStack* o) const +{ + if (!o) + return false; + + size_t frameCount = o->m_frames.size(); + if (frameCount != m_frames.size()) + return false; + + for (size_t i = 0; i < frameCount; ++i) { + if (!m_frames[i].isEqual(o->m_frames[i])) + return false; + } + + return true; +} + +PassRefPtr<InspectorArray> ScriptCallStack::buildInspectorObject() const +{ + RefPtr<InspectorArray> frames = InspectorArray::create(); + for (size_t i = 0; i < m_frames.size(); i++) + frames->pushObject(m_frames.at(i).buildInspectorObject()); + return frames; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/ScriptCallStack.h b/WebCore/inspector/ScriptCallStack.h index 17d1c46..54c6bba 100644 --- a/WebCore/bindings/js/ScriptCallStack.h +++ b/WebCore/inspector/ScriptCallStack.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Google Inc. All rights reserved. + * Copyright (c) 2008, 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 @@ -32,39 +32,30 @@ #define ScriptCallStack_h #include "ScriptCallFrame.h" -#include "ScriptState.h" #include <wtf/Noncopyable.h> -#include <wtf/RefPtr.h> - -namespace JSC { - class ExecState; - class JSValue; -} +#include <wtf/Vector.h> namespace WebCore { - class InspectorArray; +class InspectorArray; + +class ScriptCallStack : public Noncopyable { +public: + static const size_t maxCallStackSizeToCapture = 200; - class ScriptCallStack : public Noncopyable { - public: - ScriptCallStack(JSC::ExecState*, unsigned skipArgumentCount = 0); - ~ScriptCallStack(); + ScriptCallStack(Vector<ScriptCallFrame>&); + ~ScriptCallStack(); - ScriptState* state() const { return m_exec; } - ScriptState* globalState() const { return m_exec->lexicalGlobalObject()->globalExec(); } - // frame retrieval methods - const ScriptCallFrame &at(unsigned); - unsigned size(); - static bool stackTrace(int, const RefPtr<InspectorArray>&); + const ScriptCallFrame &at(size_t); + size_t size(); + static bool stackTrace(int, const RefPtr<InspectorArray>&); - private: - void initialize(); - bool m_initialized; + bool isEqual(ScriptCallStack*) const; + PassRefPtr<InspectorArray> buildInspectorObject() const; - JSC::ExecState* m_exec; - Vector<ScriptCallFrame> m_frames; - JSC::JSFunction* m_caller; - }; +private: + Vector<ScriptCallFrame> m_frames; +}; } // namespace WebCore diff --git a/WebCore/inspector/front-end/AuditsPanel.js b/WebCore/inspector/front-end/AuditsPanel.js index b4eb202..096f8ce 100644 --- a/WebCore/inspector/front-end/AuditsPanel.js +++ b/WebCore/inspector/front-end/AuditsPanel.js @@ -203,20 +203,15 @@ WebInspector.AuditsPanel.prototype = { _reloadResources: function(callback) { - this._resourceTrackingCallback = callback; - - if (WebInspector.panels.resources && !WebInspector.panels.resources.resourceTrackingEnabled) { - WebInspector.panels.resources.toggleResourceTracking(false); - this._updateLauncherViewControls(true); - } else - InspectorBackend.reloadPage(); + this._pageReloadCallback = callback; + InspectorBackend.reloadPage(); }, _didMainResourceLoad: function() { - if (this._resourceTrackingCallback) { - var callback = this._resourceTrackingCallback; - delete this._resourceTrackingCallback; + if (this._pageReloadCallback) { + var callback = this._pageReloadCallback; + delete this._pageReloadCallback; callback(); } }, diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js index 77ba89d..221a777 100644 --- a/WebCore/inspector/front-end/BreakpointManager.js +++ b/WebCore/inspector/front-end/BreakpointManager.js @@ -28,7 +28,6 @@ WebInspector.BreakpointManager = function() { this._breakpoints = {}; this._nativeBreakpoints = {}; - this._domBreakpoints = {}; } WebInspector.BreakpointManager.prototype = { @@ -137,13 +136,12 @@ WebInspector.BreakpointManager.prototype = { var breakpoint = new WebInspector.DOMBreakpoint(this, frontendId, nodeId, domEventType); this._nativeBreakpoints[frontendId] = breakpoint; - this._domBreakpoints[frontendId] = breakpoint; this.dispatchEventToListeners("dom-breakpoint-added", breakpoint); breakpoint.enabled = !disabled; return breakpoint; }, - createEventListenerBreakpoint: function(eventName, disabled) + createEventListenerBreakpoint: function(eventName) { var frontendId = eventName; if (frontendId in this._nativeBreakpoints) @@ -151,7 +149,8 @@ WebInspector.BreakpointManager.prototype = { var breakpoint = new WebInspector.EventListenerBreakpoint(this, frontendId, eventName); this._nativeBreakpoints[frontendId] = breakpoint; - breakpoint.enabled = !disabled; + this.dispatchEventToListeners("event-listener-breakpoint-added", { breakpoint: breakpoint, eventName: eventName }); + breakpoint.enabled = true; return breakpoint; }, @@ -175,8 +174,7 @@ WebInspector.BreakpointManager.prototype = { if (breakpoint.enabled) this._removeNativeBreakpointFromBackend(breakpoint); delete this._nativeBreakpoints[breakpoint._frontendId]; - if (breakpoint._type === "DOM") - delete this._domBreakpoints[breakpoint._frontendId]; + this._updateNativeBreakpointsInSettings(); breakpoint.dispatchEventToListeners("removed"); }, @@ -195,7 +193,7 @@ WebInspector.BreakpointManager.prototype = { _setNativeBreakpointOnBackend: function(breakpoint) { breakpoint._beingSetOnBackend = true; - var data = { type: breakpoint._type, condition: breakpoint._condition() }; + var data = { type: breakpoint._type, condition: breakpoint._condition }; InspectorBackend.setNativeBreakpoint(data, didSetNativeBreakpoint.bind(this)); function didSetNativeBreakpoint(backendBreakpointId) @@ -206,6 +204,7 @@ WebInspector.BreakpointManager.prototype = { this._breakpoints[backendBreakpointId] = breakpoint; } breakpoint.dispatchEventToListeners("enable-changed"); + this._updateNativeBreakpointsInSettings(); } }, @@ -215,6 +214,18 @@ WebInspector.BreakpointManager.prototype = { delete this._breakpoints[breakpoint._backendId] delete breakpoint._backendId; breakpoint.dispatchEventToListeners("enable-changed"); + this._updateNativeBreakpointsInSettings(); + }, + + _updateNativeBreakpointsInSettings: function() + { + var persistentBreakpoints = []; + for (var id in this._nativeBreakpoints) { + var breakpoint = this._nativeBreakpoints[id]; + if (breakpoint._persistentCondition) + persistentBreakpoints.push({ type: breakpoint._type, enabled: breakpoint.enabled, condition: breakpoint._persistentCondition }); + } + WebInspector.settings.nativeBreakpoints = persistentBreakpoints; }, debuggerPaused: function(details) @@ -242,31 +253,60 @@ WebInspector.BreakpointManager.prototype = { delete this._lastHitBreakpoint; }, + restoreBreakpoints: function() + { + var breakpoints = this._persistentBreakpoints(); + for (var i = 0; i < breakpoints.length; ++i) { + if (breakpoints[i].type === "EventListener") + this.createEventListenerBreakpoint(breakpoints[i].condition.eventName); + else if (breakpoints[i].type === "XHR") + this.createXHRBreakpoint(breakpoints[i].condition.url, !breakpoints[i].enabled); + } + }, + restoreDOMBreakpoints: function() { - var domBreakpoints = this._domBreakpoints; - this._domBreakpoints = {}; + function didPushNodeByPathToFrontend(path, nodeId) + { + pathToNodeId[path] = nodeId; + pendingCalls -= 1; + if (pendingCalls) + return; + for (var i = 0; i < breakpoints.length; ++i) { + var breakpoint = breakpoints[i]; + var nodeId = pathToNodeId[breakpoint.condition.path]; + if (nodeId) + this.createDOMBreakpoint(nodeId, breakpoint.condition.type, !breakpoint.enabled); + } + } - var breakpointsToRestore = {}; - for (var frontendId in domBreakpoints) { - var breakpoint = domBreakpoints[frontendId]; - var path = breakpoint._path; - if (!path) + var breakpoints = this._persistentBreakpoints(); + var pathToNodeId = {}; + var pendingCalls = 0; + for (var i = 0; i < breakpoints.length; ++i) { + if (breakpoints[i].type !== "DOM") continue; - if (!breakpointsToRestore[path]) { - breakpointsToRestore[path] = []; - InspectorBackend.pushNodeByPathToFrontend(path, restoreBreakpointsForNode.bind(this, breakpointsToRestore[path])); - } - breakpointsToRestore[path].push(breakpoint); + var path = breakpoints[i].condition.path; + if (path in pathToNodeId) + continue; + pathToNodeId[path] = 0; + pendingCalls += 1; + InspectorBackend.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path)); } + }, - function restoreBreakpointsForNode(breakpoints, nodeId) - { - if (!nodeId) - return; - for (var i = 0; i < breakpoints.length; ++i) - this.createDOMBreakpoint(nodeId, breakpoints[i]._domEventType, !breakpoints[i].enabled); + _persistentBreakpoints: function() + { + var result = []; + var breakpoints = WebInspector.settings.nativeBreakpoints; + if (breakpoints instanceof Array) { + for (var i = 0; i < breakpoints.length; ++i) { + var breakpoint = breakpoints[i]; + if ("type" in breakpoint && "condition" in breakpoint) + result.push(breakpoint) + } } + return result; } } @@ -307,7 +347,7 @@ WebInspector.Breakpoint.prototype = { set sourceText(text) { this._sourceText = text; - this.dispatchEventToListeners("text-changed"); + this.dispatchEventToListeners("label-changed"); }, get id() @@ -332,6 +372,11 @@ WebInspector.Breakpoint.prototype = { this.dispatchEventToListeners("condition-changed"); }, + click: function(event) + { + WebInspector.panels.scripts.showSourceLine(this.url, this.line); + }, + compareTo: function(other) { if (this.url != other.url) @@ -341,6 +386,18 @@ WebInspector.Breakpoint.prototype = { return 0; }, + populateLabelElement: function(element) + { + var displayName = this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)"); + var labelElement = document.createTextNode(displayName + ":" + this.line); + element.appendChild(labelElement); + + var sourceTextElement = document.createElement("div"); + sourceTextElement.textContent = this.sourceText; + sourceTextElement.className = "source-text monospace"; + element.appendChild(sourceTextElement); + }, + remove: function() { InspectorBackend.removeBreakpoint(this.sourceID, this.line); @@ -405,20 +462,16 @@ WebInspector.DOMBreakpoint = function(manager, frontendId, nodeId, domEventType) WebInspector.NativeBreakpoint.call(this, manager, frontendId, "DOM"); this._nodeId = nodeId; this._domEventType = domEventType; + this._condition = { nodeId: this._nodeId, type: this._domEventType }; var node = WebInspector.domAgent.nodeForId(this._nodeId); if (node) { node.breakpoints[this._domEventType] = this; - this._path = node.path(); + this._persistentCondition = { path: node.path(), type: this._domEventType }; } } WebInspector.DOMBreakpoint.prototype = { - click: function() - { - WebInspector.updateFocusedNode(this._nodeId); - }, - compareTo: function(other) { return this._compare(this._domEventType, other._domEventType); @@ -426,9 +479,14 @@ WebInspector.DOMBreakpoint.prototype = { populateLabelElement: function(element) { - element.appendChild(WebInspector.panels.elements.linkifyNodeById(this._nodeId)); - element.appendChild(document.createTextNode(" - ")); - element.appendChild(document.createTextNode(WebInspector.domBreakpointTypeLabel(this._domEventType))); + // FIXME: this should belong to the view, not the manager. + var linkifiedNode = WebInspector.panels.elements.linkifyNodeById(this._nodeId); + linkifiedNode.addStyleClass("monospace"); + element.appendChild(linkifiedNode); + var description = document.createElement("div"); + description.className = "source-text"; + description.textContent = WebInspector.domBreakpointTypeLabel(this._domEventType); + element.appendChild(description); }, populateStatusMessageElement: function(element, eventData) @@ -459,11 +517,6 @@ WebInspector.DOMBreakpoint.prototype = { WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append); }, - _condition: function() - { - return { nodeId: this._nodeId, type: this._domEventType }; - }, - _onRemove: function() { var node = WebInspector.domAgent.nodeForId(this._nodeId); @@ -478,6 +531,20 @@ WebInspector.EventListenerBreakpoint = function(manager, frontendId, eventName) { WebInspector.NativeBreakpoint.call(this, manager, frontendId, "EventListener"); this._eventName = eventName; + this._condition = { eventName: this._eventName }; + this._persistentCondition = this._condition; +} + +WebInspector.EventListenerBreakpoint.eventNameForUI = function(eventName) +{ + if (!WebInspector.EventListenerBreakpoint._eventNamesForUI) { + WebInspector.EventListenerBreakpoint._eventNamesForUI = { + "instrumentation:setTimer": WebInspector.UIString("Set Timer"), + "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"), + "instrumentation:timerFired": WebInspector.UIString("Timer Fired") + }; + } + return WebInspector.EventListenerBreakpoint._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1); } WebInspector.EventListenerBreakpoint.prototype = { @@ -497,21 +564,9 @@ WebInspector.EventListenerBreakpoint.prototype = { element.appendChild(document.createTextNode(status)); }, - _condition: function() - { - return { eventName: this._eventName }; - }, - _uiEventName: function() { - if (!WebInspector.EventListenerBreakpoint._uiEventNames) { - WebInspector.EventListenerBreakpoint._uiEventNames = { - "instrumentation:setTimer": WebInspector.UIString("Set Timer"), - "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"), - "instrumentation:timerFired": WebInspector.UIString("Timer Fired") - }; - } - return WebInspector.EventListenerBreakpoint._uiEventNames[this._eventName] || this._eventName.substring(this._eventName.indexOf(":") + 1); + return WebInspector.EventListenerBreakpoint.eventNameForUI(this._eventName); } } @@ -521,6 +576,8 @@ WebInspector.XHRBreakpoint = function(manager, frontendId, url) { WebInspector.NativeBreakpoint.call(this, manager, frontendId, "XHR"); this._url = url; + this._condition = { url: this._url }; + this._persistentCondition = this._condition; } WebInspector.XHRBreakpoint.prototype = { @@ -529,6 +586,11 @@ WebInspector.XHRBreakpoint.prototype = { return this._compare(this._url, other._url); }, + populateEditElement: function(element) + { + element.textContent = this._url; + }, + populateLabelElement: function(element) { var label; @@ -537,17 +599,13 @@ WebInspector.XHRBreakpoint.prototype = { else label = WebInspector.UIString("URL contains \"%s\"", this._url); element.appendChild(document.createTextNode(label)); + element.addStyleClass("cursor-auto"); }, populateStatusMessageElement: function(element) { var status = WebInspector.UIString("Paused on a XMLHttpRequest."); element.appendChild(document.createTextNode(status)); - }, - - _condition: function() - { - return { url: this._url }; } } diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js index 2151137..f010330 100644 --- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js +++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js @@ -47,46 +47,56 @@ WebInspector.BreakpointsSidebarPane.prototype = { } }, - addBreakpoint: function(breakpointItem) + addBreakpointItem: function(breakpointItem) { - breakpointItem.addEventListener("removed", this._breakpointRemoved, this); - - var element = breakpointItem.element(); + var element = breakpointItem.element; element._breakpointItem = breakpointItem; + breakpointItem.addEventListener("breakpoint-hit", this.expand, this); + breakpointItem.addEventListener("removed", this._removeListElement.bind(this, element), this); + var currentElement = this.listElement.firstChild; while (currentElement) { - if (currentElement._breakpointItem.compareTo(element._breakpointItem) > 0) { - this.listElement.insertBefore(element, currentElement); + if (currentElement._breakpointItem && currentElement._breakpointItem.compareTo(element._breakpointItem) > 0) break; - } currentElement = currentElement.nextSibling; } - if (!currentElement) - this.listElement.appendChild(element); + this._addListElement(element, currentElement); + if (breakpointItem.click) { + element.addStyleClass("cursor-pointer"); + element.addEventListener("click", breakpointItem.click.bind(breakpointItem), false); + } element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointItem), true); + }, + + _contextMenuEventFired: function(breakpointItem, event) + { + var contextMenu = new WebInspector.ContextMenu(); + contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpointItem.remove.bind(breakpointItem)); + contextMenu.show(event); + }, - if (this.emptyElement.parentElement) { - this.bodyElement.removeChild(this.emptyElement); - this.bodyElement.appendChild(this.listElement); + _addListElement: function(element, beforeElement) + { + if (beforeElement) + this.listElement.insertBefore(element, beforeElement); + else { + if (!this.listElement.firstChild) { + this.bodyElement.removeChild(this.emptyElement); + this.bodyElement.appendChild(this.listElement); + } + this.listElement.appendChild(element); } }, - _breakpointRemoved: function(event) + _removeListElement: function(element) { - this.listElement.removeChild(event.target.element()); + this.listElement.removeChild(element); if (!this.listElement.firstChild) { this.bodyElement.removeChild(this.listElement); this.bodyElement.appendChild(this.emptyElement); } - }, - - _contextMenuEventFired: function(breakpointItem, event) - { - var contextMenu = new WebInspector.ContextMenu(); - contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpointItem.remove.bind(breakpointItem)); - contextMenu.show(event); } } @@ -96,36 +106,58 @@ WebInspector.XHRBreakpointsSidebarPane = function() { WebInspector.BreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints")); + function addButtonClicked(event) + { + event.stopPropagation(); + this._startEditingBreakpoint(null); + } + var addButton = document.createElement("button"); addButton.className = "add"; - addButton.addEventListener("click", this._showEditBreakpointDialog.bind(this), false); + addButton.addEventListener("click", addButtonClicked.bind(this), false); this.titleElement.appendChild(addButton); - - this.urlInputElement = document.createElement("span"); - this.urlInputElement.className = "breakpoint-condition editing"; } WebInspector.XHRBreakpointsSidebarPane.prototype = { - _showEditBreakpointDialog: function(event) + addBreakpointItem: function(breakpointItem) { - event.stopPropagation(); + WebInspector.BreakpointsSidebarPane.prototype.addBreakpointItem.call(this, breakpointItem); + breakpointItem._labelElement.addEventListener("dblclick", this._startEditingBreakpoint.bind(this, breakpointItem), false); + }, - if (this.urlInputElement.parentElement) + _startEditingBreakpoint: function(breakpointItem) + { + if (this._editingBreakpoint) return; + this._editingBreakpoint = true; if (!this.expanded) this.expanded = true; - this.urlInputElement.textContent = ""; - this.bodyElement.insertBefore(this.urlInputElement, this.bodyElement.firstChild); - WebInspector.startEditing(this.urlInputElement, this._hideEditBreakpointDialog.bind(this, false), this._hideEditBreakpointDialog.bind(this, true)); + var inputElement = document.createElement("span"); + inputElement.className = "breakpoint-condition editing"; + if (breakpointItem) { + breakpointItem.populateEditElement(inputElement); + this.listElement.insertBefore(inputElement, breakpointItem.element); + breakpointItem.element.addStyleClass("hidden"); + } else + this._addListElement(inputElement, this.listElement.firstChild); + + var commitHandler = this._hideEditBreakpointDialog.bind(this, inputElement, true, breakpointItem); + var cancelHandler = this._hideEditBreakpointDialog.bind(this, inputElement, false, breakpointItem); + WebInspector.startEditing(inputElement, commitHandler, cancelHandler); }, - _hideEditBreakpointDialog: function(discard) + _hideEditBreakpointDialog: function(inputElement, accept, breakpointItem) { - if (!discard) - WebInspector.breakpointManager.createXHRBreakpoint(this.urlInputElement.textContent.toLowerCase()); - this.bodyElement.removeChild(this.urlInputElement); + this._removeListElement(inputElement); + this._editingBreakpoint = false; + if (accept) { + if (breakpointItem) + breakpointItem.remove(); + WebInspector.breakpointManager.createXHRBreakpoint(inputElement.textContent.toLowerCase()); + } else if (breakpointItem) + breakpointItem.element.removeStyleClass("hidden"); } } @@ -136,7 +168,6 @@ WebInspector.BreakpointItem = function(breakpoint) this._breakpoint = breakpoint; this._element = document.createElement("li"); - this._element.addEventListener("click", this._breakpointClicked.bind(this), false); var checkboxElement = document.createElement("input"); checkboxElement.className = "checkbox-elem"; @@ -145,16 +176,18 @@ WebInspector.BreakpointItem = function(breakpoint) checkboxElement.addEventListener("click", this._checkboxClicked.bind(this), false); this._element.appendChild(checkboxElement); - if ("populateLabelElement" in this._breakpoint) - this._breakpoint.populateLabelElement(this._element); + this._createLabelElement(); this._breakpoint.addEventListener("enable-changed", this._enableChanged, this); this._breakpoint.addEventListener("hit-state-changed", this._hitStateChanged, this); + this._breakpoint.addEventListener("label-changed", this._labelChanged, this); this._breakpoint.addEventListener("removed", this.dispatchEventToListeners.bind(this, "removed")); + if (breakpoint.click) + this.click = breakpoint.click.bind(breakpoint); } WebInspector.BreakpointItem.prototype = { - element: function() + get element() { return this._element; }, @@ -164,15 +197,14 @@ WebInspector.BreakpointItem.prototype = { return this._breakpoint.compareTo(other._breakpoint); }, - remove: function() + populateEditElement: function(element) { - this._breakpoint.remove(); + this._breakpoint.populateEditElement(element); }, - _breakpointClicked: function(event) + remove: function() { - if ("click" in this._breakpoint) - this._breakpoint.click(); + this._breakpoint.remove(); }, _checkboxClicked: function(event) @@ -191,45 +223,28 @@ WebInspector.BreakpointItem.prototype = { _hitStateChanged: function(event) { - if (event.target.hit) + if (event.target.hit) { this._element.addStyleClass("breakpoint-hit"); - else + this.dispatchEventToListeners("breakpoint-hit"); + } else this._element.removeStyleClass("breakpoint-hit"); - } -} - -WebInspector.BreakpointItem.prototype.__proto__ = WebInspector.Object.prototype; - -WebInspector.JSBreakpointItem = function(breakpoint) -{ - WebInspector.BreakpointItem.call(this, breakpoint); - - var displayName = this._breakpoint.url ? WebInspector.displayNameForURL(this._breakpoint.url) : WebInspector.UIString("(program)"); - var labelElement = document.createTextNode(displayName + ":" + this._breakpoint.line); - this._element.appendChild(labelElement); - - var sourceTextElement = document.createElement("div"); - sourceTextElement.textContent = this._breakpoint.sourceText; - sourceTextElement.className = "source-text monospace"; - this._element.appendChild(sourceTextElement); - - this._breakpoint.addEventListener("text-changed", this._textChanged, this); -} + }, -WebInspector.JSBreakpointItem.prototype = { - _breakpointClicked: function() + _labelChanged: function(event) { - WebInspector.panels.scripts.showSourceLine(this._breakpoint.url, this._breakpoint.line); + this._element.removeChild(this._labelElement); + this._createLabelElement(); }, - _textChanged: function() + _createLabelElement: function() { - var sourceTextElement = this._element.firstChild.nextSibling.nextSibling; - sourceTextElement.textContent = this._breakpoint.sourceText; + this._labelElement = document.createElement("span"); + this._breakpoint.populateLabelElement(this._labelElement); + this._element.appendChild(this._labelElement); } } -WebInspector.JSBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype; +WebInspector.BreakpointItem.prototype.__proto__ = WebInspector.Object.prototype; WebInspector.EventListenerBreakpointsSidebarPane = function() { @@ -240,97 +255,116 @@ WebInspector.EventListenerBreakpointsSidebarPane = function() this.categoriesElement.addStyleClass("properties-tree event-listener-breakpoints"); this.categoriesTreeOutline = new TreeOutline(this.categoriesElement); this.bodyElement.appendChild(this.categoriesElement); + + WebInspector.breakpointManager.addEventListener("event-listener-breakpoint-added", this._breakpointAdded, this); + + this._breakpointItems = {}; + this._createCategory("Mouse", "listener", ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mousewheel"]); + this._createCategory("Keyboard", "listener", ["keydown", "keypress", "keyup"]); + this._createCategory("HTML frame/object", "listener", ["load", "error", "resize", "scroll"]); + this._createCategory("Timer", "instrumentation", ["setTimer", "clearTimer", "timerFired"]); } WebInspector.EventListenerBreakpointsSidebarPane.prototype = { - _populate: function() + _createCategory: function(name, type, eventNames) { - var categories = { - "Mouse": { type: "listener", eventNames: ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mousewheel"] }, - "Keyboard": { type: "listener", eventNames: ["keydown", "keypress", "keyup"] }, - "HTML frame/object": { type: "listener", eventNames: ["load", "error", "resize", "scroll"] }, - "Timer": { type: "instrumentation", eventNames: ["setTimer", "clearTimer", "timerFired"] } - }; - - for (var category in categories) { - var categoryTreeElement = new TreeElement(WebInspector.UIString(category)); - this.categoriesTreeOutline.appendChild(categoryTreeElement); - categoryTreeElement.listItemElement.addStyleClass("event-category"); - categoryTreeElement.selectable = true; - - var categoryItem = {}; - categoryItem.checkbox = this._createCheckbox(categoryTreeElement, this._categoryCheckboxClicked.bind(this, categoryItem)); - categoryItem.children = {}; - - var categoryType = categories[category].type; - var eventNames = categories[category].eventNames; - for (var i = 0; i < eventNames.length; ++i) { - var eventName = categoryType + ":" + eventNames[i]; - - var breakpoint = WebInspector.breakpointManager.createEventListenerBreakpoint(eventName, true); - if (!breakpoint) - continue; - - var labelElement = document.createElement("div"); - breakpoint.populateLabelElement(labelElement); - var eventNameTreeElement = new TreeElement(labelElement); - categoryTreeElement.appendChild(eventNameTreeElement); - eventNameTreeElement.listItemElement.addStyleClass("source-code"); - eventNameTreeElement.selectable = true; - - var eventNameItem = {}; - eventNameItem.checkbox = this._createCheckbox(eventNameTreeElement, this._eventNameCheckboxClicked.bind(this, categoryItem, eventNameItem)); - eventNameItem.breakpoint = breakpoint; - - breakpoint.addEventListener("enable-changed", this._breakpointEnableChanged.bind(this, categoryItem, eventNameItem), true); - - categoryItem.children[eventName] = eventNameItem; - } + var categoryItem = {}; + categoryItem.element = new TreeElement(WebInspector.UIString(name)); + this.categoriesTreeOutline.appendChild(categoryItem.element); + categoryItem.element.listItemElement.addStyleClass("event-category"); + categoryItem.element.selectable = true; + + categoryItem.checkbox = this._createCheckbox(categoryItem.element); + categoryItem.checkbox.addEventListener("click", this._categoryCheckboxClicked.bind(this, categoryItem), true); + + categoryItem.children = {}; + for (var i = 0; i < eventNames.length; ++i) { + var eventName = type + ":" + eventNames[i]; + + var breakpointItem = {}; + var title = WebInspector.EventListenerBreakpoint.eventNameForUI(eventName); + breakpointItem.element = new TreeElement(title); + categoryItem.element.appendChild(breakpointItem.element); + breakpointItem.element.listItemElement.addStyleClass("source-code"); + breakpointItem.element.selectable = true; + + breakpointItem.checkbox = this._createCheckbox(breakpointItem.element); + breakpointItem.checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, breakpointItem), true); + breakpointItem.parent = categoryItem; + breakpointItem.eventName = eventName; + + this._breakpointItems[eventName] = breakpointItem; + categoryItem.children[eventName] = breakpointItem; } }, - _createCheckbox: function(treeElement, checkboxClickedDelegate) + _createCheckbox: function(treeElement) { var checkbox = document.createElement("input"); checkbox.className = "checkbox-elem"; checkbox.type = "checkbox"; - checkbox.addEventListener("click", checkboxClickedDelegate, true); treeElement.listItemElement.insertBefore(checkbox, treeElement.listItemElement.firstChild); return checkbox; }, _categoryCheckboxClicked: function(categoryItem) { - var checkbox = categoryItem.checkbox; - checkbox.indeterminate = false; + var checked = categoryItem.checkbox.checked; for (var eventName in categoryItem.children) { - var eventNameItem = categoryItem.children[eventName]; - eventNameItem.checkbox.checked = checkbox.checked; - eventNameItem.breakpoint.enabled = checkbox.checked; + var breakpointItem = categoryItem.children[eventName]; + if (breakpointItem.checkbox.checked !== checked) { + breakpointItem.checkbox.checked = checked; + this._breakpointCheckboxClicked(breakpointItem); + } } }, - _eventNameCheckboxClicked: function(categoryItem, eventNameItem) + _breakpointCheckboxClicked: function(breakpointItem) { - this._updateCategoryCheckbox(categoryItem); - eventNameItem.breakpoint.enabled = eventNameItem.checkbox.checked; + if (breakpointItem.checkbox.checked) + WebInspector.breakpointManager.createEventListenerBreakpoint(breakpointItem.eventName); + else + breakpointItem.breakpoint.remove(); }, - _breakpointEnableChanged: function(categoryItem, eventNameItem) + _breakpointAdded: function(event) { - if (eventNameItem.checkbox.checked === eventNameItem.breakpoint.enabled) - return; + var breakpoint = event.data.breakpoint; + var eventName = event.data.eventName; + + var breakpointItem = this._breakpointItems[eventName]; + breakpointItem.breakpoint = breakpoint; + breakpoint.addEventListener("hit-state-changed", this._breakpointHitStateChanged.bind(this, breakpointItem)); + breakpoint.addEventListener("removed", this._breakpointRemoved.bind(this, breakpointItem)); + breakpointItem.checkbox.checked = true; + this._updateCategoryCheckbox(breakpointItem); + }, - eventNameItem.checkbox.checked = eventNameItem.breakpoint.enabled; - this._updateCategoryCheckbox(categoryItem); + _breakpointHitStateChanged: function(breakpointItem, event) + { + if (event.target.hit) { + this.expanded = true; + var categoryItem = breakpointItem.parent; + categoryItem.element.expand(); + breakpointItem.element.listItemElement.addStyleClass("breakpoint-hit"); + } else + breakpointItem.element.listItemElement.removeStyleClass("breakpoint-hit"); }, - _updateCategoryCheckbox: function(categoryItem) + _breakpointRemoved: function(breakpointItem) { + breakpointItem.breakpoint = null; + breakpointItem.checkbox.checked = false; + this._updateCategoryCheckbox(breakpointItem); + }, + + _updateCategoryCheckbox: function(breakpointItem) + { + var categoryItem = breakpointItem.parent; var hasEnabled = false, hasDisabled = false; for (var eventName in categoryItem.children) { - var eventNameItem = categoryItem.children[eventName]; - if (eventNameItem.checkbox.checked) + var breakpointItem = categoryItem.children[eventName]; + if (breakpointItem.checkbox.checked) hasEnabled = true; else hasDisabled = true; @@ -341,8 +375,12 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = { reset: function() { - this.categoriesTreeOutline.removeChildren(); - this._populate(); + for (var eventName in this._breakpointItems) { + var breakpointItem = this._breakpointItems[eventName]; + breakpointItem.breakpoint = null; + breakpointItem.checkbox.checked = false; + this._updateCategoryCheckbox(breakpointItem); + } } } diff --git a/WebCore/inspector/front-end/CSSStyleModel.js b/WebCore/inspector/front-end/CSSStyleModel.js index 702c923..542a3b3 100644 --- a/WebCore/inspector/front-end/CSSStyleModel.js +++ b/WebCore/inspector/front-end/CSSStyleModel.js @@ -119,7 +119,7 @@ WebInspector.CSSStyleModel.prototype = { if (!newRulePayload) failureCallback(); else - successCallback(WebInspector.CSSStyleDeclaration.parseRule(newRulePayload), doesAffectSelectedNode); + successCallback(WebInspector.CSSRule.parsePayload(newRulePayload), doesAffectSelectedNode); } InspectorBackend.setRuleSelector(ruleId, newContent, nodeId, callback); @@ -133,7 +133,7 @@ WebInspector.CSSStyleModel.prototype = { // Invalid syntax for a selector failureCallback(); } else { - var styleRule = WebInspector.CSSStyleDeclaration.parseRule(rule); + var styleRule = WebInspector.CSSRule.parsePayload(rule); styleRule.rule = rule; successCallback(styleRule, doesAffectSelectedNode); } diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js index deca21c..737b84f 100644 --- a/WebCore/inspector/front-end/ConsoleView.js +++ b/WebCore/inspector/front-end/ConsoleView.js @@ -48,7 +48,7 @@ WebInspector.ConsoleView = function(drawer) this.promptElement.className = "source-code"; this.promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true); this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + "."); - this.prompt.history = WebInspector.applicationSettings.consoleHistory; + this.prompt.history = WebInspector.settings.consoleHistory; this.topGroup = new WebInspector.ConsoleGroup(null, 0); this.messagesElement.insertBefore(this.topGroup.element, this.promptElement); @@ -218,18 +218,7 @@ WebInspector.ConsoleView.prototype = { { if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) { this._incrementErrorWarningCount(msg); - - // Add message to the resource panel - if (!Preferences.networkPanelEnabled) { - var resource = WebInspector.resourceForURL(msg.url); - if (resource) { - msg.resource = resource; - if (WebInspector.panels.resources) - WebInspector.panels.resources.addMessageToResource(msg.resource, msg); - } - } else - WebInspector.resourceManager.addConsoleMessage(msg); - + WebInspector.resourceManager.addConsoleMessage(msg); this.commandSincePreviousMessage = false; this.previousMessage = msg; } else if (msg instanceof WebInspector.ConsoleCommand) { @@ -300,10 +289,7 @@ WebInspector.ConsoleView.prototype = { clearMessages: function() { - if (WebInspector.panels.resources) - WebInspector.panels.resources.clearMessages(); - if (WebInspector.resourceManager) - WebInspector.resourceManager.clearConsoleMessages(); + WebInspector.resourceManager.clearConsoleMessages(); this.messages = []; @@ -522,7 +508,7 @@ WebInspector.ConsoleView.prototype = { _enterKeyPressed: function(event) { - if (event.altKey || event.ctrlKey) + if (event.altKey || event.ctrlKey || event.shiftKey) return; event.preventDefault(); @@ -544,7 +530,7 @@ WebInspector.ConsoleView.prototype = { self.prompt.historyOffset = 0; self.prompt.text = ""; - WebInspector.applicationSettings.consoleHistory = self.prompt.history.slice(-30); + WebInspector.settings.consoleHistory = self.prompt.history.slice(-30); self.addMessage(new WebInspector.ConsoleCommandResult(result, commandMessage)); } diff --git a/WebCore/inspector/front-end/DataGrid.js b/WebCore/inspector/front-end/DataGrid.js index bc429d9..902062c 100644 --- a/WebCore/inspector/front-end/DataGrid.js +++ b/WebCore/inspector/front-end/DataGrid.js @@ -53,12 +53,12 @@ WebInspector.DataGrid = function(columns, editCallback, deleteCallback) this.aligned = {}; - var scrollContainer = document.createElement("div"); - scrollContainer.className = "data-container"; - scrollContainer.appendChild(this._dataTable); + this._scrollContainer = document.createElement("div"); + this._scrollContainer.className = "data-container"; + this._scrollContainer.appendChild(this._dataTable); this.element.appendChild(this._headerTable); - this.element.appendChild(scrollContainer); + this.element.appendChild(this._scrollContainer); var headerRow = document.createElement("tr"); var columnGroup = document.createElement("colgroup"); @@ -485,6 +485,16 @@ WebInspector.DataGrid.prototype = { this._columnWidthsInitialized = false; }, + isScrolledToLastRow: function() + { + return this._scrollContainer.scrollTop === this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight; + }, + + scrollToLastRow: function() + { + this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight; + }, + _positionResizers: function() { var headerTableColumns = this._headerTableColumnGroup.children; diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js index 1d546c2..4404051 100644 --- a/WebCore/inspector/front-end/ElementsTreeOutline.js +++ b/WebCore/inspector/front-end/ElementsTreeOutline.js @@ -758,13 +758,18 @@ WebInspector.ElementsTreeElement.prototype = { // Add debbuging-related actions contextMenu.appendSeparator(); + function handlerFunction(nodeId, breakType) + { + WebInspector.breakpointManager.createDOMBreakpoint(nodeId, breakType); + WebInspector.panels.elements.sidebarPanes.domBreakpoints.expand(); + } var node = this.representedObject; for (var key in WebInspector.DOMBreakpointTypes) { var type = WebInspector.DOMBreakpointTypes[key]; var label = WebInspector.domBreakpointTypeContextMenuLabel(type); var breakpoint = node.breakpoints[type]; if (!breakpoint) - var handler = WebInspector.breakpointManager.createDOMBreakpoint.bind(WebInspector.breakpointManager, node.id, type); + var handler = handlerFunction.bind(this, node.id, type); else var handler = breakpoint.remove.bind(breakpoint); contextMenu.appendCheckboxItem(label, handler, !!breakpoint); diff --git a/WebCore/inspector/front-end/EventListenersSidebarPane.js b/WebCore/inspector/front-end/EventListenersSidebarPane.js index 3354191..bc8bb12 100644 --- a/WebCore/inspector/front-end/EventListenersSidebarPane.js +++ b/WebCore/inspector/front-end/EventListenersSidebarPane.js @@ -46,7 +46,7 @@ WebInspector.EventListenersSidebarPane = function() option.label = WebInspector.UIString("Selected Node Only"); this.settingsSelectElement.appendChild(option); - var filter = WebInspector.applicationSettings.eventListenersFilter; + var filter = WebInspector.settings.eventListenersFilter; if (filter === "all") this.settingsSelectElement[0].selected = true; else if (filter === "selected") @@ -107,7 +107,7 @@ WebInspector.EventListenersSidebarPane.prototype = { _changeSetting: function(event) { var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex]; - WebInspector.applicationSettings.eventListenersFilter = selectedOption.value; + WebInspector.settings.eventListenersFilter = selectedOption.value; for (var i = 0; i < this.sections.length; ++i) this.sections[i].update(); @@ -137,7 +137,7 @@ WebInspector.EventListenersSection.prototype = { { // A Filtered Array simplifies when to create connectors var filteredEventListeners = this.eventListeners; - if (WebInspector.applicationSettings.eventListenersFilter === "selected") { + if (WebInspector.settings.eventListenersFilter === "selected") { filteredEventListeners = []; for (var i = 0; i < this.eventListeners.length; ++i) { var eventListener = this.eventListeners[i]; @@ -151,12 +151,6 @@ WebInspector.EventListenersSection.prototype = { for (var i = 0; i < length; ++i) { var eventListener = filteredEventListeners[i]; var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId); - if (i < length - 1) { - var connector = document.createElement("div"); - connector.className = "event-bar-connector"; - eventListenerBar.element.appendChild(connector); - } - this.eventBars.appendChild(eventListenerBar.element); } }, @@ -178,6 +172,7 @@ WebInspector.EventListenerBar = function(eventListener, nodeId) this._setFunctionSubtitle(); this.editable = false; this.element.className = "event-bar"; /* Changed from "section" */ + this.headerElement.addStyleClass("source-code"); this.propertiesElement.className = "event-properties properties-tree source-code"; /* Changed from "properties" */ } diff --git a/WebCore/inspector/front-end/ExtensionAPI.js b/WebCore/inspector/front-end/ExtensionAPI.js index 5d090b0..7d6d76c 100644 --- a/WebCore/inspector/front-end/ExtensionAPI.js +++ b/WebCore/inspector/front-end/ExtensionAPI.js @@ -197,6 +197,19 @@ PanelImpl.prototype = { callback(new ExtensionSidebarPane(id)); } extensionServer.sendRequest({ command: "createSidebarPane", panel: this._id, id: id, title: title, url: expandURL(url) }, callback && callbackWrapper); + }, + + createWatchExpressionSidebarPane: function(title, callback) + { + var id = "watch-sidebar-" + extensionServer.nextObjectId(); + function callbackWrapper(result) + { + if (result.isError) + callback(result); + else + callback(new WatchExpressionSidebarPane(id)); + } + extensionServer.sendRequest({ command: "createWatchExpressionSidebarPane", panel: this._id, id: id, title: title }, callback && callbackWrapper); } } @@ -204,6 +217,7 @@ function Panel(id) { var impl = new PanelImpl(id); this.createSidebarPane = bind(impl.createSidebarPane, impl); + this.createWatchExpressionSidebarPane = bind(impl.createWatchExpressionSidebarPane, impl); this.onSelectionChanged = new EventSink("panel-objectSelected-" + id); } @@ -235,13 +249,40 @@ ExtensionSidebarPaneImpl.prototype = { } } -function ExtensionSidebarPane(id) +function ExtensionSidebarPane(id, impl) { - var impl = new ExtensionSidebarPaneImpl(id); + if (!impl) + impl = new ExtensionSidebarPaneImpl(id); this.setHeight = bind(impl.setHeight, impl); this.setExpanded = bind(impl.setExpanded, impl); } +function WatchExpressionSidebarPaneImpl(id) +{ + ExtensionSidebarPaneImpl.call(this, id); +} + +WatchExpressionSidebarPaneImpl.prototype = { + setExpression: function(expression, rootTitle) + { + extensionServer.sendRequest({ command: "setWatchSidebarContent", id: this._id, expression: expression, rootTitle: rootTitle, evaluateOnPage: true }); + }, + + setObject: function(jsonObject, rootTitle) + { + extensionServer.sendRequest({ command: "setWatchSidebarContent", id: this._id, expression: jsonObject, rootTitle: rootTitle }); + } +} + +function WatchExpressionSidebarPane(id) +{ + var impl = new WatchExpressionSidebarPaneImpl(id); + ExtensionSidebarPane.call(this, id, impl); + this.setExpression = bind(impl.setExpression, impl); + this.setObject = bind(impl.setObject, impl); + this.onUpdated = new EventSink("watch-sidebar-updated-" + id); +} + function Audits() { } diff --git a/WebCore/inspector/front-end/ExtensionPanel.js b/WebCore/inspector/front-end/ExtensionPanel.js index ba5fa8e..4b42e68 100644 --- a/WebCore/inspector/front-end/ExtensionPanel.js +++ b/WebCore/inspector/front-end/ExtensionPanel.js @@ -80,3 +80,39 @@ WebInspector.ExtensionPanel.prototype = { } WebInspector.ExtensionPanel.prototype.__proto__ = WebInspector.Panel.prototype; + +WebInspector.ExtensionWatchSidebarPane = function(title, id) +{ + WebInspector.SidebarPane.call(this, title); + this._id = id; +} + +WebInspector.ExtensionWatchSidebarPane.prototype = { + setObject: function(object, title) + { + this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title); + }, + + setExpression: function(expression, title) + { + InjectedScriptAccess.getDefault().evaluate(expression, this._onEvaluate.bind(this, title)); + }, + + _onEvaluate: function(title, result) + { + this._setObject(WebInspector.RemoteObject.fromPayload(result), title); + }, + + _setObject: function(object, title) + { + this.bodyElement.removeChildren(); + var section = new WebInspector.ObjectPropertiesSection(object, title, null, true); + if (!title) + section.headerElement.addStyleClass("hidden"); + section.expanded = true; + this.bodyElement.appendChild(section.element); + WebInspector.extensionServer.notifyExtensionWatchSidebarUpdated(this._id); + } +} + +WebInspector.ExtensionWatchSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype; diff --git a/WebCore/inspector/front-end/ExtensionServer.js b/WebCore/inspector/front-end/ExtensionServer.js index 5e593f7..6ffa33a 100644 --- a/WebCore/inspector/front-end/ExtensionServer.js +++ b/WebCore/inspector/front-end/ExtensionServer.js @@ -42,10 +42,12 @@ WebInspector.ExtensionServer = function() this._registerHandler("getPageTimings", this._onGetPageTimings.bind(this)); this._registerHandler("createPanel", this._onCreatePanel.bind(this)); this._registerHandler("createSidebarPane", this._onCreateSidebar.bind(this)); + this._registerHandler("createWatchExpressionSidebarPane", this._onCreateWatchExpressionSidebarPane.bind(this)); this._registerHandler("log", this._onLog.bind(this)); this._registerHandler("evaluateOnInspectedPage", this._onEvaluateOnInspectedPage.bind(this)); this._registerHandler("setSidebarHeight", this._onSetSidebarHeight.bind(this)); this._registerHandler("setSidebarExpanded", this._onSetSidebarExpansion.bind(this)); + this._registerHandler("setWatchSidebarContent", this._onSetWatchSidebarContent.bind(this)); this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this)); this._registerHandler("addAuditResult", this._onAddAuditResult.bind(this)); @@ -90,6 +92,11 @@ WebInspector.ExtensionServer.prototype = { this._postNotification("reset"); }, + notifyExtensionWatchSidebarUpdated: function(id) + { + this._postNotification("watch-sidebar-updated-" + id); + }, + startAuditRun: function(category, auditRun) { this._clientObjects[auditRun.id] = auditRun; @@ -161,7 +168,22 @@ WebInspector.ExtensionServer.prototype = { return this._status.OK(); }, - _onCreateSidebar: function(message, port) + _onCreateSidebar: function(message) + { + var sidebar = this._createSidebar(message, WebInspector.SidebarPane); + if (sidebar.isError) + return sidebar; + this._createClientIframe(sidebar.bodyElement, message.url); + return this._status.OK(); + }, + + _onCreateWatchExpressionSidebarPane: function(message) + { + var sidebar = this._createSidebar(message, WebInspector.ExtensionWatchSidebarPane); + return sidebar.isError ? sidebar : this._status.OK(); + }, + + _createSidebar: function(message, constructor) { var panel = WebInspector.panels[message.panel]; if (!panel) @@ -169,12 +191,12 @@ WebInspector.ExtensionServer.prototype = { if (!panel.sidebarElement || !panel.sidebarPanes) return this._status.E_NOTSUPPORTED(); var id = message.id; - var sidebar = new WebInspector.SidebarPane(message.title); + var sidebar = new constructor(message.title, message.id); this._clientObjects[id] = sidebar; panel.sidebarPanes[id] = sidebar; panel.sidebarElement.appendChild(sidebar.element); - this._createClientIframe(sidebar.bodyElement, message.url); - return this._status.OK(); + + return sidebar; }, _createClientIframe: function(parent, url, requestId, port) @@ -205,6 +227,17 @@ WebInspector.ExtensionServer.prototype = { sidebar.collapse(); }, + _onSetWatchSidebarContent: function(message) + { + var sidebar = this._clientObjects[message.id]; + if (!sidebar) + return this._status.E_NOTFOUND(message.id); + if (message.evaluateOnPage) + sidebar.setExpression(message.expression, message.rootTitle); + else + sidebar.setObject(message.expression, message.rootTitle); + }, + _onLog: function(message) { WebInspector.log(message.message); @@ -243,13 +276,9 @@ WebInspector.ExtensionServer.prototype = { resource = WebInspector.networkResources[id] || WebInspector.resourceForURL(id); if (!resource) return this._status.E_NOTFOUND(typeof id + ": " + id); - if (Preferences.networkPanelEnabled) { - WebInspector.panels.storage.showResource(resource, message.line); - WebInspector.showPanel("storage"); - } else { - WebInspector.panels.resources.showResource(resource, message.line); - WebInspector.showPanel("resources"); - } + + WebInspector.panels.storage.showResource(resource, message.line); + WebInspector.showPanel("storage"); }, _dispatchCallback: function(requestId, port, result) @@ -303,7 +332,7 @@ WebInspector.ExtensionServer.prototype = { if (!resource) response.push(this._status.E_NOTFOUND(id)); else - resource.getContent(onContentAvailable.bind(this, id)); + resource.requestContent(onContentAvailable.bind(this, id)); } if (response.length === ids.length) this._dispatchCallback(message.requestId, port, response); diff --git a/WebCore/inspector/front-end/FileSystemView.js b/WebCore/inspector/front-end/FileSystemView.js new file mode 100644 index 0000000..0c6636b --- /dev/null +++ b/WebCore/inspector/front-end/FileSystemView.js @@ -0,0 +1,190 @@ +/* + * 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. + */ + +WebInspector.FileSystem = {} + +// Keep in sync with Type in AsyncFileSystem.h +WebInspector.FileSystem.TEMPORARY = 0; +WebInspector.FileSystem.PERSISTENT = 1; + +WebInspector.FileSystem.getFileSystemPathsAsync = function(origin) +{ + InspectorBackend.getFileSystemPathAsync(WebInspector.FileSystem.PERSISTENT, origin); + InspectorBackend.getFileSystemPathAsync(WebInspector.FileSystem.TEMPORARY, origin); +} + +WebInspector.FileSystemView = function(treeElement, fileSystemOrigin) +{ + WebInspector.View.call(this); + + this.element.addStyleClass("resource-view"); + this._treeElement = treeElement; + this._origin = fileSystemOrigin; + this._tabbedPane = new WebInspector.TabbedPane(this.element); + + this._persistentFileSystemElement = document.createElement("div"); + this._persistentFileSystemElement.className = "resource-view-headers"; + this._tabbedPane.appendTab("persistent", WebInspector.UIString("Persistent File System"), this._persistentFileSystemElement, this._selectFileSystemTab.bind(this, true)); + + this._tempFileSystemElement = document.createElement("div"); + this._tempFileSystemElement.className = "resource-view-headers"; + this._tabbedPane.appendTab("temp", WebInspector.UIString("Temporary File System"), this._tempFileSystemElement, this.selectTemporaryFileSystemTab.bind(this, true)); + + this._temporaryRoot = ""; + this._persistentRoot = ""; + this._isFileSystemDisabled = false; + this._persistentRootError = false; + this._temporaryRootError = false; + this.fileSystemVisible = true; + this._selectFileSystemTab(); + this.refreshFileSystem(); +} + +WebInspector.FileSystemView.prototype = { + show: function(parentElement) + { + WebInspector.View.prototype.show.call(this, parentElement); + this._update(); + }, + + set fileSystemVisible(x) + { + if (x === this._fileSystemVisible) + return; + this._fileSystemVisible = x; + if (x) + this.element.addStyleClass("headers-visible"); + else + this.element.removeStyleClass("headers-visible"); + this._selectFileSystemTab(); + }, + + _update: function() + { + this._selectFileSystemTab(); + WebInspector.FileSystem.getFileSystemPathsAsync(this._origin); + }, + + updateFileSystemPath: function(root, type, origin) + { + if (origin == this._origin && type == WebInspector.FileSystem.PERSISTENT) { + this._persistentRoot = root; + this._persistentRootError = false; + } + + if (origin == this._origin && type == WebInspector.FileSystem.TEMPORARY) { + this._temporaryRoot = root; + this._temporaryRootErrorError = false; + } + + this.refreshFileSystem(); + }, + + updateFileSystemError: function(type, origin) + { + if (type == WebInspector.FileSystem.PERSISTENT) + this._persistentRootError = true; + + if (type == WebInspector.FileSystem.TEMPORARY) + this._temporaryRootError = true; + + this.refreshFileSystem(); + }, + + setFileSystemDisabled: function() + { + this._isFileSystemDisabled = true; + this.refreshFileSystem(); + }, + _selectFileSystemTab: function() + { + this._tabbedPane.selectTabById("persistent"); + }, + + selectTemporaryFileSystemTab: function() + { + this._tabbedPane.selectTabById("temp"); + }, + + _revealPersistentFolderInOS: function() + { + InspectorBackend.revealFolderInOS(this._persistentRoot); + }, + + _revealTemporaryFolderInOS: function() + { + InspectorBackend.revealFolderInOS(this._temporaryRoot); + }, + + _createTextAndButton: function(fileSystemElement, rootPathText, type, isError) + { + fileSystemElement.removeChildren(); + var rootPath = WebInspector.UIString("File System root path not available."); + if (this._isFileSystemDisabled) + rootPath = WebInspector.UIString("File System is disabled."); + else if (isError) + rootPath = WebInspector.UIString("Error in fetching root path for file system."); + else if (rootPathText) + rootPath = rootPathText; + + var rootTextNode = document.createTextNode("Root: " + rootPath.escapeHTML()); + var rootSystemElement = document.createElement("div"); + rootSystemElement.className = "header-value source-code"; + rootSystemElement.appendChild(rootTextNode); + fileSystemElement.appendChild(rootSystemElement); + + if (!isError && rootPathText) { + // Append Browse button iff root path is available and it is not an error. + var contentElement = document.createElement("div"); + contentElement.className = "panel-enabler-view-content"; + fileSystemElement.appendChild(contentElement); + var choicesForm = document.createElement("form"); + contentElement.appendChild(choicesForm); + var enableButton = document.createElement("button"); + enableButton.setAttribute("type", "button"); + enableButton.textContent = WebInspector.UIString("Reveal folder in OS"); + // FIXME: Bind this directly to InspectorBackend. + if (type == WebInspector.FileSystem.PERSISTENT) + enableButton.addEventListener("click", this._revealPersistentFolderInOS.bind(this), false); + if (type == WebInspector.FileSystem.TEMPORARY) + enableButton.addEventListener("click", this._revealTemporaryFolderInOS.bind(this), false); + choicesForm.appendChild(enableButton); + fileSystemElement.appendChild(contentElement); + } + }, + + refreshFileSystem: function() + { + this._createTextAndButton(this._persistentFileSystemElement, this._persistentRoot, WebInspector.FileSystem.PERSISTENT, this._persistentRootError); + this._createTextAndButton(this._tempFileSystemElement, this._temporaryRoot, WebInspector.FileSystem.TEMPORARY, this._temporaryRootError); + }, +} + +WebInspector.FileSystemView.prototype.__proto__ = WebInspector.View.prototype; diff --git a/WebCore/inspector/front-end/ImageView.js b/WebCore/inspector/front-end/ImageView.js index 7cff056..f70fad6 100644 --- a/WebCore/inspector/front-end/ImageView.js +++ b/WebCore/inspector/front-end/ImageView.js @@ -47,15 +47,9 @@ WebInspector.ImageView.prototype = { this._container.className = "image"; this.contentElement.appendChild(this._container); - this.imagePreviewElement = document.createElement("img"); - this.imagePreviewElement.addStyleClass("resource-image-view"); - this._container.appendChild(this.imagePreviewElement); - - function onResourceContent(element, content) - { - this.imagePreviewElement.setAttribute("src", this.resource.contentURL); - } - this.resource.getContent(onResourceContent.bind(this)); + var imagePreviewElement = document.createElement("img"); + imagePreviewElement.addStyleClass("resource-image-view"); + this._container.appendChild(imagePreviewElement); this._container = document.createElement("div"); this._container.className = "info"; @@ -69,18 +63,51 @@ WebInspector.ImageView.prototype = { var infoListElement = document.createElement("dl"); infoListElement.className = "infoList"; - var imageProperties = [ - { name: WebInspector.UIString("Dimensions"), value: WebInspector.UIString("%d × %d", this.imagePreviewElement.naturalWidth, this.imagePreviewElement.height) }, - { name: WebInspector.UIString("File size"), value: Number.bytesToString(this.resource.resourceSize, WebInspector.UIString) }, - { name: WebInspector.UIString("MIME type"), value: this.resource.mimeType } - ]; + function onResourceContent(element, content) + { + imagePreviewElement.setAttribute("src", this.resource.contentURL); + } + this.resource.requestContent(onResourceContent.bind(this)); - var listHTML = ''; - for (var i = 0; i < imageProperties.length; ++i) - listHTML += "<dt>" + imageProperties[i].name + "</dt><dd>" + imageProperties[i].value + "</dd>"; - infoListElement.innerHTML = listHTML; - this._container.appendChild(infoListElement); + function onImageLoad() + { + var content = this.resource.content; + if (content) + var resourceSize = this._base64ToSize(content); + else + var resourceSize = this.resource.resourceSize; + + var imageProperties = [ + { name: WebInspector.UIString("Dimensions"), value: WebInspector.UIString("%d × %d", imagePreviewElement.naturalWidth, imagePreviewElement.naturalHeight) }, + { name: WebInspector.UIString("File size"), value: Number.bytesToString(resourceSize, WebInspector.UIString) }, + { name: WebInspector.UIString("MIME type"), value: this.resource.mimeType } + ]; + + infoListElement.removeChildren(); + for (var i = 0; i < imageProperties.length; ++i) { + var dt = document.createElement("dt"); + dt.textContent = imageProperties[i].name; + infoListElement.appendChild(dt); + var dd = document.createElement("dd"); + dd.textContent = imageProperties[i].value; + infoListElement.appendChild(dd); + } + this._container.appendChild(infoListElement); + } + imagePreviewElement.addEventListener("load", onImageLoad.bind(this), false); + }, + + _base64ToSize: function(content) + { + if (!content.length) + return 0; + var size = (content.length || 0) * 3 / 4; + if (content.length > 0 && content[content.length - 1] === "=") + size--; + if (content.length > 1 && content[content.length - 2] === "=") + size--; + return size; } } diff --git a/WebCore/inspector/front-end/Images/grayConnectorPoint.png b/WebCore/inspector/front-end/Images/grayConnectorPoint.png Binary files differdeleted file mode 100644 index fddc7ea..0000000 --- a/WebCore/inspector/front-end/Images/grayConnectorPoint.png +++ /dev/null diff --git a/WebCore/inspector/front-end/Images/resourcesSilhouette.png b/WebCore/inspector/front-end/Images/resourcesSilhouette.png Binary files differdeleted file mode 100644 index 9c8bb53..0000000 --- a/WebCore/inspector/front-end/Images/resourcesSilhouette.png +++ /dev/null diff --git a/WebCore/inspector/front-end/Images/whiteConnectorPoint.png b/WebCore/inspector/front-end/Images/whiteConnectorPoint.png Binary files differdeleted file mode 100644 index c8fb1cf..0000000 --- a/WebCore/inspector/front-end/Images/whiteConnectorPoint.png +++ /dev/null diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js index 2d60f69..fff6680 100644 --- a/WebCore/inspector/front-end/InjectedScript.js +++ b/WebCore/inspector/front-end/InjectedScript.js @@ -52,7 +52,6 @@ InjectedScript.prototype = { var objectId; if (typeof object === "object" || typeof object === "function" || this._isHTMLAllCollection(object)) { var id = this._lastBoundObjectId++; - objectId = id; this._idToWrappedObject[id] = object; var group = this._objectGroups[objectGroupName]; diff --git a/WebCore/inspector/front-end/NetworkPanel.js b/WebCore/inspector/front-end/NetworkPanel.js index c666e54..71433af 100644 --- a/WebCore/inspector/front-end/NetworkPanel.js +++ b/WebCore/inspector/front-end/NetworkPanel.js @@ -37,6 +37,7 @@ WebInspector.NetworkPanel = function() this._resources = []; this._resourcesById = {}; + this._resourcesByURL = {}; this._lastIdentifier = 0; this._staleResources = []; this._resourceGridNodes = {}; @@ -55,10 +56,10 @@ WebInspector.NetworkPanel = function() this._viewsContainerElement.className = "hidden"; this.element.appendChild(this._viewsContainerElement); - var closeButtonElement = document.createElement("button"); - closeButtonElement.className = "network-close-button"; - closeButtonElement.addEventListener("click", this._toggleGridMode.bind(this), false); - this._viewsContainerElement.appendChild(closeButtonElement); + this._closeButtonElement = document.createElement("button"); + this._closeButtonElement.id = "network-close-button"; + this._closeButtonElement.addEventListener("click", this._toggleGridMode.bind(this), false); + this._viewsContainerElement.appendChild(this._closeButtonElement); this._createSortingFunctions(); this._createTable(); @@ -67,6 +68,9 @@ WebInspector.NetworkPanel = function() this._createFilterStatusBarItems(); this._createSummaryBar(); + if (!WebInspector.settings.resourcesLargeRows) + this._setLargerResources(WebInspector.settings.resourcesLargeRows); + this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), true); this.calculator = new WebInspector.NetworkTransferTimeCalculator(); @@ -83,7 +87,7 @@ WebInspector.NetworkPanel.prototype = { get statusBarItems() { - return [this._largerResourcesButton.element, this._clearButton.element, this._filterBarElement]; + return [this._largerResourcesButton.element, this._preserveLogToggle.element, this._clearButton.element, this._filterBarElement]; }, isCategoryVisible: function(categoryName) @@ -103,11 +107,13 @@ WebInspector.NetworkPanel.prototype = { this._positionSummaryBar(); }, - updateSidebarWidth: function() + updateSidebarWidth: function(width) { if (!this._viewingResourceMode) return; - WebInspector.Panel.prototype.updateSidebarWidth.apply(this, arguments); + WebInspector.Panel.prototype.updateSidebarWidth.call(this, width); + if (this._summaryBarElement.parentElement === this.element) + this._summaryBarElement.style.width = width + "px"; }, updateMainViewWidth: function(width) @@ -126,28 +132,26 @@ WebInspector.NetworkPanel.prototype = { _positionSummaryBar: function() { // Position the total bar. - const rowHeight = 22; - const summaryBarHeight = 22; - var offsetHeight = this.element.offsetHeight; - - var parentElement = this._summaryBarElement.parentElement; - if (this._summaryBarElement.parentElement !== this.element && offsetHeight > (this._dataGrid.children.length - 1) * rowHeight + summaryBarHeight) { + var fillerRow = this._dataGrid.dataTableBody.lastChild; + if (this._summaryBarElement.parentElement !== this.element && fillerRow.offsetHeight > 0) { // Glue status to bottom. if (this._summaryBarRowNode) { this._dataGrid.removeChild(this._summaryBarRowNode); delete this._summaryBarRowNode; } this._summaryBarElement.addStyleClass("network-summary-bar-bottom"); + this._summaryBarElement.style.setProperty("width", this.sidebarElement.offsetWidth + "px"); this.element.appendChild(this._summaryBarElement); this._dataGrid.element.style.bottom = "20px"; return; } - if (!this._summaryBarRowNode && offsetHeight - summaryBarHeight < this._dataGrid.children.length * rowHeight) { + if (!this._summaryBarRowNode && !fillerRow.offsetHeight) { // Glue status to table. this._summaryBarRowNode = new WebInspector.NetworkTotalGridNode(this._summaryBarElement); this._summaryBarElement.removeStyleClass("network-summary-bar-bottom"); + this._summaryBarElement.style.removeProperty("width"); this._dataGrid.appendChild(this._summaryBarRowNode); this._dataGrid.element.style.bottom = 0; this._sortItems(); @@ -193,7 +197,7 @@ WebInspector.NetworkPanel.prototype = { columns.size.width = "10%"; columns.size.aligned = "right"; - columns.time.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Time"), WebInspector.UIString("Duration")); + columns.time.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Time"), WebInspector.UIString("Latency")); columns.time.sortable = true; columns.time.width = "10%"; columns.time.aligned = "right"; @@ -427,9 +431,7 @@ WebInspector.NetworkPanel.prototype = { selectMultiple = true; this._filter(e.target, selectMultiple); - - var searchField = document.getElementById("search"); - WebInspector.doPerformSearch(searchField.value, WebInspector.shortSearchWasForcedByKeyEvent, false, true); + this._positionSummaryBar(); }, _filter: function(target, selectMultiple) @@ -604,20 +606,16 @@ WebInspector.NetworkPanel.prototype = { this._timelineGrid.addEventDivider(divider); }, - get resourceTrackingEnabled() - { - return this._resourceTrackingEnabled; - }, - _createStatusbarButtons: function() { + this._preserveLogToggle = new WebInspector.StatusBarButton(WebInspector.UIString("Preserve Log upon Navigation"), "record-profile-status-bar-item"); + this._preserveLogToggle.addEventListener("click", this._onPreserveLogClicked.bind(this), false); + this._clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-status-bar-item"); this._clearButton.addEventListener("click", this._reset.bind(this), false); this._largerResourcesButton = new WebInspector.StatusBarButton(WebInspector.UIString("Use small resource rows."), "network-larger-resources-status-bar-item"); - this._largerResourcesButton.toggled = WebInspector.applicationSettings.resourcesLargeRows; - if (!WebInspector.applicationSettings.resourcesLargeRows) - this._setLargerResources(WebInspector.applicationSettings.resourcesLargeRows); + this._largerResourcesButton.toggled = WebInspector.settings.resourcesLargeRows; this._largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false); }, @@ -713,8 +711,8 @@ WebInspector.NetworkPanel.prototype = { delete this._refreshTimeout; } + var wasScrolledToLastRow = this._dataGrid.isScrolledToLastRow(); var staleItemsLength = this._staleResources.length; - var boundariesChanged = false; for (var i = 0; i < staleItemsLength; ++i) { @@ -745,6 +743,20 @@ WebInspector.NetworkPanel.prototype = { this._sortItems(); this._updateSummaryBar(); this._dataGrid.updateWidths(); + + if (wasScrolledToLastRow) + this._dataGrid.scrollToLastRow(); + }, + + _onPreserveLogClicked: function(e) + { + this._preserveLogToggle.toggled = !this._preserveLogToggle.toggled; + }, + + reset: function() + { + if (!this._preserveLogToggle.toggled) + this._reset(); }, _reset: function() @@ -760,6 +772,7 @@ WebInspector.NetworkPanel.prototype = { this._resources = []; this._resourcesById = {}; + this._resourcesByURL = {}; this._staleResources = []; this._resourceGridNodes = {}; @@ -772,6 +785,7 @@ WebInspector.NetworkPanel.prototype = { this._mainResourceDOMContentTime = -1; this._viewsContainerElement.removeChildren(); + this._viewsContainerElement.appendChild(this._closeButtonElement); this._resetSummaryBar(); }, @@ -780,17 +794,23 @@ WebInspector.NetworkPanel.prototype = { return this._resourcesById; }, - addResource: function(resource) + refreshResource: function(resource) { - this._resources.push(resource); if (!resource.identifier) resource.identifier = "network:" + this._lastIdentifier++; - this._resourcesById[resource.identifier] = resource; - this.refreshResource(resource); - }, - refreshResource: function(resource) - { + if (!this._resourcesById[resource.identifier]) { + this._resources.push(resource); + this._resourcesById[resource.identifier] = resource; + this._resourcesByURL[resource.url] = resource; + + // Pull all the redirects of the main resource upon commit load. + if (resource.redirects) { + for (var i = 0; i < resource.redirects.length; ++i) + this.refreshResource(resource.redirects[i]); + } + } + this._staleResources.push(resource); this._scheduleRefresh(); @@ -819,11 +839,12 @@ WebInspector.NetworkPanel.prototype = { canShowSourceLine: function(url, line) { - return false; + return !!this._resourcesByURL[url]; }, showSourceLine: function(url, line) { + this._showResource(this._resourcesByURL[url], line); }, _showResource: function(resource, line) @@ -870,8 +891,8 @@ WebInspector.NetworkPanel.prototype = { _toggleLargerResources: function() { - WebInspector.applicationSettings.resourcesLargeRows = !WebInspector.applicationSettings.resourcesLargeRows; - this._setLargerResources(WebInspector.applicationSettings.resourcesLargeRows); + WebInspector.settings.resourcesLargeRows = !WebInspector.settings.resourcesLargeRows; + this._setLargerResources(WebInspector.settings.resourcesLargeRows); }, _setLargerResources: function(enabled) @@ -888,6 +909,7 @@ WebInspector.NetworkPanel.prototype = { this._timelineGrid.element.removeStyleClass("small"); this._viewsContainerElement.removeStyleClass("small"); } + this._positionSummaryBar(); }, _getPopoverAnchor: function(element) @@ -996,6 +1018,7 @@ WebInspector.NetworkPanel.prototype = { this._viewsContainerElement.addStyleClass("hidden"); this.sidebarElement.style.right = 0; this.sidebarElement.style.removeProperty("width"); + this._summaryBarElement.style.removeProperty("width"); } if (this._briefGrid) { @@ -1467,7 +1490,7 @@ WebInspector.NetworkDataGridNode.prototype = { previewImage.src = this._resource.contentURL; } if (Preferences.useDataURLForResourceImageIcons) - this._resource.getContent(onResourceContent.bind(this)); + this._resource.requestContent(onResourceContent.bind(this)); else previewImage.src = this._resource.url; diff --git a/WebCore/inspector/front-end/Panel.js b/WebCore/inspector/front-end/Panel.js index ec9250c..4c42a60 100644 --- a/WebCore/inspector/front-end/Panel.js +++ b/WebCore/inspector/front-end/Panel.js @@ -34,7 +34,7 @@ WebInspector.Panel = function(name) this.element.addStyleClass(name); this._panelName = name; - WebInspector.applicationSettings.installApplicationSetting(this._sidebarWidthSettingName(), undefined); + WebInspector.settings.installApplicationSetting(this._sidebarWidthSettingName(), undefined); } // Should by in sync with style declarations. @@ -377,7 +377,7 @@ WebInspector.Panel.prototype = { restoreSidebarWidth: function() { - var sidebarWidth = WebInspector.applicationSettings[this._sidebarWidthSettingName()]; + var sidebarWidth = WebInspector.settings[this._sidebarWidthSettingName()]; this.updateSidebarWidth(sidebarWidth); }, @@ -385,7 +385,7 @@ WebInspector.Panel.prototype = { { if (!this.sidebarElement) return; - WebInspector.applicationSettings[this._sidebarWidthSettingName()] = this.sidebarElement.offsetWidth; + WebInspector.settings[this._sidebarWidthSettingName()] = this.sidebarElement.offsetWidth; }, updateMainViewWidth: function(width) diff --git a/WebCore/inspector/front-end/ProfilesPanel.js b/WebCore/inspector/front-end/ProfilesPanel.js index ca02f9e..0aa4174 100644 --- a/WebCore/inspector/front-end/ProfilesPanel.js +++ b/WebCore/inspector/front-end/ProfilesPanel.js @@ -386,6 +386,20 @@ WebInspector.ProfilesPanel.prototype = { return result; }, + hasTemporaryProfile: function(typeId) + { + var profilesCount = this._profiles.length; + for (var i = 0; i < profilesCount; ++i) + if (this._profiles[i].typeId === typeId && this._profiles[i].isTemporary) + return true; + return false; + }, + + hasProfile: function(profile) + { + return !!this._profilesIdMap[this._makeKey(profile.uid, profile.typeId)]; + }, + updateProfile: function(profile) { var profilesCount = this._profiles.length; @@ -443,12 +457,12 @@ WebInspector.ProfilesPanel.prototype = { if (!(titleKey in this._profileGroupsForLinks)) this._profileGroupsForLinks[titleKey] = 0; - groupNumber = ++this._profileGroupsForLinks[titleKey]; + var groupNumber = ++this._profileGroupsForLinks[titleKey]; if (groupNumber > 2) // The title is used in the console message announcing that a profile has started so it gets // incremented twice as often as it's displayed - title += " " + WebInspector.UIString("Run %d", groupNumber / 2); + title += " " + WebInspector.UIString("Run %d", (groupNumber + 1) / 2); } return title; @@ -538,10 +552,11 @@ WebInspector.ProfilesPanel.prototype = { profileHeaders.sort(function(a, b) { return a.uid - b.uid; }); var profileHeadersLength = profileHeaders.length; for (var i = 0; i < profileHeadersLength; ++i) - WebInspector.addProfileHeader(profileHeaders[i]); + if (!this.hasProfile(profileHeaders[i])) + WebInspector.addProfileHeader(profileHeaders[i]); } - InspectorBackend.getProfileHeaders(populateCallback); + InspectorBackend.getProfileHeaders(populateCallback.bind(this)); this._profilesWereRequested = true; }, diff --git a/WebCore/inspector/front-end/PropertiesSection.js b/WebCore/inspector/front-end/PropertiesSection.js index 1ca52ce..88cb1a2 100644 --- a/WebCore/inspector/front-end/PropertiesSection.js +++ b/WebCore/inspector/front-end/PropertiesSection.js @@ -31,8 +31,9 @@ WebInspector.PropertiesSection = function(title, subtitle) { WebInspector.Section.call(this, title, subtitle); + this.headerElement.addStyleClass("monospace"); this.propertiesElement = document.createElement("ol"); - this.propertiesElement.className = "properties properties-tree source-code"; + this.propertiesElement.className = "properties properties-tree monospace"; this.propertiesElement.tabIndex = 0; this.propertiesTreeOutline = new TreeOutline(this.propertiesElement); this.propertiesTreeOutline.section = this; diff --git a/WebCore/inspector/front-end/PropertiesSidebarPane.js b/WebCore/inspector/front-end/PropertiesSidebarPane.js index 75d6a48..b9c212a 100644 --- a/WebCore/inspector/front-end/PropertiesSidebarPane.js +++ b/WebCore/inspector/front-end/PropertiesSidebarPane.js @@ -54,7 +54,7 @@ WebInspector.PropertiesSidebarPane.prototype = { var title = prototype.description; if (title.match(/Prototype$/)) title = title.replace(/Prototype$/, ""); - var section = new WebInspector.ObjectPropertiesSection(prototype, title, WebInspector.UIString("Prototype")); + var section = new WebInspector.ObjectPropertiesSection(prototype, title); self.sections.push(section); body.appendChild(section.element); } diff --git a/WebCore/inspector/front-end/RemoteObject.js b/WebCore/inspector/front-end/RemoteObject.js index 003d483..4d6736c 100644 --- a/WebCore/inspector/front-end/RemoteObject.js +++ b/WebCore/inspector/front-end/RemoteObject.js @@ -41,6 +41,11 @@ WebInspector.RemoteObject.fromPrimitiveValue = function(value) return new WebInspector.RemoteObject(null, typeof value, value); } +WebInspector.RemoteObject.fromLocalObject = function(value) +{ + return new WebInspector.LocalJSONObject(value); +} + WebInspector.RemoteObject.resolveNode = function(node, callback) { function mycallback(object) @@ -136,3 +141,62 @@ WebInspector.RemoteObjectProperty = function(name, value) this.name = name; this.value = value; } + +// The below is a wrapper around a local object that provides an interface comaptible +// with RemoteObject, to be used by the UI code (primarily ObjectPropertiesSection). +// Note that only JSON-compliant objects are currently supported, as there's no provision +// for traversing prototypes, extracting class names via constuctor, handling properties +// or functions. + +WebInspector.LocalJSONObject = function(value) +{ + this._value = value; +} + +WebInspector.LocalJSONObject.prototype = { + get description() + { + var type = this.type; + switch (type) { + case "array": + return "[" + this._value.length + "]"; + case "object": + return this.hasChildren ? "{...}" : "{ }"; + default: + return JSON.stringify(this._value); + } + }, + + get type() + { + if (this._value === null) + return "null"; + if (this._value instanceof Array) + return "array"; + return typeof this._value; + }, + + get hasChildren() + { + return typeof this._value === "object" && this._value !== null && Object.keys(this._value).length; + }, + + getOwnProperties: function(abbreviate, callback) + { + return this.getProperties(false, abbreviate, callback); + }, + + getProperties: function(ignoreHasOwnProperty, abbreviate, callback) + { + function buildProperty(propName) + { + return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName])); + } + callback(Object.keys(this._value).map(buildProperty.bind(this))); + }, + + isError: function() + { + return false; + } +} diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js index 1a2ce96..24af165 100644 --- a/WebCore/inspector/front-end/Resource.js +++ b/WebCore/inspector/front-end/Resource.js @@ -25,7 +25,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - WebInspector.Resource = function(identifier, url) { this.identifier = identifier; @@ -256,7 +255,7 @@ WebInspector.Resource.prototype = { this._checkWarnings(); this.dispatchEventToListeners("finished"); if (this._pendingContentCallbacks.length) - this._requestContent(); + this._innerRequestContent(); } }, @@ -288,6 +287,20 @@ WebInspector.Resource.prototype = { set cached(x) { this._cached = x; + if (x) + delete this._timing; + }, + + + get timing() + { + return this._timing; + }, + + set timing(x) + { + if (!this._cached) + this._timing = x; }, get mimeType() @@ -332,7 +345,7 @@ WebInspector.Resource.prototype = { this.category = WebInspector.resourceCategories.xhr; break; case WebInspector.Resource.Type.WebSocket: - this.category = WebInspector.resourceCategories.websocket; + this.category = WebInspector.resourceCategories.websockets; break; case WebInspector.Resource.Type.Other: default: @@ -603,12 +616,17 @@ WebInspector.Resource.prototype = { WebInspector.console.addMessage(msg); }, + get content() + { + return this._content; + }, + set content(content) { this._content = content; }, - getContent: function(callback) + requestContent: function(callback) { if (this._content) { callback(this._content, this._contentEncoded); @@ -616,7 +634,7 @@ WebInspector.Resource.prototype = { } this._pendingContentCallbacks.push(callback); if (this.finished) - this._requestContent(); + this._innerRequestContent(); }, get contentURL() @@ -629,7 +647,7 @@ WebInspector.Resource.prototype = { return "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content; }, - _requestContent: function() + _innerRequestContent: function() { if (this._contentRequested) return; @@ -643,52 +661,10 @@ WebInspector.Resource.prototype = { for (var i = 0; i < callbacks.length; ++i) callbacks[i](this._content, this._contentEncoded); this._pendingContentCallbacks.length = 0; + delete this._contentRequested; } - WebInspector.ResourceManager.getContent(this, this._contentEncoded, onResourceContent.bind(this)); + WebInspector.ResourceManager.requestContent(this, this._contentEncoded, onResourceContent.bind(this)); } } WebInspector.Resource.prototype.__proto__ = WebInspector.Object.prototype; - -WebInspector.Resource.CompareByStartTime = function(a, b) -{ - return a.startTime - b.startTime; -} - -WebInspector.Resource.CompareByResponseReceivedTime = function(a, b) -{ - var aVal = a.responseReceivedTime; - var bVal = b.responseReceivedTime; - if (aVal === -1 ^ bVal === -1) - return bVal - aVal; - return aVal - bVal; -} - -WebInspector.Resource.CompareByEndTime = function(a, b) -{ - var aVal = a.endTime; - var bVal = b.endTime; - if (aVal === -1 ^ bVal === -1) - return bVal - aVal; - return aVal - bVal; -} - -WebInspector.Resource.CompareByDuration = function(a, b) -{ - return a.duration - b.duration; -} - -WebInspector.Resource.CompareByLatency = function(a, b) -{ - return a.latency - b.latency; -} - -WebInspector.Resource.CompareBySize = function(a, b) -{ - return a.resourceSize - b.resourceSize; -} - -WebInspector.Resource.CompareByTransferSize = function(a, b) -{ - return a.transferSize - b.transferSize; -} diff --git a/WebCore/inspector/front-end/ResourceManager.js b/WebCore/inspector/front-end/ResourceManager.js index 62273ee..bb34561 100644 --- a/WebCore/inspector/front-end/ResourceManager.js +++ b/WebCore/inspector/front-end/ResourceManager.js @@ -63,15 +63,11 @@ WebInspector.ResourceManager.prototype = { identifierForInitialRequest: function(identifier, url, loader) { var resource = this._createResource(identifier, url, loader); - if (loader.url === url) { - resource.isMainResource = true; - WebInspector.mainResource = resource; - } // It is important to bind resource url early (before scripts compile). this._bindResourceURL(resource); - WebInspector.panels.network.addResource(resource); + WebInspector.panels.network.refreshResource(resource); WebInspector.panels.audits.resourceStarted(resource); }, @@ -79,7 +75,8 @@ WebInspector.ResourceManager.prototype = { { var resource = new WebInspector.Resource(identifier, url); resource.loader = loader; - resource.documentURL = loader.url; + if (loader) + resource.documentURL = loader.url; this._resourcesById[identifier] = resource; return resource; @@ -104,7 +101,7 @@ WebInspector.ResourceManager.prototype = { resource.startTime = time; if (isRedirect) { - WebInspector.panels.network.addResource(resource); + WebInspector.panels.network.refreshResource(resource); WebInspector.panels.audits.resourceStarted(resource); } else WebInspector.panels.network.refreshResource(resource); @@ -228,9 +225,11 @@ WebInspector.ResourceManager.prototype = { var resource = this._createResource(null, cachedResource.url, cachedResource.loader); this._updateResourceWithCachedResource(resource, cachedResource); resource.cached = true; + resource.requestMethod = "GET"; resource.startTime = resource.responseReceivedTime = resource.endTime = time; + resource.finished = true; - WebInspector.panels.network.addResource(resource); + WebInspector.panels.network.refreshResource(resource); WebInspector.panels.audits.resourceStarted(resource); WebInspector.panels.audits.resourceFinished(resource); this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource); @@ -251,12 +250,20 @@ WebInspector.ResourceManager.prototype = { resource.type = WebInspector.Resource.Type[type]; resource.content = sourceString; + WebInspector.panels.storage.refreshResource(resource); WebInspector.panels.network.refreshResource(resource); }, - didCommitLoadForFrame: function(parentFrameId, loader) + didCommitLoadForFrame: function(frame, loader) { - this._resourceTreeModel.didCommitLoadForFrame(parentFrameId, loader); + this._resourceTreeModel.didCommitLoadForFrame(frame, loader); + if (!frame.parentId) { + var mainResource = this.resourceForURL(frame.url); + if (mainResource) { + WebInspector.mainResource = mainResource; + mainResource.isMainResource = true; + } + } }, frameDetachedFromParent: function(frameId) @@ -266,11 +273,9 @@ WebInspector.ResourceManager.prototype = { didCreateWebSocket: function(identifier, requestURL) { - this.identifierForInitialRequest(identifier, requestURL); - var resource = this._resourcesById[identifier]; + var resource = this._createResource(identifier, requestURL); resource.type = WebInspector.Resource.Type.WebSocket; - - WebInspector.panels.network.addResource(resource); + WebInspector.panels.network.refreshResource(resource); }, willSendWebSocketHandshakeRequest: function(identifier, time, request) @@ -314,12 +319,12 @@ WebInspector.ResourceManager.prototype = { _processCachedResources: function(mainFramePayload) { - var mainResource = this._addFramesRecursively(null, mainFramePayload); + var mainResource = this._addFramesRecursively(mainFramePayload); WebInspector.mainResource = mainResource; mainResource.isMainResource = true; }, - _addFramesRecursively: function(parentFrameId, framePayload) + _addFramesRecursively: function(framePayload) { var frameResource = this._createResource(null, framePayload.resource.url, framePayload.resource.loader); this._updateResourceWithRequest(frameResource, framePayload.resource.request); @@ -328,11 +333,11 @@ WebInspector.ResourceManager.prototype = { frameResource.finished = true; this._bindResourceURL(frameResource); - this._resourceTreeModel.addOrUpdateFrame(parentFrameId, framePayload.id, frameResource.displayName); + this._resourceTreeModel.addOrUpdateFrame(framePayload); this._resourceTreeModel.addResourceToFrame(framePayload.id, frameResource); for (var i = 0; framePayload.children && i < framePayload.children.length; ++i) - this._addFramesRecursively(framePayload.id, framePayload.children[i]); + this._addFramesRecursively(framePayload.children[i]); if (!framePayload.subresources) return; @@ -469,13 +474,9 @@ WebInspector.ResourceManager.existingResourceViewForResource = function(resource return resource._resourcesView; } -WebInspector.ResourceManager.getContent = function(resource, base64Encode, callback) +WebInspector.ResourceManager.requestContent = function(resource, base64Encode, callback) { - // FIXME: eventually, cached resources will have no identifiers. - if (resource.loader) - InspectorBackend.resourceContent(resource.loader.frameId, resource.url, base64Encode, callback); - else - InspectorBackend.getResourceContent(resource.identifier, base64Encode, callback); + InspectorBackend.resourceContent(resource.loader.frameId, resource.url, base64Encode, callback); } WebInspector.ResourceTreeModel = function() @@ -485,29 +486,29 @@ WebInspector.ResourceTreeModel = function() } WebInspector.ResourceTreeModel.prototype = { - addOrUpdateFrame: function(parentFrameId, frameId, displayName) + addOrUpdateFrame: function(frame) { - WebInspector.panels.storage.addOrUpdateFrame(parentFrameId, frameId, displayName); - var subframes = this._subframes[parentFrameId]; + var tmpResource = new WebInspector.Resource(null, frame.url); + WebInspector.panels.storage.addOrUpdateFrame(frame.parentId, frame.id, frame.name, tmpResource.displayName); + var subframes = this._subframes[frame.parentId]; if (!subframes) { subframes = {}; - this._subframes[parentFrameId || 0] = subframes; + this._subframes[frame.parentId || 0] = subframes; } - subframes[frameId] = true; + subframes[frame.id] = true; }, - didCommitLoadForFrame: function(parentFrameId, loader) + didCommitLoadForFrame: function(frame, loader) { - // parentFrameId === 0 is when main frame navigation happens. - this._clearChildFramesAndResources(parentFrameId ? loader.frameId : 0, loader.loaderId); + // frame.parentId === 0 is when main frame navigation happens. + this._clearChildFramesAndResources(frame.parentId ? frame.id : 0, loader.loaderId); - var tmpResource = new WebInspector.Resource(null, loader.url); - this.addOrUpdateFrame(parentFrameId, loader.frameId, tmpResource.displayName); + this.addOrUpdateFrame(frame); - var resourcesForFrame = this._resourcesByFrameId[loader.frameId]; + var resourcesForFrame = this._resourcesByFrameId[frame.id]; for (var i = 0; resourcesForFrame && i < resourcesForFrame.length; ++i) { WebInspector.resourceManager._bindResourceURL(resourcesForFrame[i]); - WebInspector.panels.storage.addResourceToFrame(loader.frameId, resourcesForFrame[i]); + WebInspector.panels.storage.addResourceToFrame(frame.id, resourcesForFrame[i]); } }, diff --git a/WebCore/inspector/front-end/ResourceView.js b/WebCore/inspector/front-end/ResourceView.js index ffb229d..3ca7fcc 100644 --- a/WebCore/inspector/front-end/ResourceView.js +++ b/WebCore/inspector/front-end/ResourceView.js @@ -147,7 +147,7 @@ WebInspector.ResourceView.prototype = { _selectTab: function() { - var preferredTab = WebInspector.applicationSettings.resourceViewTab; + var preferredTab = WebInspector.settings.resourceViewTab; if (this._headersVisible && this._cookiesView && preferredTab === "cookies") this._selectCookiesTab(); else if (this._headersVisible && (!this.hasContentTab() || preferredTab === "headers")) @@ -159,14 +159,14 @@ WebInspector.ResourceView.prototype = { _selectHeadersTab: function(updatePrefs) { if (updatePrefs) - WebInspector.applicationSettings.resourceViewTab = "headers"; + WebInspector.settings.resourceViewTab = "headers"; this.tabbedPane.selectTabById("headers"); }, selectContentTab: function(updatePrefs) { if (updatePrefs) - WebInspector.applicationSettings.resourceViewTab = "content"; + WebInspector.settings.resourceViewTab = "content"; this._innerSelectContentTab(); }, @@ -179,7 +179,7 @@ WebInspector.ResourceView.prototype = { _selectCookiesTab: function(updatePrefs) { if (updatePrefs) - WebInspector.applicationSettings.resourceViewTab = "cookies"; + WebInspector.settings.resourceViewTab = "cookies"; this.tabbedPane.selectTabById("cookies"); this._cookiesView.resize(); }, diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js deleted file mode 100644 index b35fc4b..0000000 --- a/WebCore/inspector/front-end/ResourcesPanel.js +++ /dev/null @@ -1,1938 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -WebInspector.ResourcesPanel = function() -{ - WebInspector.Panel.call(this, "resources"); - this.resourceURLMap = {}; - this._items = []; - this._staleItems = []; - - this._createPanelEnabler(); - - this.viewsContainerElement = document.createElement("div"); - this.viewsContainerElement.id = "resource-views"; - this.element.appendChild(this.viewsContainerElement); - - this.createFilterPanel(); - this.createInterface(); - - this._createStatusbarButtons(); - this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), true); - - this.reset(); - this.filter(this.filterAllElement, false); - this.graphsTreeElement.children[0].select(); - this._resourceTrackingEnabled = false; - - this.sidebarElement.addEventListener("contextmenu", this._contextMenu.bind(this), true); -} - -WebInspector.ResourcesPanel.prototype = { - get toolbarItemLabel() - { - return WebInspector.UIString("Resources"); - }, - - get statusBarItems() - { - return [this.enableToggleButton.element, this.largerResourcesButton.element, this.sortingSelectElement]; - }, - - get categories() - { - return WebInspector.resourceCategories; - }, - - createItemTreeElement: function(item) - { - return new WebInspector.ResourceSidebarTreeElement(item); - }, - - createItemGraph: function(item) - { - return new WebInspector.ResourceGraph(item); - }, - - isCategoryVisible: function(categoryName) - { - return (this.itemsGraphsElement.hasStyleClass("filter-all") || this.itemsGraphsElement.hasStyleClass("filter-" + categoryName.toLowerCase())); - }, - - get items() - { - return this._items; - }, - - createInterface: function() - { - this.containerElement = document.createElement("div"); - this.containerElement.id = "resources-container"; - this.containerElement.addEventListener("scroll", this._updateDividersLabelBarPosition.bind(this), false); - this.element.appendChild(this.containerElement); - - this.createSidebar(this.containerElement, this.element); - this.sidebarElement.id = "resources-sidebar"; - this.populateSidebar(); - - this._containerContentElement = document.createElement("div"); - this._containerContentElement.id = "resources-container-content"; - this.containerElement.appendChild(this._containerContentElement); - - this.summaryBar = new WebInspector.SummaryBar(this.categories); - this.summaryBar.element.id = "resources-summary"; - this._containerContentElement.appendChild(this.summaryBar.element); - - this._timelineGrid = new WebInspector.TimelineGrid(); - this._containerContentElement.appendChild(this._timelineGrid.element); - this.itemsGraphsElement = this._timelineGrid.itemsGraphsElement; - }, - - createFilterPanel: function() - { - this.filterBarElement = document.createElement("div"); - this.filterBarElement.id = "resources-filter"; - this.filterBarElement.className = "scope-bar"; - this.element.appendChild(this.filterBarElement); - - function createFilterElement(category) - { - if (category === "all") - var label = WebInspector.UIString("All"); - else if (this.categories[category]) - var label = this.categories[category].title; - - var categoryElement = document.createElement("li"); - categoryElement.category = category; - categoryElement.addStyleClass(category); - categoryElement.appendChild(document.createTextNode(label)); - categoryElement.addEventListener("click", this._updateFilter.bind(this), false); - this.filterBarElement.appendChild(categoryElement); - - return categoryElement; - } - - this.filterAllElement = createFilterElement.call(this, "all"); - - // Add a divider - var dividerElement = document.createElement("div"); - dividerElement.addStyleClass("scope-bar-divider"); - this.filterBarElement.appendChild(dividerElement); - - for (var category in this.categories) - createFilterElement.call(this, category); - }, - - showCategory: function(category) - { - var filterClass = "filter-" + category.toLowerCase(); - this.itemsGraphsElement.addStyleClass(filterClass); - this.itemsTreeElement.childrenListElement.addStyleClass(filterClass); - }, - - hideCategory: function(category) - { - var filterClass = "filter-" + category.toLowerCase(); - this.itemsGraphsElement.removeStyleClass(filterClass); - this.itemsTreeElement.childrenListElement.removeStyleClass(filterClass); - }, - - filter: function(target, selectMultiple) - { - function unselectAll() - { - for (var i = 0; i < this.filterBarElement.childNodes.length; ++i) { - var child = this.filterBarElement.childNodes[i]; - if (!child.category) - continue; - - child.removeStyleClass("selected"); - this.hideCategory(child.category); - } - } - - if (target === this.filterAllElement) { - if (target.hasStyleClass("selected")) { - // We can't unselect All, so we break early here - return; - } - - // If All wasn't selected, and now is, unselect everything else. - unselectAll.call(this); - } else { - // Something other than All is being selected, so we want to unselect All. - if (this.filterAllElement.hasStyleClass("selected")) { - this.filterAllElement.removeStyleClass("selected"); - this.hideCategory("all"); - } - } - - if (!selectMultiple) { - // If multiple selection is off, we want to unselect everything else - // and just select ourselves. - unselectAll.call(this); - - target.addStyleClass("selected"); - this.showCategory(target.category); - return; - } - - if (target.hasStyleClass("selected")) { - // If selectMultiple is turned on, and we were selected, we just - // want to unselect ourselves. - target.removeStyleClass("selected"); - this.hideCategory(target.category); - } else { - // If selectMultiple is turned on, and we weren't selected, we just - // want to select ourselves. - target.addStyleClass("selected"); - this.showCategory(target.category); - } - }, - - _updateFilter: function(e) - { - var isMac = WebInspector.isMac(); - var selectMultiple = false; - if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey) - selectMultiple = true; - if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey) - selectMultiple = true; - - this.filter(e.target, selectMultiple); - - // When we are updating our filtering, scroll to the top so we don't end up - // in blank graph under all the resources. - this.containerElement.scrollTop = 0; - - var searchField = document.getElementById("search"); - WebInspector.doPerformSearch(searchField.value, WebInspector.shortSearchWasForcedByKeyEvent, false, true); - }, - - _updateDividersLabelBarPosition: function() - { - const scrollTop = this.containerElement.scrollTop; - const offsetHeight = this.summaryBar.element.offsetHeight; - const dividersTop = (scrollTop < offsetHeight ? offsetHeight : scrollTop); - this._timelineGrid.setScrollAndDividerTop(scrollTop, dividersTop); - }, - - get needsRefresh() - { - return this._needsRefresh; - }, - - set needsRefresh(x) - { - if (this._needsRefresh === x) - return; - - this._needsRefresh = x; - - if (x) { - if (this.visible && !("_refreshTimeout" in this)) - this._refreshTimeout = setTimeout(this.refresh.bind(this), 500); - } else { - if ("_refreshTimeout" in this) { - clearTimeout(this._refreshTimeout); - delete this._refreshTimeout; - } - } - }, - - refreshIfNeeded: function() - { - if (this.needsRefresh) - this.refresh(); - }, - - resize: function() - { - WebInspector.Panel.prototype.resize.call(this); - - this.updateGraphDividersIfNeeded(); - }, - - invalidateAllItems: function() - { - this._staleItems = this._items.slice(); - }, - - get calculator() - { - return this._calculator; - }, - - set calculator(x) - { - if (!x || this._calculator === x) - return; - - this._calculator = x; - this._calculator.reset(); - - this._staleItems = this._items.slice(); - this.refresh(); - }, - - addItem: function(item) - { - this._items.push(item); - this.refreshItem(item); - }, - - removeItem: function(item) - { - this._items.remove(item, true); - - if (item._itemsTreeElement) { - this.itemsTreeElement.removeChild(item._itemsTreeElement); - this.itemsGraphsElement.removeChild(item._itemsTreeElement._itemGraph.graphElement); - } - - delete item._itemsTreeElement; - this.adjustScrollPosition(); - }, - - refreshItem: function(item) - { - this._staleItems.push(item); - this.needsRefresh = true; - }, - - revealAndSelectItem: function(item) - { - if (item._itemsTreeElement) { - item._itemsTreeElement.reveal(); - item._itemsTreeElement.select(true); - } - }, - - sortItems: function(sortingFunction) - { - var sortedElements = [].concat(this.itemsTreeElement.children); - sortedElements.sort(sortingFunction); - - var sortedElementsLength = sortedElements.length; - for (var i = 0; i < sortedElementsLength; ++i) { - var treeElement = sortedElements[i]; - if (treeElement === this.itemsTreeElement.children[i]) - continue; - - var wasSelected = treeElement.selected; - this.itemsTreeElement.removeChild(treeElement); - this.itemsTreeElement.insertChild(treeElement, i); - if (wasSelected) - treeElement.select(true); - - var graphElement = treeElement._itemGraph.graphElement; - this.itemsGraphsElement.insertBefore(graphElement, this.itemsGraphsElement.children[i]); - } - }, - - adjustScrollPosition: function() - { - // Prevent the container from being scrolled off the end. - if ((this.containerElement.scrollTop + this.containerElement.offsetHeight) > this.sidebarElement.offsetHeight) - this.containerElement.scrollTop = (this.sidebarElement.offsetHeight - this.containerElement.offsetHeight); - }, - - addEventDivider: function(divider) - { - this._timelineGrid.addEventDivider(divider); - }, - - hideEventDividers: function() - { - this._timelineGrid.hideEventDividers(); - }, - - showEventDividers: function() - { - this._timelineGrid.showEventDividers(); - }, - - populateSidebar: function() - { - this.timeGraphItem = new WebInspector.SidebarTreeElement("resources-time-graph-sidebar-item", WebInspector.UIString("Time")); - this.timeGraphItem.onselect = this._graphSelected.bind(this); - - var transferTimeCalculator = new WebInspector.ResourceTransferTimeCalculator(); - var transferDurationCalculator = new WebInspector.ResourceTransferDurationCalculator(); - - this.timeGraphItem.sortingOptions = [ - { name: WebInspector.UIString("Sort by Start Time"), sortingFunction: WebInspector.ResourceSidebarTreeElement.CompareByAscendingStartTime, calculator: transferTimeCalculator, optionName: "startTime" }, - { name: WebInspector.UIString("Sort by Response Time"), sortingFunction: WebInspector.ResourceSidebarTreeElement.CompareByAscendingResponseReceivedTime, calculator: transferTimeCalculator, optionName: "responseTime" }, - { name: WebInspector.UIString("Sort by End Time"), sortingFunction: WebInspector.ResourceSidebarTreeElement.CompareByAscendingEndTime, calculator: transferTimeCalculator, optionName: "endTime" }, - { name: WebInspector.UIString("Sort by Duration"), sortingFunction: WebInspector.ResourceSidebarTreeElement.CompareByDescendingDuration, calculator: transferDurationCalculator, optionName: "duration" }, - { name: WebInspector.UIString("Sort by Latency"), sortingFunction: WebInspector.ResourceSidebarTreeElement.CompareByDescendingLatency, calculator: transferDurationCalculator, optionName: "latency" }, - ]; - - this.timeGraphItem.isBarOpaqueAtLeft = false; - this.timeGraphItem.selectedSortingOptionIndex = 1; - - this.sizeGraphItem = new WebInspector.SidebarTreeElement("resources-size-graph-sidebar-item", WebInspector.UIString("Size")); - this.sizeGraphItem.onselect = this._graphSelected.bind(this); - - var transferSizeCalculator = new WebInspector.ResourceTransferSizeCalculator(); - this.sizeGraphItem.sortingOptions = [ - { name: WebInspector.UIString("Sort by Transfer Size"), sortingFunction: WebInspector.ResourceSidebarTreeElement.CompareByDescendingTransferSize, calculator: transferSizeCalculator, optionName: "transferSize" }, - { name: WebInspector.UIString("Sort by Size"), sortingFunction: WebInspector.ResourceSidebarTreeElement.CompareByDescendingSize, calculator: transferSizeCalculator, optionName: "size" }, - ]; - - this.sizeGraphItem.isBarOpaqueAtLeft = true; - this.sizeGraphItem.selectedSortingOptionIndex = 0; - - this.graphsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("GRAPHS"), {}, true); - this.sidebarTree.appendChild(this.graphsTreeElement); - - this.graphsTreeElement.appendChild(this.timeGraphItem); - this.graphsTreeElement.appendChild(this.sizeGraphItem); - this.graphsTreeElement.expand(); - - this.itemsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("RESOURCES"), {}, true); - this.sidebarTree.appendChild(this.itemsTreeElement); - - this.itemsTreeElement.expand(); - }, - - get resourceTrackingEnabled() - { - return this._resourceTrackingEnabled; - }, - - _createPanelEnabler: function() - { - var panelEnablerHeading = WebInspector.UIString("You need to enable resource tracking to use this panel."); - var panelEnablerDisclaimer = WebInspector.UIString("Enabling resource tracking will reload the page and make page loading slower."); - var panelEnablerButton = WebInspector.UIString("Enable resource tracking"); - - this.panelEnablerView = new WebInspector.PanelEnablerView("resources", panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton); - this.panelEnablerView.addEventListener("enable clicked", this._enableResourceTracking, this); - - this.element.appendChild(this.panelEnablerView.element); - - this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item"); - this.enableToggleButton.addEventListener("click", this.toggleResourceTracking.bind(this), false); - }, - - _createStatusbarButtons: function() - { - this.largerResourcesButton = new WebInspector.StatusBarButton(WebInspector.UIString("Use small resource rows."), "resources-larger-resources-status-bar-item"); - - this.largerResourcesButton.toggled = WebInspector.applicationSettings.resourcesLargeRows; - if (!WebInspector.applicationSettings.resourcesLargeRows) - this._setLargerResources(WebInspector.applicationSettings.resourcesLargeRows); - this._loadSortOptions(); - - this.largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false); - this.sortingSelectElement = document.createElement("select"); - this.sortingSelectElement.className = "status-bar-item"; - this.sortingSelectElement.addEventListener("change", this._changeSortingFunction.bind(this), false); - }, - - _loadSortOptions: function() - { - var newOptions = WebInspector.applicationSettings.resourcesSortOptions; - if (!newOptions) - return; - - this._loadSortOptionForGraph(this.timeGraphItem, newOptions.timeOption || "responseTime"); - this._loadSortOptionForGraph(this.sizeGraphItem, newOptions.sizeOption || "transferSize"); - }, - - _loadSortOptionForGraph: function(graphItem, newOptionName) - { - var sortingOptions = graphItem.sortingOptions; - for (var i = 0; i < sortingOptions.length; ++i) { - if (sortingOptions[i].optionName === newOptionName) { - graphItem.selectedSortingOptionIndex = i; - // Propagate the option change down to the currently selected option. - if (this._lastSelectedGraphTreeElement === graphItem) { - this._lastSelectedGraphTreeElement = null; - this._graphSelected(graphItem); - } - } - } - }, - - get mainResourceLoadTime() - { - return this._mainResourceLoadTime || -1; - }, - - set mainResourceLoadTime(x) - { - if (this._mainResourceLoadTime === x) - return; - - this._mainResourceLoadTime = x; - - // Update the dividers to draw the new line - this.updateGraphDividersIfNeeded(true); - }, - - get mainResourceDOMContentTime() - { - return this._mainResourceDOMContentTime || -1; - }, - - set mainResourceDOMContentTime(x) - { - if (this._mainResourceDOMContentTime === x) - return; - - this._mainResourceDOMContentTime = x; - - this.updateGraphDividersIfNeeded(true); - }, - - show: function() - { - WebInspector.Panel.prototype.show.call(this); - - this._updateDividersLabelBarPosition(); - this.refreshIfNeeded(); - - var visibleView = this.visibleView; - if (this.visibleResource) { - this.visibleView.headersVisible = true; - this.visibleView.show(this.viewsContainerElement); - } else if (visibleView) - visibleView.show(); - - // Hide any views that are visible that are not this panel's current visible view. - // This can happen when a ResourceView is visible in the Scripts panel then switched - // to the this panel. - var resourcesLength = this._resources.length; - for (var i = 0; i < resourcesLength; ++i) { - var resource = this._resources[i]; - var view = resource._resourcesView; - if (!view || view === visibleView) - continue; - view.visible = false; - } - }, - - get searchableViews() - { - var views = []; - - const visibleView = this.visibleView; - if (visibleView && visibleView.performSearch) - views.push(visibleView); - - var resourcesLength = this._resources.length; - for (var i = 0; i < resourcesLength; ++i) { - var resource = this._resources[i]; - if (!resource._itemsTreeElement || !resource._itemsTreeElement.selectable) - continue; - var resourceView = WebInspector.ResourceManager.resourceViewForResource(resource); - if (!resourceView.performSearch || resourceView === visibleView) - continue; - views.push(resourceView); - } - - return views; - }, - - get searchResultsSortFunction() - { - const resourceTreeElementSortFunction = this.sortingFunction; - - function sortFuction(a, b) - { - return resourceTreeElementSortFunction(a.resource._itemsTreeElement, b.resource._itemsTreeElement); - } - - return sortFuction; - }, - - searchMatchFound: function(view, matches) - { - view.resource._itemsTreeElement.searchMatches = matches; - }, - - searchCanceled: function(startingNewSearch) - { - WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch); - - if (startingNewSearch || !this._resources) - return; - - for (var i = 0; i < this._resources.length; ++i) { - var resource = this._resources[i]; - if (resource._itemsTreeElement) - resource._itemsTreeElement.updateErrorsAndWarnings(); - } - }, - - performSearch: function(query) - { - for (var i = 0; i < this._resources.length; ++i) { - var resource = this._resources[i]; - if (resource._itemsTreeElement) - resource._itemsTreeElement.resetBubble(); - } - - WebInspector.Panel.prototype.performSearch.call(this, query); - }, - - get visibleView() - { - if (this.visibleResource) - return this.visibleResource._resourcesView; - return this._resourceTrackingEnabled ? null : this.panelEnablerView; - }, - - get sortingFunction() - { - return this._sortingFunction; - }, - - set sortingFunction(x) - { - this._sortingFunction = x; - this._sortResourcesIfNeeded(); - }, - - refresh: function() - { - this.needsRefresh = false; - - var staleItemsLength = this._staleItems.length; - - var boundariesChanged = false; - - for (var i = 0; i < staleItemsLength; ++i) { - var item = this._staleItems[i]; - if (!item._itemsTreeElement) { - // Create the timeline tree element and graph. - item._itemsTreeElement = this.createItemTreeElement(item); - item._itemsTreeElement._itemGraph = this.createItemGraph(item); - - this.itemsTreeElement.appendChild(item._itemsTreeElement); - this.itemsGraphsElement.appendChild(item._itemsTreeElement._itemGraph.graphElement); - } - - if (item._itemsTreeElement.refresh) - item._itemsTreeElement.refresh(); - - if (this.calculator.updateBoundaries(item)) - boundariesChanged = true; - } - - if (boundariesChanged) { - // The boundaries changed, so all item graphs are stale. - this._staleItems = this._items.slice(); - staleItemsLength = this._staleItems.length; - } - - - const isBarOpaqueAtLeft = this.sidebarTree.selectedTreeElement && this.sidebarTree.selectedTreeElement.isBarOpaqueAtLeft; - for (var i = 0; i < staleItemsLength; ++i) - this._staleItems[i]._itemsTreeElement._itemGraph.refresh(this.calculator, isBarOpaqueAtLeft); - - this._staleItems = []; - - this.updateGraphDividersIfNeeded(); - - this._sortResourcesIfNeeded(); - this._updateSummaryGraph(); - }, - - _updateSummaryGraph: function() - { - this.summaryBar.update(this._resources); - }, - - resourceTrackingWasEnabled: function() - { - this._resourceTrackingEnabled = true; - this.reset(); - this.restoreSidebarWidth(); - }, - - resourceTrackingWasDisabled: function() - { - this._resourceTrackingEnabled = false; - this.reset(); - }, - - reset: function() - { - this._popoverHelper.hidePopup(); - this.closeVisibleResource(); - - delete this.currentQuery; - this.searchCanceled(); - - if (this._resources) { - var resourcesLength = this._resources.length; - for (var i = 0; i < resourcesLength; ++i) { - var resource = this._resources[i]; - - resource.warnings = 0; - resource.errors = 0; - - delete resource._resourcesView; - } - } - - // Begin reset timeline - this.containerElement.scrollTop = 0; - - if (this._calculator) - this._calculator.reset(); - - if (this._items) { - var itemsLength = this._items.length; - for (var i = 0; i < itemsLength; ++i) { - var item = this._items[i]; - delete item._itemsTreeElement; - } - } - - this._items = []; - this._staleItems = []; - - this.itemsTreeElement.removeChildren(); - this.itemsGraphsElement.removeChildren(); - - this.updateGraphDividersIfNeeded(true); - // End reset timeline. - - this.mainResourceLoadTime = -1; - this.mainResourceDOMContentTime = -1; - - this.viewsContainerElement.removeChildren(); - - this.summaryBar.reset(); - - if (this._resourceTrackingEnabled) { - this.enableToggleButton.title = WebInspector.UIString("Resource tracking enabled. Click to disable."); - this.enableToggleButton.toggled = true; - this.largerResourcesButton.visible = true; - this.sortingSelectElement.removeStyleClass("hidden"); - this.panelEnablerView.visible = false; - } else { - this.enableToggleButton.title = WebInspector.UIString("Resource tracking disabled. Click to enable."); - this.enableToggleButton.toggled = false; - this.largerResourcesButton.visible = false; - this.sortingSelectElement.addStyleClass("hidden"); - this.panelEnablerView.visible = true; - } - this.resourceURLMap = {}; - }, - - addResource: function(resource) - { - this.resourceURLMap[resource.url] = resource; - this._resources.push(resource); - }, - - removeResource: function(resource) - { - if (this.visibleView === resource._resourcesView) - this.closeVisibleResource(); - - this.removeItem(resource); - - resource.warnings = 0; - resource.errors = 0; - - delete resource._resourcesView; - delete this.resourceURLMap[resource.url]; - }, - - addMessageToResource: function(resource, msg) - { - if (!resource) - return; - - switch (msg.level) { - case WebInspector.ConsoleMessage.MessageLevel.Warning: - resource.warnings += msg.repeatDelta; - break; - case WebInspector.ConsoleMessage.MessageLevel.Error: - resource.errors += msg.repeatDelta; - break; - } - - if (!this.currentQuery && resource._itemsTreeElement) - resource._itemsTreeElement.updateErrorsAndWarnings(); - - var view = WebInspector.ResourceManager.resourceViewForResource(resource); - if (view.addMessage) - view.addMessage(msg); - }, - - clearMessages: function() - { - var resourcesLength = this._resources.length; - for (var i = 0; i < resourcesLength; ++i) { - var resource = this._resources[i]; - resource.warnings = 0; - resource.errors = 0; - - if (!this.currentQuery && resource._itemsTreeElement) - resource._itemsTreeElement.updateErrorsAndWarnings(); - - var view = resource._resourcesView; - if (!view || !view.clearMessages) - continue; - view.clearMessages(); - } - }, - - refreshResource: function(resource) - { - this._recreateViewForResourceIfNeeded(resource); - this.refreshItem(resource); - }, - - _recreateViewForResourceIfNeeded: function(resource) - { - if (!resource || !resource._resourcesView) - return; - - if (WebInspector.ResourceManager.resourceViewTypeMatchesResource(resource, resource._resourcesView)) - return; - var newView = WebInspector.ResourceManager.createResourceView(resource); - - if (!this.currentQuery && resource._itemsTreeElement) - resource._itemsTreeElement.updateErrorsAndWarnings(); - - var oldView = resource._resourcesView; - var oldViewParentNode = oldView.visible ? oldView.element.parentNode : null; - - resource._resourcesView.detach(); - delete resource._resourcesView; - - resource._resourcesView = newView; - - newView.headersVisible = oldView.headersVisible; - - if (oldViewParentNode) - newView.show(oldViewParentNode); - - WebInspector.panels.scripts.viewRecreated(oldView, newView); - }, - - canShowSourceLine: function(url, line) - { - return this._resourceTrackingEnabled && !!WebInspector.resourceForURL(url); - }, - - showSourceLine: function(url, line) - { - this.showResource(WebInspector.resourceForURL(url), line); - }, - - showResource: function(resource, line) - { - if (!resource) - return; - - this._popoverHelper.hidePopup(); - - this.containerElement.addStyleClass("viewing-resource"); - - if (this.visibleResource && this.visibleResource._resourcesView) - this.visibleResource._resourcesView.hide(); - - var view = WebInspector.ResourceManager.resourceViewForResource(resource); - view.headersVisible = true; - view.show(this.viewsContainerElement); - - if (line) { - view.selectContentTab(true); - if (view.revealLine) - view.revealLine(line); - if (view.highlightLine) - view.highlightLine(line); - } - - this.revealAndSelectItem(resource); - - this.visibleResource = resource; - - this.updateSidebarWidth(); - }, - - showView: function(view) - { - if (!view) - return; - this.showResource(view.resource); - }, - - closeVisibleResource: function() - { - this.containerElement.removeStyleClass("viewing-resource"); - this._updateDividersLabelBarPosition(); - - if (this.visibleResource && this.visibleResource._resourcesView) - this.visibleResource._resourcesView.hide(); - delete this.visibleResource; - - if (this._lastSelectedGraphTreeElement) - this._lastSelectedGraphTreeElement.select(true); - - this.updateSidebarWidth(); - }, - - _sortResourcesIfNeeded: function() - { - this.sortItems(this.sortingFunction); - }, - - updateGraphDividersIfNeeded: function(force) - { - var proceed = true; - if (!this.visible) { - this.needsRefresh = true; - proceed = false; - } else - proceed = this._timelineGrid.updateDividers(force, this.calculator); - - if (!proceed) - return; - - if (this.calculator.startAtZero || !this.calculator.computePercentageFromEventTime) { - // If our current sorting method starts at zero, that means it shows all - // resources starting at the same point, and so onLoad event and DOMContent - // event lines really wouldn't make much sense here, so don't render them. - // Additionally, if the calculator doesn't have the computePercentageFromEventTime - // function defined, we are probably sorting by size, and event times aren't relevant - // in this case. - return; - } - - this._timelineGrid.removeEventDividers(); - if (this.mainResourceLoadTime !== -1) { - var percent = this.calculator.computePercentageFromEventTime(this.mainResourceLoadTime); - - var loadDivider = document.createElement("div"); - loadDivider.className = "resources-event-divider resources-red-divider"; - - var loadDividerPadding = document.createElement("div"); - loadDividerPadding.className = "resources-event-divider-padding"; - loadDividerPadding.style.left = percent + "%"; - loadDividerPadding.title = WebInspector.UIString("Load event fired"); - loadDividerPadding.appendChild(loadDivider); - - this.addEventDivider(loadDividerPadding); - } - - if (this.mainResourceDOMContentTime !== -1) { - var percent = this.calculator.computePercentageFromEventTime(this.mainResourceDOMContentTime); - - var domContentDivider = document.createElement("div"); - domContentDivider.className = "resources-event-divider resources-blue-divider"; - - var domContentDividerPadding = document.createElement("div"); - domContentDividerPadding.className = "resources-event-divider-padding"; - domContentDividerPadding.style.left = percent + "%"; - domContentDividerPadding.title = WebInspector.UIString("DOMContent event fired"); - domContentDividerPadding.appendChild(domContentDivider); - - this.addEventDivider(domContentDividerPadding); - } - }, - - _graphSelected: function(treeElement) - { - if (this._lastSelectedGraphTreeElement) - this._lastSelectedGraphTreeElement.selectedSortingOptionIndex = this.sortingSelectElement.selectedIndex; - - this._lastSelectedGraphTreeElement = treeElement; - - this.sortingSelectElement.removeChildren(); - for (var i = 0; i < treeElement.sortingOptions.length; ++i) { - var sortingOption = treeElement.sortingOptions[i]; - var option = document.createElement("option"); - option.label = sortingOption.name; - option.sortingFunction = sortingOption.sortingFunction; - option.calculator = sortingOption.calculator; - option.optionName = sortingOption.optionName; - this.sortingSelectElement.appendChild(option); - } - - this.sortingSelectElement.selectedIndex = treeElement.selectedSortingOptionIndex; - this._doChangeSortingFunction(); - - this.closeVisibleResource(); - this.containerElement.scrollTop = 0; - - if (treeElement === this.sizeGraphItem) - this.hideEventDividers(); - else - this.showEventDividers(); - }, - - _toggleLargerResources: function() - { - if (!this.itemsTreeElement._childrenListNode) - return; - - WebInspector.applicationSettings.resourcesLargeRows = !WebInspector.applicationSettings.resourcesLargeRows; - this._setLargerResources(this.itemsTreeElement.smallChildren); - }, - - _setLargerResources: function(enabled) - { - this.largerResourcesButton.toggled = enabled; - this.itemsTreeElement.smallChildren = !enabled; - if (!enabled) { - this.itemsGraphsElement.addStyleClass("small"); - this.largerResourcesButton.title = WebInspector.UIString("Use large resource rows."); - this.adjustScrollPosition(); - } else { - this.itemsGraphsElement.removeStyleClass("small"); - this.largerResourcesButton.title = WebInspector.UIString("Use small resource rows."); - } - }, - - _changeSortingFunction: function() - { - this._doChangeSortingFunction(); - WebInspector.applicationSettings.resourcesSortOptions = {timeOption: this._selectedOptionNameForGraph(this.timeGraphItem), sizeOption: this._selectedOptionNameForGraph(this.sizeGraphItem)}; - }, - - _selectedOptionNameForGraph: function(graphItem) - { - return graphItem.sortingOptions[graphItem.selectedSortingOptionIndex].optionName; - }, - - _doChangeSortingFunction: function() - { - var selectedIndex = this.sortingSelectElement.selectedIndex; - if (this._lastSelectedGraphTreeElement) - this._lastSelectedGraphTreeElement.selectedSortingOptionIndex = selectedIndex; - var selectedOption = this.sortingSelectElement[selectedIndex]; - this.sortingFunction = selectedOption.sortingFunction; - this.calculator = this.summaryBar.calculator = selectedOption.calculator; - }, - - setSidebarWidth: function(width) - { - if (this.visibleResource) { - this.containerElement.style.width = width + "px"; - this.sidebarElement.style.removeProperty("width"); - } else { - this.sidebarElement.style.width = width + "px"; - this.containerElement.style.removeProperty("width"); - } - - this.sidebarResizeElement.style.left = (width - 3) + "px"; - }, - - updateMainViewWidth: function(width) - { - this.viewsContainerElement.style.left = width + "px"; - this._containerContentElement.style.left = width + "px"; - this.resize(); - }, - - _enableResourceTracking: function() - { - if (this._resourceTrackingEnabled) - return; - this.toggleResourceTracking(this.panelEnablerView.alwaysEnabled); - }, - - toggleResourceTracking: function(optionalAlways) - { - function callback(newState) { - if (newState) - WebInspector.panels.resources.resourceTrackingWasEnabled(); - else - WebInspector.panels.resources.resourceTrackingWasDisabled(); - } - - if (this._resourceTrackingEnabled) { - this.largerResourcesButton.visible = false; - this.sortingSelectElement.visible = false; - WebInspector.resources = {}; - this.resourceURLMap = {}; - InspectorBackend.setResourceTrackingEnabled(false, true, callback); - } else { - this.largerResourcesButton.visible = true; - this.sortingSelectElement.visible = true; - InspectorBackend.setResourceTrackingEnabled(true, !!optionalAlways, callback); - } - }, - - get _resources() - { - return this.items; - }, - - elementsToRestoreScrollPositionsFor: function() - { - return [ this.containerElement ]; - }, - - _getPopoverAnchor: function(element) - { - var anchor = element.enclosingNodeOrSelfWithClass("resources-graph-bar") || element.enclosingNodeOrSelfWithClass("resources-graph-label"); - if (!anchor) - return null; - var resource = anchor.parentElement.resource; - return resource && resource.timing ? anchor : null; - }, - - _showPopover: function(anchor) - { - var tableElement = document.createElement("table"); - var resource = anchor.parentElement.resource; - var rows = []; - - function addRow(title, start, end, color) - { - var row = {}; - row.title = title; - row.start = start; - row.end = end; - rows.push(row); - } - - if (resource.timing.proxyStart !== -1) - addRow(WebInspector.UIString("Proxy"), resource.timing.proxyStart, resource.timing.proxyEnd); - - if (resource.timing.dnsStart !== -1) { - addRow(WebInspector.UIString("DNS Lookup"), resource.timing.dnsStart, resource.timing.dnsEnd); - } - - if (resource.timing.connectStart !== -1) { - if (resource.connectionReused) - addRow(WebInspector.UIString("Blocking"), resource.timing.connectStart, resource.timing.connectEnd); - else { - var connectStart = resource.timing.connectStart; - // Connection includes DNS, subtract it here. - if (resource.timing.dnsStart !== -1) - connectStart += resource.timing.dnsEnd - resource.timing.dnsStart; - addRow(WebInspector.UIString("Connecting"), connectStart, resource.timing.connectEnd); - } - } - - if (resource.timing.sslStart !== -1) - addRow(WebInspector.UIString("SSL"), resource.timing.sslStart, resource.timing.sslEnd); - - var sendStart = resource.timing.sendStart; - if (resource.timing.sslStart !== -1) - sendStart += resource.timing.sslEnd - resource.timing.sslStart; - - addRow(WebInspector.UIString("Sending"), resource.timing.sendStart, resource.timing.sendEnd); - addRow(WebInspector.UIString("Waiting"), resource.timing.sendEnd, resource.timing.receiveHeadersEnd); - addRow(WebInspector.UIString("Receiving"), (resource.responseReceivedTime - resource.timing.requestTime) * 1000, (resource.endTime - resource.timing.requestTime) * 1000); - - const chartWidth = 200; - var total = (resource.endTime - resource.timing.requestTime) * 1000; - var scale = chartWidth / total; - - for (var i = 0; i < rows.length; ++i) { - var tr = document.createElement("tr"); - tableElement.appendChild(tr); - - var td = document.createElement("td"); - td.textContent = rows[i].title; - tr.appendChild(td); - - td = document.createElement("td"); - td.width = chartWidth + "px"; - - var row = document.createElement("div"); - row.className = "resource-timing-row"; - td.appendChild(row); - - var bar = document.createElement("span"); - bar.className = "resource-timing-bar"; - bar.style.left = scale * rows[i].start + "px"; - bar.style.right = scale * (total - rows[i].end) + "px"; - bar.style.backgroundColor = rows[i].color; - bar.textContent = "\u200B"; // Important for 0-time items to have 0 width. - row.appendChild(bar); - - var title = document.createElement("span"); - title.className = "resource-timing-bar-title"; - if (total - rows[i].end < rows[i].start) - title.style.right = (scale * (total - rows[i].end) + 3) + "px"; - else - title.style.left = (scale * rows[i].start + 3) + "px"; - title.textContent = Number.millisToString(rows[i].end - rows[i].start); - row.appendChild(title); - - tr.appendChild(td); - } - - var popover = new WebInspector.Popover(tableElement); - popover.show(anchor); - return popover; - }, - - hide: function() - { - WebInspector.Panel.prototype.hide.call(this); - this._popoverHelper.hidePopup(); - }, - - _contextMenu: function(event) - { - var contextMenu = new WebInspector.ContextMenu(); - var resourceTreeItem = event.target.enclosingNodeOrSelfWithClass("resource-sidebar-tree-item"); - var resource; - if (resourceTreeItem && resourceTreeItem.treeElement) - resource = resourceTreeItem.treeElement.representedObject; - - var needSeparator = false; - // createObjectURL is enabled conditionally, do not expose resource export if it's not available. - if (typeof window.createObjectURL === "function" && Preferences.resourceExportEnabled) { - if (resource) - contextMenu.appendItem(WebInspector.UIString("Export to HAR"), this._exportResource.bind(this, resource)); - contextMenu.appendItem(WebInspector.UIString("Export all to HAR"), this._exportAll.bind(this)); - needSeparator = true; - } - - if (resource && resource.category === WebInspector.resourceCategories.xhr) { - if (needSeparator) - contextMenu.appendSeparator(); - contextMenu.appendItem(WebInspector.UIString("Set XHR Breakpoint"), WebInspector.breakpointManager.createXHRBreakpoint.bind(WebInspector.breakpointManager, resource.url)); - } - - contextMenu.show(event); - }, - - _exportAll: function() - { - var harArchive = { - log: (new WebInspector.HARLog()).build() - } - offerFileForDownload(JSON.stringify(harArchive)); - }, - - _exportResource: function(resource) - { - var har = (new WebInspector.HAREntry(resource)).build(); - offerFileForDownload(JSON.stringify(har)); - } -} - -WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.Panel.prototype; - -WebInspector.ResourceBaseCalculator = function() -{ -} - -WebInspector.ResourceBaseCalculator.prototype = { - computeSummaryValues: function(items) - { - var total = 0; - var categoryValues = {}; - - var itemsLength = items.length; - for (var i = 0; i < itemsLength; ++i) { - var item = items[i]; - var value = this._value(item); - if (typeof value === "undefined") - continue; - if (!(item.category.name in categoryValues)) - categoryValues[item.category.name] = 0; - categoryValues[item.category.name] += value; - total += value; - } - - return {categoryValues: categoryValues, total: total}; - }, - - computeBarGraphPercentages: function(item) - { - return {start: 0, middle: 0, end: (this._value(item) / this.boundarySpan) * 100}; - }, - - computeBarGraphLabels: function(item) - { - const label = this.formatValue(this._value(item)); - return {left: label, right: label, tooltip: label}; - }, - - get boundarySpan() - { - return this.maximumBoundary - this.minimumBoundary; - }, - - updateBoundaries: function(item) - { - this.minimumBoundary = 0; - - var value = this._value(item); - if (typeof this.maximumBoundary === "undefined" || value > this.maximumBoundary) { - this.maximumBoundary = value; - return true; - } - return false; - }, - - reset: function() - { - delete this.minimumBoundary; - delete this.maximumBoundary; - }, - - _value: function(item) - { - return 0; - }, - - formatValue: function(value) - { - return value.toString(); - } -} - -WebInspector.ResourceTimeCalculator = function(startAtZero) -{ - WebInspector.ResourceBaseCalculator.call(this); - this.startAtZero = startAtZero; -} - -WebInspector.ResourceTimeCalculator.prototype = { - computeSummaryValues: function(resources) - { - var resourcesByCategory = {}; - var resourcesLength = resources.length; - for (var i = 0; i < resourcesLength; ++i) { - var resource = resources[i]; - if (!(resource.category.name in resourcesByCategory)) - resourcesByCategory[resource.category.name] = []; - resourcesByCategory[resource.category.name].push(resource); - } - - var earliestStart; - var latestEnd; - var categoryValues = {}; - for (var category in resourcesByCategory) { - resourcesByCategory[category].sort(WebInspector.Resource.CompareByTime); - categoryValues[category] = 0; - - var segment = {start: -1, end: -1}; - - var categoryResources = resourcesByCategory[category]; - var resourcesLength = categoryResources.length; - for (var i = 0; i < resourcesLength; ++i) { - var resource = categoryResources[i]; - if (resource.startTime === -1 || resource.endTime === -1) - continue; - - if (typeof earliestStart === "undefined") - earliestStart = resource.startTime; - else - earliestStart = Math.min(earliestStart, resource.startTime); - - if (typeof latestEnd === "undefined") - latestEnd = resource.endTime; - else - latestEnd = Math.max(latestEnd, resource.endTime); - - if (resource.startTime <= segment.end) { - segment.end = Math.max(segment.end, resource.endTime); - continue; - } - - categoryValues[category] += segment.end - segment.start; - - segment.start = resource.startTime; - segment.end = resource.endTime; - } - - // Add the last segment - categoryValues[category] += segment.end - segment.start; - } - - return {categoryValues: categoryValues, total: latestEnd - earliestStart}; - }, - - computeBarGraphPercentages: function(resource) - { - if (resource.startTime !== -1) - var start = ((resource.startTime - this.minimumBoundary) / this.boundarySpan) * 100; - else - var start = 0; - - if (resource.responseReceivedTime !== -1) - var middle = ((resource.responseReceivedTime - this.minimumBoundary) / this.boundarySpan) * 100; - else - var middle = (this.startAtZero ? start : 100); - - if (resource.endTime !== -1) - var end = ((resource.endTime - this.minimumBoundary) / this.boundarySpan) * 100; - else - var end = (this.startAtZero ? middle : 100); - - if (this.startAtZero) { - end -= start; - middle -= start; - start = 0; - } - - return {start: start, middle: middle, end: end}; - }, - - computePercentageFromEventTime: function(eventTime) - { - // This function computes a percentage in terms of the total loading time - // of a specific event. If startAtZero is set, then this is useless, and we - // want to return 0. - if (eventTime !== -1 && !this.startAtZero) - return ((eventTime - this.minimumBoundary) / this.boundarySpan) * 100; - - return 0; - }, - - computeBarGraphLabels: function(resource) - { - var rightLabel = ""; - if (resource.responseReceivedTime !== -1 && resource.endTime !== -1) - rightLabel = this.formatValue(resource.endTime - resource.responseReceivedTime); - - var hasLatency = resource.latency > 0; - if (hasLatency) - var leftLabel = this.formatValue(resource.latency); - else - var leftLabel = rightLabel; - - if (resource.timing) - return {left: leftLabel, right: rightLabel}; - - if (hasLatency && rightLabel) { - var total = this.formatValue(resource.duration); - var tooltip = WebInspector.UIString("%s latency, %s download (%s total)", leftLabel, rightLabel, total); - } else if (hasLatency) - var tooltip = WebInspector.UIString("%s latency", leftLabel); - else if (rightLabel) - var tooltip = WebInspector.UIString("%s download", rightLabel); - - if (resource.cached) - tooltip = WebInspector.UIString("%s (from cache)", tooltip); - return {left: leftLabel, right: rightLabel, tooltip: tooltip}; - }, - - updateBoundaries: function(resource) - { - var didChange = false; - - var lowerBound; - if (this.startAtZero) - lowerBound = 0; - else - lowerBound = this._lowerBound(resource); - - if (lowerBound !== -1 && (typeof this.minimumBoundary === "undefined" || lowerBound < this.minimumBoundary)) { - this.minimumBoundary = lowerBound; - didChange = true; - } - - var upperBound = this._upperBound(resource); - if (upperBound !== -1 && (typeof this.maximumBoundary === "undefined" || upperBound > this.maximumBoundary)) { - this.maximumBoundary = upperBound; - didChange = true; - } - - return didChange; - }, - - formatValue: function(value) - { - return Number.secondsToString(value, WebInspector.UIString); - }, - - _lowerBound: function(resource) - { - return 0; - }, - - _upperBound: function(resource) - { - return 0; - } -} - -WebInspector.ResourceTimeCalculator.prototype.__proto__ = WebInspector.ResourceBaseCalculator.prototype; - -WebInspector.ResourceTransferTimeCalculator = function() -{ - WebInspector.ResourceTimeCalculator.call(this, false); -} - -WebInspector.ResourceTransferTimeCalculator.prototype = { - formatValue: function(value) - { - return Number.secondsToString(value, WebInspector.UIString); - }, - - _lowerBound: function(resource) - { - return resource.startTime; - }, - - _upperBound: function(resource) - { - return resource.endTime; - } -} - -WebInspector.ResourceTransferTimeCalculator.prototype.__proto__ = WebInspector.ResourceTimeCalculator.prototype; - -WebInspector.ResourceTransferDurationCalculator = function() -{ - WebInspector.ResourceTimeCalculator.call(this, true); -} - -WebInspector.ResourceTransferDurationCalculator.prototype = { - formatValue: function(value) - { - return Number.secondsToString(value, WebInspector.UIString); - }, - - _upperBound: function(resource) - { - return resource.duration; - } -} - -WebInspector.ResourceTransferDurationCalculator.prototype.__proto__ = WebInspector.ResourceTimeCalculator.prototype; - -WebInspector.ResourceTransferSizeCalculator = function() -{ - WebInspector.ResourceBaseCalculator.call(this); -} - -WebInspector.ResourceTransferSizeCalculator.prototype = { - computeBarGraphLabels: function(resource) - { - var networkBytes = this._networkBytes(resource); - var resourceBytes = this._value(resource); - if (networkBytes && networkBytes !== resourceBytes) { - // Transferred size is not the same as reported resource length. - var networkBytesString = this.formatValue(networkBytes); - var left = networkBytesString; - var right = this.formatValue(resourceBytes); - var tooltip = right ? WebInspector.UIString("%s (%s transferred)", right, networkBytesString) : right; - } else { - var left = this.formatValue(resourceBytes); - var right = left; - var tooltip = left; - } - if (resource.cached) - tooltip = WebInspector.UIString("%s (from cache)", tooltip); - return {left: left, right: right, tooltip: tooltip}; - }, - - computeBarGraphPercentages: function(item) - { - const resourceBytesAsPercent = (this._value(item) / this.boundarySpan) * 100; - const networkBytesAsPercent = this._networkBytes(item) ? (this._networkBytes(item) / this.boundarySpan) * 100 : resourceBytesAsPercent; - return {start: 0, middle: networkBytesAsPercent, end: resourceBytesAsPercent}; - }, - - _value: function(resource) - { - return resource.resourceSize; - }, - - _networkBytes: function(resource) - { - return resource.transferSize; - }, - - formatValue: function(value) - { - return Number.bytesToString(value, WebInspector.UIString); - } -} - -WebInspector.ResourceTransferSizeCalculator.prototype.__proto__ = WebInspector.ResourceBaseCalculator.prototype; - -WebInspector.ResourceSidebarTreeElement = function(resource) -{ - this.resource = resource; - - this.createIconElement(); - - WebInspector.SidebarTreeElement.call(this, "resource-sidebar-tree-item", "", "", resource); - - this.refreshTitles(); -} - -WebInspector.ResourceSidebarTreeElement.prototype = { - onattach: function() - { - WebInspector.SidebarTreeElement.prototype.onattach.call(this); - - this._listItemNode.addStyleClass("resources-category-" + this.resource.category.name); - this._listItemNode.draggable = true; - - // FIXME: should actually add handler to parent, to be resolved via - // https://bugs.webkit.org/show_bug.cgi?id=30227 - this._listItemNode.addEventListener("dragstart", this.ondragstart.bind(this), false); - this.updateErrorsAndWarnings(); - }, - - onselect: function() - { - WebInspector.panels.resources.showResource(this.resource); - }, - - ondblclick: function(event) - { - InspectorBackend.openInInspectedWindow(this.resource.url); - }, - - ondragstart: function(event) { - event.dataTransfer.setData("text/plain", this.resource.url); - event.dataTransfer.setData("text/uri-list", this.resource.url + "\r\n"); - event.dataTransfer.effectAllowed = "copy"; - return true; - }, - - get mainTitle() - { - return this.resource.displayName; - }, - - set mainTitle(x) - { - // Do nothing. - }, - - get subtitle() - { - var subtitle = this.resource.displayDomain; - - if (this.resource.path && this.resource.lastPathComponent) { - var lastPathComponentIndex = this.resource.path.lastIndexOf("/" + this.resource.lastPathComponent); - if (lastPathComponentIndex != -1) - subtitle += this.resource.path.substring(0, lastPathComponentIndex); - } - - return subtitle; - }, - - set subtitle(x) - { - // Do nothing. - }, - - get selectable() - { - return WebInspector.panels.resources.isCategoryVisible(this.resource.category.name); - }, - - createIconElement: function() - { - var previousIconElement = this.iconElement; - - if (this.resource.category === WebInspector.resourceCategories.images) { - var previewImage = document.createElement("img"); - previewImage.className = "image-resource-icon-preview"; - - function onResourceContent() - { - previewImage.src = this.resource.contentURL; - } - if (Preferences.useDataURLForResourceImageIcons) - this.resource.getContent(onResourceContent.bind(this)); - else - previewImage.src = this.resource.url; - - this.iconElement = document.createElement("div"); - this.iconElement.className = "icon"; - this.iconElement.appendChild(previewImage); - } else { - this.iconElement = document.createElement("img"); - this.iconElement.className = "icon"; - } - - if (previousIconElement) - previousIconElement.parentNode.replaceChild(this.iconElement, previousIconElement); - }, - - refresh: function() - { - this.refreshTitles(); - - if (!this._listItemNode.hasStyleClass("resources-category-" + this.resource.category.name)) { - this._listItemNode.removeMatchingStyleClasses("resources-category-\\w+"); - this._listItemNode.addStyleClass("resources-category-" + this.resource.category.name); - - this.createIconElement(); - } - - this.tooltip = this.resource.url; - }, - - resetBubble: function() - { - this.bubbleText = ""; - this.bubbleElement.removeStyleClass("search-matches"); - this.bubbleElement.removeStyleClass("warning"); - this.bubbleElement.removeStyleClass("error"); - }, - - set searchMatches(matches) - { - this.resetBubble(); - - if (!matches) - return; - - this.bubbleText = matches; - this.bubbleElement.addStyleClass("search-matches"); - }, - - updateErrorsAndWarnings: function() - { - this.resetBubble(); - - if (this.resource.warnings || this.resource.errors) - this.bubbleText = (this.resource.warnings + this.resource.errors); - - if (this.resource.warnings) - this.bubbleElement.addStyleClass("warning"); - - if (this.resource.errors) - this.bubbleElement.addStyleClass("error"); - } -} - -WebInspector.ResourceSidebarTreeElement.CompareByAscendingStartTime = function(a, b) -{ - return WebInspector.Resource.CompareByStartTime(a.resource, b.resource) - || WebInspector.Resource.CompareByEndTime(a.resource, b.resource) - || WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.resource); -} - -WebInspector.ResourceSidebarTreeElement.CompareByAscendingResponseReceivedTime = function(a, b) -{ - return WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.resource) - || WebInspector.Resource.CompareByStartTime(a.resource, b.resource) - || WebInspector.Resource.CompareByEndTime(a.resource, b.resource); -} - -WebInspector.ResourceSidebarTreeElement.CompareByAscendingEndTime = function(a, b) -{ - return WebInspector.Resource.CompareByEndTime(a.resource, b.resource) - || WebInspector.Resource.CompareByStartTime(a.resource, b.resource) - || WebInspector.Resource.CompareByResponseReceivedTime(a.resource, b.resource); -} - -WebInspector.ResourceSidebarTreeElement.CompareByDescendingDuration = function(a, b) -{ - return -1 * WebInspector.Resource.CompareByDuration(a.resource, b.resource); -} - -WebInspector.ResourceSidebarTreeElement.CompareByDescendingLatency = function(a, b) -{ - return -1 * WebInspector.Resource.CompareByLatency(a.resource, b.resource); -} - -WebInspector.ResourceSidebarTreeElement.CompareByDescendingSize = function(a, b) -{ - return -1 * WebInspector.Resource.CompareBySize(a.resource, b.resource); -} - -WebInspector.ResourceSidebarTreeElement.CompareByDescendingTransferSize = function(a, b) -{ - return -1 * WebInspector.Resource.CompareByTransferSize(a.resource, b.resource); -} - -WebInspector.ResourceSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype; - -WebInspector.ResourceGraph = function(resource) -{ - this.resource = resource; - - this._graphElement = document.createElement("div"); - this._graphElement.className = "resources-graph-side"; - this._graphElement.addEventListener("mouseover", this.refreshLabelPositions.bind(this), false); - - if (this.resource.cached) - this._graphElement.addStyleClass("resource-cached"); - - this._barAreaElement = document.createElement("div"); - this._barAreaElement.className = "resources-graph-bar-area hidden"; - this._barAreaElement.resource = resource; - this._graphElement.appendChild(this._barAreaElement); - - this._barLeftElement = document.createElement("div"); - this._barLeftElement.className = "resources-graph-bar waiting"; - this._barAreaElement.appendChild(this._barLeftElement); - - this._barRightElement = document.createElement("div"); - this._barRightElement.className = "resources-graph-bar"; - this._barAreaElement.appendChild(this._barRightElement); - - this._labelLeftElement = document.createElement("div"); - this._labelLeftElement.className = "resources-graph-label waiting"; - this._barAreaElement.appendChild(this._labelLeftElement); - - this._labelRightElement = document.createElement("div"); - this._labelRightElement.className = "resources-graph-label"; - this._barAreaElement.appendChild(this._labelRightElement); - - this._graphElement.addStyleClass("resources-category-" + resource.category.name); -} - -WebInspector.ResourceGraph.prototype = { - get graphElement() - { - return this._graphElement; - }, - - refreshLabelPositions: function() - { - this._labelLeftElement.style.removeProperty("left"); - this._labelLeftElement.style.removeProperty("right"); - this._labelLeftElement.removeStyleClass("before"); - this._labelLeftElement.removeStyleClass("hidden"); - - this._labelRightElement.style.removeProperty("left"); - this._labelRightElement.style.removeProperty("right"); - this._labelRightElement.removeStyleClass("after"); - this._labelRightElement.removeStyleClass("hidden"); - - const labelPadding = 10; - const barRightElementOffsetWidth = this._barRightElement.offsetWidth; - const barLeftElementOffsetWidth = this._barLeftElement.offsetWidth; - - if (this._isBarOpaqueAtLeft) { - var leftBarWidth = barLeftElementOffsetWidth - labelPadding; - var rightBarWidth = (barRightElementOffsetWidth - barLeftElementOffsetWidth) - labelPadding; - } else { - var leftBarWidth = (barLeftElementOffsetWidth - barRightElementOffsetWidth) - labelPadding; - var rightBarWidth = barRightElementOffsetWidth - labelPadding; - } - - const labelLeftElementOffsetWidth = this._labelLeftElement.offsetWidth; - const labelRightElementOffsetWidth = this._labelRightElement.offsetWidth; - - const labelBefore = (labelLeftElementOffsetWidth > leftBarWidth); - const labelAfter = (labelRightElementOffsetWidth > rightBarWidth); - const graphElementOffsetWidth = this._graphElement.offsetWidth; - - if (labelBefore && (graphElementOffsetWidth * (this._percentages.start / 100)) < (labelLeftElementOffsetWidth + 10)) - var leftHidden = true; - - if (labelAfter && (graphElementOffsetWidth * ((100 - this._percentages.end) / 100)) < (labelRightElementOffsetWidth + 10)) - var rightHidden = true; - - if (barLeftElementOffsetWidth == barRightElementOffsetWidth) { - // The left/right label data are the same, so a before/after label can be replaced by an on-bar label. - if (labelBefore && !labelAfter) - leftHidden = true; - else if (labelAfter && !labelBefore) - rightHidden = true; - } - - if (labelBefore) { - if (leftHidden) - this._labelLeftElement.addStyleClass("hidden"); - this._labelLeftElement.style.setProperty("right", (100 - this._percentages.start) + "%"); - this._labelLeftElement.addStyleClass("before"); - } else { - this._labelLeftElement.style.setProperty("left", this._percentages.start + "%"); - this._labelLeftElement.style.setProperty("right", (100 - this._percentages.middle) + "%"); - } - - if (labelAfter) { - if (rightHidden) - this._labelRightElement.addStyleClass("hidden"); - this._labelRightElement.style.setProperty("left", this._percentages.end + "%"); - this._labelRightElement.addStyleClass("after"); - } else { - this._labelRightElement.style.setProperty("left", this._percentages.middle + "%"); - this._labelRightElement.style.setProperty("right", (100 - this._percentages.end) + "%"); - } - }, - - refresh: function(calculator, isBarOpaqueAtLeft) - { - var percentages = calculator.computeBarGraphPercentages(this.resource); - var labels = calculator.computeBarGraphLabels(this.resource); - - this._percentages = percentages; - - this._barAreaElement.removeStyleClass("hidden"); - - if (!this._graphElement.hasStyleClass("resources-category-" + this.resource.category.name)) { - this._graphElement.removeMatchingStyleClasses("resources-category-\\w+"); - this._graphElement.addStyleClass("resources-category-" + this.resource.category.name); - } - - this._barLeftElement.style.setProperty("left", percentages.start + "%"); - this._barRightElement.style.setProperty("right", (100 - percentages.end) + "%"); - - if (!isBarOpaqueAtLeft) { - this._barLeftElement.style.setProperty("right", (100 - percentages.end) + "%"); - this._barRightElement.style.setProperty("left", percentages.middle + "%"); - - if (this._isBarOpaqueAtLeft != isBarOpaqueAtLeft) { - this._barLeftElement.addStyleClass("waiting"); - this._barRightElement.removeStyleClass("waiting-right"); - this._labelLeftElement.addStyleClass("waiting"); - this._labelRightElement.removeStyleClass("waiting-right"); - } - } else { - this._barLeftElement.style.setProperty("right", (100 - percentages.middle) + "%"); - this._barRightElement.style.setProperty("left", percentages.start + "%"); - - if (this._isBarOpaqueAtLeft != isBarOpaqueAtLeft) { - this._barLeftElement.removeStyleClass("waiting"); - this._barRightElement.addStyleClass("waiting-right"); - this._labelLeftElement.removeStyleClass("waiting"); - this._labelRightElement.addStyleClass("waiting-right"); - } - } - - this._isBarOpaqueAtLeft = isBarOpaqueAtLeft; - - this._labelLeftElement.textContent = labels.left; - this._labelRightElement.textContent = labels.right; - - var tooltip = (labels.tooltip || ""); - this._barLeftElement.title = tooltip; - this._labelLeftElement.title = tooltip; - this._labelRightElement.title = tooltip; - this._barRightElement.title = tooltip; - - if (this.resource.cached && !this._graphElement.hasStyleClass("resource-cached")) - this._graphElement.addStyleClass("resource-cached"); - } -} diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js index 8125c1e..66260f9 100644 --- a/WebCore/inspector/front-end/ScriptsPanel.js +++ b/WebCore/inspector/front-end/ScriptsPanel.js @@ -376,7 +376,7 @@ WebInspector.ScriptsPanel.prototype = { InjectedScriptAccess.get(callFrame.worldId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback); }, - debuggerPaused: function(details) + debuggerPaused: function(callFrames) { WebInspector.breakpointManager.removeOneTimeBreakpoint(); this._paused = true; @@ -385,8 +385,8 @@ WebInspector.ScriptsPanel.prototype = { this._updateDebuggerButtons(); - this.sidebarPanes.callstack.update(details.callFrames, this._sourceIDMap); - this.sidebarPanes.callstack.selectedCallFrame = details.callFrames[0]; + this.sidebarPanes.callstack.update(callFrames, this._sourceIDMap); + this.sidebarPanes.callstack.selectedCallFrame = callFrames[0]; WebInspector.currentPanel = this; window.focus(); @@ -608,7 +608,7 @@ WebInspector.ScriptsPanel.prototype = { var url = scriptOrResource.url || scriptOrResource.sourceURL; if (url && !options.initialLoad) - WebInspector.applicationSettings.lastViewedScriptFile = url; + WebInspector.settings.lastViewedScriptFile = url; if (!options.fromBackForwardAction) { var oldIndex = this._currentBackForwardIndex; @@ -702,16 +702,22 @@ WebInspector.ScriptsPanel.prototype = { else script.filesSelectOption = option; - // Call _showScriptOrResource if the option we just appended ended up being selected. - // This will happen for the first item added to the menu. - if (select.options[select.selectedIndex] === option) + if (select.options[select.selectedIndex] === option) { + // Call _showScriptOrResource if the option we just appended ended up being selected. + // This will happen for the first item added to the menu. this._showScriptOrResource(option.representedObject, {initialLoad: true}); - else { - // if not first item, check to see if this was the last viewed + } else { + // If not first item, check to see if this was the last viewed var url = option.representedObject.url || option.representedObject.sourceURL; - var lastURL = WebInspector.applicationSettings.lastViewedScriptFile; - if (url && url === lastURL) - this._showScriptOrResource(option.representedObject, {initialLoad: true}); + var lastURL = WebInspector.settings.lastViewedScriptFile; + if (url && url === lastURL) { + // For resources containing multiple <script> tags, we first report them separately and + // then glue them all together. They all share url and there is no need to show them all one + // by one. + var isResource = !!option.representedObject.url; + if (isResource || !this.visibleView || !this.visibleView.script || this.visibleView.script.sourceURL !== url) + this._showScriptOrResource(option.representedObject, {initialLoad: true}); + } } if (script.worldType === WebInspector.Script.WorldType.EXTENSIONS_WORLD) diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js index 3fb81f5..4fd0c83 100644 --- a/WebCore/inspector/front-end/Settings.js +++ b/WebCore/inspector/front-end/Settings.js @@ -45,7 +45,7 @@ var Preferences = { onlineDetectionEnabled: true, nativeInstrumentationEnabled: false, resourceExportEnabled: false, - networkPanelEnabled: false, + fileSystemEnabled: false, useDataURLForResourceImageIcons: true } @@ -64,11 +64,15 @@ WebInspector.Settings = function() this.installApplicationSetting("lastActivePanel", "elements"); this.installProjectSetting("breakpoints", {}); + this.installProjectSetting("nativeBreakpoints", []); } WebInspector.Settings.prototype = { installApplicationSetting: function(key, defaultValue) { + if (key in this) + return; + this.__defineGetter__(key, this._get.bind(this, key, defaultValue)); this.__defineSetter__(key, this._set.bind(this, key)); }, @@ -79,6 +83,14 @@ WebInspector.Settings.prototype = { this.__defineSetter__(key, this._setProjectSetting.bind(this, key)); }, + inspectedURLChanged: function(url) + { + var fragmentIndex = url.indexOf("#"); + if (fragmentIndex !== -1) + url = url.substring(0, fragmentIndex); + this._inspectedURL = url; + }, + _get: function(key, defaultValue) { if (key in window.localStorage) { @@ -108,11 +120,7 @@ WebInspector.Settings.prototype = { _formatProjectKey: function(key) { - var url = this._mainResourceURL; - var fragmentIndex = url.indexOf("#"); - if (fragmentIndex !== -1) - url = url.substring(0, fragmentIndex); - return key + "." + url; + return key + ":" + this._inspectedURL; } } diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js index bfdc058..c7a35f7 100644 --- a/WebCore/inspector/front-end/SourceView.js +++ b/WebCore/inspector/front-end/SourceView.js @@ -84,7 +84,7 @@ WebInspector.SourceView.prototype = { this.attach(); delete this._frameNeedsSetup; - this.resource.getContent(this._contentLoaded.bind(this)); + this.resource.requestContent(this._contentLoaded.bind(this)); }, hasContentTab: function() diff --git a/WebCore/inspector/front-end/StoragePanel.js b/WebCore/inspector/front-end/StoragePanel.js index 2fa54c2..eb4eabb 100644 --- a/WebCore/inspector/front-end/StoragePanel.js +++ b/WebCore/inspector/front-end/StoragePanel.js @@ -31,37 +31,37 @@ WebInspector.StoragePanel = function(database) { WebInspector.Panel.call(this, "storage"); + WebInspector.settings.installApplicationSetting("resourcesLastSelectedItem", {}); + this.createSidebar(); this.sidebarElement.addStyleClass("outline-disclosure filter-all children small"); this.sidebarTreeElement.removeStyleClass("sidebar-tree"); - if (Preferences.networkPanelEnabled) { - this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "frame-storage-tree-item"); - this.sidebarTree.appendChild(this.resourcesListTreeElement); - this.resourcesListTreeElement.expand(); - this._treeElementForFrameId = {}; - } + this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", "frame-storage-tree-item"); + this.sidebarTree.appendChild(this.resourcesListTreeElement); + this._treeElementForFrameId = {}; - this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Databases"), "database-storage-tree-item"); + this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Databases"), "Databases", "database-storage-tree-item"); this.sidebarTree.appendChild(this.databasesListTreeElement); - this.databasesListTreeElement.expand(); - this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "domstorage-storage-tree-item local-storage"); + this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "LocalStorage", "domstorage-storage-tree-item local-storage"); this.sidebarTree.appendChild(this.localStorageListTreeElement); - this.localStorageListTreeElement.expand(); - this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "domstorage-storage-tree-item session-storage"); + this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "SessionStorage", "domstorage-storage-tree-item session-storage"); this.sidebarTree.appendChild(this.sessionStorageListTreeElement); - this.sessionStorageListTreeElement.expand(); - this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "cookie-storage-tree-item"); + this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "Cookies", "cookie-storage-tree-item"); this.sidebarTree.appendChild(this.cookieListTreeElement); - this.cookieListTreeElement.expand(); - - this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "application-cache-storage-tree-item"); + + this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", "application-cache-storage-tree-item"); this.sidebarTree.appendChild(this.applicationCacheListTreeElement); - this.applicationCacheListTreeElement.expand(); + if (Preferences.fileSystemEnabled) { + this.fileSystemListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("File System"), "FileSystem", "file-system-storage-tree-item"); + this.sidebarTree.appendChild(this.fileSystemListTreeElement); + this.fileSystemListTreeElement.expand(); + } + this.storageViews = document.createElement("div"); this.storageViews.id = "storage-views"; this.element.appendChild(this.storageViews); @@ -72,12 +72,17 @@ WebInspector.StoragePanel = function(database) this._databases = []; this._domStorage = []; this._cookieViews = {}; + this._origins = {}; + this._domains = {}; + + this.sidebarElement.addEventListener("mousemove", this._onmousemove.bind(this), false); + this.sidebarElement.addEventListener("mouseout", this._onmouseout.bind(this), false); } WebInspector.StoragePanel.prototype = { get toolbarItemLabel() { - return Preferences.networkPanelEnabled ? WebInspector.UIString("Resources") : WebInspector.UIString("Storage"); + return WebInspector.UIString("Resources"); }, get statusBarItems() @@ -85,8 +90,48 @@ WebInspector.StoragePanel.prototype = { return [this.storageViewStatusBarItemsContainer]; }, + elementsToRestoreScrollPositionsFor: function() + { + return [this.sidebarElement]; + }, + + show: function() + { + WebInspector.Panel.prototype.show.call(this); + + if (this.visibleView instanceof WebInspector.ResourceView) { + // SourceViews are shared between the panels. + this.visibleView.headersVisible = false; + this.visibleView.show(this.storageViews); + } + + if (this._initializedDefaultSelection) + return; + + this._initializedDefaultSelection = true; + var itemURL = WebInspector.settings.resourcesLastSelectedItem; + if (itemURL) { + for (var treeElement = this.sidebarTree.children[0]; treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.sidebarTree, true)) { + if (treeElement.itemURL === itemURL) { + treeElement.select(); + treeElement.reveal(); + return; + } + } + } + this._initDefaultSelection(); + }, + + _initDefaultSelection: function() + { + if (WebInspector.mainResource && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded) + this.showResource(WebInspector.mainResource); + }, + reset: function() { + this._origins = {}; + this._domains = {}; for (var i = 0; i < this._databases.length; ++i) { var database = this._databases[i]; delete database._tableViews; @@ -102,7 +147,9 @@ WebInspector.StoragePanel.prototype = { this._domStorage = []; this._cookieViews = {}; - + + this._fileSystemView = null; + this._applicationCacheView = null; delete this._cachedApplicationCacheViewStatus; @@ -111,7 +158,8 @@ WebInspector.StoragePanel.prototype = { this.sessionStorageListTreeElement.removeChildren(); this.cookieListTreeElement.removeChildren(); this.applicationCacheListTreeElement.removeChildren(); - + if (Preferences.fileSystemEnabled) + this.fileSystemListTreeElement.removeChildren(); this.storageViews.removeChildren(); this.storageViewStatusBarItemsContainer.removeChildren(); @@ -120,11 +168,11 @@ WebInspector.StoragePanel.prototype = { this.sidebarTree.selectedTreeElement.deselect(); }, - addOrUpdateFrame: function(parentFrameId, frameId, displayName) + addOrUpdateFrame: function(parentFrameId, frameId, title, subtitle) { var frameTreeElement = this._treeElementForFrameId[frameId]; if (frameTreeElement) { - frameTreeElement.displayName = displayName; + frameTreeElement.setTitles(title, subtitle); return; } @@ -134,7 +182,7 @@ WebInspector.StoragePanel.prototype = { return; } - var frameTreeElement = new WebInspector.FrameTreeElement(this, frameId, displayName); + var frameTreeElement = new WebInspector.FrameTreeElement(this, frameId, title, subtitle); this._treeElementForFrameId[frameId] = frameTreeElement; // Insert in the alphabetical order, first frames, then resources. @@ -145,7 +193,7 @@ WebInspector.StoragePanel.prototype = { parentTreeElement.insertChild(frameTreeElement, i); return; } - if (child.displayName.localeCompare(frameTreeElement.displayName) > 0) { + if (child.nameForSorting.localeCompare(frameTreeElement.nameForSorting) > 0) { parentTreeElement.insertChild(frameTreeElement, i); return; } @@ -165,6 +213,11 @@ WebInspector.StoragePanel.prototype = { addResourceToFrame: function(frameId, resource) { + this.addDocumentURL(resource.documentURL); + + if (resource.statusCode >= 301 && resource.statusCode <= 303) + return; + var frameTreeElement = this._treeElementForFrameId[frameId]; if (!frameTreeElement) { // This is a frame's main resource, it will be retained @@ -197,6 +250,16 @@ WebInspector.StoragePanel.prototype = { frameTreeElement.removeChildren(); }, + refreshResource: function(resource) + { + // FIXME: do not add XHR in the first place based on the native instrumentation. + if (resource.type === WebInspector.Resource.Type.XHR) { + var resourceTreeElement = this._findTreeElementForResource(resource); + if (resourceTreeElement) + resourceTreeElement.parent.removeChild(resourceTreeElement); + } + }, + addDatabase: function(database) { this._databases.push(database); @@ -205,11 +268,33 @@ WebInspector.StoragePanel.prototype = { database._databasesTreeElement = databaseTreeElement; this.databasesListTreeElement.appendChild(databaseTreeElement); }, - - addCookieDomain: function(domain) + + addDocumentURL: function(url) { - var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain); - this.cookieListTreeElement.appendChild(cookieDomainTreeElement); + var parsedURL = url.asParsedURL(); + if (!parsedURL) + return; + + var domain = parsedURL.host; + if (!this._domains[domain]) { + this._domains[domain] = true; + + var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain); + this.cookieListTreeElement.appendChild(cookieDomainTreeElement); + + var applicationCacheTreeElement = new WebInspector.ApplicationCacheTreeElement(this, domain); + this.applicationCacheListTreeElement.appendChild(applicationCacheTreeElement); + } + + if (Preferences.fileSystemEnabled) { + // FIXME: This should match the SecurityOrigin::toString(), add a test for this. + var securityOrigin = parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : ""); + if (!this._origins[securityOrigin]) { + this._origins[securityOrigin] = true; + var fileSystemTreeElement = new WebInspector.FileSystemTreeElement(this, securityOrigin); + this.fileSystemListTreeElement.appendChild(fileSystemTreeElement); + } + } }, addDOMStorage: function(domStorage) @@ -223,12 +308,6 @@ WebInspector.StoragePanel.prototype = { this.sessionStorageListTreeElement.appendChild(domStorageTreeElement); }, - addApplicationCache: function(domain) - { - var applicationCacheTreeElement = new WebInspector.ApplicationCacheTreeElement(this, domain); - this.applicationCacheListTreeElement.appendChild(applicationCacheTreeElement); - }, - selectDatabase: function(databaseId) { var database; @@ -258,6 +337,15 @@ WebInspector.StoragePanel.prototype = { showSourceLine: function(url, line) { + var resource = WebInspector.resourceManager.resourceForURL(url); + if (resource.type === WebInspector.Resource.Type.XHR) { + // Show XHRs in the network panel only. + if (WebInspector.panels.network && WebInspector.panels.network.canShowSourceLine(url, line)) { + WebInspector.currentPanel = WebInspector.panels.network; + WebInspector.panels.network.showSourceLine(url, line); + } + return; + } this.showResource(WebInspector.resourceManager.resourceForURL(url), line); }, @@ -291,7 +379,7 @@ WebInspector.StoragePanel.prototype = { { if (!database) return; - + var view; if (tableName) { if (!("_tableViews" in database)) @@ -352,6 +440,12 @@ WebInspector.StoragePanel.prototype = { this._applicationCacheView.updateStatus(this._cachedApplicationCacheViewStatus); }, + showFileSystem: function(treeElement, origin) + { + this._fileSystemView = new WebInspector.FileSystemView(treeElement, origin); + this._innerShowView(this._fileSystemView); + }, + showCategoryView: function(categoryName) { if (!this._categoryView) @@ -500,6 +594,24 @@ WebInspector.StoragePanel.prototype = { this._applicationCacheView.updateStatus(status); }, + updateFileSystemPath: function(root, type, origin) + { + if (this._fileSystemView && this._fileSystemView === this.visibleView) + this._fileSystemView.updateFileSystemPath(root, type, origin); + }, + + updateFileSystemError: function(type, origin) + { + if (this._fileSystemView && this._fileSystemView === this.visibleView) + this._fileSystemView.updateFileSystemError(type, origin); + }, + + setFileSystemDisabled: function() + { + if (this._fileSystemView && this._fileSystemView === this.visibleView) + this._fileSystemView.setFileSystemDisabled(); + }, + updateNetworkState: function(isNowOnline) { if (this._applicationCacheView && this._applicationCacheView === this.visibleView) @@ -536,9 +648,6 @@ WebInspector.StoragePanel.prototype = { { var views = []; - if (!Preferences.networkPanelEnabled) - return views; - const visibleView = this.visibleView; if (visibleView instanceof WebInspector.ResourceView && visibleView.performSearch) views.push(visibleView); @@ -576,13 +685,13 @@ WebInspector.StoragePanel.prototype = { { function isAncestor(ancestor, object) { - console.error("There should be no calls to isAncestor, but there was one for ", object); + // Redirects, XHRs do not belong to the tree, it is fine to silently return false here. return false; } function getParent(object) { - console.error("There should be no calls to getParent, but there was one for ", object); + // Redirects, XHRs do not belong to the tree, it is fine to silently return false here. return null; } @@ -617,6 +726,39 @@ WebInspector.StoragePanel.prototype = { { if (view) this.showResource(view.resource); + }, + + _onmousemove: function(event) + { + var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); + if (!nodeUnderMouse) + return; + + var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li"); + if (!listNode) + return; + + var element = listNode.treeElement; + if (this._previousHoveredElement === element) + return; + + if (this._previousHoveredElement) { + this._previousHoveredElement.hovered = false; + delete this._previousHoveredElement; + } + + if (element instanceof WebInspector.FrameTreeElement) { + this._previousHoveredElement = element; + element.hovered = true; + } + }, + + _onmouseout: function(event) + { + if (this._previousHoveredElement) { + this._previousHoveredElement.hovered = false; + delete this._previousHoveredElement; + } } } @@ -650,12 +792,24 @@ WebInspector.BaseStorageTreeElement.prototype = { this.listItemElement.appendChild(this.titleElement); }, + onselect: function() + { + var itemURL = this.itemURL; + if (itemURL) + WebInspector.settings.resourcesLastSelectedItem = itemURL; + }, + onreveal: function() { if (this.listItemElement) this.listItemElement.scrollIntoViewIfNeeded(false); }, + get titleText() + { + return this._titleText; + }, + set titleText(titleText) { this._titleText = titleText; @@ -675,42 +829,109 @@ WebInspector.BaseStorageTreeElement.prototype = { WebInspector.BaseStorageTreeElement.prototype.__proto__ = TreeElement.prototype; -WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, iconClass) +WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClass) { WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClass, true); + this._expandedSettingKey = "resources" + settingsKey + "Expanded"; + WebInspector.settings.installApplicationSetting(this._expandedSettingKey, settingsKey === "Frames"); this._categoryName = categoryName; } WebInspector.StorageCategoryTreeElement.prototype = { + get itemURL() + { + return "category://" + this._categoryName; + }, + onselect: function() { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); this._storagePanel.showCategoryView(this._categoryName); + }, + + onattach: function() + { + WebInspector.BaseStorageTreeElement.prototype.onattach.call(this); + if (WebInspector.settings[this._expandedSettingKey]) + this.expand(); + }, + + onexpand: function() + { + WebInspector.settings[this._expandedSettingKey] = true; + }, + + oncollapse: function() + { + WebInspector.settings[this._expandedSettingKey] = false; } } WebInspector.StorageCategoryTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; -WebInspector.FrameTreeElement = function(storagePanel, frameId, displayName) +WebInspector.FrameTreeElement = function(storagePanel, frameId, title, subtitle) { - WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, displayName, "frame-storage-tree-item"); + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", "frame-storage-tree-item"); this._frameId = frameId; - this._displayName = displayName; + this.setTitles(title, subtitle); } WebInspector.FrameTreeElement.prototype = { + get itemURL() + { + return "frame://" + encodeURI(this._displayName); + }, + + onattach: function() + { + WebInspector.BaseStorageTreeElement.prototype.onattach.call(this); + if (this._titleToSetOnAttach || this._subtitleToSetOnAttach) { + this.setTitles(this._titleToSetOnAttach, this._subtitleToSetOnAttach); + delete this._titleToSetOnAttach; + delete this._subtitleToSetOnAttach; + } + }, + onselect: function() { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); this._storagePanel.showCategoryView(this._displayName); + + this.listItemElement.removeStyleClass("hovered"); + InspectorBackend.hideFrameHighlight(); }, - get displayName() + get nameForSorting() { - return this._displayName; + return this._nameForSorting; }, - set displayName(displayName) + setTitles: function(title, subtitle) + { + this._nameForSorting = (title ? title : "") + (subtitle ? subtitle : ""); + if (this.parent) { + if (title) + this.titleElement.textContent = title; + if (subtitle) { + var subtitleElement = document.createElement("span"); + subtitleElement.className = "base-storage-tree-element-subtitle"; + subtitleElement.textContent = "(" + subtitle + ")"; + this.titleElement.appendChild(subtitleElement); + } + } else { + this._titleToSetOnAttach = title; + this._subtitleToSetOnAttach = subtitle; + } + }, + + set hovered(hovered) { - this._displayName = displayName; - this.titleText = displayName; + if (hovered) { + this.listItemElement.addStyleClass("hovered"); + InspectorBackend.highlightFrame(this._frameId); + } else { + this.listItemElement.removeStyleClass("hovered"); + InspectorBackend.hideFrameHighlight(); + } } } WebInspector.FrameTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; @@ -724,8 +945,14 @@ WebInspector.FrameResourceTreeElement = function(storagePanel, resource) } WebInspector.FrameResourceTreeElement.prototype = { + get itemURL() + { + return this._resource.url; + }, + onselect: function() { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); this._storagePanel._showResourceView(this._resource); }, @@ -836,8 +1063,14 @@ WebInspector.DatabaseTreeElement = function(storagePanel, database) } WebInspector.DatabaseTreeElement.prototype = { + get itemURL() + { + return "database://" + encodeURI(this._database.name); + }, + onselect: function() { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); this._storagePanel.showDatabase(this._database); }, @@ -872,8 +1105,14 @@ WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableNa } WebInspector.DatabaseTableTreeElement.prototype = { + get itemURL() + { + return "database://" + encodeURI(this._database.name) + "/" + encodeURI(this._tableName); + }, + onselect: function() { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); this._storagePanel.showDatabase(this._database, this._tableName); } } @@ -886,8 +1125,14 @@ WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, classNam } WebInspector.DOMStorageTreeElement.prototype = { + get itemURL() + { + return "storage://" + this._domStorage.domain + "/" + (this._domStorage.isLocalStorage ? "local" : "session"); + }, + onselect: function() { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); this._storagePanel.showDOMStorage(this._domStorage); } } @@ -900,8 +1145,14 @@ WebInspector.CookieTreeElement = function(storagePanel, cookieDomain) } WebInspector.CookieTreeElement.prototype = { + get itemURL() + { + return "cookies://" + this._cookieDomain; + }, + onselect: function() { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); this._storagePanel.showCookies(this, this._cookieDomain); } } @@ -914,13 +1165,40 @@ WebInspector.ApplicationCacheTreeElement = function(storagePanel, appcacheDomain } WebInspector.ApplicationCacheTreeElement.prototype = { + get itemURL() + { + return "appcache://" + this._appcacheDomain; + }, + onselect: function() { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); this._storagePanel.showApplicationCache(this, this._appcacheDomain); } } WebInspector.ApplicationCacheTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; +WebInspector.FileSystemTreeElement = function(storagePanel, origin) +{ + WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, origin, "file-system-storage-tree-item"); + this._origin = origin; +} + +WebInspector.FileSystemTreeElement.prototype = { + get itemURL() + { + return "file-system://" + encodeURI(this._origin); + }, + + onselect: function() + { + WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); + this._storagePanel.showFileSystem(this, this._origin); + } +} + +WebInspector.FileSystemTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; + WebInspector.StorageCategoryView = function() { WebInspector.View.call(this); diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js index cc97520..6d1b541 100644 --- a/WebCore/inspector/front-end/StylesSidebarPane.js +++ b/WebCore/inspector/front-end/StylesSidebarPane.js @@ -60,7 +60,7 @@ WebInspector.StylesSidebarPane = function(computedStylePane) this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false); this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false); - var format = WebInspector.applicationSettings.colorFormat; + var format = WebInspector.settings.colorFormat; if (format === "hex") this.settingsSelectElement[0].selected = true; else if (format === "rgb") @@ -465,7 +465,7 @@ WebInspector.StylesSidebarPane.prototype = { // Select the correct color format setting again, since it needs to be selected. var selectedIndex = 0; for (var i = 0; i < options.length; ++i) { - if (options[i].value === WebInspector.applicationSettings.colorFormat) { + if (options[i].value === WebInspector.settings.colorFormat) { selectedIndex = i; break; } @@ -477,7 +477,7 @@ WebInspector.StylesSidebarPane.prototype = { _changeColorFormat: function(event) { var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex]; - WebInspector.applicationSettings.colorFormat = selectedOption.value; + WebInspector.settings.colorFormat = selectedOption.value; for (var pseudoId in this.sections) { var sections = this.sections[pseudoId]; @@ -562,15 +562,15 @@ WebInspector.ComputedStyleSidebarPane = function() var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited"), "sidebar-pane-subtitle"); this.titleElement.appendChild(showInheritedCheckbox.element); - if (WebInspector.applicationSettings.showInheritedComputedStyleProperties) { + if (WebInspector.settings.showInheritedComputedStyleProperties) { this.bodyElement.addStyleClass("show-inherited"); showInheritedCheckbox.checked = true; } function showInheritedToggleFunction(event) { - WebInspector.applicationSettings.showInheritedComputedStyleProperties = showInheritedCheckbox.checked; - if (WebInspector.applicationSettings.showInheritedComputedStyleProperties) + WebInspector.settings.showInheritedComputedStyleProperties = showInheritedCheckbox.checked; + if (WebInspector.settings.showInheritedComputedStyleProperties) this.bodyElement.addStyleClass("show-inherited"); else this.bodyElement.removeStyleClass("show-inherited"); @@ -1010,8 +1010,9 @@ WebInspector.BlankStylePropertiesSection.prototype = { editingSelectorCommitted: function(element, newContent, oldContent, context) { var self = this; - function successCallback(styleRule, doesSelectorAffectSelectedNode) + function successCallback(newRule, doesSelectorAffectSelectedNode) { + var styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, sourceURL: newRule.sourceURL, rule: newRule }; self.makeNormal(styleRule); if (!doesSelectorAffectSelectedNode) { @@ -1200,9 +1201,9 @@ WebInspector.StylePropertyTreeElement.prototype = { var format; if (Preferences.showColorNicknames && color.nickname) format = "nickname"; - else if (WebInspector.applicationSettings.colorFormat === "rgb") + else if (WebInspector.settings.colorFormat === "rgb") format = (color.simple ? "rgb" : "rgba"); - else if (WebInspector.applicationSettings.colorFormat === "hsl") + else if (WebInspector.settings.colorFormat === "hsl") format = (color.simple ? "hsl" : "hsla"); else if (color.simple) format = (color.hasShortHex() ? "shorthex" : "hex"); diff --git a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js index 11b0e03..44063a3 100644 --- a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js +++ b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js @@ -39,7 +39,7 @@ WebInspector.WatchExpressionsSidebarPane.prototype = { { this.bodyElement.removeChildren(); - this.expanded = WebInspector.applicationSettings.watchExpressions.length > 0; + this.expanded = WebInspector.settings.watchExpressions.length > 0; this.section = new WebInspector.WatchExpressionsSection(); this.bodyElement.appendChild(this.section.element); @@ -77,7 +77,7 @@ WebInspector.WatchExpressionsSection = function() WebInspector.ObjectPropertiesSection.call(this); - this.watchExpressions = WebInspector.applicationSettings.watchExpressions; + this.watchExpressions = WebInspector.settings.watchExpressions; this.headerElement.className = "hidden"; this.editable = true; @@ -181,7 +181,7 @@ WebInspector.WatchExpressionsSection.prototype = { if (this.watchExpressions[i]) toSave.push(this.watchExpressions[i]); - WebInspector.applicationSettings.watchExpressions = toSave; + WebInspector.settings.watchExpressions = toSave; return toSave.length; } } diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc index 481f8b3..ebdd4f6 100644 --- a/WebCore/inspector/front-end/WebKit.qrc +++ b/WebCore/inspector/front-end/WebKit.qrc @@ -41,6 +41,7 @@ <file>ExtensionPanel.js</file> <file>ExtensionRegistryStub.js</file> <file>ExtensionServer.js</file> + <file>FileSystemView.js</file> <file>FontView.js</file> <file>GoToLineDialog.js</file> <file>HAREntry.js</file> @@ -70,7 +71,6 @@ <file>Resource.js</file> <file>ResourceCategory.js</file> <file>ResourceManager.js</file> - <file>ResourcesPanel.js</file> <file>ResourceView.js</file> <file>ScopeChainSidebarPane.js</file> <file>Script.js</file> @@ -167,7 +167,6 @@ <file>Images/goArrow.png</file> <file>Images/graphLabelCalloutLeft.png</file> <file>Images/graphLabelCalloutRight.png</file> - <file>Images/grayConnectorPoint.png</file> <file>Images/largerResourcesButtonGlyph.png</file> <file>Images/localStorage.png</file> <file>Images/networkIcon.png</file> @@ -198,7 +197,6 @@ <file>Images/resourcePlainIcon.png</file> <file>Images/resourcePlainIconSmall.png</file> <file>Images/resourcesIcon.png</file> - <file>Images/resourcesSilhouette.png</file> <file>Images/resourcesSizeGraphIcon.png</file> <file>Images/resourcesTimeGraphIcon.png</file> <file>Images/scriptsIcon.png</file> @@ -273,7 +271,6 @@ <file>Images/warningMediumIcon.png</file> <file>Images/warningOrangeDot.png</file> <file>Images/warningsErrors.png</file> - <file>Images/whiteConnectorPoint.png</file> <file alias="DebuggerScript.js">../../bindings/v8/DebuggerScript.js</file> </qresource> </RCC> diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css index 429e749..b26b748 100644 --- a/WebCore/inspector/front-end/inspector.css +++ b/WebCore/inspector/front-end/inspector.css @@ -508,7 +508,7 @@ body.drawer-visible #drawer { } .monospace { - font-size: 10px; + font-size: 10px !important; font-family: monospace; } @@ -519,17 +519,17 @@ body.platform-mac .monospace, body.platform-mac .source-code { /* Keep .platform-mac to make the rule more specific than the general one above. */ body.platform-mac.platform-mac-snowleopard .monospace, body.platform-mac.platform-mac-snowleopard .source-code { - font-size: 11px; + font-size: 11px !important; font-family: Menlo, monospace; } body.platform-windows .monospace, body.platform-windows .source-code { - font-size: 12px; + font-size: 12px !important; font-family: Consolas, Lucida Console, monospace; } body.platform-linux .monospace, body.platform-linux .source-code { - font-size: 11px; + font-size: 11px !important; font-family: dejavu sans mono, monospace; } @@ -1176,7 +1176,7 @@ body.platform-linux .monospace, body.platform-linux .source-code { .source-code { font-family: monospace; - font-size: 10px; + font-size: 10px !important; white-space: pre-wrap; } @@ -1311,26 +1311,21 @@ body.inactive .placard.selected { margin-top: 1px; } -.section:nth-last-of-type(1), .event-bar:nth-last-of-type(1) { - margin-bottom: 1px; -} - .watch-expressions-buttons-container { text-align: center; } -.event-bar:first-child { - margin-top: 1px; +.events-pane .section:not(:nth-of-type(1)) { + border-top: 1px solid rgb(191, 191, 191); } -.event-bar:nth-last-of-type(1) .header { - border-bottom: 1px solid rgb(163, 163, 163); +.event-bar:first-child { + margin-top: 1px; } .section .header { - padding: 2px 8px 4px 18px; - border-top: 1px solid rgb(145, 160, 192); - background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177))); + color: black; + padding: 0 8px 0 18px; min-height: 18px; white-space: nowrap; -webkit-background-origin: padding; @@ -1339,22 +1334,23 @@ body.inactive .placard.selected { .section .header::before { position: absolute; - top: 4px; + top: 2px; left: 7px; width: 8px; height: 8px; - content: url(Images/treeRightTriangleWhite.png); + content: url(Images/treeRightTriangleBlack.png); + opacity: 0.8; } .section.expanded .header::before { - content: url(Images/treeDownTriangleWhite.png); + content: url(Images/treeDownTriangleBlack.png); } .section .header .title, .event-bar .header .title { - color: white; - font-weight: bold; + font-weight: normal; word-wrap: break-word; white-space: normal; + line-height: 18px; } .section .header .title.blank-title { @@ -1371,10 +1367,8 @@ body.inactive .placard.selected { .section .header .subtitle, .event-bar .header .subtitle { float: right; - font-size: 10px; margin-left: 5px; max-width: 55%; - color: rgba(255, 255, 255, 0.7); text-overflow: ellipsis; overflow: hidden; } @@ -1389,6 +1383,7 @@ body.inactive .placard.selected { .section.expanded .properties, .event-bar.expanded .event-properties { display: block; + padding-left: 16px; } .section.no-affect .properties li { @@ -1401,7 +1396,7 @@ body.inactive .placard.selected { .properties-tree { margin: 0; - padding: 2px 6px 3px; + padding: 0 6px 2px; list-style: none; min-height: 18px; } @@ -1453,19 +1448,23 @@ body.inactive .placard.selected { } .event-listener-breakpoints .event-category { - font-size: 12px; + font-size: 11px; font-weight: bold; - color: rgb(110, 110, 110); + color: rgb(96, 96, 96); + padding-top: 2px; } .event-listener-breakpoints.properties-tree .children li { - margin-left: 17px; + margin-left: 12px; + height: 16px; } .event-listener-breakpoints .checkbox-elem { + font-size: 10px; float: left; - margin-top: 1px; - margin-left: 0px; + top: -2px; + position: relative; + left: -1px; } .section .event-bars { @@ -1478,38 +1477,21 @@ body.inactive .placard.selected { .event-bar { position: relative; -} - -.event-bar-connector { - position: absolute; - left: 75%; - bottom: -7px; - margin-left: -7px; - content: url(Images/grayConnectorPoint.png); - z-index: 3; -} - -.event-bar.expanded .event-bar-connector { - content: url(Images/whiteConnectorPoint.png); + left: 10px; } .event-bars .event-bar .header { - padding: 2px 8px 4px 18px; - border-top: 1px solid rgb(163, 163, 163); - background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(243, 243, 243)), to(rgb(207, 207, 207))); - min-height: 18px; + padding: 0 8px 0 18px; + min-height: 16px; + opacity: 1.0; white-space: nowrap; -webkit-background-origin: padding; -webkit-background-clip: padding; } -.event-bars .event-bar.expanded .header { - border-bottom: 1px solid rgb(163, 163, 163); -} - .event-bars .event-bar .header .title { - font-weight: bold; - color: #333; + font-weight: normal; + color: black; text-shadow: white 0 1px 0; } @@ -1519,7 +1501,7 @@ body.inactive .placard.selected { .event-bars .event-bar .header::before { position: absolute; - top: 4px; + top: 2px; left: 7px; width: 8px; height: 8px; @@ -1744,11 +1726,12 @@ li.editing .swatch, li.editing .enabled-button, li.editing-sub-part .delete-but font-style: italic; font-size: 10px; padding: 6px; - color: gray; + color: black; } .pane > .body .placard + .info { - border-top: 1px solid gray + border-top: 1px solid rgb(189, 189, 189); + background-color: rgb(255, 255, 194); } .pane.expanded > .body, .pane.expanded > .growbar { @@ -1932,6 +1915,11 @@ body.inactive .sidebar { content: url(Images/applicationCache.png); } +/* FIXME: Make separate png for file-system */ +.file-system-storage-tree-item .icon { + content: url(Images/applicationCache.png); +} + #storage-views { position: absolute; top: 0; @@ -1963,18 +1951,18 @@ body.inactive .sidebar { font-weight: bold; } -.storage.panel .sidebar li .selection { +.storage.panel .sidebar li.selected .selection { background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177))); border-top: 1px solid #979797; height: 17px; } -.storage.panel .sidebar :focus li .selection { +.storage.panel .sidebar :focus li.selected .selection { background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170))); border-top: 1px solid rgb(68, 128, 200); } -body.inactive .storage.panel .sidebar li .selection { +body.inactive .storage.panel .sidebar li.selected .selection { background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138))); border-top: 1px solid rgb(151, 151, 151); } @@ -1993,6 +1981,16 @@ body.inactive .storage.panel .sidebar li .selection { top: 1px; } +li.selected .base-storage-tree-element-subtitle { + color: white; +} + +.base-storage-tree-element-subtitle { + padding-left: 2px; + color: rgb(80, 80, 80); + text-shadow: none; +} + .storage.panel .status { float: right; height: 16px; @@ -2494,10 +2492,6 @@ body.inactive .panel-enabler-view button:not(.status-bar-item), .panel-enabler-v -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223))); } -.panel-enabler-view.resources img { - content: url(Images/resourcesSilhouette.png); -} - .panel-enabler-view.scripts img { content: url(Images/scriptsSilhouette.png); } @@ -2677,8 +2671,8 @@ button.enable-toggle-status-bar-item.toggled-on .glyph { background: transparent; text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0; vertical-align: middle; - padding: 1px 7px 2px; - height: 18px; + padding: 3px 7px 2px; + height: 21px; border: 1px solid transparent; border-bottom: none; } @@ -4095,7 +4089,7 @@ button.enable-toggle-status-bar-item .glyph { } ol.breakpoint-list { - -webkit-padding-start: 2px; + -webkit-padding-start: 0; list-style: none; margin: 0; } @@ -4104,9 +4098,8 @@ ol.breakpoint-list { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; - margin: 4px 0; - color: rgb(33%, 33%, 33%); - cursor: pointer; + padding: 2px 0; + color: black; } .breakpoint-list li:hover { @@ -4128,8 +4121,8 @@ ol.breakpoint-list { margin: 2px 0 0px 20px; } -.breakpoint-list .breakpoint-hit { - background-color: yellow; +.pane .breakpoint-hit { + background-color: rgb(255, 255, 194); } .webkit-html-js-node, .webkit-html-css-node { @@ -4391,3 +4384,11 @@ a.worker-item:hover { text-decoration: underline; cursor: pointer; } + +.cursor-pointer { + cursor: pointer; +} + +.cursor-auto { + cursor: auto; +}
\ No newline at end of file diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html index 96d0cfe..c681531 100644 --- a/WebCore/inspector/front-end/inspector.html +++ b/WebCore/inspector/front-end/inspector.html @@ -69,6 +69,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="DataGrid.js"></script> <script type="text/javascript" src="CookieItemsView.js"></script> <script type="text/javascript" src="ApplicationCacheItemsView.js"></script> + <script type="text/javascript" src="FileSystemView.js"></script> <script type="text/javascript" src="Script.js"></script> <script type="text/javascript" src="BreakpointManager.js"></script> <script type="text/javascript" src="SidebarPane.js"></script> @@ -95,7 +96,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="SummaryBar.js"></script> <script type="text/javascript" src="ElementsPanel.js"></script> <script type="text/javascript" src="NetworkPanel.js"></script> - <script type="text/javascript" src="ResourcesPanel.js"></script> <script type="text/javascript" src="InjectedFakeWorker.js"></script> <script type="text/javascript" src="ScriptsPanel.js"></script> <script type="text/javascript" src="StoragePanel.js"></script> diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js index f5a70c8..8323cad 100644 --- a/WebCore/inspector/front-end/inspector.js +++ b/WebCore/inspector/front-end/inspector.js @@ -50,8 +50,6 @@ var WebInspector = { resources: {}, - cookieDomains: {}, - applicationCacheDomains: {}, missingLocalizedStrings: {}, pendingDispatches: 0, @@ -181,7 +179,7 @@ var WebInspector = { for (var panelName in WebInspector.panels) { if (WebInspector.panels[panelName] === x) { - WebInspector.applicationSettings.lastActivePanel = panelName; + WebInspector.settings.lastActivePanel = panelName; this._panelHistory.setPanel(panelName); } } @@ -192,7 +190,7 @@ var WebInspector = { var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("Breakpoints")); function breakpointAdded(event) { - pane.addBreakpoint(new WebInspector.JSBreakpointItem(event.data)); + pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } WebInspector.breakpointManager.addEventListener("breakpoint-added", breakpointAdded); return pane; @@ -203,7 +201,7 @@ var WebInspector = { var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints")); function breakpointAdded(event) { - pane.addBreakpoint(new WebInspector.BreakpointItem(event.data)); + pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } WebInspector.breakpointManager.addEventListener("dom-breakpoint-added", breakpointAdded); return pane; @@ -214,7 +212,7 @@ var WebInspector = { var pane = new WebInspector.XHRBreakpointsSidebarPane(); function breakpointAdded(event) { - pane.addBreakpoint(new WebInspector.BreakpointItem(event.data)); + pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } WebInspector.breakpointManager.addEventListener("xhr-breakpoint-added", breakpointAdded); return pane; @@ -226,15 +224,9 @@ var WebInspector = { if (hiddenPanels.indexOf("elements") === -1) this.panels.elements = new WebInspector.ElementsPanel(); - if (Preferences.networkPanelEnabled) { - if (hiddenPanels.indexOf("storage") === -1 && hiddenPanels.indexOf("databases") === -1) - this.panels.storage = new WebInspector.StoragePanel(); - if (hiddenPanels.indexOf("network") === -1) - this.panels.network = new WebInspector.NetworkPanel(); - } else if (hiddenPanels.indexOf("resources") === -1) - this.panels.resources = new WebInspector.ResourcesPanel(); - - if (Preferences.networkPanelEnabled && hiddenPanels.indexOf("network") === -1) + if (hiddenPanels.indexOf("storage") === -1 && hiddenPanels.indexOf("databases") === -1) + this.panels.storage = new WebInspector.StoragePanel(); + if (hiddenPanels.indexOf("network") === -1) this.panels.network = new WebInspector.NetworkPanel(); if (hiddenPanels.indexOf("scripts") === -1) this.panels.scripts = new WebInspector.ScriptsPanel(); @@ -246,12 +238,6 @@ var WebInspector = { if (Preferences.heapProfilerPresent) this.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType()); } - - if (!Preferences.networkPanelEnabled) { - if (hiddenPanels.indexOf("storage") === -1 && hiddenPanels.indexOf("databases") === -1) - this.panels.storage = new WebInspector.StoragePanel(); - } - if (hiddenPanels.indexOf("audits") === -1) this.panels.audits = new WebInspector.AuditsPanel(); if (hiddenPanels.indexOf("console") === -1) @@ -455,29 +441,17 @@ var WebInspector = { get networkResources() { - if (Preferences.networkPanelEnabled) - return this.panels.network.resources; - else - return this.resources; + return this.panels.network.resources; }, forAllResources: function(callback) { - if (Preferences.networkPanelEnabled) - WebInspector.resourceManager.forAllResources(callback); - else { - for (var id in this.resources) { - if (callback(this.resources[id])) - return; - } - } + WebInspector.resourceManager.forAllResources(callback); }, resourceForURL: function(url) { - if (Preferences.networkPanelEnabled) - return this.resourceManager.resourceForURL(url); - return this.panels.resources.resourceURLMap[url]; + return this.resourceManager.resourceForURL(url); } } @@ -530,7 +504,7 @@ WebInspector.doLoadedDone = function() document.body.addStyleClass("port-" + port); InspectorFrontendHost.loaded(); - WebInspector.applicationSettings = new WebInspector.Settings(); + WebInspector.settings = new WebInspector.Settings(); this._registerShortcuts(); @@ -544,8 +518,7 @@ WebInspector.doLoadedDone = function() // this.changes = new WebInspector.ChangesView(this.drawer); // TODO: Remove class="hidden" from inspector.html on button#changes-status-bar-item this.drawer.visibleView = this.console; - if (Preferences.networkPanelEnabled) - this.resourceManager = new WebInspector.ResourceManager(); + this.resourceManager = new WebInspector.ResourceManager(); this.domAgent = new WebInspector.DOMAgent(); this.resourceCategories = { @@ -555,7 +528,7 @@ WebInspector.doLoadedDone = function() scripts: new WebInspector.ResourceCategory("scripts", WebInspector.UIString("Scripts"), "rgb(255,121,0)"), xhr: new WebInspector.ResourceCategory("xhr", WebInspector.UIString("XHR"), "rgb(231,231,10)"), fonts: new WebInspector.ResourceCategory("fonts", WebInspector.UIString("Fonts"), "rgb(255,82,62)"), - websocket: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSocket"), "rgb(186,186,186)"), // FIXME: Decide the color. + websockets: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSocket"), "rgb(186,186,186)"), // FIXME: Decide the color. other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)") }; @@ -573,10 +546,9 @@ WebInspector.doLoadedDone = function() for (var panelName in this.panels) previousToolbarItem = WebInspector.addPanelToolbarIcon(toolbarElement, this.panels[panelName], previousToolbarItem); - if (Preferences.networkPanelEnabled) { - this.panels.storage._toolbarItem.removeStyleClass("storage"); - this.panels.storage._toolbarItem.addStyleClass("resources"); - } + // FIXME: fix this once renamed StoragePanel.js to ResourcesPanel.js + this.panels.storage._toolbarItem.removeStyleClass("storage"); + this.panels.storage._toolbarItem.addStyleClass("resources"); this.Tips = { ResourceNotCompressed: {id: 0, message: WebInspector.UIString("You could save bandwidth by having your web server compress this transfer with gzip or zlib.")} @@ -630,19 +602,13 @@ WebInspector.doLoadedDone = function() WebInspector.monitoringXHREnabled = inspectorState.monitoringXHREnabled; if ("pauseOnExceptionsState" in inspectorState) WebInspector.panels.scripts.updatePauseOnExceptionsState(inspectorState.pauseOnExceptionsState); - if (WebInspector.panels.resources) { - if (inspectorState.resourceTrackingEnabled) - WebInspector.panels.resources.resourceTrackingWasEnabled(); - else - WebInspector.panels.resources.resourceTrackingWasDisabled(); - } } InspectorBackend.getInspectorState(populateInspectorState); function onPopulateScriptObjects() { if (!WebInspector.currentPanel) - WebInspector.showPanel(WebInspector.applicationSettings.lastActivePanel); + WebInspector.showPanel(WebInspector.settings.lastActivePanel); } InspectorBackend.populateScriptObjects(onPopulateScriptObjects); @@ -844,13 +810,8 @@ WebInspector.openResource = function(resourceURL, inResourcesPanel) { var resource = WebInspector.resourceForURL(resourceURL); if (inResourcesPanel && resource) { - if (Preferences.networkPanelEnabled) { - WebInspector.panels.storage.showResource(resource); - WebInspector.showPanel("storage"); - } else { - WebInspector.panels.resources.showResource(resource); - WebInspector.showPanel("resources"); - } + WebInspector.panels.storage.showResource(resource); + WebInspector.showPanel("storage"); } else InspectorBackend.openInInspectedWindow(resource ? resource.url : resourceURL); } @@ -1245,6 +1206,10 @@ WebInspector.showChanges = function() WebInspector.showPanel = function(panel) { + // FIXME: fix this once renamed StoragePanel.js to ResourcesPanel.js + if (panel === "resources") + panel = "storage"; + if (!(panel in this.panels)) panel = "elements"; this.currentPanel = this.panels[panel]; @@ -1267,85 +1232,8 @@ WebInspector.selectDOMStorage = function(o) WebInspector.panels.storage.selectDOMStorage(o); } -WebInspector.updateResource = function(payload) -{ - if (Preferences.networkPanelEnabled) - return; - - var identifier = payload.id; - var resource = this.resources[identifier]; - if (!resource) { - resource = new WebInspector.Resource(identifier, payload.url); - this.resources[identifier] = resource; - this.panels.resources.addResource(resource); - this.panels.audits.resourceStarted(resource); - } - - if (payload.didRequestChange) { - resource.requestHeaders = payload.requestHeaders; - resource.mainResource = payload.mainResource; - resource.requestMethod = payload.requestMethod; - resource.requestFormData = payload.requestFormData; - resource.documentURL = payload.documentURL; - if (typeof payload.webSocketRequestKey3 !== "undefined") - resource.webSocketRequestKey3 = payload.webSocketRequestKey3; - - if (resource.mainResource) - this.mainResource = resource; - - var parsedURL = payload.documentURL.asParsedURL(); - if (parsedURL) { - this._addCookieDomain(parsedURL.host); - this._addAppCacheDomain(parsedURL.host); - } - } - - if (payload.didResponseChange) { - resource.mimeType = payload.mimeType; - resource.suggestedFilename = payload.suggestedFilename; - resource.expectedContentLength = payload.expectedContentLength; - resource.statusCode = payload.statusCode; - resource.statusText = payload.statusText; - resource.suggestedFilename = payload.suggestedFilename; - resource.responseHeaders = payload.responseHeaders; - resource.connectionID = payload.connectionID; - resource.connectionReused = payload.connectionReused; - resource.timing = payload.timing; - resource.cached = payload.cached; - if (typeof payload.webSocketChallengeResponse !== "undefined") - resource.webSocketChallengeResponse = payload.webSocketChallengeResponse; - } - - if (payload.didTypeChange) - resource.type = payload.type; - - if (payload.didLengthChange) - resource.resourceSize = payload.resourceSize; - - if (payload.didCompletionChange) { - resource.failed = payload.failed; - resource.localizedFailDescription = payload.localizedFailDescription; - resource.finished = payload.finished; - if (this.panels.audits) - this.panels.audits.resourceFinished(resource); - this.extensionServer.notifyResourceFinished(resource); - } - - if (payload.didTimingChange) { - if (payload.startTime) - resource.startTime = payload.startTime; - if (payload.responseReceivedTime) - resource.responseReceivedTime = payload.responseReceivedTime; - if (payload.endTime) - resource.endTime = payload.endTime; - } - this.panels.resources.refreshResource(resource); -} - WebInspector.domContentEventFired = function(time) { - if (this.panels.resources) - this.panels.resources.mainResourceDOMContentTime = time; this.panels.audits.mainResourceDOMContentTime = time; if (this.panels.network) this.panels.network.mainResourceDOMContentTime = time; @@ -1354,29 +1242,12 @@ WebInspector.domContentEventFired = function(time) WebInspector.loadEventFired = function(time) { - if (this.panels.resources) - this.panels.resources.mainResourceLoadTime = time; this.panels.audits.mainResourceLoadTime = time; if (this.panels.network) this.panels.network.mainResourceLoadTime = time; this.mainResourceLoadTime = time; } -WebInspector.removeResource = function(identifier) -{ - if (Preferences.networkPanelEnabled) - return; - - var resource = this.resources[identifier]; - if (!resource) - return; - - delete this.resources[identifier]; - - if (this.panels.resources) - this.panels.resources.removeResource(resource); -} - WebInspector.addDatabase = function(payload) { if (!this.panels.storage) @@ -1389,30 +1260,6 @@ WebInspector.addDatabase = function(payload) this.panels.storage.addDatabase(database); } -WebInspector._addCookieDomain = function(domain) -{ - // Eliminate duplicate domains from the list. - if (domain in this.cookieDomains) - return; - this.cookieDomains[domain] = true; - - if (!this.panels.storage) - return; - this.panels.storage.addCookieDomain(domain); -} - -WebInspector._addAppCacheDomain = function(domain) -{ - // Eliminate duplicate domains from the list. - if (domain in this.applicationCacheDomains) - return; - this.applicationCacheDomains[domain] = true; - - if (!this.panels.storage) - return; - this.panels.storage.addApplicationCache(domain); -} - WebInspector.addDOMStorage = function(payload) { if (!this.panels.storage) @@ -1434,6 +1281,21 @@ WebInspector.updateApplicationCacheStatus = function(status) this.panels.storage.updateApplicationCacheStatus(status); } +WebInspector.didGetFileSystemPath = function(root, type, origin) +{ + this.panels.storage.updateFileSystemPath(root, type, origin); +} + +WebInspector.didGetFileSystemError = function(type, origin) +{ + this.panels.storage.updateFileSystemError(type, origin); +} + +WebInspector.didGetFileSystemDisabled = function() +{ + this.panels.storage.setFileSystemDisabled(); +} + WebInspector.updateNetworkState = function(isNowOnline) { this.panels.storage.updateNetworkState(isNowOnline); @@ -1491,7 +1353,7 @@ WebInspector.failedToParseScriptSource = function(sourceURL, source, startingLin WebInspector.pausedScript = function(details) { - this.panels.scripts.debuggerPaused(details); + this.panels.scripts.debuggerPaused(details.callFrames); this.breakpointManager.debuggerPaused(details); InspectorFrontendHost.bringToFront(); } @@ -1513,15 +1375,12 @@ WebInspector.reset = function() } this.resources = {}; - this.cookieDomains = {}; - this.applicationCacheDomains = {}; this.highlightDOMNode(0); - if (!Preferences.networkPanelEnabled) - delete this.mainResource; - this.console.clearMessages(); this.extensionServer.notifyInspectorReset(); + + this.breakpointManager.restoreBreakpoints(); } WebInspector.resetProfilesPanel = function() @@ -1538,7 +1397,12 @@ WebInspector.bringToFront = function() WebInspector.inspectedURLChanged = function(url) { InspectorFrontendHost.inspectedURLChanged(url); + this.settings.inspectedURLChanged(url); this.extensionServer.notifyInspectedURLChanged(); + if (!this._breakpointsRestored) { + this.breakpointManager.restoreBreakpoints(); + this._breakpointsRestored = true; + } } WebInspector.didCommitLoad = function() @@ -1669,7 +1533,7 @@ WebInspector.addProfileHeader = function(profile) WebInspector.setRecordingProfile = function(isProfiling) { this.panels.profiles.getProfileType(WebInspector.CPUProfileType.TypeId).setRecordingProfile(isProfiling); - if (this._previousIsProfiling !== isProfiling) { + if (this.panels.profiles.hasTemporaryProfile(WebInspector.CPUProfileType.TypeId) !== isProfiling) { if (!this._temporaryRecordingProfile) { this._temporaryRecordingProfile = { typeId: WebInspector.CPUProfileType.TypeId, @@ -1678,7 +1542,6 @@ WebInspector.setRecordingProfile = function(isProfiling) isTemporary: true }; } - this._previousIsProfiling = isProfiling; if (isProfiling) this.panels.profiles.addProfileHeader(this._temporaryRecordingProfile); else @@ -1749,13 +1612,14 @@ WebInspector.displayNameForURL = function(url) WebInspector._choosePanelToShowSourceLine = function(url, line, preferredPanel) { preferredPanel = preferredPanel || "resources"; - if (Preferences.networkPanelEnabled && preferredPanel === "resources") + // FIXME: remove this once StoragePanel renamed to ResourcesPanel + if (preferredPanel === "resources") preferredPanel = "storage"; var panel = this.panels[preferredPanel]; if (panel && panel.canShowSourceLine(url, line)) return panel; - panel = Preferences.networkPanelEnabled ? this.panels.storage : this.panels.resources; + panel = this.panels.storage; return panel.canShowSourceLine(url, line) ? panel : null; } @@ -1777,6 +1641,7 @@ WebInspector.linkifyStringAsFragment = function(string) { var container = document.createDocumentFragment(); var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|www\.)[\w$\-_+*'=\|\/\\(){}[\]%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({%@&#~]/; + var lineColumnRegEx = /:(\d+)(:(\d+))?$/; while (string) { var linkString = linkStringRegEx.exec(string); @@ -1794,8 +1659,17 @@ WebInspector.linkifyStringAsFragment = function(string) title = WebInspector.panels.profiles.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]); var realURL = (linkString.indexOf("www.") === 0 ? "http://" + linkString : linkString); + var lineColumnMatch = lineColumnRegEx.exec(realURL); + if (lineColumnMatch) + realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length); + var hasResourceWithURL = !!WebInspector.resourceForURL(realURL); - container.appendChild(WebInspector.linkifyURLAsNode(realURL, title, null, hasResourceWithURL)); + var urlNode = WebInspector.linkifyURLAsNode(realURL, title, null, hasResourceWithURL); + container.appendChild(urlNode); + if (lineColumnMatch) { + urlNode.setAttribute("line_number", lineColumnMatch[1]); + urlNode.setAttribute("preferred_panel", "scripts"); + } string = string.substring(linkIndex + linkString.length, string.length); } diff --git a/WebCore/inspector/front-end/networkPanel.css b/WebCore/inspector/front-end/networkPanel.css index 215681f..1e0e813 100644 --- a/WebCore/inspector/front-end/networkPanel.css +++ b/WebCore/inspector/front-end/networkPanel.css @@ -2,7 +2,7 @@ -webkit-mask-image: url(Images/largerResourcesButtonGlyph.png); } -.network.panel .data-grid { +.network-sidebar .data-grid { border: none; position: absolute; top: 0; @@ -12,17 +12,17 @@ font-size: 11px; } -.network.panel .data-grid table.data { +.network-sidebar .data-grid table.data { -webkit-background-size: 1px 82px; background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), color-stop(0.5, rgba(0, 0, 0, 0)), color-stop(0.5, rgba(0, 0, 0, 0.05)), to(rgba(0, 0, 0, 0.05))); font-size: 11px; } -.network.panel .data-grid.small table.data { +.network-sidebar .data-grid.small table.data { -webkit-background-size: 1px 42px; } -.network.panel .data-grid td { +.network-sidebar .data-grid td:not(.network-summary) { line-height: 17px; height: 37px; border-right: 1px solid rgb(210, 210, 210); @@ -30,34 +30,34 @@ vertical-align: middle; } -.network.panel .data-grid.small td { +.network-sidebar .data-grid.small td { height: 17px; } -.network.panel .data-grid th { +.network-sidebar .data-grid th { border-bottom: 1px solid rgb(64%, 64%, 64%); height: 30px; font-size: 11px; font-weight: bold; } -.network.panel .data-grid.small th { +.network-sidebar .data-grid.small th { height: 22px; } -.network.panel .data-grid th, .network.panel .data-grid th.sort-descending, .network.panel .data-grid th.sort-ascending { +.network-sidebar .data-grid th, .network.panel .data-grid th.sort-descending, .network.panel .data-grid th.sort-ascending { background: -webkit-gradient(linear, left top, left bottom, from(rgb(236, 236, 236)), to(rgb(217, 217, 217))); } -.network.panel .data-grid .data-container { +.network-sidebar .data-grid .data-container { top: 31px; } -.network.panel .data-grid.small .data-container { +.network-sidebar .data-grid.small .data-container { top: 23px; } -.network.panel .data-grid select { +.network-sidebar .data-grid select { -webkit-appearance: none; background-color: transparent; border: none; @@ -66,32 +66,32 @@ font-weight: bold; } -.network.panel .data-grid tr.filler { +.network-sidebar .data-grid tr.filler { background-color: white; } -.network.panel .data-grid td.name-column { +.network-sidebar .data-grid td.name-column { font-weight: bold; } -.network.panel .data-grid td.method-column, -.network.panel .data-grid td.status-column, -.network.panel .data-grid td.type-column, -.network.panel .data-grid td.size-column, -.network.panel .data-grid td.time-column { +.network-sidebar .data-grid td.method-column, +.network-sidebar .data-grid td.status-column, +.network-sidebar .data-grid td.type-column, +.network-sidebar .data-grid td.size-column, +.network-sidebar .data-grid td.time-column { background-color: rgba(0, 0, 0, 0.07); } -.network.panel .data-grid td.size-column, -.network.panel .data-grid td.time-column { +.network-sidebar .data-grid td.size-column, +.network-sidebar .data-grid td.time-column { text-align: right; } -.network.panel .small .network-graph-side { +.network-sidebar .small .network-graph-side { height: 14px; } -.network.panel .data-grid th.sortable:active { +.network-sidebar .data-grid th.sortable:active { background-image: none; } @@ -104,66 +104,66 @@ color: grey; } -.network.panel .data-grid.small .network-cell-subtitle, -.network.panel .data-grid.small .network-header-subtitle +.network-sidebar .data-grid.small .network-cell-subtitle, +.network-sidebar .data-grid.small .network-header-subtitle { display: none; } /* Resource preview icons */ -.network.panel .data-grid .icon { +.network-sidebar .data-grid .icon { content: url(Images/resourcePlainIcon.png); } -.network.panel .data-grid.small .icon { +.network-sidebar .data-grid.small .icon { content: url(Images/resourcePlainIconSmall.png); } -.network.panel .network-category-scripts .icon { +.network-sidebar .network-category-scripts .icon { content: url(Images/resourceJSIcon.png); } -.network.panel .data-grid.small .network-category-scripts .icon { +.network-sidebar .data-grid.small .network-category-scripts .icon { content: url(Images/resourceDocumentIconSmall.png); } -.network.panel .network-category-documents .icon { +.network-sidebar .network-category-documents .icon { content: url(Images/resourceDocumentIcon.png); } -.network.panel .data-grid.small .network-category-documents .icon { +.network-sidebar .data-grid.small .network-category-documents .icon { content: url(Images/resourceDocumentIconSmall.png); } -.network.panel .network-category-stylesheets .icon { +.network-sidebar .network-category-stylesheets .icon { content: url(Images/resourceCSSIcon.png); } -.network.panel .data-grid.small .network-category-stylesheets .icon { +.network-sidebar .data-grid.small .network-category-stylesheets .icon { content: url(Images/resourceDocumentIconSmall.png); } -.network.panel .network-category-images .icon { +.network-sidebar .network-category-images .icon { position: relative; background-image: url(Images/resourcePlainIcon.png); background-repeat: no-repeat; content: ""; } -.network.panel .network-category-images .icon { +.network-sidebar .network-category-images .icon { position: relative; background-image: url(Images/resourcePlainIcon.png); background-repeat: no-repeat; content: ""; } -.network.panel .data-grid.small .network-category-images .icon { +.network-sidebar .data-grid.small .network-category-images .icon { background-image: url(Images/resourcePlainIconSmall.png); content: ""; } -.network.panel .data-grid .icon { +.network-sidebar .data-grid .icon { float: left; width: 32px; height: 32px; @@ -171,12 +171,12 @@ margin-right: 3px; } -.network.panel .data-grid.small .icon { +.network-sidebar .data-grid.small .icon { width: 16px; height: 16px; } -.network.panel .image-network-icon-preview { +.network-sidebar .image-network-icon-preview { position: absolute; margin: auto; top: 3px; @@ -189,7 +189,7 @@ min-height: 1px; } -.network.panel .data-grid.small .image-network-icon-preview { +.network-sidebar .data-grid.small .image-network-icon-preview { top: 2px; bottom: 1px; left: 3px; @@ -407,7 +407,7 @@ z-index: 300; } -.network.panel .network-timeline-grid.small .network-event-divider { +.network-sidebar .network-timeline-grid.small .network-event-divider { top: 23px; } @@ -419,40 +419,40 @@ background-color: rgba(0, 0, 255, 0.5); } -.network.panel .resources-dividers { +.network-sidebar .resources-dividers { z-index: 0; } -.network.panel .resources-dividers-label-bar { +.network-sidebar .resources-dividers-label-bar { background-color: transparent; border: none; height: 30px; pointer-events: none; } -.network.panel .network-timeline-grid.small .resources-dividers-label-bar { +.network-sidebar .network-timeline-grid.small .resources-dividers-label-bar { height: 23px; } -.network.panel .resources-divider-label { +.network-sidebar .resources-divider-label { top: 0px; margin-top: -4px; color: black; } -.network.panel .resources-dividers-label-bar .resources-divider { +.network-sidebar .resources-dividers-label-bar .resources-divider { top: 23px; } -.network.panel .network-timeline-grid.small .resources-dividers-label-bar .resources-divider { +.network-sidebar .network-timeline-grid.small .resources-dividers-label-bar .resources-divider { top: 15px; } -.network.panel .resources-divider.first .resources-divider-label { +.network-sidebar .resources-divider.first .resources-divider-label { display: none; } -.network.panel .resources-dividers-label-bar .resources-divider.first { +.network-sidebar .resources-dividers-label-bar .resources-divider.first { background-color: transparent; } @@ -487,10 +487,12 @@ height: 20px; font-size: 11px; font-weight: bold; - padding-top: 1px; + padding-top: 3px; padding-left: 10px; z-index: 2000; white-space: pre; + overflow : hidden; + text-overflow : ellipsis; } .network-summary-bar-bottom { @@ -505,14 +507,14 @@ white-space: pre; } -.network.panel .data-grid td.network-summary { +.network-sidebar .data-grid td.network-summary { padding: 0; } /* Viewer */ -.network.panel.viewing-resource .data-grid td, -.network.panel.viewing-resource .data-grid th { +.network.panel.viewing-resource .network-sidebar .data-grid td, +.network.panel.viewing-resource .network-sidebar .data-grid th { border-right: none; } @@ -544,7 +546,7 @@ left: 0; } -.network-close-button { +#network-close-button { position: absolute; width: 14px; height: 14px; @@ -552,21 +554,39 @@ background-position: 0 0; background-color: transparent; border: 0 none transparent; - top: 4px; - right: 5px; + top: 8px; + left: 5px; z-index: 10; + display: none; +} + +#network-views.small #network-close-button { + top: 4px; +} + +#network-close-button:hover { + background-position: 14px 0; +} + +#network-close-button:active { + background-position: 28px 0; } -.network.panel .data-grid.full-grid-mode .viewer-column { +.network.panel.viewing-resource #network-close-button { + display: block; +} + + +.network-sidebar .data-grid.full-grid-mode .viewer-column { display: none; } -.network.panel .data-grid.brief-grid-mode .viewer-column, -.network.panel .data-grid.brief-grid-mode .method-column, -.network.panel .data-grid.brief-grid-mode .status-column, -.network.panel .data-grid.brief-grid-mode .type-column, -.network.panel .data-grid.brief-grid-mode .size-column, -.network.panel .data-grid.brief-grid-mode .time-column { +.network-sidebar .data-grid.brief-grid-mode .viewer-column, +.network-sidebar .data-grid.brief-grid-mode .method-column, +.network-sidebar .data-grid.brief-grid-mode .status-column, +.network-sidebar .data-grid.brief-grid-mode .type-column, +.network-sidebar .data-grid.brief-grid-mode .size-column, +.network-sidebar .data-grid.brief-grid-mode .time-column { display: none; } @@ -574,12 +594,12 @@ display: none; } -.network.panel .data-grid.viewing-resource-mode .method-column, -.network.panel .data-grid.viewing-resource-mode .status-column, -.network.panel .data-grid.viewing-resource-mode .type-column, -.network.panel .data-grid.viewing-resource-mode .size-column, -.network.panel .data-grid.viewing-resource-mode .time-column, -.network.panel .data-grid.viewing-resource-mode .timeline-column { +.network-sidebar .data-grid.viewing-resource-mode .method-column, +.network-sidebar .data-grid.viewing-resource-mode .status-column, +.network-sidebar .data-grid.viewing-resource-mode .type-column, +.network-sidebar .data-grid.viewing-resource-mode .size-column, +.network-sidebar .data-grid.viewing-resource-mode .time-column, +.network-sidebar .data-grid.viewing-resource-mode .timeline-column { display: none; } @@ -595,7 +615,7 @@ display: none; } -.network.panel.viewing-resource .data-grid-resizer { +.network.panel.viewing-resource .network-sidebar .data-grid-resizer { display: none; } @@ -604,19 +624,17 @@ padding-top: 5px; } -#network-views .resource-view.headers-visible .resource-view-content { - top: 31px; -} - -#network-views.small .resource-view.headers-visible .resource-view-content { - top: 23px; -} - -#network-views .resource-view-headers { +#network-views .resource-view-headers, +#network-views .resource-view-content, +#network-views .resource-view-cookies +{ top: 31px; } -#network-views.small .resource-view-headers { +#network-views.small .resource-view-headers, +#network-views.small .resource-view-content, +#network-views.small .resource-view-cookies +{ top: 23px; } @@ -627,12 +645,13 @@ #network-views .resource-view .tabbed-pane-header { height: 31px; - padding-top: 11px; + padding-top: 8px; + padding-left: 25px; } #network-views.small .resource-view .tabbed-pane-header { height: 23px; - padding-top: 3px; + padding-top: 0; } .network.panel.viewing-resource .data-grid .data-container { diff --git a/WebCore/loader/DocumentLoader.cpp b/WebCore/loader/DocumentLoader.cpp index 5707530..0836805 100644 --- a/WebCore/loader/DocumentLoader.cpp +++ b/WebCore/loader/DocumentLoader.cpp @@ -500,7 +500,7 @@ PassRefPtr<ArchiveResource> DocumentLoader::mainResource() const if (!mainResourceBuffer) mainResourceBuffer = SharedBuffer::create(); - return ArchiveResource::create(mainResourceBuffer, r.url(), r.mimeType(), r.textEncodingName(), frame()->tree()->name()); + return ArchiveResource::create(mainResourceBuffer, r.url(), r.mimeType(), r.textEncodingName(), frame()->tree()->uniqueName()); } PassRefPtr<ArchiveResource> DocumentLoader::subresource(const KURL& url) const diff --git a/WebCore/loader/EmptyClients.h b/WebCore/loader/EmptyClients.h index 59be8b1..3a5e0e9 100644 --- a/WebCore/loader/EmptyClients.h +++ b/WebCore/loader/EmptyClients.h @@ -106,6 +106,7 @@ public: virtual void takeFocus(FocusDirection) { } virtual void focusedNodeChanged(Node*) { } + virtual void focusedFrameChanged(Frame*) { } virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&) { return 0; } virtual void show() { } @@ -143,6 +144,10 @@ public: virtual PassRefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const { return adoptRef(new EmptyPopupMenu()); } virtual PassRefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const { return adoptRef(new EmptySearchPopupMenu()); } +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif + virtual void setStatusbarText(const String&) { } virtual bool tabsToLinks() const { return false; } @@ -153,6 +158,9 @@ public: virtual void invalidateContentsAndWindow(const IntRect&, bool) { } virtual void invalidateContentsForSlowScroll(const IntRect&, bool) {}; virtual void scroll(const IntSize&, const IntRect&, const IntRect&) { } +#if ENABLE(TILED_BACKING_STORE) + virtual void delegatedScrollRequested(const IntSize&) { } +#endif virtual IntPoint screenToWindow(const IntPoint& p) const { return p; } virtual IntRect windowToScreen(const IntRect& r) const { return r; } @@ -479,9 +487,9 @@ public: #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) virtual void checkTextOfParagraph(const UChar*, int, uint64_t, Vector<TextCheckingResult>&) { }; #endif -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - virtual void showCorrectionPanel(const FloatRect&, const String&, const String&, Editor*) { } - virtual void dismissCorrectionPanel(bool) { } +#if SUPPORT_AUTOCORRECTION_PANEL + virtual void showCorrectionPanel(CorrectionPanelInfo::PanelType, const FloatRect&, const String&, const String&, Editor*) { } + virtual void dismissCorrectionPanel(CorrectionWasRejectedOrNot) { } virtual bool isShowingCorrectionPanel() { return false; } #endif virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail&) { } diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp index 8a2adee..e4a6513 100644 --- a/WebCore/loader/FrameLoader.cpp +++ b/WebCore/loader/FrameLoader.cpp @@ -37,15 +37,19 @@ #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size #include "Archive.h" #include "ArchiveFactory.h" +<<<<<<< HEAD #endif #include "BackForwardList.h" +======= +#include "BackForwardController.h" +>>>>>>> webkit.org at r71558 #include "BeforeUnloadEvent.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedPage.h" +#include "CachedResourceLoader.h" #include "Chrome.h" #include "DOMImplementation.h" #include "DOMWindow.h" -#include "CachedResourceLoader.h" #include "Document.h" #include "DocumentLoadTiming.h" #include "DocumentLoader.h" @@ -65,9 +69,6 @@ #include "FrameView.h" #include "HTMLAnchorElement.h" #include "HTMLFormElement.h" -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) -#include "HTMLMediaElement.h" -#endif #include "HTMLNames.h" #include "HTMLObjectElement.h" #include "HTTPParsers.h" @@ -82,7 +83,6 @@ #include "PageCache.h" #include "PageGroup.h" #include "PageTransitionEvent.h" -#include "PlaceholderDocument.h" #include "PluginData.h" #include "PluginDatabase.h" #include "PluginDocument.h" @@ -104,6 +104,10 @@ #include <wtf/text/CString.h> #include <wtf/text/StringConcatenate.h> +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) +#include "HTMLMediaElement.h" +#endif + #if ENABLE(SHARED_WORKERS) #include "SharedWorkerRepository.h" #endif @@ -937,7 +941,7 @@ void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer, // If we're moving in the back/forward list, we might want to replace the content // of this child frame with whatever was there at that point. if (parentItem && parentItem->children().size() && isBackForwardLoadType(loadType)) { - HistoryItem* childItem = parentItem->childItemWithTarget(childFrame->tree()->name()); + HistoryItem* childItem = parentItem->childItemWithTarget(childFrame->tree()->uniqueName()); if (childItem) { // Use the original URL to ensure we get all the side-effects, such as // onLoad handlers, of any redirects that happened. An example of where @@ -948,8 +952,12 @@ void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer, } } +<<<<<<< HEAD #if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size RefPtr<Archive> subframeArchive = activeDocumentLoader()->popArchiveForSubframe(childFrame->tree()->name()); +======= + RefPtr<Archive> subframeArchive = activeDocumentLoader()->popArchiveForSubframe(childFrame->tree()->uniqueName()); +>>>>>>> webkit.org at r71558 if (subframeArchive) childFrame->loader()->loadArchive(subframeArchive.release()); @@ -1851,7 +1859,7 @@ void FrameLoader::commitProvisionalLoad() RefPtr<CachedPage> cachedPage = m_loadingFromCachedPage ? pageCache()->get(history()->provisionalItem()) : 0; RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader; - LOG(PageCache, "WebCoreLoading %s: About to commit provisional load from previous URL '%s' to new URL '%s'", m_frame->tree()->name().string().utf8().data(), m_URL.string().utf8().data(), + LOG(PageCache, "WebCoreLoading %s: About to commit provisional load from previous URL '%s' to new URL '%s'", m_frame->tree()->uniqueName().string().utf8().data(), m_URL.string().utf8().data(), pdl ? pdl->url().string().utf8().data() : "<no provisional DocumentLoader>"); // Check to see if we need to cache the page we are navigating away from into the back/forward cache. @@ -1899,7 +1907,7 @@ void FrameLoader::commitProvisionalLoad() didOpenURL(url); } - LOG(Loading, "WebCoreLoading %s: Finished committing provisional load to URL %s", m_frame->tree()->name().string().utf8().data(), m_URL.string().utf8().data()); + LOG(Loading, "WebCoreLoading %s: Finished committing provisional load to URL %s", m_frame->tree()->uniqueName().string().utf8().data(), m_URL.string().utf8().data()); if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isClientRedirect()) history()->updateForClientRedirect(); @@ -1972,30 +1980,28 @@ void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage) case FrameLoadTypeBack: case FrameLoadTypeBackWMLDeckNotAccessible: case FrameLoadTypeIndexedBackForward: - if (Page* page = m_frame->page()) { - if (page->backForwardList()) { - // If the first load within a frame is a navigation within a back/forward list that was attached - // without any of the items being loaded then we need to update the history in a similar manner as - // for a standard load with the exception of updating the back/forward list (<rdar://problem/8091103>). - if (!m_stateMachine.committedFirstRealDocumentLoad()) - history()->updateForStandardLoad(HistoryController::UpdateAllExceptBackForwardList); - - history()->updateForBackForwardNavigation(); - - // For cached pages, CachedFrame::restore will take care of firing the popstate event with the history item's state object - if (history()->currentItem() && !cachedPage) - m_pendingStateObject = history()->currentItem()->stateObject(); - - // Create a document view for this document, or used the cached view. - if (cachedPage) { - DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader(); - ASSERT(cachedDocumentLoader); - cachedDocumentLoader->setFrame(m_frame); - m_client->transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame()); - - } else - m_client->transitionToCommittedForNewPage(); - } + if (m_frame->page()) { + // If the first load within a frame is a navigation within a back/forward list that was attached + // without any of the items being loaded then we need to update the history in a similar manner as + // for a standard load with the exception of updating the back/forward list (<rdar://problem/8091103>). + if (!m_stateMachine.committedFirstRealDocumentLoad()) + history()->updateForStandardLoad(HistoryController::UpdateAllExceptBackForwardList); + + history()->updateForBackForwardNavigation(); + + // For cached pages, CachedFrame::restore will take care of firing the popstate event with the history item's state object + if (history()->currentItem() && !cachedPage) + m_pendingStateObject = history()->currentItem()->stateObject(); + + // Create a document view for this document, or used the cached view. + if (cachedPage) { + DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader(); + ASSERT(cachedDocumentLoader); + cachedDocumentLoader->setFrame(m_frame); + m_client->transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame()); + + } else + m_client->transitionToCommittedForNewPage(); } break; @@ -2405,7 +2411,7 @@ void FrameLoader::checkLoadCompleteForThisFrame() } if (shouldReset && item) if (Page* page = m_frame->page()) { - page->backForwardList()->goToItem(item.get()); + page->backForward()->setCurrentItem(item.get()); Settings* settings = m_frame->settings(); page->setGlobalHistoryItem((!settings || settings->privateBrowsingEnabled()) ? 0 : item.get()); } @@ -2426,9 +2432,10 @@ void FrameLoader::checkLoadCompleteForThisFrame() m_client->forceLayoutForNonHTML(); // If the user had a scroll point, scroll to it, overriding the anchor point if any. - if (Page* page = m_frame->page()) - if ((isBackForwardLoadType(m_loadType) || m_loadType == FrameLoadTypeReload || m_loadType == FrameLoadTypeReloadFromOrigin) && page->backForwardList()) + if (m_frame->page()) { + if (isBackForwardLoadType(m_loadType) || m_loadType == FrameLoadTypeReload || m_loadType == FrameLoadTypeReloadFromOrigin) history()->restoreScrollPositionAndViewState(); + } if (m_stateMachine.creatingInitialEmptyDocument() || !m_stateMachine.committedFirstRealDocumentLoad()) return; @@ -2496,9 +2503,8 @@ void FrameLoader::continueLoadAfterWillSubmitForm() void FrameLoader::didFirstLayout() { - if (Page* page = m_frame->page()) - if (isBackForwardLoadType(m_loadType) && page->backForwardList()) - history()->restoreScrollPositionAndViewState(); + if (m_frame->page() && isBackForwardLoadType(m_loadType)) + history()->restoreScrollPositionAndViewState(); if (m_stateMachine.committedFirstRealDocumentLoad() && !m_stateMachine.isDisplayingInitialEmptyDocument() && !m_stateMachine.firstLayoutDone()) m_stateMachine.advanceTo(FrameLoaderStateMachine::FirstLayoutDone); @@ -2614,9 +2620,12 @@ void FrameLoader::detachFromParent() RefPtr<Frame> protect(m_frame); closeURL(); - stopAllLoaders(); history()->saveScrollPositionAndViewStateToItem(history()->currentItem()); detachChildren(); + // stopAllLoaders() needs to be called after detachChildren(), because detachedChildren() + // will trigger the unload event handlers of any child frames, and those event + // handlers might start a new subresource load in this frame. + stopAllLoaders(); #if ENABLE(INSPECTOR) if (Page* page = m_frame->page()) @@ -2963,7 +2972,7 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, Pass if (Page* page = m_frame->page()) { Frame* mainFrame = page->mainFrame(); if (HistoryItem* resetItem = mainFrame->loader()->history()->currentItem()) { - page->backForwardList()->goToItem(resetItem); + page->backForward()->setCurrentItem(resetItem); Settings* settings = m_frame->settings(); page->setGlobalHistoryItem((!settings || settings->privateBrowsingEnabled()) ? 0 : resetItem); } @@ -3144,7 +3153,7 @@ void FrameLoader::checkDidPerformFirstNavigation() if (!page) return; - if (!m_didPerformFirstNavigation && page->backForwardList()->currentItem() && !page->backForwardList()->backItem() && !page->backForwardList()->forwardItem()) { + if (!m_didPerformFirstNavigation && page->backForward()->currentItem() && !page->backForward()->backItem() && !page->backForward()->forwardItem()) { m_didPerformFirstNavigation = true; m_client->didPerformFirstNavigation(); } diff --git a/WebCore/loader/HistoryController.cpp b/WebCore/loader/HistoryController.cpp index f06589e..07bece7 100644 --- a/WebCore/loader/HistoryController.cpp +++ b/WebCore/loader/HistoryController.cpp @@ -31,7 +31,7 @@ #include "config.h" #include "HistoryController.h" -#include "BackForwardList.h" +#include "BackForwardController.h" #include "CachedPage.h" #include "DocumentLoader.h" #include "Frame.h" @@ -149,7 +149,7 @@ void HistoryController::saveDocumentState() ASSERT(document); if (item->isCurrentDocument(document)) { - LOG(Loading, "WebCoreLoading %s: saving form state to %p", m_frame->tree()->name().string().utf8().data(), item); + LOG(Loading, "WebCoreLoading %s: saving form state to %p", m_frame->tree()->uniqueName().string().utf8().data(), item); item->setDocumentState(document->formElementsState()); } } @@ -188,7 +188,7 @@ void HistoryController::restoreDocumentState() if (!itemToRestore) return; - LOG(Loading, "WebCoreLoading %s: restoring form state from %p", m_frame->tree()->name().string().utf8().data(), itemToRestore); + LOG(Loading, "WebCoreLoading %s: restoring form state from %p", m_frame->tree()->uniqueName().string().utf8().data(), itemToRestore); doc->setStateForNewFormElements(itemToRestore->documentState()); } @@ -230,9 +230,8 @@ void HistoryController::goToItem(HistoryItem* targetItem, FrameLoadType type) // Set the BF cursor before commit, which lets the user quickly click back/forward again. // - plus, it only makes sense for the top level of the operation through the frametree, // as opposed to happening for some/one of the page commits that might happen soon - BackForwardList* bfList = page->backForwardList(); - HistoryItem* currentItem = bfList->currentItem(); - bfList->goToItem(targetItem); + HistoryItem* currentItem = page->backForward()->currentItem(); + page->backForward()->setCurrentItem(targetItem); Settings* settings = m_frame->settings(); page->setGlobalHistoryItem((!settings || settings->privateBrowsingEnabled()) ? 0 : targetItem); recursiveGoToItem(targetItem, currentItem, type); @@ -295,7 +294,7 @@ void HistoryController::updateForStandardLoad(HistoryUpdateType updateType) frameLoader->client()->updateGlobalHistoryRedirectLinks(); } if (Page* page = m_frame->page()) - page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForwardList()->currentItem()); + page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForward()->currentItem()); } } else if (frameLoader->documentLoader()->unreachableURL().isEmpty() && m_currentItem) { m_currentItem->setURL(frameLoader->documentLoader()->url()); @@ -333,7 +332,7 @@ void HistoryController::updateForRedirectWithLockedBackForwardList() m_frame->loader()->client()->updateGlobalHistoryRedirectLinks(); } if (Page* page = m_frame->page()) - page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForwardList()->currentItem()); + page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForward()->currentItem()); } } if (m_currentItem) { @@ -481,10 +480,10 @@ PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal) originalURL = blankURL(); Frame* parentFrame = m_frame->tree()->parent(); - String parent = parentFrame ? parentFrame->tree()->name() : ""; + String parent = parentFrame ? parentFrame->tree()->uniqueName() : ""; String title = documentLoader ? documentLoader->title() : ""; - RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->name(), parent, title); + RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->uniqueName(), parent, title); item->setOriginalURLString(originalURL.string()); if (!unreachableURL.isEmpty() || !documentLoader || documentLoader->response().httpStatusCode() >= 400) @@ -599,7 +598,7 @@ void HistoryController::recursiveGoToItem(HistoryItem* item, HistoryItem* fromIt // Helper method that determines whether the current frame tree matches given history item's. bool HistoryController::currentFramesMatchItem(HistoryItem* item) const { - if ((!m_frame->tree()->name().isEmpty() || !item->target().isEmpty()) && m_frame->tree()->name() != item->target()) + if ((!m_frame->tree()->uniqueName().isEmpty() || !item->target().isEmpty()) && m_frame->tree()->uniqueName() != item->target()) return false; const HistoryItemVector& childItems = item->children(); @@ -637,7 +636,7 @@ void HistoryController::updateBackForwardListClippedAtTarget(bool doClip) RefPtr<HistoryItem> topItem = frameLoader->history()->createItemTree(m_frame, doClip); LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame %s", topItem.get(), m_frame->loader()->documentLoader()->url().string().ascii().data()); - page->backForwardList()->addItem(topItem.release()); + page->backForward()->addItem(topItem.release()); } void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString) @@ -657,7 +656,7 @@ void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject, m_currentItem->setStateObject(stateObject); m_currentItem->setURLString(urlString); - page->backForwardList()->addItem(topItem.release()); + page->backForward()->addItem(topItem.release()); } void HistoryController::replaceState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString) diff --git a/WebCore/loader/HistoryController.h b/WebCore/loader/HistoryController.h index 487fdc9..1002dbc 100644 --- a/WebCore/loader/HistoryController.h +++ b/WebCore/loader/HistoryController.h @@ -75,6 +75,8 @@ public: void setCurrentItemTitle(const String&); bool currentItemShouldBeReplaced() const; + HistoryItem* previousItem() const { return m_previousItem.get(); } + HistoryItem* provisionalItem() const { return m_provisionalItem.get(); } void setProvisionalItem(HistoryItem*); diff --git a/WebCore/loader/NavigationScheduler.cpp b/WebCore/loader/NavigationScheduler.cpp index 98f21fe..28fda9a 100644 --- a/WebCore/loader/NavigationScheduler.cpp +++ b/WebCore/loader/NavigationScheduler.cpp @@ -32,7 +32,7 @@ #include "config.h" #include "NavigationScheduler.h" -#include "BackForwardList.h" +#include "BackForwardController.h" #include "DOMWindow.h" #include "DocumentLoader.h" #include "Event.h" @@ -177,7 +177,7 @@ public: } // go(i!=0) from a frame navigates into the history of the frame only, // in both IE and NS (but not in Mozilla). We can't easily do that. - frame->page()->goBackOrForward(m_historySteps); + frame->page()->backForward()->goBackOrForward(m_historySteps); } private: @@ -352,8 +352,8 @@ void NavigationScheduler::scheduleHistoryNavigation(int steps) // Invalid history navigations (such as history.forward() during a new load) have the side effect of cancelling any scheduled // redirects. We also avoid the possibility of cancelling the current load by avoiding the scheduled redirection altogether. - HistoryItem* specifiedEntry = m_frame->page()->backForwardList()->itemAtIndex(steps); - if (!specifiedEntry) { + BackForwardController* backForward = m_frame->page()->backForward(); + if (steps > backForward->forwardCount() || -steps > backForward->backCount()) { cancel(); return; } diff --git a/WebCore/loader/PlaceholderDocument.cpp b/WebCore/loader/PlaceholderDocument.cpp index 81222b3..93a26db 100644 --- a/WebCore/loader/PlaceholderDocument.cpp +++ b/WebCore/loader/PlaceholderDocument.cpp @@ -26,9 +26,6 @@ #include "config.h" #include "PlaceholderDocument.h" -#include "CSSStyleSelector.h" -#include "StyleSheetList.h" - namespace WebCore { void PlaceholderDocument::attach() diff --git a/WebCore/loader/ProgressTracker.cpp b/WebCore/loader/ProgressTracker.cpp index 561e6bc..6bc2055 100644 --- a/WebCore/loader/ProgressTracker.cpp +++ b/WebCore/loader/ProgressTracker.cpp @@ -101,7 +101,7 @@ void ProgressTracker::reset() void ProgressTracker::progressStarted(Frame* frame) { - LOG(Progress, "Progress started (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree()->name().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); + LOG(Progress, "Progress started (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree()->uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); frame->loader()->client()->willChangeEstimatedProgress(); @@ -119,7 +119,7 @@ void ProgressTracker::progressStarted(Frame* frame) void ProgressTracker::progressCompleted(Frame* frame) { - LOG(Progress, "Progress completed (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree()->name().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); + LOG(Progress, "Progress completed (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree()->uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); if (m_numProgressTrackedFrames <= 0) return; diff --git a/WebCore/loader/Request.h b/WebCore/loader/Request.h index 25bf31a..b6de312 100644 --- a/WebCore/loader/Request.h +++ b/WebCore/loader/Request.h @@ -36,13 +36,13 @@ namespace WebCore { Request(CachedResourceLoader*, CachedResource*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks); ~Request(); - CachedResource* cachedResource() { return m_object; } - CachedResourceLoader* cachedResourceLoader() { return m_cachedResourceLoader; } + CachedResource* cachedResource() const { return m_object; } + CachedResourceLoader* cachedResourceLoader() const { return m_cachedResourceLoader; } - bool isIncremental() { return m_incremental; } + bool isIncremental() const { return m_incremental; } void setIsIncremental(bool b = true) { m_incremental = b; } - bool isMultipart() { return m_multipart; } + bool isMultipart() const { return m_multipart; } void setIsMultipart(bool b = true) { m_multipart = b; } SecurityCheckPolicy shouldDoSecurityCheck() const { return m_shouldDoSecurityCheck; } diff --git a/WebCore/loader/SubframeLoader.cpp b/WebCore/loader/SubframeLoader.cpp index f73646b..d486de0 100644 --- a/WebCore/loader/SubframeLoader.cpp +++ b/WebCore/loader/SubframeLoader.cpp @@ -366,8 +366,8 @@ bool SubframeLoader::loadPlugin(HTMLPlugInImageElement* pluginElement, const KUR renderer->setWidget(widget); m_containsPlugins = true; - -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) || ENABLE(3D_PLUGIN) pluginElement->setNeedsStyleRecalc(SyntheticStyleChange); #endif return true; diff --git a/WebCore/loader/archive/cf/LegacyWebArchive.cpp b/WebCore/loader/archive/cf/LegacyWebArchive.cpp index 061f4d9..ddd564e 100644 --- a/WebCore/loader/archive/cf/LegacyWebArchive.cpp +++ b/WebCore/loader/archive/cf/LegacyWebArchive.cpp @@ -29,7 +29,7 @@ #include "config.h" #include "LegacyWebArchive.h" -#include "Cache.h" +#include "MemoryCache.h" #include "Document.h" #include "DocumentLoader.h" #include "Frame.h" @@ -492,7 +492,7 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString if (responseURL.isNull()) responseURL = KURL(ParsedURLString, ""); - PassRefPtr<ArchiveResource> mainResource = ArchiveResource::create(utf8Buffer(markupString), responseURL, response.mimeType(), "UTF-8", frame->tree()->name()); + PassRefPtr<ArchiveResource> mainResource = ArchiveResource::create(utf8Buffer(markupString), responseURL, response.mimeType(), "UTF-8", frame->tree()->uniqueName()); Vector<PassRefPtr<LegacyWebArchive> > subframeArchives; Vector<PassRefPtr<ArchiveResource> > subresources; @@ -509,7 +509,7 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString if (subframeArchive) subframeArchives.append(subframeArchive); else - LOG_ERROR("Unabled to archive subframe %s", childFrame->tree()->name().string().utf8().data()); + LOG_ERROR("Unabled to archive subframe %s", childFrame->tree()->uniqueName().string().utf8().data()); } else { ListHashSet<KURL> subresourceURLs; node->getSubresourceURLs(subresourceURLs); diff --git a/WebCore/loader/CachePolicy.h b/WebCore/loader/cache/CachePolicy.h index 2639caa..2639caa 100644 --- a/WebCore/loader/CachePolicy.h +++ b/WebCore/loader/cache/CachePolicy.h diff --git a/WebCore/loader/CachedCSSStyleSheet.cpp b/WebCore/loader/cache/CachedCSSStyleSheet.cpp index 877cd1d..f0016d1 100644 --- a/WebCore/loader/CachedCSSStyleSheet.cpp +++ b/WebCore/loader/cache/CachedCSSStyleSheet.cpp @@ -27,7 +27,7 @@ #include "config.h" #include "CachedCSSStyleSheet.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedResourceClient.h" #include "CachedResourceClientWalker.h" #include "HTTPParsers.h" @@ -59,7 +59,7 @@ void CachedCSSStyleSheet::didAddClient(CachedResourceClient *c) void CachedCSSStyleSheet::allClientsRemoved() { - if (!Cache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable()) + if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable()) makePurgeable(true); } diff --git a/WebCore/loader/CachedCSSStyleSheet.h b/WebCore/loader/cache/CachedCSSStyleSheet.h index 03bde69..abcdb85 100644 --- a/WebCore/loader/CachedCSSStyleSheet.h +++ b/WebCore/loader/cache/CachedCSSStyleSheet.h @@ -55,6 +55,7 @@ namespace WebCore { private: bool canUseSheet(bool enforceMIMEType, bool* hasValidMIMEType) const; + virtual PurgePriority purgePriority() const { return PurgeLast; } protected: RefPtr<TextResourceDecoder> m_decoder; diff --git a/WebCore/loader/CachedFont.cpp b/WebCore/loader/cache/CachedFont.cpp index e8db6c6..6297ad1 100644 --- a/WebCore/loader/CachedFont.cpp +++ b/WebCore/loader/cache/CachedFont.cpp @@ -31,7 +31,7 @@ #define STORE_FONT_CUSTOM_PLATFORM_DATA #endif -#include "Cache.h" +#include "MemoryCache.h" #include "CachedResourceClient.h" #include "CachedResourceClientWalker.h" #include "FontPlatformData.h" diff --git a/WebCore/loader/CachedFont.h b/WebCore/loader/cache/CachedFont.h index 8dc8874..e1a34e8 100644 --- a/WebCore/loader/CachedFont.h +++ b/WebCore/loader/cache/CachedFont.h @@ -39,7 +39,7 @@ namespace WebCore { class CachedResourceLoader; -class Cache; +class MemoryCache; class FontPlatformData; class SVGFontElement; @@ -81,7 +81,7 @@ private: RefPtr<SVGDocument> m_externalSVGDocument; #endif - friend class Cache; + friend class MemoryCache; }; } diff --git a/WebCore/loader/CachedImage.cpp b/WebCore/loader/cache/CachedImage.cpp index 30eaf9d..ce1c9a3 100644 --- a/WebCore/loader/CachedImage.cpp +++ b/WebCore/loader/cache/CachedImage.cpp @@ -25,7 +25,7 @@ #include "CachedImage.h" #include "BitmapImage.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedResourceClient.h" #include "CachedResourceClientWalker.h" #include "CachedResourceLoader.h" @@ -338,7 +338,7 @@ void CachedImage::destroyDecodedData() // Invoking addClient() will reconstruct the image object. m_image = 0; setDecodedSize(0); - if (!Cache::shouldMakeResourcePurgeableOnEviction()) + if (!MemoryCache::shouldMakeResourcePurgeableOnEviction()) makePurgeable(true); } else if (m_image && !errorOccurred()) m_image->destroyDecodedData(); diff --git a/WebCore/loader/CachedImage.h b/WebCore/loader/cache/CachedImage.h index 15f4238..313f3f3 100644 --- a/WebCore/loader/CachedImage.h +++ b/WebCore/loader/cache/CachedImage.h @@ -32,10 +32,10 @@ namespace WebCore { class CachedResourceLoader; -class Cache; +class MemoryCache; class CachedImage : public CachedResource, public ImageObserver { - friend class Cache; + friend class MemoryCache; public: CachedImage(const String& url); @@ -93,6 +93,7 @@ private: // If not null, changeRect is the changed part of the image. void notifyObservers(const IntRect* changeRect = 0); void decodedDataDeletionTimerFired(Timer<CachedImage>*); + virtual PurgePriority purgePriority() const { return PurgeFirst; } RefPtr<Image> m_image; Timer<CachedImage> m_decodedDataDeletionTimer; diff --git a/WebCore/loader/CachedResource.cpp b/WebCore/loader/cache/CachedResource.cpp index e519c29..c440ec9 100644 --- a/WebCore/loader/CachedResource.cpp +++ b/WebCore/loader/cache/CachedResource.cpp @@ -24,7 +24,7 @@ #include "config.h" #include "CachedResource.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedMetadata.h" #include "CachedResourceClient.h" #include "CachedResourceClientWalker.h" @@ -517,17 +517,13 @@ bool CachedResource::makePurgeable(bool purgeable) if (!m_data->hasOneRef()) return false; - // Purgeable buffers are allocated in multiples of the page size (4KB in common CPUs) so it does not make sense for very small buffers. - const size_t purgeableThreshold = 4 * 4096; - if (m_data->size() < purgeableThreshold) - return false; - if (m_data->hasPurgeableBuffer()) { m_purgeableData = m_data->releasePurgeableBuffer(); } else { m_purgeableData = PurgeableBuffer::create(m_data->data(), m_data->size()); if (!m_purgeableData) return false; + m_purgeableData->setPurgePriority(purgePriority()); } m_purgeableData->makePurgeable(true); diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/cache/CachedResource.h index 078da57..ba02459 100644 --- a/WebCore/loader/CachedResource.h +++ b/WebCore/loader/cache/CachedResource.h @@ -26,6 +26,7 @@ #include "CachePolicy.h" #include "FrameLoaderTypes.h" #include "PlatformString.h" +#include "PurgePriority.h" #include "ResourceResponse.h" #include <wtf/HashCountedSet.h> #include <wtf/HashSet.h> @@ -35,21 +36,21 @@ namespace WebCore { -class Cache; +class MemoryCache; class CachedMetadata; class CachedResourceClient; class CachedResourceHandleBase; class CachedResourceLoader; class Frame; class InspectorResource; -class Request; class PurgeableBuffer; +class Request; // A resource that is held in the cache. Classes who want to use this object should derive // from CachedResourceClient, to get the function calls in case the requested data has arrived. // This class also does the actual communication with the loader to obtain the resource from the network. class CachedResource : public Noncopyable { - friend class Cache; + friend class MemoryCache; friend class InspectorResource; public: @@ -224,11 +225,12 @@ protected: private: void addClientToSet(CachedResourceClient*); - // These are called by the friendly Cache only + // These are called by the friendly MemoryCache only void setResourceToRevalidate(CachedResource*); void switchClientsToRevalidatedResource(); void clearResourceToRevalidate(); void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse); + virtual PurgePriority purgePriority() const { return PurgeDefault; } double currentAge() const; double freshnessLifetime() const; diff --git a/WebCore/loader/CachedResourceClient.h b/WebCore/loader/cache/CachedResourceClient.h index 275d331..275d331 100644 --- a/WebCore/loader/CachedResourceClient.h +++ b/WebCore/loader/cache/CachedResourceClient.h diff --git a/WebCore/loader/CachedResourceClientWalker.cpp b/WebCore/loader/cache/CachedResourceClientWalker.cpp index 142a2a1..142a2a1 100644 --- a/WebCore/loader/CachedResourceClientWalker.cpp +++ b/WebCore/loader/cache/CachedResourceClientWalker.cpp diff --git a/WebCore/loader/CachedResourceClientWalker.h b/WebCore/loader/cache/CachedResourceClientWalker.h index d079584..d079584 100644 --- a/WebCore/loader/CachedResourceClientWalker.h +++ b/WebCore/loader/cache/CachedResourceClientWalker.h diff --git a/WebCore/loader/CachedResourceHandle.cpp b/WebCore/loader/cache/CachedResourceHandle.cpp index 871292c..871292c 100644 --- a/WebCore/loader/CachedResourceHandle.cpp +++ b/WebCore/loader/cache/CachedResourceHandle.cpp diff --git a/WebCore/loader/CachedResourceHandle.h b/WebCore/loader/cache/CachedResourceHandle.h index 7d485bf..7d485bf 100644 --- a/WebCore/loader/CachedResourceHandle.h +++ b/WebCore/loader/cache/CachedResourceHandle.h diff --git a/WebCore/loader/CachedResourceLoader.cpp b/WebCore/loader/cache/CachedResourceLoader.cpp index 5925f67..29d1204 100644 --- a/WebCore/loader/CachedResourceLoader.cpp +++ b/WebCore/loader/cache/CachedResourceLoader.cpp @@ -27,32 +27,32 @@ #include "config.h" #include "CachedResourceLoader.h" -#include "loader.h" -#include "Cache.h" #include "CachedCSSStyleSheet.h" #include "CachedFont.h" #include "CachedImage.h" #include "CachedScript.h" #include "CachedXSLStyleSheet.h" #include "Console.h" -#include "Document.h" #include "DOMWindow.h" -#include "HTMLElement.h" +#include "Document.h" #include "Frame.h" #include "FrameLoader.h" #include "FrameLoaderClient.h" +#include "HTMLElement.h" +#include "MemoryCache.h" #include "PingLoader.h" #include "SecurityOrigin.h" #include "Settings.h" +#include "loader.h" #include <wtf/text/StringConcatenate.h> #define PRELOAD_DEBUG 0 namespace WebCore { -CachedResourceLoader::CachedResourceLoader(Document* doc) +CachedResourceLoader::CachedResourceLoader(Document* document) : m_cache(cache()) - , m_doc(doc) + , m_document(document) , m_requestCount(0) #ifdef ANDROID_BLOCK_NETWORK_IMAGE , m_blockNetworkImage(false) @@ -81,7 +81,7 @@ CachedResourceLoader::~CachedResourceLoader() Frame* CachedResourceLoader::frame() const { - return m_doc->frame(); + return m_document->frame(); } void CachedResourceLoader::checkForReload(const KURL& fullURL) @@ -131,7 +131,7 @@ CachedImage* CachedResourceLoader::requestImage(const String& url) return 0; if (f->loader()->pageDismissalEventBeingDispatched()) { - KURL completeURL = m_doc->completeURL(url); + KURL completeURL = m_document->completeURL(url); if (completeURL.isValid() && canRequest(CachedResource::ImageResource, completeURL)) PingLoader::loadImage(f, completeURL); return 0; @@ -203,7 +203,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url break; #if ENABLE(XSLT) case CachedResource::XSLStyleSheet: - if (!m_doc->securityOrigin()->canRequest(url)) { + if (!m_document->securityOrigin()->canRequest(url)) { printAccessDeniedMessage(url); return false; } @@ -228,7 +228,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url #endif // These resource can inject script into the current document. if (Frame* f = frame()) - f->loader()->checkIfRunInsecureContent(m_doc->securityOrigin(), url); + f->loader()->checkIfRunInsecureContent(m_document->securityOrigin(), url); break; case CachedResource::ImageResource: case CachedResource::CSSStyleSheet: @@ -255,7 +255,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& url, const String& charset, bool isPreload) { - KURL fullURL = m_doc->completeURL(url); + KURL fullURL = m_document->completeURL(url); if (!fullURL.isValid() || !canRequest(type, fullURL)) return 0; @@ -296,9 +296,9 @@ void CachedResourceLoader::printAccessDeniedMessage(const KURL& url) const if (!settings || settings->privateBrowsingEnabled()) return; - String message = m_doc->url().isNull() ? + String message = m_document->url().isNull() ? makeString("Unsafe attempt to load URL ", url.string(), '.') : - makeString("Unsafe attempt to load URL ", url.string(), " from frame with URL ", m_doc->url().string(), ". Domains, protocols and ports must match.\n"); + makeString("Unsafe attempt to load URL ", url.string(), " from frame with URL ", m_document->url().string(), ". Domains, protocols and ports must match.\n"); // FIXME: provide a real line number and source URL. frame()->domWindow()->console()->addMessage(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String()); @@ -423,7 +423,7 @@ int CachedResourceLoader::requestCount() void CachedResourceLoader::preload(CachedResource::Type type, const String& url, const String& charset, bool referencedFromBody) { - bool hasRendering = m_doc->body() && m_doc->body()->renderer(); + bool hasRendering = m_document->body() && m_document->body()->renderer(); if (!hasRendering && (referencedFromBody || type == CachedResource::ImageResource)) { // Don't preload images or body resources before we have something to draw. This prevents // preloads from body delaying first display when bandwidth is limited. @@ -437,12 +437,12 @@ void CachedResourceLoader::preload(CachedResource::Type type, const String& url, void CachedResourceLoader::checkForPendingPreloads() { unsigned count = m_pendingPreloads.size(); - if (!count || !m_doc->body() || !m_doc->body()->renderer()) + if (!count || !m_document->body() || !m_document->body()->renderer()) return; for (unsigned i = 0; i < count; ++i) { PendingPreload& preload = m_pendingPreloads[i]; // Don't request preload if the resource already loaded normally (this will result in double load if the page is being reloaded with cached results ignored). - if (!cachedResource(m_doc->completeURL(preload.m_url))) + if (!cachedResource(m_document->completeURL(preload.m_url))) requestPreload(preload.m_type, preload.m_url, preload.m_charset); } m_pendingPreloads.clear(); @@ -452,7 +452,7 @@ void CachedResourceLoader::requestPreload(CachedResource::Type type, const Strin { String encoding; if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet) - encoding = charset.isEmpty() ? m_doc->frame()->loader()->writer()->encoding() : charset; + encoding = charset.isEmpty() ? m_document->frame()->loader()->writer()->encoding() : charset; CachedResource* resource = requestResource(type, url, encoding, true); if (!resource || (m_preloads && m_preloads->contains(resource))) diff --git a/WebCore/loader/CachedResourceLoader.h b/WebCore/loader/cache/CachedResourceLoader.h index 16d73ad..eaed52e 100644 --- a/WebCore/loader/CachedResourceLoader.h +++ b/WebCore/loader/cache/CachedResourceLoader.h @@ -48,7 +48,7 @@ class KURL; // The CachedResourceLoader manages the loading of scripts/images/stylesheets for a single document. class CachedResourceLoader : public Noncopyable { -friend class Cache; +friend class MemoryCache; friend class ImageLoader; public: @@ -88,7 +88,7 @@ public: CachePolicy cachePolicy() const; Frame* frame() const; // Can be NULL - Document* doc() const { return m_doc; } + Document* document() const { return m_document; } void removeCachedResource(CachedResource*) const; @@ -115,10 +115,10 @@ private: void checkCacheObjectStatus(CachedResource*); bool canRequest(CachedResource::Type, const KURL&); - Cache* m_cache; + MemoryCache* m_cache; HashSet<String> m_reloadedURLs; mutable DocumentResourceMap m_documentResources; - Document* m_doc; + Document* m_document; int m_requestCount; diff --git a/WebCore/loader/CachedScript.cpp b/WebCore/loader/cache/CachedScript.cpp index 1898438..50a8c17 100644 --- a/WebCore/loader/CachedScript.cpp +++ b/WebCore/loader/cache/CachedScript.cpp @@ -27,7 +27,7 @@ #include "config.h" #include "CachedScript.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedResourceClient.h" #include "CachedResourceClientWalker.h" #include "SharedBuffer.h" @@ -111,7 +111,7 @@ void CachedScript::destroyDecodedData() { m_script = String(); setDecodedSize(0); - if (!Cache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable()) + if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable()) makePurgeable(true); } diff --git a/WebCore/loader/CachedScript.h b/WebCore/loader/cache/CachedScript.h index 1bc4e8c..7311f9b 100644 --- a/WebCore/loader/CachedScript.h +++ b/WebCore/loader/cache/CachedScript.h @@ -54,6 +54,7 @@ namespace WebCore { private: void decodedDataDeletionTimerFired(Timer<CachedScript>*); + virtual PurgePriority purgePriority() const { return PurgeLast; } String m_script; RefPtr<TextResourceDecoder> m_decoder; diff --git a/WebCore/loader/CachedXSLStyleSheet.cpp b/WebCore/loader/cache/CachedXSLStyleSheet.cpp index 5b30e30..5b30e30 100644 --- a/WebCore/loader/CachedXSLStyleSheet.cpp +++ b/WebCore/loader/cache/CachedXSLStyleSheet.cpp diff --git a/WebCore/loader/CachedXSLStyleSheet.h b/WebCore/loader/cache/CachedXSLStyleSheet.h index 8587b0b..8587b0b 100644 --- a/WebCore/loader/CachedXSLStyleSheet.h +++ b/WebCore/loader/cache/CachedXSLStyleSheet.h diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/cache/MemoryCache.cpp index 7dc8a32..25af774 100644 --- a/WebCore/loader/Cache.cpp +++ b/WebCore/loader/cache/MemoryCache.cpp @@ -21,7 +21,7 @@ */ #include "config.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedCSSStyleSheet.h" #include "CachedFont.h" @@ -49,13 +49,13 @@ static const double cMinDelayBeforeLiveDecodedPrune = 1; // Seconds. static const float cTargetPrunePercentage = .95f; // Percentage of capacity toward which we prune, to avoid immediately pruning again. static const double cDefaultDecodedDataDeletionInterval = 0; -Cache* cache() +MemoryCache* cache() { - static Cache* staticCache = new Cache; + static MemoryCache* staticCache = new MemoryCache; return staticCache; } -Cache::Cache() +MemoryCache::MemoryCache() : m_disabled(false) , m_pruneEnabled(true) , m_inPruneDeadResources(false) @@ -94,9 +94,9 @@ static CachedResource* createResource(CachedResource::Type type, const KURL& url return 0; } -CachedResource* Cache::requestResource(CachedResourceLoader* cachedResourceLoader, CachedResource::Type type, const KURL& url, const String& charset, bool requestIsPreload) +CachedResource* MemoryCache::requestResource(CachedResourceLoader* cachedResourceLoader, CachedResource::Type type, const KURL& url, const String& charset, bool requestIsPreload) { - LOG(ResourceLoading, "Cache::requestResource '%s', charset '%s', preload=%u", url.string().latin1().data(), charset.latin1().data(), requestIsPreload); + LOG(ResourceLoading, "MemoryCache::requestResource '%s', charset '%s', preload=%u", url.string().latin1().data(), charset.latin1().data(), requestIsPreload); // FIXME: Do we really need to special-case an empty URL? // Would it be better to just go on with the cache code and let it fail later? @@ -107,14 +107,14 @@ CachedResource* Cache::requestResource(CachedResourceLoader* cachedResourceLoade CachedResource* resource = resourceForURL(url.string()); if (resource && requestIsPreload && !resource->isPreloaded()) { - LOG(ResourceLoading, "Cache::requestResource already has a preload request for this request, and it hasn't been preloaded yet"); + LOG(ResourceLoading, "MemoryCache::requestResource already has a preload request for this request, and it hasn't been preloaded yet"); return 0; } - if (!cachedResourceLoader->doc()->securityOrigin()->canDisplay(url)) { + if (!cachedResourceLoader->document()->securityOrigin()->canDisplay(url)) { LOG(ResourceLoading, "...URL was not allowed by SecurityOrigin"); if (!requestIsPreload) - FrameLoader::reportLocalLoadFailed(cachedResourceLoader->doc()->frame(), url.string()); + FrameLoader::reportLocalLoadFailed(cachedResourceLoader->document()->frame(), url.string()); return 0; } @@ -149,7 +149,7 @@ CachedResource* Cache::requestResource(CachedResourceLoader* cachedResourceLoade } if (resource->type() != type) { - LOG(ResourceLoading, "Cache::requestResource cannot use cached resource for '%s' due to type mismatch", url.string().latin1().data()); + LOG(ResourceLoading, "MemoryCache::requestResource cannot use cached resource for '%s' due to type mismatch", url.string().latin1().data()); return 0; } @@ -158,12 +158,12 @@ CachedResource* Cache::requestResource(CachedResourceLoader* cachedResourceLoade resourceAccessed(resource); } - LOG(ResourceLoading, "Cache::requestResource for '%s' returning resource %p\n", url.string().latin1().data(), resource); + LOG(ResourceLoading, "MemoryCache::requestResource for '%s' returning resource %p\n", url.string().latin1().data(), resource); return resource; } -CachedCSSStyleSheet* Cache::requestUserCSSStyleSheet(CachedResourceLoader* cachedResourceLoader, const String& url, const String& charset) +CachedCSSStyleSheet* MemoryCache::requestUserCSSStyleSheet(CachedResourceLoader* cachedResourceLoader, const String& url, const String& charset) { CachedCSSStyleSheet* userSheet; if (CachedResource* existing = resourceForURL(url)) { @@ -192,7 +192,7 @@ CachedCSSStyleSheet* Cache::requestUserCSSStyleSheet(CachedResourceLoader* cache return userSheet; } -void Cache::revalidateResource(CachedResource* resource, CachedResourceLoader* cachedResourceLoader) +void MemoryCache::revalidateResource(CachedResource* resource, CachedResourceLoader* cachedResourceLoader) { ASSERT(resource); ASSERT(resource->inCache()); @@ -215,7 +215,7 @@ void Cache::revalidateResource(CachedResource* resource, CachedResourceLoader* c newResource->load(cachedResourceLoader); } -void Cache::revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse& response) +void MemoryCache::revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse& response) { CachedResource* resource = revalidatingResource->resourceToRevalidate(); ASSERT(resource); @@ -241,17 +241,17 @@ void Cache::revalidationSucceeded(CachedResource* revalidatingResource, const Re revalidatingResource->clearResourceToRevalidate(); } -void Cache::revalidationFailed(CachedResource* revalidatingResource) +void MemoryCache::revalidationFailed(CachedResource* revalidatingResource) { LOG(ResourceLoading, "Revalidation failed for %p", revalidatingResource); ASSERT(revalidatingResource->resourceToRevalidate()); revalidatingResource->clearResourceToRevalidate(); } -CachedResource* Cache::resourceForURL(const String& url) +CachedResource* MemoryCache::resourceForURL(const String& url) { CachedResource* resource = m_resources.get(url); - bool wasPurgeable = Cache::shouldMakeResourcePurgeableOnEviction() && resource && resource->isPurgeable(); + bool wasPurgeable = MemoryCache::shouldMakeResourcePurgeableOnEviction() && resource && resource->isPurgeable(); if (resource && !resource->makePurgeable(false)) { ASSERT(!resource->hasClients()); evict(resource); @@ -263,7 +263,7 @@ CachedResource* Cache::resourceForURL(const String& url) return resource; } -unsigned Cache::deadCapacity() const +unsigned MemoryCache::deadCapacity() const { // Dead resource capacity is whatever space is not occupied by live resources, bounded by an independent minimum and maximum. unsigned capacity = m_capacity - min(m_liveSize, m_capacity); // Start with available capacity. @@ -272,13 +272,13 @@ unsigned Cache::deadCapacity() const return capacity; } -unsigned Cache::liveCapacity() const +unsigned MemoryCache::liveCapacity() const { // Live resource capacity is whatever is left over after calculating dead resource capacity. return m_capacity - deadCapacity(); } -void Cache::pruneLiveResources() +void MemoryCache::pruneLiveResources() { if (!m_pruneEnabled) return; @@ -322,7 +322,7 @@ void Cache::pruneLiveResources() } } -void Cache::pruneDeadResources() +void MemoryCache::pruneDeadResources() { if (!m_pruneEnabled) return; @@ -406,7 +406,7 @@ void Cache::pruneDeadResources() m_inPruneDeadResources = false; } -void Cache::setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes) +void MemoryCache::setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes) { ASSERT(minDeadBytes <= maxDeadBytes); ASSERT(maxDeadBytes <= totalBytes); @@ -416,9 +416,9 @@ void Cache::setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned prune(); } -bool Cache::makeResourcePurgeable(CachedResource* resource) +bool MemoryCache::makeResourcePurgeable(CachedResource* resource) { - if (!Cache::shouldMakeResourcePurgeableOnEviction()) + if (!MemoryCache::shouldMakeResourcePurgeableOnEviction()) return false; if (!resource->inCache()) @@ -438,7 +438,7 @@ bool Cache::makeResourcePurgeable(CachedResource* resource) return true; } -void Cache::evict(CachedResource* resource) +void MemoryCache::evict(CachedResource* resource) { LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().latin1().data()); // The resource may have already been removed by someone other than our caller, @@ -455,7 +455,7 @@ void Cache::evict(CachedResource* resource) // If the resource was purged, it means we had already decremented the size when we made the // resource purgeable in makeResourcePurgeable(). So adjust the size if we are evicting a // resource that was not marked as purgeable. - if (!Cache::shouldMakeResourcePurgeableOnEviction() || !resource->isPurgeable()) + if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() || !resource->isPurgeable()) adjustSize(resource->hasClients(), -static_cast<int>(resource->size())); } else ASSERT(m_resources.get(resource->url()) != resource); @@ -464,12 +464,12 @@ void Cache::evict(CachedResource* resource) delete resource; } -void Cache::addCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) +void MemoryCache::addCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_cachedResourceLoaders.add(cachedResourceLoader); } -void Cache::removeCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) +void MemoryCache::removeCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_cachedResourceLoaders.remove(cachedResourceLoader); } @@ -492,7 +492,7 @@ static inline unsigned fastLog2(unsigned i) return log2; } -Cache::LRUList* Cache::lruListFor(CachedResource* resource) +MemoryCache::LRUList* MemoryCache::lruListFor(CachedResource* resource) { unsigned accessCount = max(resource->accessCount(), 1U); unsigned queueIndex = fastLog2(resource->size() / accessCount); @@ -504,7 +504,7 @@ Cache::LRUList* Cache::lruListFor(CachedResource* resource) return &m_allResources[queueIndex]; } -void Cache::removeFromLRUList(CachedResource* resource) +void MemoryCache::removeFromLRUList(CachedResource* resource) { // If we've never been accessed, then we're brand new and not in any list. if (resource->accessCount() == 0) @@ -551,7 +551,7 @@ void Cache::removeFromLRUList(CachedResource* resource) list->m_head = next; } -void Cache::insertInLRUList(CachedResource* resource) +void MemoryCache::insertInLRUList(CachedResource* resource) { // Make sure we aren't in some list already. ASSERT(!resource->m_nextInAllResourcesList && !resource->m_prevInAllResourcesList); @@ -583,7 +583,7 @@ void Cache::insertInLRUList(CachedResource* resource) } -void Cache::resourceAccessed(CachedResource* resource) +void MemoryCache::resourceAccessed(CachedResource* resource) { ASSERT(resource->inCache()); @@ -602,7 +602,7 @@ void Cache::resourceAccessed(CachedResource* resource) insertInLRUList(resource); } -void Cache::removeFromLiveDecodedResourcesList(CachedResource* resource) +void MemoryCache::removeFromLiveDecodedResourcesList(CachedResource* resource) { // If we've never been accessed, then we're brand new and not in any list. if (!resource->m_inLiveDecodedResourcesList) @@ -641,7 +641,7 @@ void Cache::removeFromLiveDecodedResourcesList(CachedResource* resource) m_liveDecodedResources.m_head = next; } -void Cache::insertInLiveDecodedResourcesList(CachedResource* resource) +void MemoryCache::insertInLiveDecodedResourcesList(CachedResource* resource) { // Make sure we aren't in the list already. ASSERT(!resource->m_nextInLiveResourcesList && !resource->m_prevInLiveResourcesList && !resource->m_inLiveDecodedResourcesList); @@ -669,19 +669,19 @@ void Cache::insertInLiveDecodedResourcesList(CachedResource* resource) } -void Cache::addToLiveResourcesSize(CachedResource* resource) +void MemoryCache::addToLiveResourcesSize(CachedResource* resource) { m_liveSize += resource->size(); m_deadSize -= resource->size(); } -void Cache::removeFromLiveResourcesSize(CachedResource* resource) +void MemoryCache::removeFromLiveResourcesSize(CachedResource* resource) { m_liveSize -= resource->size(); m_deadSize += resource->size(); } -void Cache::adjustSize(bool live, int delta) +void MemoryCache::adjustSize(bool live, int delta) { if (live) { ASSERT(delta >= 0 || ((int)m_liveSize + delta >= 0)); @@ -692,7 +692,7 @@ void Cache::adjustSize(bool live, int delta) } } -void Cache::TypeStatistic::addResource(CachedResource* o) +void MemoryCache::TypeStatistic::addResource(CachedResource* o) { bool purged = o->wasPurged(); bool purgeable = o->isPurgeable() && !purged; @@ -705,7 +705,7 @@ void Cache::TypeStatistic::addResource(CachedResource* o) purgedSize += purged ? pageSize : 0; } -Cache::Statistics Cache::getStatistics() +MemoryCache::Statistics MemoryCache::getStatistics() { Statistics stats; CachedResourceMap::iterator e = m_resources.end(); @@ -736,7 +736,7 @@ Cache::Statistics Cache::getStatistics() return stats; } -void Cache::setDisabled(bool disabled) +void MemoryCache::setDisabled(bool disabled) { m_disabled = disabled; if (!m_disabled) @@ -751,7 +751,7 @@ void Cache::setDisabled(bool disabled) } #ifndef NDEBUG -void Cache::dumpStats() +void MemoryCache::dumpStats() { Statistics s = getStatistics(); printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "LiveSize", "DecodedSize", "PurgeableSize", "PurgedSize"); @@ -766,7 +766,7 @@ void Cache::dumpStats() printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n\n", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------"); } -void Cache::dumpLRULists(bool includeLive) const +void MemoryCache::dumpLRULists(bool includeLive) const { printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isPurgeable, wasPurged):\n"); diff --git a/WebCore/loader/Cache.h b/WebCore/loader/cache/MemoryCache.h index eb5b398..a40f85e 100644 --- a/WebCore/loader/Cache.h +++ b/WebCore/loader/cache/MemoryCache.h @@ -71,9 +71,9 @@ class KURL; // its member variables) are allocated in non-purgeable TC-malloc'd memory so we would see slightly // more memory use due to this. -class Cache : public Noncopyable { +class MemoryCache : public Noncopyable { public: - friend Cache* cache(); + friend MemoryCache* cache(); typedef HashMap<String, CachedResource*> CachedResourceMap; @@ -175,8 +175,8 @@ public: #endif private: - Cache(); - ~Cache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons. + MemoryCache(); + ~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons. LRUList* lruListFor(CachedResource*); void resourceAccessed(CachedResource*); @@ -223,7 +223,7 @@ private: HashMap<String, CachedResource*> m_resources; }; -inline bool Cache::shouldMakeResourcePurgeableOnEviction() +inline bool MemoryCache::shouldMakeResourcePurgeableOnEviction() { #if PLATFORM(IOS) return true; @@ -233,7 +233,7 @@ inline bool Cache::shouldMakeResourcePurgeableOnEviction() } // Function to obtain the global cache. -Cache* cache(); +MemoryCache* cache(); } diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp index aa3f246..bd27312 100644 --- a/WebCore/loader/loader.cpp +++ b/WebCore/loader/loader.cpp @@ -24,7 +24,7 @@ #include "config.h" #include "loader.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CachedImage.h" #include "CachedResource.h" #include "CachedResourceLoader.h" @@ -151,7 +151,7 @@ void Loader::load(CachedResourceLoader* cachedResourceLoader, CachedResource* re host->servePendingRequests(priority); } else { // Handle asynchronously so early low priority requests don't get scheduled before later high priority ones - InspectorInstrumentation::didScheduleResourceRequest(cachedResourceLoader->doc(), resource->url()); + InspectorInstrumentation::didScheduleResourceRequest(cachedResourceLoader->document(), resource->url()); scheduleServePendingRequests(); } } @@ -334,7 +334,7 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser // For named hosts - which are only http(s) hosts - we should always enforce the connection limit. // For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing // and we don't know all stylesheets yet. - bool shouldLimitRequests = !m_name.isNull() || cachedResourceLoader->doc()->parsing() || !cachedResourceLoader->doc()->haveStylesheetsLoaded(); + bool shouldLimitRequests = !m_name.isNull() || cachedResourceLoader->document()->parsing() || !cachedResourceLoader->document()->haveStylesheetsLoaded(); if (shouldLimitRequests && m_requestsLoading.size() + m_nonCachedRequestsInFlight >= m_maxRequestsInFlight) { serveLowerPriority = false; return; @@ -368,10 +368,10 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser #if ENABLE(LINK_PREFETCH) if (request->cachedResource()->type() == CachedResource::LinkPrefetch) - resourceRequest.setHTTPHeaderField("X-Purpose", "prefetch"); + resourceRequest.setHTTPHeaderField("Purpose", "prefetch"); #endif - RefPtr<SubresourceLoader> loader = SubresourceLoader::create(cachedResourceLoader->doc()->frame(), + RefPtr<SubresourceLoader> loader = SubresourceLoader::create(cachedResourceLoader->document()->frame(), this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks()); if (loader) { m_requestsLoading.add(loader.release(), request); @@ -405,7 +405,7 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader) CachedResourceLoader* cachedResourceLoader = request->cachedResourceLoader(); // Prevent the document from being destroyed before we are done with // the cachedResourceLoader that it will delete when the document gets deleted. - RefPtr<Document> protector(cachedResourceLoader->doc()); + RefPtr<Document> protector(cachedResourceLoader->document()); if (!request->isMultipart()) cachedResourceLoader->decrementRequestCount(request->cachedResource()); @@ -451,7 +451,7 @@ void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled) CachedResourceLoader* cachedResourceLoader = request->cachedResourceLoader(); // Prevent the document from being destroyed before we are done with // the cachedResourceLoader that it will delete when the document gets deleted. - RefPtr<Document> protector(cachedResourceLoader->doc()); + RefPtr<Document> protector(cachedResourceLoader->document()); if (!request->isMultipart()) cachedResourceLoader->decrementRequestCount(request->cachedResource()); diff --git a/WebCore/manual-tests/NPN_Invoke/NPN_Invoke.xcodeproj/project.pbxproj b/WebCore/manual-tests/NPN_Invoke/NPN_Invoke.xcodeproj/project.pbxproj index 22c6659..a8a08f3 100644 --- a/WebCore/manual-tests/NPN_Invoke/NPN_Invoke.xcodeproj/project.pbxproj +++ b/WebCore/manual-tests/NPN_Invoke/NPN_Invoke.xcodeproj/project.pbxproj @@ -113,7 +113,14 @@ isa = PBXProject; buildConfigurationList = 149C298708902C53008A9EFC /* Build configuration list for PBXProject "NPN_Invoke" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 089C166AFE841209C02AAC07 /* NetscapeMoviePlugIn */; projectDirPath = ""; projectRoot = ""; diff --git a/WebCore/manual-tests/autocorrection/continue-typing-to-dismiss-reversion.html b/WebCore/manual-tests/autocorrection/continue-typing-to-dismiss-reversion.html new file mode 100644 index 0000000..b8521c0 --- /dev/null +++ b/WebCore/manual-tests/autocorrection/continue-typing-to-dismiss-reversion.html @@ -0,0 +1,49 @@ +<html> +<head> + +<style> +.editing { + border: 2px solid red; + padding: 12px; + font-size: 24px; +} +</style> +<script src=../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script> + +<script> +function editingTest() { + typeCharacterCommand('t'); + typeCharacterCommand('h'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + typeCharacterCommand('m'); + typeCharacterCommand('e'); + typeCharacterCommand('s'); + typeCharacterCommand('a'); + typeCharacterCommand('g'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + execMoveSelectionBackwardByCharacterCommand(); +} + +</script> + +<title>Continue Typing to Dismiss Reversion Panel Test</title> +</head> +<body> +<div><p>This test verifies that, after reversion panel is shown, continue typing will dismiss the reversion panel.</p> +<p>After seeing the reversion panel, start typing (excluding whitespace). You should see the panel being +dismissed once you start typing.</p> +<p style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously +frequently revert 'message' to 'mesage'. To fix this, remove all files in ~/Library/Spelling, then kill AppleSpell.service process.</p> +<div contenteditable id="root" class="editing"> +<span id="test"></span> +</div> + + +<script> +runEditingTest(); +</script> + +</body> +</html> diff --git a/WebCore/manual-tests/autocorrection/delete-to-dismiss-reversion.html b/WebCore/manual-tests/autocorrection/delete-to-dismiss-reversion.html new file mode 100644 index 0000000..c39b2ac --- /dev/null +++ b/WebCore/manual-tests/autocorrection/delete-to-dismiss-reversion.html @@ -0,0 +1,49 @@ +<html> +<head> + +<style> +.editing { + border: 2px solid red; + padding: 12px; + font-size: 24px; +} +</style> +<script src=../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script> + +<script> +function editingTest() { + typeCharacterCommand('t'); + typeCharacterCommand('h'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + typeCharacterCommand('m'); + typeCharacterCommand('e'); + typeCharacterCommand('s'); + typeCharacterCommand('a'); + typeCharacterCommand('g'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + execMoveSelectionBackwardByCharacterCommand(); +} + +</script> + +<title>Delete to Dismiss Reversion Panel Test</title> +</head> +<body> +<div><p>This test verifies that, after reversion panel is shown, continue deleting the word will dismiss the reversion panel.</p> +<p>After seeing the reversion panel, start deleting the corrected word character by character. You should see the panel being +dismissed once you start deleting.</p> +<p style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously +frequently revert 'message' to 'mesage'. To fix this, remove all files in ~/Library/Spelling, then kill AppleSpell.service process.</p> +<div contenteditable id="root" class="editing"> +<span id="test"></span> +</div> + + +<script> +runEditingTest(); +</script> + +</body> +</html> diff --git a/WebCore/manual-tests/autocorrection/delete-to-end-of-word-to-show-reversion.html b/WebCore/manual-tests/autocorrection/delete-to-end-of-word-to-show-reversion.html new file mode 100644 index 0000000..320ed8c --- /dev/null +++ b/WebCore/manual-tests/autocorrection/delete-to-end-of-word-to-show-reversion.html @@ -0,0 +1,49 @@ +<html> +<head> + +<style> +.editing { + border: 2px solid red; + padding: 12px; + font-size: 24px; +} +</style> +<script src=../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script> + +<script> +function editingTest() { + typeCharacterCommand('t'); + typeCharacterCommand('h'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + typeCharacterCommand('m'); + typeCharacterCommand('e'); + typeCharacterCommand('s'); + typeCharacterCommand('a'); + typeCharacterCommand('g'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + execDeleteCommand(); +} + +</script> + +<title>Delete to End of Word to Show Reversion Panel Test</title> +</head> +<body> +<div><p>This test verifies that reversion panel is shown when user moves carret to previously corrected word using delete key.</p> +<p>After seeing the reversion panel, press ESC key, then space key. You should see the phrase "the mesage" +where "mesage" has red mispell underline. </p> +<p style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously +frequently revert 'message' to 'mesage'. To fix this, remove all files in ~/Library/Spelling, then kill AppleSpell.service process.</p> +<div contenteditable id="root" class="editing"> +<span id="test"></span> +</div> + + +<script> +runEditingTest(); +</script> + +</body> +</html> diff --git a/WebCore/manual-tests/autocorrection/move-to-end-of-word-to-show-reversion.html b/WebCore/manual-tests/autocorrection/move-to-end-of-word-to-show-reversion.html new file mode 100644 index 0000000..8ca2a6b --- /dev/null +++ b/WebCore/manual-tests/autocorrection/move-to-end-of-word-to-show-reversion.html @@ -0,0 +1,49 @@ +<html> +<head> + +<style> +.editing { + border: 2px solid red; + padding: 12px; + font-size: 24px; +} +</style> +<script src=../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script> + +<script> +function editingTest() { + typeCharacterCommand('t'); + typeCharacterCommand('h'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + typeCharacterCommand('m'); + typeCharacterCommand('e'); + typeCharacterCommand('s'); + typeCharacterCommand('a'); + typeCharacterCommand('g'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + execMoveSelectionBackwardByCharacterCommand(); +} + +</script> + +<title>Move to End of Word to Show Reversion Panel Test</title> +</head> +<body> +<div><p>This test verifies that reversion panel is shown when user moves carret to previously corrected word</p> +<p>After seeing the reversion panel, press ESC key, then space key. You should see the phrase "the mesage" +where "mesage" has red mispell underline. </p> +<p style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously +frequently revert 'message' to 'mesage'. To fix this, remove all files in ~/Library/Spelling, then kill AppleSpell.service process.</p> +<div contenteditable id="root" class="editing"> +<span id="test"></span> +</div> + + +<script> +runEditingTest(); +</script> + +</body> +</html> diff --git a/WebCore/manual-tests/autocorrection/type-whitespace-to-dismiss-reversion.html b/WebCore/manual-tests/autocorrection/type-whitespace-to-dismiss-reversion.html new file mode 100644 index 0000000..eeea0f7 --- /dev/null +++ b/WebCore/manual-tests/autocorrection/type-whitespace-to-dismiss-reversion.html @@ -0,0 +1,50 @@ +<html> +<head> + +<style> +.editing { + border: 2px solid red; + padding: 12px; + font-size: 24px; +} +</style> +<script src=../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script> + +<script> +function editingTest() { + typeCharacterCommand('t'); + typeCharacterCommand('h'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + typeCharacterCommand('m'); + typeCharacterCommand('e'); + typeCharacterCommand('s'); + typeCharacterCommand('a'); + typeCharacterCommand('g'); + typeCharacterCommand('e'); + typeCharacterCommand(' '); + execMoveSelectionBackwardByCharacterCommand(); +} + +</script> + +<title>Type Whitespace to Dismiss Reversion Panel Test</title> +</head> +<body> +<div><p>This test verifies that, after reversion panel is shown, typing whitespace will dismiss the reversion panel. +It also keep the existing autocorrection underline.</p> +<p>After seeing the reversion panel, type whitespace. You should see the panel being dismissed once you start typing. +However, the word "message" still has blue underline.</p> +<p style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously +frequently revert 'message' to 'mesage'. To fix this, remove all files in ~/Library/Spelling, then kill AppleSpell.service process.</p> +<div contenteditable id="root" class="editing"> +<span id="test"></span> +</div> + + +<script> +runEditingTest(); +</script> + +</body> +</html> diff --git a/WebCore/manual-tests/frames/nested-iframe-blit-on-scroll.html b/WebCore/manual-tests/frames/nested-iframe-blit-on-scroll.html new file mode 100644 index 0000000..6d4d30e --- /dev/null +++ b/WebCore/manual-tests/frames/nested-iframe-blit-on-scroll.html @@ -0,0 +1,31 @@ +<html> +<head> + <style type="text/css"> + iframe { + position: relative; + z-index: 1; + left: 10px; + top: 10px; + border: 1px solid black; + } + + #overlap { + position: absolute; + width: 100px; + height: 100px; + z-index: 2; + left: 10px; + top: 100px; + background-color: blue; + } + p { + margin-top: 50px; + } + </style> +</head> +<body> +<div id="overlap"></div> +<iframe id="frame" src="resources/blit-on-scroll-subframe.html" scrolling="no"></iframe> +<p>The blue box should not get "smeared" when you scroll the inner iframe.</p> +</body> +</html> diff --git a/WebCore/manual-tests/frames/resources/blit-on-scroll-subframe.html b/WebCore/manual-tests/frames/resources/blit-on-scroll-subframe.html new file mode 100644 index 0000000..b0dc4b9 --- /dev/null +++ b/WebCore/manual-tests/frames/resources/blit-on-scroll-subframe.html @@ -0,0 +1,10 @@ +<style type="text/css" media="screen"> + iframe { + border: 1px solid black; + } + + body { + height: 1000px; + } +</style> +<iframe id="subframe" src="blit-on-scroll-subsubframe.html" width="280" height="250"></iframe> diff --git a/WebCore/manual-tests/frames/resources/blit-on-scroll-subsubframe.html b/WebCore/manual-tests/frames/resources/blit-on-scroll-subsubframe.html new file mode 100644 index 0000000..9084096 --- /dev/null +++ b/WebCore/manual-tests/frames/resources/blit-on-scroll-subsubframe.html @@ -0,0 +1,10 @@ +<style type="text/css" media="screen"> + iframe { + padding: 10px; + } + + body { + background-color: gray; + height: 1000px; + } +</style> diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp index 762b087..83d0f85 100644 --- a/WebCore/page/Chrome.cpp +++ b/WebCore/page/Chrome.cpp @@ -87,6 +87,13 @@ void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, con m_client->scroll(scrollDelta, rectToScroll, clipRect); } +#if ENABLE(TILED_BACKING_STORE) +void Chrome::delegatedScrollRequested(const IntSize& scrollDelta) +{ + m_client->delegatedScrollRequested(scrollDelta); +} +#endif + IntPoint Chrome::screenToWindow(const IntPoint& point) const { return m_client->screenToWindow(point); @@ -163,6 +170,11 @@ void Chrome::focusedNodeChanged(Node* node) const m_client->focusedNodeChanged(node); } +void Chrome::focusedFrameChanged(Frame* frame) const +{ + m_client->focusedFrameChanged(frame); +} + Page* Chrome::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction& action) const { Page* newPage = m_client->createWindow(frame, request, features, action); @@ -502,4 +514,11 @@ PassRefPtr<SearchPopupMenu> Chrome::createSearchPopupMenu(PopupMenuClient* clien return m_client->createSearchPopupMenu(client); } +#if ENABLE(CONTEXT_MENUS) +void Chrome::showContextMenu() +{ + m_client->showContextMenu(); +} +#endif + } // namespace WebCore diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h index 9f43b11..f2c5db4 100644 --- a/WebCore/page/Chrome.h +++ b/WebCore/page/Chrome.h @@ -70,6 +70,9 @@ namespace WebCore { virtual void invalidateContentsAndWindow(const IntRect&, bool); virtual void invalidateContentsForSlowScroll(const IntRect&, bool); virtual void scroll(const IntSize&, const IntRect&, const IntRect&); +#if ENABLE(TILED_BACKING_STORE) + virtual void delegatedScrollRequested(const IntSize& scrollDelta); +#endif virtual IntPoint screenToWindow(const IntPoint&) const; virtual IntRect windowToScreen(const IntRect&) const; virtual PlatformPageClient platformPageClient() const; @@ -94,6 +97,7 @@ namespace WebCore { void takeFocus(FocusDirection) const; void focusedNodeChanged(Node*) const; + void focusedFrameChanged(Frame*) const; Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&) const; void show() const; @@ -155,6 +159,10 @@ namespace WebCore { PassRefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const; PassRefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const; +#if ENABLE(CONTEXT_MENUS) + void showContextMenu(); +#endif + private: Page* m_page; ChromeClient* m_client; diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h index 3e6f8d9..0725f46 100644 --- a/WebCore/page/ChromeClient.h +++ b/WebCore/page/ChromeClient.h @@ -94,6 +94,7 @@ namespace WebCore { virtual void takeFocus(FocusDirection) = 0; virtual void focusedNodeChanged(Node*) = 0; + virtual void focusedFrameChanged(Frame*) = 0; // The Frame pointer provides the ChromeClient with context about which // Frame wants to create the new Page. Also, the newly created window @@ -140,6 +141,9 @@ namespace WebCore { virtual void invalidateContentsAndWindow(const IntRect&, bool) = 0; virtual void invalidateContentsForSlowScroll(const IntRect&, bool) = 0; virtual void scroll(const IntSize&, const IntRect&, const IntRect&) = 0; +#if ENABLE(TILED_BACKING_STORE) + virtual void delegatedScrollRequested(const IntSize&) = 0; +#endif virtual IntPoint screenToWindow(const IntPoint&) const = 0; virtual IntRect windowToScreen(const IntRect&) const = 0; virtual PlatformPageClient platformPageClient() const = 0; @@ -269,6 +273,10 @@ namespace WebCore { virtual PassRefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const = 0; virtual PassRefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const = 0; +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() = 0; +#endif + virtual void postAccessibilityNotification(AccessibilityObject*, AXObjectCache::AXNotification) { } #if ENABLE(ANDROID_INSTALLABLE_WEB_APPS) diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp index 2d4cc98..1481ebd 100644 --- a/WebCore/page/Console.cpp +++ b/WebCore/page/Console.cpp @@ -41,6 +41,7 @@ #include "PageGroup.h" #include "PlatformString.h" +#include "ScriptArguments.h" #include "ScriptCallStack.h" #include "ScriptProfile.h" #include "ScriptProfiler.h" @@ -77,19 +78,6 @@ static void printSourceURLAndLine(const String& sourceURL, unsigned lineNumber) } } -static bool getFirstArgumentAsString(ScriptState* scriptState, const ScriptCallFrame& callFrame, String& result, bool checkForNullOrUndefined = false) -{ - if (!callFrame.argumentCount()) - return false; - - const ScriptValue& value = callFrame.argumentAt(0); - if (checkForNullOrUndefined && (value.isNull() || value.isUndefined())) - return false; - - result = value.toString(scriptState); - return true; -} - static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel level) { const char* sourceString; @@ -144,7 +132,12 @@ static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel printf("%s %s:", sourceString, levelString); } -void Console::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL, ScriptCallStack* callStack) +void Console::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL) +{ + addMessage(source, type, level, message, lineNumber, sourceURL, 0); +} + +void Console::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL, PassOwnPtr<ScriptCallStack> callStack) { Page* page = this->page(); if (!page) @@ -155,7 +148,7 @@ void Console::addMessage(MessageSource source, MessageType type, MessageLevel le #if ENABLE(INSPECTOR) if (callStack) - page->inspectorController()->addMessageToConsole(source, type, level, callStack, message); + page->inspectorController()->addMessageToConsole(source, type, level, message, 0, callStack); else page->inspectorController()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL); #endif @@ -169,7 +162,7 @@ void Console::addMessage(MessageSource source, MessageType type, MessageLevel le printf(" %s\n", message.utf8().data()); } -void Console::addMessage(MessageType type, MessageLevel level, ScriptCallStack* callStack, bool acceptNoArguments) +void Console::addMessage(MessageType type, MessageLevel level, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack, bool acceptNoArguments) { Page* page = this->page(); if (!page) @@ -177,15 +170,15 @@ void Console::addMessage(MessageType type, MessageLevel level, ScriptCallStack* const ScriptCallFrame& lastCaller = callStack->at(0); - if (!acceptNoArguments && !lastCaller.argumentCount()) + if (!acceptNoArguments && !arguments->argumentCount()) return; String message; - if (getFirstArgumentAsString(callStack->state(), lastCaller, message)) + if (arguments->getFirstArgumentAsString(message)) page->chrome()->client()->addMessageToConsole(JSMessageSource, type, level, message, lastCaller.lineNumber(), lastCaller.sourceURL()); #if ENABLE(INSPECTOR) - page->inspectorController()->addMessageToConsole(JSMessageSource, type, level, callStack, message); + page->inspectorController()->addMessageToConsole(JSMessageSource, type, level, message, arguments, callStack); #endif if (!Console::shouldPrintExceptions()) @@ -194,49 +187,49 @@ void Console::addMessage(MessageType type, MessageLevel level, ScriptCallStack* printSourceURLAndLine(lastCaller.sourceURL(), 0); printMessageSourceAndLevelPrefix(JSMessageSource, level); - for (unsigned i = 0; i < lastCaller.argumentCount(); ++i) { + for (unsigned i = 0; i < arguments->argumentCount(); ++i) { String argAsString; - if (lastCaller.argumentAt(i).getString(callStack->state(), argAsString)) + if (arguments->argumentAt(i).getString(arguments->globalState(), argAsString)) printf(" %s", argAsString.utf8().data()); } printf("\n"); } -void Console::debug(ScriptCallStack* callStack) +void Console::debug(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { // In Firebug, console.debug has the same behavior as console.log. So we'll do the same. - log(callStack); + log(arguments, callStack); } -void Console::error(ScriptCallStack* callStack) +void Console::error(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { - addMessage(LogMessageType, ErrorMessageLevel, callStack); + addMessage(LogMessageType, ErrorMessageLevel, arguments, callStack); } -void Console::info(ScriptCallStack* callStack) +void Console::info(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { - log(callStack); + log(arguments, callStack); } -void Console::log(ScriptCallStack* callStack) +void Console::log(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { - addMessage(LogMessageType, LogMessageLevel, callStack); + addMessage(LogMessageType, LogMessageLevel, arguments, callStack); } -void Console::dir(ScriptCallStack* callStack) +void Console::dir(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { - addMessage(ObjectMessageType, LogMessageLevel, callStack); + addMessage(ObjectMessageType, LogMessageLevel, arguments, callStack); } -void Console::dirxml(ScriptCallStack* callStack) +void Console::dirxml(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { // The standard behavior of our console.log will print the DOM tree for nodes. - log(callStack); + log(arguments, callStack); } -void Console::trace(ScriptCallStack* callStack) +void Console::trace(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { - addMessage(TraceMessageType, LogMessageLevel, callStack, true); + addMessage(TraceMessageType, LogMessageLevel, arguments, callStack, true); if (!shouldPrintExceptions()) return; @@ -248,15 +241,15 @@ void Console::trace(ScriptCallStack* callStack) } } -void Console::assertCondition(bool condition, ScriptCallStack* callStack) +void Console::assertCondition(bool condition, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { if (condition) return; - addMessage(AssertMessageType, ErrorMessageLevel, callStack, true); + addMessage(AssertMessageType, ErrorMessageLevel, arguments, callStack, true); } -void Console::count(ScriptCallStack* callStack) +void Console::count(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { #if ENABLE(INSPECTOR) Page* page = this->page(); @@ -267,7 +260,7 @@ void Console::count(ScriptCallStack* callStack) // Follow Firebug's behavior of counting with null and undefined title in // the same bucket as no argument String title; - getFirstArgumentAsString(callStack->state(), lastCaller, title); + arguments->getFirstArgumentAsString(title); page->inspectorController()->count(title, lastCaller.lineNumber(), lastCaller.sourceURL()); #else @@ -275,20 +268,19 @@ void Console::count(ScriptCallStack* callStack) #endif } -void Console::markTimeline(ScriptCallStack* callStack) +void Console::markTimeline(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack>) { #if ENABLE(INSPECTOR) Page* page = this->page(); if (!page) return; - const ScriptCallFrame& lastCaller = callStack->at(0); String message; - getFirstArgumentAsString(callStack->state(), lastCaller, message); + arguments->getFirstArgumentAsString(message); page->inspectorController()->markTimeline(message); #else - UNUSED_PARAM(callStack); + UNUSED_PARAM(arguments); #endif } @@ -321,7 +313,7 @@ String Console::lastWMLErrorMessage() const #if ENABLE(JAVASCRIPT_DEBUGGER) -void Console::profile(const String& title, ScriptCallStack* callStack) +void Console::profile(const String& title, ScriptState* state, PassOwnPtr<ScriptCallStack> callStack) { Page* page = this->page(); if (!page) @@ -342,7 +334,7 @@ void Console::profile(const String& title, ScriptCallStack* callStack) resolvedTitle = ""; #endif - ScriptProfiler::start(callStack->state(), resolvedTitle); + ScriptProfiler::start(state, resolvedTitle); #if ENABLE(INSPECTOR) const ScriptCallFrame& lastCaller = callStack->at(0); @@ -350,7 +342,7 @@ void Console::profile(const String& title, ScriptCallStack* callStack) #endif } -void Console::profileEnd(const String& title, ScriptCallStack* callStack) +void Console::profileEnd(const String& title, ScriptState* state, PassOwnPtr<ScriptCallStack> callStack) { Page* page = this->page(); if (!page) @@ -362,7 +354,7 @@ void Console::profileEnd(const String& title, ScriptCallStack* callStack) return; #endif - RefPtr<ScriptProfile> profile = ScriptProfiler::stop(callStack->state(), title); + RefPtr<ScriptProfile> profile = ScriptProfiler::stop(state, title); if (!profile) return; @@ -394,7 +386,7 @@ void Console::time(const String& title) #endif } -void Console::timeEnd(const String& title, ScriptCallStack* callStack) +void Console::timeEnd(const String& title, PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack> callStack) { #if ENABLE(INSPECTOR) Page* page = this->page(); @@ -420,28 +412,30 @@ void Console::timeEnd(const String& title, ScriptCallStack* callStack) #endif } -void Console::group(ScriptCallStack* callStack) +void Console::group(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { #if ENABLE(INSPECTOR) Page* page = this->page(); if (!page) return; - page->inspectorController()->startGroup(JSMessageSource, callStack); + page->inspectorController()->startGroup(arguments, callStack); #else + UNUSED_PARAM(arguments); UNUSED_PARAM(callStack); #endif } -void Console::groupCollapsed(ScriptCallStack* callStack) +void Console::groupCollapsed(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { #if ENABLE(INSPECTOR) Page* page = this->page(); if (!page) return; - page->inspectorController()->startGroup(JSMessageSource, callStack, true); + page->inspectorController()->startGroup(arguments, callStack, true); #else + UNUSED_PARAM(arguments); UNUSED_PARAM(callStack); #endif } @@ -457,9 +451,22 @@ void Console::groupEnd() #endif } -void Console::warn(ScriptCallStack* callStack) +bool Console::shouldCaptureFullStackTrace() const +{ +#if ENABLE(INSPECTOR) + Page* page = this->page(); + if (!page) + return false; + + return page->inspectorController()->hasFrontend(); +#else + return false; +#endif +} + +void Console::warn(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) { - addMessage(LogMessageType, WarningMessageLevel, callStack); + addMessage(LogMessageType, WarningMessageLevel, arguments, callStack); } MemoryInfo* Console::memory() const diff --git a/WebCore/page/Console.h b/WebCore/page/Console.h index ab62525..92fee59 100644 --- a/WebCore/page/Console.h +++ b/WebCore/page/Console.h @@ -32,6 +32,7 @@ #include "MemoryInfo.h" #include "PlatformString.h" #include "ScriptProfile.h" +#include "ScriptState.h" #include <wtf/Forward.h> #include <wtf/PassRefPtr.h> @@ -39,6 +40,8 @@ namespace WebCore { +class ScriptArguments; + #if ENABLE(JAVASCRIPT_DEBUGGER) typedef Vector<RefPtr<ScriptProfile> > ProfilesArray; #endif @@ -83,44 +86,44 @@ public: Frame* frame() const; void disconnectFrame(); - void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL, ScriptCallStack* callStack = 0); - - void debug(ScriptCallStack*); - void error(ScriptCallStack*); - void info(ScriptCallStack*); - void log(ScriptCallStack*); - void warn(ScriptCallStack*); - void dir(ScriptCallStack*); - void dirxml(ScriptCallStack*); - void trace(ScriptCallStack*); - void assertCondition(bool condition, ScriptCallStack*); - void count(ScriptCallStack*); - void markTimeline(ScriptCallStack*); + void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL); + void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL, PassOwnPtr<ScriptCallStack> callStack); + + void debug(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void error(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void info(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void log(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void warn(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void dir(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void dirxml(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void trace(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void assertCondition(bool condition, PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void count(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void markTimeline(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); #if ENABLE(WML) String lastWMLErrorMessage() const; #endif #if ENABLE(JAVASCRIPT_DEBUGGER) - void profile(const String&, ScriptCallStack*); - void profileEnd(const String&, ScriptCallStack*); + const ProfilesArray& profiles() const { return m_profiles; } + void profile(const String&, ScriptState*, PassOwnPtr<ScriptCallStack>); + void profileEnd(const String&, ScriptState*, PassOwnPtr<ScriptCallStack>); #endif void time(const String&); - void timeEnd(const String&, ScriptCallStack*); - void group(ScriptCallStack*); - void groupCollapsed(ScriptCallStack*); + void timeEnd(const String&, PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void group(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); + void groupCollapsed(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>); void groupEnd(); + bool shouldCaptureFullStackTrace() const; + static bool shouldPrintExceptions(); static void setShouldPrintExceptions(bool); -#if ENABLE(JAVASCRIPT_DEBUGGER) - const ProfilesArray& profiles() const { return m_profiles; } -#endif - MemoryInfo* memory() const; private: inline Page* page() const; - void addMessage(MessageType, MessageLevel, ScriptCallStack*, bool acceptNoArguments = false); + void addMessage(MessageType, MessageLevel, PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>, bool acceptNoArguments = false); Console(Frame*); diff --git a/WebCore/page/Console.idl b/WebCore/page/Console.idl index 52528f1..9f03911 100644 --- a/WebCore/page/Console.idl +++ b/WebCore/page/Console.idl @@ -30,10 +30,6 @@ module window { interface [OmitConstructor] Console { -#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER - readonly attribute [CustomGetter] Array profiles; -#endif - [CustomArgumentHandling] void debug(); [CustomArgumentHandling] void error(); [CustomArgumentHandling] void info(); @@ -51,8 +47,9 @@ module window { #endif #if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER - [CustomArgumentHandling] void profile(in [ConvertUndefinedOrNullToNullString] DOMString title); - [CustomArgumentHandling] void profileEnd(in [ConvertUndefinedOrNullToNullString] DOMString title); + readonly attribute [CustomGetter] Array profiles; + [Custom] void profile(in DOMString title); + [Custom] void profileEnd(in DOMString title); #endif void time(in [ConvertUndefinedOrNullToNullString] DOMString title); diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp index 08c3d2e..1f71d09 100644 --- a/WebCore/page/ContextMenuController.cpp +++ b/WebCore/page/ContextMenuController.cpp @@ -29,6 +29,7 @@ #if ENABLE(CONTEXT_MENUS) +#include "BackForwardController.h" #include "Chrome.h" #include "ContextMenu.h" #include "ContextMenuClient.h" @@ -222,11 +223,11 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item) break; case ContextMenuItemTagGoBack: if (Page* page = frame->page()) - page->goBackOrForward(-1); + page->backForward()->goBackOrForward(-1); break; case ContextMenuItemTagGoForward: if (Page* page = frame->page()) - page->goBackOrForward(1); + page->backForward()->goBackOrForward(1); break; case ContextMenuItemTagStop: frame->loader()->stop(); diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp index c7b8911..5f878a5 100644 --- a/WebCore/page/DOMWindow.cpp +++ b/WebCore/page/DOMWindow.cpp @@ -27,6 +27,7 @@ #include "DOMWindow.h" #include "AbstractDatabase.h" +#include "BackForwardController.h" #include "Base64.h" #include "BarInfo.h" #include "BeforeUnloadEvent.h" @@ -873,7 +874,7 @@ void DOMWindow::close() Settings* settings = m_frame->settings(); bool allowScriptsToCloseWindows = settings && settings->allowScriptsToCloseWindows(); - if (!(page->openedByDOM() || page->getHistoryLength() <= 1 || allowScriptsToCloseWindows)) + if (!(page->openedByDOM() || page->backForward()->count() <= 1 || allowScriptsToCloseWindows)) return; if (!m_frame->loader()->shouldClose()) diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl index 4db0944..cea4710 100644 --- a/WebCore/page/DOMWindow.idl +++ b/WebCore/page/DOMWindow.idl @@ -455,6 +455,7 @@ module window { attribute HTMLObjectElementConstructor HTMLObjectElement; attribute HTMLOptGroupElementConstructor HTMLOptGroupElement; attribute HTMLOptionElementConstructor HTMLOptionElement; + attribute HTMLOutputElementConstructor HTMLOutputElement; attribute HTMLParagraphElementConstructor HTMLParagraphElement; attribute HTMLParamElementConstructor HTMLParamElement; attribute HTMLPreElementConstructor HTMLPreElement; diff --git a/WebCore/page/EditorClient.h b/WebCore/page/EditorClient.h index 97b0902..61bdd41 100644 --- a/WebCore/page/EditorClient.h +++ b/WebCore/page/EditorClient.h @@ -27,6 +27,7 @@ #ifndef EditorClient_h #define EditorClient_h +#include "CorrectionPanelInfo.h" #include "EditorInsertAction.h" #include "FloatRect.h" #include "PlatformString.h" @@ -188,9 +189,9 @@ public: virtual void checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<TextCheckingResult>& results) = 0; #endif -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - virtual void showCorrectionPanel(const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacmentString, Editor*) = 0; - virtual void dismissCorrectionPanel(bool correctionAccepted) = 0; +#if SUPPORT_AUTOCORRECTION_PANEL + virtual void showCorrectionPanel(CorrectionPanelInfo::PanelType, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacmentString, Editor*) = 0; + virtual void dismissCorrectionPanel(CorrectionWasRejectedOrNot) = 0; virtual bool isShowingCorrectionPanel() = 0; #endif diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index 4046bd8..e12d9eb 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -2732,7 +2732,7 @@ void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, Keybo if (!page) return; - if (!page->settings() || !page->settings()->isSpatialNavigationEnabled()) + if (!isSpatialNavigationEnabled(m_frame)) return; // Arrows and other possible directional navigation keys can be used in design diff --git a/WebCore/page/EventSource.cpp b/WebCore/page/EventSource.cpp index 01af087..5e3141d 100644 --- a/WebCore/page/EventSource.cpp +++ b/WebCore/page/EventSource.cpp @@ -36,7 +36,7 @@ #include "EventSource.h" -#include "Cache.h" +#include "MemoryCache.h" #include "DOMWindow.h" #include "Event.h" #include "EventException.h" diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp index 622bf39..8ee5dff 100644 --- a/WebCore/page/FocusController.cpp +++ b/WebCore/page/FocusController.cpp @@ -86,6 +86,7 @@ FocusController::FocusController(Page* page) void FocusController::setFocusedFrame(PassRefPtr<Frame> frame) { + ASSERT(!frame || frame->page() == m_page); if (m_focusedFrame == frame || m_isChangingFocusedFrame) return; @@ -107,6 +108,8 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame) newFrame->document()->dispatchWindowEvent(Event::create(eventNames().focusEvent, false, false)); } + m_page->chrome()->focusedFrameChanged(newFrame.get()); + m_isChangingFocusedFrame = false; } diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp index a4d33a3..c38a32c 100644 --- a/WebCore/page/Frame.cpp +++ b/WebCore/page/Frame.cpp @@ -280,6 +280,7 @@ void Frame::setView(PassRefPtr<FrameView> view) void Frame::setDocument(PassRefPtr<Document> newDoc) { + ASSERT(!newDoc || newDoc->frame()); if (m_doc && m_doc->attached() && !m_doc->inPageCache()) { // FIXME: We don't call willRemove here. Why is that OK? m_doc->detach(); @@ -506,6 +507,9 @@ void Frame::injectUserScripts(UserScriptInjectionTime injectionTime) { if (!m_page) return; + + if (loader()->stateMachine()->creatingInitialEmptyDocument()) + return; // Walk the hashtable. Inject by world. const UserScriptMap* userScripts = m_page->group().userScripts(); @@ -641,7 +645,7 @@ void Frame::clearTimers(FrameView *view, Document *document) if (view) { view->unscheduleRelayout(); if (view->frame()) { - view->frame()->animation()->suspendAnimations(document); + view->frame()->animation()->suspendAnimationsForDocument(document); view->frame()->eventHandler()->stopAutoscrollTimer(); } } @@ -717,11 +721,12 @@ void Frame::transferChildFrameToNewDocument() Page* newPage = newParent ? newParent->page() : 0; Page* oldPage = m_page; if (m_page != newPage) { - if (page()->focusController()->focusedFrame() == this) - page()->focusController()->setFocusedFrame(0); + if (m_page) { + if (m_page->focusController()->focusedFrame() == this) + m_page->focusController()->setFocusedFrame(0); - if (m_page) - m_page->decrementFrameCount(); + m_page->decrementFrameCount(); + } m_page = newPage; diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h index 59e1556..832a3c2 100644 --- a/WebCore/page/Frame.h +++ b/WebCore/page/Frame.h @@ -98,7 +98,7 @@ namespace WebCore { FrameTree* tree() const; AnimationController* animation() const; ScriptController* script(); - + RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame. RenderPart* ownerRenderer() const; // Renderer for the element that contains this frame. diff --git a/WebCore/page/FrameTree.cpp b/WebCore/page/FrameTree.cpp index 1f0604c..0e15379 100644 --- a/WebCore/page/FrameTree.cpp +++ b/WebCore/page/FrameTree.cpp @@ -1,4 +1,5 @@ /* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. * Copyright (C) 2006 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or @@ -40,17 +41,19 @@ FrameTree::~FrameTree() void FrameTree::setName(const AtomicString& name) { + m_name = name; if (!parent()) { - m_name = name; + m_uniqueName = name; return; } - m_name = AtomicString(); // Remove our old frame name so it's not considered in uniqueChildName. - m_name = parent()->tree()->uniqueChildName(name); + m_uniqueName = AtomicString(); // Remove our old frame name so it's not considered in uniqueChildName. + m_uniqueName = parent()->tree()->uniqueChildName(name); } void FrameTree::clearName() { m_name = AtomicString(); + m_uniqueName = AtomicString(); } Frame* FrameTree::parent(bool checkForDisconnectedFrame) const @@ -119,19 +122,19 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const Vector<Frame*, 16> chain; Frame* frame; for (frame = m_thisFrame; frame; frame = frame->tree()->parent()) { - if (frame->tree()->name().startsWith(framePathPrefix)) + if (frame->tree()->uniqueName().startsWith(framePathPrefix)) break; chain.append(frame); } String name; name += framePathPrefix; if (frame) - name += frame->tree()->name().string().substring(framePathPrefixLength, - frame->tree()->name().length() - framePathPrefixLength - framePathSuffixLength); + name += frame->tree()->uniqueName().string().substring(framePathPrefixLength, + frame->tree()->uniqueName().length() - framePathPrefixLength - framePathSuffixLength); for (int i = chain.size() - 1; i >= 0; --i) { frame = chain[i]; name += "/"; - name += frame->tree()->name(); + name += frame->tree()->uniqueName(); } // Suffix buffer has more than enough space for: @@ -159,7 +162,7 @@ Frame* FrameTree::child(unsigned index) const Frame* FrameTree::child(const AtomicString& name) const { for (Frame* child = firstChild(); child; child = child->tree()->nextSibling()) - if (child->tree()->name() == name) + if (child->tree()->uniqueName() == name) return child; return 0; } @@ -181,7 +184,7 @@ Frame* FrameTree::find(const AtomicString& name) const // Search subtree starting with this frame first. for (Frame* frame = m_thisFrame; frame; frame = frame->tree()->traverseNext(m_thisFrame)) - if (frame->tree()->name() == name) + if (frame->tree()->uniqueName() == name) return frame; // Search the entire tree for this page next. @@ -192,7 +195,7 @@ Frame* FrameTree::find(const AtomicString& name) const return 0; for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) - if (frame->tree()->name() == name) + if (frame->tree()->uniqueName() == name) return frame; // Search the entire tree of each of the other pages in this namespace. @@ -203,7 +206,7 @@ Frame* FrameTree::find(const AtomicString& name) const Page* otherPage = *it; if (otherPage != page) { for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) { - if (frame->tree()->name() == name) + if (frame->tree()->uniqueName() == name) return frame; } } diff --git a/WebCore/page/FrameTree.h b/WebCore/page/FrameTree.h index b97aab6..58b7c1f 100644 --- a/WebCore/page/FrameTree.h +++ b/WebCore/page/FrameTree.h @@ -39,6 +39,7 @@ namespace WebCore { ~FrameTree(); const AtomicString& name() const { return m_name; } + const AtomicString& uniqueName() const { return m_uniqueName; } void setName(const AtomicString&); void clearName(); Frame* parent(bool checkForDisconnectedFrame = false) const; @@ -73,7 +74,8 @@ namespace WebCore { Frame* m_thisFrame; Frame* m_parent; - AtomicString m_name; + AtomicString m_name; // The actual frame name (may be empty). + AtomicString m_uniqueName; // FIXME: use ListRefPtr? RefPtr<Frame> m_nextSibling; diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp index 7bc29d5..bf6bd55 100644 --- a/WebCore/page/FrameView.cpp +++ b/WebCore/page/FrameView.cpp @@ -358,6 +358,16 @@ void FrameView::setMarginHeight(int h) m_margins.setHeight(h); } +bool FrameView::delegatesScrolling() +{ + ASSERT(m_frame); + + if (parent()) + return false; + + return m_frame->settings() && m_frame->settings()->shouldDelegateScrolling(); +} + bool FrameView::avoidScrollbarCreation() { ASSERT(m_frame); @@ -568,6 +578,37 @@ bool FrameView::hasCompositedContent() const return false; } +bool FrameView::hasCompositedContentIncludingDescendants() const +{ +#if USE(ACCELERATED_COMPOSITING) + for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) { + RenderView* renderView = frame->contentRenderer(); + RenderLayerCompositor* compositor = renderView ? renderView->compositor() : 0; + if (compositor) { + if (compositor->inCompositingMode()) + return true; + + if (!RenderLayerCompositor::allowsIndependentlyCompositedIFrames(this)) + break; + } + } +#endif + return false; +} + +bool FrameView::hasCompositingAncestor() const +{ +#if USE(ACCELERATED_COMPOSITING) + for (Frame* frame = m_frame->tree()->parent(); frame; frame = frame->tree()->parent()) { + if (FrameView* view = frame->view()) { + if (view->hasCompositedContent()) + return true; + } + } +#endif + return false; +} + // Sometimes (for plug-ins) we need to eagerly go into compositing mode. void FrameView::enterCompositingMode() { @@ -584,10 +625,15 @@ bool FrameView::isEnclosedInCompositingLayer() const { #if USE(ACCELERATED_COMPOSITING) RenderObject* frameOwnerRenderer = m_frame->ownerRenderer(); - return frameOwnerRenderer && frameOwnerRenderer->containerForRepaint(); -#else - return false; + if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint()) + return true; + + if (Frame* parentFrame = m_frame->tree()->parent()) { + if (FrameView* parentView = parentFrame->view()) + return parentView->isEnclosedInCompositingLayer(); + } #endif + return false; } bool FrameView::syncCompositingStateRecursive() @@ -846,7 +892,7 @@ void FrameView::layout(bool allowSubtree) #endif ASSERT(!root->needsLayout()); - setCanBlitOnScroll(!useSlowRepaints()); + updateCanBlitOnScrollRecursively(); if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER)) updateOverflowStatus(layoutWidth() < contentsWidth(), @@ -927,24 +973,48 @@ void FrameView::adjustMediaTypeForPrinting(bool printing) bool FrameView::useSlowRepaints() const { - return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque; + if (m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque) + return true; + + if (Frame* parentFrame = m_frame->tree()->parent()) { + if (FrameView* parentView = parentFrame->view()) + return parentView->useSlowRepaints(); + } + + return false; } bool FrameView::useSlowRepaintsIfNotOverlapped() const { - return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque; + if (m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque) + return true; + + if (Frame* parentFrame = m_frame->tree()->parent()) { + if (FrameView* parentView = parentFrame->view()) + return parentView->useSlowRepaintsIfNotOverlapped(); + } + + return false; +} + +void FrameView::updateCanBlitOnScrollRecursively() +{ + for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) { + if (FrameView* view = frame->view()) + view->setCanBlitOnScroll(!view->useSlowRepaints()); + } } void FrameView::setUseSlowRepaints() { m_useSlowRepaints = true; - setCanBlitOnScroll(false); + updateCanBlitOnScrollRecursively(); } void FrameView::addSlowRepaintObject() { if (!m_slowRepaintObjectCount) - setCanBlitOnScroll(false); + updateCanBlitOnScrollRecursively(); m_slowRepaintObjectCount++; } @@ -953,13 +1023,13 @@ void FrameView::removeSlowRepaintObject() ASSERT(m_slowRepaintObjectCount > 0); m_slowRepaintObjectCount--; if (!m_slowRepaintObjectCount) - setCanBlitOnScroll(!useSlowRepaints()); + updateCanBlitOnScrollRecursively(); } void FrameView::addFixedObject() { if (!m_fixedObjectCount && platformWidget()) - setCanBlitOnScroll(false); + updateCanBlitOnScrollRecursively(); ++m_fixedObjectCount; } @@ -968,7 +1038,7 @@ void FrameView::removeFixedObject() ASSERT(m_fixedObjectCount > 0); --m_fixedObjectCount; if (!m_fixedObjectCount) - setCanBlitOnScroll(!useSlowRepaints()); + updateCanBlitOnScrollRecursively(); } bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) @@ -1051,12 +1121,12 @@ void FrameView::setIsOverlapped(bool isOverlapped) return; m_isOverlapped = isOverlapped; - setCanBlitOnScroll(!useSlowRepaints()); + updateCanBlitOnScrollRecursively(); #if USE(ACCELERATED_COMPOSITING) - // Overlap can affect compositing tests, so if it changes, we need to trigger - // a layer update in the parent document. - if (hasCompositedContent()) { + if (hasCompositedContentIncludingDescendants()) { + // Overlap can affect compositing tests, so if it changes, we need to trigger + // a layer update in the parent document. if (Frame* parentFrame = m_frame->tree()->parent()) { if (RenderView* parentView = parentFrame->contentRenderer()) { RenderLayerCompositor* compositor = parentView->compositor(); @@ -1064,8 +1134,35 @@ void FrameView::setIsOverlapped(bool isOverlapped) compositor->scheduleCompositingLayerUpdate(); } } + + if (RenderLayerCompositor::allowsIndependentlyCompositedIFrames(this)) { + // We also need to trigger reevaluation for this and all descendant frames, + // since a frame uses compositing if any ancestor is compositing. + for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) { + if (RenderView* view = frame->contentRenderer()) { + RenderLayerCompositor* compositor = view->compositor(); + compositor->setCompositingLayersNeedRebuild(); + compositor->scheduleCompositingLayerUpdate(); + } + } + } + } +#endif +} + +bool FrameView::isOverlappedIncludingAncestors() const +{ + if (isOverlapped()) + return true; + + if (Frame* parentFrame = m_frame->tree()->parent()) { + if (FrameView* parentView = parentFrame->view()) { + if (parentView->isOverlapped()) + return true; + } } -#endif + + return false; } void FrameView::setContentIsOpaque(bool contentIsOpaque) @@ -1074,7 +1171,7 @@ void FrameView::setContentIsOpaque(bool contentIsOpaque) return; m_contentIsOpaque = contentIsOpaque; - setCanBlitOnScroll(!useSlowRepaints()); + updateCanBlitOnScrollRecursively(); } void FrameView::restoreScrollbar() @@ -1559,12 +1656,10 @@ void FrameView::setBaseBackgroundColor(Color bc) void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent) { for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) { - FrameView* view = frame->view(); - if (!view) - continue; - - view->setTransparent(transparent); - view->setBaseBackgroundColor(backgroundColor); + if (FrameView* view = frame->view()) { + view->setTransparent(transparent); + view->setBaseBackgroundColor(backgroundColor); + } } } diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h index f9212c1..8a1a071 100644 --- a/WebCore/page/FrameView.h +++ b/WebCore/page/FrameView.h @@ -76,6 +76,7 @@ public: virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation); + virtual bool delegatesScrolling(); virtual bool avoidScrollbarCreation(); virtual void setContentsSize(const IntSize&); @@ -106,6 +107,8 @@ public: #endif bool hasCompositedContent() const; + bool hasCompositedContentIncludingDescendants() const; + bool hasCompositingAncestor() const; void enterCompositingMode(); bool isEnclosedInCompositingLayer() const; @@ -153,6 +156,7 @@ public: void setUseSlowRepaints(); void setIsOverlapped(bool); bool isOverlapped() const { return m_isOverlapped; } + bool isOverlappedIncludingAncestors() const; void setContentIsOpaque(bool); void addSlowRepaintObject(); @@ -255,6 +259,7 @@ private: friend class RenderWidget; bool useSlowRepaints() const; bool useSlowRepaintsIfNotOverlapped() const; + void updateCanBlitOnScrollRecursively(); bool hasFixedObjects() const { return m_fixedObjectCount > 0; } diff --git a/WebCore/page/History.cpp b/WebCore/page/History.cpp index 3d463b6..95b1350 100644 --- a/WebCore/page/History.cpp +++ b/WebCore/page/History.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "History.h" +#include "BackForwardController.h" #include "ExceptionCode.h" #include "Frame.h" #include "FrameLoader.h" @@ -56,7 +57,7 @@ unsigned History::length() const return 0; if (!m_frame->page()) return 0; - return m_frame->page()->getHistoryLength(); + return m_frame->page()->backForward()->count(); } void History::back() diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp index 5609e28..65c3d90 100644 --- a/WebCore/page/Page.cpp +++ b/WebCore/page/Page.cpp @@ -145,20 +145,20 @@ static void onPackageResultAvailable() #endif Page::Page(const PageClients& pageClients) - : m_chrome(new Chrome(this, pageClients.chromeClient)) - , m_dragCaretController(new SelectionController(0, true)) + : m_chrome(adoptPtr(new Chrome(this, pageClients.chromeClient))) + , m_dragCaretController(adoptPtr(new SelectionController(0, true))) #if ENABLE(DRAG_SUPPORT) - , m_dragController(new DragController(this, pageClients.dragClient)) + , m_dragController(adoptPtr(new DragController(this, pageClients.dragClient))) #endif - , m_focusController(new FocusController(this)) + , m_focusController(adoptPtr(new FocusController(this))) #if ENABLE(CONTEXT_MENUS) - , m_contextMenuController(new ContextMenuController(this, pageClients.contextMenuClient)) + , m_contextMenuController(adoptPtr(new ContextMenuController(this, pageClients.contextMenuClient))) #endif #if ENABLE(INSPECTOR) - , m_inspectorController(new InspectorController(this, pageClients.inspectorClient)) + , m_inspectorController(adoptPtr(new InspectorController(this, pageClients.inspectorClient))) #endif #if ENABLE(CLIENT_BASED_GEOLOCATION) - , m_geolocationController(new GeolocationController(this, pageClients.geolocationControllerClient)) + , m_geolocationController(adoptPtr(new GeolocationController(this, pageClients.geolocationControllerClient))) #endif #if ENABLE(DEVICE_ORIENTATION) , m_deviceMotionController(RuntimeEnabledFeatures::deviceMotionEnabled() ? new DeviceMotionController(pageClients.deviceMotionClient) : 0) @@ -167,9 +167,9 @@ Page::Page(const PageClients& pageClients) #if ENABLE(INPUT_SPEECH) , m_speechInputClient(pageClients.speechInputClient) #endif - , m_settings(new Settings(this)) - , m_progress(new ProgressTracker) - , m_backForwardController(new BackForwardController(this, pageClients.backForwardControllerClient)) + , m_settings(adoptPtr(new Settings(this))) + , m_progress(adoptPtr(new ProgressTracker)) + , m_backForwardController(adoptPtr(new BackForwardController(this, pageClients.backForwardClient))) , m_theme(RenderTheme::themeForPage(this)) , m_editorClient(pageClients.editorClient) , m_frameCount(0) @@ -233,7 +233,7 @@ Page::~Page() m_inspectorController->inspectedPageDestroyed(); #endif - backForwardList()->close(); + backForward()->close(); #ifndef NDEBUG pageCounter.decrement(); @@ -302,12 +302,12 @@ void Page::setOpenedByDOM() BackForwardList* Page::backForwardList() const { - return m_backForwardController->list(); + return m_backForwardController->client(); } bool Page::goBack() { - HistoryItem* item = backForwardList()->backItem(); + HistoryItem* item = backForward()->backItem(); if (item) { goToItem(item, FrameLoadTypeBack); @@ -318,7 +318,7 @@ bool Page::goBack() bool Page::goForward() { - HistoryItem* item = backForwardList()->forwardItem(); + HistoryItem* item = backForward()->forwardItem(); if (item) { goToItem(item, FrameLoadTypeForward); @@ -331,9 +331,9 @@ bool Page::canGoBackOrForward(int distance) const { if (distance == 0) return true; - if (distance > 0 && distance <= backForwardList()->forwardListCount()) + if (distance > 0 && distance <= backForward()->forwardCount()) return true; - if (distance < 0 && -distance <= backForwardList()->backListCount()) + if (distance < 0 && -distance <= backForward()->backCount()) return true; return false; } @@ -343,28 +343,32 @@ void Page::goBackOrForward(int distance) if (distance == 0) return; - HistoryItem* item = backForwardList()->itemAtIndex(distance); + HistoryItem* item = backForward()->itemAtIndex(distance); if (!item) { if (distance > 0) { - int forwardListCount = backForwardList()->forwardListCount(); - if (forwardListCount > 0) - item = backForwardList()->itemAtIndex(forwardListCount); + if (int forwardCount = backForward()->forwardCount()) + item = backForward()->itemAtIndex(forwardCount); } else { - int backListCount = backForwardList()->backListCount(); - if (backListCount > 0) - item = backForwardList()->itemAtIndex(-backListCount); + if (int backCount = backForward()->backCount()) + item = backForward()->itemAtIndex(-backCount); } } - ASSERT(item); // we should not reach this line with an empty back/forward list - if (item) - goToItem(item, FrameLoadTypeIndexedBackForward); + ASSERT(item); + if (!item) + return; + + goToItem(item, FrameLoadTypeIndexedBackForward); } void Page::goToItem(HistoryItem* item, FrameLoadType type) { if (defersLoading()) return; + + // stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem + // being deref()-ed. Make sure we can still use it with HistoryController::goToItem later. + RefPtr<HistoryItem> protector(item); // Abort any current load unless we're navigating the current document to a new state object HistoryItem* currentItem = m_mainFrame->loader()->history()->currentItem(); @@ -389,7 +393,7 @@ void Page::goToItem(HistoryItem* item, FrameLoadType type) int Page::getHistoryLength() { - return backForwardList()->backListCount() + 1 + backForwardList()->forwardListCount(); + return backForward()->backCount() + 1 + backForward()->forwardCount(); } void Page::setGlobalHistoryItem(HistoryItem* item) @@ -925,4 +929,23 @@ void Page::checkFrameCountConsistency() const ASSERT(m_frameCount + 1 == frameCount); } #endif + +Page::PageClients::PageClients() + : chromeClient(0) + , contextMenuClient(0) + , editorClient(0) + , dragClient(0) + , inspectorClient(0) + , pluginHalterClient(0) + , geolocationControllerClient(0) + , deviceMotionClient(0) + , deviceOrientationClient(0) + , speechInputClient(0) +{ +} + +Page::PageClients::~PageClients() +{ +} + } // namespace WebCore diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h index 6ff64cf..89ad7b8 100644 --- a/WebCore/page/Page.h +++ b/WebCore/page/Page.h @@ -39,7 +39,6 @@ namespace JSC { namespace WebCore { class BackForwardController; - class BackForwardControllerClient; class BackForwardList; class Chrome; class ChromeClient; @@ -95,20 +94,9 @@ namespace WebCore { static void scheduleForcedStyleRecalcForAllPages(); // It is up to the platform to ensure that non-null clients are provided where required. - struct PageClients { - PageClients() - : chromeClient(0) - , contextMenuClient(0) - , editorClient(0) - , dragClient(0) - , inspectorClient(0) - , pluginHalterClient(0) - , geolocationControllerClient(0) - , deviceMotionClient(0) - , deviceOrientationClient(0) - , backForwardControllerClient(0) - , speechInputClient(0) - { } + struct PageClients : Noncopyable { + PageClients(); + ~PageClients(); ChromeClient* chromeClient; ContextMenuClient* contextMenuClient; @@ -119,7 +107,7 @@ namespace WebCore { GeolocationControllerClient* geolocationControllerClient; DeviceMotionClient* deviceMotionClient; DeviceOrientationClient* deviceOrientationClient; - BackForwardControllerClient* backForwardControllerClient; + RefPtr<BackForwardList> backForwardClient; SpeechInputClient* speechInputClient; }; @@ -145,19 +133,16 @@ namespace WebCore { bool openedByDOM() const; void setOpenedByDOM(); + // DEPRECATED. Use backForward() instead of the following 6 functions. BackForwardList* backForwardList() const; - - // FIXME: The following three methods don't fall under the responsibilities of the Page object - // They seem to fit a hypothetical Page-controller object that would be akin to the - // Frame-FrameLoader relationship. They have to live here now, but should move somewhere that - // makes more sense when that class exists. bool goBack(); bool goForward(); bool canGoBackOrForward(int distance) const; void goBackOrForward(int distance); - void goToItem(HistoryItem*, FrameLoadType); int getHistoryLength(); + void goToItem(HistoryItem*, FrameLoadType); + HistoryItem* globalHistoryItem() const { return m_globalHistoryItem.get(); } void setGlobalHistoryItem(HistoryItem*); @@ -195,7 +180,7 @@ namespace WebCore { #endif Settings* settings() const { return m_settings.get(); } ProgressTracker* progress() const { return m_progress.get(); } - + BackForwardController* backForward() const { return m_backForwardController.get(); } enum ViewMode { ViewModeInvalid, diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp index acfe23a..069296a 100644 --- a/WebCore/page/Settings.cpp +++ b/WebCore/page/Settings.cpp @@ -26,7 +26,7 @@ #include "config.h" #include "Settings.h" -#include "BackForwardList.h" +#include "BackForwardController.h" #include "CachedResourceLoader.h" #include "CookieStorage.h" #include "DOMTimer.h" @@ -64,6 +64,27 @@ bool Settings::gShouldPaintNativeControls = true; bool Settings::gShouldUseHighResolutionTimers = true; #endif +// NOTEs +// 1) EditingMacBehavior comprises Tiger, Leopard, SnowLeopard and iOS builds, as well QtWebKit and Chromium when built on Mac; +// 2) EditingWindowsBehavior comprises Win32 and WinCE builds, as well as QtWebKit and Chromium when built on Windows; +// 3) EditingUnixBehavior comprises all unix-based systems, but Darwin/MacOS (and then abusing the terminology); +// 99) MacEditingBehavior is used a fallback. +static EditingBehaviorType editingBehaviorTypeForPlatform() +{ + return +#if OS(DARWIN) + EditingMacBehavior +#elif OS(WINDOWS) + EditingWindowsBehavior +#elif OS(UNIX) + EditingUnixBehavior +#else + // Fallback + EditingMacBehavior +#endif + ; +} + Settings::Settings(Page* page) : m_page(page) #ifdef ANDROID_LAYOUT @@ -105,6 +126,7 @@ Settings::Settings(Page* page) , m_javaScriptCanOpenWindowsAutomatically(false) , m_javaScriptCanAccessClipboard(false) , m_shouldPrintBackgrounds(false) + , m_shouldDelegateScrolling(false) , m_textAreasAreResizable(false) #if ENABLE(DASHBOARD_SUPPORT) , m_usesDashboardBackwardCompatibilityMode(false) @@ -132,14 +154,7 @@ Settings::Settings(Page* page) , m_enforceCSSMIMETypeInNoQuirksMode(true) , m_usesEncodingDetector(false) , m_allowScriptsToCloseWindows(false) - , m_editingBehaviorType( -#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) - // (PLATFORM(MAC) is always false in Chromium, hence the extra condition.) - EditingMacBehavior -#else - EditingWindowsBehavior -#endif - ) + , m_editingBehaviorType(editingBehaviorTypeForPlatform()) // FIXME: This should really be disabled by default as it makes platforms that don't support the feature download files // they can't use by. Leaving enabled for now to not change existing behavior. , m_downloadableBinaryFontsEnabled(true) @@ -380,6 +395,11 @@ void Settings::setShouldPrintBackgrounds(bool shouldPrintBackgrounds) m_shouldPrintBackgrounds = shouldPrintBackgrounds; } +void Settings::setShouldDelegateScrolling(bool shouldDelegateScrolling) +{ + m_shouldDelegateScrolling = shouldDelegateScrolling; +} + void Settings::setTextAreasAreResizable(bool textAreasAreResizable) { if (m_textAreasAreResizable == textAreasAreResizable) @@ -453,10 +473,10 @@ void Settings::setUsesPageCache(bool usesPageCache) m_usesPageCache = usesPageCache; if (!m_usesPageCache) { - int first = -m_page->backForwardList()->backListCount(); - int last = m_page->backForwardList()->forwardListCount(); + int first = -m_page->backForward()->backCount(); + int last = m_page->backForward()->forwardCount(); for (int i = first; i <= last; i++) - pageCache()->remove(m_page->backForwardList()->itemAtIndex(i)); + pageCache()->remove(m_page->backForward()->itemAtIndex(i)); pageCache()->releaseAutoreleasedPagesNow(); } } diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h index b5e6fe1..0d5b875 100644 --- a/WebCore/page/Settings.h +++ b/WebCore/page/Settings.h @@ -171,7 +171,7 @@ namespace WebCore { // - HTML5/DOM Storage // - Icon Database // - Console Messages - // - Cache + // - MemoryCache // - Application Cache // - Back/Forward Page History // - Page Search Results @@ -198,6 +198,9 @@ namespace WebCore { void setShouldPrintBackgrounds(bool); bool shouldPrintBackgrounds() const { return m_shouldPrintBackgrounds; } + void setShouldDelegateScrolling(bool); + bool shouldDelegateScrolling() const { return m_shouldDelegateScrolling; } + void setTextAreasAreResizable(bool); bool textAreasAreResizable() const { return m_textAreasAreResizable; } @@ -486,6 +489,7 @@ namespace WebCore { bool m_javaScriptCanOpenWindowsAutomatically : 1; bool m_javaScriptCanAccessClipboard : 1; bool m_shouldPrintBackgrounds : 1; + bool m_shouldDelegateScrolling : 1; bool m_textAreasAreResizable : 1; #if ENABLE(DASHBOARD_SUPPORT) bool m_usesDashboardBackwardCompatibilityMode : 1; diff --git a/WebCore/page/SpatialNavigation.cpp b/WebCore/page/SpatialNavigation.cpp index 40aa52b..a42435f 100644 --- a/WebCore/page/SpatialNavigation.cpp +++ b/WebCore/page/SpatialNavigation.cpp @@ -35,8 +35,9 @@ #include "HTMLFrameOwnerElement.h" #include "IntRect.h" #include "Node.h" -#include "RenderLayer.h" #include "Page.h" +#include "RenderLayer.h" +#include "Settings.h" namespace WebCore { @@ -49,6 +50,11 @@ static bool isRectInDirection(FocusDirection, const IntRect&, const IntRect&); static void deflateIfOverlapped(IntRect&, IntRect&); static bool checkNegativeCoordsForNode(Node*, const IntRect&); +bool isSpatialNavigationEnabled(const Frame* frame) +{ + return (frame && frame->settings() && frame->settings()->isSpatialNavigationEnabled()); +} + void distanceDataForNode(FocusDirection direction, Node* start, FocusCandidate& candidate) { RenderObject* startRender = start->renderer(); diff --git a/WebCore/page/SpatialNavigation.h b/WebCore/page/SpatialNavigation.h index d3dcaba..45b0155 100644 --- a/WebCore/page/SpatialNavigation.h +++ b/WebCore/page/SpatialNavigation.h @@ -45,6 +45,8 @@ inline int fudgeFactor() return 2; } +bool isSpatialNavigationEnabled(const Frame*); + // Spatially speaking, two given elements in a web page can be: // 1) Fully aligned: There is a full intersection between the rects, either // vertically or horizontally. diff --git a/WebCore/page/Timing.cpp b/WebCore/page/Timing.cpp index 8a0de2a..3d98dc2 100644 --- a/WebCore/page/Timing.cpp +++ b/WebCore/page/Timing.cpp @@ -35,6 +35,7 @@ #include "DocumentLoadTiming.h" #include "DocumentLoader.h" +#include "DocumentTiming.h" #include "Frame.h" #include "ResourceLoadTiming.h" #include "ResourceResponse.h" @@ -246,6 +247,42 @@ unsigned long long Timing::responseEnd() const return toIntegerMilliseconds(timing->responseEnd); } +unsigned long long Timing::domLoading() const +{ + const DocumentTiming* timing = documentTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->domLoading); +} + +unsigned long long Timing::domInteractive() const +{ + const DocumentTiming* timing = documentTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->domInteractive); +} + +unsigned long long Timing::domContentLoaded() const +{ + const DocumentTiming* timing = documentTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->domContentLoaded); +} + +unsigned long long Timing::domComplete() const +{ + const DocumentTiming* timing = documentTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->domComplete); +} + unsigned long long Timing::loadEventStart() const { DocumentLoadTiming* timing = documentLoadTiming(); @@ -272,6 +309,18 @@ DocumentLoader* Timing::documentLoader() const return m_frame->loader()->documentLoader(); } +const DocumentTiming* Timing::documentTiming() const +{ + if (!m_frame) + return 0; + + Document* document = m_frame->document(); + if (!document) + return 0; + + return document->timing(); +} + DocumentLoadTiming* Timing::documentLoadTiming() const { DocumentLoader* loader = documentLoader(); diff --git a/WebCore/page/Timing.h b/WebCore/page/Timing.h index f48f525..3e3485f 100644 --- a/WebCore/page/Timing.h +++ b/WebCore/page/Timing.h @@ -40,6 +40,7 @@ namespace WebCore { struct DocumentLoadTiming; class DocumentLoader; +struct DocumentTiming; class Frame; class ResourceLoadTiming; @@ -63,12 +64,17 @@ public: unsigned long long requestEnd() const; unsigned long long responseStart() const; unsigned long long responseEnd() const; + unsigned long long domLoading() const; + unsigned long long domInteractive() const; + unsigned long long domContentLoaded() const; + unsigned long long domComplete() const; unsigned long long loadEventStart() const; unsigned long long loadEventEnd() const; private: Timing(Frame*); + const DocumentTiming* documentTiming() const; DocumentLoader* documentLoader() const; DocumentLoadTiming* documentLoadTiming() const; ResourceLoadTiming* resourceLoadTiming() const; diff --git a/WebCore/page/Timing.idl b/WebCore/page/Timing.idl index e7e46cc..00d3e24 100644 --- a/WebCore/page/Timing.idl +++ b/WebCore/page/Timing.idl @@ -45,6 +45,10 @@ module window { readonly attribute unsigned long long requestEnd; readonly attribute unsigned long long responseStart; readonly attribute unsigned long long responseEnd; + readonly attribute unsigned long long domLoading; + readonly attribute unsigned long long domInteractive; + readonly attribute unsigned long long domContentLoaded; + readonly attribute unsigned long long domComplete; readonly attribute unsigned long long loadEventStart; readonly attribute unsigned long long loadEventEnd; }; diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp index ade68b5..ad5257e 100644 --- a/WebCore/page/animation/AnimationBase.cpp +++ b/WebCore/page/animation/AnimationBase.cpp @@ -1206,10 +1206,17 @@ void AnimationBase::fireAnimationEventsIfNeeded() } } -void AnimationBase::updatePlayState(bool run) +void AnimationBase::updatePlayState(EAnimPlayState playState) { - if (paused() == run || isNew()) - updateStateMachine(run ? AnimationStateInputPlayStateRunning : AnimationStateInputPlayStatePaused, -1); + // When we get here, we can have one of 4 desired states: running, paused, suspended, paused & suspended. + // The state machine can be in one of two states: running, paused. + // Set the state machine to the desired state. + bool pause = playState == AnimPlayStatePaused || m_compAnim->suspended(); + + if (pause == paused() && !isNew()) + return; + + updateStateMachine(pause ? AnimationStateInputPlayStatePaused : AnimationStateInputPlayStateRunning, -1); } double AnimationBase::timeToNextService() diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h index f5f3172..eb9bd12 100644 --- a/WebCore/page/animation/AnimationBase.h +++ b/WebCore/page/animation/AnimationBase.h @@ -29,6 +29,7 @@ #ifndef AnimationBase_h #define AnimationBase_h +#include "RenderStyleConstants.h" #include <wtf/HashMap.h> #include <wtf/text/AtomicString.h> @@ -102,7 +103,7 @@ public: } // Called to change to or from paused state - void updatePlayState(bool running); + void updatePlayState(EAnimPlayState); bool playStatePlaying() const; bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; } diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp index b5d87e6..e8e990c 100644 --- a/WebCore/page/animation/AnimationController.cpp +++ b/WebCore/page/animation/AnimationController.cpp @@ -81,7 +81,7 @@ bool AnimationControllerPrivate::clear(RenderObject* renderer) if (!animation) return false; animation->clearRenderer(); - return animation->isSuspended(); + return animation->suspended(); } void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = false*/) @@ -92,7 +92,7 @@ void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = fa RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end(); for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) { CompositeAnimation* compAnim = it->second.get(); - if (!compAnim->isSuspended() && compAnim->hasAnimations()) { + if (!compAnim->suspended() && compAnim->hasAnimations()) { double t = compAnim->timeToNextService(); if (t != -1 && (t < needsService || needsService == -1)) needsService = t; @@ -227,7 +227,25 @@ bool AnimationControllerPrivate::isRunningAcceleratedAnimationOnRenderer(RenderO return animation->isAnimatingProperty(property, true, isRunningNow); } -void AnimationControllerPrivate::suspendAnimations(Document* document) +void AnimationControllerPrivate::suspendAnimations() +{ + suspendAnimationsForDocument(m_frame->document()); + + // Traverse subframes + for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) + child->animation()->suspendAnimations(); +} + +void AnimationControllerPrivate::resumeAnimations() +{ + resumeAnimationsForDocument(m_frame->document()); + + // Traverse subframes + for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) + child->animation()->resumeAnimations(); +} + +void AnimationControllerPrivate::suspendAnimationsForDocument(Document* document) { setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet); @@ -243,7 +261,7 @@ void AnimationControllerPrivate::suspendAnimations(Document* document) updateAnimationTimer(); } -void AnimationControllerPrivate::resumeAnimations(Document* document) +void AnimationControllerPrivate::resumeAnimationsForDocument(Document* document) { setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet); @@ -551,14 +569,24 @@ bool AnimationController::isRunningAcceleratedAnimationOnRenderer(RenderObject* return m_data->isRunningAcceleratedAnimationOnRenderer(renderer, property, isRunningNow); } -void AnimationController::suspendAnimations(Document* document) +void AnimationController::suspendAnimations() +{ + m_data->suspendAnimations(); +} + +void AnimationController::resumeAnimations() +{ + m_data->resumeAnimations(); +} + +void AnimationController::suspendAnimationsForDocument(Document* document) { - m_data->suspendAnimations(document); + m_data->suspendAnimationsForDocument(document); } -void AnimationController::resumeAnimations(Document* document) +void AnimationController::resumeAnimationsForDocument(Document* document) { - m_data->resumeAnimations(document); + m_data->resumeAnimationsForDocument(document); } void AnimationController::beginAnimationUpdate() diff --git a/WebCore/page/animation/AnimationController.h b/WebCore/page/animation/AnimationController.h index 4528dae..5279467 100644 --- a/WebCore/page/animation/AnimationController.h +++ b/WebCore/page/animation/AnimationController.h @@ -62,8 +62,11 @@ public: bool isRunningAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const; bool isRunningAcceleratedAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const; - void suspendAnimations(Document*); - void resumeAnimations(Document*); + void suspendAnimations(); + void resumeAnimations(); + + void suspendAnimationsForDocument(Document*); + void resumeAnimationsForDocument(Document*); void beginAnimationUpdate(); void endAnimationUpdate(); diff --git a/WebCore/page/animation/AnimationControllerPrivate.h b/WebCore/page/animation/AnimationControllerPrivate.h index 3305e24..893c717 100644 --- a/WebCore/page/animation/AnimationControllerPrivate.h +++ b/WebCore/page/animation/AnimationControllerPrivate.h @@ -67,8 +67,11 @@ public: bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); } - void suspendAnimations(Document*); - void resumeAnimations(Document*); + void suspendAnimations(); + void resumeAnimations(); + + void suspendAnimationsForDocument(Document*); + void resumeAnimationsForDocument(Document*); bool isRunningAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const; bool isRunningAcceleratedAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const; diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp index 57c2aa4..9d021b4 100644 --- a/WebCore/page/animation/CompositeAnimation.cpp +++ b/WebCore/page/animation/CompositeAnimation.cpp @@ -229,7 +229,7 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render // This one is still active. // Animations match, but play states may differ. Update if needed. - keyframeAnim->updatePlayState(anim->playState() == AnimPlayStatePlaying); + keyframeAnim->updatePlayState(anim->playState()); // Set the saved animation to this new one, just in case the play state has changed. keyframeAnim->setAnimation(anim); @@ -386,17 +386,17 @@ PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(int pr void CompositeAnimation::suspendAnimations() { - if (m_isSuspended) + if (m_suspended) return; - m_isSuspended = true; + m_suspended = true; if (!m_keyframeAnimations.isEmpty()) { m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { if (KeyframeAnimation* anim = it->second.get()) - anim->updatePlayState(false); + anim->updatePlayState(AnimPlayStatePaused); } } if (!m_transitions.isEmpty()) { @@ -404,17 +404,17 @@ void CompositeAnimation::suspendAnimations() for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { ImplicitAnimation* anim = it->second.get(); if (anim && anim->hasStyle()) - anim->updatePlayState(false); + anim->updatePlayState(AnimPlayStatePaused); } } } void CompositeAnimation::resumeAnimations() { - if (!m_isSuspended) + if (!m_suspended) return; - m_isSuspended = false; + m_suspended = false; if (!m_keyframeAnimations.isEmpty()) { m_keyframeAnimations.checkConsistency(); @@ -422,7 +422,7 @@ void CompositeAnimation::resumeAnimations() for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* anim = it->second.get(); if (anim && anim->playStatePlaying()) - anim->updatePlayState(true); + anim->updatePlayState(AnimPlayStatePlaying); } } @@ -431,7 +431,7 @@ void CompositeAnimation::resumeAnimations() for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { ImplicitAnimation* anim = it->second.get(); if (anim && anim->hasStyle()) - anim->updatePlayState(true); + anim->updatePlayState(AnimPlayStatePlaying); } } } diff --git a/WebCore/page/animation/CompositeAnimation.h b/WebCore/page/animation/CompositeAnimation.h index a0ac455..249f4c3 100644 --- a/WebCore/page/animation/CompositeAnimation.h +++ b/WebCore/page/animation/CompositeAnimation.h @@ -64,7 +64,7 @@ public: void suspendAnimations(); void resumeAnimations(); - bool isSuspended() const { return m_isSuspended; } + bool suspended() const { return m_suspended; } bool hasAnimations() const { return !m_transitions.isEmpty() || !m_keyframeAnimations.isEmpty(); } @@ -84,7 +84,7 @@ private: CompositeAnimation(AnimationControllerPrivate* animationController) : m_animationController(animationController) , m_numStyleAvailableWaiters(0) - , m_isSuspended(false) + , m_suspended(false) { } @@ -99,7 +99,7 @@ private: AnimationNameMap m_keyframeAnimations; Vector<AtomicStringImpl*> m_keyframeAnimationOrderMap; unsigned m_numStyleAvailableWaiters; - bool m_isSuspended; + bool m_suspended; }; } // namespace WebCore diff --git a/WebCore/platform/AsyncFileSystem.cpp b/WebCore/platform/AsyncFileSystem.cpp index 57305ff..b85a487 100644 --- a/WebCore/platform/AsyncFileSystem.cpp +++ b/WebCore/platform/AsyncFileSystem.cpp @@ -53,7 +53,7 @@ PassOwnPtr<AsyncFileSystem> AsyncFileSystem::create(const String&) } // Default implementation. -void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, Type type, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) +void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, Type type, bool, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) { String typeString = (type == Persistent) ? "Persistent" : "Temporary"; diff --git a/WebCore/platform/AsyncFileSystem.h b/WebCore/platform/AsyncFileSystem.h index 3104ebc..d96c1ad 100644 --- a/WebCore/platform/AsyncFileSystem.h +++ b/WebCore/platform/AsyncFileSystem.h @@ -66,8 +66,8 @@ public: // Creates and returns a new platform-specific AsyncFileSystem instance if the platform has its own implementation. static PassOwnPtr<AsyncFileSystem> create(const String& rootPath); - // Opens a new file system. - static void openFileSystem(const String& basePath, const String& storageIdentifier, Type, PassOwnPtr<AsyncFileSystemCallbacks>); + // Opens a new file system. The create parameter specifies whether or not to create the path if it does not already exists. + static void openFileSystem(const String& basePath, const String& storageIdentifier, Type, bool create, PassOwnPtr<AsyncFileSystemCallbacks>); // Moves a file or directory from srcPath to destPath. // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully. @@ -128,6 +128,9 @@ public: // Converts a given absolute virtual path to a platform path that starts with the platform root path of this file system. virtual String virtualToPlatformPath(const String& path) const; + // Getter for this file system's root path. + String root() const { return m_platformRootPath; } + protected: AsyncFileSystem(const String& platformRootPath) : m_platformRootPath(platformRootPath) diff --git a/WebCore/platform/ContextMenu.cpp b/WebCore/platform/ContextMenu.cpp index 369f9ce..93cdfdf 100644 --- a/WebCore/platform/ContextMenu.cpp +++ b/WebCore/platform/ContextMenu.cpp @@ -30,6 +30,7 @@ #if ENABLE(CONTEXT_MENUS) +#include "BackForwardController.h" #include "ContextMenuController.h" #include "ContextMenuClient.h" #include "CSSComputedStyleDeclaration.h" @@ -405,10 +406,10 @@ void ContextMenu::populate() #if ENABLE(INSPECTOR) if (!(frame->page() && frame->page()->inspectorController()->hasInspectorFrontendClient())) { #endif - if (frame->page() && frame->page()->canGoBackOrForward(-1)) + if (frame->page() && frame->page()->backForward()->canGoBackOrForward(-1)) appendItem(BackItem); - if (frame->page() && frame->page()->canGoBackOrForward(1)) + if (frame->page() && frame->page()->backForward()->canGoBackOrForward(1)) appendItem(ForwardItem); // use isLoadingInAPISense rather than isLoading because Stop/Reload are @@ -428,7 +429,7 @@ void ContextMenu::populate() } else { // Make an editing context menu SelectionController* selection = frame->selection(); bool inPasswordField = selection->isInPasswordField(); - bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledInFocusedNode(); + bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node); if (!inPasswordField && spellCheckingEnabled) { // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range @@ -783,10 +784,10 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const #endif #if PLATFORM(GTK) case ContextMenuItemTagGoBack: - shouldEnable = frame->page() && frame->page()->canGoBackOrForward(-1); + shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(-1); break; case ContextMenuItemTagGoForward: - shouldEnable = frame->page() && frame->page()->canGoBackOrForward(1); + shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(1); break; case ContextMenuItemTagStop: shouldEnable = frame->loader()->documentLoader()->isLoadingInAPISense(); diff --git a/WebCore/platform/ContextMenu.h b/WebCore/platform/ContextMenu.h index ca21f29..2a2a017 100644 --- a/WebCore/platform/ContextMenu.h +++ b/WebCore/platform/ContextMenu.h @@ -91,6 +91,8 @@ namespace WebCore { #endif }; +Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription); + } #endif // ContextMenu_h diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h index e3916cf..32ab417 100644 --- a/WebCore/platform/FileSystem.h +++ b/WebCore/platform/FileSystem.h @@ -144,6 +144,7 @@ static const char PlatformFilePathSeparator = '\\'; static const char PlatformFilePathSeparator = '/'; #endif +void revealFolderInOS(const String&); bool fileExists(const String&); bool deleteFile(const String&); bool deleteEmptyDirectory(const String&); diff --git a/WebCore/platform/HostWindow.h b/WebCore/platform/HostWindow.h index b0ee653..7882d48 100644 --- a/WebCore/platform/HostWindow.h +++ b/WebCore/platform/HostWindow.h @@ -48,7 +48,12 @@ public: // Requests the host invalidate the contents, not the window. This is the slow path for scrolling. virtual void invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) = 0; - + +#if ENABLE(TILED_BACKING_STORE) + // Requests the host to do the actual scrolling. This is only used in combination with a tiled backing store. + virtual void delegatedScrollRequested(const IntSize& scrollDelta) = 0; +#endif + // Methods for doing coordinate conversions to and from screen coordinates. virtual IntPoint screenToWindow(const IntPoint&) const = 0; virtual IntRect windowToScreen(const IntRect&) const = 0; diff --git a/WebCore/platform/PurgePriority.h b/WebCore/platform/PurgePriority.h new file mode 100644 index 0000000..6a2894e --- /dev/null +++ b/WebCore/platform/PurgePriority.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PurgePriority_h +#define PurgePriority_h + +namespace WebCore { + +enum PurgePriority { + PurgeLast, + PurgeMiddle, + PurgeFirst, + PurgeDefault = PurgeMiddle +}; + +} + +#endif // PurgePriority_h diff --git a/WebCore/platform/PurgeableBuffer.h b/WebCore/platform/PurgeableBuffer.h index 32341c2..9bda2d5 100644 --- a/WebCore/platform/PurgeableBuffer.h +++ b/WebCore/platform/PurgeableBuffer.h @@ -26,6 +26,7 @@ #ifndef PurgeableBuffer_h #define PurgeableBuffer_h +#include "PurgePriority.h" #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> @@ -35,7 +36,6 @@ namespace WebCore { class PurgeableBuffer : public Noncopyable { public: static PassOwnPtr<PurgeableBuffer> create(const char* data, size_t); - static PassOwnPtr<PurgeableBuffer> create(const Vector<char>& vector) { return create(vector.data(), vector.size()); } ~PurgeableBuffer(); @@ -43,9 +43,8 @@ namespace WebCore { const char* data() const; size_t size() const { return m_size; } - enum PurgePriority { PurgeLast, PurgeMiddle, PurgeFirst, PurgeDefault = PurgeMiddle }; PurgePriority purgePriority() const { return m_purgePriority; } - void setPurgePriority(PurgePriority); + void setPurgePriority(PurgePriority priority) { m_purgePriority = priority; } bool isPurgeable() const { return m_state != NonVolatile; } bool wasPurged() const; @@ -67,7 +66,6 @@ namespace WebCore { inline PassOwnPtr<PurgeableBuffer> PurgeableBuffer::create(const char*, size_t) { return PassOwnPtr<PurgeableBuffer>(); } inline PurgeableBuffer::~PurgeableBuffer() { } inline const char* PurgeableBuffer::data() const { return 0; } - inline void PurgeableBuffer::setPurgePriority(PurgePriority) { } inline bool PurgeableBuffer::wasPurged() const { return false; } inline bool PurgeableBuffer::makePurgeable(bool) { return false; } #endif diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp index 5f745b8..40d598e 100644 --- a/WebCore/platform/ScrollView.cpp +++ b/WebCore/platform/ScrollView.cpp @@ -362,6 +362,13 @@ void ScrollView::setScrollPosition(const IntPoint& scrollPoint) IntPoint newScrollPosition = scrollPoint.shrunkTo(maximumScrollPosition()); newScrollPosition.clampNegativeToZero(); +#if ENABLE(TILED_BACKING_STORE) + if (delegatesScrolling()) { + hostWindow()->delegatedScrollRequested(IntSize(scrollPoint.x(), scrollPoint.y())); + return; + } +#endif + if (newScrollPosition == scrollPosition()) return; diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h index 739e1ac..7fb5d8e 100644 --- a/WebCore/platform/ScrollView.h +++ b/WebCore/platform/ScrollView.h @@ -104,6 +104,7 @@ public: virtual void setCanHaveScrollbars(bool); bool canHaveScrollbars() const { return horizontalScrollbarMode() != ScrollbarAlwaysOff || verticalScrollbarMode() != ScrollbarAlwaysOff; } + virtual bool delegatesScrolling() { return false; } virtual bool avoidScrollbarCreation() { return false; } // By default you only receive paint events for the area that is visible. In the case of using a diff --git a/WebCore/platform/UUID.cpp b/WebCore/platform/UUID.cpp index 5208bee..eb721e0 100644 --- a/WebCore/platform/UUID.cpp +++ b/WebCore/platform/UUID.cpp @@ -39,9 +39,6 @@ #if OS(WINDOWS) #include <objbase.h> -#ifndef ARRAYSIZE -#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0])) -#endif #elif OS(DARWIN) #include <CoreFoundation/CoreFoundation.h> #elif OS(LINUX) && !PLATFORM(CHROMIUM) @@ -69,7 +66,7 @@ String createCanonicalUUIDString() if (FAILED(hr)) return String(); wchar_t uuidStr[40]; - int num = StringFromGUID2(uuid, reinterpret_cast<LPOLESTR>(uuidStr), ARRAYSIZE(uuidStr)); + int num = StringFromGUID2(uuid, reinterpret_cast<LPOLESTR>(uuidStr), WTF_ARRAY_LENGTH(uuidStr)); ASSERT(num == 39); String canonicalUuidStr = String(uuidStr + 1, num - 3).lower(); // remove opening and closing bracket and make it lower. ASSERT(canonicalUuidStr[uuidVersionIdentifierIndex] == uuidVersionRequired); diff --git a/WebCore/platform/android/LanguageAndroid.cpp b/WebCore/platform/android/LanguageAndroid.cpp new file mode 100644 index 0000000..52e614d --- /dev/null +++ b/WebCore/platform/android/LanguageAndroid.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2010, The Android Open Source Project + * + * 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 ``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 "Language.h" + +#include "PlatformBridge.h" +#include "PlatformString.h" + +namespace WebCore { + +// This function is used by Javascript to find out what the default language +// the user has selected. It is used by the JS object Navigator.language +// I guess this information should be mapped with the Accept-Language: HTTP header. +String platformDefaultLanguage() +{ + return PlatformBridge::computeDefaultLanguage(); +} + +} // namespace WebCore diff --git a/WebCore/platform/android/PlatformBridge.h b/WebCore/platform/android/PlatformBridge.h index 334629b..3098d6c 100644 --- a/WebCore/platform/android/PlatformBridge.h +++ b/WebCore/platform/android/PlatformBridge.h @@ -108,6 +108,7 @@ public: static bool cookiesEnabled(const Document*); // Plugin static NPObject* pluginScriptableObject(Widget*); +<<<<<<< HEAD // Popups static bool popupsAllowed(NPP); @@ -139,6 +140,10 @@ public: // Updates the layers on the UI static void updateLayers(FrameView* view); +======= + // Language + static String computeDefaultLanguage(); +>>>>>>> webkit.org at r71558 }; } diff --git a/WebCore/platform/android/TemporaryLinkStubs.cpp b/WebCore/platform/android/TemporaryLinkStubs.cpp index cf8aacf..b1c0276 100644 --- a/WebCore/platform/android/TemporaryLinkStubs.cpp +++ b/WebCore/platform/android/TemporaryLinkStubs.cpp @@ -92,6 +92,7 @@ using namespace WebCore; /* Completely empty stubs (mostly to allow DRT to run): */ /********************************************************/ +<<<<<<< HEAD // This function is used by Javascript to find out what the default language // the user has selected. It is used by the JS object Navigator.language // I guess this information should be mapped with the Accept-Language: HTTP header. @@ -101,6 +102,8 @@ String WebCore::platformDefaultLanguage() return "en"; } +======= +>>>>>>> webkit.org at r71558 namespace WebCore { // This function tells the bridge that a resource was loaded from the cache and thus diff --git a/WebCore/platform/animation/Animation.h b/WebCore/platform/animation/Animation.h index 1541b4d..d16f74c 100644 --- a/WebCore/platform/animation/Animation.h +++ b/WebCore/platform/animation/Animation.h @@ -93,7 +93,7 @@ public: enum { IterationCountInfinite = -1 }; int iterationCount() const { return m_iterationCount; } const String& name() const { return m_name; } - unsigned playState() const { return m_playState; } + EAnimPlayState playState() const { return static_cast<EAnimPlayState>(m_playState); } int property() const { return m_property; } const PassRefPtr<TimingFunction> timingFunction() const { return m_timingFunction; } @@ -103,7 +103,7 @@ public: void setFillMode(unsigned f) { m_fillMode = f; m_fillModeSet = true; } void setIterationCount(int c) { m_iterationCount = c; m_iterationCountSet = true; } void setName(const String& n) { m_name = n; m_nameSet = true; } - void setPlayState(unsigned d) { m_playState = d; m_playStateSet = true; } + void setPlayState(EAnimPlayState d) { m_playState = d; m_playStateSet = true; } void setProperty(int t) { m_property = t; m_propertySet = true; } void setTimingFunction(PassRefPtr<TimingFunction> f) { m_timingFunction = f; m_timingFunctionSet = true; } @@ -155,7 +155,7 @@ public: static unsigned initialAnimationFillMode() { return AnimationFillModeNone; } static int initialAnimationIterationCount() { return 1; } static String initialAnimationName() { return String("none"); } - static unsigned initialAnimationPlayState() { return AnimPlayStatePlaying; } + static EAnimPlayState initialAnimationPlayState() { return AnimPlayStatePlaying; } static int initialAnimationProperty() { return cAnimateAll; } static PassRefPtr<TimingFunction> initialAnimationTimingFunction() { return CubicBezierTimingFunction::create(); } }; diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h index 74bad04..55a4ce0 100644 --- a/WebCore/platform/chromium/ChromiumBridge.h +++ b/WebCore/platform/chromium/ChromiumBridge.h @@ -121,6 +121,7 @@ namespace WebCore { static void prefetchDNS(const String& hostname); // File --------------------------------------------------------------- + static void revealFolderInOS(const String&); static bool fileExists(const String&); static bool deleteFile(const String&); static bool deleteEmptyDirectory(const String&); diff --git a/WebCore/platform/chromium/FileSystemChromium.cpp b/WebCore/platform/chromium/FileSystemChromium.cpp index 975caf6..d8a1e3f 100644 --- a/WebCore/platform/chromium/FileSystemChromium.cpp +++ b/WebCore/platform/chromium/FileSystemChromium.cpp @@ -57,6 +57,11 @@ bool getFileModificationTime(const String& path, time_t& result) return ChromiumBridge::getFileModificationTime(path, result); } +void revealFolderInOS(const String& path) +{ + ChromiumBridge::revealFolderInOS(path); +} + String directoryName(const String& path) { return ChromiumBridge::directoryName(path); diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp index 3c807ba..3ff4ff0 100644 --- a/WebCore/platform/chromium/PopupMenuChromium.cpp +++ b/WebCore/platform/chromium/PopupMenuChromium.cpp @@ -927,15 +927,16 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd // Prepare text to be drawn. String itemText = m_popupClient->itemText(rowIndex); String itemLabel = m_popupClient->itemLabel(rowIndex); + String itemIcon = m_popupClient->itemIcon(rowIndex); if (m_settings.restrictWidthOfListBox) { // Truncate strings to fit in. // FIXME: We should leftTruncate for the rtl case. // StringTruncator::leftTruncate would have to be implemented. String str = StringTruncator::rightTruncate(itemText, maxWidth, itemFont); if (str != itemText) { itemText = str; - // Don't display the label, we already don't have enough room for the - // item text. + // Don't display the label or icon, we already don't have enough room for the item text. itemLabel = ""; + itemIcon = ""; } else if (!itemLabel.isEmpty()) { int availableWidth = maxWidth - kTextToLabelPadding - StringTruncator::width(itemText, itemFont); @@ -966,7 +967,6 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd int remainingWidth = rowRect.width() - rightPadding; // Draw the icon if applicable. - String itemIcon = m_popupClient->itemIcon(rowIndex); RefPtr<Image> image(Image::loadPlatformResource(itemIcon.utf8().data())); if (image && !image->isNull()) { IntRect imageRect = image->rect(); @@ -1089,7 +1089,13 @@ int PopupListBox::getRowHeight(int index) if (index < 0) return 0; - return getRowFont(index).height(); + String icon = m_popupClient->itemIcon(index); + RefPtr<Image> image(Image::loadPlatformResource(icon.utf8().data())); + + int fontHeight = getRowFont(index).height(); + int iconHeight = (image && !image->isNull()) ? image->rect().height() : 0; + + return max(fontHeight, iconHeight); } IntRect PopupListBox::getRowBounds(int index) @@ -1257,6 +1263,8 @@ void PopupListBox::layout() // Ensure the popup is wide enough to fit this item. String text = m_popupClient->itemText(i); String label = m_popupClient->itemLabel(i); + String icon = m_popupClient->itemIcon(i); + RefPtr<Image> iconImage(Image::loadPlatformResource(icon.utf8().data())); int width = 0; if (!text.isEmpty()) width = itemFont.width(TextRun(text)); @@ -1265,6 +1273,12 @@ void PopupListBox::layout() width += kTextToLabelPadding; width += itemFont.width(TextRun(label)); } + if (iconImage && !iconImage->isNull()) { + if (width > 0) + width += kLabelToIconPadding; + width += iconImage->rect().width(); + } + baseWidth = max(baseWidth, width); // FIXME: http://b/1210481 We should get the padding of individual option elements. paddingWidth = max(paddingWidth, diff --git a/WebCore/platform/graphics/Extensions3D.h b/WebCore/platform/graphics/Extensions3D.h new file mode 100644 index 0000000..0aed8e7 --- /dev/null +++ b/WebCore/platform/graphics/Extensions3D.h @@ -0,0 +1,75 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Extensions3D_h +#define Extensions3D_h + +#include <wtf/text/WTFString.h> + +namespace WebCore { + +// This is a base class containing only pure virtual functions. +// Implementations must provide a subclass. +// +// The supported extensions are defined below and in subclasses, +// possibly platform-specific ones. +// +// Calling any extension function not supported by the current context +// must be a no-op; in particular, it may not have side effects. In +// this situation, if the function has a return value, 0 is returned. +class Extensions3D { +public: + virtual ~Extensions3D() {} + + // Supported extensions: + // GL_EXT_texture_format_BGRA8888 + // GL_EXT_read_format_bgra + // GL_ARB_robustness + // GL_EXT_packed_depth_stencil / GL_OES_packed_depth_stencil + + // Takes full name of extension; for example, + // "GL_EXT_texture_format_BGRA8888". + virtual bool supports(const String&) = 0; + + enum { + // GL_EXT_texture_format_BGRA8888 enums + BGRA_EXT = 0x80E1, + + // GL_ARB_robustness enums + GUILTY_CONTEXT_RESET_ARB = 0x8253, + INNOCENT_CONTEXT_RESET_ARB = 0x8254, + UNKNOWN_CONTEXT_RESET_ARB = 0x8255, + + // GL_EXT/OES_packed_depth_stencil enums + DEPTH24_STENCIL8 = 0x88F0 + }; + + // GL_ARB_robustness + virtual int getGraphicsResetStatusARB() = 0; +}; + +} // namespace WebCore + +#endif // Extensions3D_h diff --git a/WebCore/platform/graphics/FloatPoint3D.cpp b/WebCore/platform/graphics/FloatPoint3D.cpp index bb05e7f..ed1816b 100644 --- a/WebCore/platform/graphics/FloatPoint3D.cpp +++ b/WebCore/platform/graphics/FloatPoint3D.cpp @@ -38,10 +38,5 @@ void FloatPoint3D::normalize() } } -float FloatPoint3D::length() const -{ - return sqrtf(lengthSquared()); -} - } // namespace WebCore diff --git a/WebCore/platform/graphics/FloatPoint3D.h b/WebCore/platform/graphics/FloatPoint3D.h index 9ee548d..b6cbaa8 100644 --- a/WebCore/platform/graphics/FloatPoint3D.h +++ b/WebCore/platform/graphics/FloatPoint3D.h @@ -113,8 +113,8 @@ public: return result; } - float length() const; float lengthSquared() const { return this->dot(*this); } + float length() const { return sqrtf(lengthSquared()); } private: float m_x; diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp index ec15d26..52312a4 100644 --- a/WebCore/platform/graphics/GraphicsContext.cpp +++ b/WebCore/platform/graphics/GraphicsContext.cpp @@ -404,25 +404,27 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const th = image->height(); if (useLowQualityScale) { - save(); + InterpolationQuality previousInterpolationQuality = imageInterpolationQuality(); + // FIXME: Should be InterpolationLow setImageInterpolationQuality(InterpolationNone); - } - image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op); - if (useLowQualityScale) - restore(); + image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op); + setImageInterpolationQuality(previousInterpolationQuality); + } else + image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op); } void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& rect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator op, bool useLowQualityScale) { if (paintingDisabled() || !image) return; + if (useLowQualityScale) { - save(); + InterpolationQuality previousInterpolationQuality = imageInterpolationQuality(); setImageInterpolationQuality(InterpolationLow); - } - image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op); - if (useLowQualityScale) - restore(); + image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op); + setImageInterpolationQuality(previousInterpolationQuality); + } else + image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op); } void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, Image::TileRule hRule, Image::TileRule vRule, CompositeOperator op, bool useLowQualityScale) @@ -430,17 +432,19 @@ void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, c if (paintingDisabled() || !image) return; - if (useLowQualityScale) { - save(); - setImageInterpolationQuality(InterpolationLow); - } - if (hRule == Image::StretchTile && vRule == Image::StretchTile) + if (hRule == Image::StretchTile && vRule == Image::StretchTile) { // Just do a scale. drawImage(image, styleColorSpace, dest, srcRect, op); - else + return; + } + + if (useLowQualityScale) { + InterpolationQuality previousInterpolationQuality = imageInterpolationQuality(); + setImageInterpolationQuality(InterpolationLow); + image->drawTiled(this, dest, srcRect, hRule, vRule, styleColorSpace, op); + setImageInterpolationQuality(previousInterpolationQuality); + } else image->drawTiled(this, dest, srcRect, hRule, vRule, styleColorSpace, op); - if (useLowQualityScale) - restore(); } void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntPoint& p, CompositeOperator op) @@ -484,14 +488,13 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS th = image->height(); if (useLowQualityScale) { - save(); + InterpolationQuality previousInterpolationQuality = imageInterpolationQuality(); + // FIXME: Should be InterpolationLow setImageInterpolationQuality(InterpolationNone); - } - - image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale); - - if (useLowQualityScale) - restore(); + image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale); + setImageInterpolationQuality(previousInterpolationQuality); + } else + image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale); } void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h index b1fa48a..a91f3d3 100644 --- a/WebCore/platform/graphics/GraphicsContext.h +++ b/WebCore/platform/graphics/GraphicsContext.h @@ -40,7 +40,6 @@ #if PLATFORM(CG) typedef struct CGContext PlatformGraphicsContext; #elif PLATFORM(CAIRO) -#include "PlatformRefPtrCairo.h" namespace WebCore { class ContextShadow; } @@ -260,7 +259,6 @@ namespace WebCore { void clearRect(const FloatRect&); - void strokeRect(const FloatRect&); void strokeRect(const FloatRect&, float lineWidth); void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver); @@ -289,7 +287,6 @@ namespace WebCore { void addRoundedRectClip(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight); void addInnerRoundedRectClip(const IntRect&, int thickness); void clipOut(const IntRect&); - void clipOutEllipseInRect(const IntRect&); void clipOutRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight); void clipPath(WindRule); void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true); @@ -355,7 +352,6 @@ namespace WebCore { void rotate(float angleInRadians); void translate(const FloatSize& size) { translate(size.width(), size.height()); } void translate(float x, float y); - IntPoint origin(); void setURLForRect(const KURL&, const IntRect&); @@ -434,7 +430,6 @@ namespace WebCore { bool inTransparencyLayer() const; PlatformPath* currentPath(); void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask); - QPen pen(); static QPainter::CompositionMode toQtCompositionMode(CompositeOperator op); #endif diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp index b8c66d5..2a65128 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.cpp +++ b/WebCore/platform/graphics/GraphicsContext3D.cpp @@ -132,13 +132,13 @@ bool GraphicsContext3D::extractImageData(ImageData* imageData, int dataBytes = width * height * 4; data.resize(dataBytes); if (!packPixels(imageData->data()->data()->data(), - kSourceFormatRGBA8, + SourceFormatRGBA8, width, height, 0, format, type, - premultiplyAlpha ? kAlphaDoPremultiply : kAlphaDoNothing, + premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data())) return false; if (flipY) { @@ -164,37 +164,37 @@ bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int heig Vector<uint8_t>& data) { // Assumes format, type, etc. have already been validated. - SourceDataFormat sourceDataFormat = kSourceFormatRGBA8; + SourceDataFormat sourceDataFormat = SourceFormatRGBA8; switch (type) { case UNSIGNED_BYTE: switch (format) { case RGBA: - sourceDataFormat = kSourceFormatRGBA8; + sourceDataFormat = SourceFormatRGBA8; break; case RGB: - sourceDataFormat = kSourceFormatRGB8; + sourceDataFormat = SourceFormatRGB8; break; case ALPHA: - sourceDataFormat = kSourceFormatA8; + sourceDataFormat = SourceFormatA8; break; case LUMINANCE: - sourceDataFormat = kSourceFormatR8; + sourceDataFormat = SourceFormatR8; break; case LUMINANCE_ALPHA: - sourceDataFormat = kSourceFormatRA8; + sourceDataFormat = SourceFormatRA8; break; default: ASSERT_NOT_REACHED(); } break; case UNSIGNED_SHORT_5_5_5_1: - sourceDataFormat = kSourceFormatRGBA5551; + sourceDataFormat = SourceFormatRGBA5551; break; case UNSIGNED_SHORT_4_4_4_4: - sourceDataFormat = kSourceFormatRGBA4444; + sourceDataFormat = SourceFormatRGBA4444; break; case UNSIGNED_SHORT_5_6_5: - sourceDataFormat = kSourceFormatRGB565; + sourceDataFormat = SourceFormatRGB565; break; default: ASSERT_NOT_REACHED(); @@ -213,7 +213,7 @@ bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int heig sourceDataFormat, width, height, unpackAlignment, format, type, - (premultiplyAlpha ? kAlphaDoPremultiply : kAlphaDoNothing), + (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data())) return false; // The pixel data is now tightly packed. @@ -303,6 +303,14 @@ void unpackRGB16BigToRGBA8(const uint16_t* source, uint8_t* destination) destination[3] = 0xFF; } +void unpackBGR8ToRGBA8(const uint8_t* source, uint8_t* destination) +{ + destination[0] = source[2]; + destination[1] = source[1]; + destination[2] = source[0]; + destination[3] = 0xFF; +} + void unpackARGB8ToRGBA8(const uint8_t* source, uint8_t* destination) { destination[0] = source[1]; @@ -327,6 +335,14 @@ void unpackARGB16BigToRGBA8(const uint16_t* source, uint8_t* destination) destination[3] = convertColor16BigTo8(source[0]); } +void unpackABGR8ToRGBA8(const uint8_t* source, uint8_t* destination) +{ + destination[0] = source[3]; + destination[1] = source[2]; + destination[2] = source[1]; + destination[3] = source[0]; +} + void unpackBGRA8ToRGBA8(const uint8_t* source, uint8_t* destination) { destination[0] = source[2]; @@ -566,7 +582,7 @@ void packRGBA8ToRGB8Unmultiply(const uint8_t* source, uint8_t* destination) destination[2] = sourceB; } -// This is only used when the source format is different than kSourceFormatRGBA8. +// This is only used when the source format is different than SourceFormatRGBA8. void packRGBA8ToRGBA8(const uint8_t* source, uint8_t* destination) { destination[0] = source[0]; @@ -772,7 +788,7 @@ static void doPacking(const void* sourceData, unsigned int destinationElementsPerPixel) { switch (sourceDataFormat) { - case GraphicsContext3D::kSourceFormatRGBA8: { + case GraphicsContext3D::SourceFormatRGBA8: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); if (!sourceElementsPerRow) { @@ -789,157 +805,169 @@ static void doPacking(const void* sourceData, } break; } - case GraphicsContext3D::kSourceFormatRGBA16Little: { + case GraphicsContext3D::SourceFormatRGBA16Little: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRGBA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRGBA16Big: { + case GraphicsContext3D::SourceFormatRGBA16Big: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRGBA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRGB8: { + case GraphicsContext3D::SourceFormatRGB8: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint8_t>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint8_t, DestType, unpackRGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRGB16Little: { + case GraphicsContext3D::SourceFormatRGB16Little: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 6, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRGB16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRGB16Big: { + case GraphicsContext3D::SourceFormatRGB16Big: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 6, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRGB16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatARGB8: { + case GraphicsContext3D::SourceFormatBGR8: { + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint8_t>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint8_t, DestType, unpackBGR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); + break; + } + case GraphicsContext3D::SourceFormatARGB8: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint8_t, DestType, unpackARGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatARGB16Little: { + case GraphicsContext3D::SourceFormatARGB16Little: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackARGB16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatARGB16Big: { + case GraphicsContext3D::SourceFormatARGB16Big: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackARGB16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatBGRA8: { + case GraphicsContext3D::SourceFormatABGR8: { + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint8_t, DestType, unpackABGR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); + break; + } + case GraphicsContext3D::SourceFormatBGRA8: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint8_t, DestType, unpackBGRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatBGRA16Little: { + case GraphicsContext3D::SourceFormatBGRA16Little: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackBGRA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatBGRA16Big: { + case GraphicsContext3D::SourceFormatBGRA16Big: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackBGRA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRGBA5551: { + case GraphicsContext3D::SourceFormatRGBA5551: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRGBA5551ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRGBA4444: { + case GraphicsContext3D::SourceFormatRGBA4444: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRGBA4444ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRGB565: { + case GraphicsContext3D::SourceFormatRGB565: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRGB565ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatR8: { + case GraphicsContext3D::SourceFormatR8: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint8_t, DestType, unpackR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatR16Little: { + case GraphicsContext3D::SourceFormatR16Little: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackR16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatR16Big: { + case GraphicsContext3D::SourceFormatR16Big: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackR16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRA8: { + case GraphicsContext3D::SourceFormatRA8: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint8_t, DestType, unpackRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRA16Little: { + case GraphicsContext3D::SourceFormatRA16Little: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatRA16Big: { + case GraphicsContext3D::SourceFormatRA16Big: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackRA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatAR8: { + case GraphicsContext3D::SourceFormatAR8: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint8_t, DestType, unpackAR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatAR16Little: { + case GraphicsContext3D::SourceFormatAR16Little: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackAR16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatAR16Big: { + case GraphicsContext3D::SourceFormatAR16Big: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackAR16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatA8: { + case GraphicsContext3D::SourceFormatA8: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint8_t, DestType, unpackA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatA16Little: { + case GraphicsContext3D::SourceFormatA16Little: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } - case GraphicsContext3D::kSourceFormatA16Big: { + case GraphicsContext3D::SourceFormatA16Big: { unsigned int sourceElementsPerPixel, sourceElementsPerRow; computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); doUnpackingAndPacking<uint16_t, DestType, unpackA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); @@ -963,7 +991,7 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, switch (destinationType) { case UNSIGNED_BYTE: { uint8_t* destination = static_cast<uint8_t*>(destinationData); - if (sourceDataFormat == kSourceFormatRGBA8 && destinationFormat == RGBA && sourceUnpackAlignment <= 4 && alphaOp == kAlphaDoNothing) { + if (sourceDataFormat == SourceFormatRGBA8 && destinationFormat == RGBA && sourceUnpackAlignment <= 4 && alphaOp == AlphaDoNothing) { // No conversion necessary. memcpy(destinationData, sourceData, width * height * 4); break; @@ -971,27 +999,27 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, switch (destinationFormat) { case RGB: switch (alphaOp) { - case kAlphaDoNothing: + case AlphaDoNothing: doPacking<uint8_t, packRGBA8ToRGB8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3); break; - case kAlphaDoPremultiply: + case AlphaDoPremultiply: doPacking<uint8_t, packRGBA8ToRGB8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3); break; - case kAlphaDoUnmultiply: + case AlphaDoUnmultiply: doPacking<uint8_t, packRGBA8ToRGB8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3); break; } break; case RGBA: switch (alphaOp) { - case kAlphaDoNothing: - ASSERT(sourceDataFormat != kSourceFormatRGBA8 || sourceUnpackAlignment > 4); // Handled above with fast case. + case AlphaDoNothing: + ASSERT(sourceDataFormat != SourceFormatRGBA8 || sourceUnpackAlignment > 4); // Handled above with fast case. doPacking<uint8_t, packRGBA8ToRGBA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4); break; - case kAlphaDoPremultiply: + case AlphaDoPremultiply: doPacking<uint8_t, packRGBA8ToRGBA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4); break; - case kAlphaDoUnmultiply: + case AlphaDoUnmultiply: doPacking<uint8_t, packRGBA8ToRGBA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4); break; default: @@ -1009,13 +1037,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, // specification, Table 3.15), the red channel is chosen // from the RGBA data. switch (alphaOp) { - case kAlphaDoNothing: + case AlphaDoNothing: doPacking<uint8_t, packRGBA8ToR8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; - case kAlphaDoPremultiply: + case AlphaDoPremultiply: doPacking<uint8_t, packRGBA8ToR8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; - case kAlphaDoUnmultiply: + case AlphaDoUnmultiply: doPacking<uint8_t, packRGBA8ToR8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; } @@ -1025,13 +1053,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, // specification, Table 3.15), the red and alpha channels // are chosen from the RGBA data. switch (alphaOp) { - case kAlphaDoNothing: + case AlphaDoNothing: doPacking<uint8_t, packRGBA8ToRA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2); break; - case kAlphaDoPremultiply: + case AlphaDoPremultiply: doPacking<uint8_t, packRGBA8ToRA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2); break; - case kAlphaDoUnmultiply: + case AlphaDoUnmultiply: doPacking<uint8_t, packRGBA8ToRA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2); break; } @@ -1042,13 +1070,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, case UNSIGNED_SHORT_4_4_4_4: { uint16_t* destination = static_cast<uint16_t*>(destinationData); switch (alphaOp) { - case kAlphaDoNothing: + case AlphaDoNothing: doPacking<uint16_t, packRGBA8ToUnsignedShort4444>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; - case kAlphaDoPremultiply: + case AlphaDoPremultiply: doPacking<uint16_t, packRGBA8ToUnsignedShort4444Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; - case kAlphaDoUnmultiply: + case AlphaDoUnmultiply: doPacking<uint16_t, packRGBA8ToUnsignedShort4444Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; } @@ -1057,13 +1085,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, case UNSIGNED_SHORT_5_5_5_1: { uint16_t* destination = static_cast<uint16_t*>(destinationData); switch (alphaOp) { - case kAlphaDoNothing: + case AlphaDoNothing: doPacking<uint16_t, packRGBA8ToUnsignedShort5551>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; - case kAlphaDoPremultiply: + case AlphaDoPremultiply: doPacking<uint16_t, packRGBA8ToUnsignedShort5551Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; - case kAlphaDoUnmultiply: + case AlphaDoUnmultiply: doPacking<uint16_t, packRGBA8ToUnsignedShort5551Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; } @@ -1072,13 +1100,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, case UNSIGNED_SHORT_5_6_5: { uint16_t* destination = static_cast<uint16_t*>(destinationData); switch (alphaOp) { - case kAlphaDoNothing: + case AlphaDoNothing: doPacking<uint16_t, packRGBA8ToUnsignedShort565>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; - case kAlphaDoPremultiply: + case AlphaDoPremultiply: doPacking<uint16_t, packRGBA8ToUnsignedShort565Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; - case kAlphaDoUnmultiply: + case AlphaDoUnmultiply: doPacking<uint16_t, packRGBA8ToUnsignedShort565Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; } @@ -1088,55 +1116,6 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, return true; } -#if !PLATFORM(CHROMIUM) -bool GraphicsContext3D::supportsBGRA() -{ - // For OpenGL ES2.0, this requires checking for - // GL_EXT_texture_format_BGRA8888 and GL_EXT_read_format_bgra. - // For desktop GL, BGRA has been supported since OpenGL 1.2. - - // However, note that the GL ES2 extension requires the internalFormat to - // glTexImage2D() be GL_BGRA, while desktop GL will not accept GL_BGRA - // (must be GL_RGBA), so this must be checked on each platform. - // Returning false for now to be safe. - return false; -} - -bool GraphicsContext3D::supportsMapSubCHROMIUM() -{ - // We don't claim support for this extension at this time. - return false; -} - -void* GraphicsContext3D::mapBufferSubDataCHROMIUM(unsigned, int, int, unsigned) -{ - return 0; -} - -void GraphicsContext3D::unmapBufferSubDataCHROMIUM(const void*) -{ -} - -void* GraphicsContext3D::mapTexSubImage2DCHROMIUM(unsigned, int, int, int, int, int, unsigned, unsigned, unsigned) -{ - return 0; -} - -void GraphicsContext3D::unmapTexSubImage2DCHROMIUM(const void*) -{ -} - -bool GraphicsContext3D::supportsCopyTextureToParentTextureCHROMIUM() -{ - // We don't claim support for this extension at this time. - return false; -} - -void GraphicsContext3D::copyTextureToParentTextureCHROMIUM(unsigned, unsigned) -{ -} -#endif - } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h index 20b4e2d..e34a2f8 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.h +++ b/WebCore/platform/graphics/GraphicsContext3D.h @@ -76,6 +76,10 @@ const Platform3DObject NullPlatform3DObject = 0; namespace WebCore { class CanvasRenderingContext; class DrawingBuffer; +class Extensions3D; +#if PLATFORM(MAC) +class Extensions3DOpenGL; +#endif class HostWindow; class Image; class ImageData; @@ -347,8 +351,6 @@ public: VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A, VERTEX_ATTRIB_ARRAY_POINTER = 0x8645, VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F, - IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A, - IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B, COMPILE_STATUS = 0x8B81, INFO_LOG_LENGTH = 0x8B84, SHADER_SOURCE_LENGTH = 0x8B88, @@ -401,19 +403,7 @@ public: // WebGL-specific enums UNPACK_FLIP_Y_WEBGL = 0x9240, UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241, - - // GL_EXT_texture_format_BGRA8888 - BGRA_EXT = 0x80E1, - - // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object) - READ_ONLY = 0x88B8, - WRITE_ONLY = 0x88B9, - - // GL_ARB_robustness enums - GUILTY_CONTEXT_RESET_ARB = 0x8253, - INNOCENT_CONTEXT_RESET_ARB = 0x8254, - UNKNOWN_CONTEXT_RESET_ARB = 0x8255 - + CONTEXT_LOST_WEBGL = 0x9242, }; // Context creation attributes. @@ -424,6 +414,7 @@ public: , stencil(false) , antialias(true) , premultipliedAlpha(true) + , canRecoverFromContextLoss(true) { } @@ -432,6 +423,7 @@ public: bool stencil; bool antialias; bool premultipliedAlpha; + bool canRecoverFromContextLoss; }; enum RenderStyle { @@ -540,34 +532,36 @@ public: // uploading. This enum must be public because it is accessed // by non-member functions. enum SourceDataFormat { - kSourceFormatRGBA8 = 0, - kSourceFormatRGBA16Little, - kSourceFormatRGBA16Big, - kSourceFormatRGB8, - kSourceFormatRGB16Little, - kSourceFormatRGB16Big, - kSourceFormatBGRA8, - kSourceFormatBGRA16Little, - kSourceFormatBGRA16Big, - kSourceFormatARGB8, - kSourceFormatARGB16Little, - kSourceFormatARGB16Big, - kSourceFormatRGBA5551, - kSourceFormatRGBA4444, - kSourceFormatRGB565, - kSourceFormatR8, - kSourceFormatR16Little, - kSourceFormatR16Big, - kSourceFormatRA8, - kSourceFormatRA16Little, - kSourceFormatRA16Big, - kSourceFormatAR8, - kSourceFormatAR16Little, - kSourceFormatAR16Big, - kSourceFormatA8, - kSourceFormatA16Little, - kSourceFormatA16Big, - kSourceFormatNumFormats + SourceFormatRGBA8 = 0, + SourceFormatRGBA16Little, + SourceFormatRGBA16Big, + SourceFormatRGB8, + SourceFormatRGB16Little, + SourceFormatRGB16Big, + SourceFormatBGR8, + SourceFormatBGRA8, + SourceFormatBGRA16Little, + SourceFormatBGRA16Big, + SourceFormatARGB8, + SourceFormatARGB16Little, + SourceFormatARGB16Big, + SourceFormatABGR8, + SourceFormatRGBA5551, + SourceFormatRGBA4444, + SourceFormatRGB565, + SourceFormatR8, + SourceFormatR16Little, + SourceFormatR16Big, + SourceFormatRA8, + SourceFormatRA16Little, + SourceFormatRA16Big, + SourceFormatAR8, + SourceFormatAR16Little, + SourceFormatAR16Big, + SourceFormatA8, + SourceFormatA16Little, + SourceFormatA16Big, + SourceFormatNumFormats }; //---------------------------------------------------------------------- @@ -786,22 +780,11 @@ public: // getError in the order they were added. void synthesizeGLError(unsigned long error); - // EXT_texture_format_BGRA8888 - bool supportsBGRA(); - - // GL_CHROMIUM_map_sub - bool supportsMapSubCHROMIUM(); - void* mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access); - void unmapBufferSubDataCHROMIUM(const void*); - void* mapTexSubImage2DCHROMIUM(unsigned target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, unsigned access); - void unmapTexSubImage2DCHROMIUM(const void*); - - // GL_CHROMIUM_copy_texture_to_parent_texture - bool supportsCopyTextureToParentTextureCHROMIUM(); - void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture); - - // GL_ARB_robustness - int getGraphicsResetStatusARB(); + // Support for extensions. Returns a non-null object, though not + // all methods it contains may necessarily be supported on the + // current hardware. Must call Extensions3D::supports() to + // determine this. + Extensions3D* getExtensions(); private: GraphicsContext3D(Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow); @@ -832,9 +815,9 @@ public: // pixel packing. FIXME: kAlphaDoUnmultiply is lossy and must // be removed. enum AlphaOp { - kAlphaDoNothing = 0, - kAlphaDoPremultiply = 1, - kAlphaDoUnmultiply = 2 + AlphaDoNothing = 0, + AlphaDoPremultiply = 1, + AlphaDoUnmultiply = 2 }; // Helper for getImageData which implements packing of pixel @@ -872,6 +855,8 @@ public: ANGLEWebKitBridge m_compiler; + OwnPtr<Extensions3DOpenGL> m_extensions; + Attributes m_attrs; Vector<Vector<float> > m_vertexArray; diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp index 79c33e0..9fb2d4a 100644 --- a/WebCore/platform/graphics/MediaPlayer.cpp +++ b/WebCore/platform/graphics/MediaPlayer.cpp @@ -648,6 +648,11 @@ MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const return m_private->movieLoadType(); } +float MediaPlayer::mediaTimeForTimeValue(float timeValue) const +{ + return m_private->mediaTimeForTimeValue(timeValue); +} + // Client callbacks. void MediaPlayer::networkStateChanged() { diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h index bf445e3..a199352 100644 --- a/WebCore/platform/graphics/MediaPlayer.h +++ b/WebCore/platform/graphics/MediaPlayer.h @@ -279,6 +279,8 @@ public: bool hasSingleSecurityOrigin() const; + float mediaTimeForTimeValue(float) const; + private: MediaPlayer(MediaPlayerClient*); diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h index a8d9b86..6a74714 100644 --- a/WebCore/platform/graphics/MediaPlayerPrivate.h +++ b/WebCore/platform/graphics/MediaPlayerPrivate.h @@ -125,6 +125,10 @@ public: virtual void prepareForRendering() { } + // Time value in the movie's time scale. It is only necessary to override this if the media + // engine uses rational numbers to represent media time. + virtual float mediaTimeForTimeValue(float timeValue) const { return timeValue; } + }; } diff --git a/WebCore/platform/graphics/cairo/CairoUtilities.cpp b/WebCore/platform/graphics/cairo/CairoUtilities.cpp index 7af5577..709ee8f 100644 --- a/WebCore/platform/graphics/cairo/CairoUtilities.cpp +++ b/WebCore/platform/graphics/cairo/CairoUtilities.cpp @@ -34,7 +34,7 @@ #include "IntRect.h" #include "OwnPtrCairo.h" #include "Path.h" -#include "PlatformRefPtrCairo.h" +#include "RefPtrCairo.h" #include <wtf/Vector.h> namespace WebCore { @@ -126,11 +126,11 @@ void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSiz cairo_save(cr); - PlatformRefPtr<cairo_surface_t> clippedImageSurface = 0; + RefPtr<cairo_surface_t> clippedImageSurface = 0; if (tileRect.size() != imageSize) { IntRect imageRect = enclosingIntRect(tileRect); - clippedImageSurface = adoptPlatformRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, imageRect.width(), imageRect.height())); - PlatformRefPtr<cairo_t> clippedImageContext(cairo_create(clippedImageSurface.get())); + clippedImageSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, imageRect.width(), imageRect.height())); + RefPtr<cairo_t> clippedImageContext(cairo_create(clippedImageSurface.get())); cairo_set_source_surface(clippedImageContext.get(), image, -tileRect.x(), -tileRect.y()); cairo_paint(clippedImageContext.get()); image = clippedImageSurface.get(); diff --git a/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp index cd9ee46..61ee625 100644 --- a/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp +++ b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp @@ -25,7 +25,7 @@ #include "CString.h" #include "Font.h" #include "OwnPtrCairo.h" -#include "PlatformRefPtrCairo.h" +#include "RefPtrCairo.h" #include "SimpleFontData.h" #include <cairo-ft.h> #include <cairo.h> @@ -83,17 +83,17 @@ FcPattern* findBestFontGivenFallbacks(const FontPlatformData& fontData, FcPatter const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) { - PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(createFontConfigPatternForCharacters(characters, length)); + RefPtr<FcPattern> pattern = adoptRef(createFontConfigPatternForCharacters(characters, length)); const FontPlatformData& fontData = font.primaryFont()->platformData(); - PlatformRefPtr<FcPattern> fallbackPattern = adoptPlatformRef(findBestFontGivenFallbacks(fontData, pattern.get())); + RefPtr<FcPattern> fallbackPattern = adoptRef(findBestFontGivenFallbacks(fontData, pattern.get())); if (fallbackPattern) { FontPlatformData alternateFontData(fallbackPattern.get(), font.fontDescription()); return getCachedFontData(&alternateFontData); } FcResult fontConfigResult; - PlatformRefPtr<FcPattern> resultPattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fontConfigResult)); + RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult)); if (!resultPattern) return 0; FontPlatformData alternateFontData(resultPattern.get(), font.fontDescription()); @@ -147,7 +147,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm) // says that we must find an exact match for font family, slant (italic or oblique can be used) // and font weight (we only match bold/non-bold here). - PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(FcPatternCreate()); + RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate()); String familyNameString(getFamilyNameStringFromFontDescriptionAndFamily(fontDescription, family)); if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data()))) return 0; @@ -174,7 +174,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD String familyNameAfterConfiguration = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterConfiguration)); FcResult fontConfigResult; - PlatformRefPtr<FcPattern> resultPattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fontConfigResult)); + RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult)); if (!resultPattern) // No match. return 0; diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp index ba307fa..394082d 100644 --- a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp +++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp @@ -120,8 +120,9 @@ FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fo , m_syntheticBold(false) , m_syntheticOblique(false) , m_fixedWidth(false) + , m_scaledFont(0) { - PlatformRefPtr<cairo_font_face_t> fontFace = adoptPlatformRef(cairo_ft_font_face_create_for_pattern(m_pattern.get())); + RefPtr<cairo_font_face_t> fontFace = adoptRef(cairo_ft_font_face_create_for_pattern(m_pattern.get())); initializeWithFontFace(fontFace.get()); int spacing; @@ -142,6 +143,7 @@ FontPlatformData::FontPlatformData(float size, bool bold, bool italic) , m_syntheticBold(bold) , m_syntheticOblique(italic) , m_fixedWidth(false) + , m_scaledFont(0) { // We cannot create a scaled font here. } @@ -151,13 +153,14 @@ FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, float size, bool , m_size(size) , m_syntheticBold(bold) , m_syntheticOblique(italic) + , m_scaledFont(0) { initializeWithFontFace(fontFace); - FT_Face fontConfigFace = cairo_ft_scaled_font_lock_face(m_scaledFont.get()); + FT_Face fontConfigFace = cairo_ft_scaled_font_lock_face(m_scaledFont); if (fontConfigFace) { m_fixedWidth = fontConfigFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH; - cairo_ft_scaled_font_unlock_face(m_scaledFont.get()); + cairo_ft_scaled_font_unlock_face(m_scaledFont); } } @@ -171,7 +174,6 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) m_syntheticBold = other.m_syntheticBold; m_syntheticOblique = other.m_syntheticOblique; m_fixedWidth = other.m_fixedWidth; - m_scaledFont = other.m_scaledFont; m_pattern = other.m_pattern; if (m_fallbacks) { @@ -180,11 +182,16 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) m_fallbacks = 0; } + if (m_scaledFont && m_scaledFont != hashTableDeletedFontValue()) + cairo_scaled_font_destroy(m_scaledFont); + m_scaledFont = cairo_scaled_font_reference(other.m_scaledFont); + return *this; } FontPlatformData::FontPlatformData(const FontPlatformData& other) : m_fallbacks(0) + , m_scaledFont(0) { *this = other; } @@ -196,7 +203,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& other, float size) // We need to reinitialize the instance, because the difference in size // necessitates a new scaled font instance. m_size = size; - initializeWithFontFace(cairo_scaled_font_get_font_face(m_scaledFont.get())); + initializeWithFontFace(cairo_scaled_font_get_font_face(m_scaledFont)); } FontPlatformData::~FontPlatformData() @@ -205,6 +212,9 @@ FontPlatformData::~FontPlatformData() FcFontSetDestroy(m_fallbacks); m_fallbacks = 0; } + + if (m_scaledFont && m_scaledFont != hashTableDeletedFontValue()) + cairo_scaled_font_destroy(m_scaledFont); } bool FontPlatformData::isFixedPitch() @@ -216,7 +226,7 @@ bool FontPlatformData::operator==(const FontPlatformData& other) const { if (m_pattern == other.m_pattern) return true; - if (!m_pattern || m_pattern.isHashTableDeletedValue() || !other.m_pattern || other.m_pattern.isHashTableDeletedValue()) + if (!m_pattern || !other.m_pattern) return false; return FcPatternEqual(m_pattern.get(), other.m_pattern.get()); } @@ -256,7 +266,7 @@ void FontPlatformData::initializeWithFontFace(cairo_font_face_t* fontFace) cairo_matrix_scale(&fontMatrix, m_size, m_size); } - m_scaledFont = adoptPlatformRef(cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options)); + m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options); cairo_font_options_destroy(options); } diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h index d47d556..016489e 100644 --- a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h +++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h @@ -29,7 +29,7 @@ #include "FontDescription.h" #include "GlyphBuffer.h" #include "HashFunctions.h" -#include "PlatformRefPtrCairo.h" +#include "RefPtrCairo.h" #include <wtf/Forward.h> typedef struct _FcFontSet FcFontSet; @@ -43,7 +43,7 @@ public: , m_size(0) , m_syntheticBold(false) , m_syntheticOblique(false) - , m_scaledFont(WTF::HashTableDeletedValue) + , m_scaledFont(hashTableDeletedFontValue()) { } FontPlatformData() @@ -51,6 +51,7 @@ public: , m_size(0) , m_syntheticBold(false) , m_syntheticOblique(false) + , m_scaledFont(0) { } FontPlatformData(FcPattern*, const FontDescription&); @@ -67,34 +68,35 @@ public: bool syntheticBold() const { return m_syntheticBold; } bool syntheticOblique() const { return m_syntheticOblique; } - cairo_scaled_font_t* scaledFont() const { return m_scaledFont.get(); } + cairo_scaled_font_t* scaledFont() const { return m_scaledFont; } unsigned hash() const { - return PtrHash<cairo_scaled_font_t*>::hash(m_scaledFont.get()); + return PtrHash<cairo_scaled_font_t*>::hash(m_scaledFont); } bool operator==(const FontPlatformData&) const; FontPlatformData& operator=(const FontPlatformData&); bool isHashTableDeletedValue() const { - return m_scaledFont.isHashTableDeletedValue(); + return m_scaledFont == hashTableDeletedFontValue(); } #ifndef NDEBUG String description() const; #endif - PlatformRefPtr<FcPattern> m_pattern; + RefPtr<FcPattern> m_pattern; mutable FcFontSet* m_fallbacks; // Initialized lazily. float m_size; bool m_syntheticBold; bool m_syntheticOblique; bool m_fixedWidth; - PlatformRefPtr<cairo_scaled_font_t> m_scaledFont; + cairo_scaled_font_t* m_scaledFont; private: void initializeWithFontFace(cairo_font_face_t*); + static cairo_scaled_font_t* hashTableDeletedFontValue() { return reinterpret_cast<cairo_scaled_font_t*>(-1); } }; } diff --git a/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp b/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp index 66e9c16..e2f09f4 100644 --- a/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp +++ b/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp @@ -45,7 +45,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b if (bufferLength > GlyphPage::size) return false; - FT_Face face = cairo_ft_scaled_font_lock_face(fontData->platformData().m_scaledFont.get()); + FT_Face face = cairo_ft_scaled_font_lock_face(fontData->platformData().scaledFont()); if (!face) return false; @@ -60,7 +60,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b } } - cairo_ft_scaled_font_unlock_face(fontData->platformData().m_scaledFont.get()); + cairo_ft_scaled_font_unlock_face(fontData->platformData().scaledFont()); return haveGlyphs; } diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index 0847da1..755adff 100644 --- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -46,7 +46,7 @@ #include "NotImplemented.h" #include "Path.h" #include "Pattern.h" -#include "PlatformRefPtrCairo.h" +#include "RefPtrCairo.h" #include "SimpleFontData.h" #include <cairo.h> #include <math.h> @@ -766,14 +766,6 @@ void GraphicsContext::translate(float x, float y) m_data->translate(x, y); } -IntPoint GraphicsContext::origin() -{ - cairo_matrix_t matrix; - cairo_t* cr = m_data->cr; - cairo_get_matrix(cr, &matrix); - return IntPoint(static_cast<int>(matrix.x0), static_cast<int>(matrix.y0)); -} - void GraphicsContext::setPlatformFillColor(const Color& col, ColorSpace colorSpace) { // Cairo contexts can't hold separate fill and stroke colors @@ -1092,16 +1084,6 @@ void GraphicsContext::clipOut(const IntRect& r) cairo_set_fill_rule(cr, savedFillRule); } -void GraphicsContext::clipOutEllipseInRect(const IntRect& r) -{ - if (paintingDisabled()) - return; - - Path p; - p.addEllipse(r); - clipOut(p); -} - static inline FloatPoint getPhase(const FloatRect& dest, const FloatRect& tile) { FloatPoint phase = dest.location(); diff --git a/WebCore/platform/graphics/cairo/ImageCairo.cpp b/WebCore/platform/graphics/cairo/ImageCairo.cpp index 8f7a194..0ac3955 100644 --- a/WebCore/platform/graphics/cairo/ImageCairo.cpp +++ b/WebCore/platform/graphics/cairo/ImageCairo.cpp @@ -35,10 +35,10 @@ #include "Color.h" #include "ContextShadow.h" #include "FloatRect.h" -#include "PlatformRefPtrCairo.h" #include "GraphicsContext.h" #include "ImageBuffer.h" #include "ImageObserver.h" +#include "RefPtrCairo.h" #include <cairo.h> #include <math.h> #include <wtf/OwnPtr.h> diff --git a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp b/WebCore/platform/graphics/cairo/RefPtrCairo.cpp index d289585..a6c983e 100644 --- a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp +++ b/WebCore/platform/graphics/cairo/RefPtrCairo.cpp @@ -17,7 +17,7 @@ */ #include "config.h" -#include "PlatformRefPtrCairo.h" +#include "RefPtrCairo.h" #include <cairo.h> @@ -28,71 +28,67 @@ namespace WTF { -template <> cairo_t* refPlatformPtr(cairo_t* ptr) +template<> void refIfNotNull(cairo_t* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) cairo_reference(ptr); - return ptr; } -template <> void derefPlatformPtr(cairo_t* ptr) +template<> void derefIfNotNull(cairo_t* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) cairo_destroy(ptr); } -template <> cairo_surface_t* refPlatformPtr(cairo_surface_t* ptr) +template<> void refIfNotNull(cairo_surface_t* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) cairo_surface_reference(ptr); - return ptr; } -template <> void derefPlatformPtr(cairo_surface_t* ptr) +template<> void derefIfNotNull(cairo_surface_t* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) cairo_surface_destroy(ptr); } -template <> cairo_font_face_t* refPlatformPtr(cairo_font_face_t* ptr) +template<> void refIfNotNull(cairo_font_face_t* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) cairo_font_face_reference(ptr); - return ptr; } -template <> void derefPlatformPtr(cairo_font_face_t* ptr) +template<> void derefIfNotNull(cairo_font_face_t* ptr) { - if (ptr) - cairo_font_face_destroy(ptr); + if (LIKELY(ptr != 0)) + cairo_font_face_reference(ptr); } -template <> cairo_scaled_font_t* refPlatformPtr(cairo_scaled_font_t* ptr) +template<> void refIfNotNull(cairo_scaled_font_t* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) cairo_scaled_font_reference(ptr); - return ptr; } -template <> void derefPlatformPtr(cairo_scaled_font_t* ptr) +template<> void derefIfNotNull(cairo_scaled_font_t* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) cairo_scaled_font_destroy(ptr); } #if defined(USE_FREETYPE) -template <> FcPattern* refPlatformPtr(FcPattern* ptr) +template<> void refIfNotNull(FcPattern* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) FcPatternReference(ptr); - return ptr; } -template <> void derefPlatformPtr(FcPattern* ptr) +template<> void derefIfNotNull(FcPattern* ptr) { - if (ptr) + if (LIKELY(ptr != 0)) FcPatternDestroy(ptr); } + #endif } diff --git a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h b/WebCore/platform/graphics/cairo/RefPtrCairo.h index 3b720c6..0429ec5 100644 --- a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h +++ b/WebCore/platform/graphics/cairo/RefPtrCairo.h @@ -17,10 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef PlatformRefPtrCairo_h -#define PlatformRefPtrCairo_h +#ifndef RefPtrCairo_h +#define RefPtrCairo_h -#include "PlatformRefPtr.h" +#include "RefPtr.h" typedef struct _cairo cairo_t; typedef struct _cairo_surface cairo_surface_t; @@ -33,23 +33,23 @@ typedef struct _FcPattern FcPattern; namespace WTF { -template <> cairo_t* refPlatformPtr(cairo_t* ptr); -template <> void derefPlatformPtr(cairo_t* ptr); +template<> void refIfNotNull(cairo_t* ptr); +template<> void derefIfNotNull(cairo_t* ptr); -template <> cairo_surface_t* refPlatformPtr(cairo_surface_t* ptr); -template <> void derefPlatformPtr(cairo_surface_t* ptr); +template<> void refIfNotNull(cairo_surface_t* ptr); +template<> void derefIfNotNull(cairo_surface_t* ptr); -template <> cairo_font_face_t* refPlatformPtr(cairo_font_face_t*); -template <> void derefPlatformPtr(cairo_font_face_t*); +template<> void refIfNotNull(cairo_font_face_t* ptr); +template<> void derefIfNotNull(cairo_font_face_t* ptr); -template <> cairo_scaled_font_t* refPlatformPtr(cairo_scaled_font_t*); -template <> void derefPlatformPtr(cairo_scaled_font_t*); +template<> void refIfNotNull(cairo_scaled_font_t* ptr); +template<> void derefIfNotNull(cairo_scaled_font_t* ptr); #if defined(USE_FREETYPE) -template <> FcPattern* refPlatformPtr(FcPattern*); -template <> void derefPlatformPtr(FcPattern*); +template<> void refIfNotNull(FcPattern* ptr); +template<> void derefIfNotNull(FcPattern* ptr); #endif } -#endif +#endif // RefPtrCairo_h diff --git a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp index 3d7c34b..d350294 100644 --- a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp +++ b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp @@ -49,7 +49,7 @@ void SimpleFontData::platformInit() { cairo_font_extents_t font_extents; cairo_text_extents_t text_extents; - cairo_scaled_font_extents(m_platformData.m_scaledFont.get(), &font_extents); + cairo_scaled_font_extents(m_platformData.scaledFont(), &font_extents); m_ascent = static_cast<int>(lroundf(font_extents.ascent)); m_descent = static_cast<int>(lroundf(font_extents.descent)); m_lineSpacing = static_cast<int>(lroundf(font_extents.height)); @@ -60,9 +60,9 @@ void SimpleFontData::platformInit() // while we figure out what's going on. if (m_lineSpacing < m_ascent + m_descent) m_lineSpacing = m_ascent + m_descent; - cairo_scaled_font_text_extents(m_platformData.m_scaledFont.get(), "x", &text_extents); + cairo_scaled_font_text_extents(m_platformData.scaledFont(), "x", &text_extents); m_xHeight = text_extents.height; - cairo_scaled_font_text_extents(m_platformData.m_scaledFont.get(), " ", &text_extents); + cairo_scaled_font_text_extents(m_platformData.scaledFont(), " ", &text_extents); m_spaceWidth = static_cast<float>(text_extents.x_advance); m_lineGap = m_lineSpacing - m_ascent - m_descent; m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f; @@ -94,19 +94,19 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes bool SimpleFontData::containsCharacters(const UChar* characters, int length) const { - FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.m_scaledFont.get()); + FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.scaledFont()); if (!face) return false; for (int i = 0; i < length; i++) { if (FcFreeTypeCharIndex(face, characters[i]) == 0) { - cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont.get()); + cairo_ft_scaled_font_unlock_face(m_platformData.scaledFont()); return false; } } - cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont.get()); + cairo_ft_scaled_font_unlock_face(m_platformData.scaledFont()); return true; } @@ -123,14 +123,14 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const float SimpleFontData::platformWidthForGlyph(Glyph glyph) const { - ASSERT(m_platformData.m_scaledFont); + ASSERT(m_platformData.scaledFont()); cairo_glyph_t cglyph = { glyph, 0, 0 }; cairo_text_extents_t extents; - cairo_scaled_font_glyph_extents(m_platformData.m_scaledFont.get(), &cglyph, 1, &extents); + cairo_scaled_font_glyph_extents(m_platformData.scaledFont(), &cglyph, 1, &extents); float w = (float)m_spaceWidth; - if (cairo_scaled_font_status(m_platformData.m_scaledFont.get()) == CAIRO_STATUS_SUCCESS && extents.x_advance) + if (cairo_scaled_font_status(m_platformData.scaledFont()) == CAIRO_STATUS_SUCCESS && extents.x_advance) w = (float)extents.x_advance; return w; diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp index a1cc805..0c6acf9 100644 --- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp @@ -59,7 +59,7 @@ enum AlphaFormat { AlphaFormatNumFormats }; -// This returns kSourceFormatNumFormats if the combination of input parameters is unsupported. +// This returns SourceFormatNumFormats if the combination of input parameters is unsupported. static GraphicsContext3D::SourceDataFormat getSourceDataFormat(unsigned int componentsPerPixel, AlphaFormat alphaFormat, bool is16BitFormat, bool bigEndian) { const static SourceDataFormatBase formatTableBase[4][AlphaFormatNumFormats] = { // componentsPerPixel x AlphaFormat @@ -69,26 +69,22 @@ static GraphicsContext3D::SourceDataFormat getSourceDataFormat(unsigned int comp { SourceFormatBaseRGB, SourceFormatBaseNumFormats, SourceFormatBaseNumFormats }, // 3 componentsPerPixel { SourceFormatBaseNumFormats, SourceFormatBaseARGB, SourceFormatBaseRGBA } // 4 componentsPerPixel }; - const static GraphicsContext3D::SourceDataFormat formatTable[SourceFormatBaseNumFormats][3] = { // SourceDataFormatBase x bitsPerComponentAndEndian - // 8bits 16bits, little endian 16bits, big endian - { GraphicsContext3D::kSourceFormatR8, GraphicsContext3D::kSourceFormatR16Little, GraphicsContext3D::kSourceFormatR16Big }, - { GraphicsContext3D::kSourceFormatA8, GraphicsContext3D::kSourceFormatA16Little, GraphicsContext3D::kSourceFormatA16Big }, - { GraphicsContext3D::kSourceFormatRA8, GraphicsContext3D::kSourceFormatRA16Little, GraphicsContext3D::kSourceFormatRA16Big }, - { GraphicsContext3D::kSourceFormatAR8, GraphicsContext3D::kSourceFormatAR16Little, GraphicsContext3D::kSourceFormatAR16Big }, - { GraphicsContext3D::kSourceFormatRGB8, GraphicsContext3D::kSourceFormatRGB16Little, GraphicsContext3D::kSourceFormatRGB16Big }, - { GraphicsContext3D::kSourceFormatRGBA8, GraphicsContext3D::kSourceFormatRGBA16Little, GraphicsContext3D::kSourceFormatRGBA16Big }, - { GraphicsContext3D::kSourceFormatARGB8, GraphicsContext3D::kSourceFormatARGB16Little, GraphicsContext3D::kSourceFormatARGB16Big } + const static GraphicsContext3D::SourceDataFormat formatTable[SourceFormatBaseNumFormats][4] = { // SourceDataFormatBase x bitsPerComponent x endian + // 8bits, little endian 8bits, big endian 16bits, little endian 16bits, big endian + { GraphicsContext3D::SourceFormatR8, GraphicsContext3D::SourceFormatR8, GraphicsContext3D::SourceFormatR16Little, GraphicsContext3D::SourceFormatR16Big }, + { GraphicsContext3D::SourceFormatA8, GraphicsContext3D::SourceFormatA8, GraphicsContext3D::SourceFormatA16Little, GraphicsContext3D::SourceFormatA16Big }, + { GraphicsContext3D::SourceFormatAR8, GraphicsContext3D::SourceFormatRA8, GraphicsContext3D::SourceFormatRA16Little, GraphicsContext3D::SourceFormatRA16Big }, + { GraphicsContext3D::SourceFormatRA8, GraphicsContext3D::SourceFormatAR8, GraphicsContext3D::SourceFormatAR16Little, GraphicsContext3D::SourceFormatAR16Big }, + { GraphicsContext3D::SourceFormatBGR8, GraphicsContext3D::SourceFormatRGB8, GraphicsContext3D::SourceFormatRGB16Little, GraphicsContext3D::SourceFormatRGB16Big }, + { GraphicsContext3D::SourceFormatABGR8, GraphicsContext3D::SourceFormatRGBA8, GraphicsContext3D::SourceFormatRGBA16Little, GraphicsContext3D::SourceFormatRGBA16Big }, + { GraphicsContext3D::SourceFormatBGRA8, GraphicsContext3D::SourceFormatARGB8, GraphicsContext3D::SourceFormatARGB16Little, GraphicsContext3D::SourceFormatARGB16Big } }; ASSERT(componentsPerPixel <= 4 && componentsPerPixel > 0); SourceDataFormatBase formatBase = formatTableBase[componentsPerPixel - 1][alphaFormat]; if (formatBase == SourceFormatBaseNumFormats) - return GraphicsContext3D::kSourceFormatNumFormats; - if (!is16BitFormat) - return formatTable[formatBase][0]; - if (!bigEndian) - return formatTable[formatBase][1]; - return formatTable[formatBase][2]; + return GraphicsContext3D::SourceFormatNumFormats; + return formatTable[formatBase][(is16BitFormat ? 2 : 0) + (bigEndian ? 1 : 0)]; } bool GraphicsContext3D::getImageData(Image* image, @@ -125,28 +121,47 @@ bool GraphicsContext3D::getImageData(Image* image, return false; size_t componentsPerPixel = bitsPerPixel / bitsPerComponent; - bool srcByteOrder16Big = false; + CGBitmapInfo bitInfo = CGImageGetBitmapInfo(cgImage); + bool bigEndianSource = false; + // These could technically be combined into one large switch + // statement, but we prefer not to so that we fail fast if we + // encounter an unexpected image configuration. if (bitsPerComponent == 16) { - CGBitmapInfo bitInfo = CGImageGetBitmapInfo(cgImage); switch (bitInfo & kCGBitmapByteOrderMask) { case kCGBitmapByteOrder16Big: - srcByteOrder16Big = true; + bigEndianSource = true; break; case kCGBitmapByteOrder16Little: - srcByteOrder16Big = false; + bigEndianSource = false; break; case kCGBitmapByteOrderDefault: // This is a bug in earlier version of cg where the default endian // is little whereas the decoded 16-bit png image data is actually // Big. Later version (10.6.4) no longer returns ByteOrderDefault. - srcByteOrder16Big = true; + bigEndianSource = true; + break; + default: + return false; + } + } else { + switch (bitInfo & kCGBitmapByteOrderMask) { + case kCGBitmapByteOrder32Big: + bigEndianSource = true; + break; + case kCGBitmapByteOrder32Little: + bigEndianSource = false; + break; + case kCGBitmapByteOrderDefault: + // It appears that the default byte order is actually big + // endian even on little endian architectures. + bigEndianSource = true; break; default: return false; } } - AlphaOp neededAlphaOp = kAlphaDoNothing; + AlphaOp neededAlphaOp = AlphaDoNothing; AlphaFormat alphaFormat = AlphaFormatNone; switch (CGImageGetAlphaInfo(cgImage)) { case kCGImageAlphaPremultipliedFirst: @@ -155,13 +170,13 @@ bool GraphicsContext3D::getImageData(Image* image, // in which case image->data() should be null. ASSERT(!image->data()); if (!premultiplyAlpha) - neededAlphaOp = kAlphaDoUnmultiply; + neededAlphaOp = AlphaDoUnmultiply; alphaFormat = AlphaFormatFirst; break; case kCGImageAlphaFirst: // This path is only accessible for MacOS earlier than 10.6.4. if (premultiplyAlpha) - neededAlphaOp = kAlphaDoPremultiply; + neededAlphaOp = AlphaDoPremultiply; alphaFormat = AlphaFormatFirst; break; case kCGImageAlphaNoneSkipFirst: @@ -173,12 +188,12 @@ bool GraphicsContext3D::getImageData(Image* image, // in which case image->data() should be null. ASSERT(!image->data()); if (!premultiplyAlpha) - neededAlphaOp = kAlphaDoUnmultiply; + neededAlphaOp = AlphaDoUnmultiply; alphaFormat = AlphaFormatLast; break; case kCGImageAlphaLast: if (premultiplyAlpha) - neededAlphaOp = kAlphaDoPremultiply; + neededAlphaOp = AlphaDoPremultiply; alphaFormat = AlphaFormatLast; break; case kCGImageAlphaNoneSkipLast: @@ -190,8 +205,8 @@ bool GraphicsContext3D::getImageData(Image* image, default: return false; } - SourceDataFormat srcDataFormat = getSourceDataFormat(componentsPerPixel, alphaFormat, bitsPerComponent == 16, srcByteOrder16Big); - if (srcDataFormat == kSourceFormatNumFormats) + SourceDataFormat srcDataFormat = getSourceDataFormat(componentsPerPixel, alphaFormat, bitsPerComponent == 16, bigEndianSource); + if (srcDataFormat == SourceFormatNumFormats) return false; RetainPtr<CFDataRef> pixelData; diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index 9e0a2f5..8d72b85 100644 --- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -669,17 +669,6 @@ void GraphicsContext::clipOut(const IntRect& rect) CGContextEOClip(platformContext()); } -void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - CGContextBeginPath(platformContext()); - CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); - CGContextAddEllipseInRect(platformContext(), rect); - CGContextEOClip(platformContext()); -} - void GraphicsContext::clipPath(WindRule clipRule) { if (paintingDisabled()) diff --git a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp index b54a427..e44ec9d 100644 --- a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp +++ b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp @@ -32,6 +32,7 @@ #include "DrawingBuffer.h" +#include "Extensions3DChromium.h" #include "GraphicsContext3D.h" #include "SharedGraphicsContext3D.h" @@ -69,9 +70,14 @@ static unsigned generateColorTexture(GraphicsContext3D* context, const IntSize& DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) : m_context(context) , m_size(size) - , m_fbo(context->createFramebuffer()) + , m_fbo(0) , m_internal(new DrawingBufferInternal) { + if (!m_context->getExtensions()->supports("GL_CHROMIUM_copy_texture_to_parent_texture")) { + m_context.clear(); + return; + } + m_fbo = context->createFramebuffer(); context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); m_internal->offscreenColorTexture = generateColorTexture(context, size); } @@ -107,7 +113,7 @@ void DrawingBuffer::publishToPlatformLayer() // happens before the compositor draws. This means we might draw stale frames sometimes. Ideally this // would insert a fence into the child command stream that the compositor could wait for. m_context->makeContextCurrent(); - m_context->copyTextureToParentTextureCHROMIUM(m_internal->offscreenColorTexture, parentTexture); + static_cast<Extensions3DChromium*>(m_context->getExtensions())->copyTextureToParentTextureCHROMIUM(m_internal->offscreenColorTexture, parentTexture); m_context->flush(); } #endif diff --git a/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/WebCore/platform/graphics/chromium/Extensions3DChromium.h new file mode 100644 index 0000000..0fd1fff --- /dev/null +++ b/WebCore/platform/graphics/chromium/Extensions3DChromium.h @@ -0,0 +1,70 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Extensions3DChromium_h +#define Extensions3DChromium_h + +#include "Extensions3D.h" + +namespace WebCore { + +class GraphicsContext3DInternal; + +class Extensions3DChromium : public Extensions3D { +public: + virtual ~Extensions3DChromium(); + + // Extensions3D methods. + virtual bool supports(const String&); + virtual int getGraphicsResetStatusARB(); + + enum { + // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object) + READ_ONLY = 0x88B8, + WRITE_ONLY = 0x88B9 + }; + + // GL_CHROMIUM_map_sub + void* mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access); + void unmapBufferSubDataCHROMIUM(const void*); + void* mapTexSubImage2DCHROMIUM(unsigned target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, unsigned access); + void unmapTexSubImage2DCHROMIUM(const void*); + + // GL_CHROMIUM_copy_texture_to_parent_texture + void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture); + +private: + // Instances of this class are strictly owned by the GraphicsContext3D implementation and do not + // need to be instantiated by any other code. + friend class GraphicsContext3DInternal; + explicit Extensions3DChromium(GraphicsContext3DInternal*); + + // Weak pointer back to GraphicsContext3DInternal + GraphicsContext3DInternal* m_internal; +}; + +} // namespace WebCore + +#endif // Extensions3DChromium_h diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp index 7c3e450..384b1c5 100644 --- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp +++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp @@ -391,10 +391,10 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons int numFonts = 0; if (script == USCRIPT_HAN) { panUniFonts = cjkFonts; - numFonts = ARRAYSIZE(cjkFonts); + numFonts = WTF_ARRAY_LENGTH(cjkFonts); } else { panUniFonts = commonFonts; - numFonts = ARRAYSIZE(commonFonts); + numFonts = WTF_ARRAY_LENGTH(commonFonts); } // Font returned from GetFallbackFamily may not cover |characters| // because it's based on script to font mapping. This problem is diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp index f668bbf..23e54e5 100644 --- a/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -370,6 +370,7 @@ void LayerChromium::setNeedsDisplay() { m_dirtyRect.setSize(m_bounds); m_contentsDirty = true; + setNeedsCommit(); } void LayerChromium::resetNeedsDisplay() diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index e93e296..e1b525b 100644 --- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -730,7 +730,10 @@ bool LayerRendererChromium::initializeSharedObjects() m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get())); m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get())); m_videoLayerSharedValues = adoptPtr(new VideoLayerChromium::SharedValues(m_context.get())); - if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized() || !m_videoLayerSharedValues->initialized()) { + m_pluginLayerSharedValues = adoptPtr(new PluginLayerChromium::SharedValues(m_context.get())); + + if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized() + || !m_videoLayerSharedValues->initialized() || !m_pluginLayerSharedValues->initialized()) { cleanupSharedObjects(); return false; } @@ -746,6 +749,7 @@ void LayerRendererChromium::cleanupSharedObjects() m_contentLayerSharedValues.clear(); m_canvasLayerSharedValues.clear(); m_videoLayerSharedValues.clear(); + m_pluginLayerSharedValues.clear(); if (m_scrollShaderProgram) { GLC(m_context, m_context->deleteProgram(m_scrollShaderProgram)); diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h index b2a32ee..52fbe36 100644 --- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h +++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h @@ -38,6 +38,7 @@ #include "ContentLayerChromium.h" #include "IntRect.h" #include "LayerChromium.h" +#include "PluginLayerChromium.h" #include "SkBitmap.h" #include "VideoLayerChromium.h" #include <wtf/HashMap.h> @@ -107,6 +108,7 @@ public: const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); } const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); } const VideoLayerChromium::SharedValues* videoLayerSharedValues() const { return m_videoLayerSharedValues.get(); } + const PluginLayerChromium::SharedValues* pluginLayerSharedValues() const { return m_pluginLayerSharedValues.get(); } void resizeOnscreenContent(const IntSize&); @@ -180,6 +182,7 @@ private: OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues; OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues; OwnPtr<VideoLayerChromium::SharedValues> m_videoLayerSharedValues; + OwnPtr<PluginLayerChromium::SharedValues> m_pluginLayerSharedValues; RefPtr<GraphicsContext3D> m_context; }; diff --git a/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp b/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp new file mode 100644 index 0000000..2d1852f --- /dev/null +++ b/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp @@ -0,0 +1,133 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "PluginLayerChromium.h" + +#include "GraphicsContext3D.h" +#include "LayerRendererChromium.h" +#include <GLES2/gl2.h> + +namespace WebCore { + +PluginLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) + : m_context(context) + , m_shaderProgram(0) + , m_shaderSamplerLocation(-1) + , m_shaderMatrixLocation(-1) + , m_shaderAlphaLocation(-1) + , m_initialized(false) +{ + char vertexShaderString[] = + "attribute vec4 a_position; \n" + "attribute vec2 a_texCoord; \n" + "uniform mat4 matrix; \n" + "varying vec2 v_texCoord; \n" + "void main() \n" + "{ \n" + " gl_Position = matrix * a_position; \n" + " v_texCoord = a_texCoord; \n" + "} \n"; + + char fragmentShaderString[] = + "precision mediump float; \n" + "varying vec2 v_texCoord; \n" + "uniform sampler2D s_texture; \n" + "uniform float alpha; \n" + "void main() \n" + "{ \n" + " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, v_texCoord.y)); \n" + " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" + "} \n"; + + m_shaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); + if (!m_shaderProgram) { + LOG_ERROR("PluginLayerChromium: Failed to create shader program"); + return; + } + + m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture"); + m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix"); + m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha"); + ASSERT(m_shaderSamplerLocation != -1); + ASSERT(m_shaderMatrixLocation != -1); + ASSERT(m_shaderAlphaLocation != -1); + + m_initialized = true; +} + +PluginLayerChromium::SharedValues::~SharedValues() +{ + if (m_shaderProgram) + GLC(m_context, m_context->deleteProgram(m_shaderProgram)); +} + +PassRefPtr<PluginLayerChromium> PluginLayerChromium::create(GraphicsLayerChromium* owner) +{ + return adoptRef(new PluginLayerChromium(owner)); +} + +PluginLayerChromium::PluginLayerChromium(GraphicsLayerChromium* owner) + : LayerChromium(owner) +{ +} + +void PluginLayerChromium::setTextureId(unsigned id) +{ + m_textureId = id; +} + +void PluginLayerChromium::updateContents() +{ +} + +void PluginLayerChromium::draw() +{ + ASSERT(layerRenderer()); + const PluginLayerChromium::SharedValues* sv = layerRenderer()->pluginLayerSharedValues(); + ASSERT(sv && sv->initialized()); + GraphicsContext3D* context = layerRendererContext(); + GLC(context, context->activeTexture(GL_TEXTURE0)); + GLC(context, context->bindTexture(GL_TEXTURE_2D, m_textureId)); + + // FIXME: setting the texture parameters every time is redundant. Move this code somewhere + // where it will only happen once per texture. + GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + + layerRenderer()->useShader(sv->shaderProgram()); + GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), + bounds().width(), bounds().height(), drawOpacity(), + sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); +} + +} +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/chromium/PluginLayerChromium.h b/WebCore/platform/graphics/chromium/PluginLayerChromium.h new file mode 100644 index 0000000..44a6cc9 --- /dev/null +++ b/WebCore/platform/graphics/chromium/PluginLayerChromium.h @@ -0,0 +1,74 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef PluginLayerChromium_h +#define PluginLayerChromium_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerChromium.h" + +namespace WebCore { + +// A Layer containing a the rendered output of a plugin instance. +class PluginLayerChromium : public LayerChromium { +public: + static PassRefPtr<PluginLayerChromium> create(GraphicsLayerChromium* owner = 0); + virtual bool drawsContent() { return true; } + virtual void updateContents(); + virtual void draw(); + + void setTextureId(unsigned textureId); + + class SharedValues { + public: + SharedValues(GraphicsContext3D* context); + ~SharedValues(); + + unsigned shaderProgram() const { return m_shaderProgram; } + int shaderSamplerLocation() const { return m_shaderSamplerLocation; } + int shaderMatrixLocation() const { return m_shaderMatrixLocation; } + int shaderAlphaLocation() const { return m_shaderAlphaLocation; } + bool initialized() const { return m_initialized; } + + private: + GraphicsContext3D* m_context; + unsigned m_shaderProgram; + int m_shaderSamplerLocation; + int m_shaderMatrixLocation; + int m_shaderAlphaLocation; + bool m_initialized; + }; + +private: + PluginLayerChromium(GraphicsLayerChromium* owner); + unsigned m_textureId; +}; + +} +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp index 46c73a1..fa6c2c8 100644 --- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp @@ -33,6 +33,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "VideoLayerChromium.h" +#include "Extensions3DChromium.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #include "RenderLayerBacking.h" @@ -302,10 +303,10 @@ void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text { ASSERT(context); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); - void* mem = context->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, GraphicsContext3D::WRITE_ONLY); + void* mem = static_cast<Extensions3DChromium*>(context->getExtensions())->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, Extensions3DChromium::WRITE_ONLY); if (mem) { memcpy(mem, data, dimensions.width() * dimensions.height()); - GLC(context, context->unmapTexSubImage2DCHROMIUM(mem)); + GLC(context, static_cast<Extensions3DChromium*>(context->getExtensions())->unmapTexSubImage2DCHROMIUM(mem)); } else { // FIXME: We should have some sort of code to handle the case when // mapTexSubImage2D fails. diff --git a/WebCore/platform/graphics/filters/FELighting.cpp b/WebCore/platform/graphics/filters/FELighting.cpp index e1df580..803b9c1 100644 --- a/WebCore/platform/graphics/filters/FELighting.cpp +++ b/WebCore/platform/graphics/filters/FELighting.cpp @@ -54,85 +54,182 @@ FELighting::FELighting(LightingType lightingType, const Color& lightingColor, fl const static int cPixelSize = 4; const static int cAlphaChannelOffset = 3; const static unsigned char cOpaqueAlpha = static_cast<unsigned char>(0xff); +const static float cFactor1div2 = -1 / 2.f; +const static float cFactor1div3 = -1 / 3.f; +const static float cFactor1div4 = -1 / 4.f; +const static float cFactor2div3 = -2 / 3.f; -ALWAYS_INLINE int FELighting::LightingData::upLeftPixelValue() +// << 1 is signed multiply by 2 +inline void FELighting::LightingData::topLeft(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize - cPixelSize + cAlphaChannelOffset)); + int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + offset += widthMultipliedByPixelSize; + int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + normalVector.setX(-(center << 1) + (right << 1) - bottom + bottomRight); + normalVector.setY(-(center << 1) - right + (bottom << 1) + bottomRight); } -ALWAYS_INLINE int FELighting::LightingData::upPixelValue() +inline void FELighting::LightingData::topRow(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize + cAlphaChannelOffset)); + int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + offset += widthMultipliedByPixelSize; + int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + normalVector.setX(-(left << 1) + (right << 1) - bottomLeft + bottomRight); + normalVector.setY(-left - (center << 1) - right + bottomLeft + (bottom << 1) + bottomRight); } -ALWAYS_INLINE int FELighting::LightingData::upRightPixelValue() +inline void FELighting::LightingData::topRight(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize + cPixelSize + cAlphaChannelOffset)); + int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + offset += widthMultipliedByPixelSize; + int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + normalVector.setX(-(left << 1) + (center << 1) - bottomLeft + bottom); + normalVector.setY(-left - (center << 1) + bottomLeft + (bottom << 1)); } -ALWAYS_INLINE int FELighting::LightingData::leftPixelValue() +inline void FELighting::LightingData::leftColumn(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + offset -= widthMultipliedByPixelSize; + int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + offset += widthMultipliedByPixelSize << 1; + int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + normalVector.setX(-top + topRight - (center << 1) + (right << 1) - bottom + bottomRight); + normalVector.setY(-(top << 1) - topRight + (bottom << 1) + bottomRight); } -ALWAYS_INLINE int FELighting::LightingData::centerPixelValue() +inline void FELighting::LightingData::interior(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + offset -= widthMultipliedByPixelSize; + int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + offset += widthMultipliedByPixelSize << 1; + int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + normalVector.setX(-topLeft + topRight - (left << 1) + (right << 1) - bottomLeft + bottomRight); + normalVector.setY(-topLeft - (top << 1) - topRight + bottomLeft + (bottom << 1) + bottomRight); } -ALWAYS_INLINE int FELighting::LightingData::rightPixelValue() +inline void FELighting::LightingData::rightColumn(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + offset -= widthMultipliedByPixelSize; + int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + offset += widthMultipliedByPixelSize << 1; + int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + normalVector.setX(-topLeft + top - (left << 1) + (center << 1) - bottomLeft + bottom); + normalVector.setY(-topLeft - (top << 1) + bottomLeft + (bottom << 1)); } -ALWAYS_INLINE int FELighting::LightingData::downLeftPixelValue() +inline void FELighting::LightingData::bottomLeft(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize - cPixelSize + cAlphaChannelOffset)); + int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + offset -= widthMultipliedByPixelSize; + int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + normalVector.setX(-top + topRight - (center << 1) + (right << 1)); + normalVector.setY(-(top << 1) - topRight + (center << 1) + right); } -ALWAYS_INLINE int FELighting::LightingData::downPixelValue() +inline void FELighting::LightingData::bottomRow(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize + cAlphaChannelOffset)); + int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + offset -= widthMultipliedByPixelSize; + int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset)); + normalVector.setX(-topLeft + topRight - (left << 1) + (right << 1)); + normalVector.setY(-topLeft - (top << 1) - topRight + left + (center << 1) + right); } -ALWAYS_INLINE int FELighting::LightingData::downRightPixelValue() +inline void FELighting::LightingData::bottomRight(int offset, IntPoint& normalVector) { - return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize + cPixelSize + cAlphaChannelOffset)); + int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + offset -= widthMultipliedByPixelSize; + int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset)); + int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset)); + normalVector.setX(-topLeft + top - (left << 1) + (center << 1)); + normalVector.setY(-topLeft - (top << 1) + left + (center << 1)); } -ALWAYS_INLINE void FELighting::setPixel(LightingData& data, LightSource::PaintingData& paintingData, - int lightX, int lightY, float factorX, int normalX, float factorY, int normalY) +inline void FELighting::inlineSetPixel(int offset, LightingData& data, LightSource::PaintingData& paintingData, + int lightX, int lightY, float factorX, float factorY, IntPoint& normal2DVector) { - m_lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->get(data.offset + 3)) * data.surfaceScale); - - data.normalVector.setX(factorX * static_cast<float>(normalX) * data.surfaceScale); - data.normalVector.setY(factorY * static_cast<float>(normalY) * data.surfaceScale); - data.normalVector.setZ(1.0f); - data.normalVector.normalize(); - - if (m_lightingType == FELighting::DiffuseLighting) - data.lightStrength = m_diffuseConstant * (data.normalVector * paintingData.lightVector); - else { - FloatPoint3D halfwayVector = paintingData.lightVector; - halfwayVector.setZ(halfwayVector.z() + 1.0f); - halfwayVector.normalize(); - if (m_specularExponent == 1.0f) - data.lightStrength = m_specularConstant * (data.normalVector * halfwayVector); - else - data.lightStrength = m_specularConstant * powf(data.normalVector * halfwayVector, m_specularExponent); + m_lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->get(offset + cAlphaChannelOffset)) * data.surfaceScale); + + float lightStrength; + if (!normal2DVector.x() && !normal2DVector.y()) { + // Normal vector is (0, 0, 1). This is a quite frequent case. + if (m_lightingType == FELighting::DiffuseLighting) + lightStrength = m_diffuseConstant * paintingData.lightVector.z() / paintingData.lightVectorLength; + else { + FloatPoint3D halfwayVector = paintingData.lightVector; + halfwayVector.setZ(halfwayVector.z() + paintingData.lightVectorLength); + float halfwayVectorLength = halfwayVector.length(); + if (m_specularExponent == 1) + lightStrength = m_specularConstant * halfwayVector.z() / halfwayVectorLength; + else + lightStrength = m_specularConstant * powf(halfwayVector.z() / halfwayVectorLength, m_specularExponent); + } + } else { + FloatPoint3D normalVector; + normalVector.setX(factorX * static_cast<float>(normal2DVector.x()) * data.surfaceScale); + normalVector.setY(factorY * static_cast<float>(normal2DVector.y()) * data.surfaceScale); + normalVector.setZ(1); + float normalVectorLength = normalVector.length(); + + if (m_lightingType == FELighting::DiffuseLighting) + lightStrength = m_diffuseConstant * (normalVector * paintingData.lightVector) / (normalVectorLength * paintingData.lightVectorLength); + else { + FloatPoint3D halfwayVector = paintingData.lightVector; + halfwayVector.setZ(halfwayVector.z() + paintingData.lightVectorLength); + float halfwayVectorLength = halfwayVector.length(); + if (m_specularExponent == 1) + lightStrength = m_specularConstant * (normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength); + else + lightStrength = m_specularConstant * powf((normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength), m_specularExponent); + } } - if (data.lightStrength > 1.0f) - data.lightStrength = 1.0f; - if (data.lightStrength < 0.0f) - data.lightStrength = 0.0f; + if (lightStrength > 1) + lightStrength = 1; + if (lightStrength < 0) + lightStrength = 0; - data.pixels->set(data.offset, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.x())); - data.pixels->set(data.offset + 1, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.y())); - data.pixels->set(data.offset + 2, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.z())); + data.pixels->set(offset, static_cast<unsigned char>(lightStrength * paintingData.colorVector.x())); + data.pixels->set(offset + 1, static_cast<unsigned char>(lightStrength * paintingData.colorVector.y())); + data.pixels->set(offset + 2, static_cast<unsigned char>(lightStrength * paintingData.colorVector.z())); +} + +void FELighting::setPixel(int offset, LightingData& data, LightSource::PaintingData& paintingData, + int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector) +{ + inlineSetPixel(offset, data, paintingData, lightX, lightY, factorX, factorY, normalVector); } -bool FELighting::drawLighting(CanvasPixelArray* pixels, int width, int height) +bool FELighting::drawLighting(ByteArray* pixels, int width, int height) { LightSource::PaintingData paintingData; LightingData data; @@ -154,81 +251,73 @@ bool FELighting::drawLighting(CanvasPixelArray* pixels, int width, int height) m_lightSource->initPaintingData(paintingData); // Top/Left corner - data.offset = 0; - setPixel(data, paintingData, 0, 0, - -2.0f / 3.0f, -2 * data.centerPixelValue() + 2 * data.rightPixelValue() - data.downPixelValue() + data.downRightPixelValue(), - -2.0f / 3.0f, -2 * data.centerPixelValue() - data.rightPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue()); + IntPoint normalVector; + int offset = 0; + data.topLeft(offset, normalVector); + setPixel(offset, data, paintingData, 0, 0, cFactor2div3, cFactor2div3, normalVector); // Top/Right pixel - data.offset = data.widthMultipliedByPixelSize - cPixelSize; - setPixel(data, paintingData, data.widthDecreasedByOne, 0, - -2.0f / 3.0f, -2 * data.leftPixelValue() + 2 * data.centerPixelValue() - data.downLeftPixelValue() + data.downPixelValue(), - -2.0f / 3.0f, -data.leftPixelValue() - 2 * data.centerPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue()); + offset = data.widthMultipliedByPixelSize - cPixelSize; + data.topRight(offset, normalVector); + setPixel(offset, data, paintingData, data.widthDecreasedByOne, 0, cFactor2div3, cFactor2div3, normalVector); // Bottom/Left pixel - data.offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize; - setPixel(data, paintingData, 0, data.heightDecreasedByOne, - -2.0f / 3.0f, -data.upPixelValue() + data.upRightPixelValue() - 2 * data.centerPixelValue() + 2 * data.rightPixelValue(), - -2.0f / 3.0f, -2 * data.upPixelValue() - data.upRightPixelValue() + 2 * data.centerPixelValue() + data.rightPixelValue()); + offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize; + data.bottomLeft(offset, normalVector); + setPixel(offset, data, paintingData, 0, data.heightDecreasedByOne, cFactor2div3, cFactor2div3, normalVector); // Bottom/Right pixel - data.offset = height * data.widthMultipliedByPixelSize - cPixelSize; - setPixel(data, paintingData, data.widthDecreasedByOne, data.heightDecreasedByOne, - -2.0f / 3.0f, -data.upLeftPixelValue() + data.upPixelValue() - 2 * data.leftPixelValue() + 2 * data.centerPixelValue(), - -2.0f / 3.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() + data.leftPixelValue() + 2 * data.centerPixelValue()); + offset = height * data.widthMultipliedByPixelSize - cPixelSize; + data.bottomRight(offset, normalVector); + setPixel(offset, data, paintingData, data.widthDecreasedByOne, data.heightDecreasedByOne, cFactor2div3, cFactor2div3, normalVector); if (width >= 3) { - // Top line - data.offset = cPixelSize; - for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) { - setPixel(data, paintingData, x, 0, - -1.0f / 3.0f, -2 * data.leftPixelValue() + 2 * data.rightPixelValue() - data.downLeftPixelValue() + data.downRightPixelValue(), - -1.0f / 2.0f, -data.leftPixelValue() - 2 * data.centerPixelValue() - data.rightPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue()); + // Top row + offset = cPixelSize; + for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) { + data.topRow(offset, normalVector); + inlineSetPixel(offset, data, paintingData, x, 0, cFactor1div3, cFactor1div2, normalVector); } - // Bottom line - data.offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize + cPixelSize; - for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) { - setPixel(data, paintingData, x, data.heightDecreasedByOne, - -1.0f / 3.0f, -data.upLeftPixelValue() + data.upRightPixelValue() - 2 * data.leftPixelValue() + 2 * data.rightPixelValue(), - -1.0f / 2.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() - data.upRightPixelValue() + data.leftPixelValue() + 2 * data.centerPixelValue() + data.rightPixelValue()); + // Bottom row + offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize + cPixelSize; + for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) { + data.bottomRow(offset, normalVector); + inlineSetPixel(offset, data, paintingData, x, data.heightDecreasedByOne, cFactor1div3, cFactor1div2, normalVector); } } if (height >= 3) { - // Left line - data.offset = data.widthMultipliedByPixelSize; - for (int y = 1; y < data.heightDecreasedByOne; ++y, data.offset += data.widthMultipliedByPixelSize) { - setPixel(data, paintingData, 0, y, - -1.0f / 2.0f, -data.upPixelValue() + data.upRightPixelValue() - 2 * data.centerPixelValue() + 2 * data.rightPixelValue() - data.downPixelValue() + data.downRightPixelValue(), - -1.0f / 3.0f, -2 * data.upPixelValue() - data.upRightPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue()); + // Left column + offset = data.widthMultipliedByPixelSize; + for (int y = 1; y < data.heightDecreasedByOne; ++y, offset += data.widthMultipliedByPixelSize) { + data.leftColumn(offset, normalVector); + inlineSetPixel(offset, data, paintingData, 0, y, cFactor1div2, cFactor1div3, normalVector); } - // Right line - data.offset = data.widthMultipliedByPixelSize + data.widthMultipliedByPixelSize - cPixelSize; - for (int y = 1; y < data.heightDecreasedByOne; ++y, data.offset += data.widthMultipliedByPixelSize) { - setPixel(data, paintingData, data.widthDecreasedByOne, y, - -1.0f / 2.0f, -data.upLeftPixelValue() + data.upPixelValue() -2 * data.leftPixelValue() + 2 * data.centerPixelValue() - data.downLeftPixelValue() + data.downPixelValue(), - -1.0f / 3.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue()); + // Right column + offset = (data.widthMultipliedByPixelSize << 1) - cPixelSize; + for (int y = 1; y < data.heightDecreasedByOne; ++y, offset += data.widthMultipliedByPixelSize) { + data.rightColumn(offset, normalVector); + inlineSetPixel(offset, data, paintingData, data.widthDecreasedByOne, y, cFactor1div2, cFactor1div3, normalVector); } } if (width >= 3 && height >= 3) { // Interior pixels for (int y = 1; y < data.heightDecreasedByOne; ++y) { - data.offset = y * data.widthMultipliedByPixelSize + cPixelSize; - for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) { - setPixel(data, paintingData, x, y, - -1.0f / 4.0f, -data.upLeftPixelValue() + data.upRightPixelValue() - 2 * data.leftPixelValue() + 2 * data.rightPixelValue() - data.downLeftPixelValue() + data.downRightPixelValue(), - -1.0f / 4.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() - data.upRightPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue()); + offset = y * data.widthMultipliedByPixelSize + cPixelSize; + for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) { + data.interior(offset, normalVector); + inlineSetPixel(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, normalVector); } } } - int totalSize = data.widthMultipliedByPixelSize * height; + int lastPixel = data.widthMultipliedByPixelSize * height; if (m_lightingType == DiffuseLighting) { - for (int i = 3; i < totalSize; i += 4) + for (int i = cAlphaChannelOffset; i < lastPixel; i += cPixelSize) data.pixels->set(i, cOpaqueAlpha); } else { - for (int i = 0; i < totalSize; i += 4) { + for (int i = 0; i < lastPixel; i += cPixelSize) { unsigned char a1 = data.pixels->get(i); unsigned char a2 = data.pixels->get(i + 1); unsigned char a3 = data.pixels->get(i + 2); @@ -253,8 +342,8 @@ void FELighting::apply(Filter* filter) setIsAlphaImage(false); IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); - RefPtr<ImageData> srcImageData(in->resultImage()->getUnmultipliedImageData(effectDrawingRect)); - CanvasPixelArray* srcPixelArray(srcImageData->data()); + RefPtr<ImageData> srcImageData = in->resultImage()->getUnmultipliedImageData(effectDrawingRect); + ByteArray* srcPixelArray = srcImageData->data()->data(); // FIXME: support kernelUnitLengths other than (1,1). The issue here is that the W3 // standard has no test case for them, and other browsers (like Firefox) has strange diff --git a/WebCore/platform/graphics/filters/FELighting.h b/WebCore/platform/graphics/filters/FELighting.h index bd56cee..c0f62ab 100644 --- a/WebCore/platform/graphics/filters/FELighting.h +++ b/WebCore/platform/graphics/filters/FELighting.h @@ -32,14 +32,12 @@ #include "Filter.h" #include "FilterEffect.h" #include "LightSource.h" -#include <wtf/AlwaysInline.h> +#include <wtf/ByteArray.h> // Common base class for FEDiffuseLighting and FESpecularLighting namespace WebCore { -class CanvasPixelArray; - class FELighting : public FilterEffect { public: virtual void apply(Filter*); @@ -53,31 +51,33 @@ protected: }; struct LightingData { - FloatPoint3D normalVector; - CanvasPixelArray* pixels; - float lightStrength; + // This structure contains only read-only (SMP safe) data + ByteArray* pixels; float surfaceScale; - int offset; int widthMultipliedByPixelSize; int widthDecreasedByOne; int heightDecreasedByOne; - ALWAYS_INLINE int upLeftPixelValue(); - ALWAYS_INLINE int upPixelValue(); - ALWAYS_INLINE int upRightPixelValue(); - ALWAYS_INLINE int leftPixelValue(); - ALWAYS_INLINE int centerPixelValue(); - ALWAYS_INLINE int rightPixelValue(); - ALWAYS_INLINE int downLeftPixelValue(); - ALWAYS_INLINE int downPixelValue(); - ALWAYS_INLINE int downRightPixelValue(); + inline void topLeft(int offset, IntPoint& normalVector); + inline void topRow(int offset, IntPoint& normalVector); + inline void topRight(int offset, IntPoint& normalVector); + inline void leftColumn(int offset, IntPoint& normalVector); + inline void interior(int offset, IntPoint& normalVector); + inline void rightColumn(int offset, IntPoint& normalVector); + inline void bottomLeft(int offset, IntPoint& normalVector); + inline void bottomRow(int offset, IntPoint& normalVector); + inline void bottomRight(int offset, IntPoint& normalVector); }; FELighting(LightingType, const Color&, float, float, float, float, float, float, PassRefPtr<LightSource>); - bool drawLighting(CanvasPixelArray*, int, int); - ALWAYS_INLINE void setPixel(LightingData&, LightSource::PaintingData&, - int lightX, int lightY, float factorX, int normalX, float factorY, int normalY); + bool drawLighting(ByteArray*, int, int); + inline void inlineSetPixel(int offset, LightingData&, LightSource::PaintingData&, + int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector); + + // Not worth to inline every occurence of setPixel. + void setPixel(int offset, LightingData&, LightSource::PaintingData&, + int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector); LightingType m_lightingType; RefPtr<LightSource> m_lightSource; diff --git a/WebCore/platform/graphics/filters/LightSource.cpp b/WebCore/platform/graphics/filters/LightSource.cpp index a80b14b..de0691e 100644 --- a/WebCore/platform/graphics/filters/LightSource.cpp +++ b/WebCore/platform/graphics/filters/LightSource.cpp @@ -42,7 +42,7 @@ void PointLightSource::updatePaintingData(PaintingData& paintingData, int x, int paintingData.lightVector.setX(m_position.x() - x); paintingData.lightVector.setY(m_position.y() - y); paintingData.lightVector.setZ(m_position.z() - z); - paintingData.lightVector.normalize(); + paintingData.lightVectorLength = paintingData.lightVector.length(); } // spot-light edge darkening depends on an absolute treshold @@ -84,9 +84,9 @@ void SpotLightSource::updatePaintingData(PaintingData& paintingData, int x, int paintingData.lightVector.setX(m_position.x() - x); paintingData.lightVector.setY(m_position.y() - y); paintingData.lightVector.setZ(m_position.z() - z); - paintingData.lightVector.normalize(); + paintingData.lightVectorLength = paintingData.lightVector.length(); - float cosineOfAngle = paintingData.lightVector * paintingData.directionVector; + float cosineOfAngle = (paintingData.lightVector * paintingData.directionVector) / paintingData.lightVectorLength; if (cosineOfAngle > paintingData.coneCutOffLimit) { // No light is produced, scanlines are not updated paintingData.colorVector.setX(0.0f); @@ -127,6 +127,7 @@ void DistantLightSource::initPaintingData(PaintingData& paintingData) paintingData.lightVector.setX(cosf(azimuth) * cosf(elevation)); paintingData.lightVector.setY(sinf(azimuth) * cosf(elevation)); paintingData.lightVector.setZ(sinf(elevation)); + paintingData.lightVectorLength = 1; } void DistantLightSource::updatePaintingData(PaintingData&, int, int, float) diff --git a/WebCore/platform/graphics/filters/LightSource.h b/WebCore/platform/graphics/filters/LightSource.h index 2e4c579..013e910 100644 --- a/WebCore/platform/graphics/filters/LightSource.h +++ b/WebCore/platform/graphics/filters/LightSource.h @@ -51,6 +51,7 @@ public: // SVGFELighting also use them FloatPoint3D lightVector; FloatPoint3D colorVector; + float lightVectorLength; // Private members FloatPoint3D directionVector; FloatPoint3D privateColorVector; diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp index 87a0b69..a230384 100644 --- a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp +++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp @@ -36,6 +36,7 @@ #include "AffineTransform.h" #include "Color.h" +#include "Extensions3D.h" #include "FloatRect.h" #include "GraphicsContext3D.h" #include "GraphicsTypes.h" @@ -52,6 +53,7 @@ namespace WebCore { PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow* hostWindow) { GraphicsContext3D::Attributes attr; + attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts. RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow); if (!context) return 0; @@ -178,18 +180,8 @@ void SharedGraphicsContext3D::readPixels(long x, long y, unsigned long width, un bool SharedGraphicsContext3D::supportsBGRA() { - return m_context->supportsBGRA(); -} - -bool SharedGraphicsContext3D::supportsCopyTextureToParentTextureCHROMIUM() - -{ - return m_context->supportsCopyTextureToParentTextureCHROMIUM(); -} - -void SharedGraphicsContext3D::copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture) -{ - return m_context->copyTextureToParentTextureCHROMIUM(texture, parentTexture); + return m_context->getExtensions()->supports("GL_EXT_texture_format_BGRA8888") + && m_context->getExtensions()->supports("GL_EXT_read_format_bgra"); } Texture* SharedGraphicsContext3D::createTexture(NativeImagePtr ptr, Texture::Format format, int width, int height) diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h index 05008c2..86c64b4 100644 --- a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h +++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h @@ -100,10 +100,6 @@ public: bool supportsBGRA(); - // GL_CHROMIUM_copy_texture_to_parent_texture - bool supportsCopyTextureToParentTextureCHROMIUM(); - void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture); - // Creates a texture associated with the given image. Is owned by this context's // TextureHashMap. Texture* createTexture(NativeImagePtr, Texture::Format, int width, int height); diff --git a/WebCore/platform/graphics/gpu/Texture.cpp b/WebCore/platform/graphics/gpu/Texture.cpp index 74807dc..18c9ead 100644 --- a/WebCore/platform/graphics/gpu/Texture.cpp +++ b/WebCore/platform/graphics/gpu/Texture.cpp @@ -34,6 +34,7 @@ #include "Texture.h" +#include "Extensions3D.h" #include "FloatRect.h" #include "GraphicsContext3D.h" #include "IntRect.h" @@ -69,8 +70,8 @@ static void convertFormat(GraphicsContext3D* context, Texture::Format format, un *glType = GraphicsContext3D::UNSIGNED_BYTE; break; case Texture::BGRA8: - if (context->supportsBGRA()) { - *glFormat = GraphicsContext3D::BGRA_EXT; + if (context->getExtensions()->supports("GL_EXT_texture_format_BGRA8888")) { + *glFormat = Extensions3D::BGRA_EXT; *glType = GraphicsContext3D::UNSIGNED_BYTE; } else { *glFormat = GraphicsContext3D::RGBA; diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp index 252abd7..6911b31 100644 --- a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp +++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp @@ -416,12 +416,6 @@ void GraphicsContext::translate(float x, float y) notImplemented(); } -IntPoint GraphicsContext::origin() -{ - notImplemented(); - return IntPoint(0, 0); -} - void GraphicsContext::rotate(float radians) { if (paintingDisabled()) @@ -446,14 +440,6 @@ void GraphicsContext::clipOut(const IntRect& rect) notImplemented(); } -void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - notImplemented(); -} - void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) { if (paintingDisabled()) @@ -482,6 +468,12 @@ void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) { } +InterpolationQuality GraphicsContext::imageInterpolationQuality() const +{ + notImplemented(); + return InterpolationDefault; +} + void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) { notImplemented(); diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm index 78d004a..ab6993f 100644 --- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm +++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm @@ -36,6 +36,7 @@ #include "ArrayBufferView.h" #include "CanvasRenderingContext.h" #include <CoreGraphics/CGBitmapContext.h> +#include "Extensions3DOpenGL.h" #include "Float32Array.h" #include "GraphicsContext.h" #include "HTMLCanvasElement.h" diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm index aa754f2..15cae20 100644 --- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm +++ b/WebCore/platform/graphics/mac/GraphicsContextMac.mm @@ -147,6 +147,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, break; } #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + // To support correction panel. case TextCheckingReplacementLineStyle: { // Constants for spelling pattern color. diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h index 3895a00..876bc16 100644 --- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h +++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h @@ -173,6 +173,8 @@ private: bool isReadyForVideoSetup() const; + virtual float mediaTimeForTimeValue(float) const; + MediaPlayer* m_player; RetainPtr<QTMovie> m_qtMovie; RetainPtr<QTMovieView> m_qtMovieView; diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm index 7b0e7af..06c7924 100644 --- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm +++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm @@ -1540,6 +1540,15 @@ void MediaPlayerPrivate::setPreload(MediaPlayer::Preload preload) resumeLoad(); } +float MediaPlayerPrivate::mediaTimeForTimeValue(float timeValue) const +{ + if (!metaDataAvailable()) + return timeValue; + + QTTime qttime = createQTTime(timeValue); + return static_cast<float>(qttime.timeValue) / qttime.timeScale; +} + } // namespace WebCore @implementation WebCoreMovieObserver diff --git a/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp new file mode 100644 index 0000000..8c62e9d --- /dev/null +++ b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp @@ -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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(3D_CANVAS) + +#include "Extensions3DOpenGL.h" + +#include "GraphicsContext3D.h" +#include <wtf/Vector.h> + +#if PLATFORM(MAC) +#include <OpenGL/gl.h> +#endif + +namespace WebCore { + +Extensions3DOpenGL::Extensions3DOpenGL() + : m_initializedAvailableExtensions(false) +{ +} + +Extensions3DOpenGL::~Extensions3DOpenGL() +{ +} + +bool Extensions3DOpenGL::supports(const String& name) +{ + // Note on support for BGRA: + // + // For OpenGL ES2.0, requires checking for + // GL_EXT_texture_format_BGRA8888 and GL_EXT_read_format_bgra. + // For desktop GL, BGRA has been supported since OpenGL 1.2. + // + // However, note that the GL ES2 extension requires the + // internalFormat to glTexImage2D() be GL_BGRA, while desktop GL + // will not accept GL_BGRA (must be GL_RGBA), so this must be + // checked on each platform. Desktop GL offers neither + // GL_EXT_texture_format_BGRA8888 or GL_EXT_read_format_bgra, so + // treat them as unsupported here. + if (!m_initializedAvailableExtensions) { + String extensionsString(reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS))); + Vector<String> availableExtensions; + extensionsString.split(" ", availableExtensions); + for (size_t i = 0; i < availableExtensions.size(); ++i) + m_availableExtensions.add(availableExtensions[i]); + m_initializedAvailableExtensions = true; + } + return m_availableExtensions.contains(name); +} + +int Extensions3DOpenGL::getGraphicsResetStatusARB() +{ + return GraphicsContext3D::NO_ERROR; +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h new file mode 100644 index 0000000..1b333b2 --- /dev/null +++ b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h @@ -0,0 +1,56 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Extensions3DOpenGL_h +#define Extensions3DOpenGL_h + +#include "Extensions3D.h" + +#include "GraphicsContext3D.h" +#include <wtf/HashSet.h> +#include <wtf/text/StringHash.h> + +namespace WebCore { + +class Extensions3DOpenGL : public Extensions3D { +public: + virtual ~Extensions3DOpenGL(); + + // Extensions3D methods. + virtual bool supports(const String&); + virtual int getGraphicsResetStatusARB(); + +private: + // This class only needs to be instantiated by GraphicsContext3D implementations. + friend class GraphicsContext3D; + Extensions3DOpenGL(); + + bool m_initializedAvailableExtensions; + HashSet<String> m_availableExtensions; +}; + +} // namespace WebCore + +#endif // Extensions3DOpenGL_h diff --git a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp index daf3b12..85089a0 100644 --- a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp +++ b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp @@ -33,6 +33,7 @@ #include "ArrayBufferView.h" #include "WebGLObject.h" #include "CanvasRenderingContext.h" +#include "Extensions3DOpenGL.h" #include "Float32Array.h" #include "GraphicsContext.h" #include "HTMLCanvasElement.h" @@ -568,12 +569,7 @@ void GraphicsContext3D::flush() void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, Platform3DObject buffer) { makeContextCurrent(); - GLuint renderbuffer = (GLuint) buffer; - if (attachment == DEPTH_STENCIL_ATTACHMENT) { - ::glFramebufferRenderbufferEXT(target, DEPTH_ATTACHMENT, renderbuffertarget, renderbuffer); - ::glFramebufferRenderbufferEXT(target, STENCIL_ATTACHMENT, renderbuffertarget, renderbuffer); - } else - ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); + ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, (GLuint) buffer); } void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, Platform3DObject texture, long level) @@ -1116,21 +1112,12 @@ void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target void GraphicsContext3D::getIntegerv(unsigned long pname, int* value) { - // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid - // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most - // useful for desktop WebGL users. // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS // because desktop GL's corresponding queries return the number of components // whereas GLES2 return the number of vectors (each vector has 4 components). // Therefore, the value returned by desktop GL needs to be divided by 4. makeContextCurrent(); switch (pname) { - case IMPLEMENTATION_COLOR_READ_FORMAT: - *value = GL_RGB; - break; - case IMPLEMENTATION_COLOR_READ_TYPE: - *value = GL_UNSIGNED_BYTE; - break; case MAX_FRAGMENT_UNIFORM_VECTORS: ::glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); *value /= 4; @@ -1445,9 +1432,11 @@ void GraphicsContext3D::synthesizeGLError(unsigned long error) m_syntheticErrors.add(error); } -int GraphicsContext3D::getGraphicsResetStatusARB() +Extensions3D* GraphicsContext3D::getExtensions() { - return NO_ERROR; + if (!m_extensions) + m_extensions = adoptPtr(new Extensions3DOpenGL); + return m_extensions.get(); } } diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp index 6527ce4..03f9b7c 100644 --- a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp +++ b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp @@ -30,8 +30,12 @@ #if defined(TEXMAP_OPENGL_ES_2) #include <GLES2/gl2.h> #elif OS(MAC_OS_X) +#include <AGL/agl.h> #include <gl.h> #else +#if OS(UNIX) +#include <GL/glx.h> +#endif #include <GL/gl.h> #endif @@ -90,6 +94,132 @@ inline static void debugGLCommand(const char* command, int line) #define GL_CMD(x) x #endif +static const GLuint gInVertexAttributeIndex = 0; + +struct TextureMapperGLData { + static struct ShaderInfo { + enum ShaderProgramIndex { + SimpleProgram, + OpacityAndMaskProgram, + TargetProgram, + + ProgramCount + }; + + enum ShaderVariableIndex { + InMatrixVariable, + InSourceMatrixVariable, + InMaskMatrixVariable, + OpacityVariable, + SourceTextureVariable, + MaskTextureVariable, + + VariableCount + }; + + struct ProgramInfo { + GLuint id; + GLint vars[VariableCount]; + }; + + GLint getUniformLocation(ShaderProgramIndex prog, ShaderVariableIndex var, const char* name) + { + return programs[prog].vars[var] = glGetUniformLocation(programs[prog].id, name); + } + + void createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource, ShaderProgramIndex index) + { + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + GL_CMD(glShaderSource(vertexShader, 1, &vertexShaderSource, 0)) + GL_CMD(glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0)) + GLuint programID = glCreateProgram(); + GL_CMD(glCompileShader(vertexShader)) + GL_CMD(glCompileShader(fragmentShader)) + GL_CMD(glAttachShader(programID, vertexShader)) + GL_CMD(glAttachShader(programID, fragmentShader)) + GL_CMD(glBindAttribLocation(programID, gInVertexAttributeIndex, "InVertex")) + GL_CMD(glLinkProgram(programID)) + programs[index].id = programID; +#ifdef PRINT_PROGRAM_INFO_LOG + char infoLog[1024]; + int len; + GL_CMD(glGetProgramInfoLog(programID, 1024, &len, infoLog)); + LOG(Graphics, "Compiled program for texture mapper. Log: %s\n", infoLog); +#endif + } + + ProgramInfo programs[ProgramCount]; + + } shaderInfo; + + struct DirectlyCompositedImageRepository { + struct Entry { + GLuint texture; + int refCount; + }; + HashMap<NativeImagePtr, Entry> imageToTexture; + + GLuint findOrCreate(NativeImagePtr image, bool& found) + { + HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); + found = false; + if (it != imageToTexture.end()) { + it->second.refCount++; + found = true; + return it->second.texture; + } + Entry entry; + GL_CMD(glGenTextures(1, &entry.texture)); + entry.refCount = 1; + imageToTexture.add(image, entry); + return entry.texture; + } + + bool deref(NativeImagePtr image) + { + HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); + if (it != imageToTexture.end()) { + if (it->second.refCount < 2) { + imageToTexture.remove(it); + return false; + } + } + return true; + } + + DirectlyCompositedImageRepository() + { + } + + ~DirectlyCompositedImageRepository() + { + for (HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.begin(); it != imageToTexture.end(); ++it) { + GLuint texture = it->second.texture; + if (texture) + GL_CMD(glDeleteTextures(1, &texture)); + } + + } + } directlyCompositedImages; + + TextureMapperGLData() + : currentProgram(TextureMapperGLData::ShaderInfo::TargetProgram) + { } + + TransformationMatrix projectionMatrix; + int currentProgram; + +#if OS(MAC_OS_X) + AGLContext aglContext; +#elif OS(UNIX) + Drawable glxDrawable; + GLXContext glxContext; +#endif +}; + +TextureMapperGLData::ShaderInfo TextureMapperGLData::shaderInfo; + class BitmapTextureGL : public BitmapTexture { public: virtual void destroy(); @@ -99,6 +229,7 @@ public: virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect); virtual void endPaint(); virtual void setContentsToImage(Image*); + ~BitmapTextureGL() { destroy(); } private: GLuint m_id; @@ -111,78 +242,32 @@ private: GLuint m_fbo; IntSize m_actualSize; bool m_surfaceNeedsReset; + TextureMapperGL* m_textureMapper; BitmapTextureGL() : m_id(0) , m_image(0) , m_opaque(false) , m_fbo(0) , m_surfaceNeedsReset(true) + , m_textureMapper(0) { } friend class TextureMapperGL; }; -static struct TexmapShaderInfo { - enum ShaderProgramIndex { - SimpleProgram, - OpacityAndMaskProgram, - TargetProgram, - NumPrograms - }; - - enum ShaderVariableIndex { - InMatrixVariable, - InSourceMatrixVariable, - InMaskMatrixVariable, - InVertexVariable, - - OpacityVariable, - SourceTextureVariable, - MaskTextureVariable, - NumVariables - }; - - struct ProgramInfo { - GLuint id; - GLint vars[NumVariables]; - }; - - GLint getUniformLocation(ShaderProgramIndex prog, ShaderVariableIndex var, const char* name) - { - return programs[prog].vars[var] = glGetUniformLocation(programs[prog].id, name); - } - - void createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource, ShaderProgramIndex index) - { - GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); - GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - GL_CMD(glShaderSource(vertexShader, 1, &vertexShaderSource, 0)) - GL_CMD(glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0)) - GLuint programID = glCreateProgram(); - GL_CMD(glCompileShader(vertexShader)) - GL_CMD(glCompileShader(fragmentShader)) - GL_CMD(glAttachShader(programID, vertexShader)) - GL_CMD(glAttachShader(programID, fragmentShader)) - GL_CMD(glBindAttribLocation(programID, 0, "InVertex")) - GL_CMD(glLinkProgram(programID)) - programs[index].id = programID; - } - - ProgramInfo programs[NumPrograms]; - -} gShaderInfo; - #define TEXMAP_GET_SHADER_VAR_LOCATION(prog, var) \ - if (gShaderInfo.getUniformLocation(TexmapShaderInfo::prog##Program, TexmapShaderInfo::var##Variable, #var) < 0) \ - LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n"); -#define TEXMAP_BUILD_SHADER(program) gShaderInfo.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TexmapShaderInfo::program##Program); + if (TextureMapperGLData::shaderInfo.getUniformLocation(TextureMapperGLData::shaderInfo.prog##Program, TextureMapperGLData::shaderInfo.var##Variable, #var) < 0) \ + LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n"); + +#define TEXMAP_BUILD_SHADER(program) \ + TextureMapperGLData::shaderInfo.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TextureMapperGLData::shaderInfo.program##Program); -TextureMapperGL::TextureMapperGL(GraphicsContext* context) - : TextureMapper(context) - , m_currentProgram(TexmapShaderInfo::TargetProgram) +TextureMapperGL::TextureMapperGL() + : m_data(new TextureMapperGLData) { static bool shadersCompiled = false; + obtainCurrentContext(); if (shadersCompiled) return; shadersCompiled = true; @@ -282,18 +367,18 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture); - TexmapShaderInfo::ShaderProgramIndex program; + TextureMapperGLData::ShaderInfo::ShaderProgramIndex program; if (maskTexture) - program = TexmapShaderInfo::OpacityAndMaskProgram; + program = TextureMapperGLData::ShaderInfo::OpacityAndMaskProgram; else - program = TexmapShaderInfo::SimpleProgram; + program = TextureMapperGLData::ShaderInfo::SimpleProgram; - const TexmapShaderInfo::ProgramInfo& programInfo = gShaderInfo.programs[program]; - if (m_currentProgram != program) { + const TextureMapperGLData::ShaderInfo::ProgramInfo& programInfo = data().shaderInfo.programs[program]; + if (data().currentProgram != program) { GL_CMD(glUseProgram(programInfo.id)) - GL_CMD(glDisableVertexAttribArray(gShaderInfo.programs[m_currentProgram].vars[TexmapShaderInfo::InVertexVariable])) - m_currentProgram = program; - GL_CMD(glEnableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) + GL_CMD(glDisableVertexAttribArray(gInVertexAttributeIndex)) + data().currentProgram = program; + GL_CMD(glEnableVertexAttribArray(gInVertexAttributeIndex)) } GL_CMD(glDisable(GL_DEPTH_TEST)) @@ -305,7 +390,7 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1}; GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect)) - TransformationMatrix matrix = TransformationMatrix(m_projectionMatrix).multLeft(modelViewMatrix).multLeft(TransformationMatrix( + TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multLeft(modelViewMatrix).multLeft(TransformationMatrix( targetRect.width(), 0, 0, 0, 0, targetRect.height(), 0, 0, 0, 0, 1, 0, @@ -321,10 +406,10 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t 0, textureGL.m_relativeSize.height(), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; - GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) - GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) - GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::SourceTextureVariable], 0)) - GL_CMD(glUniform1f(programInfo.vars[TexmapShaderInfo::OpacityVariable], opacity)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) + GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::SourceTextureVariable], 0)) + GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::ShaderInfo::OpacityVariable], opacity)) if (maskTexture && maskTexture->isValid()) { const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture); @@ -334,12 +419,11 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t 0, maskTextureGL->m_relativeSize.height(), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; - glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask); - GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::MaskTextureVariable], 1)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask)); + GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::MaskTextureVariable], 1)) GL_CMD(glActiveTexture(GL_TEXTURE0)) } - if (textureGL.m_opaque && opacity > 0.99 && !maskTexture) GL_CMD(glDisable(GL_BLEND)) else { @@ -350,7 +434,6 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)) } - const char* TextureMapperGL::type() const { return "OpenGL"; @@ -399,43 +482,6 @@ void BitmapTextureGL::endPaint() m_buffer.clear(); } -struct TexmapGLShaderTextures { - struct Entry { - GLuint texture; - int refCount; - }; - HashMap<NativeImagePtr, Entry> imageToTexture; - GLuint findOrCreate(NativeImagePtr image, bool& found) - { - HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); - found = false; - if (it != imageToTexture.end()) { - it->second.refCount++; - found = true; - return it->second.texture; - } - Entry entry; - GL_CMD(glGenTextures(1, &entry.texture)); - entry.refCount = 1; - imageToTexture.add(image, entry); - return entry.texture; - } - - bool deref(NativeImagePtr image) - { - HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); - if (it != imageToTexture.end()) { - if (it->second.refCount < 2) { - imageToTexture.remove(it); - return false; - } - } - return true; - } -}; - -static TexmapGLShaderTextures gTextureRepository; - void BitmapTextureGL::setContentsToImage(Image* image) { NativeImagePtr nativeImage = image ? image->nativeImageForCurrentFrame() : 0; @@ -448,7 +494,7 @@ void BitmapTextureGL::setContentsToImage(Image* image) if (nativeImage == m_image) return; bool found = false; - GLuint newTextureID = gTextureRepository.findOrCreate(nativeImage, found); + GLuint newTextureID = m_textureMapper->data().directlyCompositedImages.findOrCreate(nativeImage, found); if (newTextureID != m_id) { destroy(); m_id = newTextureID; @@ -464,7 +510,7 @@ void BitmapTextureGL::setContentsToImage(Image* image) void BitmapTextureGL::destroy() { - if (m_id && (!m_image || !gTextureRepository.deref(m_image))) + if (m_id && (!m_image || !m_textureMapper->data().directlyCompositedImages.deref(m_image))) GL_CMD(glDeleteTextures(1, &m_id)) if (m_fbo) GL_CMD(glDeleteFramebuffers(1, &m_fbo)) @@ -493,8 +539,32 @@ static inline TransformationMatrix createProjectionMatrix(const IntSize& size, b -1, flip ? 1 : -1, 0, 1); } -void TextureMapperGL::cleanup() +TextureMapperGL::~TextureMapperGL() { + makeContextCurrent(); + delete m_data; +} + +bool TextureMapperGL::makeContextCurrent() +{ +#if OS(MAC_OS_X) + return aglSetCurrentContext(data().aglContext); +#elif OS(UNIX) + Display* display = XOpenDisplay(0); + if (!display) + return false; + return glXMakeCurrent(display, data().glxDrawable, data().glxContext); +#endif +} + +void TextureMapperGL::obtainCurrentContext() +{ +#if OS(MAC_OS_X) + data().aglContext = aglGetCurrentContext(); +#elif OS(UNIX) + data().glxDrawable = glXGetCurrentDrawable(); + data().glxContext = glXGetCurrentContext(); +#endif } void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) @@ -503,6 +573,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) if (!surface) return; + TransformationMatrix matrix = createProjectionMatrix(surface->size(), false); matrix.translate(-surface->offset().x(), -surface->offset().y()); @@ -520,7 +591,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) } GL_CMD(glViewport(0, 0, surface->size().width(), surface->size().height())) - m_projectionMatrix = matrix; + data().projectionMatrix = matrix; } void TextureMapperGL::setClip(const IntRect& rect) @@ -540,8 +611,7 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize surface.m_actualSize.width(), 0, 0, 0, 0, surface.m_actualSize.height(), 0, 0, 0, 0, 1, 0, - surface.offset().x(), surface.offset().y(), 0, 1 - ) + surface.offset().x(), surface.offset().y(), 0, 1) ); const GLfloat m4[] = { @@ -557,18 +627,18 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize 0, 0, 0, 1}; // We already blended the alpha in; the result is premultiplied. - GL_CMD(glUseProgram(gShaderInfo.programs[TexmapShaderInfo::TargetProgram].id)) + GL_CMD(glUseProgram(data().shaderInfo.programs[TextureMapperGLData::ShaderInfo::TargetProgram].id)) GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0)) GL_CMD(glViewport(0, 0, surfaceSize.width(), surfaceSize.height())) GL_CMD(glDisable(GL_STENCIL_TEST)) - const TexmapShaderInfo::ProgramInfo& programInfo = gShaderInfo.programs[TexmapShaderInfo::TargetProgram]; - GL_CMD(glUniform1f(programInfo.vars[TexmapShaderInfo::OpacityVariable], opacity)) + const TextureMapperGLData::ShaderInfo::ProgramInfo& programInfo = data().shaderInfo.programs[TextureMapperGLData::ShaderInfo::TargetProgram]; + GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::ShaderInfo::OpacityVariable], opacity)) GL_CMD(glActiveTexture(GL_TEXTURE0)) GL_CMD(glBindTexture(GL_TEXTURE_2D, surface.m_id)) - GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::SourceTextureVariable], 0)) - GL_CMD(glEnableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) - GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) - GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) + GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::SourceTextureVariable], 0)) + GL_CMD(glEnableVertexAttribArray(gInVertexAttributeIndex)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0)) const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1}; GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect)) @@ -577,15 +647,17 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize setClip(visibleRect); GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)) - GL_CMD(glDisableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) + GL_CMD(glDisableVertexAttribArray(0)) GL_CMD(glUseProgram(0)) GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0)) - m_currentProgram = TexmapShaderInfo::TargetProgram; + data().currentProgram = TextureMapperGLData::ShaderInfo::TargetProgram; } PassRefPtr<BitmapTexture> TextureMapperGL::createTexture() { - return adoptRef(new BitmapTextureGL()); + BitmapTextureGL* texture = new BitmapTextureGL(); + texture->m_textureMapper = this; + return adoptRef(texture); } }; diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.h b/WebCore/platform/graphics/opengl/TextureMapperGL.h index 7a12c72..8035abf 100644 --- a/WebCore/platform/graphics/opengl/TextureMapperGL.h +++ b/WebCore/platform/graphics/opengl/TextureMapperGL.h @@ -29,11 +29,13 @@ namespace WebCore { +class TextureMapperGLData; + // An OpenGL-ES2 implementation of TextureMapper. class TextureMapperGL : public TextureMapper { public: - TextureMapperGL(GraphicsContext* gc); - virtual ~TextureMapperGL() {} + TextureMapperGL(); + virtual ~TextureMapperGL(); // reimps from TextureMapper virtual void drawTexture(const BitmapTexture& texture, const IntRect&, const TransformationMatrix& transform, float opacity, const BitmapTexture* maskTexture); @@ -43,11 +45,17 @@ public: virtual bool allowSurfaceForRoot() const { return true; } virtual PassRefPtr<BitmapTexture> createTexture(); virtual const char* type() const; - virtual void cleanup(); + void obtainCurrentContext(); + bool makeContextCurrent(); + static PassOwnPtr<TextureMapperGL> create() + { + return new TextureMapperGL; + } private: - TransformationMatrix m_projectionMatrix; - int m_currentProgram; + inline TextureMapperGLData& data() { return *m_data; } + TextureMapperGLData* m_data; + friend class BitmapTextureGL; }; // An offscreen buffer to be rendered by software. diff --git a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp index 37fd8ad..0d16d4d 100644 --- a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp +++ b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp @@ -340,14 +340,6 @@ void GraphicsContext::clearRect(const FloatRect& rect) m_data->setCompositeOperation(op); } -void GraphicsContext::strokeRect(const FloatRect& rect) -{ - if (paintingDisabled()) - return; - - m_data->drawRect(rect, VG_STROKE_PATH); -} - void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) { if (paintingDisabled()) @@ -452,15 +444,6 @@ void GraphicsContext::translate(float dx, float dy) m_data->translate(dx, dy); } -IntPoint GraphicsContext::origin() -{ - if (paintingDisabled()) - return IntPoint(); - - AffineTransform transformation = m_data->transformation(); - return IntPoint(roundf(transformation.e()), roundf(transformation.f())); -} - void GraphicsContext::clipOut(const IntRect& rect) { if (paintingDisabled()) @@ -471,16 +454,6 @@ void GraphicsContext::clipOut(const IntRect& rect) m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule); } -void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - Path path; - path.addEllipse(rect); - m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule); -} - void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer) { if (paintingDisabled()) diff --git a/WebCore/platform/graphics/qt/Extensions3DQt.cpp b/WebCore/platform/graphics/qt/Extensions3DQt.cpp new file mode 100644 index 0000000..6a34671 --- /dev/null +++ b/WebCore/platform/graphics/qt/Extensions3DQt.cpp @@ -0,0 +1,56 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(3D_CANVAS) + +#include "Extensions3DQt.h" + +#include "GraphicsContext3D.h" + +namespace WebCore { + +Extensions3DQt::Extensions3DQt() +{ +} + +Extensions3DQt::~Extensions3DQt() +{ +} + +bool Extensions3DQt::supports(const String&) +{ + return false; +} + +int Extensions3DQt::getGraphicsResetStatusARB() +{ + return GraphicsContext3D::NO_ERROR; +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/platform/graphics/qt/Extensions3DQt.h b/WebCore/platform/graphics/qt/Extensions3DQt.h new file mode 100644 index 0000000..29209ba --- /dev/null +++ b/WebCore/platform/graphics/qt/Extensions3DQt.h @@ -0,0 +1,49 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Extensions3DQt_h +#define Extensions3DQt_h + +#include "Extensions3D.h" + +namespace WebCore { + +class Extensions3DQt : public Extensions3D { +public: + virtual ~Extensions3DQt(); + + // Extensions3D methods. + virtual bool supports(const String&); + virtual int getGraphicsResetStatusARB(); + +private: + // This class only needs to be instantiated by GraphicsContext3D implementations. + friend class GraphicsContext3D; + Extensions3DQt(); +}; + +} // namespace WebCore + +#endif // Extensions3DQt_h diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index cda8606..26db220 100644 --- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -22,6 +22,7 @@ #include "WebGLObject.h" #include "CanvasRenderingContext.h" +#include "Extensions3DQt.h" #include "GraphicsContext.h" #include "HTMLCanvasElement.h" #include "HostWindow.h" @@ -253,6 +254,8 @@ public: QImage m_pixels; ListHashSet<unsigned long> m_syntheticErrors; + OwnPtr<Extensions3DQt> m_extensions; + private: void* getProcAddress(const String& proc); @@ -1632,6 +1635,13 @@ void GraphicsContext3D::synthesizeGLError(unsigned long error) m_internal->m_syntheticErrors.add(error); } +Extensions3D* GraphicsContext3D::getExtensions() +{ + if (!m_internal->m_extensions) + m_internal->m_extensions = adoptPtr(new Extensions3DQt); + return m_internal->m_extensions; +} + bool GraphicsContext3D::getImageData(Image* image, unsigned int format, unsigned int type, diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index 50971b5..4f68577 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -504,16 +504,18 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin for (size_t i = 1; i < numPoints; ++i) path.lineTo(points[i]); path.setFillRule(Qt::WindingFill); - m_data->p()->setClipPath(path, Qt::IntersectClip); -} - -QPen GraphicsContext::pen() -{ - if (paintingDisabled()) - return QPen(); QPainter* p = m_data->p(); - return p->pen(); + + bool painterWasAntialiased = p->testRenderHint(QPainter::Antialiasing); + + if (painterWasAntialiased != antialiased) + p->setRenderHint(QPainter::Antialiasing, antialiased); + + p->setClipPath(path, Qt::IntersectClip); + + if (painterWasAntialiased != antialiased) + p->setRenderHint(QPainter::Antialiasing, painterWasAntialiased); } void GraphicsContext::fillPath() @@ -733,9 +735,21 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight); QPainter* p = m_data->p(); if (m_data->hasShadow()) { - p->translate(m_data->shadow.offset()); - p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color)); - p->translate(-m_data->shadow.offset()); + ContextShadow* shadow = contextShadow(); + + if (shadow->m_type != ContextShadow::BlurShadow) { + // We do not need any layer for simple shadow. + p->translate(m_data->shadow.offset()); + p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color)); + p->translate(-m_data->shadow.offset()); + } else { + QPainter* shadowPainter = shadow->beginShadowLayer(p, rect); + if (shadowPainter) { + shadowPainter->setCompositionMode(QPainter::CompositionMode_Source); + shadowPainter->fillPath(path.platformPath(), QColor(m_data->shadow.m_color)); + shadow->endShadowLayer(p); + } + } } p->fillPath(path.platformPath(), QColor(color)); } @@ -1128,14 +1142,6 @@ void GraphicsContext::translate(float x, float y) } } -IntPoint GraphicsContext::origin() -{ - if (paintingDisabled()) - return IntPoint(); - const QTransform &transform = m_data->p()->transform(); - return IntPoint(qRound(transform.dx()), qRound(transform.dy())); -} - void GraphicsContext::rotate(float radians) { if (paintingDisabled()) @@ -1186,28 +1192,6 @@ void GraphicsContext::clipOut(const IntRect& rect) } } -void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - QPainter* p = m_data->p(); - QPainterPath newClip; - newClip.setFillRule(Qt::OddEvenFill); - if (p->hasClipping()) { - newClip.addRect(m_data->clipBoundingRect()); - newClip.addEllipse(QRect(rect)); - p->setClipPath(newClip, Qt::IntersectClip); - } else { - QRect clipOutRect(rect); - QRect window(p->window()); - clipOutRect &= window; - newClip.addRect(window); - newClip.addEllipse(clipOutRect); - p->setClipPath(newClip); - } -} - void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) { diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index aa7ed2f..49387a2 100644 --- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -37,12 +37,21 @@ #include <QtGui/qgraphicseffect.h> #include <QtGui/qgraphicsitem.h> #include <QtGui/qgraphicsscene.h> +#include <QtGui/qgraphicsview.h> #include <QtGui/qgraphicswidget.h> #include <QtGui/qpainter.h> #include <QtGui/qpixmap.h> #include <QtGui/qpixmapcache.h> #include <QtGui/qstyleoption.h> +#if ENABLE(TILED_BACKING_STORE) +#include "TiledBackingStore.h" +#include "TiledBackingStoreClient.h" + +// The minimum width/height for tiling. We use the same value as the Windows implementation. +#define GRAPHICS_LAYER_TILING_THRESHOLD 2000 +#endif + #define QT_DEBUG_RECACHE 0 #define QT_DEBUG_CACHEDUMP 0 @@ -112,7 +121,11 @@ public: }; #endif // QT_NO_GRAPHICSEFFECT -class GraphicsLayerQtImpl : public QGraphicsObject { +class GraphicsLayerQtImpl : public QGraphicsObject +#if ENABLE(TILED_BACKING_STORE) +, public virtual TiledBackingStoreClient +#endif +{ Q_OBJECT public: @@ -182,6 +195,16 @@ public: // ChromeClientQt::scheduleCompositingLayerSync (meaning the sync will happen ASAP) void flushChanges(bool recursive = true, bool forceTransformUpdate = false); +#if ENABLE(TILED_BACKING_STORE) + // reimplementations from TiledBackingStoreClient + virtual void tiledBackingStorePaintBegin(); + virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&); + virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea); + virtual IntRect tiledBackingStoreContentsRect(); + virtual IntRect tiledBackingStoreVisibleRect(); + virtual Color tiledBackingStoreBackgroundColor() const; +#endif + public slots: // We need to notify the client (ie. the layer compositor) when the animation actually starts. void notifyAnimationStarted(); @@ -232,6 +255,10 @@ public: int m_changeMask; +#if ENABLE(TILED_BACKING_STORE) + TiledBackingStore* m_tiledBackingStore; +#endif + QSizeF m_size; struct { QPixmapCache::Key key; @@ -303,6 +330,9 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer) , m_opacityAnimationRunning(false) , m_blockNotifySyncRequired(false) , m_changeMask(NoChanges) +#if ENABLE(TILED_BACKING_STORE) + , m_tiledBackingStore(0) +#endif #if ENABLE(3D_CANVAS) , m_gc3D(0) #endif @@ -330,7 +360,9 @@ GraphicsLayerQtImpl::~GraphicsLayerQtImpl() item->setParentItem(0); } } - +#if ENABLE(TILED_BACKING_STORE) + delete m_tiledBackingStore; +#endif #ifndef QT_NO_ANIMATION // We do, however, own the animations. QList<QWeakPointer<QAbstractAnimation> >::iterator it; @@ -352,6 +384,27 @@ QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid()) return QPixmap(); +#if ENABLE(TILED_BACKING_STORE) + const bool requiresTiling = (m_state.drawsContent && m_currentContent.contentType == HTMLContentType) && (m_size.width() > GRAPHICS_LAYER_TILING_THRESHOLD || m_size.height() > GRAPHICS_LAYER_TILING_THRESHOLD); + if (requiresTiling && !m_tiledBackingStore) { + m_tiledBackingStore = new TiledBackingStore(this); + m_tiledBackingStore->setTileCreationDelay(0); + setFlag(ItemUsesExtendedStyleOption, true); + } else if (!requiresTiling && m_tiledBackingStore) { + delete m_tiledBackingStore; + m_tiledBackingStore = 0; + setFlag(ItemUsesExtendedStyleOption, false); + } + + if (m_tiledBackingStore) { + m_tiledBackingStore->adjustVisibleRect(); + const QVector<QRect> rects = regionToUpdate.rects(); + for (int i = 0; i < rects.size(); ++i) + m_tiledBackingStore->invalidate(rects[i]); + return QPixmap(); + } +#endif + QPixmap pixmap; QRegion region = regionToUpdate; if (QPixmapCache::find(m_backingStore.key, &pixmap)) { @@ -562,8 +615,15 @@ QRectF GraphicsLayerQtImpl::boundingRect() const void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { +#if ENABLE(TILED_BACKING_STORE) + // FIXME: There's currently no Qt API to know if a new region of an item is exposed outside of the paint event. + // Suggested for Qt: http://bugreports.qt.nokia.com/browse/QTBUG-14877. + if (m_tiledBackingStore) + m_tiledBackingStore->adjustVisibleRect(); +#endif + if (m_currentContent.backgroundColor.isValid()) - painter->fillRect(option->rect, QColor(m_currentContent.backgroundColor)); + painter->fillRect(option->exposedRect, QColor(m_currentContent.backgroundColor)); switch (m_currentContent.contentType) { case HTMLContentType: @@ -828,6 +888,56 @@ afterLayerChanges: } } +#if ENABLE(TILED_BACKING_STORE) +/* \reimp (TiledBackingStoreClient.h) +*/ +void GraphicsLayerQtImpl::tiledBackingStorePaintBegin() +{ +} + +/* \reimp (TiledBackingStoreClient.h) +*/ +void GraphicsLayerQtImpl::tiledBackingStorePaint(GraphicsContext* gc, const IntRect& rect) +{ + m_layer->paintGraphicsLayerContents(*gc, rect); +} + +/* \reimp (TiledBackingStoreClient.h) +*/ +void GraphicsLayerQtImpl::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea) +{ + for (int i = 0; i < paintedArea.size(); ++i) + update(QRectF(paintedArea[i])); +} + +/* \reimp (TiledBackingStoreClient.h) +*/ +IntRect GraphicsLayerQtImpl::tiledBackingStoreContentsRect() +{ + return m_layer->contentsRect(); +} + +/* \reimp (TiledBackingStoreClient.h) +*/ +Color GraphicsLayerQtImpl::tiledBackingStoreBackgroundColor() const +{ + if (m_currentContent.contentType == PixmapContentType && !m_currentContent.pixmap.hasAlphaChannel()) + return Color(0, 0, 0); + // We return a transparent color so that the tiles initialize with alpha. + return Color(0, 0, 0, 0); +} + +IntRect GraphicsLayerQtImpl::tiledBackingStoreVisibleRect() +{ + const QGraphicsView* view = scene()->views().isEmpty() ? 0 : scene()->views().first(); + if (!view) + return mapFromScene(scene()->sceneRect()).boundingRect().toAlignedRect(); + + // All we get is the viewport's visible region. We have to map it to the scene and then to item coordinates. + return mapFromScene(view->mapToScene(view->viewport()->visibleRegion().boundingRect()).boundingRect()).boundingRect().toAlignedRect(); +} +#endif + void GraphicsLayerQtImpl::notifyAnimationStarted() { // WebCore notifies javascript when the animation starts. Here we're letting it know. diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp index 508ba6a..b686fef 100644 --- a/WebCore/platform/graphics/qt/PathQt.cpp +++ b/WebCore/platform/graphics/qt/PathQt.cpp @@ -134,10 +134,10 @@ bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) ASSERT(applier); QPainterPathStroker stroke; - GraphicsContext* gc = scratchContext(); - applier->strokeStyle(gc); + GraphicsContext* context = scratchContext(); + applier->strokeStyle(context); - QPen pen = gc->pen(); + QPen pen = context->platformContext()->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); @@ -162,12 +162,12 @@ FloatRect Path::boundingRect() const FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) { - GraphicsContext* gc = scratchContext(); + GraphicsContext* context = scratchContext(); QPainterPathStroker stroke; if (applier) { - applier->strokeStyle(gc); + applier->strokeStyle(context); - QPen pen = gc->pen(); + QPen pen = context->platformContext()->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); diff --git a/WebCore/platform/graphics/qt/TextureMapperQt.cpp b/WebCore/platform/graphics/qt/TextureMapperQt.cpp index 9236dae..6fdd7df 100644 --- a/WebCore/platform/graphics/qt/TextureMapperQt.cpp +++ b/WebCore/platform/graphics/qt/TextureMapperQt.cpp @@ -18,7 +18,7 @@ */ #include "config.h" -#include "texmap/TextureMapper.h" +#include "TextureMapperQt.h" #include <QtCore/qdebug.h> #include <QtGui/qpaintengine.h> @@ -30,45 +30,6 @@ namespace WebCore { -class BitmapTextureQt : public BitmapTexture { - friend class TextureMapperQt; -public: - BitmapTextureQt() {} - virtual void destroy(); - virtual IntSize size() const { return IntSize(m_pixmap.width(), m_pixmap.height()); } - virtual void reset(const IntSize&, bool opaque); - virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect); - virtual void endPaint(); - virtual void setContentsToImage(Image*); - virtual bool save(const String& path); - virtual bool isValid() const { return !m_pixmap.isNull(); } - virtual bool allowOfflineTextureUpload() const { return true; } - IntRect sourceRect() const { return IntRect(0, 0, contentSize().width(), contentSize().height()); } -private: - QPainter m_painter; - QPixmap m_pixmap; -}; - -class TextureMapperQt : public TextureMapper { -public: - virtual void drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture); - virtual void bindSurface(BitmapTexture* surface); - virtual void setClip(const IntRect&); - virtual bool allowSurfaceForRoot() const { return false; } - TextureMapperQt(GraphicsContext* context); - virtual const char* type() const { return "TextureMapperQt"; } - virtual PassRefPtr<BitmapTexture> createTexture(); - - static void initialize(QPainter* painter) - { - painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false); - } - -private: - QPainter* m_painter; - RefPtr<BitmapTextureQt> m_currentSurface; -}; - void BitmapTextureQt::destroy() { if (m_pixmap.paintingActive()) @@ -117,18 +78,41 @@ void BitmapTextureQt::setContentsToImage(Image* image) m_pixmap = *pixmap; } +void BitmapTextureQt::pack() +{ + if (m_pixmap.isNull()) + return; + + m_image = m_pixmap.toImage(); + m_pixmap = QPixmap(); + m_isPacked = true; +} + +void BitmapTextureQt::unpack() +{ + m_isPacked = false; + if (m_image.isNull()) + return; + + m_pixmap = QPixmap::fromImage(m_image); + m_image = QImage(); +} + void TextureMapperQt::setClip(const IntRect& rect) { QPainter* painter = m_currentSurface ? &m_currentSurface->m_painter : m_painter; painter->setClipRect(rect); } -TextureMapperQt::TextureMapperQt(GraphicsContext* context) - : TextureMapper(context) - , m_painter(context->platformContext()) - , m_currentSurface(0) +TextureMapperQt::TextureMapperQt() + : m_currentSurface(0) { - TextureMapperQt::initialize(m_painter); +} + +void TextureMapperQt::setGraphicsContext(GraphicsContext* context) +{ + m_painter = context->platformContext(); + initialize(m_painter); } void TextureMapperQt::bindSurface(BitmapTexture* surface) @@ -178,21 +162,26 @@ void TextureMapperQt::drawTexture(const BitmapTexture& texture, const IntRect& t painter->setOpacity(prevOpacity); } -PassRefPtr<TextureMapper> TextureMapper::create(GraphicsContext* context) +PassOwnPtr<TextureMapper> TextureMapper::create(GraphicsContext* context) { #ifdef QT_OPENGL_LIB - if (context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2) - return adoptRef(new TextureMapperGL(context)); + if (context && context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2) + return new TextureMapperGL; #endif - return adoptRef(new TextureMapperQt(context)); + return new TextureMapperQt; } - PassRefPtr<BitmapTexture> TextureMapperQt::createTexture() { return adoptRef(new BitmapTextureQt()); } +BitmapTextureQt::BitmapTextureQt() + : m_isPacked(false) +{ + +} + #ifdef QT_OPENGL_LIB class RGBA32PremultimpliedBufferQt : public RGBA32PremultimpliedBuffer { public: diff --git a/WebCore/platform/graphics/qt/TextureMapperQt.h b/WebCore/platform/graphics/qt/TextureMapperQt.h new file mode 100644 index 0000000..e17b968 --- /dev/null +++ b/WebCore/platform/graphics/qt/TextureMapperQt.h @@ -0,0 +1,76 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "texmap/TextureMapper.h" + +#ifndef TextureMapperQt_h +#define TextureMapperQt_h + +namespace WebCore { + +class BitmapTextureQt : public BitmapTexture { + friend class TextureMapperQt; +public: + BitmapTextureQt(); + ~BitmapTextureQt() { destroy(); } + virtual void destroy(); + virtual IntSize size() const { return IntSize(m_pixmap.width(), m_pixmap.height()); } + virtual void reset(const IntSize&, bool opaque); + virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect); + virtual void endPaint(); + virtual void setContentsToImage(Image*); + virtual bool save(const String& path); + virtual bool isValid() const { return !m_pixmap.isNull() || !m_image.isNull(); } + IntRect sourceRect() const { return IntRect(0, 0, contentSize().width(), contentSize().height()); } + virtual void pack(); + virtual void unpack(); + virtual bool isPacked() const { return m_isPacked; } + +private: + QPainter m_painter; + QPixmap m_pixmap; + QImage m_image; + bool m_isPacked; +}; + +class TextureMapperQt : public TextureMapper { +public: + TextureMapperQt(); + + virtual void drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture); + virtual void bindSurface(BitmapTexture* surface); + virtual void setClip(const IntRect&); + virtual void setGraphicsContext(GraphicsContext*); + virtual bool allowSurfaceForRoot() const { return false; } + virtual PassRefPtr<BitmapTexture> createTexture(); + + static void initialize(QPainter* painter) + { + painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false); + } + + static PassOwnPtr<TextureMapper> create() { return new TextureMapperQt; } + +private: + QPainter* m_painter; + RefPtr<BitmapTextureQt> m_currentSurface; +}; + +} +#endif diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp index c503307..d0dafb1 100644 --- a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp +++ b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp @@ -48,7 +48,7 @@ bool GraphicsContext3D::getImageData(Image* image, return false; OwnPtr<NativeImageSkia> pixels; NativeImageSkia* skiaImage = 0; - AlphaOp neededAlphaOp = kAlphaDoNothing; + AlphaOp neededAlphaOp = AlphaDoNothing; if (image->data()) { ImageSource decoder(false); decoder.setData(image->data(), true); @@ -63,12 +63,12 @@ bool GraphicsContext3D::getImageData(Image* image, return false; skiaImage = pixels.get(); if (hasAlpha && premultiplyAlpha) - neededAlphaOp = kAlphaDoPremultiply; + neededAlphaOp = AlphaDoPremultiply; } else { // This is a special case for texImage2D with HTMLCanvasElement input. skiaImage = image->nativeImageForCurrentFrame(); if (!premultiplyAlpha) - neededAlphaOp = kAlphaDoUnmultiply; + neededAlphaOp = AlphaDoUnmultiply; } if (!skiaImage) return false; @@ -77,7 +77,7 @@ bool GraphicsContext3D::getImageData(Image* image, ASSERT(skiaImage->rowBytes() == skiaImage->width() * 4); outputVector.resize(skiaImage->rowBytes() * skiaImage->height()); return packPixels(reinterpret_cast<const uint8_t*>(skiaImage->getPixels()), - kSourceFormatBGRA8, skiaImage->width(), skiaImage->height(), 0, + SourceFormatBGRA8, skiaImage->width(), skiaImage->height(), 0, format, type, neededAlphaOp, outputVector.data()); } diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp index 4bc98fb..e506e5d 100644 --- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp +++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp @@ -420,20 +420,6 @@ void GraphicsContext::clipOut(const Path& p) platformContext()->canvas()->clipPath(path, SkRegion::kDifference_Op); } -void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - SkRect oval(rect); - if (!isRectSkiaSafe(getCTM(), oval)) - return; - - SkPath path; - path.addOval(oval, SkPath::kCCW_Direction); - platformContext()->canvas()->clipPath(path, SkRegion::kDifference_Op); -} - void GraphicsContext::clipPath(WindRule clipRule) { if (paintingDisabled()) @@ -946,6 +932,11 @@ void GraphicsContext::setCompositeOperation(CompositeOperator op) platformContext()->setXfermodeMode(WebCoreCompositeToSkiaComposite(op)); } +InterpolationQuality GraphicsContext::imageInterpolationQuality() const +{ + return platformContext()->interpolationQuality(); +} + void GraphicsContext::setImageInterpolationQuality(InterpolationQuality q) { platformContext()->setInterpolationQuality(q); diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp index 6204597..d610c2a 100644 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp +++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp @@ -34,6 +34,7 @@ #include "AffineTransform.h" #include "DrawingBuffer.h" +#include "Extensions3D.h" #include "GraphicsContext.h" #include "GraphicsContext3D.h" #include "ImageBuffer.h" @@ -861,7 +862,7 @@ void PlatformContextSkia::readbackHardwareToSoftware() const for (int y = 0; y < height; ++y) { uint32_t* pixels = bitmap.getAddr32(0, y); if (context->supportsBGRA()) - context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::BGRA_EXT, GraphicsContext3D::UNSIGNED_BYTE, pixels); + context->readPixels(0, height - 1 - y, width, 1, Extensions3D::BGRA_EXT, GraphicsContext3D::UNSIGNED_BYTE, pixels); else { context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels); for (int i = 0; i < width; ++i) { diff --git a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp index 057bcfc..4698239 100644 --- a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp +++ b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp @@ -20,1077 +20,36 @@ #include "config.h" #include "GraphicsLayerTextureMapper.h" -#include "CurrentTime.h" -#include "FloatRect.h" -#include "GraphicsContext.h" -#include "HashMap.h" -#include "Image.h" -#include "RefCounted.h" -#include "TextureMapper.h" -#include "TextureMapperPlatformLayer.h" -#include "Timer.h" -#include "TransformOperations.h" -#include "TranslateTransformOperation.h" -#include "UnitBezier.h" - -#define DEBUG_TEXMAP_FPS 0 +#include "TextureMapperNode.h" namespace WebCore { -struct TexmapPaintOptions { - BitmapTexture* surface; - TextureMapper* textureMapper; - GraphicsContext* context; - TextureMapperNode* rootLayer; - float opacity; - IntRect scissorRect; - IntRect visibleRect; - bool isSurface; -}; -class TextureMapperCache { -public: - void mark(BitmapTexture* texture); - - class Entry { - public: - RefPtr<BitmapTexture> texture; - Entry() : previousCost(0) { } - inline int calculateCost() const - { - if (!texture || !texture->isValid()) - return 0; - const IntSize textureSize = texture->size(); - // an image's cost in bytes is width * height * bytes per pixel (4). - return textureSize.width() * textureSize.height() * 4; - } - Entry(BitmapTexture* newTexture) - : texture(newTexture) - { - } - bool operator==(const Entry& other) const { return texture == other.texture; } - int previousCost; - }; - - TextureMapperCache() : m_totalCost(0) {} - - void purge(); - Vector<Entry> m_data; - int m_totalCost; -#ifndef TEXMAP_TEXTURE_CACHE_KBS -#define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024 -#endif - static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024; - static const int PurgeAmount = MaxCost / 4; -}; - - -void TextureMapperCache::purge() -{ - // If this is in the GL implementation, we need an active GL context, because we might call glDeleteTextures. - const int size = m_data.size(); - - if (m_totalCost <= TextureMapperCache::MaxCost) - return; - - // Ensure that we have the right count. It might be inaccurate if content changed size. - // We only do this when we're actually ready to purge. - m_totalCost = 0; - for (int i = 0; i < size; ++i) - m_totalCost += m_data[i].calculateCost(); - - for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) { - Entry& entry = m_data[i]; - if (entry.texture->isLocked() || !entry.texture->isValid()) - continue; - m_totalCost -= entry.previousCost; - entry.texture->destroy(); - m_data.remove(i); - } -} - -void TextureMapperCache::mark(BitmapTexture* texture) -{ - if (!texture || !texture->isValid()) - return; - - Entry entry(texture); - size_t index = m_data.find(entry); - if (!index) - return; - - if (index < m_data.size()) - m_data.remove(index); - const int cost = entry.calculateCost(); - m_totalCost -= entry.previousCost; - m_totalCost += (entry.previousCost = cost); - m_data.prepend(entry); -} - -TextureMapperCache gTextureMapperCache; - -class TextureMapperCacheLock { -public: - TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture) - { - if (m_texture) - m_texture->lock(); - } - ~TextureMapperCacheLock() - { - if (m_texture) - m_texture->unlock(); - } - -private: - RefPtr<BitmapTexture> m_texture; -}; - -class TextureMapperNode : public TextureMapperContentLayer { - -public: - // This set of flags help us defer which properties of the layer have been - // modified by the compositor, so we can know what to look for in the next flush. - enum ChangeMask { - NoChanges = 0, - - ParentChange = (1L << 0), - ChildrenChange = (1L << 1), - MaskLayerChange = (1L << 2), - PositionChange = (1L << 3), - - AnchorPointChange = (1L << 4), - SizeChange = (1L << 5), - TransformChange = (1L << 6), - ContentChange = (1L << 7), - - ContentsOrientationChange = (1L << 9), - OpacityChange = (1L << 10), - ContentsRectChange = (1L << 11), - - Preserves3DChange = (1L << 12), - MasksToBoundsChange = (1L << 13), - DrawsContentChange = (1L << 14), - ContentsOpaqueChange = (1L << 15), - - BackfaceVisibilityChange = (1L << 16), - ChildrenTransformChange = (1L << 17), - DisplayChange = (1L << 18), - BackgroundColorChange = (1L << 19), - - ReplicaLayerChange = (1L << 20) - }; - - // The compositor lets us special-case images and colors, so we try to do so. - enum StaticContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType}; - - TextureMapperNode* rootLayer(); - - TextureMapperNode(GraphicsLayerTextureMapper* newLayer); - virtual ~TextureMapperNode(); - - void clearDirectImage(); - void computeTransformations(); - IntSize nearestSurfaceSize() const; - void computeReplicaTransform(); - void computeLayerType(); - void computeLocalTransform(); - void flattenTo2DSpaceIfNecessary(); - void initializeTextureMapper(TextureMapper*); - void invalidateTransform(); - void notifyChange(ChangeMask); - void syncCompositingState(bool recurse); - void performPostSyncOperations(); - void setNeedsDisplay(); - void setNeedsDisplayInRect(IntRect); - virtual void cleanupTextureMapper(); - - void paintRecursive(TexmapPaintOptions options); - void paintSelf(const TexmapPaintOptions& options); - void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect); - - int countDescendantsWithContent() const; - bool hasSurfaceDescendants() const; - - IntSize size() const { return m_size; } - - virtual void setPlatformLayerClient(TextureMapperLayerClient*); - virtual void paint(GraphicsContext*, const IntSize&, const IntRect& targetRect, const IntRect& exposedRect, const TransformationMatrix& transform, float opacity); - - static TextureMapperNode* toTextureMapperNode(GraphicsLayer*); -public: - GraphicsLayerTextureMapper* m_layer; - const char* m_lastTextureMapperType; - RefPtr<TextureMapper> m_lastTextureMapper; - struct TransformData { - TransformationMatrix base, target, replica, forDescendants, perspective, local; - IntRect targetBoundingRect; - float centerZ; - bool dirty, localDirty, perspectiveDirty; - IntRect boundingRectFromRoot; - TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { } - }; - - TransformData m_transforms; - - enum LayerType { - DefaultLayer, - RootLayer, - ScissorLayer, - ClipLayer, - TransparencyLayer - }; - - LayerType m_layerType; - - struct ContentData { - IntRect needsDisplayRect; - bool needsDisplay; - Color backgroundColor; - - StaticContentType contentType; - RefPtr<Image> image; - TextureMapperVideoLayer* media; - - ContentData() - : needsDisplay(false) - , contentType(HTMLContentType) - , image(0) - , media(0) - { - } - - }; - - inline IntRect targetRect() const - { - return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect; - } - - inline IntRect entireRect() const - { - return IntRect(0, 0, m_size.width(), m_size.height()); - } - - inline IntRect replicaRect() const - { - return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect(); - } - - RefPtr<BitmapTexture> m_texture; - RefPtr<BitmapTexture> m_surface, m_replicaSurface; - - ContentData m_pendingContent; - ContentData m_currentContent; - - Vector<TextureMapperNode*> m_children; - TextureMapperNode* m_parent; - TextureMapperNode* m_effectTarget; - int m_changeMask; - IntSize m_size, m_nearestSurfaceSize; - String m_name; - TextureMapperLayerClient* m_platformClient; - - struct State { - FloatPoint pos; - FloatPoint3D anchorPoint; - FloatSize size; - TransformationMatrix transform; - TransformationMatrix childrenTransform; - Color backgroundColor; - Color currentColor; - GraphicsLayer::CompositingCoordinatesOrientation geoOrientation; - GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation; - float opacity; - IntRect contentsRect; - int descendantsWithContent; - TextureMapperNode* maskLayer; - TextureMapperNode* replicaLayer; - bool preserves3D; - bool masksToBounds; - bool drawsContent; - bool contentsOpaque; - bool backfaceVisibility; - bool visible; - bool dirty; - bool tiled; - bool hasSurfaceDescendants; - - State() - : opacity(1.f) - , descendantsWithContent(0) - , maskLayer(0) - , replicaLayer(0) - , preserves3D(false) - , masksToBounds(false) - , drawsContent(false) - , contentsOpaque(false) - , backfaceVisibility(false) - , visible(true) - , dirty(true) - , tiled(false) - , hasSurfaceDescendants(false) - { - } - }; - State m_state; -}; - -void TextureMapperNode::setNeedsDisplayInRect(IntRect rect) -{ - if (m_platformClient) { - if (m_state.hasSurfaceDescendants) { - m_platformClient->setNeedsDisplay(); - return; - } - rect.intersect(IntRect(0, 0, m_size.width(), m_size.height())); - if (rect.isEmpty()) - return; - m_platformClient->setNeedsDisplayInRect(rect); - return; - } - - if (!m_parent) - return; - - m_parent->setNeedsDisplayInRect(rect); -} - -void TextureMapperNode::setNeedsDisplay() -{ - if (m_effectTarget) - m_effectTarget->setNeedsDisplay(); - if (m_transforms.targetBoundingRect.isEmpty()) - return; - if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) - setNeedsDisplayInRect(m_transforms.targetBoundingRect); -} - - -void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client) -{ - m_platformClient = client; -} - -static int compareGraphicsLayersZValue(const void* a, const void* b) -{ - typedef const TextureMapperNode* NodePtr; - const NodePtr* nodeA = static_cast<const NodePtr*>(a); - const NodePtr* nodeB = static_cast<const NodePtr*>(b); - return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000); -} -inline static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last) -{ - qsort(array.data(), array.size(), sizeof(TextureMapperNode*), compareGraphicsLayersZValue); -} - -bool TextureMapperNode::hasSurfaceDescendants() const -{ - if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer) - return true; - const int size = m_children.size(); - for (int i = 0; i < size; ++i) { - if (TextureMapperNode* child = m_children[i]) { - if (child->hasSurfaceDescendants()) - return true; - } - } - return false; - -} - -void TextureMapperNode::paint(GraphicsContext* context, const IntSize& size, const IntRect& targetRect, const IntRect& exposedRect, const TransformationMatrix& transform, float opacity) -{ - ASSERT(m_layerType == RootLayer); - if (m_size.isEmpty()) - return; - -#if 0 - WTF::StopWatch stopWatch; - ("[TextureMapper] RootPaint!!\n"); -#endif - - RefPtr<TextureMapper> textureMapper = TextureMapper::create(context); - - if (textureMapper->type() != m_lastTextureMapperType) - gTextureMapperCache.m_data.clear(); - - m_lastTextureMapper = textureMapper; - TexmapPaintOptions opt; - opt.opacity = 1; - opt.rootLayer = this; - opt.scissorRect = targetRect; - opt.visibleRect = exposedRect; - opt.textureMapper = textureMapper.get(); - opt.context = textureMapper->graphicsContext(); - opt.surface = 0; - paintRecursive(opt); - - if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) { - textureMapper->bindSurface(0); - textureMapper->paintToTarget(*m_surface.get(), size, transform, opacity * m_state.opacity, targetRect); - } - gTextureMapperCache.purge(); -} - -int TextureMapperNode::countDescendantsWithContent() const -{ - if (!m_state.visible || m_state.opacity < 0.001) - return 0; - int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0; - - const int size = m_children.size(); - for (int i = 0; i < size; ++i) { - if (TextureMapperNode* child = m_children[i]) - descendantsWithContent += child->countDescendantsWithContent(); - } - - return descendantsWithContent; -} - -inline TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer) -{ - return layer ? static_cast<GraphicsLayerTextureMapper*>(layer)->m_node.get() : 0; -} - -void TextureMapperNode::computeLayerType() -{ - // calculate layer type. A layer can be one of the following: - // RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport. - // only one layer is the root layer. - // ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children. - // A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip. - // ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity. - // A clip layer is a layer that masks to bounds, doesn't preserve 3D, has children, and has a transparency/mask or a non-rectangular transform. - // TransparencyLayer: creates a new framebuffer idetical in size to the current framebuffer. Then draws the fb's texture to the current framebuffer with identity transform. - // Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds. - // DefaultLayer: draws itself and its children directly to the current framebuffer. - // any layer that doesn't conform to the other rules is a DefaultLayer. - - const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType); - const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0); - const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer; - const bool hasReplica = m_state.replicaLayer; - m_layerType = DefaultLayer; - - // Layer has no parent, it must be a root layer. - if (!m_parent && !m_effectTarget) { - m_layerType = RootLayer; - return; - } - - // A layer with no contents is always a default layer. - if (!m_state.descendantsWithContent) - return; - - // A layer with content-descendants and a mask is always a clip layer. - if (hasDescendantsWithContent && m_state.maskLayer) { - m_layerType = ClipLayer; - return; - } - - // A masks-to bounds layer can be a clip or a scissor layer. It's a scissor layer only if it has a trivial clip (identity or translation), or if it has transparency. - // That's because a ClipLayer would create an intermediate drawing surface (FB) - we want to limit it to when it's actually necessary, i.e. transparency or non-trivial clip. - if (m_state.masksToBounds && hasDescendantsWithContent) { - if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D) - m_layerType = ClipLayer; - else - m_layerType = ScissorLayer; - return; - } - - // We use a transparency layer when we have two of the following 3: replica, transparency, descendants with contents. - if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1)) - m_layerType = TransparencyLayer; -} -void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper) -{ - if (textureMapper->type() == m_lastTextureMapperType) - return; - m_surface = textureMapper->createTexture(); - m_replicaSurface = textureMapper->createTexture(); - m_texture = textureMapper->createTexture(); - gTextureMapperCache.mark(m_texture.get()); - m_lastTextureMapperType = textureMapper->type(); -} - -TextureMapperNode::TextureMapperNode(GraphicsLayerTextureMapper* newLayer) - : m_layer(newLayer) - , m_lastTextureMapperType(0) - , m_lastTextureMapper(0) - , m_layerType(DefaultLayer) - , m_surface(0) - , m_parent(0) - , m_effectTarget(0) - , m_changeMask(NoChanges) - , m_platformClient(0) -{ - -} - -TextureMapperNode* TextureMapperNode::rootLayer() -{ - if (m_effectTarget) - return m_effectTarget->rootLayer(); - if (m_parent) - return m_parent->rootLayer(); - return this; -} - -void TextureMapperNode::invalidateTransform() -{ - m_transforms.dirty = true; - if (m_layerType != ClipLayer) - m_state.dirty = true; - if (m_state.replicaLayer) - m_state.replicaLayer->invalidateTransform(); - const int size = m_children.size(); - for (int i = 0; i < size; ++i) { - if (TextureMapperNode* layer = m_children[i]) - layer->invalidateTransform(); - } -} - -void TextureMapperNode::computeLocalTransform() -{ - if (!m_transforms.localDirty) - return; - const float originX = m_state.anchorPoint.x() * m_size.width(); - const float originY = m_state.anchorPoint.y() * m_size.height(); - m_transforms.local = - TransformationMatrix() - .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z()) - .multLeft(m_state.transform) - .translate3d(-originX, -originY, -m_state.anchorPoint.z()); - m_transforms.localDirty = false; -} - -void TextureMapperNode::flattenTo2DSpaceIfNecessary() -{ - if (m_state.preserves3D) - return; - m_transforms.forDescendants.setM13(0); - m_transforms.forDescendants.setM23(0); - m_transforms.forDescendants.setM31(0); - m_transforms.forDescendants.setM32(0); - m_transforms.forDescendants.setM33(1); - m_transforms.forDescendants.setM34(0); - m_transforms.forDescendants.setM43(0); -} - -IntSize TextureMapperNode::nearestSurfaceSize() const -{ - if (m_layerType == ClipLayer || m_layerType == RootLayer) - return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size; - return m_parent->nearestSurfaceSize(); -} - -void TextureMapperNode::computeReplicaTransform() -{ - if (!m_state.replicaLayer) - return; - - m_nearestSurfaceSize = nearestSurfaceSize(); - - if (m_layerType != TransparencyLayer) { - m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local); - return; - } - - const float originX = m_transforms.target.m41(); - const float originY = m_transforms.target.m42(); - m_transforms.replica = - TransformationMatrix() - .translate(originX, originY) - .multLeft(m_state.replicaLayer->m_transforms.local) - .translate(-originX, -originY); -} - -void TextureMapperNode::computeTransformations() -{ - if (!m_transforms.dirty) - return; - - m_transforms.dirty = false; - if ((m_size.isEmpty() && m_state.masksToBounds)) - return; - - TextureMapperNode* parent = m_parent; - computeLocalTransform(); - - m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local); - m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target); - - if (m_effectTarget) - return; - - m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect())); - if (m_state.replicaLayer) - m_state.replicaLayer->computeTransformations(); - - flattenTo2DSpaceIfNecessary(); - - if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) { - m_state.visible = false; - return; - } - m_state.visible = true; - - if (parent && parent->m_state.preserves3D) - m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z(); - - if (!m_children.size()) - return; - - if (m_state.childrenTransform.isIdentity()) - return; - - const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2); - if (m_transforms.perspectiveDirty) - m_transforms.perspective = TransformationMatrix() - .translate(centerPoint.x(), centerPoint.y()) - .multLeft(m_state.childrenTransform) - .translate(-centerPoint.x(), -centerPoint.y()); - m_transforms.perspectiveDirty = false; - m_transforms.forDescendants.multLeft(m_transforms.perspective); -} - -void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect) -{ - if (m_size.isEmpty() || !m_layer) { - m_texture->destroy(); - return; - } - - if (m_currentContent.contentType == DirectImageContentType) { - if (m_currentContent.image) - m_texture->setContentsToImage(m_currentContent.image.get()); - return; - } - - if (m_currentContent.contentType == MediaContentType) { - if (!m_currentContent.media) - return; - m_texture->reset(m_size, true); - PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia(); - GraphicsContext context(platformContext); - m_currentContent.media->paint(&context); - m_texture->endPaint(); - return; - } - - const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid(); - if ((m_currentContent.contentType != HTMLContentType) - || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset)) - return; - - IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height()); - if (!needsReset && !m_currentContent.needsDisplay) - dirtyRect.intersect(m_currentContent.needsDisplayRect); - if (needsReset) - m_texture->reset(m_size, m_state.contentsOpaque); - m_pendingContent.needsDisplayRect = IntRect(); - - { - GraphicsContext context(m_texture->beginPaint(dirtyRect)); - if (textureMapper && textureMapper->graphicsContext()) { - GraphicsContext* originalContext = textureMapper->graphicsContext(); - context.setImageInterpolationQuality(originalContext->imageInterpolationQuality()); - context.setTextDrawingMode(originalContext->textDrawingMode()); - } - m_layer->paintGraphicsLayerContents(context, dirtyRect); - } - m_texture->endPaint(); - m_currentContent.needsDisplay = false; - -} - -void TextureMapperNode::paintSelf(const TexmapPaintOptions& options) -{ - if (!m_layer || m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType)) - return; - - RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0; - RefPtr<BitmapTexture> replicaMaskTexture = 0; - if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer) - replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture; - - const float opacity = options.isSurface ? 1 : options.opacity; - - uploadTextureFromContent(options.textureMapper, options.visibleRect); - if (m_state.replicaLayer && !options.isSurface) - options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica, - opacity * m_state.replicaLayer->m_state.opacity, - replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get()); - - const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect(); - const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target; - options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get()); -} - -void TextureMapperNode::paintRecursive(TexmapPaintOptions options) -{ - bool isDirty = m_state.dirty; - m_state.dirty = false; - - if ((m_size.isEmpty() && (m_state.masksToBounds - || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01) - return; - - initializeTextureMapper(options.textureMapper); - computeReplicaTransform(); - - if (m_state.maskLayer) { - m_state.maskLayer->initializeTextureMapper(options.textureMapper); - m_state.maskLayer->m_state.dirty = false; - } - - if (m_state.replicaLayer) { - m_state.replicaLayer->initializeTextureMapper(options.textureMapper); - m_state.replicaLayer->m_state.dirty = false; - if (m_state.replicaLayer->m_state.maskLayer) { - m_state.replicaLayer->m_state.maskLayer->initializeTextureMapper(options.textureMapper); - m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false; - } - } - - TextureMapperNode* replica = m_state.replicaLayer; - const bool isSurface = (m_layerType == ClipLayer - || m_layerType == TransparencyLayer - || (m_layerType == RootLayer - && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) - )); - if (isSurface) - uploadTextureFromContent(options.textureMapper, options.visibleRect); - const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect; - - options.opacity *= m_state.opacity; - - TexmapPaintOptions optionsForDescendants(options); - optionsForDescendants.opacity = isSurface ? 1 : options.opacity; - options.isSurface = isSurface; - - if (m_layerType == ClipLayer) { - optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect); - optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height()); - } - - if (m_layerType == ScissorLayer) - optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect); - options.textureMapper->setClip(optionsForDescendants.scissorRect); - - TextureMapperCacheLock(m_texture.get()); - TextureMapperCacheLock(m_surface.get()); - TextureMapperCacheLock(m_replicaSurface.get()); - - gTextureMapperCache.purge(); - - if (isSurface) { - ASSERT(m_surface); - if (!m_surface->isValid()) - isDirty = true; - if (m_state.tiled) { - m_surface->reset(options.visibleRect.size()); - m_surface->setOffset(options.visibleRect.location()); - } else if (isDirty) - m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size); - gTextureMapperCache.mark(m_surface.get()); - options.textureMapper->bindSurface(m_surface.get()); - - optionsForDescendants.surface = m_surface.get(); - } else if (m_surface) - m_surface->destroy(); - - RefPtr<BitmapTexture> maskTexture; - RefPtr<BitmapTexture> replicaMaskTexture; - if (TextureMapperNode* mask = m_state.maskLayer) { - mask->uploadTextureFromContent(options.textureMapper, options.visibleRect); - maskTexture = mask->m_texture; - } - - if (replica && replica->m_state.maskLayer) { - replica->m_state.maskLayer->uploadTextureFromContent(options.textureMapper, options.visibleRect); - replicaMaskTexture = replica->m_state.maskLayer->m_texture; - } - - int childrenSize = m_children.size(); - if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid()) { - bool didPaintSelf = false; - if (!m_state.preserves3D || m_children.isEmpty()) { - paintSelf(options); - didPaintSelf = true; - } - - if (m_children.isEmpty() && !isSurface) - return; - - if (m_layerType == ScissorLayer) - optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height()))); - - for (int i = 0; i < childrenSize; ++i) { - TextureMapperNode* layer = m_children[i]; - if (!layer) - continue; - - if (!didPaintSelf && layer->m_transforms.centerZ >= 0) { - paintSelf(options); - didPaintSelf = true; - } - layer->paintRecursive(optionsForDescendants); - if (isSurface) { - ASSERT(m_surface); - gTextureMapperCache.mark(m_surface.get()); - options.textureMapper->bindSurface(m_surface.get()); - } - } - if (!didPaintSelf) { - paintSelf(options); - didPaintSelf = true; - } - } - - if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer) - return; - - ASSERT(m_surface); - BitmapTexture& texture = *m_surface.get(); - if (replica) { - ASSERT(m_replicaSurface); - m_replicaSurface->reset(options.surface->size()); - m_replicaSurface->setOffset(options.surface->offset()); - gTextureMapperCache.mark(m_replicaSurface.get()); - options.textureMapper->bindSurface(m_replicaSurface.get()); - options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get()); - options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get()); - options.textureMapper->bindSurface(options.surface); - gTextureMapperCache.mark(options.surface); - options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0); - return; - } - - options.textureMapper->bindSurface(options.surface); - options.textureMapper->drawTexture(texture, - m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) : - targetRect(), - m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target, - options.opacity, maskTexture.get()); - gTextureMapperCache.mark(&texture); -} - -void TextureMapperNode::cleanupTextureMapper() -{ - if (m_texture) - m_texture->destroy(); - if (m_surface) - m_surface->destroy(); - if (m_replicaSurface) - m_replicaSurface->destroy(); - for (int i = 0; i < m_children.size(); ++i) { - if (m_children[i]) - m_children[i]->cleanupTextureMapper(); - } - if (m_lastTextureMapper) - m_lastTextureMapper->cleanup(); -} - -TextureMapperNode::~TextureMapperNode() +GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client) + : GraphicsLayer(client) + , m_node(new TextureMapperNode()) + , m_changeMask(0) { - setNeedsDisplay(); - { - const int childrenSize = m_children.size(); - for (int i = childrenSize-1; i >= 0; --i) { - ASSERT(m_children[i]->m_parent == this); - m_children[i]->m_parent = 0; - } - } - if (m_parent) - m_parent->m_children.remove(m_parent->m_children.find(this)); } -void TextureMapperNode::notifyChange(ChangeMask changeMask) +void GraphicsLayerTextureMapper::notifyChange(TextureMapperNode::ChangeMask changeMask) { m_changeMask |= changeMask; - if (!m_layer->client()) + if (!client()) return; - m_layer->client()->notifySyncRequired(m_layer); -} - -void TextureMapperNode::performPostSyncOperations() -{ - const LayerType prevLayerType = m_layerType; - computeLayerType(); - if (prevLayerType != m_layerType) - m_state.dirty = true; - if (m_transforms.dirty) - setNeedsDisplay(); - - computeTransformations(); - if (m_state.maskLayer && !m_state.dirty) - m_state.dirty = m_state.maskLayer->m_state.dirty; - if (m_state.replicaLayer && !m_state.dirty) - m_state.dirty = m_state.replicaLayer->m_state.dirty; - - const int size = m_children.size(); - - for (int i = size - 1; i >= 0; --i) { - TextureMapperNode* layer = m_children[i]; - - layer->performPostSyncOperations(); - if (!m_state.dirty) - m_state.dirty = layer->m_state.dirty; - } - m_state.hasSurfaceDescendants = hasSurfaceDescendants(); - if (m_state.dirty) - m_state.descendantsWithContent = countDescendantsWithContent(); - - if (m_state.preserves3D) - sortByZOrder(m_children, 0, size); - if (m_state.dirty) - setNeedsDisplay(); + client()->notifySyncRequired(this); } -void TextureMapperNode::syncCompositingState(bool recurse) +void GraphicsLayerTextureMapper::didSynchronize() { - bool needsToInvalidateTransform = false; - - if (!m_layer) - return; - - if (m_changeMask == NoChanges) - goto afterCurrentLayerSync; - - setNeedsDisplay(); - if (m_parent) - m_parent->m_state.dirty = true; - - if (m_currentContent.contentType == HTMLContentType && (m_changeMask & ParentChange)) { - // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't - // try to snatch that ownership. - - if (!m_layer->parent()) - m_parent = 0; - else - m_parent = toTextureMapperNode(m_layer->parent()); - - if (!m_layer->parent() && m_parent) { - size_t index = m_parent->m_children.find(this); - m_parent->m_children.remove(index); - } - - } - - if (m_changeMask & ChildrenChange) { - m_children.clear(); - for (size_t i = 0; i < m_layer->children().size(); ++i) { - if (TextureMapperNode* child = toTextureMapperNode(m_layer->children()[i])) { - if (!child) - continue; - m_children.append(child); - child->m_parent = this; - } - } - m_state.dirty = true; - } - - if (m_changeMask & (SizeChange | ContentsRectChange)) { - IntSize wantedSize = IntSize(m_layer->size().width(), m_layer->size().height()); - if (wantedSize.isEmpty() && m_pendingContent.contentType == HTMLContentType) - wantedSize = IntSize(m_layer->contentsRect().width(), m_layer->contentsRect().height()); - - if (wantedSize != m_size) { - m_size = IntSize(wantedSize.width(), wantedSize.height()); - if (m_platformClient) - m_platformClient->setSizeChanged(m_size); - const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000; - if (m_state.tiled != needsTiling) - m_state.tiled = needsTiling; - m_state.dirty = true; - } - } - - if (m_changeMask & MaskLayerChange) { - if (TextureMapperNode* layer = toTextureMapperNode(m_layer->maskLayer())) - layer->m_effectTarget = this; - } - - if (m_changeMask & ReplicaLayerChange) { - if (TextureMapperNode* layer = toTextureMapperNode(m_layer->replicaLayer())) - layer->m_effectTarget = this; - } - - if (m_changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange)) - m_transforms.localDirty = true; - - if (m_changeMask & (ChildrenTransformChange | SizeChange)) - m_transforms.perspectiveDirty = true; - - if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange)) { - // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms, - // all these elements affect the transforms of all the descendants. - needsToInvalidateTransform = true; - } - - if (m_changeMask & DisplayChange) - m_state.dirty = true; - - m_state.maskLayer = toTextureMapperNode(m_layer->maskLayer()); - m_state.replicaLayer = toTextureMapperNode(m_layer->replicaLayer()); - m_state.pos = m_layer->position(); - m_state.anchorPoint = m_layer->anchorPoint(); - m_state.size = m_layer->size(); - m_state.transform = m_layer->transform(); - m_state.contentsRect = m_layer->contentsRect(); - m_state.opacity = m_layer->opacity(); - m_state.contentsRect = m_layer->contentsRect(); - m_state.preserves3D = m_layer->preserves3D(); - m_state.masksToBounds = m_layer->masksToBounds(); - m_state.drawsContent = m_layer->drawsContent(); - m_state.contentsOpaque = m_layer->contentsOpaque(); - m_state.backfaceVisibility = m_layer->backfaceVisibility(); - m_state.childrenTransform = m_layer->childrenTransform(); - m_currentContent.contentType = m_pendingContent.contentType; - m_currentContent.image = m_pendingContent.image; - m_currentContent.media = m_pendingContent.media; - m_currentContent.backgroundColor = m_pendingContent.backgroundColor; - m_currentContent.needsDisplay = m_currentContent.needsDisplay || m_pendingContent.needsDisplay; - m_currentContent.needsDisplayRect.unite(m_pendingContent.needsDisplayRect); + m_syncQueued = false; + m_changeMask = 0; m_pendingContent.needsDisplay = false; m_pendingContent.needsDisplayRect = IntRect(); - m_changeMask = NoChanges; - afterCurrentLayerSync: - if (needsToInvalidateTransform) - invalidateTransform(); - - if (m_state.maskLayer) { - m_state.maskLayer->syncCompositingState(false); - if (m_state.maskLayer->m_size.isEmpty()) - m_state.maskLayer->m_size = m_size; - } - - if (m_state.replicaLayer) - m_state.replicaLayer->syncCompositingState(false); - -#if 0 - if (m_state.dirty && m_texture && m_texture->allowOfflineTextureUpload()) - uploadTextureFromContent(0); -#endif - - if (!recurse) - return; - - const int childrenSize = m_children.size(); - for (int i = childrenSize-1; i >= 0; --i) - m_children[i]->syncCompositingState(true); -} - -GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client) - : GraphicsLayer(client) - , m_node(new TextureMapperNode(this)) -{ } void GraphicsLayerTextureMapper::setName(const String& name) { - m_node->m_name = name; + GraphicsLayer::setName(name); } GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper() @@ -1101,25 +60,25 @@ GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper() */ void GraphicsLayerTextureMapper::setNeedsDisplay() { - m_node->m_pendingContent.needsDisplay = true; - m_node->notifyChange(TextureMapperNode::DisplayChange); + m_pendingContent.needsDisplay = true; + notifyChange(TextureMapperNode::DisplayChange); } /* \reimp (GraphicsLayer.h) */ void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect) { - if (m_node->m_pendingContent.needsDisplay) + if (m_pendingContent.needsDisplay) return; - m_node->m_pendingContent.needsDisplayRect.unite(IntRect(rect)); - m_node->notifyChange(TextureMapperNode::DisplayChange); + m_pendingContent.needsDisplayRect.unite(IntRect(rect)); + notifyChange(TextureMapperNode::DisplayChange); } /* \reimp (GraphicsLayer.h) */ void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer) { - m_node->notifyChange(TextureMapperNode::ParentChange); + notifyChange(TextureMapperNode::ParentChange); GraphicsLayer::setParent(layer); } @@ -1127,7 +86,7 @@ void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer) */ bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children) { - m_node->notifyChange(TextureMapperNode::ChildrenChange); + notifyChange(TextureMapperNode::ChildrenChange); return GraphicsLayer::setChildren(children); } @@ -1135,7 +94,7 @@ bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& child */ void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer) { - m_node->notifyChange(TextureMapperNode::ChildrenChange); + notifyChange(TextureMapperNode::ChildrenChange); GraphicsLayer::addChild(layer); } @@ -1144,7 +103,7 @@ void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer) void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index) { GraphicsLayer::addChildAtIndex(layer, index); - m_node->notifyChange(TextureMapperNode::ChildrenChange); + notifyChange(TextureMapperNode::ChildrenChange); } /* \reimp (GraphicsLayer.h) @@ -1152,7 +111,7 @@ void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling) { GraphicsLayer::addChildAbove(layer, sibling); - m_node->notifyChange(TextureMapperNode::ChildrenChange); + notifyChange(TextureMapperNode::ChildrenChange); } /* \reimp (GraphicsLayer.h) @@ -1161,7 +120,7 @@ void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLay { GraphicsLayer::addChildBelow(layer, sibling); - m_node->notifyChange(TextureMapperNode::ChildrenChange); + notifyChange(TextureMapperNode::ChildrenChange); } /* \reimp (GraphicsLayer.h) @@ -1169,10 +128,9 @@ void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLay bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild) { if (GraphicsLayer::replaceChild(oldChild, newChild)) { - m_node->notifyChange(TextureMapperNode::ChildrenChange); + notifyChange(TextureMapperNode::ChildrenChange); return true; } - return false; } @@ -1182,7 +140,7 @@ void GraphicsLayerTextureMapper::removeFromParent() { if (!parent()) return; - m_node->notifyChange(TextureMapperNode::ParentChange); + notifyChange(TextureMapperNode::ParentChange); GraphicsLayer::removeFromParent(); } @@ -1193,7 +151,7 @@ void GraphicsLayerTextureMapper::setMaskLayer(GraphicsLayer* value) if (value == maskLayer()) return; GraphicsLayer::setMaskLayer(value); - m_node->notifyChange(TextureMapperNode::MaskLayerChange); + notifyChange(TextureMapperNode::MaskLayerChange); } @@ -1204,7 +162,7 @@ void GraphicsLayerTextureMapper::setReplicatedByLayer(GraphicsLayer* value) if (value == replicaLayer()) return; GraphicsLayer::setReplicatedByLayer(value); - m_node->notifyChange(TextureMapperNode::ReplicaLayerChange); + notifyChange(TextureMapperNode::ReplicaLayerChange); } /* \reimp (GraphicsLayer.h) @@ -1214,7 +172,7 @@ void GraphicsLayerTextureMapper::setPosition(const FloatPoint& value) if (value == position()) return; GraphicsLayer::setPosition(value); - m_node->notifyChange(TextureMapperNode::PositionChange); + notifyChange(TextureMapperNode::PositionChange); } /* \reimp (GraphicsLayer.h) @@ -1224,7 +182,7 @@ void GraphicsLayerTextureMapper::setAnchorPoint(const FloatPoint3D& value) if (value == anchorPoint()) return; GraphicsLayer::setAnchorPoint(value); - m_node->notifyChange(TextureMapperNode::AnchorPointChange); + notifyChange(TextureMapperNode::AnchorPointChange); } /* \reimp (GraphicsLayer.h) @@ -1235,7 +193,7 @@ void GraphicsLayerTextureMapper::setSize(const FloatSize& value) return; GraphicsLayer::setSize(value); - m_node->notifyChange(TextureMapperNode::SizeChange); + notifyChange(TextureMapperNode::SizeChange); } /* \reimp (GraphicsLayer.h) @@ -1246,7 +204,7 @@ void GraphicsLayerTextureMapper::setTransform(const TransformationMatrix& value) return; GraphicsLayer::setTransform(value); - m_node->notifyChange(TextureMapperNode::TransformChange); + notifyChange(TextureMapperNode::TransformChange); } /* \reimp (GraphicsLayer.h) @@ -1256,7 +214,7 @@ void GraphicsLayerTextureMapper::setChildrenTransform(const TransformationMatrix if (value == childrenTransform()) return; GraphicsLayer::setChildrenTransform(value); - m_node->notifyChange(TextureMapperNode::ChildrenTransformChange); + notifyChange(TextureMapperNode::ChildrenTransformChange); } /* \reimp (GraphicsLayer.h) @@ -1266,7 +224,7 @@ void GraphicsLayerTextureMapper::setPreserves3D(bool value) if (value == preserves3D()) return; GraphicsLayer::setPreserves3D(value); - m_node->notifyChange(TextureMapperNode::Preserves3DChange); + notifyChange(TextureMapperNode::Preserves3DChange); } /* \reimp (GraphicsLayer.h) @@ -1276,7 +234,7 @@ void GraphicsLayerTextureMapper::setMasksToBounds(bool value) if (value == masksToBounds()) return; GraphicsLayer::setMasksToBounds(value); - m_node->notifyChange(TextureMapperNode::MasksToBoundsChange); + notifyChange(TextureMapperNode::MasksToBoundsChange); } /* \reimp (GraphicsLayer.h) @@ -1285,7 +243,7 @@ void GraphicsLayerTextureMapper::setDrawsContent(bool value) { if (value == drawsContent()) return; - m_node->notifyChange(TextureMapperNode::DrawsContentChange); + notifyChange(TextureMapperNode::DrawsContentChange); GraphicsLayer::setDrawsContent(value); } @@ -1293,22 +251,22 @@ void GraphicsLayerTextureMapper::setDrawsContent(bool value) */ void GraphicsLayerTextureMapper::setBackgroundColor(const Color& value) { - if (value == m_node->m_pendingContent.backgroundColor) + if (value == m_pendingContent.backgroundColor) return; - m_node->m_pendingContent.backgroundColor = value; + m_pendingContent.backgroundColor = value; GraphicsLayer::setBackgroundColor(value); - m_node->notifyChange(TextureMapperNode::BackgroundColorChange); + notifyChange(TextureMapperNode::BackgroundColorChange); } /* \reimp (GraphicsLayer.h) */ void GraphicsLayerTextureMapper::clearBackgroundColor() { - if (!m_node->m_pendingContent.backgroundColor.isValid()) + if (!m_pendingContent.backgroundColor.isValid()) return; - m_node->m_pendingContent.backgroundColor = Color(); + m_pendingContent.backgroundColor = Color(); GraphicsLayer::clearBackgroundColor(); - m_node->notifyChange(TextureMapperNode::BackgroundColorChange); + notifyChange(TextureMapperNode::BackgroundColorChange); } /* \reimp (GraphicsLayer.h) @@ -1317,7 +275,7 @@ void GraphicsLayerTextureMapper::setContentsOpaque(bool value) { if (value == contentsOpaque()) return; - m_node->notifyChange(TextureMapperNode::ContentsOpaqueChange); + notifyChange(TextureMapperNode::ContentsOpaqueChange); GraphicsLayer::setContentsOpaque(value); } @@ -1328,7 +286,7 @@ void GraphicsLayerTextureMapper::setBackfaceVisibility(bool value) if (value == backfaceVisibility()) return; GraphicsLayer::setBackfaceVisibility(value); - m_node->notifyChange(TextureMapperNode::BackfaceVisibilityChange); + notifyChange(TextureMapperNode::BackfaceVisibilityChange); } /* \reimp (GraphicsLayer.h) @@ -1338,7 +296,7 @@ void GraphicsLayerTextureMapper::setOpacity(float value) if (value == opacity()) return; GraphicsLayer::setOpacity(value); - m_node->notifyChange(TextureMapperNode::OpacityChange); + notifyChange(TextureMapperNode::OpacityChange); } /* \reimp (GraphicsLayer.h) @@ -1348,16 +306,16 @@ void GraphicsLayerTextureMapper::setContentsRect(const IntRect& value) if (value == contentsRect()) return; GraphicsLayer::setContentsRect(value); - m_node->notifyChange(TextureMapperNode::ContentsRectChange); + notifyChange(TextureMapperNode::ContentsRectChange); } /* \reimp (GraphicsLayer.h) */ void GraphicsLayerTextureMapper::setContentsToImage(Image* image) { - m_node->notifyChange(TextureMapperNode::ContentChange); - m_node->m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType; - m_node->m_pendingContent.image = image; + notifyChange(TextureMapperNode::ContentChange); + m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType; + m_pendingContent.image = image; GraphicsLayer::setContentsToImage(image); } @@ -1365,9 +323,9 @@ void GraphicsLayerTextureMapper::setContentsToImage(Image* image) */ void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color) { - m_node->notifyChange(TextureMapperNode::ContentChange); - m_node->m_pendingContent.contentType = TextureMapperNode::ColorContentType; - m_node->m_pendingContent.backgroundColor = color; + notifyChange(TextureMapperNode::ContentChange); + m_pendingContent.contentType = TextureMapperNode::ColorContentType; + m_pendingContent.backgroundColor = color; GraphicsLayer::setContentsBackgroundColor(color); } @@ -1375,12 +333,12 @@ void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color) void GraphicsLayerTextureMapper::setContentsToMedia(PlatformLayer* media) { GraphicsLayer::setContentsToMedia(media); - m_node->notifyChange(TextureMapperNode::ContentChange); - m_node->m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType; + notifyChange(TextureMapperNode::ContentChange); + m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType; if (media) - m_node->m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media); + m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media); else - m_node->m_pendingContent.media = 0; + m_pendingContent.media = 0; } /* \reimp (GraphicsLayer.h) @@ -1389,7 +347,7 @@ void GraphicsLayerTextureMapper::setContentsOrientation(CompositingCoordinatesOr { if (contentsOrientation() == orientation) return; - m_node->notifyChange(TextureMapperNode::ContentsOrientationChange); + notifyChange(TextureMapperNode::ContentsOrientationChange); GraphicsLayer::setContentsOrientation(orientation); } @@ -1397,17 +355,14 @@ void GraphicsLayerTextureMapper::setContentsOrientation(CompositingCoordinatesOr */ void GraphicsLayerTextureMapper::syncCompositingStateForThisLayerOnly() { - m_node->syncCompositingState(false); - m_node->performPostSyncOperations(); + m_node->syncCompositingState(this, false); } /* \reimp (GraphicsLayer.h) */ void GraphicsLayerTextureMapper::syncCompositingState() { - GraphicsLayer::syncCompositingState(); - m_node->syncCompositingState(true); - m_node->performPostSyncOperations(); + m_node->syncCompositingState(this, true); } /* \reimp (GraphicsLayer.h) diff --git a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h index 36ebd74..85fa3ee 100644 --- a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h +++ b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h @@ -24,13 +24,12 @@ #include "GraphicsLayer.h" #include "GraphicsLayerClient.h" #include "Image.h" +#include "TextureMapperNode.h" #if ENABLE(3D_CANVAS) #include "GraphicsContext3D.h" #endif -#define ENABLE_TEXMAP_ANIMATION 0 - namespace WebCore { class TextureMapperNode; @@ -85,12 +84,24 @@ public: virtual NativeLayer nativeLayer() const; virtual PlatformLayer* platformLayer() const; - virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, - const String& /*keyframesName*/, double /*timeOffset*/) { return false; } + virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; } + + void notifyChange(TextureMapperNode::ChangeMask changeMask); + inline TextureMapperNode::ContentData& pendingContent() { return m_pendingContent; } + inline int changeMask() const { return m_changeMask; } + void didSynchronize(); private: OwnPtr<TextureMapperNode> m_node; + bool m_syncQueued; + int m_changeMask; + TextureMapperNode::ContentData m_pendingContent; }; +inline static GraphicsLayerTextureMapper* toGraphicsLayerTextureMapper(GraphicsLayer* layer) +{ + return static_cast<GraphicsLayerTextureMapper*>(layer); +} + } #endif // GraphicsLayerTextureMapper_h diff --git a/WebCore/platform/graphics/texmap/TextureMapper.h b/WebCore/platform/graphics/texmap/TextureMapper.h index 03c1c6d..250125b 100644 --- a/WebCore/platform/graphics/texmap/TextureMapper.h +++ b/WebCore/platform/graphics/texmap/TextureMapper.h @@ -57,6 +57,10 @@ public: m_contentSize = size; } + virtual void pack() { } + virtual void unpack() { } + virtual bool isPacked() const { return false; } + virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect) = 0; virtual void endPaint() = 0; virtual PlatformGraphicsContext* beginPaintMedia() @@ -72,6 +76,9 @@ public: inline IntSize contentSize() const { return m_contentSize; } inline void setOffset(const IntPoint& o) { m_offset = o; } inline IntPoint offset() const { return m_offset; } + +protected: + private: int m_lockCount; IntSize m_contentSize; @@ -81,11 +88,11 @@ private: // A "context" class used to encapsulate accelerated texture mapping functions: i.e. drawing a texture // onto the screen or into another texture with a specified transform, opacity and mask. -class TextureMapper : public RefCounted<TextureMapper> { +class TextureMapper { friend class BitmapTexture; public: - static PassRefPtr<TextureMapper> create(GraphicsContext*); + static PassOwnPtr<TextureMapper> create(GraphicsContext* graphicsContext = 0); virtual ~TextureMapper() { } virtual void drawTexture(const BitmapTexture& texture, const IntRect& target, const TransformationMatrix& matrix = TransformationMatrix(), float opacity = 1.0f, const BitmapTexture* maskTexture = 0) = 0; @@ -97,20 +104,28 @@ public: drawTexture(texture, IntRect(0, 0, texture.contentSize().width(), texture.contentSize().height()), matrix, opacity, 0); } + virtual void setGraphicsContext(GraphicsContext*) { } virtual void setClip(const IntRect&) = 0; virtual bool allowSurfaceForRoot() const = 0; virtual PassRefPtr<BitmapTexture> createTexture() = 0; - virtual const char* type() const = 0; - virtual void cleanup() {} - GraphicsContext* graphicsContext() const - { - return m_gc; - } + void setImageInterpolationQuality(InterpolationQuality quality) { m_interpolationQuality = quality; } + void setTextDrawingMode(int mode) { m_textDrawingMode = mode; } + + InterpolationQuality imageInterpolationQuality() const { return m_interpolationQuality; } + int textDrawingMode() const { return m_textDrawingMode; } + + void setViewportSize(const IntSize&); protected: - TextureMapper(GraphicsContext* gc) : m_gc(gc) {} - GraphicsContext* m_gc; + TextureMapper() + : m_interpolationQuality(InterpolationDefault) + , m_textDrawingMode(cTextFill) + {} + +private: + InterpolationQuality m_interpolationQuality; + int m_textDrawingMode; }; }; diff --git a/WebCore/platform/graphics/texmap/TextureMapperNode.cpp b/WebCore/platform/graphics/texmap/TextureMapperNode.cpp new file mode 100644 index 0000000..09051f9 --- /dev/null +++ b/WebCore/platform/graphics/texmap/TextureMapperNode.cpp @@ -0,0 +1,877 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "TextureMapperNode.h" + +#include "GraphicsLayerTextureMapper.h" + +namespace WebCore { + +class TextureMapperCache { +public: + void mark(BitmapTexture* texture); + + class Entry { + public: + RefPtr<BitmapTexture> texture; + Entry() : previousCost(0) { } + inline int computeCost() const + { + if (!texture || !texture->isValid() || texture->isPacked()) + return 0; + const IntSize textureSize = texture->size(); + // An image's cost in bytes is width * height * bytes per pixel (4). + return textureSize.width() * textureSize.height() * 4; + } + Entry(BitmapTexture* newTexture) + : texture(newTexture) + { + } + bool operator==(const Entry& other) const { return texture == other.texture; } + int previousCost; + }; + + TextureMapperCache() + : m_totalCost(0) + { + } + + void purge(); + Vector<Entry> m_data; + int m_totalCost; +#ifndef TEXMAP_TEXTURE_CACHE_KBS +#define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024 +#endif + static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024; + static const int PurgeAmount = MaxCost / 4; +}; + + +void TextureMapperCache::purge() +{ + const int size = m_data.size(); + + if (m_totalCost <= TextureMapperCache::MaxCost) + return; + + // Ensure that we have the right count. It might be inaccurate if content changed size. + // We only do this when we're actually ready to purge. + m_totalCost = 0; + for (int i = 0; i < size; ++i) + m_totalCost += m_data[i].computeCost(); + + for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) { + Entry& entry = m_data[i]; + if (entry.texture->isLocked() || !entry.texture->isValid() || entry.texture->isPacked()) + continue; + m_totalCost -= entry.previousCost; + entry.texture->pack(); + m_data.remove(i); + } +} + +void TextureMapperCache::mark(BitmapTexture* texture) +{ + if (!texture || !texture->isValid()) + return; + + Entry entry(texture); + size_t index = m_data.find(entry); + if (!index) + return; + + int previousCost = 0; + + if (index < m_data.size()) { + previousCost = m_data[index].previousCost; + m_data.remove(index); + } + const int cost = entry.computeCost(); + m_totalCost -= previousCost; + m_totalCost += (entry.previousCost = cost); + m_data.prepend(entry); +} + +class TextureMapperCacheLock { +public: + TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture) + { + if (m_texture) + m_texture->lock(); + } + ~TextureMapperCacheLock() + { + if (m_texture) + m_texture->unlock(); + } + +private: + RefPtr<BitmapTexture> m_texture; +}; + + +TextureMapperCache* TextureMapperNode::cache() +{ + TextureMapperNode* root = rootLayer(); + if (!root) + return 0; + if (!root->m_cache) + root->m_cache = new TextureMapperCache; + return root->m_cache; +} + +void TextureMapperNode::setNeedsDisplayInRect(IntRect rect) +{ + if (m_platformClient) { + if (m_state.hasSurfaceDescendants) { + m_platformClient->setNeedsDisplay(); + return; + } + rect.intersect(IntRect(0, 0, m_size.width(), m_size.height())); + if (rect.isEmpty()) + return; + m_platformClient->setNeedsDisplayInRect(rect); + return; + } + + if (!m_parent) + return; + + m_parent->setNeedsDisplayInRect(rect); +} + +void TextureMapperNode::setNeedsDisplay() +{ + if (m_effectTarget) + m_effectTarget->setNeedsDisplay(); + if (m_transforms.targetBoundingRect.isEmpty()) + return; + if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) + setNeedsDisplayInRect(m_transforms.targetBoundingRect); +} + +void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client) +{ + m_platformClient = client; +} + +int TextureMapperNode::compareGraphicsLayersZValue(const void* a, const void* b) +{ + typedef const TextureMapperNode* NodePtr; + const NodePtr* nodeA = static_cast<const NodePtr*>(a); + const NodePtr* nodeB = static_cast<const NodePtr*>(b); + return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000); +} + +void TextureMapperNode::sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last) +{ + qsort(array.data(), array.size(), sizeof(TextureMapperNode*), TextureMapperNode::compareGraphicsLayersZValue); +} + +bool TextureMapperNode::hasSurfaceDescendants() const +{ + if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer) + return true; + + const int size = m_children.size(); + for (int i = 0; i < size; ++i) { + if (TextureMapperNode* child = m_children[i]) { + if (child->hasSurfaceDescendants()) + return true; + } + } + return false; +} + +int TextureMapperNode::countDescendantsWithContent() const +{ + if (!m_state.visible || m_state.opacity < 0.001) + return 0; + + int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0; + + const int size = m_children.size(); + for (int i = 0; i < size; ++i) { + if (TextureMapperNode* child = m_children[i]) + descendantsWithContent += child->countDescendantsWithContent(); + } + + return descendantsWithContent; +} + +TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer) +{ + return layer ? static_cast<TextureMapperNode*>(layer->platformLayer()) : 0; +} + +void TextureMapperNode::computeLayerType() +{ + const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType); + const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0); + const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer; + const bool hasReplica = m_state.replicaLayer; + + // DefaultLayer: draws itself and its children directly to the current framebuffer. + // any layer that doesn't conform to the other rules is a DefaultLayer. + m_layerType = DefaultLayer; + + // RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport. + // only one layer is the root layer. + if (!m_parent && !m_effectTarget) { + m_layerType = RootLayer; + return; + } + + // A layer with no contents is always a default layer. + if (!m_state.descendantsWithContent) + return; + + // ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity. + // A clip layer is a layer that masks to bounds, doesn't preserve 3D, has children, and has a transparency/mask or a non-rectangular transform. + if (hasDescendantsWithContent && m_state.maskLayer) { + m_layerType = ClipLayer; + return; + } + + // ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children. + // A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip. + if (m_state.masksToBounds && hasDescendantsWithContent) { + if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D) + m_layerType = ClipLayer; + else + m_layerType = ScissorLayer; + return; + } + + // TransparencyLayer: creates a new framebuffer idetical in size to the current framebuffer. Then draws the fb's texture to the current framebuffer with identity transform. + // Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds. + if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1)) + m_layerType = TransparencyLayer; +} + +void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper) +{ + if (m_texture) + return; + m_surface = textureMapper->createTexture(); + m_replicaSurface = textureMapper->createTexture(); + m_texture = textureMapper->createTexture(); + cache()->mark(m_texture.get()); +} + +TextureMapperNode::TextureMapperNode() + : m_layerType(DefaultLayer) + , m_surface(0) + , m_parent(0) + , m_effectTarget(0) + , m_platformClient(0) + , m_cache(0) +{ +} + +TextureMapperNode* TextureMapperNode::rootLayer() +{ + if (m_effectTarget) + return m_effectTarget->rootLayer(); + if (m_parent) + return m_parent->rootLayer(); + return this; +} + +void TextureMapperNode::invalidateTransform() +{ + m_transforms.dirty = true; + if (m_layerType != ClipLayer) + m_state.dirty = true; + if (m_state.replicaLayer) + m_state.replicaLayer->invalidateTransform(); + const int size = m_children.size(); + for (int i = 0; i < size; ++i) { + if (TextureMapperNode* layer = m_children[i]) + layer->invalidateTransform(); + } +} + +void TextureMapperNode::computeLocalTransform() +{ + if (!m_transforms.localDirty) + return; + const float originX = m_state.anchorPoint.x() * m_size.width(); + const float originY = m_state.anchorPoint.y() * m_size.height(); + m_transforms.local = + TransformationMatrix() + .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z()) + .multLeft(m_state.transform) + .translate3d(-originX, -originY, -m_state.anchorPoint.z()); + m_transforms.localDirty = false; +} + +void TextureMapperNode::flattenTo2DSpaceIfNecessary() +{ + if (m_state.preserves3D) + return; + + m_transforms.forDescendants.setM13(0); + m_transforms.forDescendants.setM23(0); + m_transforms.forDescendants.setM31(0); + m_transforms.forDescendants.setM32(0); + m_transforms.forDescendants.setM33(1); + m_transforms.forDescendants.setM34(0); + m_transforms.forDescendants.setM43(0); +} + +IntSize TextureMapperNode::nearestSurfaceSize() const +{ + if (m_layerType == ClipLayer || m_layerType == RootLayer) + return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size; + return m_parent->nearestSurfaceSize(); +} + +void TextureMapperNode::computeReplicaTransform() +{ + if (!m_state.replicaLayer) + return; + + m_nearestSurfaceSize = nearestSurfaceSize(); + + if (m_layerType != TransparencyLayer) { + m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local); + return; + } + + const float originX = m_transforms.target.m41(); + const float originY = m_transforms.target.m42(); + m_transforms.replica = + TransformationMatrix() + .translate(originX, originY) + .multLeft(m_state.replicaLayer->m_transforms.local) + .translate(-originX, -originY); +} + +void TextureMapperNode::computeTransformations() +{ + if (!m_transforms.dirty) + return; + + m_transforms.dirty = false; + if ((m_size.isEmpty() && m_state.masksToBounds)) + return; + + TextureMapperNode* parent = m_parent; + computeLocalTransform(); + + m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local); + m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target); + + if (m_effectTarget) + return; + + m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect())); + if (m_state.replicaLayer) + m_state.replicaLayer->computeTransformations(); + + flattenTo2DSpaceIfNecessary(); + + if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) { + m_state.visible = false; + return; + } + m_state.visible = true; + + if (parent && parent->m_state.preserves3D) + m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z(); + + if (!m_children.size()) + return; + + if (m_state.childrenTransform.isIdentity()) + return; + + const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2); + if (m_transforms.perspectiveDirty) + m_transforms.perspective = TransformationMatrix() + .translate(centerPoint.x(), centerPoint.y()) + .multLeft(m_state.childrenTransform) + .translate(-centerPoint.x(), -centerPoint.y()); + m_transforms.perspectiveDirty = false; + m_transforms.forDescendants.multLeft(m_transforms.perspective); +} + +void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer) +{ + if (m_size.isEmpty() || !layer) { + m_texture->destroy(); + return; + } + + if (m_currentContent.contentType == DirectImageContentType) { + if (m_currentContent.image) + m_texture->setContentsToImage(m_currentContent.image.get()); + return; + } + + if (m_currentContent.contentType == MediaContentType) { + if (!m_currentContent.media) + return; + m_texture->reset(m_size, true); + PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia(); + GraphicsContext context(platformContext); + m_currentContent.media->paint(&context); + m_texture->endPaint(); + return; + } + + const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid(); + if ((m_currentContent.contentType != HTMLContentType) + || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset)) + return; + + IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height()); + if (!needsReset && !m_currentContent.needsDisplay) + dirtyRect.intersect(m_currentContent.needsDisplayRect); + + if (needsReset) + m_texture->reset(m_size, m_state.contentsOpaque); + + { + GraphicsContext context(m_texture->beginPaint(dirtyRect)); + if (textureMapper) { + context.setImageInterpolationQuality(textureMapper->imageInterpolationQuality()); + context.setTextDrawingMode(textureMapper->textDrawingMode()); + } + layer->paintGraphicsLayerContents(context, dirtyRect); + } + m_texture->endPaint(); + m_currentContent.needsDisplay = false; +} + + +void TextureMapperNode::paint(TextureMapper* textureMapper, const TextureMapperContentLayer::PaintOptions& options) +{ + ASSERT(m_layerType == RootLayer); + if (m_size.isEmpty()) + return; + + TexmapPaintOptions opt; + opt.opacity = 1; + opt.rootLayer = this; + opt.scissorRect = options.targetRect; + opt.visibleRect = options.visibleRect; + opt.textureMapper = textureMapper; + opt.surface = 0; + opt.cache = m_cache; + paintRecursive(opt); + + if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) { + textureMapper->bindSurface(0); + textureMapper->paintToTarget(*m_surface.get(), options.viewportSize, options.transform, options.opacity * m_state.opacity, options.targetRect); + } + m_cache->purge(); +} + +void TextureMapperNode::paintSelf(const TexmapPaintOptions& options) +{ + if (m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType)) + return; + + RefPtr<BitmapTexture> replicaMaskTexture; + m_texture->unpack(); + + RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0; + if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer) + replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture; + + if (maskTexture) + maskTexture->unpack(); + + if (replicaMaskTexture) + replicaMaskTexture->unpack(); + + const float opacity = options.isSurface ? 1 : options.opacity; + + if (m_state.replicaLayer && !options.isSurface) + options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica, + opacity * m_state.replicaLayer->m_state.opacity, + replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get()); + + const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect(); + const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target; + options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get()); + options.cache->mark(m_texture.get()); +} + +bool TextureMapperNode::paintReplica(const TexmapPaintOptions& options) +{ + BitmapTexture& texture = *m_surface.get(); + TextureMapperNode* replica = m_state.replicaLayer; + RefPtr<BitmapTexture> maskTexture; + if (TextureMapperNode* mask = m_state.maskLayer) + maskTexture = mask->m_texture; + RefPtr<BitmapTexture> replicaMaskTexture; + if (!replica) + return false; + + if (replica && replica->m_state.maskLayer) + replicaMaskTexture = replica->m_state.maskLayer->m_texture; + + if (replicaMaskTexture) + replicaMaskTexture->unpack(); + ASSERT(m_replicaSurface); + m_replicaSurface->reset(options.surface->size()); + m_replicaSurface->setOffset(options.surface->offset()); + options.cache->mark(m_replicaSurface.get()); + options.textureMapper->bindSurface(m_replicaSurface.get()); + options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get()); + options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get()); + options.textureMapper->bindSurface(options.surface); + options.cache->mark(options.surface); + options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0); + return true; +} + +void TextureMapperNode::paintSurface(const TexmapPaintOptions& options) +{ + if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer) + return; + + RefPtr<BitmapTexture> maskTexture; + if (TextureMapperNode* mask = m_state.maskLayer) + maskTexture = mask->m_texture; + + ASSERT(m_surface); + BitmapTexture& texture = *m_surface.get(); + if (maskTexture) + maskTexture->unpack(); + texture.unpack(); + + if (paintReplica(options)) + return; + + options.textureMapper->bindSurface(options.surface); + options.textureMapper->drawTexture(texture, + m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) : + targetRect(), + m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target, + options.opacity, maskTexture.get()); + options.cache->mark(&texture); +} + +void TextureMapperNode::paintSelfAndChildren(const TexmapPaintOptions& options, TexmapPaintOptions& optionsForDescendants) +{ + bool didPaintSelf = false; + if (!m_state.preserves3D || m_children.isEmpty()) { + paintSelf(options); + didPaintSelf = true; + } + + if (m_children.isEmpty() && !options.isSurface) + return; + + if (m_layerType == ScissorLayer) + optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height()))); + + for (int i = 0; i < m_children.size(); ++i) { + TextureMapperNode* layer = m_children[i]; + if (!layer) + continue; + + if (!didPaintSelf && layer->m_transforms.centerZ >= 0) { + paintSelf(options); + didPaintSelf = true; + } + layer->paintRecursive(optionsForDescendants); + if (options.isSurface) { + ASSERT(m_surface); + options.cache->mark(m_surface.get()); + options.textureMapper->bindSurface(m_surface.get()); + } + } + if (!didPaintSelf) { + paintSelf(options); + didPaintSelf = true; + } +} + +void TextureMapperNode::paintRecursive(TexmapPaintOptions options) +{ + bool isDirty = m_state.dirty; + m_state.dirty = false; + + if ((m_size.isEmpty() && (m_state.masksToBounds + || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01) + return; + + computeReplicaTransform(); + + if (m_state.maskLayer) + m_state.maskLayer->m_state.dirty = false; + + if (m_state.replicaLayer) { + m_state.replicaLayer->m_state.dirty = false; + if (m_state.replicaLayer->m_state.maskLayer) + m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false; + } + + const bool isSurface = (m_layerType == ClipLayer + || m_layerType == TransparencyLayer + || (m_layerType == RootLayer + && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) + )); + + const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect; + + options.opacity *= m_state.opacity; + + TexmapPaintOptions optionsForDescendants(options); + optionsForDescendants.opacity = isSurface ? 1 : options.opacity; + options.isSurface = isSurface; + + if (m_layerType == ClipLayer) { + optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect); + optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height()); + } + + if (m_layerType == ScissorLayer) + optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect); + options.textureMapper->setClip(optionsForDescendants.scissorRect); + + TextureMapperCacheLock(m_texture.get()); + TextureMapperCacheLock(m_surface.get()); + TextureMapperCacheLock(m_replicaSurface.get()); + + options.cache->purge(); + + if (isSurface) { + ASSERT(m_surface); + if (!m_surface->isValid()) + isDirty = true; + if (m_state.tiled) { + m_surface->reset(options.visibleRect.size()); + m_surface->setOffset(options.visibleRect.location()); + } else if (isDirty) + m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size); + options.cache->mark(m_surface.get()); + options.textureMapper->bindSurface(m_surface.get()); + optionsForDescendants.surface = m_surface.get(); + } else if (m_surface) + m_surface->destroy(); + + if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid()) + paintSelfAndChildren(options, optionsForDescendants); + + paintSurface(options); +} + +TextureMapperNode::~TextureMapperNode() +{ + setNeedsDisplay(); + { + const int childrenSize = m_children.size(); + for (int i = childrenSize-1; i >= 0; --i) { + ASSERT(m_children[i]->m_parent == this); + m_children[i]->m_parent = 0; + } + } + if (m_parent) + m_parent->m_children.remove(m_parent->m_children.find(this)); + if (m_cache) + delete m_cache; +} + +void TextureMapperNode::performPostSyncOperations() +{ + const LayerType prevLayerType = m_layerType; + computeLayerType(); + if (prevLayerType != m_layerType) + m_state.dirty = true; + if (m_transforms.dirty) + setNeedsDisplay(); + + computeTransformations(); + if (m_state.maskLayer && !m_state.dirty) + m_state.dirty = m_state.maskLayer->m_state.dirty; + if (m_state.replicaLayer && !m_state.dirty) + m_state.dirty = m_state.replicaLayer->m_state.dirty; + + const int size = m_children.size(); + + for (int i = size - 1; i >= 0; --i) { + TextureMapperNode* layer = m_children[i]; + + layer->performPostSyncOperations(); + if (!m_state.dirty) + m_state.dirty = layer->m_state.dirty; + } + m_state.hasSurfaceDescendants = hasSurfaceDescendants(); + if (m_state.dirty) + m_state.descendantsWithContent = countDescendantsWithContent(); + + if (m_state.preserves3D) + sortByZOrder(m_children, 0, size); + if (m_state.dirty) + setNeedsDisplay(); +} + +void TextureMapperNode::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, bool recurse) +{ + TextureMapper* textureMapper = rootLayer()->m_platformClient->textureMapper(); + syncCompositingStateInternal(graphicsLayer, recurse, textureMapper); + performPostSyncOperations(); +} + +void TextureMapperNode::syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper) +{ + const int changeMask = graphicsLayer->changeMask(); + initializeTextureMapper(textureMapper); + const TextureMapperNode::ContentData& pendingContent = graphicsLayer->pendingContent(); + if (changeMask == NoChanges && pendingContent.needsDisplayRect.isEmpty() && !pendingContent.needsDisplay) + return; + + setNeedsDisplay(); + if (m_parent) + m_parent->m_state.dirty = true; + + if (m_currentContent.contentType == HTMLContentType && (changeMask & ParentChange)) { + // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't + // try to snatch that ownership. + + if (!graphicsLayer->parent()) + m_parent = 0; + else + m_parent = toTextureMapperNode(graphicsLayer->parent()); + + if (!graphicsLayer->parent() && m_parent) { + size_t index = m_parent->m_children.find(this); + m_parent->m_children.remove(index); + } + } + + if (changeMask & ChildrenChange) { + m_children.clear(); + for (size_t i = 0; i < graphicsLayer->children().size(); ++i) { + if (TextureMapperNode* child = toTextureMapperNode(graphicsLayer->children()[i])) { + if (!child) + continue; + m_children.append(child); + child->m_parent = this; + } + } + m_state.dirty = true; + } + + if (changeMask & (SizeChange | ContentsRectChange)) { + IntSize wantedSize = IntSize(graphicsLayer->size().width(), graphicsLayer->size().height()); + if (wantedSize.isEmpty() && pendingContent.contentType == HTMLContentType) + wantedSize = IntSize(graphicsLayer->contentsRect().width(), graphicsLayer->contentsRect().height()); + + if (wantedSize != m_size) { + m_size = IntSize(wantedSize.width(), wantedSize.height()); + if (m_platformClient) + m_platformClient->setSizeChanged(m_size); + const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000; + if (m_state.tiled != needsTiling) + m_state.tiled = needsTiling; + m_state.dirty = true; + } + } + + if (changeMask & MaskLayerChange) { + if (TextureMapperNode* layer = toTextureMapperNode(graphicsLayer->maskLayer())) + layer->m_effectTarget = this; + } + + if (changeMask & ReplicaLayerChange) { + if (TextureMapperNode* layer = toTextureMapperNode(graphicsLayer->replicaLayer())) + layer->m_effectTarget = this; + } + + if (changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange)) + m_transforms.localDirty = true; + + if (changeMask & (ChildrenTransformChange | SizeChange)) + m_transforms.perspectiveDirty = true; + + if (changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange)) { + // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms, + // all these elements affect the transforms of all the descendants. + invalidateTransform(); + } + + if (changeMask & DisplayChange) + m_state.dirty = true; + + m_state.maskLayer = toTextureMapperNode(graphicsLayer->maskLayer()); + m_state.replicaLayer = toTextureMapperNode(graphicsLayer->replicaLayer()); + m_state.pos = graphicsLayer->position(); + m_state.anchorPoint = graphicsLayer->anchorPoint(); + m_state.size = graphicsLayer->size(); + m_state.transform = graphicsLayer->transform(); + m_state.contentsRect = graphicsLayer->contentsRect(); + m_state.opacity = graphicsLayer->opacity(); + m_state.contentsRect = graphicsLayer->contentsRect(); + m_state.preserves3D = graphicsLayer->preserves3D(); + m_state.masksToBounds = graphicsLayer->masksToBounds(); + m_state.drawsContent = graphicsLayer->drawsContent(); + m_state.contentsOpaque = graphicsLayer->contentsOpaque(); + m_state.backfaceVisibility = graphicsLayer->backfaceVisibility(); + m_state.childrenTransform = graphicsLayer->childrenTransform(); + m_currentContent.contentType = pendingContent.contentType; + m_currentContent.image = pendingContent.image; + m_currentContent.media = pendingContent.media; + m_currentContent.backgroundColor = pendingContent.backgroundColor; + m_currentContent.needsDisplay = m_currentContent.needsDisplay || pendingContent.needsDisplay; + m_currentContent.needsDisplayRect.unite(pendingContent.needsDisplayRect); + +} + +void TextureMapperNode::syncCompositingStateInternal(GraphicsLayerTextureMapper* graphicsLayer, bool recurse, TextureMapper* textureMapper) +{ + syncCompositingStateSelf(graphicsLayer, textureMapper); + + graphicsLayer->didSynchronize(); + + if (m_state.maskLayer) { + m_state.maskLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), false, textureMapper); + if (m_state.maskLayer->m_size.isEmpty()) + m_state.maskLayer->m_size = m_size; + } + + if (m_state.replicaLayer) + m_state.replicaLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), false, textureMapper); + + if (m_state.dirty) + uploadTextureFromContent(textureMapper, m_state.visibleRect, graphicsLayer); + + m_currentContent.needsDisplayRect = IntRect(); + m_currentContent.needsDisplay = false; + + if (!recurse) + return; + + Vector<GraphicsLayer*> children = graphicsLayer->children(); + for (int i = children.size() - 1; i >= 0; --i) { + TextureMapperNode* node = toTextureMapperNode(children[i]); + if (!node) + continue; + node->syncCompositingStateInternal(toGraphicsLayerTextureMapper(children[i]), true, textureMapper); + } +} + +} diff --git a/WebCore/platform/graphics/texmap/TextureMapperNode.h b/WebCore/platform/graphics/texmap/TextureMapperNode.h new file mode 100644 index 0000000..9694043 --- /dev/null +++ b/WebCore/platform/graphics/texmap/TextureMapperNode.h @@ -0,0 +1,252 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef TextureMapperNode_h +#define TextureMapperNode_h + +#include "CurrentTime.h" +#include "FloatRect.h" +#include "GraphicsContext.h" +#include "GraphicsLayer.h" +#include "HashMap.h" +#include "Image.h" +#include "RefCounted.h" +#include "TextureMapper.h" +#include "TextureMapperPlatformLayer.h" +#include "Timer.h" +#include "TransformOperations.h" +#include "TranslateTransformOperation.h" +#include "UnitBezier.h" + +namespace WebCore { + +class TextureMapperNode; +class TextureMapperCache; +class GraphicsLayerTextureMapper; + +struct TexmapPaintOptions { + BitmapTexture* surface; + TextureMapper* textureMapper; + TextureMapperNode* rootLayer; + float opacity; + IntRect scissorRect; + IntRect visibleRect; + bool isSurface; + TextureMapperCache* cache; +}; + +class TextureMapperNode : public TextureMapperContentLayer { + +public: + // This set of flags help us defer which properties of the layer have been + // modified by the compositor, so we can know what to look for in the next flush. + enum ChangeMask { + NoChanges = 0, + + ParentChange = (1L << 0), + ChildrenChange = (1L << 1), + MaskLayerChange = (1L << 2), + PositionChange = (1L << 3), + + AnchorPointChange = (1L << 4), + SizeChange = (1L << 5), + TransformChange = (1L << 6), + ContentChange = (1L << 7), + + ContentsOrientationChange = (1L << 9), + OpacityChange = (1L << 10), + ContentsRectChange = (1L << 11), + + Preserves3DChange = (1L << 12), + MasksToBoundsChange = (1L << 13), + DrawsContentChange = (1L << 14), + ContentsOpaqueChange = (1L << 15), + + BackfaceVisibilityChange = (1L << 16), + ChildrenTransformChange = (1L << 17), + DisplayChange = (1L << 18), + BackgroundColorChange = (1L << 19), + + ReplicaLayerChange = (1L << 20) + }; + // The compositor lets us special-case images and colors, so we try to do so. + enum ContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType}; + struct ContentData { + IntRect needsDisplayRect; + bool needsDisplay; + Color backgroundColor; + + ContentType contentType; + RefPtr<Image> image; + TextureMapperVideoLayer* media; + + ContentData() + : needsDisplay(false) + , contentType(HTMLContentType) + , image(0) + , media(0) + { + } + }; + + + TextureMapperNode(); + virtual ~TextureMapperNode(); + + void syncCompositingState(GraphicsLayerTextureMapper*, bool recursive); + +protected: + // Reimps from TextureMapperContentLayer + virtual IntSize size() const { return m_size; } + virtual void setPlatformLayerClient(TextureMapperLayerClient*); + virtual void paint(TextureMapper*, const TextureMapperContentLayer::PaintOptions&); + +private: + TextureMapperNode* rootLayer(); + void clearDirectImage(); + void computeTransformations(); + IntSize nearestSurfaceSize() const; + void computeReplicaTransform(); + void computeLayerType(); + void computeLocalTransform(); + void flattenTo2DSpaceIfNecessary(); + void initializeTextureMapper(TextureMapper*); + void invalidateTransform(); + void notifyChange(ChangeMask); + void setNeedsDisplay(); + void setNeedsDisplayInRect(IntRect); + void performPostSyncOperations(); + void syncCompositingStateInternal(GraphicsLayerTextureMapper*, bool recursive, TextureMapper*); + void syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper); + TextureMapperCache* cache(); + + void paintRecursive(TexmapPaintOptions options); + bool paintReplica(const TexmapPaintOptions& options); + void paintSurface(const TexmapPaintOptions& options); + void paintSelf(const TexmapPaintOptions& options); + void paintSelfAndChildren(const TexmapPaintOptions& options, TexmapPaintOptions& optionsForDescendants); + void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer); + + int countDescendantsWithContent() const; + bool hasSurfaceDescendants() const; + + TextureMapper* textureMapper(); + + + static TextureMapperNode* toTextureMapperNode(GraphicsLayer*); + static int compareGraphicsLayersZValue(const void* a, const void* b); + static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last); + struct TransformData { + TransformationMatrix base, target, replica, forDescendants, perspective, local; + IntRect targetBoundingRect; + float centerZ; + bool dirty, localDirty, perspectiveDirty; + IntRect boundingRectFromRoot; + TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { } + }; + + TransformData m_transforms; + + enum LayerType { + DefaultLayer, + RootLayer, + ScissorLayer, + ClipLayer, + TransparencyLayer + }; + + LayerType m_layerType; + + inline IntRect targetRect() const + { + return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect; + } + + inline IntRect entireRect() const + { + return IntRect(0, 0, m_size.width(), m_size.height()); + } + + inline IntRect replicaRect() const + { + return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect(); + } + + RefPtr<BitmapTexture> m_texture; + RefPtr<BitmapTexture> m_surface, m_replicaSurface; + + ContentData m_currentContent; + + Vector<TextureMapperNode*> m_children; + TextureMapperNode* m_parent; + TextureMapperNode* m_effectTarget; + IntSize m_size, m_nearestSurfaceSize; + String m_name; + TextureMapperLayerClient* m_platformClient; + + struct State { + FloatPoint pos; + FloatPoint3D anchorPoint; + FloatSize size; + TransformationMatrix transform; + TransformationMatrix childrenTransform; + Color backgroundColor; + Color currentColor; + GraphicsLayer::CompositingCoordinatesOrientation geoOrientation; + GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation; + float opacity; + IntRect contentsRect; + int descendantsWithContent; + TextureMapperNode* maskLayer; + TextureMapperNode* replicaLayer; + bool preserves3D; + bool masksToBounds; + bool drawsContent; + bool contentsOpaque; + bool backfaceVisibility; + bool visible; + bool dirty; + bool tiled; + bool hasSurfaceDescendants; + IntRect visibleRect; + + State() + : opacity(1.f) + , descendantsWithContent(0) + , maskLayer(0) + , replicaLayer(0) + , preserves3D(false) + , masksToBounds(false) + , drawsContent(false) + , contentsOpaque(false) + , backfaceVisibility(false) + , visible(true) + , dirty(true) + , tiled(false) + , hasSurfaceDescendants(false) + { + } + }; + + State m_state; + TextureMapperCache* m_cache; +}; + +} +#endif // TextureMapperNode_h diff --git a/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h b/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h index 23e9fc9..2a38b90 100644 --- a/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h +++ b/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h @@ -25,6 +25,7 @@ namespace WebCore { class GraphicsContext; class IntRect; class IntSize; +class TextureMapper; class TransformationMatrix; @@ -35,6 +36,7 @@ public: virtual void setNeedsDisplay() = 0; virtual void setNeedsDisplayInRect(const IntRect& rect) = 0; virtual void setSizeChanged(const IntSize&) = 0; + virtual TextureMapper* textureMapper() = 0; }; class TextureMapperPlatformLayer { @@ -50,10 +52,17 @@ public: class TextureMapperContentLayer : public TextureMapperPlatformLayer { public: + struct PaintOptions { + IntRect visibleRect; + IntRect targetRect; + IntSize viewportSize; + TransformationMatrix transform; + float opacity; + }; + virtual void setPlatformLayerClient(TextureMapperLayerClient*) = 0; - virtual void paint(GraphicsContext*, const IntSize&, const IntRect& targetRect, const IntRect& exposedRect, const TransformationMatrix& transform, float opacity) {} + virtual void paint(TextureMapper*, const PaintOptions&) {} virtual IntSize size() const = 0; - virtual void cleanupTextureMapper() {} virtual Type layerType() const { return ContentLayer; } }; diff --git a/WebCore/platform/graphics/win/FontCacheWin.cpp b/WebCore/platform/graphics/win/FontCacheWin.cpp index 2240f80..e800245 100644 --- a/WebCore/platform/graphics/win/FontCacheWin.cpp +++ b/WebCore/platform/graphics/win/FontCacheWin.cpp @@ -330,7 +330,7 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& font AtomicString("Arial") }; SimpleFontData* simpleFont; - for (int i = 0; i < ARRAYSIZE(fallbackFonts); ++i) { + for (size_t i = 0; i < WTF_ARRAY_LENGTH(fallbackFonts); ++i) { if (simpleFont = getCachedFontData(fontDescription, fallbackFonts[i])) { fallbackFontName = fallbackFonts[i]; return simpleFont; diff --git a/WebCore/platform/graphics/win/IconWin.cpp b/WebCore/platform/graphics/win/IconWin.cpp index 05959e0..4d4d219 100644 --- a/WebCore/platform/graphics/win/IconWin.cpp +++ b/WebCore/platform/graphics/win/IconWin.cpp @@ -69,7 +69,7 @@ PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames) return 0; #else TCHAR buffer[MAX_PATH]; - UINT length = ::GetSystemDirectory(buffer, ARRAYSIZE(buffer)); + UINT length = ::GetSystemDirectory(buffer, WTF_ARRAY_LENGTH(buffer)); if (!length) return 0; diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp index 5544229..34a8817 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp @@ -1053,6 +1053,16 @@ void MediaPlayerPrivateQuickTimeVisualContext::setPreload(MediaPlayer::Preload p resumeLoad(); } +float MediaPlayerPrivateQuickTimeVisualContext::mediaTimeForTimeValue(float timeValue) const +{ + long timeScale; + if (m_readyState < MediaPlayer::HaveMetadata || !(timeScale = m_movie->timeScale())) + return timeValue; + + long mediaTimeValue = static_cast<long>(timeValue * timeScale); + return static_cast<float>(mediaTimeValue) / timeScale; +} + MediaPlayerPrivateQuickTimeVisualContext::MediaRenderingMode MediaPlayerPrivateQuickTimeVisualContext::currentRenderingMode() const { if (!m_movie) diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h index 109fd0b..43d5bd5 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h @@ -173,6 +173,8 @@ private: void retrieveAndResetMovieTransform(); + virtual float mediaTimeForTimeValue(float) const; + MediaPlayer* m_player; RefPtr<QTMovie> m_movie; #if USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/win/QTMovie.cpp b/WebCore/platform/graphics/win/QTMovie.cpp index 375d8c2..e425bf8 100644 --- a/WebCore/platform/graphics/win/QTMovie.cpp +++ b/WebCore/platform/graphics/win/QTMovie.cpp @@ -738,6 +738,14 @@ void QTMovie::setClosedCaptionsVisible(bool visible) QTSetTrackProperty(ccTrack, closedCaptionTrackType, closedCaptionDisplayPropertyID, sizeof(doDisplay), &doDisplay); } +long QTMovie::timeScale() const +{ + if (!m_private->m_movie) + return 0; + + return GetMovieTimeScale(m_private->m_movie); +} + static void initializeSupportedTypes() { if (gSupportedTypes) diff --git a/WebCore/platform/graphics/win/QTMovie.h b/WebCore/platform/graphics/win/QTMovie.h index e205b68..5e4c4e7 100644 --- a/WebCore/platform/graphics/win/QTMovie.h +++ b/WebCore/platform/graphics/win/QTMovie.h @@ -115,6 +115,8 @@ public: Movie getMovieHandle() const; + long timeScale() const; + private: QTMoviePrivate* m_private; friend class QTMoviePrivate; diff --git a/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp index a11b8d8..8af6ef7 100644 --- a/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp +++ b/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp @@ -194,11 +194,6 @@ public: restore(); } - IntPoint origin() const - { - return IntPoint(stableRound(-m_transform.e()), stableRound(-m_transform.f())); - } - void translate(float x, float y) { m_transform.translate(x, y); @@ -463,8 +458,7 @@ private: RefPtr<SharedBitmap> m_bitmap; RefPtr<SharedBitmap> m_rotatedBitmap; RECT m_bmpRect; - unsigned m_key1; - unsigned m_key2; + unsigned m_key; RotationTransform m_rotation; float m_oldOpacity; AlphaPaintType m_alphaPaintType; @@ -532,7 +526,7 @@ TransparentLayerDC::TransparentLayerDC(GraphicsContextPlatformPrivate* data, Int } else m_bitmap = m_data->getTransparentLayerBitmap(m_origRect, m_alphaPaintType, m_bmpRect, true, mustCreateLayer); if (m_bitmap) - m_memDc = m_bitmap->getDC(&m_key1, &m_key2); + m_memDc = m_bitmap->getDC(&m_key); else m_memDc = m_data->m_dc; } @@ -540,15 +534,15 @@ TransparentLayerDC::TransparentLayerDC(GraphicsContextPlatformPrivate* data, Int TransparentLayerDC::~TransparentLayerDC() { if (m_rotatedBitmap) { - m_bitmap->releaseDC(m_memDc, m_key1, m_key2); - m_key1 = m_key2 = 0; + m_bitmap->releaseDC(m_memDc, m_key); + m_key = 0; rotateBitmap(m_rotatedBitmap.get(), m_bitmap.get(), m_rotation); - m_memDc = m_rotatedBitmap->getDC(&m_key1, &m_key2); + m_memDc = m_rotatedBitmap->getDC(&m_key); m_data->paintBackTransparentLayerBitmap(m_memDc, m_rotatedBitmap.get(), m_rotatedOrigRect, m_alphaPaintType, m_bmpRect); - m_rotatedBitmap->releaseDC(m_memDc, m_key1, m_key2); + m_rotatedBitmap->releaseDC(m_memDc, m_key); } else if (m_bitmap) { m_data->paintBackTransparentLayerBitmap(m_memDc, m_bitmap.get(), m_origRect, m_alphaPaintType, m_bmpRect); - m_bitmap->releaseDC(m_memDc, m_key1, m_key2); + m_bitmap->releaseDC(m_memDc, m_key); } m_data->m_opacity = m_oldOpacity; } @@ -572,19 +566,18 @@ public: : m_data(data) { if (m_data->m_bitmap) - m_data->m_dc = m_data->m_bitmap->getDC(&m_key1, &m_key2); + m_data->m_dc = m_data->m_bitmap->getDC(&m_key); } ~ScopeDCProvider() { if (m_data->m_bitmap) { - m_data->m_bitmap->releaseDC(m_data->m_dc, m_key1, m_key2); + m_data->m_bitmap->releaseDC(m_data->m_dc, m_key); m_data->m_dc = 0; } } private: GraphicsContextPlatformPrivate* m_data; - unsigned m_key1; - unsigned m_key2; + unsigned m_key; }; @@ -1159,11 +1152,6 @@ void GraphicsContext::rotate(float radians) m_data->rotate(radians); } -IntPoint GraphicsContext::origin() -{ - return m_data->origin(); -} - void GraphicsContext::scale(const FloatSize& size) { m_data->scale(size); @@ -1219,11 +1207,6 @@ void GraphicsContext::clipOut(const Path&) notImplemented(); } -void GraphicsContext::clipOutEllipseInRect(const IntRect&) -{ - notImplemented(); -} - static inline IntPoint rectCenterPoint(const RECT& rect) { return IntPoint(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2); @@ -1539,6 +1522,12 @@ void GraphicsContext::clearPlatformShadow() notImplemented(); } +InterpolationQuality GraphicsContext::imageInterpolationQuality() const +{ + notImplemented(); + return InterpolationDefault; +} + void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) { notImplemented(); @@ -1576,11 +1565,11 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo gc.scale(FloatSize(m_data->m_transform.a(), m_data->m_transform.d())); font.drawText(&gc, run, IntPoint(0, font.ascent()), from, to); } - unsigned key1, key2; - HDC memDC = bmp->getDC(&key1, &key2); + unsigned key1; + HDC memDC = bmp->getDC(&key1); if (memDC) { m_data->paintBackTransparentLayerBitmap(memDC, bmp.get(), trRect, alphaPaintType, bmpRect); - bmp->releaseDC(memDC, key1, key2); + bmp->releaseDC(memDC, key1); } } diff --git a/WebCore/platform/graphics/wince/ImageWinCE.cpp b/WebCore/platform/graphics/wince/ImageWinCE.cpp index ec7403e..c0b2b53 100644 --- a/WebCore/platform/graphics/wince/ImageWinCE.cpp +++ b/WebCore/platform/graphics/wince/ImageWinCE.cpp @@ -43,7 +43,7 @@ namespace WebCore { NativeImagePtr RGBA32Buffer::asNewNativeImage() const { - return SharedBitmap::create(m_bytes, m_size, hasAlpha()); + return SharedBitmap::create(m_backingStore, m_size, hasAlpha()); } bool FrameData::clear(bool clearMetaData) diff --git a/WebCore/platform/graphics/wince/SharedBitmap.cpp b/WebCore/platform/graphics/wince/SharedBitmap.cpp new file mode 100644 index 0000000..05d1535 --- /dev/null +++ b/WebCore/platform/graphics/wince/SharedBitmap.cpp @@ -0,0 +1,615 @@ +/* + * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved. + * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "SharedBitmap.h" + +#include "GDIExtras.h" +#include "GraphicsContext.h" +#include "GraphicsTypes.h" +#include "TransformationMatrix.h" +#include "WinCEGraphicsExtras.h" +#include <wtf/HashSet.h> +#include <wtf/RefCountedLeakCounter.h> +#include <wtf/PassOwnArrayPtr.h> +#include <wtf/OwnPtr.h> + +#include <windows.h> + +namespace WebCore { + +#ifndef NDEBUG +static WTF::RefCountedLeakCounter sharedBitmapLeakCounter("SharedBitmap"); +#endif + + +PassRefPtr<SharedBitmap> SharedBitmap::create(const IntSize& size, BitmapInfo::BitCount bitCount, bool initPixels) +{ + RefPtr<SharedBitmap> resultantBitmap = adoptRef(new SharedBitmap(size, bitCount, initPixels)); + if (resultantBitmap && !resultantBitmap->bytes()) + return 0; + return resultantBitmap.release(); +} + +PassRefPtr<SharedBitmap> SharedBitmap::create(const Vector<unsigned>& data, const IntSize& size, bool hasAlpha) +{ + RefPtr<SharedBitmap> result = create(size, BitmapInfo::BitCount32, false); + if (!result) + return 0; + memcpy(result->bytes(), data.data(), data.size() * sizeof(unsigned)); + result->setHasAlpha(hasAlpha); + return result.release(); +} + +SharedBitmap::SharedBitmap(const IntSize& size, BitmapInfo::BitCount bitCount, bool initPixels) + : m_bmpInfo(BitmapInfo::createBottomUp(size, bitCount)) + , m_locked(false) + , m_usesTransparentColor(false) + , m_transparentColor(RGB(0, 0, 0)) + , m_pixels(0) + , m_hasAlpha(false) + , m_validHeight(abs(size.height())) + , m_hbitmap(0) +{ +#ifndef NDEBUG + sharedBitmapLeakCounter.increment(); +#endif + + unsigned bufferSize = m_bmpInfo.numPixels(); + if (bitCount == BitmapInfo::BitCount16) + bufferSize /= 2; + + m_pixelData = adoptArrayPtr(new unsigned[bufferSize]); + m_pixels = m_pixelData.get(); + + if (initPixels) + resetPixels(); +} + +SharedBitmap::~SharedBitmap() +{ +#ifndef NDEBUG + sharedBitmapLeakCounter.decrement(); +#endif +} + +void SharedBitmap::resetPixels(bool black) +{ + if (!m_pixels) + return; + + unsigned bufferSize = m_bmpInfo.numPixels(); + if (black) { + unsigned bufferSizeInBytes = bufferSize * (is16bit() ? 2 : 4); + memset(m_pixels, 0, bufferSizeInBytes); + return; + } + + if (is16bit()) { + // Fill it with white color + wmemset(static_cast<wchar_t*>(m_pixels), 0xFFFF, bufferSize); + return; + } + + // Make it white but transparent + unsigned* pixel = static_cast<unsigned*>(m_pixels); + const unsigned* bufferEnd = pixel + bufferSize; + while (pixel < bufferEnd) + *pixel++ = 0x00FFFFFF; +} + +static inline unsigned short convert32To16(unsigned pixel) +{ + unsigned short r = static_cast<unsigned short>((pixel & 0x00F80000) >> 8); + unsigned short g = static_cast<unsigned short>((pixel & 0x0000FC00) >> 5); + unsigned short b = static_cast<unsigned short>((pixel & 0x000000F8) >> 3); + return r | g | b; +} + +bool SharedBitmap::to16bit() +{ + if (m_locked) + return false; + if (is16bit()) + return true; + + BitmapInfo newBmpInfo = BitmapInfo::create(m_bmpInfo.size(), BitmapInfo::BitCount16); + + int width = newBmpInfo.width(); + int paddedWidth = newBmpInfo.paddedWidth(); + int bufferSize = paddedWidth * newBmpInfo.height(); + OwnArrayPtr<unsigned> newPixelData(new unsigned[bufferSize / 2]); + void* newPixels = newPixelData.get(); + + if (!newPixels) + return false; + + unsigned short* p16 = static_cast<unsigned short*>(newPixels); + const unsigned* p32 = static_cast<const unsigned*>(m_pixels); + + bool skips = paddedWidth != width; + + const unsigned short* p16end = p16 + bufferSize; + while (p16 < p16end) { + for (unsigned short* p16lineEnd = p16 + width; p16 < p16lineEnd; ) + *p16++ = convert32To16(*p32++); + + if (skips) + *p16++ = 0; + } + + if (m_hbitmap) + m_hbitmap = nullptr; + else + m_pixelData = newPixelData.release(); + + m_pixels = newPixels; + m_bmpInfo = newBmpInfo; + + setHasAlpha(false); + return true; +} + +bool SharedBitmap::freeMemory() +{ + if (m_locked) + return false; + + if (m_hbitmap) { + m_hbitmap = nullptr; + m_pixels = 0; + return true; + } + + if (m_pixels) { + m_pixelData = nullptr; + m_pixels = 0; + return true; + } + + return false; +} + +PassOwnPtr<HBITMAP> SharedBitmap::createHandle(void** pixels, BitmapInfo* bmpInfo, int height, bool use16bit) const +{ + if (!m_pixels) + return 0; + + if (height == -1) + height = this->height(); + *bmpInfo = BitmapInfo::createBottomUp(IntSize(width(), height), (use16bit || is16bit()) ? BitmapInfo::BitCount16 : BitmapInfo::BitCount32); + + OwnPtr<HBITMAP> hbmp = adoptPtr(CreateDIBSection(0, bmpInfo, DIB_RGB_COLORS, pixels, 0, 0)); + + if (!hbmp) + return 0; + + OwnPtr<HDC> bmpDC = adoptPtr(CreateCompatibleDC(0)); + HGDIOBJ hOldBmp = SelectObject(bmpDC.get(), hbmp.get()); + + StretchDIBits(bmpDC.get(), 0, 0, width(), height, 0, 0, width(), height, m_pixels, &m_bmpInfo, DIB_RGB_COLORS, SRCCOPY); + + SelectObject(bmpDC.get(), hOldBmp); + + return hbmp.release(); +} + +bool SharedBitmap::ensureHandle() +{ + if (m_hbitmap) + return true; + + if (!m_pixels) + return false; + + if (m_locked) + return false; + + BitmapInfo bmpInfo; + void* pixels; + m_hbitmap = createHandle(&pixels, &bmpInfo, -1, !hasAlpha()); + + if (!m_hbitmap) + return false; + + m_pixelData = nullptr; + m_pixels = pixels; + m_bmpInfo = bmpInfo; + + return true; +} + +void SharedBitmap::draw(GraphicsContext* ctxt, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) +{ + if (!m_pixels) + return; + ctxt->drawBitmap(this, dstRect, srcRect, styleColorSpace, compositeOp); +} + +void SharedBitmap::draw(HDC hdc, const IntRect& dstRect, const IntRect& srcRect, CompositeOperator compositeOp) +{ + if (!m_pixels) + return; + + if (dstRect.isEmpty() || srcRect.isEmpty()) + return; + + HBITMAP hbitmap = 0; + OwnPtr<HBITMAP> hTempBitmap; + bool usingHandle = compositeOp == CompositeSourceOver && (hasAlpha() && hasAlphaBlendSupport() || usesTransparentColor()); + + if (usingHandle) { + if (ensureHandle()) + hbitmap = m_hbitmap.get(); + else { + void* pixels; + BitmapInfo bmpInfo; + hTempBitmap = createHandle(&pixels, &bmpInfo, -1, usesTransparentColor()); + hbitmap = hTempBitmap.get(); + } + } + if (!hbitmap) { + // FIXME: handle other composite operation types? + DWORD rop = compositeOp == CompositeCopy ? SRCCOPY + : compositeOp == CompositeXOR ? PATINVERT + : compositeOp == CompositeClear ? WHITENESS + : SRCCOPY; + + StretchDIBits(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), + srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), m_pixels, &m_bmpInfo, DIB_RGB_COLORS, rop); + return; + } + + OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc)); + HGDIOBJ hOldBmp = SelectObject(hmemdc.get(), hbitmap); + + if (!usesTransparentColor() && hasAlphaBlendSupport()) { + static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; + bool success = alphaBlendIfSupported(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), hmemdc.get(), + srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), blend); + ASSERT_UNUSED(success, success); + } else { + TransparentBlt(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), hmemdc.get(), + srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), transparentColor()); + } + + SelectObject(hmemdc.get(), hOldBmp); +} + +PassOwnPtr<HBITMAP> SharedBitmap::clipBitmap(const IntRect& rect, bool useAlpha, BitmapInfo& bmpInfo, void*& pixels) +{ + if (!bytes()) + return 0; + + int oldWidth = width(); + int oldHeight = height(); + int copyWidth = std::min<int>(rect.width(), oldWidth - rect.x()); + int copyHeight = std::min<int>(rect.height(), oldHeight - rect.y()); + if (!copyWidth || !copyHeight) + return 0; + + bmpInfo = BitmapInfo::createBottomUp(IntSize(copyWidth, copyHeight), (useAlpha && is32bit()) ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16); + OwnPtr<HBITMAP> newBmp = adoptPtr(CreateDIBSection(0, &bmpInfo, DIB_RGB_COLORS, &pixels, 0, 0)); + + if (!newBmp) + return 0; + + OwnPtr<HDC> dcNew = adoptPtr(CreateCompatibleDC(0)); + HGDIOBJ tmpNew = SelectObject(dcNew.get(), newBmp.get()); + + StretchDIBits(dcNew.get(), 0, 0, copyWidth, copyHeight, rect.x(), rect.y(), copyWidth, copyHeight, + bytes(), &bitmapInfo(), DIB_RGB_COLORS, SRCCOPY); + + SelectObject(dcNew.get(), tmpNew); + return newBmp.release(); +} + +PassRefPtr<SharedBitmap> SharedBitmap::clipBitmap(const IntRect& rect, bool useAlpha) +{ + int oldWidth = width(); + int oldHeight = height(); + int copyWidth = std::min<int>(rect.width(), oldWidth - rect.x()); + int copyHeight = std::min<int>(rect.height(), oldHeight - rect.y()); + if (!copyWidth || !copyHeight) + return 0; + + RefPtr<SharedBitmap> newBmp = create(IntSize(copyWidth, copyHeight), useAlpha && is32bit() ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16, false); + + if (!newBmp || !newBmp->bytes()) + return 0; + + DCHolder dcNew(newBmp.get()); + + StretchDIBits(dcNew.get(), 0, 0, copyWidth, copyHeight, rect.x(), rect.y(), copyWidth, copyHeight, + bytes(), &bitmapInfo(), DIB_RGB_COLORS, SRCCOPY); + + return newBmp; +} + +static void drawPatternSimple(HDC hdc, const RECT& destRect, HBITMAP hbmp, const POINT& phase) +{ + OwnPtr<HBRUSH> hBrush = adoptPtr(CreatePatternBrush(hbmp)); + if (!hBrush) + return; + + POINT oldOrg; + SetBrushOrgEx(hdc, destRect.left - phase.x, destRect.top - phase.y, &oldOrg); + FillRect(hdc, &destRect, hBrush.get()); + SetBrushOrgEx(hdc, oldOrg.x, oldOrg.y, 0); +} + +static void drawPatternSimple(HDC hdc, const RECT& destRect, const SharedBitmap* bmp, const SIZE& bmpSize, const POINT& phase) +{ + int dstY = destRect.top; + for (int sourceY = phase.y; dstY < destRect.bottom; ) { + int sourceH = std::min<int>(bmpSize.cy - sourceY, destRect.bottom - dstY); + int dstX = destRect.left; + for (int sourceX = phase.x; dstX < destRect.right; ) { + int sourceW = std::min<int>(bmpSize.cx - sourceX, destRect.right - dstX); + + StretchDIBits(hdc, dstX, dstY, sourceW, sourceH, sourceX, sourceY, sourceW, sourceH, + bmp->bytes(), &bmp->bitmapInfo(), DIB_RGB_COLORS, SRCCOPY); + + dstX += sourceW; + sourceX = 0; + } + + dstY += sourceH; + sourceY = 0; + } +} + +static LONG normalizePhase(LONG phase, int limit) +{ + if (!phase || limit < 2) + return 0; + + if (limit == 2) + return phase & 1; + + if (phase < 0) { + phase = -phase; + if (phase > limit) + phase = static_cast<LONG>(static_cast<unsigned>(phase) % static_cast<unsigned>(limit)); + if (phase) + phase = limit - phase; + return phase; + } + + if (phase < limit) + return phase; + + return static_cast<LONG>(static_cast<unsigned>(phase) % static_cast<unsigned>(limit)); +} + +void SharedBitmap::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize) +{ + if (!m_pixels) + return; + ctxt->drawBitmapPattern(this, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, origSourceSize); +} + +void SharedBitmap::drawPattern(HDC hdc, const AffineTransform& transform, const FloatRect& tileRectIn, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize) +{ + if (!m_pixels) + return; + + if (tileRectIn.width() <= 0 || tileRectIn.height() <= 0) + return; + + bool useAlpha = op == CompositeSourceOver && hasAlpha() && is32bit(); + + int bmpWidth = width(); + int bmpHeight = height(); + + FloatRect tileRect(tileRectIn); + if (bmpWidth != origSourceSize.width()) { + double rate = static_cast<double>(bmpWidth) / origSourceSize.width(); + double temp = tileRect.width() * rate; + tileRect.setX(tileRect.x() * rate); + tileRect.setWidth(temp); + temp = tileRect.height() * rate; + tileRect.setY(tileRect.y() * rate); + tileRect.setHeight(temp); + } + + OwnPtr<HBITMAP> clippedBmp; + + if (tileRect.x() || tileRect.y() || tileRect.width() != bmpWidth || tileRect.height() != bmpHeight) { + BitmapInfo patternBmpInfo; + void* patternPixels; + clippedBmp = clipBitmap(IntRect(tileRect), useAlpha, patternBmpInfo, patternPixels); + if (!clippedBmp) + return; + + bmpWidth = tileRect.width(); + bmpHeight = tileRect.height(); + } + + AffineTransform tf = transform; + tf *= patternTransform; + + FloatRect trRect = tf.mapRect(destRect); + + RECT clipBox; + int clipType = GetClipBox(hdc, &clipBox); + if (clipType == SIMPLEREGION) + trRect.intersect(FloatRect(clipBox.left, clipBox.top, clipBox.right - clipBox.left, clipBox.bottom - clipBox.top)); + else if (clipType == COMPLEXREGION) { + OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgn(0, 0, 0, 0)); + if (GetClipRgn(hdc, clipRgn.get()) > 0) { + DWORD regionDataSize = GetRegionData(clipRgn.get(), sizeof(RGNDATA), 0); + if (regionDataSize) { + Vector<RGNDATA> regionData(regionDataSize); + GetRegionData(clipRgn.get(), regionDataSize, regionData.data()); + RECT* rect = reinterpret_cast<RECT*>(regionData[0].Buffer); + for (DWORD i = 0; i < regionData[0].rdh.nCount; ++i, ++rect) + trRect.intersect(FloatRect(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top)); + } + } + } + + if (trRect.width() <= 0 || trRect.height() <= 0) + return; + + trRect.inflate(1); + IntRect visibleDstRect = enclosingIntRect(tf.inverse().mapRect(trRect)); + visibleDstRect.intersect(IntRect(destRect)); + + if (visibleDstRect.width() <= 0 || visibleDstRect.height() <= 0) + return; + + trRect = tf.mapRect(visibleDstRect); + RECT dstRectWin = { + stableRound(trRect.x()), + stableRound(trRect.y()), + stableRound(trRect.right()), + stableRound(trRect.bottom()), + }; + if (dstRectWin.right <= dstRectWin.left || dstRectWin.bottom <= dstRectWin.top) + return; + + SIZE bmpSize = { bmpWidth, bmpHeight }; + + // Relative to destination, in bitmap pixels + POINT phaseWin = { stableRound(visibleDstRect.x() - phase.x()), stableRound(visibleDstRect.y() - phase.y()) }; + phaseWin.x = normalizePhase(phaseWin.x, bmpSize.cx); + phaseWin.y = normalizePhase(phaseWin.y, bmpSize.cy); + + RECT srcRectWin = { + 0, + 0, + stableRound(visibleDstRect.right()) - stableRound(visibleDstRect.x()), + stableRound(visibleDstRect.bottom()) - stableRound(visibleDstRect.y()) + }; + if (srcRectWin.right <= 0 || srcRectWin.bottom <= 0) + return; + + BitmapInfo bmpInfo = BitmapInfo::createBottomUp(IntSize(srcRectWin.right, srcRectWin.bottom), useAlpha ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16); + void* pixels; + OwnPtr<HBITMAP> hbmpTemp = adoptPtr(CreateDIBSection(0, &bmpInfo, DIB_RGB_COLORS, &pixels, 0, 0)); + + if (!hbmpTemp) + return; + + OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc)); + HGDIOBJ oldBmp = SelectObject(hmemdc.get(), hbmpTemp.get()); + if (clippedBmp) + drawPatternSimple(hmemdc.get(), srcRectWin, clippedBmp.get(), phaseWin); + else if ((op != CompositeSourceOver || canUseDIBits()) && srcRectWin.right <= bmpSize.cx * 2 && srcRectWin.bottom <= bmpSize.cy * 2) + drawPatternSimple(hmemdc.get(), srcRectWin, this, bmpSize, phaseWin); + else if (ensureHandle()) + drawPatternSimple(hmemdc.get(), srcRectWin, getHandle(), phaseWin); + else { + void* pixels; + BitmapInfo bmpInfo; + OwnPtr<HBITMAP> hbmp = createHandle(&pixels, &bmpInfo, -1, false); + if (hbmp) + drawPatternSimple(hmemdc.get(), srcRectWin, hbmp.get(), phaseWin); + else { + SelectObject(hmemdc.get(), oldBmp); + return; + } + } + + if (useAlpha && hasAlphaBlendSupport()) { + static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; + bool success = alphaBlendIfSupported(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, dstRectWin.bottom - dstRectWin.top, + hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, blend); + ASSERT_UNUSED(success, success); + } else if (useAlpha && !hasAlphaBlendSupport() || op == CompositeSourceOver && usesTransparentColor()) { + TransparentBlt(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, + dstRectWin.bottom - dstRectWin.top, hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, transparentColor()); + } else { + DWORD bmpOp = op == CompositeCopy ? SRCCOPY + : op == CompositeSourceOver ? SRCCOPY + : op == CompositeXOR ? PATINVERT + : op == CompositeClear ? WHITENESS + : SRCCOPY; // FIXEME: other types? + + StretchDIBits(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, + dstRectWin.bottom - dstRectWin.top, 0, 0, srcRectWin.right, srcRectWin.bottom, + pixels, &bmpInfo, DIB_RGB_COLORS, bmpOp); + } + SelectObject(hmemdc.get(), oldBmp); +} + +SharedBitmap::DCProvider* SharedBitmap::s_dcProvider = new SharedBitmap::DCProvider; + +HDC SharedBitmap::DCProvider::getDC(SharedBitmap* bmp, unsigned* key) +{ + if (!bmp || !bmp->ensureHandle()) + return 0; + + HDC hdc = CreateCompatibleDC(0); + if (!hdc) + return 0; + + *key = reinterpret_cast<unsigned>(SelectObject(hdc, bmp->getHandle())); + RECT rect = { 0, 0, bmp->width(), bmp->height() }; + OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgnIndirect(&rect)); + SelectClipRgn(hdc, clipRgn.get()); + + return hdc; +} + +void SharedBitmap::DCProvider::releaseDC(SharedBitmap*, HDC hdc, unsigned key1) +{ + if (!hdc) + return; + + SelectObject(hdc, reinterpret_cast<HGDIOBJ>(key1)); + DeleteDC(hdc); +} + +void SharedBitmap::clearPixels(const IntRect& rect) +{ + if (!m_pixels) + return; + + IntRect bmpRect(0, 0, width(), height()); + bmpRect.intersect(rect); + if (is16bit()) { + unsigned w = m_bmpInfo.paddedWidth(); + unsigned short* dst = static_cast<unsigned short*>(m_pixels); + dst += bmpRect.y() * w + bmpRect.x(); + int wordsToSet = bmpRect.width(); + const unsigned short* dstEnd = dst + bmpRect.height() * w; + while (dst < dstEnd) { + wmemset(reinterpret_cast<wchar_t*>(dst), 0, wordsToSet); + dst += w; + } + return; + } + + unsigned w = width(); + unsigned* dst = static_cast<unsigned*>(m_pixels); + dst += bmpRect.y() * w + bmpRect.x(); + int wordsToSet = bmpRect.width() * 2; + const unsigned* dstEnd = dst + bmpRect.height() * w; + while (dst < dstEnd) { + wmemset(reinterpret_cast<wchar_t*>(dst), 0, wordsToSet); + dst += w; + } +} + +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/SharedBitmap.h b/WebCore/platform/graphics/wince/SharedBitmap.h new file mode 100644 index 0000000..82f5d54 --- /dev/null +++ b/WebCore/platform/graphics/wince/SharedBitmap.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved. + * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SharedBitmap_h +#define SharedBitmap_h + +#include "AffineTransform.h" +#include "BitmapInfo.h" +#include "ColorSpace.h" +#include "GraphicsTypes.h" +#include <wtf/PassOwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/OwnArrayPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/Vector.h> +#include <wingdi.h> + +namespace WebCore { + +class FloatPoint; +class FloatRect; +class GraphicsContext; +class IntRect; +class IntSize; +class TransformationMatrix; + +class SharedBitmap: public RefCounted<SharedBitmap> { +public: + ~SharedBitmap(); + static PassRefPtr<SharedBitmap> create(const IntSize&, BitmapInfo::BitCount = BitmapInfo::BitCount32, bool initPixels = true); + static PassRefPtr<SharedBitmap> create(const Vector<unsigned>&, const IntSize&, bool hasAlpha = true); + + const BitmapInfo& bitmapInfo() const { return m_bmpInfo; } + void* bytes() { return m_pixels; } + const void* bytes() const { return m_pixels; } + unsigned width() const { return m_bmpInfo.width(); } + unsigned height() const { return m_bmpInfo.height(); } + unsigned validHeight() const { return m_validHeight; } + void setValidHeight(unsigned validHeight) { m_validHeight = validHeight; } + void resetPixels(bool black = false); + void clearPixels(const IntRect& r); + bool locked() const { return m_locked; } + void lock() { m_locked = true; } + void unlock() { m_locked = false; } + bool freeMemory(); + bool is16bit() const { return m_bmpInfo.is16bit(); } + bool is32bit() const { return m_bmpInfo.is32bit(); } + bool to16bit(); + bool hasAlpha() const { return m_hasAlpha; } + void setHasAlpha(bool alpha) { m_hasAlpha = alpha; } + bool ensureHandle(); + HBITMAP getHandle() { return m_hbitmap.get(); } + PassOwnPtr<HBITMAP> createHandle(void** pixels, BitmapInfo* bmpInfo, int h = -1, bool use16bit = true) const; + bool usesTransparentColor() const { return m_usesTransparentColor; } + COLORREF transparentColor() const { return m_transparentColor; } + void setTransparentColor(COLORREF c) + { + m_usesTransparentColor = true; + m_transparentColor = c; + } + bool canUseDIBits() const { return !hasAlpha() && !usesTransparentColor(); } + + PassOwnPtr<HBITMAP> clipBitmap(const IntRect& rect, bool useAlpha, BitmapInfo& bmpInfo, void*& pixels); + + PassRefPtr<SharedBitmap> clipBitmap(const IntRect& rect, bool useAlpha); + + void draw(GraphicsContext* ctxt, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp); + void drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize); + void draw(HDC, const IntRect& dstRect, const IntRect& srcRect, CompositeOperator compositeOp); + void drawPattern(HDC, const AffineTransform&, const FloatRect& tileRectIn, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize); + + class DCProvider { + public: + virtual HDC getDC(SharedBitmap*, unsigned*); + virtual void releaseDC(SharedBitmap*, HDC, unsigned); + }; + + static DCProvider* s_dcProvider; + + HDC getDC(unsigned* key1) { return s_dcProvider->getDC(this, key1); } + void releaseDC(HDC hdc, unsigned key1) { s_dcProvider->releaseDC(this, hdc, key1); } + + class DCHolder { + public: + DCHolder(SharedBitmap* bmp = 0) { setInternal(bmp); } + ~DCHolder() { clearInternal(); } + void set(SharedBitmap* bmp = 0) + { + clearInternal(); + setInternal(bmp); + } + HDC get() const { return m_hdc; } + private: + DCHolder& operator=(const DCHolder&); + DCHolder(const DCHolder&); + void clearInternal() + { + if (m_hdc) + m_bitmap->releaseDC(m_hdc, m_key); + } + void setInternal(SharedBitmap* bmp) + { + m_bitmap = bmp; + m_hdc = bmp ? bmp->getDC(&m_key) : 0; + } + SharedBitmap* m_bitmap; + HDC m_hdc; + unsigned m_key; + }; + +private: + SharedBitmap(const IntSize&, BitmapInfo::BitCount, bool initPixels); + BitmapInfo m_bmpInfo; + OwnPtr<HBITMAP> m_hbitmap; + void* m_pixels; + OwnArrayPtr<unsigned> m_pixelData; + COLORREF m_transparentColor; + int m_validHeight; + bool m_locked; + bool m_usesTransparentColor; + bool m_hasAlpha; +}; + +} // namespace WebCore + +#endif // SharedBitmap_h diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp index 30daa67..53a9ccd 100644 --- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp +++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp @@ -337,11 +337,6 @@ void GraphicsContext::clipOut(const IntRect&) notImplemented(); } -void GraphicsContext::clipOutEllipseInRect(const IntRect&) -{ - notImplemented(); -} - void GraphicsContext::clipPath(WindRule) { notImplemented(); diff --git a/WebCore/platform/gtk/CursorGtk.cpp b/WebCore/platform/gtk/CursorGtk.cpp index 9971bfb..39073ae 100644 --- a/WebCore/platform/gtk/CursorGtk.cpp +++ b/WebCore/platform/gtk/CursorGtk.cpp @@ -32,7 +32,7 @@ #include "Image.h" #include "IntPoint.h" -#include "PlatformRefPtrCairo.h" +#include "RefPtrCairo.h" #include <gdk/gdk.h> #include <gtk/gtk.h> #include <wtf/Assertions.h> @@ -47,10 +47,10 @@ static PlatformRefPtr<GdkCursor> createNamedCursor(CustomCursorType cursorType) return c; IntSize cursorSize = IntSize(32, 32); - PlatformRefPtr<cairo_surface_t> source = adoptPlatformRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.bits), CAIRO_FORMAT_A1, 32, 32, 4)); - PlatformRefPtr<cairo_surface_t> mask = adoptPlatformRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.mask_bits), CAIRO_FORMAT_A1, 32, 32, 4)); - PlatformRefPtr<cairo_surface_t> surface = adoptPlatformRef(cairo_image_surface_create(CAIRO_FORMAT_A1, 32, 32)); - PlatformRefPtr<cairo_t> cr = adoptPlatformRef(cairo_create(surface.get())); + RefPtr<cairo_surface_t> source = adoptRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.bits), CAIRO_FORMAT_A1, 32, 32, 4)); + RefPtr<cairo_surface_t> mask = adoptRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.mask_bits), CAIRO_FORMAT_A1, 32, 32, 4)); + RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_A1, 32, 32)); + RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get())); cairo_set_source_surface(cr.get(), source.get(), cursor.hot_x, cursor.hot_y); cairo_mask_surface(cr.get(), mask.get(), cursor.hot_x, cursor.hot_y); diff --git a/WebCore/platform/gtk/DragImageGtk.cpp b/WebCore/platform/gtk/DragImageGtk.cpp index 9d0d838..71a65e1 100644 --- a/WebCore/platform/gtk/DragImageGtk.cpp +++ b/WebCore/platform/gtk/DragImageGtk.cpp @@ -21,7 +21,7 @@ #include "CachedImage.h" #include "Image.h" -#include "PlatformRefPtrCairo.h" +#include "RefPtrCairo.h" #include <cairo.h> namespace WebCore { @@ -49,7 +49,7 @@ DragImageRef scaleDragImage(DragImageRef image, FloatSize scale) int newHeight = scale.height() * cairo_image_surface_get_height(image); cairo_surface_t* scaledSurface = cairo_surface_create_similar(image, CAIRO_CONTENT_COLOR_ALPHA, newWidth, newHeight); - PlatformRefPtr<cairo_t> context = adoptPlatformRef(cairo_create(scaledSurface)); + RefPtr<cairo_t> context = adoptRef(cairo_create(scaledSurface)); cairo_scale(context.get(), scale.width(), scale.height()); cairo_pattern_set_extend(cairo_get_source(context.get()), CAIRO_EXTEND_PAD); cairo_pattern_set_filter(cairo_get_source(context.get()), CAIRO_FILTER_BEST); @@ -66,7 +66,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction) if (!image) return 0; - PlatformRefPtr<cairo_t> context = adoptPlatformRef(cairo_create(image)); + RefPtr<cairo_t> context = adoptRef(cairo_create(image)); cairo_set_operator(context.get(), CAIRO_OPERATOR_DEST_IN); cairo_set_source_rgba(context.get(), 0, 0, 0, fraction); cairo_paint(context.get()); diff --git a/WebCore/platform/gtk/PasteboardHelper.cpp b/WebCore/platform/gtk/PasteboardHelper.cpp index 9f75728..228d5e9 100644 --- a/WebCore/platform/gtk/PasteboardHelper.cpp +++ b/WebCore/platform/gtk/PasteboardHelper.cpp @@ -38,6 +38,16 @@ static GdkAtom textPlainAtom = gdk_atom_intern("text/plain;charset=utf-8", FALSE static GdkAtom markupAtom = gdk_atom_intern("text/html", FALSE); static GdkAtom netscapeURLAtom = gdk_atom_intern("_NETSCAPE_URL", FALSE); static GdkAtom uriListAtom = gdk_atom_intern("text/uri-list", FALSE); +static String gMarkupPrefix = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"; + +static void removeMarkupPrefix(String& markup) +{ + + // The markup prefix is not harmful, but we remove it from the string anyway, so that + // we can have consistent results with other ports during the layout tests. + if (markup.startsWith(gMarkupPrefix)) + markup.remove(0, gMarkupPrefix.length()); +} PasteboardHelper::PasteboardHelper() : m_targetList(gtk_target_list_new(0, 0)) @@ -112,7 +122,9 @@ void PasteboardHelper::getClipboardContents(GtkClipboard* clipboard) if (gtk_clipboard_wait_is_target_available(clipboard, markupAtom)) { if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, markupAtom)) { - dataObject->setMarkup(selectionDataToUTF8String(data)); + String markup(selectionDataToUTF8String(data)); + removeMarkupPrefix(markup); + dataObject->setMarkup(markup); gtk_selection_data_free(data); } } @@ -131,9 +143,11 @@ void PasteboardHelper::fillSelectionData(GtkSelectionData* selectionData, guint gtk_selection_data_set_text(selectionData, dataObject->text().utf8().data(), -1); else if (info == getIdForTargetType(TargetTypeMarkup)) { - GOwnPtr<gchar> markup(g_strdup(dataObject->markup().utf8().data())); + // Some Linux applications refuse to accept pasted markup unless it is + // prefixed by a content-type meta tag. + CString markup = (gMarkupPrefix + dataObject->markup()).utf8(); gtk_selection_data_set(selectionData, markupAtom, 8, - reinterpret_cast<const guchar*>(markup.get()), strlen(markup.get()) + 1); + reinterpret_cast<const guchar*>(markup.data()), markup.length() + 1); } else if (info == getIdForTargetType(TargetTypeURIList)) { CString uriList = dataObject->uriList().utf8(); @@ -187,9 +201,11 @@ void PasteboardHelper::fillDataObjectFromDropData(GtkSelectionData* data, guint GdkAtom target = gtk_selection_data_get_target(data); if (target == textPlainAtom) dataObject->setText(selectionDataToUTF8String(data)); - else if (target == markupAtom) - dataObject->setMarkup(selectionDataToUTF8String(data)); - else if (target == uriListAtom) { + else if (target == markupAtom) { + String markup(selectionDataToUTF8String(data)); + removeMarkupPrefix(markup); + dataObject->setMarkup(markup); + } else if (target == uriListAtom) { dataObject->setURIList(selectionDataToUTF8String(data)); } else if (target == netscapeURLAtom) { String urlWithLabel(selectionDataToUTF8String(data)); diff --git a/WebCore/platform/gtk/PopupMenuGtk.cpp b/WebCore/platform/gtk/PopupMenuGtk.cpp index a679734..e7ff78e 100644 --- a/WebCore/platform/gtk/PopupMenuGtk.cpp +++ b/WebCore/platform/gtk/PopupMenuGtk.cpp @@ -97,7 +97,7 @@ void PopupMenuGtk::show(const IntRect& rect, FrameView* view, int index) GList* children = gtk_container_get_children(GTK_CONTAINER(m_popup.get())); GList* p = children; - if (size) + if (size) { for (int i = 0; i < size; i++) { if (i > index) break; @@ -112,9 +112,11 @@ void PopupMenuGtk::show(const IntRect& rect, FrameView* view, int index) m_menuPosition.setY(m_menuPosition.y() - itemRequisition.height); p = g_list_next(p); - } else - // Center vertically the empty popup in the combo box area - m_menuPosition.setY(m_menuPosition.y() - rect.height() / 2); + } + } else { + // Center vertically the empty popup in the combo box area + m_menuPosition.setY(m_menuPosition.y() - rect.height() / 2); + } g_list_free(children); gtk_menu_popup(m_popup.get(), 0, 0, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, 0, gtk_get_current_event_time()); diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp index fa61871..43ff33b 100644 --- a/WebCore/platform/image-decoders/ImageDecoder.cpp +++ b/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -194,6 +194,11 @@ void RGBA32Buffer::setHasAlpha(bool alpha) m_hasAlpha = alpha; } +void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile) +{ + m_colorProfile = colorProfile; +} + void RGBA32Buffer::setStatus(FrameStatus status) { m_status = status; diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h index 9fe0e6b..81d6dbb 100644 --- a/WebCore/platform/image-decoders/ImageDecoder.h +++ b/WebCore/platform/image-decoders/ImageDecoder.h @@ -47,6 +47,9 @@ namespace WebCore { + // FIXME: Do we want better encapsulation? + typedef Vector<char> ColorProfile; + // The RGBA32Buffer object represents the decoded image data in RGBA32 // format. This buffer is what all decoders write a single frame into. // Frames are then instantiated for drawing by being handed this buffer. @@ -131,6 +134,7 @@ namespace WebCore { bool premultiplyAlpha() const { return m_premultiplyAlpha; } void setHasAlpha(bool alpha); + void setColorProfile(const ColorProfile&); void setRect(const IntRect& r) { m_rect = r; } void setStatus(FrameStatus status); void setDuration(unsigned duration) { m_duration = duration; } @@ -202,6 +206,7 @@ namespace WebCore { // same as ImageDecoder::m_size. bool m_hasAlpha; // Whether or not any of the pixels in the buffer // have transparency. + ColorProfile m_colorProfile; #endif IntRect m_rect; // The rect of the original specified frame within // the overall buffer. This will always just be @@ -354,6 +359,7 @@ namespace WebCore { RefPtr<SharedBuffer> m_data; // The encoded data. Vector<RGBA32Buffer> m_frameBufferCache; + ColorProfile m_colorProfile; bool m_scaled; Vector<int> m_scaledColumns; Vector<int> m_scaledRows; diff --git a/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp b/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp index 2fac7da..0f4dbc8 100644 --- a/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp +++ b/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp @@ -31,11 +31,16 @@ namespace WebCore { +static RGBA32Buffer::PixelData* getPtrAsPixelData(CFMutableDataRef data) +{ + return data ? reinterpret_cast<RGBA32Buffer::PixelData*>(CFDataGetMutableBytePtr(data)) : 0; +} + void RGBA32Buffer::copyReferenceToBitmapData(const RGBA32Buffer& other) { ASSERT(this != &other); m_backingStore = other.m_backingStore; - m_bytes = reinterpret_cast<PixelData*>(CFDataGetMutableBytePtr(m_backingStore.get())); + m_bytes = getPtrAsPixelData(m_backingStore.get()); // FIXME: The rest of this function seems redundant with RGBA32Buffer::copyBitmapData. m_size = other.m_size; setHasAlpha(other.m_hasAlpha); @@ -47,7 +52,7 @@ bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) return true; m_backingStore.adoptCF(CFDataCreateMutableCopy(kCFAllocatorDefault, 0, other.m_backingStore.get())); - m_bytes = reinterpret_cast<PixelData*>(CFDataGetMutableBytePtr(m_backingStore.get())); + m_bytes = getPtrAsPixelData(m_backingStore.get()); m_size = other.m_size; setHasAlpha(other.m_hasAlpha); return true; @@ -64,15 +69,30 @@ bool RGBA32Buffer::setSize(int newWidth, int newHeight) return true; } +static CGColorSpaceRef createColorSpace(const ColorProfile& colorProfile) +{ + if (colorProfile.isEmpty()) + return CGColorSpaceCreateDeviceRGB(); + + RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(colorProfile.data()), colorProfile.size())); +#if !defined(TARGETING_TIGER) && !defined(TARGETING_LEOPARD) + return CGColorSpaceCreateWithICCProfile(data.get()); +#else + RetainPtr<CGColorSpaceRef> deviceColorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); + RetainPtr<CGDataProviderRef> profileDataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get())); + CGFloat ranges[] = {0.0, 255.0, 0.0, 255.0, 0.0, 255.0}; + return CGColorSpaceCreateICCBased(3, ranges, profileDataProvider.get(), deviceColorSpace.get()); +#endif +} + NativeImagePtr RGBA32Buffer::asNewNativeImage() const { - // FIXME: Figure out the right color space. - DEFINE_STATIC_LOCAL(RetainPtr<CGColorSpaceRef>, deviceColorSpace, (AdoptCF, CGColorSpaceCreateDeviceRGB())); + RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, createColorSpace(m_colorProfile)); RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_backingStore.get())); CGImageAlphaInfo alphaInfo = m_premultiplyAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaFirst; - return CGImageCreate(width(), height(), 8, 32, width() * sizeof(PixelData), deviceColorSpace.get(), + return CGImageCreate(width(), height(), 8, 32, width() * sizeof(PixelData), colorSpace.get(), alphaInfo | kCGBitmapByteOrder32Host, dataProvider.get(), 0, false, kCGRenderingIntentDefault); } diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp index 4797495..18cd903 100644 --- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -96,21 +96,24 @@ int GIFImageDecoder::repetitionCount() const // This value can arrive at any point in the image data stream. Most GIFs // in the wild declare it near the beginning of the file, so it usually is // set by the time we've decoded the size, but (depending on the GIF and the - // packets sent back by the webserver) not always. Our caller is - // responsible for waiting until image decoding has finished to ask this if - // it needs an authoritative answer. In the meantime, we should default to - // "loop once". - if (m_reader) { - // Added wrinkle: ImageSource::clear() may destroy the reader, making - // the result from the reader _less_ authoritative on future calls. To - // detect this, the reader returns cLoopCountNotSeen (-2) instead of - // cAnimationLoopOnce (0) when its current incarnation hasn't actually - // seen a loop count yet; in this case we return our previously-cached - // value. - const int repetitionCount = m_reader->loop_count; - if (repetitionCount != cLoopCountNotSeen) - m_repetitionCount = repetitionCount; - } + // packets sent back by the webserver) not always. If the reader hasn't + // seen a loop count yet, it will return cLoopCountNotSeen, in which case we + // should default to looping once (the initial value for + // |m_repetitionCount|). + // + // There are two additional wrinkles here. First, ImageSource::clear() may + // destroy the reader, making the result from the reader _less_ + // authoritative on future calls if the recreated reader hasn't seen the + // loop count. We don't need to special-case this because in this case the + // new reader will once again return cLoopCountNotSeen, and we won't + // overwrite the cached correct value. + // + // Second, a GIF might never set a loop count at all, in which case we + // should continue to treat it as a "loop once" animation. We don't need + // special code here either, because in this case we'll never change + // |m_repetitionCount| from its default value. + if (m_reader && (m_reader->loop_count != cLoopCountNotSeen)) + m_repetitionCount = m_reader->loop_count; return m_repetitionCount; } @@ -295,8 +298,10 @@ bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, void GIFImageDecoder::gifComplete() { - if (m_reader) - m_repetitionCount = m_reader->loop_count; + // Cache the repetition count, which is now as authoritative as it's ever + // going to be. + repetitionCount(); + m_reader.clear(); } diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 6c6c782..da35739 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -51,7 +51,13 @@ #endif extern "C" { + #include "jpeglib.h" + +#if USE(ICCJPEG) +#include "iccjpeg.h" +#endif + } #include <setjmp.h> @@ -86,6 +92,24 @@ struct decoder_source_mgr { JPEGImageReader* decoder; }; +static ColorProfile readColorProfile(jpeg_decompress_struct* info) +{ +#if USE(ICCJPEG) + JOCTET* profile; + unsigned int profileLength; + + if (!read_icc_profile(info, &profile, &profileLength)) + return ColorProfile(); + + ColorProfile colorProfile; + colorProfile.append(reinterpret_cast<char*>(profile), profileLength); + free(profile); + return colorProfile; +#else + return ColorProfile(); +#endif +} + class JPEGImageReader { public: @@ -123,6 +147,11 @@ public: src->pub.resync_to_restart = jpeg_resync_to_restart; src->pub.term_source = term_source; src->decoder = this; + + // Enable these markers for the ICC color profile. + // Apparently there are 16 of these markers. I don't see anywhere in the header with this constant. + for (unsigned i = 0; i < 0xF; ++i) + jpeg_save_markers(&m_info, JPEG_APP0 + i, 0xFFFF); } ~JPEGImageReader() @@ -212,6 +241,8 @@ public: if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) return false; + m_decoder->setColorProfile(readColorProfile(info())); + if (m_decodingSizeOnly) { // We can stop here. Reduce our buffer length and available // data. @@ -421,6 +452,7 @@ bool JPEGImageDecoder::outputScanlines() return setFailed(); buffer.setStatus(RGBA32Buffer::FramePartial); buffer.setHasAlpha(false); + buffer.setColorProfile(m_colorProfile); // For JPEGs, the frame always fills the entire image. buffer.setRect(IntRect(IntPoint(), size())); diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h index 5047019..e942b01 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h @@ -54,6 +54,8 @@ namespace WebCore { bool outputScanlines(); void jpegComplete(); + void setColorProfile(const ColorProfile& colorProfile) { m_colorProfile = colorProfile; } + private: // Decodes the image. If |onlySize| is true, stops decoding after // calculating the image size. If decoding fails but there is no more diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 940e4c4..e4f7a0c 100644 --- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -220,6 +220,22 @@ bool PNGImageDecoder::setFailed() return ImageDecoder::setFailed(); } +static ColorProfile readColorProfile(png_structp png, png_infop info) +{ +#ifdef PNG_iCCP_SUPPORTED + char* profileName; + int compressionType; + char* profile; + png_uint_32 profileLength; + if (png_get_iCCP(png, info, &profileName, &compressionType, &profile, &profileLength)) { + ColorProfile colorProfile; + colorProfile.append(profile, profileLength); + return colorProfile; + } +#endif + return ColorProfile(); +} + void PNGImageDecoder::headerAvailable() { png_structp png = m_reader->pngPtr(); @@ -249,6 +265,16 @@ void PNGImageDecoder::headerAvailable() int bitDepth, colorType, interlaceType, compressionType, filterType, channels; png_get_IHDR(png, info, &width, &height, &bitDepth, &colorType, &interlaceType, &compressionType, &filterType); + if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_RGB_ALPHA) { + // We currently support color profiles only for RGB and RGBA PNGs. Supporting + // color profiles for gray-scale images is slightly tricky, at least using the + // CoreGraphics ICC library, because we expand gray-scale images to RGB but we + // don't similarly transform the color profile. We'd either need to transform + // the color profile or we'd need to decode into a gray-scale image buffer and + // hand that to CoreGraphics. + m_colorProfile = readColorProfile(png, info); + } + // The options we set here match what Mozilla does. // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA. @@ -311,6 +337,7 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, } buffer.setStatus(RGBA32Buffer::FramePartial); buffer.setHasAlpha(false); + buffer.setColorProfile(m_colorProfile); // For PNGs, the frame always fills the entire image. buffer.setRect(IntRect(IntPoint(), size())); diff --git a/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp b/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp index a782373..998234f 100644 --- a/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp +++ b/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp @@ -28,6 +28,8 @@ #include "config.h" #include "ImageDecoder.h" +#include "NotImplemented.h" + #include <QPixmap> #include <stdio.h> @@ -124,6 +126,11 @@ void RGBA32Buffer::setHasAlpha(bool alpha) m_hasAlpha = alpha; } +void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile) +{ + notImplemented(); +} + void RGBA32Buffer::setStatus(FrameStatus status) { m_status = status; diff --git a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp index 7baca5f..50e2106 100644 --- a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp +++ b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp @@ -30,6 +30,8 @@ #include "SkBitmapRef.h" #endif +#include "NotImplemented.h" + namespace WebCore { RGBA32Buffer::RGBA32Buffer() @@ -116,6 +118,11 @@ void RGBA32Buffer::setHasAlpha(bool alpha) m_bitmap.setIsOpaque(!alpha); } +void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile) +{ + notImplemented(); +} + void RGBA32Buffer::setStatus(FrameStatus status) { m_status = status; diff --git a/WebCore/platform/mac/ContextMenuItemMac.mm b/WebCore/platform/mac/ContextMenuItemMac.mm index 48da786..ce779ec 100644 --- a/WebCore/platform/mac/ContextMenuItemMac.mm +++ b/WebCore/platform/mac/ContextMenuItemMac.mm @@ -154,6 +154,11 @@ bool ContextMenuItem::enabled() const return [m_platformDescription.get() isEnabled]; } +bool ContextMenuItem::checked() const +{ + return [m_platformDescription.get() state] == NSOnState; +} + } // namespace WebCore #endif // ENABLE(CONTEXT_MENUS) diff --git a/WebCore/platform/mac/ContextMenuMac.mm b/WebCore/platform/mac/ContextMenuMac.mm index 8ced8cb..c427e3c 100644 --- a/WebCore/platform/mac/ContextMenuMac.mm +++ b/WebCore/platform/mac/ContextMenuMac.mm @@ -153,6 +153,19 @@ NSMutableArray* ContextMenu::releasePlatformDescription() return m_platformDescription.releaseRef(); } +Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription menu) +{ + Vector<ContextMenuItem> items; + unsigned count = [menu count]; + if (menu) + items.reserveCapacity(count); + + for (unsigned i = 0; i < count; ++i) + items.append(ContextMenuItem([menu objectAtIndex:i])); + + return items; +} + } // namespace WebCore #endif // ENABLE(CONTEXT_MENUS) diff --git a/WebCore/platform/mac/Language.mm b/WebCore/platform/mac/Language.mm index bb51cb5..c242e9e 100644 --- a/WebCore/platform/mac/Language.mm +++ b/WebCore/platform/mac/Language.mm @@ -69,17 +69,20 @@ static NSString *createHTTPStyleLanguageCode(NSString *languageCode) // Make the string lowercase. NSString *lowercaseLanguageCode = [languageCode lowercaseString]; + NSString *httpStyleLanguageCode; + // Turn a '_' into a '-' if it appears after a 2-letter language code. - if ([lowercaseLanguageCode length] < 3 || [lowercaseLanguageCode characterAtIndex:2] != '_') - return lowercaseLanguageCode; - - NSMutableString *result = [lowercaseLanguageCode mutableCopy]; - [result replaceCharactersInRange:NSMakeRange(2, 1) withString:@"-"]; - + if ([lowercaseLanguageCode length] >= 3 && [lowercaseLanguageCode characterAtIndex:2] == '_') { + NSMutableString *mutableLanguageCode = [lowercaseLanguageCode mutableCopy]; + [mutableLanguageCode replaceCharactersInRange:NSMakeRange(2, 1) withString:@"-"]; + httpStyleLanguageCode = mutableLanguageCode; + } else + httpStyleLanguageCode = [lowercaseLanguageCode retain]; + if (preferredLanguageCode) CFRelease(preferredLanguageCode); - return result; + return httpStyleLanguageCode; } String platformDefaultLanguage() diff --git a/WebCore/platform/mac/PurgeableBufferMac.cpp b/WebCore/platform/mac/PurgeableBufferMac.cpp index 54de4ed..fdbac1f 100644 --- a/WebCore/platform/mac/PurgeableBufferMac.cpp +++ b/WebCore/platform/mac/PurgeableBufferMac.cpp @@ -35,7 +35,9 @@ namespace WebCore { -static const size_t minPurgeableBufferSize = 4096; // one page +// Purgeable buffers are allocated in multiples of the page size (4KB in common CPUs) so +// it does not make sense for very small buffers. Set our minimum size to 16KB. +static const size_t minPurgeableBufferSize = 4 * 4096; PurgeableBuffer::PurgeableBuffer(char* data, size_t size) : m_data(data) @@ -143,17 +145,6 @@ bool PurgeableBuffer::wasPurged() const return false; } -void PurgeableBuffer::setPurgePriority(PurgePriority priority) -{ - if (priority == m_purgePriority) - return; - m_purgePriority = priority; - if (m_state != Volatile) - return; - m_state = NonVolatile; - makePurgeable(true); -} - const char* PurgeableBuffer::data() const { ASSERT(m_state == NonVolatile); diff --git a/WebCore/platform/network/curl/CookieJarCurl.cpp b/WebCore/platform/network/curl/CookieJarCurl.cpp index 6f8a6b7..36495d0 100644 --- a/WebCore/platform/network/curl/CookieJarCurl.cpp +++ b/WebCore/platform/network/curl/CookieJarCurl.cpp @@ -61,9 +61,11 @@ void deleteCookie(const Document*, const KURL&, const String&) // FIXME: Not yet implemented } +#if !PLATFORM(EFL) void setCookieStoragePrivateBrowsingEnabled(bool enabled) { // FIXME: Not yet implemented } +#endif } diff --git a/WebCore/platform/network/soup/SocketStreamHandle.h b/WebCore/platform/network/soup/SocketStreamHandle.h index 2ba4504..08d2d94 100644 --- a/WebCore/platform/network/soup/SocketStreamHandle.h +++ b/WebCore/platform/network/soup/SocketStreamHandle.h @@ -51,6 +51,7 @@ namespace WebCore { void connected(GSocketConnection*, GError*); void readBytes(signed long, GError*); void writeReady(); + void* id() { return m_id; } protected: virtual int platformSend(const char* data, int length); @@ -62,6 +63,7 @@ namespace WebCore { PlatformRefPtr<GOutputStream> m_outputStream; PlatformRefPtr<GSource> m_writeReadySource; char* m_readBuffer; + void* m_id; SocketStreamHandle(const KURL&, SocketStreamHandleClient*); diff --git a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp index d73b499..7f62d5a 100644 --- a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp +++ b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp @@ -48,25 +48,34 @@ namespace WebCore { // These functions immediately call the similarly named SocketStreamHandle methods. -static void connectedCallback(GSocketClient*, GAsyncResult*, SocketStreamHandle*); -static void readReadyCallback(GInputStream*, GAsyncResult*, SocketStreamHandle*); -static gboolean writeReadyCallback(GSocket*, GIOCondition, SocketStreamHandle*); +static void connectedCallback(GSocketClient*, GAsyncResult*, void*); +static void readReadyCallback(GInputStream*, GAsyncResult*, void*); +static gboolean writeReadyCallback(GSocket*, GIOCondition, void*); // Having a list of active handles means that we do not have to worry about WebCore // reference counting in GLib callbacks. Once the handle is off the active handles list // we just ignore it in the callback. We avoid a lot of extra checks and tricky // situations this way. -static Vector<SocketStreamHandle*> gActiveHandles; -bool isActiveHandle(SocketStreamHandle* handle) +static HashMap<void*, SocketStreamHandle*> gActiveHandles; +static SocketStreamHandle* getHandleFromId(void* id) { - return gActiveHandles.find(handle) != notFound; + if (!gActiveHandles.contains(id)) + return 0; + return gActiveHandles.get(id); } -void deactivateHandle(SocketStreamHandle* handle) +static void deactivateHandle(SocketStreamHandle* handle) { - size_t handleIndex = gActiveHandles.find(handle); - if (handleIndex != notFound) - gActiveHandles.remove(handleIndex); + gActiveHandles.remove(handle->id()); +} + +static void* activateHandle(SocketStreamHandle* handle) +{ + // The first id cannot be 0, because it conflicts with the HashMap emptyValue. + static gint currentHandleId = 1; + void* id = GINT_TO_POINTER(currentHandleId++); + gActiveHandles.set(id, handle); + return id; } SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client) @@ -78,10 +87,10 @@ SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient return; unsigned int port = url.hasPort() ? url.port() : 80; - gActiveHandles.append(this); + m_id = activateHandle(this); PlatformRefPtr<GSocketClient> socketClient = adoptPlatformRef(g_socket_client_new()); g_socket_client_connect_to_host_async(socketClient.get(), url.host().utf8().data(), port, 0, - reinterpret_cast<GAsyncReadyCallback>(connectedCallback), this); + reinterpret_cast<GAsyncReadyCallback>(connectedCallback), m_id); } SocketStreamHandle::~SocketStreamHandle() @@ -104,7 +113,7 @@ void SocketStreamHandle::connected(GSocketConnection* socketConnection, GError* m_readBuffer = new char[READ_BUFFER_SIZE]; g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0, - reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this); + reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id); // The client can close the handle, potentially removing the last reference. RefPtr<SocketStreamHandle> protect(this); @@ -131,7 +140,7 @@ void SocketStreamHandle::readBytes(signed long bytesRead, GError* error) m_client->didReceiveData(this, m_readBuffer, bytesRead); if (m_inputStream) // The client may have closed the connection. g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0, - reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this); + reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id); } void SocketStreamHandle::writeReady() @@ -215,7 +224,7 @@ void SocketStreamHandle::beginWaitingForSocketWritability() m_writeReadySource = adoptPlatformRef(g_socket_create_source( g_socket_connection_get_socket(m_socketConnection.get()), static_cast<GIOCondition>(G_IO_OUT), 0)); - g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), this, 0); + g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), m_id, 0); g_source_attach(m_writeReadySource.get(), 0); } @@ -228,14 +237,15 @@ void SocketStreamHandle::stopWaitingForSocketWritability() m_writeReadySource = 0; } -static void connectedCallback(GSocketClient* client, GAsyncResult* result, SocketStreamHandle* handle) +static void connectedCallback(GSocketClient* client, GAsyncResult* result, void* id) { // Always finish the connection, even if this SocketStreamHandle was deactivated earlier. GOwnPtr<GError> error; GSocketConnection* socketConnection = g_socket_client_connect_to_host_finish(client, result, &error.outPtr()); // The SocketStreamHandle has been deactivated, so just close the connection, ignoring errors. - if (!isActiveHandle(handle)) { + SocketStreamHandle* handle = getHandleFromId(id); + if (!handle) { g_io_stream_close(G_IO_STREAM(socketConnection), 0, &error.outPtr()); return; } @@ -243,20 +253,23 @@ static void connectedCallback(GSocketClient* client, GAsyncResult* result, Socke handle->connected(socketConnection, error.get()); } -static void readReadyCallback(GInputStream* stream, GAsyncResult* result, SocketStreamHandle* handle) +static void readReadyCallback(GInputStream* stream, GAsyncResult* result, void* id) { // Always finish the read, even if this SocketStreamHandle was deactivated earlier. GOwnPtr<GError> error; gssize bytesRead = g_input_stream_read_finish(stream, result, &error.outPtr()); - if (!isActiveHandle(handle)) + SocketStreamHandle* handle = getHandleFromId(id); + if (!handle) return; + handle->readBytes(bytesRead, error.get()); } -static gboolean writeReadyCallback(GSocket*, GIOCondition condition, SocketStreamHandle* handle) +static gboolean writeReadyCallback(GSocket*, GIOCondition condition, void* id) { - if (!isActiveHandle(handle)) + SocketStreamHandle* handle = getHandleFromId(id); + if (!handle) return FALSE; // G_IO_HUP and G_IO_ERR are are always active. See: diff --git a/WebCore/platform/qt/ContextMenuItemQt.cpp b/WebCore/platform/qt/ContextMenuItemQt.cpp index b91a2a7..a65e50c 100644 --- a/WebCore/platform/qt/ContextMenuItemQt.cpp +++ b/WebCore/platform/qt/ContextMenuItemQt.cpp @@ -104,6 +104,12 @@ void ContextMenuItem::setChecked(bool on) m_platformDescription.checked = on; } +bool ContextMenuItem::checked() const +{ + // FIXME - Implement + return false; +} + void ContextMenuItem::setEnabled(bool on) { m_platformDescription.enabled = on; diff --git a/WebCore/platform/qt/ContextMenuQt.cpp b/WebCore/platform/qt/ContextMenuQt.cpp index 30c4c2d..2c1a6cb 100644 --- a/WebCore/platform/qt/ContextMenuQt.cpp +++ b/WebCore/platform/qt/ContextMenuQt.cpp @@ -74,6 +74,11 @@ PlatformMenuDescription ContextMenu::releasePlatformDescription() return PlatformMenuDescription(); } +Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription) +{ + // FIXME - Implement + return Vector<ContextMenuItem>(); +} } // vim: ts=4 sw=4 et diff --git a/WebCore/platform/qt/PlatformScreenQt.cpp b/WebCore/platform/qt/PlatformScreenQt.cpp index 8221760..db34e21 100644 --- a/WebCore/platform/qt/PlatformScreenQt.cpp +++ b/WebCore/platform/qt/PlatformScreenQt.cpp @@ -58,16 +58,30 @@ int screenDepth(Widget* w) int screenDepthPerComponent(Widget* w) { + int depth = QApplication::desktop()->screen(0)->depth(); if (w) { QWebPageClient* client = w->root()->hostWindow()->platformPageClient(); if (client) { QWidget* view = client->ownerWidget(); if (view) - return view->depth(); + depth = view->depth(); } } - return QApplication::desktop()->screen(0)->depth(); + // An interface to establish the actual number of bits per color + // doesn't exist in Qt, or probably at all, so use common-sense + // values for each screen depth and assume RGB/RGBA where appropriate. + // Per http://www.w3.org/TR/css3-mediaqueries/#color, 'If different color + // components are represented by different number of bits, the smallest + // number is used.' + switch (depth) { + case 8: + return 2; + case 32: + return 8; + default: + return qRound(depth / 3); + } } bool screenIsMonochrome(Widget* w) diff --git a/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp b/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp index be3f302..990e331 100644 --- a/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp +++ b/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp @@ -300,7 +300,7 @@ int textBreakNext(TextBreakIterator* iterator) if ((iterator->m_type == UBRK_LINE && iterator->m_logAttrs[index].is_line_break) || (iterator->m_type == UBRK_WORD && (iterator->m_logAttrs[index].is_word_start || iterator->m_logAttrs[index].is_word_end)) || (iterator->m_type == UBRK_CHARACTER && iterator->m_logAttrs[index].is_cursor_position) - || (iterator->m_type == UBRK_SENTENCE && (iterator->m_logAttrs[index].is_sentence_start || iterator->m_logAttrs[index].is_sentence_end)) ) { + || (iterator->m_type == UBRK_SENTENCE && iterator->m_logAttrs[index].is_sentence_boundary)) { break; } } @@ -315,7 +315,7 @@ int textBreakPrevious(TextBreakIterator* iterator) if ((iterator->m_type == UBRK_LINE && iterator->m_logAttrs[index].is_line_break) || (iterator->m_type == UBRK_WORD && (iterator->m_logAttrs[index].is_word_start || iterator->m_logAttrs[index].is_word_end)) || (iterator->m_type == UBRK_CHARACTER && iterator->m_logAttrs[index].is_cursor_position) - || (iterator->m_type == UBRK_SENTENCE && (iterator->m_logAttrs[index].is_sentence_start || iterator->m_logAttrs[index].is_sentence_end)) ) { + || (iterator->m_type == UBRK_SENTENCE && iterator->m_logAttrs[index].is_sentence_boundary)) { break; } } diff --git a/WebCore/platform/text/gtk/TextCodecGtk.cpp b/WebCore/platform/text/gtk/TextCodecGtk.cpp index bf6afcd..9308b33 100644 --- a/WebCore/platform/text/gtk/TextCodecGtk.cpp +++ b/WebCore/platform/text/gtk/TextCodecGtk.cpp @@ -543,9 +543,28 @@ CString TextCodecGtk::encode(const UChar* characters, size_t length, Unencodable &error.outPtr()); input += bytesRead; inputLength -= bytesRead; - result.grow(size + bytesWritten); - memcpy(result.data() + size, buffer, bytesWritten); - size += bytesWritten; + if (bytesWritten > 0) { + result.grow(size + bytesWritten); + memcpy(result.data() + size, buffer, bytesWritten); + size += bytesWritten; + } + + if (error && g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_INVALID_DATA)) { + UChar codePoint = reinterpret_cast<const UChar*>(input)[0]; + UnencodableReplacementArray replacement; + int replacementLength = TextCodec::getUnencodableReplacement(codePoint, handling, replacement); + + // Consume the invalid character. + input += sizeof(UChar); + inputLength -= sizeof(UChar); + + // Append replacement string to result buffer. + result.grow(size + replacementLength); + memcpy(result.data() + size, replacement, replacementLength); + size += replacementLength; + + error.clear(); + } } while (inputLength && !error.get()); if (error) { diff --git a/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/WebCore/platform/win/ClipboardUtilitiesWin.cpp index 19888bf..eb1e659 100644 --- a/WebCore/platform/win/ClipboardUtilitiesWin.cpp +++ b/WebCore/platform/win/ClipboardUtilitiesWin.cpp @@ -86,13 +86,13 @@ static bool getWebLocData(IDataObject* dataObject, String& url, String* title) if (!hdrop) return false; - if (!DragQueryFileW(hdrop, 0, filename, ARRAYSIZE(filename))) + if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename))) goto exit; if (_wcsicmp(PathFindExtensionW(filename), L".url")) goto exit; - if (!GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, urlBuffer, ARRAYSIZE(urlBuffer), filename)) + if (!GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, urlBuffer, WTF_ARRAY_LENGTH(urlBuffer), filename)) goto exit; if (title) { diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp index f467d65..58cfe44 100644 --- a/WebCore/platform/win/ClipboardWin.cpp +++ b/WebCore/platform/win/ClipboardWin.cpp @@ -56,7 +56,7 @@ #include <wininet.h> #include <wtf/RefPtr.h> #include <wtf/text/CString.h> -#include <wtf/text/StringConcatenate.h> +#include <wtf/text/StringConcatenate.h> #include <wtf/text/StringHash.h> using namespace std; @@ -99,6 +99,7 @@ static inline FORMATETC* fileContentFormatZero() return &fileContentFormat; } +#if !OS(WINCE) static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length) { size_t writeTo = 0; @@ -112,9 +113,14 @@ static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length) } psz[writeTo] = 0; } +#endif static String filesystemPathFromUrlOrTitle(const String& url, const String& title, TCHAR* extension, bool isLink) { +#if OS(WINCE) + notImplemented(); + return String(); +#else static const size_t fsPathMaxLengthExcludingNullTerminator = MAX_PATH - 1; bool usedURL = false; WCHAR fsPathBuffer[MAX_PATH]; @@ -159,25 +165,7 @@ static String filesystemPathFromUrlOrTitle(const String& url, const String& titl String result(static_cast<UChar*>(fsPathBuffer)); result += String(static_cast<UChar*>(extension)); return result; -} - -static HGLOBAL createGlobalURLContent(const CString& content) -{ - HRESULT hr = S_OK; - HGLOBAL memObj = 0; - - char* fileContents; - - memObj = GlobalAlloc(GPTR, content.length()); - if (!memObj) - return 0; - - fileContents = (PSTR)GlobalLock(memObj); - CopyMemory(fileContents, content.data(), content.length()); - - GlobalUnlock(memObj); - - return memObj; +#endif } static HGLOBAL createGlobalImageFileContent(SharedBuffer* data) @@ -213,9 +201,13 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share else return 0; } else { +#if OS(WINCE) + notImplemented(); + return 0; +#else WCHAR tempPath[MAX_PATH]; WCHAR extension[MAX_PATH]; - if (!::GetTempPath(ARRAYSIZE(tempPath), tempPath)) + if (!::GetTempPath(WTF_ARRAY_LENGTH(tempPath), tempPath)) return 0; if (!::PathAppend(tempPath, fileName.charactersWithNullTermination())) return 0; @@ -242,6 +234,7 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share CloseHandle(tempFileHandle); if (!tempWriteSucceeded) return 0; +#endif } SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * (wcslen(filePath) + 2)); @@ -258,36 +251,6 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share return memObj; } -static HGLOBAL createGlobalUrlFileDescriptor(const String& url, const String& title, const CString& content) -{ - HRESULT hr = S_OK; - HGLOBAL memObj = 0; - String fsPath; - memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR)); - if (!memObj) - return 0; - - FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj); - memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR)); - fgd->cItems = 1; - fgd->fgd[0].dwFlags = FD_FILESIZE; - fgd->fgd[0].nFileSizeLow = content.length(); - fsPath = filesystemPathFromUrlOrTitle(url, title, L".URL", true); - - if (fsPath.length() <= 0) { - GlobalUnlock(memObj); - GlobalFree(memObj); - return 0; - } - - int maxSize = min(fsPath.length(), ARRAYSIZE(fgd->fgd[0].cFileName)); - CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar)); - GlobalUnlock(memObj); - - return memObj; -} - - static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& title, CachedImage* image) { ASSERT_ARG(image, image); @@ -322,7 +285,7 @@ static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& return 0; } - int maxSize = min(fsPath.length(), ARRAYSIZE(fgd->fgd[0].cFileName)); + int maxSize = min(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName)); CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar)); GlobalUnlock(memObj); @@ -355,11 +318,13 @@ static HRESULT writeFileToDataObject(IDataObject* dataObject, HGLOBAL fileDescri if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE))) goto exit; +#if PLATFORM(CF) // HDROP if (hDropContent) { medium.hGlobal = hDropContent; hr = dataObject->SetData(cfHDropFormat(), &medium, TRUE); } +#endif exit: if (FAILED(hr)) { @@ -567,6 +532,10 @@ HashSet<String> ClipboardWin::types() const PassRefPtr<FileList> ClipboardWin::files() const { +#if OS(WINCE) + notImplemented(); + return 0; +#else RefPtr<FileList> files = FileList::create(); if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable) return files.release(); @@ -585,7 +554,7 @@ PassRefPtr<FileList> ClipboardWin::files() const WCHAR filename[MAX_PATH]; UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0); for (UINT i = 0; i < fileCount; i++) { - if (!DragQueryFileW(hdrop, i, filename, ARRAYSIZE(filename))) + if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename))) continue; files->append(File::create(reinterpret_cast<UChar*>(filename))); } @@ -593,6 +562,7 @@ PassRefPtr<FileList> ClipboardWin::files() const GlobalUnlock(medium.hGlobal); ReleaseStgMedium(&medium); return files.release(); +#endif } void ClipboardWin::setDragImage(CachedImage* image, Node *node, const IntPoint &loc) @@ -725,16 +695,36 @@ void ClipboardWin::writeURL(const KURL& kurl, const String& titleStr, Frame*) String url = kurl.string(); ASSERT(url.containsOnlyASCII()); // KURL::string() is URL encoded. + String fsPath = filesystemPathFromUrlOrTitle(url, titleStr, L".URL", true); CString content = makeString("[InternetShortcut]\r\nURL=", url, "\r\n").ascii(); - HGLOBAL urlFileDescriptor = createGlobalUrlFileDescriptor(url, titleStr, content); + if (fsPath.length() <= 0) + return; + + HGLOBAL urlFileDescriptor = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR)); if (!urlFileDescriptor) return; - HGLOBAL urlFileContent = createGlobalURLContent(content); + + HGLOBAL urlFileContent = GlobalAlloc(GPTR, content.length()); if (!urlFileContent) { GlobalFree(urlFileDescriptor); return; } + + FILEGROUPDESCRIPTOR* fgd = static_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(urlFileDescriptor)); + ZeroMemory(fgd, sizeof(FILEGROUPDESCRIPTOR)); + fgd->cItems = 1; + fgd->fgd[0].dwFlags = FD_FILESIZE; + fgd->fgd[0].nFileSizeLow = content.length(); + + unsigned maxSize = min(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName)); + CopyMemory(fgd->fgd[0].cFileName, fsPath.characters(), maxSize * sizeof(UChar)); + GlobalUnlock(urlFileDescriptor); + + char* fileContents = static_cast<char*>(GlobalLock(urlFileContent)); + CopyMemory(fileContents, content.data(), content.length()); + GlobalUnlock(urlFileContent); + writeFileToDataObject(m_writableDataObject.get(), urlFileDescriptor, urlFileContent, 0); } diff --git a/WebCore/platform/win/ContextMenuItemWin.cpp b/WebCore/platform/win/ContextMenuItemWin.cpp index ade0db0..d2ce76d 100644 --- a/WebCore/platform/win/ContextMenuItemWin.cpp +++ b/WebCore/platform/win/ContextMenuItemWin.cpp @@ -184,6 +184,12 @@ void ContextMenuItem::setChecked(bool checked) } } +bool ContextMenuItem::checked() const +{ + // FIXME - Implement + return false; +} + void ContextMenuItem::setEnabled(bool enabled) { m_platformDescription->fMask |= MIIM_STATE; diff --git a/WebCore/platform/win/ContextMenuWin.cpp b/WebCore/platform/win/ContextMenuWin.cpp index 5260866..82511e4 100644 --- a/WebCore/platform/win/ContextMenuWin.cpp +++ b/WebCore/platform/win/ContextMenuWin.cpp @@ -155,4 +155,10 @@ HMENU ContextMenu::releasePlatformDescription() return description; } +Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription) +{ + // FIXME - Implement + return Vector<ContextMenuItem>(); +} + } diff --git a/WebCore/platform/win/DragDataWin.cpp b/WebCore/platform/win/DragDataWin.cpp index 05f9103..56345e2 100644 --- a/WebCore/platform/win/DragDataWin.cpp +++ b/WebCore/platform/win/DragDataWin.cpp @@ -72,7 +72,7 @@ void DragData::asFilenames(Vector<String>& result) const const unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0); for (unsigned i = 0; i < numFiles; i++) { - if (!DragQueryFileW(hdrop, 0, filename, ARRAYSIZE(filename))) + if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename))) continue; result.append((UChar*)filename); } diff --git a/WebCore/platform/win/FileSystemWin.cpp b/WebCore/platform/win/FileSystemWin.cpp index 2cca08c..cef7196 100644 --- a/WebCore/platform/win/FileSystemWin.cpp +++ b/WebCore/platform/win/FileSystemWin.cpp @@ -274,7 +274,7 @@ bool safeCreateFile(const String& path, CFDataRef data) { // Create a temporary file. WCHAR tempDirPath[MAX_PATH]; - if (!GetTempPathW(ARRAYSIZE(tempDirPath), tempDirPath)) + if (!GetTempPathW(WTF_ARRAY_LENGTH(tempDirPath), tempDirPath)) return false; WCHAR tempPath[MAX_PATH]; diff --git a/WebCore/platform/win/WCDataObject.cpp b/WebCore/platform/win/WCDataObject.cpp index aaa41cf..6b4c859 100644 --- a/WebCore/platform/win/WCDataObject.cpp +++ b/WebCore/platform/win/WCDataObject.cpp @@ -285,6 +285,7 @@ void WCDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC { switch(pMedSrc->tymed) { +#if !OS(WINCE) case TYMED_HGLOBAL: pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal,pFmtSrc->cfFormat, 0); break; @@ -300,6 +301,7 @@ void WCDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC case TYMED_FILE: pMedSrc->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName,pFmtSrc->cfFormat, 0); break; +#endif case TYMED_ISTREAM: pMedDest->pstm = pMedSrc->pstm; pMedSrc->pstm->AddRef(); diff --git a/WebCore/plugins/gtk/PluginPackageGtk.cpp b/WebCore/plugins/gtk/PluginPackageGtk.cpp index d0218fb..a702296 100644 --- a/WebCore/plugins/gtk/PluginPackageGtk.cpp +++ b/WebCore/plugins/gtk/PluginPackageGtk.cpp @@ -74,7 +74,8 @@ bool PluginPackage::fetchInfo() gchar** mimeDescs = g_strsplit(types, ";", -1); for (int i = 0; mimeDescs[i] && mimeDescs[i][0]; i++) { - gchar** mimeData = g_strsplit(mimeDescs[i], ":", 3); + GOwnPtr<char> mime(g_utf8_strdown(mimeDescs[i], -1)); + gchar** mimeData = g_strsplit(mime.get(), ":", 3); if (g_strv_length(mimeData) < 3) { g_strfreev(mimeData); continue; diff --git a/WebCore/plugins/gtk/PluginViewGtk.cpp b/WebCore/plugins/gtk/PluginViewGtk.cpp index 80641a1..6608f6c 100644 --- a/WebCore/plugins/gtk/PluginViewGtk.cpp +++ b/WebCore/plugins/gtk/PluginViewGtk.cpp @@ -66,6 +66,7 @@ #include <gtk/gtk.h> #if defined(XP_UNIX) +#include "RefPtrCairo.h" #include "gtk2xtbin.h" #define Bool int // this got undefined somewhere #define Status int // ditto @@ -195,18 +196,18 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) exposedRect.intersect(frameRect()); exposedRect.move(-frameRect().x(), -frameRect().y()); - PlatformRefPtr<cairo_surface_t> drawableSurface = adoptPlatformRef(cairo_xlib_surface_create(display, - m_drawable, - m_visual, - m_windowRect.width(), - m_windowRect.height())); + RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(display, + m_drawable, + m_visual, + m_windowRect.width(), + m_windowRect.height())); if (m_isTransparent) { // If we have a 32 bit drawable and the plugin wants transparency, // we'll clear the exposed area to transparent first. Otherwise, // we'd end up with junk in there from the last paint, or, worse, // uninitialized data. - PlatformRefPtr<cairo_t> cr = adoptPlatformRef(cairo_create(drawableSurface.get())); + RefPtr<cairo_t> cr = adoptRef(cairo_create(drawableSurface.get())); if (!(cairo_surface_get_content(drawableSurface.get()) & CAIRO_CONTENT_ALPHA)) { // Attempt to fake it when we don't have an alpha channel on our diff --git a/WebCore/plugins/mac/PluginViewMac.mm b/WebCore/plugins/mac/PluginViewMac.mm index aef9420..7119f0d 100644 --- a/WebCore/plugins/mac/PluginViewMac.mm +++ b/WebCore/plugins/mac/PluginViewMac.mm @@ -725,30 +725,11 @@ static int modifiersForEvent(UIEventWithKeyState* event) #endif #ifndef NP_NO_CARBON -static bool tigerOrBetter() -{ - static SInt32 systemVersion = 0; - - if (!systemVersion) { - if (Gestalt(gestaltSystemVersion, &systemVersion) != noErr) - return false; - } - - return systemVersion >= 0x1040; -} -#endif - -#ifndef NP_NO_CARBON Point PluginView::globalMousePosForPlugin() const { Point pos; GetGlobalMouse(&pos); - float scaleFactor = tigerOrBetter() ? HIGetScaleFactor() : 1; - - pos.h = short(pos.h * scaleFactor); - pos.v = short(pos.v * scaleFactor); - #if PLATFORM(WX) // make sure the titlebar/toolbar size is included WindowRef windowRef = nativeWindowFor(platformPluginWidget()); diff --git a/WebCore/plugins/qt/PluginPackageQt.cpp b/WebCore/plugins/qt/PluginPackageQt.cpp index e7058c7..ce07faf 100644 --- a/WebCore/plugins/qt/PluginPackageQt.cpp +++ b/WebCore/plugins/qt/PluginPackageQt.cpp @@ -69,10 +69,10 @@ bool PluginPackage::fetchInfo() void PluginPackage::setMIMEDescription(const String& mimeDescription) { - m_fullMIMEDescription = mimeDescription; + m_fullMIMEDescription = mimeDescription.lower(); Vector<String> types; - mimeDescription.split(UChar(';'), false, types); + mimeDescription.lower().split(UChar(';'), false, types); for (unsigned i = 0; i < types.size(); ++i) { Vector<String> mime; types[i].split(UChar(':'), true, mime); diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp index 9b4e595..fdbe552 100644 --- a/WebCore/plugins/qt/PluginViewQt.cpp +++ b/WebCore/plugins/qt/PluginViewQt.cpp @@ -784,7 +784,7 @@ bool PluginView::platformGetValue(NPNVariable variable, void* value, NPError* re void PluginView::invalidateRect(const IntRect& rect) { -#if USE(ACCELERATED_COMPOSITING) +#if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER) if (m_platformLayer) { m_platformLayer->update(QRectF(rect)); return; @@ -918,7 +918,7 @@ bool PluginView::platformStart() setPlatformWidget(0); m_pluginDisplay = getPluginDisplay(); -#if USE(ACCELERATED_COMPOSITING) +#if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER) if (m_parentFrame->page()->chrome()->client()->allowsAcceleratedCompositing() && m_parentFrame->page()->settings() && m_parentFrame->page()->settings()->acceleratedCompositingEnabled()) { diff --git a/WebCore/rendering/AutoTableLayout.cpp b/WebCore/rendering/AutoTableLayout.cpp index bf1bcd9..bb0df0b 100644 --- a/WebCore/rendering/AutoTableLayout.cpp +++ b/WebCore/rendering/AutoTableLayout.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 Lars Knoll (knoll@kde.org) * (C) 2002 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006, 2008, 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 @@ -34,9 +34,7 @@ namespace WebCore { AutoTableLayout::AutoTableLayout(RenderTable* table) : TableLayout(table) , m_hasPercent(false) - , m_percentagesDirty(true) - , m_effWidthDirty(true) - , m_totalPercent(0) + , m_effectiveLogicalWidthDirty(true) { } @@ -44,21 +42,14 @@ AutoTableLayout::~AutoTableLayout() { } -/* recalculates the full structure needed to do layouting and minmax calculations. - This is usually calculated on the fly, but needs to be done fully when table cells change - dynamically -*/ void AutoTableLayout::recalcColumn(int effCol) { - Layout &l = m_layoutStruct[effCol]; - - RenderObject* child = m_table->firstChild(); - // first we iterate over all rows. + Layout& columnLayout = m_layoutStruct[effCol]; RenderTableCell* fixedContributor = 0; RenderTableCell* maxContributor = 0; - while (child) { + for (RenderObject* child = m_table->firstChild(); child; child = child->nextSibling()) { if (child->isTableCol()) toRenderTableCol(child)->computePreferredLogicalWidths(); else if (child->isTableSection()) { @@ -70,142 +61,131 @@ void AutoTableLayout::recalcColumn(int effCol) bool cellHasContent = cell && !current.inColSpan && (cell->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding()); if (cellHasContent) - l.emptyCellsOnly = false; + columnLayout.emptyCellsOnly = false; - if (current.inColSpan) + if (current.inColSpan || !cell) continue; - if (cell && cell->colSpan() == 1) { + + if (cell->colSpan() == 1) { // A cell originates in this column. Ensure we have // a min/max width of at least 1px for this column now. - l.minWidth = max(l.minWidth, cellHasContent ? 1 : 0); - l.maxWidth = max(l.maxWidth, 1); + columnLayout.minLogicalWidth = max(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0); + columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, 1); if (cell->preferredLogicalWidthsDirty()) cell->computePreferredLogicalWidths(); - l.minWidth = max(cell->minPreferredLogicalWidth(), l.minWidth); - if (cell->maxPreferredLogicalWidth() > l.maxWidth) { - l.maxWidth = cell->maxPreferredLogicalWidth(); + columnLayout.minLogicalWidth = max(cell->minPreferredLogicalWidth(), columnLayout.minLogicalWidth); + if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) { + columnLayout.maxLogicalWidth = cell->maxPreferredLogicalWidth(); maxContributor = cell; } - Length w = cell->styleOrColWidth(); + Length cellLogicalWidth = cell->styleOrColLogicalWidth(); // FIXME: What is this arbitrary value? - if (w.rawValue() > 32760) - w.setRawValue(32760); - if (w.isNegative()) - w.setValue(0); - switch (w.type()) { + if (cellLogicalWidth.rawValue() > 32760) + cellLogicalWidth.setRawValue(32760); + if (cellLogicalWidth.isNegative()) + cellLogicalWidth.setValue(0); + switch (cellLogicalWidth.type()) { case Fixed: // ignore width=0 - if (w.value() > 0 && (int)l.width.type() != Percent) { - int wval = cell->computeBorderBoxLogicalWidth(w.value()); - if (l.width.isFixed()) { + if (cellLogicalWidth.value() > 0 && columnLayout.logicalWidth.type() != Percent) { + int logicalWidth = cell->computeBorderBoxLogicalWidth(cellLogicalWidth.value()); + if (columnLayout.logicalWidth.isFixed()) { // Nav/IE weirdness - if ((wval > l.width.value()) || - ((l.width.value() == wval) && (maxContributor == cell))) { - l.width.setValue(wval); + if ((logicalWidth > columnLayout.logicalWidth.value()) || + ((columnLayout.logicalWidth.value() == logicalWidth) && (maxContributor == cell))) { + columnLayout.logicalWidth.setValue(logicalWidth); fixedContributor = cell; } } else { - l.width.setValue(Fixed, wval); + columnLayout.logicalWidth.setValue(Fixed, logicalWidth); fixedContributor = cell; } } break; case Percent: m_hasPercent = true; - if (w.isPositive() && (!l.width.isPercent() || w.rawValue() > l.width.rawValue())) - l.width = w; + if (cellLogicalWidth.isPositive() && (!columnLayout.logicalWidth.isPercent() || cellLogicalWidth.rawValue() > columnLayout.logicalWidth.rawValue())) + columnLayout.logicalWidth = cellLogicalWidth; break; case Relative: // FIXME: Need to understand this case and whether it makes sense to compare values // which are not necessarily of the same type. - if (w.isAuto() || (w.isRelative() && w.value() > l.width.rawValue())) - l.width = w; + if (cellLogicalWidth.isAuto() || (cellLogicalWidth.isRelative() && cellLogicalWidth.value() > columnLayout.logicalWidth.rawValue())) + columnLayout.logicalWidth = cellLogicalWidth; default: break; } - } else { - if (cell && (!effCol || section->primaryCellAt(i, effCol-1) != cell)) { - // This spanning cell originates in this column. Ensure we have - // a min/max width of at least 1px for this column now. - l.minWidth = max(l.minWidth, cellHasContent ? 1 : 0); - l.maxWidth = max(l.maxWidth, 1); - insertSpanCell(cell); - } + } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) { + // This spanning cell originates in this column. Ensure we have + // a min/max width of at least 1px for this column now. + columnLayout.minLogicalWidth = max(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0); + columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, 1); + insertSpanCell(cell); } } } - child = child->nextSibling(); } // Nav/IE weirdness - if (l.width.isFixed()) { - if (m_table->document()->inQuirksMode() && l.maxWidth > l.width.value() && fixedContributor != maxContributor) { - l.width = Length(); + if (columnLayout.logicalWidth.isFixed()) { + if (m_table->document()->inQuirksMode() && columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { + columnLayout.logicalWidth = Length(); fixedContributor = 0; } } - l.maxWidth = max(l.maxWidth, l.minWidth); - - // ### we need to add col elements as well + columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, columnLayout.minLogicalWidth); } void AutoTableLayout::fullRecalc() { - m_percentagesDirty = true; m_hasPercent = false; - m_effWidthDirty = true; + m_effectiveLogicalWidthDirty = true; int nEffCols = m_table->numEffCols(); m_layoutStruct.resize(nEffCols); m_layoutStruct.fill(Layout()); m_spanCells.fill(0); - RenderObject *child = m_table->firstChild(); - Length grpWidth; - int cCol = 0; - while (child) { - if (child->isTableCol()) { - RenderTableCol *col = toRenderTableCol(child); - int span = col->span(); - if (col->firstChild()) { - grpWidth = col->style()->width(); - } else { - Length w = col->style()->width(); - if (w.isAuto()) - w = grpWidth; - if ((w.isFixed() || w.isPercent()) && w.isZero()) - w = Length(); - int cEffCol = m_table->colToEffCol(cCol); - if (!w.isAuto() && span == 1 && cEffCol < nEffCols) { - if (m_table->spanOfEffCol(cEffCol) == 1) { - m_layoutStruct[cEffCol].width = w; - if (w.isFixed() && m_layoutStruct[cEffCol].maxWidth < w.value()) - m_layoutStruct[cEffCol].maxWidth = w.value(); - } - } - cCol += span; + RenderObject* child = m_table->firstChild(); + Length groupLogicalWidth; + int currentColumn = 0; + while (child && child->isTableCol()) { + RenderTableCol* col = toRenderTableCol(child); + int span = col->span(); + if (col->firstChild()) + groupLogicalWidth = col->style()->logicalWidth(); + else { + Length colLogicalWidth = col->style()->logicalWidth(); + if (colLogicalWidth.isAuto()) + colLogicalWidth = groupLogicalWidth; + if ((colLogicalWidth.isFixed() || colLogicalWidth.isPercent()) && colLogicalWidth.isZero()) + colLogicalWidth = Length(); + int effCol = m_table->colToEffCol(currentColumn); + if (!colLogicalWidth.isAuto() && span == 1 && effCol < nEffCols && m_table->spanOfEffCol(effCol) == 1) { + m_layoutStruct[effCol].logicalWidth = colLogicalWidth; + if (colLogicalWidth.isFixed() && m_layoutStruct[effCol].maxLogicalWidth < colLogicalWidth.value()) + m_layoutStruct[effCol].maxLogicalWidth = colLogicalWidth.value(); } - } else { - break; + currentColumn += span; } - RenderObject *next = child->firstChild(); + RenderObject* next = child->firstChild(); if (!next) next = child->nextSibling(); if (!next && child->parent()->isTableCol()) { next = child->parent()->nextSibling(); - grpWidth = Length(); + groupLogicalWidth = Length(); } child = next; } - for (int i = 0; i < nEffCols; i++) recalcColumn(i); } +// FIXME: This needs to be adapted for vertical writing modes. static bool shouldScaleColumns(RenderTable* table) { // A special case. If this table is not fixed width and contained inside @@ -243,7 +223,7 @@ void AutoTableLayout::computePreferredLogicalWidths(int& minWidth, int& maxWidth { fullRecalc(); - int spanMaxWidth = calcEffectiveWidth(); + int spanMaxLogicalWidth = calcEffectiveLogicalWidth(); minWidth = 0; maxWidth = 0; float maxPercent = 0; @@ -255,17 +235,17 @@ void AutoTableLayout::computePreferredLogicalWidths(int& minWidth, int& maxWidth const int epsilon = 1; int remainingPercent = 100 * percentScaleFactor; - for (unsigned int i = 0; i < m_layoutStruct.size(); i++) { - minWidth += m_layoutStruct[i].effMinWidth; - maxWidth += m_layoutStruct[i].effMaxWidth; + for (size_t i = 0; i < m_layoutStruct.size(); ++i) { + minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; + maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; if (scaleColumns) { - if (m_layoutStruct[i].effWidth.isPercent()) { - int percent = min(m_layoutStruct[i].effWidth.rawValue(), remainingPercent); - float pw = static_cast<float>(m_layoutStruct[i].effMaxWidth) * 100 * percentScaleFactor / max(percent, epsilon); - maxPercent = max(pw, maxPercent); + if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { + int percent = min(m_layoutStruct[i].effectiveLogicalWidth.rawValue(), remainingPercent); + float logicalWidth = static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) * 100 * percentScaleFactor / max(percent, epsilon); + maxPercent = max(logicalWidth, maxPercent); remainingPercent -= percent; } else - maxNonPercent += m_layoutStruct[i].effMaxWidth; + maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; } } @@ -275,15 +255,15 @@ void AutoTableLayout::computePreferredLogicalWidths(int& minWidth, int& maxWidth maxWidth = max(maxWidth, static_cast<int>(min(maxPercent, INT_MAX / 2.0f))); } - maxWidth = max(maxWidth, spanMaxWidth); - - int bs = m_table->bordersPaddingAndSpacing(); - minWidth += bs; - maxWidth += bs; + maxWidth = max(maxWidth, spanMaxLogicalWidth); - Length tw = m_table->style()->width(); - if (tw.isFixed() && tw.value() > 0) { - minWidth = max(minWidth, tw.value()); + int bordersPaddingAndSpacing = m_table->bordersPaddingAndSpacingInRowDirection(); + minWidth += bordersPaddingAndSpacing; + maxWidth += bordersPaddingAndSpacing; + + Length tableLogicalWidth = m_table->style()->logicalWidth(); + if (tableLogicalWidth.isFixed() && tableLogicalWidth.value() > 0) { + minWidth = max(minWidth, tableLogicalWidth.value()); maxWidth = minWidth; } } @@ -292,50 +272,52 @@ void AutoTableLayout::computePreferredLogicalWidths(int& minWidth, int& maxWidth This method takes care of colspans. effWidth is the same as width for cells without colspans. If we have colspans, they get modified. */ -int AutoTableLayout::calcEffectiveWidth() +int AutoTableLayout::calcEffectiveLogicalWidth() { - float tMaxWidth = 0; + float maxLogicalWidth = 0; - unsigned int nEffCols = m_layoutStruct.size(); - int hspacing = m_table->hBorderSpacing(); + size_t nEffCols = m_layoutStruct.size(); + int spacingInRowDirection = m_table->hBorderSpacing(); - for (unsigned int i = 0; i < nEffCols; i++) { - m_layoutStruct[i].effWidth = m_layoutStruct[i].width; - m_layoutStruct[i].effMinWidth = m_layoutStruct[i].minWidth; - m_layoutStruct[i].effMaxWidth = m_layoutStruct[i].maxWidth; + for (size_t i = 0; i < nEffCols; ++i) { + m_layoutStruct[i].effectiveLogicalWidth = m_layoutStruct[i].logicalWidth; + m_layoutStruct[i].effectiveMinLogicalWidth = m_layoutStruct[i].minLogicalWidth; + m_layoutStruct[i].effectiveMaxLogicalWidth = m_layoutStruct[i].maxLogicalWidth; } - for (unsigned int i = 0; i < m_spanCells.size(); i++) { - RenderTableCell *cell = m_spanCells[i]; + for (size_t i = 0; i < m_spanCells.size(); ++i) { + RenderTableCell* cell = m_spanCells[i]; if (!cell) break; + int span = cell->colSpan(); - Length w = cell->styleOrColWidth(); - if (!w.isRelative() && w.isZero()) - w = Length(); // make it Auto + Length cellLogicalWidth = cell->styleOrColLogicalWidth(); + if (!cellLogicalWidth.isRelative() && cellLogicalWidth.isZero()) + cellLogicalWidth = Length(); // make it Auto - int col = m_table->colToEffCol(cell->col()); - unsigned int lastCol = col; - int cMinWidth = cell->minPreferredLogicalWidth() + hspacing; - float cMaxWidth = cell->maxPreferredLogicalWidth() + hspacing; + int effCol = m_table->colToEffCol(cell->col()); + size_t lastCol = effCol; + int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRowDirection; + float cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRowDirection; int totalPercent = 0; - int minWidth = 0; - float maxWidth = 0; + int spanMinLogicalWidth = 0; + float spanMaxLogicalWidth = 0; bool allColsArePercent = true; bool allColsAreFixed = true; bool haveAuto = false; bool spanHasEmptyCellsOnly = true; int fixedWidth = 0; while (lastCol < nEffCols && span > 0) { - switch (m_layoutStruct[lastCol].width.type()) { + Layout& columnLayout = m_layoutStruct[lastCol]; + switch (columnLayout.logicalWidth.type()) { case Percent: - totalPercent += m_layoutStruct[lastCol].width.rawValue(); + totalPercent += columnLayout.logicalWidth.rawValue(); allColsAreFixed = false; break; case Fixed: - if (m_layoutStruct[lastCol].width.value() > 0) { - fixedWidth += m_layoutStruct[lastCol].width.value(); + if (columnLayout.logicalWidth.value() > 0) { + fixedWidth += columnLayout.logicalWidth.value(); allColsArePercent = false; // IE resets effWidth to Auto here, but this breaks the konqueror about page and seems to be some bad // legacy behaviour anyway. mozilla doesn't do this so I decided we don't neither. @@ -353,116 +335,112 @@ int AutoTableLayout::calcEffectiveWidth() // <tr><td>1</td><td colspan=2>2-3</tr> // <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr> // </table> - if (!m_layoutStruct[lastCol].effWidth.isPercent()) { - m_layoutStruct[lastCol].effWidth = Length(); + if (!columnLayout.effectiveLogicalWidth.isPercent()) { + columnLayout.effectiveLogicalWidth = Length(); allColsArePercent = false; - } - else - totalPercent += m_layoutStruct[lastCol].effWidth.rawValue(); + } else + totalPercent += columnLayout.effectiveLogicalWidth.rawValue(); allColsAreFixed = false; } - if (!m_layoutStruct[lastCol].emptyCellsOnly) + if (!columnLayout.emptyCellsOnly) spanHasEmptyCellsOnly = false; span -= m_table->spanOfEffCol(lastCol); - minWidth += m_layoutStruct[lastCol].effMinWidth; - maxWidth += m_layoutStruct[lastCol].effMaxWidth; + spanMinLogicalWidth += columnLayout.effectiveMinLogicalWidth; + spanMaxLogicalWidth += columnLayout.effectiveMaxLogicalWidth; lastCol++; - cMinWidth -= hspacing; - cMaxWidth -= hspacing; + cellMinLogicalWidth -= spacingInRowDirection; + cellMaxLogicalWidth -= spacingInRowDirection; } // adjust table max width if needed - if (w.isPercent()) { - if (totalPercent > w.rawValue() || allColsArePercent) { + if (cellLogicalWidth.isPercent()) { + if (totalPercent > cellLogicalWidth.rawValue() || allColsArePercent) { // can't satify this condition, treat as variable - w = Length(); + cellLogicalWidth = Length(); } else { - float spanMax = max(maxWidth, cMaxWidth); - tMaxWidth = max(tMaxWidth, spanMax * 100 * percentScaleFactor / w.rawValue()); + maxLogicalWidth = max(maxLogicalWidth, max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 * percentScaleFactor / cellLogicalWidth.rawValue()); // all non percent columns in the span get percent values to sum up correctly. - int percentMissing = w.rawValue() - totalPercent; + int percentMissing = cellLogicalWidth.rawValue() - totalPercent; float totalWidth = 0; - for (unsigned int pos = col; pos < lastCol; pos++) { - if (!(m_layoutStruct[pos].effWidth.isPercent())) - totalWidth += m_layoutStruct[pos].effMaxWidth; + for (unsigned pos = effCol; pos < lastCol; ++pos) { + if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) + totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWidth; } - for (unsigned int pos = col; pos < lastCol && totalWidth > 0; pos++) { - if (!(m_layoutStruct[pos].effWidth.isPercent())) { - int percent = static_cast<int>(percentMissing * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / totalWidth); - totalWidth -= m_layoutStruct[pos].effMaxWidth; + for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++pos) { + if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) { + int percent = static_cast<int>(percentMissing * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / totalWidth); + totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth; percentMissing -= percent; if (percent > 0) - m_layoutStruct[pos].effWidth.setRawValue(Percent, percent); + m_layoutStruct[pos].effectiveLogicalWidth.setRawValue(Percent, percent); else - m_layoutStruct[pos].effWidth = Length(); + m_layoutStruct[pos].effectiveLogicalWidth = Length(); } } - } } // make sure minWidth and maxWidth of the spanning cell are honoured - if (cMinWidth > minWidth) { + if (cellMinLogicalWidth > spanMinLogicalWidth) { if (allColsAreFixed) { - for (unsigned int pos = col; fixedWidth > 0 && pos < lastCol; pos++) { - int w = max(m_layoutStruct[pos].effMinWidth, cMinWidth * m_layoutStruct[pos].width.value() / fixedWidth); - fixedWidth -= m_layoutStruct[pos].width.value(); - cMinWidth -= w; - m_layoutStruct[pos].effMinWidth = w; + for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++pos) { + int cellLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, cellMinLogicalWidth * m_layoutStruct[pos].logicalWidth.value() / fixedWidth); + fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); + cellMinLogicalWidth -= cellLogicalWidth; + m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWidth; } - } else { - float maxw = maxWidth; - int minw = minWidth; + float remainingMaxLogicalWidth = spanMaxLogicalWidth; + int remainingMinLogicalWidth = spanMinLogicalWidth; // Give min to variable first, to fixed second, and to others third. - for (unsigned int pos = col; maxw >= 0 && pos < lastCol; pos++) { - if (m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth) { - int w = max(m_layoutStruct[pos].effMinWidth, m_layoutStruct[pos].width.value()); - fixedWidth -= m_layoutStruct[pos].width.value(); - minw -= m_layoutStruct[pos].effMinWidth; - maxw -= m_layoutStruct[pos].effMaxWidth; - cMinWidth -= w; - m_layoutStruct[pos].effMinWidth = w; + for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol; ++pos) { + if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth) { + int colMinLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value()); + fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); + remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth; + remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth; + cellMinLogicalWidth -= colMinLogicalWidth; + m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLogicalWidth; } } - for (unsigned int pos = col; maxw >= 0 && pos < lastCol && minw < cMinWidth; pos++) { - if (!(m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth)) { - int w = max(m_layoutStruct[pos].effMinWidth, static_cast<int>(maxw ? cMinWidth * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / maxw : cMinWidth)); - w = min(m_layoutStruct[pos].effMinWidth+(cMinWidth-minw), w); - - maxw -= m_layoutStruct[pos].effMaxWidth; - minw -= m_layoutStruct[pos].effMinWidth; - cMinWidth -= w; - m_layoutStruct[pos].effMinWidth = w; + for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) { + if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth)) { + int colMinLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMinLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / remainingMaxLogicalWidth : cellMinLogicalWidth)); + colMinLogicalWidth = min(m_layoutStruct[pos].effectiveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colMinLogicalWidth); + remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth; + remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth; + cellMinLogicalWidth -= colMinLogicalWidth; + m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLogicalWidth; } } } } - if (!(w.isPercent())) { - if (cMaxWidth > maxWidth) { - for (unsigned int pos = col; maxWidth >= 0 && pos < lastCol; pos++) { - int w = max(m_layoutStruct[pos].effMaxWidth, static_cast<int>(maxWidth ? cMaxWidth * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / maxWidth : cMaxWidth)); - maxWidth -= m_layoutStruct[pos].effMaxWidth; - cMaxWidth -= w; - m_layoutStruct[pos].effMaxWidth = w; + if (!cellLogicalWidth.isPercent()) { + if (cellMaxLogicalWidth > spanMaxLogicalWidth) { + for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < lastCol; ++pos) { + int colMaxLogicalWidth = max(m_layoutStruct[pos].effectiveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogicalWidth : cellMaxLogicalWidth)); + spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth; + cellMaxLogicalWidth -= colMaxLogicalWidth; + m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogicalWidth; } } } else { - for (unsigned int pos = col; pos < lastCol; pos++) - m_layoutStruct[pos].maxWidth = max(m_layoutStruct[pos].maxWidth, m_layoutStruct[pos].minWidth); + for (unsigned pos = effCol; pos < lastCol; ++pos) + m_layoutStruct[pos].maxLogicalWidth = max(m_layoutStruct[pos].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth); } // treat span ranges consisting of empty cells only as if they had content - if (spanHasEmptyCellsOnly) - for (unsigned int pos = col; pos < lastCol; pos++) + if (spanHasEmptyCellsOnly) { + for (unsigned pos = effCol; pos < lastCol; ++pos) m_layoutStruct[pos].emptyCellsOnly = false; + } } - m_effWidthDirty = false; + m_effectiveLogicalWidthDirty = false; - return static_cast<int>(min(tMaxWidth, INT_MAX / 2.0f)); + return static_cast<int>(min(maxLogicalWidth, INT_MAX / 2.0f)); } /* gets all cells that originate in a column and have a cellspan > 1 @@ -470,6 +448,7 @@ int AutoTableLayout::calcEffectiveWidth() */ void AutoTableLayout::insertSpanCell(RenderTableCell *cell) { + ASSERT_ARG(cell, cell && cell->colSpan() != 1); if (!cell || cell->colSpan() == 1) return; @@ -498,17 +477,17 @@ void AutoTableLayout::layout() return; #endif // table layout based on the values collected in the layout structure. - int tableWidth = m_table->width() - m_table->bordersPaddingAndSpacing(); - int available = tableWidth; - int nEffCols = m_table->numEffCols(); + int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection(); + int available = tableLogicalWidth; + size_t nEffCols = m_table->numEffCols(); - if (nEffCols != (int)m_layoutStruct.size()) { + if (nEffCols != m_layoutStruct.size()) { fullRecalc(); nEffCols = m_table->numEffCols(); } - if (m_effWidthDirty) - calcEffectiveWidth(); + if (m_effectiveLogicalWidthDirty) + calcEffectiveLogicalWidth(); bool havePercent = false; int totalRelative = 0; @@ -518,35 +497,35 @@ void AutoTableLayout::layout() float totalFixed = 0; int totalPercent = 0; int allocAuto = 0; - int numAutoEmptyCellsOnly = 0; + unsigned numAutoEmptyCellsOnly = 0; // fill up every cell with its minWidth - for (int i = 0; i < nEffCols; i++) { - int w = m_layoutStruct[i].effMinWidth; - m_layoutStruct[i].calcWidth = w; - available -= w; - Length& width = m_layoutStruct[i].effWidth; - switch (width.type()) { + for (size_t i = 0; i < nEffCols; ++i) { + int cellLogicalWidth = m_layoutStruct[i].effectiveMinLogicalWidth; + m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; + available -= cellLogicalWidth; + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + switch (logicalWidth.type()) { case Percent: havePercent = true; - totalPercent += width.rawValue(); + totalPercent += logicalWidth.rawValue(); break; case Relative: - totalRelative += width.value(); + totalRelative += logicalWidth.value(); break; case Fixed: numFixed++; - totalFixed += m_layoutStruct[i].effMaxWidth; + totalFixed += m_layoutStruct[i].effectiveMaxLogicalWidth; // fall through break; case Auto: case Static: - if (m_layoutStruct[i].emptyCellsOnly) - numAutoEmptyCellsOnly++; + if (m_layoutStruct[i].emptyCellsOnly) + numAutoEmptyCellsOnly++; else { numAuto++; - totalAuto += m_layoutStruct[i].effMaxWidth; - allocAuto += w; + totalAuto += m_layoutStruct[i].effectiveMaxLogicalWidth; + allocAuto += cellLogicalWidth; } break; default: @@ -556,26 +535,26 @@ void AutoTableLayout::layout() // allocate width to percent cols if (available > 0 && havePercent) { - for (int i = 0; i < nEffCols; i++) { - Length &width = m_layoutStruct[i].effWidth; - if (width.isPercent()) { - int w = max(int(m_layoutStruct[i].effMinWidth), width.calcMinValue(tableWidth)); - available += m_layoutStruct[i].calcWidth - w; - m_layoutStruct[i].calcWidth = w; + for (size_t i = 0; i < nEffCols; ++i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isPercent()) { + int cellLogicalWidth = max(m_layoutStruct[i].effectiveMinLogicalWidth, logicalWidth.calcMinValue(tableLogicalWidth)); + available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth; + m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; } } if (totalPercent > 100 * percentScaleFactor) { // remove overallocated space from the last columns - int excess = tableWidth*(totalPercent - 100 * percentScaleFactor) / (100 * percentScaleFactor); - for (int i = nEffCols-1; i >= 0; i--) { - if (m_layoutStruct[i].effWidth.isPercent()) { - int w = m_layoutStruct[i].calcWidth; - int reduction = min(w, excess); + int excess = tableLogicalWidth * (totalPercent - 100 * percentScaleFactor) / (100 * percentScaleFactor); + for (int i = nEffCols - 1; i >= 0; --i) { + if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { + int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidth; + int reduction = min(cellLogicalWidth, excess); // the lines below might look inconsistent, but that's the way it's handled in mozilla excess -= reduction; - int newWidth = max(static_cast<int>(m_layoutStruct[i].effMinWidth), w - reduction); - available += w - newWidth; - m_layoutStruct[i].calcWidth = newWidth; + int newLogicalWidth = max(m_layoutStruct[i].effectiveMinLogicalWidth, cellLogicalWidth - reduction); + available += cellLogicalWidth - newLogicalWidth; + m_layoutStruct[i].computedLogicalWidth = newLogicalWidth; } } } @@ -583,24 +562,24 @@ void AutoTableLayout::layout() // then allocate width to fixed cols if (available > 0) { - for (int i = 0; i < nEffCols; ++i) { - Length &width = m_layoutStruct[i].effWidth; - if (width.isFixed() && width.value() > m_layoutStruct[i].calcWidth) { - available += m_layoutStruct[i].calcWidth - width.value(); - m_layoutStruct[i].calcWidth = width.value(); + for (size_t i = 0; i < nEffCols; ++i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[i].computedLogicalWidth) { + available += m_layoutStruct[i].computedLogicalWidth - logicalWidth.value(); + m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); } } } // now satisfy relative if (available > 0) { - for (int i = 0; i < nEffCols; i++) { - Length &width = m_layoutStruct[i].effWidth; - if (width.isRelative() && width.value() != 0) { + for (size_t i = 0; i < nEffCols; ++i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isRelative() && logicalWidth.value() != 0) { // width=0* gets effMinWidth. - int w = width.value() * tableWidth / totalRelative; - available += m_layoutStruct[i].calcWidth - w; - m_layoutStruct[i].calcWidth = w; + int cellLogicalWidth = logicalWidth.value() * tableLogicalWidth / totalRelative; + available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth; + m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; } } } @@ -608,42 +587,41 @@ void AutoTableLayout::layout() // now satisfy variable if (available > 0 && numAuto) { available += allocAuto; // this gets redistributed - for (int i = 0; i < nEffCols; i++) { - Length &width = m_layoutStruct[i].effWidth; - if (width.isAuto() && totalAuto != 0 && !m_layoutStruct[i].emptyCellsOnly) { - int w = max(m_layoutStruct[i].calcWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effMaxWidth) / totalAuto)); - available -= w; - totalAuto -= m_layoutStruct[i].effMaxWidth; - m_layoutStruct[i].calcWidth = w; + for (size_t i = 0; i < nEffCols; ++i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCellsOnly) { + int cellLogicalWidth = max(m_layoutStruct[i].computedLogicalWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalAuto)); + available -= cellLogicalWidth; + totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth; + m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; } } } // spread over fixed columns if (available > 0 && numFixed) { - // still have some width to spread, distribute to fixed columns - for (int i = 0; i < nEffCols; i++) { - Length &width = m_layoutStruct[i].effWidth; - if (width.isFixed()) { - int w = static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effMaxWidth) / totalFixed); - available -= w; - totalFixed -= m_layoutStruct[i].effMaxWidth; - m_layoutStruct[i].calcWidth += w; + for (size_t i = 0; i < nEffCols; ++i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isFixed()) { + int cellLogicalWidth = static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalFixed); + available -= cellLogicalWidth; + totalFixed -= m_layoutStruct[i].effectiveMaxLogicalWidth; + m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; } } } // spread over percent colums if (available > 0 && m_hasPercent && totalPercent < 100 * percentScaleFactor) { - // still have some width to spread, distribute weighted to percent columns - for (int i = 0; i < nEffCols; i++) { - Length &width = m_layoutStruct[i].effWidth; - if (width.isPercent()) { - int w = available * width.rawValue() / totalPercent; - available -= w; - totalPercent -= width.rawValue(); - m_layoutStruct[i].calcWidth += w; - if (!available || !totalPercent) break; + for (size_t i = 0; i < nEffCols; ++i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isPercent()) { + int cellLogicalWidth = available * logicalWidth.rawValue() / totalPercent; + available -= cellLogicalWidth; + totalPercent -= logicalWidth.rawValue(); + m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; + if (!available || !totalPercent) + break; } } } @@ -652,15 +630,14 @@ void AutoTableLayout::layout() if (available > 0 && nEffCols > numAutoEmptyCellsOnly) { int total = nEffCols - numAutoEmptyCellsOnly; // still have some width to spread - int i = nEffCols; - while (i--) { + for (int i = nEffCols - 1; i >= 0; --i) { // variable columns with empty cells only don't get any width - if (m_layoutStruct[i].effWidth.isAuto() && m_layoutStruct[i].emptyCellsOnly) + if (m_layoutStruct[i].effectiveLogicalWidth.isAuto() && m_layoutStruct[i].emptyCellsOnly) continue; - int w = available / total; - available -= w; + int cellLogicalWidth = available / total; + available -= cellLogicalWidth; total--; - m_layoutStruct[i].calcWidth += w; + m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; } } @@ -674,21 +651,21 @@ void AutoTableLayout::layout() // (4) Percent // This is basically the reverse of how we grew the cells. if (available < 0) { - int mw = 0; - for (int i = nEffCols-1; i >= 0; i--) { - Length &width = m_layoutStruct[i].effWidth; - if (width.isAuto()) - mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth; + int logicalWidthBeyondMin = 0; + for (int i = nEffCols - 1; i >= 0; --i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isAuto()) + logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; } - for (int i = nEffCols-1; i >= 0 && mw > 0; i--) { - Length &width = m_layoutStruct[i].effWidth; - if (width.isAuto()) { - int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth; - int reduce = available * minMaxDiff / mw; - m_layoutStruct[i].calcWidth += reduce; + for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isAuto()) { + int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; + int reduce = available * minMaxDiff / logicalWidthBeyondMin; + m_layoutStruct[i].computedLogicalWidth += reduce; available -= reduce; - mw -= minMaxDiff; + logicalWidthBeyondMin -= minMaxDiff; if (available >= 0) break; } @@ -696,21 +673,21 @@ void AutoTableLayout::layout() } if (available < 0) { - int mw = 0; - for (int i = nEffCols-1; i >= 0; i--) { - Length& width = m_layoutStruct[i].effWidth; - if (width.isRelative()) - mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth; + int logicalWidthBeyondMin = 0; + for (int i = nEffCols - 1; i >= 0; --i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isRelative()) + logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; } - for (int i = nEffCols-1; i >= 0 && mw > 0; i--) { - Length& width = m_layoutStruct[i].effWidth; - if (width.isRelative()) { - int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth; - int reduce = available * minMaxDiff / mw; - m_layoutStruct[i].calcWidth += reduce; + for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isRelative()) { + int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; + int reduce = available * minMaxDiff / logicalWidthBeyondMin; + m_layoutStruct[i].computedLogicalWidth += reduce; available -= reduce; - mw -= minMaxDiff; + logicalWidthBeyondMin -= minMaxDiff; if (available >= 0) break; } @@ -718,21 +695,21 @@ void AutoTableLayout::layout() } if (available < 0) { - int mw = 0; - for (int i = nEffCols-1; i >= 0; i--) { - Length& width = m_layoutStruct[i].effWidth; - if (width.isFixed()) - mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth; + int logicalWidthBeyondMin = 0; + for (int i = nEffCols - 1; i >= 0; --i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isFixed()) + logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; } - for (int i = nEffCols-1; i >= 0 && mw > 0; i--) { - Length& width = m_layoutStruct[i].effWidth; - if (width.isFixed()) { - int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth; - int reduce = available * minMaxDiff / mw; - m_layoutStruct[i].calcWidth += reduce; + for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isFixed()) { + int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; + int reduce = available * minMaxDiff / logicalWidthBeyondMin; + m_layoutStruct[i].computedLogicalWidth += reduce; available -= reduce; - mw -= minMaxDiff; + logicalWidthBeyondMin -= minMaxDiff; if (available >= 0) break; } @@ -740,21 +717,21 @@ void AutoTableLayout::layout() } if (available < 0) { - int mw = 0; - for (int i = nEffCols-1; i >= 0; i--) { - Length& width = m_layoutStruct[i].effWidth; - if (width.isPercent()) - mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth; + int logicalWidthBeyondMin = 0; + for (int i = nEffCols - 1; i >= 0; --i) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isPercent()) + logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; } - for (int i = nEffCols-1; i >= 0 && mw > 0; i--) { - Length& width = m_layoutStruct[i].effWidth; - if (width.isPercent()) { - int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth; - int reduce = available * minMaxDiff / mw; - m_layoutStruct[i].calcWidth += reduce; + for (int i = nEffCols-1; i >= 0 && logicalWidthBeyondMin > 0; i--) { + Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; + if (logicalWidth.isPercent()) { + int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; + int reduce = available * minMaxDiff / logicalWidthBeyondMin; + m_layoutStruct[i].computedLogicalWidth += reduce; available -= reduce; - mw -= minMaxDiff; + logicalWidthBeyondMin -= minMaxDiff; if (available >= 0) break; } @@ -763,25 +740,11 @@ void AutoTableLayout::layout() } int pos = 0; - for (int i = 0; i < nEffCols; i++) { + for (size_t i = 0; i < nEffCols; ++i) { m_table->columnPositions()[i] = pos; - pos += m_layoutStruct[i].calcWidth + m_table->hBorderSpacing(); + pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing(); } m_table->columnPositions()[m_table->columnPositions().size() - 1] = pos; } - -void AutoTableLayout::calcPercentages() const -{ - unsigned totalPercent = 0; - for (unsigned i = 0; i < m_layoutStruct.size(); i++) { - if (m_layoutStruct[i].width.isPercent()) - totalPercent += m_layoutStruct[i].width.rawValue(); - } - m_totalPercent = totalPercent / percentScaleFactor; - m_percentagesDirty = false; -} - -#undef DEBUG_LAYOUT - } diff --git a/WebCore/rendering/AutoTableLayout.h b/WebCore/rendering/AutoTableLayout.h index 5726ba6..7ade0d6 100644 --- a/WebCore/rendering/AutoTableLayout.h +++ b/WebCore/rendering/AutoTableLayout.h @@ -38,46 +38,39 @@ public: virtual void computePreferredLogicalWidths(int& minWidth, int& maxWidth); virtual void layout(); -protected: +private: void fullRecalc(); void recalcColumn(int effCol); - void calcPercentages() const; - int totalPercent() const - { - if (m_percentagesDirty) - calcPercentages(); - return m_totalPercent; - } - - int calcEffectiveWidth(); + int calcEffectiveLogicalWidth(); void insertSpanCell(RenderTableCell*); struct Layout { Layout() - : minWidth(0) - , maxWidth(0) - , effMinWidth(0) - , effMaxWidth(0) - , calcWidth(0) - , emptyCellsOnly(true) {} - Length width; - Length effWidth; - int minWidth; - int maxWidth; - int effMinWidth; - int effMaxWidth; - int calcWidth; + : minLogicalWidth(0) + , maxLogicalWidth(0) + , effectiveMinLogicalWidth(0) + , effectiveMaxLogicalWidth(0) + , computedLogicalWidth(0) + , emptyCellsOnly(true) + { + } + + Length logicalWidth; + Length effectiveLogicalWidth; + int minLogicalWidth; + int maxLogicalWidth; + int effectiveMinLogicalWidth; + int effectiveMaxLogicalWidth; + int computedLogicalWidth; bool emptyCellsOnly; }; Vector<Layout, 4> m_layoutStruct; Vector<RenderTableCell*, 4> m_spanCells; bool m_hasPercent : 1; - mutable bool m_percentagesDirty : 1; - mutable bool m_effWidthDirty : 1; - mutable unsigned short m_totalPercent; + mutable bool m_effectiveLogicalWidthDirty : 1; }; } // namespace WebCore diff --git a/WebCore/rendering/FixedTableLayout.cpp b/WebCore/rendering/FixedTableLayout.cpp index ba99336..3285d15 100644 --- a/WebCore/rendering/FixedTableLayout.cpp +++ b/WebCore/rendering/FixedTableLayout.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 Lars Knoll (knoll@kde.org) * (C) 2002 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -89,46 +89,43 @@ int FixedTableLayout::calcWidthArray(int) int currentEffectiveColumn = 0; Length grpWidth; - while (child) { - if (child->isTableCol()) { - RenderTableCol* col = toRenderTableCol(child); - if (col->firstChild()) - grpWidth = col->style()->width(); - else { - Length w = col->style()->width(); - if (w.isAuto()) - w = grpWidth; - int effWidth = 0; - if (w.isFixed() && w.value() > 0) - effWidth = w.value(); - - int span = col->span(); - while (span) { - int spanInCurrentEffectiveColumn; - if (currentEffectiveColumn >= nEffCols) { - m_table->appendColumn(span); + while (child && child->isTableCol()) { + RenderTableCol* col = toRenderTableCol(child); + if (col->firstChild()) + grpWidth = col->style()->logicalWidth(); + else { + Length w = col->style()->logicalWidth(); + if (w.isAuto()) + w = grpWidth; + int effWidth = 0; + if (w.isFixed() && w.value() > 0) + effWidth = w.value(); + + int span = col->span(); + while (span) { + int spanInCurrentEffectiveColumn; + if (currentEffectiveColumn >= nEffCols) { + m_table->appendColumn(span); + nEffCols++; + m_width.append(Length()); + spanInCurrentEffectiveColumn = span; + } else { + if (span < m_table->spanOfEffCol(currentEffectiveColumn)) { + m_table->splitColumn(currentEffectiveColumn, span); nEffCols++; m_width.append(Length()); - spanInCurrentEffectiveColumn = span; - } else { - if (span < m_table->spanOfEffCol(currentEffectiveColumn)) { - m_table->splitColumn(currentEffectiveColumn, span); - nEffCols++; - m_width.append(Length()); - } - spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn); - } - if ((w.isFixed() || w.isPercent()) && w.isPositive()) { - m_width[currentEffectiveColumn].setRawValue(w.type(), w.rawValue() * spanInCurrentEffectiveColumn); - usedWidth += effWidth * spanInCurrentEffectiveColumn; } - span -= spanInCurrentEffectiveColumn; - currentEffectiveColumn++; + spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn); } + if ((w.isFixed() || w.isPercent()) && w.isPositive()) { + m_width[currentEffectiveColumn].setRawValue(w.type(), w.rawValue() * spanInCurrentEffectiveColumn); + usedWidth += effWidth * spanInCurrentEffectiveColumn; + } + span -= spanInCurrentEffectiveColumn; + currentEffectiveColumn++; } - toRenderTableCol(child)->computePreferredLogicalWidths(); - } else - break; + } + col->computePreferredLogicalWidths(); RenderObject* next = child->firstChild(); if (!next) @@ -158,7 +155,7 @@ int FixedTableLayout::calcWidthArray(int) if (cell->preferredLogicalWidthsDirty()) cell->computePreferredLogicalWidths(); - Length w = cell->styleOrColWidth(); + Length w = cell->styleOrColLogicalWidth(); int span = cell->colSpan(); int effWidth = 0; if (w.isFixed() && w.isPositive()) @@ -201,12 +198,12 @@ void FixedTableLayout::computePreferredLogicalWidths(int& minWidth, int& maxWidt // cols/cells with a fixed width. // // The maximum width is max(minWidth, tableWidth). - int bs = m_table->bordersPaddingAndSpacing(); - - int tableWidth = m_table->style()->width().isFixed() ? m_table->style()->width().value() - bs : 0; - int mw = calcWidthArray(tableWidth) + bs; + int bordersPaddingAndSpacing = m_table->bordersPaddingAndSpacingInRowDirection(); + + int tableLogicalWidth = m_table->style()->logicalWidth().isFixed() ? m_table->style()->logicalWidth().value() - bordersPaddingAndSpacing : 0; + int mw = calcWidthArray(tableLogicalWidth) + bordersPaddingAndSpacing; - minWidth = max(mw, tableWidth); + minWidth = max(mw, tableLogicalWidth); maxWidth = minWidth; // This quirk is very similar to one that exists in RenderBlock::calcBlockPrefWidths(). @@ -223,14 +220,13 @@ void FixedTableLayout::computePreferredLogicalWidths(int& minWidth, int& maxWidt // In this example, the two inner tables should be as large as the outer table. // We can achieve this effect by making the maxwidth of fixed tables with percentage // widths be infinite. - if (m_table->document()->inQuirksMode() && m_table->style()->width().isPercent() - && maxWidth < TABLE_MAX_WIDTH) + if (m_table->document()->inQuirksMode() && m_table->style()->logicalWidth().isPercent() && maxWidth < TABLE_MAX_WIDTH) maxWidth = TABLE_MAX_WIDTH; } void FixedTableLayout::layout() { - int tableWidth = m_table->width() - m_table->bordersPaddingAndSpacing(); + int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection(); int nEffCols = m_table->numEffCols(); Vector<int> calcWidth(nEffCols, 0); @@ -249,7 +245,7 @@ void FixedTableLayout::layout() calcWidth[i] = m_width[i].value(); totalFixedWidth += calcWidth[i]; } else if (m_width[i].isPercent()) { - calcWidth[i] = m_width[i].calcValue(tableWidth); + calcWidth[i] = m_width[i].calcValue(tableLogicalWidth); totalPercentWidth += calcWidth[i]; totalRawPercent += m_width[i].rawValue(); } else if (m_width[i].isAuto()) { @@ -260,16 +256,16 @@ void FixedTableLayout::layout() int hspacing = m_table->hBorderSpacing(); int totalWidth = totalFixedWidth + totalPercentWidth; - if (!numAuto || totalWidth > tableWidth) { + if (!numAuto || totalWidth > tableLogicalWidth) { // If there are no auto columns, or if the total is too wide, take // what we have and scale it to fit as necessary. - if (totalWidth != tableWidth) { + if (totalWidth != tableLogicalWidth) { // Fixed widths only scale up - if (totalFixedWidth && totalWidth < tableWidth) { + if (totalFixedWidth && totalWidth < tableLogicalWidth) { totalFixedWidth = 0; for (int i = 0; i < nEffCols; i++) { if (m_width[i].isFixed()) { - calcWidth[i] = calcWidth[i] * tableWidth / totalWidth; + calcWidth[i] = calcWidth[i] * tableLogicalWidth / totalWidth; totalFixedWidth += calcWidth[i]; } } @@ -278,7 +274,7 @@ void FixedTableLayout::layout() totalPercentWidth = 0; for (int i = 0; i < nEffCols; i++) { if (m_width[i].isPercent()) { - calcWidth[i] = m_width[i].rawValue() * (tableWidth - totalFixedWidth) / totalRawPercent; + calcWidth[i] = m_width[i].rawValue() * (tableLogicalWidth - totalFixedWidth) / totalRawPercent; totalPercentWidth += calcWidth[i]; } } @@ -287,7 +283,7 @@ void FixedTableLayout::layout() } } else { // Divide the remaining width among the auto columns. - int remainingWidth = tableWidth - totalFixedWidth - totalPercentWidth - hspacing * (autoSpan - numAuto); + int remainingWidth = tableLogicalWidth - totalFixedWidth - totalPercentWidth - hspacing * (autoSpan - numAuto); int lastAuto = 0; for (int i = 0; i < nEffCols; i++) { if (m_width[i].isAuto()) { @@ -305,12 +301,12 @@ void FixedTableLayout::layout() // Last one gets the remainder. if (remainingWidth) calcWidth[lastAuto] += remainingWidth; - totalWidth = tableWidth; + totalWidth = tableLogicalWidth; } - if (totalWidth < tableWidth) { + if (totalWidth < tableLogicalWidth) { // Spread extra space over columns. - int remainingWidth = tableWidth - totalWidth; + int remainingWidth = tableLogicalWidth - totalWidth; int total = nEffCols; while (total) { int w = remainingWidth / total; diff --git a/WebCore/rendering/FixedTableLayout.h b/WebCore/rendering/FixedTableLayout.h index bf26d1b..6c135c0 100644 --- a/WebCore/rendering/FixedTableLayout.h +++ b/WebCore/rendering/FixedTableLayout.h @@ -36,7 +36,7 @@ public: virtual void computePreferredLogicalWidths(int& minWidth, int& maxWidth); virtual void layout(); -protected: +private: int calcWidthArray(int tableWidth); Vector<Length> m_width; diff --git a/WebCore/rendering/InlineBox.cpp b/WebCore/rendering/InlineBox.cpp index 1ce68f9..b8f0ce1 100644 --- a/WebCore/rendering/InlineBox.cpp +++ b/WebCore/rendering/InlineBox.cpp @@ -95,7 +95,7 @@ int InlineBox::logicalHeight() const if (renderer()->isText()) return m_isText ? renderer()->style(m_firstLine)->font().height() : 0; if (renderer()->isBox() && parent()) - return m_isVertical ? toRenderBox(m_renderer)->width() : toRenderBox(m_renderer)->height(); + return isHorizontal() ? toRenderBox(m_renderer)->height() : toRenderBox(m_renderer)->width(); ASSERT(isInlineFlowBox()); RenderBoxModelObject* flowObject = boxModelObject(); @@ -279,28 +279,29 @@ int InlineBox::placeEllipsisBox(bool, int, int, int, bool&) return -1; } -void InlineBox::adjustForFlippedBlocksWritingMode(IntPoint& point) +IntPoint InlineBox::locationIncludingFlipping() { if (!renderer()->style()->isFlippedBlocksWritingMode()) - return; - + return IntPoint(x(), y()); RenderBlock* block = root()->block(); if (block->style()->isHorizontalWritingMode()) - point.setY(block->height() - height() - point.y()); + return IntPoint(x(), block->height() - height() - y()); else - point.setX(block->width() - width() - point.x()); + return IntPoint(block->width() - width() - x(), y()); } -void InlineBox::adjustForFlippedBlocksWritingMode(IntRect& rect) +void InlineBox::flipForWritingMode(IntRect& rect) { if (!renderer()->style()->isFlippedBlocksWritingMode()) return; - - RenderBlock* block = root()->block(); - if (block->style()->isHorizontalWritingMode()) - rect.setY(block->height() - rect.bottom()); - else - rect.setX(block->width() - rect.right()); + root()->block()->flipForWritingMode(rect); +} + +IntPoint InlineBox::flipForWritingMode(const IntPoint& point) +{ + if (!renderer()->style()->isFlippedBlocksWritingMode()) + return point; + return root()->block()->flipForWritingMode(point); } } // namespace WebCore diff --git a/WebCore/rendering/InlineBox.h b/WebCore/rendering/InlineBox.h index 1e4b8bf..72e5534 100644 --- a/WebCore/rendering/InlineBox.h +++ b/WebCore/rendering/InlineBox.h @@ -51,7 +51,7 @@ public: #if ENABLE(SVG) , m_hasVirtualLogicalHeight(false) #endif - , m_isVertical(false) + , m_isHorizontal(true) , m_endsWithBreak(false) , m_hasSelectedChildren(false) , m_hasEllipsisBoxOrHyphen(false) @@ -69,7 +69,7 @@ public: } InlineBox(RenderObject* obj, int x, int y, int logicalWidth, bool firstLine, bool constructed, - bool dirty, bool extracted, bool isVertical, InlineBox* next, InlineBox* prev, InlineFlowBox* parent) + bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent) : m_next(next) , m_prev(prev) , m_parent(parent) @@ -85,7 +85,7 @@ public: #if ENABLE(SVG) , m_hasVirtualLogicalHeight(false) #endif - , m_isVertical(isVertical) + , m_isHorizontal(isHorizontal) , m_endsWithBreak(false) , m_hasSelectedChildren(false) , m_hasEllipsisBoxOrHyphen(false) @@ -152,8 +152,8 @@ public: return 0; } - bool isVertical() const { return m_isVertical; } - void setIsVertical(bool v) { m_isVertical = v; } + bool isHorizontal() const { return m_isHorizontal; } + void setIsHorizontal(bool horizontal) { m_isHorizontal = horizontal; } virtual IntRect calculateBoundaries() const { @@ -216,26 +216,26 @@ public: void setY(int y) { m_y = y; } int y() const { return m_y; } - int width() const { return m_isVertical ? logicalHeight() : logicalWidth(); } - int height() const { return m_isVertical ? logicalWidth() : logicalHeight(); } + int width() const { return isHorizontal() ? logicalWidth() : logicalHeight(); } + int height() const { return isHorizontal() ? logicalHeight() : logicalWidth(); } // The logicalLeft position is the left edge of the line box in a horizontal line and the top edge in a vertical line. - int logicalLeft() const { return !m_isVertical ? m_x : m_y; } + int logicalLeft() const { return isHorizontal() ? m_x : m_y; } int logicalRight() const { return logicalLeft() + logicalWidth(); } void setLogicalLeft(int left) { - if (!m_isVertical) + if (isHorizontal()) m_x = left; else m_y = left; } // The logicalTop[ position is the top edge of the line box in a horizontal line and the left edge in a vertical line. - int logicalTop() const { return !m_isVertical ? m_y : m_x; } + int logicalTop() const { return isHorizontal() ? m_y : m_x; } int logicalBottom() const { return logicalTop() + logicalHeight(); } void setLogicalTop(int top) { - if (!m_isVertical) + if (isHorizontal()) m_y = top; else m_x = top; @@ -248,8 +248,8 @@ public: // The logical height is our extent in the block flow direction, i.e., height for horizontal text and width for vertical text. int logicalHeight() const; - virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOnContainingLine); } - virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOnContainingLine); } + virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); } + virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); } virtual int caretMinOffset() const; @@ -290,8 +290,9 @@ public: return 0; } - void adjustForFlippedBlocksWritingMode(IntPoint&); - void adjustForFlippedBlocksWritingMode(IntRect&); + IntPoint locationIncludingFlipping(); + void flipForWritingMode(IntRect&); + IntPoint flipForWritingMode(const IntPoint&); private: InlineBox* m_next; // The next element on the same line as us. @@ -319,7 +320,7 @@ protected: bool m_extracted : 1; bool m_hasVirtualLogicalHeight : 1; - bool m_isVertical : 1; + bool m_isHorizontal : 1; // for RootInlineBox bool m_endsWithBreak : 1; // Whether the line ends with a <br>. diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp index d165231..8525673 100644 --- a/WebCore/rendering/InlineFlowBox.cpp +++ b/WebCore/rendering/InlineFlowBox.cpp @@ -80,7 +80,7 @@ void InlineFlowBox::addToLine(InlineBox* child) m_lastChild = child; } child->setFirstLineStyleBit(m_firstLine); - child->setIsVertical(m_isVertical); + child->setIsHorizontal(isHorizontal()); if (child->isText()) m_hasTextChildren = true; @@ -328,22 +328,22 @@ int InlineFlowBox::placeBoxesInInlineDirection(int logicalLeft, bool& needsWordS } else if (!curr->renderer()->isListMarker() || toRenderListMarker(curr->renderer())->isInside()) { // The box can have a different writing-mode than the overall line, so this is a bit complicated. // Just get all the physical margin and overflow values by hand based off |isVertical|. - int logicalLeftMargin = !isVertical() ? curr->boxModelObject()->marginLeft() : curr->boxModelObject()->marginTop(); - int logicalRightMargin = !isVertical() ? curr->boxModelObject()->marginRight() : curr->boxModelObject()->marginBottom(); + int logicalLeftMargin = isHorizontal() ? curr->boxModelObject()->marginLeft() : curr->boxModelObject()->marginTop(); + int logicalRightMargin = isHorizontal() ? curr->boxModelObject()->marginRight() : curr->boxModelObject()->marginBottom(); logicalLeft += logicalLeftMargin; curr->setLogicalLeft(logicalLeft); RenderBox* box = toRenderBox(curr->renderer()); - int childOverflowLogicalLeft = box->hasOverflowClip() ? 0 : (!isVertical() ? box->leftLayoutOverflow() : box->topLayoutOverflow()); - int childOverflowLogicalRight = box->hasOverflowClip() ? curr->logicalWidth() : (!isVertical() ? box->rightLayoutOverflow() : box->bottomLayoutOverflow()); + int childOverflowLogicalLeft = box->hasOverflowClip() ? 0 : (isHorizontal() ? box->leftLayoutOverflow() : box->topLayoutOverflow()); + int childOverflowLogicalRight = box->hasOverflowClip() ? curr->logicalWidth() : (isHorizontal() ? box->rightLayoutOverflow() : box->bottomLayoutOverflow()); logicalLeftLayoutOverflow = min(logicalLeft + childOverflowLogicalLeft, logicalLeftLayoutOverflow); logicalRightLayoutOverflow = max(logicalLeft + childOverflowLogicalRight, logicalRightLayoutOverflow); - logicalLeftVisualOverflow = min(logicalLeft + (!isVertical() ? box->leftVisualOverflow() : box->topVisualOverflow()), logicalLeftVisualOverflow); - logicalRightVisualOverflow = max(logicalLeft + (!isVertical() ? box->rightVisualOverflow() : box->bottomVisualOverflow()), logicalRightVisualOverflow); + logicalLeftVisualOverflow = min(logicalLeft + (isHorizontal() ? box->leftVisualOverflow() : box->topVisualOverflow()), logicalLeftVisualOverflow); + logicalRightVisualOverflow = max(logicalLeft + (isHorizontal() ? box->rightVisualOverflow() : box->bottomVisualOverflow()), logicalRightVisualOverflow); logicalLeft += curr->logicalWidth() + logicalRightMargin; } @@ -480,7 +480,7 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi } } -void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom) +void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop) { if (isRootInlineBox()) setLogicalTop(top + maxAscent - baselinePosition()); // Place our root box. @@ -493,7 +493,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs // line-height). bool isInlineFlow = curr->isInlineFlowBox(); if (isInlineFlow) - static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom); + static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom, setLineTop); bool childAffectsTopBottomPos = true; if (curr->logicalTop() == PositionTop) @@ -525,7 +525,11 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs if (childAffectsTopBottomPos) { int boxHeight = curr->logicalHeight(); - lineTop = min(lineTop, newLogicalTop); + if (!setLineTop) { + setLineTop = true; + lineTop = newLogicalTop; + } else + lineTop = min(lineTop, newLogicalTop); lineBottom = max(lineBottom, newLogicalTop + boxHeight); } } @@ -535,7 +539,11 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs setLogicalTop(logicalTop() + baselinePosition() - font.ascent()); if (hasTextChildren() || strictMode) { - lineTop = min(lineTop, logicalTop()); + if (!setLineTop) { + setLineTop = true; + lineTop = logicalTop(); + } else + lineTop = min(lineTop, logicalTop()); lineBottom = max(lineBottom, logicalTop() + logicalHeight()); } @@ -633,7 +641,7 @@ void InlineFlowBox::computeBlockDirectionOverflow(int lineTop, int lineBottom, b int childBottomVisualOverflow; RenderBox* box = toRenderBox(curr->renderer()); - box->blockDirectionOverflow(isVertical(), childTopLayoutOverflow, childBottomLayoutOverflow, + box->blockDirectionOverflow(isHorizontal(), childTopLayoutOverflow, childBottomLayoutOverflow, childTopVisualOverflow, childBottomVisualOverflow); if (box->hasOverflowClip()) { @@ -654,6 +662,7 @@ void InlineFlowBox::computeBlockDirectionOverflow(int lineTop, int lineBottom, b bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty) { IntRect overflowRect(visibleOverflowRect()); + flipForWritingMode(overflowRect); overflowRect.move(tx, ty); if (!overflowRect.intersects(result.rectForPoint(x, y))) return false; @@ -667,9 +676,11 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re } // Now check ourselves. - IntRect rect(tx + m_x, ty + m_y, width(), height()); + IntPoint boxOrigin = locationIncludingFlipping(); + boxOrigin.move(tx, ty); + IntRect rect(boxOrigin, IntSize(width(), height())); if (visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) { - renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); // Don't add in m_x or m_y here, we want coords in the containing block's space. + renderer()->updateHitTestResult(result, flipForWritingMode(IntPoint(x - tx, y - ty))); // Don't add in m_x or m_y here, we want coords in the containing block's space. if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, rect)) return true; } @@ -681,7 +692,7 @@ void InlineFlowBox::paint(PaintInfo& paintInfo, int tx, int ty) { IntRect overflowRect(visibleOverflowRect()); overflowRect.inflate(renderer()->maximalOutlineSize(paintInfo.phase)); - adjustForFlippedBlocksWritingMode(overflowRect); + flipForWritingMode(overflowRect); overflowRect.move(tx, ty); if (!paintInfo.rect.intersects(overflowRect)) @@ -769,10 +780,10 @@ void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, c int totalLogicalWidth = logicalOffsetOnLine; for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) totalLogicalWidth += curr->logicalWidth(); - int stripX = tx - (isVertical() ? 0 : logicalOffsetOnLine); - int stripY = ty - (isVertical() ? logicalOffsetOnLine : 0); - int stripWidth = isVertical() ? width() : totalLogicalWidth; - int stripHeight = isVertical() ? totalLogicalWidth : height(); + int stripX = tx - (isHorizontal() ? logicalOffsetOnLine : 0); + int stripY = ty - (isHorizontal() ? 0 : logicalOffsetOnLine); + int stripWidth = isHorizontal() ? totalLogicalWidth : width(); + int stripHeight = isHorizontal() ? height() : totalLogicalWidth; paintInfo.context->save(); paintInfo.context->clip(IntRect(tx, ty, width(), height())); boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, stripX, stripY, stripWidth, stripHeight, this, op); @@ -798,25 +809,25 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty) int x = m_x; int y = m_y; - int w = m_isVertical ? logicalHeight() : logicalWidth(); - int h = m_isVertical ? logicalWidth() : logicalHeight(); + int w = width(); + int h = height(); // Constrain our background/border painting to the line top and bottom if necessary. bool noQuirksMode = renderer()->document()->inNoQuirksMode(); if (!hasTextChildren() && !noQuirksMode) { RootInlineBox* rootBox = root(); - int& top = m_isVertical ? x : y; - int& logicalHeight = m_isVertical ? w : h; + int& top = isHorizontal() ? y : x; + int& logicalHeight = isHorizontal() ? h : w; int bottom = min(rootBox->lineBottom(), top + logicalHeight); top = max(rootBox->lineTop(), top); logicalHeight = bottom - top; } // Move x/y to our coordinates. - IntPoint localPoint(x, y); - adjustForFlippedBlocksWritingMode(localPoint); - tx += localPoint.x(); - ty += localPoint.y(); + IntRect localRect(x, y, w, h); + flipForWritingMode(localRect); + tx += localRect.x(); + ty += localRect.y(); GraphicsContext* context = paintInfo.context; @@ -861,10 +872,10 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty) int totalLogicalWidth = logicalOffsetOnLine; for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) totalLogicalWidth += curr->logicalWidth(); - int stripX = tx - (isVertical() ? 0 : logicalOffsetOnLine); - int stripY = ty - (isVertical() ? logicalOffsetOnLine : 0); - int stripWidth = isVertical() ? w : totalLogicalWidth; - int stripHeight = isVertical() ? totalLogicalWidth : h; + int stripX = tx - (isHorizontal() ? logicalOffsetOnLine : 0); + int stripY = ty - (isHorizontal() ? 0 : logicalOffsetOnLine); + int stripWidth = isHorizontal() ? totalLogicalWidth : w; + int stripHeight = isHorizontal() ? h : totalLogicalWidth; context->save(); context->clip(IntRect(tx, ty, w, h)); boxModelObject()->paintBorder(context, stripX, stripY, stripWidth, stripHeight, renderer()->style()); @@ -881,25 +892,25 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, int tx, int ty) int x = m_x; int y = m_y; - int w = m_isVertical ? logicalHeight() : logicalWidth(); - int h = m_isVertical ? logicalWidth() : logicalHeight(); + int w = width(); + int h = height(); // Constrain our background/border painting to the line top and bottom if necessary. bool noQuirksMode = renderer()->document()->inNoQuirksMode(); if (!hasTextChildren() && !noQuirksMode) { RootInlineBox* rootBox = root(); - int& top = m_isVertical ? x : y; - int& logicalHeight = m_isVertical ? w : h; + int& top = isHorizontal() ? y : x; + int& logicalHeight = isHorizontal() ? h : w; int bottom = min(rootBox->lineBottom(), top + logicalHeight); top = max(rootBox->lineTop(), top); logicalHeight = bottom - top; } // Move x/y to our coordinates. - IntPoint localPoint(x, y); - adjustForFlippedBlocksWritingMode(localPoint); - tx += localPoint.x(); - ty += localPoint.y(); + IntRect localRect(x, y, w, h); + flipForWritingMode(localRect); + tx += localRect.x(); + ty += localRect.y(); const NinePieceImage& maskNinePieceImage = renderer()->style()->maskBoxImage(); StyleImage* maskBoxImage = renderer()->style()->maskBoxImage().image(); @@ -939,10 +950,10 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, int tx, int ty) int totalLogicalWidth = logicalOffsetOnLine; for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) totalLogicalWidth += curr->logicalWidth(); - int stripX = tx - (isVertical() ? 0 : logicalOffsetOnLine); - int stripY = ty - (isVertical() ? logicalOffsetOnLine : 0); - int stripWidth = isVertical() ? w : totalLogicalWidth; - int stripHeight = isVertical() ? totalLogicalWidth : h; + int stripX = tx - (isHorizontal() ? logicalOffsetOnLine : 0); + int stripY = ty - (isHorizontal() ? 0 : logicalOffsetOnLine); + int stripWidth = isHorizontal() ? totalLogicalWidth : w; + int stripHeight = isHorizontal() ? h : totalLogicalWidth; paintInfo.context->save(); paintInfo.context->clip(IntRect(tx, ty, w, h)); boxModelObject()->paintNinePieceImage(paintInfo.context, stripX, stripY, stripWidth, stripHeight, renderer()->style(), maskNinePieceImage, compositeOp); diff --git a/WebCore/rendering/InlineFlowBox.h b/WebCore/rendering/InlineFlowBox.h index a168f98..be6dfd2 100644 --- a/WebCore/rendering/InlineFlowBox.h +++ b/WebCore/rendering/InlineFlowBox.h @@ -108,37 +108,37 @@ public: { if (!includeLogicalLeftEdge()) return 0; - return !isVertical() ? boxModelObject()->marginLeft() : boxModelObject()->marginTop(); + return isHorizontal() ? boxModelObject()->marginLeft() : boxModelObject()->marginTop(); } int marginLogicalRight() const { if (!includeLogicalRightEdge()) return 0; - return !isVertical() ? boxModelObject()->marginRight() : boxModelObject()->marginBottom(); + return isHorizontal() ? boxModelObject()->marginRight() : boxModelObject()->marginBottom(); } int borderLogicalLeft() const { if (!includeLogicalLeftEdge()) return 0; - return !isVertical() ? renderer()->style()->borderLeftWidth() : renderer()->style()->borderTopWidth(); + return isHorizontal() ? renderer()->style()->borderLeftWidth() : renderer()->style()->borderTopWidth(); } int borderLogicalRight() const { if (!includeLogicalRightEdge()) return 0; - return !isVertical() ? renderer()->style()->borderRightWidth() : renderer()->style()->borderBottomWidth(); + return isHorizontal() ? renderer()->style()->borderRightWidth() : renderer()->style()->borderBottomWidth(); } int paddingLogicalLeft() const { if (!includeLogicalLeftEdge()) return 0; - return !isVertical() ? boxModelObject()->paddingLeft() : boxModelObject()->paddingTop(); + return isHorizontal() ? boxModelObject()->paddingLeft() : boxModelObject()->paddingTop(); } int paddingLogicalRight() const { if (!includeLogicalRightEdge()) return 0; - return !isVertical() ? boxModelObject()->paddingRight() : boxModelObject()->paddingBottom(); + return isHorizontal() ? boxModelObject()->paddingRight() : boxModelObject()->paddingBottom(); } bool includeLogicalLeftEdge() const { return m_includeLogicalLeftEdge; } @@ -158,7 +158,7 @@ public: int& maxAscent, int& maxDescent, bool strictMode, GlyphOverflowAndFallbackFontsMap&); void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent, int maxPositionTop, int maxPositionBottom); - void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom); + void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop); void flipLinesInBlockDirection(int lineTop, int lineBottom); void computeBlockDirectionOverflow(int lineTop, int lineBottom, bool strictMode, GlyphOverflowAndFallbackFontsMap&); @@ -182,15 +182,17 @@ public: int bottomVisibleOverflow() const { return std::max(bottomLayoutOverflow(), bottomVisualOverflow()); } int leftVisibleOverflow() const { return std::min(leftLayoutOverflow(), leftVisualOverflow()); } int rightVisibleOverflow() const { return std::max(rightLayoutOverflow(), rightVisualOverflow()); } + int logicalLeftVisibleOverflow() const { return std::min(logicalLeftLayoutOverflow(), logicalLeftVisualOverflow()); } + int logicalRightVisibleOverflow() const { return std::max(logicalRightLayoutOverflow(), logicalRightVisualOverflow()); } int logicalTopVisibleOverflow() const { return std::min(logicalTopLayoutOverflow(), logicalTopVisualOverflow()); } int logicalBottomVisibleOverflow() const { return std::max(logicalBottomLayoutOverflow(), logicalBottomVisualOverflow()); } IntRect visibleOverflowRect() const { return m_overflow ? m_overflow->visibleOverflowRect() : IntRect(m_x, m_y, width(), height()); } int topLayoutOverflow() const { return m_overflow ? m_overflow->topLayoutOverflow() : m_y; } - int bottomLayoutOverflow() const { return m_overflow ? m_overflow->bottomLayoutOverflow() : m_y + logicalHeight(); } + int bottomLayoutOverflow() const { return m_overflow ? m_overflow->bottomLayoutOverflow() : m_y + height(); } int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : m_x; } - int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : m_x + m_logicalWidth; } + int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : m_x + width(); } IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : IntRect(m_x, m_y, width(), height()); } int logicalLeftLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftLayoutOverflow() : topLayoutOverflow(); } int logicalRightLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? rightLayoutOverflow() : bottomLayoutOverflow(); } @@ -198,9 +200,9 @@ public: int logicalBottomLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? bottomLayoutOverflow() : rightLayoutOverflow(); } int topVisualOverflow() const { return m_overflow ? m_overflow->topVisualOverflow() : m_y; } - int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : m_y + logicalHeight(); } + int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : m_y + height(); } int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : m_x; } - int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : m_x + m_logicalWidth; } + int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : m_x + width(); } IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : IntRect(m_x, m_y, width(), height()); } int logicalLeftVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? leftVisualOverflow() : topVisualOverflow(); } int logicalRightVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? rightVisualOverflow() : bottomVisualOverflow(); } @@ -239,23 +241,19 @@ inline void InlineFlowBox::setInlineDirectionOverflowPositions(int logicalLeftLa if (logicalLeftLayoutOverflow == logicalLeft() && logicalRightLayoutOverflow == logicalRight() && logicalLeftVisualOverflow == logicalLeft() && logicalRightVisualOverflow == logicalRight()) return; - - int width = isVertical() ? logicalHeight() : logicalWidth(); - int height = isVertical() ? logicalWidth() : logicalHeight(); - - m_overflow = adoptPtr(new RenderOverflow(IntRect(m_x, m_y, width, height))); + m_overflow = adoptPtr(new RenderOverflow(IntRect(m_x, m_y, width(), height()))); } - if (isVertical()) { - m_overflow->setTopLayoutOverflow(logicalLeftLayoutOverflow); - m_overflow->setBottomLayoutOverflow(logicalRightLayoutOverflow); - m_overflow->setTopVisualOverflow(logicalLeftVisualOverflow); - m_overflow->setBottomVisualOverflow(logicalRightVisualOverflow); - } else { + if (isHorizontal()) { m_overflow->setLeftLayoutOverflow(logicalLeftLayoutOverflow); m_overflow->setRightLayoutOverflow(logicalRightLayoutOverflow); m_overflow->setLeftVisualOverflow(logicalLeftVisualOverflow); m_overflow->setRightVisualOverflow(logicalRightVisualOverflow); + } else { + m_overflow->setTopLayoutOverflow(logicalLeftLayoutOverflow); + m_overflow->setBottomLayoutOverflow(logicalRightLayoutOverflow); + m_overflow->setTopVisualOverflow(logicalLeftVisualOverflow); + m_overflow->setBottomVisualOverflow(logicalRightVisualOverflow); } } @@ -266,14 +264,10 @@ inline void InlineFlowBox::setBlockDirectionOverflowPositions(int logicalTopLayo if (logicalTopLayoutOverflow == logicalTop() && logicalBottomLayoutOverflow == logicalBottom() && logicalTopVisualOverflow == logicalTop() && logicalBottomVisualOverflow == logicalBottom()) return; - - int width = isVertical() ? logicalHeight() : logicalWidth(); - int height = isVertical() ? logicalWidth() : logicalHeight(); - - m_overflow = adoptPtr(new RenderOverflow(IntRect(m_x, m_y, width, height))); + m_overflow = adoptPtr(new RenderOverflow(IntRect(m_x, m_y, width(), height()))); } - if (!isVertical()) { + if (isHorizontal()) { m_overflow->setTopLayoutOverflow(logicalTopLayoutOverflow); m_overflow->setBottomLayoutOverflow(logicalBottomLayoutOverflow); m_overflow->setTopVisualOverflow(logicalTopVisualOverflow); diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp index 43b025a..9c96cc6 100644 --- a/WebCore/rendering/InlineTextBox.cpp +++ b/WebCore/rendering/InlineTextBox.cpp @@ -64,6 +64,11 @@ int InlineTextBox::selectionTop() return root()->selectionTop(); } +int InlineTextBox::selectionBottom() +{ + return root()->selectionBottom(); +} + int InlineTextBox::selectionHeight() { return root()->selectionHeight(); @@ -162,11 +167,13 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos) else if (r.right() > m_logicalWidth) logicalWidth = m_logicalWidth - r.x(); - IntPoint topPoint = m_isVertical ? IntPoint(tx + selTop, ty + m_y + r.x()) : IntPoint(tx + m_x + r.x(), ty + selTop); - int width = m_isVertical ? selHeight : logicalWidth; - int height = m_isVertical ? logicalWidth : selHeight; + IntPoint topPoint = isHorizontal() ? IntPoint(tx + m_x + r.x(), ty + selTop) : IntPoint(tx + selTop, ty + m_y + r.x()); + int width = isHorizontal() ? logicalWidth : selHeight; + int height = isHorizontal() ? selHeight : logicalWidth; - return IntRect(topPoint, IntSize(width, height)); + IntRect result = IntRect(topPoint, IntSize(width, height)); + flipForWritingMode(result); + return result; } void InlineTextBox::deleteLine(RenderArena* arena) @@ -309,23 +316,25 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in if (isLineBreak()) return false; - IntRect rect(tx + m_x, ty + m_y, width(), height()); + IntPoint boxOrigin = locationIncludingFlipping(); + boxOrigin.move(tx, ty); + IntRect rect(boxOrigin, IntSize(width(), height())); if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) { - renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); + renderer()->updateHitTestResult(result, flipForWritingMode(IntPoint(x - tx, y - ty))); if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, rect)) return true; } return false; } -FloatSize InlineTextBox::applyShadowToGraphicsContext(GraphicsContext* context, const ShadowData* shadow, const FloatRect& textRect, bool stroked, bool opaque, bool vertical) +FloatSize InlineTextBox::applyShadowToGraphicsContext(GraphicsContext* context, const ShadowData* shadow, const FloatRect& textRect, bool stroked, bool opaque, bool horizontal) { if (!shadow) return FloatSize(); FloatSize extraOffset; - int shadowX = vertical ? shadow->y() : shadow->x(); - int shadowY = vertical ? -shadow->x() : shadow->y(); + int shadowX = horizontal ? shadow->x() : shadow->y(); + int shadowY = horizontal ? shadow->y() : -shadow->x(); FloatSize shadowOffset(shadowX, shadowY); int shadowBlur = shadow->blur(); const Color& shadowColor = shadow->color(); @@ -346,7 +355,7 @@ FloatSize InlineTextBox::applyShadowToGraphicsContext(GraphicsContext* context, } static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, int startOffset, int endOffset, int truncationPoint, const IntPoint& textOrigin, - const IntRect& boxRect, const ShadowData* shadow, bool stroked, bool vertical) + const IntRect& boxRect, const ShadowData* shadow, bool stroked, bool horizontal) { Color fillColor = context->fillColor(); ColorSpace fillColorSpace = context->fillColorSpace(); @@ -357,7 +366,7 @@ static void paintTextWithShadows(GraphicsContext* context, const Font& font, con do { IntSize extraOffset; if (shadow) - extraOffset = roundedIntSize(InlineTextBox::applyShadowToGraphicsContext(context, shadow, boxRect, stroked, opaque, vertical)); + extraOffset = roundedIntSize(InlineTextBox::applyShadowToGraphicsContext(context, shadow, boxRect, stroked, opaque, horizontal)); else if (!opaque) context->setFillColor(fillColor, fillColorSpace); @@ -394,11 +403,11 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) // Would it be simpler to just check our own shadow and stroke overflow by hand here? int logicalLeftOverflow = parent()->logicalLeft() - parent()->logicalLeftVisualOverflow(); int logicalRightOverflow = parent()->logicalRightVisualOverflow() - (parent()->logicalLeft() + parent()->logicalWidth()); - int logicalStart = logicalLeft() - logicalLeftOverflow + (isVertical() ? ty : tx); + int logicalStart = logicalLeft() - logicalLeftOverflow + (isHorizontal() ? tx : ty); int logicalExtent = logicalWidth() + logicalLeftOverflow + logicalRightOverflow; - int paintEnd = isVertical() ? paintInfo.rect.bottom() : paintInfo.rect.right(); - int paintStart = isVertical() ? paintInfo.rect.y() : paintInfo.rect.x(); + int paintEnd = isHorizontal() ? paintInfo.rect.right() : paintInfo.rect.bottom(); + int paintStart = isHorizontal() ? paintInfo.rect.x() : paintInfo.rect.y(); if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart) return; @@ -424,7 +433,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) int widthOfVisibleText = toRenderText(renderer())->width(m_start, m_truncation, textPos(), m_firstLine); int widthOfHiddenText = m_logicalWidth - widthOfVisibleText; // FIXME: The hit testing logic also needs to take this translation int account. - if (!m_isVertical) + if (isHorizontal()) tx += isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText; else ty += isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText; @@ -437,14 +446,12 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) ty -= styleToUse->isHorizontalWritingMode() ? 0 : logicalHeight(); - IntPoint boxOrigin(m_x, m_y); - adjustForFlippedBlocksWritingMode(boxOrigin); - boxOrigin.move(tx, ty); - - IntPoint textOrigin = IntPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->font().ascent()); + IntPoint boxOrigin = locationIncludingFlipping(); + boxOrigin.move(tx, ty); IntRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight())); + IntPoint textOrigin = IntPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->font().ascent()); - if (m_isVertical) { + if (!isHorizontal()) { context->save(); context->translate(boxRect.x(), boxRect.bottom()); context->rotate(static_cast<float>(deg2rad(90.))); @@ -571,9 +578,9 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace()); if (!paintSelectedTextSeparately || ePos <= sPos) { // FIXME: Truncate right-to-left text correctly. - paintTextWithShadows(context, font, textRun, 0, length, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, m_isVertical); + paintTextWithShadows(context, font, textRun, 0, length, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); } else - paintTextWithShadows(context, font, textRun, ePos, sPos, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, m_isVertical); + paintTextWithShadows(context, font, textRun, ePos, sPos, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); if (textStrokeWidth > 0) context->restore(); @@ -585,7 +592,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) context->save(); updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth, styleToUse->colorSpace()); - paintTextWithShadows(context, font, textRun, sPos, ePos, length, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, m_isVertical); + paintTextWithShadows(context, font, textRun, sPos, ePos, length, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal()); if (selectionStrokeWidth > 0) context->restore(); @@ -626,7 +633,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) } } - if (m_isVertical) + if (!isHorizontal()) context->restore(); } @@ -680,7 +687,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& box ePos = length; } - int deltaY = logicalTop() - selectionTop(); + int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop(); int selHeight = selectionHeight(); IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); context->clip(IntRect(localOrigin, IntSize(m_logicalWidth, selHeight))); @@ -705,7 +712,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const I updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw text at all! - int deltaY = logicalTop() - selectionTop(); + int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop(); int selHeight = selectionHeight(); IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, @@ -769,8 +776,8 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo for (const ShadowData* s = shadow; s; s = s->next()) { IntRect shadowRect(localOrigin, IntSize(width, baseline + 2)); shadowRect.inflate(s->blur()); - int shadowX = m_isVertical ? s->y() : s->x(); - int shadowY = m_isVertical ? -s->x() : s->y(); + int shadowX = isHorizontal() ? s->x() : s->y(); + int shadowY = isHorizontal() ? s->y() : -s->x(); shadowRect.move(shadowX, shadowY); clipRect.unite(shadowRect); extraOffset = max(extraOffset, max(0, shadowY) + s->blur()); @@ -792,8 +799,8 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo localOrigin.move(0, -extraOffset); extraOffset = 0; } - int shadowX = m_isVertical ? shadow->y() : shadow->x(); - int shadowY = m_isVertical ? -shadow->x() : shadow->y(); + int shadowX = isHorizontal() ? shadow->x() : shadow->y(); + int shadowY = isHorizontal() ? shadow->y() : -shadow->x(); context->setShadow(IntSize(shadowX, shadowY - extraOffset), shadow->blur(), shadow->color(), colorSpace); setShadow = true; shadow = shadow->next(); @@ -867,7 +874,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP endPosition = min<int>(endPosition, m_truncation); // Calculate start & width - int deltaY = logicalTop() - selectionTop(); + int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop(); int selHeight = selectionHeight(); IntPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY); TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()); @@ -909,7 +916,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const IntPoint& bo { // Use same y positioning and height as for selection, so that when the selection and this highlight are on // the same word there are no pieces sticking out. - int deltaY = logicalTop() - selectionTop(); + int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop(); int selHeight = selectionHeight(); int sPos = max(marker.startOffset - m_start, (unsigned)0); @@ -1080,15 +1087,13 @@ unsigned InlineTextBox::caretMaxRenderedOffset() const int InlineTextBox::textPos() const { - if (x() == 0) + if (logicalLeft() == 0) return 0; - RenderBlock* blockElement = renderer()->containingBlock(); - return !isLeftToRightDirection() ? x() - blockElement->borderRight() - blockElement->paddingRight() - : x() - blockElement->borderLeft() - blockElement->paddingLeft(); + return logicalLeft() - blockElement->borderStart() - blockElement->paddingStart(); } -int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const +int InlineTextBox::offsetForPosition(int lineOffset, bool includePartialGlyphs) const { if (isLineBreak()) return 0; @@ -1097,7 +1102,7 @@ int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const RenderStyle* style = text->style(m_firstLine); const Font* f = &style->font(); return f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()), - _x - m_x, includePartialGlyphs); + lineOffset - logicalLeft(), includePartialGlyphs); } int InlineTextBox::positionForOffset(int offset) const @@ -1106,7 +1111,7 @@ int InlineTextBox::positionForOffset(int offset) const ASSERT(offset <= m_start + m_len); if (isLineBreak()) - return m_x; + return logicalLeft(); RenderText* text = toRenderText(renderer()); const Font& f = text->style(m_firstLine)->font(); @@ -1114,7 +1119,7 @@ int InlineTextBox::positionForOffset(int offset) const int to = !isLeftToRightDirection() ? m_len : offset - m_start; // FIXME: Do we need to add rightBearing here? return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride), - IntPoint(m_x, 0), 0, from, to)).right(); + IntPoint(logicalLeft(), 0), 0, from, to)).right(); } bool InlineTextBox::containsCaretOffset(int offset) const diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h index 9c4c72f..e72d625 100644 --- a/WebCore/rendering/InlineTextBox.h +++ b/WebCore/rendering/InlineTextBox.h @@ -74,8 +74,9 @@ public: virtual int lineHeight() const; private: - virtual int selectionTop(); - virtual int selectionHeight(); + int selectionTop(); + int selectionBottom(); + int selectionHeight(); public: virtual IntRect calculateBoundaries() const { return IntRect(x(), y(), logicalWidth(), logicalHeight()); } @@ -127,7 +128,7 @@ public: bool containsCaretOffset(int offset) const; // false for offset after line break // Needs to be public, so the static paintTextWithShadows() function can use it. - static FloatSize applyShadowToGraphicsContext(GraphicsContext*, const ShadowData*, const FloatRect& textRect, bool stroked, bool opaque, bool vertical); + static FloatSize applyShadowToGraphicsContext(GraphicsContext*, const ShadowData*, const FloatRect& textRect, bool stroked, bool opaque, bool horizontal); private: InlineTextBox* m_prevTextBox; // The previous box that also uses our RenderObject diff --git a/WebCore/rendering/RenderApplet.cpp b/WebCore/rendering/RenderApplet.cpp index f9eb56e..eaa3535 100644 --- a/WebCore/rendering/RenderApplet.cpp +++ b/WebCore/rendering/RenderApplet.cpp @@ -26,6 +26,7 @@ #include "HTMLAppletElement.h" #include "HTMLNames.h" #include "HTMLParamElement.h" +#include "PluginViewBase.h" #include "Widget.h" namespace WebCore { @@ -91,4 +92,19 @@ void RenderApplet::layout() setNeedsLayout(false); } +#if USE(ACCELERATED_COMPOSITING) +bool RenderApplet::requiresLayer() const +{ + if (RenderWidget::requiresLayer()) + return true; + + return allowsAcceleratedCompositing(); +} + +bool RenderApplet::allowsAcceleratedCompositing() const +{ + return widget() && widget()->isPluginViewBase() && static_cast<PluginViewBase*>(widget())->platformLayer(); +} +#endif + } // namespace WebCore diff --git a/WebCore/rendering/RenderApplet.h b/WebCore/rendering/RenderApplet.h index 641568d..007902d 100644 --- a/WebCore/rendering/RenderApplet.h +++ b/WebCore/rendering/RenderApplet.h @@ -27,34 +27,42 @@ namespace WebCore { - class HTMLAppletElement; +class HTMLAppletElement; - class RenderApplet : public RenderWidget { - public: - RenderApplet(HTMLAppletElement*, const HashMap<String, String>& args); - virtual ~RenderApplet(); +class RenderApplet : public RenderWidget { +public: + RenderApplet(HTMLAppletElement*, const HashMap<String, String>& args); + virtual ~RenderApplet(); - void createWidgetIfNecessary(); + void createWidgetIfNecessary(); - private: - virtual const char* renderName() const { return "RenderApplet"; } +#if USE(ACCELERATED_COMPOSITING) + virtual bool allowsAcceleratedCompositing() const; +#endif - virtual bool isApplet() const { return true; } +private: + virtual const char* renderName() const { return "RenderApplet"; } - virtual void layout(); - virtual IntSize intrinsicSize() const; + virtual bool isApplet() const { return true; } - HashMap<String, String> m_args; - }; + virtual void layout(); + virtual IntSize intrinsicSize() const; - inline RenderApplet* toRenderApplet(RenderObject* object) - { - ASSERT(!object || object->isApplet()); - return static_cast<RenderApplet*>(object); - } +#if USE(ACCELERATED_COMPOSITING) + virtual bool requiresLayer() const; +#endif - // This will catch anyone doing an unnecessary cast. - void toRenderApplet(const RenderApplet*); + HashMap<String, String> m_args; +}; + +inline RenderApplet* toRenderApplet(RenderObject* object) +{ + ASSERT(!object || object->isApplet()); + return static_cast<RenderApplet*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderApplet(const RenderApplet*); } // namespace WebCore diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp index e4ac673..a43fea9 100644 --- a/WebCore/rendering/RenderBlock.cpp +++ b/WebCore/rendering/RenderBlock.cpp @@ -60,10 +60,6 @@ using namespace Unicode; namespace WebCore { -// Number of pixels to allow as a fudge factor when clicking above or below a line. -// clicking up to verticalLineClickFudgeFactor pixels above a line will correspond to the closest point on the line. -static const int verticalLineClickFudgeFactor = 3; - using namespace HTMLNames; typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap; @@ -2283,8 +2279,7 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty) } } - IntPoint childPoint(tx, ty); - adjustForFlippedBlocksWritingMode(child, childPoint, ParentToChildFlippingAdjustment); + IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment); if (!child->hasSelfPaintingLayer() && !child->isFloating()) child->paint(info, childPoint.x(), childPoint.y()); @@ -2419,9 +2414,7 @@ void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preserv if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) { PaintInfo currentPaintInfo(paintInfo); currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground; - IntPoint childPoint(tx + r->left() + r->m_renderer->marginLeft() - r->m_renderer->x(), - ty + r->top() + r->m_renderer->marginTop() - r->m_renderer->y()); - adjustForFlippedBlocksWritingMode(r->m_renderer, childPoint, ParentToChildFlippingAdjustment); + IntPoint childPoint = flipForWritingMode(r->m_renderer, IntPoint(tx + r->left() + r->m_renderer->marginLeft() - r->m_renderer->x(), ty + r->top() + r->m_renderer->marginTop() - r->m_renderer->y()), ParentToChildFlippingAdjustment); r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y()); if (!preservePhase) { currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds; @@ -2544,7 +2537,7 @@ bool RenderBlock::isSelectionRoot() const if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() || isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() || - hasReflection() || hasMask()) + hasReflection() || hasMask() || isWritingModeRoot()) return true; if (view() && view()->selectionStart()) { @@ -2572,20 +2565,20 @@ GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintC offsetFromRepaintContainer -= layer()->scrolledContentOffset(); int lastTop = 0; - int lastLeft = leftSelectionOffset(this, lastTop); - int lastRight = rightSelectionOffset(this, lastTop); + int lastLeft = logicalLeftSelectionOffset(this, lastTop); + int lastRight = logicalRightSelectionOffset(this, lastTop); - return fillSelectionGaps(this, offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), lastTop, lastLeft, lastRight); + return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight); } void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty) { if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) { int lastTop = 0; - int lastLeft = leftSelectionOffset(this, lastTop); - int lastRight = rightSelectionOffset(this, lastTop); + int lastLeft = logicalLeftSelectionOffset(this, lastTop); + int lastRight = logicalRightSelectionOffset(this, lastTop); paintInfo.context->save(); - IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo); + IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo); if (!gapRectsBounds.isEmpty()) { if (RenderLayer* layer = enclosingLayer()) { gapRectsBounds.move(IntSize(-tx, -ty)); @@ -2601,8 +2594,7 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty) } } -#ifndef BUILDING_ON_TIGER -static void clipOutPositionedObjects(const PaintInfo* paintInfo, int tx, int ty, RenderBlock::PositionedObjectsListHashSet* positionedObjects) +static void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects) { if (!positionedObjects) return; @@ -2610,33 +2602,58 @@ static void clipOutPositionedObjects(const PaintInfo* paintInfo, int tx, int ty, RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end(); for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) { RenderBox* r = *it; - paintInfo->context->clipOut(IntRect(tx + r->x(), ty + r->y(), r->width(), r->height())); + paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height())); } } -#endif -GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, - int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo) +static int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock) +{ + return rootBlock->style()->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width(); +} + +static int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock) +{ + return rootBlock->style()->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height(); +} + +IntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect) +{ + IntRect result; + if (style()->isHorizontalWritingMode()) + result = logicalRect; + else + result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width()); + flipForWritingMode(result); + result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y()); + return result; +} + +GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo) { -#ifndef BUILDING_ON_TIGER // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore. // Clip out floating and positioned objects when painting selection gaps. if (paintInfo) { // Note that we don't clip out overflow for positioned objects. We just stick to the border box. - clipOutPositionedObjects(paintInfo, tx, ty, m_positionedObjects); + IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height()); + rootBlock->flipForWritingMode(flippedBlockRect); + flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y()); + clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects); if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects. for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock()) - clipOutPositionedObjects(paintInfo, cb->x(), cb->y(), cb->m_positionedObjects); + clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects); // FIXME: Not right for flipped writing modes. if (m_floatingObjects) { for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); it.current(); ++it) { FloatingObject* r = it.current(); - paintInfo->context->clipOut(IntRect(tx + r->left() + r->m_renderer->marginLeft(), - ty + r->top() + r->m_renderer->marginTop(), - r->m_renderer->width(), r->m_renderer->height())); + IntRect floatBox = IntRect(offsetFromRootBlock.width() + r->left() + r->m_renderer->marginLeft(), + offsetFromRootBlock.height() + r->top() + r->m_renderer->marginTop(), + r->m_renderer->width(), r->m_renderer->height()); + rootBlock->flipForWritingMode(floatBox); + floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y()); + paintInfo->context->clipOut(floatBox); } } } -#endif // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is // fixed). @@ -2646,26 +2663,26 @@ GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int if (hasColumns() || hasTransform() || style()->columnSpan()) { // FIXME: We should learn how to gap fill multiple columns and transforms eventually. - lastTop = (ty - blockY) + height(); - lastLeft = leftSelectionOffset(rootBlock, height()); - lastRight = rightSelectionOffset(rootBlock, height()); + lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight(); + lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()); + lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight()); return result; } if (childrenInline()) - result = fillInlineSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo); + result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); else - result = fillBlockSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo); + result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block. if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd)) - result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + height(), - rootBlock, blockX, blockY, paintInfo)); + result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, + logicalHeight(), paintInfo)); return result; } -GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, - int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo) +GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo) { GapRects result; @@ -2673,11 +2690,11 @@ GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX if (!firstLineBox()) { if (containsStart) { - // Go ahead and update our lastY to be the bottom of the block. <hr>s or empty blocks with height can trip this + // Go ahead and update our lastLogicalTop to be the bottom of the block. <hr>s or empty blocks with height can trip this // case. - lastTop = (ty - blockY) + height(); - lastLeft = leftSelectionOffset(rootBlock, height()); - lastRight = rightSelectionOffset(rootBlock, height()); + lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight(); + lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()); + lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight()); } return result; } @@ -2693,11 +2710,15 @@ GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX if (!containsStart && !lastSelectedLine && selectionState() != SelectionStart && selectionState() != SelectionBoth) - result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + selTop, - rootBlock, blockX, blockY, paintInfo)); - - if (!paintInfo || (ty + selTop < paintInfo->rect.bottom() && ty + selTop + selHeight > paintInfo->rect.y())) - result.unite(curr->fillLineSelectionGap(selTop, selHeight, rootBlock, blockX, blockY, tx, ty, paintInfo)); + result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, + selTop, paintInfo)); + + IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight); + logicalRect.move(style()->isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width())); + IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect); + if (!paintInfo || (style()->isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.bottom() && physicalRect.bottom() > paintInfo->rect.y()) + || (!style()->isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.right() && physicalRect.right() > paintInfo->rect.x())) + result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo)); lastSelectedLine = curr; } @@ -2708,15 +2729,15 @@ GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) { // Go ahead and update our lastY to be the bottom of the last selected line. - lastTop = (ty - blockY) + lastSelectedLine->selectionBottom(); - lastLeft = leftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); - lastRight = rightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); + lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom(); + lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); + lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); } return result; } -GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, - int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo) +GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo) { GapRects result; @@ -2746,8 +2767,8 @@ GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, // We need to fill the vertical gap above this object. if (childState == SelectionEnd || childState == SelectionInside) // Fill the gap above the object. - result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, - ty + curr->y(), rootBlock, blockX, blockY, paintInfo)); + result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, + curr->logicalTop(), paintInfo)); // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past* // our object. We know this if the selection did not end inside our object. @@ -2756,91 +2777,81 @@ GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, // Fill side gaps on this object based off its state. bool leftGap, rightGap; - getHorizontalSelectionGapInfo(childState, leftGap, rightGap); + getSelectionGapInfo(childState, leftGap, rightGap); if (leftGap) - result.uniteLeft(fillLeftSelectionGap(this, curr->x(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo)); + result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo)); if (rightGap) - result.uniteRight(fillRightSelectionGap(this, curr->x() + curr->width(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo)); + result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo)); - // Update lastTop to be just underneath the object. lastLeft and lastRight extend as far as + // Update lastLogicalTop to be just underneath the object. lastLogicalLeft and lastLogicalRight extend as far as // they can without bumping into floating or positioned objects. Ideally they will go right up // to the border of the root selection block. - lastTop = (ty - blockY) + (curr->y() + curr->height()); - lastLeft = leftSelectionOffset(rootBlock, curr->y() + curr->height()); - lastRight = rightSelectionOffset(rootBlock, curr->y() + curr->height()); + lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom(); + lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom()); + lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom()); } else if (childState != SelectionNone) // We must be a block that has some selected object inside it. Go ahead and recur. - result.unite(toRenderBlock(curr)->fillSelectionGaps(rootBlock, blockX, blockY, tx + curr->x(), ty + curr->y(), - lastTop, lastLeft, lastRight, paintInfo)); + result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), + lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo)); } return result; } -IntRect RenderBlock::fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo* paintInfo) +IntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo) { - if (width <= 0 || height <= 0) - return IntRect(); - IntRect gapRect(xPos, yPos, width, height); - if (paintInfo && selObj->style()->visibility() == VISIBLE) - paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace()); - return gapRect; -} - -IntRect RenderBlock::fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock, - int blockX, int blockY, const PaintInfo* paintInfo) -{ - int top = blockY + lastTop; - int height = bottomY - top; - if (height <= 0) + int logicalTop = lastLogicalTop; + int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop; + if (logicalHeight <= 0) return IntRect(); // Get the selection offsets for the bottom of the gap - int left = blockX + max(lastLeft, leftSelectionOffset(rootBlock, bottomY)); - int right = blockX + min(lastRight, rightSelectionOffset(rootBlock, bottomY)); - int width = right - left; - if (width <= 0) + int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom)); + int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom)); + int logicalWidth = logicalRight - logicalLeft; + if (logicalWidth <= 0) return IntRect(); - IntRect gapRect(left, top, width, height); + IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight)); if (paintInfo) paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace()); return gapRect; } -IntRect RenderBlock::fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, - int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo) +IntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo) { - int top = yPos + ty; - int left = blockX + max(leftSelectionOffset(rootBlock, yPos), leftSelectionOffset(rootBlock, yPos + height)); - int right = min(xPos + tx, blockX + min(rightSelectionOffset(rootBlock, yPos), rightSelectionOffset(rootBlock, yPos + height))); - int width = right - left; - if (width <= 0) + int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop; + int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)); + int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight))); + int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft; + if (rootBlockLogicalWidth <= 0) return IntRect(); - IntRect gapRect(left, top, width, height); + IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight)); if (paintInfo) paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace()); return gapRect; } -IntRect RenderBlock::fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, - int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo) +IntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo) { - int left = max(xPos + tx, blockX + max(leftSelectionOffset(rootBlock, yPos), leftSelectionOffset(rootBlock, yPos + height))); - int top = yPos + ty; - int right = blockX + min(rightSelectionOffset(rootBlock, yPos), rightSelectionOffset(rootBlock, yPos + height)); - int width = right - left; - if (width <= 0) + int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop; + int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight))); + int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)); + int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft; + if (rootBlockLogicalWidth <= 0) return IntRect(); - IntRect gapRect(left, top, width, height); + IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight)); if (paintInfo) paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace()); return gapRect; } -void RenderBlock::getHorizontalSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap) +void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap) { bool ltr = style()->isLeftToRightDirection(); leftGap = (state == RenderObject::SelectionInside) || @@ -2851,43 +2862,40 @@ void RenderBlock::getHorizontalSelectionGapInfo(SelectionState state, bool& left (state == RenderObject::SelectionEnd && !ltr); } -int RenderBlock::leftSelectionOffset(RenderBlock* rootBlock, int yPos) +int RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, int position) { - int left = logicalLeftOffsetForLine(yPos, false); - if (left == borderLeft() + paddingLeft()) { + int logicalLeft = logicalLeftOffsetForLine(position, false); + if (logicalLeft == logicalLeftOffsetForContent()) { if (rootBlock != this) // The border can potentially be further extended by our containingBlock(). - return containingBlock()->leftSelectionOffset(rootBlock, yPos + y()); - return left; - } - else { + return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop()); + return logicalLeft; + } else { RenderBlock* cb = this; while (cb != rootBlock) { - left += cb->x(); + logicalLeft += cb->logicalLeft(); cb = cb->containingBlock(); } } - - return left; + return logicalLeft; } -int RenderBlock::rightSelectionOffset(RenderBlock* rootBlock, int yPos) +int RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, int position) { - int right = logicalRightOffsetForLine(yPos, false); - if (right == (contentWidth() + (borderLeft() + paddingLeft()))) { + int logicalRight = logicalRightOffsetForLine(position, false); + if (logicalRight == logicalRightOffsetForContent()) { if (rootBlock != this) // The border can potentially be further extended by our containingBlock(). - return containingBlock()->rightSelectionOffset(rootBlock, yPos + y()); - return right; - } - else { + return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop()); + return logicalRight; + } else { RenderBlock* cb = this; while (cb != rootBlock) { - right += cb->x(); + logicalRight += cb->logicalLeft(); cb = cb->containingBlock(); } } - return right; + return logicalRight; } void RenderBlock::insertPositionedObject(RenderBox* o) @@ -4165,10 +4173,11 @@ bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& re DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); for (it.toLast(); (floatingObject = it.current()); --it) { if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) { - int xOffset = tx + floatingObject->left() + floatingObject->m_renderer->marginLeft() - floatingObject->m_renderer->x(); - int yOffset = ty + floatingObject->top() + floatingObject->m_renderer->marginTop() - floatingObject->m_renderer->y(); - if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), xOffset, yOffset)) { - updateHitTestResult(result, IntPoint(x - xOffset, y - yOffset)); + int xOffset = floatingObject->left() + floatingObject->m_renderer->marginLeft() - floatingObject->m_renderer->x(); + int yOffset = floatingObject->top() + floatingObject->m_renderer->marginTop() - floatingObject->m_renderer->y(); + IntPoint childPoint= flipForWritingMode(floatingObject->m_renderer, IntPoint(tx + xOffset, ty + yOffset), ParentToChildFlippingAdjustment); + if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) { + updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y())); return true; } } @@ -4223,7 +4232,8 @@ bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& if (hitTestAction == HitTestChildBlockBackgrounds) childHitTest = HitTestChildBlockBackground; for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) { - if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, tx, ty, childHitTest)) + IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment); + if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, childPoint.x(), childPoint.y(), childHitTest)) return true; } } @@ -4312,18 +4322,8 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& firstRootBoxWithChildren = root; lastRootBoxWithChildren = root; - // set the bottom based on whether there is a next root box - // FIXME: This will consider nextRootBox even if it has no children, and maybe it shouldn't. - int bottom; - if (root->nextRootBox()) { - // FIXME: We would prefer to make the break point halfway between the bottom - // of the previous root box and the top of the next root box. - bottom = root->nextRootBox()->lineTop(); - } else - bottom = root->lineBottom() + verticalLineClickFudgeFactor; - // check if this root line box is located at this y coordinate - if (pointInContents.y() < bottom) { + if (pointInContents.y() < root->selectionBottom()) { closestBox = root->closestLeafChildForXPos(pointInContents.x()); if (closestBox) break; @@ -4338,7 +4338,7 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& } if (closestBox) { - if (moveCaretToBoundary && pointInContents.y() < firstRootBoxWithChildren->lineTop() - verticalLineClickFudgeFactor) { + if (moveCaretToBoundary && pointInContents.y() < firstRootBoxWithChildren->selectionTop()) { // y coordinate is above first root line box, so return the start of the first return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM); } @@ -4728,7 +4728,7 @@ void RenderBlock::computePreferredLogicalWidths() } if (isTableCell()) { - Length w = toRenderTableCell(this)->styleOrColWidth(); + Length w = toRenderTableCell(this)->styleOrColLogicalWidth(); if (w.isFixed() && w.value() > 0) m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value())); } diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h index 4956fc0..1cc89c0 100644 --- a/WebCore/rendering/RenderBlock.h +++ b/WebCore/rendering/RenderBlock.h @@ -115,14 +115,13 @@ public: bool containsNonZeroBidiLevel() const; GapRects selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer); - IntRect fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, - int blockX, int blockY, int tx, int ty, const PaintInfo*); - IntRect fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, - int blockX, int blockY, int tx, int ty, const PaintInfo*); - IntRect fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo*); - - void getHorizontalSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap); - + IntRect logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo*); + IntRect logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo*); + void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap); + IntRect logicalRectToPhysicalRect(const IntPoint& physicalPosition, const IntRect& logicalRect); + // Helper methods for computing line counts and heights for line counts. RootInlineBox* lineAtIndex(int); int lineCount(); @@ -531,17 +530,17 @@ private: } virtual bool shouldPaintSelectionGaps() const; bool isSelectionRoot() const; - GapRects fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, - int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* = 0); - GapRects fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, - int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*); - GapRects fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, - int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*); - IntRect fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock, - int blockX, int blockY, const PaintInfo*); - int leftSelectionOffset(RenderBlock* rootBlock, int y); - int rightSelectionOffset(RenderBlock* rootBlock, int y); - + GapRects selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* = 0); + GapRects inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo*); + GapRects blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo*); + IntRect blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo*); + int logicalLeftSelectionOffset(RenderBlock* rootBlock, int position); + int logicalRightSelectionOffset(RenderBlock* rootBlock, int position); + virtual void absoluteRects(Vector<IntRect>&, int tx, int ty); virtual void absoluteQuads(Vector<FloatQuad>&); diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp index 0b2387d..e843110 100644 --- a/WebCore/rendering/RenderBlockLineLayout.cpp +++ b/WebCore/rendering/RenderBlockLineLayout.cpp @@ -215,7 +215,7 @@ InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj, bool firstLine) ASSERT(newBox->isInlineFlowBox()); parentBox = static_cast<InlineFlowBox*>(newBox); parentBox->setFirstLineStyleBit(firstLine); - parentBox->setIsVertical(!style()->isHorizontalWritingMode()); + parentBox->setIsHorizontal(style()->isHorizontalWritingMode()); constructedNewBox = true; } diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp index ebd965f..fc617c4 100644 --- a/WebCore/rendering/RenderBox.cpp +++ b/WebCore/rendering/RenderBox.cpp @@ -1434,6 +1434,9 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, In return; } + if (o->isBox()) + toRenderBox(o)->flipForWritingMode(rect); + o->computeRectForRepaint(repaintContainer, rect, fixed); } @@ -3253,40 +3256,64 @@ int RenderBox::baselinePosition(bool /*firstLine*/, LineDirectionMode direction, return 0; } -void RenderBox::blockDirectionOverflow(bool isLineVertical, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow, +void RenderBox::blockDirectionOverflow(bool isLineHorizontal, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow, int& logicalTopVisualOverflow, int& logicalBottomVisualOverflow) { - if (isLineVertical) { - logicalTopLayoutOverflow = leftLayoutOverflow(); - logicalBottomLayoutOverflow = rightLayoutOverflow(); - logicalTopVisualOverflow = leftVisualOverflow(); - logicalBottomVisualOverflow = rightVisualOverflow(); - } else { + if (isLineHorizontal) { logicalTopLayoutOverflow = topLayoutOverflow(); logicalBottomLayoutOverflow = bottomLayoutOverflow(); logicalTopVisualOverflow = topVisualOverflow(); logicalBottomVisualOverflow = bottomVisualOverflow(); - } + } else { + logicalTopLayoutOverflow = leftLayoutOverflow(); + logicalBottomLayoutOverflow = rightLayoutOverflow(); + logicalTopVisualOverflow = leftVisualOverflow(); + logicalBottomVisualOverflow = rightVisualOverflow(); + } } -void RenderBox::adjustForFlippedBlocksWritingMode(RenderBox* child, IntPoint& point, FlippingAdjustment adjustment) +IntPoint RenderBox::flipForWritingMode(RenderBox* child, const IntPoint& point, FlippingAdjustment adjustment) { if (!style()->isFlippedBlocksWritingMode()) - return; + return point; // The child is going to add in its x() and y(), so we have to make sure it ends up in // the right place. if (style()->isHorizontalWritingMode()) - point.move(0, height() - child->height() - child->y() - (adjustment == ParentToChildFlippingAdjustment ? child->y() : 0)); + return IntPoint(point.x(), point.y() + height() - child->height() - child->y() - (adjustment == ParentToChildFlippingAdjustment ? child->y() : 0)); + return IntPoint(point.x() + width() - child->width() - child->x() - (adjustment == ParentToChildFlippingAdjustment ? child->x() : 0), point.y()); +} + +void RenderBox::flipForWritingMode(IntRect& rect) +{ + if (!style()->isFlippedBlocksWritingMode()) + return; + + if (style()->isHorizontalWritingMode()) + rect.setY(height() - rect.bottom()); else - point.move(width() - child->width() - child->x() - (adjustment == ParentToChildFlippingAdjustment ? child->x() : 0), 0); + rect.setX(width() - rect.right()); +} + +int RenderBox::flipForWritingMode(int position) +{ + if (!style()->isFlippedBlocksWritingMode()) + return position; + return logicalHeight() - position; +} + +IntPoint RenderBox::flipForWritingMode(const IntPoint& position) +{ + if (!style()->isFlippedBlocksWritingMode()) + return position; + return style()->isHorizontalWritingMode() ? IntPoint(position.x(), height() - position.y()) : IntPoint(width() - position.x(), position.y()); } -int RenderBox::convertFromFlippedWritingMode(int logicalPosition) +IntSize RenderBox::flipForWritingMode(const IntSize& offset) { if (!style()->isFlippedBlocksWritingMode()) - return logicalPosition; - return logicalHeight() - logicalPosition; + return offset; + return style()->isHorizontalWritingMode() ? IntSize(offset.width(), height() - offset.height()) : IntSize(width() - offset.width(), offset.height()); } IntSize RenderBox::locationOffsetIncludingFlipping() @@ -3295,8 +3322,7 @@ IntSize RenderBox::locationOffsetIncludingFlipping() return locationOffset(); RenderBox* parent = parentBox(); - IntPoint localPoint(x(), y()); - parent->adjustForFlippedBlocksWritingMode(this, localPoint, ChildToParentFlippingAdjustment); + IntPoint localPoint = parent->flipForWritingMode(this, location(), ChildToParentFlippingAdjustment); return IntSize(localPoint.x(), localPoint.y()); } diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h index 3b261bd..ac96bb7 100644 --- a/WebCore/rendering/RenderBox.h +++ b/WebCore/rendering/RenderBox.h @@ -51,9 +51,12 @@ public: void setHeight(int height) { m_frameRect.setHeight(height); } int logicalLeft() const { return style()->isHorizontalWritingMode() ? x() : y(); } + int logicalRight() const { return logicalLeft() + logicalWidth(); } int logicalTop() const { return style()->isHorizontalWritingMode() ? y() : x(); } + int logicalBottom() const { return logicalTop() + logicalHeight(); } int logicalWidth() const { return style()->isHorizontalWritingMode() ? width() : height(); } int logicalHeight() const { return style()->isHorizontalWritingMode() ? height() : width(); } + void setLogicalLeft(int left) { if (style()->isHorizontalWritingMode()) @@ -155,7 +158,7 @@ public: void addOverflowFromChild(RenderBox* child, const IntSize& delta); void clearLayoutOverflow(); - void blockDirectionOverflow(bool isLineVertical, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow, + void blockDirectionOverflow(bool isLineHorizontal, int& logicalTopLayoutOverflow, int& logicalBottomLayoutOverflow, int& logicalTopVisualOverflow, int& logicalBottomVisualOverflow); int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); } @@ -378,8 +381,11 @@ public: virtual int baselinePosition(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const; enum FlippingAdjustment { ChildToParentFlippingAdjustment, ParentToChildFlippingAdjustment }; - void adjustForFlippedBlocksWritingMode(RenderBox* child, IntPoint&, FlippingAdjustment); - int convertFromFlippedWritingMode(int position); + IntPoint flipForWritingMode(RenderBox* child, const IntPoint&, FlippingAdjustment); + int flipForWritingMode(int position); + IntPoint flipForWritingMode(const IntPoint&); + IntSize flipForWritingMode(const IntSize&); + void flipForWritingMode(IntRect&); IntSize locationOffsetIncludingFlipping(); #ifdef ANDROID_LAYOUT diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp index e83b709..ae89e0a 100644 --- a/WebCore/rendering/RenderBoxModelObject.cpp +++ b/WebCore/rendering/RenderBoxModelObject.cpp @@ -526,17 +526,17 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co if (!includeLeftEdge) { topLeft = IntSize(); - if (box->isVertical()) - topRight = IntSize(); - else + if (box->isHorizontal()) bottomLeft = IntSize(); + else + topRight = IntSize(); } if (!includeRightEdge) { - if (box->isVertical()) - bottomLeft = IntSize(); - else + if (box->isHorizontal()) topRight = IntSize(); + else + bottomLeft = IntSize(); bottomRight = IntSize(); } diff --git a/WebCore/rendering/RenderIndicator.h b/WebCore/rendering/RenderIndicator.h index b1f4acf..15741dc 100644 --- a/WebCore/rendering/RenderIndicator.h +++ b/WebCore/rendering/RenderIndicator.h @@ -35,6 +35,7 @@ protected: virtual void layout(); virtual void updateFromElement(); virtual bool requiresForcedStyleRecalcPropagation() const { return true; } + virtual bool canHaveChildren() const { return false; } virtual void layoutParts() = 0; virtual bool shouldHaveParts() const = 0; diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp index 4b28268..1a792e7 100644 --- a/WebCore/rendering/RenderInline.cpp +++ b/WebCore/rendering/RenderInline.cpp @@ -559,18 +559,22 @@ IntRect RenderInline::linesBoundingBox() const ASSERT(!firstLineBox() == !lastLineBox()); // Either both are null or both exist. if (firstLineBox() && lastLineBox()) { // Return the width of the minimal left side and the maximal right side. - int leftSide = 0; - int rightSide = 0; + int logicalLeftSide = 0; + int logicalRightSide = 0; for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { - if (curr == firstLineBox() || curr->x() < leftSide) - leftSide = curr->x(); - if (curr == firstLineBox() || curr->x() + curr->logicalWidth() > rightSide) - rightSide = curr->x() + curr->logicalWidth(); + if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide) + logicalLeftSide = curr->logicalLeft(); + if (curr == firstLineBox() || curr->logicalRight() > logicalRightSide) + logicalRightSide = curr->logicalRight(); } - result.setWidth(rightSide - leftSide); - result.setX(leftSide); - result.setHeight(lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y()); - result.setY(firstLineBox()->y()); + + bool isHorizontal = style()->isHorizontalWritingMode(); + + int x = isHorizontal ? logicalLeftSide : firstLineBox()->x(); + int y = isHorizontal ? firstLineBox()->y() : logicalLeftSide; + int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->logicalBottom() - x; + int height = isHorizontal ? lastLineBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide; + result = IntRect(x, y, width, height); } return result; @@ -582,15 +586,20 @@ IntRect RenderInline::linesVisibleOverflowBoundingBox() const return IntRect(); // Return the width of the minimal left side and the maximal right side. - int leftSide = numeric_limits<int>::max(); - int rightSide = numeric_limits<int>::min(); + int logicalLeftSide = numeric_limits<int>::max(); + int logicalRightSide = numeric_limits<int>::min(); for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { - leftSide = min(leftSide, curr->leftVisibleOverflow()); - rightSide = max(rightSide, curr->rightVisibleOverflow()); + logicalLeftSide = min(logicalLeftSide, curr->logicalLeftVisibleOverflow()); + logicalRightSide = max(logicalRightSide, curr->logicalRightVisibleOverflow()); } - return IntRect(leftSide, firstLineBox()->topVisibleOverflow(), rightSide - leftSide, - lastLineBox()->bottomVisibleOverflow() - firstLineBox()->topVisibleOverflow()); + bool isHorizontal = style()->isHorizontalWritingMode(); + + int x = isHorizontal ? logicalLeftSide : firstLineBox()->leftVisibleOverflow(); + int y = isHorizontal ? firstLineBox()->topVisibleOverflow() : logicalLeftSide; + int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->rightVisibleOverflow() - firstLineBox()->leftVisibleOverflow(); + int height = isHorizontal ? lastLineBox()->bottomVisibleOverflow() - firstLineBox()->topVisibleOverflow() : logicalRightSide - logicalLeftSide; + return IntRect(x, y, width, height); } IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) @@ -619,6 +628,8 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repain } IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.height() + ow * 2); + cb->flipForWritingMode(r); + if (cb->hasColumns()) cb->adjustRectForColumns(r); diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp index 11ae66f..2678207 100644 --- a/WebCore/rendering/RenderLayer.cpp +++ b/WebCore/rendering/RenderLayer.cpp @@ -3787,8 +3787,14 @@ void RenderLayer::repaintIncludingNonCompositingDescendants(RenderBoxModelObject bool RenderLayer::shouldBeNormalFlowOnly() const { - return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isVideo() || renderer()->isEmbeddedObject() || - renderer()->isRenderIFrame() || renderer()->style()->specifiesColumns()) + return (renderer()->hasOverflowClip() + || renderer()->hasReflection() + || renderer()->hasMask() + || renderer()->isVideo() + || renderer()->isEmbeddedObject() + || renderer()->isApplet() + || renderer()->isRenderIFrame() + || renderer()->style()->specifiesColumns()) && !renderer()->isPositioned() && !renderer()->isRelPositioned() && !renderer()->hasTransform() @@ -3797,11 +3803,22 @@ bool RenderLayer::shouldBeNormalFlowOnly() const bool RenderLayer::isSelfPaintingLayer() const { +<<<<<<< HEAD #if ENABLE(ANDROID_OVERFLOW_SCROLL) if (hasOverflowScroll()) return true; #endif return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo() || renderer()->isEmbeddedObject() || renderer()->isRenderIFrame(); +======= + return !isNormalFlowOnly() + || renderer()->hasReflection() + || renderer()->hasMask() + || renderer()->isTableRow() + || renderer()->isVideo() + || renderer()->isEmbeddedObject() + || renderer()->isApplet() + || renderer()->isRenderIFrame(); +>>>>>>> webkit.org at r71558 } void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*) diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp index ce7690a..6f8dbc8 100644 --- a/WebCore/rendering/RenderLayerBacking.cpp +++ b/WebCore/rendering/RenderLayerBacking.cpp @@ -46,6 +46,7 @@ #include "InspectorInstrumentation.h" #include "KeyframeList.h" #include "PluginViewBase.h" +#include "RenderApplet.h" #include "RenderBox.h" #include "RenderIFrame.h" #include "RenderImage.h" @@ -228,6 +229,7 @@ void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth, bool isUpdat bool RenderLayerBacking::updateGraphicsLayerConfiguration() { RenderLayerCompositor* compositor = this->compositor(); + RenderObject* renderer = this->renderer(); bool layerConfigChanged = false; if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer))) @@ -236,7 +238,7 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), compositor->clipsCompositingDescendants(m_owningLayer))) layerConfigChanged = true; - if (updateMaskLayer(m_owningLayer->renderer()->hasMask())) + if (updateMaskLayer(renderer->hasMask())) m_graphicsLayer->setMaskLayer(m_maskLayer.get()); if (m_owningLayer->hasReflection()) { @@ -250,27 +252,28 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() if (isDirectlyCompositedImage()) updateImageContents(); - if (renderer()->isEmbeddedObject() && toRenderEmbeddedObject(renderer())->allowsAcceleratedCompositing()) { - PluginViewBase* pluginViewBase = static_cast<PluginViewBase*>(toRenderEmbeddedObject(renderer())->widget()); + if ((renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) + || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing())) { + PluginViewBase* pluginViewBase = static_cast<PluginViewBase*>(toRenderWidget(renderer)->widget()); m_graphicsLayer->setContentsToMedia(pluginViewBase->platformLayer()); } #if ENABLE(VIDEO) - else if (renderer()->isVideo()) { - HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer()->node()); + else if (renderer->isVideo()) { + HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer->node()); m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer()); } #endif #if ENABLE(3D_CANVAS) || ENABLE(ACCELERATED_2D_CANVAS) - else if (isAcceleratedCanvas(renderer())) { - HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node()); + else if (isAcceleratedCanvas(renderer)) { + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node()); if (CanvasRenderingContext* context = canvas->renderingContext()) m_graphicsLayer->setContentsToCanvas(context->platformLayer()); layerConfigChanged = true; } #endif - if (renderer()->isRenderIFrame()) - layerConfigChanged = RenderLayerCompositor::parentIFrameContentLayers(toRenderIFrame(renderer())); + if (renderer->isRenderIFrame()) + layerConfigChanged = RenderLayerCompositor::parentIFrameContentLayers(toRenderIFrame(renderer)); return layerConfigChanged; } diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp index 835d21e..da804dd 100644 --- a/WebCore/rendering/RenderLayerCompositor.cpp +++ b/WebCore/rendering/RenderLayerCompositor.cpp @@ -42,6 +42,7 @@ #include "HitTestResult.h" #include "NodeList.h" #include "Page.h" +#include "RenderApplet.h" #include "RenderEmbeddedObject.h" #include "RenderIFrame.h" #include "RenderLayerBacking.h" @@ -1101,6 +1102,15 @@ bool RenderLayerCompositor::has3DContent() const return layerHas3DContent(rootRenderLayer()); } +bool RenderLayerCompositor::allowsIndependentlyCompositedIFrames(const FrameView* view) +{ +#if PLATFORM(MAC) + // iframes are only independently composited in Mac pre-WebKit2. + return view->platformWidget(); +#endif + return false; +} + bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame() const { // Parent document content needs to be able to render on top of a composited iframe, so correct behavior @@ -1111,12 +1121,7 @@ bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame() const if (!renderer || !renderer->isRenderIFrame()) return false; -#if !PLATFORM(MAC) - // On non-Mac platforms, let compositing propagate for all iframes. - return true; -#else - // If we're viewless (i.e. WebKit2), we always propagate compositing. - if (!m_renderView->frameView()->platformWidget()) + if (!allowsIndependentlyCompositedIFrames(m_renderView->frameView())) return true; // On Mac, only propagate compositing if the iframe is overlapped in the parent @@ -1125,17 +1130,11 @@ bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame() const if (iframeRenderer->widget()) { ASSERT(iframeRenderer->widget()->isFrameView()); FrameView* view = static_cast<FrameView*>(iframeRenderer->widget()); - if (view->isOverlapped()) + if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor()) return true; - - if (RenderView* view = iframeRenderer->view()) { - if (view->compositor()->inCompositingMode()) - return true; - } } return false; -#endif } HTMLFrameOwnerElement* RenderLayerCompositor::enclosingIFrameElement() const @@ -1314,21 +1313,20 @@ bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const { - if (!renderer->isEmbeddedObject()) - return false; - - RenderEmbeddedObject* embedRenderer = toRenderEmbeddedObject(renderer); - if (!embedRenderer->allowsAcceleratedCompositing()) + bool composite = (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) + || (renderer->isApplet() && toRenderApplet(renderer)->allowsAcceleratedCompositing()); + if (!composite) return false; m_compositingDependsOnGeometry = true; - + + RenderWidget* pluginRenderer = toRenderWidget(renderer); // If we can't reliably know the size of the plugin yet, don't change compositing state. - if (renderer->needsLayout()) - return embedRenderer->hasLayer() && embedRenderer->layer()->isComposited(); + if (pluginRenderer->needsLayout()) + return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited(); // Don't go into compositing mode if height or width are zero, or size is 1x1. - IntRect contentBox = embedRenderer->contentBoxRect(); + IntRect contentBox = pluginRenderer->contentBoxRect(); return contentBox.height() * contentBox.width() > 1; } @@ -1561,7 +1559,7 @@ void RenderLayerCompositor::notifyIFramesOfCompositingChange() if (!frame) return; - for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { + for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->traverseNext(frame)) { if (child->document() && child->document()->ownerElement()) scheduleNeedsStyleRecalc(child->document()->ownerElement()); } diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h index b4e3afe..ad1e2e1 100644 --- a/WebCore/rendering/RenderLayerCompositor.h +++ b/WebCore/rendering/RenderLayerCompositor.h @@ -151,8 +151,9 @@ public: // to know if there is non-affine content, e.g. for drawing into an image. bool has3DContent() const; - // Some platforms may wish to connect compositing layer trees between iframes and - // their parent document. + // Most platforms connect compositing layer trees between iframes and their parent document. + // Some (currently just Mac) allow iframes to do their own compositing. + static bool allowsIndependentlyCompositedIFrames(const FrameView*); bool shouldPropagateCompositingToEnclosingIFrame() const; // FIXME: This should be a RenderIFrame* diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp index e5fc791..3139fd5 100644 --- a/WebCore/rendering/RenderLineBoxList.cpp +++ b/WebCore/rendering/RenderLineBoxList.cpp @@ -145,55 +145,55 @@ void RenderLineBoxList::dirtyLineBoxes() curr->dirtyLineBoxes(); } -bool RenderLineBoxList::rangeIntersectsDirtyRect(RenderBoxModelObject* renderer, int logicalTop, int logicalBottom, const PaintInfo& paintInfo, int tx, int ty) const +bool RenderLineBoxList::rangeIntersectsRect(RenderBoxModelObject* renderer, int logicalTop, int logicalBottom, const IntRect& rect, int tx, int ty) const { RenderBox* block; if (renderer->isBox()) block = toRenderBox(renderer); else block = renderer->containingBlock(); - int physicalStart = block->convertFromFlippedWritingMode(logicalTop); - int physicalEnd = block->convertFromFlippedWritingMode(logicalBottom); + int physicalStart = block->flipForWritingMode(logicalTop); + int physicalEnd = block->flipForWritingMode(logicalBottom); int physicalExtent = abs(physicalEnd - physicalStart); physicalStart = min(physicalStart, physicalEnd); if (renderer->style()->isHorizontalWritingMode()) { physicalStart += ty; - if (physicalStart >= paintInfo.rect.bottom() || physicalStart + physicalExtent <= paintInfo.rect.y()) + if (physicalStart >= rect.bottom() || physicalStart + physicalExtent <= rect.y()) return false; } else { physicalStart += tx; - if (physicalStart >= paintInfo.rect.right() || physicalStart + physicalExtent <= paintInfo.rect.x()) + if (physicalStart >= rect.right() || physicalStart + physicalExtent <= rect.x()) return false; } return true; } -bool RenderLineBoxList::anyLineIntersectsDirtyRect(RenderBoxModelObject* renderer, const PaintInfo& paintInfo, int tx, int ty, bool usePrintRect) const +bool RenderLineBoxList::anyLineIntersectsRect(RenderBoxModelObject* renderer, const IntRect& rect, int tx, int ty, bool usePrintRect, int outlineSize) const { - // We can check the first box and last box and avoid painting if we don't + // We can check the first box and last box and avoid painting/hit testing if we don't // intersect. This is a quick short-circuit that we can take to avoid walking any lines. // FIXME: This check is flawed in the following extremely obscure way: // if some line in the middle has a huge overflow, it might actually extend below the last line. - int firstLineTop = firstLineBox()->topVisibleOverflow(); + int firstLineTop = firstLineBox()->logicalTopVisibleOverflow(); if (usePrintRect && !firstLineBox()->parent()) firstLineTop = min(firstLineTop, firstLineBox()->root()->lineTop()); - int lastLineBottom = lastLineBox()->bottomVisibleOverflow(); + int lastLineBottom = lastLineBox()->logicalBottomVisibleOverflow(); if (usePrintRect && !lastLineBox()->parent()) lastLineBottom = max(lastLineBottom, lastLineBox()->root()->lineBottom()); - int logicalTop = firstLineTop - renderer->maximalOutlineSize(paintInfo.phase); - int logicalBottom = renderer->maximalOutlineSize(paintInfo.phase) + lastLineBottom; + int logicalTop = firstLineTop - outlineSize; + int logicalBottom = outlineSize + lastLineBottom; - return rangeIntersectsDirtyRect(renderer, logicalTop, logicalBottom, paintInfo, tx, ty); + return rangeIntersectsRect(renderer, logicalTop, logicalBottom, rect, tx, ty); } bool RenderLineBoxList::lineIntersectsDirtyRect(RenderBoxModelObject* renderer, InlineFlowBox* box, const PaintInfo& paintInfo, int tx, int ty) const { - int logicalTop = min(box->topVisibleOverflow(), box->root()->selectionTop()) - renderer->maximalOutlineSize(paintInfo.phase); - int logicalBottom = box->bottomVisibleOverflow() + renderer->maximalOutlineSize(paintInfo.phase); + int logicalTop = min(box->logicalTopVisibleOverflow(), box->root()->selectionTop()) - renderer->maximalOutlineSize(paintInfo.phase); + int logicalBottom = box->logicalBottomVisibleOverflow() + renderer->maximalOutlineSize(paintInfo.phase); - return rangeIntersectsDirtyRect(renderer, logicalTop, logicalBottom, paintInfo, tx, ty); + return rangeIntersectsRect(renderer, logicalTop, logicalBottom, paintInfo.rect, tx, ty); } void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintInfo, int tx, int ty) const @@ -214,8 +214,8 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn // NSViews. Do not add any more code for this. RenderView* v = renderer->view(); bool usePrintRect = !v->printRect().isEmpty(); - - if (!anyLineIntersectsDirtyRect(renderer, paintInfo, tx, ty, usePrintRect)) + int outlineSize = renderer->maximalOutlineSize(paintInfo.phase); + if (!anyLineIntersectsRect(renderer, paintInfo.rect, tx, ty, usePrintRect, outlineSize)) return; PaintInfo info(paintInfo); @@ -278,26 +278,21 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq if (!firstLineBox()) return false; - bool isVertical = firstLineBox()->isVertical(); + bool isHorizontal = firstLineBox()->isHorizontal(); - int logicalPointStart = isVertical ? x - result.leftPadding() : y - result.topPadding(); - int logicalPointEnd = isVertical ? x + result.rightPadding() : y + result.bottomPadding(); - int offset = isVertical ? tx : ty; - - // We can check the first box and last box and avoid hit testing if we don't - // contain the point. This is a quick short-circuit that we can take to avoid walking any lines. - // FIXME: This check is flawed in the following extremely obscure way: - // if some line in the middle has a huge overflow, it might actually extend below the last line. - if (logicalPointStart >= offset + lastLineBox()->root()->logicalBottomVisibleOverflow() - || logicalPointEnd < offset + firstLineBox()->root()->logicalTopVisibleOverflow()) + int logicalPointStart = isHorizontal ? y - result.topPadding() : x - result.leftPadding(); + int logicalPointEnd = (isHorizontal ? y + result.bottomPadding() : x + result.rightPadding()) + 1; + IntRect rect(isHorizontal ? x : logicalPointStart, isHorizontal ? logicalPointStart : y, + isHorizontal ? 1 : logicalPointEnd - logicalPointStart, + isHorizontal ? logicalPointEnd - logicalPointStart : 1); + if (!anyLineIntersectsRect(renderer, rect, tx, ty)) return false; // See if our root lines contain the point. If so, then we hit test // them further. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) { - if (logicalPointEnd >= offset + curr->root()->logicalTopVisibleOverflow() - && logicalPointStart < offset + curr->root()->logicalBottomVisibleOverflow()) { + if (rangeIntersectsRect(renderer, curr->logicalTopVisibleOverflow(), curr->logicalBottomVisibleOverflow(), rect, tx, ty)) { bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty); if (inside) { renderer->updateHitTestResult(result, IntPoint(x - tx, y - ty)); diff --git a/WebCore/rendering/RenderLineBoxList.h b/WebCore/rendering/RenderLineBoxList.h index 9ffacdf..9708d67 100644 --- a/WebCore/rendering/RenderLineBoxList.h +++ b/WebCore/rendering/RenderLineBoxList.h @@ -67,9 +67,9 @@ public: bool hitTest(RenderBoxModelObject*, const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction) const; private: - bool anyLineIntersectsDirtyRect(RenderBoxModelObject*, const PaintInfo&, int x, int y, bool usePrintRect) const; - bool lineIntersectsDirtyRect(RenderBoxModelObject*, InlineFlowBox*, const PaintInfo&, int x, int y) const; - bool rangeIntersectsDirtyRect(RenderBoxModelObject*, int logicalTop, int logicalBottom, const PaintInfo&, int x, int y) const; + bool anyLineIntersectsRect(RenderBoxModelObject*, const IntRect&, int tx, int ty, bool usePrintRect = false, int outlineSize = 0) const; + bool lineIntersectsDirtyRect(RenderBoxModelObject*, InlineFlowBox*, const PaintInfo&, int tx, int ty) const; + bool rangeIntersectsRect(RenderBoxModelObject*, int logicalTop, int logicalBottom, const IntRect&, int tx, int ty) const; // For block flows, each box represents the root inline box for a line in the // paragraph. diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp index 9d2895f..b04d455 100644 --- a/WebCore/rendering/RenderObject.cpp +++ b/WebCore/rendering/RenderObject.cpp @@ -1734,8 +1734,14 @@ StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsign void RenderObject::setStyle(PassRefPtr<RenderStyle> style) { - if (m_style == style) + if (m_style == style) { +#if USE(ACCELERATED_COMPOSITING) + // We need to run through adjustStyleDifference() for iframes and plugins, so + // style sharing is disabled for them. That should ensure that we never hit this code path. + ASSERT(!isRenderIFrame() && !isEmbeddedObject() &&!isApplet()); +#endif return; + } StyleDifference diff = StyleDifferenceEqual; unsigned contextSensitiveProperties = ContextSensitivePropertyNone; diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp index 117a6ae..a007a2c 100644 --- a/WebCore/rendering/RenderTable.cpp +++ b/WebCore/rendering/RenderTable.cpp @@ -4,7 +4,7 @@ * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) * * This library is free software; you can redistribute it and/or @@ -59,8 +59,8 @@ RenderTable::RenderTable(Node* node) , m_needsSectionRecalc(0) , m_hSpacing(0) , m_vSpacing(0) - , m_borderLeft(0) - , m_borderRight(0) + , m_borderStart(0) + , m_borderEnd(0) { setChildrenInline(false); m_columnPos.fill(0, 2); @@ -89,7 +89,7 @@ void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldSty if (!m_tableLayout || style()->tableLayout() != oldTableLayout) { // According to the CSS2 spec, you only use fixed table layout if an // explicit width is specified on the table. Auto width implies auto table layout. - if (style()->tableLayout() == TFIXED && !style()->width().isAuto()) + if (style()->tableLayout() == TFIXED && !style()->logicalWidth().isAuto()) m_tableLayout.set(new FixedTableLayout(this)); else m_tableLayout.set(new AutoTableLayout(this)); @@ -215,35 +215,35 @@ void RenderTable::computeLogicalWidth() computePositionedLogicalWidth(); RenderBlock* cb = containingBlock(); - int availableWidth = cb->availableLogicalWidth(); - LengthType widthType = style()->width().type(); - if (widthType > Relative && style()->width().isPositive()) { + int availableLogicalWidth = containingBlockLogicalWidthForContent(); + bool hasPerpendicularContainingBlock = cb->style()->isHorizontalWritingMode() != style()->isHorizontalWritingMode(); + int containerWidthInInlineDirection = hasPerpendicularContainingBlock ? perpendicularContainingBlockLogicalHeight() : availableLogicalWidth; + + LengthType logicalWidthType = style()->logicalWidth().type(); + if (logicalWidthType > Relative && style()->logicalWidth().isPositive()) { // Percent or fixed table - setWidth(style()->width().calcMinValue(availableWidth)); - setWidth(max(minPreferredLogicalWidth(), width())); + setLogicalWidth(style()->logicalWidth().calcMinValue(containerWidthInInlineDirection)); + setLogicalWidth(max(minPreferredLogicalWidth(), logicalWidth())); } else { - // An auto width table should shrink to fit within the line width if necessary in order to - // avoid overlapping floats. - availableWidth = cb->availableLogicalWidthForLine(y(), false); - // Subtract out any fixed margins from our available width for auto width tables. int marginTotal = 0; - if (!style()->marginLeft().isAuto()) - marginTotal += style()->marginLeft().calcValue(availableWidth); - if (!style()->marginRight().isAuto()) - marginTotal += style()->marginRight().calcValue(availableWidth); + if (!style()->marginStart().isAuto()) + marginTotal += style()->marginStart().calcValue(availableLogicalWidth); + if (!style()->marginEnd().isAuto()) + marginTotal += style()->marginEnd().calcValue(availableLogicalWidth); // Subtract out our margins to get the available content width. - int availContentWidth = max(0, availableWidth - marginTotal); + int availableContentLogicalWidth = max(0, containerWidthInInlineDirection - marginTotal); // Ensure we aren't bigger than our max width or smaller than our min width. - setWidth(min(availContentWidth, maxPreferredLogicalWidth())); + setLogicalWidth(min(availableContentLogicalWidth, maxPreferredLogicalWidth())); } - - setWidth(max(width(), minPreferredLogicalWidth())); + + setLogicalWidth(max(logicalWidth(), minPreferredLogicalWidth())); // Finally, with our true width determined, compute our margins for real. +<<<<<<< HEAD m_marginRight = 0; m_marginLeft = 0; #ifdef ANDROID_LAYOUT @@ -252,6 +252,16 @@ void RenderTable::computeLogicalWidth() return; #endif computeInlineDirectionMargins(cb, availableWidth, width()); +======= + setMarginStart(0); + setMarginEnd(0); + if (!hasPerpendicularContainingBlock) + computeInlineDirectionMargins(cb, availableLogicalWidth, logicalWidth()); + else { + setMarginStart(style()->marginStart().calcMinValue(availableLogicalWidth)); + setMarginEnd(style()->marginEnd().calcMinValue(availableLogicalWidth)); + } +>>>>>>> webkit.org at r71558 } void RenderTable::layout() @@ -266,11 +276,12 @@ void RenderTable::layout() LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y())); - setHeight(0); + setLogicalHeight(0); m_overflow.clear(); initMaxMarginValues(); +<<<<<<< HEAD #ifdef ANDROID_LAYOUT bool relayoutChildren = false; #endif @@ -308,6 +319,12 @@ void RenderTable::layout() } #endif if (m_caption && width() != oldWidth) +======= + int oldLogicalWidth = logicalWidth(); + computeLogicalWidth(); + + if (m_caption && logicalWidth() != oldLogicalWidth) +>>>>>>> webkit.org at r71558 m_caption->setNeedsLayout(true, false); // FIXME: The optimisation below doesn't work since the internal table @@ -317,11 +334,10 @@ void RenderTable::layout() // if ( oldWidth != width() || columns.size() + 1 != columnPos.size() ) m_tableLayout->layout(); - setCellWidths(); + setCellLogicalWidths(); - // layout child objects - int calculatedHeight = 0; - int oldTableTop = m_caption ? m_caption->height() + m_caption->marginTop() + m_caption->marginBottom() : 0; + int totalSectionLogicalHeight = 0; + int oldTableLogicalTop = m_caption ? m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter() : 0; bool collapsing = collapseBorders(); @@ -339,7 +355,7 @@ void RenderTable::layout() if (child->isTableSection()) { child->layoutIfNeeded(); RenderTableSection* section = toRenderTableSection(child); - calculatedHeight += section->calcRowHeight(); + totalSectionLogicalHeight += section->calcRowLogicalHeight(); if (collapsing) section->recalcOuterBorder(); ASSERT(!section->needsLayout()); @@ -357,80 +373,80 @@ void RenderTable::layout() // section down (it is quite unlikely that any of the following sections // did not shift). bool sectionMoved = false; - int movedSectionTop = 0; + int movedSectionLogicalTop = 0; // FIXME: Collapse caption margin. if (m_caption && m_caption->style()->captionSide() != CAPBOTTOM) { IntRect captionRect(m_caption->x(), m_caption->y(), m_caption->width(), m_caption->height()); - m_caption->setLocation(m_caption->marginLeft(), height()); + m_caption->setLogicalLocation(m_caption->marginStart(), logicalHeight()); if (!selfNeedsLayout() && m_caption->checkForRepaintDuringLayout()) m_caption->repaintDuringLayoutIfMoved(captionRect); - setHeight(height() + m_caption->height() + m_caption->marginTop() + m_caption->marginBottom()); + setLogicalHeight(logicalHeight() + m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter()); - if (height() != oldTableTop) { + if (logicalHeight() != oldTableLogicalTop) { sectionMoved = true; - movedSectionTop = min(height(), oldTableTop); + movedSectionLogicalTop = min(logicalHeight(), oldTableLogicalTop); } } - int bpTop = borderTop() + (collapsing ? 0 : paddingTop()); - int bpBottom = borderBottom() + (collapsing ? 0 : paddingBottom()); - - setHeight(height() + bpTop); + int borderAndPaddingBefore = borderBefore() + (collapsing ? 0 : paddingBefore()); + int borderAndPaddingAfter = borderAfter() + (collapsing ? 0 : paddingAfter()); + + setLogicalHeight(logicalHeight() + borderAndPaddingBefore); if (!isPositioned()) computeLogicalHeight(); - Length h = style()->height(); - int th = 0; - if (h.isFixed()) + Length logicalHeightLength = style()->logicalHeight(); + int computedLogicalHeight = 0; + if (logicalHeightLength.isFixed()) { // Tables size as though CSS height includes border/padding. - th = h.value() - (bpTop + bpBottom); - else if (h.isPercent()) - th = computePercentageLogicalHeight(h); - th = max(0, th); + computedLogicalHeight = logicalHeightLength.value() - (borderAndPaddingBefore + borderAndPaddingAfter); + } else if (logicalHeightLength.isPercent()) + computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength); + computedLogicalHeight = max(0, computedLogicalHeight); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one. - toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, th - calculatedHeight) : 0); + toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0); } - if (!m_firstBody && th > calculatedHeight && !document()->inQuirksMode()) { + if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) { // Completely empty tables (with no sections or anything) should at least honor specified height // in strict mode. - setHeight(height() + th); + setLogicalHeight(logicalHeight() + computedLogicalHeight); } - - int bl = borderLeft(); + + int sectionLogicalLeft = style()->isLeftToRightDirection() ? borderStart() : borderEnd(); if (!collapsing) - bl += paddingLeft(); + sectionLogicalLeft += style()->isLeftToRightDirection() ? paddingStart() : paddingEnd(); // position the table sections RenderTableSection* section = m_head ? m_head : (m_firstBody ? m_firstBody : m_foot); while (section) { - if (!sectionMoved && section->y() != height()) { + if (!sectionMoved && section->logicalTop() != logicalHeight()) { sectionMoved = true; - movedSectionTop = min(height(), section->y()) + section->topVisibleOverflow(); + movedSectionLogicalTop = min(logicalHeight(), section->logicalTop()) + (style()->isHorizontalWritingMode() ? section->topVisibleOverflow() : section->leftVisibleOverflow()); } - section->setLocation(bl, height()); + section->setLogicalLocation(sectionLogicalLeft, logicalHeight()); - setHeight(height() + section->height()); + setLogicalHeight(logicalHeight() + section->logicalHeight()); section = sectionBelow(section); } - setHeight(height() + bpBottom); + setLogicalHeight(logicalHeight() + borderAndPaddingAfter); if (m_caption && m_caption->style()->captionSide() == CAPBOTTOM) { IntRect captionRect(m_caption->x(), m_caption->y(), m_caption->width(), m_caption->height()); - m_caption->setLocation(m_caption->marginLeft(), height()); + m_caption->setLogicalLocation(m_caption->marginStart(), logicalHeight()); if (!selfNeedsLayout() && m_caption->checkForRepaintDuringLayout()) m_caption->repaintDuringLayoutIfMoved(captionRect); - setHeight(height() + m_caption->height() + m_caption->marginTop() + m_caption->marginBottom()); + setLogicalHeight(logicalHeight() + m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter()); } if (isPositioned()) @@ -469,17 +485,21 @@ void RenderTable::layout() bool didFullRepaint = repainter.repaintAfterLayout(); // Repaint with our new bounds if they are different from our old bounds. - if (!didFullRepaint && sectionMoved) - repaintRectangle(IntRect(leftVisibleOverflow(), movedSectionTop, rightVisibleOverflow() - leftVisibleOverflow(), bottomVisibleOverflow() - movedSectionTop)); - + if (!didFullRepaint && sectionMoved) { + if (style()->isHorizontalWritingMode()) + repaintRectangle(IntRect(leftVisibleOverflow(), movedSectionLogicalTop, rightVisibleOverflow() - leftVisibleOverflow(), bottomVisibleOverflow() - movedSectionLogicalTop)); + else + repaintRectangle(IntRect(movedSectionLogicalTop, topVisibleOverflow(), rightVisibleOverflow() - movedSectionLogicalTop, bottomVisibleOverflow() - topVisibleOverflow())); + } + setNeedsLayout(false); } -void RenderTable::setCellWidths() +void RenderTable::setCellLogicalWidths() { for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) - toRenderTableSection(child)->setCellWidths(); + toRenderTableSection(child)->setCellLogicalWidths(); } } @@ -526,8 +546,10 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty) info.updatePaintingRootForChildren(this); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { - if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption)) - child->paint(info, tx, ty); + if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption)) { + IntPoint childPoint = flipForWritingMode(toRenderBox(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment); + child->paint(info, childPoint.x(), childPoint.y()); + } } if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) { @@ -537,44 +559,57 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty) info.phase = PaintPhaseCollapsedTableBorders; RenderTableCell::CollapsedBorderStyles borderStyles; RenderObject* stop = nextInPreOrderAfterChildren(); - for (RenderObject* o = firstChild(); o && o != stop; o = o->nextInPreOrder()) + for (RenderObject* o = firstChild(); o && o != stop; o = o->nextInPreOrder()) { if (o->isTableCell()) toRenderTableCell(o)->collectBorderStyles(borderStyles); + } RenderTableCell::sortBorderStyles(borderStyles); size_t count = borderStyles.size(); for (size_t i = 0; i < count; ++i) { m_currentBorder = &borderStyles[i]; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) - if (child->isTableSection()) - child->paint(info, tx, ty); + if (child->isTableSection()) { + IntPoint childPoint = flipForWritingMode(toRenderTableSection(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment); + child->paint(info, childPoint.x(), childPoint.y()); + } } m_currentBorder = 0; } } +void RenderTable::subtractCaptionRect(IntRect& rect) const +{ + if (!m_caption) + return; + + int captionLogicalHeight = m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter(); + bool captionIsBefore = (m_caption->style()->captionSide() != CAPBOTTOM) ^ style()->isFlippedBlocksWritingMode(); + if (style()->isHorizontalWritingMode()) { + rect.setHeight(rect.height() - captionLogicalHeight); + if (captionIsBefore) + rect.move(0, captionLogicalHeight); + } else { + rect.setWidth(rect.width() - captionLogicalHeight); + if (captionIsBefore) + rect.move(captionLogicalHeight, 0); + } +} + void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty) { if (!paintInfo.shouldPaintWithinRoot(this)) return; - int w = width(); - int h = height(); + IntRect rect(tx, ty, width(), height()); + subtractCaptionRect(rect); - // Account for the caption. - if (m_caption) { - int captionHeight = (m_caption->height() + m_caption->marginBottom() + m_caption->marginTop()); - h -= captionHeight; - if (m_caption->style()->captionSide() != CAPBOTTOM) - ty += captionHeight; - } - - paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Normal); + paintBoxShadow(paintInfo.context, rect.x(), rect.y(), rect.width(), rect.height(), style(), Normal); - paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), tx, ty, w, h); - paintBoxShadow(paintInfo.context, tx, ty, w, h, style(), Inset); + paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), rect.x(), rect.y(), rect.width(), rect.height()); + paintBoxShadow(paintInfo.context, rect.x(), rect.y(), rect.width(), rect.height(), style(), Inset); if (style()->hasBorder() && !collapseBorders()) - paintBorder(paintInfo.context, tx, ty, w, h, style()); + paintBorder(paintInfo.context, rect.x(), rect.y(), rect.width(), rect.height(), style()); } void RenderTable::paintMask(PaintInfo& paintInfo, int tx, int ty) @@ -582,18 +617,10 @@ void RenderTable::paintMask(PaintInfo& paintInfo, int tx, int ty) if (style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask) return; - int w = width(); - int h = height(); + IntRect rect(tx, ty, width(), height()); + subtractCaptionRect(rect); - // Account for the caption. - if (m_caption) { - int captionHeight = (m_caption->height() + m_caption->marginBottom() + m_caption->marginTop()); - h -= captionHeight; - if (m_caption->style()->captionSide() != CAPBOTTOM) - ty += captionHeight; - } - - paintMaskImages(paintInfo, tx, ty, w, h); + paintMaskImages(paintInfo, rect.x(), rect.y(), rect.width(), rect.height()); } void RenderTable::computePreferredLogicalWidths() @@ -601,7 +628,7 @@ void RenderTable::computePreferredLogicalWidths() ASSERT(preferredLogicalWidthsDirty()); recalcSectionsIfNeeded(); - recalcHorizontalBorders(); + recalcBordersInRowDirection(); m_tableLayout->computePreferredLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth); @@ -780,7 +807,7 @@ void RenderTable::recalcSections() const m_needsSectionRecalc = false; } -int RenderTable::calcBorderLeft() const +int RenderTable::calcBorderStart() const { if (collapseBorders()) { // Determined by the first cell of the first row. See the CSS 2.1 spec, section 17.6.2. @@ -789,16 +816,14 @@ int RenderTable::calcBorderLeft() const unsigned borderWidth = 0; - const BorderValue& tb = style()->borderLeft(); + const BorderValue& tb = style()->borderStart(); if (tb.style() == BHIDDEN) return 0; if (tb.style() > BHIDDEN) borderWidth = tb.width(); - int leftmostColumn = !style()->isLeftToRightDirection() ? numEffCols() - 1 : 0; - RenderTableCol* colGroup = colElement(leftmostColumn); - if (colGroup) { - const BorderValue& gb = style()->borderLeft(); + if (RenderTableCol* colGroup = colElement(0)) { + const BorderValue& gb = colGroup->style()->borderStart(); if (gb.style() == BHIDDEN) return 0; if (gb.style() > BHIDDEN) @@ -810,21 +835,21 @@ int RenderTable::calcBorderLeft() const firstNonEmptySection = sectionBelow(firstNonEmptySection, true); if (firstNonEmptySection) { - const BorderValue& sb = firstNonEmptySection->style()->borderLeft(); + const BorderValue& sb = firstNonEmptySection->style()->borderStart(); if (sb.style() == BHIDDEN) return 0; if (sb.style() > BHIDDEN) borderWidth = max(borderWidth, static_cast<unsigned>(sb.width())); - const RenderTableSection::CellStruct& cs = firstNonEmptySection->cellAt(0, leftmostColumn); + const RenderTableSection::CellStruct& cs = firstNonEmptySection->cellAt(0, 0); if (cs.hasCells()) { - const BorderValue& cb = cs.primaryCell()->style()->borderLeft(); + const BorderValue& cb = cs.primaryCell()->style()->borderStart(); // FIXME: Make this work with perpendicualr and flipped cells. if (cb.style() == BHIDDEN) return 0; - const BorderValue& rb = cs.primaryCell()->parent()->style()->borderLeft(); + const BorderValue& rb = cs.primaryCell()->parent()->style()->borderStart(); if (rb.style() == BHIDDEN) return 0; @@ -834,12 +859,12 @@ int RenderTable::calcBorderLeft() const borderWidth = max(borderWidth, static_cast<unsigned>(rb.width())); } } - return borderWidth / 2; + return (borderWidth + (style()->isLeftToRightDirection() ? 0 : 1)) / 2; } - return RenderBlock::borderLeft(); + return RenderBlock::borderStart(); } - -int RenderTable::calcBorderRight() const + +int RenderTable::calcBorderEnd() const { if (collapseBorders()) { // Determined by the last cell of the first row. See the CSS 2.1 spec, section 17.6.2. @@ -848,16 +873,15 @@ int RenderTable::calcBorderRight() const unsigned borderWidth = 0; - const BorderValue& tb = style()->borderRight(); + const BorderValue& tb = style()->borderEnd(); if (tb.style() == BHIDDEN) return 0; if (tb.style() > BHIDDEN) borderWidth = tb.width(); - int rightmostColumn = !style()->isLeftToRightDirection() ? 0 : numEffCols() - 1; - RenderTableCol* colGroup = colElement(rightmostColumn); - if (colGroup) { - const BorderValue& gb = style()->borderRight(); + int endColumn = numEffCols() - 1; + if (RenderTableCol* colGroup = colElement(endColumn)) { + const BorderValue& gb = colGroup->style()->borderEnd(); if (gb.style() == BHIDDEN) return 0; if (gb.style() > BHIDDEN) @@ -869,21 +893,21 @@ int RenderTable::calcBorderRight() const firstNonEmptySection = sectionBelow(firstNonEmptySection, true); if (firstNonEmptySection) { - const BorderValue& sb = firstNonEmptySection->style()->borderRight(); + const BorderValue& sb = firstNonEmptySection->style()->borderEnd(); if (sb.style() == BHIDDEN) return 0; if (sb.style() > BHIDDEN) borderWidth = max(borderWidth, static_cast<unsigned>(sb.width())); - const RenderTableSection::CellStruct& cs = firstNonEmptySection->cellAt(0, rightmostColumn); + const RenderTableSection::CellStruct& cs = firstNonEmptySection->cellAt(0, endColumn); if (cs.hasCells()) { - const BorderValue& cb = cs.primaryCell()->style()->borderRight(); + const BorderValue& cb = cs.primaryCell()->style()->borderEnd(); // FIXME: Make this work with perpendicular and flipped cells. if (cb.style() == BHIDDEN) return 0; - const BorderValue& rb = cs.primaryCell()->parent()->style()->borderRight(); + const BorderValue& rb = cs.primaryCell()->parent()->style()->borderEnd(); if (rb.style() == BHIDDEN) return 0; @@ -893,32 +917,32 @@ int RenderTable::calcBorderRight() const borderWidth = max(borderWidth, static_cast<unsigned>(rb.width())); } } - return (borderWidth + 1) / 2; + return (borderWidth + (style()->isLeftToRightDirection() ? 1 : 0)) / 2; } - return RenderBlock::borderRight(); + return RenderBlock::borderEnd(); } -void RenderTable::recalcHorizontalBorders() +void RenderTable::recalcBordersInRowDirection() { - m_borderLeft = calcBorderLeft(); - m_borderRight = calcBorderRight(); + m_borderStart = calcBorderStart(); + m_borderEnd = calcBorderEnd(); } -int RenderTable::borderTop() const +int RenderTable::borderBefore() const { if (collapseBorders()) - return outerBorderTop(); - return RenderBlock::borderTop(); + return outerBorderBefore(); + return RenderBlock::borderBefore(); } -int RenderTable::borderBottom() const +int RenderTable::borderAfter() const { if (collapseBorders()) - return outerBorderBottom(); - return RenderBlock::borderBottom(); + return outerBorderAfter(); + return RenderBlock::borderAfter(); } -int RenderTable::outerBorderTop() const +int RenderTable::outerBorderBefore() const { if (!collapseBorders()) return 0; @@ -933,11 +957,11 @@ int RenderTable::outerBorderTop() const else topSection = 0; if (topSection) { - borderWidth = topSection->outerBorderTop(); + borderWidth = topSection->outerBorderBefore(); if (borderWidth == -1) return 0; // Overridden by hidden } - const BorderValue& tb = style()->borderTop(); + const BorderValue& tb = style()->borderBefore(); if (tb.style() == BHIDDEN) return 0; if (tb.style() > BHIDDEN) @@ -945,7 +969,7 @@ int RenderTable::outerBorderTop() const return borderWidth; } -int RenderTable::outerBorderBottom() const +int RenderTable::outerBorderAfter() const { if (!collapseBorders()) return 0; @@ -959,11 +983,11 @@ int RenderTable::outerBorderBottom() const bottomSection = child ? toRenderTableSection(child) : 0; } if (bottomSection) { - borderWidth = bottomSection->outerBorderBottom(); + borderWidth = bottomSection->outerBorderAfter(); if (borderWidth == -1) return 0; // Overridden by hidden } - const BorderValue& tb = style()->borderBottom(); + const BorderValue& tb = style()->borderAfter(); if (tb.style() == BHIDDEN) return 0; if (tb.style() > BHIDDEN) @@ -971,24 +995,24 @@ int RenderTable::outerBorderBottom() const return borderWidth; } -int RenderTable::outerBorderLeft() const +int RenderTable::outerBorderStart() const { if (!collapseBorders()) return 0; int borderWidth = 0; - const BorderValue& tb = style()->borderLeft(); + const BorderValue& tb = style()->borderStart(); if (tb.style() == BHIDDEN) return 0; if (tb.style() > BHIDDEN) - borderWidth = tb.width() / 2; + borderWidth = (tb.width() + (style()->isLeftToRightDirection() ? 0 : 1)) / 2; bool allHidden = true; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (!child->isTableSection()) continue; - int sw = toRenderTableSection(child)->outerBorderLeft(); + int sw = toRenderTableSection(child)->outerBorderStart(); if (sw == -1) continue; else @@ -1001,24 +1025,24 @@ int RenderTable::outerBorderLeft() const return borderWidth; } -int RenderTable::outerBorderRight() const +int RenderTable::outerBorderEnd() const { if (!collapseBorders()) return 0; int borderWidth = 0; - const BorderValue& tb = style()->borderRight(); + const BorderValue& tb = style()->borderEnd(); if (tb.style() == BHIDDEN) return 0; if (tb.style() > BHIDDEN) - borderWidth = (tb.width() + 1) / 2; + borderWidth = (tb.width() + (style()->isLeftToRightDirection() ? 1 : 0)) / 2; bool allHidden = true; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (!child->isTableSection()) continue; - int sw = toRenderTableSection(child)->outerBorderRight(); + int sw = toRenderTableSection(child)->outerBorderEnd(); if (sw == -1) continue; else @@ -1156,6 +1180,9 @@ void RenderTable::updateFirstLetter() int RenderTable::firstLineBoxBaseline() const { + if (isWritingModeRoot()) + return -1; + RenderTableSection* firstNonEmptySection = m_head ? m_head : (m_firstBody ? m_firstBody : m_foot); if (firstNonEmptySection && !firstNonEmptySection->numRows()) firstNonEmptySection = sectionBelow(firstNonEmptySection, true); @@ -1163,7 +1190,7 @@ int RenderTable::firstLineBoxBaseline() const if (!firstNonEmptySection) return -1; - return firstNonEmptySection->y() + firstNonEmptySection->firstLineBoxBaseline(); + return firstNonEmptySection->logicalTop() + firstNonEmptySection->firstLineBoxBaseline(); } IntRect RenderTable::overflowClipRect(int tx, int ty) @@ -1177,8 +1204,13 @@ IntRect RenderTable::overflowClipRect(int tx, int ty) // supported. When we actually support left/right and stop mapping them to top/bottom, // we might have to hack this code first (depending on what order we do these bug fixes in). if (m_caption) { - rect.setHeight(height()); - rect.setY(ty); + if (style()->isHorizontalWritingMode()) { + rect.setHeight(height()); + rect.setY(ty); + } else { + rect.setWidth(width()); + rect.setX(tx); + } } return rect; diff --git a/WebCore/rendering/RenderTable.h b/WebCore/rendering/RenderTable.h index beb48f4..5495615 100644 --- a/WebCore/rendering/RenderTable.h +++ b/WebCore/rendering/RenderTable.h @@ -4,7 +4,7 @@ * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2009, 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 @@ -47,21 +47,78 @@ public: int vBorderSpacing() const { return m_vSpacing; } bool collapseBorders() const { return style()->borderCollapse(); } - int borderLeft() const { return m_borderLeft; } - int borderRight() const { return m_borderRight; } - int borderTop() const; - int borderBottom() const; - + + int borderStart() const { return m_borderStart; } + int borderEnd() const { return m_borderEnd; } + int borderBefore() const; + int borderAfter() const; + + int borderLeft() const + { + if (style()->isHorizontalWritingMode()) + return style()->isLeftToRightDirection() ? borderStart() : borderEnd(); + return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore(); + } + + int borderRight() const + { + if (style()->isHorizontalWritingMode()) + return style()->isLeftToRightDirection() ? borderEnd() : borderStart(); + return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter(); + } + + int borderTop() const + { + if (style()->isHorizontalWritingMode()) + return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore(); + return style()->isLeftToRightDirection() ? borderStart() : borderEnd(); + } + + int borderBottom() const + { + if (style()->isHorizontalWritingMode()) + return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter(); + return style()->isLeftToRightDirection() ? borderEnd() : borderStart(); + } + const Color bgColor() const { return style()->visitedDependentColor(CSSPropertyBackgroundColor); } - int outerBorderTop() const; - int outerBorderBottom() const; - int outerBorderLeft() const; - int outerBorderRight() const; - - int calcBorderLeft() const; - int calcBorderRight() const; - void recalcHorizontalBorders(); + int outerBorderBefore() const; + int outerBorderAfter() const; + int outerBorderStart() const; + int outerBorderEnd() const; + + int outerBorderLeft() const + { + if (style()->isHorizontalWritingMode()) + return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd(); + return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore(); + } + + int outerBorderRight() const + { + if (style()->isHorizontalWritingMode()) + return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart(); + return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter(); + } + + int outerBorderTop() const + { + if (style()->isHorizontalWritingMode()) + return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore(); + return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd(); + } + + int outerBorderBottom() const + { + if (style()->isHorizontalWritingMode()) + return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter(); + return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart(); + } + + int calcBorderStart() const; + int calcBorderEnd() const; + void recalcBordersInRowDirection(); virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); @@ -108,10 +165,10 @@ public: return c; } - int bordersPaddingAndSpacing() const + int bordersPaddingAndSpacingInRowDirection() const { - return borderLeft() + borderRight() + - (collapseBorders() ? 0 : (paddingLeft() + paddingRight() + (numEffCols() + 1) * hBorderSpacing())); + return borderStart() + borderEnd() + + (collapseBorders() ? 0 : (paddingStart() + paddingEnd() + (numEffCols() + 1) * hBorderSpacing())); } RenderTableCol* colElement(int col, bool* startEdge = 0, bool* endEdge = 0) const; @@ -174,12 +231,14 @@ private: virtual RenderBlock* firstLineBlock() const; virtual void updateFirstLetter(); - virtual void setCellWidths(); + virtual void setCellLogicalWidths(); virtual void computeLogicalWidth(); virtual IntRect overflowClipRect(int tx, int ty); + void subtractCaptionRect(IntRect&) const; + void recalcSections() const; mutable Vector<int> m_columnPos; @@ -202,8 +261,8 @@ private: #endif short m_hSpacing; short m_vSpacing; - int m_borderLeft; - int m_borderRight; + int m_borderStart; + int m_borderEnd; }; inline RenderTable* toRenderTable(RenderObject* object) diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp index 88cdd5e..3ba185a 100644 --- a/WebCore/rendering/RenderTableCell.cpp +++ b/WebCore/rendering/RenderTableCell.cpp @@ -85,20 +85,18 @@ void RenderTableCell::updateFromElement() } } -Length RenderTableCell::styleOrColWidth() const +Length RenderTableCell::styleOrColLogicalWidth() const { - Length w = style()->width(); + Length w = style()->logicalWidth(); if (!w.isAuto()) return w; - RenderTableCol* tableCol = table()->colElement(col()); - - if (tableCol) { + if (RenderTableCol* tableCol = table()->colElement(col())) { int colSpanCount = colSpan(); Length colWidthSum = Length(0, Fixed); for (int i = 1; i <= colSpanCount; i++) { - Length colWidth = tableCol->style()->width(); + Length colWidth = tableCol->style()->logicalWidth(); // Percentage value should be returned only for colSpan == 1. // Otherwise we return original width for the cell. @@ -120,7 +118,7 @@ Length RenderTableCell::styleOrColWidth() const // Percentages don't need to be handled since they're always treated this way (even when specified on the cells). // See Bugzilla bug 8126 for details. if (colWidthSum.isFixed() && colWidthSum.value() > 0) - colWidthSum = Length(max(0, colWidthSum.value() - borderAndPaddingWidth()), Fixed); + colWidthSum = Length(max(0, colWidthSum.value() - borderAndPaddingLogicalWidth()), Fixed); return colWidthSum; } @@ -137,7 +135,7 @@ void RenderTableCell::computePreferredLogicalWidths() RenderBlock::computePreferredLogicalWidths(); if (node() && style()->autoWrap()) { // See if nowrap was set. - Length w = styleOrColWidth(); + Length w = styleOrColLogicalWidth(); String nowrap = static_cast<Element*>(node())->getAttribute(nowrapAttr); if (!nowrap.isNull() && w.isFixed()) // Nowrap is set, but we didn't actually use it because of the @@ -157,12 +155,13 @@ void RenderTableCell::computeLogicalWidth() #endif } -void RenderTableCell::updateWidth(int w) +void RenderTableCell::updateLogicalWidth(int w) { - if (w != width()) { - setWidth(w); - setCellWidthChanged(true); - } + if (w == logicalWidth()) + return; + + setLogicalWidth(w); + setCellWidthChanged(true); } void RenderTableCell::layout() @@ -393,69 +392,62 @@ static CollapsedBorderValue chooseBorder(const CollapsedBorderValue& border1, co return border.style() == BHIDDEN ? CollapsedBorderValue() : border; } -CollapsedBorderValue RenderTableCell::collapsedLeftBorder(bool rtl) const +CollapsedBorderValue RenderTableCell::collapsedStartBorder() const { - RenderTable* tableElt = table(); - bool leftmostColumn; - if (!rtl) - leftmostColumn = col() == 0; - else { - int effCol = tableElt->colToEffCol(col() + colSpan() - 1); - leftmostColumn = effCol == tableElt->numEffCols() - 1; - } - - // For border left, we need to check, in order of precedence: - // (1) Our left border. - int left = CSSPropertyBorderLeftColor; - int right = CSSPropertyBorderRightColor; - CollapsedBorderValue result(&style()->borderLeft(), style()->visitedDependentColor(left), BCELL); - - // (2) The right border of the cell to the left. - RenderTableCell* prevCell = rtl ? tableElt->cellAfter(this) : tableElt->cellBefore(this); - if (prevCell) { - CollapsedBorderValue prevCellBorder = CollapsedBorderValue(&prevCell->style()->borderRight(), prevCell->style()->visitedDependentColor(right), BCELL); - result = rtl ? chooseBorder(result, prevCellBorder) : chooseBorder(prevCellBorder, result); + RenderTable* table = this->table(); + bool isStartColumn = col() == 0; + + // For the start border, we need to check, in order of precedence: + // (1) Our start border. + int start = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderStartColor, table->style()->direction(), table->style()->writingMode()); + int end = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderEndColor, table->style()->direction(), table->style()->writingMode()); + CollapsedBorderValue result(&style()->borderStart(), style()->visitedDependentColor(start), BCELL); + + // (2) The end border of the preceding cell. + if (RenderTableCell* prevCell = table->cellBefore(this)) { + CollapsedBorderValue prevCellBorder = CollapsedBorderValue(&prevCell->style()->borderEnd(), prevCell->style()->visitedDependentColor(end), BCELL); + result = chooseBorder(prevCellBorder, result); if (!result.exists()) return result; - } else if (leftmostColumn) { - // (3) Our row's left border. - result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderLeft(), parent()->style()->visitedDependentColor(left), BROW)); + } else if (isStartColumn) { + // (3) Our row's start border. + result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderStart(), parent()->style()->visitedDependentColor(start), BROW)); if (!result.exists()) return result; - // (4) Our row group's left border. - result = chooseBorder(result, CollapsedBorderValue(§ion()->style()->borderLeft(), section()->style()->visitedDependentColor(left), BROWGROUP)); + // (4) Our row group's start border. + result = chooseBorder(result, CollapsedBorderValue(§ion()->style()->borderStart(), section()->style()->visitedDependentColor(start), BROWGROUP)); if (!result.exists()) return result; } - // (5) Our column and column group's left borders. + // (5) Our column and column group's start borders. bool startColEdge; bool endColEdge; - RenderTableCol* colElt = tableElt->colElement(col() + (rtl ? colSpan() - 1 : 0), &startColEdge, &endColEdge); - if (colElt && (!rtl ? startColEdge : endColEdge)) { - result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderLeft(), colElt->style()->visitedDependentColor(left), BCOL)); + RenderTableCol* colElt = table->colElement(col(), &startColEdge, &endColEdge); + if (colElt && startColEdge) { + result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderStart(), colElt->style()->visitedDependentColor(start), BCOL)); if (!result.exists()) return result; - if (colElt->parent()->isTableCol() && (!rtl ? !colElt->previousSibling() : !colElt->nextSibling())) { - result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderLeft(), colElt->parent()->style()->visitedDependentColor(left), BCOLGROUP)); + if (colElt->parent()->isTableCol() && !colElt->previousSibling()) { + result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderStart(), colElt->parent()->style()->visitedDependentColor(start), BCOLGROUP)); if (!result.exists()) return result; } } - // (6) The right border of the column to the left. - if (!leftmostColumn) { - colElt = tableElt->colElement(col() + (rtl ? colSpan() : -1), &startColEdge, &endColEdge); - if (colElt && (!rtl ? endColEdge : startColEdge)) { - CollapsedBorderValue rightBorder = CollapsedBorderValue(&colElt->style()->borderRight(), colElt->style()->visitedDependentColor(right), BCOL); - result = rtl ? chooseBorder(result, rightBorder) : chooseBorder(rightBorder, result); + // (6) The end border of the preceding column. + if (!isStartColumn) { + colElt = table->colElement(col() -1, &startColEdge, &endColEdge); + if (colElt && endColEdge) { + CollapsedBorderValue endBorder = CollapsedBorderValue(&colElt->style()->borderEnd(), colElt->style()->visitedDependentColor(end), BCOL); + result = chooseBorder(endBorder, result); if (!result.exists()) return result; } } else { - // (7) The table's left border. - result = chooseBorder(result, CollapsedBorderValue(&tableElt->style()->borderLeft(), tableElt->style()->visitedDependentColor(left), BTABLE)); + // (7) The table's start border. + result = chooseBorder(result, CollapsedBorderValue(&table->style()->borderStart(), table->style()->visitedDependentColor(start), BTABLE)); if (!result.exists()) return result; } @@ -463,71 +455,65 @@ CollapsedBorderValue RenderTableCell::collapsedLeftBorder(bool rtl) const return result; } -CollapsedBorderValue RenderTableCell::collapsedRightBorder(bool rtl) const +CollapsedBorderValue RenderTableCell::collapsedEndBorder() const { - RenderTable* tableElt = table(); - bool rightmostColumn; - if (rtl) - rightmostColumn = col() == 0; - else { - int effCol = tableElt->colToEffCol(col() + colSpan() - 1); - rightmostColumn = effCol == tableElt->numEffCols() - 1; - } - - // For border right, we need to check, in order of precedence: - // (1) Our right border. - int left = CSSPropertyBorderLeftColor; - int right = CSSPropertyBorderRightColor; - CollapsedBorderValue result = CollapsedBorderValue(&style()->borderRight(), style()->visitedDependentColor(right), BCELL); + RenderTable* table = this->table(); + bool isEndColumn = table->colToEffCol(col() + colSpan() - 1) == table->numEffCols() - 1; + + // For end border, we need to check, in order of precedence: + // (1) Our end border. + int start = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderStartColor, table->style()->direction(), table->style()->writingMode()); + int end = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderEndColor, table->style()->direction(), table->style()->writingMode()); + CollapsedBorderValue result = CollapsedBorderValue(&style()->borderEnd(), style()->visitedDependentColor(end), BCELL); - // (2) The left border of the cell to the right. - if (!rightmostColumn) { - RenderTableCell* nextCell = rtl ? tableElt->cellBefore(this) : tableElt->cellAfter(this); + // (2) The start border of the following cell. + if (!isEndColumn) { + RenderTableCell* nextCell = table->cellAfter(this); if (nextCell && nextCell->style()) { - CollapsedBorderValue leftBorder = CollapsedBorderValue(&nextCell->style()->borderLeft(), nextCell->style()->visitedDependentColor(left), BCELL); - result = rtl ? chooseBorder(leftBorder, result) : chooseBorder(result, leftBorder); + CollapsedBorderValue startBorder = CollapsedBorderValue(&nextCell->style()->borderStart(), nextCell->style()->visitedDependentColor(start), BCELL); + result = chooseBorder(result, startBorder); if (!result.exists()) return result; } } else { - // (3) Our row's right border. - result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderRight(), parent()->style()->visitedDependentColor(right), BROW)); + // (3) Our row's end border. + result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderEnd(), parent()->style()->visitedDependentColor(end), BROW)); if (!result.exists()) return result; - // (4) Our row group's right border. - result = chooseBorder(result, CollapsedBorderValue(§ion()->style()->borderRight(), section()->style()->visitedDependentColor(right), BROWGROUP)); + // (4) Our row group's end border. + result = chooseBorder(result, CollapsedBorderValue(§ion()->style()->borderEnd(), section()->style()->visitedDependentColor(end), BROWGROUP)); if (!result.exists()) return result; } - // (5) Our column and column group's right borders. + // (5) Our column and column group's end borders. bool startColEdge; bool endColEdge; - RenderTableCol* colElt = tableElt->colElement(col() + (rtl ? 0 : colSpan() - 1), &startColEdge, &endColEdge); - if (colElt && (!rtl ? endColEdge : startColEdge)) { - result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderRight(), colElt->style()->visitedDependentColor(right), BCOL)); + RenderTableCol* colElt = table->colElement(col() + colSpan() - 1, &startColEdge, &endColEdge); + if (colElt && endColEdge) { + result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderEnd(), colElt->style()->visitedDependentColor(end), BCOL)); if (!result.exists()) return result; - if (colElt->parent()->isTableCol() && (!rtl ? !colElt->nextSibling() : !colElt->previousSibling())) { - result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderRight(), colElt->parent()->style()->visitedDependentColor(right), BCOLGROUP)); + if (colElt->parent()->isTableCol() && !colElt->nextSibling()) { + result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderEnd(), colElt->parent()->style()->visitedDependentColor(end), BCOLGROUP)); if (!result.exists()) return result; } } - // (6) The left border of the column to the right. - if (!rightmostColumn) { - colElt = tableElt->colElement(col() + (rtl ? -1 : colSpan()), &startColEdge, &endColEdge); - if (colElt && (!rtl ? startColEdge : endColEdge)) { - CollapsedBorderValue leftBorder = CollapsedBorderValue(&colElt->style()->borderLeft(), colElt->style()->visitedDependentColor(left), BCOL); - result = rtl ? chooseBorder(leftBorder, result) : chooseBorder(result, leftBorder); + // (6) The start border of the next column. + if (!isEndColumn) { + colElt = table->colElement(col() + colSpan(), &startColEdge, &endColEdge); + if (colElt && startColEdge) { + CollapsedBorderValue startBorder = CollapsedBorderValue(&colElt->style()->borderStart(), colElt->style()->visitedDependentColor(start), BCOL); + result = chooseBorder(result, startBorder); if (!result.exists()) return result; } } else { - // (7) The table's right border. - result = chooseBorder(result, CollapsedBorderValue(&tableElt->style()->borderRight(), tableElt->style()->visitedDependentColor(right), BTABLE)); + // (7) The table's end border. + result = chooseBorder(result, CollapsedBorderValue(&table->style()->borderEnd(), table->style()->visitedDependentColor(end), BTABLE)); if (!result.exists()) return result; } @@ -535,28 +521,30 @@ CollapsedBorderValue RenderTableCell::collapsedRightBorder(bool rtl) const return result; } -CollapsedBorderValue RenderTableCell::collapsedTopBorder() const +CollapsedBorderValue RenderTableCell::collapsedBeforeBorder() const { - // For border top, we need to check, in order of precedence: - // (1) Our top border. - int top = CSSPropertyBorderTopColor; - int bottom = CSSPropertyBorderBottomColor; - CollapsedBorderValue result = CollapsedBorderValue(&style()->borderTop(), style()->visitedDependentColor(top), BCELL); + RenderTable* table = this->table(); + + // For before border, we need to check, in order of precedence: + // (1) Our before border. + int before = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderBeforeColor, table->style()->direction(), table->style()->writingMode()); + int after = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderAfterColor, table->style()->direction(), table->style()->writingMode()); + CollapsedBorderValue result = CollapsedBorderValue(&style()->borderBefore(), style()->visitedDependentColor(before), BCELL); - RenderTableCell* prevCell = table()->cellAbove(this); + RenderTableCell* prevCell = table->cellAbove(this); if (prevCell) { - // (2) A previous cell's bottom border. - result = chooseBorder(CollapsedBorderValue(&prevCell->style()->borderBottom(), prevCell->style()->visitedDependentColor(bottom), BCELL), result); - if (!result.exists()) + // (2) A before cell's after border. + result = chooseBorder(CollapsedBorderValue(&prevCell->style()->borderAfter(), prevCell->style()->visitedDependentColor(after), BCELL), result); + if (!result.exists()) return result; } - // (3) Our row's top border. - result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderTop(), parent()->style()->visitedDependentColor(top), BROW)); + // (3) Our row's before border. + result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderBefore(), parent()->style()->visitedDependentColor(before), BROW)); if (!result.exists()) return result; - // (4) The previous row's bottom border. + // (4) The previous row's after border. if (prevCell) { RenderObject* prevRow = 0; if (prevCell->section() == section()) @@ -565,7 +553,7 @@ CollapsedBorderValue RenderTableCell::collapsedTopBorder() const prevRow = prevCell->section()->lastChild(); if (prevRow) { - result = chooseBorder(CollapsedBorderValue(&prevRow->style()->borderBottom(), prevRow->style()->visitedDependentColor(bottom), BROW), result); + result = chooseBorder(CollapsedBorderValue(&prevRow->style()->borderAfter(), prevRow->style()->visitedDependentColor(after), BROW), result); if (!result.exists()) return result; } @@ -574,37 +562,36 @@ CollapsedBorderValue RenderTableCell::collapsedTopBorder() const // Now check row groups. RenderTableSection* currSection = section(); if (!row()) { - // (5) Our row group's top border. - result = chooseBorder(result, CollapsedBorderValue(&currSection->style()->borderTop(), currSection->style()->visitedDependentColor(top), BROWGROUP)); + // (5) Our row group's before border. + result = chooseBorder(result, CollapsedBorderValue(&currSection->style()->borderBefore(), currSection->style()->visitedDependentColor(before), BROWGROUP)); if (!result.exists()) return result; - // (6) Previous row group's bottom border. - currSection = table()->sectionAbove(currSection); + // (6) Previous row group's after border. + currSection = table->sectionAbove(currSection); if (currSection) { - result = chooseBorder(CollapsedBorderValue(&currSection->style()->borderBottom(), currSection->style()->visitedDependentColor(bottom), BROWGROUP), result); + result = chooseBorder(CollapsedBorderValue(&currSection->style()->borderAfter(), currSection->style()->visitedDependentColor(after), BROWGROUP), result); if (!result.exists()) return result; } } if (!currSection) { - // (8) Our column and column group's top borders. - RenderTableCol* colElt = table()->colElement(col()); + // (8) Our column and column group's before borders. + RenderTableCol* colElt = table->colElement(col()); if (colElt) { - result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderTop(), colElt->style()->visitedDependentColor(top), BCOL)); + result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderBefore(), colElt->style()->visitedDependentColor(before), BCOL)); if (!result.exists()) return result; if (colElt->parent()->isTableCol()) { - result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderTop(), colElt->parent()->style()->visitedDependentColor(top), BCOLGROUP)); + result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderBefore(), colElt->parent()->style()->visitedDependentColor(before), BCOLGROUP)); if (!result.exists()) return result; } } - // (9) The table's top border. - RenderTable* enclosingTable = table(); - result = chooseBorder(result, CollapsedBorderValue(&enclosingTable->style()->borderTop(), enclosingTable->style()->visitedDependentColor(top), BTABLE)); + // (9) The table's before border. + result = chooseBorder(result, CollapsedBorderValue(&table->style()->borderBefore(), table->style()->visitedDependentColor(before), BTABLE)); if (!result.exists()) return result; } @@ -612,30 +599,32 @@ CollapsedBorderValue RenderTableCell::collapsedTopBorder() const return result; } -CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const +CollapsedBorderValue RenderTableCell::collapsedAfterBorder() const { - // For border top, we need to check, in order of precedence: - // (1) Our bottom border. - int top = CSSPropertyBorderTopColor; - int bottom = CSSPropertyBorderBottomColor; - CollapsedBorderValue result = CollapsedBorderValue(&style()->borderBottom(), style()->visitedDependentColor(bottom), BCELL); + RenderTable* table = this->table(); + + // For after border, we need to check, in order of precedence: + // (1) Our after border. + int before = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderBeforeColor, table->style()->direction(), table->style()->writingMode()); + int after = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderAfterColor, table->style()->direction(), table->style()->writingMode()); + CollapsedBorderValue result = CollapsedBorderValue(&style()->borderAfter(), style()->visitedDependentColor(after), BCELL); - RenderTableCell* nextCell = table()->cellBelow(this); + RenderTableCell* nextCell = table->cellBelow(this); if (nextCell) { - // (2) A following cell's top border. - result = chooseBorder(result, CollapsedBorderValue(&nextCell->style()->borderTop(), nextCell->style()->visitedDependentColor(top), BCELL)); + // (2) An after cell's before border. + result = chooseBorder(result, CollapsedBorderValue(&nextCell->style()->borderBefore(), nextCell->style()->visitedDependentColor(before), BCELL)); if (!result.exists()) return result; } - // (3) Our row's bottom border. (FIXME: Deal with rowspan!) - result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderBottom(), parent()->style()->visitedDependentColor(bottom), BROW)); + // (3) Our row's after border. (FIXME: Deal with rowspan!) + result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderAfter(), parent()->style()->visitedDependentColor(after), BROW)); if (!result.exists()) return result; - // (4) The next row's top border. + // (4) The next row's before border. if (nextCell) { - result = chooseBorder(result, CollapsedBorderValue(&nextCell->parent()->style()->borderTop(), nextCell->parent()->style()->visitedDependentColor(top), BROW)); + result = chooseBorder(result, CollapsedBorderValue(&nextCell->parent()->style()->borderBefore(), nextCell->parent()->style()->visitedDependentColor(before), BROW)); if (!result.exists()) return result; } @@ -643,36 +632,35 @@ CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const // Now check row groups. RenderTableSection* currSection = section(); if (row() + rowSpan() >= currSection->numRows()) { - // (5) Our row group's bottom border. - result = chooseBorder(result, CollapsedBorderValue(&currSection->style()->borderBottom(), currSection->style()->visitedDependentColor(bottom), BROWGROUP)); + // (5) Our row group's after border. + result = chooseBorder(result, CollapsedBorderValue(&currSection->style()->borderAfter(), currSection->style()->visitedDependentColor(after), BROWGROUP)); if (!result.exists()) return result; - // (6) Following row group's top border. - currSection = table()->sectionBelow(currSection); + // (6) Following row group's before border. + currSection = table->sectionBelow(currSection); if (currSection) { - result = chooseBorder(result, CollapsedBorderValue(&currSection->style()->borderTop(), currSection->style()->visitedDependentColor(top), BROWGROUP)); + result = chooseBorder(result, CollapsedBorderValue(&currSection->style()->borderBefore(), currSection->style()->visitedDependentColor(before), BROWGROUP)); if (!result.exists()) return result; } } if (!currSection) { - // (8) Our column and column group's bottom borders. - RenderTableCol* colElt = table()->colElement(col()); + // (8) Our column and column group's after borders. + RenderTableCol* colElt = table->colElement(col()); if (colElt) { - result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderBottom(), colElt->style()->visitedDependentColor(bottom), BCOL)); + result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderAfter(), colElt->style()->visitedDependentColor(after), BCOL)); if (!result.exists()) return result; if (colElt->parent()->isTableCol()) { - result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderBottom(), colElt->parent()->style()->visitedDependentColor(bottom), BCOLGROUP)); + result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderAfter(), colElt->parent()->style()->visitedDependentColor(after), BCOLGROUP)); if (!result.exists()) return result; } } - // (9) The table's bottom border. - RenderTable* enclosingTable = table(); - result = chooseBorder(result, CollapsedBorderValue(&enclosingTable->style()->borderBottom(), enclosingTable->style()->visitedDependentColor(bottom), BTABLE)); + // (9) The table's after border. + result = chooseBorder(result, CollapsedBorderValue(&table->style()->borderAfter(), table->style()->visitedDependentColor(after), BTABLE)); if (!result.exists()) return result; } @@ -680,6 +668,38 @@ CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const return result; } +CollapsedBorderValue RenderTableCell::collapsedLeftBorder() const +{ + RenderStyle* tableStyle = table()->style(); + if (tableStyle->isHorizontalWritingMode()) + return tableStyle->isLeftToRightDirection() ? collapsedStartBorder() : collapsedEndBorder(); + return tableStyle->isFlippedBlocksWritingMode() ? collapsedAfterBorder() : collapsedBeforeBorder(); +} + +CollapsedBorderValue RenderTableCell::collapsedRightBorder() const +{ + RenderStyle* tableStyle = table()->style(); + if (tableStyle->isHorizontalWritingMode()) + return tableStyle->isLeftToRightDirection() ? collapsedEndBorder() : collapsedStartBorder(); + return tableStyle->isFlippedBlocksWritingMode() ? collapsedBeforeBorder() : collapsedAfterBorder(); +} + +CollapsedBorderValue RenderTableCell::collapsedTopBorder() const +{ + RenderStyle* tableStyle = table()->style(); + if (tableStyle->isHorizontalWritingMode()) + return tableStyle->isFlippedBlocksWritingMode() ? collapsedAfterBorder() : collapsedBeforeBorder(); + return tableStyle->isLeftToRightDirection() ? collapsedStartBorder() : collapsedEndBorder(); +} + +CollapsedBorderValue RenderTableCell::collapsedBottomBorder() const +{ + RenderStyle* tableStyle = table()->style(); + if (tableStyle->isHorizontalWritingMode()) + return tableStyle->isFlippedBlocksWritingMode() ? collapsedBeforeBorder() : collapsedAfterBorder(); + return tableStyle->isLeftToRightDirection() ? collapsedEndBorder() : collapsedStartBorder(); +} + int RenderTableCell::borderLeft() const { return table()->collapseBorders() ? borderHalfLeft(false) : RenderBlock::borderLeft(); @@ -704,53 +724,85 @@ int RenderTableCell::borderBottom() const // work with different block flow values instead of being hard-coded to top-to-bottom. int RenderTableCell::borderStart() const { - return table()->collapseBorders() ? borderHalfLeft(false) : RenderBlock::borderStart(); + return table()->collapseBorders() ? borderHalfStart(false) : RenderBlock::borderStart(); } int RenderTableCell::borderEnd() const { - return table()->collapseBorders() ? borderHalfRight(false) : RenderBlock::borderEnd(); + return table()->collapseBorders() ? borderHalfEnd(false) : RenderBlock::borderEnd(); } int RenderTableCell::borderBefore() const { - return table()->collapseBorders() ? borderHalfTop(false) : RenderBlock::borderBefore(); + return table()->collapseBorders() ? borderHalfBefore(false) : RenderBlock::borderBefore(); } int RenderTableCell::borderAfter() const { - return table()->collapseBorders() ? borderHalfBottom(false) : RenderBlock::borderAfter(); + return table()->collapseBorders() ? borderHalfAfter(false) : RenderBlock::borderAfter(); } int RenderTableCell::borderHalfLeft(bool outer) const { - CollapsedBorderValue border = collapsedLeftBorder(!table()->style()->isLeftToRightDirection()); + RenderStyle* tableStyle = table()->style(); + if (tableStyle->isHorizontalWritingMode()) + return tableStyle->isLeftToRightDirection() ? borderHalfStart(outer) : borderHalfEnd(outer); + return tableStyle->isFlippedBlocksWritingMode() ? borderHalfAfter(outer) : borderHalfBefore(outer); +} + +int RenderTableCell::borderHalfRight(bool outer) const +{ + RenderStyle* tableStyle = table()->style(); + if (tableStyle->isHorizontalWritingMode()) + return tableStyle->isLeftToRightDirection() ? borderHalfEnd(outer) : borderHalfStart(outer); + return tableStyle->isFlippedBlocksWritingMode() ? borderHalfBefore(outer) : borderHalfAfter(outer); +} + +int RenderTableCell::borderHalfTop(bool outer) const +{ + RenderStyle* tableStyle = table()->style(); + if (tableStyle->isHorizontalWritingMode()) + return tableStyle->isFlippedBlocksWritingMode() ? borderHalfAfter(outer) : borderHalfBefore(outer); + return tableStyle->isLeftToRightDirection() ? borderHalfStart(outer) : borderHalfEnd(outer); +} + +int RenderTableCell::borderHalfBottom(bool outer) const +{ + RenderStyle* tableStyle = table()->style(); + if (tableStyle->isHorizontalWritingMode()) + return tableStyle->isFlippedBlocksWritingMode() ? borderHalfBefore(outer) : borderHalfAfter(outer); + return tableStyle->isLeftToRightDirection() ? borderHalfEnd(outer) : borderHalfStart(outer); +} + +int RenderTableCell::borderHalfStart(bool outer) const +{ + CollapsedBorderValue border = collapsedStartBorder(); if (border.exists()) - return (border.width() + (outer ? 0 : 1)) / 2; // Give the extra pixel to top and left. + return (border.width() + ((table()->style()->isLeftToRightDirection() ^ outer) ? 1 : 0)) / 2; // Give the extra pixel to top and left. return 0; } -int RenderTableCell::borderHalfRight(bool outer) const +int RenderTableCell::borderHalfEnd(bool outer) const { - CollapsedBorderValue border = collapsedRightBorder(!table()->style()->isLeftToRightDirection()); + CollapsedBorderValue border = collapsedEndBorder(); if (border.exists()) - return (border.width() + (outer ? 1 : 0)) / 2; + return (border.width() + ((table()->style()->isLeftToRightDirection() ^ outer) ? 0 : 1)) / 2; return 0; } -int RenderTableCell::borderHalfTop(bool outer) const +int RenderTableCell::borderHalfBefore(bool outer) const { - CollapsedBorderValue border = collapsedTopBorder(); + CollapsedBorderValue border = collapsedBeforeBorder(); if (border.exists()) - return (border.width() + (outer ? 0 : 1)) / 2; // Give the extra pixel to top and left. + return (border.width() + ((table()->style()->isFlippedBlocksWritingMode() ^ outer) ? 0 : 1)) / 2; // Give the extra pixel to top and left. return 0; } -int RenderTableCell::borderHalfBottom(bool outer) const +int RenderTableCell::borderHalfAfter(bool outer) const { - CollapsedBorderValue border = collapsedBottomBorder(); + CollapsedBorderValue border = collapsedAfterBorder(); if (border.exists()) - return (border.width() + (outer ? 1 : 0)) / 2; + return (border.width() + ((table()->style()->isFlippedBlocksWritingMode() ^ outer) ? 1 : 0)) / 2; return 0; } @@ -844,11 +896,10 @@ static void addBorderStyle(RenderTableCell::CollapsedBorderStyles& borderStyles, void RenderTableCell::collectBorderStyles(CollapsedBorderStyles& borderStyles) const { - bool rtl = !table()->style()->isLeftToRightDirection(); - addBorderStyle(borderStyles, collapsedLeftBorder(rtl)); - addBorderStyle(borderStyles, collapsedRightBorder(rtl)); - addBorderStyle(borderStyles, collapsedTopBorder()); - addBorderStyle(borderStyles, collapsedBottomBorder()); + addBorderStyle(borderStyles, collapsedStartBorder()); + addBorderStyle(borderStyles, collapsedEndBorder()); + addBorderStyle(borderStyles, collapsedBeforeBorder()); + addBorderStyle(borderStyles, collapsedAfterBorder()); } static int compareBorderStylesForQSort(const void* pa, const void* pb) @@ -871,9 +922,8 @@ void RenderTableCell::paintCollapsedBorder(GraphicsContext* graphicsContext, int if (!table()->currentBorderStyle()) return; - bool rtl = !table()->style()->isLeftToRightDirection(); - CollapsedBorderValue leftVal = collapsedLeftBorder(rtl); - CollapsedBorderValue rightVal = collapsedRightBorder(rtl); + CollapsedBorderValue leftVal = collapsedLeftBorder(); + CollapsedBorderValue rightVal = collapsedRightBorder(); CollapsedBorderValue topVal = collapsedTopBorder(); CollapsedBorderValue bottomVal = collapsedBottomBorder(); diff --git a/WebCore/rendering/RenderTableCell.h b/WebCore/rendering/RenderTableCell.h index 31879d6..15e6bab 100644 --- a/WebCore/rendering/RenderTableCell.h +++ b/WebCore/rendering/RenderTableCell.h @@ -51,11 +51,11 @@ public: RenderTableSection* section() const { return toRenderTableSection(parent()->parent()); } RenderTable* table() const { return toRenderTable(parent()->parent()->parent()); } - Length styleOrColWidth() const; + Length styleOrColLogicalWidth() const; virtual void computePreferredLogicalWidths(); - void updateWidth(int); + void updateLogicalWidth(int); virtual int borderLeft() const; virtual int borderRight() const; @@ -71,8 +71,18 @@ public: int borderHalfTop(bool outer) const; int borderHalfBottom(bool outer) const; - CollapsedBorderValue collapsedLeftBorder(bool rtl) const; - CollapsedBorderValue collapsedRightBorder(bool rtl) const; + int borderHalfStart(bool outer) const; + int borderHalfEnd(bool outer) const; + int borderHalfBefore(bool outer) const; + int borderHalfAfter(bool outer) const; + + CollapsedBorderValue collapsedStartBorder() const; + CollapsedBorderValue collapsedEndBorder() const; + CollapsedBorderValue collapsedBeforeBorder() const; + CollapsedBorderValue collapsedAfterBorder() const; + + CollapsedBorderValue collapsedLeftBorder() const; + CollapsedBorderValue collapsedRightBorder() const; CollapsedBorderValue collapsedTopBorder() const; CollapsedBorderValue collapsedBottomBorder() const; diff --git a/WebCore/rendering/RenderTableRow.cpp b/WebCore/rendering/RenderTableRow.cpp index d0bd511..2166ef2 100644 --- a/WebCore/rendering/RenderTableRow.cpp +++ b/WebCore/rendering/RenderTableRow.cpp @@ -4,7 +4,7 @@ * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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 @@ -54,7 +54,7 @@ void RenderTableRow::destroy() void RenderTableRow::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) { - if (section() && style() && style()->height() != newStyle->height()) + if (section() && style() && style()->logicalHeight() != newStyle->logicalHeight()) section()->setNeedsCellRecalc(); ASSERT(newStyle->display() == TABLE_ROW); diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp index e9aa3cb..b262934 100644 --- a/WebCore/rendering/RenderTableSection.cpp +++ b/WebCore/rendering/RenderTableSection.cpp @@ -4,7 +4,7 @@ * (C) 1998 Waldo Bastian (bastian@kde.org) * (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) * * This library is free software; you can redistribute it and/or @@ -47,12 +47,12 @@ namespace WebCore { using namespace HTMLNames; -static inline void setRowHeightToRowStyleHeightIfNotRelative(RenderTableSection::RowStruct* row) +static inline void setRowLogicalHeightToRowStyleLogicalHeightIfNotRelative(RenderTableSection::RowStruct* row) { ASSERT(row && row->rowRenderer); - row->height = row->rowRenderer->style()->height(); - if (row->height.isRelative()) - row->height = Length(); + row->logicalHeight = row->rowRenderer->style()->logicalHeight(); + if (row->logicalHeight.isRelative()) + row->logicalHeight = Length(); } RenderTableSection::RenderTableSection(Node* node) @@ -60,10 +60,10 @@ RenderTableSection::RenderTableSection(Node* node) , m_gridRows(0) , m_cCol(0) , m_cRow(-1) - , m_outerBorderLeft(0) - , m_outerBorderRight(0) - , m_outerBorderTop(0) - , m_outerBorderBottom(0) + , m_outerBorderStart(0) + , m_outerBorderEnd(0) + , m_outerBorderBefore(0) + , m_outerBorderAfter(0) , m_needsCellRecalc(false) , m_hasOverflowingCell(false) , m_hasMultipleCellLevels(false) @@ -137,7 +137,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild m_grid[m_cRow].rowRenderer = toRenderTableRow(child); if (!beforeChild) - setRowHeightToRowStyleHeightIfNotRelative(&m_grid[m_cRow]); + setRowLogicalHeightToRowStyleLogicalHeightIfNotRelative(&m_grid[m_cRow]); // If the next renderer is actually wrapped in an anonymous table row, we need to go up and find that. while (beforeChild && beforeChild->parent() != this) @@ -169,7 +169,7 @@ bool RenderTableSection::ensureRows(int numRows) m_grid[r].row = new Row(nCols); m_grid[r].rowRenderer = 0; m_grid[r].baseline = 0; - m_grid[r].height = Length(); + m_grid[r].logicalHeight = Length(); } } @@ -194,19 +194,19 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row) if (rSpan == 1) { // we ignore height settings on rowspan cells - Length height = cell->style()->height(); - if (height.isPositive() || (height.isRelative() && height.value() >= 0)) { - Length cRowHeight = m_grid[m_cRow].height; - switch (height.type()) { + Length logicalHeight = cell->style()->logicalHeight(); + if (logicalHeight.isPositive() || (logicalHeight.isRelative() && logicalHeight.value() >= 0)) { + Length cRowLogicalHeight = m_grid[m_cRow].logicalHeight; + switch (logicalHeight.type()) { case Percent: - if (!(cRowHeight.isPercent()) || - (cRowHeight.isPercent() && cRowHeight.rawValue() < height.rawValue())) - m_grid[m_cRow].height = height; + if (!(cRowLogicalHeight.isPercent()) || + (cRowLogicalHeight.isPercent() && cRowLogicalHeight.rawValue() < logicalHeight.rawValue())) + m_grid[m_cRow].logicalHeight = logicalHeight; break; case Fixed: - if (cRowHeight.type() < Percent || - (cRowHeight.isFixed() && cRowHeight.value() < height.value())) - m_grid[m_cRow].height = height; + if (cRowLogicalHeight.type() < Percent || + (cRowLogicalHeight.isFixed() && cRowLogicalHeight.value() < logicalHeight.value())) + m_grid[m_cRow].logicalHeight = logicalHeight; break; case Relative: default: @@ -252,7 +252,7 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row) cell->setCol(table()->effColToCol(col)); } -void RenderTableSection::setCellWidths() +void RenderTableSection::setCellLogicalWidths() { Vector<int>& columnPos = table()->columnPositions(); @@ -284,6 +284,7 @@ void RenderTableSection::setCellWidths() endCol++; } int w = columnPos[endCol] - columnPos[j] - table()->hBorderSpacing(); +<<<<<<< HEAD #ifdef ANDROID_LAYOUT if (table()->isSingleColumn()) { int b = table()->collapseBorders() ? @@ -297,6 +298,10 @@ void RenderTableSection::setCellWidths() #else if (w != oldWidth) { #endif +======= + int oldLogicalWidth = cell->logicalWidth(); + if (w != oldLogicalWidth) { +>>>>>>> webkit.org at r71558 cell->setNeedsLayout(true); if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout()) { if (!statePusher.didPush()) { @@ -306,10 +311,14 @@ void RenderTableSection::setCellWidths() } cell->repaint(); } +<<<<<<< HEAD #ifdef ANDROID_LAYOUT if (w != oldWidth) #endif cell->updateWidth(w); +======= + cell->updateLogicalWidth(w); +>>>>>>> webkit.org at r71558 } } } @@ -317,7 +326,7 @@ void RenderTableSection::setCellWidths() statePusher.pop(); // only pops if we pushed } -int RenderTableSection::calcRowHeight() +int RenderTableSection::calcRowLogicalHeight() { #ifndef NDEBUG setNeedsLayoutIsForbidden(true); @@ -348,7 +357,7 @@ int RenderTableSection::calcRowHeight() m_grid[r].baseline = 0; int baseline = 0; int bdesc = 0; - int ch = m_grid[r].height.calcMinValue(0); + int ch = m_grid[r].logicalHeight.calcMinValue(0); int pos = m_rowPos[r] + ch + (m_grid[r].rowRenderer ? spacing : 0); m_rowPos[r + 1] = max(m_rowPos[r + 1], pos); @@ -378,17 +387,17 @@ int RenderTableSection::calcRowHeight() cell->setChildNeedsLayout(true, false); cell->layoutIfNeeded(); } - - int adjustedPaddingTop = cell->paddingTop() - cell->intrinsicPaddingBefore(); - int adjustedPaddingBottom = cell->paddingBottom() - cell->intrinsicPaddingAfter(); - int adjustedHeight = cell->height() - (cell->intrinsicPaddingBefore() + cell->intrinsicPaddingAfter()); - + + int adjustedPaddingBefore = cell->paddingBefore() - cell->intrinsicPaddingBefore(); + int adjustedPaddingAfter = cell->paddingAfter() - cell->intrinsicPaddingAfter(); + int adjustedLogicalHeight = cell->logicalHeight() - (cell->intrinsicPaddingBefore() + cell->intrinsicPaddingAfter()); + // Explicit heights use the border box in quirks mode. In strict mode do the right // thing and actually add in the border and padding. - ch = cell->style()->height().calcValue(0) + - (document()->inQuirksMode() ? 0 : (adjustedPaddingTop + adjustedPaddingBottom + - cell->borderTop() + cell->borderBottom())); - ch = max(ch, adjustedHeight); + ch = cell->style()->logicalHeight().calcValue(0) + + (document()->inQuirksMode() ? 0 : (adjustedPaddingBefore + adjustedPaddingAfter + + cell->borderBefore() + cell->borderAfter())); + ch = max(ch, adjustedLogicalHeight); pos = m_rowPos[indx] + ch + (m_grid[r].rowRenderer ? spacing : 0); @@ -398,7 +407,7 @@ int RenderTableSection::calcRowHeight() EVerticalAlign va = cell->style()->verticalAlign(); if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB) { int b = cell->baselinePosition(); - if (b > cell->borderTop() + cell->paddingTop()) { + if (b > cell->borderBefore() + cell->paddingBefore()) { baseline = max(baseline, b - cell->intrinsicPaddingBefore()); bdesc = max(bdesc, m_rowPos[indx] + ch - (b - cell->intrinsicPaddingBefore())); } @@ -504,7 +513,7 @@ int RenderTableSection::layoutRows(int toAdd) int totalRows = m_gridRows; // Set the width of our section now. The rows will also be this width. - setWidth(table()->contentWidth()); + setLogicalWidth(table()->contentLogicalWidth()); m_overflow.clear(); m_hasOverflowingCell = false; @@ -515,10 +524,10 @@ int RenderTableSection::layoutRows(int toAdd) int totalPercent = 0; int numAuto = 0; for (int r = 0; r < totalRows; r++) { - if (m_grid[r].height.isAuto()) + if (m_grid[r].logicalHeight.isAuto()) numAuto++; - else if (m_grid[r].height.isPercent()) - totalPercent += m_grid[r].height.rawValue(); + else if (m_grid[r].logicalHeight.isPercent()) + totalPercent += m_grid[r].logicalHeight.rawValue(); } if (totalPercent) { // try to satisfy percent @@ -526,14 +535,14 @@ int RenderTableSection::layoutRows(int toAdd) totalPercent = min(totalPercent, 100 * percentScaleFactor); int rh = m_rowPos[1] - m_rowPos[0]; for (int r = 0; r < totalRows; r++) { - if (totalPercent > 0 && m_grid[r].height.isPercent()) { - int toAdd = min(dh, (totalHeight * m_grid[r].height.rawValue() / (100 * percentScaleFactor)) - rh); + if (totalPercent > 0 && m_grid[r].logicalHeight.isPercent()) { + int toAdd = min(dh, (totalHeight * m_grid[r].logicalHeight.rawValue() / (100 * percentScaleFactor)) - rh); // If toAdd is negative, then we don't want to shrink the row (this bug // affected Outlook Web Access). toAdd = max(0, toAdd); add += toAdd; dh -= toAdd; - totalPercent -= m_grid[r].height.rawValue(); + totalPercent -= m_grid[r].logicalHeight.rawValue(); } if (r < totalRows - 1) rh = m_rowPos[r + 2] - m_rowPos[r + 1]; @@ -544,7 +553,7 @@ int RenderTableSection::layoutRows(int toAdd) // distribute over variable cols int add = 0; for (int r = 0; r < totalRows; r++) { - if (numAuto > 0 && m_grid[r].height.isAuto()) { + if (numAuto > 0 && m_grid[r].logicalHeight.isAuto()) { int toAdd = dh / numAuto; add += toAdd; dh -= toAdd; @@ -577,8 +586,8 @@ int RenderTableSection::layoutRows(int toAdd) // Set the row's x/y position and width/height. if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) { rowRenderer->setLocation(0, m_rowPos[r]); - rowRenderer->setWidth(width()); - rowRenderer->setHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); + rowRenderer->setLogicalWidth(logicalWidth()); + rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); } for (int c = 0; c < nEffCols; c++) { @@ -605,11 +614,11 @@ int RenderTableSection::layoutRows(int toAdd) // match the behavior perfectly, but we'll continue to refine it as we discover new // bugs. :) bool cellChildrenFlex = false; - bool flexAllChildren = cell->style()->height().isFixed() - || (!table()->style()->height().isAuto() && rHeight != cell->height()); + bool flexAllChildren = cell->style()->logicalHeight().isFixed() + || (!table()->style()->logicalHeight().isAuto() && rHeight != cell->logicalHeight()); for (RenderObject* o = cell->firstChild(); o; o = o->nextSibling()) { - if (!o->isText() && o->style()->height().isPercent() && (flexAllChildren || o->isReplaced() || (o->isBox() && toRenderBox(o)->scrollsOverflow()))) { + if (!o->isText() && o->style()->logicalHeight().isPercent() && (flexAllChildren || o->isReplaced() || (o->isBox() && toRenderBox(o)->scrollsOverflow()))) { // Tables with no sections do not flex. if (!o->isTable() || toRenderTable(o)->hasSections()) { o->setNeedsLayout(true, false); @@ -644,24 +653,24 @@ int RenderTableSection::layoutRows(int toAdd) // height, which becomes irrelevant once the cell has // been resized based off its percentage. cell->setOverrideSize(max(0, - rHeight - cell->borderTop() - cell->paddingTop() - - cell->borderBottom() - cell->paddingBottom())); + rHeight - cell->borderBefore() - cell->paddingBefore() - + cell->borderAfter() - cell->paddingAfter())); cell->layoutIfNeeded(); - + // If the baseline moved, we may have to update the data for our row. Find out the new baseline. EVerticalAlign va = cell->style()->verticalAlign(); if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB) { int b = cell->baselinePosition(); - if (b > cell->borderTop() + cell->paddingTop()) + if (b > cell->borderBefore() + cell->paddingBefore()) m_grid[r].baseline = max(m_grid[r].baseline, b); } } - - int oldTe = cell->intrinsicPaddingBefore(); - int oldBe = cell->intrinsicPaddingAfter(); - int heightWithoutIntrinsicPadding = cell->height() - oldTe - oldBe; - - int te = 0; + + int oldIntrinsicPaddingBefore = cell->intrinsicPaddingBefore(); + int oldIntrinsicPaddingAfter = cell->intrinsicPaddingAfter(); + int logicalHeightWithoutIntrinsicPadding = cell->logicalHeight() - oldIntrinsicPaddingBefore - oldIntrinsicPaddingAfter; + + int intrinsicPaddingBefore = 0; switch (cell->style()->verticalAlign()) { case SUB: case SUPER: @@ -669,46 +678,46 @@ int RenderTableSection::layoutRows(int toAdd) case TEXT_BOTTOM: case BASELINE: { int b = cell->baselinePosition(); - if (b > cell->borderTop() + cell->paddingTop()) - te = getBaseline(r) - (b - oldTe); + if (b > cell->borderBefore() + cell->paddingBefore()) + intrinsicPaddingBefore = getBaseline(r) - (b - oldIntrinsicPaddingBefore); break; } case TOP: - te = 0; break; case MIDDLE: - te = (rHeight - heightWithoutIntrinsicPadding) / 2; + intrinsicPaddingBefore = (rHeight - logicalHeightWithoutIntrinsicPadding) / 2; break; case BOTTOM: - te = rHeight - heightWithoutIntrinsicPadding; + intrinsicPaddingBefore = rHeight - logicalHeightWithoutIntrinsicPadding; break; default: break; } - int be = rHeight - heightWithoutIntrinsicPadding - te; - cell->setIntrinsicPaddingBefore(te); - cell->setIntrinsicPaddingAfter(be); - + int intrinsicPaddingAfter = rHeight - logicalHeightWithoutIntrinsicPadding - intrinsicPaddingBefore; + cell->setIntrinsicPaddingBefore(intrinsicPaddingBefore); + cell->setIntrinsicPaddingAfter(intrinsicPaddingAfter); + IntRect oldCellRect(cell->x(), cell->y() , cell->width(), cell->height()); - + if (!style()->isLeftToRightDirection()) - cell->setLocation(table()->columnPositions()[nEffCols] - table()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + hspacing, m_rowPos[rindx]); + cell->setLogicalLocation(table()->columnPositions()[nEffCols] - table()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + hspacing, m_rowPos[rindx]); else - cell->setLocation(table()->columnPositions()[c] + hspacing, m_rowPos[rindx]); + cell->setLogicalLocation(table()->columnPositions()[c] + hspacing, m_rowPos[rindx]); view()->addLayoutDelta(IntSize(oldCellRect.x() - cell->x(), oldCellRect.y() - cell->y())); - if (te != oldTe || be != oldBe) + if (intrinsicPaddingBefore != oldIntrinsicPaddingBefore || intrinsicPaddingAfter != oldIntrinsicPaddingAfter) cell->setNeedsLayout(true, false); - + if (!cell->needsLayout() && view()->layoutState()->m_pageHeight && view()->layoutState()->pageY(cell->y()) != cell->pageY()) cell->setChildNeedsLayout(true, false); - + cell->layoutIfNeeded(); - - if (view()->layoutState()->m_pageHeight && cell->height() != rHeight) + + // FIXME: Make pagination work with vertical tables. + if (style()->isHorizontalWritingMode() && view()->layoutState()->m_pageHeight && cell->height() != rHeight) cell->setHeight(rHeight); // FIXME: Pagination might have made us change size. For now just shrink or grow the cell to fit without doing a relayout. - + IntSize childOffset(cell->x() - oldCellRect.x(), cell->y() - oldCellRect.y()); if (childOffset.width() || childOffset.height()) { view()->addLayoutDelta(childOffset); @@ -728,7 +737,7 @@ int RenderTableSection::layoutRows(int toAdd) ASSERT(!needsLayout()); - setHeight(m_rowPos[totalRows]); + setLogicalHeight(m_rowPos[totalRows]); // Now that our height has been determined, add in overflow from cells. for (int r = 0; r < totalRows; r++) { @@ -820,7 +829,7 @@ int RenderTableSection::leftmostPosition(bool includeOverflowInterior, bool incl return left; } -int RenderTableSection::calcOuterBorderTop() const +int RenderTableSection::calcOuterBorderBefore() const { int totalCols = table()->numEffCols(); if (!m_gridRows || !totalCols) @@ -828,13 +837,13 @@ int RenderTableSection::calcOuterBorderTop() const unsigned borderWidth = 0; - const BorderValue& sb = style()->borderTop(); + const BorderValue& sb = style()->borderBefore(); if (sb.style() == BHIDDEN) return -1; if (sb.style() > BHIDDEN) borderWidth = sb.width(); - const BorderValue& rb = firstChild()->style()->borderTop(); + const BorderValue& rb = firstChild()->style()->borderBefore(); if (rb.style() == BHIDDEN) return -1; if (rb.style() > BHIDDEN && rb.width() > borderWidth) @@ -845,11 +854,11 @@ int RenderTableSection::calcOuterBorderTop() const const CellStruct& current = cellAt(0, c); if (current.inColSpan || !current.hasCells()) continue; - const BorderValue& cb = current.primaryCell()->style()->borderTop(); + const BorderValue& cb = current.primaryCell()->style()->borderBefore(); // FIXME: Make this work with perpendicular and flipped cells. // FIXME: Don't repeat for the same col group RenderTableCol* colGroup = table()->colElement(c); if (colGroup) { - const BorderValue& gb = colGroup->style()->borderTop(); + const BorderValue& gb = colGroup->style()->borderBefore(); if (gb.style() == BHIDDEN || cb.style() == BHIDDEN) continue; allHidden = false; @@ -871,7 +880,7 @@ int RenderTableSection::calcOuterBorderTop() const return borderWidth / 2; } -int RenderTableSection::calcOuterBorderBottom() const +int RenderTableSection::calcOuterBorderAfter() const { int totalCols = table()->numEffCols(); if (!m_gridRows || !totalCols) @@ -879,13 +888,13 @@ int RenderTableSection::calcOuterBorderBottom() const unsigned borderWidth = 0; - const BorderValue& sb = style()->borderBottom(); + const BorderValue& sb = style()->borderAfter(); if (sb.style() == BHIDDEN) return -1; if (sb.style() > BHIDDEN) borderWidth = sb.width(); - const BorderValue& rb = lastChild()->style()->borderBottom(); + const BorderValue& rb = lastChild()->style()->borderAfter(); if (rb.style() == BHIDDEN) return -1; if (rb.style() > BHIDDEN && rb.width() > borderWidth) @@ -896,11 +905,11 @@ int RenderTableSection::calcOuterBorderBottom() const const CellStruct& current = cellAt(m_gridRows - 1, c); if (current.inColSpan || !current.hasCells()) continue; - const BorderValue& cb = current.primaryCell()->style()->borderBottom(); + const BorderValue& cb = current.primaryCell()->style()->borderAfter(); // FIXME: Make this work with perpendicular and flipped cells. // FIXME: Don't repeat for the same col group RenderTableCol* colGroup = table()->colElement(c); if (colGroup) { - const BorderValue& gb = colGroup->style()->borderBottom(); + const BorderValue& gb = colGroup->style()->borderAfter(); if (gb.style() == BHIDDEN || cb.style() == BHIDDEN) continue; allHidden = false; @@ -922,7 +931,7 @@ int RenderTableSection::calcOuterBorderBottom() const return (borderWidth + 1) / 2; } -int RenderTableSection::calcOuterBorderLeft(bool rtl) const +int RenderTableSection::calcOuterBorderStart() const { int totalCols = table()->numEffCols(); if (!m_gridRows || !totalCols) @@ -930,16 +939,14 @@ int RenderTableSection::calcOuterBorderLeft(bool rtl) const unsigned borderWidth = 0; - const BorderValue& sb = style()->borderLeft(); + const BorderValue& sb = style()->borderStart(); if (sb.style() == BHIDDEN) return -1; if (sb.style() > BHIDDEN) borderWidth = sb.width(); - int leftmostColumn = rtl ? totalCols - 1 : 0; - RenderTableCol* colGroup = table()->colElement(leftmostColumn); - if (colGroup) { - const BorderValue& gb = colGroup->style()->borderLeft(); + if (RenderTableCol* colGroup = table()->colElement(0)) { + const BorderValue& gb = colGroup->style()->borderStart(); if (gb.style() == BHIDDEN) return -1; if (gb.style() > BHIDDEN && gb.width() > borderWidth) @@ -948,12 +955,12 @@ int RenderTableSection::calcOuterBorderLeft(bool rtl) const bool allHidden = true; for (int r = 0; r < m_gridRows; r++) { - const CellStruct& current = cellAt(r, leftmostColumn); + const CellStruct& current = cellAt(r, 0); if (!current.hasCells()) continue; // FIXME: Don't repeat for the same cell - const BorderValue& cb = current.primaryCell()->style()->borderLeft(); - const BorderValue& rb = current.primaryCell()->parent()->style()->borderLeft(); + const BorderValue& cb = current.primaryCell()->style()->borderStart(); // FIXME: Make this work with perpendicular and flipped cells. + const BorderValue& rb = current.primaryCell()->parent()->style()->borderStart(); if (cb.style() == BHIDDEN || rb.style() == BHIDDEN) continue; allHidden = false; @@ -965,10 +972,10 @@ int RenderTableSection::calcOuterBorderLeft(bool rtl) const if (allHidden) return -1; - return borderWidth / 2; + return (borderWidth + (table()->style()->isLeftToRightDirection() ? 0 : 1)) / 2; } -int RenderTableSection::calcOuterBorderRight(bool rtl) const +int RenderTableSection::calcOuterBorderEnd() const { int totalCols = table()->numEffCols(); if (!m_gridRows || !totalCols) @@ -976,16 +983,14 @@ int RenderTableSection::calcOuterBorderRight(bool rtl) const unsigned borderWidth = 0; - const BorderValue& sb = style()->borderRight(); + const BorderValue& sb = style()->borderEnd(); if (sb.style() == BHIDDEN) return -1; if (sb.style() > BHIDDEN) borderWidth = sb.width(); - int rightmostColumn = rtl ? 0 : totalCols - 1; - RenderTableCol* colGroup = table()->colElement(rightmostColumn); - if (colGroup) { - const BorderValue& gb = colGroup->style()->borderRight(); + if (RenderTableCol* colGroup = table()->colElement(totalCols - 1)) { + const BorderValue& gb = colGroup->style()->borderEnd(); if (gb.style() == BHIDDEN) return -1; if (gb.style() > BHIDDEN && gb.width() > borderWidth) @@ -994,12 +999,12 @@ int RenderTableSection::calcOuterBorderRight(bool rtl) const bool allHidden = true; for (int r = 0; r < m_gridRows; r++) { - const CellStruct& current = cellAt(r, rightmostColumn); + const CellStruct& current = cellAt(r, totalCols - 1); if (!current.hasCells()) continue; // FIXME: Don't repeat for the same cell - const BorderValue& cb = current.primaryCell()->style()->borderRight(); - const BorderValue& rb = current.primaryCell()->parent()->style()->borderRight(); + const BorderValue& cb = current.primaryCell()->style()->borderEnd(); // FIXME: Make this work with perpendicular and flipped cells. + const BorderValue& rb = current.primaryCell()->parent()->style()->borderEnd(); if (cb.style() == BHIDDEN || rb.style() == BHIDDEN) continue; allHidden = false; @@ -1011,16 +1016,15 @@ int RenderTableSection::calcOuterBorderRight(bool rtl) const if (allHidden) return -1; - return (borderWidth + 1) / 2; + return (borderWidth + (table()->style()->isLeftToRightDirection() ? 1 : 0)) / 2; } void RenderTableSection::recalcOuterBorder() { - bool rtl = !table()->style()->isLeftToRightDirection(); - m_outerBorderTop = calcOuterBorderTop(); - m_outerBorderBottom = calcOuterBorderBottom(); - m_outerBorderLeft = calcOuterBorderLeft(rtl); - m_outerBorderRight = calcOuterBorderRight(rtl); + m_outerBorderBefore = calcOuterBorderBefore(); + m_outerBorderAfter = calcOuterBorderAfter(); + m_outerBorderStart = calcOuterBorderStart(); + m_outerBorderEnd = calcOuterBorderEnd(); } int RenderTableSection::firstLineBoxBaseline() const @@ -1038,7 +1042,7 @@ int RenderTableSection::firstLineBoxBaseline() const CellStruct& cs = firstRow->at(i); RenderTableCell* cell = cs.primaryCell(); if (cell) - firstLineBaseline = max(firstLineBaseline, cell->y() + cell->paddingTop() + cell->borderTop() + cell->contentHeight()); + firstLineBaseline = max(firstLineBaseline, cell->logicalTop() + cell->paddingBefore() + cell->borderBefore() + cell->contentLogicalHeight()); } return firstLineBaseline; @@ -1075,6 +1079,7 @@ static inline bool compareCellPositions(RenderTableCell* elem1, RenderTableCell* void RenderTableSection::paintCell(RenderTableCell* cell, PaintInfo& paintInfo, int tx, int ty) { + IntPoint cellPoint = flipForWritingMode(cell, IntPoint(tx, ty), ParentToChildFlippingAdjustment); PaintPhase paintPhase = paintInfo.phase; RenderTableRow* row = toRenderTableRow(cell->parent()); @@ -1091,20 +1096,19 @@ void RenderTableSection::paintCell(RenderTableCell* cell, PaintInfo& paintInfo, // the stack, since we have already opened a transparency layer (potentially) for the table row group. // Note that we deliberately ignore whether or not the cell has a layer, since these backgrounds paint "behind" the // cell. - cell->paintBackgroundsBehindCell(paintInfo, tx, ty, colGroup); - cell->paintBackgroundsBehindCell(paintInfo, tx, ty, col); + cell->paintBackgroundsBehindCell(paintInfo, cellPoint.x(), cellPoint.y(), colGroup); + cell->paintBackgroundsBehindCell(paintInfo, cellPoint.x(), cellPoint.y(), col); // Paint the row group next. - cell->paintBackgroundsBehindCell(paintInfo, tx, ty, this); + cell->paintBackgroundsBehindCell(paintInfo, cellPoint.x(), cellPoint.y(), this); // Paint the row next, but only if it doesn't have a layer. If a row has a layer, it will be responsible for // painting the row background for the cell. if (!row->hasSelfPaintingLayer()) - cell->paintBackgroundsBehindCell(paintInfo, tx, ty, row); + cell->paintBackgroundsBehindCell(paintInfo, cellPoint.x(), cellPoint.y(), row); } if ((!cell->hasSelfPaintingLayer() && !row->hasSelfPaintingLayer()) || paintInfo.phase == PaintPhaseCollapsedTableBorders) - cell->paint(paintInfo, tx, ty); - + cell->paint(paintInfo, cellPoint.x(), cellPoint.y()); } void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty) @@ -1249,7 +1253,7 @@ void RenderTableSection::recalcCells() RenderTableRow* tableRow = toRenderTableRow(row); m_grid[m_cRow].rowRenderer = tableRow; - setRowHeightToRowStyleHeightIfNotRelative(&m_grid[m_cRow]); + setRowLogicalHeightToRowStyleLogicalHeightIfNotRelative(&m_grid[m_cRow]); for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) { if (cell->isTableCell()) diff --git a/WebCore/rendering/RenderTableSection.h b/WebCore/rendering/RenderTableSection.h index fce1e0f..0327d59 100644 --- a/WebCore/rendering/RenderTableSection.h +++ b/WebCore/rendering/RenderTableSection.h @@ -47,9 +47,9 @@ public: void addCell(RenderTableCell*, RenderTableRow* row); - void setCellWidths(); - int calcRowHeight(); - int layoutRows(int height); + void setCellLogicalWidths(); + int calcRowLogicalHeight(); + int layoutRows(int logicalHeight); RenderTable* table() const { return toRenderTable(parent()); } @@ -79,7 +79,7 @@ public: Row* row; RenderTableRow* rowRenderer; int baseline; - Length height; + Length logicalHeight; }; CellStruct& cellAt(int row, int col) { return (*m_grid[row].row)[col]; } @@ -93,16 +93,16 @@ public: void appendColumn(int pos); void splitColumn(int pos, int first); - int calcOuterBorderTop() const; - int calcOuterBorderBottom() const; - int calcOuterBorderLeft(bool rtl) const; - int calcOuterBorderRight(bool rtl) const; + int calcOuterBorderBefore() const; + int calcOuterBorderAfter() const; + int calcOuterBorderStart() const; + int calcOuterBorderEnd() const; void recalcOuterBorder(); - int outerBorderTop() const { return m_outerBorderTop; } - int outerBorderBottom() const { return m_outerBorderBottom; } - int outerBorderLeft() const { return m_outerBorderLeft; } - int outerBorderRight() const { return m_outerBorderRight; } + int outerBorderBefore() const { return m_outerBorderBefore; } + int outerBorderAfter() const { return m_outerBorderAfter; } + int outerBorderStart() const { return m_outerBorderStart; } + int outerBorderEnd() const { return m_outerBorderEnd; } int numRows() const { return m_gridRows; } int numColumns() const; @@ -163,10 +163,10 @@ private: int m_cCol; int m_cRow; - int m_outerBorderLeft; - int m_outerBorderRight; - int m_outerBorderTop; - int m_outerBorderBottom; + int m_outerBorderStart; + int m_outerBorderEnd; + int m_outerBorderBefore; + int m_outerBorderAfter; bool m_needsCellRecalc; bool m_hasOverflowingCell; diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp index 510d830..aa362b3 100644 --- a/WebCore/rendering/RenderText.cpp +++ b/WebCore/rendering/RenderText.cpp @@ -418,38 +418,41 @@ VisiblePosition RenderText::positionForPoint(const IntPoint& point) // Get the offset for the position, since this will take rtl text into account. int offset; + int pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y(); + int pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x(); + // FIXME: We should be able to roll these special cases into the general cases in the loop below. - if (firstTextBox() && point.y() < firstTextBox()->root()->lineBottom() && point.x() < firstTextBox()->m_x) { + if (firstTextBox() && pointBlockDirection < firstTextBox()->root()->lineBottom() && pointLineDirection < firstTextBox()->logicalLeft()) { // at the y coordinate of the first line or above // and the x coordinate is to the left of the first text box left edge - offset = firstTextBox()->offsetForPosition(point.x()); + offset = firstTextBox()->offsetForPosition(pointLineDirection); return createVisiblePosition(offset + firstTextBox()->start(), DOWNSTREAM); } - if (lastTextBox() && point.y() >= lastTextBox()->root()->lineTop() && point.x() >= lastTextBox()->m_x + lastTextBox()->logicalWidth()) { + if (lastTextBox() && pointBlockDirection >= lastTextBox()->root()->lineTop() && pointLineDirection >= lastTextBox()->logicalRight()) { // at the y coordinate of the last line or below // and the x coordinate is to the right of the last text box right edge - offset = lastTextBox()->offsetForPosition(point.x()); + offset = lastTextBox()->offsetForPosition(pointLineDirection); return createVisiblePosition(offset + lastTextBox()->start(), VP_UPSTREAM_IF_POSSIBLE); } InlineTextBox* lastBoxAbove = 0; for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) { - if (point.y() >= box->root()->lineTop()) { + if (pointBlockDirection >= box->root()->lineTop()) { int bottom = box->root()->nextRootBox() ? box->root()->nextRootBox()->lineTop() : box->root()->lineBottom(); - if (point.y() < bottom) { - offset = box->offsetForPosition(point.x()); + if (pointBlockDirection < bottom) { + offset = box->offsetForPosition(pointLineDirection); - if (point.x() == box->m_x) + if (pointLineDirection == box->logicalLeft()) // the x coordinate is equal to the left edge of this box // the affinity must be downstream so the position doesn't jump back to the previous line return createVisiblePosition(offset + box->start(), DOWNSTREAM); - if (point.x() < box->m_x + box->logicalWidth()) + if (pointLineDirection < box->logicalRight()) // and the x coordinate is to the left of the right edge of this box // check to see if position goes in this box return createVisiblePosition(offset + box->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM); - if (!box->prevOnLine() && point.x() < box->m_x) + if (!box->prevOnLine() && pointLineDirection < box->logicalLeft()) // box is first on line // and the x coordinate is to the left of the first text box left edge return createVisiblePosition(offset + box->start(), DOWNSTREAM); @@ -488,7 +491,7 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e left -= caretWidthLeftOfOffset; int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset; - int rootLeft = box->root()->x(); + int rootLeft = box->root()->logicalLeft(); int rootRight = rootLeft + box->root()->logicalWidth(); // FIXME: should we use the width of the root inline box or the // width of the containing block for this? @@ -500,11 +503,11 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e int leftEdge; int rightEdge; if (style()->autoWrap()) { - leftEdge = cb->x(); - rightEdge = cb->frameRect().right(); + leftEdge = cb->logicalLeft(); + rightEdge = cb->logicalRight(); } else { - leftEdge = min(cb->x(), rootLeft); - rightEdge = max(cb->frameRect().right(), rootRight); + leftEdge = min(cb->logicalLeft(), rootLeft); + rightEdge = max(cb->logicalRight(), rootRight); } bool rightAligned = false; @@ -532,7 +535,7 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e left = max(left, rootLeft); } - return IntRect(left, top, caretWidth, height); + return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, height) : IntRect(top, left, height, caretWidth); } ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const @@ -1237,18 +1240,22 @@ IntRect RenderText::linesBoundingBox() const ASSERT(!firstTextBox() == !lastTextBox()); // Either both are null or both exist. if (firstTextBox() && lastTextBox()) { // Return the width of the minimal left side and the maximal right side. - int leftSide = 0; - int rightSide = 0; + int logicalLeftSide = 0; + int logicalRightSide = 0; for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) { - if (curr == firstTextBox() || curr->x() < leftSide) - leftSide = curr->x(); - if (curr == firstTextBox() || curr->x() + curr->logicalWidth() > rightSide) - rightSide = curr->x() + curr->logicalWidth(); + if (curr == firstTextBox() || curr->logicalLeft() < logicalLeftSide) + logicalLeftSide = curr->logicalLeft(); + if (curr == firstTextBox() || curr->logicalRight() > logicalRightSide) + logicalRightSide = curr->logicalRight(); } - result.setWidth(rightSide - leftSide); - result.setX(leftSide); - result.setHeight(lastTextBox()->y() + lastTextBox()->logicalHeight() - firstTextBox()->y()); - result.setY(firstTextBox()->y()); + + bool isHorizontal = style()->isHorizontalWritingMode(); + + int x = isHorizontal ? logicalLeftSide : firstTextBox()->x(); + int y = isHorizontal ? firstTextBox()->y() : logicalLeftSide; + int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTextBox()->logicalBottom() - x; + int height = isHorizontal ? lastTextBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide; + result = IntRect(x, y, width, height); } return result; diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp index 3d6b04b..e81dfb9 100644 --- a/WebCore/rendering/RenderTextControl.cpp +++ b/WebCore/rendering/RenderTextControl.cpp @@ -200,7 +200,7 @@ void RenderTextControl::setLastChangeWasUserEdit(bool lastChangeWasUserEdit) document()->setIgnoreAutofocus(lastChangeWasUserEdit); } -int RenderTextControl::selectionStart() +int RenderTextControl::selectionStart() const { Frame* frame = this->frame(); if (!frame) @@ -208,7 +208,7 @@ int RenderTextControl::selectionStart() return indexForVisiblePosition(frame->selection()->start()); } -int RenderTextControl::selectionEnd() +int RenderTextControl::selectionEnd() const { Frame* frame = this->frame(); if (!frame) @@ -264,7 +264,7 @@ PassRefPtr<Range> RenderTextControl::selection(int start, int end) const return Range::create(document(), m_innerText, start, m_innerText, end); } -VisiblePosition RenderTextControl::visiblePositionForIndex(int index) +VisiblePosition RenderTextControl::visiblePositionForIndex(int index) const { if (index <= 0) return VisiblePosition(m_innerText.get(), 0, DOWNSTREAM); @@ -281,7 +281,7 @@ VisiblePosition RenderTextControl::visiblePositionForIndex(int index) return VisiblePosition(endContainer, endOffset, UPSTREAM); } -int RenderTextControl::indexForVisiblePosition(const VisiblePosition& pos) +int RenderTextControl::indexForVisiblePosition(const VisiblePosition& pos) const { Position indexPosition = pos.deepEquivalent(); if (!indexPosition.node() || indexPosition.node()->rootEditableElement() != m_innerText) diff --git a/WebCore/rendering/RenderTextControl.h b/WebCore/rendering/RenderTextControl.h index b75de0e..0060973 100644 --- a/WebCore/rendering/RenderTextControl.h +++ b/WebCore/rendering/RenderTextControl.h @@ -40,8 +40,8 @@ public: bool lastChangeWasUserEdit() const { return m_lastChangeWasUserEdit; } void setLastChangeWasUserEdit(bool lastChangeWasUserEdit); - int selectionStart(); - int selectionEnd(); + int selectionStart() const; + int selectionEnd() const; PassRefPtr<Range> selection(int start, int end) const; virtual void subtreeHasChanged(); @@ -49,8 +49,8 @@ public: String textWithHardLineBreaks(); void selectionChanged(bool userTriggered); - VisiblePosition visiblePositionForIndex(int index); - int indexForVisiblePosition(const VisiblePosition&); + VisiblePosition visiblePositionForIndex(int index) const; + int indexForVisiblePosition(const VisiblePosition&) const; void updatePlaceholderVisibility(bool, bool); diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp index 763371f..e5ccd05 100644 --- a/WebCore/rendering/RenderWidget.cpp +++ b/WebCore/rendering/RenderWidget.cpp @@ -300,7 +300,7 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty) if (m_widget->isFrameView()) { FrameView* frameView = static_cast<FrameView*>(m_widget.get()); - bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContent(); + bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContentIncludingDescendants(); if (paintInfo.overlapTestRequests && runOverlapTests) { ASSERT(!paintInfo.overlapTestRequests->contains(this)); paintInfo.overlapTestRequests->set(this, m_widget->frameRect()); @@ -350,7 +350,8 @@ void RenderWidget::updateWidgetPosition() // content size is wrong) we have to do a layout to set the right widget size if (m_widget && m_widget->isFrameView()) { FrameView* frameView = static_cast<FrameView*>(m_widget.get()); - if (boundsChanged || frameView->needsLayout()) + // Check the frame's page to make sure that the frame isn't in the process of being destroyed. + if ((boundsChanged || frameView->needsLayout()) && frameView->frame()->page()) frameView->layout(); } #endif diff --git a/WebCore/rendering/RootInlineBox.cpp b/WebCore/rendering/RootInlineBox.cpp index 178b1ad..3e5b6c7 100644 --- a/WebCore/rendering/RootInlineBox.cpp +++ b/WebCore/rendering/RootInlineBox.cpp @@ -48,7 +48,7 @@ RootInlineBox::RootInlineBox(RenderBlock* block) , m_paginationStrut(0) , m_blockLogicalHeight(0) { - setIsVertical(!block->style()->isHorizontalWritingMode()); + setIsHorizontal(block->style()->isHorizontalWritingMode()); } @@ -99,7 +99,7 @@ void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr, bool ltr, in // Create an ellipsis box. EllipsisBox* ellipsisBox = new (renderer()->renderArena()) EllipsisBox(renderer(), ellipsisStr, this, ellipsisWidth - (markupBox ? markupBox->logicalWidth() : 0), logicalHeight(), - y(), !prevRootBox(), isVertical(), markupBox); + y(), !prevRootBox(), isHorizontal(), markupBox); if (!gEllipsisBoxMap) gEllipsisBoxMap = new EllipsisBoxMap(); @@ -238,7 +238,8 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn int maxHeight = maxAscent + maxDescent; int lineTop = heightOfBlock; int lineBottom = heightOfBlock; - placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom); + bool setLineTop = false; + placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, setLineTop); computeBlockDirectionOverflow(lineTop, lineBottom, noQuirksMode, textBoxDataMap); setLineTopBottomPositions(lineTop, lineBottom); @@ -249,26 +250,24 @@ int RootInlineBox::alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAn return heightOfBlock + maxHeight; } -GapRects RootInlineBox::fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, - const PaintInfo* paintInfo) +GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, + int selTop, int selHeight, const PaintInfo* paintInfo) { RenderObject::SelectionState lineState = selectionState(); bool leftGap, rightGap; - block()->getHorizontalSelectionGapInfo(lineState, leftGap, rightGap); + block()->getSelectionGapInfo(lineState, leftGap, rightGap); GapRects result; InlineBox* firstBox = firstSelectedBox(); InlineBox* lastBox = lastSelectedBox(); if (leftGap) - result.uniteLeft(block()->fillLeftSelectionGap(firstBox->parent()->renderer(), - firstBox->x(), selTop, selHeight, - rootBlock, blockX, blockY, tx, ty, paintInfo)); + result.uniteLeft(block()->logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, + firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo)); if (rightGap) - result.uniteRight(block()->fillRightSelectionGap(lastBox->parent()->renderer(), - lastBox->x() + lastBox->logicalWidth(), selTop, selHeight, - rootBlock, blockX, blockY, tx, ty, paintInfo)); + result.uniteRight(block()->logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, + lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo)); // When dealing with bidi text, a non-contiguous selection region is possible. // e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capitals LTR) is layed out @@ -279,15 +278,20 @@ GapRects RootInlineBox::fillLineSelectionGap(int selTop, int selHeight, RenderBl // We can see that the |bbb| run is not part of the selection while the runs around it are. if (firstBox && firstBox != lastBox) { // Now fill in any gaps on the line that occurred between two selected elements. - int lastX = firstBox->x() + firstBox->logicalWidth(); + int lastLogicalLeft = firstBox->logicalRight(); bool isPreviousBoxSelected = firstBox->selectionState() != RenderObject::SelectionNone; for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLeafChild()) { if (box->selectionState() != RenderObject::SelectionNone) { - if (isPreviousBoxSelected) // VisibleSelection may be non-contiguous, see comment above. - result.uniteCenter(block()->fillHorizontalSelectionGap(box->parent()->renderer(), - lastX + tx, selTop + ty, - box->x() - lastX, selHeight, paintInfo)); - lastX = box->x() + box->logicalWidth(); + IntRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft() - lastLogicalLeft, selHeight); + logicalRect.move(renderer()->style()->isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width())); + IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect); + if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.height() > 0) { + if (paintInfo && box->parent()->renderer()->style()->visibility() == VISIBLE) + paintInfo->context->fillRect(gapRect, box->parent()->renderer()->selectionBackgroundColor(), box->parent()->renderer()->style()->colorSpace()); + // VisibleSelection may be non-contiguous, see comment above. + result.uniteCenter(gapRect); + } + lastLogicalLeft = box->logicalRight(); } if (box == lastBox) break; @@ -348,18 +352,18 @@ InlineBox* RootInlineBox::lastSelectedBox() int RootInlineBox::selectionTop() const { int selectionTop = m_lineTop; - if (!prevRootBox()) + if (renderer()->style()->isFlippedLinesWritingMode()) return selectionTop; - int prevBottom = prevRootBox()->selectionBottom(); + int prevBottom = prevRootBox() ? prevRootBox()->selectionBottom() : block()->borderBefore() + block()->paddingBefore(); if (prevBottom < selectionTop && block()->containsFloats()) { // This line has actually been moved further down, probably from a large line-height, but possibly because the // line was forced to clear floats. If so, let's check the offsets, and only be willing to use the previous - // line's bottom overflow if the offsets are greater on both sides. - int prevLeft = block()->logicalLeftOffsetForLine(prevBottom, !prevRootBox()); - int prevRight = block()->logicalRightOffsetForLine(prevBottom, !prevRootBox()); - int newLeft = block()->logicalLeftOffsetForLine(selectionTop, !prevRootBox()); - int newRight = block()->logicalRightOffsetForLine(selectionTop, !prevRootBox()); + // line's bottom if the offsets are greater on both sides. + int prevLeft = block()->logicalLeftOffsetForLine(prevBottom, false); + int prevRight = block()->logicalRightOffsetForLine(prevBottom, false); + int newLeft = block()->logicalLeftOffsetForLine(selectionTop, false); + int newRight = block()->logicalRightOffsetForLine(selectionTop, false); if (prevLeft > newLeft || prevRight < newRight) return selectionTop; } @@ -367,6 +371,28 @@ int RootInlineBox::selectionTop() const return prevBottom; } +int RootInlineBox::selectionBottom() const +{ + int selectionBottom = m_lineBottom; + if (!renderer()->style()->isFlippedLinesWritingMode() || !nextRootBox()) + return selectionBottom; + + int nextTop = nextRootBox()->selectionTop(); + if (nextTop > selectionBottom && block()->containsFloats()) { + // The next line has actually been moved further over, probably from a large line-height, but possibly because the + // line was forced to clear floats. If so, let's check the offsets, and only be willing to use the next + // line's top if the offsets are greater on both sides. + int nextLeft = block()->logicalLeftOffsetForLine(nextTop, false); + int nextRight = block()->logicalRightOffsetForLine(nextTop, false); + int newLeft = block()->logicalLeftOffsetForLine(selectionBottom, false); + int newRight = block()->logicalRightOffsetForLine(selectionBottom, false); + if (nextLeft > newLeft || nextRight < newRight) + return selectionBottom; + } + + return nextTop; +} + RenderBlock* RootInlineBox::block() const { return toRenderBlock(renderer()); diff --git a/WebCore/rendering/RootInlineBox.h b/WebCore/rendering/RootInlineBox.h index 4a0b485..f13d00f 100644 --- a/WebCore/rendering/RootInlineBox.h +++ b/WebCore/rendering/RootInlineBox.h @@ -54,7 +54,7 @@ public: void setPaginationStrut(int s) { m_paginationStrut = s; } int selectionTop() const; - int selectionBottom() const { return lineBottom(); } + int selectionBottom() const; int selectionHeight() const { return max(0, selectionBottom() - selectionTop()); } int alignBoxesInBlockDirection(int heightOfBlock, GlyphOverflowAndFallbackFontsMap&); @@ -88,8 +88,8 @@ public: virtual void clearTruncation(); - virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOfInteriorLineBoxes); } - virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, m_isVertical ? VerticalLine : HorizontalLine, PositionOfInteriorLineBoxes); } + virtual int baselinePosition() const { return boxModelObject()->baselinePosition(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); } + virtual int lineHeight() const { return boxModelObject()->lineHeight(m_firstLine, isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); } #if PLATFORM(MAC) void addHighlightOverflow(); @@ -106,8 +106,7 @@ public: InlineBox* firstSelectedBox(); InlineBox* lastSelectedBox(); - GapRects fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY, - int tx, int ty, const PaintInfo*); + GapRects lineSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, int selTop, int selHeight, const PaintInfo*); RenderBlock* block() const; diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp index b7f7f95..b9a854d 100644 --- a/WebCore/rendering/SVGRenderTreeAsText.cpp +++ b/WebCore/rendering/SVGRenderTreeAsText.cpp @@ -411,7 +411,7 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGPath& path) writeNameValuePair(ts, "r", element->r().value(element)); } else if (svgElement->hasTagName(SVGNames::polygonTag) || svgElement->hasTagName(SVGNames::polylineTag)) { SVGPolyElement* element = static_cast<SVGPolyElement*>(svgElement); - writeNameAndQuotedValue(ts, "points", element->points()->valueAsString()); + writeNameAndQuotedValue(ts, "points", element->pointList().valueAsString()); } else if (svgElement->hasTagName(SVGNames::pathTag)) { SVGPathElement* element = static_cast<SVGPathElement*>(svgElement); String pathString; diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp index f9641f4..6495d04 100644 --- a/WebCore/rendering/TextControlInnerElements.cpp +++ b/WebCore/rendering/TextControlInnerElements.cpp @@ -124,6 +124,11 @@ void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<Render parent->renderer()->addChild(renderer); } +bool TextControlInnerElement::isSpellCheckingEnabled() const +{ + return m_shadowParent && m_shadowParent->isSpellCheckingEnabled(); +} + // ---------------------------- inline TextControlInnerTextElement::TextControlInnerTextElement(Document* document, HTMLElement* shadowParent) @@ -142,7 +147,11 @@ void TextControlInnerTextElement::defaultEventHandler(Event* event) // Then we would add one to the text field's inner div, and we wouldn't need this subclass. // Or possibly we could just use a normal event listener. if (event->isBeforeTextInsertedEvent() || event->type() == eventNames().webkitEditableContentChangedEvent) { - if (Node* shadowAncestor = shadowAncestorNode()) + Node* shadowAncestor = shadowAncestorNode(); + // A TextControlInnerTextElement can be its own shadow ancestor if its been detached, but kept alive by an EditCommand. + // In this case, an undo/redo can cause events to be sent to the TextControlInnerTextElement. + // To prevent an infinite loop, we must check for this case before sending the event up the chain. + if (shadowAncestor && shadowAncestor != this) shadowAncestor->defaultEventHandler(event); } if (event->defaultHandled()) diff --git a/WebCore/rendering/TextControlInnerElements.h b/WebCore/rendering/TextControlInnerElements.h index 46c1c8e..61c9dba 100644 --- a/WebCore/rendering/TextControlInnerElements.h +++ b/WebCore/rendering/TextControlInnerElements.h @@ -49,6 +49,7 @@ private: virtual bool isMouseFocusable() const { return false; } virtual bool isShadowNode() const { return m_shadowParent; } virtual ContainerNode* shadowParentNode() { return m_shadowParent; } + virtual bool isSpellCheckingEnabled() const; void setShadowParentNode(HTMLElement* shadowParent) { m_shadowParent = shadowParent; } HTMLElement* m_shadowParent; diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp index ec77367..a6e7d59 100644 --- a/WebCore/rendering/style/RenderStyle.cpp +++ b/WebCore/rendering/style/RenderStyle.cpp @@ -463,6 +463,10 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon if (inherited_flags.m_writingMode != other->inherited_flags.m_writingMode) return StyleDifferenceLayout; + // Check text combine mode. + if (rareNonInheritedData->m_textCombine != other->rareNonInheritedData->m_textCombine) + return StyleDifferenceLayout; + // Overflow returns a layout hint. if (noninherited_flags._overflowX != other->noninherited_flags._overflowX || noninherited_flags._overflowY != other->noninherited_flags._overflowY) @@ -1144,6 +1148,52 @@ Length RenderStyle::logicalMaxHeight() const return maxWidth(); } +const BorderValue& RenderStyle::borderBefore() const +{ + switch (writingMode()) { + case TopToBottomWritingMode: + return borderTop(); + case BottomToTopWritingMode: + return borderBottom(); + case LeftToRightWritingMode: + return borderLeft(); + case RightToLeftWritingMode: + return borderRight(); + } + ASSERT_NOT_REACHED(); + return borderTop(); +} + +const BorderValue& RenderStyle::borderAfter() const +{ + switch (writingMode()) { + case TopToBottomWritingMode: + return borderBottom(); + case BottomToTopWritingMode: + return borderTop(); + case LeftToRightWritingMode: + return borderRight(); + case RightToLeftWritingMode: + return borderLeft(); + } + ASSERT_NOT_REACHED(); + return borderBottom(); +} + +const BorderValue& RenderStyle::borderStart() const +{ + if (isHorizontalWritingMode()) + return isLeftToRightDirection() ? borderLeft() : borderRight(); + return isLeftToRightDirection() ? borderTop() : borderBottom(); +} + +const BorderValue& RenderStyle::borderEnd() const +{ + if (isHorizontalWritingMode()) + return isLeftToRightDirection() ? borderRight() : borderLeft(); + return isLeftToRightDirection() ? borderBottom() : borderTop(); +} + unsigned short RenderStyle::borderBeforeWidth() const { switch (writingMode()) { diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h index f14e8f5..75dc58f 100644 --- a/WebCore/rendering/style/RenderStyle.h +++ b/WebCore/rendering/style/RenderStyle.h @@ -109,6 +109,7 @@ typedef Vector<RefPtr<RenderStyle>, 4> PseudoStyleCache; class RenderStyle: public RefCounted<RenderStyle> { friend class AnimationBase; // Used by CSS animations. We can't allow them to animate based off visited colors. friend class ApplyStyleCommand; // Editing has to only reveal unvisited info. + friend class EditingStyle; // Editing has to only reveal unvisited info. friend class CSSStyleSelector; // Sets members directly. friend class CSSComputedStyleDeclaration; // Ignores visited styles, so needs to be able to see unvisited info. friend class PropertyWrapperMaybeInvalidColor; // Used by CSS animations. We can't allow them to animate based off visited colors. @@ -404,6 +405,11 @@ public: const BorderValue& borderTop() const { return surround->border.top(); } const BorderValue& borderBottom() const { return surround->border.bottom(); } + const BorderValue& borderBefore() const; + const BorderValue& borderAfter() const; + const BorderValue& borderStart() const; + const BorderValue& borderEnd() const; + const NinePieceImage& borderImage() const { return surround->border.image(); } const LengthSize& borderTopLeftRadius() const { return surround->border.topLeft(); } @@ -717,6 +723,8 @@ public: void setPageScaleTransform(float); bool hasMask() const { return rareNonInheritedData->m_mask.hasImage() || rareNonInheritedData->m_maskBoxImage.hasImage(); } + + TextCombine textCombine() const { return static_cast<TextCombine>(rareNonInheritedData->m_textCombine); } // End CSS3 Getters // Apple-specific property getter methods @@ -1069,6 +1077,7 @@ public: void setTransformOriginY(Length l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_y, l); } void setTransformOriginZ(float f) { SET_VAR(rareNonInheritedData.access()->m_transform, m_z, f); } void setSpeak(ESpeak s) { SET_VAR(rareInheritedData, speak, s); } + void setTextCombine(TextCombine v) { SET_VAR(rareNonInheritedData, m_textCombine, v); } // End CSS3 Setters // Apple-specific property setters @@ -1213,6 +1222,7 @@ public: static EClear initialClear() { return CNONE; } static TextDirection initialDirection() { return LTR; } static WritingMode initialWritingMode() { return TopToBottomWritingMode; } + static TextCombine initialTextCombine() { return TextCombineNone; } static EDisplay initialDisplay() { return INLINE; } static EEmptyCell initialEmptyCells() { return SHOW; } static EFloat initialFloating() { return FNONE; } @@ -1360,8 +1370,12 @@ inline int adjustForAbsoluteZoom(int value, const RenderStyle* style) if (zoomFactor == 1) return value; // Needed because computeLengthInt truncates (rather than rounds) when scaling up. - if (zoomFactor > 1) - value++; + if (zoomFactor > 1) { + if (value < 0) + value--; + else + value++; + } return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(value / zoomFactor); } diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h index 0112c03..b8e2079 100644 --- a/WebCore/rendering/style/RenderStyleConstants.h +++ b/WebCore/rendering/style/RenderStyleConstants.h @@ -133,6 +133,10 @@ enum WritingMode { TopToBottomWritingMode, RightToLeftWritingMode, LeftToRightWritingMode, BottomToTopWritingMode }; +enum TextCombine { + TextCombineNone, TextCombineCluster, TextCombineUpright +}; + enum EFillAttachment { ScrollBackgroundAttachment, LocalBackgroundAttachment, FixedBackgroundAttachment }; diff --git a/WebCore/rendering/style/SVGRenderStyle.h b/WebCore/rendering/style/SVGRenderStyle.h index 8f0be39..7f032e7 100644 --- a/WebCore/rendering/style/SVGRenderStyle.h +++ b/WebCore/rendering/style/SVGRenderStyle.h @@ -92,28 +92,36 @@ public: static SVGLength initialBaselineShiftValue() { SVGLength length; - length.newValueSpecifiedUnits(LengthTypeNumber, 0); + ExceptionCode ec = 0; + length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec); + ASSERT(!ec); return length; } static SVGLength initialKerning() { SVGLength length; - length.newValueSpecifiedUnits(LengthTypeNumber, 0); + ExceptionCode ec = 0; + length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec); + ASSERT(!ec); return length; } static SVGLength initialStrokeDashOffset() { SVGLength length; - length.newValueSpecifiedUnits(LengthTypeNumber, 0); + ExceptionCode ec = 0; + length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec); + ASSERT(!ec); return length; } static SVGLength initialStrokeWidth() { SVGLength length; - length.newValueSpecifiedUnits(LengthTypeNumber, 1); + ExceptionCode ec = 0; + length.newValueSpecifiedUnits(LengthTypeNumber, 1, ec); + ASSERT(!ec); return length; } diff --git a/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/WebCore/rendering/style/StyleRareNonInheritedData.cpp index e0f7f7a..42cf966 100644 --- a/WebCore/rendering/style/StyleRareNonInheritedData.cpp +++ b/WebCore/rendering/style/StyleRareNonInheritedData.cpp @@ -42,6 +42,7 @@ StyleRareNonInheritedData::StyleRareNonInheritedData() , matchNearestMailBlockquoteColor(RenderStyle::initialMatchNearestMailBlockquoteColor()) , m_appearance(RenderStyle::initialAppearance()) , m_borderFit(RenderStyle::initialBorderFit()) + , m_textCombine(RenderStyle::initialTextCombine()) , m_counterIncrement(0) , m_counterReset(0) #if USE(ACCELERATED_COMPOSITING) @@ -78,6 +79,7 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited , matchNearestMailBlockquoteColor(o.matchNearestMailBlockquoteColor) , m_appearance(o.m_appearance) , m_borderFit(o.m_borderFit) + , m_textCombine(o.m_textCombine) , m_counterIncrement(o.m_counterIncrement) , m_counterReset(o.m_counterReset) #if USE(ACCELERATED_COMPOSITING) @@ -123,6 +125,7 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c && matchNearestMailBlockquoteColor == o.matchNearestMailBlockquoteColor && m_appearance == o.m_appearance && m_borderFit == o.m_borderFit + && m_textCombine == o.m_textCombine && m_counterIncrement == o.m_counterIncrement && m_counterReset == o.m_counterReset #if USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/rendering/style/StyleRareNonInheritedData.h b/WebCore/rendering/style/StyleRareNonInheritedData.h index 3f693f9..a53eee7 100644 --- a/WebCore/rendering/style/StyleRareNonInheritedData.h +++ b/WebCore/rendering/style/StyleRareNonInheritedData.h @@ -103,6 +103,7 @@ public: unsigned matchNearestMailBlockquoteColor : 1; // EMatchNearestMailBlockquoteColor, FIXME: This property needs to be eliminated. It should never have been added. unsigned m_appearance : 6; // EAppearance unsigned m_borderFit : 1; // EBorderFit + unsigned m_textCombine : 2; // CSS3 text-combine properties short m_counterIncrement; short m_counterReset; diff --git a/WebCore/rendering/svg/SVGInlineTextBox.cpp b/WebCore/rendering/svg/SVGInlineTextBox.cpp index 7dd779a..699d788 100644 --- a/WebCore/rendering/svg/SVGInlineTextBox.cpp +++ b/WebCore/rendering/svg/SVGInlineTextBox.cpp @@ -523,7 +523,7 @@ void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl FloatSize extraOffset; if (shadow) - extraOffset = applyShadowToGraphicsContext(context, shadow, shadowRect, false /* stroked */, true /* opaque */, false /* vertical */); + extraOffset = applyShadowToGraphicsContext(context, shadow, shadowRect, false /* stroked */, true /* opaque */, true /* horizontal */); font.drawText(context, textRun, textOrigin + extraOffset, startPosition, endPosition); restoreGraphicsContextAfterTextPainting(context, textRun); diff --git a/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp b/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp index 2474a5c..3122912 100644 --- a/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp +++ b/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp @@ -72,21 +72,15 @@ static inline void extractFloatValuesFromSVGLengthList(SVGElement* lengthContext } } -static inline void extractFloatValuesFromSVGNumberList(SVGNumberList* list, Vector<float>& floatValues, unsigned textContentLength) +static inline void extractFloatValuesFromSVGNumberList(const SVGNumberList& list, Vector<float>& floatValues, unsigned textContentLength) { - ASSERT(list); - - unsigned length = list->numberOfItems(); + unsigned length = list.size(); if (length > textContentLength) length = textContentLength; floatValues.reserveCapacity(length); - ExceptionCode ec = 0; - for (unsigned i = 0; i < length; ++i) { - float length = list->getItem(i, ec); - ASSERT(!ec); - floatValues.append(length); - } + for (unsigned i = 0; i < length; ++i) + floatValues.append(list.at(i)); } void SVGTextLayoutAttributesBuilder::buildLayoutScope(LayoutScope& scope, RenderObject* renderer, unsigned textContentStart, unsigned textContentLength) const diff --git a/WebCore/storage/IDBCursorBackendImpl.cpp b/WebCore/storage/IDBCursorBackendImpl.cpp index 40b46c6..8d5c8a1 100644 --- a/WebCore/storage/IDBCursorBackendImpl.cpp +++ b/WebCore/storage/IDBCursorBackendImpl.cpp @@ -37,6 +37,7 @@ #include "IDBKeyRange.h" #include "IDBObjectStoreBackendImpl.h" #include "IDBRequest.h" +#include "IDBSQLiteDatabase.h" #include "IDBTransactionBackendInterface.h" #include "SQLiteDatabase.h" #include "SQLiteStatement.h" @@ -44,19 +45,8 @@ namespace WebCore { -IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBObjectStoreBackendImpl> idbObjectStore, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, IDBTransactionBackendInterface* transaction) - : m_idbObjectStore(idbObjectStore) - , m_keyRange(keyRange) - , m_direction(direction) - , m_query(query) - , m_isSerializedScriptValueCursor(true) - , m_transaction(transaction) -{ - loadCurrentRow(); -} - -IDBCursorBackendImpl::IDBCursorBackendImpl(PassRefPtr<IDBIndexBackendImpl> idbIndex, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface* transaction) - : m_idbIndex(idbIndex) +IDBCursorBackendImpl::IDBCursorBackendImpl(IDBSQLiteDatabase* database, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface* transaction) + : m_database(database) , m_keyRange(keyRange) , m_direction(direction) , m_query(query) @@ -113,7 +103,7 @@ void IDBCursorBackendImpl::updateInternal(ScriptExecutionContext*, PassRefPtr<ID } String sql = "UPDATE ObjectStoreData SET value = ? WHERE id = ?"; - SQLiteStatement updateQuery(cursor->database()->sqliteDatabase(), sql); + SQLiteStatement updateQuery(cursor->database(), sql); bool ok = updateQuery.prepare() == SQLResultOk; ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. @@ -189,7 +179,7 @@ void IDBCursorBackendImpl::removeInternal(ScriptExecutionContext*, PassRefPtr<ID } String sql = "DELETE FROM ObjectStoreData WHERE id = ?"; - SQLiteStatement deleteQuery(cursor->database()->sqliteDatabase(), sql); + SQLiteStatement deleteQuery(cursor->database(), sql); bool ok = deleteQuery.prepare() == SQLResultOk; ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. @@ -214,11 +204,9 @@ void IDBCursorBackendImpl::loadCurrentRow() m_currentIDBKeyValue = IDBKey::fromQuery(*m_query, 4); } -IDBDatabaseBackendImpl* IDBCursorBackendImpl::database() const +SQLiteDatabase& IDBCursorBackendImpl::database() const { - if (m_idbObjectStore) - return m_idbObjectStore->database(); - return m_idbIndex->objectStore()->database(); + return m_database->db(); } } // namespace WebCore diff --git a/WebCore/storage/IDBCursorBackendImpl.h b/WebCore/storage/IDBCursorBackendImpl.h index 5dd45f2..b646f1c 100644 --- a/WebCore/storage/IDBCursorBackendImpl.h +++ b/WebCore/storage/IDBCursorBackendImpl.h @@ -41,19 +41,17 @@ class IDBDatabaseBackendImpl; class IDBIndexBackendImpl; class IDBKeyRange; class IDBObjectStoreBackendImpl; +class IDBSQLiteDatabase; class IDBTransactionBackendInterface; +class SQLiteDatabase; class SQLiteStatement; class SerializedScriptValue; class IDBCursorBackendImpl : public IDBCursorBackendInterface { public: - static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, IDBTransactionBackendInterface* transaction) + static PassRefPtr<IDBCursorBackendImpl> create(IDBSQLiteDatabase* database, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface* transaction) { - return adoptRef(new IDBCursorBackendImpl(objectStore, keyRange, direction, query, transaction)); - } - static PassRefPtr<IDBCursorBackendImpl> create(PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, IDBCursor::Direction direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface* transaction) - { - return adoptRef(new IDBCursorBackendImpl(index, keyRange, direction, query, isSerializedScriptValueCursor, transaction)); + return adoptRef(new IDBCursorBackendImpl(database, keyRange, direction, query, isSerializedScriptValueCursor, transaction)); } virtual ~IDBCursorBackendImpl(); @@ -65,11 +63,10 @@ public: virtual void remove(PassRefPtr<IDBCallbacks>, ExceptionCode&); private: - IDBCursorBackendImpl(PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassOwnPtr<SQLiteStatement> query, IDBTransactionBackendInterface*); - IDBCursorBackendImpl(PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface*); + IDBCursorBackendImpl(IDBSQLiteDatabase*, PassRefPtr<IDBKeyRange>, IDBCursor::Direction, PassOwnPtr<SQLiteStatement> query, bool isSerializedScriptValueCursor, IDBTransactionBackendInterface*); void loadCurrentRow(); - IDBDatabaseBackendImpl* database() const; + SQLiteDatabase& database() const; static void updateInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl>, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBCallbacks>); static void continueFunctionInternal(ScriptExecutionContext*, PassRefPtr<IDBCursorBackendImpl>, PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>); @@ -77,9 +74,7 @@ private: static const int64_t InvalidId = -1; - // Only one or the other should be used. - RefPtr<IDBObjectStoreBackendImpl> m_idbObjectStore; - RefPtr<IDBIndexBackendImpl> m_idbIndex; + RefPtr<IDBSQLiteDatabase> m_database; RefPtr<IDBKeyRange> m_keyRange; IDBCursor::Direction m_direction; diff --git a/WebCore/storage/IDBDatabaseBackendImpl.cpp b/WebCore/storage/IDBDatabaseBackendImpl.cpp index 020ddb9..004dc7b 100644 --- a/WebCore/storage/IDBDatabaseBackendImpl.cpp +++ b/WebCore/storage/IDBDatabaseBackendImpl.cpp @@ -31,9 +31,10 @@ #include "CrossThreadTask.h" #include "DOMStringList.h" #include "IDBDatabaseException.h" +#include "IDBFactoryBackendImpl.h" #include "IDBObjectStoreBackendImpl.h" #include "IDBSQLiteDatabase.h" -#include "IDBTransactionBackendInterface.h" +#include "IDBTransactionBackendImpl.h" #include "IDBTransactionCoordinator.h" #include "SQLiteStatement.h" #include "SQLiteTransaction.h" @@ -88,12 +89,14 @@ static bool setMetaData(SQLiteDatabase& sqliteDatabase, const String& name, cons return true; } -IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& description, IDBSQLiteDatabase* sqliteDatabase, IDBTransactionCoordinator* coordinator) +IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& description, IDBSQLiteDatabase* sqliteDatabase, IDBTransactionCoordinator* coordinator, IDBFactoryBackendImpl* factory, const String& uniqueIdentifier) : m_sqliteDatabase(sqliteDatabase) , m_id(InvalidId) , m_name(name) , m_description(description) , m_version("") + , m_identifier(uniqueIdentifier) + , m_factory(factory) , m_transactionCoordinator(coordinator) { ASSERT(!m_name.isNull()); @@ -108,6 +111,7 @@ IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& IDBDatabaseBackendImpl::~IDBDatabaseBackendImpl() { + m_factory->removeIDBDatabaseBackend(m_identifier); } void IDBDatabaseBackendImpl::setDescription(const String& description) @@ -139,7 +143,7 @@ PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::createObject return 0; } - RefPtr<IDBObjectStoreBackendImpl> objectStore = IDBObjectStoreBackendImpl::create(this, name, keyPath, autoIncrement); + RefPtr<IDBObjectStoreBackendImpl> objectStore = IDBObjectStoreBackendImpl::create(m_sqliteDatabase.get(), name, keyPath, autoIncrement); ASSERT(objectStore->name() == name); RefPtr<IDBDatabaseBackendImpl> database = this; @@ -220,7 +224,7 @@ void IDBDatabaseBackendImpl::setVersion(const String& version, PassRefPtr<IDBCal RefPtr<IDBDatabaseBackendImpl> database = this; RefPtr<IDBCallbacks> callbacks = prpCallbacks; RefPtr<DOMStringList> objectStores = DOMStringList::create(); - RefPtr<IDBTransactionBackendInterface> transaction = m_transactionCoordinator->createTransaction(objectStores.get(), IDBTransaction::VERSION_CHANGE, 0, this); + RefPtr<IDBTransactionBackendInterface> transaction = IDBTransactionBackendImpl::create(objectStores.get(), IDBTransaction::VERSION_CHANGE, 0, this); if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::setVersionInternal, database, version, callbacks, transaction), createCallbackTask(&IDBDatabaseBackendImpl::resetVersion, database, m_version))) { ec = IDBDatabaseException::NOT_ALLOWED_ERR; @@ -243,7 +247,7 @@ void IDBDatabaseBackendImpl::setVersionInternal(ScriptExecutionContext*, PassRef PassRefPtr<IDBTransactionBackendInterface> IDBDatabaseBackendImpl::transaction(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, ExceptionCode&) { // FIXME: Return not allowed err if close has been called. - return m_transactionCoordinator->createTransaction(objectStores, mode, timeout, this); + return IDBTransactionBackendImpl::create(objectStores, mode, timeout, this); } void IDBDatabaseBackendImpl::close() @@ -265,7 +269,7 @@ void IDBDatabaseBackendImpl::loadObjectStores() String keyPath = objectStoresQuery.getColumnText(2); bool autoIncrement = !!objectStoresQuery.getColumnInt(3); - m_objectStores.set(name, IDBObjectStoreBackendImpl::create(this, id, name, keyPath, autoIncrement)); + m_objectStores.set(name, IDBObjectStoreBackendImpl::create(m_sqliteDatabase.get(), id, name, keyPath, autoIncrement)); } } diff --git a/WebCore/storage/IDBDatabaseBackendImpl.h b/WebCore/storage/IDBDatabaseBackendImpl.h index 53e1a5f..8c97a70 100644 --- a/WebCore/storage/IDBDatabaseBackendImpl.h +++ b/WebCore/storage/IDBDatabaseBackendImpl.h @@ -35,6 +35,7 @@ namespace WebCore { +class IDBFactoryBackendImpl; class IDBObjectStoreBackendImpl; class IDBSQLiteDatabase; class IDBTransactionCoordinator; @@ -42,9 +43,9 @@ class SQLiteDatabase; class IDBDatabaseBackendImpl : public IDBDatabaseBackendInterface { public: - static PassRefPtr<IDBDatabaseBackendImpl> create(const String& name, const String& description, IDBSQLiteDatabase* database, IDBTransactionCoordinator* coordinator) + static PassRefPtr<IDBDatabaseBackendImpl> create(const String& name, const String& description, IDBSQLiteDatabase* database, IDBTransactionCoordinator* coordinator, IDBFactoryBackendImpl* factory, const String& uniqueIdentifier) { - return adoptRef(new IDBDatabaseBackendImpl(name, description, database, coordinator)); + return adoptRef(new IDBDatabaseBackendImpl(name, description, database, coordinator, factory, uniqueIdentifier)); } virtual ~IDBDatabaseBackendImpl(); @@ -69,7 +70,7 @@ public: IDBTransactionCoordinator* transactionCoordinator() const { return m_transactionCoordinator.get(); } private: - IDBDatabaseBackendImpl(const String& name, const String& description, IDBSQLiteDatabase* database, IDBTransactionCoordinator*); + IDBDatabaseBackendImpl(const String& name, const String& description, IDBSQLiteDatabase* database, IDBTransactionCoordinator*, IDBFactoryBackendImpl*, const String& uniqueIdentifier); void loadObjectStores(); @@ -88,6 +89,10 @@ private: String m_description; String m_version; + String m_identifier; + // This might not need to be a RefPtr since the factory's lifetime is that of the page group, but it's better to be conservitive than sorry. + RefPtr<IDBFactoryBackendImpl> m_factory; + typedef HashMap<String, RefPtr<IDBObjectStoreBackendImpl> > ObjectStoreMap; ObjectStoreMap m_objectStores; diff --git a/WebCore/storage/IDBFactoryBackendImpl.cpp b/WebCore/storage/IDBFactoryBackendImpl.cpp index 1905c0c..e4d0ee8 100644 --- a/WebCore/storage/IDBFactoryBackendImpl.cpp +++ b/WebCore/storage/IDBFactoryBackendImpl.cpp @@ -52,10 +52,16 @@ IDBFactoryBackendImpl::~IDBFactoryBackendImpl() { } -void IDBFactoryBackendImpl::removeSQLiteDatabase(const String& filePath) +void IDBFactoryBackendImpl::removeIDBDatabaseBackend(const String& uniqueIdentifier) { - ASSERT(m_sqliteDatabaseMap.contains(filePath)); - m_sqliteDatabaseMap.remove(filePath); + ASSERT(m_databaseBackendMap.contains(uniqueIdentifier)); + m_databaseBackendMap.remove(uniqueIdentifier); +} + +void IDBFactoryBackendImpl::removeSQLiteDatabase(const String& uniqueIdentifier) +{ + ASSERT(m_sqliteDatabaseMap.contains(uniqueIdentifier)); + m_sqliteDatabaseMap.remove(uniqueIdentifier); } static PassRefPtr<IDBSQLiteDatabase> openSQLiteDatabase(SecurityOrigin* securityOrigin, const String& pathBase, int64_t maximumSize, const String& fileIdentifier, IDBFactoryBackendImpl* factory) @@ -124,7 +130,7 @@ void IDBFactoryBackendImpl::open(const String& name, const String& description, if (it != m_databaseBackendMap.end()) { if (!description.isNull()) it->second->setDescription(description); // The description may have changed. - callbacks->onSuccess(it->second.get()); + callbacks->onSuccess(it->second); return; } @@ -144,9 +150,9 @@ void IDBFactoryBackendImpl::open(const String& name, const String& description, m_sqliteDatabaseMap.set(fileIdentifier, sqliteDatabase.get()); } - RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, description, sqliteDatabase.get(), m_transactionCoordinator.get()); + RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, description, sqliteDatabase.get(), m_transactionCoordinator.get(), this, uniqueIdentifier); callbacks->onSuccess(databaseBackend.get()); - m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.release()); + m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get()); } String IDBFactoryBackendImpl::databaseFileName(SecurityOrigin* securityOrigin) diff --git a/WebCore/storage/IDBFactoryBackendImpl.h b/WebCore/storage/IDBFactoryBackendImpl.h index 381c402..d618fe2 100644 --- a/WebCore/storage/IDBFactoryBackendImpl.h +++ b/WebCore/storage/IDBFactoryBackendImpl.h @@ -50,8 +50,9 @@ public: } virtual ~IDBFactoryBackendImpl(); - // IDBSQLiteDatabase's lifetime may be shorter than ours, so we need notification when it dies. - void removeSQLiteDatabase(const String& filePath); + // Notifications from weak pointers. + void removeIDBDatabaseBackend(const String& uniqueIdentifier); + void removeSQLiteDatabase(const String& uniqueIdentifier); virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*, const String& dataDir, int64_t maximumSize); @@ -60,8 +61,7 @@ public: private: IDBFactoryBackendImpl(); - // FIXME: Just hold a weak pointer. - typedef HashMap<String, RefPtr<IDBDatabaseBackendImpl> > IDBDatabaseBackendMap; + typedef HashMap<String, IDBDatabaseBackendImpl*> IDBDatabaseBackendMap; IDBDatabaseBackendMap m_databaseBackendMap; typedef HashMap<String, IDBSQLiteDatabase*> SQLiteDatabaseMap; diff --git a/WebCore/storage/IDBIndexBackendImpl.cpp b/WebCore/storage/IDBIndexBackendImpl.cpp index 2a991fa..84af234 100644 --- a/WebCore/storage/IDBIndexBackendImpl.cpp +++ b/WebCore/storage/IDBIndexBackendImpl.cpp @@ -36,24 +36,27 @@ #include "IDBKey.h" #include "IDBKeyRange.h" #include "IDBObjectStoreBackendImpl.h" +#include "IDBSQLiteDatabase.h" #include "SQLiteDatabase.h" #include "SQLiteStatement.h" namespace WebCore { -IDBIndexBackendImpl::IDBIndexBackendImpl(IDBObjectStoreBackendImpl* objectStore, int64_t id, const String& name, const String& keyPath, bool unique) - : m_objectStore(objectStore) +IDBIndexBackendImpl::IDBIndexBackendImpl(IDBSQLiteDatabase* database, int64_t id, const String& name, const String& storeName, const String& keyPath, bool unique) + : m_database(database) , m_id(id) , m_name(name) + , m_storeName(storeName) , m_keyPath(keyPath) , m_unique(unique) { } -IDBIndexBackendImpl::IDBIndexBackendImpl(IDBObjectStoreBackendImpl* objectStore, const String& name, const String& keyPath, bool unique) - : m_objectStore(objectStore) +IDBIndexBackendImpl::IDBIndexBackendImpl(IDBSQLiteDatabase* database, const String& name, const String& storeName, const String& keyPath, bool unique) + : m_database(database) , m_id(InvalidId) , m_name(name) + , m_storeName(storeName) , m_keyPath(keyPath) , m_unique(unique) { @@ -63,11 +66,6 @@ IDBIndexBackendImpl::~IDBIndexBackendImpl() { } -String IDBIndexBackendImpl::storeName() -{ - return m_objectStore->name(); -} - void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, unsigned short untypedDirection, bool objectCursor, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) { // Several files depend on this order of selects. @@ -106,7 +104,7 @@ void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr return; } - RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(index, range, direction, query.release(), objectCursor, transaction.get()); + RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(index->m_database.get(), range, direction, query.release(), objectCursor, transaction.get()); callbacks->onSuccess(cursor.release()); } @@ -200,7 +198,7 @@ bool IDBIndexBackendImpl::addingKeyAllowed(IDBKey* key) SQLiteDatabase& IDBIndexBackendImpl::sqliteDatabase() const { - return m_objectStore->database()->sqliteDatabase(); + return m_database->db(); } } // namespace WebCore diff --git a/WebCore/storage/IDBIndexBackendImpl.h b/WebCore/storage/IDBIndexBackendImpl.h index d5e81ae..e640b5a 100644 --- a/WebCore/storage/IDBIndexBackendImpl.h +++ b/WebCore/storage/IDBIndexBackendImpl.h @@ -34,18 +34,19 @@ namespace WebCore { class IDBKey; class IDBObjectStoreBackendImpl; +class IDBSQLiteDatabase; class SQLiteDatabase; class ScriptExecutionContext; class IDBIndexBackendImpl : public IDBIndexBackendInterface { public: - static PassRefPtr<IDBIndexBackendImpl> create(IDBObjectStoreBackendImpl* objectStore, int64_t id, const String& name, const String& keyPath, bool unique) + static PassRefPtr<IDBIndexBackendImpl> create(IDBSQLiteDatabase* database, int64_t id, const String& name, const String& storeName, const String& keyPath, bool unique) { - return adoptRef(new IDBIndexBackendImpl(objectStore, id, name, keyPath, unique)); + return adoptRef(new IDBIndexBackendImpl(database, id, name, storeName, keyPath, unique)); } - static PassRefPtr<IDBIndexBackendImpl> create(IDBObjectStoreBackendImpl* objectStore, const String& name, const String& keyPath, bool unique) + static PassRefPtr<IDBIndexBackendImpl> create(IDBSQLiteDatabase* database, const String& name, const String& storeName, const String& keyPath, bool unique) { - return adoptRef(new IDBIndexBackendImpl(objectStore, name, keyPath, unique)); + return adoptRef(new IDBIndexBackendImpl(database, name, storeName, keyPath, unique)); } virtual ~IDBIndexBackendImpl(); @@ -60,7 +61,7 @@ public: // Implements IDBIndexBackendInterface. virtual String name() { return m_name; } - virtual String storeName(); + virtual String storeName() { return m_storeName; } virtual String keyPath() { return m_keyPath; } virtual bool unique() { return m_unique; } @@ -69,11 +70,9 @@ public: virtual void get(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&); virtual void getKey(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&); - IDBObjectStoreBackendImpl* objectStore() const { return m_objectStore.get(); } - private: - IDBIndexBackendImpl(IDBObjectStoreBackendImpl*, int64_t id, const String& name, const String& keyPath, bool unique); - IDBIndexBackendImpl(IDBObjectStoreBackendImpl*, const String& name, const String& keyPath, bool unique); + IDBIndexBackendImpl(IDBSQLiteDatabase*, int64_t id, const String& name, const String& storeName, const String& keyPath, bool unique); + IDBIndexBackendImpl(IDBSQLiteDatabase*, const String& name, const String& storeName, const String& keyPath, bool unique); SQLiteDatabase& sqliteDatabase() const; @@ -82,10 +81,11 @@ private: static const int64_t InvalidId = 0; - RefPtr<IDBObjectStoreBackendImpl> m_objectStore; + RefPtr<IDBSQLiteDatabase> m_database; int64_t m_id; String m_name; + String m_storeName; String m_keyPath; bool m_unique; }; diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.cpp b/WebCore/storage/IDBObjectStoreBackendImpl.cpp index 4892556..653fb4e 100644 --- a/WebCore/storage/IDBObjectStoreBackendImpl.cpp +++ b/WebCore/storage/IDBObjectStoreBackendImpl.cpp @@ -40,6 +40,7 @@ #include "IDBKeyPath.h" #include "IDBKeyPathBackendImpl.h" #include "IDBKeyRange.h" +#include "IDBSQLiteDatabase.h" #include "IDBTransactionBackendInterface.h" #include "ScriptExecutionContext.h" #include "SQLiteDatabase.h" @@ -52,7 +53,7 @@ IDBObjectStoreBackendImpl::~IDBObjectStoreBackendImpl() { } -IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBDatabaseBackendImpl* database, int64_t id, const String& name, const String& keyPath, bool autoIncrement) +IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBSQLiteDatabase* database, int64_t id, const String& name, const String& keyPath, bool autoIncrement) : m_database(database) , m_id(id) , m_name(name) @@ -62,7 +63,7 @@ IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBDatabaseBackendImpl* dat loadIndexes(); } -IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBDatabaseBackendImpl* database, const String& name, const String& keyPath, bool autoIncrement) +IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBSQLiteDatabase* database, const String& name, const String& keyPath, bool autoIncrement) : m_database(database) , m_id(InvalidId) , m_name(name) @@ -301,7 +302,7 @@ PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(cons return 0; } - RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(this, name, keyPath, unique); + RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(m_database.get(), name, m_name, keyPath, unique); ASSERT(index->name() == name); RefPtr<IDBObjectStoreBackendImpl> objectStore = this; @@ -427,7 +428,7 @@ void IDBObjectStoreBackendImpl::openCursorInternal(ScriptExecutionContext*, Pass return; } - RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(objectStore, range, direction, query.release(), transaction.get()); + RefPtr<IDBCursorBackendInterface> cursor = IDBCursorBackendImpl::create(objectStore->m_database.get(), range, direction, query.release(), true, transaction.get()); callbacks->onSuccess(cursor.release()); } @@ -445,13 +446,13 @@ void IDBObjectStoreBackendImpl::loadIndexes() String keyPath = indexQuery.getColumnText(2); bool unique = !!indexQuery.getColumnInt(3); - m_indexes.set(name, IDBIndexBackendImpl::create(this, id, name, keyPath, unique)); + m_indexes.set(name, IDBIndexBackendImpl::create(m_database.get(), id, name, m_name, keyPath, unique)); } } SQLiteDatabase& IDBObjectStoreBackendImpl::sqliteDatabase() const { - return m_database->sqliteDatabase(); + return m_database->db(); } void IDBObjectStoreBackendImpl::removeIndexFromMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBIndexBackendImpl> index) diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.h b/WebCore/storage/IDBObjectStoreBackendImpl.h index 60e011f..add849b 100644 --- a/WebCore/storage/IDBObjectStoreBackendImpl.h +++ b/WebCore/storage/IDBObjectStoreBackendImpl.h @@ -36,17 +36,18 @@ namespace WebCore { class IDBDatabaseBackendImpl; class IDBIndexBackendImpl; +class IDBSQLiteDatabase; class IDBTransactionBackendInterface; class SQLiteDatabase; class ScriptExecutionContext; class IDBObjectStoreBackendImpl : public IDBObjectStoreBackendInterface { public: - static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBDatabaseBackendImpl* database, int64_t id, const String& name, const String& keyPath, bool autoIncrement) + static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBSQLiteDatabase* database, int64_t id, const String& name, const String& keyPath, bool autoIncrement) { return adoptRef(new IDBObjectStoreBackendImpl(database, id, name, keyPath, autoIncrement)); } - static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBDatabaseBackendImpl* database, const String& name, const String& keyPath, bool autoIncrement) + static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBSQLiteDatabase* database, const String& name, const String& keyPath, bool autoIncrement) { return adoptRef(new IDBObjectStoreBackendImpl(database, name, keyPath, autoIncrement)); } @@ -75,11 +76,9 @@ public: virtual void openCursor(PassRefPtr<IDBKeyRange> range, unsigned short direction, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&); - IDBDatabaseBackendImpl* database() const { return m_database.get(); } - private: - IDBObjectStoreBackendImpl(IDBDatabaseBackendImpl*, int64_t id, const String& name, const String& keyPath, bool autoIncrement); - IDBObjectStoreBackendImpl(IDBDatabaseBackendImpl*, const String& name, const String& keyPath, bool autoIncrement); + IDBObjectStoreBackendImpl(IDBSQLiteDatabase*, int64_t id, const String& name, const String& keyPath, bool autoIncrement); + IDBObjectStoreBackendImpl(IDBSQLiteDatabase*, const String& name, const String& keyPath, bool autoIncrement); void loadIndexes(); SQLiteDatabase& sqliteDatabase() const; @@ -95,7 +94,7 @@ private: static void removeIndexFromMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>); static void addIndexToMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>); - RefPtr<IDBDatabaseBackendImpl> m_database; + RefPtr<IDBSQLiteDatabase> m_database; int64_t m_id; String m_name; diff --git a/WebCore/storage/IDBTransactionBackendImpl.cpp b/WebCore/storage/IDBTransactionBackendImpl.cpp index 2b1f732..e8d864d 100644 --- a/WebCore/storage/IDBTransactionBackendImpl.cpp +++ b/WebCore/storage/IDBTransactionBackendImpl.cpp @@ -34,16 +34,15 @@ namespace WebCore { -PassRefPtr<IDBTransactionBackendImpl> IDBTransactionBackendImpl::create(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl* database) +PassRefPtr<IDBTransactionBackendImpl> IDBTransactionBackendImpl::create(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, IDBDatabaseBackendImpl* database) { - return adoptRef(new IDBTransactionBackendImpl(objectStores, mode, timeout, id, database)); + return adoptRef(new IDBTransactionBackendImpl(objectStores, mode, timeout, database)); } -IDBTransactionBackendImpl::IDBTransactionBackendImpl(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl* database) +IDBTransactionBackendImpl::IDBTransactionBackendImpl(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, IDBDatabaseBackendImpl* database) : m_objectStoreNames(objectStores) , m_mode(mode) , m_timeout(timeout) // FIXME: Implement timeout. - , m_id(id) , m_state(Unused) , m_database(database) , m_transaction(new SQLiteTransaction(database->sqliteDatabase())) @@ -51,6 +50,13 @@ IDBTransactionBackendImpl::IDBTransactionBackendImpl(DOMStringList* objectStores , m_taskEventTimer(this, &IDBTransactionBackendImpl::taskEventTimerFired) , m_pendingEvents(0) { + m_database->transactionCoordinator()->didCreateTransaction(this); +} + +IDBTransactionBackendImpl::~IDBTransactionBackendImpl() +{ + // It shouldn't be possible for this object to get deleted until it's either complete or aborted. + ASSERT(m_state == Finished); } PassRefPtr<IDBObjectStoreBackendInterface> IDBTransactionBackendImpl::objectStore(const String& name) @@ -94,6 +100,8 @@ void IDBTransactionBackendImpl::abort() m_callbacks->onAbort(); m_database->transactionCoordinator()->didFinishTransaction(this); + ASSERT(!m_database->transactionCoordinator()->isActive(this)); + m_database = 0; } void IDBTransactionBackendImpl::didCompleteTaskEvents() @@ -133,6 +141,7 @@ void IDBTransactionBackendImpl::commit() m_transaction->commit(); m_callbacks->onComplete(); m_database->transactionCoordinator()->didFinishTransaction(this); + m_database = 0; } void IDBTransactionBackendImpl::taskTimerFired(Timer<IDBTransactionBackendImpl>*) diff --git a/WebCore/storage/IDBTransactionBackendImpl.h b/WebCore/storage/IDBTransactionBackendImpl.h index 5f7409b..88542f4 100644 --- a/WebCore/storage/IDBTransactionBackendImpl.h +++ b/WebCore/storage/IDBTransactionBackendImpl.h @@ -42,21 +42,20 @@ class IDBDatabaseBackendImpl; class IDBTransactionBackendImpl : public IDBTransactionBackendInterface { public: - static PassRefPtr<IDBTransactionBackendImpl> create(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl*); - virtual ~IDBTransactionBackendImpl() { abort(); } + static PassRefPtr<IDBTransactionBackendImpl> create(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, IDBDatabaseBackendImpl*); + virtual ~IDBTransactionBackendImpl(); virtual PassRefPtr<IDBObjectStoreBackendInterface> objectStore(const String& name); virtual unsigned short mode() const { return m_mode; } virtual bool scheduleTask(PassOwnPtr<ScriptExecutionContext::Task> task, PassOwnPtr<ScriptExecutionContext::Task> abortTask); virtual void didCompleteTaskEvents(); virtual void abort(); - virtual int id() const { return m_id; } virtual void setCallbacks(IDBTransactionCallbacks* callbacks) { m_callbacks = callbacks; } void run(); private: - IDBTransactionBackendImpl(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl*); + IDBTransactionBackendImpl(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, IDBDatabaseBackendImpl*); enum State { Unused, // Created, but no tasks yet. @@ -74,7 +73,6 @@ private: RefPtr<DOMStringList> m_objectStoreNames; unsigned short m_mode; unsigned long m_timeout; - int m_id; State m_state; RefPtr<IDBTransactionCallbacks> m_callbacks; diff --git a/WebCore/storage/IDBTransactionBackendInterface.h b/WebCore/storage/IDBTransactionBackendInterface.h index 65b097d..80135f0 100644 --- a/WebCore/storage/IDBTransactionBackendInterface.h +++ b/WebCore/storage/IDBTransactionBackendInterface.h @@ -53,7 +53,6 @@ public: virtual bool scheduleTask(PassOwnPtr<ScriptExecutionContext::Task> task, PassOwnPtr<ScriptExecutionContext::Task> abortTask = 0) = 0; virtual void didCompleteTaskEvents() = 0; virtual void abort() = 0; - virtual int id() const = 0; virtual void setCallbacks(IDBTransactionCallbacks*) = 0; }; diff --git a/WebCore/storage/IDBTransactionCoordinator.cpp b/WebCore/storage/IDBTransactionCoordinator.cpp index 0ece309..f867f42 100644 --- a/WebCore/storage/IDBTransactionCoordinator.cpp +++ b/WebCore/storage/IDBTransactionCoordinator.cpp @@ -36,8 +36,12 @@ namespace WebCore { +PassRefPtr<IDBTransactionCoordinator> IDBTransactionCoordinator::create() +{ + return adoptRef(new IDBTransactionCoordinator()); +} + IDBTransactionCoordinator::IDBTransactionCoordinator() - : m_nextID(0) { } @@ -45,16 +49,15 @@ IDBTransactionCoordinator::~IDBTransactionCoordinator() { } -PassRefPtr<IDBTransactionBackendInterface> IDBTransactionCoordinator::createTransaction(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, IDBDatabaseBackendImpl* database) +void IDBTransactionCoordinator::didCreateTransaction(IDBTransactionBackendImpl* transaction) { - RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::create(objectStores, mode, timeout, ++m_nextID, database); - m_transactions.add(m_nextID, transaction); - return transaction.release(); + ASSERT(!m_transactions.contains(transaction)); + m_transactions.add(transaction, transaction); } void IDBTransactionCoordinator::didStartTransaction(IDBTransactionBackendImpl* transaction) { - ASSERT(m_transactions.contains(transaction->id())); + ASSERT(m_transactions.contains(transaction)); m_startedTransactions.add(transaction); processStartedTransactions(); @@ -62,7 +65,7 @@ void IDBTransactionCoordinator::didStartTransaction(IDBTransactionBackendImpl* t void IDBTransactionCoordinator::didFinishTransaction(IDBTransactionBackendImpl* transaction) { - ASSERT(m_transactions.contains(transaction->id())); + ASSERT(m_transactions.contains(transaction)); if (m_startedTransactions.contains(transaction)) { ASSERT(!m_runningTransactions.contains(transaction)); @@ -70,16 +73,34 @@ void IDBTransactionCoordinator::didFinishTransaction(IDBTransactionBackendImpl* } else if (m_runningTransactions.contains(transaction)) m_runningTransactions.remove(transaction); - m_transactions.remove(transaction->id()); + m_transactions.remove(transaction); processStartedTransactions(); } +#ifndef NDEBUG +// Verifies internal consistiency while returning whether anything is found. +bool IDBTransactionCoordinator::isActive(IDBTransactionBackendImpl* transaction) +{ + bool found = false; + if (m_startedTransactions.contains(transaction)) + found = true; + if (m_runningTransactions.contains(transaction)) { + ASSERT(!found); + found = true; + } + ASSERT(found == m_transactions.contains(transaction)); + return found; +} +#endif + void IDBTransactionCoordinator::processStartedTransactions() { - // FIXME: This should allocate a thread to the next transaction that's - // ready to run. For now we only have a single running transaction. - if (m_startedTransactions.isEmpty() || !m_runningTransactions.isEmpty()) + // FIXME: For now, we only allow one transaction to run at a time. + if (!m_runningTransactions.isEmpty()) + return; + + if (m_startedTransactions.isEmpty()) return; IDBTransactionBackendImpl* transaction = *m_startedTransactions.begin(); diff --git a/WebCore/storage/IDBTransactionCoordinator.h b/WebCore/storage/IDBTransactionCoordinator.h index fddb003..ef99e73 100644 --- a/WebCore/storage/IDBTransactionCoordinator.h +++ b/WebCore/storage/IDBTransactionCoordinator.h @@ -39,39 +39,31 @@ class IDBTransactionBackendImpl; class IDBTransactionCallbacks; class IDBDatabaseBackendImpl; -// This class manages transactions as follows. Requests for new transactions are -// always satisfied and the new transaction is placed in a queue. -// Transactions are not actually started until the first operation is issued. -// Each transaction executes in a separate thread and is committed automatically -// when there are no more operations issued in its context. -// When starting, a transaction will attempt to lock all the object stores in its -// scope. If this does not happen within a given timeout, an exception is raised. -// The Coordinator maintains a pool of threads. If there are no threads available -// the next transaction in the queue will have to wait until a thread becomes -// available. // Transactions are executed in the order the were created. class IDBTransactionCoordinator : public RefCounted<IDBTransactionCoordinator> { public: - static PassRefPtr<IDBTransactionCoordinator> create() { return adoptRef(new IDBTransactionCoordinator()); } + static PassRefPtr<IDBTransactionCoordinator> create(); virtual ~IDBTransactionCoordinator(); - PassRefPtr<IDBTransactionBackendInterface> createTransaction(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, IDBDatabaseBackendImpl*); - // Called by transactions as they start and finish. + void didCreateTransaction(IDBTransactionBackendImpl*); void didStartTransaction(IDBTransactionBackendImpl*); void didFinishTransaction(IDBTransactionBackendImpl*); +#ifndef NDEBUG + bool isActive(IDBTransactionBackendImpl*); +#endif + private: IDBTransactionCoordinator(); void processStartedTransactions(); - // This map owns all transactions known to the coordinator. - HashMap<int, RefPtr<IDBTransactionBackendImpl> > m_transactions; + // This is just an efficient way to keep references to all transactions. + HashMap<IDBTransactionBackendImpl*, RefPtr<IDBTransactionBackendImpl> > m_transactions; // Transactions in different states are grouped below. ListHashSet<IDBTransactionBackendImpl*> m_startedTransactions; HashSet<IDBTransactionBackendImpl*> m_runningTransactions; - int m_nextID; }; } // namespace WebCore diff --git a/WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h b/WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h index ab23bae..e20a4c7 100644 --- a/WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h +++ b/WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h @@ -23,8 +23,6 @@ #if ENABLE(SVG) #include "PlatformString.h" -#include "SVGNumberList.h" -#include "SVGPreserveAspectRatio.h" #include "SVGTransformList.h" namespace WebCore { @@ -32,54 +30,6 @@ namespace WebCore { template<typename Type> struct DeprecatedSVGAnimatedPropertyTraits : public Noncopyable { }; -// SVGAnimatedNumber -template<> -struct DeprecatedSVGAnimatedPropertyTraits<float> : public Noncopyable { - typedef const float& PassType; - typedef float ReturnType; - typedef float StoredType; - - static ReturnType null() { return 0.0f; } - static ReturnType toReturnType(const StoredType& type) { return type; } - static String toString(PassType type) { return String::number(type); } -}; - -// SVGAnimatedNumberList -template<> -struct DeprecatedSVGAnimatedPropertyTraits<SVGNumberList*> : public Noncopyable { - typedef SVGNumberList* PassType; - typedef SVGNumberList* ReturnType; - typedef RefPtr<SVGNumberList> StoredType; - - static ReturnType null() { return 0; } - static ReturnType toReturnType(const StoredType& type) { return type.get(); } - static String toString(PassType type) { return type ? type->valueAsString() : String(); } -}; - -// SVGAnimatedPreserveAspectRatio -template<> -struct DeprecatedSVGAnimatedPropertyTraits<SVGPreserveAspectRatio> : public Noncopyable { - typedef const SVGPreserveAspectRatio& PassType; - typedef SVGPreserveAspectRatio ReturnType; - typedef SVGPreserveAspectRatio StoredType; - - static ReturnType null() { return SVGPreserveAspectRatio(); } - static ReturnType toReturnType(const StoredType& type) { return type; } - static String toString(PassType type) { return type.valueAsString(); } -}; - -// SVGAnimatedString -template<> -struct DeprecatedSVGAnimatedPropertyTraits<String> : public Noncopyable { - typedef const String& PassType; - typedef String ReturnType; - typedef String StoredType; - - static ReturnType null() { return String(); } - static ReturnType toReturnType(const StoredType& type) { return type; } - static String toString(PassType type) { return type; } -}; - // SVGAnimatedTransformList template<> struct DeprecatedSVGAnimatedPropertyTraits<SVGTransformList*> : public Noncopyable { diff --git a/WebCore/svg/DeprecatedSVGAnimatedTemplate.h b/WebCore/svg/DeprecatedSVGAnimatedTemplate.h index 939db59..9258692 100644 --- a/WebCore/svg/DeprecatedSVGAnimatedTemplate.h +++ b/WebCore/svg/DeprecatedSVGAnimatedTemplate.h @@ -23,16 +23,14 @@ #if ENABLE(SVG) #include "DeprecatedSVGAnimatedPropertyTraits.h" +#include "QualifiedName.h" #include <wtf/Forward.h> #include <wtf/HashMap.h> namespace WebCore { class SVGElement; - class SVGNumberList; - class SVGPreserveAspectRatio; class SVGTransformList; - class QualifiedName; struct DeprecatedSVGAnimatedTypeWrapperKey { // Empty value @@ -154,10 +152,6 @@ namespace WebCore { } // Common type definitions, to ease IDL generation. - typedef DeprecatedSVGAnimatedTemplate<float> SVGAnimatedNumber; - typedef DeprecatedSVGAnimatedTemplate<SVGNumberList*> SVGAnimatedNumberList; - typedef DeprecatedSVGAnimatedTemplate<SVGPreserveAspectRatio> SVGAnimatedPreserveAspectRatio; - typedef DeprecatedSVGAnimatedTemplate<String> SVGAnimatedString; typedef DeprecatedSVGAnimatedTemplate<SVGTransformList*> SVGAnimatedTransformList; } diff --git a/WebCore/svg/SVGAElement.cpp b/WebCore/svg/SVGAElement.cpp index 56078ad..8e429d0 100644 --- a/WebCore/svg/SVGAElement.cpp +++ b/WebCore/svg/SVGAElement.cpp @@ -71,7 +71,7 @@ String SVGAElement::title() const void SVGAElement::parseMappedAttribute(Attribute* attr) { if (attr->name() == SVGNames::targetAttr) - setTargetBaseValue(attr->value()); + setSVGTargetBaseValue(attr->value()); else { if (SVGURIReference::parseMappedAttribute(attr)) return; @@ -105,14 +105,14 @@ void SVGAElement::synchronizeProperty(const QualifiedName& attrName) SVGStyledTransformableElement::synchronizeProperty(attrName); if (attrName == anyQName()) { - synchronizeTarget(); + synchronizeSVGTarget(); synchronizeHref(); synchronizeExternalResourcesRequired(); return; } if (attrName == SVGNames::targetAttr) - synchronizeTarget(); + synchronizeSVGTarget(); else if (SVGURIReference::isKnownAttribute(attrName)) synchronizeHref(); else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) diff --git a/WebCore/svg/SVGAElement.h b/WebCore/svg/SVGAElement.h index 0effda2..f919a6e 100644 --- a/WebCore/svg/SVGAElement.h +++ b/WebCore/svg/SVGAElement.h @@ -46,6 +46,7 @@ namespace WebCore { virtual bool isValid() const { return SVGTests::isValid(); } virtual String title() const; + virtual String target() const { return svgTarget(); } virtual void parseMappedAttribute(Attribute*); virtual void svgAttributeChanged(const QualifiedName&); @@ -62,10 +63,13 @@ namespace WebCore { virtual bool childShouldCreateRenderer(Node*) const; - DECLARE_ANIMATED_PROPERTY(SVGAElement, SVGNames::targetAttr, String, Target, target) + // This defines a non-virtual "String& target() const" method before, that would clash with "virtual String target() const" + // in Element. That's why it's now named "String& svgTarget() const", to avoid the clash. The CodeGenerators take care + // of calling svgTargetAnimated() instead of targetAnimated(), see CodeGenerator.pm. + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGAElement, SVGNames::targetAttr, String, SVGTarget, svgTarget) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGAElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGAElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGAElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGAllInOne.cpp b/WebCore/svg/SVGAllInOne.cpp index 2cb63af..e01af2c 100644 --- a/WebCore/svg/SVGAllInOne.cpp +++ b/WebCore/svg/SVGAllInOne.cpp @@ -31,7 +31,6 @@ #include "SVGAngle.cpp" #include "SVGAnimateColorElement.cpp" #include "SVGAnimatedPathData.cpp" -#include "SVGAnimatedPoints.cpp" #include "SVGAnimateElement.cpp" #include "SVGAnimateMotionElement.cpp" #include "SVGAnimateTransformElement.cpp" diff --git a/WebCore/svg/SVGAltGlyphElement.h b/WebCore/svg/SVGAltGlyphElement.h index ae0903a..b9d0bc0 100644 --- a/WebCore/svg/SVGAltGlyphElement.h +++ b/WebCore/svg/SVGAltGlyphElement.h @@ -52,7 +52,7 @@ namespace WebCore { virtual bool childShouldCreateRenderer(Node*) const; // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGAltGlyphElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGAltGlyphElement, XLinkNames::hrefAttr, String, Href, href) }; } // namespace WebCore diff --git a/WebCore/svg/SVGAngle.idl b/WebCore/svg/SVGAngle.idl index b36670a..be01ff9 100644 --- a/WebCore/svg/SVGAngle.idl +++ b/WebCore/svg/SVGAngle.idl @@ -37,10 +37,10 @@ module svg { attribute [ConvertNullToNullString] DOMString valueAsString setter raises(DOMException); - void newValueSpecifiedUnits(in unsigned short unitType, in float valueInSpecifiedUnits) + [StrictTypeChecking, RequiresAllArguments=Raise] void newValueSpecifiedUnits(in unsigned short unitType, in float valueInSpecifiedUnits) raises(DOMException); - void convertToSpecifiedUnits(in unsigned short unitType) + [StrictTypeChecking, RequiresAllArguments=Raise] void convertToSpecifiedUnits(in unsigned short unitType) raises(DOMException); }; diff --git a/WebCore/svg/SVGAnimateElement.cpp b/WebCore/svg/SVGAnimateElement.cpp index c47a378..152b342 100644 --- a/WebCore/svg/SVGAnimateElement.cpp +++ b/WebCore/svg/SVGAnimateElement.cpp @@ -170,12 +170,12 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat else if (percentage == 1.f) results->m_animatedPoints = m_toPoints; else { - if (m_fromPoints && m_toPoints) - results->m_animatedPoints = SVGPointList::createAnimated(m_fromPoints.get(), m_toPoints.get(), percentage); + if (!m_fromPoints.isEmpty() && !m_toPoints.isEmpty()) + SVGPointList::createAnimated(m_fromPoints, m_toPoints, results->m_animatedPoints, percentage); else results->m_animatedPoints.clear(); // Fall back to discrete animation if the points are not compatible - if (!results->m_animatedPoints) + if (results->m_animatedPoints.isEmpty()) results->m_animatedPoints = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f) ? m_toPoints : m_fromPoints; } @@ -215,14 +215,12 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const m_fromPath.clear(); m_toPath.clear(); } else if (m_propertyType == PointsProperty) { - m_fromPoints = SVGPointList::create(SVGNames::pointsAttr); - if (pointsListFromSVGData(m_fromPoints.get(), fromString)) { - m_toPoints = SVGPointList::create(SVGNames::pointsAttr); - if (pointsListFromSVGData(m_toPoints.get(), toString)) + m_fromPoints.clear(); + if (pointsListFromSVGData(m_fromPoints, fromString)) { + m_toPoints.clear(); + if (pointsListFromSVGData(m_toPoints, toString)) return true; } - m_fromPoints.clear(); - m_toPoints.clear(); } m_fromString = fromString; m_toString = toString; @@ -299,12 +297,9 @@ void SVGAnimateElement::applyResultsToTarget() SVGPathParserFactory* factory = SVGPathParserFactory::self(); factory->buildStringFromByteStream(m_animatedPathPointer, valueToApply, UnalteredParsing); } - } else if (m_propertyType == PointsProperty) { - if (!m_animatedPoints || !m_animatedPoints->numberOfItems()) - valueToApply = m_animatedString; - else - valueToApply = m_animatedPoints->valueAsString(); - } else + } else if (m_propertyType == PointsProperty) + valueToApply = m_animatedPoints.isEmpty() ? m_animatedString : m_animatedPoints.valueAsString(); + else valueToApply = m_animatedString; setTargetAttributeAnimatedValue(valueToApply); diff --git a/WebCore/svg/SVGAnimateElement.h b/WebCore/svg/SVGAnimateElement.h index 9993d84..e478cf8 100644 --- a/WebCore/svg/SVGAnimateElement.h +++ b/WebCore/svg/SVGAnimateElement.h @@ -27,12 +27,12 @@ #include "Color.h" #include "SVGAnimationElement.h" #include "SVGPathByteStream.h" +#include "SVGPointList.h" #include <wtf/OwnPtr.h> namespace WebCore { class SVGPathSegList; - class SVGPointList; class SVGAnimateElement : public SVGAnimationElement { public: @@ -69,9 +69,9 @@ namespace WebCore { OwnPtr<SVGPathByteStream> m_toPath; OwnPtr<SVGPathByteStream> m_animatedPath; SVGPathByteStream* m_animatedPathPointer; - RefPtr<SVGPointList> m_fromPoints; - RefPtr<SVGPointList> m_toPoints; - RefPtr<SVGPointList> m_animatedPoints; + SVGPointList m_fromPoints; + SVGPointList m_toPoints; + SVGPointList m_animatedPoints; }; } // namespace WebCore diff --git a/WebCore/svg/SVGAnimatedBoolean.idl b/WebCore/svg/SVGAnimatedBoolean.idl index 2591c50..3e41e3c 100644 --- a/WebCore/svg/SVGAnimatedBoolean.idl +++ b/WebCore/svg/SVGAnimatedBoolean.idl @@ -27,7 +27,7 @@ module svg { interface [Conditional=SVG] SVGAnimatedBoolean { attribute [StrictTypeChecking] boolean baseVal; - readonly attribute [StrictTypeChecking] boolean animVal; + readonly attribute boolean animVal; }; } diff --git a/WebCore/svg/SVGAnimatedEnumeration.idl b/WebCore/svg/SVGAnimatedEnumeration.idl index 8a9d3b4..c0840f2 100644 --- a/WebCore/svg/SVGAnimatedEnumeration.idl +++ b/WebCore/svg/SVGAnimatedEnumeration.idl @@ -26,7 +26,7 @@ module svg { interface [Conditional=SVG] SVGAnimatedEnumeration { - attribute unsigned short baseVal; + attribute [StrictTypeChecking] unsigned short baseVal; readonly attribute unsigned short animVal; }; diff --git a/WebCore/svg/SVGAnimatedInteger.idl b/WebCore/svg/SVGAnimatedInteger.idl index 6ea9138..61de26c 100644 --- a/WebCore/svg/SVGAnimatedInteger.idl +++ b/WebCore/svg/SVGAnimatedInteger.idl @@ -26,8 +26,7 @@ module svg { interface [Conditional=SVG] SVGAnimatedInteger { - attribute long baseVal - /*setter raises(DOMException)*/; + attribute [StrictTypeChecking] long baseVal; readonly attribute long animVal; }; diff --git a/WebCore/svg/SVGAnimatedPoints.h b/WebCore/svg/SVGAnimatedNumber.h index a62f60c..6897aad 100644 --- a/WebCore/svg/SVGAnimatedPoints.h +++ b/WebCore/svg/SVGAnimatedNumber.h @@ -1,6 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) Research In Motion Limited 2010. 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 @@ -18,27 +17,17 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedPoints_h -#define SVGAnimatedPoints_h +#ifndef SVGAnimatedNumber_h +#define SVGAnimatedNumber_h #if ENABLE(SVG) +#include "SVGAnimatedStaticPropertyTearOff.h" namespace WebCore { - class SVGPointList; - - class SVGAnimatedPoints { - public: - virtual ~SVGAnimatedPoints() { } - - // 'SVGAnimatedPoints' functions - virtual SVGPointList* points() const = 0; - virtual SVGPointList* animatedPoints() const = 0; - }; +typedef SVGAnimatedStaticPropertyTearOff<float> SVGAnimatedNumber; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGAnimatedNumber.idl b/WebCore/svg/SVGAnimatedNumber.idl index dea9d96..c3b0419 100644 --- a/WebCore/svg/SVGAnimatedNumber.idl +++ b/WebCore/svg/SVGAnimatedNumber.idl @@ -27,8 +27,7 @@ module svg { interface [Conditional=SVG] SVGAnimatedNumber { - attribute float baseVal - /*setter raises(DOMException)*/; + attribute [StrictTypeChecking] float baseVal; readonly attribute float animVal; }; diff --git a/WebCore/svg/SVGAnimatedNumberList.h b/WebCore/svg/SVGAnimatedNumberList.h new file mode 100644 index 0000000..f86b3c2 --- /dev/null +++ b/WebCore/svg/SVGAnimatedNumberList.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SVGAnimatedNumberList_h +#define SVGAnimatedNumberList_h + +#if ENABLE(SVG) +#include "SVGAnimatedListPropertyTearOff.h" +#include "SVGNumberList.h" + +namespace WebCore { + +typedef SVGAnimatedListPropertyTearOff<SVGNumberList> SVGAnimatedNumberList; + +} // namespace WebCore + +#endif // ENABLE(SVG) +#endif diff --git a/WebCore/svg/SVGAnimatedPoints.cpp b/WebCore/svg/SVGAnimatedPoints.cpp deleted file mode 100644 index 6f54888..0000000 --- a/WebCore/svg/SVGAnimatedPoints.cpp +++ /dev/null @@ -1 +0,0 @@ -// This file is now intentionally empty. Delete it after removing it from all the build systems and project files. diff --git a/WebCore/svg/SVGAnimatedPreserveAspectRatio.h b/WebCore/svg/SVGAnimatedPreserveAspectRatio.h new file mode 100644 index 0000000..57d8621 --- /dev/null +++ b/WebCore/svg/SVGAnimatedPreserveAspectRatio.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SVGAnimatedPreserveAspectRatio_h +#define SVGAnimatedPreserveAspectRatio_h + +#if ENABLE(SVG) +#include "SVGAnimatedPropertyTearOff.h" +#include "SVGPreserveAspectRatio.h" + +namespace WebCore { + +typedef SVGAnimatedPropertyTearOff<SVGPreserveAspectRatio> SVGAnimatedPreserveAspectRatio; + +} // namespace WebCore + +#endif // ENABLE(SVG) +#endif diff --git a/WebCore/svg/SVGAnimatedString.h b/WebCore/svg/SVGAnimatedString.h new file mode 100644 index 0000000..c8b842f --- /dev/null +++ b/WebCore/svg/SVGAnimatedString.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SVGAnimatedString_h +#define SVGAnimatedString_h + +#if ENABLE(SVG) +#include "SVGAnimatedStaticPropertyTearOff.h" +#include <wtf/text/WTFString.h> + +namespace WebCore { + +typedef SVGAnimatedStaticPropertyTearOff<String> SVGAnimatedString; + +} // namespace WebCore + +#endif // ENABLE(SVG) +#endif diff --git a/WebCore/svg/SVGComponentTransferFunctionElement.cpp b/WebCore/svg/SVGComponentTransferFunctionElement.cpp index c1750d7..078b30d 100644 --- a/WebCore/svg/SVGComponentTransferFunctionElement.cpp +++ b/WebCore/svg/SVGComponentTransferFunctionElement.cpp @@ -33,7 +33,6 @@ namespace WebCore { SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(const QualifiedName& tagName, Document* document) : SVGElement(tagName, document) , m_type(FECOMPONENTTRANSFER_TYPE_UNKNOWN) - , m_tableValues(SVGNumberList::create(SVGNames::tableValuesAttr)) , m_slope(1) , m_amplitude(1) , m_exponent(1) @@ -54,10 +53,12 @@ void SVGComponentTransferFunctionElement::parseMappedAttribute(Attribute* attr) setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_LINEAR); else if (value == "gamma") setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_GAMMA); - } - else if (attr->name() == SVGNames::tableValuesAttr) - tableValuesBaseValue()->parse(value); - else if (attr->name() == SVGNames::slopeAttr) + } else if (attr->name() == SVGNames::tableValuesAttr) { + SVGNumberList newList; + newList.parse(value); + detachAnimatedTableValuesListWrappers(newList.size()); + tableValuesBaseValue() = newList; + } else if (attr->name() == SVGNames::slopeAttr) setSlopeBaseValue(value.toFloat()); else if (attr->name() == SVGNames::interceptAttr) setInterceptBaseValue(value.toFloat()); @@ -105,18 +106,13 @@ void SVGComponentTransferFunctionElement::synchronizeProperty(const QualifiedNam ComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction() const { ComponentTransferFunction func; - func.type = (ComponentTransferType) type(); + func.type = static_cast<ComponentTransferType>(type()); func.slope = slope(); func.intercept = intercept(); func.amplitude = amplitude(); func.exponent = exponent(); func.offset = offset(); - SVGNumberList* numbers = tableValues(); - - ExceptionCode ec = 0; - unsigned int nr = numbers->numberOfItems(); - for (unsigned int i = 0; i < nr; i++) - func.tableValues.append(numbers->getItem(i, ec)); + func.tableValues = tableValues(); return func; } diff --git a/WebCore/svg/SVGComponentTransferFunctionElement.h b/WebCore/svg/SVGComponentTransferFunctionElement.h index d46668b..e02fc16 100644 --- a/WebCore/svg/SVGComponentTransferFunctionElement.h +++ b/WebCore/svg/SVGComponentTransferFunctionElement.h @@ -22,9 +22,9 @@ #define SVGComponentTransferFunctionElement_h #if ENABLE(SVG) && ENABLE(FILTERS) +#include "FEComponentTransfer.h" #include "SVGAnimatedPropertyMacros.h" #include "SVGNumberList.h" -#include "FEComponentTransfer.h" namespace WebCore { @@ -40,12 +40,12 @@ namespace WebCore { private: DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGComponentTransferFunctionElement, SVGNames::typeAttr, int, Type, type) - DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::tableValuesAttr, SVGNumberList*, TableValues, tableValues) - DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::slopeAttr, float, Slope, slope) - DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::interceptAttr, float, Intercept, intercept) - DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::amplitudeAttr, float, Amplitude, amplitude) - DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::exponentAttr, float, Exponent, exponent) - DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::offsetAttr, float, Offset, offset) + DECLARE_ANIMATED_LIST_PROPERTY_NEW(SVGComponentTransferFunctionElement, SVGNames::tableValuesAttr, SVGNumberList, TableValues, tableValues) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGComponentTransferFunctionElement, SVGNames::slopeAttr, float, Slope, slope) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGComponentTransferFunctionElement, SVGNames::interceptAttr, float, Intercept, intercept) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGComponentTransferFunctionElement, SVGNames::amplitudeAttr, float, Amplitude, amplitude) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGComponentTransferFunctionElement, SVGNames::exponentAttr, float, Exponent, exponent) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGComponentTransferFunctionElement, SVGNames::offsetAttr, float, Offset, offset) }; } // namespace WebCore diff --git a/WebCore/svg/SVGCursorElement.h b/WebCore/svg/SVGCursorElement.h index e09739a..d3bcb8b 100644 --- a/WebCore/svg/SVGCursorElement.h +++ b/WebCore/svg/SVGCursorElement.h @@ -58,7 +58,7 @@ namespace WebCore { DECLARE_ANIMATED_PROPERTY_NEW(SVGCursorElement, SVGNames::yAttr, SVGLength, Y, y) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGCursorElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGCursorElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGCursorElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGFEBlendElement.h b/WebCore/svg/SVGFEBlendElement.h index a0010be..44d45bf 100644 --- a/WebCore/svg/SVGFEBlendElement.h +++ b/WebCore/svg/SVGFEBlendElement.h @@ -38,8 +38,8 @@ private: virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); - DECLARE_ANIMATED_PROPERTY(SVGFEBlendElement, SVGNames::inAttr, String, In1, in1) - DECLARE_ANIMATED_PROPERTY(SVGFEBlendElement, SVGNames::in2Attr, String, In2, in2) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEBlendElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEBlendElement, SVGNames::in2Attr, String, In2, in2) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEBlendElement, SVGNames::modeAttr, int, Mode, mode) }; diff --git a/WebCore/svg/SVGFEColorMatrixElement.cpp b/WebCore/svg/SVGFEColorMatrixElement.cpp index 83d112c..eed728d 100644 --- a/WebCore/svg/SVGFEColorMatrixElement.cpp +++ b/WebCore/svg/SVGFEColorMatrixElement.cpp @@ -32,7 +32,6 @@ namespace WebCore { inline SVGFEColorMatrixElement::SVGFEColorMatrixElement(const QualifiedName& tagName, Document* document) : SVGFilterPrimitiveStandardAttributes(tagName, document) , m_type(FECOLORMATRIX_TYPE_UNKNOWN) - , m_values(SVGNumberList::create(SVGNames::valuesAttr)) { } @@ -56,9 +55,12 @@ void SVGFEColorMatrixElement::parseMappedAttribute(Attribute* attr) } else if (attr->name() == SVGNames::inAttr) setIn1BaseValue(value); - else if (attr->name() == SVGNames::valuesAttr) - valuesBaseValue()->parse(value); - else + else if (attr->name() == SVGNames::valuesAttr) { + SVGNumberList newList; + newList.parse(value); + detachAnimatedValuesListWrappers(newList.size()); + valuesBaseValue() = newList; + } else SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } @@ -99,7 +101,6 @@ PassRefPtr<FilterEffect> SVGFEColorMatrixElement::build(SVGFilterBuilder* filter return 0; Vector<float> filterValues; - SVGNumberList* numbers = values(); const ColorMatrixType filterType(static_cast<ColorMatrixType>(type())); // Use defaults if values is empty (SVG 1.1 15.10). @@ -119,12 +120,8 @@ PassRefPtr<FilterEffect> SVGFEColorMatrixElement::build(SVGFilterBuilder* filter break; } } else { - size_t size = numbers->numberOfItems(); - for (size_t i = 0; i < size; i++) { - ExceptionCode ec = 0; - filterValues.append(numbers->getItem(i, ec)); - } - size = filterValues.size(); + filterValues = values(); + unsigned size = filterValues.size(); if ((filterType == FECOLORMATRIX_TYPE_MATRIX && size != 20) || (filterType == FECOLORMATRIX_TYPE_HUEROTATE && size != 1) diff --git a/WebCore/svg/SVGFEColorMatrixElement.h b/WebCore/svg/SVGFEColorMatrixElement.h index 5ec301f..dcdeb41 100644 --- a/WebCore/svg/SVGFEColorMatrixElement.h +++ b/WebCore/svg/SVGFEColorMatrixElement.h @@ -40,9 +40,9 @@ private: virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); - DECLARE_ANIMATED_PROPERTY(SVGFEColorMatrixElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEColorMatrixElement, SVGNames::inAttr, String, In1, in1) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEColorMatrixElement, SVGNames::typeAttr, int, Type, type) - DECLARE_ANIMATED_PROPERTY(SVGFEColorMatrixElement, SVGNames::valuesAttr, SVGNumberList*, Values, values) + DECLARE_ANIMATED_LIST_PROPERTY_NEW(SVGFEColorMatrixElement, SVGNames::valuesAttr, SVGNumberList, Values, values) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEComponentTransferElement.h b/WebCore/svg/SVGFEComponentTransferElement.h index 957661e..fe0e562 100644 --- a/WebCore/svg/SVGFEComponentTransferElement.h +++ b/WebCore/svg/SVGFEComponentTransferElement.h @@ -38,7 +38,7 @@ private: virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); - DECLARE_ANIMATED_PROPERTY(SVGFEComponentTransferElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEComponentTransferElement, SVGNames::inAttr, String, In1, in1) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFECompositeElement.h b/WebCore/svg/SVGFECompositeElement.h index 95443e4..4870848 100644 --- a/WebCore/svg/SVGFECompositeElement.h +++ b/WebCore/svg/SVGFECompositeElement.h @@ -39,13 +39,13 @@ private: virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); - DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::inAttr, String, In1, in1) - DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::in2Attr, String, In2, in2) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFECompositeElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFECompositeElement, SVGNames::in2Attr, String, In2, in2) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFECompositeElement, SVGNames::operatorAttr, int, _operator, _operator) - DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::k1Attr, float, K1, k1) - DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::k2Attr, float, K2, k2) - DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::k3Attr, float, K3, k3) - DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::k4Attr, float, K4, k4) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFECompositeElement, SVGNames::k1Attr, float, K1, k1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFECompositeElement, SVGNames::k2Attr, float, K2, k2) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFECompositeElement, SVGNames::k3Attr, float, K3, k3) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFECompositeElement, SVGNames::k4Attr, float, K4, k4) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEConvolveMatrixElement.cpp b/WebCore/svg/SVGFEConvolveMatrixElement.cpp index d7f14a2..1137543 100644 --- a/WebCore/svg/SVGFEConvolveMatrixElement.cpp +++ b/WebCore/svg/SVGFEConvolveMatrixElement.cpp @@ -35,12 +35,8 @@ namespace WebCore { -char SVGKernelUnitLengthXAttrIdentifier[] = "SVGKernelUnitLengthXAttr"; -char SVGKernelUnitLengthYAttrIdentifier[] = "SVGKernelUnitLengthYAttr"; - inline SVGFEConvolveMatrixElement::SVGFEConvolveMatrixElement(const QualifiedName& tagName, Document* document) : SVGFilterPrimitiveStandardAttributes(tagName, document) - , m_kernelMatrix(SVGNumberList::create(SVGNames::kernelMatrixAttr)) , m_edgeMode(EDGEMODE_DUPLICATE) { } @@ -50,6 +46,30 @@ PassRefPtr<SVGFEConvolveMatrixElement> SVGFEConvolveMatrixElement::create(const return adoptRef(new SVGFEConvolveMatrixElement(tagName, document)); } +const AtomicString& SVGFEConvolveMatrixElement::kernelUnitLengthXIdentifier() +{ + DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX")); + return s_identifier; +} + +const AtomicString& SVGFEConvolveMatrixElement::kernelUnitLengthYIdentifier() +{ + DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY")); + return s_identifier; +} + +const AtomicString& SVGFEConvolveMatrixElement::orderXIdentifier() +{ + DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrderX")); + return s_identifier; +} + +const AtomicString& SVGFEConvolveMatrixElement::orderYIdentifier() +{ + DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrderY")); + return s_identifier; +} + void SVGFEConvolveMatrixElement::parseMappedAttribute(Attribute* attr) { const String& value = attr->value(); @@ -68,9 +88,12 @@ void SVGFEConvolveMatrixElement::parseMappedAttribute(Attribute* attr) setEdgeModeBaseValue(EDGEMODE_WRAP); else if (value == "none") setEdgeModeBaseValue(EDGEMODE_NONE); - } else if (attr->name() == SVGNames::kernelMatrixAttr) - kernelMatrixBaseValue()->parse(value); - else if (attr->name() == SVGNames::divisorAttr) + } else if (attr->name() == SVGNames::kernelMatrixAttr) { + SVGNumberList newList; + newList.parse(value); + detachAnimatedKernelMatrixListWrappers(newList.size()); + kernelMatrixBaseValue() = newList; + } else if (attr->name() == SVGNames::divisorAttr) setDivisorBaseValue(value.toFloat()); else if (attr->name() == SVGNames::biasAttr) setBiasBaseValue(value.toFloat()); @@ -131,22 +154,16 @@ PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* fil if (!input1) return 0; - Vector<float> kernelMatrixValues; - SVGNumberList* numbers = kernelMatrix(); - - ExceptionCode ec = 0; - int numberOfItems = numbers->numberOfItems(); - for (int i = 0; i < numberOfItems; ++i) - kernelMatrixValues.append(numbers->getItem(i, ec)); - int orderXValue = orderX(); int orderYValue = orderY(); if (!hasAttribute(SVGNames::orderAttr)) { orderXValue = 3; orderYValue = 3; } + SVGNumberList& kernelMatrix = this->kernelMatrix(); + int kernelMatrixSize = kernelMatrix.size(); // The spec says this is a requirement, and should bail out if fails - if (orderXValue * orderYValue != numberOfItems) + if (orderXValue * orderYValue != kernelMatrixSize) return 0; int targetXValue = targetX(); @@ -166,8 +183,8 @@ PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* fil if (hasAttribute(SVGNames::divisorAttr) && !divisorValue) return 0; if (!hasAttribute(SVGNames::divisorAttr)) { - for (int i = 0; i < numberOfItems; ++i) - divisorValue += kernelMatrixValues[i]; + for (int i = 0; i < kernelMatrixSize; ++i) + divisorValue += kernelMatrix.at(i); if (!divisorValue) divisorValue = 1; } @@ -175,7 +192,7 @@ PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* fil RefPtr<FilterEffect> effect = FEConvolveMatrix::create( IntSize(orderXValue, orderYValue), divisorValue, bias(), IntPoint(targetXValue, targetYValue), static_cast<EdgeModeType>(edgeMode()), - FloatPoint(kernelUnitLengthX(), kernelUnitLengthX()), preserveAlpha(), kernelMatrixValues); + FloatPoint(kernelUnitLengthX(), kernelUnitLengthX()), preserveAlpha(), kernelMatrix); effect->inputEffects().append(input1); return effect.release(); } diff --git a/WebCore/svg/SVGFEConvolveMatrixElement.h b/WebCore/svg/SVGFEConvolveMatrixElement.h index cb31949..b36b7f1 100644 --- a/WebCore/svg/SVGFEConvolveMatrixElement.h +++ b/WebCore/svg/SVGFEConvolveMatrixElement.h @@ -40,18 +40,23 @@ private: virtual void parseMappedAttribute(Attribute*); virtual void svgAttributeChanged(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); + static const AtomicString& orderXIdentifier(); + static const AtomicString& orderYIdentifier(); - DECLARE_ANIMATED_PROPERTY(SVGFEConvolveMatrixElement, SVGNames::inAttr, String, In1, in1) - DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::orderXAttr, long, OrderX, orderX) - DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::orderYAttr, long, OrderY, orderY) - DECLARE_ANIMATED_PROPERTY(SVGFEConvolveMatrixElement, SVGNames::kernelMatrixAttr, SVGNumberList*, KernelMatrix, kernelMatrix) - DECLARE_ANIMATED_PROPERTY(SVGFEConvolveMatrixElement, SVGNames::divisorAttr, float, Divisor, divisor) - DECLARE_ANIMATED_PROPERTY(SVGFEConvolveMatrixElement, SVGNames::biasAttr, float, Bias, bias) + static const AtomicString& kernelUnitLengthXIdentifier(); + static const AtomicString& kernelUnitLengthYIdentifier(); + + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEConvolveMatrixElement, SVGNames::orderAttr, orderXIdentifier(), long, OrderX, orderX) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEConvolveMatrixElement, SVGNames::orderAttr, orderYIdentifier(), long, OrderY, orderY) + DECLARE_ANIMATED_LIST_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::kernelMatrixAttr, SVGNumberList, KernelMatrix, kernelMatrix) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::divisorAttr, float, Divisor, divisor) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::biasAttr, float, Bias, bias) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::targetXAttr, long, TargetX, targetX) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::targetYAttr, long, TargetY, targetY) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::operatorAttr, int, EdgeMode, edgeMode) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEConvolveMatrixElement, SVGNames::kernelUnitLengthAttr, SVGKernelUnitLengthXIdentifier, float, KernelUnitLengthX, kernelUnitLengthX) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEConvolveMatrixElement, SVGNames::kernelUnitLengthAttr, SVGKernelUnitLengthYIdentifier, float, KernelUnitLengthY, kernelUnitLengthY) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEConvolveMatrixElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), float, KernelUnitLengthX, kernelUnitLengthX) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEConvolveMatrixElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), float, KernelUnitLengthY, kernelUnitLengthY) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEConvolveMatrixElement, SVGNames::preserveAlphaAttr, bool, PreserveAlpha, preserveAlpha) }; diff --git a/WebCore/svg/SVGFEDiffuseLightingElement.cpp b/WebCore/svg/SVGFEDiffuseLightingElement.cpp index ccdf8a0..6da804f 100644 --- a/WebCore/svg/SVGFEDiffuseLightingElement.cpp +++ b/WebCore/svg/SVGFEDiffuseLightingElement.cpp @@ -47,13 +47,13 @@ PassRefPtr<SVGFEDiffuseLightingElement> SVGFEDiffuseLightingElement::create(cons const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthXIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX")); - return s_identifier; + return s_identifier; } const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthYIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY")); - return s_identifier; + return s_identifier; } void SVGFEDiffuseLightingElement::parseMappedAttribute(Attribute* attr) diff --git a/WebCore/svg/SVGFEDiffuseLightingElement.h b/WebCore/svg/SVGFEDiffuseLightingElement.h index b8f56a6..fa946e6 100644 --- a/WebCore/svg/SVGFEDiffuseLightingElement.h +++ b/WebCore/svg/SVGFEDiffuseLightingElement.h @@ -46,11 +46,11 @@ private: static const AtomicString& kernelUnitLengthXIdentifier(); static const AtomicString& kernelUnitLengthYIdentifier(); - DECLARE_ANIMATED_PROPERTY(SVGFEDiffuseLightingElement, SVGNames::inAttr, String, In1, in1) - DECLARE_ANIMATED_PROPERTY(SVGFEDiffuseLightingElement, SVGNames::diffuseConstantAttr, float, DiffuseConstant, diffuseConstant) - DECLARE_ANIMATED_PROPERTY(SVGFEDiffuseLightingElement, SVGNames::surfaceScaleAttr, float, SurfaceScale, surfaceScale) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), float, KernelUnitLengthX, kernelUnitLengthX) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), float, KernelUnitLengthY, kernelUnitLengthY) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEDiffuseLightingElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEDiffuseLightingElement, SVGNames::diffuseConstantAttr, float, DiffuseConstant, diffuseConstant) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEDiffuseLightingElement, SVGNames::surfaceScaleAttr, float, SurfaceScale, surfaceScale) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), float, KernelUnitLengthX, kernelUnitLengthX) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), float, KernelUnitLengthY, kernelUnitLengthY) PassRefPtr<LightSource> findLights() const; }; diff --git a/WebCore/svg/SVGFEDisplacementMapElement.h b/WebCore/svg/SVGFEDisplacementMapElement.h index c42783c..a2c9e43 100644 --- a/WebCore/svg/SVGFEDisplacementMapElement.h +++ b/WebCore/svg/SVGFEDisplacementMapElement.h @@ -39,11 +39,11 @@ private: virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); - DECLARE_ANIMATED_PROPERTY(SVGFEDisplacementMapElement, SVGNames::inAttr, String, In1, in1) - DECLARE_ANIMATED_PROPERTY(SVGFEDisplacementMapElement, SVGNames::in2Attr, String, In2, in2) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEDisplacementMapElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEDisplacementMapElement, SVGNames::in2Attr, String, In2, in2) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEDisplacementMapElement, SVGNames::xChannelSelectorAttr, int, XChannelSelector, xChannelSelector) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEDisplacementMapElement, SVGNames::yChannelSelectorAttr, int, YChannelSelector, yChannelSelector) - DECLARE_ANIMATED_PROPERTY(SVGFEDisplacementMapElement, SVGNames::scaleAttr, float, Scale, scale) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEDisplacementMapElement, SVGNames::scaleAttr, float, Scale, scale) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEGaussianBlurElement.cpp b/WebCore/svg/SVGFEGaussianBlurElement.cpp index e307a8ea..c17c748 100644 --- a/WebCore/svg/SVGFEGaussianBlurElement.cpp +++ b/WebCore/svg/SVGFEGaussianBlurElement.cpp @@ -42,13 +42,13 @@ PassRefPtr<SVGFEGaussianBlurElement> SVGFEGaussianBlurElement::create(const Qual const AtomicString& SVGFEGaussianBlurElement::stdDeviationXIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationX")); - return s_identifier; + return s_identifier; } const AtomicString& SVGFEGaussianBlurElement::stdDeviationYIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationY")); - return s_identifier; + return s_identifier; } void SVGFEGaussianBlurElement::setStdDeviation(float x, float y) diff --git a/WebCore/svg/SVGFEGaussianBlurElement.h b/WebCore/svg/SVGFEGaussianBlurElement.h index d1579a5..3ddb437 100644 --- a/WebCore/svg/SVGFEGaussianBlurElement.h +++ b/WebCore/svg/SVGFEGaussianBlurElement.h @@ -44,9 +44,9 @@ private: static const AtomicString& stdDeviationXIdentifier(); static const AtomicString& stdDeviationYIdentifier(); - DECLARE_ANIMATED_PROPERTY(SVGFEGaussianBlurElement, SVGNames::inAttr, String, In1, in1) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, stdDeviationXIdentifier(), float, StdDeviationX, stdDeviationX) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, stdDeviationYIdentifier(), float, StdDeviationY, stdDeviationY) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEGaussianBlurElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, stdDeviationXIdentifier(), float, StdDeviationX, stdDeviationX) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, stdDeviationYIdentifier(), float, StdDeviationY, stdDeviationY) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEImageElement.h b/WebCore/svg/SVGFEImageElement.h index 901cb19..0dcf2c8 100644 --- a/WebCore/svg/SVGFEImageElement.h +++ b/WebCore/svg/SVGFEImageElement.h @@ -56,10 +56,10 @@ private: void requestImageResource(); - DECLARE_ANIMATED_PROPERTY(SVGFEImageElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY_NEW(SVGFEImageElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGFEImageElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEImageElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEImageElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGFELightElement.h b/WebCore/svg/SVGFELightElement.h index d594475..986a0dc 100644 --- a/WebCore/svg/SVGFELightElement.h +++ b/WebCore/svg/SVGFELightElement.h @@ -24,8 +24,8 @@ #if ENABLE(SVG) && ENABLE(FILTERS) #include "LightSource.h" +#include "SVGAnimatedPropertyMacros.h" #include "SVGElement.h" -#include "SVGNames.h" namespace WebCore { @@ -42,16 +42,16 @@ private: virtual void synchronizeProperty(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::azimuthAttr, float, Azimuth, azimuth) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::elevationAttr, float, Elevation, elevation) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::xAttr, float, X, x) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::yAttr, float, Y, y) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::zAttr, float, Z, z) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::pointsAtXAttr, float, PointsAtX, pointsAtX) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::pointsAtYAttr, float, PointsAtY, pointsAtY) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::pointsAtZAttr, float, PointsAtZ, pointsAtZ) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::specularExponentAttr, float, SpecularExponent, specularExponent) - DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::limitingConeAngleAttr, float, LimitingConeAngle, limitingConeAngle) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::azimuthAttr, float, Azimuth, azimuth) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::elevationAttr, float, Elevation, elevation) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::xAttr, float, X, x) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::yAttr, float, Y, y) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::zAttr, float, Z, z) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::pointsAtXAttr, float, PointsAtX, pointsAtX) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::pointsAtYAttr, float, PointsAtY, pointsAtY) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::pointsAtZAttr, float, PointsAtZ, pointsAtZ) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::specularExponentAttr, float, SpecularExponent, specularExponent) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFELightElement, SVGNames::limitingConeAngleAttr, float, LimitingConeAngle, limitingConeAngle) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEMergeNodeElement.h b/WebCore/svg/SVGFEMergeNodeElement.h index 89506dc..a40d7a2 100644 --- a/WebCore/svg/SVGFEMergeNodeElement.h +++ b/WebCore/svg/SVGFEMergeNodeElement.h @@ -22,8 +22,8 @@ #define SVGFEMergeNodeElement_h #if ENABLE(SVG) && ENABLE(FILTERS) +#include "SVGAnimatedPropertyMacros.h" #include "SVGElement.h" -#include "SVGNames.h" namespace WebCore { @@ -38,7 +38,7 @@ namespace WebCore { virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); - DECLARE_ANIMATED_PROPERTY(SVGFEMergeNodeElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEMergeNodeElement, SVGNames::inAttr, String, In1, in1) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEMorphologyElement.cpp b/WebCore/svg/SVGFEMorphologyElement.cpp index bfd0c0f..c7954b2 100644 --- a/WebCore/svg/SVGFEMorphologyElement.cpp +++ b/WebCore/svg/SVGFEMorphologyElement.cpp @@ -28,9 +28,6 @@ namespace WebCore { -char SVGRadiusXAttrIdentifier[] = "SVGRadiusXAttr"; -char SVGRadiusYAttrIdentifier[] = "SVGRadiusYAttr"; - inline SVGFEMorphologyElement::SVGFEMorphologyElement(const QualifiedName& tagName, Document* document) : SVGFilterPrimitiveStandardAttributes(tagName, document) , m__operator(FEMORPHOLOGY_OPERATOR_ERODE) @@ -42,6 +39,18 @@ PassRefPtr<SVGFEMorphologyElement> SVGFEMorphologyElement::create(const Qualifie return adoptRef(new SVGFEMorphologyElement(tagName, document)); } +const AtomicString& SVGFEMorphologyElement::radiusXIdentifier() +{ + DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGRadiusX")); + return s_identifier; +} + +const AtomicString& SVGFEMorphologyElement::radiusYIdentifier() +{ + DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGRadiusY")); + return s_identifier; +} + void SVGFEMorphologyElement::setRadius(float x, float y) { setRadiusXBaseValue(x); diff --git a/WebCore/svg/SVGFEMorphologyElement.h b/WebCore/svg/SVGFEMorphologyElement.h index 671e7f0..845294b 100644 --- a/WebCore/svg/SVGFEMorphologyElement.h +++ b/WebCore/svg/SVGFEMorphologyElement.h @@ -26,9 +26,6 @@ namespace WebCore { -extern char SVGRadiusXAttrIdentifier[]; -extern char SVGRadiusYAttrIdentifier[]; - class SVGFEMorphologyElement : public SVGFilterPrimitiveStandardAttributes { public: static PassRefPtr<SVGFEMorphologyElement> create(const QualifiedName&, Document*); @@ -46,10 +43,10 @@ private: static const AtomicString& radiusXIdentifier(); static const AtomicString& radiusYIdentifier(); - DECLARE_ANIMATED_PROPERTY(SVGFEMorphologyElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEMorphologyElement, SVGNames::inAttr, String, In1, in1) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEMorphologyElement, SVGNames::operatorAttr, int, _operator, _operator) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, SVGRadiusXAttrIdentifier, float, RadiusX, radiusX) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, SVGRadiusYAttrIdentifier, float, RadiusY, radiusY) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEMorphologyElement, SVGNames::radiusAttr, radiusXIdentifier(), float, RadiusX, radiusX) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFEMorphologyElement, SVGNames::radiusAttr, radiusYIdentifier(), float, RadiusY, radiusY) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEOffsetElement.h b/WebCore/svg/SVGFEOffsetElement.h index 2d522a2..6f5e843 100644 --- a/WebCore/svg/SVGFEOffsetElement.h +++ b/WebCore/svg/SVGFEOffsetElement.h @@ -39,9 +39,9 @@ private: virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); - DECLARE_ANIMATED_PROPERTY(SVGFEOffsetElement, SVGNames::inAttr, String, In1, in1) - DECLARE_ANIMATED_PROPERTY(SVGFEOffsetElement, SVGNames::dxAttr, float, Dx, dx) - DECLARE_ANIMATED_PROPERTY(SVGFEOffsetElement, SVGNames::dyAttr, float, Dy, dy) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEOffsetElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEOffsetElement, SVGNames::dxAttr, float, Dx, dx) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFEOffsetElement, SVGNames::dyAttr, float, Dy, dy) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFESpecularLightingElement.cpp b/WebCore/svg/SVGFESpecularLightingElement.cpp index 949b183..548eb15 100644 --- a/WebCore/svg/SVGFESpecularLightingElement.cpp +++ b/WebCore/svg/SVGFESpecularLightingElement.cpp @@ -48,13 +48,13 @@ PassRefPtr<SVGFESpecularLightingElement> SVGFESpecularLightingElement::create(co const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthXIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX")); - return s_identifier; + return s_identifier; } const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthYIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY")); - return s_identifier; + return s_identifier; } void SVGFESpecularLightingElement::parseMappedAttribute(Attribute* attr) diff --git a/WebCore/svg/SVGFESpecularLightingElement.h b/WebCore/svg/SVGFESpecularLightingElement.h index 82093eb..c5d3ac4 100644 --- a/WebCore/svg/SVGFESpecularLightingElement.h +++ b/WebCore/svg/SVGFESpecularLightingElement.h @@ -42,12 +42,12 @@ private: static const AtomicString& kernelUnitLengthXIdentifier(); static const AtomicString& kernelUnitLengthYIdentifier(); - DECLARE_ANIMATED_PROPERTY(SVGFESpecularLightingElement, SVGNames::inAttr, String, In1, in1) - DECLARE_ANIMATED_PROPERTY(SVGFESpecularLightingElement, SVGNames::specularConstantAttr, float, SpecularConstant, specularConstant) - DECLARE_ANIMATED_PROPERTY(SVGFESpecularLightingElement, SVGNames::specularExponentAttr, float, SpecularExponent, specularExponent) - DECLARE_ANIMATED_PROPERTY(SVGFESpecularLightingElement, SVGNames::surfaceScaleAttr, float, SurfaceScale, surfaceScale) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), float, KernelUnitLengthX, kernelUnitLengthX) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), float, KernelUnitLengthY, kernelUnitLengthY) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFESpecularLightingElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFESpecularLightingElement, SVGNames::specularConstantAttr, float, SpecularConstant, specularConstant) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFESpecularLightingElement, SVGNames::specularExponentAttr, float, SpecularExponent, specularExponent) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFESpecularLightingElement, SVGNames::surfaceScaleAttr, float, SurfaceScale, surfaceScale) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), float, KernelUnitLengthX, kernelUnitLengthX) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), float, KernelUnitLengthY, kernelUnitLengthY) PassRefPtr<LightSource> findLights() const; }; diff --git a/WebCore/svg/SVGFETileElement.h b/WebCore/svg/SVGFETileElement.h index b943c55..ffa9d81 100644 --- a/WebCore/svg/SVGFETileElement.h +++ b/WebCore/svg/SVGFETileElement.h @@ -38,7 +38,7 @@ private: virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); - DECLARE_ANIMATED_PROPERTY(SVGFETileElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFETileElement, SVGNames::inAttr, String, In1, in1) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFETurbulenceElement.cpp b/WebCore/svg/SVGFETurbulenceElement.cpp index 7a4d7d4..53b8fb0 100644 --- a/WebCore/svg/SVGFETurbulenceElement.cpp +++ b/WebCore/svg/SVGFETurbulenceElement.cpp @@ -44,13 +44,13 @@ PassRefPtr<SVGFETurbulenceElement> SVGFETurbulenceElement::create(const Qualifie const AtomicString& SVGFETurbulenceElement::baseFrequencyXIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGBaseFrequencyX")); - return s_identifier; + return s_identifier; } const AtomicString& SVGFETurbulenceElement::baseFrequencyYIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGBaseFrequencyY")); - return s_identifier; + return s_identifier; } void SVGFETurbulenceElement::parseMappedAttribute(Attribute* attr) diff --git a/WebCore/svg/SVGFETurbulenceElement.h b/WebCore/svg/SVGFETurbulenceElement.h index cbe0643..5c41fdd 100644 --- a/WebCore/svg/SVGFETurbulenceElement.h +++ b/WebCore/svg/SVGFETurbulenceElement.h @@ -48,10 +48,10 @@ private: static const AtomicString& baseFrequencyXIdentifier(); static const AtomicString& baseFrequencyYIdentifier(); - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, baseFrequencyXIdentifier(), float, BaseFrequencyX, baseFrequencyX) - DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, baseFrequencyYIdentifier(), float, BaseFrequencyY, baseFrequencyY) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, baseFrequencyXIdentifier(), float, BaseFrequencyX, baseFrequencyX) + DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, baseFrequencyYIdentifier(), float, BaseFrequencyY, baseFrequencyY) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFETurbulenceElement, SVGNames::numOctavesAttr, long, NumOctaves, numOctaves) - DECLARE_ANIMATED_PROPERTY(SVGFETurbulenceElement, SVGNames::seedAttr, float, Seed, seed) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFETurbulenceElement, SVGNames::seedAttr, float, Seed, seed) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFETurbulenceElement, SVGNames::stitchTilesAttr, int, StitchTiles, stitchTiles) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFETurbulenceElement, SVGNames::typeAttr, int, Type, type) }; diff --git a/WebCore/svg/SVGFilterElement.cpp b/WebCore/svg/SVGFilterElement.cpp index 8c56c46..323dd4c 100644 --- a/WebCore/svg/SVGFilterElement.cpp +++ b/WebCore/svg/SVGFilterElement.cpp @@ -63,13 +63,13 @@ PassRefPtr<SVGFilterElement> SVGFilterElement::create(const QualifiedName& tagNa const AtomicString& SVGFilterElement::filterResXIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGFilterResX")); - return s_identifier; + return s_identifier; } const AtomicString& SVGFilterElement::filterResYIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGFilterResY")); - return s_identifier; + return s_identifier; } void SVGFilterElement::setFilterRes(unsigned long filterResX, unsigned long filterResY) diff --git a/WebCore/svg/SVGFilterElement.h b/WebCore/svg/SVGFilterElement.h index ce9f75e..4efb958 100644 --- a/WebCore/svg/SVGFilterElement.h +++ b/WebCore/svg/SVGFilterElement.h @@ -72,7 +72,7 @@ private: DECLARE_ANIMATED_STATIC_PROPERTY_MULTIPLE_WRAPPERS_NEW(SVGFilterElement, SVGNames::filterResAttr, filterResYIdentifier(), long, FilterResY, filterResY) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGFilterElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFilterElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFilterElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h index 6202888..6ac1962 100644 --- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h +++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h @@ -66,7 +66,7 @@ private: DECLARE_ANIMATED_PROPERTY_NEW(SVGFilterPrimitiveStandardAttributes, SVGNames::yAttr, SVGLength, Y, y) DECLARE_ANIMATED_PROPERTY_NEW(SVGFilterPrimitiveStandardAttributes, SVGNames::widthAttr, SVGLength, Width, width) DECLARE_ANIMATED_PROPERTY_NEW(SVGFilterPrimitiveStandardAttributes, SVGNames::heightAttr, SVGLength, Height, height) - DECLARE_ANIMATED_PROPERTY(SVGFilterPrimitiveStandardAttributes, SVGNames::resultAttr, String, Result, result) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGFilterPrimitiveStandardAttributes, SVGNames::resultAttr, String, Result, result) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFitToViewBox.cpp b/WebCore/svg/SVGFitToViewBox.cpp index 5297e8f..e5bd5db 100644 --- a/WebCore/svg/SVGFitToViewBox.cpp +++ b/WebCore/svg/SVGFitToViewBox.cpp @@ -27,6 +27,7 @@ #include "Attr.h" #include "Document.h" #include "FloatRect.h" +#include "SVGDocumentExtensions.h" #include "SVGNames.h" #include "SVGParserUtilities.h" #include "SVGPreserveAspectRatio.h" @@ -85,7 +86,7 @@ AffineTransform SVGFitToViewBox::viewBoxToViewTransform(const FloatRect& viewBox if (!viewBoxRect.width() || !viewBoxRect.height()) return AffineTransform(); - return preserveAspectRatio.getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), 0, 0, viewWidth, viewHeight); + return preserveAspectRatio.getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), viewWidth, viewHeight); } bool SVGFitToViewBox::parseMappedAttribute(Document* document, Attribute* attr) diff --git a/WebCore/svg/SVGFitToViewBox.h b/WebCore/svg/SVGFitToViewBox.h index df41fce..3d62271 100644 --- a/WebCore/svg/SVGFitToViewBox.h +++ b/WebCore/svg/SVGFitToViewBox.h @@ -22,12 +22,16 @@ #define SVGFitToViewBox_h #if ENABLE(SVG) -#include "SVGElement.h" -#include "SVGPreserveAspectRatio.h" +#include <wtf/text/WTFString.h> namespace WebCore { class AffineTransform; +class Attribute; +class Document; +class FloatRect; +class QualifiedName; +class SVGPreserveAspectRatio; class SVGFitToViewBox { public: @@ -40,7 +44,7 @@ public: bool isKnownAttribute(const QualifiedName&); virtual void setViewBoxBaseValue(const FloatRect&) = 0; - virtual void setPreserveAspectRatioBaseValue(DeprecatedSVGAnimatedPropertyTraits<SVGPreserveAspectRatio>::PassType) = 0; + virtual void setPreserveAspectRatioBaseValue(const SVGPreserveAspectRatio&) = 0; private: bool parseViewBox(Document*, const String&, FloatRect&); diff --git a/WebCore/svg/SVGForeignObjectElement.h b/WebCore/svg/SVGForeignObjectElement.h index 55ddb3c..ee17c19 100644 --- a/WebCore/svg/SVGForeignObjectElement.h +++ b/WebCore/svg/SVGForeignObjectElement.h @@ -58,7 +58,7 @@ namespace WebCore { DECLARE_ANIMATED_PROPERTY_NEW(SVGForeignObjectElement, SVGNames::heightAttr, SVGLength, Height, height) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGForeignObjectElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGForeignObjectElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGForeignObjectElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGGradientElement.h b/WebCore/svg/SVGGradientElement.h index fdfb72c..6e23608 100644 --- a/WebCore/svg/SVGGradientElement.h +++ b/WebCore/svg/SVGGradientElement.h @@ -54,7 +54,7 @@ namespace WebCore { DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::gradientTransformAttr, SVGTransformList*, GradientTransform, gradientTransform) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGGradientElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGGradientElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGGradientElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGImageElement.h b/WebCore/svg/SVGImageElement.h index ee105d2..b9f3865 100644 --- a/WebCore/svg/SVGImageElement.h +++ b/WebCore/svg/SVGImageElement.h @@ -70,10 +70,10 @@ namespace WebCore { DECLARE_ANIMATED_PROPERTY_NEW(SVGImageElement, SVGNames::yAttr, SVGLength, Y, y) DECLARE_ANIMATED_PROPERTY_NEW(SVGImageElement, SVGNames::widthAttr, SVGLength, Width, width) DECLARE_ANIMATED_PROPERTY_NEW(SVGImageElement, SVGNames::heightAttr, SVGLength, Height, height) - DECLARE_ANIMATED_PROPERTY(SVGImageElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY_NEW(SVGImageElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGImageElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGImageElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGImageElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGLength.cpp b/WebCore/svg/SVGLength.cpp index a8cfb4e..f8381bf 100644 --- a/WebCore/svg/SVGLength.cpp +++ b/WebCore/svg/SVGLength.cpp @@ -27,14 +27,13 @@ #include "CSSHelper.h" #include "FloatConversion.h" #include "FrameView.h" -#include "NotImplemented.h" #include "RenderObject.h" #include "RenderView.h" #include "SVGParserUtilities.h" #include "SVGSVGElement.h" -#include <math.h> -#include <wtf/Assertions.h> +#include <wtf/MathExtras.h> +#include <wtf/text/StringConcatenate.h> namespace WebCore { @@ -83,6 +82,7 @@ static inline String lengthTypeToString(SVGLengthType type) return "pc"; } + ASSERT_NOT_REACHED(); return String(); } @@ -126,10 +126,11 @@ inline SVGLengthType stringToLengthType(const UChar*& ptr, const UChar* end) } SVGLength::SVGLength(SVGLengthMode mode, const String& valueAsString) - : m_valueInSpecifiedUnits(0.0f) + : m_valueInSpecifiedUnits(0) , m_unit(storeUnit(mode, LengthTypeNumber)) { - setValueAsString(valueAsString); + ExceptionCode ec = 0; + setValueAsString(valueAsString, ec); } SVGLength::SVGLength(const SVGLength& other) @@ -156,35 +157,24 @@ SVGLengthType SVGLength::unitType() const float SVGLength::value(const SVGElement* context) const { - SVGLengthType type = extractType(m_unit); - if (type == LengthTypeUnknown) - return 0.0f; + ExceptionCode ec = 0; + return value(context, ec); +} - switch (type) { +float SVGLength::value(const SVGElement* context, ExceptionCode& ec) const +{ + switch (extractType(m_unit)) { + case LengthTypeUnknown: + ec = NOT_SUPPORTED_ERR; + return 0; case LengthTypeNumber: return m_valueInSpecifiedUnits; case LengthTypePercentage: - return SVGLength::PercentageOfViewport(m_valueInSpecifiedUnits / 100.0f, context, extractMode(m_unit)); + return convertValueFromPercentageToUserUnits(m_valueInSpecifiedUnits / 100, context, ec); case LengthTypeEMS: + return convertValueFromEMSToUserUnits(m_valueInSpecifiedUnits, context, ec); case LengthTypeEXS: - { - RenderStyle* style = 0; - if (context && context->renderer()) - style = context->renderer()->style(); - if (style) { - float useSize = style->fontSize(); - ASSERT(useSize > 0); - if (type == LengthTypeEMS) - return m_valueInSpecifiedUnits * useSize; - else { - float xHeight = style->font().xHeight(); - // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg - // if this causes problems in real world cases maybe it would be best to remove this - return m_valueInSpecifiedUnits * ceilf(xHeight); - } - } - return 0.0f; - } + return convertValueFromEXSToUserUnits(m_valueInSpecifiedUnits, context, ec); case LengthTypePX: return m_valueInSpecifiedUnits; case LengthTypeCM: @@ -194,31 +184,45 @@ float SVGLength::value(const SVGElement* context) const case LengthTypeIN: return m_valueInSpecifiedUnits * cssPixelsPerInch; case LengthTypePT: - return m_valueInSpecifiedUnits / 72.0f * cssPixelsPerInch; + return m_valueInSpecifiedUnits / 72 * cssPixelsPerInch; case LengthTypePC: - return m_valueInSpecifiedUnits / 6.0f * cssPixelsPerInch; - default: - break; + return m_valueInSpecifiedUnits / 6 * cssPixelsPerInch; } ASSERT_NOT_REACHED(); - return 0.0f; + return 0; } -void SVGLength::setValue(float value) +void SVGLength::setValue(float value, const SVGElement* context, ExceptionCode& ec) { - SVGLengthType type = extractType(m_unit); - ASSERT(type != LengthTypeUnknown); - - switch (type) { + switch (extractType(m_unit)) { + case LengthTypeUnknown: + ec = NOT_SUPPORTED_ERR; + break; case LengthTypeNumber: m_valueInSpecifiedUnits = value; break; case LengthTypePercentage: + { + float result = convertValueFromUserUnitsToPercentage(value, context, ec); + if (!ec) + m_valueInSpecifiedUnits = result; + break; + } case LengthTypeEMS: + { + float result = convertValueFromUserUnitsToEMS(value, context, ec); + if (!ec) + m_valueInSpecifiedUnits = result; + break; + } case LengthTypeEXS: - notImplemented(); + { + float result = convertValueFromUserUnitsToEXS(value, context, ec); + if (!ec) + m_valueInSpecifiedUnits = result; break; + } case LengthTypePX: m_valueInSpecifiedUnits = value; break; @@ -232,97 +236,104 @@ void SVGLength::setValue(float value) m_valueInSpecifiedUnits = value / cssPixelsPerInch; break; case LengthTypePT: - m_valueInSpecifiedUnits = value * 72.0f / cssPixelsPerInch; + m_valueInSpecifiedUnits = value * 72 / cssPixelsPerInch; break; case LengthTypePC: - m_valueInSpecifiedUnits = value / 6.0f * cssPixelsPerInch; - break; - default: + m_valueInSpecifiedUnits = value * 6 / cssPixelsPerInch; break; } } -void SVGLength::setValueInSpecifiedUnits(float value) -{ - m_valueInSpecifiedUnits = value; -} - -float SVGLength::valueInSpecifiedUnits() const -{ - return m_valueInSpecifiedUnits; -} - float SVGLength::valueAsPercentage() const { // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed if (extractType(m_unit) == LengthTypePercentage) - return valueInSpecifiedUnits() / 100.0f; + return m_valueInSpecifiedUnits / 100; - return valueInSpecifiedUnits(); + return m_valueInSpecifiedUnits; } -bool SVGLength::setValueAsString(const String& s) +void SVGLength::setValueAsString(const String& string, ExceptionCode& ec) { - if (s.isEmpty()) - return false; + if (string.isEmpty()) + return; - float convertedNumber = 0.0f; - const UChar* ptr = s.characters(); - const UChar* end = ptr + s.length(); + float convertedNumber = 0; + const UChar* ptr = string.characters(); + const UChar* end = ptr + string.length(); - if (!parseNumber(ptr, end, convertedNumber, false)) - return false; + if (!parseNumber(ptr, end, convertedNumber, false)) { + ec = SYNTAX_ERR; + return; + } SVGLengthType type = stringToLengthType(ptr, end); - if (type == LengthTypeUnknown) - return false; + if (type == LengthTypeUnknown) { + ec = SYNTAX_ERR; + return; + } m_unit = storeUnit(extractMode(m_unit), type); m_valueInSpecifiedUnits = convertedNumber; - return true; } String SVGLength::valueAsString() const { - return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(extractType(m_unit)); + return makeString(String::number(m_valueInSpecifiedUnits), lengthTypeToString(extractType(m_unit))); } -void SVGLength::newValueSpecifiedUnits(unsigned short type, float value) +void SVGLength::newValueSpecifiedUnits(unsigned short type, float value, ExceptionCode& ec) { - if (type == LengthTypeUnknown || type > LengthTypePC) + if (type == LengthTypeUnknown || type > LengthTypePC) { + ec = NOT_SUPPORTED_ERR; return; + } - m_unit = storeUnit(extractMode(m_unit), (SVGLengthType) type); + m_unit = storeUnit(extractMode(m_unit), static_cast<SVGLengthType>(type)); m_valueInSpecifiedUnits = value; } -void SVGLength::convertToSpecifiedUnits(unsigned short type, const SVGElement* context) +void SVGLength::convertToSpecifiedUnits(unsigned short type, const SVGElement* context, ExceptionCode& ec) { - if (type == LengthTypeUnknown || type > LengthTypePC) + if (type == LengthTypeUnknown || type > LengthTypePC) { + ec = NOT_SUPPORTED_ERR; return; + } - float valueInUserUnits = value(context); - m_unit = storeUnit(extractMode(m_unit), (SVGLengthType) type); - setValue(valueInUserUnits); + float valueInUserUnits = value(context, ec); + if (ec) + return; + + unsigned int originalUnitAndType = m_unit; + m_unit = storeUnit(extractMode(m_unit), static_cast<SVGLengthType>(type)); + setValue(valueInUserUnits, context, ec); + if (!ec) + return; + + // Eventually restore old unit and type + m_unit = originalUnitAndType; } -float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SVGLengthMode mode) +bool SVGLength::determineViewport(const SVGElement* context, float& width, float& height) const { - ASSERT(context); - - float width = 0.0f, height = 0.0f; - SVGElement* viewportElement = context->viewportElement(); + if (!context) + return false; - // PercentageOfViewport() is used to resolve all relative-positioned values within a SVG document (fragment) - Document* doc = context->document(); - if (doc->documentElement() == context) { - // Resolve value against outermost <svg> element - if (RenderView* view = toRenderView(doc->renderer())) { + // Take size from outermost <svg> element. + Document* document = context->document(); + if (document->documentElement() == context) { + if (RenderView* view = toRenderView(document->renderer())) { width = view->viewWidth(); height = view->viewHeight(); - } - } else if (viewportElement && viewportElement->isSVG()) { - // Resolve value against nearest viewport element (common case: inner <svg> elements) + return true; + } + + return false; + } + + // Resolve value against nearest viewport element (common case: inner <svg> elements) + SVGElement* viewportElement = context->viewportElement(); + if (viewportElement && viewportElement->isSVG()) { const SVGSVGElement* svg = static_cast<const SVGSVGElement*>(viewportElement); if (svg->hasAttribute(SVGNames::viewBoxAttr)) { width = svg->viewBox().width(); @@ -331,25 +342,127 @@ float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SV width = svg->width().value(svg); height = svg->height().value(svg); } - } else if (context->parent() && !context->parent()->isSVGElement()) { - // Resolve value against enclosing non-SVG RenderBox - if (RenderObject* renderer = context->renderer()) { - if (renderer->isBox()) { - RenderBox* box = toRenderBox(renderer); - width = box->width(); - height = box->height(); - } - } + + return true; } + + // Resolve value against enclosing non-SVG RenderBox + if (!context->parent() || context->parent()->isSVGElement()) + return false; - if (mode == LengthModeWidth) + RenderObject* renderer = context->renderer(); + if (!renderer || !renderer->isBox()) + return false; + + RenderBox* box = toRenderBox(renderer); + width = box->width(); + height = box->height(); + return true; +} + +float SVGLength::convertValueFromUserUnitsToPercentage(float value, const SVGElement* context, ExceptionCode& ec) const +{ + float width = 0; + float height = 0; + if (!determineViewport(context, width, height)) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + switch (extractMode(m_unit)) { + case LengthModeWidth: + return value / width * 100; + case LengthModeHeight: + return value / height * 100; + case LengthModeOther: + return value / (sqrtf((width * width + height * height) / 2)) * 100; + }; + + ASSERT_NOT_REACHED(); + return 0; +} + +float SVGLength::convertValueFromPercentageToUserUnits(float value, const SVGElement* context, ExceptionCode& ec) const +{ + float width = 0; + float height = 0; + if (!determineViewport(context, width, height)) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + switch (extractMode(m_unit)) { + case LengthModeWidth: return value * width; - else if (mode == LengthModeHeight) + case LengthModeHeight: return value * height; - else if (mode == LengthModeOther) - return value * sqrtf(powf(width, 2) + powf(height, 2)) / sqrtf(2.0f); + case LengthModeOther: + return value * sqrtf((width * width + height * height) / 2); + }; - return 0.0f; + ASSERT_NOT_REACHED(); + return 0; +} + +float SVGLength::convertValueFromUserUnitsToEMS(float value, const SVGElement* context, ExceptionCode& ec) const +{ + if (!context || !context->renderer() || !context->renderer()->style()) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + RenderStyle* style = context->renderer()->style(); + float fontSize = style->fontSize(); + if (!fontSize) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + return value / fontSize; +} + +float SVGLength::convertValueFromEMSToUserUnits(float value, const SVGElement* context, ExceptionCode& ec) const +{ + if (!context || !context->renderer() || !context->renderer()->style()) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + RenderStyle* style = context->renderer()->style(); + return value * style->fontSize(); +} + +float SVGLength::convertValueFromUserUnitsToEXS(float value, const SVGElement* context, ExceptionCode& ec) const +{ + if (!context || !context->renderer() || !context->renderer()->style()) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + RenderStyle* style = context->renderer()->style(); + + // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg + // if this causes problems in real world cases maybe it would be best to remove this + float xHeight = ceilf(style->font().xHeight()); + if (!xHeight) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + return value / xHeight; +} + +float SVGLength::convertValueFromEXSToUserUnits(float value, const SVGElement* context, ExceptionCode& ec) const +{ + if (!context || !context->renderer() || !context->renderer()->style()) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + RenderStyle* style = context->renderer()->style(); + // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg + // if this causes problems in real world cases maybe it would be best to remove this + return value * ceilf(style->font().xHeight()); } SVGLength SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value) @@ -397,8 +510,12 @@ SVGLength SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value) if (svgType == LengthTypeUnknown) return SVGLength(); + ExceptionCode ec = 0; SVGLength length; - length.newValueSpecifiedUnits(svgType, value->getFloatValue()); + length.newValueSpecifiedUnits(svgType, value->getFloatValue(), ec); + if (ec) + return SVGLength(); + return length; } @@ -438,8 +555,6 @@ PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(const SVGLength& le case LengthTypePC: cssType = CSSPrimitiveValue::CSS_PC; break; - default: - ASSERT_NOT_REACHED(); }; return CSSPrimitiveValue::create(length.valueInSpecifiedUnits(), cssType); diff --git a/WebCore/svg/SVGLength.h b/WebCore/svg/SVGLength.h index a0551f7..ccd22ee 100644 --- a/WebCore/svg/SVGLength.h +++ b/WebCore/svg/SVGLength.h @@ -22,7 +22,8 @@ #define SVGLength_h #if ENABLE(SVG) -#include "PlatformString.h" +#include "ExceptionCode.h" +#include <wtf/text/WTFString.h> namespace WebCore { @@ -76,32 +77,43 @@ public: bool operator!=(const SVGLength&) const; float value(const SVGElement* context) const; - void setValue(float); + float value(const SVGElement* context, ExceptionCode&) const; + void setValue(float, const SVGElement* context, ExceptionCode&); + + float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; } + void setValueInSpecifiedUnits(float value) { m_valueInSpecifiedUnits = value; } - float valueInSpecifiedUnits() const; - void setValueInSpecifiedUnits(float); - float valueAsPercentage() const; String valueAsString() const; - bool setValueAsString(const String&); + void setValueAsString(const String&, ExceptionCode&); - void newValueSpecifiedUnits(unsigned short, float valueInSpecifiedUnits); - void convertToSpecifiedUnits(unsigned short, const SVGElement* context); + void newValueSpecifiedUnits(unsigned short, float valueInSpecifiedUnits, ExceptionCode&); + void convertToSpecifiedUnits(unsigned short, const SVGElement* context, ExceptionCode&); // Helper functions - static float PercentageOfViewport(float value, const SVGElement* context, SVGLengthMode); - inline bool isRelative() const { SVGLengthType type = unitType(); - return (type == LengthTypePercentage || type == LengthTypeEMS || type == LengthTypeEXS); + return type == LengthTypePercentage || type == LengthTypeEMS || type == LengthTypeEXS; } static SVGLength fromCSSPrimitiveValue(CSSPrimitiveValue*); static PassRefPtr<CSSPrimitiveValue> toCSSPrimitiveValue(const SVGLength&); private: + bool determineViewport(const SVGElement* context, float& width, float& height) const; + + float convertValueFromPercentageToUserUnits(float value, const SVGElement* context, ExceptionCode&) const; + float convertValueFromUserUnitsToPercentage(float value, const SVGElement* context, ExceptionCode&) const; + + float convertValueFromUserUnitsToEMS(float value, const SVGElement* context, ExceptionCode&) const; + float convertValueFromEMSToUserUnits(float value, const SVGElement* context, ExceptionCode&) const; + + float convertValueFromUserUnitsToEXS(float value, const SVGElement* context, ExceptionCode&) const; + float convertValueFromEXSToUserUnits(float value, const SVGElement* context, ExceptionCode&) const; + +private: float m_valueInSpecifiedUnits; unsigned int m_unit; }; diff --git a/WebCore/svg/SVGLength.idl b/WebCore/svg/SVGLength.idl index 166019e..0e6807f 100644 --- a/WebCore/svg/SVGLength.idl +++ b/WebCore/svg/SVGLength.idl @@ -37,14 +37,20 @@ module svg { const unsigned short SVG_LENGTHTYPE_PC = 10; readonly attribute unsigned short unitType; - attribute [CustomGetter] float value; - attribute float valueInSpecifiedUnits; - attribute [ConvertNullToNullString] DOMString valueAsString; + attribute [Custom, StrictTypeChecking] float value + setter raises(DOMException), + getter raises(DOMException); - void newValueSpecifiedUnits(in unsigned short unitType, - in float valueInSpecifiedUnits); + attribute [StrictTypeChecking] float valueInSpecifiedUnits; + attribute [ConvertNullToNullString, StrictTypeChecking] DOMString valueAsString + setter raises(DOMException); - [Custom] void convertToSpecifiedUnits(in unsigned short unitType); + [StrictTypeChecking, RequiresAllArguments=Raise] void newValueSpecifiedUnits(in unsigned short unitType, + in float valueInSpecifiedUnits) + raises(DOMException); + + [Custom, StrictTypeChecking, RequiresAllArguments=Raise] void convertToSpecifiedUnits(in unsigned short unitType) + raises(DOMException); }; } diff --git a/WebCore/svg/SVGLengthList.cpp b/WebCore/svg/SVGLengthList.cpp index 3ab7c1a..a05ea4b 100644 --- a/WebCore/svg/SVGLengthList.cpp +++ b/WebCore/svg/SVGLengthList.cpp @@ -31,6 +31,7 @@ namespace WebCore { void SVGLengthList::parse(const String& value, SVGLengthMode mode) { clear(); + ExceptionCode ec = 0; const UChar* ptr = value.characters(); const UChar* end = ptr + value.length(); @@ -40,8 +41,13 @@ void SVGLengthList::parse(const String& value, SVGLengthMode mode) ptr++; if (ptr == start) break; + SVGLength length(mode); - if (!length.setValueAsString(String(start, ptr - start))) + String valueString(start, ptr - start); + if (valueString.isEmpty()) + return; + length.setValueAsString(valueString, ec); + if (ec) return; append(length); skipOptionalSpacesOrDelimiter(ptr, end); diff --git a/WebCore/svg/SVGLengthList.idl b/WebCore/svg/SVGLengthList.idl index 73a8d21..a5771d2 100644 --- a/WebCore/svg/SVGLengthList.idl +++ b/WebCore/svg/SVGLengthList.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, SVGListProperty=SVGLengthList] SVGLengthList { + interface [Conditional=SVG] SVGLengthList { readonly attribute unsigned long numberOfItems; void clear() diff --git a/WebCore/svg/SVGLocatable.cpp b/WebCore/svg/SVGLocatable.cpp index 9a823ff..b3dce01 100644 --- a/WebCore/svg/SVGLocatable.cpp +++ b/WebCore/svg/SVGLocatable.cpp @@ -26,8 +26,9 @@ #include "SVGLocatable.h" #include "RenderObject.h" -#include "SVGStyledLocatableElement.h" #include "SVGException.h" +#include "SVGNames.h" +#include "SVGStyledLocatableElement.h" namespace WebCore { diff --git a/WebCore/svg/SVGMPathElement.h b/WebCore/svg/SVGMPathElement.h index c025cf9..3d10e5b 100644 --- a/WebCore/svg/SVGMPathElement.h +++ b/WebCore/svg/SVGMPathElement.h @@ -44,7 +44,7 @@ namespace WebCore { virtual void synchronizeProperty(const QualifiedName&); // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGMPathElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGMPathElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGMPathElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGMarkerElement.cpp b/WebCore/svg/SVGMarkerElement.cpp index ef2b3dd..8b6d41c 100644 --- a/WebCore/svg/SVGMarkerElement.cpp +++ b/WebCore/svg/SVGMarkerElement.cpp @@ -55,13 +55,13 @@ PassRefPtr<SVGMarkerElement> SVGMarkerElement::create(const QualifiedName& tagNa const AtomicString& SVGMarkerElement::orientTypeIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientType")); - return s_identifier; + return s_identifier; } const AtomicString& SVGMarkerElement::orientAngleIdentifier() { DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientAngle")); - return s_identifier; + return s_identifier; } AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const diff --git a/WebCore/svg/SVGMarkerElement.h b/WebCore/svg/SVGMarkerElement.h index fd67cfc..e84357e 100644 --- a/WebCore/svg/SVGMarkerElement.h +++ b/WebCore/svg/SVGMarkerElement.h @@ -89,7 +89,7 @@ private: // SVGFitToViewBox DECLARE_ANIMATED_PROPERTY_NEW(SVGMarkerElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) - DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY_NEW(SVGMarkerElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) }; } diff --git a/WebCore/svg/SVGNumber.idl b/WebCore/svg/SVGNumber.idl index 32e9620..83e3b6b 100644 --- a/WebCore/svg/SVGNumber.idl +++ b/WebCore/svg/SVGNumber.idl @@ -22,8 +22,8 @@ module svg { - interface [Conditional=SVG, PODType=float] SVGNumber { - attribute float value; + interface [Conditional=SVG] SVGNumber { + attribute [StrictTypeChecking] float value; }; } diff --git a/WebCore/svg/SVGNumberList.cpp b/WebCore/svg/SVGNumberList.cpp index 96fe55f..a1dc430 100644 --- a/WebCore/svg/SVGNumberList.cpp +++ b/WebCore/svg/SVGNumberList.cpp @@ -24,45 +24,39 @@ #include "SVGNumberList.h" #include "SVGParserUtilities.h" +#include <wtf/text/StringBuilder.h> namespace WebCore { -SVGNumberList::SVGNumberList(const QualifiedName& attributeName) - : SVGPODList<float>(attributeName) -{ -} - void SVGNumberList::parse(const String& value) { - ExceptionCode ec = 0; - clear(ec); + clear(); - float number = 0.0f; - + float number = 0; const UChar* ptr = value.characters(); const UChar* end = ptr + value.length(); + // The spec strangely doesn't allow leading whitespace. We might choose to violate that intentionally. (section 4.1) while (ptr < end) { if (!parseNumber(ptr, end, number)) return; - appendItem(number, ec); + append(number); } } String SVGNumberList::valueAsString() const { - String result; + StringBuilder builder; - ExceptionCode ec = 0; - for (unsigned int i = 0; i < numberOfItems(); ++i) { + unsigned size = this->size(); + for (unsigned i = 0; i < size; ++i) { if (i > 0) - result += ", "; + builder.append(", "); - result += String::number(getItem(i, ec)); - ASSERT(ec == 0); + builder.append(String::number(at(i))); } - return result; + return builder.toString(); } } diff --git a/WebCore/svg/SVGNumberList.h b/WebCore/svg/SVGNumberList.h index e64b0b7..abc82da 100644 --- a/WebCore/svg/SVGNumberList.h +++ b/WebCore/svg/SVGNumberList.h @@ -22,23 +22,18 @@ #define SVGNumberList_h #if ENABLE(SVG) -#include "SVGList.h" -#include <wtf/Forward.h> -#include <wtf/PassRefPtr.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebCore { - class SVGNumberList : public SVGPODList<float> { - public: - static PassRefPtr<SVGNumberList> create(const QualifiedName& attributeName) { return adoptRef(new SVGNumberList(attributeName)); } +class SVGNumberList : public Vector<float> { +public: + SVGNumberList() { } - void parse(const String& value); - - String valueAsString() const; - - private: - SVGNumberList(const QualifiedName&); - }; + void parse(const String&); + String valueAsString() const; +}; } // namespace WebCore diff --git a/WebCore/svg/SVGParserUtilities.cpp b/WebCore/svg/SVGParserUtilities.cpp index c37d207..5a77ce2 100644 --- a/WebCore/svg/SVGParserUtilities.cpp +++ b/WebCore/svg/SVGParserUtilities.cpp @@ -26,9 +26,7 @@ #include "SVGParserUtilities.h" #include "Document.h" -#include "ExceptionCode.h" #include "FloatPoint.h" -#include "PlatformString.h" #include "SVGPointList.h" #include <wtf/ASCIICType.h> @@ -167,7 +165,7 @@ bool parseNumberOptionalNumber(const String& s, float& x, float& y) return cur == end; } -bool pointsListFromSVGData(SVGPointList* pointsList, const String& points) +bool pointsListFromSVGData(SVGPointList& pointsList, const String& points) { if (points.isEmpty()) return true; @@ -195,8 +193,7 @@ bool pointsListFromSVGData(SVGPointList* pointsList, const String& points) } skipOptionalSpaces(cur, end); - ExceptionCode ec = 0; - pointsList->appendItem(FloatPoint(xPos, yPos), ec); + pointsList.append(FloatPoint(xPos, yPos)); } return cur == end && !delimParsed; } diff --git a/WebCore/svg/SVGParserUtilities.h b/WebCore/svg/SVGParserUtilities.h index 4e9362d..0718d50 100644 --- a/WebCore/svg/SVGParserUtilities.h +++ b/WebCore/svg/SVGParserUtilities.h @@ -63,7 +63,7 @@ namespace WebCore { return ptr < end; } - bool pointsListFromSVGData(SVGPointList* pointsList, const String& points); + bool pointsListFromSVGData(SVGPointList& pointsList, const String& points); Vector<String> parseDelimitedString(const String& input, const char seperator); bool parseKerningUnicodeString(const String& input, UnicodeRanges&, HashSet<String>& stringList); bool parseGlyphName(const String& input, HashSet<String>& values); diff --git a/WebCore/svg/SVGPathElement.h b/WebCore/svg/SVGPathElement.h index f4e2b8a..91d55b1 100644 --- a/WebCore/svg/SVGPathElement.h +++ b/WebCore/svg/SVGPathElement.h @@ -105,7 +105,7 @@ namespace WebCore { mutable RefPtr<SVGPathSegList> m_pathSegList; - DECLARE_ANIMATED_PROPERTY(SVGPathElement, SVGNames::pathLengthAttr, float, PathLength, pathLength) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPathElement, SVGNames::pathLengthAttr, float, PathLength, pathLength) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPathElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGPatternElement.h b/WebCore/svg/SVGPatternElement.h index 84e0415..ce63a22 100644 --- a/WebCore/svg/SVGPatternElement.h +++ b/WebCore/svg/SVGPatternElement.h @@ -73,14 +73,14 @@ namespace WebCore { DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::patternTransformAttr, SVGTransformList*, PatternTransform, patternTransform) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGPatternElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPatternElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPatternElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) // SVGPatternElement DECLARE_ANIMATED_PROPERTY_NEW(SVGPatternElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) - DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY_NEW(SVGPatternElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) }; } // namespace WebCore diff --git a/WebCore/svg/SVGPoint.idl b/WebCore/svg/SVGPoint.idl index 46ca671..19c6292 100644 --- a/WebCore/svg/SVGPoint.idl +++ b/WebCore/svg/SVGPoint.idl @@ -22,9 +22,9 @@ module svg { - interface [Conditional=SVG, PODType=FloatPoint] SVGPoint { - attribute float x; - attribute float y; + interface [Conditional=SVG] SVGPoint { + attribute [StrictTypeChecking] float x; + attribute [StrictTypeChecking] float y; SVGPoint matrixTransform(in SVGMatrix matrix); }; diff --git a/WebCore/svg/SVGPointList.cpp b/WebCore/svg/SVGPointList.cpp index 0d8e10c..ae460a1 100644 --- a/WebCore/svg/SVGPointList.cpp +++ b/WebCore/svg/SVGPointList.cpp @@ -22,32 +22,27 @@ #if ENABLE(SVG) #include "SVGPointList.h" -#include "SVGPathSegList.h" -#include "PlatformString.h" -namespace WebCore { +#include "FloatPoint.h" +#include <wtf/text/StringBuilder.h> +#include <wtf/text/StringConcatenate.h> -SVGPointList::SVGPointList(const QualifiedName& attributeName) - : SVGPODList<FloatPoint>(attributeName) -{ -} +namespace WebCore { String SVGPointList::valueAsString() const { - String result; + StringBuilder builder; - ExceptionCode ec = 0; - for (unsigned int i = 0; i < numberOfItems(); ++i) { + unsigned size = this->size(); + for (unsigned i = 0; i < size; ++i) { if (i > 0) - result += " "; - - FloatPoint point = getItem(i, ec); - ASSERT(ec == 0); + builder.append(" "); // FIXME: Shouldn't we use commas to seperate? - result += String::format("%.6lg %.6lg", point.x(), point.y()); + const FloatPoint& point = at(i); + builder.append(makeString(String::number(point.x()), ' ', String::number(point.y()))); } - return result; + return builder.toString(); } float inline adjustAnimatedValue(float from, float to, float progress) @@ -55,27 +50,19 @@ float inline adjustAnimatedValue(float from, float to, float progress) return (to - from) * progress + from; } -PassRefPtr<SVGPointList> SVGPointList::createAnimated(const SVGPointList* fromList, const SVGPointList* toList, float progress) +bool SVGPointList::createAnimated(const SVGPointList& fromList, const SVGPointList& toList, SVGPointList& resultList, float progress) { - unsigned itemCount = fromList->numberOfItems(); - if (!itemCount || itemCount != toList->numberOfItems()) - return 0; - RefPtr<SVGPointList> result = create(fromList->associatedAttributeName()); - ExceptionCode ec = 0; + unsigned itemCount = fromList.size(); + if (!itemCount || itemCount != toList.size()) + return false; for (unsigned n = 0; n < itemCount; ++n) { - FloatPoint from = fromList->getItem(n, ec); - if (ec) - return 0; - FloatPoint to = toList->getItem(n, ec); - if (ec) - return 0; + const FloatPoint& from = fromList.at(n); + const FloatPoint& to = toList.at(n); FloatPoint segment = FloatPoint(adjustAnimatedValue(from.x(), to.x(), progress), adjustAnimatedValue(from.y(), to.y(), progress)); - result->appendItem(segment, ec); - if (ec) - return 0; + resultList.append(segment); } - return result.release(); + return true; } } diff --git a/WebCore/svg/SVGPointList.h b/WebCore/svg/SVGPointList.h index 43edbbb..9f2efc9 100644 --- a/WebCore/svg/SVGPointList.h +++ b/WebCore/svg/SVGPointList.h @@ -22,24 +22,22 @@ #define SVGPointList_h #if ENABLE(SVG) -#include "SVGList.h" -#include "FloatPoint.h" -#include <wtf/Forward.h> -#include <wtf/PassRefPtr.h> +#include "QualifiedName.h" +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebCore { - class SVGPointList : public SVGPODList<FloatPoint> { - public: - static PassRefPtr<SVGPointList> create(const QualifiedName& attributeName) { return adoptRef(new SVGPointList(attributeName)); } +class FloatPoint; - String valueAsString() const; +class SVGPointList : public Vector<FloatPoint> { +public: + SVGPointList() { } - static PassRefPtr<SVGPointList> createAnimated(const SVGPointList* fromList, const SVGPointList* toList, float progress); + String valueAsString() const; - private: - SVGPointList(const QualifiedName&); - }; + static bool createAnimated(const SVGPointList& fromList, const SVGPointList& toList, SVGPointList& resultList, float progress); +}; } // namespace WebCore diff --git a/WebCore/svg/SVGPolyElement.cpp b/WebCore/svg/SVGPolyElement.cpp index 6e935f1..7b95a32 100644 --- a/WebCore/svg/SVGPolyElement.cpp +++ b/WebCore/svg/SVGPolyElement.cpp @@ -39,29 +39,18 @@ SVGPolyElement::SVGPolyElement(const QualifiedName& tagName, Document* document) { } -SVGPointList* SVGPolyElement::points() const -{ - if (!m_points) - m_points = SVGPointList::create(SVGNames::pointsAttr); - - return m_points.get(); -} - -SVGPointList* SVGPolyElement::animatedPoints() const -{ - // FIXME! - return 0; -} - void SVGPolyElement::parseMappedAttribute(Attribute* attr) { const AtomicString& value = attr->value(); if (attr->name() == SVGNames::pointsAttr) { - ExceptionCode ec = 0; - points()->clear(ec); - - if (!pointsListFromSVGData(points(), value)) + SVGPointList newList; + if (!pointsListFromSVGData(newList, value)) document()->accessSVGExtensions()->reportError("Problem parsing points=\"" + value + "\""); + + if (SVGAnimatedListPropertyTearOff<SVGPointList>* list = m_animatablePointsList.get()) + list->detachListWrappers(newList.size()); + + m_points.value = newList; } else { if (SVGTests::parseMappedAttribute(attr)) return; @@ -77,10 +66,6 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); - // The points property is not a regular SVGAnimatedProperty, still we use the same SVG<->XML DOM synchronization framework. - if (attrName == SVGNames::pointsAttr) - invalidateSVGAttributes(); - RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); if (!renderer) return; @@ -109,14 +94,44 @@ void SVGPolyElement::synchronizeProperty(const QualifiedName& attrName) if (attrName == anyQName()) { synchronizeExternalResourcesRequired(); - SVGAnimatedPropertySynchronizer<true>::synchronize(this, SVGNames::pointsAttr, points()->valueAsString()); + synchronizePoints(); return; } if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) synchronizeExternalResourcesRequired(); else if (attrName == SVGNames::pointsAttr) - SVGAnimatedPropertySynchronizer<true>::synchronize(this, attrName, points()->valueAsString()); + synchronizePoints(); +} + +void SVGPolyElement::synchronizePoints() +{ + if (!m_points.shouldSynchronize) + return; + + SVGAnimatedPropertySynchronizer<true>::synchronize(this, SVGNames::pointsAttr, m_points.value.valueAsString()); +} + +SVGListPropertyTearOff<SVGPointList>* SVGPolyElement::points() +{ + if (!m_animatablePointsList) { + m_points.shouldSynchronize = true; + m_animatablePointsList = SVGAnimatedProperty::lookupOrCreateWrapper<SVGAnimatedListPropertyTearOff<SVGPointList> , SVGPointList> + (this, SVGNames::pointsAttr, SVGNames::pointsAttr.localName(), m_points.value); + } + + return static_cast<SVGListPropertyTearOff<SVGPointList>*>(m_animatablePointsList->baseVal()); +} + +SVGListPropertyTearOff<SVGPointList>* SVGPolyElement::animatedPoints() +{ + if (!m_animatablePointsList) { + m_points.shouldSynchronize = true; + m_animatablePointsList = SVGAnimatedProperty::lookupOrCreateWrapper<SVGAnimatedListPropertyTearOff<SVGPointList> , SVGPointList> + (this, SVGNames::pointsAttr, SVGNames::pointsAttr.localName(), m_points.value); + } + + return static_cast<SVGListPropertyTearOff<SVGPointList>*>(m_animatablePointsList->animVal()); } } diff --git a/WebCore/svg/SVGPolyElement.h b/WebCore/svg/SVGPolyElement.h index 64d4abb..0855218 100644 --- a/WebCore/svg/SVGPolyElement.h +++ b/WebCore/svg/SVGPolyElement.h @@ -22,41 +22,46 @@ #define SVGPolyElement_h #if ENABLE(SVG) -#include "SVGAnimatedPoints.h" #include "SVGAnimatedPropertyMacros.h" #include "SVGExternalResourcesRequired.h" #include "SVGLangSpace.h" +#include "SVGPointList.h" #include "SVGStyledTransformableElement.h" #include "SVGTests.h" namespace WebCore { - class SVGPolyElement : public SVGStyledTransformableElement, - public SVGTests, - public SVGLangSpace, - public SVGExternalResourcesRequired, - public SVGAnimatedPoints { - public: - virtual SVGPointList* points() const; - virtual SVGPointList* animatedPoints() const; +class SVGPolyElement : public SVGStyledTransformableElement + , public SVGTests + , public SVGLangSpace + , public SVGExternalResourcesRequired { +public: + SVGListPropertyTearOff<SVGPointList>* points(); + SVGListPropertyTearOff<SVGPointList>* animatedPoints(); - protected: - SVGPolyElement(const QualifiedName&, Document*); + SVGPointList& pointList() const { return m_points.value; } - private: - virtual bool isValid() const { return SVGTests::isValid(); } +protected: + SVGPolyElement(const QualifiedName&, Document*); - virtual void parseMappedAttribute(Attribute*); - virtual void svgAttributeChanged(const QualifiedName&); - virtual void synchronizeProperty(const QualifiedName&); +private: + virtual bool isValid() const { return SVGTests::isValid(); } - virtual bool supportsMarkers() const { return true; } + virtual void parseMappedAttribute(Attribute*); + virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); - // SVGExternalResourcesRequired - DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPolyElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) + virtual bool supportsMarkers() const { return true; } - mutable RefPtr<SVGPointList> m_points; - }; + // SVGExternalResourcesRequired + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPolyElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) + + void synchronizePoints(); + +protected: + mutable SVGSynchronizableAnimatedProperty<SVGPointList> m_points; + RefPtr<SVGAnimatedListPropertyTearOff<SVGPointList> > m_animatablePointsList; +}; } // namespace WebCore diff --git a/WebCore/svg/SVGPolygonElement.cpp b/WebCore/svg/SVGPolygonElement.cpp index 38f5bce..3439a78 100644 --- a/WebCore/svg/SVGPolygonElement.cpp +++ b/WebCore/svg/SVGPolygonElement.cpp @@ -23,8 +23,6 @@ #if ENABLE(SVG) #include "SVGPolygonElement.h" -#include "SVGPointList.h" - namespace WebCore { inline SVGPolygonElement::SVGPolygonElement(const QualifiedName& tagName, Document* document) @@ -41,15 +39,15 @@ void SVGPolygonElement::toPathData(Path& path) const { ASSERT(path.isEmpty()); - int len = points()->numberOfItems(); - if (len < 1) + SVGPointList& points = pointList(); + if (points.isEmpty()) return; - - ExceptionCode ec = 0; - path.moveTo(points()->getItem(0, ec)); - for (int i = 1; i < len; ++i) - path.addLineTo(points()->getItem(i, ec)); + path.moveTo(points.first()); + + unsigned size = points.size(); + for (unsigned i = 1; i < size; ++i) + path.addLineTo(points.at(i)); path.closeSubpath(); } diff --git a/WebCore/svg/SVGPolygonElement.idl b/WebCore/svg/SVGPolygonElement.idl index e58ec38..b767aaa 100644 --- a/WebCore/svg/SVGPolygonElement.idl +++ b/WebCore/svg/SVGPolygonElement.idl @@ -30,8 +30,9 @@ module svg { SVGLangSpace, SVGExternalResourcesRequired, SVGStylable, - SVGTransformable, - SVGAnimatedPoints { + SVGTransformable { + readonly attribute SVGPointList points; + readonly attribute SVGPointList animatedPoints; }; } diff --git a/WebCore/svg/SVGPolylineElement.cpp b/WebCore/svg/SVGPolylineElement.cpp index c9750b2..8bd6d7b 100644 --- a/WebCore/svg/SVGPolylineElement.cpp +++ b/WebCore/svg/SVGPolylineElement.cpp @@ -23,8 +23,6 @@ #if ENABLE(SVG) #include "SVGPolylineElement.h" -#include "SVGPointList.h" - namespace WebCore { inline SVGPolylineElement::SVGPolylineElement(const QualifiedName& tagName, Document* document) @@ -41,15 +39,15 @@ void SVGPolylineElement::toPathData(Path& path) const { ASSERT(path.isEmpty()); - int len = points()->numberOfItems(); - if (len < 1) + SVGPointList& points = pointList(); + if (points.isEmpty()) return; - ExceptionCode ec = 0; - path.moveTo(points()->getItem(0, ec)); + path.moveTo(points.first()); - for (int i = 1; i < len; ++i) - path.addLineTo(points()->getItem(i, ec)); + unsigned size = points.size(); + for (unsigned i = 1; i < size; ++i) + path.addLineTo(points.at(i)); } } diff --git a/WebCore/svg/SVGPolylineElement.idl b/WebCore/svg/SVGPolylineElement.idl index e3f1cd7..b7af89f 100644 --- a/WebCore/svg/SVGPolylineElement.idl +++ b/WebCore/svg/SVGPolylineElement.idl @@ -30,8 +30,9 @@ module svg { SVGLangSpace, SVGExternalResourcesRequired, SVGStylable, - SVGTransformable, - SVGAnimatedPoints { + SVGTransformable { + readonly attribute SVGPointList points; + readonly attribute SVGPointList animatedPoints; }; } diff --git a/WebCore/svg/SVGPreserveAspectRatio.cpp b/WebCore/svg/SVGPreserveAspectRatio.cpp index a129fe6..c9c452e 100644 --- a/WebCore/svg/SVGPreserveAspectRatio.cpp +++ b/WebCore/svg/SVGPreserveAspectRatio.cpp @@ -25,8 +25,9 @@ #include "SVGPreserveAspectRatio.h" #include "AffineTransform.h" +#include "FloatRect.h" #include "SVGParserUtilities.h" -#include "SVGSVGElement.h" +#include <wtf/text/StringConcatenate.h> namespace WebCore { @@ -34,27 +35,26 @@ SVGPreserveAspectRatio::SVGPreserveAspectRatio() : m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID) , m_meetOrSlice(SVG_MEETORSLICE_MEET) { - // FIXME: Should the two values default to UNKNOWN instead? } -void SVGPreserveAspectRatio::setAlign(unsigned short align) +void SVGPreserveAspectRatio::setAlign(unsigned short align, ExceptionCode& ec) { - m_align = align; -} + if (align == SVG_PRESERVEASPECTRATIO_UNKNOWN || align > SVG_PRESERVEASPECTRATIO_XMAXYMAX) { + ec = NOT_SUPPORTED_ERR; + return; + } -unsigned short SVGPreserveAspectRatio::align() const -{ - return m_align; + m_align = static_cast<SVGPreserveAspectRatioType>(align); } -void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice) +void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice, ExceptionCode& ec) { - m_meetOrSlice = meetOrSlice; -} + if (meetOrSlice == SVG_MEETORSLICE_UNKNOWN || meetOrSlice > SVG_MEETORSLICE_SLICE) { + ec = NOT_SUPPORTED_ERR; + return; + } -unsigned short SVGPreserveAspectRatio::meetOrSlice() const -{ - return m_meetOrSlice; + m_meetOrSlice = static_cast<SVGMeetOrSliceType>(meetOrSlice); } SVGPreserveAspectRatio SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate, bool& result) @@ -64,6 +64,7 @@ SVGPreserveAspectRatio SVGPreserveAspectRatio::parsePreserveAspectRatio(const UC aspectRatio.m_meetOrSlice = SVG_MEETORSLICE_MEET; result = false; + // FIXME: Rewrite this parser, without gotos! if (!skipOptionalSpaces(currParam, end)) goto bail_out; @@ -160,167 +161,184 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe FloatSize imageSize = srcRect.size(); float origDestWidth = destRect.width(); float origDestHeight = destRect.height(); - if (meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET) { + switch (m_meetOrSlice) { + case SVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN: + break; + case SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET: + { float widthToHeightMultiplier = srcRect.height() / srcRect.width(); - if (origDestHeight > (origDestWidth * widthToHeightMultiplier)) { + if (origDestHeight > origDestWidth * widthToHeightMultiplier) { destRect.setHeight(origDestWidth * widthToHeightMultiplier); - switch (align()) { + switch (m_align) { case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: - destRect.setY(destRect.y() + origDestHeight / 2.0f - destRect.height() / 2.0f); + destRect.setY(destRect.y() + origDestHeight / 2 - destRect.height() / 2); break; case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: destRect.setY(destRect.y() + origDestHeight - destRect.height()); break; + default: + break; } } - if (origDestWidth > (origDestHeight / widthToHeightMultiplier)) { + if (origDestWidth > origDestHeight / widthToHeightMultiplier) { destRect.setWidth(origDestHeight / widthToHeightMultiplier); - switch (align()) { + switch (m_align) { case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: - destRect.setX(destRect.x() + origDestWidth / 2.0f - destRect.width() / 2.0f); + destRect.setX(destRect.x() + origDestWidth / 2 - destRect.width() / 2); break; case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: destRect.setX(destRect.x() + origDestWidth - destRect.width()); break; + default: + break; } } - } else if (meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE) { + break; + } + case SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE: + { float widthToHeightMultiplier = srcRect.height() / srcRect.width(); // if the destination height is less than the height of the image we'll be drawing - if (origDestHeight < (origDestWidth * widthToHeightMultiplier)) { + if (origDestHeight < origDestWidth * widthToHeightMultiplier) { float destToSrcMultiplier = srcRect.width() / destRect.width(); srcRect.setHeight(destRect.height() * destToSrcMultiplier); - switch (align()) { + switch (m_align) { case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: - srcRect.setY(destRect.y() + imageSize.height() / 2.0f - srcRect.height() / 2.0f); + srcRect.setY(destRect.y() + imageSize.height() / 2 - srcRect.height() / 2); break; case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: srcRect.setY(destRect.y() + imageSize.height() - srcRect.height()); break; + default: + break; } } // if the destination width is less than the width of the image we'll be drawing - if (origDestWidth < (origDestHeight / widthToHeightMultiplier)) { + if (origDestWidth < origDestHeight / widthToHeightMultiplier) { float destToSrcMultiplier = srcRect.height() / destRect.height(); srcRect.setWidth(destRect.width() * destToSrcMultiplier); - switch (align()) { + switch (m_align) { case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: - srcRect.setX(destRect.x() + imageSize.width() / 2.0f - srcRect.width() / 2.0f); + srcRect.setX(destRect.x() + imageSize.width() / 2 - srcRect.width() / 2); break; case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: srcRect.setX(destRect.x() + imageSize.width() - srcRect.width()); break; + default: + break; } } + break; + } } } -AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY, - double logicWidth, double logicHeight, - double /*physX*/, double /*physY*/, - double physWidth, double physHeight) const +// FIXME: We should use floats here, like everywhere else! +AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY, double logicWidth, double logicHeight, double physWidth, double physHeight) const { - AffineTransform temp; + AffineTransform transform; + if (m_align == SVG_PRESERVEASPECTRATIO_UNKNOWN) + return transform; - if (align() == SVG_PRESERVEASPECTRATIO_UNKNOWN) - return temp; + double logicalRatio = logicWidth / logicHeight; + double physRatio = physWidth / physHeight; - double vpar = logicWidth / logicHeight; - double svgar = physWidth / physHeight; + if (m_align == SVG_PRESERVEASPECTRATIO_NONE) { + transform.scaleNonUniform(physWidth / logicWidth, physHeight / logicHeight); + transform.translate(-logicX, -logicY); + return transform; + } - if (align() == SVG_PRESERVEASPECTRATIO_NONE) { - temp.scaleNonUniform(physWidth / logicWidth, physHeight / logicHeight); - temp.translate(-logicX, -logicY); - } else if ((vpar < svgar && (meetOrSlice() == SVG_MEETORSLICE_MEET)) || (vpar >= svgar && (meetOrSlice() == SVG_MEETORSLICE_SLICE))) { - temp.scaleNonUniform(physHeight / logicHeight, physHeight / logicHeight); + if ((logicalRatio < physRatio && (m_meetOrSlice == SVG_MEETORSLICE_MEET)) || (logicalRatio >= physRatio && (m_meetOrSlice == SVG_MEETORSLICE_SLICE))) { + transform.scaleNonUniform(physHeight / logicHeight, physHeight / logicHeight); - if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMINYMAX) - temp.translate(-logicX, -logicY); - else if (align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMAX) - temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight) / 2, -logicY); + if (m_align == SVG_PRESERVEASPECTRATIO_XMINYMIN || m_align == SVG_PRESERVEASPECTRATIO_XMINYMID || m_align == SVG_PRESERVEASPECTRATIO_XMINYMAX) + transform.translate(-logicX, -logicY); + else if (m_align == SVG_PRESERVEASPECTRATIO_XMIDYMIN || m_align == SVG_PRESERVEASPECTRATIO_XMIDYMID || m_align == SVG_PRESERVEASPECTRATIO_XMIDYMAX) + transform.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight) / 2, -logicY); else - temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY); - } else { - temp.scaleNonUniform(physWidth / logicWidth, physWidth / logicWidth); - - if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMAXYMIN) - temp.translate(-logicX, -logicY); - else if (align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMAXYMID) - temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth) / 2); - else - temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth)); + transform.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY); + + return transform; } - return temp; + transform.scaleNonUniform(physWidth / logicWidth, physWidth / logicWidth); + + if (m_align == SVG_PRESERVEASPECTRATIO_XMINYMIN || m_align == SVG_PRESERVEASPECTRATIO_XMIDYMIN || m_align == SVG_PRESERVEASPECTRATIO_XMAXYMIN) + transform.translate(-logicX, -logicY); + else if (m_align == SVG_PRESERVEASPECTRATIO_XMINYMID || m_align == SVG_PRESERVEASPECTRATIO_XMIDYMID || m_align == SVG_PRESERVEASPECTRATIO_XMAXYMID) + transform.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth) / 2); + else + transform.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth)); + + return transform; } String SVGPreserveAspectRatio::valueAsString() const { - String result; + String alignType; - switch ((SVGPreserveAspectRatioType) align()) { - default: + switch (m_align) { case SVG_PRESERVEASPECTRATIO_NONE: - result = "none"; + alignType = "none"; break; case SVG_PRESERVEASPECTRATIO_XMINYMIN: - result = "xMinYMin"; + alignType = "xMinYMin"; break; case SVG_PRESERVEASPECTRATIO_XMIDYMIN: - result = "xMidYMin"; + alignType = "xMidYMin"; break; case SVG_PRESERVEASPECTRATIO_XMAXYMIN: - result = "xMaxYMin"; + alignType = "xMaxYMin"; break; case SVG_PRESERVEASPECTRATIO_XMINYMID: - result = "xMinYMid"; + alignType = "xMinYMid"; break; case SVG_PRESERVEASPECTRATIO_XMIDYMID: - result = "xMidYMid"; + alignType = "xMidYMid"; break; case SVG_PRESERVEASPECTRATIO_XMAXYMID: - result = "xMaxYMid"; + alignType = "xMaxYMid"; break; case SVG_PRESERVEASPECTRATIO_XMINYMAX: - result = "xMinYMax"; + alignType = "xMinYMax"; break; case SVG_PRESERVEASPECTRATIO_XMIDYMAX: - result = "xMidYMax"; + alignType = "xMidYMax"; break; case SVG_PRESERVEASPECTRATIO_XMAXYMAX: - result = "xMaxYMax"; + alignType = "xMaxYMax"; + break; + case SVG_PRESERVEASPECTRATIO_UNKNOWN: + alignType = "unknown"; break; }; - switch ((SVGMeetOrSliceType) meetOrSlice()) { + switch (m_meetOrSlice) { default: case SVG_MEETORSLICE_UNKNOWN: - break; + return alignType; case SVG_MEETORSLICE_MEET: - result += " meet"; - break; + return makeString(alignType, " meet"); case SVG_MEETORSLICE_SLICE: - result += " slice"; - break; + return makeString(alignType, " slice"); }; - - return result; } } diff --git a/WebCore/svg/SVGPreserveAspectRatio.h b/WebCore/svg/SVGPreserveAspectRatio.h index f29b7d3..eda82d4 100644 --- a/WebCore/svg/SVGPreserveAspectRatio.h +++ b/WebCore/svg/SVGPreserveAspectRatio.h @@ -22,72 +22,70 @@ #define SVGPreserveAspectRatio_h #if ENABLE(SVG) -#include "FloatRect.h" -#include "PlatformString.h" -#include "SVGNames.h" -#include <wtf/Forward.h> +#include "ExceptionCode.h" +#include <wtf/text/WTFString.h> namespace WebCore { - class AffineTransform; - - class SVGPreserveAspectRatio { - public: - enum SVGPreserveAspectRatioType { - SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, - SVG_PRESERVEASPECTRATIO_NONE = 1, - SVG_PRESERVEASPECTRATIO_XMINYMIN = 2, - SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3, - SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4, - SVG_PRESERVEASPECTRATIO_XMINYMID = 5, - SVG_PRESERVEASPECTRATIO_XMIDYMID = 6, - SVG_PRESERVEASPECTRATIO_XMAXYMID = 7, - SVG_PRESERVEASPECTRATIO_XMINYMAX = 8, - SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9, - SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10 - }; - - enum SVGMeetOrSliceType { - SVG_MEETORSLICE_UNKNOWN = 0, - SVG_MEETORSLICE_MEET = 1, - SVG_MEETORSLICE_SLICE = 2 - }; - - SVGPreserveAspectRatio(); - - void setAlign(unsigned short); - unsigned short align() const; - - void setMeetOrSlice(unsigned short); - unsigned short meetOrSlice() const; - - void transformRect(FloatRect& destRect, FloatRect& srcRect); - - AffineTransform getCTM(double logicX, double logicY, - double logicWidth, double logicHeight, - double physX, double physY, - double physWidth, double physHeight) const; - - template<class Consumer> - static bool parsePreserveAspectRatio(Consumer* consumer, const String& value, bool validate = true) - { - bool result = false; - const UChar* begin = value.characters(); - const UChar* end = begin + value.length(); - consumer->setPreserveAspectRatioBaseValue(parsePreserveAspectRatio(begin, end, validate, result)); - return result; - } - - // It's recommended to use the method above, only SVGViewSpec needs this parsing method - static SVGPreserveAspectRatio parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate, bool& result); - - String valueAsString() const; - - private: - unsigned short m_align; - unsigned short m_meetOrSlice; +class AffineTransform; +class FloatRect; + +class SVGPreserveAspectRatio { +public: + enum SVGPreserveAspectRatioType { + SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, + SVG_PRESERVEASPECTRATIO_NONE = 1, + SVG_PRESERVEASPECTRATIO_XMINYMIN = 2, + SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3, + SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4, + SVG_PRESERVEASPECTRATIO_XMINYMID = 5, + SVG_PRESERVEASPECTRATIO_XMIDYMID = 6, + SVG_PRESERVEASPECTRATIO_XMAXYMID = 7, + SVG_PRESERVEASPECTRATIO_XMINYMAX = 8, + SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9, + SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10 }; + enum SVGMeetOrSliceType { + SVG_MEETORSLICE_UNKNOWN = 0, + SVG_MEETORSLICE_MEET = 1, + SVG_MEETORSLICE_SLICE = 2 + }; + + SVGPreserveAspectRatio(); + + void setAlign(unsigned short align, ExceptionCode&); + unsigned short align() const { return m_align; } + + void setMeetOrSlice(unsigned short, ExceptionCode&); + unsigned short meetOrSlice() const { return m_meetOrSlice; } + + void transformRect(FloatRect& destRect, FloatRect& srcRect); + + AffineTransform getCTM(double logicX, double logicY, + double logicWidth, double logicHeight, + double physWidth, double physHeight) const; + + template<class Consumer> + static bool parsePreserveAspectRatio(Consumer* consumer, const String& value, bool validate = true) + { + bool result = false; + const UChar* begin = value.characters(); + const UChar* end = begin + value.length(); + consumer->setPreserveAspectRatioBaseValue(parsePreserveAspectRatio(begin, end, validate, result)); + return result; + } + + // It's recommended to use the method above, only SVGViewSpec needs this parsing method + static SVGPreserveAspectRatio parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate, bool& result); + + String valueAsString() const; + +private: + SVGPreserveAspectRatioType m_align; + SVGMeetOrSliceType m_meetOrSlice; +}; + } // namespace WebCore #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGPreserveAspectRatio.idl b/WebCore/svg/SVGPreserveAspectRatio.idl index 7537e9b..80696e7 100644 --- a/WebCore/svg/SVGPreserveAspectRatio.idl +++ b/WebCore/svg/SVGPreserveAspectRatio.idl @@ -25,10 +25,10 @@ module svg { - interface [Conditional=SVG, PODType=SVGPreserveAspectRatio] SVGPreserveAspectRatio { + interface [Conditional=SVG] SVGPreserveAspectRatio { // Alignment Types - const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0; - const unsigned short SVG_PRESERVEASPECTRATIO_NONE = 1; + const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0; + const unsigned short SVG_PRESERVEASPECTRATIO_NONE = 1; const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMIN = 2; const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3; const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4; @@ -38,15 +38,17 @@ module svg { const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMAX = 8; const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9; const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10; + // Meet-or-slice Types - const unsigned short SVG_MEETORSLICE_UNKNOWN = 0; - const unsigned short SVG_MEETORSLICE_MEET = 1; - const unsigned short SVG_MEETORSLICE_SLICE = 2; + const unsigned short SVG_MEETORSLICE_UNKNOWN = 0; + const unsigned short SVG_MEETORSLICE_MEET = 1; + const unsigned short SVG_MEETORSLICE_SLICE = 2; + + attribute [StrictTypeChecking] unsigned short align + setter raises(DOMException); - attribute unsigned short align - /*setter raises(DOMException)*/; - attribute unsigned short meetOrSlice - /*setter raises(DOMException)*/; + attribute [StrictTypeChecking] unsigned short meetOrSlice + setter raises(DOMException); }; } diff --git a/WebCore/svg/SVGSVGElement.cpp b/WebCore/svg/SVGSVGElement.cpp index 2354b27..314f522 100644 --- a/WebCore/svg/SVGSVGElement.cpp +++ b/WebCore/svg/SVGSVGElement.cpp @@ -213,14 +213,14 @@ void SVGSVGElement::setCurrentScale(float scale) RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); } -FloatPoint SVGSVGElement::currentTranslate() const +void SVGSVGElement::setCurrentTranslate(const FloatPoint& translation) { - return m_translation; + m_translation = translation; + updateCurrentTranslate(); } -void SVGSVGElement::setCurrentTranslate(const FloatPoint &translation) +void SVGSVGElement::updateCurrentTranslate() { - m_translation = translation; if (RenderObject* object = renderer()) object->setNeedsLayout(true); diff --git a/WebCore/svg/SVGSVGElement.h b/WebCore/svg/SVGSVGElement.h index b2a5812..dca3ac2 100644 --- a/WebCore/svg/SVGSVGElement.h +++ b/WebCore/svg/SVGSVGElement.h @@ -78,9 +78,12 @@ namespace WebCore { float currentScale() const; void setCurrentScale(float scale); - FloatPoint currentTranslate() const; + FloatPoint& currentTranslate() { return m_translation; } void setCurrentTranslate(const FloatPoint&); - + + // Only used from the bindings. + void updateCurrentTranslate(); + SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); } void pauseAnimations(); @@ -147,7 +150,7 @@ namespace WebCore { // SVGFitToViewBox DECLARE_ANIMATED_PROPERTY_NEW(SVGSVGElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) - DECLARE_ANIMATED_PROPERTY(SVGSVGElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY_NEW(SVGSVGElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) virtual void documentWillBecomeInactive(); virtual void documentDidBecomeActive(); diff --git a/WebCore/svg/SVGScriptElement.h b/WebCore/svg/SVGScriptElement.h index d4eb61d..e8695fb 100644 --- a/WebCore/svg/SVGScriptElement.h +++ b/WebCore/svg/SVGScriptElement.h @@ -76,7 +76,7 @@ namespace WebCore { virtual void dispatchErrorEvent(); // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGScriptElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGScriptElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGScriptElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGStopElement.h b/WebCore/svg/SVGStopElement.h index 232b97a..8da2655 100644 --- a/WebCore/svg/SVGStopElement.h +++ b/WebCore/svg/SVGStopElement.h @@ -22,7 +22,7 @@ #define SVGStopElement_h #if ENABLE(SVG) -#include "SVGNames.h" +#include "SVGAnimatedPropertyMacros.h" #include "SVGStyledElement.h" namespace WebCore { @@ -44,7 +44,7 @@ namespace WebCore { virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - DECLARE_ANIMATED_PROPERTY(SVGStopElement, SVGNames::offsetAttr, float, Offset, offset) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGStopElement, SVGNames::offsetAttr, float, Offset, offset) }; } // namespace WebCore diff --git a/WebCore/svg/SVGStringList.cpp b/WebCore/svg/SVGStringList.cpp index 9f4809f..3eb392a 100644 --- a/WebCore/svg/SVGStringList.cpp +++ b/WebCore/svg/SVGStringList.cpp @@ -23,29 +23,31 @@ #if ENABLE(SVG) #include "SVGStringList.h" +#include "SVGElement.h" #include "SVGParserUtilities.h" namespace WebCore { -SVGStringList::SVGStringList(const QualifiedName& attributeName) - : SVGList<String>(attributeName) +void SVGStringList::commitChange(SVGElement* contextElement) { + ASSERT(contextElement); + contextElement->invalidateSVGAttributes(); + contextElement->svgAttributeChanged(m_attributeName); } -void SVGStringList::reset(const String& str) +void SVGStringList::reset(const String& string) { - ExceptionCode ec = 0; + parse(string, ' '); - parse(str, ' '); - if (numberOfItems() == 0) - appendItem(String(""), ec); // Create empty string... + // Add empty string, if list is empty. + if (isEmpty()) + append(String("")); } void SVGStringList::parse(const String& data, UChar delimiter) { // TODO : more error checking/reporting - ExceptionCode ec = 0; - clear(ec); + clear(); const UChar* ptr = data.characters(); const UChar* end = ptr + data.length(); @@ -55,7 +57,7 @@ void SVGStringList::parse(const String& data, UChar delimiter) ptr++; if (ptr == start) break; - appendItem(String(start, ptr - start), ec); + append(String(start, ptr - start)); skipOptionalSpacesOrDelimiter(ptr, end, delimiter); } } diff --git a/WebCore/svg/SVGStringList.h b/WebCore/svg/SVGStringList.h index e8841ea..c741b9d 100644 --- a/WebCore/svg/SVGStringList.h +++ b/WebCore/svg/SVGStringList.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> * * This library is free software; you can redistribute it and/or @@ -22,23 +22,32 @@ #define SVGStringList_h #if ENABLE(SVG) -#include "PlatformString.h" -#include "SVGList.h" +#include "QualifiedName.h" +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebCore { - class SVGStringList : public SVGList<String> { - public: - static PassRefPtr<SVGStringList> create(const QualifiedName& attributeName) { return adoptRef(new SVGStringList(attributeName)); } +class SVGElement; - void reset(const String& str); - void parse(const String& data, UChar delimiter = ','); - - private: - SVGStringList(const QualifiedName&); - }; +class SVGStringList : public Vector<String> { +public: + SVGStringList(const QualifiedName& attributeName) + : m_attributeName(attributeName) + { + } + + void reset(const String&); + void parse(const String&, UChar delimiter = ','); + + // Only used by SVGStringListPropertyTearOff. + void commitChange(SVGElement* contextElement); + +private: + const QualifiedName& m_attributeName; +}; } // namespace WebCore #endif // ENABLE(SVG) -#endif // SVGStringList_h +#endif diff --git a/WebCore/svg/SVGStyledElement.h b/WebCore/svg/SVGStyledElement.h index 5e996b3..4f796b8 100644 --- a/WebCore/svg/SVGStyledElement.h +++ b/WebCore/svg/SVGStyledElement.h @@ -22,8 +22,8 @@ #define SVGStyledElement_h #if ENABLE(SVG) +#include "SVGAnimatedPropertyMacros.h" #include "HTMLNames.h" -#include "SVGElement.h" #include "SVGLocatable.h" #include "SVGStylable.h" #include <wtf/HashSet.h> @@ -83,7 +83,7 @@ namespace WebCore { HashSet<SVGStyledElement*> m_elementsWithRelativeLengths; - DECLARE_ANIMATED_PROPERTY(SVGStyledElement, HTMLNames::classAttr, String, ClassName, className) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGStyledElement, HTMLNames::classAttr, String, ClassName, className) }; } // namespace WebCore diff --git a/WebCore/svg/SVGStyledTransformableElement.cpp b/WebCore/svg/SVGStyledTransformableElement.cpp index 9b34203..87d812c 100644 --- a/WebCore/svg/SVGStyledTransformableElement.cpp +++ b/WebCore/svg/SVGStyledTransformableElement.cpp @@ -54,7 +54,7 @@ AffineTransform SVGStyledTransformableElement::getScreenCTM(StyleUpdateStrategy AffineTransform SVGStyledTransformableElement::animatedLocalTransform() const { - return m_supplementalTransform ? transform()->concatenate().matrix() * *m_supplementalTransform : transform()->concatenate().matrix(); + return m_supplementalTransform ? *m_supplementalTransform * transform()->concatenate().matrix() : transform()->concatenate().matrix(); } AffineTransform* SVGStyledTransformableElement::supplementalTransform() diff --git a/WebCore/svg/SVGStyledTransformableElement.h b/WebCore/svg/SVGStyledTransformableElement.h index 5349cfa..f6309dd 100644 --- a/WebCore/svg/SVGStyledTransformableElement.h +++ b/WebCore/svg/SVGStyledTransformableElement.h @@ -23,6 +23,7 @@ #if ENABLE(SVG) #include "Path.h" +#include "SVGAnimatedPropertyMacros.h" #include "SVGStyledLocatableElement.h" #include "SVGTransformable.h" diff --git a/WebCore/svg/SVGSymbolElement.h b/WebCore/svg/SVGSymbolElement.h index 6c561f2..1aa7cbf 100644 --- a/WebCore/svg/SVGSymbolElement.h +++ b/WebCore/svg/SVGSymbolElement.h @@ -52,7 +52,7 @@ namespace WebCore { // SVGFitToViewBox DECLARE_ANIMATED_PROPERTY_NEW(SVGSymbolElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) - DECLARE_ANIMATED_PROPERTY(SVGSymbolElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY_NEW(SVGSymbolElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTRefElement.h b/WebCore/svg/SVGTRefElement.h index 7a79ae5..ffbfa55 100644 --- a/WebCore/svg/SVGTRefElement.h +++ b/WebCore/svg/SVGTRefElement.h @@ -45,7 +45,7 @@ namespace WebCore { void updateReferencedText(); // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGTRefElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGTRefElement, XLinkNames::hrefAttr, String, Href, href) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTests.cpp b/WebCore/svg/SVGTests.cpp index e4813cd..3317964 100644 --- a/WebCore/svg/SVGTests.cpp +++ b/WebCore/svg/SVGTests.cpp @@ -26,63 +26,41 @@ #include "Attribute.h" #include "DOMImplementation.h" #include "Language.h" -#include "SVGElement.h" #include "SVGNames.h" #include "SVGStringList.h" namespace WebCore { SVGTests::SVGTests() + : m_features(SVGNames::requiredFeaturesAttr) + , m_extensions(SVGNames::requiredExtensionsAttr) + , m_systemLanguage(SVGNames::systemLanguageAttr) { } -SVGTests::~SVGTests() +bool SVGTests::hasExtension(const String&) const { -} - -SVGStringList* SVGTests::requiredFeatures() const -{ - if (!m_features) - m_features = SVGStringList::create(SVGNames::requiredFeaturesAttr); - - return m_features.get(); -} - -SVGStringList* SVGTests::requiredExtensions() const -{ - if (!m_extensions) - m_extensions = SVGStringList::create(SVGNames::requiredExtensionsAttr); - - return m_extensions.get(); -} - -SVGStringList* SVGTests::systemLanguage() const -{ - if (!m_systemLanguage) - m_systemLanguage = SVGStringList::create(SVGNames::systemLanguageAttr); - - return m_systemLanguage.get(); + // FIXME: Implement me! + return false; } bool SVGTests::isValid() const { - ExceptionCode ec = 0; - - if (m_features) { - for (unsigned long i = 0; i < m_features->numberOfItems(); i++) { - String value = m_features->getItem(i, ec); - if (value.isEmpty() || !DOMImplementation::hasFeature(value, String())) - return false; - } + unsigned featuresSize = m_features.size(); + for (unsigned i = 0; i < featuresSize; ++i) { + String value = m_features.at(i); + if (value.isEmpty() || !DOMImplementation::hasFeature(value, String())) + return false; } - if (m_systemLanguage) { - for (unsigned long i = 0; i < m_systemLanguage->numberOfItems(); i++) - if (m_systemLanguage->getItem(i, ec) != defaultLanguage().substring(0, 2)) - return false; + unsigned systemLanguageSize = m_systemLanguage.size(); + for (unsigned i = 0; i < systemLanguageSize; ++i) { + String value = m_systemLanguage.at(i); + if (value != defaultLanguage().substring(0, 2)) + return false; } - if (m_extensions && m_extensions->numberOfItems() > 0) + if (!m_extensions.isEmpty()) return false; return true; @@ -91,13 +69,13 @@ bool SVGTests::isValid() const bool SVGTests::parseMappedAttribute(Attribute* attr) { if (attr->name() == SVGNames::requiredFeaturesAttr) { - requiredFeatures()->reset(attr->value()); + m_features.reset(attr->value()); return true; } else if (attr->name() == SVGNames::requiredExtensionsAttr) { - requiredExtensions()->reset(attr->value()); + m_extensions.reset(attr->value()); return true; } else if (attr->name() == SVGNames::systemLanguageAttr) { - systemLanguage()->reset(attr->value()); + m_systemLanguage.reset(attr->value()); return true; } @@ -106,9 +84,9 @@ bool SVGTests::parseMappedAttribute(Attribute* attr) bool SVGTests::isKnownAttribute(const QualifiedName& attrName) { - return (attrName == SVGNames::requiredFeaturesAttr || - attrName == SVGNames::requiredExtensionsAttr || - attrName == SVGNames::systemLanguageAttr); + return attrName == SVGNames::requiredFeaturesAttr + || attrName == SVGNames::requiredExtensionsAttr + || attrName == SVGNames::systemLanguageAttr; } } diff --git a/WebCore/svg/SVGTests.h b/WebCore/svg/SVGTests.h index c5bb70f..f662e9a 100644 --- a/WebCore/svg/SVGTests.h +++ b/WebCore/svg/SVGTests.h @@ -22,37 +22,33 @@ #define SVGTests_h #if ENABLE(SVG) -#include <wtf/Forward.h> -#include <wtf/RefPtr.h> +#include "SVGStringList.h" namespace WebCore { - class Attribute; - class QualifiedName; - class SVGStringList; +class Attribute; +class QualifiedName; - class SVGTests { - public: - SVGStringList* requiredFeatures() const; - SVGStringList* requiredExtensions() const; - SVGStringList* systemLanguage() const; +class SVGTests { +public: + SVGStringList& requiredFeatures() { return m_features; } + SVGStringList& requiredExtensions() { return m_extensions; } + SVGStringList& systemLanguage() { return m_systemLanguage; } - bool hasExtension(const String&) const { return false; } + bool hasExtension(const String&) const; + bool isValid() const; - bool isValid() const; - - bool parseMappedAttribute(Attribute*); - bool isKnownAttribute(const QualifiedName&); + bool parseMappedAttribute(Attribute*); + bool isKnownAttribute(const QualifiedName&); - protected: - SVGTests(); - ~SVGTests(); +protected: + SVGTests(); - private: - mutable RefPtr<SVGStringList> m_features; - mutable RefPtr<SVGStringList> m_extensions; - mutable RefPtr<SVGStringList> m_systemLanguage; - }; +private: + SVGStringList m_features; + SVGStringList m_extensions; + SVGStringList m_systemLanguage; +}; } // namespace WebCore diff --git a/WebCore/svg/SVGTextPathElement.h b/WebCore/svg/SVGTextPathElement.h index b06c2bf..2375078 100644 --- a/WebCore/svg/SVGTextPathElement.h +++ b/WebCore/svg/SVGTextPathElement.h @@ -72,7 +72,7 @@ namespace WebCore { DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGTextPathElement, SVGNames::spacingAttr, int, Spacing, spacing) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGTextPathElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGTextPathElement, XLinkNames::hrefAttr, String, Href, href) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTextPositioningElement.cpp b/WebCore/svg/SVGTextPositioningElement.cpp index d64dd1f..dc1f915 100644 --- a/WebCore/svg/SVGTextPositioningElement.cpp +++ b/WebCore/svg/SVGTextPositioningElement.cpp @@ -34,7 +34,6 @@ namespace WebCore { SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document* document) : SVGTextContentElement(tagName, document) - , m_rotate(SVGNumberList::create(SVGNames::rotateAttr)) { } @@ -60,9 +59,12 @@ void SVGTextPositioningElement::parseMappedAttribute(Attribute* attr) newList.parse(attr->value(), LengthModeHeight); detachAnimatedDyListWrappers(newList.size()); dyBaseValue() = newList; - } else if (attr->name() == SVGNames::rotateAttr) - rotateBaseValue()->parse(attr->value()); - else + } else if (attr->name() == SVGNames::rotateAttr) { + SVGNumberList newList; + newList.parse(attr->value()); + detachAnimatedRotateListWrappers(newList.size()); + rotateBaseValue() = newList; + } else SVGTextContentElement::parseMappedAttribute(attr); } diff --git a/WebCore/svg/SVGTextPositioningElement.h b/WebCore/svg/SVGTextPositioningElement.h index 1fb1c3c..e1798de 100644 --- a/WebCore/svg/SVGTextPositioningElement.h +++ b/WebCore/svg/SVGTextPositioningElement.h @@ -46,7 +46,7 @@ namespace WebCore { DECLARE_ANIMATED_LIST_PROPERTY_NEW(SVGTextPositioningElement, SVGNames::yAttr, SVGLengthList, Y, y) DECLARE_ANIMATED_LIST_PROPERTY_NEW(SVGTextPositioningElement, SVGNames::dxAttr, SVGLengthList, Dx, dx) DECLARE_ANIMATED_LIST_PROPERTY_NEW(SVGTextPositioningElement, SVGNames::dyAttr, SVGLengthList, Dy, dy) - DECLARE_ANIMATED_PROPERTY(SVGTextPositioningElement, SVGNames::rotateAttr, SVGNumberList*, Rotate, rotate) + DECLARE_ANIMATED_LIST_PROPERTY_NEW(SVGTextPositioningElement, SVGNames::rotateAttr, SVGNumberList, Rotate, rotate) }; } // namespace WebCore diff --git a/WebCore/svg/SVGURIReference.h b/WebCore/svg/SVGURIReference.h index 096f5a5..3804791 100644 --- a/WebCore/svg/SVGURIReference.h +++ b/WebCore/svg/SVGURIReference.h @@ -27,20 +27,20 @@ namespace WebCore { - class Attribute; +class Attribute; - class SVGURIReference { - public: - virtual ~SVGURIReference() { } +class SVGURIReference { +public: + virtual ~SVGURIReference() { } - bool parseMappedAttribute(Attribute*); - bool isKnownAttribute(const QualifiedName&); + bool parseMappedAttribute(Attribute*); + bool isKnownAttribute(const QualifiedName&); - static String getTarget(const String& url); + static String getTarget(const String& url); - protected: - virtual void setHrefBaseValue(DeprecatedSVGAnimatedPropertyTraits<String>::PassType) = 0; - }; +protected: + virtual void setHrefBaseValue(const String&) = 0; +}; } // namespace WebCore diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp index 474b0a4..75ed4c5 100644 --- a/WebCore/svg/SVGUseElement.cpp +++ b/WebCore/svg/SVGUseElement.cpp @@ -948,6 +948,9 @@ void SVGUseElement::associateInstancesWithShadowTreeElements(Node* target, SVGEl while (node && !node->isSVGElement()) node = node->nextSibling(); + if (!node) + break; + associateInstancesWithShadowTreeElements(node, instance); node = node->nextSibling(); } diff --git a/WebCore/svg/SVGUseElement.h b/WebCore/svg/SVGUseElement.h index bb7e6d0..b127450 100644 --- a/WebCore/svg/SVGUseElement.h +++ b/WebCore/svg/SVGUseElement.h @@ -87,7 +87,7 @@ namespace WebCore { DECLARE_ANIMATED_PROPERTY_NEW(SVGUseElement, SVGNames::heightAttr, SVGLength, Height, height) // SVGURIReference - DECLARE_ANIMATED_PROPERTY(SVGUseElement, XLinkNames::hrefAttr, String, Href, href) + DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGUseElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGUseElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGViewElement.cpp b/WebCore/svg/SVGViewElement.cpp index 6a83066..c59a080 100644 --- a/WebCore/svg/SVGViewElement.cpp +++ b/WebCore/svg/SVGViewElement.cpp @@ -34,6 +34,7 @@ namespace WebCore { inline SVGViewElement::SVGViewElement(const QualifiedName& tagName, Document* document) : SVGStyledElement(tagName, document) + , m_viewTarget(SVGNames::viewTargetAttr) { } @@ -42,18 +43,10 @@ PassRefPtr<SVGViewElement> SVGViewElement::create(const QualifiedName& tagName, return adoptRef(new SVGViewElement(tagName, document)); } -SVGStringList* SVGViewElement::viewTarget() const -{ - if (!m_viewTarget) - m_viewTarget = SVGStringList::create(SVGNames::viewTargetAttr); - - return m_viewTarget.get(); -} - void SVGViewElement::parseMappedAttribute(Attribute* attr) { if (attr->name() == SVGNames::viewTargetAttr) - viewTarget()->reset(attr->value()); + viewTarget().reset(attr->value()); else { if (SVGExternalResourcesRequired::parseMappedAttribute(attr) || SVGFitToViewBox::parseMappedAttribute(document(), attr) diff --git a/WebCore/svg/SVGViewElement.h b/WebCore/svg/SVGViewElement.h index f0e756f..7e239e3 100644 --- a/WebCore/svg/SVGViewElement.h +++ b/WebCore/svg/SVGViewElement.h @@ -23,6 +23,7 @@ #if ENABLE(SVG) #include "SVGAnimatedPropertyMacros.h" +#include "SVGStringList.h" #include "SVGStyledElement.h" #include "SVGExternalResourcesRequired.h" #include "SVGFitToViewBox.h" @@ -30,7 +31,6 @@ namespace WebCore { - class SVGStringList; class SVGViewElement : public SVGStyledElement, public SVGExternalResourcesRequired, public SVGFitToViewBox, @@ -38,7 +38,7 @@ namespace WebCore { public: static PassRefPtr<SVGViewElement> create(const QualifiedName&, Document*); - SVGStringList* viewTarget() const; + SVGStringList& viewTarget() { return m_viewTarget; } private: SVGViewElement(const QualifiedName&, Document*); @@ -53,9 +53,9 @@ namespace WebCore { // SVGFitToViewBox DECLARE_ANIMATED_PROPERTY_NEW(SVGViewElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) - DECLARE_ANIMATED_PROPERTY(SVGViewElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) - - mutable RefPtr<SVGStringList> m_viewTarget; + DECLARE_ANIMATED_PROPERTY_NEW(SVGViewElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + + SVGStringList m_viewTarget; }; } // namespace WebCore diff --git a/WebCore/svg/SVGViewSpec.h b/WebCore/svg/SVGViewSpec.h index 6fcc94e..f557d23 100644 --- a/WebCore/svg/SVGViewSpec.h +++ b/WebCore/svg/SVGViewSpec.h @@ -59,7 +59,7 @@ namespace WebCore { // SVGFitToViewBox DECLARE_ANIMATED_PROPERTY_NEW(SVGViewSpec, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) - DECLARE_ANIMATED_PROPERTY(SVGViewSpec, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY_NEW(SVGViewSpec, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) mutable RefPtr<SVGTransformList> m_transform; String m_viewTargetString; diff --git a/WebCore/svg/animation/SVGSMILElement.cpp b/WebCore/svg/animation/SVGSMILElement.cpp index a90b444..6757fee 100644 --- a/WebCore/svg/animation/SVGSMILElement.cpp +++ b/WebCore/svg/animation/SVGSMILElement.cpp @@ -528,7 +528,8 @@ SMILTime SVGSMILElement::repeatDur() const return m_cachedRepeatDur; const AtomicString& value = getAttribute(SVGNames::repeatDurAttr); SMILTime clockValue = parseClockValue(value); - return m_cachedRepeatDur = clockValue < 0 ? SMILTime::unresolved() : clockValue; + m_cachedRepeatDur = clockValue <= 0 ? SMILTime::unresolved() : clockValue; + return m_cachedRepeatDur; } // So a count is not really a time but let just all pretend we did not notice. diff --git a/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h b/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h index c002d09..0777b6a 100644 --- a/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h +++ b/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h @@ -23,6 +23,7 @@ #if ENABLE(SVG) #include "SVGAnimatedProperty.h" #include "SVGListPropertyTearOff.h" +#include "SVGStaticListPropertyTearOff.h" namespace WebCore { @@ -32,17 +33,21 @@ class SVGPropertyTearOff; template<typename PropertyType> class SVGAnimatedListPropertyTearOff : public SVGAnimatedProperty { public: + typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; + typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; + typedef Vector<RefPtr<ListItemTearOff> > ListWrapperCache; + SVGProperty* baseVal() { if (!m_baseVal) - m_baseVal = SVGListPropertyTearOff<PropertyType>::create(this, BaseValRole, m_property); + m_baseVal = SVGListPropertyTearOff<PropertyType>::create(this, BaseValRole); return m_baseVal.get(); } SVGProperty* animVal() { if (!m_animVal) - m_animVal = SVGListPropertyTearOff<PropertyType>::create(this, AnimValRole, m_property); + m_animVal = SVGListPropertyTearOff<PropertyType>::create(this, AnimValRole); return m_animVal.get(); } @@ -50,39 +55,56 @@ public: int removeItemFromList(SVGProperty* property, bool shouldSynchronizeWrappers) { - // FIXME: No animVal support. - if (!m_baseVal) - return -1; - + // This should ever be called for our baseVal, as animVal can't modify the list. typedef SVGPropertyTearOff<typename SVGPropertyTraits<PropertyType>::ListItemType> ListItemTearOff; return static_pointer_cast<SVGListPropertyTearOff<PropertyType> >(m_baseVal)->removeItemFromList(static_cast<ListItemTearOff*>(property), shouldSynchronizeWrappers); } void detachListWrappers(unsigned newListSize) { - if (m_baseVal) - static_pointer_cast<SVGListPropertyTearOff<PropertyType> >(m_baseVal)->detachListWrappers(newListSize); - if (m_animVal) - static_pointer_cast<SVGListPropertyTearOff<PropertyType> >(m_animVal)->detachListWrappers(newListSize); + // See SVGPropertyTearOff::detachWrapper() for an explaination what's happening here. + unsigned size = m_wrappers.size(); + ASSERT(size == m_values.size()); + for (unsigned i = 0; i < size; ++i) { + RefPtr<ListItemTearOff>& item = m_wrappers.at(i); + if (!item) + continue; + item->detachWrapper(); + } + + // Reinitialize the wrapper cache to be equal to the new values size, after the XML DOM changed the list. + if (newListSize) + m_wrappers.fill(0, newListSize); + else + m_wrappers.clear(); } + PropertyType& values() { return m_values; } + ListWrapperCache& wrappers() { return m_wrappers; } + private: friend class SVGAnimatedProperty; - static PassRefPtr<SVGAnimatedListPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, PropertyType& property) + static PassRefPtr<SVGAnimatedListPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, PropertyType& values) { ASSERT(contextElement); - return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(contextElement, attributeName, property)); + return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(contextElement, attributeName, values)); } - SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, PropertyType& property) + SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, PropertyType& values) : SVGAnimatedProperty(contextElement, attributeName) - , m_property(property) + , m_values(values) { + if (!values.isEmpty()) + m_wrappers.fill(0, values.size()); } private: - PropertyType& m_property; + PropertyType& m_values; + + // FIXME: The list wrapper cache is shared between baseVal/animVal. If we implement animVal, + // we need two seperated wrapper caches if the attribute gets animated. + ListWrapperCache m_wrappers; RefPtr<SVGProperty> m_baseVal; RefPtr<SVGProperty> m_animVal; diff --git a/WebCore/svg/properties/SVGAnimatedPropertyMacros.h b/WebCore/svg/properties/SVGAnimatedPropertyMacros.h index 12d0565..e1c75b9 100644 --- a/WebCore/svg/properties/SVGAnimatedPropertyMacros.h +++ b/WebCore/svg/properties/SVGAnimatedPropertyMacros.h @@ -32,6 +32,42 @@ namespace WebCore { +class SVGElement; + +// GetOwnerElementForType implementation +template<typename OwnerType, bool isDerivedFromSVGElement> +struct GetOwnerElementForType; + +template<typename OwnerType> +struct GetOwnerElementForType<OwnerType, true> { + static SVGElement* ownerElement(OwnerType* type) + { + return type; + } +}; + +template<typename OwnerType> +struct GetOwnerElementForType<OwnerType, false> { + static SVGElement* ownerElement(OwnerType* type) + { + SVGElement* context = type->contextElement(); + ASSERT(context); + return context; + } +}; + +// IsDerivedFromSVGElement implementation +template<typename OwnerType> +struct IsDerivedFromSVGElement { + static const bool value = true; +}; + +class SVGViewSpec; +template<> +struct IsDerivedFromSVGElement<SVGViewSpec> { + static const bool value = false; +}; + template<typename PropertyType> struct SVGSynchronizableAnimatedProperty { SVGSynchronizableAnimatedProperty() diff --git a/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h b/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h index 2b816ab..b97073d 100644 --- a/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h +++ b/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h @@ -23,42 +23,6 @@ #if ENABLE(SVG) namespace WebCore { -class SVGElement; - -// GetOwnerElementForType implementation -template<typename OwnerType, bool isDerivedFromSVGElement> -struct GetOwnerElementForType; - -template<typename OwnerType> -struct GetOwnerElementForType<OwnerType, true> : public Noncopyable { - static SVGElement* ownerElement(OwnerType* type) - { - return type; - } -}; - -template<typename OwnerType> -struct GetOwnerElementForType<OwnerType, false> : public Noncopyable { - static SVGElement* ownerElement(OwnerType* type) - { - SVGElement* context = type->contextElement(); - ASSERT(context); - return context; - } -}; - -// IsDerivedFromSVGElement implementation -template<typename OwnerType> -struct IsDerivedFromSVGElement : public Noncopyable { - static const bool value = true; -}; - -class SVGViewSpec; -template<> -struct IsDerivedFromSVGElement<SVGViewSpec> : public Noncopyable { - static const bool value = false; -}; - // Helper template used for synchronizing SVG <-> XML properties template<bool isDerivedFromSVGElement> struct SVGAnimatedPropertySynchronizer { diff --git a/WebCore/svg/properties/SVGListProperty.h b/WebCore/svg/properties/SVGListProperty.h new file mode 100644 index 0000000..7edc0f1 --- /dev/null +++ b/WebCore/svg/properties/SVGListProperty.h @@ -0,0 +1,412 @@ +/* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SVGListProperty_h +#define SVGListProperty_h + +#if ENABLE(SVG) +#include "ExceptionCode.h" +#include "SVGAnimatedProperty.h" +#include "SVGPropertyTearOff.h" +#include "SVGPropertyTraits.h" + +namespace WebCore { + +template<typename PropertyType> +class SVGAnimatedListPropertyTearOff; + +template<typename PropertyType> +class SVGListProperty : public SVGProperty { +public: + typedef SVGListProperty<PropertyType> Self; + + typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; + typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; + typedef PassRefPtr<ListItemTearOff> PassListItemTearOff; + typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff; + typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache; + + bool canAlterList(ExceptionCode& ec) const + { + if (m_role == AnimValRole) { + ec = NO_MODIFICATION_ALLOWED_ERR; + return false; + } + + return true; + } + + // SVGList::clear() + void clearValues(PropertyType& values, ExceptionCode& ec) + { + if (!canAlterList(ec)) + return; + + values.clear(); + commitChange(); + } + + void clearValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, ExceptionCode& ec) + { + ASSERT(animatedList); + if (!canAlterList(ec)) + return; + + animatedList->detachListWrappers(0); + animatedList->values().clear(); + commitChange(); + } + + // SVGList::numberOfItems() + unsigned numberOfItemsValues(PropertyType& values) const + { + return values.size(); + } + + unsigned numberOfItemsValuesAndWrappers(AnimatedListPropertyTearOff* animatedList) const + { + ASSERT(animatedList); + return animatedList->values().size(); + } + + // SVGList::initialize() + ListItemType initializeValues(PropertyType& values, const ListItemType& newItem, ExceptionCode& ec) + { + if (!canAlterList(ec)) + return ListItemType(); + + // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list. + processIncomingListItemValue(newItem, 0); + + // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter. + values.clear(); + values.append(newItem); + + commitChange(); + return newItem; + } + + PassListItemTearOff initializeValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, PassListItemTearOff passNewItem, ExceptionCode& ec) + { + ASSERT(animatedList); + if (!canAlterList(ec)) + return 0; + + // Not specified, but FF/Opera do it this way, and it's just sane. + if (!passNewItem) { + ec = TYPE_MISMATCH_ERR; + return 0; + } + + PropertyType& values = animatedList->values(); + ListWrapperCache& wrappers = animatedList->wrappers(); + + RefPtr<ListItemTearOff> newItem = passNewItem; + ASSERT(values.size() == wrappers.size()); + + // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list. + processIncomingListItemWrapper(newItem, 0); + + // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter. + animatedList->detachListWrappers(0); + values.clear(); + + values.append(newItem->propertyReference()); + wrappers.append(newItem); + + commitChange(); + return newItem.release(); + } + + // SVGList::getItem() + bool canGetItem(PropertyType& values, unsigned index, ExceptionCode& ec) + { + if (index >= values.size()) { + ec = INDEX_SIZE_ERR; + return false; + } + + return true; + } + + ListItemType getItemValues(PropertyType& values, unsigned index, ExceptionCode& ec) + { + if (!canGetItem(values, index, ec)) + return ListItemType(); + + // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy. + return values.at(index); + } + + PassListItemTearOff getItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionCode& ec) + { + ASSERT(animatedList); + PropertyType& values = animatedList->values(); + if (!canGetItem(values, index, ec)) + return 0; + + ListWrapperCache& wrappers = animatedList->wrappers(); + + // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy. + // Any changes made to the item are immediately reflected in the list. + ASSERT(values.size() == wrappers.size()); + RefPtr<ListItemTearOff> wrapper = wrappers.at(index); + if (!wrapper) { + // Create new wrapper, which is allowed to directly modify the item in the list, w/o copying and cache the wrapper in our map. + // It is also associated with our animated property, so it can notify the SVG Element which holds the SVGAnimated*List + // that it has been modified (and thus can call svgAttributeChanged(associatedAttributeName)). + wrapper = ListItemTearOff::create(animatedList, UndefinedRole, values.at(index)); + wrappers.at(index) = wrapper; + } + + return wrapper.release(); + } + + // SVGList::insertItemBefore() + ListItemType insertItemBeforeValues(PropertyType& values, const ListItemType& newItem, unsigned index, ExceptionCode& ec) + { + if (!canAlterList(ec)) + return ListItemType(); + + // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. + if (index > values.size()) + index = values.size(); + + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. + processIncomingListItemValue(newItem, &index); + + // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be + // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. + values.insert(index, newItem); + + commitChange(); + return newItem; + } + + PassListItemTearOff insertItemBeforeValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) + { + ASSERT(animatedList); + if (!canAlterList(ec)) + return 0; + + // Not specified, but FF/Opera do it this way, and it's just sane. + if (!passNewItem) { + ec = TYPE_MISMATCH_ERR; + return 0; + } + + PropertyType& values = animatedList->values(); + ListWrapperCache& wrappers = animatedList->wrappers(); + + // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. + if (index > values.size()) + index = values.size(); + + RefPtr<ListItemTearOff> newItem = passNewItem; + ASSERT(values.size() == wrappers.size()); + + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. + processIncomingListItemWrapper(newItem, &index); + + // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be + // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. + values.insert(index, newItem->propertyReference()); + + // Store new wrapper at position 'index', change its underlying value, so mutations of newItem, directly affect the item in the list. + wrappers.insert(index, newItem); + + commitChange(); + return newItem.release(); + } + + // SVGList::replaceItem() + bool canReplaceItem(PropertyType& values, unsigned index, ExceptionCode& ec) + { + if (!canAlterList(ec)) + return false; + + if (index >= values.size()) { + ec = INDEX_SIZE_ERR; + return false; + } + + return true; + } + + ListItemType replaceItemValues(PropertyType& values, const ListItemType& newItem, unsigned index, ExceptionCode& ec) + { + if (!canReplaceItem(values, index, ec)) + return ListItemType(); + + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. + // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. + processIncomingListItemValue(newItem, &index); + + // Update the value at the desired position 'index'. + values.at(index) = newItem; + + commitChange(); + return newItem; + } + + PassListItemTearOff replaceItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) + { + ASSERT(animatedList); + PropertyType& values = animatedList->values(); + if (!canReplaceItem(values, index, ec)) + return 0; + + // Not specified, but FF/Opera do it this way, and it's just sane. + if (!passNewItem) { + ec = TYPE_MISMATCH_ERR; + return 0; + } + + ListWrapperCache& wrappers = animatedList->wrappers(); + ASSERT(values.size() == wrappers.size()); + RefPtr<ListItemTearOff> newItem = passNewItem; + + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. + // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. + processIncomingListItemWrapper(newItem, &index); + + // Detach the existing wrapper. + RefPtr<ListItemTearOff>& oldItem = wrappers.at(index); + if (oldItem) + oldItem->detachWrapper(); + + // Update the value and the wrapper at the desired position 'index'. + values.at(index) = newItem->propertyReference(); + wrappers.at(index) = newItem; + + commitChange(); + return newItem.release(); + } + + // SVGList::removeItem() + bool canRemoveItem(PropertyType& values, unsigned index, ExceptionCode& ec) + { + if (!canAlterList(ec)) + return false; + + if (index >= values.size()) { + ec = INDEX_SIZE_ERR; + return false; + } + + return true; + } + + ListItemType removeItemValues(PropertyType& values, unsigned index, ExceptionCode& ec) + { + if (!canRemoveItem(values, index, ec)) + return ListItemType(); + + ListItemType oldItem = values.at(index); + values.remove(index); + + commitChange(); + return oldItem; + } + + PassListItemTearOff removeItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionCode& ec) + { + ASSERT(animatedList); + PropertyType& values = animatedList->values(); + if (!canRemoveItem(values, index, ec)) + return 0; + + ListWrapperCache& wrappers = animatedList->wrappers(); + ASSERT(values.size() == wrappers.size()); + + // Detach the existing wrapper. + RefPtr<ListItemTearOff>& oldItem = wrappers.at(index); + if (oldItem) + oldItem->detachWrapper(); + + wrappers.remove(index); + values.remove(index); + + commitChange(); + return oldItem.release(); + } + + // SVGList::appendItem() + ListItemType appendItemValues(PropertyType& values, const ListItemType& newItem, ExceptionCode& ec) + { + if (!canAlterList(ec)) + return ListItemType(); + + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. + processIncomingListItemValue(newItem, 0); + + // Append the value at the end of the list. + values.append(newItem); + + commitChange(); + return newItem; + } + + PassListItemTearOff appendItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, PassListItemTearOff passNewItem, ExceptionCode& ec) + { + ASSERT(animatedList); + if (!canAlterList(ec)) + return 0; + + // Not specified, but FF/Opera do it this way, and it's just sane. + if (!passNewItem) { + ec = TYPE_MISMATCH_ERR; + return 0; + } + + PropertyType& values = animatedList->values(); + ListWrapperCache& wrappers = animatedList->wrappers(); + + RefPtr<ListItemTearOff> newItem = passNewItem; + ASSERT(values.size() == wrappers.size()); + + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. + processIncomingListItemWrapper(newItem, 0); + + // Append the value and wrapper at the end of the list. + values.append(newItem->propertyReference()); + wrappers.append(newItem); + + commitChange(); + return newItem.release(); + } + +protected: + SVGListProperty(SVGPropertyRole role) + : m_role(role) + { + } + + virtual void commitChange() = 0; + virtual void processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) = 0; + virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) = 0; + +private: + SVGPropertyRole m_role; +}; + +} + +#endif // ENABLE(SVG) +#endif // SVGListProperty_h diff --git a/WebCore/svg/properties/SVGListPropertyTearOff.h b/WebCore/svg/properties/SVGListPropertyTearOff.h index 2801168..56d626f 100644 --- a/WebCore/svg/properties/SVGListPropertyTearOff.h +++ b/WebCore/svg/properties/SVGListPropertyTearOff.h @@ -21,52 +21,43 @@ #define SVGListPropertyTearOff_h #if ENABLE(SVG) -#include "ExceptionCode.h" -#include "SVGAnimatedProperty.h" -#include "SVGPropertyTearOff.h" -#include "SVGPropertyTraits.h" +#include "SVGListProperty.h" namespace WebCore { template<typename PropertyType> -class SVGAnimatedListPropertyTearOff; - -template<typename PropertyType> -class SVGListPropertyTearOff : public SVGProperty { +class SVGListPropertyTearOff : public SVGListProperty<PropertyType> { public: - typedef SVGListPropertyTearOff<PropertyType> Self; + typedef SVGListProperty<PropertyType> Base; typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; typedef PassRefPtr<ListItemTearOff> PassListItemTearOff; - typedef Vector<RefPtr<ListItemTearOff> > ListWrapperCache; + typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff; + typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache; - // Used for [SVGAnimatedProperty] types (for example: SVGAnimatedLengthList::baseVal()) - static PassRefPtr<Self> create(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, PropertyType& values) + static PassRefPtr<SVGListPropertyTearOff<PropertyType> > create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role) { ASSERT(animatedProperty); - return adoptRef(new Self(animatedProperty, role, values)); - } - - // Used for non-animated POD types (for example: SVGStringList). - static PassRefPtr<Self> create(const PropertyType& initialValue) - { - return adoptRef(new Self(initialValue)); + return adoptRef(new SVGListPropertyTearOff<PropertyType>(animatedProperty, role)); } int removeItemFromList(ListItemTearOff* removeItem, bool shouldSynchronizeWrappers) { + PropertyType& values = m_animatedProperty->values(); + ListWrapperCache& wrappers = m_animatedProperty->wrappers(); + // Lookup item in cache and remove its corresponding wrapper. - unsigned size = m_wrappers.size(); - ASSERT(size == m_values->size()); + unsigned size = wrappers.size(); + ASSERT(size == values.size()); for (unsigned i = 0; i < size; ++i) { - RefPtr<ListItemTearOff>& item = m_wrappers.at(i); + RefPtr<ListItemTearOff>& item = wrappers.at(i); if (item != removeItem) continue; item->detachWrapper(); - m_wrappers.remove(i); - m_values->remove(i); + wrappers.remove(i); + values.remove(i); if (shouldSynchronizeWrappers) commitChange(); @@ -77,275 +68,103 @@ public: return -1; } - void detachListWrappers(unsigned newListSize) - { - // See SVGPropertyTearOff::detachWrapper() for an explaination what's happening here. - unsigned size = m_wrappers.size(); - ASSERT(size == m_values->size()); - for (unsigned i = 0; i < size; ++i) { - RefPtr<ListItemTearOff>& item = m_wrappers.at(i); - if (!item) - continue; - item->detachWrapper(); - } - - // Reinitialize the wrapper cache to be equal to the new values size, after the XML DOM changed the list. - if (newListSize) - m_wrappers.fill(0, newListSize); - else - m_wrappers.clear(); - } - // SVGList API void clear(ExceptionCode& ec) { - if (m_role == AnimValRole) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return; - } - - detachListWrappers(0); - m_values->clear(); + Base::clearValuesAndWrappers(m_animatedProperty.get(), ec); } unsigned numberOfItems() const { - return m_values->size(); + return Base::numberOfItemsValuesAndWrappers(m_animatedProperty.get()); } PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionCode& ec) { - if (m_role == AnimValRole) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return 0; - } - - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = TYPE_MISMATCH_ERR; - return 0; - } - - RefPtr<ListItemTearOff> newItem = passNewItem; - ASSERT(m_values->size() == m_wrappers.size()); - - // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list. - removeItemFromListIfNeeded(newItem.get(), 0); - - // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter. - detachListWrappers(0); - m_values->clear(); - - m_values->append(newItem->propertyReference()); - m_wrappers.append(newItem); - - commitChange(); - return newItem.release(); + return Base::initializeValuesAndWrappers(m_animatedProperty.get(), passNewItem, ec); } PassListItemTearOff getItem(unsigned index, ExceptionCode& ec) { - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return 0; - } - - // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy. - // Any changes made to the item are immediately reflected in the list. - ASSERT(m_values->size() == m_wrappers.size()); - RefPtr<ListItemTearOff> wrapper = m_wrappers.at(index); - if (!wrapper) { - // Create new wrapper, which is allowed to directly modify the item in the list, w/o copying and cache the wrapper in our map. - // It is also associated with our animated property, so it can notify the SVG Element which holds the SVGAnimated*List - // that it has been modified (and thus can call svgAttributeChanged(associatedAttributeName)). - wrapper = ListItemTearOff::create(m_animatedProperty.get(), UndefinedRole, m_values->at(index)); - m_wrappers.at(index) = wrapper; - } - - return wrapper.release(); + return Base::getItemValuesAndWrappers(m_animatedProperty.get(), index, ec); } PassListItemTearOff insertItemBefore(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) { - if (m_role == AnimValRole) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return 0; - } - - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = TYPE_MISMATCH_ERR; - return 0; - } - - // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. - if (index > m_values->size()) - index = m_values->size(); - - RefPtr<ListItemTearOff> newItem = passNewItem; - ASSERT(m_values->size() == m_wrappers.size()); - - // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. - removeItemFromListIfNeeded(newItem.get(), &index); - - // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be - // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. - m_values->insert(index, newItem->propertyReference()); - - // Store new wrapper at position 'index', change its underlying value, so mutations of newItem, directly affect the item in the list. - m_wrappers.insert(index, newItem); - - commitChange(); - return newItem.release(); + return Base::insertItemBeforeValuesAndWrappers(m_animatedProperty.get(), passNewItem, index, ec); } PassListItemTearOff replaceItem(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) { - if (m_role == AnimValRole) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return 0; - } - - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return 0; - } - - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = TYPE_MISMATCH_ERR; - return 0; - } - - RefPtr<ListItemTearOff> newItem = passNewItem; - ASSERT(m_values->size() == m_wrappers.size()); - - // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. - // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. - removeItemFromListIfNeeded(newItem.get(), &index); - - // Detach the existing wrapper. - RefPtr<ListItemTearOff>& oldItem = m_wrappers.at(index); - if (oldItem) - oldItem->detachWrapper(); - - // Update the value and the wrapper at the desired position 'index'. - m_values->at(index) = newItem->propertyReference(); - m_wrappers.at(index) = newItem; - - commitChange(); - return newItem.release(); + return Base::replaceItemValuesAndWrappers(m_animatedProperty.get(), passNewItem, index, ec); } PassListItemTearOff removeItem(unsigned index, ExceptionCode& ec) { - if (m_role == AnimValRole) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return 0; - } - - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return 0; - } - - ASSERT(m_values->size() == m_wrappers.size()); - - // Detach the existing wrapper. - RefPtr<ListItemTearOff>& oldItem = m_wrappers.at(index); - if (oldItem) { - oldItem->detachWrapper(); - m_wrappers.remove(index); - } - - m_values->remove(index); - - commitChange(); - return oldItem.release(); + return Base::removeItemValuesAndWrappers(m_animatedProperty.get(), index, ec); } PassListItemTearOff appendItem(PassListItemTearOff passNewItem, ExceptionCode& ec) { - if (m_role == AnimValRole) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return 0; - } - - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = TYPE_MISMATCH_ERR; - return 0; - } - - RefPtr<ListItemTearOff> newItem = passNewItem; - ASSERT(m_values->size() == m_wrappers.size()); - - // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. - removeItemFromListIfNeeded(newItem.get(), 0); - - // Append the value and wrapper at the end of the list. - m_values->append(newItem->propertyReference()); - m_wrappers.append(newItem); - - commitChange(); - return newItem.release(); + return Base::appendItemValuesAndWrappers(m_animatedProperty.get(), passNewItem, ec); } private: - SVGListPropertyTearOff(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, PropertyType& values) - : m_animatedProperty(animatedProperty) - , m_role(role) - , m_values(&values) - , m_valuesIsCopy(false) - { - // Using operator & is completly fine, as SVGAnimatedProperty owns this reference, - // and we're guaranteed to live as long as SVGAnimatedProperty does. - if (!values.isEmpty()) - m_wrappers.fill(0, values.size()); - } - - SVGListPropertyTearOff(const PropertyType& initialValue) - : m_animatedProperty(0) - , m_role(UndefinedRole) - , m_values(new PropertyType(initialValue)) - , m_valuesIsCopy(true) + SVGListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role) + : SVGListProperty<PropertyType>(role) + , m_animatedProperty(animatedProperty) { } - virtual ~SVGListPropertyTearOff() + virtual void commitChange() { - if (m_valuesIsCopy) - delete m_values; - } + PropertyType& values = m_animatedProperty->values(); + ListWrapperCache& wrappers = m_animatedProperty->wrappers(); - void commitChange() - { - // Update existing wrappers, as the index in the m_values list has changed. - unsigned size = m_wrappers.size(); - ASSERT(size == m_values->size()); + // Update existing wrappers, as the index in the values list has changed. + unsigned size = wrappers.size(); + ASSERT(size == values.size()); for (unsigned i = 0; i < size; ++i) { - RefPtr<ListItemTearOff>& item = m_wrappers.at(i); + RefPtr<ListItemTearOff>& item = wrappers.at(i); if (!item) continue; item->setAnimatedProperty(m_animatedProperty.get()); - item->setValue(m_values->at(i)); + item->setValue(values.at(i)); } - ASSERT(!m_valuesIsCopy); - ASSERT(m_animatedProperty); m_animatedProperty->commitChange(); } - void removeItemFromListIfNeeded(ListItemTearOff* newItem, unsigned* indexToModify) + virtual void processIncomingListItemValue(const ListItemType&, unsigned*) + { + ASSERT_NOT_REACHED(); + } + + virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) { - // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty(); - if (!animatedPropertyOfItem || !animatedPropertyOfItem->isAnimatedListTearOff()) + + // newItem has been created manually, it doesn't belong to any SVGElement. + // (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createSVGLength())") + if (!animatedPropertyOfItem) + return; + + // newItem belongs to a SVGElement, but its associated SVGAnimatedProperty is not an animated list tear off. + // (for example: "textElement.x.baseVal.appendItem(rectElement.width.baseVal)") + if (!animatedPropertyOfItem->isAnimatedListTearOff()) { + // We have to copy the incoming newItem, as we're not allowed to insert this tear off as is into our wrapper cache. + // Otherwhise we'll end up having two SVGAnimatedPropertys that operate on the same SVGPropertyTearOff. Consider the example above: + // SVGRectElements SVGAnimatedLength 'width' property baseVal points to the same tear off object + // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would + // mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that. + newItem = ListItemTearOff::create(newItem->propertyReference()); return; + } + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal. bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; - int removedIndex = static_cast<SVGAnimatedListPropertyTearOff<PropertyType>*>(animatedPropertyOfItem)->removeItemFromList(newItem, livesInOtherList); + int removedIndex = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem)->removeItemFromList(newItem.get(), livesInOtherList); ASSERT(removedIndex != -1); if (!indexToModify) @@ -363,17 +182,7 @@ private: private: // Back pointer to the animated property that created us // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAnimatedLengthList object - RefPtr<SVGAnimatedProperty> m_animatedProperty; - - // The role of this property (baseVal or animVal) - SVGPropertyRole m_role; - - // For the example above (text.x.baseVal): A reference to the SVGLengthList& stored in the SVGTextElement, which we can directly modify - PropertyType* m_values; - bool m_valuesIsCopy : 1; - - // A list of wrappers, which is always in sync between m_values. - ListWrapperCache m_wrappers; + RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; }; } diff --git a/WebCore/svg/properties/SVGPropertyTearOff.h b/WebCore/svg/properties/SVGPropertyTearOff.h index 17588b4..2ffaede 100644 --- a/WebCore/svg/properties/SVGPropertyTearOff.h +++ b/WebCore/svg/properties/SVGPropertyTearOff.h @@ -32,7 +32,7 @@ class SVGPropertyTearOff : public SVGProperty { public: typedef SVGPropertyTearOff<PropertyType> Self; - // Used for [SVGAnimatedProperty] types (for example: SVGAnimatedLength::baseVal()). + // Used for child types (baseVal/animVal) of a SVGAnimated* property (for example: SVGAnimatedLength::baseVal()). // Also used for list tear offs (for example: text.x.baseVal.getItem(0)). static PassRefPtr<Self> create(SVGAnimatedProperty* animatedProperty, SVGPropertyRole, PropertyType& value) { @@ -40,7 +40,7 @@ public: return adoptRef(new Self(animatedProperty, value)); } - // Used for non-animated POD types (for example: SVGLength). + // Used for non-animated POD types (for example: SVGSVGElement::createSVGLength()). static PassRefPtr<Self> create(const PropertyType& initialValue) { return adoptRef(new Self(initialValue)); @@ -49,8 +49,6 @@ public: PropertyType& propertyReference() { return *m_value; } SVGAnimatedProperty* animatedProperty() const { return m_animatedProperty.get(); } - virtual int removeItemFromList(SVGAnimatedProperty*) { return -1; } - // Used only by the list tear offs! void setValue(PropertyType& value) { @@ -81,16 +79,17 @@ public: ASSERT(!m_valueIsCopy); m_value = new PropertyType(*m_value); m_valueIsCopy = true; + m_animatedProperty = 0; } - void commitChange() + virtual void commitChange() { if (!m_animatedProperty || m_valueIsCopy) return; m_animatedProperty->commitChange(); } -private: +protected: SVGPropertyTearOff(SVGAnimatedProperty* animatedProperty, PropertyType& value) : m_animatedProperty(animatedProperty) , m_value(&value) diff --git a/WebCore/svg/properties/SVGPropertyTraits.h b/WebCore/svg/properties/SVGPropertyTraits.h index 8d82a61..85bca7e 100644 --- a/WebCore/svg/properties/SVGPropertyTraits.h +++ b/WebCore/svg/properties/SVGPropertyTraits.h @@ -26,7 +26,10 @@ #include "SVGAngle.h" #include "SVGLength.h" #include "SVGLengthList.h" +#include "SVGNumberList.h" +#include "SVGPointList.h" #include "SVGPreserveAspectRatio.h" +#include "SVGStringList.h" #include <wtf/text/StringBuilder.h> namespace WebCore { @@ -79,6 +82,14 @@ struct SVGPropertyTraits<float> { }; template<> +struct SVGPropertyTraits<SVGNumberList> { + typedef float ListItemType; + + static SVGNumberList initialValue() { return SVGNumberList(); } + static String toString(const SVGNumberList& type) { return type.valueAsString(); } +}; + +template<> struct SVGPropertyTraits<SVGPreserveAspectRatio> { static SVGPreserveAspectRatio initialValue() { return SVGPreserveAspectRatio(); } static String toString(const SVGPreserveAspectRatio& type) { return type.valueAsString(); } @@ -108,6 +119,17 @@ struct SVGPropertyTraits<String> { static String toString(const String& type) { return type; } }; +template<> +struct SVGPropertyTraits<SVGStringList> { + typedef String ListItemType; +}; + +template<> +struct SVGPropertyTraits<SVGPointList> { + static SVGPointList initialValue() { return SVGPointList(); } + typedef FloatPoint ListItemType; +}; + } #endif diff --git a/WebCore/svg/properties/SVGStaticListPropertyTearOff.h b/WebCore/svg/properties/SVGStaticListPropertyTearOff.h new file mode 100644 index 0000000..a6f0f28 --- /dev/null +++ b/WebCore/svg/properties/SVGStaticListPropertyTearOff.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SVGStaticListPropertyTearOff_h +#define SVGStaticListPropertyTearOff_h + +#if ENABLE(SVG) +#include "SVGListProperty.h" + +namespace WebCore { + +template<typename PropertyType> +class SVGStaticListPropertyTearOff : public SVGListProperty<PropertyType> { +public: + typedef SVGListProperty<PropertyType> Base; + + typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; + typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; + + static PassRefPtr<SVGStaticListPropertyTearOff<PropertyType> > create(SVGElement* contextElement, PropertyType& values) + { + ASSERT(contextElement); + return adoptRef(new SVGStaticListPropertyTearOff<PropertyType>(contextElement, values)); + } + + // SVGList API + void clear(ExceptionCode& ec) + { + Base::clearValues(m_values, ec); + } + + unsigned numberOfItems() const + { + return Base::numberOfItemsValues(m_values); + } + + ListItemType initialize(const ListItemType& newItem, ExceptionCode& ec) + { + return Base::initializeValues(m_values, newItem, ec); + } + + ListItemType getItem(unsigned index, ExceptionCode& ec) + { + return Base::getItemValues(m_values, index, ec); + } + + ListItemType insertItemBefore(const ListItemType& newItem, unsigned index, ExceptionCode& ec) + { + return Base::insertItemBeforeValues(m_values, newItem, index, ec); + } + + ListItemType replaceItem(const ListItemType& newItem, unsigned index, ExceptionCode& ec) + { + return Base::replaceItemValues(m_values, newItem, index, ec); + } + + ListItemType removeItem(unsigned index, ExceptionCode& ec) + { + return Base::removeItemValues(m_values, index, ec); + } + + ListItemType appendItem(const ListItemType& newItem, ExceptionCode& ec) + { + return Base::appendItemValues(m_values, newItem, ec); + } + +private: + SVGStaticListPropertyTearOff(SVGElement* contextElement, PropertyType& values) + : SVGListProperty<PropertyType>(UndefinedRole) + , m_contextElement(contextElement) + , m_values(values) + { + } + + virtual void commitChange() + { + m_values.commitChange(m_contextElement.get()); + } + + virtual void processIncomingListItemValue(const ListItemType&, unsigned*) + { + // no-op for static lists + } + + virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*) + { + ASSERT_NOT_REACHED(); + } + +private: + RefPtr<SVGElement> m_contextElement; + PropertyType& m_values; +}; + +} + +#endif // ENABLE(SVG) +#endif // SVGStaticListPropertyTearOff_h diff --git a/WebCore/svg/properties/SVGStaticPropertyTearOff.h b/WebCore/svg/properties/SVGStaticPropertyTearOff.h new file mode 100644 index 0000000..8f31909 --- /dev/null +++ b/WebCore/svg/properties/SVGStaticPropertyTearOff.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SVGStaticPropertyTearOff_h +#define SVGStaticPropertyTearOff_h + +#if ENABLE(SVG) +#include "SVGPropertyTearOff.h" + +namespace WebCore { + +#if COMPILER(MSVC) +// UpdateMethod is 12 bytes. We have to pack to a size greater than or equal to that to avoid an +// alignment warning (C4121). 16 is the next-largest size allowed for packing, so we use that. +#pragma pack(push, 16) +#endif +template<typename ContextElement, typename PropertyType> +class SVGStaticPropertyTearOff : public SVGPropertyTearOff<PropertyType> { +public: + typedef SVGStaticPropertyTearOff<ContextElement, PropertyType> Self; + typedef void (ContextElement::*UpdateMethod)(); + + // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute + // (for example: SVGSVGElement::currentTranslate). + static PassRefPtr<Self> create(ContextElement* contextElement, PropertyType& value, UpdateMethod update) + { + ASSERT(contextElement); + return adoptRef(new Self(contextElement, value, update)); + } + + virtual void commitChange() { (m_contextElement.get()->*m_update)(); } + +private: + SVGStaticPropertyTearOff(ContextElement* contextElement, PropertyType& value, UpdateMethod update) + : SVGPropertyTearOff<PropertyType>(0, value) + , m_update(update) + , m_contextElement(contextElement) + { + } + + UpdateMethod m_update; + RefPtr<ContextElement> m_contextElement; +}; +#if COMPILER(MSVC) +#pragma pack(pop) +#endif + +} + +#endif // ENABLE(SVG) +#endif // SVGStaticPropertyTearOff_h diff --git a/WebCore/svg/svgattrs.in b/WebCore/svg/svgattrs.in index fe48c8a..dbe7663 100644 --- a/WebCore/svg/svgattrs.in +++ b/WebCore/svg/svgattrs.in @@ -141,8 +141,6 @@ onzoom opacity operator order -orderX -orderY orient orientation origin diff --git a/WebCore/webaudio/AudioBasicProcessorNode.cpp b/WebCore/webaudio/AudioBasicProcessorNode.cpp index cadaa73..828062e 100644 --- a/WebCore/webaudio/AudioBasicProcessorNode.cpp +++ b/WebCore/webaudio/AudioBasicProcessorNode.cpp @@ -29,6 +29,7 @@ #include "AudioBasicProcessorNode.h" #include "AudioBus.h" +#include "AudioContext.h" #include "AudioNodeInput.h" #include "AudioNodeOutput.h" #include "AudioProcessor.h" @@ -109,7 +110,7 @@ void AudioBasicProcessorNode::reset() // uninitialize and then re-initialize with the new channel count. void AudioBasicProcessorNode::checkNumberOfChannelsForInput(AudioNodeInput* input) { - ASSERT(isMainThread()); + ASSERT(context()->isAudioThread() && context()->isGraphOwner()); ASSERT(input == this->input(0)); if (input != this->input(0)) @@ -128,12 +129,14 @@ void AudioBasicProcessorNode::checkNumberOfChannelsForInput(AudioNodeInput* inpu uninitialize(); } - // This will propagate the channel count to any nodes connected further down the chain... - output(0)->setNumberOfChannels(numberOfChannels); + if (!isInitialized()) { + // This will propagate the channel count to any nodes connected further down the chain... + output(0)->setNumberOfChannels(numberOfChannels); - // Re-initialize the processor with the new channel count. - processor()->setNumberOfChannels(numberOfChannels); - initialize(); + // Re-initialize the processor with the new channel count. + processor()->setNumberOfChannels(numberOfChannels); + initialize(); + } } unsigned AudioBasicProcessorNode::numberOfChannels() diff --git a/WebCore/webaudio/AudioBufferSourceNode.cpp b/WebCore/webaudio/AudioBufferSourceNode.cpp new file mode 100644 index 0000000..7aaeb04 --- /dev/null +++ b/WebCore/webaudio/AudioBufferSourceNode.cpp @@ -0,0 +1,454 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(WEB_AUDIO) + +#include "AudioBufferSourceNode.h" + +#include "AudioContext.h" +#include "AudioNodeOutput.h" +#include <algorithm> + +using namespace std; + +namespace WebCore { + +const double DefaultGrainDuration = 0.020; // 20ms + +PassRefPtr<AudioBufferSourceNode> AudioBufferSourceNode::create(AudioContext* context, double sampleRate) +{ + return adoptRef(new AudioBufferSourceNode(context, sampleRate)); +} + +AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* context, double sampleRate) + : AudioSourceNode(context, sampleRate) + , m_buffer(0) + , m_isPlaying(false) + , m_isLooping(false) + , m_hasFinished(false) + , m_startTime(0.0) + , m_schedulingFrameDelay(0) + , m_readIndex(0) + , m_isGrain(false) + , m_grainOffset(0.0) + , m_grainDuration(DefaultGrainDuration) + , m_grainFrameCount(0) + , m_lastGain(1.0) + , m_pannerNode(0) +{ + setType(NodeTypeAudioBufferSource); + + m_gain = AudioGain::create("gain", 1.0, 0.0, 1.0); + m_playbackRate = AudioParam::create("playbackRate", 1.0, 0.0, AudioResampler::MaxRate); + + // Default to mono. A call to setBuffer() will set the number of output channels to that of the buffer. + addOutput(adoptPtr(new AudioNodeOutput(this, 1))); + + initialize(); +} + +AudioBufferSourceNode::~AudioBufferSourceNode() +{ + uninitialize(); +} + +void AudioBufferSourceNode::process(size_t framesToProcess) +{ + AudioBus* outputBus = output(0)->bus(); + + if (!isInitialized()) { + outputBus->zero(); + return; + } + + // The audio thread can't block on this lock, so we call tryLock() instead. + // Careful - this is a tryLock() and not an autolocker, so we must unlock() before every return. + if (m_processLock.tryLock()) { + // Check if it's time to start playing. + double sampleRate = this->sampleRate(); + double pitchRate = totalPitchRate(); + double quantumStartTime = context()->currentTime(); + double quantumEndTime = quantumStartTime + framesToProcess / sampleRate; + + if (!m_isPlaying || m_hasFinished || !buffer() || m_startTime >= quantumEndTime) { + // FIXME: can optimize here by propagating silent hint instead of forcing the whole chain to process silence. + outputBus->zero(); + m_processLock.unlock(); + return; + } + + // Handle sample-accurate scheduling so that buffer playback will happen at a very precise time. + m_schedulingFrameDelay = 0; + if (m_startTime >= quantumStartTime) { + // m_schedulingFrameDelay is set here only the very first render quantum (because of above check: m_startTime >= quantumEndTime) + // So: quantumStartTime <= m_startTime < quantumEndTime + ASSERT(m_startTime < quantumEndTime); + + double startTimeInQuantum = m_startTime - quantumStartTime; + double startFrameInQuantum = startTimeInQuantum * sampleRate; + + // m_schedulingFrameDelay is used in provideInput(), so factor in the current playback pitch rate. + m_schedulingFrameDelay = static_cast<int>(pitchRate * startFrameInQuantum); + } + + // FIXME: optimization opportunity: + // With a bit of work, it should be possible to avoid going through the resampler completely when the pitchRate == 1, + // especially if the pitchRate has never deviated from 1 in the past. + + // Read the samples through the pitch resampler. Our provideInput() method will be called by the resampler. + m_resampler.setRate(pitchRate); + m_resampler.process(this, outputBus, framesToProcess); + + // Apply the gain (in-place) to the output bus. + double totalGain = gain()->value() * m_buffer->gain(); + outputBus->copyWithGainFrom(*outputBus, &m_lastGain, totalGain); + + m_processLock.unlock(); + } else { + // Too bad - the tryLock() failed. We must be in the middle of changing buffers and were already outputting silence anyway. + outputBus->zero(); + } +} + +// The resampler calls us back here to get the input samples from our buffer. +void AudioBufferSourceNode::provideInput(AudioBus* bus, size_t numberOfFrames) +{ + ASSERT(context()->isAudioThread()); + + // Basic sanity checking + ASSERT(bus); + ASSERT(buffer()); + if (!bus || !buffer()) + return; + + unsigned numberOfChannels = this->numberOfChannels(); + unsigned busNumberOfChannels = bus->numberOfChannels(); + + // FIXME: we can add support for sources with more than two channels, but this is not a common case. + bool channelCountGood = numberOfChannels == busNumberOfChannels && (numberOfChannels == 1 || numberOfChannels == 2); + ASSERT(channelCountGood); + if (!channelCountGood) + return; + + // Get the destination pointers. + float* destinationL = bus->channel(0)->data(); + ASSERT(destinationL); + if (!destinationL) + return; + float* destinationR = (numberOfChannels < 2) ? 0 : bus->channel(1)->data(); + + size_t bufferLength = buffer()->length(); + double bufferSampleRate = buffer()->sampleRate(); + + // Calculate the start and end frames in our buffer that we want to play. + // If m_isGrain is true, then we will be playing a portion of the total buffer. + unsigned startFrame = m_isGrain ? static_cast<unsigned>(m_grainOffset * bufferSampleRate) : 0; + unsigned endFrame = m_isGrain ? static_cast<unsigned>(startFrame + m_grainDuration * bufferSampleRate) : bufferLength; + + // This is a HACK to allow for HRTF tail-time - avoids glitch at end. + // FIXME: implement tailTime for each AudioNode for a more general solution to this problem. + if (m_isGrain) + endFrame += 512; + + // Do some sanity checking. + if (startFrame >= bufferLength) + startFrame = !bufferLength ? 0 : bufferLength - 1; + if (endFrame > bufferLength) + endFrame = bufferLength; + if (m_readIndex >= endFrame) + m_readIndex = startFrame; // reset to start + + int framesToProcess = numberOfFrames; + + // Handle sample-accurate scheduling so that we play the buffer at a very precise time. + // m_schedulingFrameDelay will only be non-zero the very first time that provideInput() is called, which corresponds + // with the very start of the buffer playback. + if (m_schedulingFrameDelay > 0) { + ASSERT(m_schedulingFrameDelay <= framesToProcess); + if (m_schedulingFrameDelay <= framesToProcess) { + // Generate silence for the initial portion of the destination. + memset(destinationL, 0, sizeof(float) * m_schedulingFrameDelay); + destinationL += m_schedulingFrameDelay; + if (destinationR) { + memset(destinationR, 0, sizeof(float) * m_schedulingFrameDelay); + destinationR += m_schedulingFrameDelay; + } + + // Since we just generated silence for the initial portion, we have fewer frames to provide. + framesToProcess -= m_schedulingFrameDelay; + } + } + + // We have to generate a certain number of output sample-frames, but we need to handle the case where we wrap around + // from the end of the buffer to the start if playing back with looping and also the case where we simply reach the + // end of the sample data, but haven't yet rendered numberOfFrames worth of output. + while (framesToProcess > 0) { + ASSERT(m_readIndex <= endFrame); + if (m_readIndex > endFrame) + return; + + // Figure out how many frames we can process this time. + int framesAvailable = endFrame - m_readIndex; + int framesThisTime = min(framesToProcess, framesAvailable); + + // Create the destination bus for the part of the destination we're processing this time. + AudioBus currentDestinationBus(busNumberOfChannels, framesThisTime, false); + currentDestinationBus.setChannelMemory(0, destinationL, framesThisTime); + if (busNumberOfChannels > 1) + currentDestinationBus.setChannelMemory(1, destinationR, framesThisTime); + + // Generate output from the buffer. + readFromBuffer(¤tDestinationBus, framesThisTime); + + // Update the destination pointers. + destinationL += framesThisTime; + if (busNumberOfChannels > 1) + destinationR += framesThisTime; + + framesToProcess -= framesThisTime; + + // Handle the case where we reach the end of the part of the sample data we're supposed to play for the buffer. + if (m_readIndex >= endFrame) { + m_readIndex = startFrame; + m_grainFrameCount = 0; + + if (!looping()) { + // If we're not looping, then stop playing when we get to the end. + m_isPlaying = false; + + if (framesToProcess > 0) { + // We're not looping and we've reached the end of the sample data, but we still need to provide more output, + // so generate silence for the remaining. + memset(destinationL, 0, sizeof(float) * framesToProcess); + + if (destinationR) + memset(destinationR, 0, sizeof(float) * framesToProcess); + } + + if (!m_hasFinished) { + // Let the context dereference this AudioNode. + context()->notifyNodeFinishedProcessing(this); + m_hasFinished = true; + } + return; + } + } + } +} + +void AudioBufferSourceNode::readFromBuffer(AudioBus* destinationBus, size_t framesToProcess) +{ + bool isBusGood = destinationBus && destinationBus->length() == framesToProcess && destinationBus->numberOfChannels() == numberOfChannels(); + ASSERT(isBusGood); + if (!isBusGood) + return; + + unsigned numberOfChannels = this->numberOfChannels(); + // FIXME: we can add support for sources with more than two channels, but this is not a common case. + bool channelCountGood = numberOfChannels == 1 || numberOfChannels == 2; + ASSERT(channelCountGood); + if (!channelCountGood) + return; + + // Get pointers to the start of the sample buffer. + float* sourceL = m_buffer->getChannelData(0)->data(); + float* sourceR = m_buffer->numberOfChannels() == 2 ? m_buffer->getChannelData(1)->data() : 0; + + // Sanity check buffer access. + bool isSourceGood = sourceL && (numberOfChannels == 1 || sourceR) && m_readIndex + framesToProcess <= m_buffer->length(); + ASSERT(isSourceGood); + if (!isSourceGood) + return; + + // Offset the pointers to the current read position in the sample buffer. + sourceL += m_readIndex; + sourceR += m_readIndex; + + // Get pointers to the destination. + float* destinationL = destinationBus->channel(0)->data(); + float* destinationR = numberOfChannels == 2 ? destinationBus->channel(1)->data() : 0; + bool isDestinationGood = destinationL && (numberOfChannels == 1 || destinationR); + ASSERT(isDestinationGood); + if (!isDestinationGood) + return; + + if (m_isGrain) + readFromBufferWithGrainEnvelope(sourceL, sourceR, destinationL, destinationR, framesToProcess); + else { + // Simply copy the data from the source buffer to the destination. + memcpy(destinationL, sourceL, sizeof(float) * framesToProcess); + if (numberOfChannels == 2) + memcpy(destinationR, sourceR, sizeof(float) * framesToProcess); + } + + // Advance the buffer's read index. + m_readIndex += framesToProcess; +} + +void AudioBufferSourceNode::readFromBufferWithGrainEnvelope(float* sourceL, float* sourceR, float* destinationL, float* destinationR, size_t framesToProcess) +{ + ASSERT(sourceL && destinationL); + if (!sourceL || !destinationL) + return; + + int grainFrameLength = static_cast<int>(m_grainDuration * m_buffer->sampleRate()); + bool isStereo = sourceR && destinationR; + + int n = framesToProcess; + while (n--) { + // Apply the grain envelope. + float x = static_cast<float>(m_grainFrameCount) / static_cast<float>(grainFrameLength); + m_grainFrameCount++; + + x = min(1.0f, x); + float grainEnvelope = sinf(M_PI * x); + + *destinationL++ = grainEnvelope * *sourceL++; + + if (isStereo) + *destinationR++ = grainEnvelope * *sourceR++; + } +} + +void AudioBufferSourceNode::reset() +{ + m_resampler.reset(); + m_readIndex = 0; + m_grainFrameCount = 0; + m_lastGain = gain()->value(); +} + +void AudioBufferSourceNode::setBuffer(AudioBuffer* buffer) +{ + ASSERT(isMainThread()); + + // The context must be locked since changing the buffer can re-configure the number of channels that are output. + AudioContext::AutoLocker contextLocker(context()); + + // This synchronizes with process(). + MutexLocker processLocker(m_processLock); + + if (buffer) { + // Do any necesssary re-configuration to the buffer's number of channels. + unsigned numberOfChannels = buffer->numberOfChannels(); + m_resampler.configureChannels(numberOfChannels); + output(0)->setNumberOfChannels(numberOfChannels); + } + + m_readIndex = 0; + m_buffer = buffer; +} + +unsigned AudioBufferSourceNode::numberOfChannels() +{ + return output(0)->numberOfChannels(); +} + +void AudioBufferSourceNode::noteOn(double when) +{ + ASSERT(isMainThread()); + if (m_isPlaying) + return; + + m_isGrain = false; + m_startTime = when; + m_readIndex = 0; + m_isPlaying = true; +} + +void AudioBufferSourceNode::noteGrainOn(double when, double grainOffset, double grainDuration) +{ + ASSERT(isMainThread()); + if (m_isPlaying) + return; + + if (!buffer()) + return; + + // Do sanity checking of grain parameters versus buffer size. + double bufferDuration = buffer()->duration(); + + if (grainDuration > bufferDuration) + return; // FIXME: maybe should throw exception - consider in specification. + + double maxGrainOffset = bufferDuration - grainDuration; + maxGrainOffset = max(0.0, maxGrainOffset); + + grainOffset = max(0.0, grainOffset); + grainOffset = min(maxGrainOffset, grainOffset); + m_grainOffset = grainOffset; + + m_grainDuration = grainDuration; + m_grainFrameCount = 0; + + m_isGrain = true; + m_startTime = when; + m_readIndex = static_cast<int>(m_grainOffset * buffer()->sampleRate()); + m_isPlaying = true; +} + +void AudioBufferSourceNode::noteOff(double) +{ + ASSERT(isMainThread()); + if (!m_isPlaying) + return; + + // FIXME: the "when" argument to this method is ignored. + m_isPlaying = false; + m_readIndex = 0; +} + +double AudioBufferSourceNode::totalPitchRate() +{ + double dopplerRate = 1.0; + if (m_pannerNode.get()) + dopplerRate = m_pannerNode->dopplerRate(); + + // Incorporate buffer's sample-rate versus AudioContext's sample-rate. + // Normally it's not an issue because buffers are loaded at the AudioContext's sample-rate, but we can handle it in any case. + double sampleRateFactor = 1.0; + if (buffer()) + sampleRateFactor = buffer()->sampleRate() / sampleRate(); + + double basePitchRate = playbackRate()->value(); + + double totalRate = dopplerRate * sampleRateFactor * basePitchRate; + + // Sanity check the total rate. It's very important that the resampler not get any bad rate values. + totalRate = max(0.0, totalRate); + totalRate = min(AudioResampler::MaxRate, totalRate); + + bool isTotalRateValid = !isnan(totalRate) && !isinf(totalRate); + ASSERT(isTotalRateValid); + if (!isTotalRateValid) + totalRate = 1.0; + + return totalRate; +} + +} // namespace WebCore + +#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioBufferSourceNode.h b/WebCore/webaudio/AudioBufferSourceNode.h new file mode 100644 index 0000000..40b8555 --- /dev/null +++ b/WebCore/webaudio/AudioBufferSourceNode.h @@ -0,0 +1,147 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AudioBufferSourceNode_h +#define AudioBufferSourceNode_h + +#include "AudioBuffer.h" +#include "AudioBus.h" +#include "AudioGain.h" +#include "AudioPannerNode.h" +#include "AudioResampler.h" +#include "AudioSourceNode.h" +#include "AudioSourceProvider.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/Threading.h> + +namespace WebCore { + +class AudioContext; + +// AudioBufferSourceNode is an AudioNode representing an audio source from an in-memory audio asset represented by an AudioBuffer. +// It generally will be used for short sounds which require a high degree of scheduling flexibility (can playback in rhythmically perfect ways). + +class AudioBufferSourceNode : public AudioSourceNode, public AudioSourceProvider { +public: + static PassRefPtr<AudioBufferSourceNode> create(AudioContext*, double sampleRate); + + virtual ~AudioBufferSourceNode(); + + // AudioNode + virtual void process(size_t framesToProcess); + virtual void reset(); + + // AudioSourceProvider + // When process() is called, the resampler calls provideInput (in the audio thread) to gets its input stream. + virtual void provideInput(AudioBus*, size_t numberOfFrames); + + // setBuffer() is called on the main thread. This is the buffer we use for playback. + void setBuffer(AudioBuffer*); + AudioBuffer* buffer() { return m_buffer.get(); } + + // numberOfChannels() returns the number of output channels. This value equals the number of channels from the buffer. + // If a new buffer is set with a different number of channels, then this value will dynamically change. + unsigned numberOfChannels(); + + // Play-state + // noteOn(), noteGrainOn(), and noteOff() must all be called from the main thread. + void noteOn(double when); + void noteGrainOn(double when, double grainOffset, double grainDuration); + void noteOff(double when); + + bool looping() const { return m_isLooping; } + void setLooping(bool looping) { m_isLooping = looping; } + + AudioGain* gain() { return m_gain.get(); } + AudioParam* playbackRate() { return m_playbackRate.get(); } + + // If a panner node is set, then we can incorporate doppler shift into the playback pitch rate. + void setPannerNode(PassRefPtr<AudioPannerNode> pannerNode) { m_pannerNode = pannerNode; } + +private: + AudioBufferSourceNode(AudioContext*, double sampleRate); + + // m_buffer holds the sample data which this node outputs. + RefPtr<AudioBuffer> m_buffer; + + // Used for the "gain" and "playbackRate" attributes. + RefPtr<AudioGain> m_gain; + RefPtr<AudioParam> m_playbackRate; + + // m_isPlaying is set to true when noteOn() or noteGrainOn() is called. + bool m_isPlaying; + + // If m_isLooping is false, then this node will be done playing and become inactive after it reaches the end of the sample data in the buffer. + // If true, it will wrap around to the start of the buffer each time it reaches the end. + bool m_isLooping; + + // This node is considered finished when it reaches the end of the buffer's sample data after noteOn() has been called. + // This will only be set to true if m_isLooping == false. + bool m_hasFinished; + + // m_startTime is the time to start playing based on the context's timeline (0.0 or a time less than the context's current time means "now"). + double m_startTime; // in seconds + + // m_schedulingFrameDelay is the sample-accurate scheduling offset. + // It's used so that we start rendering audio samples at a very precise point in time. + // It will only be a non-zero value the very first render quantum that we render from the buffer. + int m_schedulingFrameDelay; + + // m_readIndex is a sample-frame index into our buffer representing the current playback position. + unsigned m_readIndex; + + // Granular playback + bool m_isGrain; + double m_grainOffset; // in seconds + double m_grainDuration; // in seconds + int m_grainFrameCount; // keeps track of which frame in the grain we're currently rendering + + // totalPitchRate() returns the instantaneous pitch rate (non-time preserving). + // It incorporates the base pitch rate, any sample-rate conversion factor from the buffer, and any doppler shift from an associated panner node. + double totalPitchRate(); + + // m_resampler performs the pitch rate changes to the buffer playback. + AudioResampler m_resampler; + + // m_lastGain provides continuity when we dynamically adjust the gain. + double m_lastGain; + + // We optionally keep track of a panner node which has a doppler shift that is incorporated into the pitch rate. + RefPtr<AudioPannerNode> m_pannerNode; + + // This synchronizes process() with setBuffer() which can cause dynamic channel count changes. + mutable Mutex m_processLock; + + // Reads the next framesToProcess sample-frames from the AudioBuffer into destinationBus. + // A grain envelope will be applied if m_isGrain is set to true. + void readFromBuffer(AudioBus* destinationBus, size_t framesToProcess); + + // readFromBufferWithGrainEnvelope() is a low-level blitter which reads from the AudioBuffer and applies a grain envelope. + void readFromBufferWithGrainEnvelope(float* sourceL, float* sourceR, float* destinationL, float* destinationR, size_t framesToProcess); +}; + +} // namespace WebCore + +#endif // AudioBufferSourceNode_h diff --git a/WebCore/webaudio/AudioBufferSourceNode.idl b/WebCore/webaudio/AudioBufferSourceNode.idl new file mode 100644 index 0000000..c8a3efb --- /dev/null +++ b/WebCore/webaudio/AudioBufferSourceNode.idl @@ -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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module audio { + // A cached (non-streamed), memory-resident audio source + interface [ + Conditional=WEB_AUDIO, + GenerateToJS + ] AudioBufferSourceNode : AudioSourceNode { + attribute [Custom] AudioBuffer buffer; + + readonly attribute AudioGain gain; + readonly attribute AudioParam playbackRate; + attribute boolean looping; // FIXME: change name to 'loop' once samples are updated + + void noteOn(in float when); + void noteGrainOn(in float when, in float grainOffset, in float grainDuration); + void noteOff(in float when); + }; +} diff --git a/WebCore/webaudio/AudioChannelSplitter.cpp b/WebCore/webaudio/AudioChannelSplitter.cpp index 2689cd7..f4fa041 100644 --- a/WebCore/webaudio/AudioChannelSplitter.cpp +++ b/WebCore/webaudio/AudioChannelSplitter.cpp @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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" @@ -72,7 +68,7 @@ void AudioChannelSplitter::process(size_t framesToProcess) // Split the channel out if it exists in the source. // It would be nice to avoid the copy and simply pass along pointers, but this becomes extremely difficult with fanout and fanin. destination->channel(0)->copyFrom(source->channel(i)); - } else if (output(i)->fanOutCount() > 0) { + } else if (output(i)->renderingFanOutCount() > 0) { // Only bother zeroing out the destination if it's connected to anything destination->zero(); } diff --git a/WebCore/webaudio/AudioChannelSplitter.h b/WebCore/webaudio/AudioChannelSplitter.h index 29092d6..7dadac5 100644 --- a/WebCore/webaudio/AudioChannelSplitter.h +++ b/WebCore/webaudio/AudioChannelSplitter.h @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 AudioChannelSplitter_h diff --git a/WebCore/webaudio/AudioChannelSplitter.idl b/WebCore/webaudio/AudioChannelSplitter.idl index a7450e6..076c051 100644 --- a/WebCore/webaudio/AudioChannelSplitter.idl +++ b/WebCore/webaudio/AudioChannelSplitter.idl @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 audio { diff --git a/WebCore/webaudio/AudioDestinationNode.cpp b/WebCore/webaudio/AudioDestinationNode.cpp index 82f5145..d2f4928 100644 --- a/WebCore/webaudio/AudioDestinationNode.cpp +++ b/WebCore/webaudio/AudioDestinationNode.cpp @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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" @@ -69,7 +65,7 @@ void AudioDestinationNode::initialize() m_destination = AudioDestination::create(*this, hardwareSampleRate); m_destination->start(); - m_isInitialized = true; + AudioNode::initialize(); } void AudioDestinationNode::uninitialize() @@ -79,7 +75,7 @@ void AudioDestinationNode::uninitialize() m_destination->stop(); - m_isInitialized = false; + AudioNode::uninitialize(); } // The audio hardware calls us back here to gets its input stream. @@ -92,6 +88,9 @@ void AudioDestinationNode::provideInput(AudioBus* destinationBus, size_t numberO return; } + // Let the context take care of any business at the start of each render quantum. + context()->handlePreRenderTasks(); + // This will cause the node(s) connected to us to process, which in turn will pull on their input(s), // all the way backwards through the rendering graph. AudioBus* renderedBus = input(0)->pull(destinationBus, numberOfFrames); diff --git a/WebCore/webaudio/AudioDestinationNode.h b/WebCore/webaudio/AudioDestinationNode.h index b130518..4c21bb8 100644 --- a/WebCore/webaudio/AudioDestinationNode.h +++ b/WebCore/webaudio/AudioDestinationNode.h @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 AudioDestinationNode_h diff --git a/WebCore/webaudio/AudioDestinationNode.idl b/WebCore/webaudio/AudioDestinationNode.idl index 1d2a235..d7bf09f 100644 --- a/WebCore/webaudio/AudioDestinationNode.idl +++ b/WebCore/webaudio/AudioDestinationNode.idl @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 audio { diff --git a/WebCore/webaudio/AudioGainNode.cpp b/WebCore/webaudio/AudioGainNode.cpp index 332929d..5b9af07 100644 --- a/WebCore/webaudio/AudioGainNode.cpp +++ b/WebCore/webaudio/AudioGainNode.cpp @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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" @@ -105,10 +101,11 @@ void AudioGainNode::checkNumberOfChannelsForInput(AudioNodeInput* input) uninitialize(); } - // This will propagate the channel count to any nodes connected further downstream in the graph. - output(0)->setNumberOfChannels(numberOfChannels); - - initialize(); + if (!isInitialized()) { + // This will propagate the channel count to any nodes connected further downstream in the graph. + output(0)->setNumberOfChannels(numberOfChannels); + initialize(); + } } } // namespace WebCore diff --git a/WebCore/webaudio/AudioGainNode.h b/WebCore/webaudio/AudioGainNode.h index 91f9d16..3710472 100644 --- a/WebCore/webaudio/AudioGainNode.h +++ b/WebCore/webaudio/AudioGainNode.h @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 AudioGainNode_h diff --git a/WebCore/webaudio/AudioGainNode.idl b/WebCore/webaudio/AudioGainNode.idl index 8bf117a..3d4f40f 100644 --- a/WebCore/webaudio/AudioGainNode.idl +++ b/WebCore/webaudio/AudioGainNode.idl @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 audio { diff --git a/WebCore/webaudio/AudioPannerNode.cpp b/WebCore/webaudio/AudioPannerNode.cpp index b7282e3..4afca27 100644 --- a/WebCore/webaudio/AudioPannerNode.cpp +++ b/WebCore/webaudio/AudioPannerNode.cpp @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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" @@ -307,8 +303,8 @@ void AudioPannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node) AudioNodeInput* input = node->input(i); // For each input, go through all of its connections, looking for AudioBufferSourceNodes. - for (unsigned j = 0; j < input->numberOfConnections(); ++j) { - AudioNodeOutput* connectedOutput = input->output(j); + for (unsigned j = 0; j < input->numberOfRenderingConnections(); ++j) { + AudioNodeOutput* connectedOutput = input->renderingOutput(j); AudioNode* connectedNode = connectedOutput->node(); notifyAudioSourcesConnectedToNode(connectedNode); // recurse } diff --git a/WebCore/webaudio/AudioPannerNode.h b/WebCore/webaudio/AudioPannerNode.h index 144b61b..6d0d759 100644 --- a/WebCore/webaudio/AudioPannerNode.h +++ b/WebCore/webaudio/AudioPannerNode.h @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 AudioPannerNode_h diff --git a/WebCore/webaudio/AudioPannerNode.idl b/WebCore/webaudio/AudioPannerNode.idl index eb6db40..595a603 100644 --- a/WebCore/webaudio/AudioPannerNode.idl +++ b/WebCore/webaudio/AudioPannerNode.idl @@ -1,29 +1,25 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * 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: - * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 audio { diff --git a/WebCore/webaudio/AudioProcessingEvent.cpp b/WebCore/webaudio/AudioProcessingEvent.cpp new file mode 100644 index 0000000..54ce521 --- /dev/null +++ b/WebCore/webaudio/AudioProcessingEvent.cpp @@ -0,0 +1,59 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(WEB_AUDIO) + +#include "AudioProcessingEvent.h" + +#include "AudioBuffer.h" +#include "EventNames.h" + +namespace WebCore { + +PassRefPtr<AudioProcessingEvent> AudioProcessingEvent::create(PassRefPtr<AudioBuffer> inputBuffer, PassRefPtr<AudioBuffer> outputBuffer) +{ + return adoptRef(new AudioProcessingEvent(inputBuffer, outputBuffer)); +} + +AudioProcessingEvent::AudioProcessingEvent(PassRefPtr<AudioBuffer> inputBuffer, PassRefPtr<AudioBuffer> outputBuffer) + : Event(eventNames().audioprocessEvent, true, false) + , m_inputBuffer(inputBuffer) + , m_outputBuffer(outputBuffer) +{ +} + +AudioProcessingEvent::~AudioProcessingEvent() +{ +} + +bool AudioProcessingEvent::isAudioProcessingEvent() const +{ + return true; +} + +} // namespace WebCore + +#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioProcessingEvent.h b/WebCore/webaudio/AudioProcessingEvent.h new file mode 100644 index 0000000..a88669c --- /dev/null +++ b/WebCore/webaudio/AudioProcessingEvent.h @@ -0,0 +1,57 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AudioProcessingEvent_h +#define AudioProcessingEvent_h + +#include "AudioBuffer.h" +#include "Event.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class AudioBuffer; + +class AudioProcessingEvent : public Event { +public: + static PassRefPtr<AudioProcessingEvent> create(PassRefPtr<AudioBuffer> inputBuffer, PassRefPtr<AudioBuffer> outputBuffer); + + virtual ~AudioProcessingEvent(); + + virtual bool isAudioProcessingEvent() const; + + AudioBuffer* inputBuffer() { return m_inputBuffer.get(); } + AudioBuffer* outputBuffer() { return m_outputBuffer.get(); } + +private: + AudioProcessingEvent(PassRefPtr<AudioBuffer> inputBuffer, PassRefPtr<AudioBuffer> outputBuffer); + + RefPtr<AudioBuffer> m_inputBuffer; + RefPtr<AudioBuffer> m_outputBuffer; +}; + +} // namespace WebCore + +#endif // AudioProcessingEvent_h diff --git a/WebCore/webaudio/AudioProcessingEvent.idl b/WebCore/webaudio/AudioProcessingEvent.idl new file mode 100644 index 0000000..c2f8a83 --- /dev/null +++ b/WebCore/webaudio/AudioProcessingEvent.idl @@ -0,0 +1,33 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module audio { + interface [ + Conditional=WEB_AUDIO, + GenerateToJS + ] AudioProcessingEvent : Event { + readonly attribute AudioBuffer inputBuffer; + readonly attribute AudioBuffer outputBuffer; + }; +} diff --git a/WebCore/webaudio/ConvolverNode.cpp b/WebCore/webaudio/ConvolverNode.cpp new file mode 100644 index 0000000..c778a41 --- /dev/null +++ b/WebCore/webaudio/ConvolverNode.cpp @@ -0,0 +1,152 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(WEB_AUDIO) + +#include "ConvolverNode.h" + +#include "AudioBuffer.h" +#include "AudioNodeInput.h" +#include "AudioNodeOutput.h" +#include "Reverb.h" + +// Note about empirical tuning: +// The maximum FFT size affects reverb performance and accuracy. +// If the reverb is single-threaded and processes entirely in the real-time audio thread, +// it's important not to make this too high. In this case 8192 is a good value. +// But, the Reverb object is multi-threaded, so we want this as high as possible without losing too much accuracy. +// Very large FFTs will have worse phase errors. Given these constraints 16384 is a good compromise. +const size_t MaxFFTSize = 16384; + +namespace WebCore { + +ConvolverNode::ConvolverNode(AudioContext* context, double sampleRate) + : AudioNode(context, sampleRate) +{ + addInput(adoptPtr(new AudioNodeInput(this))); + addOutput(adoptPtr(new AudioNodeOutput(this, 2))); + + setType(NodeTypeConvolver); + + initialize(); +} + +ConvolverNode::~ConvolverNode() +{ + uninitialize(); +} + +void ConvolverNode::process(size_t framesToProcess) +{ + AudioBus* outputBus = output(0)->bus(); + ASSERT(outputBus); + + // Synchronize with possible dynamic changes to the impulse response. + if (m_processLock.tryLock()) { + if (!isInitialized() || !m_reverb.get()) + outputBus->zero(); + else { + // Process using the convolution engine. + // Note that we can handle the case where nothing is connected to the input, in which case we'll just feed silence into the convolver. + // FIXME: If we wanted to get fancy we could try to factor in the 'tail time' and stop processing once the tail dies down if + // we keep getting fed silence. + m_reverb->process(input(0)->bus(), outputBus, framesToProcess); + } + + m_processLock.unlock(); + } else { + // Too bad - the tryLock() failed. We must be in the middle of setting a new impulse response. + outputBus->zero(); + } +} + +void ConvolverNode::reset() +{ + MutexLocker locker(m_processLock); + if (m_reverb.get()) + m_reverb->reset(); +} + +void ConvolverNode::initialize() +{ + if (isInitialized()) + return; + + AudioNode::initialize(); +} + +void ConvolverNode::uninitialize() +{ + if (!isInitialized()) + return; + + m_reverb.clear(); + AudioNode::uninitialize(); +} + +void ConvolverNode::setBuffer(AudioBuffer* buffer) +{ + ASSERT(isMainThread()); + + ASSERT(buffer); + if (!buffer) + return; + + unsigned numberOfChannels = buffer->numberOfChannels(); + size_t bufferLength = buffer->length(); + + // The current implementation supports up to four channel impulse responses, which are interpreted as true-stereo (see Reverb class). + bool isBufferGood = numberOfChannels > 0 && numberOfChannels <= 4 && bufferLength; + ASSERT(isBufferGood); + if (!isBufferGood) + return; + + // Wrap the AudioBuffer by an AudioBus. It's an efficient pointer set and not a memcpy(). + // This memory is simply used in the Reverb constructor and no reference to it is kept for later use in that class. + AudioBus bufferBus(numberOfChannels, bufferLength, false); + for (unsigned i = 0; i < numberOfChannels; ++i) + bufferBus.setChannelMemory(i, buffer->getChannelData(i)->data(), bufferLength); + + // Create the reverb with the given impulse response. + OwnPtr<Reverb> reverb = adoptPtr(new Reverb(&bufferBus, AudioNode::ProcessingSizeInFrames, MaxFFTSize, 2, true)); + + { + // Synchronize with process(). + MutexLocker locker(m_processLock); + m_reverb = reverb.release(); + m_buffer = buffer; + } +} + +AudioBuffer* ConvolverNode::buffer() +{ + ASSERT(isMainThread()); + return m_buffer.get(); +} + +} // namespace WebCore + +#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/ConvolverNode.h b/WebCore/webaudio/ConvolverNode.h new file mode 100644 index 0000000..7b71ba9 --- /dev/null +++ b/WebCore/webaudio/ConvolverNode.h @@ -0,0 +1,69 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ConvolverNode_h +#define ConvolverNode_h + +#include "AudioNode.h" +#include <wtf/OwnPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/Threading.h> + +namespace WebCore { + +class AudioBuffer; +class Reverb; + +class ConvolverNode : public AudioNode { +public: + static PassRefPtr<ConvolverNode> create(AudioContext* context, double sampleRate) + { + return adoptRef(new ConvolverNode(context, sampleRate)); + } + + virtual ~ConvolverNode(); + + // AudioNode + virtual void process(size_t framesToProcess); + virtual void reset(); + virtual void initialize(); + virtual void uninitialize(); + + // Impulse responses + void setBuffer(AudioBuffer*); + AudioBuffer* buffer(); + +private: + ConvolverNode(AudioContext*, double sampleRate); + + OwnPtr<Reverb> m_reverb; + RefPtr<AudioBuffer> m_buffer; + + // This synchronizes dynamic changes to the convolution impulse response with process(). + mutable Mutex m_processLock; +}; + +} // namespace WebCore + +#endif // ConvolverNode_h diff --git a/WebCore/webaudio/ConvolverNode.idl b/WebCore/webaudio/ConvolverNode.idl new file mode 100644 index 0000000..cb49a45 --- /dev/null +++ b/WebCore/webaudio/ConvolverNode.idl @@ -0,0 +1,33 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module audio { + // A linear convolution effect + interface [ + Conditional=WEB_AUDIO, + GenerateToJS + ] ConvolverNode : AudioNode { + attribute [Custom] AudioBuffer buffer; + }; +} diff --git a/WebCore/webaudio/RealtimeAnalyser.cpp b/WebCore/webaudio/RealtimeAnalyser.cpp new file mode 100644 index 0000000..282f299 --- /dev/null +++ b/WebCore/webaudio/RealtimeAnalyser.cpp @@ -0,0 +1,300 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(WEB_AUDIO) + +#include "RealtimeAnalyser.h" + +#include "AudioBus.h" +#include "AudioUtilities.h" +#include "FFTFrame.h" + +#if ENABLE(3D_CANVAS) +#include "Float32Array.h" +#include "Uint8Array.h" +#endif + +#include <algorithm> +#include <limits.h> +#include <wtf/Complex.h> +#include <wtf/Threading.h> + +using namespace std; + +namespace WebCore { + +const double RealtimeAnalyser::DefaultSmoothingTimeConstant = 0.8; +const double RealtimeAnalyser::DefaultMinDecibels = -100.0; +const double RealtimeAnalyser::DefaultMaxDecibels = -30.0; + +const unsigned RealtimeAnalyser::DefaultFFTSize = 2048; +const unsigned RealtimeAnalyser::MaxFFTSize = 2048; +const unsigned RealtimeAnalyser::InputBufferSize = RealtimeAnalyser::MaxFFTSize * 2; + +RealtimeAnalyser::RealtimeAnalyser() + : m_inputBuffer(InputBufferSize) + , m_writeIndex(0) + , m_fftSize(DefaultFFTSize) + , m_magnitudeBuffer(DefaultFFTSize / 2) + , m_smoothingTimeConstant(DefaultSmoothingTimeConstant) + , m_minDecibels(DefaultMinDecibels) + , m_maxDecibels(DefaultMaxDecibels) +{ + m_analysisFrame = adoptPtr(new FFTFrame(DefaultFFTSize)); +} + +RealtimeAnalyser::~RealtimeAnalyser() +{ +} + +void RealtimeAnalyser::reset() +{ + m_writeIndex = 0; + m_inputBuffer.zero(); + m_magnitudeBuffer.zero(); +} + +void RealtimeAnalyser::setFftSize(size_t size) +{ + ASSERT(isMainThread()); + + // Only allow powers of two. + unsigned log2size = static_cast<unsigned>(log2(size)); + bool isPOT(1UL << log2size == size); + + if (!isPOT || size > MaxFFTSize) { + // FIXME: It would be good to also set an exception. + return; + } + + if (m_fftSize != size) { + m_analysisFrame = adoptPtr(new FFTFrame(m_fftSize)); + m_magnitudeBuffer.resize(size); + m_fftSize = size; + } +} + +void RealtimeAnalyser::writeInput(AudioBus* bus, size_t framesToProcess) +{ + bool isBusGood = bus && bus->numberOfChannels() > 0 && bus->channel(0)->length() >= framesToProcess; + ASSERT(isBusGood); + if (!isBusGood) + return; + + // FIXME : allow to work with non-FFTSize divisible chunking + bool isDestinationGood = m_writeIndex < m_inputBuffer.size() && m_writeIndex + framesToProcess <= m_inputBuffer.size(); + ASSERT(isDestinationGood); + if (!isDestinationGood) + return; + + // Perform real-time analysis + // FIXME : for now just use left channel (must mix if stereo source) + float* source = bus->channel(0)->data(); + + // The source has already been sanity checked with isBusGood above. + + memcpy(m_inputBuffer.data() + m_writeIndex, source, sizeof(float) * framesToProcess); + + m_writeIndex += framesToProcess; + if (m_writeIndex >= InputBufferSize) + m_writeIndex = 0; +} + +namespace { + +void applyWindow(float* p, size_t n) +{ + ASSERT(isMainThread()); + + // Blackman window + double alpha = 0.16; + double a0 = 0.5 * (1.0 - alpha); + double a1 = 0.5; + double a2 = 0.5 * alpha; + + for (unsigned i = 0; i < n; ++i) { + double x = static_cast<double>(i) / static_cast<double>(n); + double window = a0 - a1 * cos(2.0 * M_PI * x) + a2 * cos(4.0 * M_PI * x); + p[i] *= float(window); + } +} + +} // namespace + +void RealtimeAnalyser::doFFTAnalysis() +{ + ASSERT(isMainThread()); + + // Unroll the input buffer into a temporary buffer, where we'll apply an analysis window followed by an FFT. + size_t fftSize = this->fftSize(); + + AudioFloatArray temporaryBuffer(fftSize); + float* inputBuffer = m_inputBuffer.data(); + float* tempP = temporaryBuffer.data(); + + // Take the previous fftSize values from the input buffer and copy into the temporary buffer. + // FIXME : optimize with memcpy(). + unsigned writeIndex = m_writeIndex; + for (unsigned i = 0; i < fftSize; ++i) + tempP[i] = inputBuffer[(i + writeIndex - fftSize + InputBufferSize) % InputBufferSize]; + + // Window the input samples. + applyWindow(tempP, fftSize); + + // Do the analysis. + m_analysisFrame->doFFT(tempP); + + size_t n = DefaultFFTSize / 2; + + float* realP = m_analysisFrame->realData(); + float* imagP = m_analysisFrame->imagData(); + + // Blow away the packed nyquist component. + imagP[0] = 0.0f; + + // Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT scaling factor). + const double MagnitudeScale = 1.0 / DefaultFFTSize; + + // A value of 0 does no averaging with the previous result. Larger values produce slower, but smoother changes. + double k = m_smoothingTimeConstant; + k = max(0.0, k); + k = min(1.0, k); + + // Convert the analysis data from complex to magnitude and average with the previous result. + float* destination = magnitudeBuffer().data(); + for (unsigned i = 0; i < n; ++i) { + Complex c(realP[i], imagP[i]); + double scalarMagnitude = abs(c) * MagnitudeScale; + destination[i] = float(k * destination[i] + (1.0 - k) * scalarMagnitude); + } +} + +#if ENABLE(3D_CANVAS) + +void RealtimeAnalyser::getFloatFrequencyData(Float32Array* destinationArray) +{ + ASSERT(isMainThread()); + + if (!destinationArray) + return; + + doFFTAnalysis(); + + // Convert from linear magnitude to floating-point decibels. + const double MinDecibels = m_minDecibels; + unsigned sourceLength = magnitudeBuffer().size(); + size_t len = min(sourceLength, destinationArray->length()); + if (len > 0) { + const float* source = magnitudeBuffer().data(); + float* destination = destinationArray->data(); + + for (unsigned i = 0; i < len; ++i) { + float linearValue = source[i]; + double dbMag = !linearValue ? MinDecibels : AudioUtilities::linearToDecibels(linearValue); + destination[i] = float(dbMag); + } + } +} + +void RealtimeAnalyser::getByteFrequencyData(Uint8Array* destinationArray) +{ + ASSERT(isMainThread()); + + if (!destinationArray) + return; + + doFFTAnalysis(); + + // Convert from linear magnitude to unsigned-byte decibels. + unsigned sourceLength = magnitudeBuffer().size(); + size_t len = min(sourceLength, destinationArray->length()); + if (len > 0) { + const double RangeScaleFactor = m_maxDecibels == m_minDecibels ? 1.0 : 1.0 / (m_maxDecibels - m_minDecibels); + + const float* source = magnitudeBuffer().data(); + unsigned char* destination = destinationArray->data(); + + for (unsigned i = 0; i < len; ++i) { + float linearValue = source[i]; + double dbMag = !linearValue ? m_minDecibels : AudioUtilities::linearToDecibels(linearValue); + + // The range m_minDecibels to m_maxDecibels will be scaled to byte values from 0 to UCHAR_MAX. + double scaledValue = UCHAR_MAX * (dbMag - m_minDecibels) * RangeScaleFactor; + + // Clip to valid range. + if (scaledValue < 0.0) + scaledValue = 0.0; + if (scaledValue > UCHAR_MAX) + scaledValue = UCHAR_MAX; + + destination[i] = static_cast<unsigned char>(scaledValue); + } + } +} + +void RealtimeAnalyser::getByteTimeDomainData(Uint8Array* destinationArray) +{ + ASSERT(isMainThread()); + + if (!destinationArray) + return; + + unsigned fftSize = this->fftSize(); + size_t len = min(fftSize, destinationArray->length()); + if (len > 0) { + bool isInputBufferGood = m_inputBuffer.size() == InputBufferSize && m_inputBuffer.size() > fftSize; + ASSERT(isInputBufferGood); + if (!isInputBufferGood) + return; + + float* inputBuffer = m_inputBuffer.data(); + unsigned char* destination = destinationArray->data(); + + unsigned writeIndex = m_writeIndex; + + for (unsigned i = 0; i < len; ++i) { + // Buffer access is protected due to modulo operation. + float value = inputBuffer[(i + writeIndex - fftSize + InputBufferSize) % InputBufferSize]; + + // Scale from nominal -1.0 -> +1.0 to unsigned byte. + double scaledValue = 128.0 * (value + 1.0); + + // Clip to valid range. + if (scaledValue < 0.0) + scaledValue = 0.0; + if (scaledValue > UCHAR_MAX) + scaledValue = UCHAR_MAX; + + destination[i] = static_cast<unsigned char>(scaledValue); + } + } +} + +#endif // 3D_CANVAS + +} // namespace WebCore + +#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/RealtimeAnalyser.h b/WebCore/webaudio/RealtimeAnalyser.h new file mode 100644 index 0000000..686c17c --- /dev/null +++ b/WebCore/webaudio/RealtimeAnalyser.h @@ -0,0 +1,103 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RealtimeAnalyser_h +#define RealtimeAnalyser_h + +#include "AudioArray.h" +#include <wtf/NonCopyable.h> +#include <wtf/OwnPtr.h> + +namespace WebCore { + +class AudioBus; +class FFTFrame; + +#if ENABLE(3D_CANVAS) +class Float32Array; +class Uint8Array; +#endif + +class RealtimeAnalyser : public Noncopyable { +public: + RealtimeAnalyser(); + virtual ~RealtimeAnalyser(); + + void reset(); + + size_t fftSize() const { return m_fftSize; } + void setFftSize(size_t size); + + unsigned frequencyBinCount() const { return m_fftSize / 2; } + + void setMinDecibels(float k) { m_minDecibels = k; } + float minDecibels() const { return static_cast<float>(m_minDecibels); } + + void setMaxDecibels(float k) { m_maxDecibels = k; } + float maxDecibels() const { return static_cast<float>(m_maxDecibels); } + + void setSmoothingTimeConstant(float k) { m_smoothingTimeConstant = k; } + float smoothingTimeConstant() const { return static_cast<float>(m_smoothingTimeConstant); } + +#if ENABLE(3D_CANVAS) + void getFloatFrequencyData(Float32Array*); + void getByteFrequencyData(Uint8Array*); + void getByteTimeDomainData(Uint8Array*); +#endif + + // The audio thread writes input data here. + void writeInput(AudioBus*, size_t framesToProcess); + + static const double DefaultSmoothingTimeConstant; + static const double DefaultMinDecibels; + static const double DefaultMaxDecibels; + + static const unsigned DefaultFFTSize; + static const unsigned MaxFFTSize; + static const unsigned InputBufferSize; + +private: + // The audio thread writes the input audio here. + AudioFloatArray m_inputBuffer; + unsigned m_writeIndex; + + size_t m_fftSize; + OwnPtr<FFTFrame> m_analysisFrame; + void doFFTAnalysis(); + + // doFFTAnalysis() stores the floating-point magnitude analysis data here. + AudioFloatArray m_magnitudeBuffer; + AudioFloatArray& magnitudeBuffer() { return m_magnitudeBuffer; } + + // A value between 0 and 1 which averages the previous version of m_magnitudeBuffer with the current analysis magnitude data. + double m_smoothingTimeConstant; + + // The range used when converting when using getByteFrequencyData(). + double m_minDecibels; + double m_maxDecibels; +}; + +} // namespace WebCore + +#endif // RealtimeAnalyser_h diff --git a/WebCore/webaudio/RealtimeAnalyserNode.cpp b/WebCore/webaudio/RealtimeAnalyserNode.cpp new file mode 100644 index 0000000..2ba751a --- /dev/null +++ b/WebCore/webaudio/RealtimeAnalyserNode.cpp @@ -0,0 +1,88 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(WEB_AUDIO) + +#include "RealtimeAnalyserNode.h" + +#include "AudioNodeInput.h" +#include "AudioNodeOutput.h" + +namespace WebCore { + +RealtimeAnalyserNode::RealtimeAnalyserNode(AudioContext* context, double sampleRate) + : AudioNode(context, sampleRate) +{ + addInput(adoptPtr(new AudioNodeInput(this))); + addOutput(adoptPtr(new AudioNodeOutput(this, 2))); + + setType(NodeTypeAnalyser); + + initialize(); +} + +RealtimeAnalyserNode::~RealtimeAnalyserNode() +{ + uninitialize(); +} + +void RealtimeAnalyserNode::process(size_t framesToProcess) +{ + AudioBus* outputBus = output(0)->bus(); + + if (!isInitialized() || !input(0)->isConnected()) { + outputBus->zero(); + return; + } + + AudioBus* inputBus = input(0)->bus(); + + // Give the analyser the audio which is passing through this AudioNode. + m_analyser.writeInput(inputBus, framesToProcess); + + // For in-place processing, our override of pullInputs() will just pass the audio data through unchanged if the channel count matches from input to output + // (resulting in inputBus == outputBus). Otherwise, do an up-mix to stereo. + if (inputBus != outputBus) + outputBus->copyFrom(*inputBus); +} + +// We override pullInputs() as an optimization allowing this node to take advantage of in-place processing, +// where the input is simply passed through unprocessed to the output. +// Note: this only applies if the input and output channel counts match. +void RealtimeAnalyserNode::pullInputs(size_t framesToProcess) +{ + // Render input stream - try to render directly into output bus for pass-through processing where process() doesn't need to do anything... + input(0)->pull(output(0)->bus(), framesToProcess); +} + +void RealtimeAnalyserNode::reset() +{ + m_analyser.reset(); +} + +} // namespace WebCore + +#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/RealtimeAnalyserNode.h b/WebCore/webaudio/RealtimeAnalyserNode.h new file mode 100644 index 0000000..9f62464 --- /dev/null +++ b/WebCore/webaudio/RealtimeAnalyserNode.h @@ -0,0 +1,76 @@ +/* + * 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RealtimeAnalyserNode_h +#define RealtimeAnalyserNode_h + +#include "AudioNode.h" +#include "RealtimeAnalyser.h" + +namespace WebCore { + +class RealtimeAnalyserNode : public AudioNode { +public: + static PassRefPtr<RealtimeAnalyserNode> create(AudioContext* context, double sampleRate) + { + return adoptRef(new RealtimeAnalyserNode(context, sampleRate)); + } + + virtual ~RealtimeAnalyserNode(); + + // AudioNode + virtual void process(size_t framesToProcess); + virtual void pullInputs(size_t framesToProcess); + virtual void reset(); + + // Javascript bindings + unsigned int fftSize() const { return m_analyser.fftSize(); } + void setFftSize(unsigned int size) { m_analyser.setFftSize(size); } + + unsigned frequencyBinCount() const { return m_analyser.frequencyBinCount(); } + + void setMinDecibels(float k) { m_analyser.setMinDecibels(k); } + float minDecibels() const { return m_analyser.minDecibels(); } + + void setMaxDecibels(float k) { m_analyser.setMaxDecibels(k); } + float maxDecibels() const { return m_analyser.maxDecibels(); } + + void setSmoothingTimeConstant(float k) { m_analyser.setSmoothingTimeConstant(k); } + float smoothingTimeConstant() const { return m_analyser.smoothingTimeConstant(); } + +#if ENABLE(3D_CANVAS) + void getFloatFrequencyData(Float32Array* array) { m_analyser.getFloatFrequencyData(array); } + void getByteFrequencyData(Uint8Array* array) { m_analyser.getByteFrequencyData(array); } + void getByteTimeDomainData(Uint8Array* array) { m_analyser.getByteTimeDomainData(array); } +#endif + +private: + RealtimeAnalyserNode(AudioContext*, double sampleRate); + + RealtimeAnalyser m_analyser; +}; + +} // namespace WebCore + +#endif // RealtimeAnalyserNode_h diff --git a/WebCore/webaudio/RealtimeAnalyserNode.idl b/WebCore/webaudio/RealtimeAnalyserNode.idl new file mode 100644 index 0000000..5b2b223 --- /dev/null +++ b/WebCore/webaudio/RealtimeAnalyserNode.idl @@ -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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module audio { + interface [ + Conditional=WEB_AUDIO, + GenerateToJS + ] RealtimeAnalyserNode : AudioNode { + attribute unsigned long fftSize; + readonly attribute unsigned long frequencyBinCount; + + // minDecibels / maxDecibels represent the range to scale the FFT analysis data for conversion to unsigned byte values. + attribute float minDecibels; + attribute float maxDecibels; + + // A value from 0.0 -> 1.0 where 0.0 represents no time averaging with the last analysis frame. + attribute float smoothingTimeConstant; + + // Copies the current frequency data into the passed array. + // If the array has fewer elements than the frequencyBinCount, the excess elements will be dropped. + [Conditional=3D_CANVAS] void getFloatFrequencyData(in Float32Array array); + [Conditional=3D_CANVAS] void getByteFrequencyData(in Uint8Array array); + + // Real-time waveform data + [Conditional=3D_CANVAS] void getByteTimeDomainData(in Uint8Array array); + }; +} diff --git a/WebCore/wml/WMLDoElement.cpp b/WebCore/wml/WMLDoElement.cpp index 17a6d10..899bee1 100644 --- a/WebCore/wml/WMLDoElement.cpp +++ b/WebCore/wml/WMLDoElement.cpp @@ -90,7 +90,7 @@ void WMLDoElement::defaultEventHandler(Event* event) eventTimer->stop(); } - pageState->page()->goBack(); + pageState->page()->backForward()->goBack(); } else if (m_type == "reset") { WMLPageState* pageState = wmlPageStateForDocument(document()); if (!pageState) diff --git a/WebCore/wml/WMLDocument.cpp b/WebCore/wml/WMLDocument.cpp index 9781a68..440f8ee 100644 --- a/WebCore/wml/WMLDocument.cpp +++ b/WebCore/wml/WMLDocument.cpp @@ -68,11 +68,7 @@ void WMLDocument::finishedParsing() if (!page) return; - BackForwardList* list = page->backForwardList(); - if (!list) - return; - - HistoryItem* item = list->backItem(); + HistoryItem* item = page->backForward()->backItem(); if (!item) return; diff --git a/WebCore/wml/WMLPageState.cpp b/WebCore/wml/WMLPageState.cpp index d03cf44..5779e0e 100644 --- a/WebCore/wml/WMLPageState.cpp +++ b/WebCore/wml/WMLPageState.cpp @@ -64,8 +64,8 @@ void WMLPageState::reset() m_variables.clear(); // Clear the navigation history state - if (BackForwardList* list = m_page ? m_page->backForwardList() : 0) - list->clearWMLPageHistory(); + if (m_page) + m_page->backForward()->client()->clearWMLPageHistory(); } static inline String normalizedHostName(const String& passedHost) @@ -121,15 +121,11 @@ static bool tryAccessHistoryURLs(Page* page, KURL& previousURL, KURL& currentURL if (!frame || !frame->document()) return false; - BackForwardList* list = page->backForwardList(); - if (!list) - return false; - - HistoryItem* previousItem = list->backItem(); + HistoryItem* previousItem = page->backForward()->backItem(); if (!previousItem) return false; - HistoryItem* currentItem = list->currentItem(); + HistoryItem* currentItem = page->backForward()->currentItem(); if (!currentItem) return false; diff --git a/WebCore/wml/WMLPrevElement.cpp b/WebCore/wml/WMLPrevElement.cpp index b90e22b..fccdc0b 100644 --- a/WebCore/wml/WMLPrevElement.cpp +++ b/WebCore/wml/WMLPrevElement.cpp @@ -64,7 +64,7 @@ void WMLPrevElement::executeTask() if (WMLTimerElement* eventTimer = card->eventTimer()) eventTimer->stop(); - pageState->page()->goBack(); + pageState->page()->backForward()->goBack(); } } diff --git a/WebCore/xml/XMLHttpRequest.cpp b/WebCore/xml/XMLHttpRequest.cpp index afab73d..43ee8a8 100644 --- a/WebCore/xml/XMLHttpRequest.cpp +++ b/WebCore/xml/XMLHttpRequest.cpp @@ -23,7 +23,7 @@ #include "XMLHttpRequest.h" #include "Blob.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CrossOriginAccessControl.h" #include "DOMFormData.h" #include "DOMImplementation.h" @@ -600,7 +600,7 @@ void XMLHttpRequest::createRequest(ExceptionCode& ec) setPendingActivity(this); // For now we should only balance the nonCached request count for main-thread XHRs and not - // Worker XHRs, as the Cache is not thread-safe. + // Worker XHRs, as the MemoryCache is not thread-safe. // This will become irrelevant after https://bugs.webkit.org/show_bug.cgi?id=27165 is resolved. if (!scriptExecutionContext()->isWorkerContext()) { ASSERT(isMainThread()); diff --git a/WebCore/xml/XSLTProcessorLibxslt.cpp b/WebCore/xml/XSLTProcessorLibxslt.cpp index c2869c7..a307c21 100644 --- a/WebCore/xml/XSLTProcessorLibxslt.cpp +++ b/WebCore/xml/XSLTProcessorLibxslt.cpp @@ -117,10 +117,10 @@ static xmlDocPtr docLoaderFunc(const xmlChar* uri, Vector<char> data; - bool requestAllowed = globalCachedResourceLoader->frame() && globalCachedResourceLoader->doc()->securityOrigin()->canRequest(url); + bool requestAllowed = globalCachedResourceLoader->frame() && globalCachedResourceLoader->document()->securityOrigin()->canRequest(url); if (requestAllowed) { globalCachedResourceLoader->frame()->loader()->loadResourceSynchronously(url, AllowStoredCredentials, error, response, data); - requestAllowed = globalCachedResourceLoader->doc()->securityOrigin()->canRequest(response.url()); + requestAllowed = globalCachedResourceLoader->document()->securityOrigin()->canRequest(response.url()); } if (!requestAllowed) { data.clear(); diff --git a/WebKit/CMakeLists.txt b/WebKit/CMakeLists.txt index 6fb9582..0d3edca 100644 --- a/WebKit/CMakeLists.txt +++ b/WebKit/CMakeLists.txt @@ -14,6 +14,7 @@ SET(WebKit_INCLUDE_DIRECTORIES "${WEBCORE_DIR}/inspector" "${WEBCORE_DIR}/loader" "${WEBCORE_DIR}/loader/icon" + "${WEBCORE_DIR}/loader/cache" "${WEBCORE_DIR}/page" "${WEBCORE_DIR}/page/animation" "${WEBCORE_DIR}/platform" diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog index 9a6a950..ff4ab64 100644 --- a/WebKit/ChangeLog +++ b/WebKit/ChangeLog @@ -1,3 +1,19 @@ +2010-11-08 Leandro Pereira <leandro@profusion.mobi> + + [EFL] Unreviewed. Build fix after r71496. + + * CMakeLists.txt: Add WebCore/loader/cache directory to WebKit's + include directories list. + +2010-11-04 Mike Thole <mthole@apple.com> + + Reviewed by Dan Bernstein. + + Title for images should use localized numerals + https://bugs.webkit.org/show_bug.cgi?id=49017 + + * English.lproj/Localizable.strings: Updated. + 2010-10-28 Mark Rowe <mrowe@apple.com> Stop allowing deprecated methods to be used in NetscapePluginHostProxy.mm now diff --git a/WebKit/English.lproj/Localizable.strings b/WebKit/English.lproj/Localizable.strings Binary files differindex 3d09f86..9e9018b 100644 --- a/WebKit/English.lproj/Localizable.strings +++ b/WebKit/English.lproj/Localizable.strings diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog index 9eeb48b..6867714 100644 --- a/WebKit/chromium/ChangeLog +++ b/WebKit/chromium/ChangeLog @@ -1,3 +1,479 @@ +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * src/ChromeClientImpl.cpp: + (WebKit::ChromeClientImpl::focusedFrameChanged): + * src/ChromeClientImpl.h: + +2010-11-08 Andrey Kosyakov <caseq@chromium.org> + + Reviewed by Yury Semikhatsky. + + Only call WebInspector_syncDispatch if it's actually a function. + https://bugs.webkit.org/show_bug.cgi?id=49180 + + * src/WebDevToolsFrontendImpl.cpp: + (WebKit::WebDevToolsFrontendImpl::WebDevToolsFrontendImpl): + (WebKit::WebDevToolsFrontendImpl::dispatchOnInspectorFrontend): + * src/WebDevToolsFrontendImpl.h: + +2010-11-07 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Rename Cache to MemoryCache + https://bugs.webkit.org/show_bug.cgi?id=49159 + + * public/WebCache.h: + * src/WebCache.cpp: + (WebKit::ToResourceTypeStat): + (WebKit::WebCache::setCapacities): + (WebKit::WebCache::clear): + (WebKit::WebCache::getUsageStats): + (WebKit::WebCache::getResourceTypeStats): + +2010-11-07 Jay Civelli <jcivelli@chromium.org> + + Reviewed by Kent Tamura. + + Fixing a crasher with the select popup on Mac that happens when a + page removes the select node when the select changes. + https://bugs.webkit.org/show_bug.cgi?id=49108 + + * src/ExternalPopupMenu.cpp: + (WebKit::ExternalPopupMenu::didAcceptIndex): + (WebKit::ExternalPopupMenu::didCancel): + +2010-11-06 Pavel Feldman <pfeldman@chromium.org> + + Not reviewed. Chromium DevTools: disable filesystem inspection + until polished. + https://bugs.webkit.org/show_bug.cgi?id=48963 + + * src/js/DevTools.js: + +2010-11-05 Ilya Sherman <isherman@chromium.org> + + Reviewed by Simon Fraser. + + Querying selection start and end should be const + https://bugs.webkit.org/show_bug.cgi?id=48786 + + * public/WebInputElement.h: + * src/WebInputElement.cpp: + (WebKit::WebInputElement::selectionStart): + (WebKit::WebInputElement::selectionEnd): + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Move resumeAnimations/suspendAnimations from Frame to AnimationController. + https://bugs.webkit.org/show_bug.cgi?id=49073 + + * src/WebAnimationControllerImpl.cpp: + (WebKit::WebAnimationControllerImpl::suspendAnimations): + (WebKit::WebAnimationControllerImpl::resumeAnimations): + +2010-11-04 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + Need to simulate DEPTH_STENCIL in framebufferRenderbuffer / getFramebufferAttachmentParameter + https://bugs.webkit.org/show_bug.cgi?id=49020 + + * src/WebGraphicsContext3DDefaultImpl.cpp: Remove DEPTH_STENCIL_ATTACHMENT emulation at this level. + +2010-11-05 Darin Fisher <darin@chromium.org> + + Pull chromium@65229 to fix the build. + + * DEPS: + +2010-11-05 Darin Fisher <darin@chromium.org> + + Reviewed by Nate Chapin. + + Replace deprecated TargetIsSub{Frame,Resource} with TargetIsSub{frame,resource}. + https://bugs.webkit.org/show_bug.cgi?id=49074 + + * public/WebURLRequest.h: + * src/FrameLoaderClientImpl.cpp: + +2010-11-05 Charlie Reis <creis@chromium.org> + + Reviewed by Darin Fisher. + + WebFrame::previousHistoryItem() should return last committed item. + https://bugs.webkit.org/show_bug.cgi?id=48809 + + * src/WebFrameImpl.cpp: + +2010-10-27 Jeremy Orlow <jorlow@chromium.org> + + Reviewed by Steve Block. + + Clean up IDBTransactionBackend/Coordinator + https://bugs.webkit.org/show_bug.cgi?id=48425 + + Remove obsolete ::id() method. + + * public/WebIDBTransaction.h: + * src/IDBTransactionBackendProxy.cpp: + * src/IDBTransactionBackendProxy.h: + * src/WebIDBTransactionImpl.cpp: + * src/WebIDBTransactionImpl.h: + +2010-11-04 usaini <usaini08@gmail.com> + + Reviewed by Antonio Gomes. + + WebWindowFeatures has a faulty constructor for WebCore::WindowFeatures + https://bugs.webkit.org/show_bug.cgi?id=48035 + + * public/WebWindowFeatures.h: + (WebKit::WebWindowFeatures::WebWindowFeatures): updated the constructor + that takes in a WebCore::WindowFeature and had it copy all the variables + over properly so that after calling the constructor WebWindowFeatures is + always in a valid state. Before, the x,y,width,height booleans may be true, but + the corresponding int values would not be updated. + +2010-11-04 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + Remove IMPLEMENTATION_COLOR_READ_FORMAT and TYPE + https://bugs.webkit.org/show_bug.cgi?id=48938 + + * src/WebGraphicsContext3DDefaultImpl.cpp: + (WebKit::WebGraphicsContext3DDefaultImpl::getIntegerv): + +2010-11-04 Kavita Kanetkar <kkanetkar@chromium.org> + + Reviewed by Adam Barth. + + Web Inspector: Enable files ystem UI for chromium + https://bugs.webkit.org/show_bug.cgi?id=48963 + + * src/js/DevTools.js: + +2010-11-03 Adam Barth <abarth@webkit.org> + + Roll Chromium DEPS + https://bugs.webkit.org/show_bug.cgi?id=48978 + + * DEPS: + +2010-11-03 Vincent Scheib <scheib@chromium.org> + + Reviewed by James Robinson. + + [chromium] GraphicsContext3D creation attributes include canRecoverFromContextLoss option + https://bugs.webkit.org/show_bug.cgi?id=48850 + + Implementations of GraphicsContext3D may respect the creation attribute + canRecoverFromContextLoss being false, and then only succeeding initialization if + the context can satisfy that request of never being lost. DX9 on XP can not satisfy + such a request. + + Test by use of accelerated canvas 2d in Chromium with ANGLE on XP machines. + + * public/WebGraphicsContext3D.h: + (WebKit::WebGraphicsContext3D::Attributes::Attributes): + * src/GraphicsContext3DChromium.cpp: + (WebCore::GraphicsContext3DInternal::initialize): + +2010-11-03 Jenn Braithwaite <jennb@chromium.org> + + Reviewed by Dmitry Titov. + + Chromium: Update resource tracking when moving a frame between documents + https://bugs.webkit.org/show_bug.cgi?id=48363 + + * public/WebFrameClient.h: + (WebKit::WebFrameClient::removeIdentifierForRequest): + Added + * src/FrameLoaderClientImpl.cpp: + (WebKit::FrameLoaderClientImpl::transferLoadingResourceFromPage): + Notify current WebFrameClient of the resource and remove from + former WebFrameClient. + +2010-11-03 Adam Barth <abarth@webkit.org> + + Roll Chromium DEPs + https://bugs.webkit.org/show_bug.cgi?id=48959 + + * DEPS: + +2010-11-03 Kenneth Russell <kbr@google.com> + + Reviewed by Chris Marrin. + + Redesign extension mechanism in GraphicsContext3D + https://bugs.webkit.org/show_bug.cgi?id=46894 + + Upon request, factored out extension support from GraphicsContext3D + into a new Extensions3D class. (The plural was chosen because the + class and subclasses hold multiple extensions.) + + Unlike GraphicsContext3D, Extensions3D contains only pure virtual + methods. This was done because Extensions3D's inheritance diagram + and usage pattern is very different from that of GraphicsContext3D, + and the concrete subclasses need to decide how to implement the + various entry points. Requiring them to be placed at the + Extensions3D level will cause implementation details to leak into + the base class, which is highly undesirable. Any virtual call + overhead to these entry points will be negligible. + + Changed call sites utilizing these extensions to call through the + Extensions3D object or its subclasses. + + Tested: + - Chromium on Linux with accelerated 2D canvas and HTML5 video + - Chromium on Mac OS X with WebGL and CSS 3D content + - Safari on Mac OS X with WebGL and CSS 3D content + + No new tests. Covered by existing tests. + + * WebKit.gyp: + * public/WebGraphicsContext3D.h: + * src/Extensions3DChromium.cpp: Added. + (WebCore::Extensions3DChromium::Extensions3DChromium): + (WebCore::Extensions3DChromium::~Extensions3DChromium): + (WebCore::Extensions3DChromium::supports): + (WebCore::Extensions3DChromium::getGraphicsResetStatusARB): + (WebCore::Extensions3DChromium::mapBufferSubDataCHROMIUM): + (WebCore::Extensions3DChromium::unmapBufferSubDataCHROMIUM): + (WebCore::Extensions3DChromium::mapTexSubImage2DCHROMIUM): + (WebCore::Extensions3DChromium::unmapTexSubImage2DCHROMIUM): + (WebCore::Extensions3DChromium::copyTextureToParentTextureCHROMIUM): + * src/GraphicsContext3DChromium.cpp: + (WebCore::GraphicsContext3DInternal::GraphicsContext3DInternal): + (WebCore::GraphicsContext3DInternal::getExtensions): + (WebCore::GraphicsContext3DInternal::supportsExtension): + * src/GraphicsContext3DInternal.h: + * src/WebGraphicsContext3DDefaultImpl.cpp: + (WebKit::WebGraphicsContext3DDefaultImpl::copyTextureToParentTextureCHROMIUM): + (WebKit::WebGraphicsContext3DDefaultImpl::getString): + * src/WebGraphicsContext3DDefaultImpl.h: + * src/WebViewImpl.cpp: + (WebKit::WebViewImpl::composite): + +2010-11-03 Daniel Bates <dbates@rim.com> + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 1 of 2. + + Substitute FrameTree::uniqueName() for FrameTree::name() in the Chromium port. + + * src/WebFrameImpl.cpp: + (WebKit::WebFrameImpl::name): + +2010-11-02 Al Patrick <apatrick@chromium.org> + + Reviewed by Kenneth Russell. + + [chromium] Plugin instances can propagate the ID of the OpenGL texture they render to. + + https://bugs.webkit.org/show_bug.cgi?id=48032 + + * public/WebPlugin.h: + (WebKit::WebPlugin::getBackingTextureId): + * public/WebPluginContainer.h: + (WebKit::WebPluginContainer::commitBackingTexture): + * src/WebPluginContainerImpl.cpp: + (WebKit::WebPluginContainerImpl::commitBackingTexture): + (WebKit::WebPluginContainerImpl::platformLayer): + (WebKit::WebPluginContainerImpl::WebPluginContainerImpl): + * src/WebPluginContainerImpl.h: + +2010-11-02 Kavita Kanetkar <kkanetkar@chromium.org> + + Reviewed by Dumitru Daniliuc. + + [FileSystem] Support not creating directories when queried by inspector. + https://bugs.webkit.org/show_bug.cgi?id=48169 + + * src/LocalFileSystemChromium.cpp: + (WebCore::LocalFileSystem::readFileSystem): + (WebCore::LocalFileSystem::requestFileSystem): + +2010-11-02 Chris Guillory <chris.guillory@google.com> + + Reviewed by Chris Fleizach. + + Chromium: Propagate a document value changed notification on scroll. + https://bugs.webkit.org/show_bug.cgi?id=48817 + + * src/WebAccessibilityObject.cpp: + (WebKit::WebAccessibilityObject::boundingBoxRect): + +2010-10-29 John Abd-El-Malek <jam@chromium.org> + + Reviewed by Darin Fisher. + + [chromium]: Allow plugins to use optimized scrolling + https://bugs.webkit.org/show_bug.cgi?id=48660 + + * public/WebPluginContainer.h: + * src/WebPluginContainerImpl.cpp: + (WebKit::WebPluginContainerImpl::scrollRect): + * src/WebPluginContainerImpl.h: + +2010-11-02 Marc-Antoine Ruel <maruel@chromium.org> + + Reviewed by Dimitri Glazkov. + + Disable incremental linking for webkit_unit_test and DumpRenderTRee on x86 Windows on chromium build. + https://bugs.webkit.org/show_bug.cgi?id=48836 + + It fails to link otherwise due to lack of virtual address space. + + * WebKit.gyp: + +2010-11-02 Ilya Sherman <isherman@chromium.org> + + Reviewed by Kent Tamura. + + Expose the sendChangeEvent parameter in WebInputElement::setValue() API, + primarily so that chromium form autofill can fire the onChange event. + https://bugs.webkit.org/show_bug.cgi?id=48177 + + * public/WebInputElement.h: + * src/WebInputElement.cpp: + (WebKit::WebInputElement::setValue): + +2010-11-02 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: make properties and event listeners look consistent with the styles section. + https://bugs.webkit.org/show_bug.cgi?id=48827 + + * src/js/devTools.css: + +2010-11-01 Tony Chang <tony@chromium.org> + + Reviewed by Kent Tamura. + + [chromium] Compile TestNetscapePlugin on chromium win + https://bugs.webkit.org/show_bug.cgi?id=48802 + + It creates npTestNetscapePlugin.dll in the build directory, so + it's not yet loaded by DRT or test_shell. + + * WebKit.gyp: + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * src/ChromeClientImpl.h: + (WebKit::ChromeClientImpl::showContextMenu): + +2010-11-01 Pavel Feldman <pfeldman@chromium.org> + + Not reviewed: Chromium build fix. + + * src/WebDevToolsAgentImpl.cpp: + (WebKit::WebDevToolsAgentImpl::WebDevToolsAgentImpl): + +2010-11-01 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: remove old resources panel. + https://bugs.webkit.org/show_bug.cgi?id=45657 + + * src/WebDevToolsAgentImpl.cpp: + (WebKit::WebDevToolsAgentImpl::setApuAgentEnabled): + * src/WebDevToolsAgentImpl.h: + +2010-11-01 Leandro Gracia Gil <leandrogracia@google.com> + + Reviewed by Jeremy Orlow. + + This is the last part of a 4-sided patch for the language attribute + in speech text buttons. This patch removes what now is dead code + and re-enables the layout test introduced by bug 47089. + https://bugs.webkit.org/show_bug.cgi?id=47420 + + * public/WebSpeechInputControllerMock.h: + * src/WebSpeechInputControllerMockImpl.cpp: + * src/WebSpeechInputControllerMockImpl.h: + +2010-10-31 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: unhide new network and resources panels. + https://bugs.webkit.org/show_bug.cgi?id=48725 + + * src/WebDevToolsAgentImpl.cpp: + (WebKit::WebDevToolsAgentImpl::setApuAgentEnabled): + +2010-10-29 Daniel Bates <dbates@rim.com> + + No review, rolling out 70971. + http://trac.webkit.org/changeset/70971 + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Rolling out changeset 70971 <http://trac.webkit.org/changeset/70971> since + it caused layout test failures on all bots. In particular, the + child count in a generated frame name differs after this patch. We need + to look into this further. + + * src/WebFrameImpl.cpp: + (WebKit::WebFrameImpl::name): + +2010-10-28 Antonio Gomes <agomes@rim.com> + + Reviewed by Ojan Vafai. + + Needs a "LinuxEditingBehavior", perhaps with a better name + https://bugs.webkit.org/show_bug.cgi?id=36627 + + Added the corresponding Chromium setting to WebCore's EditingUnixBehavior: EditingBehaviorUnix. + + * public/WebSettings.h: + * src/AssertMatchingEnums.cpp: + +2010-10-29 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Modified Chromium-port to use FrameTree::uniqueName(). + + * src/WebFrameImpl.cpp: + (WebKit::WebFrameImpl::name): + +2010-10-29 Kavita Kanetkar <kkanetkar@chromium.org> + + Reviewed by Pavel Feldman. + + Web Inspector: FileSystem integration + https://bugs.webkit.org/show_bug.cgi?id=45982 + + * public/WebFileUtilities.h: + (WebKit::WebFileUtilities::revealFolderInOS): + * src/ChromiumBridge.cpp: + (WebCore::ChromiumBridge::revealFolderInOS): + + 2010-10-29 Darin Adler <darin@apple.com> Reviewed by Sam Weinig. diff --git a/WebKit/chromium/DEPS b/WebKit/chromium/DEPS index aaf0b0a..4fc0372 100644 --- a/WebKit/chromium/DEPS +++ b/WebKit/chromium/DEPS @@ -32,7 +32,7 @@ vars = { 'chromium_svn': 'http://src.chromium.org/svn/trunk/src', - 'chromium_rev': '64214' + 'chromium_rev': '65229' } deps = { @@ -91,14 +91,12 @@ deps = { Var('chromium_svn')+'/media@'+Var('chromium_rev'), 'printing': Var('chromium_svn')+'/printing@'+Var('chromium_rev'), + 'ppapi': + Var('chromium_svn')+'/ppapi@'+Var('chromium_rev'), 'third_party/angle': # needed by the gpu process From('chromium_deps', 'src/third_party/angle'), 'third_party/ffmpeg': # needed by webkit/media From('chromium_deps', 'src/third_party/ffmpeg'), - 'third_party/libvpx/include': - From('chromium_deps', 'src/third_party/libvpx/include'), - 'third_party/libvpx/lib': - From('chromium_deps', 'src/third_party/libvpx/lib'), 'third_party/libwebp': Var('chromium_svn')+'/third_party/libwebp@'+Var('chromium_rev'), 'tools/grit': @@ -111,8 +109,6 @@ deps = { Var('chromium_svn')+'/third_party@'+Var('chromium_rev'), 'third_party/icu': From('chromium_deps', 'src/third_party/icu'), - 'third_party/ppapi': - From('chromium_deps', 'src/third_party/ppapi'), 'third_party/ots': From('chromium_deps', 'src/third_party/ots'), } diff --git a/WebKit/chromium/WebKit.gyp b/WebKit/chromium/WebKit.gyp index f121c5f..4dcc61a 100644 --- a/WebKit/chromium/WebKit.gyp +++ b/WebKit/chromium/WebKit.gyp @@ -328,6 +328,7 @@ 'src/EditorClientImpl.h', 'src/EventListenerWrapper.cpp', 'src/EventListenerWrapper.h', + 'src/Extensions3DChromium.cpp', 'src/ExternalPopupMenu.cpp', 'src/ExternalPopupMenu.h', 'src/FrameLoaderClientImpl.cpp', @@ -741,7 +742,6 @@ 'action': ['python', '<@(_script_name)', '<@(_input_page)', '<@(_search_path)', '<@(_outputs)'], }], }, - { 'target_name': 'webkit_unit_tests', 'type': 'executable', @@ -801,6 +801,17 @@ }], ], }], + ['inside_chromium_build==1 and OS=="win" and component!="shared_library"', { + 'configurations': { + 'Debug_Base': { + 'msvs_settings': { + 'VCLinkerTool': { + 'LinkIncremental': '<(msvs_large_module_debug_link_mode)', + }, + }, + }, + }, + }], ], }, { @@ -826,6 +837,7 @@ 'dependencies': [ 'ImageDiff', 'inspector_resources', + 'TestNetscapePlugIn', 'webkit', '../../JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp:wtf_config', '<(chromium_src_dir)/third_party/icu/icu.gyp:icuuc', @@ -872,6 +884,17 @@ '../../JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp:wtf', ], }], + ['inside_chromium_build==1', { + 'configurations': { + 'Debug_Base': { + 'msvs_settings': { + 'VCLinkerTool': { + 'LinkIncremental': '<(msvs_large_module_debug_link_mode)', + }, + }, + }, + }, + }], ], 'copies': [{ 'destination': '<(PRODUCT_DIR)', @@ -881,9 +904,6 @@ 'sources/': [ ['exclude', 'Win\\.cpp$'], ], - 'dependencies': [ - 'TestNetscapePlugIn', - ], 'actions': [ { 'action_name': 'repack_locale', @@ -972,6 +992,63 @@ }], ], }, + { + 'target_name': 'TestNetscapePlugIn', + 'type': 'loadable_module', + 'sources': [ '<@(test_plugin_files)' ], + 'dependencies': [ + '<(chromium_src_dir)/third_party/npapi/npapi.gyp:npapi', + ], + 'include_dirs': [ + '<(chromium_src_dir)', + '../../WebKitTools/DumpRenderTree/TestNetscapePlugIn', + '../../WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders', + ], + 'conditions': [ + ['OS=="mac"', { + 'mac_bundle': 1, + # It would be nice to name this + # TestNetscapePlugIn, but that name is already + # used by the fork of this plugin in Chromium. + 'product_name': 'WebKitTestNetscapePlugIn', + 'product_extension': 'plugin', + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/Carbon.framework', + '$(SDKROOT)/System/Library/Frameworks/Cocoa.framework', + '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework', + ] + }, + 'xcode_settings': { + 'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO', + # This is a temporary fork of + # DRT/TestNetscapePlugIn/mac/Info.plist. Once + # we get rid of our forked plugin in the + # chromium repo, we can share the same + # Info.plist. + 'INFOPLIST_FILE': '../../WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/Info.plist', + }, + }], + ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', { + 'cflags': [ + '-fvisibility=default', + ], + }], + ['OS=="win"', { + 'defines': [ + # This seems like a hack, but this is what Safari Win does. + 'snprintf=_snprintf', + ], + 'sources': [ + '../../WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.def', + '../../WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.rc', + ], + # The .rc file requires that the name of the dll is npTestNetscapePlugin.dll. + # This adds the 'np' to the dll name. + 'product_prefix': 'np', + }], + ], + }, ], # targets 'conditions': [ ['OS=="win"', { @@ -980,54 +1057,6 @@ 'type': 'executable', 'sources': ['../../WebKitTools/DumpRenderTree/chromium/LayoutTestHelperWin.cpp'], }], - }, { # OS!="win" - 'targets': [ - { - 'target_name': 'TestNetscapePlugIn', - 'type': 'loadable_module', - 'sources': [ '<@(test_plugin_files)' ], - 'dependencies': [ - '<(chromium_src_dir)/third_party/npapi/npapi.gyp:npapi', - ], - 'include_dirs': [ - '<(chromium_src_dir)', - '../../WebKitTools/DumpRenderTree/TestNetscapePlugIn', - '../../WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders', - ], - - 'conditions': [ - ['OS=="mac"', { - 'mac_bundle': 1, - # It would be nice to name this - # TestNetscapePlugIn, but that name is already - # used by the fork of this plugin in Chromium. - 'product_name': 'WebKitTestNetscapePlugIn', - 'product_extension': 'plugin', - 'link_settings': { - 'libraries': [ - '$(SDKROOT)/System/Library/Frameworks/Carbon.framework', - '$(SDKROOT)/System/Library/Frameworks/Cocoa.framework', - '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework', - ] - }, - 'xcode_settings': { - 'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO', - # This is a temporary fork of - # DRT/TestNetscapePlugIn/mac/Info.plist. Once - # we get rid of our forked plugin in the - # chromium repo, we can share the same - # Info.plist. - 'INFOPLIST_FILE': '../../WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/Info.plist', - }, - }], - ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', { - 'cflags': [ - '-fvisibility=default', - ], - }], - ], - }, - ], }], ['OS=="mac"', { 'targets': [ diff --git a/WebKit/chromium/public/WebCache.h b/WebKit/chromium/public/WebCache.h index 433eb1a..e8a18d3 100644 --- a/WebKit/chromium/public/WebCache.h +++ b/WebKit/chromium/public/WebCache.h @@ -48,7 +48,7 @@ public: size_t deadSize; }; - // A struct mirroring WebCore::Cache::TypeStatistic. + // A struct mirroring WebCore::MemoryCache::TypeStatistic. struct ResourceTypeStat { size_t count; size_t size; @@ -56,7 +56,7 @@ public: size_t decodedSize; }; - // A struct mirroring WebCore::Cache::Statistics. + // A struct mirroring WebCore::MemoryCache::Statistics. struct ResourceTypeStats { ResourceTypeStat images; ResourceTypeStat cssStyleSheets; diff --git a/WebKit/chromium/public/WebFileUtilities.h b/WebKit/chromium/public/WebFileUtilities.h index 456ba69..c8876f2 100644 --- a/WebKit/chromium/public/WebFileUtilities.h +++ b/WebKit/chromium/public/WebFileUtilities.h @@ -48,7 +48,7 @@ public: #else typedef int FileHandle; #endif - + virtual void revealFolderInOS(const WebString& path) { } virtual bool fileExists(const WebString& path) { return false; } virtual bool deleteFile(const WebString& path) { return false; } virtual bool deleteEmptyDirectory(const WebString& path) { return false; } diff --git a/WebKit/chromium/public/WebFrameClient.h b/WebKit/chromium/public/WebFrameClient.h index c5cfc21..9063350 100644 --- a/WebKit/chromium/public/WebFrameClient.h +++ b/WebKit/chromium/public/WebFrameClient.h @@ -240,6 +240,10 @@ public: virtual void assignIdentifierToRequest( WebFrame*, unsigned identifier, const WebURLRequest&) { } + // Remove the association between an identifier assigned to a request if + // the client keeps such an association. + virtual void removeIdentifierForRequest(unsigned identifier) { } + // A request is about to be sent out, and the client may modify it. Request // is writable, and changes to the URL, for example, will change the request // made. If this request is the result of a redirect, then redirectResponse diff --git a/WebKit/chromium/public/WebGraphicsContext3D.h b/WebKit/chromium/public/WebGraphicsContext3D.h index 15e6365..9656887 100644 --- a/WebKit/chromium/public/WebGraphicsContext3D.h +++ b/WebKit/chromium/public/WebGraphicsContext3D.h @@ -64,6 +64,7 @@ public: , stencil(true) , antialias(true) , premultipliedAlpha(true) + , canRecoverFromContextLoss(true) { } @@ -72,6 +73,7 @@ public: bool stencil; bool antialias; bool premultipliedAlpha; + bool canRecoverFromContextLoss; }; // This destructor needs to be public so that using classes can destroy instances if initialization fails. @@ -134,18 +136,13 @@ public: // getError in the order they were added. virtual void synthesizeGLError(unsigned long error) = 0; - // EXT_texture_format_BGRA8888 - virtual bool supportsBGRA() = 0; - // GL_CHROMIUM_map_sub - virtual bool supportsMapSubCHROMIUM() = 0; virtual void* mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access) = 0; virtual void unmapBufferSubDataCHROMIUM(const void*) = 0; virtual void* mapTexSubImage2DCHROMIUM(unsigned target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, unsigned access) = 0; virtual void unmapTexSubImage2DCHROMIUM(const void*) = 0; // GL_CHROMIUM_copy_texture_to_parent_texture - virtual bool supportsCopyTextureToParentTextureCHROMIUM() = 0; virtual void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture) = 0; // The entry points below map directly to the OpenGL ES 2.0 API. diff --git a/WebKit/chromium/public/WebIDBTransaction.h b/WebKit/chromium/public/WebIDBTransaction.h index 385dd1e..cff7c67 100644 --- a/WebKit/chromium/public/WebIDBTransaction.h +++ b/WebKit/chromium/public/WebIDBTransaction.h @@ -52,11 +52,6 @@ public: } virtual void abort() { WEBKIT_ASSERT_NOT_REACHED(); } virtual void didCompleteTaskEvents() { WEBKIT_ASSERT_NOT_REACHED(); } - virtual int id() const - { - WEBKIT_ASSERT_NOT_REACHED(); - return 0; - } virtual void setCallbacks(WebIDBTransactionCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } // FIXME: this is never called from WebCore. Find a cleaner solution. diff --git a/WebKit/chromium/public/WebInputElement.h b/WebKit/chromium/public/WebInputElement.h index 8fea4fa..0c0764c 100644 --- a/WebKit/chromium/public/WebInputElement.h +++ b/WebKit/chromium/public/WebInputElement.h @@ -66,7 +66,7 @@ namespace WebKit { WEBKIT_API bool isActivatedSubmit() const; WEBKIT_API void setActivatedSubmit(bool); WEBKIT_API int size() const; - WEBKIT_API void setValue(const WebString&); + WEBKIT_API void setValue(const WebString&, bool sendChangeEvent = false); WEBKIT_API WebString value() const; WEBKIT_API void setSuggestedValue(const WebString&); WEBKIT_API WebString suggestedValue() const; @@ -76,8 +76,8 @@ namespace WebKit { WEBKIT_API void setAutofilled(bool); WEBKIT_API void dispatchFormControlChangeEvent(); WEBKIT_API void setSelectionRange(int, int); - WEBKIT_API int selectionStart(); - WEBKIT_API int selectionEnd(); + WEBKIT_API int selectionStart() const; + WEBKIT_API int selectionEnd() const; WEBKIT_API bool isValidValue(const WebString&) const; #if WEBKIT_IMPLEMENTATION diff --git a/WebKit/chromium/public/WebPlugin.h b/WebKit/chromium/public/WebPlugin.h index 17e29e2..4a6f081 100644 --- a/WebKit/chromium/public/WebPlugin.h +++ b/WebKit/chromium/public/WebPlugin.h @@ -64,6 +64,10 @@ public: virtual void updateGeometry( const WebRect& frameRect, const WebRect& clipRect, const WebVector<WebRect>& cutOutsRects, bool isVisible) = 0; + + // If the plugin instance is backed by an OpenGL texture, return its ID in the + // compositors namespace. Otherwise return 0. Returns 0 by default. + virtual unsigned getBackingTextureId() { return 0; } virtual void updateFocus(bool) = 0; virtual void updateVisibility(bool) = 0; diff --git a/WebKit/chromium/public/WebPluginContainer.h b/WebKit/chromium/public/WebPluginContainer.h index af20c66..c580f81 100644 --- a/WebKit/chromium/public/WebPluginContainer.h +++ b/WebKit/chromium/public/WebPluginContainer.h @@ -49,11 +49,15 @@ public: virtual void invalidate() = 0; virtual void invalidateRect(const WebRect&) = 0; + virtual void scrollRect(int dx, int dy, const WebRect&) = 0; // Causes the container to report its current geometry via // WebPlugin::updateGeometry. virtual void reportGeometry() = 0; - + + // Called when the backing texture is ready to be composited. + virtual void commitBackingTexture() {} + // Drop any references to script objects allocated by the plugin. // These are objects derived from WebPlugin::scriptableObject. This is // called when the plugin is being destroyed or if it needs to be diff --git a/WebKit/chromium/public/WebSettings.h b/WebKit/chromium/public/WebSettings.h index 6a37e08..469db05 100644 --- a/WebKit/chromium/public/WebSettings.h +++ b/WebKit/chromium/public/WebSettings.h @@ -45,7 +45,8 @@ class WebSettings { public: enum EditingBehavior { EditingBehaviorMac, - EditingBehaviorWin + EditingBehaviorWin, + EditingBehaviorUnix }; virtual void setStandardFontFamily(const WebString&) = 0; diff --git a/WebKit/chromium/public/WebSpeechInputControllerMock.h b/WebKit/chromium/public/WebSpeechInputControllerMock.h index b4c50a0..0a7f6f9 100644 --- a/WebKit/chromium/public/WebSpeechInputControllerMock.h +++ b/WebKit/chromium/public/WebSpeechInputControllerMock.h @@ -45,10 +45,6 @@ public: virtual ~WebSpeechInputControllerMock() { } virtual void setMockRecognitionResult(const WebString& result, const WebString& language) = 0; - - // FIXME: this is a fix for a two-sided patch. Delete as soon as the chromium side is patched. - // Chromium patch not uploaded yet, but will depend on http://codereview.chromium.org/3615005/show patch. - virtual void setMockRecognitionResult(const WebString& result) = 0; }; } // namespace WebKit diff --git a/WebKit/chromium/public/WebURLRequest.h b/WebKit/chromium/public/WebURLRequest.h index e64ce80..c800452 100644 --- a/WebKit/chromium/public/WebURLRequest.h +++ b/WebKit/chromium/public/WebURLRequest.h @@ -58,9 +58,7 @@ public: enum TargetType { TargetIsMainFrame = 0, - TargetIsSubFrame = 1, // Temporary for backward compatibility. TargetIsSubframe = 1, - TargetIsSubResource = 2, // Temporary for backward comptibility. TargetIsSubresource = 2, TargetIsStyleSheet = 3, TargetIsScript = 4, diff --git a/WebKit/chromium/public/WebWindowFeatures.h b/WebKit/chromium/public/WebWindowFeatures.h index 2e7278a..99d8580 100644 --- a/WebKit/chromium/public/WebWindowFeatures.h +++ b/WebKit/chromium/public/WebWindowFeatures.h @@ -81,9 +81,13 @@ struct WebWindowFeatures { #if WEBKIT_IMPLEMENTATION WebWindowFeatures(const WebCore::WindowFeatures& f) - : xSet(f.xSet) + : x(f.x) + , xSet(f.xSet) + , y(f.y) , ySet(f.ySet) + , width(f.width) , widthSet(f.widthSet) + , height(f.height) , heightSet(f.heightSet) , menuBarVisible(f.menuBarVisible) , statusBarVisible(f.statusBarVisible) diff --git a/WebKit/chromium/src/AssertMatchingEnums.cpp b/WebKit/chromium/src/AssertMatchingEnums.cpp index c6ab85a..3fffd60 100644 --- a/WebKit/chromium/src/AssertMatchingEnums.cpp +++ b/WebKit/chromium/src/AssertMatchingEnums.cpp @@ -344,6 +344,7 @@ COMPILE_ASSERT_MATCHING_ENUM(WebScrollbar::ScrollByPixel, ScrollByPixel); COMPILE_ASSERT_MATCHING_ENUM(WebSettings::EditingBehaviorMac, EditingMacBehavior); COMPILE_ASSERT_MATCHING_ENUM(WebSettings::EditingBehaviorWin, EditingWindowsBehavior); +COMPILE_ASSERT_MATCHING_ENUM(WebSettings::EditingBehaviorUnix, EditingUnixBehavior); COMPILE_ASSERT_MATCHING_ENUM(WebTextAffinityUpstream, UPSTREAM); COMPILE_ASSERT_MATCHING_ENUM(WebTextAffinityDownstream, DOWNSTREAM); diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp b/WebKit/chromium/src/ChromeClientImpl.cpp index df13b29..18f7a02 100644 --- a/WebKit/chromium/src/ChromeClientImpl.cpp +++ b/WebKit/chromium/src/ChromeClientImpl.cpp @@ -252,6 +252,10 @@ void ChromeClientImpl::focusedNodeChanged(Node* node) m_webView->client()->setKeyboardFocusURL(focusURL); } +void ChromeClientImpl::focusedFrameChanged(Frame*) +{ +} + Page* ChromeClientImpl::createWindow( Frame* frame, const FrameLoadRequest& r, const WindowFeatures& features, const NavigationAction&) { diff --git a/WebKit/chromium/src/ChromeClientImpl.h b/WebKit/chromium/src/ChromeClientImpl.h index 039fc1b..87c1653 100644 --- a/WebKit/chromium/src/ChromeClientImpl.h +++ b/WebKit/chromium/src/ChromeClientImpl.h @@ -70,6 +70,7 @@ public: virtual bool canTakeFocus(WebCore::FocusDirection); virtual void takeFocus(WebCore::FocusDirection); virtual void focusedNodeChanged(WebCore::Node*); + virtual void focusedFrameChanged(WebCore::Frame*); virtual WebCore::Page* createWindow( WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&); virtual void show(); @@ -174,6 +175,10 @@ public: virtual PassRefPtr<WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const; virtual PassRefPtr<WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const; +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif + private: void getPopupMenuInfo(WebCore::PopupContainer*, WebPopupMenuInfo*); diff --git a/WebKit/chromium/src/ChromiumBridge.cpp b/WebKit/chromium/src/ChromiumBridge.cpp index 1af32cf..39d2566 100644 --- a/WebKit/chromium/src/ChromiumBridge.cpp +++ b/WebKit/chromium/src/ChromiumBridge.cpp @@ -345,6 +345,11 @@ bool ChromiumBridge::getFileSize(const String& path, long long& result) return webKitClient()->fileUtilities()->getFileSize(path, result); } +void ChromiumBridge::revealFolderInOS(const String& path) +{ + webKitClient()->fileUtilities()->revealFolderInOS(path); +} + bool ChromiumBridge::getFileModificationTime(const String& path, time_t& result) { double modificationTime; diff --git a/WebKit/chromium/src/Extensions3DChromium.cpp b/WebKit/chromium/src/Extensions3DChromium.cpp new file mode 100644 index 0000000..c36040b --- /dev/null +++ b/WebKit/chromium/src/Extensions3DChromium.cpp @@ -0,0 +1,84 @@ +/* + * 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(3D_CANVAS) + +#include "Extensions3DChromium.h" + +#include "GraphicsContext3D.h" +#include "GraphicsContext3DInternal.h" + +namespace WebCore { + +Extensions3DChromium::Extensions3DChromium(GraphicsContext3DInternal* internal) + : m_internal(internal) +{ +} + +Extensions3DChromium::~Extensions3DChromium() +{ +} + +bool Extensions3DChromium::supports(const String& name) +{ + return m_internal->supportsExtension(name); +} + +int Extensions3DChromium::getGraphicsResetStatusARB() +{ + // FIXME: implement this in GraphicsContext3DInternal / WebGraphicsContext3DInternal. + return GraphicsContext3D::NO_ERROR; +} + +void* Extensions3DChromium::mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access) +{ + return m_internal->mapBufferSubDataCHROMIUM(target, offset, size, access); +} + +void Extensions3DChromium::unmapBufferSubDataCHROMIUM(const void* data) +{ + m_internal->unmapBufferSubDataCHROMIUM(data); +} + +void* Extensions3DChromium::mapTexSubImage2DCHROMIUM(unsigned target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, unsigned access) +{ + return m_internal->mapTexSubImage2DCHROMIUM(target, level, xoffset, yoffset, width, height, format, type, access); +} + +void Extensions3DChromium::unmapTexSubImage2DCHROMIUM(const void* data) +{ + m_internal->unmapTexSubImage2DCHROMIUM(data); +} + +void Extensions3DChromium::copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture) +{ + m_internal->copyTextureToParentTextureCHROMIUM(texture, parentTexture); +} + +} // namespace WebCore + +#endif // ENABLE(3D_CANVAS) diff --git a/WebKit/chromium/src/ExternalPopupMenu.cpp b/WebKit/chromium/src/ExternalPopupMenu.cpp index a0243eb..0f208fb 100644 --- a/WebKit/chromium/src/ExternalPopupMenu.cpp +++ b/WebKit/chromium/src/ExternalPopupMenu.cpp @@ -98,15 +98,26 @@ void ExternalPopupMenu::didChangeSelection(int index) void ExternalPopupMenu::didAcceptIndex(int index) { + // Calling methods on the PopupMenuClient might lead to this object being + // derefed. This ensures it does not get deleted while we are running this + // method. + RefPtr<ExternalPopupMenu> guard(this); + if (m_popupMenuClient) { m_popupMenuClient->valueChanged(index); - m_popupMenuClient->popupDidHide(); + // The call to valueChanged above might have lead to a call to + // disconnectClient, so we might not have a PopupMenuClient anymore. + if (m_popupMenuClient) + m_popupMenuClient->popupDidHide(); } m_webExternalPopupMenu = 0; } void ExternalPopupMenu::didCancel() { + // See comment in didAcceptIndex on why we need this. + RefPtr<ExternalPopupMenu> guard(this); + if (m_popupMenuClient) m_popupMenuClient->popupDidHide(); m_webExternalPopupMenu = 0; diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.cpp b/WebKit/chromium/src/FrameLoaderClientImpl.cpp index 29141ac..ef28981 100644 --- a/WebKit/chromium/src/FrameLoaderClientImpl.cpp +++ b/WebKit/chromium/src/FrameLoaderClientImpl.cpp @@ -288,7 +288,7 @@ void FrameLoaderClientImpl::assignIdentifierToInitialRequest( // this includes images and xmlhttp requests. It is important to note that a // subresource is NOT limited to stuff loaded through the frame's subresource // loader. Synchronous xmlhttp requests for example, do not go through the -// subresource loader, but we still label them as TargetIsSubResource. +// subresource loader, but we still label them as TargetIsSubresource. // // The important edge cases to consider when modifying this function are // how synchronous resource loads are treated during load/unload threshold. @@ -1389,9 +1389,13 @@ void FrameLoaderClientImpl::didTransferChildFrameToNewDocument(Page*) m_webFrame->setClient(newParent->client()); } -void FrameLoaderClientImpl::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*) +void FrameLoaderClientImpl::transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, Page* oldPage) { - notImplemented(); + assignIdentifierToInitialRequest(identifier, loader, request); + + WebFrameImpl* oldWebFrame = WebFrameImpl::fromFrame(oldPage->mainFrame()); + if (oldWebFrame && oldWebFrame->client()) + oldWebFrame->client()->removeIdentifierForRequest(identifier); } PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin( diff --git a/WebKit/chromium/src/GraphicsContext3DChromium.cpp b/WebKit/chromium/src/GraphicsContext3DChromium.cpp index afc2707..4d9e40b 100644 --- a/WebKit/chromium/src/GraphicsContext3DChromium.cpp +++ b/WebKit/chromium/src/GraphicsContext3DChromium.cpp @@ -39,6 +39,7 @@ #include "CanvasRenderingContext.h" #include "Chrome.h" #include "ChromeClientImpl.h" +#include "Extensions3DChromium.h" #include "GraphicsContext3DInternal.h" #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" @@ -83,6 +84,7 @@ namespace WebCore { GraphicsContext3DInternal::GraphicsContext3DInternal() : m_webViewImpl(0) + , m_initializedAvailableExtensions(false) #if PLATFORM(SKIA) #elif PLATFORM(CG) , m_renderOutput(0) @@ -108,6 +110,7 @@ bool GraphicsContext3DInternal::initialize(GraphicsContext3D::Attributes attrs, webAttributes.stencil = attrs.stencil; webAttributes.antialias = attrs.antialias; webAttributes.premultipliedAlpha = attrs.premultipliedAlpha; + webAttributes.canRecoverFromContextLoss = attrs.canRecoverFromContextLoss; WebKit::WebGraphicsContext3D* webContext = WebKit::webKitClient()->createGraphicsContext3D(); if (!webContext) return false; @@ -675,13 +678,31 @@ DELEGATE_TO_IMPL_1(deleteShader, unsigned) DELEGATE_TO_IMPL_1(deleteTexture, unsigned) DELEGATE_TO_IMPL_1(synthesizeGLError, unsigned long) -DELEGATE_TO_IMPL_R(supportsBGRA, bool) -DELEGATE_TO_IMPL_R(supportsMapSubCHROMIUM, bool) + +Extensions3D* GraphicsContext3DInternal::getExtensions() +{ + if (!m_extensions) + m_extensions = adoptPtr(new Extensions3DChromium(this)); + return m_extensions.get(); +} + +bool GraphicsContext3DInternal::supportsExtension(const String& name) +{ + if (!m_initializedAvailableExtensions) { + String extensionsString = getString(GraphicsContext3D::EXTENSIONS); + Vector<String> availableExtensions; + extensionsString.split(" ", availableExtensions); + for (size_t i = 0; i < availableExtensions.size(); ++i) + m_availableExtensions.add(availableExtensions[i]); + m_initializedAvailableExtensions = true; + } + return m_availableExtensions.contains(name); +} + DELEGATE_TO_IMPL_4R(mapBufferSubDataCHROMIUM, unsigned, int, int, unsigned, void*) DELEGATE_TO_IMPL_1(unmapBufferSubDataCHROMIUM, const void*) DELEGATE_TO_IMPL_9R(mapTexSubImage2DCHROMIUM, unsigned, int, int, int, int, int, unsigned, unsigned, unsigned, void*) DELEGATE_TO_IMPL_1(unmapTexSubImage2DCHROMIUM, const void*) -DELEGATE_TO_IMPL_R(supportsCopyTextureToParentTextureCHROMIUM, bool) DELEGATE_TO_IMPL_2(copyTextureToParentTextureCHROMIUM, unsigned, unsigned) //---------------------------------------------------------------------- @@ -1023,14 +1044,7 @@ DELEGATE_TO_INTERNAL_1(deleteShader, unsigned) DELEGATE_TO_INTERNAL_1(deleteTexture, unsigned) DELEGATE_TO_INTERNAL_1(synthesizeGLError, unsigned long) -DELEGATE_TO_INTERNAL_R(supportsBGRA, bool) -DELEGATE_TO_INTERNAL_R(supportsMapSubCHROMIUM, bool) -DELEGATE_TO_INTERNAL_4R(mapBufferSubDataCHROMIUM, unsigned, int, int, unsigned, void*) -DELEGATE_TO_INTERNAL_1(unmapBufferSubDataCHROMIUM, const void*) -DELEGATE_TO_INTERNAL_9R(mapTexSubImage2DCHROMIUM, unsigned, int, int, int, int, int, unsigned, unsigned, unsigned, void*) -DELEGATE_TO_INTERNAL_1(unmapTexSubImage2DCHROMIUM, const void*) -DELEGATE_TO_INTERNAL_R(supportsCopyTextureToParentTextureCHROMIUM, bool) -DELEGATE_TO_INTERNAL_2(copyTextureToParentTextureCHROMIUM, unsigned, unsigned) +DELEGATE_TO_INTERNAL_R(getExtensions, Extensions3D*) bool GraphicsContext3D::isGLES2Compliant() const { @@ -1047,11 +1061,6 @@ bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const return m_internal->isErrorGeneratedOnOutOfBoundsAccesses(); } -int GraphicsContext3D::getGraphicsResetStatusARB() -{ - return NO_ERROR; -} - } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebKit/chromium/src/GraphicsContext3DInternal.h b/WebKit/chromium/src/GraphicsContext3DInternal.h index f12fff0..17163a4 100644 --- a/WebKit/chromium/src/GraphicsContext3DInternal.h +++ b/WebKit/chromium/src/GraphicsContext3DInternal.h @@ -27,6 +27,7 @@ #define GraphicsContext3DInternal_h #include "GraphicsContext3D.h" +#include <wtf/HashSet.h> #include <wtf/OwnPtr.h> #if PLATFORM(SKIA) #include "SkBitmap.h" @@ -39,6 +40,7 @@ class WebViewImpl; namespace WebCore { +class Extensions3DChromium; #if USE(ACCELERATED_COMPOSITING) class WebGLLayerChromium; #endif @@ -260,7 +262,9 @@ public: void synthesizeGLError(unsigned long error); - void swapBuffers(); + // Extensions3D support. + Extensions3D* getExtensions(); + bool supportsExtension(const String& name); // EXT_texture_format_BGRA8888 bool supportsBGRA(); @@ -278,7 +282,10 @@ public: private: OwnPtr<WebKit::WebGraphicsContext3D> m_impl; + OwnPtr<Extensions3DChromium> m_extensions; WebKit::WebViewImpl* m_webViewImpl; + bool m_initializedAvailableExtensions; + HashSet<String> m_availableExtensions; #if USE(ACCELERATED_COMPOSITING) RefPtr<WebGLLayerChromium> m_compositingLayer; #endif diff --git a/WebKit/chromium/src/IDBTransactionBackendProxy.cpp b/WebKit/chromium/src/IDBTransactionBackendProxy.cpp index 4b19ee4..7a88b13 100644 --- a/WebKit/chromium/src/IDBTransactionBackendProxy.cpp +++ b/WebKit/chromium/src/IDBTransactionBackendProxy.cpp @@ -84,11 +84,6 @@ void IDBTransactionBackendProxy::didCompleteTaskEvents() m_webIDBTransaction->didCompleteTaskEvents(); } -int IDBTransactionBackendProxy::id() const -{ - return m_webIDBTransaction->id(); -} - void IDBTransactionBackendProxy::setCallbacks(IDBTransactionCallbacks* callbacks) { m_webIDBTransaction->setCallbacks(new WebIDBTransactionCallbacksImpl(callbacks)); diff --git a/WebKit/chromium/src/IDBTransactionBackendProxy.h b/WebKit/chromium/src/IDBTransactionBackendProxy.h index 0c56f19..0bf84da 100644 --- a/WebKit/chromium/src/IDBTransactionBackendProxy.h +++ b/WebKit/chromium/src/IDBTransactionBackendProxy.h @@ -47,7 +47,6 @@ public: virtual void abort(); virtual bool scheduleTask(PassOwnPtr<ScriptExecutionContext::Task>, PassOwnPtr<ScriptExecutionContext::Task>); virtual void didCompleteTaskEvents(); - virtual int id() const; virtual void setCallbacks(IDBTransactionCallbacks*); WebKit::WebIDBTransaction* getWebIDBTransaction() const { return m_webIDBTransaction.get(); } diff --git a/WebKit/chromium/src/LocalFileSystemChromium.cpp b/WebKit/chromium/src/LocalFileSystemChromium.cpp index 25b1feb..a9c61d0 100644 --- a/WebKit/chromium/src/LocalFileSystemChromium.cpp +++ b/WebKit/chromium/src/LocalFileSystemChromium.cpp @@ -57,13 +57,21 @@ LocalFileSystem& LocalFileSystem::localFileSystem() return *localFileSystem; } +void LocalFileSystem::readFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long size, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) +{ + ASSERT(context && context->isDocument()); + Document* document = static_cast<Document*>(context); + WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); + webFrame->client()->openFileSystem(webFrame, static_cast<WebFileSystem::Type>(type), size, false, new WebFileSystemCallbacksImpl(callbacks)); +} + void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long size, PassOwnPtr<AsyncFileSystemCallbacks> callbacks, bool synchronous) { ASSERT(context); if (context->isDocument()) { Document* document = static_cast<Document*>(context); WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); - webFrame->client()->openFileSystem(webFrame, static_cast<WebFileSystem::Type>(type), size, new WebFileSystemCallbacksImpl(callbacks)); + webFrame->client()->openFileSystem(webFrame, static_cast<WebFileSystem::Type>(type), size, true, new WebFileSystemCallbacksImpl(callbacks)); } else { WorkerContext* workerContext = static_cast<WorkerContext*>(context); WorkerLoaderProxy* workerLoaderProxy = &workerContext->thread()->workerLoaderProxy(); diff --git a/WebKit/chromium/src/WebAccessibilityObject.cpp b/WebKit/chromium/src/WebAccessibilityObject.cpp index 96a3173..9df69cf 100644 --- a/WebKit/chromium/src/WebAccessibilityObject.cpp +++ b/WebKit/chromium/src/WebAccessibilityObject.cpp @@ -351,7 +351,7 @@ WebRect WebAccessibilityObject::boundingBoxRect() const return WebRect(); m_private->updateBackingStore(); - return m_private->documentFrameView()->contentsToWindow(m_private->boundingBoxRect()); + return m_private->boundingBoxRect(); } WebString WebAccessibilityObject::helpText() const diff --git a/WebKit/chromium/src/WebAnimationControllerImpl.cpp b/WebKit/chromium/src/WebAnimationControllerImpl.cpp index 15df140..e6eb828 100644 --- a/WebKit/chromium/src/WebAnimationControllerImpl.cpp +++ b/WebKit/chromium/src/WebAnimationControllerImpl.cpp @@ -94,7 +94,7 @@ void WebAnimationControllerImpl::suspendAnimations() const return; if (!m_frameImpl->frame()) return; - controller->suspendAnimations(m_frameImpl->frame()->document()); + controller->suspendAnimations(); } void WebAnimationControllerImpl::resumeAnimations() const @@ -104,7 +104,7 @@ void WebAnimationControllerImpl::resumeAnimations() const return; if (!m_frameImpl->frame()) return; - controller->resumeAnimations(m_frameImpl->frame()->document()); + controller->resumeAnimations(); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebCache.cpp b/WebKit/chromium/src/WebCache.cpp index c124bdf..2203498 100644 --- a/WebKit/chromium/src/WebCache.cpp +++ b/WebKit/chromium/src/WebCache.cpp @@ -31,20 +31,20 @@ #include "config.h" #include "WebCache.h" -// Instead of providing accessors, we make all members of Cache public. -// This will make it easier to track WebCore changes to the Cache class. -// FIXME: We should introduce public getters on the Cache class. +// Instead of providing accessors, we make all members of MemoryCache public. +// This will make it easier to track WebCore changes to the MemoryCache class. +// FIXME: We should introduce public getters on the MemoryCache class. #define private public -#include "Cache.h" +#include "MemoryCache.h" #undef private using namespace WebCore; namespace WebKit { -// A helper method for coverting a Cache::TypeStatistic to a +// A helper method for coverting a MemoryCache::TypeStatistic to a // WebCache::ResourceTypeStat. -static void ToResourceTypeStat(const Cache::TypeStatistic& from, +static void ToResourceTypeStat(const MemoryCache::TypeStatistic& from, WebCache::ResourceTypeStat& to) { to.count = static_cast<size_t>(from.count); @@ -56,7 +56,7 @@ static void ToResourceTypeStat(const Cache::TypeStatistic& from, void WebCache::setCapacities( size_t minDeadCapacity, size_t maxDeadCapacity, size_t capacity) { - Cache* cache = WebCore::cache(); + MemoryCache* cache = WebCore::cache(); if (cache) cache->setCapacities(static_cast<unsigned int>(minDeadCapacity), static_cast<unsigned int>(maxDeadCapacity), @@ -65,7 +65,7 @@ void WebCache::setCapacities( void WebCache::clear() { - Cache* cache = WebCore::cache(); + MemoryCache* cache = WebCore::cache(); if (cache && !cache->disabled()) { cache->setDisabled(true); cache->setDisabled(false); @@ -76,7 +76,7 @@ void WebCache::getUsageStats(UsageStats* result) { ASSERT(result); - Cache* cache = WebCore::cache(); + MemoryCache* cache = WebCore::cache(); if (cache) { result->minDeadCapacity = cache->m_minDeadCapacity; result->maxDeadCapacity = cache->m_maxDeadCapacity; @@ -89,9 +89,9 @@ void WebCache::getUsageStats(UsageStats* result) void WebCache::getResourceTypeStats(ResourceTypeStats* result) { - Cache* cache = WebCore::cache(); + MemoryCache* cache = WebCore::cache(); if (cache) { - Cache::Statistics stats = cache->getStatistics(); + MemoryCache::Statistics stats = cache->getStatistics(); ToResourceTypeStat(stats.images, result->images); ToResourceTypeStat(stats.cssStyleSheets, result->cssStyleSheets); ToResourceTypeStat(stats.scripts, result->scripts); diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp index 9b7b2bd..880adb4 100644 --- a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp +++ b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp @@ -177,7 +177,6 @@ WebDevToolsAgentImpl::WebDevToolsAgentImpl( , m_client(client) , m_webViewImpl(webViewImpl) , m_apuAgentEnabled(false) - , m_resourceTrackingWasEnabled(false) , m_attached(false) { DebuggerAgentManager::setExposeV8DebuggerProtocol( @@ -264,20 +263,12 @@ void WebDevToolsAgentImpl::setApuAgentEnabled(bool enabled) if (enabled) { if (!ic->hasFrontend()) connectFrontend(true); - m_resourceTrackingWasEnabled = ic->resourceTrackingEnabled(); + ic->startTimelineProfiler(); - if (!m_resourceTrackingWasEnabled) { - // TODO(knorton): Introduce some kind of agents dependency here so that - // user could turn off resource tracking while apu agent is on. - ic->setResourceTrackingEnabled(true); - } m_debuggerAgentImpl->setAutoContinueOnException(true); - } else { + } else ic->stopTimelineProfiler(); - if (!m_resourceTrackingWasEnabled) - ic->setResourceTrackingEnabled(false); - m_resourceTrackingWasEnabled = false; - } + m_client->runtimePropertyChanged( kApuAgentFeatureName, enabled ? String("true") : String("false")); diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.h b/WebKit/chromium/src/WebDevToolsAgentImpl.h index 47c4ccf..feb4bdd 100644 --- a/WebKit/chromium/src/WebDevToolsAgentImpl.h +++ b/WebKit/chromium/src/WebDevToolsAgentImpl.h @@ -109,7 +109,6 @@ private: WebViewImpl* m_webViewImpl; OwnPtr<DebuggerAgentImpl> m_debuggerAgentImpl; bool m_apuAgentEnabled; - bool m_resourceTrackingWasEnabled; bool m_attached; }; diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp index 905bc6d..ea59ab6 100644 --- a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp +++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp @@ -92,7 +92,6 @@ WebDevToolsFrontendImpl::WebDevToolsFrontendImpl( : m_webViewImpl(webViewImpl) , m_client(client) , m_applicationLocale(applicationLocale) - , m_loaded(false) { InspectorController* ic = m_webViewImpl->page()->inspectorController(); ic->setInspectorFrontendClient(new InspectorFrontendClientImpl(m_webViewImpl->page(), m_client, this)); @@ -113,7 +112,9 @@ void WebDevToolsFrontendImpl::dispatchOnInspectorFrontend(const WebString& messa v8::Handle<v8::Context> frameContext = V8Proxy::context(frame->frame()); v8::Context::Scope contextScope(frameContext); v8::Handle<v8::Value> dispatchFunction = frameContext->Global()->Get(v8::String::New("WebInspector_syncDispatch")); - ASSERT(dispatchFunction->IsFunction()); + // The frame might have navigated away from the front-end page (which is still weird). + if (!dispatchFunction->IsFunction()) + return; v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(dispatchFunction); Vector< v8::Handle<v8::Value> > args; args.append(ToV8String(message)); diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.h b/WebKit/chromium/src/WebDevToolsFrontendImpl.h index bde906f..866a1cb 100644 --- a/WebKit/chromium/src/WebDevToolsFrontendImpl.h +++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.h @@ -73,7 +73,6 @@ private: WebKit::WebViewImpl* m_webViewImpl; WebKit::WebDevToolsFrontendClient* m_client; String m_applicationLocale; - bool m_loaded; }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebFrameImpl.cpp b/WebKit/chromium/src/WebFrameImpl.cpp index b4d23c0..41b8321 100644 --- a/WebKit/chromium/src/WebFrameImpl.cpp +++ b/WebKit/chromium/src/WebFrameImpl.cpp @@ -486,7 +486,7 @@ WebFrame* WebFrame::fromFrameOwnerElement(const WebElement& element) WebString WebFrameImpl::name() const { - return m_frame->tree()->name(); + return m_frame->tree()->uniqueName(); } void WebFrameImpl::setName(const WebString& name) @@ -986,7 +986,7 @@ WebHistoryItem WebFrameImpl::previousHistoryItem() const // only get saved to history when it becomes the previous item. The caller // is expected to query the history item after a navigation occurs, after // the desired history item has become the previous entry. - return WebHistoryItem(viewImpl()->previousHistoryItem()); + return WebHistoryItem(m_frame->loader()->history()->previousItem()); } WebHistoryItem WebFrameImpl::currentHistoryItem() const diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp index e805c55..4cb701f 100644 --- a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp @@ -40,7 +40,8 @@ #include "WebView.h" #include <wtf/OwnArrayPtr.h> #include <wtf/PassOwnPtr.h> -#include <wtf/text/CString.h> +#include <wtf/text/StringBuilder.h> +#include <wtf/text/WTFString.h> #include <stdio.h> #include <string.h> @@ -48,8 +49,6 @@ namespace WebKit { enum { - IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B, - IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A, MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB, MAX_VARYING_VECTORS = 0x8DFC, MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD @@ -531,20 +530,6 @@ void WebGraphicsContext3DDefaultImpl::synthesizeGLError(unsigned long error) m_syntheticErrors.add(error); } -bool WebGraphicsContext3DDefaultImpl::supportsBGRA() -{ - // Supported since OpenGL 1.2. However, glTexImage2D() must be modified - // to translate the internalFormat from GL_BGRA to GL_RGBA, since the - // former is not accepted by desktop GL. Return false until this is done. - return false; -} - -bool WebGraphicsContext3DDefaultImpl::supportsMapSubCHROMIUM() -{ - // We don't claim support for this extension at this time - return false; -} - void* WebGraphicsContext3DDefaultImpl::mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access) { return 0; @@ -563,15 +548,11 @@ void WebGraphicsContext3DDefaultImpl::unmapTexSubImage2DCHROMIUM(const void* mem { } -bool WebGraphicsContext3DDefaultImpl::supportsCopyTextureToParentTextureCHROMIUM() -{ - // This extension requires this desktopGL-only function (GLES2 doesn't - // support it), so check for its existence here. - return glGetTexLevelParameteriv; -} - void WebGraphicsContext3DDefaultImpl::copyTextureToParentTextureCHROMIUM(unsigned id, unsigned id2) { + if (!glGetTexLevelParameteriv) + return; + makeContextCurrent(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_copyTextureToParentTextureFBO); glFramebufferTexture2DEXT(GL_FRAMEBUFFER, @@ -855,16 +836,7 @@ DELEGATE_TO_GL(finish, Finish) DELEGATE_TO_GL(flush, Flush) -void WebGraphicsContext3DDefaultImpl::framebufferRenderbuffer(unsigned long target, unsigned long attachment, - unsigned long renderbuffertarget, WebGLId buffer) -{ - makeContextCurrent(); - if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { - glFramebufferRenderbufferEXT(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, buffer); - glFramebufferRenderbufferEXT(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, buffer); - } else - glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer); -} +DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbufferEXT, unsigned long, unsigned long, unsigned long, WebGLId) DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT, unsigned long, unsigned long, unsigned long, WebGLId, long) @@ -979,21 +951,12 @@ void WebGraphicsContext3DDefaultImpl::getFramebufferAttachmentParameteriv(unsign void WebGraphicsContext3DDefaultImpl::getIntegerv(unsigned long pname, int* value) { - // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid - // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most - // useful for desktop WebGL users. // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS // because desktop GL's corresponding queries return the number of components // whereas GLES2 return the number of vectors (each vector has 4 components). // Therefore, the value returned by desktop GL needs to be divided by 4. makeContextCurrent(); switch (pname) { - case IMPLEMENTATION_COLOR_READ_FORMAT: - *value = GL_RGB; - break; - case IMPLEMENTATION_COLOR_READ_TYPE: - *value = GL_UNSIGNED_BYTE; - break; case MAX_FRAGMENT_UNIFORM_VECTORS: glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); *value /= 4; @@ -1130,7 +1093,16 @@ WebString WebGraphicsContext3DDefaultImpl::getShaderSource(WebGLId shader) WebString WebGraphicsContext3DDefaultImpl::getString(unsigned long name) { makeContextCurrent(); - return WebString::fromUTF8(reinterpret_cast<const char*>(glGetString(name))); + StringBuilder result; + result.append(reinterpret_cast<const char*>(glGetString(name))); + if (name == GL_EXTENSIONS) { + // GL_CHROMIUM_copy_texture_to_parent_texture requires this + // desktopGL-only function (GLES2 doesn't support it), so + // check for its existence here. + if (glGetTexLevelParameteriv) + result.append(" GL_CHROMIUM_copy_texture_to_parent_texture"); + } + return WebString(result.toString()); } DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, unsigned long, unsigned long, float*) diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h index 5eebf12..c1de77c 100644 --- a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h @@ -81,13 +81,10 @@ public: virtual void prepareTexture(); virtual void synthesizeGLError(unsigned long error); - virtual bool supportsBGRA(); - virtual bool supportsMapSubCHROMIUM(); virtual void* mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access); virtual void unmapBufferSubDataCHROMIUM(const void*); virtual void* mapTexSubImage2DCHROMIUM(unsigned target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, unsigned access); virtual void unmapTexSubImage2DCHROMIUM(const void*); - virtual bool supportsCopyTextureToParentTextureCHROMIUM(); virtual void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture); virtual void activeTexture(unsigned long texture); diff --git a/WebKit/chromium/src/WebIDBTransactionImpl.cpp b/WebKit/chromium/src/WebIDBTransactionImpl.cpp index f5d8748..4307cb5 100644 --- a/WebKit/chromium/src/WebIDBTransactionImpl.cpp +++ b/WebKit/chromium/src/WebIDBTransactionImpl.cpp @@ -69,11 +69,6 @@ void WebIDBTransactionImpl::didCompleteTaskEvents() m_backend->didCompleteTaskEvents(); } -int WebIDBTransactionImpl::id() const -{ - return m_backend->id(); -} - void WebIDBTransactionImpl::setCallbacks(WebIDBTransactionCallbacks* callbacks) { RefPtr<IDBTransactionCallbacks> idbCallbacks = IDBTransactionCallbacksProxy::create(callbacks); diff --git a/WebKit/chromium/src/WebIDBTransactionImpl.h b/WebKit/chromium/src/WebIDBTransactionImpl.h index 24bab91..b26b3ac 100644 --- a/WebKit/chromium/src/WebIDBTransactionImpl.h +++ b/WebKit/chromium/src/WebIDBTransactionImpl.h @@ -45,7 +45,6 @@ public: virtual WebIDBObjectStore* objectStore(const WebString& name); virtual void abort(); virtual void didCompleteTaskEvents(); - virtual int id() const; virtual void setCallbacks(WebIDBTransactionCallbacks*); virtual WebCore::IDBTransactionBackendInterface* getIDBTransactionBackendInterface() const; diff --git a/WebKit/chromium/src/WebInputElement.cpp b/WebKit/chromium/src/WebInputElement.cpp index 7779dbc..d032ef8 100644 --- a/WebKit/chromium/src/WebInputElement.cpp +++ b/WebKit/chromium/src/WebInputElement.cpp @@ -95,9 +95,9 @@ int WebInputElement::size() const return constUnwrap<HTMLInputElement>()->size(); } -void WebInputElement::setValue(const WebString& value) +void WebInputElement::setValue(const WebString& value, bool sendChangeEvent) { - unwrap<HTMLInputElement>()->setValue(value); + unwrap<HTMLInputElement>()->setValue(value, sendChangeEvent); } WebString WebInputElement::value() const @@ -145,14 +145,14 @@ void WebInputElement::setSelectionRange(int start, int end) unwrap<HTMLInputElement>()->setSelectionRange(start, end); } -int WebInputElement::selectionStart() +int WebInputElement::selectionStart() const { - return unwrap<HTMLInputElement>()->selectionStart(); + return constUnwrap<HTMLInputElement>()->selectionStart(); } -int WebInputElement::selectionEnd() +int WebInputElement::selectionEnd() const { - return unwrap<HTMLInputElement>()->selectionEnd(); + return constUnwrap<HTMLInputElement>()->selectionEnd(); } bool WebInputElement::isValidValue(const WebString& value) const diff --git a/WebKit/chromium/src/WebPluginContainerImpl.cpp b/WebKit/chromium/src/WebPluginContainerImpl.cpp index 58deecc..43d9757 100644 --- a/WebKit/chromium/src/WebPluginContainerImpl.cpp +++ b/WebKit/chromium/src/WebPluginContainerImpl.cpp @@ -33,6 +33,7 @@ #include "Chrome.h" #include "ChromeClientImpl.h" +#include "PluginLayerChromium.h" #include "WebClipboard.h" #include "WebCursorInfo.h" #include "WebDataSourceImpl.h" @@ -275,6 +276,25 @@ void WebPluginContainerImpl::invalidateRect(const WebRect& rect) invalidateRect(static_cast<IntRect>(rect)); } +void WebPluginContainerImpl::scrollRect(int dx, int dy, const WebRect& rect) +{ + Widget* parentWidget = parent(); + if (parentWidget->isFrameView()) { + FrameView* parentFrameView = static_cast<FrameView*>(parentWidget); + if (!parentFrameView->isOverlapped()) { + IntRect damageRect = convertToContainingWindow(static_cast<IntRect>(rect)); + IntSize scrollDelta(dx, dy); + // scroll() only uses the second rectangle, clipRect, and ignores the first + // rectangle. + parent()->hostWindow()->scroll(scrollDelta, damageRect, damageRect); + return; + } + } + + // Use slow scrolling instead. + invalidateRect(rect); +} + void WebPluginContainerImpl::reportGeometry() { if (!parent()) @@ -287,6 +307,14 @@ void WebPluginContainerImpl::reportGeometry() m_webPlugin->updateGeometry(windowRect, clipRect, cutOutRects, isVisible()); } +void WebPluginContainerImpl::commitBackingTexture() +{ +#if USE(ACCELERATED_COMPOSITING) + if (platformLayer()) + platformLayer()->setNeedsDisplay(); +#endif +} + void WebPluginContainerImpl::clearScriptObjects() { Frame* frame = m_element->document()->frame(); @@ -393,8 +421,33 @@ void WebPluginContainerImpl::willDestroyPluginLoadObserver(WebPluginLoadObserver m_pluginLoadObservers.remove(pos); } +#if USE(ACCELERATED_COMPOSITING) +WebCore::LayerChromium* WebPluginContainerImpl::platformLayer() const +{ + // FIXME: In the event of a context lost, the texture needs to be recreated on the compositor's + // context and rebound to the platform layer here. + unsigned backingTextureId = m_webPlugin->getBackingTextureId(); + if (!backingTextureId) + return 0; + + m_platformLayer->setTextureId(backingTextureId); + + return m_platformLayer.get(); +} +#endif + // Private methods ------------------------------------------------------------- +WebPluginContainerImpl::WebPluginContainerImpl(WebCore::HTMLPlugInElement* element, WebPlugin* webPlugin) + : WebCore::PluginViewBase(0) + , m_element(element) + , m_webPlugin(webPlugin) +#if USE(ACCELERATED_COMPOSITING) + , m_platformLayer(PluginLayerChromium::create(0)) +#endif +{ +} + WebPluginContainerImpl::~WebPluginContainerImpl() { for (size_t i = 0; i < m_pluginLoadObservers.size(); ++i) diff --git a/WebKit/chromium/src/WebPluginContainerImpl.h b/WebKit/chromium/src/WebPluginContainerImpl.h index 27f5f2e..ebe6983 100644 --- a/WebKit/chromium/src/WebPluginContainerImpl.h +++ b/WebKit/chromium/src/WebPluginContainerImpl.h @@ -31,9 +31,10 @@ #ifndef WebPluginContainerImpl_h #define WebPluginContainerImpl_h +#include "PluginViewBase.h" #include "WebPluginContainer.h" - #include "Widget.h" + #include <wtf/PassRefPtr.h> #include <wtf/Vector.h> @@ -43,7 +44,9 @@ namespace WebCore { class HTMLPlugInElement; class IntRect; class KeyboardEvent; +class LayerChromium; class MouseEvent; +class PluginLayerChromium; class ResourceError; class ResourceResponse; class WheelEvent; @@ -54,7 +57,7 @@ namespace WebKit { class WebPlugin; class WebPluginLoadObserver; -class WebPluginContainerImpl : public WebCore::Widget, public WebPluginContainer { +class WebPluginContainerImpl : public WebCore::PluginViewBase, public WebPluginContainer { public: static PassRefPtr<WebPluginContainerImpl> create(WebCore::HTMLPlugInElement* element, WebPlugin* webPlugin) { @@ -79,12 +82,14 @@ public: virtual WebElement element(); virtual void invalidate(); virtual void invalidateRect(const WebRect&); + virtual void scrollRect(int dx, int dy, const WebRect&); virtual void reportGeometry(); + virtual void commitBackingTexture(); virtual void clearScriptObjects(); virtual NPObject* scriptableObjectForElement(); virtual WebString executeScriptURL(const WebURL&, bool popupsAllowed); virtual void loadFrameRequest(const WebURLRequest&, const WebString& target, bool notifyNeeded, void* notifyData); - virtual void zoomLevelChanged(double zoomLevel); + virtual void zoomLevelChanged(double zoomLevel); // This cannot be null. WebPlugin* plugin() { return m_webPlugin; } @@ -117,10 +122,12 @@ public: void willDestroyPluginLoadObserver(WebPluginLoadObserver*); +#if USE(ACCELERATED_COMPOSITING) + virtual WebCore::LayerChromium* platformLayer() const; +#endif + private: - WebPluginContainerImpl(WebCore::HTMLPlugInElement* element, WebPlugin* webPlugin) - : m_element(element) - , m_webPlugin(webPlugin) { } + WebPluginContainerImpl(WebCore::HTMLPlugInElement* element, WebPlugin* webPlugin); ~WebPluginContainerImpl(); void handleMouseEvent(WebCore::MouseEvent*); @@ -138,6 +145,10 @@ private: WebCore::HTMLPlugInElement* m_element; WebPlugin* m_webPlugin; Vector<WebPluginLoadObserver*> m_pluginLoadObservers; + +#if USE(ACCELERATED_COMPOSITING) + RefPtr<WebCore::PluginLayerChromium> m_platformLayer; +#endif }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebSpeechInputControllerMockImpl.cpp b/WebKit/chromium/src/WebSpeechInputControllerMockImpl.cpp index 3b56338..ce8eba6 100644 --- a/WebKit/chromium/src/WebSpeechInputControllerMockImpl.cpp +++ b/WebKit/chromium/src/WebSpeechInputControllerMockImpl.cpp @@ -55,11 +55,6 @@ WebSpeechInputControllerMockImpl::~WebSpeechInputControllerMockImpl() m_webcoreMock->setListener(0); } -void WebSpeechInputControllerMockImpl::setMockRecognitionResult(const WebString& result) -{ - m_webcoreMock->setRecognitionResult(result, WebString::fromUTF8("")); -} - void WebSpeechInputControllerMockImpl::setMockRecognitionResult(const WebString& result, const WebString &language) { m_webcoreMock->setRecognitionResult(result, language); diff --git a/WebKit/chromium/src/WebSpeechInputControllerMockImpl.h b/WebKit/chromium/src/WebSpeechInputControllerMockImpl.h index c98f92a..7b50a8b 100644 --- a/WebKit/chromium/src/WebSpeechInputControllerMockImpl.h +++ b/WebKit/chromium/src/WebSpeechInputControllerMockImpl.h @@ -64,10 +64,6 @@ public: // WebSpeechInputControllerMock methods. void setMockRecognitionResult(const WebString& result, const WebString& language); - // FIXME: this is a fix for a two-sided patch. Delete as soon as the chromium side is patched. - // Chromium patch not uploaded yet, but will depend on http://codereview.chromium.org/3615005/show patch. - void setMockRecognitionResult(const WebString& result); - private: OwnPtr<WebCore::SpeechInputClientMock> m_webcoreMock; WebSpeechInputListener* m_listener; diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp index 57d0ca4..490c620 100644 --- a/WebKit/chromium/src/WebViewImpl.cpp +++ b/WebKit/chromium/src/WebViewImpl.cpp @@ -52,6 +52,7 @@ #include "DragData.h" #include "Editor.h" #include "EventHandler.h" +#include "Extensions3D.h" #include "FocusController.h" #include "FontDescription.h" #include "FrameLoader.h" @@ -1050,7 +1051,7 @@ void WebViewImpl::composite(bool finish) m_layerRenderer->present(); GraphicsContext3D* context = m_layerRenderer->context(); - if (context->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR) + if (context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR) reallocateRenderer(); #endif } diff --git a/WebKit/chromium/src/js/DevTools.js b/WebKit/chromium/src/js/DevTools.js index 4c23057..8b3aea0 100644 --- a/WebKit/chromium/src/js/DevTools.js +++ b/WebKit/chromium/src/js/DevTools.js @@ -46,6 +46,7 @@ var context = {}; // Used by WebCore's inspector routines. Preferences.canEditScriptSource = true; Preferences.onlineDetectionEnabled = false; Preferences.nativeInstrumentationEnabled = true; + Preferences.fileSystemEnabled = false; })(); var devtools = devtools || {}; diff --git a/WebKit/chromium/src/js/devTools.css b/WebKit/chromium/src/js/devTools.css index 9495fb8..64ea9d5 100644 --- a/WebKit/chromium/src/js/devTools.css +++ b/WebKit/chromium/src/js/devTools.css @@ -37,11 +37,6 @@ body.platform-linux #scripts-files { line-height: 12px; } -.section > .header { - border: 1px solid rgb(92, 116, 157); - background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(105, 133, 180)), to(rgb(92, 116, 157))); -} - .console-group-messages .section > .header { padding: 0 8px 0 0; background-image: none; diff --git a/WebKit/efl/ChangeLog b/WebKit/efl/ChangeLog index bf9af1e..b436e58 100644 --- a/WebKit/efl/ChangeLog +++ b/WebKit/efl/ChangeLog @@ -1,3 +1,105 @@ +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::focusedFrameChanged): + * WebCoreSupport/ChromeClientEfl.h: + +2010-11-05 Patrick Gansterer <paroga@webkit.org> + + Reviewed by David Kilzer. + + Replace ARRAYSIZE with WTF_ARRAY_LENGTH + https://bugs.webkit.org/show_bug.cgi?id=48903 + + * WebCoreSupport/EditorClientEfl.cpp: + (WebCore::EditorClientEfl::interpretKeyEvent): + +2010-11-04 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Adam Barth. + + [EFL] Reflect latest EFL changes related to stride. + https://bugs.webkit.org/show_bug.cgi?id=48971 + + Remove adjustment code to compare stride of cairo_image_surfece and evas_object_image, as following changes of latest EFL. + + * ewk/ewk_util.cpp: + (ewk_util_image_from_cairo_surface_add): + +2010-11-03 Daniel Bates <dbates@rim.com> + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 1 of 2. + + Substitute FrameTree::uniqueName() for FrameTree::name() in the EFL port. + + * ewk/ewk_frame.cpp: + (ewk_frame_name_get): + +2010-11-02 Daniel Bates <dbates@rim.com> + + Reviewed by Martin Robinson. + + Set frame name before appending it to the frame tree in the Apple Windows, + GTK, and EFL ports + https://bugs.webkit.org/show_bug.cgi?id=48806 + + Make the frame creation process in the EFL-port consistent with the + Mac, Qt, and Haiku ports. In particular, set the name of the new + frame before it's appended to the frame tree. + + At this time we cannot test this change since it is being masked by + HTMLFrameElementBase::setName() <http://trac.webkit.org/browser/trunk/WebCore/html/HTMLFrameElementBase.cpp?rev=70976#L160>. + We'll be able to test this once we fix bug #6751. + + * ewk/ewk_frame.cpp: + (ewk_frame_child_add): + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * WebCoreSupport/ChromeClientEfl.h: + (WebCore::ChromeClientEfl::showContextMenu): + +2010-10-29 Daniel Bates <dbates@rim.com> + + No review, rolling out 70971. + http://trac.webkit.org/changeset/70971 + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Rolling out changeset 70971 <http://trac.webkit.org/changeset/70971> since + it caused layout test failures on all bots. In particular, the + child count in a generated frame name differs after this patch. We need + to look into this further. + + * ewk/ewk_frame.cpp: + (ewk_frame_name_get): + +2010-10-29 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Modified EFL-port to use FrameTree::uniqueName(). + + * ewk/ewk_frame.cpp: + (ewk_frame_name_get): + 2010-10-29 Darin Adler <darin@apple.com> Reviewed by Sam Weinig. diff --git a/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp b/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp index d99f0bc..1aac4ff 100644 --- a/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp +++ b/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp @@ -91,6 +91,10 @@ void ChromeClientEfl::focusedNodeChanged(Node*) notImplemented(); } +void ChromeClientEfl::focusedFrameChanged(Frame*) +{ +} + FloatRect ChromeClientEfl::windowRect() { Ecore_Evas* ee = 0; diff --git a/WebKit/efl/WebCoreSupport/ChromeClientEfl.h b/WebKit/efl/WebCoreSupport/ChromeClientEfl.h index f0aeb8d..c6c82d4 100644 --- a/WebKit/efl/WebCoreSupport/ChromeClientEfl.h +++ b/WebKit/efl/WebCoreSupport/ChromeClientEfl.h @@ -53,6 +53,7 @@ public: virtual void takeFocus(FocusDirection); virtual void focusedNodeChanged(Node*); + virtual void focusedFrameChanged(Frame*); virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&); virtual void show(); @@ -115,6 +116,10 @@ public: virtual void reachedApplicationCacheOriginQuota(SecurityOrigin*); #endif +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif + virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>); virtual void chooseIconForFiles(const Vector<String>&, FileChooser*); virtual void formStateDidChange(const Node*); diff --git a/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp b/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp index a63b712..9184812 100644 --- a/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp +++ b/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp @@ -292,8 +292,6 @@ static const KeyPressEntry keyPressEntries[] = { { '\r', AltKey | ShiftKey, "InsertNewline" }, }; -#define ARRAYSIZE(array) (sizeof(array) / sizeof((array)[0])) - const char* EditorClientEfl::interpretKeyEvent(const KeyboardEvent* event) { ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent); @@ -305,10 +303,10 @@ const char* EditorClientEfl::interpretKeyEvent(const KeyboardEvent* event) keyDownCommandsMap = new HashMap<int, const char*>; keyPressCommandsMap = new HashMap<int, const char*>; - for (unsigned i = 0; i < ARRAYSIZE(keyDownEntries); i++) + for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyDownEntries); ++i) keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name); - for (unsigned i = 0; i < ARRAYSIZE(keyPressEntries); i++) + for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyPressEntries); ++i) keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name); } diff --git a/WebKit/efl/ewk/ewk_frame.cpp b/WebKit/efl/ewk/ewk_frame.cpp index 1395fa5..5076be5 100644 --- a/WebKit/efl/ewk/ewk_frame.cpp +++ b/WebKit/efl/ewk/ewk_frame.cpp @@ -474,7 +474,7 @@ const char* ewk_frame_name_get(const Evas_Object* o) return 0; } - WTF::String s = sd->frame->tree()->name(); + WTF::String s = sd->frame->tree()->uniqueName(); WTF::CString cs = s.utf8(); sd->name = eina_stringshare_add_length(cs.data(), cs.length()); return sd->name; @@ -1623,11 +1623,11 @@ Evas_Object* ewk_frame_child_add(Evas_Object* o, WTF::PassRefPtr<WebCore::Frame> } cf = child.get(); - sd->frame->tree()->appendChild(child); if (cf->tree()) cf->tree()->setName(name); else ERR("no tree for child object"); + sd->frame->tree()->appendChild(child); if (!ewk_frame_init(frame, sd->view, cf)) { evas_object_del(frame); diff --git a/WebKit/efl/ewk/ewk_util.cpp b/WebKit/efl/ewk/ewk_util.cpp index bf82695..6830f76 100644 --- a/WebKit/efl/ewk/ewk_util.cpp +++ b/WebKit/efl/ewk/ewk_util.cpp @@ -81,9 +81,9 @@ Evas_Object* ewk_util_image_from_cairo_surface_add(Evas* canvas, cairo_surface_t evas_object_image_size_set(image, w, h); evas_object_image_alpha_set(image, format == CAIRO_FORMAT_ARGB32); - if (evas_object_image_stride_get(image) * 4 != stride) { + if (evas_object_image_stride_get(image) != stride) { ERR("evas' stride %d diverges from cairo's %d.", - evas_object_image_stride_get(image) * 4, stride); + evas_object_image_stride_get(image), stride); evas_object_del(image); return 0; } diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog index cd11751..3a7e381 100644 --- a/WebKit/gtk/ChangeLog +++ b/WebKit/gtk/ChangeLog @@ -1,3 +1,341 @@ +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * WebCoreSupport/ChromeClientGtk.cpp: + (WebKit::ChromeClient::focusedFrameChanged): + * WebCoreSupport/ChromeClientGtk.h: + +2010-11-08 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Andreas Kling. + + [GTK] Error page templates are not filled properly + https://bugs.webkit.org/show_bug.cgi?id=49148 + + Replace a call to makeString with String::format. This was mistakenly + changed to makeString in an earlier commit. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::dispatchDidFailLoad): + +2010-11-08 Xan Lopez <xlopez@igalia.com> + + Reviewed by Martin Robinson. + + * NEWS: update for release. + +2010-11-08 Csaba Osztrogonac <ossy@webkit.org> + + Unreviewed, rolling out r71466. + http://trac.webkit.org/changeset/71466 + https://bugs.webkit.org/show_bug.cgi?id=48865 + + It broke layout tests on GTK bots. + + * WebCoreSupport/ChromeClientGtk.cpp: + (WebKit::ChromeClient::closeWindowSoon): + * webkit/webkitprivate.h: + * webkit/webkitwebview.cpp: + (webkit_web_view_init): + (webkit_web_view_set_group_name): + +2010-11-07 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Rename Cache to MemoryCache + https://bugs.webkit.org/show_bug.cgi?id=49159 + + * webkit/webkitwebview.cpp: + +2010-11-05 Nicolas Dufresne <nicolas.dufresne@collabora.co.uk> + + Reviewed by Martin Robinson. + + [GTK] Link with target name set does not work correctly + https://bugs.webkit.org/show_bug.cgi?id=48865 + + When a new page is created with a name (target=myFrame), the new + mainFrame could not be found because they where not stored in the + same PageGroup. As PageGroup are not exposed externally so the + simpliest solution is to use a global page group name. This also fixes + issue with visited link coloration across pages. After this change the + private function webkit_web_view_set_group_name() was no longer used + so it was removed completly. + + * WebCoreSupport/ChromeClientGtk.cpp: + (WebKit::ChromeClient::closeWindowSoon): + * webkit/webkitprivate.h: + * webkit/webkitwebview.cpp: + (webkit_web_view_init): + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Move resumeAnimations/suspendAnimations from Frame to AnimationController. + https://bugs.webkit.org/show_bug.cgi?id=49073 + + * webkit/webkitwebframe.cpp: + (webkit_web_frame_suspend_animations): + (webkit_web_frame_resume_animations): + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Unreviewed. + + Small fix to GTK build + + * webkit/webkitwebframe.cpp: + (webkit_web_frame_suspend_animations): + (webkit_web_frame_resume_animations): + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Make suspendAnimations/resumeAnimations and setCSSAnimations traverse through subframes and remember state + https://bugs.webkit.org/show_bug.cgi?id=46945 + + * webkit/webkitwebframe.cpp: + (webkit_web_frame_suspend_animations): + (webkit_web_frame_resume_animations): + +2010-11-03 Daniel Bates <dbates@rim.com> + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 1 of 2. + + Substitute FrameTree::uniqueName() for FrameTree::name() in the GTK port. + + * webkit/webkitwebframe.cpp: + (webkit_web_frame_get_name): + +2010-11-02 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Adam Barth. + + [Cairo] Remove PlatformRefPtrCairo + https://bugs.webkit.org/show_bug.cgi?id=48192 + + Replace instances of PlatformRefPtr smart pointers that wrap Cairo + types with RefPtrs. + + * WebCoreSupport/DragClientGtk.cpp: Use RefPtr instead of PlatformRefPtr. + (WebKit::dragIconWindowDrawEventCallback): + * WebCoreSupport/DragClientGtk.h: Ditto. + +2010-11-02 Daniel Bates <dbates@rim.com> + + Reviewed by Martin Robinson. + + Set frame name before appending it to the frame tree in the Apple Windows, + GTK, and EFL ports + https://bugs.webkit.org/show_bug.cgi?id=48806 + + Make the frame creation process in the GTK-port consistent with the + Mac, Qt, and Haiku ports. In particular, set the name of the new + frame before it's appended to the frame tree. + + At this time we cannot test this change since it is being masked by + HTMLFrameElementBase::setName() <http://trac.webkit.org/browser/trunk/WebCore/html/HTMLFrameElementBase.cpp?rev=70976#L160>. + We'll be able to test this once we fix bug #6751. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::createFrame): + +2010-11-01 Jennifer Braithwaite <jennb@google.com> + + Reviewed by Martin Robinson. + + GTK: Update resource tracking when moving a frame between documents + https://bugs.webkit.org/show_bug.cgi?id=48362 + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::transferLoadingResourceFromPage): + Assign resource id to current web view and remove from former web view. + * webkit/webkitprivate.h: + * webkit/webkitwebview.cpp: + (webkit_web_view_remove_resource): + Added. + +2010-11-01 Mario Sanchez Prada <msanchez@igalia.com> + + Reviewed by Martin Robinson. + + [GTK] Cleanup needed in testatk.c file + https://bugs.webkit.org/show_bug.cgi?id=48759 + + Cleanup done in testatk.c, mainly addressing the following issues: + + - Removed any trace of extra main loops in tests, so now we just + spin the original main loop in all of them to get the a11y + objects. + + - As we no longer use the extra main loops, removed the bail_out + function, used along with g_idle_add() to stop those extra loops. + + - As we now spin the loop in every test, created a new function + waitForAccessibilityObjects() to write the loop just once. + + - Fixed name in incorrectly named test testWekitAtkTextSelections. + + - Alphabetically sorted the list of includes. + + - Renamed all identifiers to camel Case notation. + + - Declare variables when needed only (instead of declaring all of + them at the beginning of the function). + + - Don't declare two variables of the same type in the same line. + + - No more short names like 'obj', 'textObj' or 'alloc'. Use names + like 'object', 'textObject' and 'allocation' instead. + + - Fixed indentation. + + - Make sure all comments finish with '.' + + - Replace NULL's with 0's. + + * tests/testatk.c: + (waitForAccessibleObjects): New, manually spins the main context + to make sure accessible objects are created before continuing. + (testGetTextFunction): Fixed this function to be compliant with + the WebKit's coding style. + (runGetTextTests): Ditto. + (testWebkitAtkGetTextAtOffsetForms): Ditto. + (testWebkitAtkGetTextAtOffset): Ditto. + (testWebkitAtkGetTextAtOffsetNewlines): Ditto. + (testWebkitAtkGetTextAtOffsetTextarea): Ditto. + (testWebkitAtkGetTextAtOffsetTextInput): Ditto. + (testWebkitAtkGetTextInParagraphAndBodySimple): Ditto. + (testWebkitAtkGetTextInParagraphAndBodyModerate): Ditto. + (testWebkitAtkGetTextInTable): Ditto. + (testWebkitAtkGetHeadersInTable): Ditto. + (compAtkAttribute): Ditto. + (atkAttributeSetAttributeNameHasValue): Ditto. + (testWebkitAtkTextAttributes): Ditto. + (testWebkitAtkTextSelections): Ditto. + (testWebkitAtkGetExtents): Ditto. + (testWebkitAtkLayoutAndDataTables): Ditto. + (testWebkitAtkLinksWithInlineImages): Ditto. + (testWebkitAtkHypertextAndHyperlinks): Ditto. + (testWebkitAtkListsOfItems): Ditto. + (testWebkitAtkTextChangedNotifications): Ditto. + (main): Ditto. + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * WebCoreSupport/ChromeClientGtk.h: + (WebKit::ChromeClient::showContextMenu): + +2010-11-01 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [GTK] Pasting markup into Thunderbird compose window produces no text + https://bugs.webkit.org/show_bug.cgi?id=43737 + + Added a test verifying that the meta tag prefix on markup data exists. + + * tests/testcopyandpaste.c: + (load_status_cb): Add a check for the meta tag prefix. + +2010-11-01 Mario Sanchez Prada <msanchez@igalia.com> + + Reviewed by Martin Robinson. + + [Gtk] AtkHyperlink needs to be implemented + https://bugs.webkit.org/show_bug.cgi?id=33785 + + New test to ensure the AtkHypertext/AtkHyperlink stuff works. + + * tests/testatk.c: + (testWebkitAtkHypertextAndHyperlinks): New test, checking both the + implementation of the AtkHypertext interface, the subclass of the + AtkHyperlink abstract class, and the implementation of the + AtkAction interface in that subclass. + (main): Added the new unit test. + +2010-10-30 Xan Lopez <xlopez@igalia.com> + + Reviewed by Martin Robinson. + + [GTK] Use new width for height APIs in GTK+ 3.x + https://bugs.webkit.org/show_bug.cgi?id=48709 + + Use the new width for height APIs in GTK+ 3.x, since size-request + is deprecated. + + For now we just return the same value for preferred and minimum + width/height, which should match the 2.x behavior. Probably we + could do something smarter for the minimum values. + + * webkit/webkitwebview.cpp: + (webkit_web_view_get_preferred_width): return our preferred width. + (webkit_web_view_get_preferred_height): return our preferred height. + (webkit_web_view_class_init): hook the new default handlers. + +2010-10-29 Daniel Bates <dbates@rim.com> + + No review, rolling out 70971. + http://trac.webkit.org/changeset/70971 + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Rolling out changeset 70971 <http://trac.webkit.org/changeset/70971> since + it caused layout test failures on all bots. In particular, the + child count in a generated frame name differs after this patch. We need + to look into this further. + + * webkit/webkitwebframe.cpp: + (webkit_web_frame_get_name): + +2010-10-28 Antonio Gomes <agomes@rim.com> + + Reviewed by Ojan Vafai. + + Needs a "LinuxEditingBehavior", perhaps with a better name + https://bugs.webkit.org/show_bug.cgi?id=36627 + + Added the corresponding GTK+ setting to WebCore's EditingUnixBehavior: WEBKIT_EDITING_BEHAVIOR_UNIX. + + * webkit/webkitwebsettings.cpp: + (webkit_web_settings_class_init): + * webkit/webkitwebsettings.h: + +2010-10-29 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Modified GTK-port to use FrameTree::uniqueName(). + + * webkit/webkitwebframe.cpp: + (webkit_web_frame_get_name): + +2010-10-29 Martin Robinson <mrobinson@igalia.com> + + Build fix for GTK+ after BackForwardListImpl introduction. + + * webkit/webkitwebbackforwardlist.cpp: + (webkit_web_back_forward_list_new_with_web_view): + 2010-10-29 Darin Adler <darin@apple.com> Reviewed by Sam Weinig. diff --git a/WebKit/gtk/NEWS b/WebKit/gtk/NEWS index ed4cd81..ead8923 100644 --- a/WebKit/gtk/NEWS +++ b/WebKit/gtk/NEWS @@ -1,4 +1,13 @@ ================ +WebKitGTK+ 1.3.6 +================ + +What's new in WebKitGTK+ 1.3.6? + + - Update to compile with GTK+ 3.x 2.91.4. + - Many, many other bugfixes. + +================ WebKitGTK+ 1.3.5 ================ diff --git a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp index e864ea7..d4ab7ab 100644 --- a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp @@ -275,6 +275,10 @@ void ChromeClient::focusedNodeChanged(Node*) { } +void ChromeClient::focusedFrameChanged(Frame*) +{ +} + bool ChromeClient::canRunBeforeUnloadConfirmPanel() { return true; diff --git a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h index b925313..8252f06 100644 --- a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h +++ b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h @@ -55,6 +55,7 @@ namespace WebKit { virtual void takeFocus(WebCore::FocusDirection); virtual void focusedNodeChanged(WebCore::Node*); + virtual void focusedFrameChanged(WebCore::Frame*); virtual WebCore::Page* createWindow(WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&); virtual void show(); @@ -117,6 +118,9 @@ namespace WebKit { virtual void reachedMaxAppCacheSize(int64_t spaceNeeded); virtual void reachedApplicationCacheOriginQuota(WebCore::SecurityOrigin*); #endif +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif virtual void runOpenPanel(WebCore::Frame*, PassRefPtr<WebCore::FileChooser>); virtual void chooseIconForFiles(const Vector<WTF::String>&, WebCore::FileChooser*); diff --git a/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp b/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp index b850cec..be0fb10 100644 --- a/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp @@ -44,7 +44,7 @@ namespace WebKit { #ifdef GTK_API_VERSION_2 static gboolean dragIconWindowDrawEventCallback(GtkWidget* widget, GdkEventExpose* event, DragClient* client) { - PlatformRefPtr<cairo_t> context = adoptPlatformRef(gdk_cairo_create(event->window)); + RefPtr<cairo_t> context = adoptRef(gdk_cairo_create(event->window)); client->drawDragIconWindow(widget, context.get()); return TRUE; } diff --git a/WebKit/gtk/WebCoreSupport/DragClientGtk.h b/WebKit/gtk/WebCoreSupport/DragClientGtk.h index 0d07c88..086ec69 100644 --- a/WebKit/gtk/WebCoreSupport/DragClientGtk.h +++ b/WebKit/gtk/WebCoreSupport/DragClientGtk.h @@ -32,7 +32,7 @@ #include "DragClient.h" #include "GRefPtr.h" -#include "PlatformRefPtrCairo.h" +#include "RefPtrCairo.h" typedef struct _WebKitWebView WebKitWebView; @@ -60,7 +60,7 @@ namespace WebKit { WebKitWebView* m_webView; WebCore::IntPoint m_startPos; PlatformRefPtr<GtkWidget> m_dragIconWindow; - PlatformRefPtr<cairo_surface_t> m_dragImage; + RefPtr<cairo_surface_t> m_dragImage; }; } diff --git a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp index 20aafc2..b23bd70 100644 --- a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp @@ -584,8 +584,8 @@ PassRefPtr<Frame> FrameLoaderClient::createFrame(const KURL& url, const String& RefPtr<Frame> childFrame = Frame::create(page, ownerElement, new FrameLoaderClient(kitFrame)); framePrivate->coreFrame = childFrame.get(); - parentFrame->tree()->appendChild(childFrame); childFrame->tree()->setName(name); + parentFrame->tree()->appendChild(childFrame); childFrame->init(); // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. @@ -620,8 +620,16 @@ void FrameLoaderClient::didTransferChildFrameToNewDocument(WebCore::Page*) ASSERT(core(getViewFromFrame(m_frame)) == coreFrame->page()); } -void FrameLoaderClient::transferLoadingResourceFromPage(unsigned long, WebCore::DocumentLoader*, const WebCore::ResourceRequest&, WebCore::Page*) +void FrameLoaderClient::transferLoadingResourceFromPage(unsigned long identifier, WebCore::DocumentLoader* docLoader, const WebCore::ResourceRequest& request, WebCore::Page* oldPage) { + ASSERT(oldPage != core(m_frame)->page()); + + GOwnPtr<gchar> identifierString(toString(identifier)); + ASSERT(!webkit_web_view_get_resource(getViewFromFrame(m_frame), identifierString.get())); + + assignIdentifierToInitialRequest(identifier, docLoader, request); + + webkit_web_view_remove_resource(kit(oldPage), identifierString.get()); } void FrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget) @@ -1131,7 +1139,7 @@ void FrameLoaderClient::dispatchDidFailLoad(const ResourceError& error) if (!loaded) content = makeString("<html><body>", webError->message, "</body></html>"); else - content = makeString(fileContent, error.failingURL(), webError->message); + content = String::format(fileContent, error.failingURL().utf8().data(), webError->message); } webkit_web_frame_load_alternate_string(m_frame, content.utf8().data(), 0, error.failingURL().utf8().data()); diff --git a/WebKit/gtk/tests/testatk.c b/WebKit/gtk/tests/testatk.c index bd6473a..509cb86 100644 --- a/WebKit/gtk/tests/testatk.c +++ b/WebKit/gtk/tests/testatk.c @@ -18,10 +18,10 @@ */ #include <errno.h> -#include <unistd.h> #include <glib.h> #include <glib/gstdio.h> #include <gtk/gtk.h> +#include <unistd.h> #include <webkit/webkit.h> #if GLIB_CHECK_VERSION(2, 16, 0) && GTK_CHECK_VERSION(2, 14, 0) @@ -46,6 +46,8 @@ static const char* contentsInTableWithHeaders = "<html><body><table><tr><th>foo< static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>"; +static const char* hypertextAndHyperlinks = "<html><body><p>A paragraph with no links at all</p><p><a href='http://foo.bar.baz/'>A line</a> with <a href='http://bar.baz.foo/'>a link in the middle</a> as well as at the beginning and <a href='http://baz.foo.bar/'>at the end</a></p></body></html>"; + static const char* layoutAndDataTables = "<html><body><table><tr><th>Odd</th><th>Even</th></tr><tr><td>1</td><td>2</td></tr></table><table><tr><td>foo</td><td>bar</td></tr></table></body></html>"; static const char* linksWithInlineImages = "<html><head><style>a.http:before {content: url(no-image.png);}</style><body><p><a class='http' href='foo'>foo</a> bar baz</p><p>foo <a class='http' href='bar'>bar</a> baz</p><p>foo bar <a class='http' href='baz'>baz</a></p></body></html>"; @@ -56,474 +58,411 @@ static const char* textForSelections = "<html><body><p>A paragraph with plain te static const char* textWithAttributes = "<html><head><style>.st1 {font-family: monospace; color:rgb(120,121,122);} .st2 {text-decoration:underline; background-color:rgb(80,81,82);}</style></head><body><p style=\"font-size:14; text-align:right;\">This is the <i>first</i><b> sentence of this text.</b></p><p class=\"st1\">This sentence should have an style applied <span class=\"st2\">and this part should have another one</span>.</p><p>x<sub>1</sub><sup>2</sup>=x<sub>2</sub><sup>3</sup></p><p style=\"text-align:center;\">This sentence is the <strike>last</strike> one.</p></body></html>"; -static gboolean bail_out(GMainLoop* loop) +static void waitForAccessibleObjects() { - if (g_main_loop_is_running(loop)) - g_main_loop_quit(loop); - - return FALSE; + /* Manually spin the main context to make sure the accessible + objects are properly created before continuing. */ + while (g_main_context_pending(0)) + g_main_context_iteration(0, TRUE); } typedef gchar* (*AtkGetTextFunction) (AtkText*, gint, AtkTextBoundary, gint*, gint*); -static void test_get_text_function(AtkText* text_obj, AtkGetTextFunction fn, AtkTextBoundary boundary, gint offset, const char* text_result, gint start_offset_result, gint end_offset_result) +static void testGetTextFunction(AtkText* textObject, AtkGetTextFunction fn, AtkTextBoundary boundary, gint offset, const char* textResult, gint startOffsetResult, gint endOffsetResult) { - gint start_offset, end_offset; - char* text; - - text = fn(text_obj, offset, boundary, &start_offset, &end_offset); - g_assert_cmpstr(text, ==, text_result); - g_assert_cmpint(start_offset, ==, start_offset_result); - g_assert_cmpint(end_offset, ==, end_offset_result); + gint startOffset; + gint endOffset; + char* text = fn(textObject, offset, boundary, &startOffset, &endOffset); + g_assert_cmpstr(text, ==, textResult); + g_assert_cmpint(startOffset, ==, startOffsetResult); + g_assert_cmpint(endOffset, ==, endOffsetResult); g_free(text); } -static void run_get_text_tests(AtkText* text_obj) +static void runGetTextTests(AtkText* textObject) { - char* text = atk_text_get_text(text_obj, 0, -1); + char* text = atk_text_get_text(textObject, 0, -1); g_assert_cmpstr(text, ==, "This is a test. This is the second sentence. And this the third."); g_free(text); /* ATK_TEXT_BOUNDARY_CHAR */ - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, - 0, "T", 0, 1); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, + 0, "T", 0, 1); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_CHAR, - 0, "h", 1, 2); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_CHAR, + 0, "h", 1, 2); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR, - 0, "", 0, 0); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR, + 0, "", 0, 0); + + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR, + 1, "T", 0, 1); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR, - 1, "T", 0, 1); - /* ATK_TEXT_BOUNDARY_WORD_START */ - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, - 0, "This ", 0, 5); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, + 0, "This ", 0, 5); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, - 4, "This ", 0, 5); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, + 4, "This ", 0, 5); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, - 10, "test. ", 10, 16); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, + 10, "test. ", 10, 16); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, - 58, "third.", 58, 64); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, + 58, "third.", 58, 64); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START, - 5, "This ", 0, 5); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START, + 5, "This ", 0, 5); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START, - 7, "This ", 0, 5); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START, + 7, "This ", 0, 5); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, - 0, "is ", 5, 8); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, + 0, "is ", 5, 8); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, - 4, "is ", 5, 8); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, + 4, "is ", 5, 8); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, - 3, "is ", 5, 8); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, + 3, "is ", 5, 8); /* ATK_TEXT_BOUNDARY_WORD_END */ - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, - 0, "This", 0, 4); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 0, "This", 0, 4); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, - 4, " is", 4, 7); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 4, " is", 4, 7); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, - 5, " is", 4, 7); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 5, " is", 4, 7); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, - 9, " test", 9, 14); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 9, " test", 9, 14); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, - 5, "This", 0, 4); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, + 5, "This", 0, 4); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, - 4, "This", 0, 4); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, + 4, "This", 0, 4); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, - 7, " is", 4, 7); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, + 7, " is", 4, 7); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END, - 5, " a", 7, 9); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END, + 5, " a", 7, 9); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END, - 4, " a", 7, 9); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END, + 4, " a", 7, 9); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, - 58, " third", 57, 63); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, + 58, " third", 57, 63); /* ATK_TEXT_BOUNDARY_SENTENCE_START */ - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, - 0, "This is a test. ", 0, 16); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 0, "This is a test. ", 0, 16); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, - 15, "This is a test. ", 0, 16); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 15, "This is a test. ", 0, 16); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, - 0, "This is the second sentence. ", 16, 45); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 0, "This is the second sentence. ", 16, 45); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, - 15, "This is the second sentence. ", 16, 45); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 15, "This is the second sentence. ", 16, 45); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, - 16, "This is a test. ", 0, 16); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 16, "This is a test. ", 0, 16); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, - 44, "This is a test. ", 0, 16); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 44, "This is a test. ", 0, 16); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, - 15, "", 0, 0); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, + 15, "", 0, 0); /* ATK_TEXT_BOUNDARY_SENTENCE_END */ - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 0, "This is a test.", 0, 15); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 0, "This is a test.", 0, 15); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 15, " This is the second sentence.", 15, 44); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 15, " This is the second sentence.", 15, 44); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 16, " This is the second sentence.", 15, 44); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 16, " This is the second sentence.", 15, 44); - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 17, " This is the second sentence.", 15, 44); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 17, " This is the second sentence.", 15, 44); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 0, " This is the second sentence.", 15, 44); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 0, " This is the second sentence.", 15, 44); - test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 15, " And this the third.", 44, 64); + testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 15, " And this the third.", 44, 64); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 16, "This is a test.", 0, 15); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 16, "This is a test.", 0, 15); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 15, "This is a test.", 0, 15); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 15, "This is a test.", 0, 15); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 14, "", 0, 0); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 14, "", 0, 0); - test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, - 44, " This is the second sentence.", 15, 44); + testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, + 44, " This is the second sentence.", 15, 44); /* It's trick to test these properly right now, since our a11y - implementation splits different lines in different a11y - items */ + implementation splits different lines in different a11y items. */ /* ATK_TEXT_BOUNDARY_LINE_START */ - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_START, - 0, "This is a test. This is the second sentence. And this the third.", 0, 64); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_START, + 0, "This is a test. This is the second sentence. And this the third.", 0, 64); /* ATK_TEXT_BOUNDARY_LINE_END */ - test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END, - 0, "This is a test. This is the second sentence. And this the third.", 0, 64); + testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END, + 0, "This is a test. This is the second sentence. And this the third.", 0, 64); } -static void test_webkit_atk_get_text_at_offset_forms(void) +static void testWebkitAtkGetTextAtOffsetForms() { - WebKitWebView* webView; - AtkObject* obj; - GMainLoop* loop; - AtkText* text_obj; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contents, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contents, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - /* Get to the inner AtkText object */ - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - obj = atk_object_ref_accessible_child(obj, 0); - g_assert(obj); + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); - text_obj = ATK_TEXT(obj); - g_assert(ATK_IS_TEXT(text_obj)); + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); - run_get_text_tests(text_obj); + runGetTextTests(textObject); g_object_unref(webView); } -static void test_webkit_atk_get_text_at_offset(void) +static void testWebkitAtkGetTextAtOffset() { - WebKitWebView* webView; - AtkObject* obj; - GMainLoop* loop; - AtkText* text_obj; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contents, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contents, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - /* Get to the inner AtkText object */ - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - obj = atk_object_ref_accessible_child(obj, 0); - g_assert(obj); + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); - text_obj = ATK_TEXT(obj); - g_assert(ATK_IS_TEXT(text_obj)); + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); - run_get_text_tests(text_obj); + runGetTextTests(textObject); g_object_unref(webView); } -static void test_webkit_atk_get_text_at_offset_newlines(void) +static void testWebkitAtkGetTextAtOffsetNewlines() { - WebKitWebView* webView; - AtkObject* obj; - GMainLoop* loop; - AtkText* text_obj; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contentsWithNewlines, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsWithNewlines, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - /* Get to the inner AtkText object */ - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - obj = atk_object_ref_accessible_child(obj, 0); - g_assert(obj); + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); - text_obj = ATK_TEXT(obj); - g_assert(ATK_IS_TEXT(text_obj)); + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); - run_get_text_tests(text_obj); + runGetTextTests(textObject); g_object_unref(webView); } -static void test_webkit_atk_get_text_at_offset_textarea(void) +static void testWebkitAtkGetTextAtOffsetTextarea() { - WebKitWebView* webView; - AtkObject* obj; - GMainLoop* loop; - AtkText* text_obj; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contentsInTextarea, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInTextarea, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - /* Get to the inner AtkText object */ - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - obj = atk_object_ref_accessible_child(obj, 0); - g_assert(obj); - obj = atk_object_ref_accessible_child(obj, 0); - g_assert(obj); + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); - text_obj = ATK_TEXT(obj); - g_assert(ATK_IS_TEXT(text_obj)); + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); - run_get_text_tests(text_obj); + runGetTextTests(textObject); g_object_unref(webView); } -static void test_webkit_atk_get_text_at_offset_text_input(void) +static void testWebkitAtkGetTextAtOffsetTextInput() { - WebKitWebView* webView; - AtkObject* obj; - GMainLoop* loop; - AtkText* text_obj; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contentsInTextInput, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInTextInput, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - /* Get to the inner AtkText object */ - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - obj = atk_object_ref_accessible_child(obj, 0); - g_assert(obj); - obj = atk_object_ref_accessible_child(obj, 0); - g_assert(obj); + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); - text_obj = ATK_TEXT(obj); - g_assert(ATK_IS_TEXT(text_obj)); + AtkText* textObject = ATK_TEXT(object); + g_assert(ATK_IS_TEXT(textObject)); - run_get_text_tests(text_obj); + runGetTextTests(textObject); g_object_unref(webView); } -static void testWebkitAtkGetTextInParagraphAndBodySimple(void) +static void testWebkitAtkGetTextInParagraphAndBodySimple() { - WebKitWebView* webView; - AtkObject* obj; - AtkObject* obj1; - AtkObject* obj2; - GMainLoop* loop; - AtkText* textObj1; - AtkText* textObj2; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contentsInParagraphAndBodySimple, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); - - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); - - /* Get to the inner AtkText object */ - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - obj1 = atk_object_ref_accessible_child(obj, 0); - g_assert(obj1); - obj2 = atk_object_ref_accessible_child(obj, 1); - g_assert(obj2); - - textObj1 = ATK_TEXT(obj1); - g_assert(ATK_IS_TEXT(textObj1)); - textObj2 = ATK_TEXT(obj2); - g_assert(ATK_IS_TEXT(textObj2)); - - char *text = atk_text_get_text(textObj1, 0, -1); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInParagraphAndBodySimple, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + AtkObject* object1 = atk_object_ref_accessible_child(object, 0); + g_assert(object1); + AtkObject* object2 = atk_object_ref_accessible_child(object, 1); + g_assert(object2); + + AtkText* textObject1 = ATK_TEXT(object1); + g_assert(ATK_IS_TEXT(textObject1)); + AtkText* textObject2 = ATK_TEXT(object2); + g_assert(ATK_IS_TEXT(textObject2)); + + char *text = atk_text_get_text(textObject1, 0, -1); g_assert_cmpstr(text, ==, "This is a test."); - text = atk_text_get_text(textObj2, 0, 12); + text = atk_text_get_text(textObject2, 0, 12); g_assert_cmpstr(text, ==, "Hello world."); - g_object_unref(obj1); - g_object_unref(obj2); + g_object_unref(object1); + g_object_unref(object2); g_object_unref(webView); } -static void testWebkitAtkGetTextInParagraphAndBodyModerate(void) +static void testWebkitAtkGetTextInParagraphAndBodyModerate() { - WebKitWebView* webView; - AtkObject* obj; - AtkObject* obj1; - AtkObject* obj2; - GMainLoop* loop; - AtkText* textObj1; - AtkText* textObj2; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contentsInParagraphAndBodyModerate, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); - - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); - - /* Get to the inner AtkText object */ - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - obj1 = atk_object_ref_accessible_child(obj, 0); - g_assert(obj1); - obj2 = atk_object_ref_accessible_child(obj, 1); - g_assert(obj2); - - textObj1 = ATK_TEXT(obj1); - g_assert(ATK_IS_TEXT(textObj1)); - textObj2 = ATK_TEXT(obj2); - g_assert(ATK_IS_TEXT(textObj2)); - - char *text = atk_text_get_text(textObj1, 0, -1); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInParagraphAndBodyModerate, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + /* Get to the inner AtkText object. */ + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + AtkObject* object1 = atk_object_ref_accessible_child(object, 0); + g_assert(object1); + AtkObject* object2 = atk_object_ref_accessible_child(object, 1); + g_assert(object2); + + AtkText* textObject1 = ATK_TEXT(object1); + g_assert(ATK_IS_TEXT(textObject1)); + AtkText* textObject2 = ATK_TEXT(object2); + g_assert(ATK_IS_TEXT(textObject2)); + + char *text = atk_text_get_text(textObject1, 0, -1); g_assert_cmpstr(text, ==, "This is a test."); - text = atk_text_get_text(textObj2, 0, 53); + text = atk_text_get_text(textObject2, 0, 53); g_assert_cmpstr(text, ==, "Hello world.\nThis sentence is green.\nThis one is not."); - g_object_unref(obj1); - g_object_unref(obj2); + g_object_unref(object1); + g_object_unref(object2); g_object_unref(webView); } -static void testWebkitAtkGetTextInTable(void) +static void testWebkitAtkGetTextInTable() { - WebKitWebView* webView; - AtkObject* obj; - GMainLoop* loop; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contentsInTable, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInTable, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - obj = atk_object_ref_accessible_child(obj, 0); - g_assert(obj); + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + object = atk_object_ref_accessible_child(object, 0); + g_assert(object); - /* Tables should not implement AtkText */ - g_assert(G_TYPE_INSTANCE_GET_INTERFACE(obj, ATK_TYPE_TEXT, AtkTextIface) == NULL); + /* Tables should not implement AtkText. */ + g_assert(!G_TYPE_INSTANCE_GET_INTERFACE(object, ATK_TYPE_TEXT, AtkTextIface)); - g_object_unref(obj); + g_object_unref(object); g_object_unref(webView); } -static void testWebkitAtkGetHeadersInTable(void) +static void testWebkitAtkGetHeadersInTable() { - WebKitWebView* webView; - AtkObject* axWebView; - AtkObject* table; - AtkObject* colHeader; - AtkObject* rowHeader; - GMainLoop* loop; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, contentsInTableWithHeaders, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, contentsInTableWithHeaders, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - axWebView = gtk_widget_get_accessible(GTK_WIDGET(webView)); + AtkObject* axWebView = gtk_widget_get_accessible(GTK_WIDGET(webView)); g_assert(axWebView); - // Check table with both column and row headers - table = atk_object_ref_accessible_child(axWebView, 0); + /* Check table with both column and row headers. */ + AtkObject* table = atk_object_ref_accessible_child(axWebView, 0); g_assert(table); g_assert(atk_object_get_role(table) == ATK_ROLE_TABLE); - colHeader = atk_table_get_column_header(ATK_TABLE(table), 0); + AtkObject* colHeader = atk_table_get_column_header(ATK_TABLE(table), 0); g_assert(colHeader); g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); g_assert(atk_object_get_index_in_parent(colHeader) == 0); @@ -543,7 +482,7 @@ static void testWebkitAtkGetHeadersInTable(void) g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); g_assert(atk_object_get_index_in_parent(colHeader) == 2); - rowHeader = atk_table_get_row_header(ATK_TABLE(table), 0); + AtkObject* rowHeader = atk_table_get_row_header(ATK_TABLE(table), 0); g_assert(rowHeader); g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); g_assert(atk_object_get_index_in_parent(rowHeader) == 0); @@ -565,7 +504,7 @@ static void testWebkitAtkGetHeadersInTable(void) g_object_unref(table); - // Check table with no headers at all + /* Check table with no headers at all. */ table = atk_object_ref_accessible_child(axWebView, 1); g_assert(table); g_assert(atk_object_get_role(table) == ATK_ROLE_TABLE); @@ -588,8 +527,7 @@ static void testWebkitAtkGetHeadersInTable(void) static gint compAtkAttribute(AtkAttribute* a1, AtkAttribute* a2) { - gint strcmpVal; - strcmpVal = g_strcmp0(a1->name, a2->name); + gint strcmpVal = g_strcmp0(a1->name, a2->name); if (strcmpVal) return strcmpVal; return g_strcmp0(a1->value, a2->value); @@ -602,10 +540,9 @@ static gint compAtkAttributeName(AtkAttribute* a1, AtkAttribute* a2) static gboolean atkAttributeSetAttributeNameHasValue(AtkAttributeSet* set, const gchar* attributeName, const gchar* value) { - GSList* element; AtkAttribute at; at.name = (gchar*)attributeName; - element = g_slist_find_custom(set, &at, (GCompareFunc)compAtkAttributeName); + GSList* element = g_slist_find_custom(set, &at, (GCompareFunc)compAtkAttributeName); return element && !g_strcmp0(((AtkAttribute*)(element->data))->value, value); } @@ -640,52 +577,42 @@ static gboolean atkAttributeSetAreEqual(AtkAttributeSet* set1, AtkAttributeSet* return (!set2); } -static void testWebkitAtkTextAttributes(void) +static void testWebkitAtkTextAttributes() { - WebKitWebView* webView; - AtkObject* obj; - AtkObject* child; - GMainLoop* loop; - AtkText* childText; - AtkAttributeSet* set1; - AtkAttributeSet* set2; - AtkAttributeSet* set3; - AtkAttributeSet* set4; - gint startOffset, endOffset; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - - webkit_web_view_load_string(webView, textWithAttributes, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, textWithAttributes, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); - child = atk_object_ref_accessible_child(obj, 0); + AtkObject* child = atk_object_ref_accessible_child(object, 0); g_assert(child && ATK_IS_TEXT(child)); - childText = ATK_TEXT(child); - set1 = atk_text_get_run_attributes(childText, 0, &startOffset, &endOffset); + AtkText* childText = ATK_TEXT(child); + + gint startOffset; + gint endOffset; + AtkAttributeSet* set1 = atk_text_get_run_attributes(childText, 0, &startOffset, &endOffset); g_assert_cmpint(startOffset, ==, 0); g_assert_cmpint(endOffset, ==, 12); - g_assert(atkAttributeSetAreEqual(set1, NULL)); + g_assert(atkAttributeSetAreEqual(set1, 0)); - set2 = atk_text_get_run_attributes(childText, 15, &startOffset, &endOffset); + AtkAttributeSet* set2 = atk_text_get_run_attributes(childText, 15, &startOffset, &endOffset); g_assert_cmpint(startOffset, ==, 12); g_assert_cmpint(endOffset, ==, 17); g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_STYLE, "italic")); - set3 = atk_text_get_run_attributes(childText, 17, &startOffset, &endOffset); + AtkAttributeSet* set3 = atk_text_get_run_attributes(childText, 17, &startOffset, &endOffset); g_assert_cmpint(startOffset, ==, 17); g_assert_cmpint(endOffset, ==, 40); g_assert(atkAttributeSetAttributeHasValue(set3, ATK_TEXT_ATTR_WEIGHT, "700")); - set4 = atk_text_get_default_attributes(childText); + AtkAttributeSet* set4 = atk_text_get_default_attributes(childText); g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_STYLE, "normal")); g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_JUSTIFICATION, "right")); g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_SIZE, "14")); @@ -694,7 +621,7 @@ static void testWebkitAtkTextAttributes(void) atk_attribute_set_free(set3); atk_attribute_set_free(set4); - child = atk_object_ref_accessible_child(obj, 1); + child = atk_object_ref_accessible_child(object, 1); g_assert(child && ATK_IS_TEXT(child)); childText = ATK_TEXT(child); @@ -708,14 +635,14 @@ static void testWebkitAtkTextAttributes(void) set2 = atk_text_get_run_attributes(childText, 43, &startOffset, &endOffset); g_assert_cmpint(startOffset, ==, 43); g_assert_cmpint(endOffset, ==, 80); - // Checks that default attributes of text are not returned when called to atk_text_get_run_attributes + /* Checks that default attributes of text are not returned when called to atk_text_get_run_attributes. */ g_assert(!atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_FG_COLOR, "120,121,122")); g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_UNDERLINE, "single")); g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_BG_COLOR, "80,81,82")); atk_attribute_set_free(set1); atk_attribute_set_free(set2); - child = atk_object_ref_accessible_child(obj, 2); + child = atk_object_ref_accessible_child(object, 2); g_assert(child && ATK_IS_TEXT(child)); childText = ATK_TEXT(child); @@ -740,7 +667,7 @@ static void testWebkitAtkTextAttributes(void) atk_attribute_set_free(set3); atk_attribute_set_free(set4); - child = atk_object_ref_accessible_child(obj, 3); + child = atk_object_ref_accessible_child(object, 3); g_assert(child && ATK_IS_TEXT(child)); childText = ATK_TEXT(child); set1 = atk_text_get_run_attributes(childText, 24, &startOffset, &endOffset); @@ -751,7 +678,7 @@ static void testWebkitAtkTextAttributes(void) set2 = atk_text_get_run_attributes(childText, 25, &startOffset, &endOffset); g_assert_cmpint(startOffset, ==, 25); g_assert_cmpint(endOffset, ==, 30); - g_assert(atkAttributeSetAreEqual(set2, NULL)); + g_assert(atkAttributeSetAreEqual(set2, 0)); set3 = atk_text_get_default_attributes(childText); g_assert(atkAttributeSetAttributeHasValue(set3, ATK_TEXT_ATTR_JUSTIFICATION, "center")); @@ -760,53 +687,49 @@ static void testWebkitAtkTextAttributes(void) atk_attribute_set_free(set3); } -static void testWekitAtkTextSelections(void) +static void testWebkitAtkTextSelections() { - WebKitWebView* webView; - AtkObject* obj; - GMainLoop* loop; - gchar* selectedText; - gint startOffset; - gint endOffset; - gboolean result; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, textForSelections, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, textForSelections, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); - AtkText* paragraph1 = ATK_TEXT(atk_object_ref_accessible_child(obj, 0)); + AtkText* paragraph1 = ATK_TEXT(atk_object_ref_accessible_child(object, 0)); g_assert(ATK_IS_TEXT(paragraph1)); - AtkText* paragraph2 = ATK_TEXT(atk_object_ref_accessible_child(obj, 1)); + AtkText* paragraph2 = ATK_TEXT(atk_object_ref_accessible_child(object, 1)); g_assert(ATK_IS_TEXT(paragraph2)); AtkText* link = ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(paragraph2), 0)); g_assert(ATK_IS_TEXT(link)); - // First paragraph (simple text) + /* First paragraph (simple text). */ - // Basic initial checks + /* Basic initial checks. */ g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0); - selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); + + gint startOffset; + gint endOffset; + gchar* selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); g_assert_cmpint(startOffset, ==, 0); g_assert_cmpint(endOffset, ==, 0); - g_assert_cmpstr(selectedText, ==, NULL); + g_assert_cmpstr(selectedText, ==, 0); g_free (selectedText); - // Try removing a non existing (yet) selection - result = atk_text_remove_selection(paragraph1, 0); + + /* Try removing a non existing (yet) selection. */ + gboolean result = atk_text_remove_selection(paragraph1, 0); g_assert(!result); - // Try setting a 0-char selection + + /* Try setting a 0-char selection. */ result = atk_text_set_selection(paragraph1, 0, 5, 5); g_assert(result); - // Make a selection and test it + /* Make a selection and test it. */ result = atk_text_set_selection(paragraph1, 0, 5, 25); g_assert(result); g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 1); @@ -815,29 +738,29 @@ static void testWekitAtkTextSelections(void) g_assert_cmpint(endOffset, ==, 25); g_assert_cmpstr(selectedText, ==, "agraph with plain te"); g_free (selectedText); - // Try removing the selection from other AtkText object (should fail) + /* Try removing the selection from other AtkText object (should fail). */ result = atk_text_remove_selection(paragraph2, 0); g_assert(!result); - // Remove the selection and test everything again + /* Remove the selection and test everything again. */ result = atk_text_remove_selection(paragraph1, 0); g_assert(result); g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0); selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); - // Now offsets should be the same, set to the last position of the caret + /* Now offsets should be the same, set to the last position of the caret. */ g_assert_cmpint(startOffset, ==, endOffset); g_assert_cmpint(startOffset, ==, 25); g_assert_cmpint(endOffset, ==, 25); - g_assert_cmpstr(selectedText, ==, NULL); + g_assert_cmpstr(selectedText, ==, 0); g_free (selectedText); - // Second paragraph (text + link + text) + /* Second paragraph (text + link + text). */ - // Set a selection partially covering the link and test it + /* Set a selection partially covering the link and test it. */ result = atk_text_set_selection(paragraph2, 0, 7, 21); g_assert(result); - // Test the paragraph first + /* Test the paragraph first. */ g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 1); selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); g_assert_cmpint(startOffset, ==, 7); @@ -845,7 +768,7 @@ static void testWekitAtkTextSelections(void) g_assert_cmpstr(selectedText, ==, "raph with a li"); g_free (selectedText); - // Now test just the link + /* Now test just the link. */ g_assert_cmpint(atk_text_get_n_selections(link), ==, 1); selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset); g_assert_cmpint(startOffset, ==, 0); @@ -853,21 +776,21 @@ static void testWekitAtkTextSelections(void) g_assert_cmpstr(selectedText, ==, "a li"); g_free (selectedText); - // Remove selections and text everything again + /* Remove selections and text everything again. */ result = atk_text_remove_selection(paragraph2, 0); g_assert(result); g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 0); selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); - // Now offsets should be the same (no selection) + /* Now offsets should be the same (no selection). */ g_assert_cmpint(startOffset, ==, endOffset); - g_assert_cmpstr(selectedText, ==, NULL); + g_assert_cmpstr(selectedText, ==, 0); g_free (selectedText); g_assert_cmpint(atk_text_get_n_selections(link), ==, 0); selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset); - // Now offsets should be the same (no selection) + /* Now offsets should be the same (no selection). */ g_assert_cmpint(startOffset, ==, endOffset); - g_assert_cmpstr(selectedText, ==, NULL); + g_assert_cmpstr(selectedText, ==, 0); g_free (selectedText); g_object_unref(paragraph1); @@ -875,136 +798,133 @@ static void testWekitAtkTextSelections(void) g_object_unref(webView); } -static void testWebkitAtkGetExtents(void) +static void testWebkitAtkGetExtents() { - WebKitWebView* webView; - AtkObject* obj; - GMainLoop* loop; - - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, centeredContents, NULL, NULL, NULL); - loop = g_main_loop_new(NULL, TRUE); - - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); - - obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); - - AtkText* short_text1 = ATK_TEXT(atk_object_ref_accessible_child(obj, 0)); - g_assert(ATK_IS_TEXT(short_text1)); - AtkText* long_text = ATK_TEXT(atk_object_ref_accessible_child(obj, 1)); - g_assert(ATK_IS_TEXT(long_text)); - AtkText* short_text2 = ATK_TEXT(atk_object_ref_accessible_child(obj, 2)); - g_assert(ATK_IS_TEXT(short_text2)); - AtkText* multiline_text = ATK_TEXT(atk_object_ref_accessible_child(obj, 3)); - g_assert(ATK_IS_TEXT(multiline_text)); - - // Start with window extents. + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, centeredContents, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + AtkText* shortText1 = ATK_TEXT(atk_object_ref_accessible_child(object, 0)); + g_assert(ATK_IS_TEXT(shortText1)); + AtkText* longText = ATK_TEXT(atk_object_ref_accessible_child(object, 1)); + g_assert(ATK_IS_TEXT(longText)); + AtkText* shortText2 = ATK_TEXT(atk_object_ref_accessible_child(object, 2)); + g_assert(ATK_IS_TEXT(shortText2)); + AtkText* multilineText = ATK_TEXT(atk_object_ref_accessible_child(object, 3)); + g_assert(ATK_IS_TEXT(multilineText)); + + /* Start with window extents. */ AtkTextRectangle sline_window1, sline_window2, lline_window, mline_window; - atk_text_get_range_extents(short_text1, 0, 10, ATK_XY_WINDOW, &sline_window1); - atk_text_get_range_extents(long_text, 0, 44, ATK_XY_WINDOW, &lline_window); - atk_text_get_range_extents(short_text2, 0, 10, ATK_XY_WINDOW, &sline_window2); - atk_text_get_range_extents(multiline_text, 0, 60, ATK_XY_WINDOW, &mline_window); + atk_text_get_range_extents(shortText1, 0, 10, ATK_XY_WINDOW, &sline_window1); + atk_text_get_range_extents(longText, 0, 44, ATK_XY_WINDOW, &lline_window); + atk_text_get_range_extents(shortText2, 0, 10, ATK_XY_WINDOW, &sline_window2); + atk_text_get_range_extents(multilineText, 0, 60, ATK_XY_WINDOW, &mline_window); - // Check vertical line position. + /* Check vertical line position. */ g_assert_cmpint(sline_window1.y + sline_window1.height, <=, lline_window.y); g_assert_cmpint(lline_window.y + lline_window.height + sline_window2.height, <=, mline_window.y); - // Paragraphs 1 and 3 have identical text and alignment. + /* Paragraphs 1 and 3 have identical text and alignment. */ g_assert_cmpint(sline_window1.x, ==, sline_window2.x); g_assert_cmpint(sline_window1.width, ==, sline_window2.width); g_assert_cmpint(sline_window1.height, ==, sline_window2.height); - // All lines should be the same height; line 2 is the widest line. + /* All lines should be the same height; line 2 is the widest line. */ g_assert_cmpint(sline_window1.height, ==, lline_window.height); g_assert_cmpint(sline_window1.width, <, lline_window.width); - // Make sure the character extents jive with the range extents. - gint x, y, width, height; + /* Make sure the character extents jive with the range extents. */ + gint x; + gint y; + gint width; + gint height; - // First paragraph (short text) - atk_text_get_character_extents(short_text1, 0, &x, &y, &width, &height, ATK_XY_WINDOW); + /* First paragraph (short text). */ + atk_text_get_character_extents(shortText1, 0, &x, &y, &width, &height, ATK_XY_WINDOW); g_assert_cmpint(x, ==, sline_window1.x); g_assert_cmpint(y, ==, sline_window1.y); g_assert_cmpint(height, ==, sline_window1.height); - atk_text_get_character_extents(short_text1, 9, &x, &y, &width, &height, ATK_XY_WINDOW); + atk_text_get_character_extents(shortText1, 9, &x, &y, &width, &height, ATK_XY_WINDOW); g_assert_cmpint(x, ==, sline_window1.x + sline_window1.width - width); g_assert_cmpint(y, ==, sline_window1.y); g_assert_cmpint(height, ==, sline_window1.height); - // Second paragraph (long text) - atk_text_get_character_extents(long_text, 0, &x, &y, &width, &height, ATK_XY_WINDOW); + /* Second paragraph (long text). */ + atk_text_get_character_extents(longText, 0, &x, &y, &width, &height, ATK_XY_WINDOW); g_assert_cmpint(x, ==, lline_window.x); g_assert_cmpint(y, ==, lline_window.y); g_assert_cmpint(height, ==, lline_window.height); - atk_text_get_character_extents(long_text, 43, &x, &y, &width, &height, ATK_XY_WINDOW); + atk_text_get_character_extents(longText, 43, &x, &y, &width, &height, ATK_XY_WINDOW); g_assert_cmpint(x, ==, lline_window.x + lline_window.width - width); g_assert_cmpint(y, ==, lline_window.y); g_assert_cmpint(height, ==, lline_window.height); - // Third paragraph (short text) - atk_text_get_character_extents(short_text2, 0, &x, &y, &width, &height, ATK_XY_WINDOW); + /* Third paragraph (short text). */ + atk_text_get_character_extents(shortText2, 0, &x, &y, &width, &height, ATK_XY_WINDOW); g_assert_cmpint(x, ==, sline_window2.x); g_assert_cmpint(y, ==, sline_window2.y); g_assert_cmpint(height, ==, sline_window2.height); - atk_text_get_character_extents(short_text2, 9, &x, &y, &width, &height, ATK_XY_WINDOW); + atk_text_get_character_extents(shortText2, 9, &x, &y, &width, &height, ATK_XY_WINDOW); g_assert_cmpint(x, ==, sline_window2.x + sline_window2.width - width); g_assert_cmpint(y, ==, sline_window2.y); g_assert_cmpint(height, ==, sline_window2.height); - // Four paragraph (3 lines multi-line text) - atk_text_get_character_extents(multiline_text, 0, &x, &y, &width, &height, ATK_XY_WINDOW); + /* Four paragraph (3 lines multi-line text). */ + atk_text_get_character_extents(multilineText, 0, &x, &y, &width, &height, ATK_XY_WINDOW); g_assert_cmpint(x, ==, mline_window.x); g_assert_cmpint(y, ==, mline_window.y); g_assert_cmpint(3 * height, ==, mline_window.height); - atk_text_get_character_extents(multiline_text, 59, &x, &y, &width, &height, ATK_XY_WINDOW); - // Last line won't fill the whole width of the rectangle + atk_text_get_character_extents(multilineText, 59, &x, &y, &width, &height, ATK_XY_WINDOW); + /* Last line won't fill the whole width of the rectangle. */ g_assert_cmpint(x, <=, mline_window.x + mline_window.width - width); g_assert_cmpint(y, ==, mline_window.y + mline_window.height - height); g_assert_cmpint(height, <=, mline_window.height); - g_object_unref(short_text1); - g_object_unref(short_text2); - g_object_unref(long_text); - g_object_unref(multiline_text); + g_object_unref(shortText1); + g_object_unref(shortText2); + g_object_unref(longText); + g_object_unref(multilineText); g_object_unref(webView); } -static void testWebkitAtkLayoutAndDataTables(void) +static void testWebkitAtkLayoutAndDataTables() { WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); webkit_web_view_load_string(webView, layoutAndDataTables, 0, 0, 0); - // Manually spin the main context to get the accessible objects - while (g_main_context_pending(0)) - g_main_context_iteration(0, TRUE); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - AtkObject* obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); - // Check the non-layout table (data table) + /* Check the non-layout table (data table). */ - AtkObject* table1 = atk_object_ref_accessible_child(obj, 0); + AtkObject* table1 = atk_object_ref_accessible_child(object, 0); g_assert(ATK_IS_TABLE(table1)); AtkAttributeSet* set1 = atk_object_get_attributes(table1); g_assert(set1); g_assert(!atkAttributeSetContainsAttributeName(set1, "layout-guess")); atk_attribute_set_free(set1); - // Check the layout table + /* Check the layout table. */ - AtkObject* table2 = atk_object_ref_accessible_child(obj, 1); + AtkObject* table2 = atk_object_ref_accessible_child(object, 1); g_assert(ATK_IS_TABLE(table2)); AtkAttributeSet* set2 = atk_object_get_attributes(table2); g_assert(set2); @@ -1017,22 +937,21 @@ static void testWebkitAtkLayoutAndDataTables(void) g_object_unref(webView); } -static void testWebkitAtkLinksWithInlineImages(void) +static void testWebkitAtkLinksWithInlineImages() { WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); webkit_web_view_load_string(webView, linksWithInlineImages, 0, 0, 0); - // Manually spin the main context to get the accessible objects - while (g_main_context_pending(0)) - g_main_context_iteration(0, TRUE); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); g_assert(object); - // First paragraph (link at the beginning) + /* First paragraph (link at the beginning). */ AtkObject* paragraph = atk_object_ref_accessible_child(object, 0); g_assert(ATK_IS_TEXT(paragraph)); gint startOffset; @@ -1045,7 +964,7 @@ static void testWebkitAtkLinksWithInlineImages(void) g_free(text); g_object_unref(paragraph); - // Second paragraph (link in the middle) + /* Second paragraph (link in the middle). */ paragraph = atk_object_ref_accessible_child(object, 1); g_assert(ATK_IS_TEXT(paragraph)); text = atk_text_get_text_at_offset(ATK_TEXT(paragraph), 0, ATK_TEXT_BOUNDARY_LINE_START, &startOffset, &endOffset); @@ -1056,7 +975,7 @@ static void testWebkitAtkLinksWithInlineImages(void) g_free(text); g_object_unref(paragraph); - // Third paragraph (link at the end) + /* Third paragraph (link at the end). */ paragraph = atk_object_ref_accessible_child(object, 2); g_assert(ATK_IS_TEXT(paragraph)); text = atk_text_get_text_at_offset(ATK_TEXT(paragraph), 0, ATK_TEXT_BOUNDARY_LINE_START, &startOffset, &endOffset); @@ -1070,24 +989,97 @@ static void testWebkitAtkLinksWithInlineImages(void) g_object_unref(webView); } -static void testWebkitAtkListsOfItems(void) +static void testWebkitAtkHypertextAndHyperlinks() { WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); - webkit_web_view_load_string(webView, listsOfItems, NULL, NULL, NULL); - GMainLoop* loop = g_main_loop_new(NULL, TRUE); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, hypertextAndHyperlinks, 0, 0, 0); - g_idle_add((GSourceFunc)bail_out, loop); - g_main_loop_run(loop); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - AtkObject* obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); - // Unordered list + AtkObject* paragraph1 = atk_object_ref_accessible_child(object, 0); + g_assert(ATK_OBJECT(paragraph1)); + g_assert(atk_object_get_role(paragraph1) == ATK_ROLE_PARAGRAPH); + g_assert(ATK_IS_HYPERTEXT(paragraph1)); + + /* No links in the first paragraph. */ + gint nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph1)); + g_assert_cmpint(nLinks, ==, 0); + + AtkObject* paragraph2 = atk_object_ref_accessible_child(object, 1); + g_assert(ATK_OBJECT(paragraph2)); + g_assert(atk_object_get_role(paragraph2) == ATK_ROLE_PARAGRAPH); + g_assert(ATK_IS_HYPERTEXT(paragraph2)); + + /* Check links in the second paragraph. + nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph2)); + g_assert_cmpint(nLinks, ==, 3); */ + + AtkHyperlink* hLink1 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 0); + g_assert(ATK_HYPERLINK(hLink1)); + AtkObject* hLinkObject1 = atk_hyperlink_get_object(hLink1, 0); + g_assert(ATK_OBJECT(hLinkObject1)); + g_assert(atk_object_get_role(hLinkObject1) == ATK_ROLE_LINK); + g_assert_cmpint(atk_hyperlink_get_start_index(hLink1), ==, 0); + g_assert_cmpint(atk_hyperlink_get_end_index(hLink1), ==, 6); + g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink1), ==, 1); + g_assert_cmpstr(atk_hyperlink_get_uri(hLink1, 0), ==, "http://foo.bar.baz/"); + + AtkHyperlink* hLink2 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 1); + g_assert(ATK_HYPERLINK(hLink2)); + AtkObject* hLinkObject2 = atk_hyperlink_get_object(hLink2, 0); + g_assert(ATK_OBJECT(hLinkObject2)); + g_assert(atk_object_get_role(hLinkObject2) == ATK_ROLE_LINK); + g_assert_cmpint(atk_hyperlink_get_start_index(hLink2), ==, 12); + g_assert_cmpint(atk_hyperlink_get_end_index(hLink2), ==, 32); + g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink2), ==, 1); + g_assert_cmpstr(atk_hyperlink_get_uri(hLink2, 0), ==, "http://bar.baz.foo/"); + + AtkHyperlink* hLink3 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 2); + g_assert(ATK_HYPERLINK(hLink3)); + AtkObject* hLinkObject3 = atk_hyperlink_get_object(hLink3, 0); + g_assert(ATK_OBJECT(hLinkObject3)); + g_assert(atk_object_get_role(hLinkObject3) == ATK_ROLE_LINK); + g_assert_cmpint(atk_hyperlink_get_start_index(hLink3), ==, 65); + g_assert_cmpint(atk_hyperlink_get_end_index(hLink3), ==, 75); + g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink3), ==, 1); + g_assert_cmpstr(atk_hyperlink_get_uri(hLink3, 0), ==, "http://baz.foo.bar/"); + + /* Finally check the AtkAction interface for a given AtkHyperlink. */ + g_assert(ATK_IS_ACTION(hLink1)); + g_assert_cmpint(atk_action_get_n_actions(ATK_ACTION(hLink1)), ==, 1); + g_assert_cmpstr(atk_action_get_keybinding(ATK_ACTION(hLink1), 0), ==, ""); + g_assert_cmpstr(atk_action_get_name(ATK_ACTION(hLink1), 0), ==, "jump"); + g_assert(atk_action_do_action(ATK_ACTION(hLink1), 0)); - AtkObject* uList = atk_object_ref_accessible_child(obj, 0); + g_object_unref(paragraph1); + g_object_unref(paragraph2); + g_object_unref(webView); +} + +static void testWebkitAtkListsOfItems() +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); + webkit_web_view_load_string(webView, listsOfItems, 0, 0, 0); + + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); + + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); + + /* Unordered list. */ + + AtkObject* uList = atk_object_ref_accessible_child(object, 0); g_assert(ATK_OBJECT(uList)); g_assert(atk_object_get_role(uList) == ATK_ROLE_LIST); g_assert_cmpint(atk_object_get_n_accessible_children(uList), ==, 3); @@ -1111,9 +1103,9 @@ static void testWebkitAtkListsOfItems(void) g_object_unref(item2); g_object_unref(item3); - // Ordered list + /* Ordered list. */ - AtkObject* oList = atk_object_ref_accessible_child(obj, 1); + AtkObject* oList = atk_object_ref_accessible_child(object, 1); g_assert(ATK_OBJECT(oList)); g_assert(atk_object_get_role(oList) == ATK_ROLE_LIST); g_assert_cmpint(atk_object_get_n_accessible_children(oList), ==, 3); @@ -1162,22 +1154,21 @@ static gboolean checkTextChanges(gpointer unused) return FALSE; } -static void testWebkitAtkTextChangedNotifications(void) +static void testWebkitAtkTextChangedNotifications() { WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); g_object_ref_sink(webView); - GtkAllocation alloc = { 0, 0, 800, 600 }; - gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); + GtkAllocation allocation = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation); webkit_web_view_load_string(webView, formWithTextInputs, 0, 0, 0); - // Manually spin the main context to get the accessible objects - while (g_main_context_pending(0)) - g_main_context_iteration(0, TRUE); + /* Wait for the accessible objects to be created. */ + waitForAccessibleObjects(); - AtkObject* obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); - g_assert(obj); + AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(object); - AtkObject* form = atk_object_ref_accessible_child(obj, 0); + AtkObject* form = atk_object_ref_accessible_child(object, 0); g_assert(ATK_IS_OBJECT(form)); AtkObject* textEntry = atk_object_ref_accessible_child(form, 0); @@ -1206,22 +1197,23 @@ static void testWebkitAtkTextChangedNotifications(void) int main(int argc, char** argv) { - g_thread_init(NULL); - gtk_test_init(&argc, &argv, NULL); + g_thread_init(0); + gtk_test_init(&argc, &argv, 0); g_test_bug_base("https://bugs.webkit.org/"); - g_test_add_func("/webkit/atk/get_text_at_offset", test_webkit_atk_get_text_at_offset); - g_test_add_func("/webkit/atk/get_text_at_offset_forms", test_webkit_atk_get_text_at_offset_forms); - g_test_add_func("/webkit/atk/get_text_at_offset_newlines", test_webkit_atk_get_text_at_offset_newlines); - g_test_add_func("/webkit/atk/get_text_at_offset_textarea", test_webkit_atk_get_text_at_offset_textarea); - g_test_add_func("/webkit/atk/get_text_at_offset_text_input", test_webkit_atk_get_text_at_offset_text_input); + g_test_add_func("/webkit/atk/getTextAtOffset", testWebkitAtkGetTextAtOffset); + g_test_add_func("/webkit/atk/getTextAtOffsetForms", testWebkitAtkGetTextAtOffsetForms); + g_test_add_func("/webkit/atk/getTextAtOffsetNewlines", testWebkitAtkGetTextAtOffsetNewlines); + g_test_add_func("/webkit/atk/getTextAtOffsetTextarea", testWebkitAtkGetTextAtOffsetTextarea); + g_test_add_func("/webkit/atk/getTextAtOffsetTextInput", testWebkitAtkGetTextAtOffsetTextInput); g_test_add_func("/webkit/atk/getTextInParagraphAndBodySimple", testWebkitAtkGetTextInParagraphAndBodySimple); g_test_add_func("/webkit/atk/getTextInParagraphAndBodyModerate", testWebkitAtkGetTextInParagraphAndBodyModerate); g_test_add_func("/webkit/atk/getTextInTable", testWebkitAtkGetTextInTable); g_test_add_func("/webkit/atk/getHeadersInTable", testWebkitAtkGetHeadersInTable); g_test_add_func("/webkit/atk/textAttributes", testWebkitAtkTextAttributes); - g_test_add_func("/webkit/atk/textSelections", testWekitAtkTextSelections); + g_test_add_func("/webkit/atk/textSelections", testWebkitAtkTextSelections); g_test_add_func("/webkit/atk/getExtents", testWebkitAtkGetExtents); + g_test_add_func("/webkit/atk/hypertextAndHyperlinks", testWebkitAtkHypertextAndHyperlinks); g_test_add_func("/webkit/atk/layoutAndDataTables", testWebkitAtkLayoutAndDataTables); g_test_add_func("/webkit/atk/linksWithInlineImages", testWebkitAtkLinksWithInlineImages); g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems); diff --git a/WebKit/gtk/tests/testcopyandpaste.c b/WebKit/gtk/tests/testcopyandpaste.c index f7889bd..1b5fb7b 100644 --- a/WebKit/gtk/tests/testcopyandpaste.c +++ b/WebKit/gtk/tests/testcopyandpaste.c @@ -92,6 +92,17 @@ static void load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer da g_assert(!text || !strcmp(text, fixture->info->expectedContent)); g_free(text); + // Verify that the markup starts with the proper content-type meta tag prefix. + GtkSelectionData* selectionData = gtk_clipboard_wait_for_contents(clipboard, gdk_atom_intern("text/html", FALSE)); + if (selectionData) { + static const char* markupPrefix = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"; + char* markup = g_strndup((const char*) gtk_selection_data_get_data(selectionData), + gtk_selection_data_get_length(selectionData)); + g_assert(strlen(markupPrefix) <= strlen(markup)); + g_assert(!strncmp(markupPrefix, markup, strlen(markupPrefix))); + g_free(markup); + } + g_assert(!gtk_clipboard_wait_is_uris_available(clipboard)); g_assert(!gtk_clipboard_wait_is_image_available(clipboard)); diff --git a/WebKit/gtk/webkit/webkitprivate.h b/WebKit/gtk/webkit/webkitprivate.h index 261c437..3ac3563 100644 --- a/WebKit/gtk/webkit/webkitprivate.h +++ b/WebKit/gtk/webkit/webkitprivate.h @@ -278,6 +278,9 @@ extern "C" { void webkit_web_view_add_resource(WebKitWebView*, const char*, WebKitWebResource*); + void + webkit_web_view_remove_resource(WebKitWebView*, const char*); + WebKitWebResource* webkit_web_view_get_resource(WebKitWebView*, char*); diff --git a/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp b/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp index c5913fd..9b5bf8b 100644 --- a/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp +++ b/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp @@ -19,17 +19,15 @@ */ #include "config.h" - #include "webkitwebbackforwardlist.h" + +#include "BackForwardListImpl.h" +#include "HistoryItem.h" #include "webkitprivate.h" #include "webkitwebhistoryitem.h" #include "webkitwebview.h" - #include <glib.h> -#include "BackForwardListImpl.h" -#include "HistoryItem.h" - /** * SECTION:webkitwebbackforwardlist * @short_description: The history of a #WebKitWebView @@ -115,7 +113,7 @@ WebKitWebBackForwardList* webkit_web_back_forward_list_new_with_web_view(WebKitW webBackForwardList = WEBKIT_WEB_BACK_FORWARD_LIST(g_object_new(WEBKIT_TYPE_WEB_BACK_FORWARD_LIST, NULL)); WebKitWebBackForwardListPrivate* priv = webBackForwardList->priv; - priv->backForwardList = static_cast<BackForwardListImpl*>(core(webView)->backForwardList()); + priv->backForwardList = static_cast<WebCore::BackForwardListImpl*>(core(webView)->backForwardList()); priv->backForwardList->setEnabled(TRUE); return webBackForwardList; diff --git a/WebKit/gtk/webkit/webkitwebframe.cpp b/WebKit/gtk/webkit/webkitwebframe.cpp index c581ce6..63a2413 100644 --- a/WebKit/gtk/webkit/webkitwebframe.cpp +++ b/WebKit/gtk/webkit/webkitwebframe.cpp @@ -480,7 +480,7 @@ G_CONST_RETURN gchar* webkit_web_frame_get_name(WebKitWebFrame* frame) if (!coreFrame) return ""; - String string = coreFrame->tree()->name(); + String string = coreFrame->tree()->uniqueName(); priv->name = g_strdup(string.utf8().data()); return priv->name; } @@ -1059,11 +1059,7 @@ void webkit_web_frame_suspend_animations(WebKitWebFrame* frame) if (!coreFrame) return; - AnimationController* controller = coreFrame->animation(); - if (!controller) - return; - - controller->suspendAnimations(coreFrame->document()); + coreFrame->animation()->suspendAnimations(); } void webkit_web_frame_resume_animations(WebKitWebFrame* frame) @@ -1072,11 +1068,7 @@ void webkit_web_frame_resume_animations(WebKitWebFrame* frame) if (!coreFrame) return; - AnimationController* controller = coreFrame->animation(); - if (!controller) - return; - - controller->resumeAnimations(coreFrame->document()); + coreFrame->animation()->resumeAnimations(); } gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame) diff --git a/WebKit/gtk/webkit/webkitwebsettings.cpp b/WebKit/gtk/webkit/webkitwebsettings.cpp index cd59bdb..2661b82 100644 --- a/WebKit/gtk/webkit/webkitwebsettings.cpp +++ b/WebKit/gtk/webkit/webkitwebsettings.cpp @@ -689,6 +689,7 @@ static void webkit_web_settings_class_init(WebKitWebSettingsClass* klass) COMPILE_ASSERT(static_cast<int>(WEBKIT_EDITING_BEHAVIOR_MAC) == static_cast<int>(WebCore::EditingMacBehavior), editing_behavior_type_mac_match); COMPILE_ASSERT(static_cast<int>(WEBKIT_EDITING_BEHAVIOR_WINDOWS) == static_cast<int>(WebCore::EditingWindowsBehavior), editing_behavior_type_windows_match); + COMPILE_ASSERT(static_cast<int>(WEBKIT_EDITING_BEHAVIOR_UNIX) == static_cast<int>(WebCore::EditingUnixBehavior), editing_behavior_type_unix_match); /** * WebKitWebSettings:editing-behavior @@ -713,7 +714,7 @@ static void webkit_web_settings_class_init(WebKitWebSettingsClass* klass) _("Editing behavior"), _("The behavior mode to use in editing mode"), WEBKIT_TYPE_EDITING_BEHAVIOR, - WEBKIT_EDITING_BEHAVIOR_MAC, + WEBKIT_EDITING_BEHAVIOR_UNIX, flags)); /** diff --git a/WebKit/gtk/webkit/webkitwebsettings.h b/WebKit/gtk/webkit/webkitwebsettings.h index d8dafd9..eee0d04 100644 --- a/WebKit/gtk/webkit/webkitwebsettings.h +++ b/WebKit/gtk/webkit/webkitwebsettings.h @@ -36,7 +36,8 @@ G_BEGIN_DECLS typedef enum { WEBKIT_EDITING_BEHAVIOR_MAC, - WEBKIT_EDITING_BEHAVIOR_WINDOWS + WEBKIT_EDITING_BEHAVIOR_WINDOWS, + WEBKIT_EDITING_BEHAVIOR_UNIX } WebKitEditingBehavior; typedef struct _WebKitWebSettingsPrivate WebKitWebSettingsPrivate; diff --git a/WebKit/gtk/webkit/webkitwebview.cpp b/WebKit/gtk/webkit/webkitwebview.cpp index a295fce..314da16 100644 --- a/WebKit/gtk/webkit/webkitwebview.cpp +++ b/WebKit/gtk/webkit/webkitwebview.cpp @@ -43,7 +43,7 @@ #include "AXObjectCache.h" #include "AbstractDatabase.h" #include "BackForwardListImpl.h" -#include "Cache.h" +#include "MemoryCache.h" #include "ChromeClientGtk.h" #include "ClipboardUtilitiesGtk.h" #include "ContextMenuClientGtk.h" @@ -868,6 +868,7 @@ static gboolean webkit_web_view_scroll_event(GtkWidget* widget, GdkEventScroll* return frame->eventHandler()->handleWheelEvent(wheelEvent); } +#ifdef GTK_API_VERSION_2 static void webkit_web_view_size_request(GtkWidget* widget, GtkRequisition* requisition) { WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget); @@ -882,6 +883,35 @@ static void webkit_web_view_size_request(GtkWidget* widget, GtkRequisition* requ requisition->width = view->contentsWidth(); requisition->height = view->contentsHeight(); } +#else +static void webkit_web_view_get_preferred_width(GtkWidget* widget, gint* minimum, gint* natural) +{ + WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget); + Frame* coreFrame = core(webkit_web_view_get_main_frame(web_view)); + if (!coreFrame) + return; + + FrameView* view = coreFrame->view(); + if (!view) + return; + + *minimum = *natural = view->contentsWidth(); +} + +static void webkit_web_view_get_preferred_height(GtkWidget* widget, gint* minimum, gint* natural) +{ + WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget); + Frame* coreFrame = core(webkit_web_view_get_main_frame(web_view)); + if (!coreFrame) + return; + + FrameView* view = coreFrame->view(); + if (!view) + return; + + *minimum = *natural = view->contentsHeight(); +} +#endif static void webkit_web_view_size_allocate(GtkWidget* widget, GtkAllocation* allocation) { @@ -2602,7 +2632,12 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) widgetClass->motion_notify_event = webkit_web_view_motion_event; widgetClass->scroll_event = webkit_web_view_scroll_event; widgetClass->size_allocate = webkit_web_view_size_allocate; +#ifdef GTK_API_VERSION_2 widgetClass->size_request = webkit_web_view_size_request; +#else + widgetClass->get_preferred_width = webkit_web_view_get_preferred_width; + widgetClass->get_preferred_height = webkit_web_view_get_preferred_height; +#endif widgetClass->popup_menu = webkit_web_view_popup_menu_handler; widgetClass->grab_focus = webkit_web_view_grab_focus; widgetClass->focus_in_event = webkit_web_view_focus_in_event; @@ -4612,6 +4647,16 @@ void webkit_web_view_add_resource(WebKitWebView* webView, const char* identifier g_hash_table_insert(priv->subResources.get(), g_strdup(identifier), webResource); } +void webkit_web_view_remove_resource(WebKitWebView* webView, const char* identifier) +{ + WebKitWebViewPrivate* priv = webView->priv; + if (g_str_equal(identifier, priv->mainResourceIdentifier.data())) { + priv->mainResourceIdentifier = ""; + priv->mainResource = 0; + } else + g_hash_table_remove(priv->subResources.get(), identifier); +} + WebKitWebResource* webkit_web_view_get_resource(WebKitWebView* webView, char* identifier) { WebKitWebViewPrivate* priv = webView->priv; diff --git a/WebKit/haiku/ChangeLog b/WebKit/haiku/ChangeLog index 7ed4fad..723c957 100644 --- a/WebKit/haiku/ChangeLog +++ b/WebKit/haiku/ChangeLog @@ -1,3 +1,29 @@ +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. Also, added missing "virtual" + keywords all over the place. + + * WebCoreSupport/ChromeClientHaiku.cpp: + (WebCore::ChromeClientHaiku::focusedFrameChanged): + * WebCoreSupport/ChromeClientHaiku.h: + (WebCore::ChromeClientHaiku::scrollbarsModeDidChange): + (WebCore::ChromeClientHaiku::cancelGeolocationPermissionRequestForFrame): + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * WebCoreSupport/ChromeClientHaiku.h: + (WebCore::ChromeClientHaiku::showContextMenu): + 2010-10-29 Alexey Proskuryakov <ap@apple.com> Reviewed by Darin Adler. diff --git a/WebKit/haiku/WebCoreSupport/ChromeClientHaiku.cpp b/WebKit/haiku/WebCoreSupport/ChromeClientHaiku.cpp index 134cabe..01b9c1d 100644 --- a/WebKit/haiku/WebCoreSupport/ChromeClientHaiku.cpp +++ b/WebKit/haiku/WebCoreSupport/ChromeClientHaiku.cpp @@ -108,6 +108,10 @@ void ChromeClientHaiku::focusedNodeChanged(Node*) { } +void ChromeClientHaiku::focusedFrameChanged(Frame*) +{ +} + Page* ChromeClientHaiku::createWindow(Frame*, const FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&) { notImplemented(); diff --git a/WebKit/haiku/WebCoreSupport/ChromeClientHaiku.h b/WebKit/haiku/WebCoreSupport/ChromeClientHaiku.h index 9409c69..deb3678 100644 --- a/WebKit/haiku/WebCoreSupport/ChromeClientHaiku.h +++ b/WebKit/haiku/WebCoreSupport/ChromeClientHaiku.h @@ -43,83 +43,84 @@ namespace WebCore { public: ChromeClientHaiku(); virtual ~ChromeClientHaiku(); - void chromeDestroyed(); + virtual void chromeDestroyed(); - void setWindowRect(const FloatRect&); - FloatRect windowRect(); + virtual void setWindowRect(const FloatRect&); + virtual FloatRect windowRect(); - FloatRect pageRect(); + virtual FloatRect pageRect(); - float scaleFactor(); + virtual float scaleFactor(); - void focus(); - void unfocus(); + virtual void focus(); + virtual void unfocus(); - bool canTakeFocus(FocusDirection); - void takeFocus(FocusDirection); + virtual bool canTakeFocus(FocusDirection); + virtual void takeFocus(FocusDirection); - void focusedNodeChanged(Node*); + virtual void focusedNodeChanged(Node*); + virtual void focusedFrameChanged(Frame*); - Page* createWindow(Frame*, const FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&); - Page* createModalDialog(Frame*, const FrameLoadRequest&); - void show(); + virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&); + virtual Page* createModalDialog(Frame*, const FrameLoadRequest&); + virtual void show(); - bool canRunModal(); - void runModal(); + virtual bool canRunModal(); + virtual void runModal(); - void setToolbarsVisible(bool); - bool toolbarsVisible(); + virtual void setToolbarsVisible(bool); + virtual bool toolbarsVisible(); - void setStatusbarVisible(bool); - bool statusbarVisible(); + virtual void setStatusbarVisible(bool); + virtual bool statusbarVisible(); - void setScrollbarsVisible(bool); - bool scrollbarsVisible(); + virtual void setScrollbarsVisible(bool); + virtual bool scrollbarsVisible(); - void setMenubarVisible(bool); - bool menubarVisible(); + virtual void setMenubarVisible(bool); + virtual bool menubarVisible(); - void setResizable(bool); + virtual void setResizable(bool); - void addMessageToConsole(const String& message, unsigned int lineNumber, + virtual void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID); - void addMessageToConsole(MessageSource, MessageLevel, const String& message, + virtual void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned int lineNumber, const String& sourceID); - void addMessageToConsole(MessageSource, MessageType, MessageLevel, + virtual void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, unsigned int, const String&); - bool canRunBeforeUnloadConfirmPanel(); + virtual bool canRunBeforeUnloadConfirmPanel(); - bool runBeforeUnloadConfirmPanel(const String& message, Frame* frame); + virtual bool runBeforeUnloadConfirmPanel(const String& message, Frame* frame); - void closeWindowSoon(); + virtual void closeWindowSoon(); - void runJavaScriptAlert(Frame*, const String&); - bool runJavaScriptConfirm(Frame*, const String&); - bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result); - bool shouldInterruptJavaScript(); + virtual void runJavaScriptAlert(Frame*, const String&); + virtual bool runJavaScriptConfirm(Frame*, const String&); + virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result); + virtual bool shouldInterruptJavaScript(); - void setStatusbarText(const WTF::String&); - bool tabsToLinks() const; - IntRect windowResizerRect() const; + virtual void setStatusbarText(const WTF::String&); + virtual bool tabsToLinks() const; + virtual IntRect windowResizerRect() const; - void invalidateWindow(const IntRect&, bool); - void invalidateContentsAndWindow(const IntRect&, bool); - void invalidateContentsForSlowScroll(const IntRect&, bool); - void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); + virtual void invalidateWindow(const IntRect&, bool); + virtual void invalidateContentsAndWindow(const IntRect&, bool); + virtual void invalidateContentsForSlowScroll(const IntRect&, bool); + virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); - IntPoint screenToWindow(const IntPoint&) const; - IntRect windowToScreen(const IntRect&) const; - PlatformPageClient platformPageClient() const; - void contentsSizeChanged(Frame*, const IntSize&) const; - void scrollRectIntoView(const IntRect&, const ScrollView*) const; + virtual IntPoint screenToWindow(const IntPoint&) const; + virtual IntRect windowToScreen(const IntRect&) const; + virtual PlatformPageClient platformPageClient() const; + virtual void contentsSizeChanged(Frame*, const IntSize&) const; + virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const; void addToDirtyRegion(const IntRect&); void scrollBackingStore(int, int, const IntRect&, const IntRect&); void updateBackingStore(); - void scrollbarsModeDidChange() const { } - void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); + virtual void scrollbarsModeDidChange() const { } + virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); void setToolTip(const String&); @@ -127,7 +128,9 @@ namespace WebCore { void print(Frame*); - void exceededDatabaseQuota(Frame*, const String& databaseName); +#if ENABLE(DATABASE) + virtual void exceededDatabaseQuota(Frame*, const String& databaseName); +#endif virtual bool selectItemWritingDirectionIsNatural(); virtual PassRefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const; @@ -137,22 +140,25 @@ namespace WebCore { virtual void reachedMaxAppCacheSize(int64_t spaceNeeded); virtual void reachedApplicationCacheOriginQuota(SecurityOrigin*); #endif +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif // This is an asynchronous call. The ChromeClient can display UI asking the user for permission // to use Geolococation. - void requestGeolocationPermissionForFrame(Frame*, Geolocation*); - void cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*) { } + virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*); + virtual void cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*) { } - void runOpenPanel(Frame*, PassRefPtr<FileChooser>); - void chooseIconForFiles(const Vector<String>&, FileChooser*); + virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>); + virtual void chooseIconForFiles(const Vector<String>&, FileChooser*); - void setCursor(const Cursor&); + virtual void setCursor(const Cursor&); // Notification that the given form element has changed. This function // will be called frequently, so handling should be very fast. - void formStateDidChange(const Node*); + virtual void formStateDidChange(const Node*); - PassOwnPtr<HTMLParserQuirks> createHTMLParserQuirks(); + virtual PassOwnPtr<HTMLParserQuirks> createHTMLParserQuirks(); }; } // namespace WebCore diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog index e7abf3d..8d54870 100644 --- a/WebKit/mac/ChangeLog +++ b/WebKit/mac/ChangeLog @@ -1,3 +1,224 @@ +2010-11-08 Anders Carlsson <andersca@apple.com> + + Reviewed by Dan Bernstein. + + Plug-in views should not assume that plugins are RenderEmbeddedObjects + https://bugs.webkit.org/show_bug.cgi?id=49196 + <rdar://problem/8638467> + + * Plugins/Hosted/WebHostedNetscapePluginView.mm: + (-[WebHostedNetscapePluginView pluginHostDied]): + +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * WebCoreSupport/WebChromeClient.h: + * WebCoreSupport/WebChromeClient.mm: + (WebChromeClient::focusedFrameChanged): + +2010-11-08 Anders Carlsson <andersca@apple.com> + + Build fix. + + * MigrateHeaders.make: + +2010-11-08 Anders Carlsson <andersca@apple.com> + + Reviewed by Adam Roben. + + Remove use of HIGetScaleFactor + https://bugs.webkit.org/show_bug.cgi?id=49186 + <rdar://problem/8618410> + + Scale factors can vary on a display-by-display basis and it doesn't make sense + to compute scale factor event coordinates like this. + + * Plugins/WebNetscapePluginEventHandlerCarbon.mm: + (getCarbonEvent): + +2010-11-08 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Sam Weinig. + + Allow applets to participate in accelerated compositing + https://bugs.webkit.org/show_bug.cgi?id=49117 + <rdar://problem/8625819> + + If Java is being loaded via the Netscape Plugin API, create a + NetscapePluginWidget so that it has an implementation of platformLayer(). + + Also clean up by using early returns. + + * WebCoreSupport/WebFrameLoaderClient.mm: + +2010-11-07 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Rename Cache to MemoryCache + https://bugs.webkit.org/show_bug.cgi?id=49159 + + * Misc/WebCache.mm: + (+[WebCache statistics]): + * WebCoreSupport/WebDeviceOrientationClient.mm: + (WebDeviceOrientationClient::setController): + * WebView/WebView.mm: + +2010-11-05 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=49100 + ASSERT([self window]) fails in -[WebBaseNetscapePluginView restartTimers] + + * Plugins/WebBaseNetscapePluginView.mm: (-[WebBaseNetscapePluginView restartTimers]): + Removed the assertion. Multiple callers provide no guarantee that the plug-in is still alive + (see bug comments), and there seems to be no harm in executing this function in that case. + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Move resumeAnimations/suspendAnimations from Frame to AnimationController. + https://bugs.webkit.org/show_bug.cgi?id=49073 + + * WebView/WebFrame.mm: + (-[WebFrame _suspendAnimations]): + (-[WebFrame _resumeAnimations]): + +2010-11-04 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=49008 + <rdar://problem/7906226> Frequent crashes on mail.yahoo.co.jp + + Callers of NetscapePluginInstanceProxy::waitForReply() are not prepared to be deleted during + the call, unless it returns 0. There are two reasons for NetscapePluginInstanceProxy to be + deleted during wait: + - plugin crashed; + - plugin was stopped (e.g. due to a DOM modification performed by another reply that came in + while waiting). + + We didn't recognize the latter. + + * Plugins/Hosted/NetscapePluginHostProxy.mm: + (WebKit::PluginDestroyDeferrer::~PluginDestroyDeferrer): + * Plugins/Hosted/NetscapePluginInstanceProxy.h: + (WebKit::NetscapePluginInstanceProxy::waitForReply): + * Plugins/Hosted/NetscapePluginInstanceProxy.mm: + (WebKit::NetscapePluginInstanceProxy::didCallPluginFunction): + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Make suspendAnimations/resumeAnimations and setCSSAnimations traverse through subframes and remember state + https://bugs.webkit.org/show_bug.cgi?id=46945 + + * WebView/WebFrame.mm: + (-[WebFrame _suspendAnimations]): + (-[WebFrame _resumeAnimations]): + +2010-11-04 Jia Pu <jpu@apple.com> + + Reviewed by Dan Bernstein. + + reversion bubble in WebViews + https://bugs.webkit.org/show_bug.cgi?id=47630 + <rdar://problem/8530960> + + This patch is to add reversion to correction panel. Please see WebCore/ChangeLog for detail. + + * WebCoreSupport/WebEditorClient.h: Adopted new signature of base class method. + * WebCoreSupport/WebEditorClient.mm: Adopted new signature of base class method. And code + change to use new reversion API in AppKit. + (WebEditorClient::WebEditorClient): + (WebEditorClient::~WebEditorClient): + (WebEditorClient::respondToChangedSelection): + (WebEditorClient::showCorrectionPanel): + (WebEditorClient::dismissCorrectionPanel): + (WebEditorClient::isShowingCorrectionPanel): + +2010-11-04 Mike Thole <mthole@apple.com> + + Reviewed by Dan Bernstein. + + Title for images should use localized numerals + https://bugs.webkit.org/show_bug.cgi?id=49017 + + * WebCoreSupport/WebPlatformStrategies.mm: + (WebPlatformStrategies::imageTitle): Use localized numerals on Snow Leopard or newer. + +2010-11-02 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 1 of 2. + + Substitute FrameTree::uniqueName() for FrameTree::name() in the Mac port. + + * WebView/WebFrame.mm: + (-[WebFrame name]): + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * WebCoreSupport/WebChromeClient.h: + (WebChromeClient::showContextMenu): + +2010-10-29 Daniel Bates <dbates@rim.com> + + No review, rolling out 70971. + http://trac.webkit.org/changeset/70971 + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Rolling out changeset 70971 <http://trac.webkit.org/changeset/70971> since + it caused layout test failures on all bots. In particular, the + child count in a generated frame name differs after this patch. We need + to look into this further. + + * WebView/WebFrame.mm: + (-[WebFrame name]): + +2010-10-28 Antonio Gomes <agomes@rim.com> + + Reviewed by Ojan Vafai. + + Needs a "LinuxEditingBehavior", perhaps with a better name + https://bugs.webkit.org/show_bug.cgi?id=36627 + + Added the corresponding GTK+ setting to WebCore's EditingUnixBehavior: WebKitEditingUnixBehavior. + + * WebView/WebFrame.mm: + (core): + * WebView/WebPreferencesPrivate.h: + +2010-10-29 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Modified Mac-port to use FrameTree::uniqueName(). + + * WebView/WebFrame.mm: + (-[WebFrame name]): + 2010-10-29 Darin Adler <darin@apple.com> Reviewed by Sam Weinig. diff --git a/WebKit/mac/Configurations/Version.xcconfig b/WebKit/mac/Configurations/Version.xcconfig index 8739787..56baf78 100644 --- a/WebKit/mac/Configurations/Version.xcconfig +++ b/WebKit/mac/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 534; -MINOR_VERSION = 11; +MINOR_VERSION = 12; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/WebKit/mac/MigrateHeaders.make b/WebKit/mac/MigrateHeaders.make index 2e6f24a..d674d4d 100644 --- a/WebKit/mac/MigrateHeaders.make +++ b/WebKit/mac/MigrateHeaders.make @@ -222,7 +222,6 @@ all : \ $(PRIVATE_HEADERS_DIR)/DOMSVGAnimatedNumberList.h \ $(INTERNAL_HEADERS_DIR)/DOMSVGAnimatedNumberListInternal.h \ $(PRIVATE_HEADERS_DIR)/DOMSVGAnimatedPathData.h \ - $(PRIVATE_HEADERS_DIR)/DOMSVGAnimatedPoints.h \ $(PRIVATE_HEADERS_DIR)/DOMSVGAnimatedPreserveAspectRatio.h \ $(INTERNAL_HEADERS_DIR)/DOMSVGAnimatedPreserveAspectRatioInternal.h \ $(PRIVATE_HEADERS_DIR)/DOMSVGAnimatedRect.h \ diff --git a/WebKit/mac/Misc/WebCache.mm b/WebKit/mac/Misc/WebCache.mm index 747d213..0517bc4 100644 --- a/WebKit/mac/Misc/WebCache.mm +++ b/WebKit/mac/Misc/WebCache.mm @@ -31,7 +31,7 @@ #import "WebView.h" #import "WebViewInternal.h" #import <WebCore/ApplicationCacheStorage.h> -#import <WebCore/Cache.h> +#import <WebCore/MemoryCache.h> #import <WebCore/CrossOriginPreflightResultCache.h> @implementation WebCache @@ -43,7 +43,7 @@ + (NSArray *)statistics { - WebCore::Cache::Statistics s = WebCore::cache()->getStatistics(); + WebCore::MemoryCache::Statistics s = WebCore::cache()->getStatistics(); return [NSArray arrayWithObjects: [NSDictionary dictionaryWithObjectsAndKeys: diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm index 067b8bb..4506f03 100644 --- a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm +++ b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm @@ -74,7 +74,8 @@ public: ~PluginDestroyDeferrer() { - m_proxy->didCallPluginFunction(); + bool stopped; + m_proxy->didCallPluginFunction(stopped); } private: diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h index 3081120..f784ade 100644 --- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h +++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h @@ -153,7 +153,7 @@ public: void invalidate(); void willCallPluginFunction(); - void didCallPluginFunction(); + void didCallPluginFunction(bool& stopped); bool shouldStop(); uint32_t nextRequestID(); @@ -262,8 +262,14 @@ public: ASSERT(reply->m_type == T::ReplyType); m_waitingForReply = false; - - didCallPluginFunction(); + + bool stopped = false; + didCallPluginFunction(stopped); + if (stopped) { + // The instance proxy may have been deleted from didCallPluginFunction(), so a null reply needs to be returned. + delete static_cast<T*>(reply); + return std::auto_ptr<T>(); + } return std::auto_ptr<T>(static_cast<T*>(reply)); } diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm index a2d4a96..ecaa0d6 100644 --- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm +++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm @@ -1455,7 +1455,7 @@ void NetscapePluginInstanceProxy::willCallPluginFunction() m_pluginFunctionCallDepth++; } -void NetscapePluginInstanceProxy::didCallPluginFunction() +void NetscapePluginInstanceProxy::didCallPluginFunction(bool& stopped) { ASSERT(m_pluginFunctionCallDepth > 0); m_pluginFunctionCallDepth--; @@ -1465,6 +1465,7 @@ void NetscapePluginInstanceProxy::didCallPluginFunction() if (!m_pluginFunctionCallDepth && m_shouldStopSoon) { m_shouldStopSoon = false; [m_pluginView stop]; + stopped = true; } } diff --git a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm index 63a7b6a..362dd97 100644 --- a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm +++ b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm @@ -380,9 +380,11 @@ extern "C" { - (void)pluginHostDied { - RenderEmbeddedObject* renderer = toRenderEmbeddedObject(_element->renderer()); - if (renderer) + if (_element->renderer() && _element->renderer()->isEmbeddedObject()) { + // FIXME: The renderer could also be a RenderApplet, we should handle that. + RenderEmbeddedObject* renderer = toRenderEmbeddedObject(_element->renderer()); renderer->setShowsCrashedPluginIndicator(); + } _pluginLayer = nil; _proxy = 0; diff --git a/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm b/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm index 708b017..b6b8b64 100644 --- a/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm +++ b/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm @@ -326,8 +326,6 @@ String WebHaltablePlugin::pluginName() const - (void)restartTimers { - ASSERT([self window]); - [self stopTimers]; if (!_isStarted || [[self window] isMiniaturized]) diff --git a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm index 3d2b68e..a3aca1f 100644 --- a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm +++ b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCarbon.mm @@ -49,8 +49,6 @@ static void getCarbonEvent(EventRecord* carbonEvent) carbonEvent->when = TickCount(); GetGlobalMouse(&carbonEvent->where); - carbonEvent->where.h = static_cast<short>(carbonEvent->where.h * HIGetScaleFactor()); - carbonEvent->where.v = static_cast<short>(carbonEvent->where.v * HIGetScaleFactor()); carbonEvent->modifiers = GetCurrentKeyModifiers(); if (!Button()) carbonEvent->modifiers |= btnState; @@ -87,11 +85,8 @@ static EventModifiers modifiersForEvent(NSEvent *event) static void getCarbonEvent(EventRecord *carbonEvent, NSEvent *cocoaEvent) { - if (WKConvertNSEventToCarbonEvent(carbonEvent, cocoaEvent)) { - carbonEvent->where.h = static_cast<short>(carbonEvent->where.h * HIGetScaleFactor()); - carbonEvent->where.v = static_cast<short>(carbonEvent->where.v * HIGetScaleFactor()); + if (WKConvertNSEventToCarbonEvent(carbonEvent, cocoaEvent)) return; - } NSPoint where = [[cocoaEvent window] convertBaseToScreen:[cocoaEvent locationInWindow]]; diff --git a/WebKit/mac/WebCoreSupport/WebChromeClient.h b/WebKit/mac/WebCoreSupport/WebChromeClient.h index 209c2b9..a5f49e3 100644 --- a/WebKit/mac/WebCoreSupport/WebChromeClient.h +++ b/WebKit/mac/WebCoreSupport/WebChromeClient.h @@ -54,6 +54,7 @@ public: virtual void takeFocus(WebCore::FocusDirection); virtual void focusedNodeChanged(WebCore::Node*); + virtual void focusedFrameChanged(WebCore::Frame*); virtual WebCore::Page* createWindow(WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&); virtual void show(); @@ -178,6 +179,9 @@ public: virtual PassRefPtr<WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const; virtual PassRefPtr<WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const; +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif private: WebView *m_webView; }; diff --git a/WebKit/mac/WebCoreSupport/WebChromeClient.mm b/WebKit/mac/WebCoreSupport/WebChromeClient.mm index 3610896..fe95989 100644 --- a/WebKit/mac/WebCoreSupport/WebChromeClient.mm +++ b/WebKit/mac/WebCoreSupport/WebChromeClient.mm @@ -200,6 +200,10 @@ void WebChromeClient::focusedNodeChanged(Node*) { } +void WebChromeClient::focusedFrameChanged(Frame*) +{ +} + Page* WebChromeClient::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&) { NSURLRequest *URLRequest = nil; diff --git a/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.mm b/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.mm index f0c624d..3a4d5d7 100644 --- a/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.mm +++ b/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.mm @@ -41,7 +41,7 @@ WebDeviceOrientationClient::WebDeviceOrientationClient(WebView* webView) void WebDeviceOrientationClient::setController(DeviceOrientationController* controller) { // This is called by the Page constructor before our WebView has the provider set up. - // Cache the controller for later use. + // MemoryCache the controller for later use. m_controller = controller; } diff --git a/WebKit/mac/WebCoreSupport/WebEditorClient.h b/WebKit/mac/WebCoreSupport/WebEditorClient.h index ad324b9..23cf312 100644 --- a/WebKit/mac/WebCoreSupport/WebEditorClient.h +++ b/WebKit/mac/WebCoreSupport/WebEditorClient.h @@ -133,8 +133,8 @@ public: virtual void willSetInputMethodState(); virtual void setInputMethodState(bool enabled); #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - virtual void showCorrectionPanel(const WebCore::FloatRect& boundingBoxOfReplacedString, const WTF::String& replacedString, const WTF::String& replacementString, WebCore::Editor*); - virtual void dismissCorrectionPanel(bool correctionAccepted); + virtual void showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const WTF::String& replacedString, const WTF::String& replacementString, WebCore::Editor*); + virtual void dismissCorrectionPanel(WebCore::CorrectionWasRejectedOrNot); virtual bool isShowingCorrectionPanel(); #endif private: @@ -146,6 +146,6 @@ private: bool m_haveUndoRedoOperations; #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - NSInteger m_correctionPanelTag; + BOOL m_correctionPanelIsShown; #endif }; diff --git a/WebKit/mac/WebCoreSupport/WebEditorClient.mm b/WebKit/mac/WebCoreSupport/WebEditorClient.mm index 2bf3259..39b511e 100644 --- a/WebKit/mac/WebCoreSupport/WebEditorClient.mm +++ b/WebKit/mac/WebCoreSupport/WebEditorClient.mm @@ -186,7 +186,7 @@ WebEditorClient::WebEditorClient(WebView *webView) , m_undoTarget([[[WebEditorUndoTarget alloc] init] autorelease]) , m_haveUndoRedoOperations(false) #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - , m_correctionPanelTag(InvalidCorrectionPanelTag) + , m_correctionPanelIsShown(false) #endif { } @@ -194,7 +194,7 @@ WebEditorClient::WebEditorClient(WebView *webView) WebEditorClient::~WebEditorClient() { #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - dismissCorrectionPanel(true); + dismissCorrectionPanel(WebCore::CorrectionWasNotRejected); #endif } @@ -310,10 +310,6 @@ void WebEditorClient::respondToChangedSelection() { [m_webView _selectionChanged]; -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - dismissCorrectionPanel(true); -#endif - // FIXME: This quirk is needed due to <rdar://problem/5009625> - We can phase it out once Aperture can adopt the new behavior on their end if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_APERTURE_QUIRK) && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Aperture"]) return; @@ -860,8 +856,8 @@ void WebEditorClient::updateSpellingUIWithGrammarString(const String& badGrammar } #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) -void WebEditorClient::showCorrectionPanel(const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, Editor* editor) { - dismissCorrectionPanel(true); +void WebEditorClient::showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType panelType, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, Editor* editor) { + dismissCorrectionPanel(WebCore::CorrectionWasNotRejected); NSRect boundingBoxAsNSRect = boundingBoxOfReplacedString; NSRect webViewFrame = m_webView.frame; @@ -871,25 +867,33 @@ void WebEditorClient::showCorrectionPanel(const FloatRect& boundingBoxOfReplaced NSString *replacedStringAsNSString = replacedString; NSString *replacementStringAsNSString = replacementString; - m_correctionPanelTag = [[NSSpellChecker sharedSpellChecker] showCorrection:replacementStringAsNSString forStringInRect:boundingBoxAsNSRect view:m_webView completionHandler:^(BOOL accepted) { - if (!accepted) { + m_correctionPanelIsShown = YES; + NSCorrectionBubbleType bubbleType = panelType == WebCore::CorrectionPanelInfo::PanelTypeCorrection ? NSCorrectionBubbleTypeCorrection : NSCorrectionBubbleTypeReversion; + [[NSSpellChecker sharedSpellChecker] showCorrectionBubbleOfType:bubbleType primaryString:replacementStringAsNSString alternativeStrings:nil forStringInRect:boundingBoxAsNSRect view:m_webView completionHandler:^(NSString *acceptedString) { + if (!acceptedString && bubbleType == NSCorrectionBubbleTypeCorrection) { [[NSSpellChecker sharedSpellChecker] recordResponse:NSCorrectionResponseRejected toCorrection:replacementStringAsNSString forWord:replacedStringAsNSString language:nil inSpellDocumentWithTag:[m_webView spellCheckerDocumentTag]]; editor->handleRejectedCorrection(); + } else if (acceptedString && bubbleType == NSCorrectionBubbleTypeReversion) { + [[NSSpellChecker sharedSpellChecker] recordResponse:NSCorrectionResponseReverted toCorrection:replacedStringAsNSString forWord:replacementStringAsNSString language:nil inSpellDocumentWithTag:[m_webView spellCheckerDocumentTag]]; + editor->handleRejectedCorrection(); } }]; } -void WebEditorClient::dismissCorrectionPanel(bool correctionAccepted) +void WebEditorClient::dismissCorrectionPanel(WebCore::CorrectionWasRejectedOrNot correctionWasRejectedOrNot) { - if (m_correctionPanelTag != InvalidCorrectionPanelTag) { - [[NSSpellChecker sharedSpellChecker] dismissCorrection:m_correctionPanelTag acceptCorrection:correctionAccepted]; - m_correctionPanelTag = InvalidCorrectionPanelTag; + if (isShowingCorrectionPanel()) { + if (correctionWasRejectedOrNot == CorrectionWasRejected) + [[NSSpellChecker sharedSpellChecker] cancelCorrectionBubbleForView:m_webView]; + else + [[NSSpellChecker sharedSpellChecker] dismissCorrectionBubbleForView:m_webView]; + m_correctionPanelIsShown = NO; } } bool WebEditorClient::isShowingCorrectionPanel() { - return m_correctionPanelTag != InvalidCorrectionPanelTag; + return m_correctionPanelIsShown; } #endif diff --git a/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm b/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm index 3053b49..7ca27c0 100644 --- a/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm +++ b/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm @@ -1752,6 +1752,8 @@ PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& s [values addObject:[NSString stringWithFormat:@"%d", size.height()]]; } view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, names, values, baseURL, kit(element), NO); + if (view) + return adoptRef(new PluginWidget(view)); } #if ENABLE(NETSCAPE_PLUGIN_API) else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) { @@ -1764,6 +1766,8 @@ PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& s attributeValues:kit(paramValues) loadManually:NO element:element] autorelease]; + if (view) + return adoptRef(new NetscapePluginWidget(view)); } else { ASSERT_NOT_REACHED(); } @@ -1781,15 +1785,9 @@ PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& s } } - ASSERT(view); - return adoptRef(new PluginWidget(view)); - END_BLOCK_OBJC_EXCEPTIONS; - - return adoptRef(new PluginWidget); -#else - return 0; #endif // ENABLE(JAVA_BRIDGE) + return 0; } #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) diff --git a/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm b/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm index 9d8fd11..f95594a 100644 --- a/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm +++ b/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm @@ -660,7 +660,13 @@ String WebPlatformStrategies::unknownFileSizeText() String WebPlatformStrategies::imageTitle(const String& filename, const IntSize& size) { +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + NSString *widthString = [NSNumberFormatter localizedStringFromNumber:[NSNumber numberWithInt:size.width()] numberStyle:NSNumberFormatterDecimalStyle]; + NSString *heightString = [NSNumberFormatter localizedStringFromNumber:[NSNumber numberWithInt:size.height()] numberStyle:NSNumberFormatterDecimalStyle]; + return [NSString localizedStringWithFormat:UI_STRING("%@ %@×%@ pixels", "window title for a standalone image (uses multiplication symbol, not x)"), (NSString *)filename, widthString, heightString]; +#else return [NSString stringWithFormat:UI_STRING("%@ %d×%d pixels", "window title for a standalone image (uses multiplication symbol, not x)"), (NSString *)filename, size.width(), size.height()]; +#endif } String WebPlatformStrategies::mediaElementLoadingStateText() diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm index 4f8c1ba..fb6d69c 100644 --- a/WebKit/mac/WebView/WebFrame.mm +++ b/WebKit/mac/WebView/WebFrame.mm @@ -203,6 +203,8 @@ WebCore::EditingBehaviorType core(WebKitEditingBehavior behavior) return WebCore::EditingMacBehavior; case WebKitEditingWinBehavior: return WebCore::EditingWindowsBehavior; + case WebKitEditingUnixBehavior: + return WebCore::EditingUnixBehavior; } ASSERT_NOT_REACHED(); return WebCore::EditingMacBehavior; @@ -1134,12 +1136,8 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) Frame* frame = core(self); if (!frame) return; - - AnimationController* controller = frame->animation(); - if (!controller) - return; - - controller->suspendAnimations(frame->document()); + + frame->animation()->suspendAnimations(); } - (void) _resumeAnimations @@ -1148,11 +1146,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) if (!frame) return; - AnimationController* controller = frame->animation(); - if (!controller) - return; - - controller->resumeAnimations(frame->document()); + frame->animation()->resumeAnimations(); } - (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle @@ -1406,7 +1400,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader) Frame* coreFrame = _private->coreFrame; if (!coreFrame) return nil; - return coreFrame->tree()->name(); + return coreFrame->tree()->uniqueName(); } - (WebFrameView *)frameView diff --git a/WebKit/mac/WebView/WebPreferencesPrivate.h b/WebKit/mac/WebView/WebPreferencesPrivate.h index 2ec08e8..2ee07d7 100644 --- a/WebKit/mac/WebView/WebPreferencesPrivate.h +++ b/WebKit/mac/WebView/WebPreferencesPrivate.h @@ -45,7 +45,8 @@ typedef enum { typedef enum { WebKitEditingMacBehavior, - WebKitEditingWinBehavior + WebKitEditingWinBehavior, + WebKitEditingUnixBehavior } WebKitEditingBehavior; extern NSString *WebPreferencesChangedNotification; diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm index 7456898..49bb451 100644 --- a/WebKit/mac/WebView/WebView.mm +++ b/WebKit/mac/WebView/WebView.mm @@ -111,7 +111,7 @@ #import <WebCore/AbstractDatabase.h> #import <WebCore/ApplicationCacheStorage.h> #import <WebCore/BackForwardListImpl.h> -#import <WebCore/Cache.h> +#import <WebCore/MemoryCache.h> #import <WebCore/ColorMac.h> #import <WebCore/CSSComputedStyleDeclaration.h> #import <WebCore/Cursor.h> @@ -2611,9 +2611,9 @@ static PassOwnPtr<Vector<String> > toStringVector(NSArray* patterns) Frame* frame = core([self mainFrame]); if (suspended) - frame->animation()->suspendAnimations(frame->document()); + frame->animation()->suspendAnimations(); else - frame->animation()->resumeAnimations(frame->document()); + frame->animation()->resumeAnimations(); } + (void)_setDomainRelaxationForbidden:(BOOL)forbidden forURLScheme:(NSString *)scheme diff --git a/WebKit/qt/Api/qgraphicswebview.cpp b/WebKit/qt/Api/qgraphicswebview.cpp index df28626..f026827 100644 --- a/WebKit/qt/Api/qgraphicswebview.cpp +++ b/WebKit/qt/Api/qgraphicswebview.cpp @@ -140,6 +140,7 @@ void QGraphicsWebViewPrivate::updateResizesToContentsForPage() QObject::disconnect(page->mainFrame(), SIGNAL(contentsSizeChanged(QSize)), q, SLOT(_q_contentsSizeChanged(const QSize&))); } + page->d->page->settings()->setShouldDelegateScrolling(resizesToContents); } void QGraphicsWebViewPrivate::_q_contentsSizeChanged(const QSize& size) @@ -411,6 +412,8 @@ void QGraphicsWebViewPrivate::detachCurrentPage() if (!page) return; + page->d->page->settings()->setShouldDelegateScrolling(false); + page->d->view.clear(); // The client has always to be deleted. diff --git a/WebKit/qt/Api/qwebelement.cpp b/WebKit/qt/Api/qwebelement.cpp index 68fa17a..8121111 100644 --- a/WebKit/qt/Api/qwebelement.cpp +++ b/WebKit/qt/Api/qwebelement.cpp @@ -311,6 +311,11 @@ void QWebElement::setOuterXml(const QString &markup) \note This is currently implemented for (X)HTML elements only. + \note The format of the markup returned will obey the namespace of the + document containing the element. This means the return value will obey XML + formatting rules, such as self-closing tags, only if the document is + 'text/xhtml+xml'. + \sa setOuterXml(), setInnerXml(), toInnerXml() */ QString QWebElement::toOuterXml() const @@ -345,6 +350,11 @@ void QWebElement::setInnerXml(const QString &markup) \note This is currently implemented for (X)HTML elements only. + \note The format of the markup returned will obey the namespace of the + document containing the element. This means the return value will obey XML + formatting rules, such as self-closing tags, only if the document is + 'text/xhtml+xml'. + \sa setInnerXml(), setOuterXml(), toOuterXml() */ QString QWebElement::toInnerXml() const diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp index 39e74d9..7d423d5 100644 --- a/WebKit/qt/Api/qwebframe.cpp +++ b/WebKit/qt/Api/qwebframe.cpp @@ -97,6 +97,7 @@ #include "runtime_root.h" #endif #if USE(TEXTURE_MAPPER) +#include "texmap/TextureMapper.h" #include "texmap/TextureMapperPlatformLayer.h" #endif #include "wtf/HashMap.h" @@ -294,19 +295,38 @@ void QWebFramePrivate::renderFromTiledBackingStore(GraphicsContext* context, con painter->restore(); } -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) - // TextureMapper might use raw OpenGL or some other backend that requires native painting. On raster this doesn't have any effect. - if (rootGraphicsLayer) { - painter->beginNativePainting(); - rootGraphicsLayer->paint(context, view->size(), view->frameRect(), IntRect(clip.boundingRect()), TransformationMatrix(), painter->opacity()); - painter->endNativePainting(); - } +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) + renderCompositedLayers(context, IntRect(clip.boundingRect())); renderRelativeCoords(context, (QWebFrame::RenderLayer)(QWebFrame::ScrollBarLayer | QWebFrame::PanIconLayer), clip); #endif } #endif +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +void QWebFramePrivate::renderCompositedLayers(GraphicsContext* context, const IntRect& clip) +{ + if (!rootGraphicsLayer) + return; + + textureMapper->setGraphicsContext(context); + textureMapper->setImageInterpolationQuality(context->imageInterpolationQuality()); + textureMapper->setTextDrawingMode(context->textDrawingMode()); + QPainter* painter = context->platformContext(); + FrameView* view = frame->view(); + painter->save(); + painter->beginNativePainting(); + TextureMapperContentLayer::PaintOptions options; + options.visibleRect = clip; + options.targetRect = view->frameRect(); + options.viewportSize = view->size(); + options.opacity = painter->opacity(); + rootGraphicsLayer->paint(textureMapper.get(), options); + painter->endNativePainting(); + painter->restore(); +} +#endif + void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QWebFrame::RenderLayer layer, const QRegion& clip) { if (!frame->view() || !frame->contentRenderer()) @@ -349,16 +369,8 @@ void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QWebFrame: context->restore(); } painter->restore(); - #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) - if (rootGraphicsLayer) { - painter->save(); - painter->beginNativePainting(); - rootGraphicsLayer->paint(context, view->size(), view->frameRect(), IntRect(clip.boundingRect()), - TransformationMatrix(), context->platformContext()->opacity()); - painter->endNativePainting(); - painter->restore(); - } + renderCompositedLayers(context, IntRect(clip.boundingRect())); #endif } if (layer & (QWebFrame::PanIconLayer | QWebFrame::ScrollBarLayer)) { @@ -758,7 +770,7 @@ QIcon QWebFrame::icon() const */ QString QWebFrame::frameName() const { - return d->frame->tree()->name(); + return d->frame->tree()->uniqueName(); } /*! diff --git a/WebKit/qt/Api/qwebframe_p.h b/WebKit/qt/Api/qwebframe_p.h index 5660bd1..7c0d235 100644 --- a/WebKit/qt/Api/qwebframe_p.h +++ b/WebKit/qt/Api/qwebframe_p.h @@ -33,6 +33,10 @@ #include "Frame.h" #include "ViewportArguments.h" +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +#include "texmap/TextureMapper.h" +#endif + namespace WebCore { class FrameLoaderClientQt; class FrameView; @@ -94,6 +98,9 @@ public: void renderFromTiledBackingStore(WebCore::GraphicsContext*, const QRegion& clip); #endif +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) + void renderCompositedLayers(WebCore::GraphicsContext* context, const WebCore::IntRect& clip); +#endif QWebFrame *q; Qt::ScrollBarPolicy horizontalScrollBarPolicy; Qt::ScrollBarPolicy verticalScrollBarPolicy; @@ -106,6 +113,7 @@ public: int marginHeight; #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) WebCore::TextureMapperContentLayer* rootGraphicsLayer; + OwnPtr<WebCore::TextureMapper> textureMapper; #endif bool zoomTextOnly; }; diff --git a/WebKit/qt/Api/qwebkitplatformplugin.h b/WebKit/qt/Api/qwebkitplatformplugin.h index a851d56..2ceaac1 100644 --- a/WebKit/qt/Api/qwebkitplatformplugin.h +++ b/WebKit/qt/Api/qwebkitplatformplugin.h @@ -102,6 +102,19 @@ public: virtual void playHapticFeedback(const HapticEvent, const QString& hapticType, const HapticStrength) = 0; }; +class QWebTouchModifier : public QObject +{ + Q_OBJECT +public: + virtual ~QWebTouchModifier() {} + + enum PaddingDirection { + Up, Right, Down, Left + }; + + virtual unsigned hitTestPaddingForTouch(const PaddingDirection) const = 0; +}; + class QWebKitPlatformPlugin { public: @@ -110,13 +123,14 @@ public: enum Extension { MultipleSelections, Notifications, - Haptics + Haptics, + TouchInteraction }; virtual bool supportsExtension(Extension extension) const = 0; virtual QObject* createExtension(Extension extension) const = 0; }; -Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.5"); +Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.6"); #endif // QWEBKITPLATFORMPLUGIN_H diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp index 40f41c5..a6ca65a 100644 --- a/WebKit/qt/Api/qwebpage.cpp +++ b/WebKit/qt/Api/qwebpage.cpp @@ -31,13 +31,17 @@ #include "qwebinspector.h" #include "qwebinspector_p.h" #include "qwebsettings.h" +#include "qwebkitplatformplugin.h" #include "qwebkitversion.h" +#include "CSSComputedStyleDeclaration.h" +#include "CSSParser.h" #include "ApplicationCacheStorage.h" #include "BackForwardListImpl.h" -#include "Cache.h" +#include "MemoryCache.h" #include "Chrome.h" #include "ChromeClientQt.h" +#include "ClientRect.h" #include "ContextMenu.h" #include "ContextMenuClientQt.h" #include "ContextMenuController.h" @@ -60,6 +64,7 @@ #include "FrameView.h" #include "GeolocationPermissionClientQt.h" #include "HTMLFormElement.h" +#include "HTMLFrameOwnerElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" #include "HashMap.h" @@ -74,7 +79,9 @@ #include "MIMETypeRegistry.h" #include "NavigationAction.h" #include "NetworkingContext.h" +#include "NodeList.h" #include "NotificationPresenterClientQt.h" +#include "NotImplemented.h" #include "Page.h" #include "PageClientQt.h" #include "PageGroup.h" @@ -86,6 +93,7 @@ #include "PluginDatabase.h" #include "PluginPackage.h" #include "ProgressTracker.h" +#include "QtPlatformPlugin.h" #include "RefPtr.h" #include "RenderTextControl.h" #include "SchemeRegistry.h" @@ -657,6 +665,7 @@ void QWebPagePrivate::mousePressEvent(T* ev) } bool accepted = false; + adjustPointForClicking(ev); PlatformMouseEvent mev(ev, 1); // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton if (mev.button() != NoButton) @@ -736,6 +745,7 @@ void QWebPagePrivate::mouseReleaseEvent(T *ev) return; bool accepted = false; + adjustPointForClicking(ev); PlatformMouseEvent mev(ev, 0); // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton if (mev.button() != NoButton) @@ -1024,9 +1034,9 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) return; } - RenderObject* renderer = 0; + Node* node = 0; if (frame->selection()->rootEditableElement()) - renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); + node = frame->selection()->rootEditableElement()->shadowAncestorNode(); Vector<CompositionUnderline> underlines; bool hasSelection = false; @@ -1054,8 +1064,8 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) case QInputMethodEvent::Selection: { hasSelection = true; // A selection in the inputMethodEvent is always reflected in the visible text - if (renderer && renderer->node()) - setSelectionRange(renderer->node(), qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length))); + if (node) + setSelectionRange(node, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length))); if (!ev->preeditString().isEmpty()) { editor->setComposition(ev->preeditString(), underlines, @@ -1263,6 +1273,42 @@ bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame) return frame->eventHandler()->scrollRecursively(direction, granularity); } +void QWebPagePrivate::adjustPointForClicking(QMouseEvent*) +{ + notImplemented(); +} + +void QWebPagePrivate::adjustPointForClicking(QGraphicsSceneMouseEvent* ev) +{ + QtPlatformPlugin platformPlugin; + QWebTouchModifier* touchModifier = platformPlugin.createTouchModifier(); + if (!touchModifier) + return; + + unsigned topPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Up); + unsigned rightPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Right); + unsigned bottomPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Down); + unsigned leftPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Left); + + delete touchModifier; + touchModifier = 0; + + if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) + return; + + Document* startingDocument = page->mainFrame()->document(); + if (!startingDocument) + return; + + IntPoint originalPoint(QPointF(ev->pos()).toPoint()); + TouchAdjuster touchAdjuster(topPadding, rightPadding, bottomPadding, leftPadding); + IntPoint adjustedPoint = touchAdjuster.findCandidatePointForTouch(originalPoint, startingDocument); + if (adjustedPoint == IntPoint::zero()) + return; + + ev->setPos(QPointF(adjustedPoint)); +} + bool QWebPagePrivate::touchEvent(QTouchEvent* event) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); @@ -1319,14 +1365,11 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const return QVariant(QFont()); } case Qt::ImCursorPosition: { - if (renderTextControl) { - if (editor->hasComposition()) { - RefPtr<Range> range = editor->compositionRange(); - return QVariant(renderTextControl->selectionEnd() - TextIterator::rangeLength(range.get())); - } - return QVariant(frame->selection()->extent().offsetInContainerNode()); + if (editor->hasComposition()) { + RefPtr<Range> range = editor->compositionRange(); + return QVariant(frame->selection()->end().offsetInContainerNode() - TextIterator::rangeLength(range.get())); } - return QVariant(); + return QVariant(frame->selection()->extent().offsetInContainerNode()); } case Qt::ImSurroundingText: { if (renderTextControl) { @@ -1340,23 +1383,20 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const } case Qt::ImCurrentSelection: { if (renderTextControl) { - int start = renderTextControl->selectionStart(); - int end = renderTextControl->selectionEnd(); + int start = frame->selection()->start().offsetInContainerNode(); + int end = frame->selection()->end().offsetInContainerNode(); if (end > start) - return QVariant(QString(renderTextControl->text()).mid(start,end-start)); + return QVariant(QString(renderTextControl->text()).mid(start, end - start)); } return QVariant(); } case Qt::ImAnchorPosition: { - if (renderTextControl) { - if (editor->hasComposition()) { - RefPtr<Range> range = editor->compositionRange(); - return QVariant(renderTextControl->selectionStart() - TextIterator::rangeLength(range.get())); - } - return QVariant(frame->selection()->base().offsetInContainerNode()); + if (editor->hasComposition()) { + RefPtr<Range> range = editor->compositionRange(); + return QVariant(frame->selection()->start().offsetInContainerNode() - TextIterator::rangeLength(range.get())); } - return QVariant(); + return QVariant(frame->selection()->base().offsetInContainerNode()); } case Qt::ImMaximumTextLength: { if (frame->selection()->isContentEditable()) { @@ -1435,6 +1475,124 @@ quint16 QWebPagePrivate::inspectorServerPort() return 0; } +static bool hasMouseListener(Element* element) +{ + ASSERT(element); + return element->hasEventListeners(eventNames().clickEvent) + || element->hasEventListeners(eventNames().mousedownEvent) + || element->hasEventListeners(eventNames().mouseupEvent); +} + +static bool isClickableElement(Element* element, RefPtr<NodeList> list) +{ + ASSERT(element); + bool isClickable = hasMouseListener(element); + if (!isClickable && list) { + Element* parent = element->parentElement(); + unsigned count = list->length(); + for (unsigned i = 0; i < count && parent; i++) { + if (list->item(i) != parent) + continue; + + isClickable = hasMouseListener(parent); + if (isClickable) + break; + + parent = parent->parentElement(); + } + } + + ExceptionCode ec = 0; + return isClickable + || element->webkitMatchesSelector("a,*:link,*:visited,*[role=button],button,input,select,label", ec) + || computedStyle(element)->getPropertyValue(cssPropertyID("cursor")) == "pointer"; +} + +static bool isValidFrameOwner(Element* element) +{ + ASSERT(element); + return element->isFrameOwnerElement() && static_cast<HTMLFrameOwnerElement*>(element)->contentFrame(); +} + +static Element* nodeToElement(Node* node) +{ + if (node && node->isElementNode()) + return static_cast<Element*>(node); + return 0; +} + +QWebPagePrivate::TouchAdjuster::TouchAdjuster(unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding) + : m_topPadding(topPadding) + , m_rightPadding(rightPadding) + , m_bottomPadding(bottomPadding) + , m_leftPadding(leftPadding) +{ +} + +IntPoint QWebPagePrivate::TouchAdjuster::findCandidatePointForTouch(const IntPoint& touchPoint, Document* document) const +{ + if (!document) + return IntPoint(); + + int x = touchPoint.x(); + int y = touchPoint.y(); + + RefPtr<NodeList> intersectedNodes = document->nodesFromRect(x, y, m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding, false); + if (!intersectedNodes) + return IntPoint(); + + Element* closestClickableElement = 0; + IntRect largestIntersectionRect; + FrameView* view = document->frame()->view(); + + // Touch rect in contents coordinates. + IntRect touchRect(HitTestResult::rectForPoint(view->windowToContents(IntPoint(x, y)), m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding)); + + // Iterate over the list of nodes hit looking for the one whose bounding area + // has largest intersection with the touch area (point + padding). + for (unsigned i = 0; i < intersectedNodes->length(); i++) { + Node* currentNode = intersectedNodes->item(i); + + Element* currentElement = nodeToElement(currentNode); + if (!currentElement || (!isClickableElement(currentElement, 0) && !isValidFrameOwner(currentElement))) + continue; + + IntRect currentElementBoundingRect = currentElement->getRect(); + currentElementBoundingRect.intersect(touchRect); + + if (currentElementBoundingRect.isEmpty()) + continue; + + int currentIntersectionRectArea = currentElementBoundingRect.width() * currentElementBoundingRect.height(); + int largestIntersectionRectArea = largestIntersectionRect.width() * largestIntersectionRect.height(); + if (currentIntersectionRectArea > largestIntersectionRectArea) { + closestClickableElement = currentElement; + largestIntersectionRect = currentElementBoundingRect; + } + } + + if (largestIntersectionRect.isEmpty()) + return IntPoint(); + + // Handle the case when user taps a inner frame. It is done in three steps: + // 1) Transform the original touch point to the inner document coordinates; + // 1) Call nodesFromRect for the inner document in case; + // 3) Re-add the inner frame offset (location) before passing the new clicking + // position to WebCore. + if (closestClickableElement->isFrameOwnerElement()) { + // Adjust client coordinates' origin to be top left of inner frame viewport. + PassRefPtr<ClientRect> rect = closestClickableElement->getBoundingClientRect(); + IntPoint newTouchPoint = touchPoint; + IntSize offset = IntSize(rect->left(), rect->top()); + newTouchPoint -= offset; + + HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(closestClickableElement); + Document* childDocument = owner->contentFrame()->document(); + return findCandidatePointForTouch(newTouchPoint, childDocument); + } + return view->contentsToWindow(largestIntersectionRect).center(); +} + /*! \enum QWebPage::FindFlag @@ -2424,7 +2582,10 @@ bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest & QString QWebPage::selectedText() const { d->createMainFrame(); - return d->page->focusController()->focusedOrMainFrame()->editor()->selectedText(); + WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame(); + if (frame->selection()->selection().selectionType() == VisibleSelection::NoSelection) + return QString(); + return frame->editor()->selectedText(); } #ifndef QT_NO_ACTION diff --git a/WebKit/qt/Api/qwebpage_p.h b/WebKit/qt/Api/qwebpage_p.h index 1f70293..1b9cd66 100644 --- a/WebKit/qt/Api/qwebpage_p.h +++ b/WebKit/qt/Api/qwebpage_p.h @@ -31,6 +31,7 @@ #include "qwebhistory.h" #include "qwebframe.h" +#include "IntPoint.h" #include "KURL.h" #include "PlatformString.h" @@ -43,10 +44,13 @@ namespace WebCore { class ContextMenuClientQt; class ContextMenuItem; class ContextMenu; + class Document; class EditorClientQt; class Element; class InspectorController; + class IntRect; class Node; + class NodeList; class Page; class Frame; } @@ -126,6 +130,22 @@ public: // Returns whether the default action was cancelled in the JS event handler bool touchEvent(QTouchEvent*); + class TouchAdjuster { + public: + TouchAdjuster(unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding); + + WebCore::IntPoint findCandidatePointForTouch(const WebCore::IntPoint&, WebCore::Document*) const; + + private: + unsigned m_topPadding; + unsigned m_rightPadding; + unsigned m_bottomPadding; + unsigned m_leftPadding; + }; + + void adjustPointForClicking(QMouseEvent*); + void adjustPointForClicking(QGraphicsSceneMouseEvent*); + void setInspector(QWebInspector*); QWebInspector* getOrCreateInspector(); WebCore::InspectorController* inspectorController(); diff --git a/WebKit/qt/Api/qwebsettings.cpp b/WebKit/qt/Api/qwebsettings.cpp index 3cd36f2..ed425c2 100644 --- a/WebKit/qt/Api/qwebsettings.cpp +++ b/WebKit/qt/Api/qwebsettings.cpp @@ -25,7 +25,7 @@ #include "qwebplugindatabase_p.h" #include "AbstractDatabase.h" -#include "Cache.h" +#include "MemoryCache.h" #include "CrossOriginPreflightResultCache.h" #include "FontCache.h" #include "Page.h" diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog index 98d6d45..fdfa41f 100644 --- a/WebKit/qt/ChangeLog +++ b/WebKit/qt/ChangeLog @@ -1,3 +1,313 @@ +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::focusedNodeChanged): Removed unneeded namespace prefix. + (WebCore::ChromeClientQt::focusedFrameChanged): + * WebCoreSupport/ChromeClientQt.h: + +2010-11-08 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Texmap] [Qt] Texture mapper initial implementation + https://bugs.webkit.org/show_bug.cgi?id=47070 + + Reorganized the textureMapper to be a member of QWebFramePrivate, to help with making + TextureMapper thread-safe. + + * Api/qwebframe.cpp: + (QWebFramePrivate::renderCompositedLayers): + * Api/qwebframe_p.h: + * WebCoreSupport/PageClientQt.cpp: + (WebCore::PlatformLayerProxyQt::setTextureMapper): + (WebCore::PlatformLayerProxyQt::textureMapper): + (WebCore::PlatformLayerProxyQWidget::PlatformLayerProxyQWidget): + (WebCore::PlatformLayerProxyQGraphicsObject::PlatformLayerProxyQGraphicsObject): + +2010-11-07 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Rename Cache to MemoryCache + https://bugs.webkit.org/show_bug.cgi?id=49159 + + * Api/qwebpage.cpp: + * Api/qwebsettings.cpp: + +2010-11-07 Chang Shu <chang.shu@nokia.com> + + Reviewed by Antonio Gomes. + + Add a helper function to avoid duplicated code. + https://bugs.webkit.org/show_bug.cgi?id=49085 + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::handleKeyboardEvent): + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Move resumeAnimations/suspendAnimations from Frame to AnimationController. + https://bugs.webkit.org/show_bug.cgi?id=49073 + + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::suspendAnimations): + (DumpRenderTreeSupportQt::resumeAnimations): + +2010-11-03 Antonio Gomes <tonikitoo@webkit.org>, Andre Pedralho <andre.pedralho@gmail.com> + + Reviewed by Kenneth Rohde Christiansen and Antti Koivisto. + + [Qt] Making effective use of nodesFromRect. + https://bugs.webkit.org/show_bug.cgi?id=44089 + + Patch adds a helper class (named TouchAdjuster) to improve tap actions + on mobile touch devices. TouchAdjuster makes use of the newly added rect + based hit test extension through the Document::nodesFromRect method. + Given a rectangle as input, nodesFromRect returns a z-index ordered list + of nodes whose boundaries intersect the rectangle. + + Basically the TouchAdjuster class intercepts the QGraphicsSceneMouseEvent + passed to both QWebPagePrivate::mouse{Press,Release}Event methods before + they are passed down to WebCore. The goal is to infer the target click position. + For that, a rectangle is built up using the event position as a center point and + expanding it based on the values and directions set in the Platform Plugin + QWebTouchModifier::hitTestPadding. + + TouchAdjuster iterates over the list of nodes returned by nodesFromRect and + picks the clickable one that has the largest intersection area with the hit + test rectangle. The target position is then the center point of this intersection + area. + + In case of no clickable node intersects the hit test area, the click position + is not altered. + + TouchAdjuster is *only* working for QGraphicsWebView based views. + + * Api/qwebpage.cpp: + (QWebPagePrivate::mousePressEvent): + (QWebPagePrivate::mouseReleaseEvent): + (QWebPagePrivate::adjustPointForClicking): + (QWebPagePrivate::TouchAdjuster::TouchAdjuster): + (QWebPagePrivate::TouchAdjuster::findCandidatePointForTouch): + (isClickableElement): + (hasMouseListener): + (isValidFrameOwner): + (nodeToElement): + * Api/qwebpage_p.h: + +2010-10-20 Chang Shu <chang.shu@nokia.com>, Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Fraser. + + [Qt] Makes <input type=text> and <textarea> functional with + Spatial Navigation enabled. Before this patch, the focus cannot + move away from input box once it is in. This patch allows focus + move to neighbor nodes when the caret reaches the edge of the texts. + This patch does not support yet cases where the focused <input> + has a JS handler for the arrow keys. + https://bugs.webkit.org/show_bug.cgi?id=37153 + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::handleKeyboardEvent): + +2010-11-04 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by David Hyatt. + + Delegate scrolling via a separate method + https://bugs.webkit.org/show_bug.cgi?id=48988 + + Implement delegatedScrollRequested and make it emit the + scrollRequested signal for Qt. + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::delegatedScrollRequested): + * WebCoreSupport/ChromeClientQt.h: + +2010-11-04 Robert Hogan <robert@webkit.org> + + Reviewed by Andreas Kling. + + [Qt] Clarify expected return values of innerXml(), outerXml() + + If you put HTML in (e.g. using setHTML()) you will get HTML out, + even if you marked it up as XML. + + https://bugs.webkit.org/show_bug.cgi?id=44876 + + * Api/qwebelement.cpp: + +2010-11-03 Andre Pedralho <andre.pedralho@gmail.com> + + Reviewed by Kenneth Rohde Christiansen. + + Using the Platform Plugin to define the default values for the padding of HitTestResult. + https://bugs.webkit.org/show_bug.cgi?id=48450 + + * Api/qwebkitplatformplugin.h: + (QWebTouchModifier::~QWebTouchModifier): + * WebCoreSupport/QtPlatformPlugin.cpp: + (WebCore::QtPlatformPlugin::createTouchModifier): + * WebCoreSupport/QtPlatformPlugin.h: + * examples/platformplugin/WebPlugin.cpp: + (WebPlugin::supportsExtension): + (WebPlugin::createExtension): + * examples/platformplugin/WebPlugin.h: + (TouchModifier::hitTestPaddingForTouch): + * examples/platformplugin/qwebkitplatformplugin.h: + (QWebTouchModifier::~QWebTouchModifier): + +2010-11-03 Andreas Kling <kling@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QGWV: Keep the scrolling delegation intact when switching pages + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::updateResizesToContentsForPage): Turn on/off + scrolling delegation depending on the resizeToContents mode. + (QGraphicsWebViewPrivate::detachCurrentPage): Turn off scrolling delegation. + (QGraphicsWebView::setResizesToContents): + +2010-11-03 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Andreas Kling. + + Make it possible to delegate scrolling to the UI + https://bugs.webkit.org/show_bug.cgi?id=48907 + + Enable scrolling delegation when setResizesToContents is active. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::setResizesToContents): + +2010-11-03 Daniel Bates <dbates@rim.com> + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 1 of 2. + + Substitute FrameTree::uniqueName() for FrameTree::name() in the Qt port. + + * Api/qwebframe.cpp: + (QWebFrame::frameName): + +2010-11-02 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Some refactor for texmap to enable WebKit2: remove globals, and allow TextureMapper to exist without a GraphicsContext. + This will allow rendering the TextureMapperNode tree without an active QPainter, into the current GL context. + Most of the changes simply move the globas in TextureMapperGL into members of that class. + + [Texmap] [Qt] Texture mapper initial implementation + https://bugs.webkit.org/show_bug.cgi?id=47070 + + * Api/qwebframe.cpp: + (QWebFramePrivate::renderFromTiledBackingStore): + (QWebFramePrivate::renderCompositedLayers): + (QWebFramePrivate::renderRelativeCoords): + * Api/qwebframe_p.h: + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * WebCoreSupport/ChromeClientQt.h: + (WebCore::ChromeClientQt::showContextMenu): + +2010-10-31 Robert Hogan <robert@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] Support nodesFromRect in DRT + + https://bugs.webkit.org/show_bug.cgi?id=48716 + + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::nodesFromRect): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + +2010-10-31 Andreas Kling <kling@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Short-circuit QWebPage::selectedText() if frame has no selection + https://bugs.webkit.org/show_bug.cgi?id=48736 + + Do an early return if the selection is empty. + + No new tests, this is covered by tst_QWebPage::findText(). + + * Api/qwebpage.cpp: + (QWebPage::selectedText): + +2010-10-30 Andreas Kling <kling@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] IM: Don't manipulate selection via RenderTextControl + https://bugs.webkit.org/show_bug.cgi?id=48700 + + Go directly through the Frame's SelectionController instead. + + No new tests, this is covered by tst_QWebPage::inputMethods. + + * Api/qwebpage.cpp: + (QWebPagePrivate::inputMethodEvent): + (QWebPage::inputMethodQuery): + +2010-10-29 Daniel Bates <dbates@rim.com> + + No review, rolling out 70971. + http://trac.webkit.org/changeset/70971 + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Rolling out changeset 70971 <http://trac.webkit.org/changeset/70971> since + it caused layout test failures on all bots. In particular, the + child count in a generated frame name differs after this patch. We need + to look into this further. + + * Api/qwebframe.cpp: + (QWebFrame::frameName): + +2010-10-28 Antonio Gomes <agomes@rim.com> + + Reviewed by Ojan Vafai. + + Needs a "LinuxEditingBehavior", perhaps with a better name + https://bugs.webkit.org/show_bug.cgi?id=36627 + + Adding support to Qt's DRTSupport class to test the newly introduced Unix editing behavior. + + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::setEditingBehavior): + +2010-10-29 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Modified Qt-port to use FrameTree::uniqueName(). + + * Api/qwebframe.cpp: + (QWebFrame::frameName): + 2010-10-29 Andreas Kling <kling@webkit.org> Reviewed by Ariya Hidayat. diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index f0d3903..3fec1d3 100644 --- a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -165,10 +165,13 @@ void ChromeClientQt::takeFocus(FocusDirection) } -void ChromeClientQt::focusedNodeChanged(WebCore::Node*) +void ChromeClientQt::focusedNodeChanged(Node*) { } +void ChromeClientQt::focusedFrameChanged(Frame*) +{ +} Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&) { @@ -412,6 +415,13 @@ void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect); } +#if ENABLE(TILED_BACKING_STORE) +void ChromeClientQt::delegatedScrollRequested(const IntSize& delta) +{ + emit m_webPage->scrollRequested(delta.width(), delta.height(), QRect(QPoint(0, 0), m_webPage->viewportSize())); +} +#endif + IntRect ChromeClientQt::windowToScreen(const IntRect& rect) const { QWebPageClient* pageClient = platformPageClient(); diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.h b/WebKit/qt/WebCoreSupport/ChromeClientQt.h index bbd2452..b8bc72d 100644 --- a/WebKit/qt/WebCoreSupport/ChromeClientQt.h +++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.h @@ -72,6 +72,7 @@ namespace WebCore { virtual void takeFocus(FocusDirection); virtual void focusedNodeChanged(Node*); + virtual void focusedFrameChanged(Frame*); virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&); virtual void show(); @@ -115,6 +116,9 @@ namespace WebCore { virtual void invalidateContentsAndWindow(const IntRect&, bool); virtual void invalidateContentsForSlowScroll(const IntRect&, bool); virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); +#if ENABLE(TILED_BACKING_STORE) + virtual void delegatedScrollRequested(const IntSize& scrollDelta); +#endif virtual IntPoint screenToWindow(const IntPoint&) const; virtual IntRect windowToScreen(const IntRect&) const; @@ -134,6 +138,9 @@ namespace WebCore { virtual void reachedMaxAppCacheSize(int64_t spaceNeeded); virtual void reachedApplicationCacheOriginQuota(SecurityOrigin*); #endif +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif #if ENABLE(NOTIFICATIONS) virtual NotificationPresenter* notificationPresenter() const; diff --git a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp index 4309e5c..f5fa06b 100644 --- a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp +++ b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp @@ -47,6 +47,7 @@ #include "HistoryItem.h" #include "HTMLInputElement.h" #include "InspectorController.h" +#include "NodeList.h" #include "NotificationPresenterClientQt.h" #include "Page.h" #include "PageGroup.h" @@ -278,7 +279,7 @@ void DumpRenderTreeSupportQt::suspendAnimations(QWebFrame *frame) if (!controller) return; - controller->suspendAnimations(coreFrame->document()); + controller->suspendAnimations(); } void DumpRenderTreeSupportQt::resumeAnimations(QWebFrame *frame) @@ -291,7 +292,7 @@ void DumpRenderTreeSupportQt::resumeAnimations(QWebFrame *frame) if (!controller) return; - controller->resumeAnimations(coreFrame->document()); + controller->resumeAnimations(); } void DumpRenderTreeSupportQt::clearFrameName(QWebFrame* frame) @@ -544,6 +545,8 @@ void DumpRenderTreeSupportQt::setEditingBehavior(QWebPage* page, const QString& coreEditingBehavior = EditingWindowsBehavior; else if (editingBehavior == "mac") coreEditingBehavior = EditingMacBehavior; + else if (editingBehavior == "unix") + coreEditingBehavior = EditingUnixBehavior; else { ASSERT_NOT_REACHED(); return; @@ -778,6 +781,26 @@ QString DumpRenderTreeSupportQt::plainText(const QVariant& range) return map.value("innerText").toString(); } +QVariantList DumpRenderTreeSupportQt::nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping) +{ + QVariantList res; + WebCore::Element* webElement = document.m_element; + if (!webElement) + return res; + + Document* doc = webElement->document(); + if (!doc) + return res; + RefPtr<NodeList> nodes = doc->nodesFromRect(x, y, top, right, bottom, left, ignoreClipping); + for (int i = 0; i < nodes->length(); i++) { + QVariant v; + // QWebElement will be null if the Node is not an HTML Element + v.setValue(QWebElement(nodes->item(i))); + res << v; + } + return res; +} + // Provide a backward compatibility with previously exported private symbols as of QtWebKit 4.6 release void QWEBKIT_EXPORT qt_resumeActiveDOMObjects(QWebFrame* frame) diff --git a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h index 356b226..82d9319 100644 --- a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h +++ b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h @@ -133,6 +133,8 @@ public: static void addUserStyleSheet(QWebPage* page, const QString& sourceCode); static void simulateDesktopNotificationClick(const QString& title); static QString viewportAsText(QWebPage*, const QSize&); + + static QVariantList nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping); }; #endif diff --git a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp index 2dd3b37..91a0cc6 100644 --- a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp @@ -46,6 +46,7 @@ #include "PlatformKeyboardEvent.h" #include "QWebPageClient.h" #include "Range.h" +#include "Settings.h" #include "WindowsKeyboardCodes.h" #include "qwebpage.h" #include "qwebpage_p.h" @@ -360,9 +361,21 @@ void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event) // FIXME: refactor all of this to use Actions or something like them if (start->isContentEditable()) { + bool doSpatialNavigation = false; + if (isSpatialNavigationEnabled(frame)) { + if (!kevent->modifiers()) { + switch (kevent->windowsVirtualKeyCode()) { + case VK_LEFT: + case VK_RIGHT: + case VK_UP: + case VK_DOWN: + doSpatialNavigation = true; + } + } + } #ifndef QT_NO_SHORTCUT QWebPage::WebAction action = QWebPagePrivate::editorActionForKeyEvent(kevent->qtEvent()); - if (action != QWebPage::NoWebAction) { + if (action != QWebPage::NoWebAction && !doSpatialNavigation) { const char* cmd = QWebPagePrivate::editorCommandForWebActions(action); // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated, // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated @@ -386,26 +399,26 @@ void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event) case VK_LEFT: if (kevent->shiftKey()) frame->editor()->command("MoveLeftAndModifySelection").execute(); - else - frame->editor()->command("MoveLeft").execute(); + else if (!frame->editor()->command("MoveLeft").execute()) + return; break; case VK_RIGHT: if (kevent->shiftKey()) frame->editor()->command("MoveRightAndModifySelection").execute(); - else - frame->editor()->command("MoveRight").execute(); + else if (!frame->editor()->command("MoveRight").execute()) + return; break; case VK_UP: if (kevent->shiftKey()) frame->editor()->command("MoveUpAndModifySelection").execute(); - else - frame->editor()->command("MoveUp").execute(); + else if (!frame->editor()->command("MoveUp").execute()) + return; break; case VK_DOWN: if (kevent->shiftKey()) frame->editor()->command("MoveDownAndModifySelection").execute(); - else - frame->editor()->command("MoveDown").execute(); + else if (!frame->editor()->command("MoveDown").execute()) + return; break; case VK_PRIOR: // PageUp if (kevent->shiftKey()) diff --git a/WebKit/qt/WebCoreSupport/PageClientQt.cpp b/WebKit/qt/WebCoreSupport/PageClientQt.cpp index 4d42c39..9fa5bf7 100644 --- a/WebKit/qt/WebCoreSupport/PageClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/PageClientQt.cpp @@ -21,15 +21,19 @@ #include "config.h" #include "PageClientQt.h" +#include "TextureMapperQt.h" #include "texmap/TextureMapperPlatformLayer.h" - +#include <QGraphicsScene> +#include <QGraphicsView> #if defined(Q_WS_X11) #include <QX11Info> #endif #ifdef QT_OPENGL_LIB +#include "opengl/TextureMapperGL.h" #include <QGLWidget> #endif + namespace WebCore { #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) @@ -45,6 +49,11 @@ public: m_frame->d->rootGraphicsLayer = m_layer; } + void setTextureMapper(PassOwnPtr<TextureMapper> textureMapper) + { + m_frame->d->textureMapper = textureMapper; + } + virtual ~PlatformLayerProxyQt() { if (m_layer) @@ -53,6 +62,11 @@ public: m_frame->d->rootGraphicsLayer = 0; } + virtual TextureMapper* textureMapper() + { + return m_frame->d->textureMapper.get(); + } + // Since we just paint the composited tree and never create a special item for it, we don't have to handle its size changes. void setSizeChanged(const IntSize&) { } @@ -69,6 +83,11 @@ public: { if (m_widget) m_widget->installEventFilter(this); + + if (textureMapper()) + return; + + setTextureMapper(TextureMapperQt::create()); } // We don't want a huge region-clip on the compositing layers; instead we unite the rectangles together @@ -103,6 +122,17 @@ public: : PlatformLayerProxyQt(frame, layer, object) , m_graphicsItem(object) { + if (textureMapper()) + return; + +#ifdef QT_OPENGL_LIB + QGraphicsView* view = object->scene()->views()[0]; + if (view && view->viewport() && view->viewport()->inherits("QGLWidget")) { + setTextureMapper(TextureMapperGL::create()); + return; + } +#endif + setTextureMapper(TextureMapperQt::create()); } void setNeedsDisplay() diff --git a/WebKit/qt/WebCoreSupport/QtPlatformPlugin.cpp b/WebKit/qt/WebCoreSupport/QtPlatformPlugin.cpp index 9786967..ede8a73 100644 --- a/WebKit/qt/WebCoreSupport/QtPlatformPlugin.cpp +++ b/WebKit/qt/WebCoreSupport/QtPlatformPlugin.cpp @@ -107,4 +107,10 @@ QWebHapticFeedbackPlayer* QtPlatformPlugin::createHapticFeedbackPlayer() return p ? static_cast<QWebHapticFeedbackPlayer*>(p->createExtension(QWebKitPlatformPlugin::Haptics)) : 0; } +QWebTouchModifier* QtPlatformPlugin::createTouchModifier() +{ + QWebKitPlatformPlugin* p = plugin(); + return p ? static_cast<QWebTouchModifier*>(p->createExtension(QWebKitPlatformPlugin::TouchInteraction)) : 0; +} + } diff --git a/WebKit/qt/WebCoreSupport/QtPlatformPlugin.h b/WebKit/qt/WebCoreSupport/QtPlatformPlugin.h index a3e50c2..ef14a1f 100644 --- a/WebKit/qt/WebCoreSupport/QtPlatformPlugin.h +++ b/WebKit/qt/WebCoreSupport/QtPlatformPlugin.h @@ -28,6 +28,7 @@ class QWebKitPlatformPlugin; class QWebNotificationPresenter; class QWebHapticFeedbackPlayer; class QWebSelectData; +class QWebTouchModifier; namespace WebCore { @@ -39,6 +40,7 @@ public: QWebSelectMethod* createSelectInputMethod(); QWebNotificationPresenter* createNotificationPresenter(); QWebHapticFeedbackPlayer* createHapticFeedbackPlayer(); + QWebTouchModifier* createTouchModifier(); QWebKitPlatformPlugin* plugin(); diff --git a/WebKit/qt/examples/platformplugin/WebPlugin.cpp b/WebKit/qt/examples/platformplugin/WebPlugin.cpp index 23b938e..d029b73 100644 --- a/WebKit/qt/examples/platformplugin/WebPlugin.cpp +++ b/WebKit/qt/examples/platformplugin/WebPlugin.cpp @@ -217,6 +217,8 @@ bool WebPlugin::supportsExtension(Extension extension) const case Notifications: return true; #endif + case TouchInteraction: + return true; default: return false; } @@ -231,6 +233,8 @@ QObject* WebPlugin::createExtension(Extension extension) const case Notifications: return new WebNotificationPresenter(); #endif + case TouchInteraction: + return new TouchModifier(); default: return 0; } diff --git a/WebKit/qt/examples/platformplugin/WebPlugin.h b/WebKit/qt/examples/platformplugin/WebPlugin.h index 3df345f..0243f57 100644 --- a/WebKit/qt/examples/platformplugin/WebPlugin.h +++ b/WebKit/qt/examples/platformplugin/WebPlugin.h @@ -82,6 +82,18 @@ private: Popup* createMultipleSelectionPopup(const QWebSelectData& data); }; +class TouchModifier : public QWebTouchModifier +{ + Q_OBJECT +public: + unsigned hitTestPaddingForTouch(const PaddingDirection direction) const { + // Use 10 as padding in each direction but Up. + if (direction == QWebTouchModifier::Up) + return 15; + return 10; + } +}; + class WebPlugin : public QObject, public QWebKitPlatformPlugin { Q_OBJECT diff --git a/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h b/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h index faa6989..f38a8fb 100644 --- a/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h +++ b/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h @@ -98,6 +98,19 @@ public: virtual void playHapticFeedback(const HapticEvent, const QString& hapticType, const HapticStrength) = 0; }; +class QWebTouchModifier : public QObject +{ + Q_OBJECT +public: + virtual ~QWebTouchModifier() {} + + enum PaddingDirection { + Up, Right, Down, Left + }; + + virtual unsigned hitTestPaddingForTouch(const PaddingDirection) const = 0; +}; + class QWebKitPlatformPlugin { public: @@ -106,13 +119,14 @@ public: enum Extension { MultipleSelections, Notifications, - Haptics + Haptics, + TouchInteraction }; virtual bool supportsExtension(Extension extension) const = 0; virtual QObject* createExtension(Extension extension) const = 0; }; -Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.5"); +Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.6"); #endif // QWEBKITPLATFORMPLUGIN_H diff --git a/WebKit/win/ChangeLog b/WebKit/win/ChangeLog index fb8f19e..e816b34 100644 --- a/WebKit/win/ChangeLog +++ b/WebKit/win/ChangeLog @@ -1,3 +1,213 @@ +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Windows build fix. + + * WebCoreSupport/WebChromeClient.h: Added namespace prefix. + +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * WebCoreSupport/WebChromeClient.cpp: + (WebChromeClient::focusedFrameChanged): + * WebCoreSupport/WebChromeClient.h: + +2010-11-07 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Rename Cache to MemoryCache + https://bugs.webkit.org/show_bug.cgi?id=49159 + + * WebCache.cpp: + (WebCache::statistics): + * WebFrame.cpp: + * WebView.cpp: + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Move resumeAnimations/suspendAnimations from Frame to AnimationController. + https://bugs.webkit.org/show_bug.cgi?id=49073 + + * WebFrame.cpp: + (WebFrame::suspendAnimations): + (WebFrame::resumeAnimations): + +2010-11-05 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Anders Carlsson. + + Assertion failure in PluginStream::~PluginStream when running userscripts/user-script-plugin-document.html + https://bugs.webkit.org/show_bug.cgi?id=48751 + <rdar://problem/8615536> + + Always call committedLoad in WebFrameLoaderClient::finishedLoading, even if we have a manual loader. We were + running into a case where we were trying to load an empty plugin document, which uses a manual loader, and + PluginStream::didFinishLoading was never being called. The stream was never being stopped, making us fire + an assert in the PluginStream destructor. + + * WebCoreSupport/WebFrameLoaderClient.cpp: + (WebFrameLoaderClient::finishedLoading): + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + Make suspendAnimations/resumeAnimations and setCSSAnimations traverse through subframes and remember state + https://bugs.webkit.org/show_bug.cgi?id=46945 + + * WebFrame.cpp: + (WebFrame::suspendAnimations): + (WebFrame::resumeAnimations): + +2010-11-05 Patrick Gansterer <paroga@webkit.org> + + Reviewed by David Kilzer. + + Replace ARRAYSIZE with WTF_ARRAY_LENGTH + https://bugs.webkit.org/show_bug.cgi?id=48903 + + * WebCoreSupport/WebChromeClient.cpp: + (WebChromeClient::exceededDatabaseQuota): + * WebKitDLL.cpp: + (DllGetClassObject): + * WebView.cpp: + (WebView::mouseWheel): + +2010-11-02 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 1 of 2. + + Substitute FrameTree::uniqueName() for FrameTree::name() in the Apple Windows port. + + * WebFrame.cpp: + (WebFrame::name): + +2010-11-02 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/8346191> and https://bugs.webkit.org/show_bug.cgi?id=48868 + Implement IMutableWebRequest::setTimeoutInterval + + * WebMutableURLRequest.cpp: + (WebMutableURLRequest::setTimeoutInterval): + +2010-11-02 Daniel Bates <dbates@rim.com> + + Reviewed by Martin Robinson. + + Set frame name before appending it to the frame tree in the Apple Windows, + GTK, and EFL ports + https://bugs.webkit.org/show_bug.cgi?id=48806 + + Make the frame creation process in the Apple Windows-port consistent + with the Mac, Qt, and Haiku ports. In particular, set the name of + the new frame before it's appended to the frame tree. + + At this time we cannot test this change since it is being masked by + HTMLFrameElementBase::setName() <http://trac.webkit.org/browser/trunk/WebCore/html/HTMLFrameElementBase.cpp?rev=70976#L160>. + We'll be able to test this once we fix bug #6751. + + * WebCoreSupport/WebFrameLoaderClient.cpp: + (WebFrameLoaderClient::createFrame): + +2010-11-01 Jenn Braithwaite <jennb@chromium.org> + + Reviewed by Adam Roben. + + Windows: Update resource tracking when moving a frame between documents + https://bugs.webkit.org/show_bug.cgi?id=48364 + + * Interfaces/IWebResourceLoadDelegatePrivate2.idl:Added + Added removeIdentifierForRequest. + * Interfaces/WebKit.idl: + Added IWebResourceLoadDelegatePrivate2.idl. + * WebCoreSupport/WebFrameLoaderClient.cpp: + (WebFrameLoaderClient::transferLoadingResourceFromPage): + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * WebCoreSupport/WebChromeClient.h: + (WebChromeClient::showContextMenu): + +2010-11-01 Adam Roben <aroben@apple.com> + + Cancel main resource loads after we hand them off to the media engine + + This is the Windows equivalent of r51104. Clearly this code should be + moved to a cross-platform location someday. + + Fixes <http://webkit.org/b/48531> <rdar://problem/8606635> Assertion + failure in DocumentLoader::commitData when loading a media document in + WebKit1 on Windows + + Reviewed by Dan Bernstein. + + * WebCoreSupport/WebFrameLoaderClient.cpp: + (WebFrameLoaderClient::committedLoad): Cancel the main resource load + after handing off the load to the media engine. This code originally + came from -[WebHTMLRepresentation receivedData:withDataSource:]. + + * WebFrame.cpp: + (WebFrame::shouldFallBack): Don't fall back when handing the resource + load off to the media engine or a plugin. Added error domain checking + so that we don't rely on error codes being unique. + +2010-10-29 Daniel Bates <dbates@rim.com> + + No review, rolling out 70971. + http://trac.webkit.org/changeset/70971 + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Rolling out changeset 70971 <http://trac.webkit.org/changeset/70971> since + it caused layout test failures on all bots. In particular, the + child count in a generated frame name differs after this patch. We need + to look into this further. + + * WebFrame.cpp: + (WebFrame::name): + +2010-10-28 Antonio Gomes <agomes@rim.com> + + Reviewed by Ojan Vafai. + + Needs a "LinuxEditingBehavior", perhaps with a better name + https://bugs.webkit.org/show_bug.cgi?id=36627 + + Added the corresponding GTK+ setting to WebCore's EditingUnixBehavior: WebKitEditingUnixBehavior. + + * Interfaces/IWebPreferences.idl: + +2010-10-29 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Modified Apple Windows-port to use FrameTree::uniqueName(). + + * WebFrame.cpp: + (WebFrame::name): + 2010-10-29 Darin Adler <darin@apple.com> Reviewed by Sam Weinig. diff --git a/WebKit/win/Interfaces/IWebPreferences.idl b/WebKit/win/Interfaces/IWebPreferences.idl index 4fb3de8..dd7f282 100644 --- a/WebKit/win/Interfaces/IWebPreferences.idl +++ b/WebKit/win/Interfaces/IWebPreferences.idl @@ -49,7 +49,8 @@ typedef enum WebKitEditableLinkBehavior { typedef enum WebKitEditingBehavior { WebKitEditingMacBehavior = 0, - WebKitEditingWinBehavior + WebKitEditingWinBehavior, + WebKitEditingUnixBehavior } WebKitEditingBehavior; diff --git a/WebKit/win/Interfaces/IWebResourceLoadDelegatePrivate2.idl b/WebKit/win/Interfaces/IWebResourceLoadDelegatePrivate2.idl new file mode 100644 index 0000000..7e98e6a --- /dev/null +++ b/WebKit/win/Interfaces/IWebResourceLoadDelegatePrivate2.idl @@ -0,0 +1,52 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DO_NO_IMPORTS +import "oaidl.idl"; +import "ocidl.idl"; +import "IWebView.idl"; +#endif + +interface IWebView; + +[ + object, + oleautomation, + uuid(3517ADDA-5870-4aab-9A4E-056E65989DF8), + pointer_default(unique) +] +interface IWebResourceLoadDelegatePrivate2 : IUnknown +{ + /*! + @method webView:removeIdentifierForRequest + @param webView The WebView sending the message. + @param identifier An identifier that can be used to track the progress of a resource load across + multiple call backs. + @discussion This message is sent to notify the delegate to stop using the identifier + to track the progress of a resource load. + - (void)webView:(WebView *)sender removeIdentifierForRequest:(id)identifier; + */ + HRESULT removeIdentifierForRequest([in] IWebView* webView, [in] unsigned long identifier); +} diff --git a/WebKit/win/Interfaces/WebKit.idl b/WebKit/win/Interfaces/WebKit.idl index e936af6..3f401be 100644 --- a/WebKit/win/Interfaces/WebKit.idl +++ b/WebKit/win/Interfaces/WebKit.idl @@ -117,6 +117,7 @@ import "ocidl.idl"; #include "IWebResource.idl" #include "IWebResourceLoadDelegate.idl" #include "IWebResourceLoadDelegatePrivate.idl" +#include "IWebResourceLoadDelegatePrivate2.idl" #include "IWebScriptWorld.idl" #include "IWebScrollBarDelegatePrivate.idl" #include "IWebScrollBarPrivate.idl" @@ -300,3 +301,4 @@ library WebKit [default] interface IWebUserContentURLPattern; } } + diff --git a/WebKit/win/WebCache.cpp b/WebKit/win/WebCache.cpp index d82fc43..dff53fe 100644 --- a/WebKit/win/WebCache.cpp +++ b/WebKit/win/WebCache.cpp @@ -31,7 +31,7 @@ #pragma warning(push, 0) #include <WebCore/ApplicationCacheStorage.h> -#include <WebCore/Cache.h> +#include <WebCore/MemoryCache.h> #include <WebCore/CrossOriginPreflightResultCache.h> #pragma warning(pop) @@ -100,7 +100,7 @@ HRESULT STDMETHODCALLTYPE WebCache::statistics( if (!s) return S_OK; - WebCore::Cache::Statistics stat = WebCore::cache()->getStatistics(); + WebCore::MemoryCache::Statistics stat = WebCore::cache()->getStatistics(); static CFStringRef imagesKey = CFSTR("images"); static CFStringRef stylesheetsKey = CFSTR("style sheets"); diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.cpp b/WebKit/win/WebCoreSupport/WebChromeClient.cpp index b1332ed..d046c21 100644 --- a/WebKit/win/WebCoreSupport/WebChromeClient.cpp +++ b/WebKit/win/WebCoreSupport/WebChromeClient.cpp @@ -172,6 +172,10 @@ void WebChromeClient::focusedNodeChanged(Node*) { } +void WebChromeClient::focusedFrameChanged(Frame*) +{ +} + static COMPtr<IPropertyBag> createWindowFeaturesPropertyBag(const WindowFeatures& features) { HashMap<String, COMVariant> map; @@ -592,7 +596,7 @@ void WebChromeClient::exceededDatabaseQuota(Frame* frame, const String& database HMODULE safariHandle = GetModuleHandle(TEXT("Safari.exe")); if (!safariHandle) return; - GetModuleFileName(safariHandle, path, ARRAYSIZE(path)); + GetModuleFileName(safariHandle, path, WTF_ARRAY_LENGTH(path)); DWORD handle; DWORD versionSize = GetFileVersionInfoSize(path, &handle); if (!versionSize) diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.h b/WebKit/win/WebCoreSupport/WebChromeClient.h index 5167c06..55167b6 100644 --- a/WebKit/win/WebCoreSupport/WebChromeClient.h +++ b/WebKit/win/WebCoreSupport/WebChromeClient.h @@ -57,6 +57,7 @@ public: virtual void takeFocus(WebCore::FocusDirection); virtual void focusedNodeChanged(WebCore::Node*); + virtual void focusedFrameChanged(WebCore::Frame*); virtual WebCore::Page* createWindow(WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&); virtual void show(); @@ -122,6 +123,10 @@ public: virtual void reachedApplicationCacheOriginQuota(WebCore::SecurityOrigin*); #endif +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif + virtual void populateVisitedLinks(); virtual bool paintCustomScrollbar(WebCore::GraphicsContext*, const WebCore::FloatRect&, WebCore::ScrollbarControlSize, diff --git a/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp b/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp index 6591347..24f97ca 100644 --- a/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp +++ b/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp @@ -494,11 +494,17 @@ void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* dat if (!m_manualLoader) loader->commitData(data, length); + // If the document is a stand-alone media document, now is the right time to cancel the WebKit load. + // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>. + Frame* coreFrame = core(m_webFrame); + if (coreFrame->document()->isMediaDocument()) + loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response())); + if (!m_manualLoader) return; if (!m_hasSentResponseToPlugin) { - m_manualLoader->didReceiveResponse(core(m_webFrame)->loader()->documentLoader()->response()); + m_manualLoader->didReceiveResponse(loader->response()); // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader // to null @@ -514,10 +520,10 @@ void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader) // Telling the frame we received some data and passing 0 as the data is our // way to get work done that is normally done when the first bit of data is // received, even for the case of a document with no data (like about:blank) - if (!m_manualLoader) { - committedLoad(loader, 0, 0); + committedLoad(loader, 0, 0); + + if (!m_manualLoader) return; - } m_manualLoader->didFinishLoading(); m_manualLoader = 0; @@ -741,8 +747,22 @@ void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*) m_webFrame->setWebView(webView); } -void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*) +void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, Page* oldPage) { + assignIdentifierToInitialRequest(identifier, loader, request); + + WebView* oldWebView = kit(oldPage); + if (!oldWebView) + return; + + COMPtr<IWebResourceLoadDelegate> oldResourceLoadDelegate; + if (FAILED(oldWebView->resourceLoadDelegate(&oldResourceLoadDelegate))) + return; + + COMPtr<IWebResourceLoadDelegatePrivate2> oldResourceLoadDelegatePrivate2(Query, oldResourceLoadDelegate); + if (!oldResourceLoadDelegatePrivate2) + return; + oldResourceLoadDelegatePrivate2->removeIdentifierForRequest(oldWebView, identifier); } PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer) @@ -754,8 +774,8 @@ PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const Strin RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement); - coreFrame->tree()->appendChild(childFrame); childFrame->tree()->setName(name); + coreFrame->tree()->appendChild(childFrame); childFrame->init(); coreFrame->loader()->loadURLIntoChildFrame(URL, referrer, childFrame.get()); diff --git a/WebKit/win/WebFrame.cpp b/WebKit/win/WebFrame.cpp index 9db6a2a..60be4d5 100644 --- a/WebKit/win/WebFrame.cpp +++ b/WebKit/win/WebFrame.cpp @@ -55,7 +55,7 @@ #include "WebView.h" #pragma warning( push, 0 ) #include <WebCore/BString.h> -#include <WebCore/Cache.h> +#include <WebCore/MemoryCache.h> #include <WebCore/Document.h> #include <WebCore/DocumentLoader.h> #include <WebCore/DOMImplementation.h> @@ -438,7 +438,7 @@ HRESULT STDMETHODCALLTYPE WebFrame::name( if (!coreFrame) return E_FAIL; - *frameName = BString(coreFrame->tree()->name()).release(); + *frameName = BString(coreFrame->tree()->uniqueName()).release(); return S_OK; } @@ -1299,11 +1299,7 @@ HRESULT WebFrame::suspendAnimations() if (!frame) return E_FAIL; - AnimationController* controller = frame->animation(); - if (!controller) - return E_FAIL; - - controller->suspendAnimations(frame->document()); + frame->animation()->suspendAnimations(); return S_OK; } @@ -1313,11 +1309,7 @@ HRESULT WebFrame::resumeAnimations() if (!frame) return E_FAIL; - AnimationController* controller = frame->animation(); - if (!controller) - return E_FAIL; - - controller->resumeAnimations(frame->document()); + frame->animation()->resumeAnimations(); return S_OK; } @@ -1718,7 +1710,13 @@ ResourceError WebFrame::pluginWillHandleLoadError(const ResourceResponse& respon bool WebFrame::shouldFallBack(const ResourceError& error) { - return error.errorCode() != WebURLErrorCancelled; + if (error.errorCode() == WebURLErrorCancelled && error.domain() == String(WebURLErrorDomain)) + return false; + + if (error.errorCode() == WebKitErrorPlugInWillHandleLoad && error.domain() == String(WebKitErrorDomain)) + return false; + + return true; } COMPtr<WebFramePolicyListener> WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction function) diff --git a/WebKit/win/WebKitDLL.cpp b/WebKit/win/WebKitDLL.cpp index f8aa261..bc7aa60 100644 --- a/WebKit/win/WebKitDLL.cpp +++ b/WebKit/win/WebKitDLL.cpp @@ -78,7 +78,7 @@ STDAPI_(BOOL) DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpRe STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { bool found = false; - for (int i = 0; i < ARRAYSIZE(gRegCLSIDs); i++) { + for (size_t i = 0; i < WTF_ARRAY_LENGTH(gRegCLSIDs); ++i) { if (IsEqualGUID(rclsid, gRegCLSIDs[i])) { found = true; break; diff --git a/WebKit/win/WebMutableURLRequest.cpp b/WebKit/win/WebMutableURLRequest.cpp index 655b411..02829d7 100644 --- a/WebKit/win/WebMutableURLRequest.cpp +++ b/WebKit/win/WebMutableURLRequest.cpp @@ -320,10 +320,10 @@ HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setMainDocumentURL( } HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setTimeoutInterval( - /* [in] */ double /*timeoutInterval*/) + /* [in] */ double timeoutInterval) { - ASSERT_NOT_REACHED(); - return E_NOTIMPL; + m_request.setTimeoutInterval(timeoutInterval); + return S_OK; } HRESULT STDMETHODCALLTYPE WebMutableURLRequest::setURL( diff --git a/WebKit/win/WebView.cpp b/WebKit/win/WebView.cpp index fb62809..7ce7812 100644 --- a/WebKit/win/WebView.cpp +++ b/WebKit/win/WebView.cpp @@ -69,7 +69,7 @@ #include <WebCore/BString.h> #include <WebCore/BackForwardListImpl.h> #include <WebCore/BitmapInfo.h> -#include <WebCore/Cache.h> +#include <WebCore/MemoryCache.h> #include <WebCore/Chrome.h> #include <WebCore/ContextMenu.h> #include <WebCore/ContextMenuController.h> @@ -1634,9 +1634,9 @@ bool WebView::mouseWheel(WPARAM wParam, LPARAM lParam, bool isMouseHWheel) TCHAR className[256]; // Make sure truncation won't affect the comparison. - ASSERT(ARRAYSIZE(className) > _tcslen(PopupMenuWin::popupClassName())); + ASSERT(WTF_ARRAY_LENGTH(className) > _tcslen(PopupMenuWin::popupClassName())); - if (GetClassName(focusedWindow, className, ARRAYSIZE(className)) && !_tcscmp(className, PopupMenuWin::popupClassName())) { + if (GetClassName(focusedWindow, className, WTF_ARRAY_LENGTH(className)) && !_tcscmp(className, PopupMenuWin::popupClassName())) { // We don't let the WebView scroll here for two reasons - 1) To match Firefox behavior, 2) If we do scroll, we lose the // focus ring around the select menu. SetFocus(m_viewWindow); @@ -2331,7 +2331,7 @@ static String webKitVersion() } *lpTranslate; TCHAR path[MAX_PATH]; - GetModuleFileName(gInstance, path, ARRAYSIZE(path)); + GetModuleFileName(gInstance, path, WTF_ARRAY_LENGTH(path)); DWORD handle; DWORD versionSize = GetFileVersionInfoSize(path, &handle); if (!versionSize) @@ -2345,7 +2345,7 @@ static String webKitVersion() if (!VerQueryValue(data, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate)) goto exit; TCHAR key[256]; - _stprintf_s(key, ARRAYSIZE(key), TEXT("\\StringFileInfo\\%04x%04x\\ProductVersion"), lpTranslate[0].wLanguage, lpTranslate[0].wCodePage); + _stprintf_s(key, WTF_ARRAY_LENGTH(key), TEXT("\\StringFileInfo\\%04x%04x\\ProductVersion"), lpTranslate[0].wLanguage, lpTranslate[0].wCodePage); LPCTSTR productVersion; UINT productVersionLength; if (!VerQueryValue(data, (LPTSTR)(LPCTSTR)key, (void**)&productVersion, &productVersionLength)) diff --git a/WebKit/wince/ChangeLog b/WebKit/wince/ChangeLog index bbf5d59..0cbd925 100644 --- a/WebKit/wince/ChangeLog +++ b/WebKit/wince/ChangeLog @@ -1,3 +1,30 @@ +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * WebCoreSupport/ChromeClientWinCE.cpp: + (WebKit::ChromeClientWinCE::focusedFrameChanged): + * WebCoreSupport/ChromeClientWinCE.h: + +2010-11-02 Patrick Gansterer <paroga@webkit.org> + + Unreviewed, build fix after r71041. + + * WebCoreSupport/ChromeClientWinCE.h: + (WebKit::ChromeClientWinCE::showContextMenu): + +2010-10-30 Patrick Gansterer <paroga@webkit.org> + + Unreviewed, build fix after r70574. + + * WebCoreSupport/FrameLoaderClientWinCE.cpp: + (WebKit::FrameLoaderClientWinCE::transferLoadingResourceFromPage): + 2010-10-29 Alexey Proskuryakov <ap@apple.com> Reviewed by Darin Adler. diff --git a/WebKit/wince/WebCoreSupport/ChromeClientWinCE.cpp b/WebKit/wince/WebCoreSupport/ChromeClientWinCE.cpp index c99635a..e19d6ad 100644 --- a/WebKit/wince/WebCoreSupport/ChromeClientWinCE.cpp +++ b/WebKit/wince/WebCoreSupport/ChromeClientWinCE.cpp @@ -174,6 +174,10 @@ void ChromeClientWinCE::focusedNodeChanged(Node*) notImplemented(); } +void ChromeClientWinCE::focusedFrameChanged(Frame*) +{ +} + bool ChromeClientWinCE::canRunBeforeUnloadConfirmPanel() { return true; diff --git a/WebKit/wince/WebCoreSupport/ChromeClientWinCE.h b/WebKit/wince/WebCoreSupport/ChromeClientWinCE.h index 3818ce0..7219934 100644 --- a/WebKit/wince/WebCoreSupport/ChromeClientWinCE.h +++ b/WebKit/wince/WebCoreSupport/ChromeClientWinCE.h @@ -51,6 +51,7 @@ public: virtual void takeFocus(WebCore::FocusDirection); virtual void focusedNodeChanged(WebCore::Node*); + virtual void focusedFrameChanged(Frame*); // The Frame pointer provides the ChromeClient with context about which // Frame wants to create the new Page. Also, the newly created window @@ -125,6 +126,10 @@ public: virtual void reachedMaxAppCacheSize(int64_t spaceNeeded) = 0; #endif +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif + #if ENABLE(NOTIFICATIONS) virtual WebCore::NotificationPresenter* notificationPresenter() const = 0; #endif diff --git a/WebKit/wince/WebCoreSupport/FrameLoaderClientWinCE.cpp b/WebKit/wince/WebCoreSupport/FrameLoaderClientWinCE.cpp index 0b95213..f3643b2 100644 --- a/WebKit/wince/WebCoreSupport/FrameLoaderClientWinCE.cpp +++ b/WebKit/wince/WebCoreSupport/FrameLoaderClientWinCE.cpp @@ -165,7 +165,7 @@ void FrameLoaderClientWinCE::didTransferChildFrameToNewDocument(Page*) { } -void FrameLoaderClientWinCE::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*) +void FrameLoaderClientWinCE::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const WebCore::ResourceRequest&, Page*) { } diff --git a/WebKit/wx/ChangeLog b/WebKit/wx/ChangeLog index 123b839..e0f0cd1 100644 --- a/WebKit/wx/ChangeLog +++ b/WebKit/wx/ChangeLog @@ -1,3 +1,37 @@ +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * WebKitSupport/ChromeClientWx.cpp: + (WebCore::ChromeClientWx::focusedFrameChanged): + * WebKitSupport/ChromeClientWx.h: + +2010-11-07 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Rename Cache to MemoryCache + https://bugs.webkit.org/show_bug.cgi?id=49159 + + * WebView.cpp: + (wxWebView::SetCachePolicy): + * WebView.h: + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * WebKitSupport/ChromeClientWx.h: + (WebCore::ChromeClientWx::showContextMenu): + 2010-10-29 Darin Adler <darin@apple.com> Reviewed by Sam Weinig. diff --git a/WebKit/wx/WebKitSupport/ChromeClientWx.cpp b/WebKit/wx/WebKitSupport/ChromeClientWx.cpp index 97b98cf..65f0eea 100644 --- a/WebKit/wx/WebKitSupport/ChromeClientWx.cpp +++ b/WebKit/wx/WebKitSupport/ChromeClientWx.cpp @@ -137,6 +137,10 @@ void ChromeClientWx::focusedNodeChanged(Node*) { } +void ChromeClientWx::focusedFrameChanged(Frame*) +{ +} + Page* ChromeClientWx::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&) { Page* myPage = 0; diff --git a/WebKit/wx/WebKitSupport/ChromeClientWx.h b/WebKit/wx/WebKitSupport/ChromeClientWx.h index 755beb7..2ccad43 100644 --- a/WebKit/wx/WebKitSupport/ChromeClientWx.h +++ b/WebKit/wx/WebKitSupport/ChromeClientWx.h @@ -56,6 +56,7 @@ public: virtual void takeFocus(FocusDirection); virtual void focusedNodeChanged(Node*); + virtual void focusedFrameChanged(Frame*); virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&); virtual Page* createModalDialog(Frame*, const FrameLoadRequest&); @@ -129,6 +130,10 @@ public: virtual void reachedApplicationCacheOriginQuota(SecurityOrigin*); #endif +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif + virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>); virtual void chooseIconForFiles(const Vector<String>&, FileChooser*); diff --git a/WebKit/wx/WebView.cpp b/WebKit/wx/WebView.cpp index 5980236..667aa88 100644 --- a/WebKit/wx/WebView.cpp +++ b/WebKit/wx/WebView.cpp @@ -24,13 +24,14 @@ */ #include "config.h" -#include "Cache.h" +#include "WebView.h" + #include "ContextMenu.h" -#include "ContextMenuItem.h" #include "ContextMenuController.h" +#include "ContextMenuItem.h" #include "Document.h" -#include "Element.h" #include "Editor.h" +#include "Element.h" #include "EmptyClients.h" #include "EventHandler.h" #include "FileChooser.h" @@ -41,7 +42,7 @@ #include "GraphicsContext.h" #include "HTMLFormElement.h" #include "Logging.h" -#include "markup.h" +#include "MemoryCache.h" #include "Page.h" #include "PlatformKeyboardEvent.h" #include "PlatformMouseEvent.h" @@ -56,6 +57,7 @@ #include "Settings.h" #include "SubstituteData.h" #include "Threading.h" +#include "markup.h" #if __WXMSW__ #include "WebCoreInstanceHandle.h" #endif @@ -87,7 +89,6 @@ #include "WebDOMNode.h" #include "WebFrame.h" -#include "WebView.h" #include "WebViewPrivate.h" #include <wx/defs.h> @@ -269,12 +270,12 @@ static wxWebViewCachePolicy gs_cachePolicy; /* static */ void wxWebView::SetCachePolicy(const wxWebViewCachePolicy& cachePolicy) { - WebCore::Cache* globalCache = WebCore::cache(); + WebCore::MemoryCache* globalCache = WebCore::cache(); globalCache->setCapacities(cachePolicy.GetMinDeadCapacity(), cachePolicy.GetMaxDeadCapacity(), cachePolicy.GetCapacity()); - // store a copy since there is no getter for Cache values + // store a copy since there is no getter for MemoryCache values gs_cachePolicy = cachePolicy; } diff --git a/WebKit/wx/WebView.h b/WebKit/wx/WebView.h index 3ddb45e..4a6b081 100644 --- a/WebKit/wx/WebView.h +++ b/WebKit/wx/WebView.h @@ -54,7 +54,7 @@ namespace WebCore { extern WXDLLIMPEXP_WEBKIT const wxChar* wxWebViewNameStr; #endif -static const int defaultCacheCapacity = 8192 * 1024; // mirrors Cache.cpp +static const int defaultCacheCapacity = 8192 * 1024; // mirrors MemoryCache.cpp class WXDLLIMPEXP_WEBKIT wxWebViewCachePolicy { diff --git a/WebKitExamplePlugins/ChangeLog b/WebKitExamplePlugins/ChangeLog index 724bf26..eafec02 100644 --- a/WebKitExamplePlugins/ChangeLog +++ b/WebKitExamplePlugins/ChangeLog @@ -1,3 +1,17 @@ +2010-11-03 Darin Adler <darin@apple.com> + + Updated Xcode projects by opening them with Xcode 3.2.4. + Updated svn:ignore for Xcode projects. + + * NetscapeCocoaPlugin/NetscapeCocoaPlugin.xcodeproj: Added property svn:ignore. + * NetscapeCocoaPlugin/NetscapeCocoaPlugin.xcodeproj/project.pbxproj: Updated with Xcode 3.2.4. + * NetscapeCoreAnimationMoviePlugin/NetscapeCoreAnimationMoviePlugin.xcodeproj: Added property svn:ignore. + * NetscapeCoreAnimationMoviePlugin/NetscapeCoreAnimationMoviePlugin.xcodeproj/project.pbxproj: + * NetscapeCoreAnimationPlugin/NetscapeCoreAnimationPlugin.xcodeproj: Added property svn:ignore. + * NetscapeCoreAnimationPlugin/NetscapeCoreAnimationPlugin.xcodeproj/project.pbxproj: + * NetscapeInputMethodPlugin/NetscapeInputMethodPlugin.xcodeproj: Added property svn:ignore. + * NetscapeInputMethodPlugin/NetscapeInputMethodPlugin.xcodeproj/project.pbxproj: Updated with Xcode 3.2.4. + 2010-06-16 Anders Carlsson <andersca@apple.com> Fix build. diff --git a/WebKitExamplePlugins/NetscapeCocoaPlugin/NetscapeCocoaPlugin.xcodeproj/project.pbxproj b/WebKitExamplePlugins/NetscapeCocoaPlugin/NetscapeCocoaPlugin.xcodeproj/project.pbxproj index cf36a4d..c9a0b70 100644 --- a/WebKitExamplePlugins/NetscapeCocoaPlugin/NetscapeCocoaPlugin.xcodeproj/project.pbxproj +++ b/WebKitExamplePlugins/NetscapeCocoaPlugin/NetscapeCocoaPlugin.xcodeproj/project.pbxproj @@ -109,7 +109,14 @@ isa = PBXProject; buildConfigurationList = 149C298708902C53008A9EFC /* Build configuration list for PBXProject "NetscapeCocoaPlugin" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 089C166AFE841209C02AAC07 /* NetscapeCocoaPlugin */; projectDirPath = ""; projectRoot = ""; diff --git a/WebKitExamplePlugins/NetscapeCoreAnimationMoviePlugin/NetscapeCoreAnimationMoviePlugin.xcodeproj/project.pbxproj b/WebKitExamplePlugins/NetscapeCoreAnimationMoviePlugin/NetscapeCoreAnimationMoviePlugin.xcodeproj/project.pbxproj index 9f5747b..fef3db9 100644 --- a/WebKitExamplePlugins/NetscapeCoreAnimationMoviePlugin/NetscapeCoreAnimationMoviePlugin.xcodeproj/project.pbxproj +++ b/WebKitExamplePlugins/NetscapeCoreAnimationMoviePlugin/NetscapeCoreAnimationMoviePlugin.xcodeproj/project.pbxproj @@ -135,7 +135,14 @@ isa = PBXProject; buildConfigurationList = 149C298708902C53008A9EFC /* Build configuration list for PBXProject "NetscapeCoreAnimationMoviePlugin" */; compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 089C166AFE841209C02AAC07 /* NetscapeCoreAnimationMoviePlugin */; projectDirPath = ""; projectRoot = ""; diff --git a/WebKitExamplePlugins/NetscapeCoreAnimationPlugin/NetscapeCoreAnimationPlugin.xcodeproj/project.pbxproj b/WebKitExamplePlugins/NetscapeCoreAnimationPlugin/NetscapeCoreAnimationPlugin.xcodeproj/project.pbxproj index 6b2a52a..a1e3390 100644 --- a/WebKitExamplePlugins/NetscapeCoreAnimationPlugin/NetscapeCoreAnimationPlugin.xcodeproj/project.pbxproj +++ b/WebKitExamplePlugins/NetscapeCoreAnimationPlugin/NetscapeCoreAnimationPlugin.xcodeproj/project.pbxproj @@ -115,7 +115,14 @@ isa = PBXProject; buildConfigurationList = 149C298708902C53008A9EFC /* Build configuration list for PBXProject "NetscapeCoreAnimationPlugin" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 089C166AFE841209C02AAC07 /* NetscapeCoreAnimationPlugin */; projectDirPath = ""; projectRoot = ""; diff --git a/WebKitExamplePlugins/NetscapeInputMethodPlugin/NetscapeInputMethodPlugin.xcodeproj/project.pbxproj b/WebKitExamplePlugins/NetscapeInputMethodPlugin/NetscapeInputMethodPlugin.xcodeproj/project.pbxproj index c5248be..474c2cb 100644 --- a/WebKitExamplePlugins/NetscapeInputMethodPlugin/NetscapeInputMethodPlugin.xcodeproj/project.pbxproj +++ b/WebKitExamplePlugins/NetscapeInputMethodPlugin/NetscapeInputMethodPlugin.xcodeproj/project.pbxproj @@ -104,7 +104,14 @@ isa = PBXProject; buildConfigurationList = 149C298708902C53008A9EFC /* Build configuration list for PBXProject "NetscapeInputMethodPlugin" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 089C166AFE841209C02AAC07 /* NetscapeInputMethodPlugin */; projectDirPath = ""; projectRoot = ""; diff --git a/WebKitLibraries/ChangeLog b/WebKitLibraries/ChangeLog index b5d248f..767d09a 100644 --- a/WebKitLibraries/ChangeLog +++ b/WebKitLibraries/ChangeLog @@ -1,3 +1,15 @@ +2010-10-29 Dan Bernstein <mitz@apple.com> + + Snow Leopard PowerPC build fix. + + * libWebKitSystemInterfaceSnowLeopard.a: + +2010-10-29 Dan Bernstein <mitz@apple.com> + + Leopard PowerPC build fix. + + * libWebKitSystemInterfaceLeopard.a: + 2010-10-29 Csaba Osztrogonác <ossy@webkit.org> Reviewed by Adam Roben and David Kilzer. diff --git a/WebKitLibraries/libWebKitSystemInterfaceLeopard.a b/WebKitLibraries/libWebKitSystemInterfaceLeopard.a Binary files differindex 979989a..678342a 100644 --- a/WebKitLibraries/libWebKitSystemInterfaceLeopard.a +++ b/WebKitLibraries/libWebKitSystemInterfaceLeopard.a diff --git a/WebKitLibraries/libWebKitSystemInterfaceSnowLeopard.a b/WebKitLibraries/libWebKitSystemInterfaceSnowLeopard.a Binary files differindex 5bc2b65..1f82d39 100644 --- a/WebKitLibraries/libWebKitSystemInterfaceSnowLeopard.a +++ b/WebKitLibraries/libWebKitSystemInterfaceSnowLeopard.a diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json index 71c20f0..f39e10c 100644 --- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json +++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json @@ -91,7 +91,7 @@ { "name": "Windows Release (Build)", "type": "Build", "builddir": "win-release", "platform": "win", "configuration": "release", "architectures": ["i386"], - "triggers": ["win-release-tests"], + "triggers": ["win-release-tests", "win-release-tests-wk2"], "slavenames": ["apple-windows-2", "test-slave"] }, { @@ -102,7 +102,7 @@ { "name": "Windows Debug (Build)", "type": "Build", "builddir": "win-debug", "platform": "win", "configuration": "debug", "architectures": ["i386"], - "triggers": ["win-debug-tests", "win-debug-tests-wk2"], + "triggers": ["win-debug-tests"], "slavenames": ["apple-windows-1", "test-slave"] }, { @@ -240,8 +240,8 @@ { "type": "Triggerable", "name": "win-debug-tests", "builderNames": ["Windows Debug (Tests)"] }, - { "type": "Triggerable", "name": "win-debug-tests-wk2", - "builderNames": ["Windows Debug (WebKit2 Tests)"] + { "type": "Triggerable", "name": "win-release-tests-wk2", + "builderNames": ["Windows Release (WebKit2 Tests)"] } ] } diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg index 5c44525..97641bf 100644 --- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg +++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg @@ -305,6 +305,51 @@ class RunGtkAPITests(shell.Test): return [self.name] +class RunQtAPITests(shell.Test): + name = "API tests" + description = ["API tests running"] + descriptionDone = ["API tests"] + command = ["python", "./WebKitTools/Scripts/run-qtwebkit-tests", + "--output-file=qt-unit-tests.html", "--do-not-open-results", + WithProperties("WebKitBuild/%(configuration_pretty)s/WebKit/qt/tests/")] + + def start(self): + self.setProperty("configuration_pretty", self.getProperty("configuration").title()) + return shell.Test.start(self) + + def commandComplete(self, cmd): + shell.Test.commandComplete(self, cmd) + + logText = cmd.logs['stdio'].getText() + foundItems = re.findall("TOTALS: (?P<passed>\d+) passed, (?P<failed>\d+) failed, (?P<skipped>\d+) skipped", logText) + + self.incorrectTests = 0 + self.statusLine = [] + + if foundItems: + self.incorrectTests = int(foundItems[0][1]) + if self.incorrectTests > 0: + self.statusLine = [ + "%s passed, %s failed, %s skipped" % (foundItems[0][0], foundItems[0][1], foundItems[0][2]) + ] + + def evaluateCommand(self, cmd): + if self.incorrectTests: + return WARNINGS + + if cmd.rc != 0: + return FAILURE + + return SUCCESS + + def getText(self, cmd, results): + return self.getText2(cmd, results) + + def getText2(self, cmd, results): + if results != SUCCESS and self.incorrectTests: + return self.statusLine + + return [self.name] class RunWebKitLeakTests(RunWebKitTests): def start(self): @@ -421,6 +466,8 @@ class BuildAndTestFactory(Factory): self.addStep(ExtractTestResults) if platform == "gtk": self.addStep(RunGtkAPITests) + if platform == "qt": + self.addStep(RunQtAPITests) class BuildAndTestLeaksFactory(BuildAndTestFactory): TestClass = RunWebKitLeakTests diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog index 1c7d1bf..a5e6893 100644 --- a/WebKitTools/ChangeLog +++ b/WebKitTools/ChangeLog @@ -1,3 +1,1241 @@ +2010-11-05 Adam Roben <aroben@apple.com> + + Make webkitpy.common.system.executive_unittest pass when running under + Win32 Python + + Fixes <http://webkit.org/b/49033>. + + Reviewed by Dave Levin and Eric Seidel. + + * Scripts/webkitpy/common/system/executive.py: + (Executive._run_command_with_teed_output): Pass the arguments through + encode_argument_if_needed rather than using Cygwin-specific code here. + (Executive.run_and_throw_if_fail): Use child_process_encoding to decode + the output. + (Executive.run_command): Use encode_argument_if_needed to encode the + arguments and child_process_encoding to decode the output. + (Executive._child_process_encoding): Returns the encoding that should be + used when communicating with child processes. On Windows we use mbcs, + which maps to the current code page. On all other platforms we use + UTF-8. + (Executive._should_encode_child_process_arguments): Returns True if + arguments to child processes need to be encoded. This is currently + only needed on Cygwin and Win32 Python 2.x. + (Executive._encode_argument_if_needed): Encode the argument using + child_process_encoding if we need to encode arguments to child + processes on this platform. + + * Scripts/webkitpy/common/system/executive_unittest.py: + (never_ending_command): Added. Returns arguments to run a command that + will not quit until we kill it. On Windows we use wmic, on other + platforms we use yes. + (ExecutiveTest.test_run_command_with_unicode): Changed to expect the + mbcs encoding to be used and for output from the child processes to + have been roundtripped through encode/decode on Win32 Python. When + UTF-8 is the encoding the roundtripping is undetectable, but with mbcs + it's possible that some characters will not be able to be converted + and will be replaced by question marks; the round-tripping allows us + to expect this result. + + (ExecutiveTest.test_kill_process): + (ExecutiveTest.test_kill_all): + Use never_ending_command instead of invoking "yes" directly. Expect an + exit code of 1 when using Win32 Python, as that's what seems to happen. + +2010-11-08 Adam Roben <aroben@apple.com> + + Roll out r71532 + + It broke the build for Cygwin 1.7 installs. Cygwin 1.7's default + .bashrc unsets %TEMP%, which broke copy-tools.cmd. + + * Scripts/webkitdirs.pm: + +2010-11-08 Tony Chang <tony@chromium.org> + + Reviewed by Adam Barth. + + run platform/chromium/plugins/nested-plugin-objects.html on all platforms + https://bugs.webkit.org/show_bug.cgi?id=49094 + + This tests that objects created by plugins are proplery cleaned up. + + * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp: + (testPassTestObject): + (pluginInvoke): + * DumpRenderTree/TestNetscapePlugIn/TestObject.cpp: + (testAllocate): + (testDeallocate): + (testGetProperty): + (testConstruct): + +2010-11-08 Adam Roben <aroben@apple.com> + + Mark Windows builds triggered from Perl as being non-interactive + + This affects whether some of our scripts will show alerts vs. printing + to the build log. + + Fixes <http://webkit.org/b/49181> Windows build fail mysteriously when + .vsprops files are updated + + Reviewed by Steve Falkenburg. + + * Scripts/webkitdirs.pm: + (buildVisualStudioProject): Set WEBKIT_NONINTERACTIVE_BUILD to 1. + +2010-11-08 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Ojan Vafai. + + Make http locking default in NRWT. + https://bugs.webkit.org/show_bug.cgi?id=48053 + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-11-08 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Csaba Osztrogonác. + + [NRWT] If the http lock fails we shouldn't do any locking + https://bugs.webkit.org/show_bug.cgi?id=49164 + + If something goes wrong with the locking, the test should keep going. + + * Scripts/webkitpy/layout_tests/port/http_lock.py: + +2010-11-08 Adam Roben <aroben@apple.com> + + Switch back to using kCGImageAlphaPremultipliedFirst when generating + pixel dumps on Windows + + I changed this behavior in r71418 thinking that it was required for + getting plugins to show up in pixel dumps. But it doesn't seem to be + necessary, and was making it impossible to compare new Windows pixel + dumps with existing Windows or Mac pixel dumps (because ImageDiff won't + compare an image with alpha to an image without alpha). + + Fixes <http://webkit.org/b/49172> REGRESION (r71418): Can't compare + new Windows pixel results to existing Windows or Mac results + + Reviewed by Antti Koivisto. + + * DumpRenderTree/win/PixelDumpSupportWin.cpp: + (createBitmapContextFromWebView): Replaced kCGImageAlphaNoneSkipFirst + with kCGImageAlphaPremultipliedFirst. + +2010-11-08 Csaba Osztrogonac <ossy@webkit.org> + + Unreviewed, rolling out r71466. + http://trac.webkit.org/changeset/71466 + https://bugs.webkit.org/show_bug.cgi?id=48865 + + It broke layout tests on GTK bots. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (createWebView): + +2010-11-08 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Csaba Osztrogonác. + + Enable running of Qt API tests on BuildBot + https://bugs.webkit.org/show_bug.cgi?id=49004 + + * BuildSlaveSupport/build.webkit.org-config/master.cfg: + +2010-11-08 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + Add clean-review-queue command to remove closed bugs from the webkit.org/pending-review + https://bugs.webkit.org/show_bug.cgi?id=49160 + + Bugzilla doesn't automatically remove r? when a bug gets closed. + This script takes care of that for webkit.org. + + * Scripts/webkitpy/common/net/bugzilla.py: + * Scripts/webkitpy/tool/commands/upload.py: + +2010-11-07 Fumitoshi Ukai <ukai@chromium.org> + + Unreviewed, rolling out r71474. + http://trac.webkit.org/changeset/71474 + https://bugs.webkit.org/show_bug.cgi?id=48280 + + breaks chromium webkit tests + https://bugs.webkit.org/show_bug.cgi?id=49151 + + * Scripts/webkitpy/layout_tests/port/base.py: + * Scripts/webkitpy/layout_tests/port/base_unittest.py: + * Scripts/webkitpy/layout_tests/port/config.py: + * Scripts/webkitpy/layout_tests/port/config_unittest.py: + * Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py: + * Scripts/webkitpy/layout_tests/port/webkit.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py: + * Scripts/webkitpy/tool/mocktool.py: + +2010-11-07 Fumitoshi Ukai <ukai@chromium.org> + + Unreviewed, rolling out r71475. + http://trac.webkit.org/changeset/71475 + + breaks chromium webkit tests + https://bugs.webkit.org/show_bug.cgi?id=49151 + + * Scripts/webkitpy/common/newstringio.py: Removed. + * Scripts/webkitpy/common/newstringio_unittest.py: Removed. + * Scripts/webkitpy/common/system/executive_mock.py: Removed. + * Scripts/webkitpy/common/system/filesystem_mock.py: Removed. + * Scripts/webkitpy/layout_tests/port/config_mock.py: Removed. + +2010-11-06 Dirk Pranke <dpranke@chromium.org> + + Unreviewed, build fix. + + Add files inexplicably not committed in r71474 as part of the + fix for bug 48280. + + * Scripts/webkitpy/common/newstringio.py: Added. + * Scripts/webkitpy/common/newstringio_unittest.py: Added. + * Scripts/webkitpy/common/system/executive_mock.py: Added. + * Scripts/webkitpy/common/system/filesystem_mock.py: Added. + * Scripts/webkitpy/layout_tests/port/config_mock.py: Added. + +2010-11-06 Dirk Pranke <dpranke@chromium.org> + + Reviewed by Eric Siedel. + + new-run-webkit-tests: update port/base and port/webkit to use the + new FileSystem and Config abstractions, pulling more logic out of + the base Port classes into separate, mockable objects. + + Also create a MockFileSystem object, a MockConfig object, move + MockExecutive into common/system to be next to executive, and + update the config object to use a FileSystem. + + https://bugs.webkit.org/show_bug.cgi?id=48280 + + * Scripts/webkitpy/common/newstringio.py: Added. + * Scripts/webkitpy/common/newstringio_unittest.py: Added. + * Scripts/webkitpy/common/system/executive_mock.py: Added. + * Scripts/webkitpy/common/system/filesystem_mock.py: Added. + * Scripts/webkitpy/layout_tests/port/base.py: + * Scripts/webkitpy/layout_tests/port/base_unittest.py: + * Scripts/webkitpy/layout_tests/port/config.py: + * Scripts/webkitpy/layout_tests/port/config_mock.py: + * Scripts/webkitpy/layout_tests/port/config_unittest.py: + * Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py: + * Scripts/webkitpy/layout_tests/port/webkit.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py: + * Scripts/webkitpy/tool/mocktool.py: + +2010-11-06 Dirk Pranke <dpranke@chromium.org> + + Unreviewed, build breakage. + + Apparently I uploaded the wrong version of the file to fix 49122 + and neither Eric or I noticed - it was missing a dirname() call. + Fixing ... + + https://bugs.webkit.org/show_bug.cgi?id=49122 + + * Scripts/webkitpy/common/checkout/scm.py: + +2010-11-06 Dirk Pranke <dpranke@chromium.org> + + Reviewed by Eric Seidel. + + webkitpy/tool/* unittests change cwd and don't clean up properly + + https://bugs.webkit.org/show_bug.cgi?id=49122 + + * Scripts/webkitpy/common/checkout/scm.py: + +2010-11-05 Chris Marrin <cmarrin@apple.com> + + Reviewed by Simon Fraser. + + suspendAnimations/resumeAnimations not present in WebKit2 + https://bugs.webkit.org/show_bug.cgi?id=49109 + + * WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl: + * WebKitTestRunner/InjectedBundle/LayoutTestController.cpp: + (WTR::LayoutTestController::suspendAnimations): + (WTR::LayoutTestController::resumeAnimations): + * WebKitTestRunner/InjectedBundle/LayoutTestController.h: + +2010-11-05 Tony Chang <tony@chromium.org> + + Reviewed by David Levin. + + cleanup style in TestNetscapePlugIn/PluginObject.cpp + https://bugs.webkit.org/show_bug.cgi?id=49044 + + * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp: + (getPluginClass): + (pluginGetProperty): + (pluginSetProperty): + (variantToIdentifier): + (testCallback): + (getURL): + (getURLNotify): + (testInvokeDefault): + (testGetProperty): + (testDocumentOpen): + (testWindowOpen): + (pluginInvoke): + (handleCallback): + (notifyStream): + * DumpRenderTree/TestNetscapePlugIn/PluginObject.h: + +2010-11-05 Eric Seidel <eric@webkit.org> + + Reviewed by David Levin. + + Add QueueStatusServer/__init__.py so others can run the QueueStatusServer tests + https://bugs.webkit.org/show_bug.cgi?id=49032 + + I wrote this file as part of bug 47847, but I forgot to commit it. + No one else noticed it missing because test-webkitpy knows how + to recover in the case where it can't import QueueStatusServer + (which generally occurs due to not having installed the AppEngine SDK). + + * QueueStatusServer/__init__.py: Added. + * QueueStatusServer/model/workitems_unittest.py: + - Remove a test which fails. This was probably landed (by me) + from my other machine, which since this __init__.py was missing + I never noticed the failure and landed this invalid test. + Sadly we can't really test remove_work_item as it depends + on .key() working. .key() will throw unless the object + has already been saved it seems. + This may be a mis-design in our remove_work_item implementation, + but for now, just removing the test. + +2010-11-04 Adam Roben <aroben@apple.com> + + Teach check-webkit-style about TestNetscapePlugIn + + Fixes <http://webkit.org/b/49030> check-webkit-style is ignorant of + TestNetscapePlugIn's coding conventions + + Reviewed by John Sullivan. + + * Scripts/webkitpy/style/checker.py: Lump TestNetscapePlugIn in with + WebKitAPITest and TestWebKitAPI in having different include order and + naming conventions than WebCore. Added some comments about why the + exceptions exist. + +2010-11-04 Adam Roben <aroben@apple.com> + + Add a test that shows that windowed plugins are able to paint + + Somehow we never had a test for this before. + + Fixes <http://webkit.org/b/49029> Should add a test that shows + windowed plugins can paint + + Reviewed by Jon Honeycutt. + + * DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp: Added. + (DrawsGradient::DrawsGradient): + (DrawsGradient::wndProc): We handle the WM_PAINT and WM_PRINTCLIENT messages. + + (DrawsGradient::onPaint): + (DrawsGradient::onPrintClient): + These both just call through to paint. + + (DrawsGradient::paint): Fills our client area with some gradients. + + * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: Link + against Msimg32.lib for ::GradientFill and added DrawsGradient. + + * DumpRenderTree/win/PixelDumpSupportWin.cpp: + (createBitmapContextFromWebView): Use WM_PRINT instead of + WM_PRINTCLIENT so that ::DefWindowProc will send + WM_PRINT/WM_PRINTCLIENT messages to the WebView's child windows. + Replaced kCGImageAlphaPremultipledFirst with kCGImageAlphaNoneSkipFirst + because GDI doesn't support alpha and kCGImageBitmapOrder32Little with + kCGImageBitmapOrder32Host because, who knows, maybe someday Windows + will run on a big-endian platform. + +2010-11-04 Adam Roben <aroben@apple.com> + + Extract much of NPNInvalidateRectInvalidatesWindow's code into a + WindowedPluginTest base class + + The base class takes care of subclassing the plugin's window so that a + custom WNDPROC is called. This will make it easier to write tests that + need to handle window messages. + + Fixes <http://webkit.org/b/49028> It's hard to write a PluginTest with + a custom WNDPROC + + Reviewed by Jon Honeycutt. + + * DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp: + (NPNInvalidateRectInvalidatesWindow::NPNInvalidateRectInvalidatesWindow): + (NPNInvalidateRectInvalidatesWindow::NPP_SetWindow): + (NPNInvalidateRectInvalidatesWindow::wndProc): + (NPNInvalidateRectInvalidatesWindow::testInvalidateRect): + Moved code from here to WindowedPluginTest. Changed to use window() + instead of m_window. + + * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: + Added WindowedPluginTest and added TestNetscapePlugIn/win to the + include path. Also reordered the include path to make a little more + sense and simplified the entry that added TestNetscapePlugIn itself to + the include path. + + * DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp: Added. + (WindowedPluginTest::WindowedPluginTest): + (WindowedPluginTest::NPP_SetWindow): + (WindowedPluginTest::staticWndProc): + * DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.h: Added. + (WindowedPluginTest::window): + Code came from NPNInvalidateRectInvalidatesWindow. + +2010-11-04 Adam Roben <aroben@apple.com> + + Add a plugin test to show that windowed plugins are clipped correctly + + Fixes <http://webkit.org/b/49024> <rdar://problem/8487847> Windowed + plugins aren't clipped in WebKit2 on Windows + + Reviewed by Jon Honeycutt. + + * DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp: Added. + (WindowRegionIsSetToClipRect::WindowRegionIsSetToClipRect): Initialize members. + (WindowRegionIsSetToClipRect::NPP_SetWindow): Check that our window + region matches the clip rect we know we should have based on + window-region-is-set-to-clip-rect.html, and check that our window class + doesn't have the CS_PARENTDC style. + + * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: + Added WindowRegionIsSetToClipRect. + +2010-11-05 Alejandro G. Castro <alex@igalia.com> + + Reviewed by Martin Robinson. + + [GTK] Avoid font hinting in the DRT + https://bugs.webkit.org/show_bug.cgi?id=48548 + + Change the settings to avoid font hinting, it was causing + different results depending on the distribution. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (initializeGtkFontSettings): + * DumpRenderTree/gtk/fonts/fonts.conf: + +2010-11-05 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + build-webkit spams system.log by repeatedly checking for PBXProductDirectory in com.apple.Xcode + https://bugs.webkit.org/show_bug.cgi?id=49051 + + This is a speculative fix. The unit tests cover these methods, however + I don't know if this will fully stop the system.log spam. + + * Scripts/webkitpy/layout_tests/port/base.py: + * Scripts/webkitpy/layout_tests/port/webkit.py: + +2010-11-05 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + Add basic support for showing bot id on /queue-status/ pages + https://bugs.webkit.org/show_bug.cgi?id=49037 + + This support is really simple. Eventually we'll want to + show the bot id in the lock table too, but we don't have + that information stored in the server yet. + + * QueueStatusServer/handlers/queuestatus.py: + * QueueStatusServer/handlers/queuestatus_unittest.py: Added. + * QueueStatusServer/templates/includes/singlequeuestatus.html: + +2010-11-04 Dirk Pranke <dpranke@chromium.org> + + Reviewed by Adam Barth. + + Create a filesystem wrapper that we can use to enforce + particular conventions and use for mocking and dependency + injection down the line. + + https://bugs.webkit.org/show_bug.cgi?id=48144 + + * Scripts/webkitpy/common/system/filesystem.py: Added. + * Scripts/webkitpy/common/system/filesystem_unittest.py: Added. + +2010-11-04 Mihai Parparita <mihaip@chromium.org> + + Reviewed by Tony Chang. + + run_webkit_tests_unittest fails under Python 2.5 + https://bugs.webkit.org/show_bug.cgi?id=49043 + + Switch from itertools.chain.from_iterable (which was added in 2.6) + to using itertools.chain directly. + + * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py: + +2010-11-04 Mihai Parparita <mihaip@chromium.org> + + Unreviewed fix to webkit-patch rebaseline-server so that it runs under + Python 2.5 (it needs an import to use the with statement). + + * Scripts/webkitpy/tool/commands/rebaselineserver.py: + +2010-11-04 Dirk Pranke <dpranke@chromium.org> + + Reviewed by Adam Barth. + + new-run-webkit-tests: split out webkit-specific configuration stuff into a new module + + The current NRWT code has webkit-specific configuration code (like + _script_path, default configuration, etc.) mixed in with + layout-test-specific stuff in port/base. The configuration code + should be split out into a separate module for easier mocking, + testing, and isolation. + + https://bugs.webkit.org/show_bug.cgi?id=48264 + + * Scripts/webkitpy/layout_tests/port/config.py: Added. + * Scripts/webkitpy/layout_tests/port/config_unittest.py: Added. + +2010-11-04 Mihai Parparita <mihaip@chromium.org> + + Reviewed by Tony Chang. + + Rebaseline server: initial framework + https://bugs.webkit.org/show_bug.cgi?id=48892 + + Adds the basic framework for the rebaseline server (details at + http://webkit.org/b/47761). Includes the rebaseline-server webkit-patch + command, which starts an HTTP server that can serve static files or + invoke handler methods on a class. + + * Scripts/webkitpy/tool/commands/__init__.py: + * Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html: Added. + * Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css: Added. + * Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js: Added. + * Scripts/webkitpy/tool/commands/rebaselineserver.py: Added. + +2010-11-04 Dirk Pranke <dpranke@chromium.org> + + Reviewed by James Robinson. + + new-run-webkit-tests wasn't using DRT by default for + --platform chromium-gpu + + The default value was set to False instead of None, which meant + that the platform specific logic wasn't firing to change the + value to True (b/c we were afraid we'd be overriding the user + preference). + + https://bugs.webkit.org/show_bug.cgi?id=49038 + + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-11-04 Tony Chang <tony@chromium.org> + + Reviewed by Adam Barth. + + make platform/chromium/plugins/multiple-plugins.html pass on all platforms + https://bugs.webkit.org/show_bug.cgi?id=49026 + + Have the testObject.bar property return the string "bar". This lets + us run and pass platform/chromium/plugins/multiple-plugins.html on all + platforms. + + * DumpRenderTree/TestNetscapePlugIn/TestObject.cpp: + (testGetProperty): + +2010-11-04 Mihai Parparita <mihaip@chromium.org> + + Reviewed by Tony Chang. + + NRWT doesn't have good test coverage for --run-chunk, --batch-size, --run-part, etc. + https://bugs.webkit.org/show_bug.cgi?id=48878 + + Add get_tests_run so that it's easy to see which tests get run (and with + what batching) for a given flag combination. Flesh out the various + test cases that have FIXMEs. + + Also fixes an off-by-one error (batch sizes were one larger than + expected) and makes --run-part also have wraparound behavior, like + --run-chunk. + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py: + +2010-11-04 Erik Arvidsson <arv@chromium.org> + + Reviewed by Dimitri Glazkov. + + Support box-sizing without the vendor prefix + https://bugs.webkit.org/show_bug.cgi?id=36713 + + Based on patch by Peter Beverloo <peter@lvp-media.com> + + * iExploder/htdocs/cssproperties.in: Change -webkit-box-sizing to box-sizing. + +2010-11-04 Csaba Osztrogonác <ossy@webkit.org> + + Unreviewed rollout r71340, because it broke Chromium Windows bot. + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-11-04 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Ojan Vafai. + + Make http locking default in NRWT. + https://bugs.webkit.org/show_bug.cgi?id=48053 + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-11-04 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Eric Seidel. + + [NRWT] Clear invalid http locks on Windows platform as well + https://bugs.webkit.org/show_bug.cgi?id=48515 + + * Scripts/webkitpy/common/system/executive.py: + * Scripts/webkitpy/common/system/executive_unittest.py: + * Scripts/webkitpy/layout_tests/port/http_lock.py: + +2010-11-02 Adam Roben <aroben@apple.com> + + Reduce our dependence on coreutils when running Python tests + + This patch introduces versions of the standard echo and cat utilities + implemented in Python. They are probably missing features of their + coreutils equivalents, but they can do what's necessary for our Python + tests. This is useful on Windows, where these utilities typically + aren't available. + + Fixes <http://webkit.org/b/48883> executive_unittest relies on echo + and cat utilities from coreutils, which are not present on Windows + + Reviewed by Eric Seidel. + + * Scripts/webkitpy/common/system/executive_unittest.py: Changed to use + our Python-based echo and cat. + + * Scripts/webkitpy/common/system/fileutils.py: Added. + (make_stdout_binary): On Windows, puts sys.stdout into binary mode so + that \n won't be translated into \r\n. I couldn't think of a good way + to test this directly without touching the filesystem, but it is tested + indirectly by echo_unittest. + + * Scripts/webkitpy/test/cat.py: Added. + (command_arguments): Returns a list for invoking cat with the given arguments. + (main): Acts like a simplified version of the coreutils cat utility. + + * Scripts/webkitpy/test/cat_unittest.py: Added. + (CatTest.assert_cat): Runs cat with the given input and ensures the + output matches the input. + (CatTest.test_basic): Performs a simple test of cat. + (CatTest.test_no_newline): Tests what happens when the input string + doesn't have a trailing newline. + (CatTest.test_unicode): Tests passing a unicode string to cat. + (CatTest.test_as_command): Tests running cat as a separate command. + + * Scripts/webkitpy/test/echo.py: Added. + (command_arguments): Returns a list for invoking echo with the given arguments. + (main): Acts like a simplified version of the coreutils echo utility. + + * Scripts/webkitpy/test/echo_unittest.py: Added. + (EchoTest.test_basic): Performs a simple test of echo. + (EchoTest.test_no_newline): Tests passing -n to echo to suppress the + trailing newline. + (EchoTest.test_unicode): Tests passing unicode and non-unicode strings + to echo. + (EchoTest.test_argument_order): Tests what happens when -n is not the + first argument. + (EchoTest.test_empty_arguments): Tests what happens when you pass [] to + echo.main. + (EchoTest.test_no_arguments): Tests what happens when you call + echo.main with no arguments. + (EchoTest.test_as_command): Tests running echo as a separate command. + +2010-11-04 Renata Hodovan <reni@inf.u-szeged.hu> + + Unreviewed: Add myself to the list of Committers. + + * Scripts/webkitpy/common/config/committers.py: + +2010-11-04 Andreas Kling <kling@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Hook into QWebPage::scrollRequested for resizes-to-contents mode + + In RTC mode the QGraphicsWebView item is the size of the contents, + scrolling works a bit differently (we need to react to scrollRequested.) + + Normally QGraphicsView will replay the last mouse event when scrolling, + so to prevent WebKit from getting confused by this we temporarily make + the QGraphicsView non-interactive. + + * QtTestBrowser/webview.cpp: + (WebViewGraphicsBased::setPage): + (WebViewGraphicsBased::scrollRequested): + * QtTestBrowser/webview.h: + +2010-11-04 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Andreas Kling. + + Use OS(MAC_OS_X) rather than PLATFORM(MAC) in TestControllerQt + + PLATFORM(MAC) is not defined for the Qt port, as it refers to + the Mac-port, not the Mac OS X operating system. + + * WebKitTestRunner/qt/TestControllerQt.cpp: + (WTR::isExistingLibrary): + +2010-11-04 Leonid Ebril <leonid.ebril@nokia.com> + + Reviewed by Andreas Kling. + + [Qt] Adding iphone user agent string the user agent list for QtTestBrowser + https://bugs.webkit.org/show_bug.cgi?id=48869 + + * QtTestBrowser/useragentlist.txt: + +2010-11-03 Adam Roben <aroben@apple.com> + + Always use uppercase drive names in strings returned by abspath_to_uri + + Some versions of cygpath use lowercase drive letters while others use + uppercase, which makes it hard to test the output of code that uses + cygpath. + + Fixes <http://webkit.org/b/48914> webkitpy.common.system.path_unittest + fails with Cygwin 1.5 + + Reviewed by Eric Seidel. + + * Scripts/webkitpy/common/system/path.py: + (cygpath): Updated the docstring to indicate that only absolute paths + should be passed for now (though relative paths will work fine). + (_Cygpath.convert): Upper-case the first letter of the converted Windows path. + +2010-11-03 George Guo <George.Guo@Nokia.com> + + Reviewed by Andreas Kling. + + [Qt] QtTestBrowser : set mmp rule pageddata in Symbian + https://bugs.webkit.org/show_bug.cgi?id=48767 + + Paging is needd on Symbian devices to support benchmarks tests like + dromaeo.com and Celtic Kane that need a lot of memory to run + + * QtTestBrowser/QtTestBrowser.pro: + +2010-11-03 Jenn Braithwaite <jennb@chromium.org> + + Reviewed by Dmitry Titov. + + Chromium: Update resource tracking when moving a frame between documents + https://bugs.webkit.org/show_bug.cgi?id=48363 + + * DumpRenderTree/chromium/WebViewHost.cpp: + (WebViewHost::assignIdentifierToRequest): + Always put resource id in map so we can make assumptions about its + presence. + (WebViewHost::removeIdentifierForRequest): + Added. + (WebViewHost::didFinishResourceLoad): + (WebViewHost::didFailResourceLoad): + Check existence of resource id before removing from map. + * DumpRenderTree/chromium/WebViewHost.h: + +2010-11-03 Victor Wang <victorw@chromium.org> + + Reviewed by Adam Barth. + + [Chromium] update buildbot names in chromium rebaseline tool. + + https://bugs.webkit.org/show_bug.cgi?id=48881 + + * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py: + +2010-11-03 Darin Adler <darin@apple.com> + + Updated Xcode projects by opening them with Xcode 3.2.4. + Updated svn:ignore for Xcode projects. + + * MiniBrowser/MiniBrowser.xcodeproj: Added property svn:ignore. + * TestWebKitAPI/TestWebKitAPI.xcodeproj: Added property svn:ignore. + * WebKitLauncher/WebKitLauncher.xcodeproj: Modified property svn:ignore. + * WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj: Updated with Xcode 3.2.4. + +2010-11-03 Adam Roben <aroben@apple.com> + + Stop waiting for messages from the web process after a timeout elapses + + TestController::runUntil now takes a timeout parameter that specifies + how long to wait for the condition to become true. WebKitTestRunner + takes a --timeout flag that specifies how long the timeout should be. + run-webkit-tests passes this flag to WebKitTestRunner so its timeout + will be similar to run-webkit-tests. + + Fixes <http://webkit.org/b/43047> <rdar://problem/8365833> + WebKitTestRunner waits forever if the web process crashes + + Reviewed by Darin Adler and Anders Carlsson. + + * Scripts/old-run-webkit-tests: + (top level): Moved the GuardMalloc timeout adjustment here from + readFromDumpToolWithTimer. + (openDumpTool): Make WTR use a timeout similar to but slightly shorter + than the one that was specified on the command line. + + * WebKitTestRunner/TestController.cpp: + (WTR::TestController::TestController): Initialize our timeout values. + (WTR::TestController::initialize): Parse the --timeout flag and use it + to modify our timeout values. + (WTR::TestController::resetStateToConsistentValues): Changed to use a + short timeout while waiting for the web process to reset and to return + a boolean indicating whether we were able to reset the web process. + Uses a 5-second timeout while waiting for the process to be reset. + (WTR::TestController::runTest): Changed to return a boolean indicating + whether we were able to reset the web process (and thus run the test). + (WTR::TestController::runUntil): Call through to platformRunUntil. + + (WTR::TestController::runTestingServerLoop): + (WTR::TestController::run): + Changed to bail if any test can't be run. This will cause the process + to exit. (Unfortunately this will make run-webkit-tests think we + crashed; see <http://webkit.org/b/48943>.) + + * WebKitTestRunner/TestController.h: Added platformRunUntil, + m_longTimeout, and m_shortTimeout. + + * WebKitTestRunner/TestInvocation.cpp: + (WTR::TestInvocation::invoke): Use a short timeout when waiting for the + initial response and a long timeout when waiting for the test to + complete. Check whether runUntil timed out and print an error message + if so. + + * WebKitTestRunner/mac/TestControllerMac.mm: + (WTR::TestController::platformRunUntil): Renamed from runUntil. Pass + [NSDate distantPast] to -[NSRunLoop runMode:beforeDate:] so that we + won't block waiting for the run loop. Only loop until the timeout + elapses. + + * WebKitTestRunner/qt/TestControllerQt.cpp: + (WTR::TestController::platformRunUntil): Renamed from runUntil. Added a + FIXME about honoring the timeout. + + * WebKitTestRunner/win/TestControllerWin.cpp: + (WTR::TestController::platformRunUntil): Renamed from runUntil. Use + ::MsgWaitForMultipleObjectsEx to implement the timeout. Changed to use + ::PeekMessageW so that we don't block waiting for messages to become + available. + +2010-11-03 Adam Roben <aroben@apple.com> + + Add a plugin test that evaluates JS after removing the plugin element + from the document + + This test replaces platform/win/plugins/plugin-delayed-destroy.html. + That test was made to prevent a crash very similar to this one, but + unfortunately tested only the mechanism that prevented the crash and + not whether the crash itself was prevented. Since WebKit2 uses a + different mechanism to prevent the crash, the test was failing even + though WebKit2 was not vulnerable to the crash. This new test crashes + if there is no mechanism in place to prevent it and passes in both + WebKit1 and WebKit2. + + Fixes <http://webkit.org/b/46711> <rdar://problem/8485903> + platform/win/plugins/plugin-delayed-destroy.html fails in WebKit2 + + Reviewed by Anders Carlsson. + + * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: + * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: + * DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro: + * GNUmakefile.am: + Added new file. + + * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp: + (pluginDeallocate): Make sure we delete the PluginTest object. This + prevents a leak and also allows us to test the crash. + + * DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp: + (PluginTest::executeScript): Made this into a non-static member + function. + + (PluginTest::waitUntilDone): + (PluginTest::notifyDone): + Updated for changes to executeScript. + + * DumpRenderTree/TestNetscapePlugIn/PluginTest.h: Added executeScript. + + * DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp: Added. + (EvaluateJSAfterRemovingPluginElement::EvaluateJSAfterRemovingPluginElement): + Initialize ourselves and tell the test harness to wait. + (EvaluateJSAfterRemovingPluginElement::NPP_DestroyStream): Remove our + plugin element from the document, then execute some JavaScript. If + WebKit does not have appropriate mechanisms in place, we'll be + destroyed inside the first call to executeScript and crash on the + second call. + +2010-11-02 Stephen White <senorblanco@chromium.org> + + Reviewed by Tony Chang. + + [chromium] Fix LayoutTestController UMRs. + https://bugs.webkit.org/show_bug.cgi?id=48872 + + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::LayoutTestController): + +2010-11-03 Kent Tamura <tkent@chromium.org> + + Reviewed by Dimitri Glazkov. + + REGRESSION: rebaseline-chromium-webkit-tests uses non-zero tolerance for + image dup detection + https://bugs.webkit.org/show_bug.cgi?id=48744 + + * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py: + - Make a function for option parsing for ease of test + - Set 0 to options.tolerance + * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py: + - Add a test for this change + +2010-11-02 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Unreviewed: Add myself to the list of Committers. + + * Scripts/webkitpy/common/config/committers.py: + +2010-11-02 Anders Carlsson <andersca@apple.com> + + Fix build. + + * TestWebKitAPI/PlatformUtilities.cpp: + (TestWebKitAPI::Util::createContextForInjectedBundleTest): + +2010-11-02 Sam Weinig <sam@webkit.org> + + Reviewed by Anders Carlsson. + + Add a way to send startup messages on the context which can be posted when a process launches + <rdar://problem/8617928> + https://bugs.webkit.org/show_bug.cgi?id=48838 + + * MiniBrowser/mac/WebBundle/WebBundleMain.m: + (WKBundleInitialize): + * TestWebKitAPI/InjectedBundleController.cpp: + (TestWebKitAPI::InjectedBundleController::initialize): + (TestWebKitAPI::InjectedBundleController::didReceiveMessage): + * TestWebKitAPI/InjectedBundleController.h: + * TestWebKitAPI/InjectedBundleMain.cpp: + (WKBundleInitialize): + * TestWebKitAPI/PlatformUtilities.cpp: + (TestWebKitAPI::Util::createContextForInjectedBundleTest): + * WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp: + (WKBundleInitialize): + Update implementations of WKBundleInitialize to take an initial userData + argument. Change TestWebKitAPI to use the new initial userData to initialize + each test's bundle. + +2010-11-02 Benjamin Kalman <kalman@google.com> + + Reviewed by Ojan Vafai. + + new-run-webkit-tests doesn't strip "LayoutTests/" from prefix, unlike old-run-webkit-tests + https://bugs.webkit.org/show_bug.cgi?id=48794 + + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: Strip the "LayoutTests/" prefix from test argument paths. + +2010-11-02 Adam Roben <aroben@apple.com> + + Skip webkitpy.layout_tests.run_webkit_tests_unittest.MainTest on Cygwin + Python 2.5.x + + It is known to hang on that version of Python. See + <http://webkit.org/b/48614>. + + Reviewed by Adam Barth. + + * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py: Use + skip_if to skip MainTest on Cygwin Python 2.5.x. + + * Scripts/webkitpy/test/skip.py: Added. + (skip_if): If the passed-in condition is false, find all the test_* + methods of the given class and replace them with a function that just + logs that we're skipping these tests. This is loosely based on the + unittest.skip_if decorator added in Python 3.1. + (_skipped_method): Returns a function that just logs that the tests are + being skipped. This is used in place of the actual test_* functions. + + * Scripts/webkitpy/test/skip_unittest.py: Added. + (SkipTest.setUp): Create a logger for ourselves and give it a handler + that logs to a private stream. + (SkipTest.tearDown): Reset the logger. + (SkipTest.create_fixture_class): Returns a class that we use to test + skip_if. It has a single test_* method, test_foo, that just calls + through to a callback. + (SkipTest.foo_callback): Record that test_foo was called. + (SkipTest.test_skip_if_false): Pass skip_if a False condition and test + that test_foo does get called. + (SkipTest.test_skip_if_true): Pass skip_if a True condition and test + that test_foo does not get called and the appropriate message gets + logged. + +2010-11-02 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + webkit-patch should tell check-webkit-style which files were changed so + check-webkit-style doesn't have to stat the whole working copy again + https://bugs.webkit.org/show_bug.cgi?id=48792 + + * Scripts/webkitpy/tool/mocktool.py: + * Scripts/webkitpy/tool/steps/checkstyle.py: + +2010-11-02 Robert Kroeger <rjkroege@chromium.org> + + Reviewed by James Robinson. + + [Chromium/DRT] Make EventSendingController honour leapForward for touch events. + https://bugs.webkit.org/show_bug.cgi?id=48777 + + * DumpRenderTree/chromium/EventSender.cpp: + (EventSender::sendCurrentTouchEvent): + +2010-11-02 Adam Roben <aroben@apple.com> + + Only track resource identifiers in DRT when dumpResourceLoadCallbacks + is on + + This reverts Windows to our pre-r71097 behavior. That patch made us + track all resource identifiers, including the main resource, so the + main resource's URL started appearing in test output instead of + "<unknown>". Arguably having the main resource's URL is better, but all + other platforms print "<unknown>" and we want to match. + + Fixes <http://webkit.org/b/48837> <rdar://problem/8620351> REGRESSION + (r71097): Many http tests failing on Windows + + Reviewed by Anders Carlsson. + + * DumpRenderTree/win/ResourceLoadDelegate.cpp: + (ResourceLoadDelegate::identifierForInitialRequest): Don't add the + identifier to the URL map if we're not supposed to dump resource load + callbacks. + (ResourceLoadDelegate::removeIdentifierForRequest): Always remove the + identifier from the URL map even if we're already "done". There's no + point in keeping out-of-date identifiers around. + +2010-11-01 Jenn Braithwaite <jennb@chromium.org> + + Reviewed by Adam Roben. + + Windows: Update resource tracking when moving a frame between documents + https://bugs.webkit.org/show_bug.cgi?id=48364 + + * DumpRenderTree/win/DumpRenderTree.cpp: + (createWebViewAndOffscreenWindow): + (main): + Give each WebView its own ResourceLoadDelegate instance in order to + make assertions about resource ids on a particular WebView. + * DumpRenderTree/win/ResourceLoadDelegate.cpp: + (ResourceLoadDelegate::identifierForInitialRequest): + Always add id to the map. + (ResourceLoadDelegate::removeIdentifierForRequest): + Added. + (ResourceLoadDelegate::willSendRequest): + (ResourceLoadDelegate::didReceiveAuthenticationChallenge): + (ResourceLoadDelegate::didReceiveResponse): + (ResourceLoadDelegate::didFinishLoadingFromDataSource): + (ResourceLoadDelegate::didFailLoadingWithError): + (ResourceLoadDelegate::descriptionSuitableForTestResult): + Replace static descriptionSuitableForTestResult with static member function to access identifier map. + * DumpRenderTree/win/ResourceLoadDelegate.h: + (ResourceLoadDelegate::urlMap): + Moved within class so that each WebView has its own id map. + +2010-11-01 Ojan Vafai <ojan@chromium.org> + + Reviewed by Dimitri Glazkov. + + remove debug code from run_webkit_tests.py + https://bugs.webkit.org/show_bug.cgi?id=48800 + + Remove temporary debug code and make --master-name required + if --test-results-server is set now that all clients set + --master-name. + + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-11-01 Tony Chang <tony@chromium.org> + + Reviewed by Kent Tamura. + + add plugin event logging for linux + https://bugs.webkit.org/show_bug.cgi?id=48779 + + This is taken from Chromium's fork of the layout test plugin: + http://git.chromium.org/gitweb/?p=chromium.git/.git;a=blob;f=webkit/tools/npapi_layout_test_plugin/main.cpp;h=3ebdada2f049b3624756438cff852364f86a2ede;hb=HEAD#l348 + + * DumpRenderTree/TestNetscapePlugIn/main.cpp: + (handleEventX11): + (NPP_HandleEvent): + +2010-11-01 Dirk Pranke <dpranke@chromium.org> + + Reviewed by James Robinson. + + new-run-webkit-tests: use DRT, child-processes=1 for GPU tests by default + https://bugs.webkit.org/show_bug.cgi?id=48790 + + * Scripts/webkitpy/layout_tests/port/chromium_gpu.py: + * Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py: + +2010-11-01 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Teach check-webkit-style how to accept a list of files to diff on the + command line + https://bugs.webkit.org/show_bug.cgi?id=48784 + + In a future patch, webkit-patch will use this option to improve + performance. I'm landing this in two pieces to avoid causing a version + skew problem for the style-bot. + + * Scripts/check-webkit-style: + * Scripts/webkitpy/style/optparser.py: + * Scripts/webkitpy/style/optparser_unittest.py: + * Scripts/webkitpy/style_references.py: + +2010-11-01 Anders Carlsson <andersca@apple.com> + + Reviewed by John Sullivan. + + Tear down the related WebProcessProxy when a WebContext is deallocated + https://bugs.webkit.org/show_bug.cgi?id=48769 + + * TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp: + (TestWebKitAPI::didFailProvisionalLoadWithErrorForFrame): + We don't support empty URLs anymore, update test to expect a null URL instead. + +2010-11-01 Søren Gjesse <sgjesse@chromium.org> + + Reviewed by Andreas Kling. + + Fix warning when compiling the chromium port of DumpRenderShell + with clang. + https://bugs.webkit.org/show_bug.cgi?id=48414 + + * DumpRenderTree/chromium/TestShell.h: + (TestShell::javaScriptFlagsForLoad): + +2010-11-01 Adam Roben <aroben@apple.com> + + Fix typo from r71022 + + * BuildSlaveSupport/build.webkit.org-config/config.json: + +2010-11-01 Adam Roben <aroben@apple.com> + + Trigger the Windows Release WebKit2 tests when a Release build + finishes, not when a Debug build finishes + + Fixes <http://webkit.org/b/48754> Windows Release WebKit2 tests are + triggered at the wrong time + + Reviewed by Sam Weinig. + + * BuildSlaveSupport/build.webkit.org-config/config.json: Fixed + triggerable name and trigger. + +2010-11-01 Mario Sanchez Prada <msanchez@igalia.com> + + Unreviewed. Adding my IRC nickname to the list of committers. + + * Scripts/webkitpy/common/config/committers.py: + +2010-10-31 Robert Hogan <robert@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] [Gtk] Plug-ins having upper case in mime type are failing to load + + Qt and Gtk are case-sensitive when storing the declared mime-type + of plugins. Since plugin mime-types are lowercased prior to searching + for them in the plugin database, ensure they are loaded with the + mime-type in lower case too. + + Change the test netscape plugin to declare its mimetype in sentence + case so that the correct behaviour is enforced. + + https://bugs.webkit.org/show_bug.cgi?id=36815 + + * DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp: + (NP_GetMIMEDescription): + +2010-10-31 Robert Hogan <robert@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] Support nodesFromRect in DRT + + https://bugs.webkit.org/show_bug.cgi?id=48716 + + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + (LayoutTestController::nodesFromRect): + * DumpRenderTree/qt/LayoutTestControllerQt.h: + +2010-10-30 Andreas Kling <kling@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] QtTestBrowser: Switching view type moves the embedded inspector + https://bugs.webkit.org/show_bug.cgi?id=48705 + + Reinsert the embedded inspector into the splitter after changing + between QWebView/QGraphicsWebView. + + * QtTestBrowser/launcherwindow.cpp: + (LauncherWindow::init): + (LauncherWindow::initializeView): + * QtTestBrowser/webinspector.h: + (WebInspector::WebInspector): + +2010-10-28 Antonio Gomes <agomes@rim.com> + + Reviewed by Ojan Vafai. + + Needs a "LinuxEditingBehavior", perhaps with a better name + https://bugs.webkit.org/show_bug.cgi?id=36627 + + Adding support to Mac's, GTK+'s, Windows' and Chromium's LayoutTestController class to test the newly introduced Unix editing behavior. + + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::setEditingBehavior): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setEditingBehavior): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setEditingBehavior): + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setEditingBehavior): + 2010-10-29 Andreas Kling <kling@webkit.org> Reviewed by Kenneth Rohde Christiansen. diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj index bf0aebf..b2eb8e9 100644 --- a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj +++ b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj @@ -132,6 +132,7 @@ BCD08B710E1059D200A7D0C1 /* AccessibilityControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */; }; BCF6C6500C98E9C000AC063E /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF6C64F0C98E9C000AC063E /* GCController.cpp */; }; C06F9ABC1267A7060058E1F6 /* PassDifferentNPPStruct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */; }; + C0E720751281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */; }; C0EC3C9C12787F0500939164 /* NullNPPGetValuePointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */; }; E1B7816511AF31B7007E1BC2 /* MockGeolocationProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */; }; E1B7816711AF31C3007E1BC2 /* MockGeolocationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = E1B7808511AF1643007E1BC2 /* MockGeolocationProvider.h */; }; @@ -307,6 +308,7 @@ BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityControllerMac.mm; path = mac/AccessibilityControllerMac.mm; sourceTree = "<group>"; }; BCF6C64F0C98E9C000AC063E /* GCController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GCController.cpp; sourceTree = "<group>"; }; C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PassDifferentNPPStruct.cpp; sourceTree = "<group>"; }; + C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EvaluateJSAfterRemovingPluginElement.cpp; sourceTree = "<group>"; }; C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullNPPGetValuePointer.cpp; sourceTree = "<group>"; }; E1B7808511AF1643007E1BC2 /* MockGeolocationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MockGeolocationProvider.h; path = mac/MockGeolocationProvider.h; sourceTree = "<group>"; }; E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MockGeolocationProvider.mm; path = mac/MockGeolocationProvider.mm; sourceTree = "<group>"; }; @@ -462,6 +464,7 @@ isa = PBXGroup; children = ( 1A215A7511F26072008AD0F5 /* DocumentOpenInDestroyStream.cpp */, + C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */, 1A24BAA8120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp */, 1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */, C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */, @@ -751,6 +754,7 @@ 1A24BAA9120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp in Sources */, C06F9ABC1267A7060058E1F6 /* PassDifferentNPPStruct.cpp in Sources */, C0EC3C9C12787F0500939164 /* NullNPPGetValuePointer.cpp in Sources */, + C0E720751281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp index db73a9d..7f1c4b4 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp @@ -27,13 +27,13 @@ #include "PluginObject.h" +#include "PluginTest.h" #include "TestObject.h" #include <assert.h> #include <stdarg.h> #include <stdio.h> - -#include <string.h> #include <stdlib.h> +#include <string.h> // Helper function which takes in the plugin window object for logging to the console object. static void pluginLogWithWindowObject(NPObject* windowObject, NPP instance, const char* message) @@ -118,10 +118,10 @@ static NPClass pluginClass = { pluginSetProperty, 0, // NPClass::removeProperty 0, // NPClass::enumerate - 0 // NPClass::construct + 0, // NPClass::construct }; -NPClass *getPluginClass(void) +NPClass* getPluginClass(void) { return &pluginClass; } @@ -176,6 +176,7 @@ enum { ID_TEST_GET_PROPERTY_RETURN_VALUE, ID_TEST_IDENTIFIER_TO_STRING, ID_TEST_IDENTIFIER_TO_INT, + ID_TEST_PASS_TEST_OBJECT, ID_TEST_POSTURL_FILE, ID_TEST_CONSTRUCT, ID_TEST_THROW_EXCEPTION_METHOD, @@ -212,6 +213,7 @@ static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = { "testGetPropertyReturnValue", "testIdentifierToString", "testIdentifierToInt", + "testPassTestObject", "testPostURLFile", "testConstruct", "testThrowException", @@ -270,38 +272,48 @@ static bool pluginGetProperty(NPObject* obj, NPIdentifier name, NPVariant* resul strcpy(buf, originalString); STRINGZ_TO_NPVARIANT(buf, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) { BOOLEAN_TO_NPVARIANT(plugin->eventLogging, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) { BOOLEAN_TO_NPVARIANT(plugin->logDestroy, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) { - BOOLEAN_TO_NPVARIANT(plugin->stream != 0, *result); + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) { + BOOLEAN_TO_NPVARIANT(plugin->stream, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) { NPObject* testObject = plugin->testObject; browser->retainobject(testObject); OBJECT_TO_NPVARIANT(testObject, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) { BOOLEAN_TO_NPVARIANT(plugin->returnErrorFromNewStream, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) { BOOLEAN_TO_NPVARIANT(plugin->returnNegativeOneFromWrite, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_PRIVATE_BROWSING_ENABLED]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_PRIVATE_BROWSING_ENABLED]) { NPBool privateBrowsingEnabled = FALSE; browser->getvalue(plugin->npp, NPNVprivateModeBool, &privateBrowsingEnabled); BOOLEAN_TO_NPVARIANT(privateBrowsingEnabled, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_CACHED_PRIVATE_BROWSING_ENABLED]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_CACHED_PRIVATE_BROWSING_ENABLED]) { BOOLEAN_TO_NPVARIANT(plugin->cachedPrivateBrowsingMode, *result); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) { browser->setexception(obj, "plugin object testThrowExceptionProperty SUCCESS"); return true; - } else if (name == pluginPropertyIdentifiers[ID_LAST_SET_WINDOW_ARGUMENTS]) { + } + if (name == pluginPropertyIdentifiers[ID_LAST_SET_WINDOW_ARGUMENTS]) { char* buf = static_cast<char*>(browser->memalloc(256)); snprintf(buf, 256, "x: %d, y: %d, width: %u, height: %u, clipRect: (%u, %u, %u, %u)", (int)plugin->lastWindow.x, (int)plugin->lastWindow.y, (unsigned)plugin->lastWindow.width, (unsigned)plugin->lastWindow.height, plugin->lastWindow.clipRect.left, plugin->lastWindow.clipRect.top, plugin->lastWindow.clipRect.right - plugin->lastWindow.clipRect.left, plugin->lastWindow.clipRect.bottom - plugin->lastWindow.clipRect.top); @@ -319,19 +331,24 @@ static bool pluginSetProperty(NPObject* obj, NPIdentifier name, const NPVariant* if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) { plugin->eventLogging = NPVARIANT_TO_BOOLEAN(*variant); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) { plugin->logDestroy = NPVARIANT_TO_BOOLEAN(*variant); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) { plugin->returnErrorFromNewStream = NPVARIANT_TO_BOOLEAN(*variant); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) { plugin->returnNegativeOneFromWrite = NPVARIANT_TO_BOOLEAN(*variant); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) { browser->setexception(obj, "plugin object testThrowExceptionProperty SUCCESS"); return true; - } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_WINDOWED_PLUGIN]) { + } + if (name == pluginPropertyIdentifiers[ID_PROPERTY_WINDOWED_PLUGIN]) { browser->setvalue(plugin->npp, NPPVpluginWindowBool, (void *)NPVARIANT_TO_BOOLEAN(*variant)); return true; } @@ -391,9 +408,9 @@ static NPIdentifier variantToIdentifier(NPVariant variant) { if (NPVARIANT_IS_STRING(variant)) return stringVariantToIdentifier(variant); - else if (NPVARIANT_IS_INT32(variant)) + if (NPVARIANT_IS_INT32(variant)) return int32VariantToIdentifier(variant); - else if (NPVARIANT_IS_DOUBLE(variant)) + if (NPVARIANT_IS_DOUBLE(variant)) return doubleVariantToIdentifier(variant); return 0; } @@ -424,9 +441,29 @@ static bool testIdentifierToInt(PluginObject*, const NPVariant* args, uint32_t a return true; } +static bool testPassTestObject(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) +{ + if (argCount != 2 || !NPVARIANT_IS_STRING(args[0])) + return false; + + NPObject* windowScriptObject; + browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); + + NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); + NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); + free(callbackString); + + NPVariant browserResult; + browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, &args[1], 1, &browserResult); + browser->releasevariantvalue(&browserResult); + + VOID_TO_NPVARIANT(*result); + return true; +} + static bool testCallback(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { - if (argCount == 0 || !NPVARIANT_IS_STRING(args[0])) + if (!argCount || !NPVARIANT_IS_STRING(args[0])) return false; NPObject* windowScriptObject; @@ -457,7 +494,8 @@ static bool getURL(PluginObject* obj, const NPVariant* args, uint32_t argCount, INT32_TO_NPVARIANT(npErr, *result); return true; - } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) { + } + if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) { NPUTF8* urlString = createCStringFromNPVariant(&args[0]); NPError npErr = browser->geturl(obj->npp, urlString, 0); free(urlString); @@ -476,7 +514,7 @@ static bool getURLNotify(PluginObject* obj, const NPVariant* args, uint32_t argC return false; NPUTF8* urlString = createCStringFromNPVariant(&args[0]); - NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL); + NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : 0); NPUTF8* callbackString = createCStringFromNPVariant(&args[2]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); @@ -495,7 +533,7 @@ static bool testInvokeDefault(PluginObject* obj, const NPVariant* args, uint32_t if (!NPVARIANT_IS_OBJECT(args[0])) return false; - NPObject *callback = NPVARIANT_TO_OBJECT(args[0]); + NPObject* callback = NPVARIANT_TO_OBJECT(args[0]); NPVariant invokeArgs[1]; NPVariant browserResult; @@ -568,10 +606,10 @@ static bool testGetIntIdentifier(PluginObject*, const NPVariant* args, uint32_t static bool testGetProperty(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { - if (argCount == 0) + if (!argCount) return false; - NPObject *object; + NPObject* object; browser->getvalue(obj->npp, NPNVWindowNPObject, &object); for (uint32_t i = 0; i < argCount; i++) { @@ -730,7 +768,7 @@ bool testDocumentOpen(NPP npp) NPIdentifier documentId = browser->getstringidentifier("document"); NPIdentifier openId = browser->getstringidentifier("open"); - NPObject *windowObject = NULL; + NPObject* windowObject = 0; browser->getvalue(npp, NPNVWindowNPObject, &windowObject); if (!windowObject) return false; @@ -742,7 +780,7 @@ bool testDocumentOpen(NPP npp) return false; } - NPObject *documentObject = NPVARIANT_TO_OBJECT(docVariant); + NPObject* documentObject = NPVARIANT_TO_OBJECT(docVariant); NPVariant openArgs[2]; STRINGZ_TO_NPVARIANT("text/html", openArgs[0]); @@ -774,7 +812,7 @@ bool testWindowOpen(NPP npp) { NPIdentifier openId = browser->getstringidentifier("open"); - NPObject *windowObject = NULL; + NPObject* windowObject = 0; browser->getvalue(npp, NPNVWindowNPObject, &windowObject); if (!windowObject) return false; @@ -856,87 +894,100 @@ static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* a PluginObject* plugin = reinterpret_cast<PluginObject*>(header); if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD]) return testCallback(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) + if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) return getURL(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) + if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) return testDOMAccess(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) + if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) return getURLNotify(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT]) + if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT]) return testInvokeDefault(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE]) + if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE]) return testEnumerate(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) + if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) return destroyStream(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER]) + if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER]) return testGetIntIdentifier(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE]) + if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE]) return testEvaluate(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY]) + if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY]) return testGetProperty(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE]) + if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE]) return testGetPropertyReturnValue(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY]) + if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY]) return testHasProperty(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD]) + if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD]) return testHasMethod(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING]) + if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING]) return testIdentifierToString(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT]) + if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT]) return testIdentifierToInt(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE]) + if (name == pluginMethodIdentifiers[ID_TEST_PASS_TEST_OBJECT]) + return testPassTestObject(plugin, args, argCount, result); + if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE]) return testPostURLFile(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT]) + if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT]) return testConstruct(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) { + if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) { browser->setexception(header, "plugin object testThrowException SUCCESS"); return true; - } else if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) { + } + if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) { NPObject* windowScriptObject; browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject); browser->invoke(plugin->npp, windowScriptObject, name, args, argCount, result); - } else if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM]) + return false; + } + if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM]) return destroyNullStream(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_NO_PAGES]) { + if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_NO_PAGES]) { browser->reloadplugins(false); return true; - } else if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) { + } + if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) { browser->reloadplugins(true); return true; - } else if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) { + } + if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) { browser->getproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), result); return true; - } else if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) { + } + if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) { browser->setproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), &args[2]); return true; - } else if (name == pluginMethodIdentifiers[ID_REMEMBER]) { + } + if (name == pluginMethodIdentifiers[ID_REMEMBER]) { if (plugin->rememberedObject) browser->releaseobject(plugin->rememberedObject); plugin->rememberedObject = NPVARIANT_TO_OBJECT(args[0]); browser->retainobject(plugin->rememberedObject); VOID_TO_NPVARIANT(*result); return true; - } else if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) { + } + if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) { assert(plugin->rememberedObject); browser->retainobject(plugin->rememberedObject); OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result); return true; - } else if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) { + } + if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) { assert(plugin->rememberedObject); OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result); plugin->rememberedObject = 0; return true; - } else if (name == pluginMethodIdentifiers[ID_REF_COUNT]) { + } + if (name == pluginMethodIdentifiers[ID_REF_COUNT]) { uint32_t refCount = NPVARIANT_TO_OBJECT(args[0])->referenceCount; INT32_TO_NPVARIANT(refCount, *result); return true; - } else if (name == pluginMethodIdentifiers[ID_SET_STATUS]) + } + if (name == pluginMethodIdentifiers[ID_SET_STATUS]) return testSetStatus(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_RESIZE_TO]) + if (name == pluginMethodIdentifiers[ID_RESIZE_TO]) return testResizeTo(plugin, args, argCount, result); - else if (name == pluginMethodIdentifiers[ID_NORMALIZE]) + if (name == pluginMethodIdentifiers[ID_NORMALIZE]) return normalizeOverride(plugin, args, argCount, result); - + return false; } @@ -990,6 +1041,7 @@ static NPObject *pluginAllocate(NPP npp, NPClass *theClass) static void pluginDeallocate(NPObject* header) { PluginObject* plugin = reinterpret_cast<PluginObject*>(header); + delete plugin->pluginTest; if (plugin->testObject) browser->releaseobject(plugin->testObject); if (plugin->rememberedObject) @@ -1008,14 +1060,14 @@ void handleCallback(PluginObject* object, const char *url, NPReason reason, void NPVariant args[2]; - NPObject *windowScriptObject; + NPObject* windowScriptObject; browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject); NPIdentifier callbackIdentifier = notifyData; INT32_TO_NPVARIANT(reason, args[0]); - char *strHdr = NULL; + char* strHdr = 0; if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) { // Format expected by JavaScript validator: four fields separated by \n\n: // First URL; first header block; last URL; last header block. @@ -1040,7 +1092,7 @@ void handleCallback(PluginObject* object, const char *url, NPReason reason, void void notifyStream(PluginObject* object, const char *url, const char *headers) { - if (object->firstUrl == NULL) { + if (!object->firstUrl) { if (url) object->firstUrl = strdup(url); if (headers) @@ -1048,8 +1100,8 @@ void notifyStream(PluginObject* object, const char *url, const char *headers) } else { free(object->lastUrl); free(object->lastHeaders); - object->lastUrl = (url ? strdup(url) : NULL); - object->lastHeaders = (headers ? strdup(headers) : NULL); + object->lastUrl = (url ? strdup(url) : 0); + object->lastHeaders = (headers ? strdup(headers) : 0); } } diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h index 99d5bf6..def8ad8 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h @@ -23,6 +23,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef PluginObject_h +#define PluginObject_h + #include <WebKit/npfunctions.h> #if defined(XP_MACOSX) @@ -90,3 +93,4 @@ extern bool testWindowOpen(NPP npp); extern void* createCoreAnimationLayer(); #endif +#endif // PluginObject_h diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp index e41e6e5..06c9953 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp @@ -101,28 +101,28 @@ bool PluginTest::NPN_RemoveProperty(NPObject* npObject, NPIdentifier propertyNam return browser->removeproperty(m_npp, npObject, propertyName); } -static void executeScript(NPP npp, const char* script) +void PluginTest::executeScript(const char* script) { NPObject* windowScriptObject; - browser->getvalue(npp, NPNVWindowNPObject, &windowScriptObject); + browser->getvalue(m_npp, NPNVWindowNPObject, &windowScriptObject); NPString npScript; npScript.UTF8Characters = script; npScript.UTF8Length = strlen(script); NPVariant browserResult; - browser->evaluate(npp, windowScriptObject, &npScript, &browserResult); + browser->evaluate(m_npp, windowScriptObject, &npScript, &browserResult); browser->releasevariantvalue(&browserResult); } void PluginTest::waitUntilDone() { - executeScript(m_npp, "layoutTestController.waitUntilDone()"); + executeScript("layoutTestController.waitUntilDone()"); } void PluginTest::notifyDone() { - executeScript(m_npp, "layoutTestController.notifyDone()"); + executeScript("layoutTestController.notifyDone()"); } void PluginTest::registerCreateTestFunction(const string& identifier, CreateTestFunction createTestFunction) diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h index 0497764..ae9bd82 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h @@ -68,6 +68,8 @@ public: NPObject* NPN_CreateObject(NPClass*); bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName); + void executeScript(const char*); + template<typename TestClassTy> class Register { public: Register(const std::string& identifier) diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp index 0b32191..8946c0e 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp @@ -59,18 +59,29 @@ NPClass *getTestClass(void) return &testClass; } -static bool identifiersInitialized = false; +typedef struct { + NPObject header; + NPObject* testObject; +} TestObject; -#define ID_OBJECT_POINTER 2 +static bool identifiersInitialized = false; #define NUM_ENUMERATABLE_TEST_IDENTIFIERS 2 -#define NUM_TEST_IDENTIFIERS 3 + +enum { + ID_PROPERTY_FOO = 0, + ID_PROPERTY_BAR, + ID_PROPERTY_OBJECT_POINTER, + ID_PROPERTY_TEST_OBJECT, + NUM_TEST_IDENTIFIERS, +}; static NPIdentifier testIdentifiers[NUM_TEST_IDENTIFIERS]; static const NPUTF8 *testIdentifierNames[NUM_TEST_IDENTIFIERS] = { "foo", "bar", "objectPointer", + "testObject", }; #define ID_THROW_EXCEPTION_METHOD 0 @@ -87,20 +98,24 @@ static void initializeIdentifiers(void) browser->getstringidentifiers(testMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, testMethodIdentifiers); } -static NPObject *testAllocate(NPP /*npp*/, NPClass* /*theClass*/) +static NPObject* testAllocate(NPP /*npp*/, NPClass* /*theClass*/) { - NPObject *newInstance = static_cast<NPObject*>(malloc(sizeof(NPObject))); - + TestObject* newInstance = static_cast<TestObject*>(malloc(sizeof(TestObject))); + newInstance->testObject = 0; + if (!identifiersInitialized) { identifiersInitialized = true; initializeIdentifiers(); } - - return newInstance; + + return reinterpret_cast<NPObject*>(newInstance); } static void testDeallocate(NPObject *obj) { + TestObject* testObject = reinterpret_cast<TestObject*>(obj); + if (testObject->testObject) + browser->releaseobject(testObject->testObject); free(obj); } @@ -134,17 +149,30 @@ static bool testHasProperty(NPObject*, NPIdentifier name) static bool testGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result) { - if (name == testIdentifiers[ID_OBJECT_POINTER]) { + if (name == testIdentifiers[ID_PROPERTY_FOO]) { + char* mem = static_cast<char*>(browser->memalloc(4)); + strcpy(mem, "foo"); + STRINGZ_TO_NPVARIANT(mem, *result); + return true; + } + if (name == testIdentifiers[ID_PROPERTY_OBJECT_POINTER]) { int32_t objectPointer = static_cast<int32_t>(reinterpret_cast<long long>(npobj)); INT32_TO_NPVARIANT(objectPointer, *result); return true; } + if (name == testIdentifiers[ID_PROPERTY_TEST_OBJECT]) { + TestObject* testObject = reinterpret_cast<TestObject*>(npobj); + if (!testObject->testObject) + testObject->testObject = browser->createobject(0, &testClass); + browser->retainobject(testObject->testObject); + OBJECT_TO_NPVARIANT(testObject->testObject, *result); + return true; + } return false; } - static bool testEnumerate(NPObject* /*npobj*/, NPIdentifier **value, uint32_t *count) { *count = NUM_ENUMERATABLE_TEST_IDENTIFIERS; @@ -163,5 +191,3 @@ static bool testConstruct(NPObject* npobj, const NPVariant* /*args*/, uint32_t / OBJECT_TO_NPVARIANT(npobj, *result); return true; } - - diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp new file mode 100644 index 0000000..4b5d3e0 --- /dev/null +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PluginTest.h" + +#include "PluginObject.h" + +using namespace std; + +// Executing JS after removing the plugin element from the document should not crash. + +class EvaluateJSAfterRemovingPluginElement : public PluginTest { +public: + EvaluateJSAfterRemovingPluginElement(NPP, const string& identifier); + +private: + virtual NPError NPP_DestroyStream(NPStream*, NPReason); + + bool m_didExecuteScript; +}; + +static PluginTest::Register<EvaluateJSAfterRemovingPluginElement> registrar("evaluate-js-after-removing-plugin-element"); + +EvaluateJSAfterRemovingPluginElement::EvaluateJSAfterRemovingPluginElement(NPP npp, const string& identifier) + : PluginTest(npp, identifier) + , m_didExecuteScript(false) +{ + waitUntilDone(); +} + +NPError EvaluateJSAfterRemovingPluginElement::NPP_DestroyStream(NPStream*, NPReason) +{ + if (m_didExecuteScript) + return NPERR_NO_ERROR; + m_didExecuteScript = true; + + executeScript("var plugin = document.getElementsByTagName('embed')[0]; plugin.parentElement.removeChild(plugin);"); + executeScript("document.body.appendChild(document.createTextNode('Executing script after removing the plugin element from the document succeeded.'));"); + notifyDone(); + + return NPERR_NO_ERROR; +} diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp new file mode 100644 index 0000000..2b06198 --- /dev/null +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp @@ -0,0 +1,118 @@ +/* Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "WindowedPluginTest.h" + +#include "PluginObject.h" + +using namespace std; + +// Just fills its window with some gradients + +class DrawsGradient : public WindowedPluginTest { +public: + DrawsGradient(NPP, const string& identifier); + +private: + void paint(HDC) const; + + LRESULT onPaint(WPARAM, LPARAM, bool& handled); + LRESULT onPrintClient(WPARAM, LPARAM, bool& handled); + + virtual LRESULT wndProc(UINT message, WPARAM, LPARAM, bool& handled); +}; + +static PluginTest::Register<DrawsGradient> registrar("draws-gradient"); + +DrawsGradient::DrawsGradient(NPP npp, const string& identifier) + : WindowedPluginTest(npp, identifier) +{ +} + +LRESULT DrawsGradient::wndProc(UINT message, WPARAM wParam, LPARAM lParam, bool& handled) +{ + LRESULT result = 0; + + switch (message) { + case WM_PAINT: + result = onPaint(wParam, lParam, handled); + break; + case WM_PRINTCLIENT: + result = onPrintClient(wParam, lParam, handled); + break; + default: + handled = false; + } + + return result; +} + +LRESULT DrawsGradient::onPaint(WPARAM, LPARAM, bool& handled) +{ + PAINTSTRUCT paintStruct; + HDC dc = ::BeginPaint(window(), &paintStruct); + if (!dc) + return 0; + + paint(dc); + ::EndPaint(window(), &paintStruct); + + handled = true; + return 0; +} + +LRESULT DrawsGradient::onPrintClient(WPARAM wParam, LPARAM, bool& handled) +{ + paint(reinterpret_cast<HDC>(wParam)); + + handled = true; + return 0; +} + +void DrawsGradient::paint(HDC dc) const +{ + RECT clientRect; + if (!::GetClientRect(window(), &clientRect)) + return; + + TRIVERTEX vertices[] = { + // Upper-left: green + { clientRect.left, clientRect.top, 0, 0xff00, 0, 0 }, + // Upper-right: blue + { clientRect.right, clientRect.top, 0, 0, 0xff00, 0 }, + // Lower-left: yellow + { clientRect.left, clientRect.bottom, 0xff00, 0xff00, 0, 0 }, + // Lower-right: red + { clientRect.right, clientRect.bottom, 0xff00, 0, 0, 0 }, + }; + + GRADIENT_TRIANGLE mesh[] = { + // Upper-left triangle + { 0, 1, 2 }, + // Lower-right triangle + { 1, 2, 3 }, + }; + + ::GradientFill(dc, vertices, _countof(vertices), mesh, _countof(mesh), GRADIENT_FILL_TRIANGLE); +} diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp index 90ea54d..e598c49 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp @@ -23,7 +23,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#include "PluginTest.h" +#include "WindowedPluginTest.h" #include "PluginObject.h" @@ -69,28 +69,24 @@ TemporaryWindowMover::~TemporaryWindowMover() ::SetWindowPos(m_window, 0, m_savedWindowRect.left, m_savedWindowRect.top, 0, 0, SWP_HIDEWINDOW | standardSetWindowPosFlags); } -class NPNInvalidateRectInvalidatesWindow : public PluginTest { +class NPNInvalidateRectInvalidatesWindow : public WindowedPluginTest { public: NPNInvalidateRectInvalidatesWindow(NPP, const string& identifier); ~NPNInvalidateRectInvalidatesWindow(); private: - static LRESULT CALLBACK wndProc(HWND, UINT message, WPARAM, LPARAM); + virtual LRESULT wndProc(UINT message, WPARAM, LPARAM, bool& handled); void onPaint(); void testInvalidateRect(); virtual NPError NPP_SetWindow(NPP, NPWindow*); - HWND m_window; - WNDPROC m_originalWndProc; TemporaryWindowMover* m_windowMover; }; NPNInvalidateRectInvalidatesWindow::NPNInvalidateRectInvalidatesWindow(NPP npp, const string& identifier) - : PluginTest(npp, identifier) - , m_window(0) - , m_originalWndProc(0) + : WindowedPluginTest(npp, identifier) , m_windowMover(0) { } @@ -100,30 +96,20 @@ NPNInvalidateRectInvalidatesWindow::~NPNInvalidateRectInvalidatesWindow() delete m_windowMover; } -NPError NPNInvalidateRectInvalidatesWindow::NPP_SetWindow(NPP instance, NPWindow* window) +NPError NPNInvalidateRectInvalidatesWindow::NPP_SetWindow(NPP instance, NPWindow* npWindow) { - HWND newWindow = reinterpret_cast<HWND>(window->window); - if (newWindow == m_window) - return NPERR_NO_ERROR; - - if (m_window) { - ::RemovePropW(m_window, instancePointerProperty); - ::SetWindowLongPtr(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_originalWndProc)); - m_originalWndProc = 0; - } + NPError error = WindowedPluginTest::NPP_SetWindow(instance, npWindow); + if (error != NPERR_NO_ERROR) + return error; - m_window = newWindow; - if (!m_window) + if (!window()) return NPERR_NO_ERROR; - m_originalWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtrW(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wndProc))); - ::SetPropW(m_window, instancePointerProperty, this); - // The test harness's window (the one that contains the WebView) is off-screen and hidden. // We need to move it on-screen and make it visible in order for the plugin's window to // accumulate an update region when the DWM is disabled. - HWND testHarnessWindow = ::GetAncestor(m_window, GA_ROOT); + HWND testHarnessWindow = ::GetAncestor(window(), GA_ROOT); if (!testHarnessWindow) { pluginLog(instance, "Failed to get test harness window"); return NPERR_GENERIC_ERROR; @@ -141,14 +127,13 @@ NPError NPNInvalidateRectInvalidatesWindow::NPP_SetWindow(NPP instance, NPWindow return NPERR_NO_ERROR; } -LRESULT NPNInvalidateRectInvalidatesWindow::wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT NPNInvalidateRectInvalidatesWindow::wndProc(UINT message, WPARAM wParam, LPARAM lParam, bool& handled) { - NPNInvalidateRectInvalidatesWindow* instance = reinterpret_cast<NPNInvalidateRectInvalidatesWindow*>(::GetPropW(hwnd, instancePointerProperty)); - if (message == WM_PAINT) - instance->onPaint(); + onPaint(); - return ::CallWindowProcW(instance->m_originalWndProc, hwnd, message, wParam, lParam); + handled = false; + return 0; } void NPNInvalidateRectInvalidatesWindow::onPaint() @@ -162,7 +147,7 @@ void NPNInvalidateRectInvalidatesWindow::onPaint() void NPNInvalidateRectInvalidatesWindow::testInvalidateRect() { RECT clientRect; - if (!::GetClientRect(m_window, &clientRect)) { + if (!::GetClientRect(window(), &clientRect)) { pluginLog(m_npp, "::GetClientRect failed"); return; } @@ -173,7 +158,7 @@ void NPNInvalidateRectInvalidatesWindow::testInvalidateRect() } // Clear the invalid region. - if (!::ValidateRect(m_window, 0)) { + if (!::ValidateRect(window(), 0)) { pluginLog(m_npp, "::ValidateRect failed"); return; } @@ -187,7 +172,7 @@ void NPNInvalidateRectInvalidatesWindow::testInvalidateRect() NPN_InvalidateRect(&rectToInvalidate); RECT invalidRect; - if (!::GetUpdateRect(m_window, &invalidRect, FALSE)) { + if (!::GetUpdateRect(window(), &invalidRect, FALSE)) { pluginLog(m_npp, "::GetUpdateRect failed"); return; } diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp new file mode 100644 index 0000000..975a598 --- /dev/null +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PluginTest.h" + +#include "PluginObject.h" + +using namespace std; + +// The plugin's window's window region should be set to the plugin's clip rect. + +class WindowRegionIsSetToClipRect : public PluginTest { +public: + WindowRegionIsSetToClipRect(NPP, const string& identifier); + +private: + virtual NPError NPP_SetWindow(NPP, NPWindow*); + + bool m_didReceiveInitialSetWindowCall; +}; + +static PluginTest::Register<WindowRegionIsSetToClipRect> registrar("window-region-is-set-to-clip-rect"); + +WindowRegionIsSetToClipRect::WindowRegionIsSetToClipRect(NPP npp, const string& identifier) + : PluginTest(npp, identifier) + , m_didReceiveInitialSetWindowCall(false) +{ +} + +NPError WindowRegionIsSetToClipRect::NPP_SetWindow(NPP instance, NPWindow* window) +{ + if (m_didReceiveInitialSetWindowCall) + return NPERR_NO_ERROR; + m_didReceiveInitialSetWindowCall = true; + + if (window->type != NPWindowTypeWindow) { + pluginLog(instance, "window->type should be NPWindowTypeWindow but was %d", window->type); + return NPERR_GENERIC_ERROR; + } + + HWND hwnd = reinterpret_cast<HWND>(window->window); + + RECT regionRect; + if (::GetWindowRgnBox(hwnd, ®ionRect) == ERROR) { + pluginLog(instance, "::GetWindowRgnBox failed with error %u", ::GetLastError()); + return NPERR_GENERIC_ERROR; + } + + // This expected rect is based on the layout of window-region-is-set-to-clip-rect.html. + RECT expectedRect = { 50, 50, 100, 100 }; + if (!::EqualRect(®ionRect, &expectedRect)) { + pluginLog(instance, "Expected region rect {left=%u, top=%u, right=%u, bottom=%u}, but got {left=%d, top=%d, right=%d, bottom=%d}", expectedRect.left, expectedRect.top, expectedRect.right, expectedRect.bottom, regionRect.left, regionRect.top, regionRect.right, regionRect.bottom); + return NPERR_GENERIC_ERROR; + } + + pluginLog(instance, "PASS: Plugin's window's window region has been set as expected"); + + // While we're here, check that our window class doesn't have the CS_PARENTDC style, which + // defeats clipping by ignoring the window region and always clipping to the parent window. + // FIXME: It would be nice to have a pixel test that shows that we're + // getting clipped correctly, but unfortunately window regions are ignored + // during WM_PRINT (see <http://webkit.org/b/49034>). + wchar_t className[512]; + if (!::GetClassNameW(hwnd, className, _countof(className))) { + pluginLog(instance, "::GetClassName failed with error %u", ::GetLastError()); + return NPERR_GENERIC_ERROR; + } + +#ifdef DEBUG_ALL + const wchar_t webKitDLLName[] = L"WebKit_debug.dll"; +#else + const wchar_t webKitDLLName[] = L"WebKit.dll"; +#endif + HMODULE webKitModule = ::GetModuleHandleW(webKitDLLName); + if (!webKitModule) { + pluginLog(instance, "::GetModuleHandleW failed with error %u", ::GetLastError()); + return NPERR_GENERIC_ERROR; + } + + WNDCLASSW wndClass; + if (!::GetClassInfoW(webKitModule, className, &wndClass)) { + pluginLog(instance, "::GetClassInfoW failed with error %u", ::GetLastError()); + return NPERR_GENERIC_ERROR; + } + + if (wndClass.style & CS_PARENTDC) + pluginLog(instance, "FAIL: Plugin's window's class has the CS_PARENTDC style, which will defeat clipping"); + else + pluginLog(instance, "PASS: Plugin's window's class does not have the CS_PARENTDC style"); + + return NPERR_NO_ERROR; +} diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp index e5246c4..2110a8a 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp @@ -29,6 +29,10 @@ #include <cstdlib> #include <string> +#ifdef XP_UNIX +#include <X11/Xlib.h> +#endif + #if !defined(NP_NO_CARBON) && defined(QD_HEADERS_ARE_PRIVATE) && QD_HEADERS_ARE_PRIVATE extern "C" void GlobalToLocal(Point*); #endif @@ -565,6 +569,54 @@ static int16_t handleEventCocoa(NPP instance, PluginObject* obj, NPCocoaEvent* e #endif // XP_MACOSX +#ifdef XP_UNIX +static int16_t handleEventX11(NPP instance, PluginObject* obj, XEvent* event) +{ + XButtonPressedEvent* buttonPressEvent = reinterpret_cast<XButtonPressedEvent*>(event); + XButtonReleasedEvent* buttonReleaseEvent = reinterpret_cast<XButtonReleasedEvent*>(event); + switch (event->type) { + case ButtonPress: + pluginLog(instance, "mouseDown at (%d, %d)", buttonPressEvent->x, buttonPressEvent->y); + if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript) + executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown); + break; + case ButtonRelease: + pluginLog(instance, "mouseUp at (%d, %d)", buttonReleaseEvent->x, buttonReleaseEvent->y); + break; + case KeyPress: + // FIXME: extract key code + pluginLog(instance, "NOTIMPLEMENTED: keyDown '%c'", ' '); + if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript) + executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown); + break; + case KeyRelease: + // FIXME: extract key code + pluginLog(instance, "NOTIMPLEMENTED: keyUp '%c'", ' '); + break; + case GraphicsExpose: + pluginLog(instance, "updateEvt"); + break; + // NPAPI events + case FocusIn: + pluginLog(instance, "getFocusEvent"); + break; + case FocusOut: + pluginLog(instance, "loseFocusEvent"); + break; + case EnterNotify: + case LeaveNotify: + case MotionNotify: + pluginLog(instance, "adjustCursorEvent"); + break; + default: + pluginLog(instance, "event %d", event->type); + } + + fflush(stdout); + return 0; +} +#endif // XP_UNIX + int16_t NPP_HandleEvent(NPP instance, void *event) { PluginObject* obj = static_cast<PluginObject*>(instance->pdata); @@ -579,6 +631,8 @@ int16_t NPP_HandleEvent(NPP instance, void *event) assert(obj->eventModel == NPEventModelCocoa); return handleEventCocoa(instance, obj, static_cast<NPCocoaEvent*>(event)); +#elif defined(XP_UNIX) + return handleEventX11(instance, obj, static_cast<XEvent*>(event)); #else // FIXME: Implement for other platforms. return 0; diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj index 74042bc..a2e6809 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj @@ -39,7 +39,7 @@ />
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(ProjectDir)..\..\TestNetscapePlugin";"$(WebKitLibrariesDir)\include""
+ AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)..";"$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include""
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
DisableSpecificWarnings="4819"
/>
@@ -55,6 +55,7 @@ />
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -109,7 +110,7 @@ />
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(ProjectDir)..\..\TestNetscapePlugin";"$(WebKitLibrariesDir)\include""
+ AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)..";"$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include""
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
DisableSpecificWarnings="4819"
/>
@@ -125,6 +126,7 @@ />
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -178,7 +180,7 @@ />
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(ProjectDir)..\..\TestNetscapePlugin";"$(WebKitLibrariesDir)\include""
+ AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)..";"$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include""
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
RuntimeLibrary="3"
DisableSpecificWarnings="4819"
@@ -195,6 +197,7 @@ />
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -248,7 +251,7 @@ />
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(ProjectDir)..\..\TestNetscapePlugin";"$(WebKitLibrariesDir)\include""
+ AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)..";"$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include""
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
DisableSpecificWarnings="4819"
/>
@@ -264,6 +267,7 @@ />
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -317,7 +321,7 @@ />
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(ProjectDir)..\..\TestNetscapePlugin";"$(WebKitLibrariesDir)\include""
+ AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)..";"$(WebKitOutputDir)\Include";"$(WebKitOutputDir)\Include\JavaScriptCore";"$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include""
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
RuntimeLibrary="3"
DisableSpecificWarnings="4819"
@@ -334,6 +338,7 @@ />
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -375,6 +380,10 @@ >
</File>
<File
+ RelativePath="..\Tests\EvaluateJSAfterRemovingPluginElement.cpp"
+ >
+ </File>
+ <File
RelativePath="..\Tests\NPRuntimeObjectFromDestroyedPlugin.cpp"
>
</File>
@@ -398,6 +407,10 @@ Name="win"
>
<File
+ RelativePath="..\Tests\win\DrawsGradient.cpp"
+ >
+ </File>
+ <File
RelativePath="..\Tests\win\GetValueNetscapeWindow.cpp"
>
</File>
@@ -409,8 +422,24 @@ RelativePath="..\Tests\win\WindowGeometryInitializedBeforeSetWindow.cpp"
>
</File>
+ <File
+ RelativePath="..\Tests\win\WindowRegionIsSetToClipRect.cpp"
+ >
+ </File>
</Filter>
</Filter>
+ <Filter
+ Name="win"
+ >
+ <File
+ RelativePath=".\WindowedPluginTest.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\WindowedPluginTest.h"
+ >
+ </File>
+ </Filter>
<File
RelativePath="..\main.cpp"
>
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp new file mode 100644 index 0000000..96b51f8 --- /dev/null +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "WindowedPluginTest.h" + +using namespace std; + +static const wchar_t instancePointerProperty[] = L"org.webkit.TestNetscapePlugin.WindowedPluginTest.InstancePointer"; + +WindowedPluginTest::WindowedPluginTest(NPP npp, const string& identifier) + : PluginTest(npp, identifier) + , m_window(0) + , m_originalWndProc(0) +{ +} + +NPError WindowedPluginTest::NPP_SetWindow(NPP instance, NPWindow* window) +{ + HWND newWindow = reinterpret_cast<HWND>(window->window); + if (newWindow == m_window) + return NPERR_NO_ERROR; + + if (m_window) { + ::RemovePropW(m_window, instancePointerProperty); + ::SetWindowLongPtr(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_originalWndProc)); + m_originalWndProc = 0; + } + + m_window = newWindow; + if (!m_window) + return NPERR_NO_ERROR; + + m_originalWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtrW(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(staticWndProc))); + ::SetPropW(m_window, instancePointerProperty, this); + + return NPERR_NO_ERROR; +} + +LRESULT WindowedPluginTest::staticWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WindowedPluginTest* instance = reinterpret_cast<WindowedPluginTest*>(::GetPropW(hwnd, instancePointerProperty)); + + bool handled = false; + LRESULT result = instance->wndProc(message, wParam, lParam, handled); + if (handled) + return result; + + return ::CallWindowProcW(instance->m_originalWndProc, hwnd, message, wParam, lParam); +} diff --git a/WebCore/history/BackForwardControllerClient.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.h index 289ad12..7abc734 100644 --- a/WebCore/history/BackForwardControllerClient.h +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.h @@ -23,26 +23,28 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef BackForwardControllerClient_h -#define BackForwardControllerClient_h +#ifndef WindowedPluginTest_h +#define WindowedPluginTest_h -#include "BackForwardList.h" -#include <wtf/PassRefPtr.h> +#include "PluginTest.h" -namespace WebCore { +class WindowedPluginTest : public PluginTest { +protected: + WindowedPluginTest(NPP, const std::string& identifier); -class Page; + HWND window() const { return m_window; } -class BackForwardControllerClient { -public: - virtual void backForwardControllerDestroyed() = 0; + // For derived classes to override + virtual LRESULT wndProc(UINT message, WPARAM, LPARAM, bool& handled) = 0; - virtual PassRefPtr<BackForwardList> createBackForwardList(Page*) = 0; + // PluginTest + virtual NPError NPP_SetWindow(NPP, NPWindow*); -protected: - virtual ~BackForwardControllerClient() { } -}; +private: + static LRESULT CALLBACK staticWndProc(HWND, UINT message, WPARAM, LPARAM); -} // namespace WebCore + HWND m_window; + WNDPROC m_originalWndProc; +}; -#endif // BackForwardControllerClient_h +#endif // WindowedPluginTest_h diff --git a/WebKitTools/DumpRenderTree/chromium/EventSender.cpp b/WebKitTools/DumpRenderTree/chromium/EventSender.cpp index e250dfc..ec16cf7 100644 --- a/WebKitTools/DumpRenderTree/chromium/EventSender.cpp +++ b/WebKitTools/DumpRenderTree/chromium/EventSender.cpp @@ -873,6 +873,7 @@ void EventSender::sendCurrentTouchEvent(const WebInputEvent::Type type) WebTouchEvent touchEvent; touchEvent.type = type; touchEvent.modifiers = touchModifiers; + touchEvent.timeStampSeconds = getCurrentEventTimeSec(); touchEvent.touchPointsLength = touchPoints.size(); for (unsigned i = 0; i < touchPoints.size(); ++i) touchEvent.touchPoints[i] = touchPoints[i]; diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp index d713b04..5b0c844 100644 --- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp +++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp @@ -71,6 +71,8 @@ using namespace std; LayoutTestController::LayoutTestController(TestShell* shell) : m_shell(shell) + , m_closeRemainingWindows(false) + , m_deferMainResourceDataLoad(false) , m_workQueue(this) { @@ -1486,6 +1488,9 @@ void LayoutTestController::setEditingBehavior(const CppArgumentList& arguments, } else if (key == "win") { m_shell->preferences()->editingBehavior = WebSettings::EditingBehaviorWin; m_shell->applyPreferences(); + } else if (key == "unix") { + m_shell->preferences()->editingBehavior = WebSettings::EditingBehaviorUnix; + m_shell->applyPreferences(); } else logErrorToConsole("Passed invalid editing behavior. Should be 'mac' or 'win'."); } diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.h b/WebKitTools/DumpRenderTree/chromium/TestShell.h index ca06812..06e77cc 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShell.h +++ b/WebKitTools/DumpRenderTree/chromium/TestShell.h @@ -144,7 +144,7 @@ public: // The JavaScript flags are specified as a vector of strings. Each element of the vector is full flags string // which can contain multiple flags (e.g. "--xxx --yyy"). With multiple load testing it is possible to specify // separate sets of flags to each load. - std::string javaScriptFlagsForLoad(size_t load) { return (load >= 0 && load < m_javaScriptFlags.size()) ? m_javaScriptFlags[load] : ""; } + std::string javaScriptFlagsForLoad(size_t load) { return (load < m_javaScriptFlags.size()) ? m_javaScriptFlags[load] : ""; } void setJavaScriptFlags(Vector<std::string> javaScriptFlags) { m_javaScriptFlags = javaScriptFlags; } // Set whether to dump when the loaded page has finished processing. This is used with multiple load diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp index 847e7dc..2f9bdfb 100644 --- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp +++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp @@ -940,11 +940,16 @@ void WebViewHost::didChangeLocationWithinPage(WebFrame* frame) void WebViewHost::assignIdentifierToRequest(WebFrame*, unsigned identifier, const WebURLRequest& request) { - if (!m_shell->shouldDumpResourceLoadCallbacks()) - return; + ASSERT(!m_resourceIdentifierMap.contains(identifier)); m_resourceIdentifierMap.set(identifier, descriptionSuitableForTestResult(request.url().spec())); } +void WebViewHost::removeIdentifierForRequest(unsigned identifier) +{ + ASSERT(m_resourceIdentifierMap.contains(identifier)); + m_resourceIdentifierMap.remove(identifier); +} + void WebViewHost::willSendRequest(WebFrame*, unsigned identifier, WebURLRequest& request, const WebURLResponse& redirectResponse) { // Need to use GURL for host() and SchemeIs() @@ -1022,7 +1027,7 @@ void WebViewHost::didFinishResourceLoad(WebFrame*, unsigned identifier) printResourceDescription(identifier); fputs(" - didFinishLoading\n", stdout); } - m_resourceIdentifierMap.remove(identifier); + removeIdentifierForRequest(identifier); } void WebViewHost::didFailResourceLoad(WebFrame*, unsigned identifier, const WebURLError& error) @@ -1033,7 +1038,7 @@ void WebViewHost::didFailResourceLoad(WebFrame*, unsigned identifier, const WebU fputs(webkit_support::MakeURLErrorDescription(error).c_str(), stdout); fputs("\n", stdout); } - m_resourceIdentifierMap.remove(identifier); + removeIdentifierForRequest(identifier); } void WebViewHost::didDisplayInsecureContent(WebFrame*) diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h index 1380ebd..f21e663 100644 --- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h +++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h @@ -185,6 +185,7 @@ class WebViewHost : public WebKit::WebViewClient, public WebKit::WebFrameClient, virtual void didNavigateWithinPage(WebKit::WebFrame*, bool isNewNavigation); virtual void didChangeLocationWithinPage(WebKit::WebFrame*); virtual void assignIdentifierToRequest(WebKit::WebFrame*, unsigned identifier, const WebKit::WebURLRequest&); + virtual void removeIdentifierForRequest(unsigned identifier); virtual void willSendRequest(WebKit::WebFrame*, unsigned identifier, WebKit::WebURLRequest&, const WebKit::WebURLResponse&); virtual void didReceiveResponse(WebKit::WebFrame*, unsigned identifier, const WebKit::WebURLResponse&); virtual void didFinishResourceLoad(WebKit::WebFrame*, unsigned identifier); diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp index 1c851d7..54acc49 100644 --- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -137,10 +137,9 @@ static void initializeGtkFontSettings(const char* testURL) GtkSettings* settings = gtk_settings_get_default(); if (!settings) return; - g_object_set(settings, "gtk-xft-antialias", 1, NULL); - g_object_set(settings, "gtk-xft-hinting", 1, NULL); - g_object_set(settings, "gtk-xft-hintstyle", "hintfull", NULL); - g_object_set(settings, "gtk-font-name", "Liberation Sans 16", NULL); + g_object_set(settings, "gtk-xft-antialias", 1, + "gtk-xft-hinting", 0, + "gtk-font-name", "Liberation Sans 16", NULL); // One test needs subpixel anti-aliasing turned on, but generally we // want all text in other tests to use to grayscale anti-aliasing. diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 688b3f8..ab70a3e 100644 --- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -813,8 +813,10 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior) if (!strcmp(editingBehavior, "win")) g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_WINDOWS, NULL); - if (!strcmp(editingBehavior, "mac")) + else if (!strcmp(editingBehavior, "mac")) g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_MAC, NULL); + else if (!strcmp(editingBehavior, "unix")) + g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_UNIX, NULL); } void LayoutTestController::abortModal() diff --git a/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf b/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf index 6eb057e..2d9af17 100644 --- a/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf +++ b/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf @@ -2,6 +2,19 @@ <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> + <!-- Due to patent (http://freetype.sourceforge.net/patents.html) + issues hinting gives different results depending on the + freetype version of the linux distribution, avoiding hinting + gives more consistent results. When all the distributions + release freetype the 2.4, which enables by default the + hinting method that was patented, we could undo this change + and try the hinting again. --> + <match target="font"> + <edit name="hinting" mode="assign"> + <bool>false</bool> + </edit> + </match> + <!-- The sans-serif font should be Liberation Serif --> <match target="pattern"> <test qual="any" name="family"> @@ -158,6 +171,9 @@ <edit name="family" mode="assign"> <string>Liberation Serif</string> </edit> + <edit name="hinting" mode="assign"> + <bool>true</bool> + </edit> <edit name="hintstyle" mode="assign"> <const>hintslight</const> </edit> @@ -175,7 +191,7 @@ <edit name="hintstyle" mode="assign"> <const>hintfull</const> </edit> - <edit name="hinting" mode="assign"> + <edit name="hinting" mode="assign"> <bool>false</bool> </edit> </match> @@ -187,6 +203,9 @@ <edit name="family" mode="assign"> <string>Liberation Serif</string> </edit> + <edit name="hinting" mode="assign"> + <bool>true</bool> + </edit> <edit name="autohint" mode="assign"> <bool>true</bool> </edit> @@ -202,6 +221,9 @@ <edit name="family" mode="assign"> <string>Liberation Serif</string> </edit> + <edit name="hinting" mode="assign"> + <bool>true</bool> + </edit> <edit name="autohint" mode="assign"> <bool>false</bool> </edit> @@ -217,6 +239,9 @@ <edit name="family" mode="assign"> <string>Liberation Serif</string> </edit> + <edit name="hinting" mode="assign"> + <bool>true</bool> + </edit> <edit name="autohint" mode="assign"> <bool>true</bool> </edit> diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm index 150b6f9..431d4e9 100644 --- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm +++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm @@ -935,8 +935,10 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior) NSString* editingBehaviorNS = [[NSString alloc] initWithUTF8String:editingBehavior]; if ([editingBehaviorNS isEqualToString:@"mac"]) [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingMacBehavior]; - if ([editingBehaviorNS isEqualToString:@"win"]) + else if ([editingBehaviorNS isEqualToString:@"win"]) [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingWinBehavior]; + else if ([editingBehaviorNS isEqualToString:@"unix"]) + [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingUnixBehavior]; [editingBehaviorNS release]; } diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp index f99ec4f..3e50e06 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp @@ -810,5 +810,10 @@ bool LayoutTestController::hasSpellingMarker(int, int) return false; } +QVariantList LayoutTestController::nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping) +{ + return DumpRenderTreeSupportQt::nodesFromRect(document, x, y, top, right, bottom, left, ignoreClipping); +} + const unsigned LayoutTestController::maxViewWidth = 800; const unsigned LayoutTestController::maxViewHeight = 600; diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h index 11d72e4..dfb12fe 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h @@ -222,6 +222,8 @@ public slots: void abortModal() {} bool hasSpellingMarker(int from, int length); + QVariantList nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping); + /* Policy values: 'on', 'auto' or 'off'. Orientation values: 'vertical' or 'horizontal'. diff --git a/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro b/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro index b958025..1d460d7 100644 --- a/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro +++ b/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro @@ -29,6 +29,7 @@ SOURCES = PluginObject.cpp \ PluginTest.cpp \ TestObject.cpp \ Tests/DocumentOpenInDestroyStream.cpp \ + Tests/EvaluateJSAfterRemovingPluginElement.cpp \ Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \ Tests/NPRuntimeRemoveProperty.cpp \ Tests/NullNPPGetValuePointer.cpp \ diff --git a/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp b/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp index 14bb8ef..2298ef1 100644 --- a/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp +++ b/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp @@ -372,7 +372,9 @@ webkit_test_plugin_set_value(NPP instance, NPNVariable variable, void* value) char * NP_GetMIMEDescription(void) { - return const_cast<char*>("application/x-webkit-test-netscape:testnetscape:test netscape content"); + // We sentence-case the mime-type here to ensure that ports are not + // case-sensitive when loading plugins. See https://webkit.org/b/36815 + return const_cast<char*>("application/x-Webkit-Test-Netscape:testnetscape:test netscape content"); } NPError diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp index 5138562..7c3d9b3 100644 --- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp @@ -98,7 +98,6 @@ PolicyDelegate* policyDelegate; COMPtr<FrameLoadDelegate> sharedFrameLoadDelegate; COMPtr<UIDelegate> sharedUIDelegate; COMPtr<EditingDelegate> sharedEditingDelegate; -COMPtr<ResourceLoadDelegate> sharedResourceLoadDelegate; COMPtr<HistoryDelegate> sharedHistoryDelegate; IWebFrame* frame; @@ -1201,7 +1200,10 @@ IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow) if (FAILED(viewEditing->setEditingDelegate(sharedEditingDelegate.get()))) return 0; - if (FAILED(webView->setResourceLoadDelegate(sharedResourceLoadDelegate.get()))) + ResourceLoadDelegate* resourceLoadDelegate = new ResourceLoadDelegate(); + HRESULT result = webView->setResourceLoadDelegate(resourceLoadDelegate); + resourceLoadDelegate->Release(); // The delegate is owned by the WebView, so release our reference to it. + if (FAILED(result)) return 0; openWindows().append(hostWindow); @@ -1285,7 +1287,6 @@ int main(int argc, char* argv[]) sharedFrameLoadDelegate.adoptRef(new FrameLoadDelegate); sharedUIDelegate.adoptRef(new UIDelegate); sharedEditingDelegate.adoptRef(new EditingDelegate); - sharedResourceLoadDelegate.adoptRef(new ResourceLoadDelegate); sharedHistoryDelegate.adoptRef(new HistoryDelegate); // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592> diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp index d7c41e0..386f118 100644 --- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp +++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp @@ -1383,8 +1383,10 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior) string behaviorString(editingBehavior); if (behaviorString == "mac") preferences->setEditingBehavior(WebKitEditingMacBehavior); - if (behaviorString == "win") + else if (behaviorString == "win") preferences->setEditingBehavior(WebKitEditingWinBehavior); + else if (behaviorString == "unix") + preferences->setEditingBehavior(WebKitEditingUnixBehavior); } void LayoutTestController::abortModal() diff --git a/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp b/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp index b0c76d6..752cc39 100644 --- a/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp +++ b/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp @@ -63,7 +63,7 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool inc HDC memoryDC = CreateCompatibleDC(0); SelectObject(memoryDC, bitmap); - SendMessage(webViewWindow, WM_PRINTCLIENT, reinterpret_cast<WPARAM>(memoryDC), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED); + SendMessage(webViewWindow, WM_PRINT, reinterpret_cast<WPARAM>(memoryDC), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED); DeleteDC(memoryDC); BITMAP info = {0}; @@ -73,7 +73,7 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool inc #if PLATFORM(CG) RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8, - info.bmWidthBytes, colorSpace.get(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); + info.bmWidthBytes, colorSpace.get(), kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst); #elif PLATFORM(CAIRO) cairo_surface_t* image = cairo_image_surface_create_for_data((unsigned char*)info.bmBits, CAIRO_FORMAT_ARGB32, info.bmWidth, info.bmHeight, info.bmWidthBytes); diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp index 825366a..09b07d6 100644 --- a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp +++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp @@ -35,7 +35,6 @@ #include <comutil.h> #include <sstream> #include <tchar.h> -#include <wtf/HashMap.h> #include <wtf/Vector.h> using namespace std; @@ -60,26 +59,17 @@ static inline BSTR BSTRFromString(const string& str) return result; } -typedef HashMap<unsigned long, wstring> IdentifierMap; - -IdentifierMap& urlMap() -{ - static IdentifierMap urlMap; - - return urlMap; -} - -static wstring descriptionSuitableForTestResult(unsigned long identifier) +wstring ResourceLoadDelegate::descriptionSuitableForTestResult(unsigned long identifier) const { - IdentifierMap::iterator it = urlMap().find(identifier); + IdentifierMap::const_iterator it = m_urlMap.find(identifier); - if (it == urlMap().end()) + if (it == m_urlMap.end()) return L"<unknown>"; return urlSuitableForTestResult(it->second); } -static wstring descriptionSuitableForTestResult(IWebURLRequest* request) +wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebURLRequest* request) { if (!request) return L"(null)"; @@ -108,7 +98,7 @@ static wstring descriptionSuitableForTestResult(IWebURLRequest* request) return L"<NSURLRequest URL " + url + L", main document URL " + mainDocumentURL + L", http method " + httpMethod + L">"; } -static wstring descriptionSuitableForTestResult(IWebURLResponse* response) +wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebURLResponse* response) { if (!response) return L"(null)"; @@ -128,7 +118,7 @@ static wstring descriptionSuitableForTestResult(IWebURLResponse* response) return L"<NSURLResponse " + url + L", http status code " + wstringFromInt(statusCode) + L">"; } -static wstring descriptionSuitableForTestResult(IWebError* error, unsigned long identifier) +wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebError* error, unsigned long identifier) const { wstring result = L"<NSError "; @@ -197,6 +187,8 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::QueryInterface(REFIID riid, void *ppvObject = static_cast<IWebResourceLoadDelegate*>(this); else if (IsEqualGUID(riid, IID_IWebResourceLoadDelegate)) *ppvObject = static_cast<IWebResourceLoadDelegate*>(this); + else if (IsEqualGUID(riid, IID_IWebResourceLoadDelegatePrivate2)) + *ppvObject = static_cast<IWebResourceLoadDelegatePrivate2*>(this); else return E_NOINTERFACE; @@ -229,12 +221,22 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::identifierForInitialRequest( if (FAILED(request->URL(&urlStr))) return E_FAIL; + ASSERT(!urlMap().contains(identifier)); urlMap().set(identifier, wstringFromBSTR(urlStr)); } return S_OK; } +HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::removeIdentifierForRequest( + /* [in] */ IWebView* webView, + /* [in] */ unsigned long identifier) +{ + urlMap().remove(identifier); + + return S_OK; +} + HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::willSendRequest( /* [in] */ IWebView* webView, /* [in] */ unsigned long identifier, @@ -351,11 +353,12 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFinishLoadingFromDataSource( { if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) { printf("%S - didFinishLoading\n", - descriptionSuitableForTestResult(identifier).c_str()), - urlMap().remove(identifier); + descriptionSuitableForTestResult(identifier).c_str()); } - return S_OK; + removeIdentifierForRequest(webView, identifier); + + return S_OK; } HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFailLoadingWithError( @@ -368,8 +371,9 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFailLoadingWithError( printf("%S - didFailLoadingWithError: %S\n", descriptionSuitableForTestResult(identifier).c_str(), descriptionSuitableForTestResult(error, identifier).c_str()); - urlMap().remove(identifier); } + removeIdentifierForRequest(webView, identifier); + return S_OK; } diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h index 924727b..3f20f47 100644 --- a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h +++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h @@ -30,8 +30,10 @@ #define ResourceLoadDelegate_h #include <WebKit/WebKit.h> +#include <string> +#include <wtf/HashMap.h> -class ResourceLoadDelegate : public IWebResourceLoadDelegate { +class ResourceLoadDelegate : public IWebResourceLoadDelegate, public IWebResourceLoadDelegatePrivate2 { public: ResourceLoadDelegate(); virtual ~ResourceLoadDelegate(); @@ -95,8 +97,22 @@ public: /* [in] */ IWebView *webView, /* [in] */ IWebError *error, /* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; } + + // IWebResourceLoadDelegatePrivate2 + virtual HRESULT STDMETHODCALLTYPE removeIdentifierForRequest( + /* [in] */ IWebView *webView, + /* [in] */ unsigned long identifier); -protected: +private: + static std::wstring descriptionSuitableForTestResult(IWebURLRequest*); + static std::wstring descriptionSuitableForTestResult(IWebURLResponse*); + std::wstring descriptionSuitableForTestResult(unsigned long) const; + std::wstring descriptionSuitableForTestResult(IWebError*, unsigned long) const; + + typedef HashMap<unsigned long, std::wstring> IdentifierMap; + IdentifierMap& urlMap() { return m_urlMap; } + IdentifierMap m_urlMap; + ULONG m_refCount; }; diff --git a/WebKitTools/GNUmakefile.am b/WebKitTools/GNUmakefile.am index 2700869..d20b3b5 100644 --- a/WebKitTools/GNUmakefile.am +++ b/WebKitTools/GNUmakefile.am @@ -167,6 +167,7 @@ TestNetscapePlugin_libtestnetscapeplugin_la_SOURCES = \ WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/ForwardingHeaders/WebKit/npruntime.h \ WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/DocumentOpenInDestroyStream.cpp \ + WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NPRuntimeRemoveProperty.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp \ diff --git a/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m b/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m index 1fffce6..f3d44a5 100644 --- a/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m +++ b/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m @@ -88,7 +88,7 @@ void didRecieveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef me CFRelease(cfMessageName); } -void WKBundleInitialize(WKBundleRef bundle) +void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData) { globalBundle = bundle; diff --git a/WebKitTools/QtTestBrowser/QtTestBrowser.pro b/WebKitTools/QtTestBrowser/QtTestBrowser.pro index 08e0fb8..62d2c02 100644 --- a/WebKitTools/QtTestBrowser/QtTestBrowser.pro +++ b/WebKitTools/QtTestBrowser/QtTestBrowser.pro @@ -49,6 +49,7 @@ linux-* { symbian { TARGET.UID3 = 0xA000E543 TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices Location + MMP_RULES *= pageddata } contains(QT_CONFIG, opengl) { diff --git a/WebKitTools/QtTestBrowser/launcherwindow.cpp b/WebKitTools/QtTestBrowser/launcherwindow.cpp index e5e49be..7608063 100644 --- a/WebKitTools/QtTestBrowser/launcherwindow.cpp +++ b/WebKitTools/QtTestBrowser/launcherwindow.cpp @@ -70,12 +70,11 @@ void LauncherWindow::init() resize(800, 600); #endif - m_inspector = new WebInspector(splitter); + m_inspector = new WebInspector; #ifndef QT_NO_PROPERTIES if (!m_windowOptions.inspectorUrl.isEmpty()) m_inspector->setProperty("_q_inspectorUrl", m_windowOptions.inspectorUrl); #endif - m_inspector->hide(); connect(this, SIGNAL(destroyed()), m_inspector, SLOT(deleteLater())); // the zoom values are chosen to be like in Mozilla Firefox 3 @@ -130,6 +129,7 @@ void LauncherWindow::initializeView() applyPrefs(); + splitter->addWidget(m_inspector); m_inspector->setPage(page()); m_inspector->hide(); diff --git a/WebKitTools/QtTestBrowser/useragentlist.txt b/WebKitTools/QtTestBrowser/useragentlist.txt index b4b00f6..1c424d9 100644 --- a/WebKitTools/QtTestBrowser/useragentlist.txt +++ b/WebKitTools/QtTestBrowser/useragentlist.txt @@ -3,6 +3,7 @@ Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0; en-GB) AppleWebKit/533.3 (KHTML, li Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/125.2 (KHTML, like Gecko) Safari/125.8 Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2 Mozilla/5.0 (iPhone; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10 +Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7 Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10 Opera/9.25 (Windows NT 6.0; U; en) Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Nokia5800d-1b/20.2.014; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413 diff --git a/WebKitTools/QtTestBrowser/webinspector.h b/WebKitTools/QtTestBrowser/webinspector.h index d251c5c..5cc7f8a 100644 --- a/WebKitTools/QtTestBrowser/webinspector.h +++ b/WebKitTools/QtTestBrowser/webinspector.h @@ -35,7 +35,7 @@ class WebInspector : public QWebInspector { Q_OBJECT public: - WebInspector(QWidget* parent) : QWebInspector(parent) {} + WebInspector(QWidget* parent = 0) : QWebInspector(parent) {} signals: void visibleChanged(bool nowVisible); diff --git a/WebKitTools/QtTestBrowser/webview.cpp b/WebKitTools/QtTestBrowser/webview.cpp index 242daf6..fffaf9c 100644 --- a/WebKitTools/QtTestBrowser/webview.cpp +++ b/WebKitTools/QtTestBrowser/webview.cpp @@ -59,9 +59,26 @@ WebViewGraphicsBased::WebViewGraphicsBased(QWidget* parent) void WebViewGraphicsBased::setPage(QWebPage* page) { connect(page->mainFrame(), SIGNAL(contentsSizeChanged(const QSize&)), SLOT(contentsSizeChanged(const QSize&))); + connect(page, SIGNAL(scrollRequested(int, int, const QRect&)), SLOT(scrollRequested(int, int))); graphicsWebView()->setPage(page); } +void WebViewGraphicsBased::scrollRequested(int x, int y) +{ + if (!m_resizesToContents) + return; + + // Turn off interactive mode while scrolling, or QGraphicsView will replay the + // last mouse event which may cause WebKit to initiate a drag operation. + bool interactive = isInteractive(); + setInteractive(false); + + verticalScrollBar()->setValue(-y); + horizontalScrollBar()->setValue(-x); + + setInteractive(interactive); +} + void WebViewGraphicsBased::contentsSizeChanged(const QSize& size) { if (m_resizesToContents) diff --git a/WebKitTools/QtTestBrowser/webview.h b/WebKitTools/QtTestBrowser/webview.h index e34d081..240ea89 100644 --- a/WebKitTools/QtTestBrowser/webview.h +++ b/WebKitTools/QtTestBrowser/webview.h @@ -97,6 +97,7 @@ public slots: void animatedFlip(); void animatedYFlip(); void contentsSizeChanged(const QSize&); + void scrollRequested(int, int); signals: void currentFPSUpdated(int fps); diff --git a/WebKitTools/QueueStatusServer/__init__.py b/WebKitTools/QueueStatusServer/__init__.py new file mode 100644 index 0000000..2346c23 --- /dev/null +++ b/WebKitTools/QueueStatusServer/__init__.py @@ -0,0 +1,29 @@ +# Required for Python to search this directory for module files + +# This __init__.py makes unit testing easier by allowing us to treat the entire server as one big module. +# This file is only accessed when not on AppEngine itself. + +# Make sure that this module will load in that case by including paths to +# the default Google AppEngine install. + + +def fix_sys_path(): + import sys + import os + + # AppEngine imports a bunch of google-specific modules. Thankfully the dev_appserver + # knows how to do the same. Re-use the dev_appserver fix_sys_path logic to import + # all the google.appengine.* stuff so we can run under test-webkitpy + sys.path.append("/usr/local/google_appengine") + import dev_appserver + dev_appserver.fix_sys_path() + + # test-webkitpy adds $WEBKIT/WebKitTools to the sys.path and imports + # QueueStatusServer to run all the tests. However, when AppEngine runs + # our code QueueStatusServer is the root (and thus in the path). + # Emulate that here for test-webkitpy so that we can import "model." + # not "QueueStatusServer.model.", etc. + sys.path.append(os.path.dirname(__file__)) + + +fix_sys_path() diff --git a/WebKitTools/QueueStatusServer/handlers/queuestatus.py b/WebKitTools/QueueStatusServer/handlers/queuestatus.py index 5c31537..54c0fdd 100644 --- a/WebKitTools/QueueStatusServer/handlers/queuestatus.py +++ b/WebKitTools/QueueStatusServer/handlers/queuestatus.py @@ -26,11 +26,12 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import itertools + from google.appengine.ext import webapp from google.appengine.ext.webapp import template from model.queues import Queue - from model import queuestatus @@ -49,6 +50,12 @@ class QueueStatus(webapp.RequestHandler): }) return rows + def _grouping_key_for_status(self, status): + return "%s-%s" % (status.active_patch_id, status.bot_id) + + def _build_status_groups(self, statuses): + return [list(group) for key, group in itertools.groupby(statuses, self._grouping_key_for_status)] + def get(self, queue_name): queue_name = queue_name.lower() queue = Queue.queue_with_name(queue_name) @@ -56,24 +63,10 @@ class QueueStatus(webapp.RequestHandler): self.error(404) return - status_groups = [] - last_patch_id = None - synthetic_patch_id_counter = 0 - statuses = queuestatus.QueueStatus.all().filter("queue_name =", queue.name()).order("-date").fetch(15) - for status in statuses: - patch_id = status.active_patch_id - if not patch_id or last_patch_id != patch_id: - status_group = [] - status_groups.append(status_group) - else: - status_group = status_groups[-1] - status_group.append(status) - last_patch_id = patch_id - template_values = { "display_queue_name": queue.display_name(), "work_item_rows": self._rows_for_work_items(queue), - "status_groups": status_groups, + "status_groups": self._build_status_groups(statuses), } self.response.out.write(template.render("templates/queuestatus.html", template_values)) diff --git a/WebKitTools/QueueStatusServer/handlers/queuestatus_unittest.py b/WebKitTools/QueueStatusServer/handlers/queuestatus_unittest.py new file mode 100644 index 0000000..a5ae844 --- /dev/null +++ b/WebKitTools/QueueStatusServer/handlers/queuestatus_unittest.py @@ -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 Research in Motion Ltd. 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. + +import unittest + +from handlers.queuestatus import QueueStatus +from model.queues import Queue + + +class MockStatus(object): + def __init__(self, patch_id, bot_id): + self.active_patch_id = patch_id + self.bot_id = bot_id + + +class QueueStatusTest(unittest.TestCase): + def test_build_status_groups(self): + queue_status = QueueStatus() + statuses = [ + MockStatus(1, "foo"), + MockStatus(1, "foo"), + MockStatus(2, "foo"), + MockStatus(1, "foo"), + MockStatus(1, "bar"), + MockStatus(1, "foo"), + ] + groups = queue_status._build_status_groups(statuses) + self.assertEqual(len(groups), 5) + self.assertEqual(groups[0], statuses[0:2]) + self.assertEqual(groups[1], statuses[2:3]) + self.assertEqual(groups[2], statuses[3:4]) + self.assertEqual(groups[3], statuses[4:5]) + self.assertEqual(groups[4], statuses[5:6]) + + +if __name__ == '__main__': + unittest.main() diff --git a/WebKitTools/QueueStatusServer/model/workitems.py b/WebKitTools/QueueStatusServer/model/workitems.py index fae6830..772fc39 100644 --- a/WebKitTools/QueueStatusServer/model/workitems.py +++ b/WebKitTools/QueueStatusServer/model/workitems.py @@ -52,6 +52,7 @@ class WorkItems(db.Model, QueuePropertyMixin): work_items.item_ids.append(attachment_id) work_items.put() + # Because this uses .key() self.is_saved() must be True or this will throw NotSavedError. def add_work_item(self, attachment_id): db.run_in_transaction(self._unguarded_add, self.key(), attachment_id) @@ -63,5 +64,6 @@ class WorkItems(db.Model, QueuePropertyMixin): work_items.item_ids.remove(attachment_id) work_items.put() + # Because this uses .key() self.is_saved() must be True or this will throw NotSavedError. def remove_work_item(self, attachment_id): db.run_in_transaction(self._unguarded_remove, self.key(), attachment_id) diff --git a/WebKitTools/QueueStatusServer/model/workitems_unittest.py b/WebKitTools/QueueStatusServer/model/workitems_unittest.py index d53302e..b1ff1d3 100644 --- a/WebKitTools/QueueStatusServer/model/workitems_unittest.py +++ b/WebKitTools/QueueStatusServer/model/workitems_unittest.py @@ -40,14 +40,6 @@ class WorkItemsTest(unittest.TestCase): self.assertEquals(items.display_position_for_attachment(1), 2) self.assertEquals(items.display_position_for_attachment(3), None) - def test_remove_work_item(self): - items = WorkItems() - items.item_ids = [0, 1, 2] - items.remove_work_item(0) - self.assertEqual(items.item_ids, [1, 2]) - items.remove_work_item(4) # Should not throw - self.assertEqual(items.item_ids, [1, 2]) - if __name__ == '__main__': unittest.main() diff --git a/WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html b/WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html index 075cd39..0adbfbd 100644 --- a/WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html +++ b/WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html @@ -1,4 +1,8 @@ -<span class="status-date">{{ status.date|timesince }} ago</span> +<span class="status-date">{{ status.date|timesince }} ago +{% if status.bot_id %} +({{ status.bot_id }}) +{% endif %} +</span> <span class="status-message">{{ status.message|force_escape|urlize|webkit_linkify|safe }}</span> {% if status.results_file %} <span class="status-results">[{{ status.key.id|results_link|safe }}]</span> diff --git a/WebKitTools/Scripts/check-webkit-style b/WebKitTools/Scripts/check-webkit-style index e29d4b1..076c712 100755 --- a/WebKitTools/Scripts/check-webkit-style +++ b/WebKitTools/Scripts/check-webkit-style @@ -112,10 +112,11 @@ def main(): file_reader = TextFileReader(style_processor) - if paths: + if paths and not options.diff_files: file_reader.process_paths(paths) else: - patch = checkout.create_patch(options.git_commit) + changed_files = paths if options.diff_files else None + patch = checkout.create_patch(options.git_commit, changed_files=changed_files) patch_checker = PatchReader(file_reader) patch_checker.check(patch) diff --git a/WebKitTools/Scripts/old-run-webkit-tests b/WebKitTools/Scripts/old-run-webkit-tests index e40b3ad..2cef18b 100755 --- a/WebKitTools/Scripts/old-run-webkit-tests +++ b/WebKitTools/Scripts/old-run-webkit-tests @@ -373,6 +373,8 @@ if ($useWebKitTestRunner) { } } +$timeoutSeconds *= 10 if $guardMalloc; + $stripEditingCallbacks = isCygwin() unless defined $stripEditingCallbacks; my $ignoreSkipped = $treatSkipped eq "ignore"; @@ -1483,6 +1485,12 @@ sub openDumpTool() unshift @args, "valgrind", "--suppressions=$platformBaseDirectory/qt/SuppressedValgrindErrors"; } + if ($useWebKitTestRunner) { + # Make WebKitTestRunner use a similar timeout. We don't use the exact same timeout to avoid + # race conditions. + push @args, "--timeout", $timeoutSeconds - 5; + } + $CLEAN_ENV{MallocStackLogging} = 1 if $shouldCheckLeaks; $dumpToolPID = open3(\*OUT, \*IN, \*ERROR, launchWithEnv(@args, %CLEAN_ENV)) or die "Failed to start tool: $dumpTool\n"; @@ -2089,7 +2097,6 @@ sub readFromDumpToolWithTimer(**) setFileHandleNonBlocking($fhError, 1); my $maximumSecondsWithoutOutput = $timeoutSeconds; - $maximumSecondsWithoutOutput *= 10 if $guardMalloc; my $microsecondsToWaitBeforeReadingAgain = 1000; my $timeOfLastSuccessfulRead = time; diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py index 9b602c3..8aadcb8 100644 --- a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py +++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py @@ -64,7 +64,7 @@ def default_scm(): cwd = os.getcwd() scm_system = detect_scm_system(cwd) if not scm_system: - script_directory = os.path.abspath(sys.path[0]) + script_directory = os.path.dirname(os.path.abspath(__file__)) scm_system = detect_scm_system(script_directory) if scm_system: log("The current directory (%s) is not a WebKit checkout, using %s" % (cwd, scm_system.checkout_root)) diff --git a/WebKitTools/Scripts/webkitpy/common/config/committers.py b/WebKitTools/Scripts/webkitpy/common/config/committers.py index 71d764c..446c2b1 100644 --- a/WebKitTools/Scripts/webkitpy/common/config/committers.py +++ b/WebKitTools/Scripts/webkitpy/common/config/committers.py @@ -112,6 +112,7 @@ committers_unable_to_review = [ Committer("Girish Ramakrishnan", ["girish@forwardbias.in", "ramakrishnan.girish@gmail.com"]), Committer("Graham Dennis", ["Graham.Dennis@gmail.com", "gdennis@webkit.org"]), Committer("Greg Bolsinga", "bolsinga@apple.com"), + Committer("Gyuyoung Kim", ["gyuyoung.kim@samsung.com", "gyuyoung@gmail.com", "gyuyoung@webkit.org"], "gyuyoung"), Committer("Hans Wennborg", "hans@chromium.org", "hwennborg"), Committer("Hayato Ito", "hayato@chromium.org", "hayato"), Committer("Hin-Chung Lam", ["hclam@google.com", "hclam@chromium.org"]), @@ -147,7 +148,7 @@ committers_unable_to_review = [ Committer("Luiz Agostini", ["luiz@webkit.org", "luiz.agostini@openbossa.org"], "lca"), Committer("Mads Ager", "ager@chromium.org"), Committer("Marcus Voltis Bulach", "bulach@chromium.org"), - Committer("Mario Sanchez Prada", ["msanchez@igalia.com", "mario@webkit.org"]), + Committer("Mario Sanchez Prada", ["msanchez@igalia.com", "mario@webkit.org"], "msanchez"), Committer("Matt Delaney", "mdelaney@apple.com"), Committer("Matt Lilek", ["webkit@mattlilek.com", "pewtermoose@webkit.org"]), Committer("Matt Perry", "mpcomplete@chromium.org"), @@ -171,6 +172,7 @@ committers_unable_to_review = [ Committer("Philippe Normand", ["pnormand@igalia.com", "philn@webkit.org"], "philn-tp"), Committer("Pierre d'Herbemont", ["pdherbemont@free.fr", "pdherbemont@apple.com"], "pdherbemont"), Committer("Pierre-Olivier Latour", "pol@apple.com", "pol"), + Committer("Renata Hodovan", "reni@webkit.org", "reni"), Committer("Robert Hogan", ["robert@webkit.org", "robert@roberthogan.net", "lists@roberthogan.net"], "mwenge"), Committer("Roland Steiner", "rolandsteiner@chromium.org"), Committer("Ryosuke Niwa", "rniwa@webkit.org", "rniwa"), diff --git a/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py b/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py index 1cc8e2e..a7dc1b7 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py +++ b/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py @@ -281,7 +281,7 @@ class BugzillaQueries(object): return sum([self._fetch_bug(bug_id).commit_queued_patches() for bug_id in self.fetch_bug_ids_from_commit_queue()], []) - def _fetch_bug_ids_from_review_queue(self): + def fetch_bug_ids_from_review_queue(self): review_queue_url = "buglist.cgi?query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=flagtypes.name&type0-0-0=equals&value0-0-0=review?" return self._fetch_bug_ids_advanced_query(review_queue_url) @@ -289,7 +289,7 @@ class BugzillaQueries(object): def fetch_patches_from_review_queue(self, limit=None): # [:None] returns the whole array. return sum([self._fetch_bug(bug_id).unreviewed_patches() - for bug_id in self._fetch_bug_ids_from_review_queue()[:limit]], []) + for bug_id in self.fetch_bug_ids_from_review_queue()[:limit]], []) # NOTE: This is the only client of _fetch_attachment_ids_request_query # This method only makes one request to bugzilla. diff --git a/WebKitTools/Scripts/webkitpy/common/system/executive.py b/WebKitTools/Scripts/webkitpy/common/system/executive.py index 216cf58..37f4e53 100644 --- a/WebKitTools/Scripts/webkitpy/common/system/executive.py +++ b/WebKitTools/Scripts/webkitpy/common/system/executive.py @@ -33,6 +33,7 @@ try: except ImportError: multiprocessing = None +import ctypes import errno import logging import os @@ -44,6 +45,7 @@ import sys import time from webkitpy.common.system.deprecated_logging import tee +from webkitpy.python24 import versioning _log = logging.getLogger("webkitpy.common.system") @@ -103,13 +105,8 @@ class Executive(object): def _run_command_with_teed_output(self, args, teed_output): args = map(unicode, args) # Popen will throw an exception if args are non-strings (like int()) - if sys.platform == 'cygwin': - # Cygwin's Python's os.execv doesn't support unicode command - # arguments, and neither does Cygwin's execv itself. - # FIXME: Using UTF-8 here will confuse Windows-native commands - # which will expect arguments to be encoded using the current code - # page. - args = [arg.encode('utf-8') for arg in args] + args = map(self._encode_argument_if_needed, args) + child_process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, @@ -148,9 +145,8 @@ class Executive(object): child_output = child_out_file.getvalue() child_out_file.close() - # We assume the child process output utf-8 if decode_output: - child_output = child_output.decode("utf-8") + child_output = child_output.decode(self._child_process_encoding()) if exit_code: raise ScriptError(script_args=args, @@ -205,6 +201,55 @@ class Executive(object): return raise + def _win32_check_running_pid(self): + + class PROCESSENTRY32(ctypes.Structure): + _fields_ = [("dwSize", ctypes.c_ulong), + ("cntUsage", ctypes.c_ulong), + ("th32ProcessID", ctypes.c_ulong), + ("th32DefaultHeapID", ctypes.c_ulong), + ("th32ModuleID", ctypes.c_ulong), + ("cntThreads", ctypes.c_ulong), + ("th32ParentProcessID", ctypes.c_ulong), + ("pcPriClassBase", ctypes.c_ulong), + ("dwFlags", ctypes.c_ulong), + ("szExeFile", ctypes.c_char * 260)] + + CreateToolhelp32Snapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot + Process32First = ctypes.windll.kernel32.Process32First + Process32Next = ctypes.windll.kernel32.Process32Next + CloseHandle = ctypes.windll.kernel32.CloseHandle + TH32CS_SNAPPROCESS = 0x00000002 # win32 magic number + hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) + pe32 = PROCESSENTRY32() + pe32.dwSize = ctypes.sizeof(PROCESSENTRY32) + result = False + if not Process32First(hProcessSnap, ctypes.byref(pe32)): + _log.debug("Failed getting first process.") + CloseHandle(hProcessSnap) + return result + while True: + if pe32.th32ProcessID == pid: + result = True + break + if not Process32Next(hProcessSnap, ctypes.byref(pe32)): + break + CloseHandle(hProcessSnap) + return result + + def check_running_pid(self, pid): + """Return True if pid is alive, otherwise return False.""" + if sys.platform in ('darwin', 'linux2', 'cygwin'): + try: + os.kill(pid, 0) + return True + except OSError: + return False + elif sys.platform == 'win32': + return self._win32_check_running_pid() + + assert(False) + def _windows_image_name(self, process_name): name, extension = os.path.splitext(process_name) if not extension: @@ -260,7 +305,7 @@ class Executive(object): # for an example of a regresion caused by passing a unicode string directly. # FIXME: We may need to encode differently on different platforms. if isinstance(input, unicode): - input = input.encode("utf-8") + input = input.encode(self._child_process_encoding()) return (subprocess.PIPE, input) def _command_for_printing(self, args): @@ -288,13 +333,8 @@ class Executive(object): assert(isinstance(args, list) or isinstance(args, tuple)) start_time = time.time() args = map(unicode, args) # Popen will throw an exception if args are non-strings (like int()) - if sys.platform == 'cygwin': - # Cygwin's Python's os.execv doesn't support unicode command - # arguments, and neither does Cygwin's execv itself. - # FIXME: Using UTF-8 here will confuse Windows-native commands - # which will expect arguments to be encoded using the current code - # page. - args = [arg.encode('utf-8') for arg in args] + args = map(self._encode_argument_if_needed, args) + stdin, string_to_communicate = self._compute_stdin(input) stderr = subprocess.STDOUT if return_stderr else None @@ -305,9 +345,11 @@ class Executive(object): cwd=cwd, close_fds=self._should_close_fds()) output = process.communicate(string_to_communicate)[0] + # run_command automatically decodes to unicode() unless explicitly told not to. if decode_output: - output = output.decode("utf-8") + output = output.decode(self._child_process_encoding()) + # wait() is not threadsafe and can throw OSError due to: # http://bugs.python.org/issue1731717 exit_code = process.wait() @@ -324,3 +366,34 @@ class Executive(object): cwd=cwd) (error_handler or self.default_error_handler)(script_error) return output + + def _child_process_encoding(self): + # Win32 Python 2.x uses CreateProcessA rather than CreateProcessW + # to launch subprocesses, so we have to encode arguments using the + # current code page. + if sys.platform == 'win32' and versioning.compare_version(sys, '3.0')[0] < 0: + return 'mbcs' + # All other platforms use UTF-8. + # FIXME: Using UTF-8 on Cygwin will confuse Windows-native commands + # which will expect arguments to be encoded using the current code + # page. + return 'utf-8' + + def _should_encode_child_process_arguments(self): + # Cygwin's Python's os.execv doesn't support unicode command + # arguments, and neither does Cygwin's execv itself. + if sys.platform == 'cygwin': + return True + + # Win32 Python 2.x uses CreateProcessA rather than CreateProcessW + # to launch subprocesses, so we have to encode arguments using the + # current code page. + if sys.platform == 'win32' and versioning.compare_version(sys, '3.0')[0] < 0: + return True + + return False + + def _encode_argument_if_needed(self, argument): + if not self._should_encode_child_process_arguments(): + return argument + return argument.encode(self._child_process_encoding()) diff --git a/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py b/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py index 32f8f51..b8fd82e 100644 --- a/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py +++ b/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py @@ -27,12 +27,23 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import os import signal import subprocess import sys import unittest from webkitpy.common.system.executive import Executive, run_command, ScriptError +from webkitpy.test import cat, echo + + +def never_ending_command(): + """Arguments for a command that will never end (useful for testing process + killing). It should be a process that is unlikely to already be running + because all instances will be killed.""" + if sys.platform == 'win32': + return ['wmic'] + return ['yes'] class ExecutiveTest(unittest.TestCase): @@ -46,46 +57,56 @@ class ExecutiveTest(unittest.TestCase): executive = Executive() self.assertRaises(AssertionError, executive.run_command, "echo") self.assertRaises(AssertionError, executive.run_command, u"echo") - executive.run_command(["echo", "foo"]) - executive.run_command(("echo", "foo")) + executive.run_command(echo.command_arguments('foo')) + executive.run_command(tuple(echo.command_arguments('foo'))) def test_run_command_with_unicode(self): """Validate that it is safe to pass unicode() objects to Executive.run* methods, and they will return unicode() objects by default unless decode_output=False""" + unicode_tor_input = u"WebKit \u2661 Tor Arne Vestb\u00F8!" + if sys.platform == 'win32': + encoding = 'mbcs' + else: + encoding = 'utf-8' + encoded_tor = unicode_tor_input.encode(encoding) + # On Windows, we expect the unicode->mbcs->unicode roundtrip to be + # lossy. On other platforms, we expect a lossless roundtrip. + if sys.platform == 'win32': + unicode_tor_output = encoded_tor.decode(encoding) + else: + unicode_tor_output = unicode_tor_input + executive = Executive() - unicode_tor = u"WebKit \u2661 Tor Arne Vestb\u00F8!" - utf8_tor = unicode_tor.encode("utf-8") - output = executive.run_command(["cat"], input=unicode_tor) - self.assertEquals(output, unicode_tor) + output = executive.run_command(cat.command_arguments(), input=unicode_tor_input) + self.assertEquals(output, unicode_tor_output) - output = executive.run_command(["echo", "-n", unicode_tor]) - self.assertEquals(output, unicode_tor) + output = executive.run_command(echo.command_arguments("-n", unicode_tor_input)) + self.assertEquals(output, unicode_tor_output) - output = executive.run_command(["echo", "-n", unicode_tor], decode_output=False) - self.assertEquals(output, utf8_tor) + output = executive.run_command(echo.command_arguments("-n", unicode_tor_input), decode_output=False) + self.assertEquals(output, encoded_tor) # Make sure that str() input also works. - output = executive.run_command(["cat"], input=utf8_tor, decode_output=False) - self.assertEquals(output, utf8_tor) + output = executive.run_command(cat.command_arguments(), input=encoded_tor, decode_output=False) + self.assertEquals(output, encoded_tor) # FIXME: We should only have one run* method to test - output = executive.run_and_throw_if_fail(["echo", "-n", unicode_tor], quiet=True) - self.assertEquals(output, unicode_tor) + output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor_input), quiet=True) + self.assertEquals(output, unicode_tor_output) - output = executive.run_and_throw_if_fail(["echo", "-n", unicode_tor], quiet=True, decode_output=False) - self.assertEquals(output, utf8_tor) + output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor_input), quiet=True, decode_output=False) + self.assertEquals(output, encoded_tor) def test_kill_process(self): executive = Executive() - # We use "yes" because it loops forever. - process = subprocess.Popen(["yes"], stdout=subprocess.PIPE) + process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running executive.kill_process(process.pid) # Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32" if sys.platform == "win32": - expected_exit_code = 0 # taskkill.exe results in exit(0) + expected_exit_code = 1 else: expected_exit_code = -signal.SIGKILL self.assertEqual(process.wait(), expected_exit_code) @@ -109,14 +130,22 @@ class ExecutiveTest(unittest.TestCase): def test_kill_all(self): executive = Executive() # We use "yes" because it loops forever. - process = subprocess.Popen(["yes"], stdout=subprocess.PIPE) + process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE) self.assertEqual(process.poll(), None) # Process is running - executive.kill_all("yes") + executive.kill_all(never_ending_command()[0]) # Note: Can't use a ternary since signal.SIGTERM is undefined for sys.platform == "win32" - if sys.platform in ("win32", "cygwin"): - expected_exit_code = 0 # taskkill.exe results in exit(0) + if sys.platform == "cygwin": + expected_exit_code = 0 # os.kill results in exit(0) for this process. + elif sys.platform == "win32": + expected_exit_code = 1 else: expected_exit_code = -signal.SIGTERM self.assertEqual(process.wait(), expected_exit_code) # Killing again should fail silently. - executive.kill_all("yes") + executive.kill_all(never_ending_command()[0]) + + def test_check_running_pid(self): + executive = Executive() + self.assertTrue(executive.check_running_pid(os.getpid())) + # Maximum pid number on Linux is 32768 by default + self.assertFalse(executive.check_running_pid(100000)) diff --git a/WebKitTools/Scripts/webkitpy/common/system/filesystem.py b/WebKitTools/Scripts/webkitpy/common/system/filesystem.py new file mode 100644 index 0000000..c7efde3 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/common/system/filesystem.py @@ -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. +# * 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. + +"""Wrapper object for the file system / source tree.""" + +from __future__ import with_statement + +import codecs +import errno +import os +import tempfile + + +class FileSystem(object): + """FileSystem interface for webkitpy. + + Unless otherwise noted, all paths are allowed to be either absolute + or relative.""" + + def exists(self, path): + """Return whether the path exists in the filesystem.""" + return os.path.exists(path) + + def isdir(self, path): + """Return whether the path refers to a directory.""" + return os.path.isdir(path) + + def join(self, *comps): + """Return the path formed by joining the components.""" + return os.path.join(*comps) + + def listdir(self, path): + """Return the contents of the directory pointed to by path.""" + return os.listdir(path) + + def mkdtemp(self, **kwargs): + """Create and return a uniquely named directory. + + This is like tempfile.mkdtemp, but if used in a with statement + the directory will self-delete at the end of the block (if the + directory is empty; non-empty directories raise errors). The + directory can be safely deleted inside the block as well, if so + desired.""" + class TemporaryDirectory(object): + def __init__(self, **kwargs): + self._kwargs = kwargs + self._directory_path = None + + def __enter__(self): + self._directory_path = tempfile.mkdtemp(**self._kwargs) + return self._directory_path + + def __exit__(self, type, value, traceback): + # Only self-delete if necessary. + + # FIXME: Should we delete non-empty directories? + if os.path.exists(self._directory_path): + os.rmdir(self._directory_path) + + return TemporaryDirectory(**kwargs) + + def maybe_make_directory(self, *path): + """Create the specified directory if it doesn't already exist.""" + try: + os.makedirs(os.path.join(*path)) + except OSError, e: + if e.errno != errno.EEXIST: + raise + + def read_binary_file(self, path): + """Return the contents of the file at the given path as a byte string.""" + with file(path, 'rb') as f: + return f.read() + + def read_text_file(self, path): + """Return the contents of the file at the given path as a Unicode string. + + The file is read assuming it is a UTF-8 encoded file with no BOM.""" + with codecs.open(path, 'r', 'utf8') as f: + return f.read() + + def write_binary_file(self, path, contents): + """Write the contents to the file at the given location.""" + with file(path, 'wb') as f: + f.write(contents) + + def write_text_file(self, path, contents): + """Write the contents to the file at the given location. + + The file is written encoded as UTF-8 with no BOM.""" + with codecs.open(path, 'w', 'utf8') as f: + f.write(contents) diff --git a/WebKitTools/Scripts/webkitpy/common/system/filesystem_unittest.py b/WebKitTools/Scripts/webkitpy/common/system/filesystem_unittest.py new file mode 100644 index 0000000..95684b7 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/common/system/filesystem_unittest.py @@ -0,0 +1,157 @@ +# vim: set fileencoding=utf-8 : +# 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. + +# NOTE: The fileencoding comment on the first line of the file is +# important; without it, Python will choke while trying to parse the file, +# since it includes non-ASCII characters. + +from __future__ import with_statement + +import os +import stat +import sys +import tempfile +import unittest + +from filesystem import FileSystem + + +class FileSystemTest(unittest.TestCase): + def setUp(self): + self._this_dir = os.path.dirname(os.path.abspath(__file__)) + self._missing_file = os.path.join(self._this_dir, 'missing_file.py') + self._this_file = os.path.join(self._this_dir, 'filesystem_unittest.py') + + def test_exists__true(self): + fs = FileSystem() + self.assertTrue(fs.exists(self._this_file)) + + def test_exists__false(self): + fs = FileSystem() + self.assertFalse(fs.exists(self._missing_file)) + + def test_isdir__true(self): + fs = FileSystem() + self.assertTrue(fs.isdir(self._this_dir)) + + def test_isdir__false(self): + fs = FileSystem() + self.assertFalse(fs.isdir(self._this_file)) + + def test_join(self): + fs = FileSystem() + self.assertEqual(fs.join('foo', 'bar'), + os.path.join('foo', 'bar')) + + def test_listdir(self): + fs = FileSystem() + with fs.mkdtemp(prefix='filesystem_unittest_') as d: + self.assertEqual(fs.listdir(d), []) + new_file = os.path.join(d, 'foo') + fs.write_text_file(new_file, u'foo') + self.assertEqual(fs.listdir(d), ['foo']) + os.remove(new_file) + + def test_maybe_make_directory__success(self): + fs = FileSystem() + + with fs.mkdtemp(prefix='filesystem_unittest_') as base_path: + sub_path = os.path.join(base_path, "newdir") + self.assertFalse(os.path.exists(sub_path)) + self.assertFalse(fs.isdir(sub_path)) + + fs.maybe_make_directory(sub_path) + self.assertTrue(os.path.exists(sub_path)) + self.assertTrue(fs.isdir(sub_path)) + + # Make sure we can re-create it. + fs.maybe_make_directory(sub_path) + self.assertTrue(os.path.exists(sub_path)) + self.assertTrue(fs.isdir(sub_path)) + + # Clean up. + os.rmdir(sub_path) + + self.assertFalse(os.path.exists(base_path)) + self.assertFalse(fs.isdir(base_path)) + + def test_maybe_make_directory__failure(self): + # FIXME: os.chmod() doesn't work on Windows to set directories + # as readonly, so we skip this test for now. + if sys.platform in ('win32', 'cygwin'): + return + + fs = FileSystem() + with fs.mkdtemp(prefix='filesystem_unittest_') as d: + # Remove write permissions on the parent directory. + os.chmod(d, stat.S_IRUSR) + + # Now try to create a sub directory - should fail. + sub_dir = fs.join(d, 'subdir') + self.assertRaises(OSError, fs.maybe_make_directory, sub_dir) + + # Clean up in case the test failed and we did create the + # directory. + if os.path.exists(sub_dir): + os.rmdir(sub_dir) + + def test_read_and_write_file(self): + fs = FileSystem() + text_path = None + binary_path = None + + unicode_text_string = u'Ūnĭcōde̽' + hex_equivalent = '\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD' + try: + text_path = tempfile.mktemp(prefix='tree_unittest_') + binary_path = tempfile.mktemp(prefix='tree_unittest_') + fs.write_text_file(text_path, unicode_text_string) + contents = fs.read_binary_file(text_path) + self.assertEqual(contents, hex_equivalent) + + fs.write_text_file(binary_path, hex_equivalent) + text_contents = fs.read_text_file(binary_path) + self.assertEqual(text_contents, unicode_text_string) + except: + if text_path: + os.remove(text_path) + if binary_path: + os.remove(binary_path) + + def test_read_binary_file__missing(self): + fs = FileSystem() + self.assertRaises(IOError, fs.read_binary_file, self._missing_file) + + def test_read_text_file__missing(self): + fs = FileSystem() + self.assertRaises(IOError, fs.read_text_file, self._missing_file) + + +if __name__ == '__main__': + unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/common/system/fileutils.py b/WebKitTools/Scripts/webkitpy/common/system/fileutils.py new file mode 100644 index 0000000..55821f8 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/common/system/fileutils.py @@ -0,0 +1,33 @@ +# Copyright (C) 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 +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import sys + + +def make_stdout_binary(): + """Puts sys.stdout into binary mode (on platforms that have a distinction + between text and binary mode).""" + if sys.platform != 'win32' or not hasattr(sys.stdout, 'fileno'): + return + import msvcrt + import os + msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) diff --git a/WebKitTools/Scripts/webkitpy/common/system/path.py b/WebKitTools/Scripts/webkitpy/common/system/path.py index 43c6410..09787d7 100644 --- a/WebKitTools/Scripts/webkitpy/common/system/path.py +++ b/WebKitTools/Scripts/webkitpy/common/system/path.py @@ -44,7 +44,7 @@ def abspath_to_uri(path, platform=None): def cygpath(path): - """Converts a cygwin path to Windows path.""" + """Converts an absolute cygwin path to an absolute Windows path.""" return _CygPath.convert_using_singleton(path) @@ -103,7 +103,11 @@ class _CygPath(object): self.start() self._child_process.stdin.write("%s\r\n" % path) self._child_process.stdin.flush() - return self._child_process.stdout.readline().rstrip() + windows_path = self._child_process.stdout.readline().rstrip() + # Some versions of cygpath use lowercase drive letters while others + # use uppercase. We always convert to uppercase for consistency. + windows_path = '%s%s' % (windows_path[0].upper(), windows_path[1:]) + return windows_path def _escape(path): diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py index 3e3ba0b..9f2de7e 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py @@ -341,7 +341,7 @@ class TestShellThread(WatchableThread): def cancel(self): """Clean up http lock and set a flag telling this thread to quit.""" - self._stop_http_lock() + self._stop_servers_with_lock() WatchableThread.cancel(self) def next_timeout(self): @@ -389,23 +389,15 @@ class TestShellThread(WatchableThread): self._current_group, self._filename_list = \ self._filename_list_queue.get_nowait() except Queue.Empty: - self._stop_http_lock() + self._stop_servers_with_lock() self._kill_dump_render_tree() tests_run_file.close() return - if self._options.wait_for_httpd: - if self._current_group == "tests_to_http_lock": - self._http_lock_wait_begin = time.time() - self._port.acquire_http_lock() - - self._port.start_http_server() - self._port.start_websocket_server() - - self._have_http_lock = True - self._http_lock_wait_end = time.time() - elif self._have_http_lock: - self._stop_http_lock() + if self._current_group == "tests_to_http_lock": + self._start_servers_with_lock() + elif self._have_http_lock: + self._stop_servers_with_lock() self._num_tests_in_current_group = len(self._filename_list) self._current_group_start_time = time.time() @@ -440,7 +432,7 @@ class TestShellThread(WatchableThread): self._port.relative_test_filename(filename))) self._result_queue.put(result.dumps()) - if batch_size > 0 and batch_count > batch_size: + if batch_size > 0 and batch_count >= batch_size: # Bounce the shell and reset count. self._kill_dump_render_tree() batch_count = 0 @@ -545,11 +537,26 @@ class TestShellThread(WatchableThread): self._options) self._driver.start() - def _stop_http_lock(self): + def _start_servers_with_lock(self): + """Acquire http lock and start the servers.""" + self._http_lock_wait_begin = time.time() + _log.debug('Acquire http lock ...') + self._port.acquire_http_lock() + _log.debug('Starting HTTP server ...') + self._port.start_http_server() + _log.debug('Starting WebSocket server ...') + self._port.start_websocket_server() + self._http_lock_wait_end = time.time() + self._have_http_lock = True + + def _stop_servers_with_lock(self): """Stop the servers and release http lock.""" if self._have_http_lock: + _log.debug('Stopping HTTP server ...') self._port.stop_http_server() + _log.debug('Stopping WebSocket server ...') self._port.stop_websocket_server() + _log.debug('Release http lock ...') self._port.release_http_lock() self._have_http_lock = False diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py index cd7d663..a98b858 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py @@ -47,6 +47,7 @@ import http_server import test_files import websocket_server +from webkitpy.common.memoized import memoized from webkitpy.common.system import logutils from webkitpy.common.system.executive import Executive, ScriptError from webkitpy.common.system.path import abspath_to_uri @@ -725,13 +726,25 @@ class Port(object): e.message_with_output())) return self._pretty_patch_error_html - def _webkit_build_directory(self, args): - args = ["perl", self.script_path("webkit-build-directory")] + args + def _webkit_build_directory_command(self, args): + return ["perl", self.script_path("webkit-build-directory")] + args + + @memoized + def _webkit_top_level_build_directory(self, top_level=True): + """This directory is above where products are built to and contains things like the Configuration file.""" + args = self._webkit_build_directory_command(["--top-level"]) + return self._executive.run_command(args).rstrip() + + @memoized + def _webkit_configuration_build_directory(self, configuration=None): + """This is where products are normally built to.""" + if not configuration: + configuration = self.flag_from_configuration(self.get_option('configuration')) + args = self._webkit_build_directory_command(["--configuration", configuration]) return self._executive.run_command(args).rstrip() def _configuration_file_path(self): - build_root = self._webkit_build_directory(["--top-level"]) - return os.path.join(build_root, "Configuration") + return os.path.join(self._webkit_top_level_build_directory(), "Configuration") # Easy override for unit tests def _open_configuration_file(self): diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py index 5d28fae..57b6989 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py @@ -71,6 +71,8 @@ def _set_gpu_options(options): options.accelerated_2d_canvas = True if options.builder_name is not None: options.builder_name = options.builder_name + ' - GPU' + if options.use_drt is None: + options.use_drt = True def _gpu_overrides(port): @@ -96,6 +98,9 @@ class ChromiumGpuLinuxPort(chromium_linux.ChromiumLinuxPort): return (map(self._webkit_baseline_path, ['chromium-gpu-linux', 'chromium-gpu-win', 'chromium-gpu']) + chromium_linux.ChromiumLinuxPort.baseline_search_path(self)) + def default_child_processes(self): + return 1 + def path_to_test_expectations_file(self): return self.path_from_webkit_base('LayoutTests', 'platform', 'chromium-gpu', 'test_expectations.txt') @@ -114,6 +119,9 @@ class ChromiumGpuMacPort(chromium_mac.ChromiumMacPort): return (map(self._webkit_baseline_path, ['chromium-gpu-mac', 'chromium-gpu']) + chromium_mac.ChromiumMacPort.baseline_search_path(self)) + def default_child_processes(self): + return 1 + def path_to_test_expectations_file(self): return self.path_from_webkit_base('LayoutTests', 'platform', 'chromium-gpu', 'test_expectations.txt') @@ -132,6 +140,9 @@ class ChromiumGpuWinPort(chromium_win.ChromiumWinPort): return (map(self._webkit_baseline_path, ['chromium-gpu-win', 'chromium-gpu']) + chromium_win.ChromiumWinPort.baseline_search_path(self)) + def default_child_processes(self): + return 1 + def path_to_test_expectations_file(self): return self.path_from_webkit_base('LayoutTests', 'platform', 'chromium-gpu', 'test_expectations.txt') diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py index 88524fc..03bc98a 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py @@ -45,10 +45,14 @@ class ChromiumGpuTest(unittest.TestCase): # test that we got the right port mock_options = mocktool.MockOptions(accelerated_compositing=None, accelerated_2d_canvas=None, - builder_name='foo') + builder_name='foo', + use_drt=None, + child_processes=None) port = chromium_gpu.get(port_name=port_name, options=mock_options) self.assertTrue(port._options.accelerated_compositing) self.assertTrue(port._options.accelerated_2d_canvas) + self.assertTrue(port._options.use_drt) + self.assertEqual(port.default_child_processes(), 1) self.assertEqual(port._options.builder_name, 'foo - GPU') # we use startswith() instead of Equal to gloss over platform versions. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py new file mode 100644 index 0000000..2364098 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python +# 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. + +"""Wrapper objects for WebKit-specific utility routines.""" + +# FIXME: This file needs to be unified with common/checkout/scm.py and +# common/config/ports.py . + +from __future__ import with_statement + +import codecs +import os + +from webkitpy.common.checkout import scm +from webkitpy.common.system import logutils + + +_log = logutils.get_logger(__file__) + +# +# This is used to record if we've already hit the filesystem to look +# for a default configuration. We cache this to speed up the unit tests, +# but this can be reset with clear_cached_configuration(). +# +_determined_configuration = None + + +def clear_cached_configuration(): + global _determined_configuration + _determined_configuration = -1 + + +class Config(object): + _FLAGS_FROM_CONFIGURATIONS = { + "Debug": "--debug", + "Release": "--release", + } + + def __init__(self, executive): + self._executive = executive + self._webkit_base_dir = None + self._default_configuration = None + self._build_directories = {} + + def build_directory(self, configuration): + """Returns the path to the build directory for the configuration.""" + if configuration: + flags = ["--configuration", + self._FLAGS_FROM_CONFIGURATIONS[configuration]] + configuration = "" + else: + configuration = "" + flags = ["--top-level"] + + if not self._build_directories.get(configuration): + args = ["perl", self._script_path("webkit-build-directory")] + flags + self._build_directories[configuration] = ( + self._executive.run_command(args).rstrip()) + + return self._build_directories[configuration] + + def build_dumprendertree(self, configuration): + """Builds DRT in the given configuration. + + Returns True if the build was successful and up-to-date.""" + flag = self._FLAGS_FROM_CONFIGURATIONS[configuration] + exit_code = self._executive.run_command([ + self._script_path("build-dumprendertree"), flag], + return_exit_code=True) + if exit_code != 0: + _log.error("Failed to build DumpRenderTree") + return False + return True + + def default_configuration(self): + """Returns the default configuration for the user. + + Returns the value set by 'set-webkit-configuration', or "Release" + if that has not been set. This mirrors the logic in webkitdirs.pm.""" + if not self._default_configuration: + self._default_configuration = self._determine_configuration() + if not self._default_configuration: + self._default_configuration = 'Release' + if self._default_configuration not in self._FLAGS_FROM_CONFIGURATIONS: + _log.warn("Configuration \"%s\" is not a recognized value.\n" % + self._default_configuration) + _log.warn("Scripts may fail. " + "See 'set-webkit-configuration --help'.") + return self._default_configuration + + def path_from_webkit_base(self, *comps): + return os.path.join(self.webkit_base_dir(), *comps) + + def webkit_base_dir(self): + """Returns the absolute path to the top of the WebKit tree. + + Raises an AssertionError if the top dir can't be determined.""" + # FIXME: Consider determining this independently of scm in order + # to be able to run in a bare tree. + if not self._webkit_base_dir: + self._webkit_base_dir = scm.find_checkout_root() + assert self._webkit_base_dir, "Could not determine the top of the WebKit checkout" + return self._webkit_base_dir + + def _script_path(self, script_name): + return os.path.join(self.webkit_base_dir(), "WebKitTools", + "Scripts", script_name) + + def _determine_configuration(self): + # This mirrors the logic in webkitdirs.pm:determineConfiguration(). + global _determined_configuration + if _determined_configuration == -1: + contents = self._read_configuration() + if contents == "Deployment": + contents = "Release" + if contents == "Development": + contents = "Debug" + _determined_configuration = contents + return _determined_configuration + + def _read_configuration(self): + configuration_path = os.path.join(self.build_directory(None), + "Configuration") + if not os.path.exists(configuration_path): + return None + + with codecs.open(configuration_path, "r", "utf-8") as fh: + return fh.read().rstrip() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py new file mode 100644 index 0000000..4674cba --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py @@ -0,0 +1,176 @@ +# 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. + +import codecs +import os +import StringIO +import unittest + +from webkitpy.common.system import outputcapture + +import config + + +# FIXME: This makes StringIO objects work with "with". Remove +# when we upgrade to 2.6. +class NewStringIO(StringIO.StringIO): + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + pass + + +class MockExecutive(object): + def __init__(self, output='', exit_code=0): + self._output = output + self._exit_code = exit_code + + def run_command(self, arg_list, return_exit_code=False, + decode_output=False): + if return_exit_code: + return self._exit_code + return self._output + + +class ConfigTest(unittest.TestCase): + def tearDown(self): + config.clear_cached_configuration() + + def assertConfiguration(self, contents, expected): + # This tests that a configuration file containing + # _contents_ endsd up being interpreted as _expected_. + # + # FIXME: rewrite this when we have a filesystem abstraction we + # can mock out more easily. + config.clear_cached_configuration() + orig_open = codecs.open + + def wrap_open(contents): + def open_wrapper(path, mode, encoding): + return NewStringIO(contents) + return open_wrapper + + try: + orig_exists = os.path.exists + os.path.exists = lambda p: True + codecs.open = wrap_open(contents) + + e = MockExecutive(output='foo') + c = config.Config(e) + self.assertEqual(c.default_configuration(), expected) + finally: + os.path.exists = orig_exists + codecs.open = orig_open + + def test_build_directory_toplevel(self): + e = MockExecutive(output="toplevel") + c = config.Config(e) + self.assertEqual(c.build_directory(None), 'toplevel') + + # Test again to check caching + self.assertEqual(c.build_directory(None), 'toplevel') + + def test_build_directory__release(self): + e = MockExecutive(output="release") + c = config.Config(e) + self.assertEqual(c.build_directory('Release'), 'release') + + def test_build_directory__debug(self): + e = MockExecutive(output="debug") + c = config.Config(e) + self.assertEqual(c.build_directory('Debug'), 'debug') + + def test_build_directory__unknown(self): + e = MockExecutive(output="unknown") + c = config.Config(e) + self.assertRaises(KeyError, c.build_directory, 'Unknown') + + def test_build_dumprendertree__success(self): + e = MockExecutive(exit_code=0) + c = config.Config(e) + self.assertTrue(c.build_dumprendertree("Debug")) + self.assertTrue(c.build_dumprendertree("Release")) + self.assertRaises(KeyError, c.build_dumprendertree, "Unknown") + + def test_build_dumprendertree__failure(self): + e = MockExecutive(exit_code=-1) + c = config.Config(e) + + oc = outputcapture.OutputCapture() + oc.capture_output() + self.assertFalse(c.build_dumprendertree('Debug')) + (out, err) = oc.restore_output() + + oc.capture_output() + self.assertFalse(c.build_dumprendertree('Release')) + oc.restore_output() + + def test_default_configuration__release(self): + self.assertConfiguration('Release', 'Release') + + def test_default_configuration__debug(self): + self.assertConfiguration('Debug', 'Debug') + + def test_default_configuration__deployment(self): + self.assertConfiguration('Deployment', 'Release') + + def test_default_configuration__development(self): + self.assertConfiguration('Development', 'Debug') + + def test_default_configuration__notfound(self): + # This tests what happens if the default configuration file + # doesn't exist. + config.clear_cached_configuration() + try: + orig_exists = os.path.exists + os.path.exists = lambda p: False + e = MockExecutive(output="foo") + c = config.Config(e) + self.assertEqual(c.default_configuration(), "Release") + finally: + os.path.exists = orig_exists + + def test_default_configuration__unknown(self): + # Ignore the warning about an unknown configuration value. + oc = outputcapture.OutputCapture() + oc.capture_output() + self.assertConfiguration('Unknown', 'Unknown') + oc.restore_output() + + def test_path_from_webkit_base(self, *comps): + c = config.Config(None) + self.assertTrue(c.path_from_webkit_base('foo')) + + def test_webkit_base_dir(self): + c = config.Config(None) + self.assertTrue(c.webkit_base_dir()) + + +if __name__ == '__main__': + unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py index b2615a3..d65801d 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py @@ -29,27 +29,38 @@ http and websocket tests in a same time.""" import glob +import logging import os import sys import tempfile import time +from webkitpy.common.system.executive import Executive + + +_log = logging.getLogger("webkitpy.layout_tests.port.http_lock") + class HttpLock(object): def __init__(self, lock_path, lock_file_prefix="WebKitHttpd.lock.", guard_lock="WebKit.lock"): - if not lock_path: + self._lock_path = lock_path + if not self._lock_path: self._lock_path = tempfile.gettempdir() self._lock_file_prefix = lock_file_prefix self._lock_file_path_prefix = os.path.join(self._lock_path, self._lock_file_prefix) self._guard_lock_file = os.path.join(self._lock_path, guard_lock) self._process_lock_file_name = "" + self._executive = Executive() + # maximum wait time for the lock creation + self._guard_lock_max_wait = 1 * 60 def cleanup_http_lock(self): """Delete the lock file if exists.""" if os.path.exists(self._process_lock_file_name): + _log.debug("Removing lock file: %s" % self._process_lock_file_name) os.unlink(self._process_lock_file_name) def _extract_lock_number(self, lock_file_name): @@ -70,17 +81,6 @@ class HttpLock(object): return 0 return self._extract_lock_number(lock_list[-1]) + 1 - def _check_pid(self, current_pid): - """Return True if pid is alive, otherwise return False. - FIXME: os.kill() doesn't work on Windows for checking if - a pid is alive, so always return True""" - if sys.platform in ('darwin', 'linux2'): - try: - os.kill(current_pid, 0) - except OSError: - return False - return True - def _curent_lock_pid(self): """Return with the current lock pid. If the lock is not valid it deletes the lock file.""" @@ -91,7 +91,8 @@ class HttpLock(object): current_lock_file = open(lock_list[0], 'r') current_pid = current_lock_file.readline() current_lock_file.close() - if not (current_pid and self._check_pid(int(current_pid))): + if not (current_pid and self._executive.check_running_pid(int(current_pid))): + _log.debug("Removing stuck lock file: %s" % lock_list[0]) os.unlink(lock_list[0]) return except IOError, OSError: @@ -102,22 +103,34 @@ class HttpLock(object): """The lock files are used to schedule the running test sessions in first come first served order. The sequential guard lock ensures that the lock numbers are sequential.""" + if not os.path.exists(self._lock_path): + _log.debug("Lock directory does not exist: %s" % self._lock_path) + return False + + start_time = time.time() while(True): try: sequential_guard_lock = os.open(self._guard_lock_file, os.O_CREAT | os.O_EXCL) self._process_lock_file_name = (self._lock_file_path_prefix + str(self._next_lock_number())) lock_file = open(self._process_lock_file_name, 'w') + _log.debug("Creating lock file: %s" % self._process_lock_file_name) lock_file.write(str(os.getpid())) lock_file.close() os.close(sequential_guard_lock) os.unlink(self._guard_lock_file) - break + return True except OSError: - pass + if time.time() - start_time > self._guard_lock_max_wait: + _log.debug("Lock does not created: %s" % str(sys.exc_info())) + return False def wait_for_httpd_lock(self): - """Create a lock file and wait until it's turn comes.""" - self._create_lock_file() + """Create a lock file and wait until it's turn comes. If something goes wrong + it wont do any locking.""" + if not self._create_lock_file(): + _log.debug("Warning, http locking failed!") + return + while self._curent_lock_pid() != os.getpid(): time.sleep(1) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py index 0d0d3e0..0b324f5 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py @@ -60,7 +60,6 @@ class WebKitPort(base.Port): def __init__(self, **kwargs): base.Port.__init__(self, **kwargs) - self._cached_build_root = None self._cached_apache_path = None # FIXME: disable pixel tests until they are run by default on the @@ -358,12 +357,8 @@ class WebKitPort(base.Port): 'mac-tiger', 'mac-leopard', 'mac-snowleopard') def _build_path(self, *comps): - if not self._cached_build_root: - self._cached_build_root = self._webkit_build_directory([ - "--configuration", - self.flag_from_configuration(self.get_option('configuration')), - ]) - return os.path.join(self._cached_build_root, *comps) + build_root = self._webkit_configuration_build_directory() + return os.path.join(build_root, *comps) def _path_to_driver(self): return self._build_path('DumpRenderTree') diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py index 434058e..55c4558 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py @@ -70,11 +70,11 @@ _log = logging.getLogger("webkitpy.layout_tests." BASELINE_SUFFIXES = ['.txt', '.png', '.checksum'] REBASELINE_PLATFORM_ORDER = ['mac', 'win', 'win-xp', 'win-vista', 'linux'] -ARCHIVE_DIR_NAME_DICT = {'win': 'webkit-rel', +ARCHIVE_DIR_NAME_DICT = {'win': 'Webkit_Win', 'win-vista': 'webkit-dbg-vista', - 'win-xp': 'webkit-rel', - 'mac': 'webkit-rel-mac5', - 'linux': 'webkit-rel-linux', + 'win-xp': 'Webkit_Win', + 'mac': 'Webkit_Mac10_5', + 'linux': 'webkit-rel-linux64', 'win-canary': 'webkit-rel-webkit-org', 'win-vista-canary': 'webkit-dbg-vista', 'win-xp-canary': 'webkit-rel-webkit-org', @@ -819,9 +819,8 @@ def get_host_port_object(options): return port_obj -def main(executive=Executive()): - """Main function to produce new baselines.""" - +def parse_options(args): + """Parse options and return a pair of host options and target options.""" option_parser = optparse.OptionParser() option_parser.add_option('-v', '--verbose', action='store_true', @@ -874,7 +873,20 @@ def main(executive=Executive()): help=('The target platform to rebaseline ' '("mac", "chromium", "qt", etc.). Defaults ' 'to "chromium".')) - options = option_parser.parse_args()[0] + options = option_parser.parse_args(args)[0] + + target_options = copy.copy(options) + if options.target_platform == 'chromium': + target_options.chromium = True + options.tolerance = 0 + + return (options, target_options) + + +def main(executive=Executive()): + """Main function to produce new baselines.""" + + (options, target_options) = parse_options(sys.argv[1:]) # We need to create three different Port objects over the life of this # script. |target_port_obj| is used to determine configuration information: @@ -882,9 +894,6 @@ def main(executive=Executive()): # |port_obj| is used for runtime functionality like actually diffing # Then we create a rebaselining port to actual find and manage the # baselines. - target_options = copy.copy(options) - if options.target_platform == 'chromium': - target_options.chromium = True target_port_obj = port.get(None, target_options) # Set up our logging format. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py index 8db31a6..7c55b94 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py @@ -95,6 +95,15 @@ class TestRebaseliner(unittest.TestCase): return rebaseline_chromium_webkit_tests.Rebaseliner( host_port_obj, target_port_obj, platform, options) + def test_parse_options(self): + (options, target_options) = rebaseline_chromium_webkit_tests.parse_options([]) + self.assertTrue(target_options.chromium) + self.assertEqual(options.tolerance, 0) + + (options, target_options) = rebaseline_chromium_webkit_tests.parse_options(['--target-platform', 'qt']) + self.assertFalse(hasattr(target_options, 'chromium')) + self.assertEqual(options.tolerance, 0) + def test_noop(self): # this method tests that was can at least instantiate an object, even # if there is nothing to do. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index 704180c..f360adc 100755 --- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py @@ -85,6 +85,8 @@ _log = logging.getLogger("webkitpy.layout_tests.run_webkit_tests") # Builder base URL where we have the archived test results. BUILDER_BASE_URL = "http://build.chromium.org/buildbot/layout_test_results/" +LAYOUT_TESTS_DIRECTORY = "LayoutTests" + os.sep + TestExpectationsFile = test_expectations.TestExpectationsFile @@ -283,12 +285,17 @@ class TestRunner: last_unexpected_results: list of unexpected results to retest, if any """ - paths = [arg for arg in args if arg and arg != ''] + paths = [self._strip_test_dir_prefix(arg) for arg in args if arg and arg != ''] paths += last_unexpected_results if self._options.test_list: paths += read_test_files(self._options.test_list) self._test_files = self._port.tests(paths) + def _strip_test_dir_prefix(self, path): + if path.startswith(LAYOUT_TESTS_DIRECTORY): + return path[len(LAYOUT_TESTS_DIRECTORY):] + return path + def lint(self): # Creating the expecations for each platform/configuration pair does # all the test list parsing and ensures it's correct syntax (e.g. no @@ -404,9 +411,8 @@ class TestRunner: # If we reached the end and we don't have enough tests, we run some # from the beginning. - if (self._options.run_chunk and - (slice_end - slice_start < chunk_len)): - extra = 1 + chunk_len - (slice_end - slice_start) + if slice_end - slice_start < chunk_len: + extra = chunk_len - (slice_end - slice_start) extra_msg = (' last chunk is partial, appending [0:%d]' % extra) self._printer.print_expected(extra_msg) @@ -470,9 +476,9 @@ class TestRunner: def _get_dir_for_test_file(self, test_file): """Returns the highest-level directory by which to shard the given test file.""" - index = test_file.rfind(os.sep + 'LayoutTests' + os.sep) + index = test_file.rfind(os.sep + LAYOUT_TESTS_DIRECTORY) - test_file = test_file[index + len('LayoutTests/'):] + test_file = test_file[index + len(LAYOUT_TESTS_DIRECTORY):] test_file_parts = test_file.split(os.sep, 1) directory = test_file_parts[0] test_file = test_file_parts[1] @@ -741,17 +747,6 @@ class TestRunner: if not result_summary: return None - # Do not start when http locking is enabled. - if not self._options.wait_for_httpd: - if self.needs_http(): - self._printer.print_update('Starting HTTP server ...') - self._port.start_http_server() - - if self.needs_websocket(): - self._printer.print_update('Starting WebSocket server ...') - self._port.start_websocket_server() - # self._websocket_secure_server.Start() - return result_summary def run(self, result_summary): @@ -841,11 +836,6 @@ class TestRunner: sys.stdout.flush() _log.debug("flushing stderr") sys.stderr.flush() - if not self._options.wait_for_httpd: - _log.debug("stopping http server") - self._port.stop_http_server() - _log.debug("stopping websocket server") - self._port.stop_websocket_server() _log.debug("stopping helper") self._port.stop_helper() @@ -948,14 +938,15 @@ class TestRunner: if not self._options.test_results_server: return + if not self._options.master_name: + _log.error("--test-results-server was set, but --master-name was not. Not uploading JSON files.") + return + _log.info("Uploading JSON files for builder: %s", self._options.builder_name) - attrs = [("builder", self._options.builder_name), ("testtype", "layout-tests")] - # FIXME: master_name should be required if test_results_server is set. - # Throw an error if master_name isn't set. - if self._options.master_name: - attrs.append(("master", self._options.master_name)) + attrs = [("builder", self._options.builder_name), ("testtype", "layout-tests"), + ("master", self._options.master_name)] json_files = ["expectations.json"] if self._options.upload_full_results: @@ -966,13 +957,6 @@ class TestRunner: files = [(file, os.path.join(self._options.results_directory, file)) for file in json_files] - # FIXME: Remove this. This is temporary debug logging. - if self._options.builder_name.startswith("Webkit Linux"): - for filename in files: - _log.debug(filename[1]) - with codecs.open(filename[1], "r") as results_file: - _log.debug("%s:\n%s" % (filename[0], results_file.read())) - uploader = test_results_uploader.TestResultsUploader( self._options.test_results_server) try: @@ -1530,7 +1514,7 @@ def parse_args(args=None): default=False, help="Don't check the system dependencies (themes)"), optparse.make_option("--use-drt", action="store_true", - default=False, + default=None, help="Use DumpRenderTree instead of test_shell"), optparse.make_option("--accelerated-compositing", action="store_true", @@ -1612,9 +1596,6 @@ def parse_args(args=None): optparse.make_option("--no-record-results", action="store_false", default=True, dest="record_results", help="Don't record the results."), - optparse.make_option("--wait-for-httpd", action="store_true", - default=False, dest="wait_for_httpd", - help="Wait for http locks."), # old-run-webkit-tests also has HTTP toggle options: # --[no-]http Run (or do not run) http tests # (default: run) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py index 0f09ffa..f21e7a5 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py @@ -31,6 +31,7 @@ """Unit tests for run_webkit_tests.""" import codecs +import itertools import logging import os import Queue @@ -48,7 +49,9 @@ from webkitpy.common.system import user from webkitpy.layout_tests import port from webkitpy.layout_tests import run_webkit_tests from webkitpy.layout_tests.layout_package import dump_render_tree_thread -from webkitpy.layout_tests.port.test import TestPort +from webkitpy.layout_tests.port.test import TestPort, TestDriver +from webkitpy.python24.versioning import compare_version +from webkitpy.test.skip import skip_if from webkitpy.thirdparty.mock import Mock @@ -61,41 +64,44 @@ class MockUser(): self.url = url -def passing_run(args=[], port_obj=None, record_results=False, +def passing_run(extra_args=None, port_obj=None, record_results=False, tests_included=False): - new_args = ['--print', 'nothing'] - if not '--platform' in args: - new_args.extend(['--platform', 'test']) + extra_args = extra_args or [] + args = ['--print', 'nothing'] + if not '--platform' in extra_args: + args.extend(['--platform', 'test']) if not record_results: - new_args.append('--no-record-results') - new_args.extend(args) + args.append('--no-record-results') + args.extend(extra_args) if not tests_included: # We use the glob to test that globbing works. - new_args.extend(['passes', - 'http/tests', - 'http/tests/websocket/tests', - 'failures/expected/*']) - options, parsed_args = run_webkit_tests.parse_args(new_args) - if port_obj is None: + args.extend(['passes', + 'http/tests', + 'http/tests/websocket/tests', + 'failures/expected/*']) + options, parsed_args = run_webkit_tests.parse_args(args) + if not port_obj: port_obj = port.get(port_name=options.platform, options=options, user=MockUser()) res = run_webkit_tests.run(port_obj, options, parsed_args) return res == 0 -def logging_run(args=[], tests_included=False): - new_args = ['--no-record-results'] - if not '--platform' in args: - new_args.extend(['--platform', 'test']) - new_args.extend(args) +def logging_run(extra_args=None, port_obj=None, tests_included=False): + extra_args = extra_args or [] + args = ['--no-record-results'] + if not '--platform' in extra_args: + args.extend(['--platform', 'test']) + args.extend(extra_args) if not tests_included: - new_args.extend(['passes', - 'http/tests', - 'http/tests/websocket/tests', - 'failures/expected/*']) - options, parsed_args = run_webkit_tests.parse_args(new_args) + args.extend(['passes', + 'http/tests', + 'http/tests/websocket/tests', + 'failures/expected/*']) + options, parsed_args = run_webkit_tests.parse_args(args) user = MockUser() - port_obj = port.get(port_name=options.platform, options=options, user=user) + if not port_obj: + port_obj = port.get(port_name=options.platform, options=options, user=user) buildbot_output = array_stream.ArrayStream() regular_output = array_stream.ArrayStream() res = run_webkit_tests.run(port_obj, options, parsed_args, @@ -104,6 +110,54 @@ def logging_run(args=[], tests_included=False): return (res, buildbot_output, regular_output, user) +def get_tests_run(extra_args=None, tests_included=False, flatten_batches=False): + extra_args = extra_args or [] + args = [ + '--print', 'nothing', + '--platform', 'test', + '--no-record-results', + '--child-processes', '1'] + args.extend(extra_args) + if not tests_included: + # Not including http tests since they get run out of order (that + # behavior has its own test, see test_get_test_file_queue) + args.extend(['passes', 'failures']) + options, parsed_args = run_webkit_tests.parse_args(args) + user = MockUser() + + test_batches = [] + + class RecordingTestDriver(TestDriver): + def __init__(self, port, image_path, options): + TestDriver.__init__(self, port, image_path, options, executive=None) + self._current_test_batch = None + + def poll(self): + # So that we don't create a new driver for every test + return None + + def stop(self): + self._current_test_batch = None + + def run_test(self, uri, timeoutms, image_hash): + if self._current_test_batch is None: + self._current_test_batch = [] + test_batches.append(self._current_test_batch) + self._current_test_batch.append(self._port.uri_to_test_name(uri)) + return TestDriver.run_test(self, uri, timeoutms, image_hash) + + class RecordingTestPort(TestPort): + def create_driver(self, image_path, options): + return RecordingTestDriver(self, image_path, options) + + recording_port = RecordingTestPort(options=options, user=user) + logging_run(extra_args=args, port_obj=recording_port, tests_included=True) + + if flatten_batches: + return list(itertools.chain(*test_batches)) + + return test_batches + class MainTest(unittest.TestCase): def test_accelerated_compositing(self): # This just tests that we recognize the command line args @@ -119,8 +173,9 @@ class MainTest(unittest.TestCase): self.assertTrue(passing_run()) def test_batch_size(self): - # FIXME: verify # of tests run - self.assertTrue(passing_run(['--batch-size', '2'])) + batch_tests_run = get_tests_run(['--batch-size', '2']) + for batch in batch_tests_run: + self.assertTrue(len(batch) <= 2, '%s had too many tests' % ', '.join(batch)) def test_child_process_1(self): (res, buildbot_output, regular_output, user) = logging_run( @@ -194,8 +249,15 @@ class MainTest(unittest.TestCase): self.assertTrue(passing_run(['--randomize-order'])) def test_run_chunk(self): - # FIXME: verify # of tests run - self.assertTrue(passing_run(['--run-chunk', '1:4'])) + # Test that we actually select the right chunk + all_tests_run = get_tests_run(flatten_batches=True) + chunk_tests_run = get_tests_run(['--run-chunk', '1:4'], flatten_batches=True) + self.assertEquals(all_tests_run[4:8], chunk_tests_run) + + # Test that we wrap around if the number of tests is not evenly divisible by the chunk size + tests_to_run = ['passes/error.html', 'passes/image.html', 'passes/platform_image.html', 'passes/text.html'] + chunk_tests_run = get_tests_run(['--run-chunk', '1:3'] + tests_to_run, tests_included=True, flatten_batches=True) + self.assertEquals(['passes/text.html', 'passes/error.html', 'passes/image.html'], chunk_tests_run) def test_run_force(self): # This raises an exception because we run @@ -203,23 +265,33 @@ class MainTest(unittest.TestCase): self.assertRaises(ValueError, logging_run, ['--force']) def test_run_part(self): - # FIXME: verify # of tests run - self.assertTrue(passing_run(['--run-part', '1:2'])) + # Test that we actually select the right part + tests_to_run = ['passes/error.html', 'passes/image.html', 'passes/platform_image.html', 'passes/text.html'] + tests_run = get_tests_run(['--run-part', '1:2'] + tests_to_run, tests_included=True, flatten_batches=True) + self.assertEquals(['passes/error.html', 'passes/image.html'], tests_run) + + # Test that we wrap around if the number of tests is not evenly divisible by the chunk size + # (here we end up with 3 parts, each with 2 tests, and we only have 4 tests total, so the + # last part repeats the first two tests). + chunk_tests_run = get_tests_run(['--run-part', '3:3'] + tests_to_run, tests_included=True, flatten_batches=True) + self.assertEquals(['passes/error.html', 'passes/image.html'], chunk_tests_run) def test_run_singly(self): - self.assertTrue(passing_run(['--run-singly'])) + batch_tests_run = get_tests_run(['--run-singly']) + for batch in batch_tests_run: + self.assertEquals(len(batch), 1, '%s had too many tests' % ', '.join(batch)) def test_single_file(self): - # FIXME: verify # of tests run - self.assertTrue(passing_run(['passes/text.html'], tests_included=True)) + tests_run = get_tests_run(['passes/text.html'], tests_included=True, flatten_batches=True) + self.assertEquals(['passes/text.html'], tests_run) def test_test_list(self): filename = tempfile.mktemp() tmpfile = file(filename, mode='w+') tmpfile.write('passes/text.html') tmpfile.close() - self.assertTrue(passing_run(['--test-list=%s' % filename], - tests_included=True)) + tests_run = get_tests_run(['--test-list=%s' % filename], tests_included=True, flatten_batches=True) + self.assertEquals(['passes/text.html'], tests_run) os.remove(filename) res, out, err, user = logging_run(['--test-list=%s' % filename], tests_included=True) @@ -271,7 +343,7 @@ class MainTest(unittest.TestCase): def get_port_for_run(args): options, parsed_args = run_webkit_tests.parse_args(args) test_port = ImageDiffTestPort(options=options, user=MockUser()) - passing_run(args=args, port_obj=test_port, tests_included=True) + passing_run(args, port_obj=test_port, tests_included=True) return test_port base_args = ['--pixel-tests', 'failures/expected/*'] @@ -287,6 +359,8 @@ class MainTest(unittest.TestCase): test_port = get_port_for_run(base_args) self.assertEqual(None, test_port.tolerance_used_for_diff_image) +MainTest = skip_if(MainTest, sys.platform == 'cygwin' and compare_version(sys, '2.6')[0] < 0, 'new-run-webkit-tests tests hang on Cygwin Python 2.5.2') + def _mocked_open(original_open, file_list): def _wrapper(name, mode, encoding): diff --git a/WebKitTools/Scripts/webkitpy/style/checker.py b/WebKitTools/Scripts/webkitpy/style/checker.py index 11e3e33..fb93eb9 100644 --- a/WebKitTools/Scripts/webkitpy/style/checker.py +++ b/WebKitTools/Scripts/webkitpy/style/checker.py @@ -115,7 +115,13 @@ _PATH_RULES_SPECIFIER = [ # Files in these directories are consumers of the WebKit # API and therefore do not follow the same header including # discipline as WebCore. - (["WebKitTools/WebKitAPITest/", + + ([# TestNetscapePlugIn has no config.h and uses funny names like + # NPP_SetWindow. + "WebKitTools/DumpRenderTree/TestNetscapePlugIn/", + # The API test harnesses have no config.h and use funny macros like + # TEST_CLASS_NAME. + "WebKitTools/WebKitAPITest/", "WebKitTools/TestWebKitAPI/"], ["-build/include", "-readability/naming"]), diff --git a/WebKitTools/Scripts/webkitpy/style/optparser.py b/WebKitTools/Scripts/webkitpy/style/optparser.py index 3ba0fae..f4e9923 100644 --- a/WebKitTools/Scripts/webkitpy/style/optparser.py +++ b/WebKitTools/Scripts/webkitpy/style/optparser.py @@ -145,6 +145,7 @@ class CommandOptionValues(object): def __init__(self, filter_rules=None, git_commit=None, + diff_files=None, is_verbose=False, min_confidence=1, output_format="emacs"): @@ -163,6 +164,7 @@ class CommandOptionValues(object): self.filter_rules = filter_rules self.git_commit = git_commit + self.diff_files = diff_files self.is_verbose = is_verbose self.min_confidence = min_confidence self.output_format = output_format @@ -174,6 +176,8 @@ class CommandOptionValues(object): return False if self.git_commit != other.git_commit: return False + if self.diff_files != other.diff_files: + return False if self.is_verbose != other.is_verbose: return False if self.min_confidence != other.min_confidence: @@ -214,6 +218,8 @@ class ArgumentPrinter(object): flags['filter'] = ",".join(filter_rules) if options.git_commit: flags['git-commit'] = options.git_commit + if options.diff_files: + flags['diff_files'] = options.diff_files flag_string = '' # Alphabetizing lets us unit test this method. @@ -308,6 +314,9 @@ class ArgumentParser(object): parser.add_option("-g", "--git-diff", "--git-commit", metavar="COMMIT", dest="git_commit", help=git_commit_help,) + diff_files_help = "diff the files passed on the command line rather than checking the style of every line" + parser.add_option("--diff-files", action="store_true", dest="diff_files", default=False, help=diff_files_help) + min_confidence_help = ("set the minimum confidence of style errors " "to report. Can be an integer 1-5, with 1 " "displaying all errors. Defaults to %default.") @@ -409,6 +418,7 @@ class ArgumentParser(object): filter_value = options.filter_value git_commit = options.git_commit + diff_files = options.diff_files is_verbose = options.is_verbose min_confidence = options.min_confidence output_format = options.output_format @@ -420,10 +430,6 @@ class ArgumentParser(object): # Validate user-provided values. - if paths and git_commit: - self._parse_error('You cannot provide both paths and a git ' - 'commit at the same time.') - min_confidence = int(min_confidence) if (min_confidence < 1) or (min_confidence > 5): self._parse_error('option --min-confidence: invalid integer: ' @@ -442,6 +448,7 @@ class ArgumentParser(object): options = CommandOptionValues(filter_rules=filter_rules, git_commit=git_commit, + diff_files=diff_files, is_verbose=is_verbose, min_confidence=min_confidence, output_format=output_format) diff --git a/WebKitTools/Scripts/webkitpy/style/optparser_unittest.py b/WebKitTools/Scripts/webkitpy/style/optparser_unittest.py index b7e3eda..a6b64da 100644 --- a/WebKitTools/Scripts/webkitpy/style/optparser_unittest.py +++ b/WebKitTools/Scripts/webkitpy/style/optparser_unittest.py @@ -136,11 +136,6 @@ class ArgumentParserTest(LoggingTestCase): self.assertLog(['ERROR: Invalid filter rule "build": ' 'every rule must start with + or -.\n']) parse(['--filter=+build']) # works - # Pass files and git-commit at the same time. - self.assertRaises(SystemExit, parse, ['--git-commit=committish', - 'file.txt']) - self.assertLog(['ERROR: You cannot provide both paths and ' - 'a git commit at the same time.\n']) def test_parse_default_arguments(self): parse = self._parse @@ -151,6 +146,7 @@ class ArgumentParserTest(LoggingTestCase): self.assertEquals(options.filter_rules, []) self.assertEquals(options.git_commit, None) + self.assertEquals(options.diff_files, False) self.assertEquals(options.is_verbose, False) self.assertEquals(options.min_confidence, 3) self.assertEquals(options.output_format, 'vs7') @@ -171,6 +167,8 @@ class ArgumentParserTest(LoggingTestCase): self.assertEquals(options.git_commit, 'commit') (files, options) = parse(['--verbose']) self.assertEquals(options.is_verbose, True) + (files, options) = parse(['--diff-files', 'file.txt']) + self.assertEquals(options.diff_files, True) # Pass user_rules. (files, options) = parse(['--filter=+build,-whitespace']) diff --git a/WebKitTools/Scripts/webkitpy/style_references.py b/WebKitTools/Scripts/webkitpy/style_references.py index 34f3bff..a21e931 100644 --- a/WebKitTools/Scripts/webkitpy/style_references.py +++ b/WebKitTools/Scripts/webkitpy/style_references.py @@ -69,6 +69,6 @@ class WebKitCheckout(object): """Return the checkout root as an absolute path.""" return self._scm.checkout_root - def create_patch(self, git_commit): - return self._scm.create_patch(git_commit) - + def create_patch(self, git_commit, changed_files=None): + # FIXME: SCM.create_patch should understand how to handle None. + return self._scm.create_patch(git_commit, changed_files=changed_files or []) diff --git a/WebKitTools/Scripts/webkitpy/test/cat.py b/WebKitTools/Scripts/webkitpy/test/cat.py new file mode 100644 index 0000000..ae1e143 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/test/cat.py @@ -0,0 +1,42 @@ +# Copyright (C) 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 +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os.path +import sys + +# Add WebKitTools/Scripts to the path to ensure we can find webkitpy. +sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) + +from webkitpy.common.system import fileutils + + +def command_arguments(*args): + return ['python', __file__] + list(args) + + +def main(): + fileutils.make_stdout_binary() + sys.stdout.write(sys.stdin.read()) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/WebKitTools/Scripts/webkitpy/test/cat_unittest.py b/WebKitTools/Scripts/webkitpy/test/cat_unittest.py new file mode 100644 index 0000000..4ed1f67 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/test/cat_unittest.py @@ -0,0 +1,52 @@ +# Copyright (C) 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 +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import StringIO +import os.path +import sys +import unittest + +from webkitpy.common.system import executive, outputcapture +from webkitpy.test import cat + + +class CatTest(outputcapture.OutputCaptureTestCaseBase): + def assert_cat(self, input): + saved_stdin = sys.stdin + sys.stdin = StringIO.StringIO(input) + cat.main() + self.assertStdout(input) + sys.stdin = saved_stdin + + def test_basic(self): + self.assert_cat('foo bar baz\n') + + def test_no_newline(self): + self.assert_cat('foo bar baz') + + def test_unicode(self): + self.assert_cat(u'WebKit \u2661 Tor Arne Vestb\u00F8!') + + def test_as_command(self): + input = 'foo bar baz\n' + output = executive.Executive().run_command(cat.command_arguments(), input=input) + self.assertEqual(input, output) diff --git a/WebKitTools/Scripts/webkitpy/test/echo.py b/WebKitTools/Scripts/webkitpy/test/echo.py new file mode 100644 index 0000000..f7468f7 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/test/echo.py @@ -0,0 +1,52 @@ +# Copyright (C) 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 +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os.path +import sys + +# Add WebKitTools/Scripts to the path to ensure we can find webkitpy. +sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) + +from webkitpy.common.system import fileutils + + +def command_arguments(*args): + return ['python', __file__] + list(args) + + +def main(args=None): + if args is None: + args = sys.argv[1:] + + fileutils.make_stdout_binary() + + print_newline = True + if len(args) and args[0] == '-n': + print_newline = False + del args[0] + sys.stdout.write(' '.join(args)) + if print_newline: + sys.stdout.write('\n') + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/WebKitTools/Scripts/webkitpy/test/echo_unittest.py b/WebKitTools/Scripts/webkitpy/test/echo_unittest.py new file mode 100644 index 0000000..bc13b5e --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/test/echo_unittest.py @@ -0,0 +1,64 @@ +# Copyright (C) 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 +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os.path +import sys +import unittest + +from webkitpy.common.system import executive, outputcapture +from webkitpy.test import echo + + +class EchoTest(outputcapture.OutputCaptureTestCaseBase): + def test_basic(self): + echo.main(['foo', 'bar', 'baz']) + self.assertStdout('foo bar baz\n') + + def test_no_newline(self): + echo.main(['-n', 'foo', 'bar', 'baz']) + self.assertStdout('foo bar baz') + + def test_unicode(self): + echo.main([u'WebKit \u2661', 'Tor Arne', u'Vestb\u00F8!']) + self.assertStdout(u'WebKit \u2661 Tor Arne Vestb\u00F8!\n') + + def test_argument_order(self): + echo.main(['foo', '-n', 'bar']) + self.assertStdout('foo -n bar\n') + + def test_empty_arguments(self): + old_argv = sys.argv + sys.argv = ['echo.py', 'foo', 'bar', 'baz'] + echo.main([]) + self.assertStdout('\n') + sys.argv = old_argv + + def test_no_arguments(self): + old_argv = sys.argv + sys.argv = ['echo.py', 'foo', 'bar', 'baz'] + echo.main() + self.assertStdout('foo bar baz\n') + sys.argv = old_argv + + def test_as_command(self): + output = executive.Executive().run_command(echo.command_arguments('foo', 'bar', 'baz')) + self.assertEqual(output, 'foo bar baz\n') diff --git a/WebKitTools/Scripts/webkitpy/test/skip.py b/WebKitTools/Scripts/webkitpy/test/skip.py new file mode 100644 index 0000000..8587d56 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/test/skip.py @@ -0,0 +1,52 @@ +# Copyright (C) 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 +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import logging + +_log = logging.getLogger(__name__) + + +def skip_if(klass, condition, message=None, logger=None): + """Makes all test_* methods in a given class no-ops if the given condition + is False. Backported from Python 3.1+'s unittest.skipIf decorator.""" + if not logger: + logger = _log + if not condition: + return klass + for name in dir(klass): + attr = getattr(klass, name) + if not callable(attr): + continue + if not name.startswith('test_'): + continue + setattr(klass, name, _skipped_method(attr, message, logger)) + klass._printed_skipped_message = False + return klass + + +def _skipped_method(method, message, logger): + def _skip(*args): + if method.im_class._printed_skipped_message: + return + method.im_class._printed_skipped_message = True + logger.info('Skipping %s.%s: %s' % (method.__module__, method.im_class.__name__, message)) + return _skip diff --git a/WebKitTools/Scripts/webkitpy/test/skip_unittest.py b/WebKitTools/Scripts/webkitpy/test/skip_unittest.py new file mode 100644 index 0000000..f61a1bb --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/test/skip_unittest.py @@ -0,0 +1,77 @@ +# Copyright (C) 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 +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import StringIO +import logging +import unittest + +from webkitpy.test.skip import skip_if + + +class SkipTest(unittest.TestCase): + def setUp(self): + self.logger = logging.getLogger(__name__) + + self.old_level = self.logger.level + self.logger.setLevel(logging.INFO) + + self.old_propagate = self.logger.propagate + self.logger.propagate = False + + self.log_stream = StringIO.StringIO() + self.handler = logging.StreamHandler(self.log_stream) + self.logger.addHandler(self.handler) + + self.foo_was_called = False + + def tearDown(self): + self.logger.removeHandler(self.handler) + self.propagate = self.old_propagate + self.logger.setLevel(self.old_level) + + def create_fixture_class(self): + class TestSkipFixture(object): + def __init__(self, callback): + self.callback = callback + + def test_foo(self): + self.callback() + + return TestSkipFixture + + def foo_callback(self): + self.foo_was_called = True + + def test_skip_if_false(self): + klass = skip_if(self.create_fixture_class(), False, 'Should not see this message.', logger=self.logger) + klass(self.foo_callback).test_foo() + self.assertEqual(self.log_stream.getvalue(), '') + self.assertTrue(self.foo_was_called) + + def test_skip_if_true(self): + klass = skip_if(self.create_fixture_class(), True, 'Should see this message.', logger=self.logger) + klass(self.foo_callback).test_foo() + self.assertEqual(self.log_stream.getvalue(), 'Skipping webkitpy.test.skip_unittest.TestSkipFixture: Should see this message.\n') + self.assertFalse(self.foo_was_called) + +if __name__ == '__main__': + unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py b/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py index 9bdec8f..a070324 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py @@ -2,4 +2,5 @@ from webkitpy.tool.commands.prettydiff import PrettyDiff from webkitpy.tool.commands.rebaseline import Rebaseline +from webkitpy.tool.commands.rebaselineserver import RebaselineServer # FIXME: Add the rest of the commands here. diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html new file mode 100644 index 0000000..5667cd2 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<!-- + 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. +--> +<html> +<head> + <title>Layout Test Rebaseline Server</title> + <link rel="stylesheet" href="/main.css" type="text/css"> + <script src="/main.js"></script> +</head> +<body class="loading"> + <a href="/quitquitquit">Exit</a> +</body> +</html> diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css new file mode 100644 index 0000000..35bd6a5 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css @@ -0,0 +1,56 @@ +/* + * 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. + */ + +body { + font-size: 12px; + font-family: Helvetica, Arial, sans-serif; + padding: 0; + margin: 0; +} + +.loading { + opacity: 0.5; +} + +div { + margin: 0; +} + +a, .link { + color: #aaf; + text-decoration: underline; + cursor: pointer; +} + +.link.selected { + color: #fff; + font-weight: bold; + text-decoration: none; +} diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js new file mode 100644 index 0000000..55f19a4 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js @@ -0,0 +1,36 @@ +/* + * 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. + */ + +function main() +{ + document.body.classList.remove('loading'); +} + +window.addEventListener('DOMContentLoaded', main); diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py b/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py new file mode 100644 index 0000000..0a37677 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py @@ -0,0 +1,157 @@ +# 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. + +"""Starts a local HTTP server which displays layout test failures (given a test +results directory), provides comparisons of expected and actual results (both +images and text) and allows one-click rebaselining of tests.""" +from __future__ import with_statement + +import codecs +import datetime +import mimetypes +import os +import os.path +import shutil +import threading +import time +import urlparse +import BaseHTTPServer + +from optparse import make_option +from wsgiref.handlers import format_date_time + +from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand + + +class RebaselineHTTPServer(BaseHTTPServer.HTTPServer): + def __init__(self, httpd_port, results_directory): + BaseHTTPServer.HTTPServer.__init__(self, ("", httpd_port), RebaselineHTTPRequestHandler) + self.results_directory = results_directory + + +class RebaselineHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + STATIC_FILE_NAMES = frozenset([ + "index.html", + "main.js", + "main.css", + ]) + + STATIC_FILE_DIRECTORY = os.path.join( + os.path.dirname(__file__), "data", "rebaselineserver") + + def do_GET(self): + self._handle_request() + + def do_POST(self): + self._handle_request() + + def _handle_request(self): + # Parse input. + if "?" in self.path: + path, query_string = self.path.split("?", 1) + self.query = urlparse.parse_qs(query_string) + else: + path = self.path + self.query = {} + function_or_file_name = path[1:] or "index.html" + + # See if a static file matches. + if function_or_file_name in RebaselineHTTPRequestHandler.STATIC_FILE_NAMES: + self._serve_static_file(function_or_file_name) + return + + # See if a class method matches. + function_name = function_or_file_name.replace(".", "_") + if not hasattr(self, function_name): + self.send_error(404, "Unknown function %s" % function_name) + return + if function_name[0] == "_": + self.send_error( + 401, "Not allowed to invoke private or protected methods") + return + function = getattr(self, function_name) + function() + + def _serve_static_file(self, static_path): + self._serve_file(os.path.join( + RebaselineHTTPRequestHandler.STATIC_FILE_DIRECTORY, static_path)) + + def quitquitquit(self): + self.send_response(200) + self.send_header("Content-type", "text/plain") + self.end_headers() + self.wfile.write("Quit.\n") + + # Shutdown has to happen on another thread from the server's thread, + # otherwise there's a deadlock + threading.Thread(target=lambda: self.server.shutdown()).start() + + def _serve_file(self, file_path, cacheable_seconds=0): + if not os.path.exists(file_path): + self.send_error(404, "File not found") + return + with codecs.open(file_path, "rb") as static_file: + self.send_response(200) + self.send_header("Content-Length", os.path.getsize(file_path)) + mime_type, encoding = mimetypes.guess_type(file_path) + if mime_type: + self.send_header("Content-type", mime_type) + + if cacheable_seconds: + expires_time = (datetime.datetime.now() + + datetime.timedelta(0, cacheable_seconds)) + expires_formatted = format_date_time( + time.mktime(expires_time.timetuple())) + self.send_header("Expires", expires_formatted) + self.end_headers() + + shutil.copyfileobj(static_file, self.wfile) + + +class RebaselineServer(AbstractDeclarativeCommand): + name = "rebaseline-server" + help_text = __doc__ + argument_names = "/path/to/results/directory" + + def __init__(self): + options = [ + make_option("--httpd-port", action="store", type="int", default=8127, help="Port to use for the the rebaseline HTTP server"), + ] + AbstractDeclarativeCommand.__init__(self, options=options) + + def execute(self, options, args, tool): + results_directory = args[0] + + print "Starting server at http://localhost:%d/" % options.httpd_port + print ("Use the 'Exit' link in the UI, http://localhost:%d/" + "quitquitquit or Ctrl-C to stop") % options.httpd_port + + httpd = RebaselineHTTPServer( + httpd_port=options.httpd_port, + results_directory=results_directory) + httpd.serve_forever() diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py index ed91f5a..e12c8e2 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py @@ -92,6 +92,32 @@ class CleanPendingCommit(AbstractDeclarativeCommand): self._tool.bugs.obsolete_attachment(patch.id(), message) +# FIXME: This should be share more logic with AssignToCommitter and CleanPendingCommit +class CleanReviewQueue(AbstractDeclarativeCommand): + name = "clean-review-queue" + help_text = "Clear r? on obsolete patches so they do not appear in the pending-commit list." + + def execute(self, options, args, tool): + queue_url = "http://webkit.org/pending-review" + # We do this inefficient dance to be more like webkit.org/pending-review + # bugs.queries.fetch_bug_ids_from_review_queue() doesn't return + # closed bugs, but folks using /pending-review will see them. :( + for patch_id in tool.bugs.queries.fetch_attachment_ids_from_review_queue(): + patch = self._tool.bugs.fetch_attachment(patch_id) + if not patch.review() == "?": + continue + attachment_obsolete_modifier = "" + if patch.is_obsolete(): + attachment_obsolete_modifier = "obsolete " + elif patch.bug().is_closed(): + bug_closed_explanation = " If you would like this patch reviewed, please attach it to a new bug (or re-open this bug before marking it for review again)." + else: + # Neither the patch was obsolete or the bug was closed, next patch... + continue + message = "Cleared review? from %sattachment %s so that this bug does not appear in %s.%s" % (attachment_obsolete_modifier, patch.id(), queue_url, bug_closed_explanation) + self._tool.bugs.obsolete_attachment(patch.id(), message) + + class AssignToCommitter(AbstractDeclarativeCommand): name = "assign-to-committer" help_text = "Assign bug to whoever attached the most recent r+'d patch" diff --git a/WebKitTools/Scripts/webkitpy/tool/mocktool.py b/WebKitTools/Scripts/webkitpy/tool/mocktool.py index af232d9..b6ee95f 100644 --- a/WebKitTools/Scripts/webkitpy/tool/mocktool.py +++ b/WebKitTools/Scripts/webkitpy/tool/mocktool.py @@ -424,6 +424,9 @@ class MockSCM(Mock): # will actually be the root. Since getcwd() is wrong, use a globally fake root for now. self.checkout_root = self.fake_checkout_root + def changed_files(self, git_commit=None): + return ["MockFile1"] + def create_patch(self, git_commit, changed_files=None): return "Patch1" diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py b/WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py index af38214..af66c50 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py @@ -52,6 +52,9 @@ class CheckStyle(AbstractStep): args.append("--git-commit") args.append(self._options.git_commit) + args.append("--diff-files") + args.extend(self._changed_files(state)) + try: self._run_script("check-webkit-style", args) except ScriptError, e: diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp b/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp index 2674801..5942ec8 100644 --- a/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp +++ b/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp @@ -45,7 +45,7 @@ InjectedBundleController::InjectedBundleController() { } -void InjectedBundleController::initialize(WKBundleRef bundle) +void InjectedBundleController::initialize(WKBundleRef bundle, WKTypeRef initializationUserData) { m_bundle = bundle; @@ -57,6 +57,12 @@ void InjectedBundleController::initialize(WKBundleRef bundle) didReceiveMessage }; WKBundleSetClient(m_bundle, &client); + + // Initialize the test from the "initializationUserData". + assert(WKGetTypeID(initializationUserData) == WKStringGetTypeID()); + WKStringRef testName = static_cast<WKStringRef>(initializationUserData); + + initializeTestNamed(bundle, Util::toSTD(testName)); } void InjectedBundleController::didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo) @@ -76,16 +82,6 @@ void InjectedBundleController::willDestroyPage(WKBundleRef bundle, WKBundlePageR void InjectedBundleController::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo) { InjectedBundleController* self = static_cast<InjectedBundleController*>(const_cast<void*>(clientInfo)); - - if (WKStringIsEqualToUTF8CString(messageName, "BundleTestInstantiator")) { - assert(WKGetTypeID(messageBody) == WKStringGetTypeID()); - WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody); - - self->initializeTestNamed(bundle, Util::toSTD(messageBodyString)); - - return; - } - assert(self->m_currentTest); self->m_currentTest->didReceiveMessage(bundle, messageName, messageBody); } diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleController.h b/WebKitTools/TestWebKitAPI/InjectedBundleController.h index 8b45fff..91c571e 100644 --- a/WebKitTools/TestWebKitAPI/InjectedBundleController.h +++ b/WebKitTools/TestWebKitAPI/InjectedBundleController.h @@ -38,7 +38,7 @@ class InjectedBundleController { public: static InjectedBundleController& shared(); - void initialize(WKBundleRef); + void initialize(WKBundleRef, WKTypeRef); void dumpTestNames(); void initializeTestNamed(WKBundleRef bundle, const std::string&); diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp b/WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp index 8f9e8ad..355c35b 100644 --- a/WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp +++ b/WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp @@ -31,7 +31,7 @@ extern "C" __declspec(dllexport) #else extern "C" #endif -void WKBundleInitialize(WKBundleRef bundle) +void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData) { - TestWebKitAPI::InjectedBundleController::shared().initialize(bundle); + TestWebKitAPI::InjectedBundleController::shared().initialize(bundle, initializationUserData); } diff --git a/WebKitTools/TestWebKitAPI/PlatformUtilities.cpp b/WebKitTools/TestWebKitAPI/PlatformUtilities.cpp index 2fadf3a..281fb13 100644 --- a/WebKitTools/TestWebKitAPI/PlatformUtilities.cpp +++ b/WebKitTools/TestWebKitAPI/PlatformUtilities.cpp @@ -37,13 +37,10 @@ WKContextRef createContextForInjectedBundleTest(const std::string& testName) { WKRetainPtr<WKStringRef> injectedBundlePath(AdoptWK, createInjectedBundlePath()); WKContextRef context = WKContextCreateWithInjectedBundlePath(injectedBundlePath.get()); - - WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("BundleTestInstantiator")); - WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(testName.c_str())); - // Enqueue message to instantiate the bundle test. - WKContextPostMessageToInjectedBundle(context, messageName.get(), messageBody.get()); - + WKRetainPtr<WKStringRef> testNameString(AdoptWK, WKStringCreateWithUTF8CString(testName.c_str())); + WKContextSetInitializationUserDataForInjectedBundle(context, testNameString.get()); + return context; } diff --git a/WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp b/WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp index b7db746..0ccee5a 100644 --- a/WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp +++ b/WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp @@ -41,10 +41,7 @@ static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef f TEST_ASSERT(WKFrameGetFrameLoadState(frame) == kWKFrameLoadStateFinished); WKURLRef url = WKFrameCopyProvisionalURL(frame); - WKURLRef emptyURL = WKURLCreateWithUTF8CString(""); - TEST_ASSERT(WKURLIsEqual(url, emptyURL)); - WKRelease(url); - WKRelease(emptyURL); + TEST_ASSERT(!url); testDone = true; } diff --git a/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj b/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj index 36eacc5..c130f45 100644 --- a/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj +++ b/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj @@ -239,7 +239,14 @@ isa = PBXProject; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WebKitLauncher" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* WebKit */; projectDirPath = ""; projectRoot = ""; diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl b/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl index a0e36ad..583eb0a 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl @@ -64,6 +64,8 @@ module WTR { // Animation testing. int numberOfActiveAnimations(); boolean pauseAnimationAtTimeOnElementWithId(in DOMString animationName, in double time, in DOMString elementId); + void suspendAnimations(); + void resumeAnimations(); // UserContent testing. void addUserScript(in DOMString source, in boolean runAtStart, in boolean allFrames); diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp index b1bc89d..c4cf892 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp @@ -31,7 +31,7 @@ extern "C" __declspec(dllexport) #else extern "C" #endif -void WKBundleInitialize(WKBundleRef bundle) +void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData) { WTR::InjectedBundle::shared().initialize(bundle); } diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp index e828c46..de37383 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp @@ -150,6 +150,18 @@ bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef anima return WKBundleFramePauseAnimationOnElementWithId(mainFrame, toWK(animationName).get(), toWK(elementId).get(), time); } +void LayoutTestController::suspendAnimations() +{ + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKBundleFrameSuspendAnimations(mainFrame); +} + +void LayoutTestController::resumeAnimations() +{ + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKBundleFrameResumeAnimations(mainFrame); +} + JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const { WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h index dfafb55..427d05e 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h @@ -91,7 +91,9 @@ public: // Animation testing. unsigned numberOfActiveAnimations() const; bool pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId); - + void suspendAnimations(); + void resumeAnimations(); + // Compositing testing. JSRetainPtr<JSStringRef> layerTreeAsText() const; diff --git a/WebKitTools/WebKitTestRunner/TestController.cpp b/WebKitTools/WebKitTestRunner/TestController.cpp index c88062a..8ca0529 100644 --- a/WebKitTools/WebKitTestRunner/TestController.cpp +++ b/WebKitTools/WebKitTestRunner/TestController.cpp @@ -35,6 +35,9 @@ namespace WTR { +static const double defaultLongTimeout = 30; +static const double defaultShortTimeout = 5; + static WKURLRef blankURL() { static WKURLRef staticBlankURL = WKURLCreateWithUTF8CString("about:blank"); @@ -56,6 +59,8 @@ TestController::TestController(int argc, const char* argv[]) , m_usingServerMode(false) , m_state(Initial) , m_doneResetting(false) + , m_longTimeout(defaultLongTimeout) + , m_shortTimeout(defaultShortTimeout) { initialize(argc, argv); controller = this; @@ -146,6 +151,12 @@ void TestController::initialize(int argc, const char* argv[]) for (int i = 1; i < argc; ++i) { std::string argument(argv[i]); + if (argument == "--timeout" && i + 1 < argc) { + m_longTimeout = atoi(argv[++i]); + // Scale up the short timeout to match. + m_shortTimeout = defaultShortTimeout * m_longTimeout / defaultLongTimeout; + continue; + } if (argument == "--pixel-tests") { m_dumpPixels = true; continue; @@ -253,7 +264,7 @@ void TestController::initialize(int argc, const char* argv[]) WKPageSetPageLoaderClient(m_mainWebView->page(), &pageLoaderClient); } -void TestController::resetStateToConsistentValues() +bool TestController::resetStateToConsistentValues() { m_state = Resetting; @@ -285,17 +296,21 @@ void TestController::resetStateToConsistentValues() m_doneResetting = false; WKPageLoadURL(m_mainWebView->page(), blankURL()); - TestController::runUntil(m_doneResetting); + runUntil(m_doneResetting, ShortTimeout); + return m_doneResetting; } -void TestController::runTest(const char* test) +bool TestController::runTest(const char* test) { - resetStateToConsistentValues(); + if (!resetStateToConsistentValues()) + return false; m_state = RunningTest; m_currentInvocation.set(new TestInvocation(test)); m_currentInvocation->invoke(); m_currentInvocation.clear(); + + return true; } void TestController::runTestingServerLoop() @@ -309,7 +324,8 @@ void TestController::runTestingServerLoop() if (strlen(filenameBuffer) == 0) continue; - runTest(filenameBuffer); + if (!runTest(filenameBuffer)) + break; } } @@ -318,11 +334,18 @@ void TestController::run() if (m_usingServerMode) runTestingServerLoop(); else { - for (size_t i = 0; i < m_paths.size(); ++i) - runTest(m_paths[i].c_str()); + for (size_t i = 0; i < m_paths.size(); ++i) { + if (!runTest(m_paths[i].c_str())) + break; + } } } +void TestController::runUntil(bool& done, TimeoutDuration timeoutDuration) +{ + platformRunUntil(done, timeoutDuration == ShortTimeout ? m_shortTimeout : m_longTimeout); +} + // WKContextInjectedBundleClient void TestController::didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo) diff --git a/WebKitTools/WebKitTestRunner/TestController.h b/WebKitTools/WebKitTestRunner/TestController.h index b12f1b2..1396c94 100644 --- a/WebKitTools/WebKitTestRunner/TestController.h +++ b/WebKitTools/WebKitTestRunner/TestController.h @@ -53,22 +53,24 @@ public: WKPageNamespaceRef pageNamespace() { return m_pageNamespace.get(); } WKContextRef context() { return m_context.get(); } - // Helper - static void runUntil(bool& done); + // Runs the run loop until `done` is true or the timeout elapses. + enum TimeoutDuration { ShortTimeout, LongTimeout }; + void runUntil(bool& done, TimeoutDuration); private: void initialize(int argc, const char* argv[]); void run(); void runTestingServerLoop(); - void runTest(const char* pathOrURL); + bool runTest(const char* pathOrURL); void platformInitialize(); void platformInitializeContext(); + void platformRunUntil(bool& done, double timeout); void initializeInjectedBundlePath(); void initializeTestPluginDirectory(); - void resetStateToConsistentValues(); + bool resetStateToConsistentValues(); // WKContextInjectedBundleClient static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*); @@ -102,6 +104,9 @@ private: }; State m_state; bool m_doneResetting; + + double m_longTimeout; + double m_shortTimeout; }; } // namespace WTR diff --git a/WebKitTools/WebKitTestRunner/TestInvocation.cpp b/WebKitTools/WebKitTestRunner/TestInvocation.cpp index 04a56f1..e88de53 100644 --- a/WebKitTools/WebKitTestRunner/TestInvocation.cpp +++ b/WebKitTools/WebKitTestRunner/TestInvocation.cpp @@ -120,7 +120,11 @@ void TestInvocation::invoke() WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("BeginTest")); WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0); - TestController::runUntil(m_gotInitialResponse); + TestController::shared().runUntil(m_gotInitialResponse, TestController::ShortTimeout); + if (!m_gotInitialResponse) { + dump("Timed out waiting for initial response from web process\n"); + return; + } if (m_error) { dump("FAIL\n"); return; @@ -128,7 +132,11 @@ void TestInvocation::invoke() WKPageLoadURL(TestController::shared().mainWebView()->page(), m_url.get()); - TestController::runUntil(m_gotFinalMessage); + TestController::shared().runUntil(m_gotFinalMessage, TestController::LongTimeout); + if (!m_gotFinalMessage) { + dump("Timed out waiting for final message from web process\n"); + return; + } if (m_error) { dump("FAIL\n"); return; diff --git a/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm b/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm index be9aa33..268f718 100644 --- a/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm +++ b/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm @@ -45,10 +45,11 @@ void TestController::initializeTestPluginDirectory() m_testPluginDirectory.adopt(WKStringCreateWithCFString((CFStringRef)[[NSBundle mainBundle] bundlePath])); } -void TestController::runUntil(bool& done) +void TestController::platformRunUntil(bool& done, double timeout) { - while (!done) - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; + CFAbsoluteTime end = CFAbsoluteTimeGetCurrent() + timeout; + while (!done && CFAbsoluteTimeGetCurrent() < end) + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]; } void TestController::platformInitializeContext() diff --git a/WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp b/WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp index d3aee4a..d4de1ba 100644 --- a/WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp +++ b/WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp @@ -83,8 +83,9 @@ void TestController::platformInitialize() { } -void TestController::runUntil(bool& done) +void TestController::platformRunUntil(bool& done, double) { + // FIXME: Honor the timeout parameter <http://webkit.org/b/48941>. RunUntilConditionLoop::start(done); ASSERT(done); } @@ -93,7 +94,7 @@ static bool isExistingLibrary(const QString& path) { #if OS(WINDOWS) || OS(SYMBIAN) const char* librarySuffixes[] = { ".dll" }; -#elif PLATFORM(MAC) +#elif OS(MAC_OS_X) const char* librarySuffixes[] = { ".bundle", ".dylib", ".so" }; #elif OS(UNIX) const char* librarySuffixes[] = { ".so" }; diff --git a/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp b/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp index 9643c40..3fd853f 100644 --- a/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp +++ b/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp @@ -120,15 +120,25 @@ void TestController::initializeTestPluginDirectory() m_testPluginDirectory.adopt(WKStringCreateWithCFString(testPluginDirectoryPath.get())); } -void TestController::runUntil(bool& done) +void TestController::platformRunUntil(bool& done, double timeout) { + DWORD end = ::GetTickCount() + timeout * 1000; while (!done) { - MSG msg; - BOOL result = GetMessage(&msg, 0, 0, 0); - if (result == -1) + DWORD now = ::GetTickCount(); + if (now > end) + return; + + DWORD result = ::MsgWaitForMultipleObjectsEx(0, 0, end - now, QS_ALLINPUT, 0); + if (result == WAIT_TIMEOUT) return; - TranslateMessage(&msg); - DispatchMessage(&msg); + + ASSERT(result == WAIT_OBJECT_0); + // There are messages in the queue. Process them. + MSG msg; + while (::PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) { + ::TranslateMessage(&msg); + ::DispatchMessageW(&msg); + } } } diff --git a/WebKitTools/iExploder/htdocs/cssproperties.in b/WebKitTools/iExploder/htdocs/cssproperties.in index 9ced1c3..d49eb8e 100644 --- a/WebKitTools/iExploder/htdocs/cssproperties.in +++ b/WebKitTools/iExploder/htdocs/cssproperties.in @@ -37,7 +37,6 @@ -webkit-box-pack -webkit-box-reflect -webkit-box-shadow --webkit-box-sizing -webkit-color-correction -webkit-column-break-after -webkit-column-break-before @@ -156,6 +155,7 @@ border-top-style border-top-width border-width bottom +box-sizing caption-side clear clip |