Skip to content

Instantly share code, notes, and snippets.

@yellows8
Created February 24, 2016 15:06
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yellows8/b1e10caa1d8bb8a46316 to your computer and use it in GitHub Desktop.
Save yellows8/b1e10caa1d8bb8a46316 to your computer and use it in GitHub Desktop.
Old3DS browser v10.2 -> v10. OSS diff.
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/JavaScriptCore/wtf/WKC/FastMallocDebugWKC.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/JavaScriptCore/wtf/WKC/FastMallocDebugWKC.cpp
index f839452..59441db 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/JavaScriptCore/wtf/WKC/FastMallocDebugWKC.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/JavaScriptCore/wtf/WKC/FastMallocDebugWKC.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2010,2011 ACCESS CO., LTD. All rights reserved.
+// Copyright (c) 2010,2011,2016 ACCESS CO., LTD. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -1132,6 +1132,8 @@ static void attachAddressInfo(MemoryInfo& inMemInfo, UsedMemoryInfo& inUsedMemIn
{
const int index = findSpanInfo(inMemInfo, inUsedMemInfo, cl);
ASSERT(index >= 0 && index < (int)inMemInfo.numSpanArray);
+ if (!(index >= 0 && index < (int)inMemInfo.numSpanArray))
+ return;
SpanInfo* spanInfo = inMemInfo.spanPtrArray[index];
spanInfo->requestedSize += inUsedMemInfo.requestSize;
if (needUsedMemory) {
@@ -2324,12 +2326,16 @@ static bool initializeStackTrace()
bool ret = false;
#if ENABLE(WKC_FASTMALLOC_WIN_STACK_TRACE)
- gCurProcess = GetCurrentProcess();
+ static bool initialized = false;
+ if (!initialized) {
+ initialized = true;
+ gCurProcess = GetCurrentProcess();
- SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_OMAP_FIND_NEAREST);
+ SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_OMAP_FIND_NEAREST);
- if (!SymInitialize(gCurProcess, NULL, TRUE)) {
- goto exit_func;
+ if (!SymInitialize(gCurProcess, NULL, TRUE)) {
+ goto exit_func;
+ }
}
#endif /* ENABLE(WKC_FASTMALLOC_WIN_STACK_TRACE) */
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebCore/platform/graphics/WKC/PlatformPathWKC.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebCore/platform/graphics/WKC/PlatformPathWKC.cpp
index 585294f..08ef693 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebCore/platform/graphics/WKC/PlatformPathWKC.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebCore/platform/graphics/WKC/PlatformPathWKC.cpp
@@ -258,6 +258,8 @@ static void addArcPoints(PathPolygon& poly, const PlatformPathElement::ArcTo& da
double curAngle = startPoint - data.m_center;
double endAngle = data.m_end - data.m_center;
double angleStep = 2. / std::max(data.m_radius.m_x, data.m_radius.m_y);
+ if (fabs(angleStep) < 1E-10)
+ return;
if (data.m_clockwise) {
if (endAngle <= curAngle || startPoint == data.m_end)
endAngle += 2 * piDouble;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebCore/platform/network/WKC/ResourceHandleManager.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebCore/platform/network/WKC/ResourceHandleManager.cpp
index 754e2c8..dc3ba1e 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebCore/platform/network/WKC/ResourceHandleManager.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebCore/platform/network/WKC/ResourceHandleManager.cpp
@@ -12,7 +12,7 @@
* Copyright (C) 2009 Appcelerator Inc.
* Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org>
* All rights reserved.
- * Copyright (c) 2010-2013 ACCESS CO., LTD. All rights reserved.
+ * Copyright (c) 2010-2013, 2016 ACCESS CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1471,9 +1471,11 @@ static void parseDataUrl(ResourceHandle* job)
{
FUNCTIONPRINTF(("<rhm>parseDataUrl(%p)", job));
- ResourceHandleClient* client = job->client();
- ASSERT(client);
- if (!client)
+ if (!job || job->getInternal()->m_cancelled)
+ return;
+
+ ASSERT(job->client());
+ if (!job->client())
return;
String url = job->request().url().string();
@@ -1481,7 +1483,7 @@ static void parseDataUrl(ResourceHandle* job)
int index = url.find(',');
if (index == -1) {
- client->cannotShowURL(job);
+ job->client()->cannotShowURL(job);
return;
}
@@ -1506,18 +1508,21 @@ static void parseDataUrl(ResourceHandle* job)
if (base64) {
data = decodeURLEscapeSequences(data);
response.setTextEncodingName(charset);
- client->didReceiveResponse(job, response);
if (job->getInternal()->m_cancelled)
return;
- client = job->client();
+ if (job->client())
+ job->client()->didReceiveResponse(job, response);
+
+ if (job->getInternal()->m_cancelled)
+ return;
// WebCore's decoder fails on Acid3 test 97 (whitespace).
Vector<char> out;
- if (client && base64Decode(data.latin1().data(), data.latin1().length(), out) && out.size() > 0) {
- client->willReceiveData(job, out.size());
+ if (job->client() && base64Decode(data.latin1().data(), data.latin1().length(), out) && out.size() > 0) {
+ job->client()->willReceiveData(job, out.size());
if (job->getInternal()->m_cancelled)
return;
- client->didReceiveData(job, out.data(), out.size(), 0);
+ job->client()->didReceiveData(job, out.data(), out.size(), 0);
if (job->getInternal()->m_cancelled)
return;
}
@@ -1525,23 +1530,24 @@ static void parseDataUrl(ResourceHandle* job)
// We have to convert to UTF-16 early due to limitations in KURL
data = decodeURLEscapeSequences(data, TextEncoding(charset));
response.setTextEncodingName("UTF-16");
- client->didReceiveResponse(job, response);
+ if (job->client())
+ job->client()->didReceiveResponse(job, response);
if (job->getInternal()->m_cancelled)
return;
- client = job->client();
- if (client && data.length() > 0) {
- client->willReceiveData(job, data.length() * sizeof(UChar));
+ if (job->client() && data.length() > 0) {
+ job->client()->willReceiveData(job, data.length() * sizeof(UChar));
if (job->getInternal()->m_cancelled)
return;
- client->didReceiveData(job, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);
+ if (job->client())
+ job->client()->didReceiveData(job, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);
if (job->getInternal()->m_cancelled)
return;
}
}
- if (client)
- client->didFinishLoading(job);
+ if (job->client())
+ job->client()->didFinishLoading(job);
}
void ResourceHandleManager::dispatchSynchronousJob(ResourceHandle* job)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebCore/platform/network/WKC/ResourceHandleManagerSSL.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebCore/platform/network/WKC/ResourceHandleManagerSSL.cpp
index 0c9970f..6e2e7ba 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebCore/platform/network/WKC/ResourceHandleManagerSSL.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebCore/platform/network/WKC/ResourceHandleManagerSSL.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010,2011 ACCESS CO., LTD. All rights reserved.
+ * Copyright (c) 2010,2011,2016 ACCESS CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -504,7 +504,7 @@ void ResourceHandleManagerSSL::initializeHandleSSL(ResourceHandle* job)
curl_easy_setopt(d->m_handle, CURLOPT_SSL_STATE_FUNCTION, ssl_state_callback);
curl_easy_setopt(d->m_handle, CURLOPT_SSL_STATE_DATA, job);
- curl_easy_setopt(d->m_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
+ curl_easy_setopt(d->m_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1|CURL_SSLVERSION_TLSv1_1|CURL_SSLVERSION_TLSv1_2);
curl_easy_setopt(d->m_handle, CURLOPT_CERTINFO, 1L);
if (allowsServerHost(SSLhostAndPort(kurl))) {
@@ -516,6 +516,8 @@ void ResourceHandleManagerSSL::initializeHandleSSL(ResourceHandle* job)
curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, 1);
}
+ curl_easy_setopt(d->m_handle, CURLOPT_SSL_CIPHER_LIST, "ALL:!aNULL:!eNULL:!SSLv2:!RC2:!RC4:!DES:!EXPORT56:!ADH:+HIGH:+MEDIUM:!LOW");
+
d->m_SSLVerifyPeerResult = 0;
d->m_SSLVerifyHostResult = 0;
d->m_certChain = 0;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebCore/platform/text/WKC/TextCodecWKC.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebCore/platform/text/WKC/TextCodecWKC.cpp
index c252799..2ffb433 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebCore/platform/text/WKC/TextCodecWKC.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebCore/platform/text/WKC/TextCodecWKC.cpp
@@ -3,7 +3,7 @@
* Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
* Copyright (C) 2008 Jurg Billeter <j@bitron.ch>
* Copyright (C) 2009 Dominik Rottsches <dominik.roettsches@access-company.com>
- * Copyright (c) 2010,2011 ACCESS CO., LTD. All rights reserved.
+ * Copyright (c) 2010,2011,2016 ACCESS CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -447,16 +447,30 @@ TextCodecWKC::decode(const char* str, size_t length, bool flush, bool stopOnErro
}
CString
-TextCodecWKC::encode(const UChar* str, size_t length, UnencodableHandling)
+TextCodecWKC::encode(const UChar* str, size_t length, UnencodableHandling handling)
{
int len, len2;
char* buf = NULL;
int remains = 0;
CString ret;
+ int fallback = WKC_I18N_ENCODEERRORFALLBACK_NONE;
if (!str || !length) {
goto error_end;
}
+ switch (handling) {
+ case QuestionMarksForUnencodables:
+ fallback = WKC_I18N_ENCODEERRORFALLBACK_QUESTION;
+ break;
+ case EntitiesForUnencodables:
+ fallback = WKC_I18N_ENCODEERRORFALLBACK_ESCAPE_XML_DECIMAL;
+ break;
+ case URLEncodedEntitiesForUnencodables:
+ fallback = WKC_I18N_ENCODEERRORFALLBACK_ESCAPE_URLENCODE;
+ break;
+ default:
+ break;
+ }
// should we consider dividing between surrogate pair ?
// 100331 ACCESS Co.,Ltd.
@@ -467,14 +481,14 @@ TextCodecWKC::encode(const UChar* str, size_t length, UnencodableHandling)
goto error_end;
}
}
- len = wkcI18NEncodePeer(m_encoder, str, length, NULL, NULL, &remains);
+ len = wkcI18NEncodePeer(m_encoder, str, length, NULL, NULL, &remains, fallback);
if (len<=0) {
goto error_end;
}
len += wkcI18NFlushEncodeStatePeer(m_encoder, false, NULL, NULL);
ret = CString::newUninitialized(len, buf);
- len2 = wkcI18NEncodePeer(m_encoder, str, length, buf, len, &remains);
+ len2 = wkcI18NEncodePeer(m_encoder, str, length, buf, len, &remains, fallback);
wkcI18NFlushEncodeStatePeer(m_encoder, false, buf + len2, len - len2);
return ret;
@@ -482,32 +496,32 @@ TextCodecWKC::encode(const UChar* str, size_t length, UnencodableHandling)
error_end:
return CString("");
}
-
-// returned value: 0 or more if succeeded, -1 if failed.
-int
-TextCodecWKC::getDecodedTextLength(const char* str, size_t length)
-{
- int ulen = 0;
-
- if (!m_decoder) {
- m_decoder = wkcI18NBeginDecodePeer(m_codecId);
- if (!m_decoder) {
- return -1;
- }
- }
-
- if (!str || !length) {
- return 0;
- }
-
- wkcI18NSaveDecodeStatePeer(m_decoder);
- ulen = decode(str, length, 0, 0);
- wkcI18NRestoreDecodeStatePeer(m_decoder);
- if (ulen < 0) {
- return -1;
- }
-
- return ulen;
-}
+
+// returned value: 0 or more if succeeded, -1 if failed.
+int
+TextCodecWKC::getDecodedTextLength(const char* str, size_t length)
+{
+ int ulen = 0;
+
+ if (!m_decoder) {
+ m_decoder = wkcI18NBeginDecodePeer(m_codecId);
+ if (!m_decoder) {
+ return -1;
+ }
+ }
+
+ if (!str || !length) {
+ return 0;
+ }
+
+ wkcI18NSaveDecodeStatePeer(m_decoder);
+ ulen = decode(str, length, 0, 0);
+ wkcI18NRestoreDecodeStatePeer(m_decoder);
+ if (ulen < 0) {
+ return -1;
+ }
+
+ return ulen;
+}
} // namespace WebCore
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebKit/WKC/WebCoreSupport/FrameLoaderClientWKC.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebKit/WKC/WebCoreSupport/FrameLoaderClientWKC.cpp
index 11f0260..a6efe85 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebKit/WKC/WebCoreSupport/FrameLoaderClientWKC.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebKit/WKC/WebCoreSupport/FrameLoaderClientWKC.cpp
@@ -614,8 +614,9 @@ FrameLoaderClientWKC::createFrame(const WebCore::KURL& url, const WebCore::Strin
if (!child) return 0;
RefPtr<WebCore::Frame> childframe = adoptRef(child->privateFrame()->core());
- frame->tree()->appendChild(childframe);
+
childframe->tree()->setName(name);
+ frame->tree()->appendChild(childframe);
childframe->init();
if (!childframe->page()) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebKit/WKC/webkit/WKCVersion.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebKit/WKC/webkit/WKCVersion.h
index fc153c4..09d458a 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebKit/WKC/webkit/WKCVersion.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebKit/WKC/webkit/WKCVersion.h
@@ -1,7 +1,7 @@
/*
* WKCVersion.h
*
- * Copyright (c) 2013-2015 ACCESS CO., LTD. All rights reserved.
+ * Copyright (c) 2013-2016 ACCESS CO., LTD. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,7 +29,7 @@
#define WKC_VERSION_CHECK(major, minor, micro) \
(((major)*10000) + ((minor)*100) + (micro)) >= ((WKC_VERSION_MAJOR*10000) + (WKC_VERSION_MINOR*100) + (WKC_VERSION_MICRO))
-#define WKC_CUSTOMER_RELEASE_VERSION "1.8.17"
+#define WKC_CUSTOMER_RELEASE_VERSION "1.8.18"
#define WKC_WEBKIT_VERSION "532.7"
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebKit/WKC/webkit/WKCWebFrame.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebKit/WKC/webkit/WKCWebFrame.cpp
index a1a9d3a..948d983 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebKit/WKC/webkit/WKCWebFrame.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebKit/WKC/webkit/WKCWebFrame.cpp
@@ -216,7 +216,6 @@ WKCWebFrame::construct(WKCWebViewPrivate* view, WKCClientBuilders& builders, WKC
}
m_private = WKCWebFramePrivate::create(this, view, builders, owner);
if (!m_private) return false;
- m_private->core()->init();
return true;
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebKit/WKC/webkit/WKCWebView.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebKit/WKC/webkit/WKCWebView.cpp
index 47ebea4..a1bcb40 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/WKC/WebKit/WKC/webkit/WKCWebView.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/WKC/WebKit/WKC/webkit/WKCWebView.cpp
@@ -11,7 +11,7 @@
Copyright (C) 2009 Igalia S.L.
Copyright (C) 2009 Movial Creative Technologies Inc.
Copyright (C) 2009 Bobby Powers
- Copyright (c) 2010-2013 ACCESS CO., LTD. All rights reserved.
+ Copyright (c) 2010-2015 ACCESS CO., LTD. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -160,6 +160,7 @@
#include "html/HTMLOptGroupElement.h"
#include "html/HTMLOptionElement.h"
#include "html/HTMLParser.h"
+#include "html/HTMLTokenizer.h"
#include "html/HTMLSelectElement.h"
#include "html/HTMLTableElement.h"
#include "html/HTMLTextAreaElement.h"
@@ -279,6 +280,7 @@ extern bool initializeSharedTimer();
extern void finalizeSharedTimer();
extern void RenderThemeWKC_resetVariables();
+extern void RenderSlider_resetVariables();
extern void CookieJar_resetVariables();
extern void JSImageDataCustom_deleteSharedInstance();
extern void JSImageDataCustom_resetVariables();
@@ -467,6 +469,7 @@ WKCWebViewPrivate::construct()
m_mainFrame = WKC::WKCWebFrame::create(this, m_clientBuilders);
if (!m_mainFrame) goto error_end;
+ m_mainFrame->privateFrame()->core()->init();
m_dropdownlist = WKC::DropDownListClientWKC::create(this);
if (!m_dropdownlist) goto error_end;
@@ -3594,6 +3597,7 @@ WKCWebKitResetVariables()
WebCore::HTMLOptGroupElement::resetVariables();
WebCore::HTMLOptionElement::resetVariables();
WebCore::HTMLParser::resetVariables();
+ WebCore::HTMLTokenizer::resetVariables();
WebCore::HTMLSelectElement::resetVariables();
WebCore::HTMLTableElement::resetVariables();
WebCore::HTMLTextAreaElement::resetVariables();
@@ -3614,6 +3618,7 @@ WKCWebKitResetVariables()
WebCore::Pasteboard::resetVariables();
WebCore::RenderThemeWKC_resetVariables();
+ WebCore::RenderSlider_resetVariables();
WebCore::ScrollbarTheme::resetVariables();
WebCore::HTMLElementFactory::resetVariables();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/ChangeLog b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/ChangeLog
index bf0c440..69ad491 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/ChangeLog
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/ChangeLog
@@ -1,3 +1,144 @@
+2013-08-16 Filip Pizlo <fpizlo@apple.com>
+
+ Object properties added using dot syntax (o.f = ...) from code that isn't in eval should be less likely to cause an object to become a dictionary
+ https://bugs.webkit.org/show_bug.cgi?id=119897
+
+ Reviewed by Oliver Hunt.
+
+ 6-10x speed-up on microbenchmarks that create large static objects. 40-65% speed-up
+ on Octane/gbemu. 3% overall speed-up on Octane. No slow-downs anywhere; our ability
+ to turn objects into dictionaries when you're storing using bracket syntax or using
+ eval is still in place.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::putByIdContext):
+ * dfg/DFGOperations.cpp:
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * runtime/JSObject.h:
+ (JSC::JSObject::putDirectInternal):
+ * runtime/PutPropertySlot.h:
+ (JSC::PutPropertySlot::PutPropertySlot):
+ (JSC::PutPropertySlot::context):
+ * runtime/Structure.cpp:
+ (JSC::Structure::addPropertyTransition):
+ * runtime/Structure.h:
+
+2012-11-26 Daniel Bates <dbates@webkit.org>
+
+ JavaScript fails to handle String.replace() with large replacement string
+ https://bugs.webkit.org/show_bug.cgi?id=102956
+ <rdar://problem/12738012>
+
+ Reviewed by Oliver Hunt.
+
+ Fix an issue where we didn't check for overflow when computing the length
+ of the result of String.replace() with a large replacement string.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::jsSpliceSubstringsWithSeparators):
+
+2011-10-18 Gavin Barraclough <barraclough@apple.com>
+
+ Array.prototype methods missing exception checks
+ https://bugs.webkit.org/show_bug.cgi?id=70360
+
+ Reviewed by Geoff Garen.
+
+ Missing exception checks after calls to the static getProperty helper,
+ these may result in the wrong exception being thrown (or an ASSERT being hit,
+ as is currently the case running test-262).
+
+ No performance impact.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncConcat):
+ (JSC::arrayProtoFuncReverse):
+ (JSC::arrayProtoFuncShift):
+ (JSC::arrayProtoFuncSlice):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncUnShift):
+ (JSC::arrayProtoFuncReduce):
+ (JSC::arrayProtoFuncReduceRight):
+ (JSC::arrayProtoFuncIndexOf):
+ (JSC::arrayProtoFuncLastIndexOf):
+
+2011-05-31 Yong Li <yoli@rim.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=54807
+ We have been assuming plain bitfields (like "int a : 31") are always signed integers.
+ However some compilers can treat them as unsigned. For example, RVCT 4.0 states plain
+ bitfields (declared without either signed or unsigned qualifiers) are treats as unsigned.
+ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0348c/Babjddhe.html
+ Although we can use "--signed-bitfields" flag to make RVCT 4.0 behave as most other compilers,
+ always using "signed"/"unsigned" qualifier to declare integral type bitfields is still a good
+ rule we should have in order to make our code independent from compilers and compiler flags.
+
+ No new test added because this change is not known to fix any issue.
+
+ * bytecode/StructureStubInfo.h:
+
+2011-04-12 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=58395
+ Exceptions thrown from property getters called from Array prototype functions can be missed
+
+ This is caught by an ASSERT in the top of Interpreter::executeCall.
+ Check for exceptions after accessing properties that could be getters.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncSort):
+ (JSC::arrayProtoFuncFilter):
+ (JSC::arrayProtoFuncMap):
+ (JSC::arrayProtoFuncEvery):
+ (JSC::arrayProtoFuncForEach):
+ (JSC::arrayProtoFuncSome):
+ (JSC::arrayProtoFuncReduce):
+ (JSC::arrayProtoFuncReduceRight):
+ - Add exception checks.
+
+2011-01-18 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Antti Koivisto.
+
+ [jsfunfuzz] Assertion in codegen for array of NaN constants
+ https://bugs.webkit.org/show_bug.cgi?id=52643
+
+ Don't cache NaN literals in the code generator, as NaN doesn't compare
+ as equal to itself it causes problems when rehashing the number cache.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitLoad):
+
+2010-09-29 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Add additional checks to StringBuffer.
+ <rdar://problem/7756381>
+
+ * wtf/text/StringBuffer.h:
+ (WTF::StringBuffer::StringBuffer):
+ (WTF::StringBuffer::resize):
+
+2010-01-13 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by NOBODY (OOPS!).
+
+ https://bugs.webkit.org/show_bug.cgi?id=33641
+ Assertion failure in Lexer.cpp if input stream ends while in string escape
+
+ Test: fast/js/end-in-string-escape.html
+
+ * parser/Lexer.cpp: (JSC::Lexer::lex): Bail out quickly on end of stream, not giving the
+ assertion a chance to fire.
+
2010-01-08 Norbert Leser <norbert.leser@nokia.com>
Reviewed by Darin Adler.
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/bytecode/CodeBlock.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/bytecode/CodeBlock.h
index eb874cc..35275a7 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/bytecode/CodeBlock.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/bytecode/CodeBlock.h
@@ -36,6 +36,7 @@
#include "JSGlobalObject.h"
#include "JumpTable.h"
#include "Nodes.h"
+#include "PutPropertySlot.h"
#include "PtrAndFlags.h"
#include "RegExp.h"
#include "UString.h"
@@ -376,6 +377,12 @@ namespace JSC {
bool usesArguments() const { return m_usesArguments; }
CodeType codeType() const { return m_codeType; }
+ PutPropertySlot::Context putByIdContext() const
+ {
+ if (codeType() == EvalCode)
+ return PutPropertySlot::PutByIdEval;
+ return PutPropertySlot::PutById;
+ }
SourceProvider* source() const { return m_source.get(); }
unsigned sourceOffset() const { return m_sourceOffset; }
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/bytecode/StructureStubInfo.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/bytecode/StructureStubInfo.h
index 8e2c489..1d49245 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -140,8 +140,8 @@ namespace JSC {
seen = true;
}
- int accessType : 31;
- int seen : 1;
+ signed accessType : 31;
+ unsigned seen : 1;
union {
struct {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 4cf543c..a050f22 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -985,8 +985,9 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
{
// FIXME: Our hash tables won't hold infinity, so we make a new JSNumberCell each time.
- // Later we can do the extra work to handle that like the other cases.
- if (number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
+ // Later we can do the extra work to handle that like the other cases. They also don't
+ // work correctly with NaN as a key.
+ if (isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
return emitLoad(dst, jsNumber(globalData(), number));
JSValue& valueInMap = m_numberMap.add(number, JSValue()).first->second;
if (!valueInMap)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/interpreter/Interpreter.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/interpreter/Interpreter.cpp
index ceee9b6..679f540 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/interpreter/Interpreter.cpp
@@ -1679,7 +1679,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
+#if PLATFORM(WKC)
+ if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() > 0) {
+#else
if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) {
+#endif
JSValue result = jsNumber(callFrame, dividend.asInt32() % divisor.asInt32());
ASSERT(result);
callFrame->r(dst) = result;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/jit/JITStubs.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/jit/JITStubs.cpp
index fb7f931..4a8c5bc 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/jit/JITStubs.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/jit/JITStubs.cpp
@@ -1146,7 +1146,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
{
STUB_INIT_STACK_FRAME(stackFrame);
- PutPropertySlot slot;
+ PutPropertySlot slot(stackFrame.callFrame->codeBlock()->putByIdContext());
stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1174,7 +1174,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
- PutPropertySlot slot;
+ PutPropertySlot slot(stackFrame.callFrame->codeBlock()->putByIdContext());
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
@@ -1194,7 +1194,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_fail)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
- PutPropertySlot slot;
+ PutPropertySlot slot(stackFrame.callFrame->codeBlock()->putByIdContext());
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/parser/Lexer.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/parser/Lexer.cpp
index 15bda7b..2a269b8 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/parser/Lexer.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/parser/Lexer.cpp
@@ -142,19 +142,19 @@ void Lexer::setCode(const SourceCode& source, ParserArena& arena)
m_lastToken = -1;
const UChar* data = source.provider()->data();
-#if PLATFORM(WKC)
- if (!data) {
- m_source = &source;
- const_cast<SourceCode*>(m_source)->invalidate();
- m_codeStart = (UChar*)0;
- m_code = (UChar*)0;
- m_codeEnd = (UChar*)0;
- m_codeWithoutBOMs.shrink(0);
- m_error = true;
- m_atLineStart = true;
- m_current = m_next1 = m_next2 = m_next3 = -1;
- return;
- }
+#if PLATFORM(WKC)
+ if (!data) {
+ m_source = &source;
+ const_cast<SourceCode*>(m_source)->invalidate();
+ m_codeStart = (UChar*)0;
+ m_code = (UChar*)0;
+ m_codeEnd = (UChar*)0;
+ m_codeWithoutBOMs.shrink(0);
+ m_error = true;
+ m_atLineStart = true;
+ m_current = m_next1 = m_next2 = m_next3 = -1;
+ return;
+ }
#endif
m_source = &source;
@@ -654,6 +654,8 @@ inStringEscapeSequence:
shiftLineTerminator();
goto inString;
}
+ if (m_current == -1)
+ goto returnError;
record16(singleEscape(m_current));
shift1();
goto inString;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp
index 13120dc..a121435 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -326,7 +326,10 @@ JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue t
unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
JSObject* curObject = curArg.toObject(exec);
for (unsigned k = 0; k < length; ++k) {
- if (JSValue v = getProperty(exec, curObject, k))
+ JSValue v = getProperty(exec, curObject, k);
+ if (exec->hadException())
+ return jsUndefined();
+ if (v)
arr->put(exec, n, v);
n++;
}
@@ -388,7 +391,11 @@ JSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValue
for (unsigned k = 0; k < middle; k++) {
unsigned lk1 = length - k - 1;
JSValue obj2 = getProperty(exec, thisObj, lk1);
+ if (exec->hadException())
+ return jsUndefined();
JSValue obj = getProperty(exec, thisObj, k);
+ if (exec->hadException())
+ return jsUndefined();
if (obj2)
thisObj->put(exec, k, obj2);
@@ -415,7 +422,10 @@ JSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec, JSObject*, JSValue th
} else {
result = thisObj->get(exec, 0);
for (unsigned k = 1; k < length; k++) {
- if (JSValue obj = getProperty(exec, thisObj, k))
+ JSValue obj = getProperty(exec, thisObj, k);
+ if (exec->hadException())
+ return jsUndefined();
+ if (obj)
thisObj->put(exec, k - 1, obj);
else
thisObj->deleteProperty(exec, k - 1);
@@ -464,7 +474,10 @@ JSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValue th
int b = static_cast<int>(begin);
int e = static_cast<int>(end);
for (int k = b; k < e; k++, n++) {
- if (JSValue v = getProperty(exec, thisObj, k))
+ JSValue v = getProperty(exec, thisObj, k);
+ if (exec->hadException())
+ return jsUndefined();
+ if (v)
resObj->put(exec, n, v);
}
resObj->setLength(n);
@@ -498,10 +511,14 @@ JSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue thi
// or quicksort, and much less swapping than bubblesort/insertionsort.
for (unsigned i = 0; i < length - 1; ++i) {
JSValue iObj = thisObj->get(exec, i);
+ if (exec->hadException())
+ return jsUndefined();
unsigned themin = i;
JSValue minObj = iObj;
for (unsigned j = i + 1; j < length; ++j) {
JSValue jObj = thisObj->get(exec, j);
+ if (exec->hadException())
+ return jsUndefined();
double compareResult;
if (jObj.isUndefined())
compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
@@ -574,7 +591,10 @@ JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue t
deleteCount = length - begin;
for (unsigned k = 0; k < deleteCount; k++) {
- if (JSValue v = getProperty(exec, thisObj, k + begin))
+ JSValue v = getProperty(exec, thisObj, k + begin);
+ if (exec->hadException())
+ return jsUndefined();
+ if (v)
resObj->put(exec, k, v);
}
resObj->setLength(deleteCount);
@@ -583,7 +603,10 @@ JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue t
if (additionalArgs != deleteCount) {
if (additionalArgs < deleteCount) {
for (unsigned k = begin; k < length - deleteCount; ++k) {
- if (JSValue v = getProperty(exec, thisObj, k + deleteCount))
+ JSValue v = getProperty(exec, thisObj, k + deleteCount);
+ if (exec->hadException())
+ return jsUndefined();
+ if (v)
thisObj->put(exec, k + additionalArgs, v);
else
thisObj->deleteProperty(exec, k + additionalArgs);
@@ -592,7 +615,10 @@ JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue t
thisObj->deleteProperty(exec, k - 1);
} else {
for (unsigned k = length - deleteCount; k > begin; --k) {
- if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1))
+ JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1);
+ if (exec->hadException())
+ return jsUndefined();
+ if (obj)
thisObj->put(exec, k + additionalArgs - 1, obj);
else
thisObj->deleteProperty(exec, k + additionalArgs - 1);
@@ -615,7 +641,10 @@ JSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValue
unsigned nrArgs = args.size();
if (nrArgs) {
for (unsigned k = length; k > 0; --k) {
- if (JSValue v = getProperty(exec, thisObj, k - 1))
+ JSValue v = getProperty(exec, thisObj, k - 1);
+ if (exec->hadException())
+ return jsUndefined();
+ if (v)
thisObj->put(exec, k + nrArgs - 1, v);
else
thisObj->deleteProperty(exec, k + nrArgs - 1);
@@ -672,6 +701,9 @@ JSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue t
JSValue v = slot.getValue(exec, k);
+ if (exec->hadException())
+ return jsUndefined();
+
MarkedArgumentBuffer eachArguments;
eachArguments.append(v);
@@ -725,12 +757,18 @@ JSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue this
JSValue v = slot.getValue(exec, k);
+ if (exec->hadException())
+ return jsUndefined();
+
MarkedArgumentBuffer eachArguments;
eachArguments.append(v);
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
+ if (exec->hadException())
+ return jsUndefined();
+
JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
resultArray->put(exec, k, result);
}
@@ -788,6 +826,9 @@ JSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue th
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
+ if (exec->hadException())
+ return jsUndefined();
+
bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (!predicateResult) {
@@ -839,6 +880,9 @@ JSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValue
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
+ if (exec->hadException())
+ return jsUndefined();
+
call(exec, function, callType, callData, applyThis, eachArguments);
}
return jsUndefined();
@@ -887,6 +931,9 @@ JSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue thi
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
+ if (exec->hadException())
+ return jsUndefined();
+
bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (predicateResult) {
@@ -924,6 +971,8 @@ JSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec, JSObject*, JSValue t
} else {
for (i = 0; i < length; i++) {
rv = getProperty(exec, thisObj, i);
+ if (exec->hadException())
+ return jsUndefined();
if (rv)
break;
}
@@ -953,6 +1002,8 @@ JSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec, JSObject*, JSValue t
for (; i < length && !exec->hadException(); ++i) {
JSValue prop = getProperty(exec, thisObj, i);
+ if (exec->hadException())
+ return jsUndefined();
if (!prop)
continue;
@@ -994,6 +1045,8 @@ JSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec, JSObject*, JSVa
} else {
for (i = 0; i < length; i++) {
rv = getProperty(exec, thisObj, length - i - 1);
+ if (exec->hadException())
+ return jsUndefined();
if (rv)
break;
}
@@ -1022,6 +1075,8 @@ JSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec, JSObject*, JSVa
for (; i < length && !exec->hadException(); ++i) {
unsigned idx = length - i - 1;
JSValue prop = getProperty(exec, thisObj, idx);
+ if (exec->hadException())
+ return jsUndefined();
if (!prop)
continue;
@@ -1058,6 +1113,8 @@ JSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue
JSValue searchElement = args.at(0);
for (; index < length; ++index) {
JSValue e = getProperty(exec, thisObj, index);
+ if (exec->hadException())
+ return jsUndefined();
if (!e)
continue;
if (JSValue::strictEqual(exec, searchElement, e))
@@ -1089,6 +1146,8 @@ JSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSVa
JSValue searchElement = args.at(0);
for (; index >= 0; --index) {
JSValue e = getProperty(exec, thisObj, index);
+ if (exec->hadException())
+ return jsUndefined();
if (!e)
continue;
if (JSValue::strictEqual(exec, searchElement, e))
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Collector.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Collector.cpp
index 7f083c6..1e726ee 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Collector.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Collector.cpp
@@ -1466,7 +1466,8 @@ static void setCollectorHeapStatistics(CollectorHeapStatistics& stat, int type,
unsigned int num = stat.numBlockInfo;
ASSERT(block);
- ASSERT(num < kMaxBlockInfo);
+ if (num >= kMaxBlockInfo)
+ return;
info = &stat.blockInfo[num];
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Executable.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Executable.cpp
index 2946221..71f5920 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Executable.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Executable.cpp
@@ -268,8 +268,10 @@ PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifi
return 0;
StatementNode* exprStatement = program->singleStatement();
+#if !PLATFORM(WKC)
ASSERT(exprStatement);
ASSERT(exprStatement->isExprStatement());
+#endif
if (!exprStatement || !exprStatement->isExprStatement())
return 0;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/JSObject.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/JSObject.h
index a5da267..b91b5b0 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/JSObject.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/JSObject.h
@@ -501,7 +501,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
if (specificFunction && m_structure->hasTransition(propertyName, attributes))
specificFunction = 0;
- RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset);
+ RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset, slot.context());
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/JSString.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/JSString.cpp
index 69164f8..fa19019 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/JSString.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/JSString.cpp
@@ -40,6 +40,8 @@ void JSString::Rope::destructNonRecursive()
unsigned length = rope->ropeLength();
for (unsigned i = 0; i < length; ++i) {
Fiber& fiber = rope->fibers(i);
+ if (!fiber.string())
+ continue;
if (fiber.isString())
fiber.string()->deref();
else {
@@ -117,6 +119,12 @@ void JSString::resolveRope(ExecState* exec) const
while (true) {
if (currentFiber.isRope()) {
Rope* rope = currentFiber.rope();
+ if (rope->ropeLength()==0) {
+ for (unsigned i = 0; i < m_ropeLength; ++i)
+ m_fibers[i].deref();
+ m_ropeLength = 0;
+ return;
+ }
// Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber'
// (we will be working backwards over the rope).
unsigned ropeLengthMinusOne = rope->ropeLength() - 1;
@@ -126,8 +134,16 @@ void JSString::resolveRope(ExecState* exec) const
} else {
UString::Rep* string = currentFiber.string();
unsigned length = string->size();
- position -= length;
- copyChars(position, string->data(), length);
+ if (position-length >= buffer) {
+ position -= length;
+ copyChars(position, string->data(), length);
+ } else {
+ for (unsigned i = 0; i < m_ropeLength; ++i)
+ m_fibers[i].deref();
+ m_ropeLength = 0;
+ throwOutOfMemoryError(exec);
+ return;
+ }
// Was this the last item in the work queue?
if (workQueue.isEmpty()) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/JSString.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/JSString.h
index 54e67d9..a9341c3 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/JSString.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/JSString.h
@@ -118,7 +118,11 @@ namespace JSC {
static PassRefPtr<Rope> createOrNull(unsigned ropeLength)
{
void* allocation;
+#if PLATFORM(WKC)
+ if (tryFastZeroedMalloc(sizeof(Rope) + (ropeLength - 1) * sizeof(Fiber)).getValue(allocation))
+#else
if (tryFastMalloc(sizeof(Rope) + (ropeLength - 1) * sizeof(Fiber)).getValue(allocation))
+#endif
return adoptRef(new (allocation) Rope(ropeLength));
return 0;
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Operations.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Operations.h
index c256b4b..680c29a 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Operations.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Operations.h
@@ -148,12 +148,9 @@ namespace JSC {
if (UNLIKELY(!rope))
return throwOutOfMemoryError(exec);
-#if 1 // webkit.org trunk r54925
- unsigned length = 0;
- bool overflow = false;
-#endif
+ unsigned oldLength = 0;
- unsigned index = 0;
+ unsigned int index = 0;
for (unsigned i = 0; i < count; ++i) {
JSValue v = strings[i].jsValue();
if (LIKELY(v.isString()))
@@ -161,18 +158,10 @@ namespace JSC {
else
rope->append(index, v.toString(exec));
-#if 1 // webkit.org trunk r54925
- unsigned newLength = rope->ropeLength();
- if (newLength < length)
- overflow = true;
- length = newLength;
- }
-
- if (overflow)
- return throwOutOfMemoryError(exec);
-#else
+ if (rope->stringLength() < oldLength)
+ return throwOutOfMemoryError(exec);
+ oldLength = rope->stringLength();
}
-#endif
ASSERT(index == ropeLength);
return new (globalData) JSString(globalData, rope.release());
@@ -197,16 +186,17 @@ namespace JSC {
if (UNLIKELY(!rope))
return throwOutOfMemoryError(exec);
+ unsigned oldLength = 0;
+
unsigned index = 0;
if (LIKELY(thisValue.isString()))
rope->append(index, asString(thisValue));
else
rope->append(index, thisValue.toString(exec));
-#if 1 // webkit.org trunk r54925
- unsigned length = 0;
- bool overflow = false;
-#endif
+ if (rope->stringLength() < oldLength)
+ return throwOutOfMemoryError(exec);
+ oldLength = rope->stringLength();
for (unsigned i = 0; i < args.size(); ++i) {
JSValue v = args.at(i);
@@ -214,18 +204,14 @@ namespace JSC {
rope->append(index, asString(v));
else
rope->append(index, v.toString(exec));
-#if 1 // webkit.org trunk r54925
- unsigned newLength = rope->ropeLength();
- if (newLength < length)
- overflow = true;
- length = newLength;
- }
- if (overflow)
- return throwOutOfMemoryError(exec);
-#else
+ if (rope->stringLength() < oldLength) {
+ rope.clear();
+ return throwOutOfMemoryError(exec);
+ }
+ oldLength = rope->stringLength();
}
-#endif
+
ASSERT(index == ropeLength);
JSGlobalData* globalData = &exec->globalData();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/PutPropertySlot.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/PutPropertySlot.h
index eb8ea8a..22512de 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/PutPropertySlot.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/PutPropertySlot.h
@@ -37,10 +37,16 @@ namespace JSC {
class PutPropertySlot {
public:
enum Type { Uncachable, ExistingProperty, NewProperty };
+#if !PLATFORM(WKC)
+ enum Context { UnknownContext, PutById, PutByIdEval };
+#else
+ enum Context { UnknownContext, PutById, PutByIdEval, Contexts = 0x7fffffff };
+#endif
- PutPropertySlot()
+ PutPropertySlot(Context context = UnknownContext)
: m_type(Uncachable)
, m_base(0)
+ , m_context(context)
{
}
@@ -58,6 +64,8 @@ namespace JSC {
m_offset = offset;
}
+ Context context() const { return static_cast<Context>(m_context); }
+
Type type() const { return m_type; }
JSObject* base() const { return m_base; }
@@ -70,6 +78,7 @@ namespace JSC {
Type m_type;
JSObject* m_base;
size_t m_offset;
+ uint8_t m_context;
};
} // namespace JSC
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Structure.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Structure.cpp
index 0dbe7ca..e3dc291 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Structure.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Structure.cpp
@@ -410,7 +410,7 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct
return 0;
}
-PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
+PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset, PutPropertySlot::Context context)
{
ASSERT(!structure->isDictionary());
ASSERT(structure->typeInfo().type() == ObjectType);
@@ -422,7 +422,12 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
specificValue = 0;
#endif
- if (structure->transitionCount() > s_maxTransitionLength) {
+ int maxTransitionLength;
+ if (context == PutPropertySlot::PutById)
+ maxTransitionLength = s_maxTransitionLengthForNonEvalPutById;
+ else
+ maxTransitionLength = s_maxTransitionLength;
+ if (structure->transitionCount() > maxTransitionLength) {
RefPtr<Structure> transition = toCacheableDictionaryTransition(structure);
ASSERT(structure != transition);
offset = transition->put(propertyName, attributes, specificValue);
@@ -506,7 +511,7 @@ PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structur
{
#if 1
// added at webkit.org trunk r52948
- ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
+// ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
#endif
RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Structure.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Structure.h
index ce71210..a04c56f 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/Structure.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/Structure.h
@@ -33,6 +33,7 @@
#include "PropertyMapHashTable.h"
#include "PropertyNameArray.h"
#include "Protect.h"
+#include "PutPropertySlot.h"
#include "StructureChain.h"
#include "StructureTransitionTable.h"
#include "JSTypeInfo.h"
@@ -66,7 +67,7 @@ namespace JSC {
static void dumpStatistics();
- static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
+ static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset, PutPropertySlot::Context = PutPropertySlot::UnknownContext);
static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset);
static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValue prototype);
@@ -195,6 +196,7 @@ namespace JSC {
static const unsigned emptyEntryIndex = 0;
static const signed char s_maxTransitionLength = 64;
+ static const int s_maxTransitionLengthForNonEvalPutById = 512;
static const signed char noOffset = -1;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/UString.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/UString.cpp
index 742b65b..3d37650 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/JavaScriptCore/runtime/UString.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/JavaScriptCore/runtime/UString.cpp
@@ -399,10 +399,18 @@ UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, in
}
int totalLength = 0;
- for (int i = 0; i < rangeCount; i++)
+ for (int i = 0; i < rangeCount; i++) {
+ if ((unsigned int)totalLength + (unsigned int)substringRanges[i].length > 0x7fffffff) {
+ return "";
+ }
totalLength += substringRanges[i].length;
- for (int i = 0; i < separatorCount; i++)
+ }
+ for (int i = 0; i < separatorCount; i++) {
+ if ((unsigned int)totalLength + (unsigned int)separators[i].size() > 0x7fffffff) {
+ return "";
+ }
totalLength += separators[i].size();
+ }
if (totalLength == 0)
return "";
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/ChangeLog b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/ChangeLog
index bf59b0a..7b2ee9f 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/ChangeLog
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/ChangeLog
@@ -1,3 +1,2132 @@
+2015-11-02 Jiewen Tan <jiewen_tan@apple.com>
+
+ Null dereference loading Blink layout test fast/css/background-repeat-null-y-crash.html
+ https://bugs.webkit.org/show_bug.cgi?id=150211
+ <rdar://problem/23137321>
+
+ Reviewed by Alex Christensen.
+
+ This is a merge of Blink r188842:
+ https://codereview.chromium.org/846933002
+
+ By setting the backgroundRepeatY property to null it can
+ happen that accessing that CSS value returns a null pointer.
+ In that case simply bail out early.
+
+ Test: fast/css/background-repeat-null-y-crash.html
+
+ * css/StyleProperties.cpp:
+ (WebCore::StyleProperties::getLayeredShorthandValue):
+
+2014-10-17 Jeffrey Pfau <jpfau@apple.com>
+
+ Ensure attached frame count doesn't exceed the maximum allowed frames
+ https://bugs.webkit.org/show_bug.cgi?id=136457
+
+ Reviewed by Alexey Proskuryakov.
+
+ Test: fast/frames/exponential-frames.html
+
+ * html/HTMLFrameElementBase.cpp:
+ (WebCore::HTMLFrameElementBase::isURLAllowed):
+
+2014-05-07 Dean Jackson <dino@apple.com>
+
+ Using a fill pattern much larger than actual canvas reliably segfaults browser
+ https://bugs.webkit.org/show_bug.cgi?id=132635
+
+ Reviewed by Simon Fraser.
+
+ Make sure that createPattern checks that the canvas it is about to use
+ as a source is valid.
+
+ Test: fast/canvas/pattern-too-large-to-create.html
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::createPattern): Check that the source canvas has
+ an ok ImageBuffer.
+
+2014-04-22 Zalan Bujtas <zalan@apple.com>
+
+ Do not paint border image when the border rect is empty.
+ https://bugs.webkit.org/show_bug.cgi?id=131988
+
+ Reviewed by Darin Adler.
+
+ http://trac.webkit.org/changeset/167351 introduced an early return when border
+ rect is empty. This patch ensures that border image is not painted either in that case.
+
+ Modified padding-margin-negative-border.html to cover border-image case.
+
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintBorder):
+
+2014-04-11 Jon Honeycutt <jhoneycutt@apple.com>
+
+ Assertion failure changing select element size during focus event
+ dispatch
+ <https://bugs.webkit.org/show_bug.cgi?id=131566>
+ <rdar://problem/16400735>
+
+ Reviewed by Andy Estes.
+
+ Test: fast/forms/select-change-size-during-focus.html
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::listBoxDefaultEventHandler):
+ Adopt the fix from Chromium r171216; check that the renderer is still
+ of the expected type, and return early if it is not.
+
+2014-03-21 Oliver Hunt <oliver@apple.com>
+
+ Fix a crash when assigning an object to document.location
+ https://bugs.webkit.org/show_bug.cgi?id=130213
+
+ Reviewed by Geoffrey Garen.
+
+ Convert location to string before we make use the document.
+ This prevents us from attempting to navigate a frame that
+ has already been removed.
+
+ Test: fast/dom/navigation-with-sideeffects-crash.html
+
+ * bindings/js/JSDocumentCustom.cpp:
+ (WebCore::JSDocument::location):
+ (WebCore::JSDocument::setLocation):
+
+2013-08-14 Rob Buis <rwlbuis@webkit.org>
+
+ Assertion failure in RenderObject::drawLineForBoxSide
+ https://bugs.webkit.org/show_bug.cgi?id=108187
+
+ Reviewed by David Hyatt.
+
+ Don't draw the outline if the rectangle to draw is empty.
+
+ Test: fast/css/outline-negative.html
+
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::paintOutlineForLine):
+
+2013-07-18 Santosh Mahto <santosh.ma@samsung.com>
+
+ ASSERTION FAILED: !listItems().size() || m_activeSelectionAnchorIndex >= 0 in WebCore::HTMLSelectElement::updateListBoxSelection
+ https://bugs.webkit.org/show_bug.cgi?id=118591
+
+ Reviewed by Kent Tamura.
+
+ Test: fast/forms/select/selectall-command-crash.html
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::selectAll):
+ We should return this function if activeSelectionAnchorIndex is not valid index
+
+2013-02-13 Abhishek Arya <inferno@chromium.org>
+
+ ASSERTION FAILED: !object || object->isBox(), Bad cast in RenderBox::computeLogicalHeight
+ https://bugs.webkit.org/show_bug.cgi?id=107748
+
+ Reviewed by Levi Weintraub.
+
+ Make sure that body renderer is not an inline-block display
+ when determining that it stretches to viewport or when paginated
+ content needs base height.
+
+ Test: fast/block/body-inline-block-crash.html
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::computeLogicalHeight):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::stretchesToViewport):
+
+2013-02-11 Emil A Eklund <eae@chromium.org>
+
+ Change RenderFrameSet::paint to use m-rows/m_cols directly.
+ https://bugs.webkit.org/show_bug.cgi?id=108503
+
+ Reviewed by Eric Seidel.
+
+ Test: fast/frames/invalid-frameset.html
+
+ * rendering/RenderFrameSet.cpp:
+ (WebCore::RenderFrameSet::paint):
+
+2013-01-02 Douglas Stockwell <dstockwell@chromium.org>
+
+ Crash in WebCore::InlineBox::deleteLine
+ https://bugs.webkit.org/show_bug.cgi?id=93448
+
+ Reviewed by Eric Seidel.
+
+ When we ran off the end of the line while looking for line breaks in an
+ inline with white-space:nowrap nested in a block with white-space:pre
+ it was possible for the line break to be set at or before the current
+ position -- this could result in duplications in the render tree or
+ infinite looping.
+
+ This patch changes the "fixup" logic that runs after we have finished
+ iterating through elements and text and have potentially found a break
+ point. In the case of a block setting white-space:pre we would back up
+ a character in some cases. Not doing so could leave whitespace that
+ should have been collapsed at the end of an inline.
+
+ For example in '<span style="white-space:nowrap">x_</span>_y' if a
+ break was inserted before 'y' the space after 'x' would still be
+ rendered (rather than be collapsed with the break).
+
+ To avoid this problem we will not take the opportunity to break until
+ we have finished collapsing whitespace.
+
+ Tests: fast/text/whitespace/inline-whitespace-wrapping-1.html
+ fast/text/whitespace/inline-whitespace-wrapping-2.html
+ fast/text/whitespace/inline-whitespace-wrapping-3.html
+ fast/text/whitespace/inline-whitespace-wrapping-4.html
+ fast/text/whitespace/nowrap-white-space-collapse.html
+ fast/text/whitespace/pre-block-normal-inline-crash-1.html
+ fast/text/whitespace/pre-block-normal-inline-crash-2.html
+
+ * rendering/RenderBlockLineLayout.cpp:
+ (WebCore::RenderBlock::LineBreaker::nextLineBreak): Collapse
+ whitespace before breaking. Avoid setting the break before the current
+ position.
+
+2012-12-03 Hajime Morrita <morrita@google.com>
+
+ Corrupted DOM tree during appendChild/insertBefore
+ https://bugs.webkit.org/show_bug.cgi?id=103601
+
+ Reviewed by Abhishek Arya.
+
+ There are some missing protection in appendChild() and insertBefore().
+ This change added these.
+
+ Dromaeo dom-modify shows no speed regression (5445run/s before vs 5351run/s after)
+
+ Tests: fast/events/mutation-during-append-child.html
+ fast/events/mutation-during-insert-before.html
+
+ * dom/ContainerNode.cpp:
+ (WebCore::checkAcceptChildGuaranteedNodeTypes):
+ (WebCore):
+ (WebCore::ContainerNode::insertBefore):
+ (WebCore::ContainerNode::appendChild):
+
+2012-11-25 Takashi Sakamoto <tasak@google.com>
+
+ WebCore::RenderBlock::determineStartPosition crash
+ https://bugs.webkit.org/show_bug.cgi?id=98993
+
+ Reviewed by Brent Fulgham.
+
+ If we move some node and the node has some text,
+ InlineFlowBox::removeChild() is invoked. The method invokes
+ RootInlineBox::childRemoved(). childRemoved() checks whether the
+ removed inlinebox has the renderer of its parent's line break object.
+ If so, use setLineBreakInfo to make the parent's line break info to
+ be 0. However in RenderBlock::determineStartPosition(), the code
+ assume that all line break info is solved, i.e.
+ prevRootBox->lineBreakObj()->isText(). Since lineBreakObj() returns 0
+ because of removeChild(), determineStartPosition crash occurs.
+
+ Test: fast/inline/inline-box-append-child-crash.html
+
+ * rendering/RenderBlockLineLayout.cpp:
+ (WebCore::RenderBlock::determineStartPosition):
+ Checks whether lineBreakObj() is 0 or not before using lineBreakObj().
+
+2012-11-21 Daniel Bates <dbates@webkit.org>
+
+ JavaScript fails to concatenate large strings
+ <https://bugs.webkit.org/show_bug.cgi?id=102963>
+
+ Reviewed by Michael Saboff.
+
+ Fixes an issue where we inadvertently didn't check the length of
+ a JavaScript string for overflow.
+
+ * runtime/Operations.h:
+ (JSC::jsString):
+ (JSC::jsStringFromArguments):
+
+2012-08-09 MORITA Hajime <morrita@google.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=93587
+ Node::replaceChild() can create bad DOM topology with MutationEvent, Part 2
+
+ Reviewed by Kent Tamura.
+
+ This is a followup of r124156. replaceChild() has yet another hidden
+ MutationEvent trigger. This change added a guard for it.
+
+ Test: fast/events/mutation-during-replace-child-2.html
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::replaceChild):
+
+2012-07-30 MORITA Hajime <morrita@google.com>
+
+ Node::replaceChild() can create bad DOM topology with MutationEvent
+ https://bugs.webkit.org/show_bug.cgi?id=92619
+
+ Reviewed by Ryosuke Niwa.
+
+ Node::replaceChild() calls insertBeforeCommon() after dispatching
+ a MutationEvent event for removeChild(). But insertBeforeCommon()
+ expects call sites to check the invariant and doesn't have
+ suffient check. So a MutationEvent handler can let some bad tree
+ topology to slip into insertBeforeCommon().
+
+ This change adds a guard for checking the invariant using
+ checkReplaceChild() between removeChild() and insertBeforeCommon().
+
+ Test: fast/events/mutation-during-replace-child.html
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::replaceChild): Added a guard.
+
+2012-05-10 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Crash in computedCSSPadding* functions due to RenderImage::imageDimensionsChanged called during attachment
+ https://bugs.webkit.org/show_bug.cgi?id=85912
+
+ Reviewed by Eric Seidel.
+
+ Tests: fast/images/link-body-content-imageDimensionChanged-crash.html
+ fast/images/script-counter-imageDimensionChanged-crash.html
+
+ The bug comes from CSS generated images that could end up calling imageDimensionsChanged during attachment. As the
+ rest of the code (e.g. computedCSSPadding*) would assumes that we are already inserted in the tree, we would crash.
+
+ The solution is to bail out in this case as newly inserted RenderObject will trigger layout later on and properly
+ handle what we would be doing as part of imageDimensionChanged (the only exception being updating our intrinsic
+ size which should be done as part of imageDimensionsChanged).
+
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::imageDimensionsChanged):
+
+2012-02-29 Parag Radke <parag@motorola.com>
+
+ Crash in WebCore::CompositeEditCommand::insertNodeAt
+ https://bugs.webkit.org/show_bug.cgi?id=67764
+
+ Reviewed by Ryosuke Niwa.
+
+ If caret position after deletion and destination position coincides then
+ removing the node will result in removing the destination node also. Hence crash.
+
+ Test: editing/deleting/delete-block-merge-contents-025.html
+
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::cleanupAfterDeletion):
+ If the caret position after delete and the destination position
+ renderes at the same place, pruning the node and making an early exit.
+
+2012-02-06 Cris Neckar <cdn@chromium.org>
+
+ Add RefPtrs for parent and sibling counter nodes
+ https://bugs.webkit.org/show_bug.cgi?id=75212
+
+ Reviewed by Adam Barth.
+
+ Test: fast/css/counters/reparent-table-children-with-counters-crash.html
+
+ * rendering/RenderCounter.cpp:
+ (WebCore::findPlaceForCounter):
+ (WebCore::makeCounterNode):
+ (WebCore::updateCounters):
+
+2012-01-05 Kent Tamura <tkent@chromium.org>
+
+ Fix a crash by importing an element of which local name ends with ":input".
+ https://bugs.webkit.org/show_bug.cgi?id=75103
+
+ Reviewed by Ryosuke Niwa.
+
+ Test: fast/dom/importNode-confusing-localName.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::importNode): Pass QualifiedName of the source elemnt
+ to createElement() in order to avoid unnecessary serialization and
+ parsing of the qualified name
+
+2011-11-18 Chris Evans <cevans@google.com>
+
+ Crash with ranges across a detached, reparented node tree
+ https://bugs.webkit.org/show_bug.cgi?id=72757
+
+ Reviewed by Adam Barth.
+
+ Test: fast/dom/move-detached-child-in-range.html
+
+ * dom/RangeBoundaryPoint.h:
+ (WebCore::RangeBoundaryPoint::childBefore): protect the raw child node from getting pulled from under us.
+
+2011-11-08 Chris Evans <cevans@google.com>
+
+ Crash accessing font fact rule parent
+ https://bugs.webkit.org/show_bug.cgi?id=71860
+
+ Reviewed by Adam Barth.
+
+ Test: fast/css/css-fontface-rule-crash.html
+
+ * css/CSSFontFaceRule.cpp:
+ (WebCore::CSSFontFaceRule::~CSSFontFaceRule): tell our child rule when we are going away.
+
+2011-09-27 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Crash because CSSPrimitiveValue::computeLengthDouble assumes fontMetrics are available
+ https://bugs.webkit.org/show_bug.cgi?id=66291
+
+ Reviewed by Darin Adler.
+
+ Test: fast/canvas/crash-set-font.html
+
+ This is Yet Another Missing updateFont (similar to bug 57756 and likely others). Here the issue is that
+ applying one of the font properties could mutate the parent style's font if m_parentStyle == m_style.
+ We would then query the newly created font when applying CSSPropertyFontSize, which has no font fallback
+ list as Font::update was never called.
+
+ The right fix would be to refactor of how we handle fonts to avoid such manual updates (see bug 62390).
+ Until this happens, it is better not to crash.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::applyProperty): Added updateFont() here as the fonts could have been
+ mutated by the previous property change. Also added a comment explaining why it is safe to do it
+ this way.
+
+2011-09-24 Abhishek Arya <inferno@chromium.org>
+
+ Issues with merging block children of a ruby
+ base with another ruby base having inline children.
+ https://bugs.webkit.org/show_bug.cgi?id=66124
+
+ Reviewed by Dan Bernstein.
+
+ Test: fast/ruby/ruby-base-merge-block-children-crash.html
+
+ * rendering/RenderRubyBase.cpp:
+ (WebCore::RenderRubyBase::moveInlineChildren): add a firstChild()
+ check to prevent empty anonymous block addition, just like
+ moveBlockChildren method.
+ * rendering/RenderRubyBase.cpp:
+ (WebCore::RenderRubyBase::moveBlockChildren): This was incorrectly
+ doing optimizations to see if current ruby base has only inline
+ children before beforeChild and then trying to take out them from
+ their parent anonymous blocks. The problem is those inlines could
+ be split and have continuations because of encountering a block
+ inside inline flow. In those cases, we cannot take the inline out.
+ So, we should just make children non-inline in the destination
+ block and transfer the children as it-is.
+ * rendering/RenderRubyBase.h: remove unncessary functions.
+
+2011-09-15 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Crash in RenderBox::paintMaskImages due to a mask without an associated image
+ https://bugs.webkit.org/show_bug.cgi?id=50151
+
+ Reviewed by Simon Fraser.
+
+ Test: fast/css/empty-webkit-mask-crash.html
+
+ The crash stems from the fact that FillLayer::hasImage would walk over the linked list
+ of FillLayers and return true if one had an image. This means that hasImage() is true
+ does not mean that image() is non-NULL on all FillLayers.
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::paintMaskImages): Simplify the logic by doing the hasImage() check up-front
+ and properly check image() for each FillLayers. This has the nice benefit of changing the complexity
+ from O(n^2) to O(n), which was what the code expected anyway.
+
+2011-08-30 Abhishek Arya <inferno@chromium.org>
+
+ Style not updated for table parts in :before, :after content.
+ https://bugs.webkit.org/show_bug.cgi?id=66141
+
+ Reviewed by Dave Hyatt.
+
+ Tests: fast/table/table-before-child-style-update.html
+ fast/table/table-row-before-child-style-update.html
+
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::RenderObjectChildList::updateBeforeAfterContent):
+
+2011-08-30 Tony Chang <tony@chromium.org>
+
+ refactor box-ordinal-group handling so we don't timeout on large values
+ https://bugs.webkit.org/show_bug.cgi?id=65783
+
+ Reviewed by David Hyatt.
+
+ The old code walked from 1 to the last box-ordinal-group while
+ iterating over each flex item. The new code collects ordinals as
+ we do the first walk and sorts them. Each additional iteration
+ through the flex items gets the next oridnal from the sorted list.
+
+ This maintains the single pass for the common case of no
+ box-ordinal-groups specified. If there are ordinal groups,
+ the runtime is O(n*m + m lg m) where n is the # of flex items and
+ m is the number of unique box-ordinal-group values. The memory
+ usage is O(2m).
+
+ Test: fast/flexbox/box-ordinal-group.html
+
+ * rendering/RenderDeprecatedFlexibleBox.cpp:
+ (WebCore::FlexBoxIterator::FlexBoxIterator):
+ (WebCore::FlexBoxIterator::reset):
+ (WebCore::FlexBoxIterator::next):
+ (WebCore::FlexBoxIterator::compareFlexOrder):
+
+2011-08-25 Abhishek Arya <inferno@chromium.org>
+
+ Incorrect layout of :before and :after content, with display
+ table, table-row and table-cell.
+ https://bugs.webkit.org/show_bug.cgi?id=66699
+
+ Reviewed by David Hyatt.
+
+ Tests: fast/table/table-after-child-in-table.html
+ fast/table/table-before-child-in-table.html
+ fast/table/table-cell-after-child-in-block.html
+ fast/table/table-cell-after-child-in-table.html
+ fast/table/table-cell-before-child-in-block.html
+ fast/table/table-cell-before-child-in-table.html
+ fast/table/table-row-after-child-in-block.html
+ fast/table/table-row-after-child-in-table.html
+ fast/table/table-row-before-child-in-block.html
+ fast/table/table-row-before-child-in-table.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::addChildIgnoringAnonymousColumnBlocks):
+ Fix the looping condition to detect :after child correctly.
+ isAnonymousBlock() does not apply to tables, instead
+ using isAnonymous().
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::addChild): Don't add the new child
+ in the generatedContainer with :before, :after content.
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::addChild): Don't add the new child
+ in the generatedContainer with :before, :after content.
+
+2011-08-20 Darin Adler <darin@apple.com>
+
+ If Range::insertNode is passed an empty document fragment, it creates a broken DOM tree
+ https://bugs.webkit.org/show_bug.cgi?id=65015
+
+ Reviewed by Alexey Proskuryakov.
+
+ Test: fast/dom/Range/insertNode-empty-fragment-crash.html
+
+ * dom/Range.cpp: (WebCore::Range::insertNode): Don't adjust the range after insertion
+ if we didn't add anything. Otherwise the code will put a wrong "child before" value into
+ the range end boundary point.
+
+2011-08-11 Cris Neckar <cdn@chromium.org>
+
+ Fixes several bugs when adding CounterNodes to a tree which can cause asymetrical relationships.
+ https://bugs.webkit.org/show_bug.cgi?id=65996
+
+ Reviewed by Eric Seidel.
+
+ Test: fast/css/counters/counter-reparent-table-children-crash.html
+
+ * rendering/CounterNode.cpp:
+ (WebCore::CounterNode::insertAfter):
+ * rendering/RenderCounter.cpp:
+ (WebCore::findPlaceForCounter):
+ (WebCore::makeCounterNode):
+
+2011-07-29 Emil A Eklund <eae@chromium.org>
+
+ -webkit-marquee with anonymous node causes segmentation fault in Node::document
+ https://bugs.webkit.org/show_bug.cgi?id=64693
+
+ Reviewed by Simon Fraser.
+
+ Test: fast/css/webkit-marquee-anonymous-node-crash.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::scrollTo):
+ Add null check as renderer()->node() is null for anonymous nodes.
+
+2011-07-27 Ryosuke Niwa <rniwa@webkit.org>
+
+ Calling window.find immediately after mutating the document crashes WebKit.
+ https://bugs.webkit.org/show_bug.cgi?id=65296
+
+ Reviewed by Darin Adler.
+
+ Don't forget to layout first.
+
+ Test: editing/text-iterator/find-after-mutation.html
+
+ * editing/TextIterator.cpp:
+ (WebCore::findPlainText):
+
+2011-07-20 Tony Chang <tony@chromium.org>
+
+ Stale pointer due to floats not removed (flexible box display)
+ https://bugs.webkit.org/show_bug.cgi?id=64603
+
+ Reviewed by David Hyatt.
+
+ Flexbox items should avoid floats.
+
+ Test: fast/flexbox/horizontal-box-float-crash.html
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::avoidsFloats):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::isDeprecatedFlexItem):
+
+2011-07-13 MORITA Hajime <morrita@google.com>
+
+ Refactoring: Ignored ExceptionCode value should be less annoying.
+ https://bugs.webkit.org/show_bug.cgi?id=63688
+
+ - Introduced ExceptionCodePlaceholder class for the default parameter of ExceptionCode.
+ - Introduced ASSERT_NO_EXCEPTION to check ExceptionCode not set to non-zero after the call.
+ - Adopted ASSERT_NO_EXCEPTION in Range.cpp
+
+ No new tests. No behaviour change.
+
+ Reviewed by Darin Adler.
+
+ * GNUmakefile.list.am:
+ * WebCore.gypi:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/ExceptionCodePlaceholder.h: Added.
+ (WebCore::ExceptionCodePlaceholder::ExceptionCodePlaceholder):
+ (WebCore::ExceptionCodePlaceholder::operator ExceptionCode& ):
+ (WebCore::IgnorableExceptionCode::IgnorableExceptionCode):
+ (WebCore::CheckedExceptionCode::CheckedExceptionCode):
+ (WebCore::CheckedExceptionCode::~CheckedExceptionCode):
+ * dom/Range.cpp:
+ (WebCore::Range::Range):
+ (WebCore::Range::editingStartPosition):
+ * dom/Range.h:
+
+2011-06-30 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Ryosuke Niwa.
+
+ Crash when calling DOMSubtreeModified event when extracting range
+ contents.
+ https://bugs.webkit.org/show_bug.cgi?id=63650
+
+ Convert a few nodes to RefPtrs and add commonRoot verification checks
+ for Range::processContents.
+
+ Tests: fast/dom/Range/range-extract-contents-event-fire-crash.html
+ fast/dom/Range/range-extract-contents-event-fire-crash2.html
+
+ * dom/Range.cpp:
+ (WebCore::childOfCommonRootBeforeOffset):
+ (WebCore::Range::processContents):
+ (WebCore::Range::processContentsBetweenOffsets):
+ (WebCore::Range::processAncestorsAndTheirSiblings):
+
+2011-06-29 Darin Adler <darin@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ [WebKit2] Crash loading page that adds/removes frame in DOMContentLoaded/loaded
+ https://bugs.webkit.org/show_bug.cgi?id=63483
+
+ Test: fast/loader/create-frame-in-DOMContentLoaded.html
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::init): Added an assertion.
+ (WebCore::FrameLoader::finishedLoadingDocument): Removed a non-helpful #if
+ statement. The rule that we do not call the client when creating the initial
+ empty document was nominally specific to Windows and Chromium but is needed
+ for all platforms.
+
+2011-06-28 Roland Steiner <rolandsteiner@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Bug 55930 - (CVE-2011-1440) Incorrect handling of 'display:' property within nested <ruby> tags
+ https://bugs.webkit.org/show_bug.cgi?id=55930
+
+ Don't set style type BEFORE/AFTER on anonymous wrapper block.
+ Rather, check style type on generated wrapped child.
+
+ Tests: fast/ruby/generated-after-counter-doesnt-crash.html
+ fast/ruby/generated-before-and-after-counter-doesnt-crash.html
+ fast/ruby/generated-before-counter-doesnt-crash.html
+
+ * rendering/RenderRuby.cpp:
+ (WebCore::isAnonymousRubyInlineBlock):
+ (WebCore::isRubyBeforeBlock):
+ (WebCore::isRubyAfterBlock):
+ (WebCore::rubyBeforeBlock):
+ (WebCore::rubyAfterBlock):
+ (WebCore::createAnonymousRubyInlineBlock):
+ (WebCore::RenderRubyAsInline::addChild):
+ (WebCore::RenderRubyAsBlock::addChild):
+
+2011-05-31 Yong Li <yoli@rim.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=54807
+ We have been assuming plain bitfields (like "int a : 31") are always signed integers.
+ However some compilers can treat them as unsigned. For example, RVCT 4.0 states plain
+ bitfields (declared without either signed or unsigned qualifiers) are treats as unsigned.
+ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0348c/Babjddhe.html
+ Although we can use "--signed-bitfields" flag to make RVCT 4.0 behave as most other compilers,
+ always using "signed"/"unsigned" qualifier to declare integral type bitfields is still a good
+ rule we should have in order to make our code independent from compilers and compiler flags.
+
+ No new test added because this change is not known to fix any issue.
+
+ * css/CSSPrimitiveValue.h:
+ * css/CSSProperty.h:
+ * rendering/InlineBox.h:
+ * rendering/RenderBlock.h:
+
+2011-04-13 Roland Steiner <rolandsteiner@chromium.org>
+
+ Reviewed by David Hyatt.
+
+ Bug 55930 - Incorrect handling of 'display:' property within nested <ruby> tags
+ https://bugs.webkit.org/show_bug.cgi?id=55930
+
+ Non-inline :before/:after generated content is now wrapped with an anonymous inline block.
+
+ Also, added an additional check in RenderObjectChildList::updateBeforeAfterContent()
+ to verify that the created render object is legal under the parent.
+
+ Tests: fast/ruby/after-block-doesnt-crash.html
+ fast/ruby/after-table-doesnt-crash.html
+ fast/ruby/before-block-doesnt-crash.html
+ fast/ruby/before-table-doesnt-crash.html
+
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::RenderObjectChildList::updateBeforeAfterContent):
+ * rendering/RenderRuby.cpp:
+ (WebCore::isAnonymousRubyInlineBlock):
+ (WebCore::rubyBeforeBlock):
+ (WebCore::rubyAfterBlock):
+ (WebCore::createAnonymousRubyInlineBlock):
+ (WebCore::lastRubyRun):
+ (WebCore::RenderRubyAsInline::addChild):
+ (WebCore::RenderRubyAsInline::removeChild):
+ (WebCore::RenderRubyAsBlock::addChild):
+ (WebCore::RenderRubyAsBlock::removeChild):
+ * rendering/RenderRuby.h:
+
+2011-03-30 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/9199518> Crash when focusing a styled editable element
+
+ Test: editing/deleting/delete-button-background-image-none.html
+
+ * editing/DeleteButtonController.cpp:
+ (WebCore::isDeletableElement): Check all background layers for background images.
+ * rendering/style/RenderStyle.h: Removed backgroundImage() as it was only used, incorrectly,
+ in the above function.
+
+2011-03-10 Alice Boxhall <aboxhall@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ NULL pointer crash when using :empty and :first-line pseudoclass selectors together
+ https://bugs.webkit.org/show_bug.cgi?id=53316
+
+ :empty is calculated for each element during parsing, but then not
+ recalculated after any child elements are attached. Force style
+ re-calculation on elements which have :empty in their style when
+ their children are changed.
+
+ Test: fast/css/empty-first-line-crash.html
+
+ * dom/Element.cpp:
+ (WebCore::checkForEmptyStyleChange): Pull out empty style checking
+ logic from checkForSiblingStyleChanges().
+ (WebCore::checkForSiblingStyleChanges): Use new checkForEmptyStyleChanges()
+ method.
+ (WebCore::Element::childrenChanged): Call checkForEmptyStyleChanges() when
+ called with changedByParser = true.
+
+2011-03-09 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ <rdar://problem/8733254> Float disappears after incremental layout
+ Fixed the original bug and a copule more issues noticed while doing so.
+
+ Tests: fast/dynamic/dirty-float-in-clean-line.html
+ fast/dynamic/float-at-line-break.html
+ fast/dynamic/float-from-empty-line.html
+
+ * rendering/RenderBlock.h:
+ * rendering/RenderBlockLineLayout.cpp:
+ (WebCore::RenderBlock::layoutInlineChildren): If findNextLineBreak() returned an empty line,
+ update the line break info of the last line with the new line break position. This is tested
+ by float-from-empty-line.html.
+ (WebCore::RenderBlock::checkFloatsInCleanLine): Factored out code from determineStartPosition()
+ into this new function.
+ (WebCore::RenderBlock::determineStartPosition): Call checkFloatsInCleanLine().
+ (WebCore::RenderBlock::determineEndPosition): When iterating over lines, check clean lines with
+ floats, as they may yet become dirty because of the floats. This is tested by
+ dirty-float-in-clean-line.html.
+ (WebCore::RenderBlock::findNextLineBreak): If a float fits on the line, and the current line
+ break is at the float, advance it to after the float. Otherwise, if the line gets dirty and the
+ next one does not, the float will not make it into any line. This is tested by
+ float-at-line-break.html.
+
+2011-02-01 chris reiss <christopher.reiss@nokia.com>
+
+ Reviewed by Adam Barth.
+
+ Self-replicating code makes Safari hang and eventually crash
+ https://bugs.webkit.org/show_bug.cgi?id=15123
+
+
+ Here we are replicating the Firefox safeguard against
+ recursive document.write( ) 's.
+
+ See https://bug197052.bugzilla.mozilla.org/attachment.cgi?id=293907 in bug
+ https://bugzilla.mozilla.org/show_bug.cgi?id=197052 . Firefox does two things -
+ a) imposes a recursion limit of 20 on document.write( ) and
+ b) once that limit is passed, panics all the way the call stack (rather than just returning one level.)
+ To see why this is necessary, consider the script :
+
+ <script>
+ var t = document.body.innerHTML;
+ document.write(t);
+ </script>
+
+ This will create a tree both broad and deep as the script keeps appending itself to the text. If
+ we just return one level after the recursion limit is reached, we still allow millions of copies to
+ duplicate (and execute).
+
+ The recursion is fortunately depth-first, so as soon as we cross this limit, we panic up the callstack
+ to prevent this situation. (IE apparently does the same thing, with a lower recursion limit.)
+
+ Test: fast/dom/Document/document-write-recursion.html
+ Test: fast/dom/Document/document-close-iframe-load.html
+ Test: fast/dom/Document/document-close-nested-iframe-load.html
+
+
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::write):
+ * dom/Document.h:
+
+2011-01-20 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Eric "Baller" Seidel.
+
+ RenderTableSection's setNeedsCellRecalc needs to null check table()
+ https://bugs.webkit.org/show_bug.cgi?id=52770
+
+ Null checks table() before deferencing it in RenderTableSection::setNeedsCellRecalc.
+ This can be null during detach(). Test constructed by Eric Seidel.
+
+ Test: fast/css-generated-content/table-with-scrollbar-corner.html
+
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::setNeedsCellRecalc):
+ * rendering/RenderTableSection.h:
+
+2011-01-20 Xiaomei Ji <xji@chromium.org>
+
+ Reviewed by Dan Bernstein.
+
+ Fix regression(r71566): PDF in RTL block might messes up text directionality.
+ https://bugs.webkit.org/show_bug.cgi?id=52776
+
+ Test: fast/dom/52776.html
+
+ * platform/text/BidiResolver.h:
+ (WebCore::::checkDirectionInLowerRaiseEmbeddingLevel):
+ (WebCore::::lowerExplicitEmbeddingLevel):
+ (WebCore::::raiseExplicitEmbeddingLevel):
+ (WebCore::::createBidiRunsForLine):
+
+2011-01-19 Yuzo Fujishima <yuzo@google.com>
+
+ Reviewed by Kent Tamura.
+
+ Fix for Bug 52279 - WebCore::RenderBlock::updateFirstLetter crashes for anonymous blocks
+ https://bugs.webkit.org/show_bug.cgi?id=52279
+
+ In constructing text fragments to handle first-letter rule, first add
+ the text for the non-first letters and then remove the original text,
+ rather than the other way around. Otherwise, the text can be added to
+ an anoymous block that is different from the original one. This breaks
+ the assumption that a first letter render object has a non-null sibling
+ for the non-first letters and causes a crash.
+
+ Test: fast/css/first-letter-anonymous-block-crash.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::updateFirstLetter):
+
+2011-01-14 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by David Hyatt.
+
+ Prevent merging of anonymous blocks if one of them is already getting
+ destroyed.
+ https://bugs.webkit.org/show_bug.cgi?id=52402
+
+ Test: fast/block/merge-anonymous-block-remove-child-crash2.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::RenderBlock): initialize m_beingDestroyed to false.
+ (WebCore::RenderBlock::destroy): set m_beingDestroyed to true.
+ (WebCore::canMergeContiguousAnonymousBlocks): do not merge if any or prev or next is being destroyed.
+ (WebCore::RenderBlock::removeChild): remove the hack previously done for preventing oldChild merging with nextBlock's next sibling.
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::beingDestroyed): public function for m_beingDestroyed.
+
+2011-01-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Webkit crashes when a gradient is applied using the first-line pseudo element
+ https://bugs.webkit.org/show_bug.cgi?id=52225
+
+ When a pseudostyle references images, we fail to register/unregister
+ the relevant RenderObjects as clients of the image in the style.
+ For gradients, this caused a crash.
+
+ This patch fixes the crash by returning a null gradient image in this
+ situation.
+
+ Test: fast/gradients/gradient-on-pseudoelement-crash.html
+
+ * css/CSSGradientValue.cpp:
+ (WebCore::CSSGradientValue::image):
+
+2011-01-11 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ RefPtr the FrameView to prevent scrollbar from getting deleted inside
+ its scroll event.
+ https://bugs.webkit.org/show_bug.cgi?id=52238
+
+ Test: scrollbars/scrollable-iframe-remove-crash.html
+
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::scrollTo):
+
+2010-12-29 Tony Gentilcore <tonyg@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Assertion failure: element->inDocument() in AsyncScriptRunner::executeScriptSoon()
+ https://bugs.webkit.org/show_bug.cgi?id=51067
+
+ Typically when a script element is removed from the document, the cached script
+ client is removed. However, during the before load event, the cached script client
+ hasn't been created yet so it can't be removed.
+
+ This patch handles that case by explicitly checking if the script element was
+ removed during the beforeload event. Also, it avoids caching the Document references
+ over the arbitrary script execution in the before load event.
+
+ Test: fast/dom/HTMLScriptElement/move-in-beforeload.html
+ fast/dom/HTMLScriptElement/remove-in-beforeload.html
+
+ * dom/ScriptElement.cpp:
+ (WebCore::ScriptElement::requestScript):
+
+2010-12-15 Yong Li <yoli@rim.com>
+
+ Reviewed by Darin Adler.
+
+ Fix stack overflow when there are too many sibling inline boxes by using
+ a loop to traverse children instead of calling each sibling from the first child.
+ https://bugs.webkit.org/show_bug.cgi?id=48255
+
+ Test: fast/overflow/lots-of-sibling-inline-boxes.html
+
+ * rendering/InlineBox.h:
+ (WebCore::InlineBox::setConstructed):
+ (WebCore::InlineBox::next):
+ * rendering/InlineFlowBox.h:
+ (WebCore::InlineFlowBox::setConstructed):
+
+2010-12-14 Emil Eklund <eae@chromium.org>
+
+ Reviewed by NOBODY (OOPS!).
+
+ Change ContainerNode::willRemoveChildren to not fire mutation events for children
+ added as a result of a mutation event, thereby avoiding an infinite loop.
+ https://bugs.webkit.org/show_bug.cgi?id=51079
+
+ Test: fast/dom/containerNode.html
+
+ * dom/ContainerNode.cpp:
+ (WebCore::willRemoveChildren): Don't fire mutation events for children added during a mutation event.
+
+2010-12-10 Emil Eklund <eae@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Fix crash in Range::processContents when modified during mutation event.
+ https://bugs.webkit.org/show_bug.cgi?id=50710
+
+ Test: fast/dom/Range/range-extractContents.html
+
+ * dom/Range.cpp:
+ (WebCore::Range::processContents):
+ Replace raw pointers with RefPtrs and add checks.
+
+2010-12-09 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ As part of r73559, I added the referenceNode check to validate whether the root
+ node of the iterator matches the node which is getting moved to other document.
+ referenceNode is initialized to root, however can get moved using previousNode
+ and nextNode methods, so it is required to use root directly.
+ https://bugs.webkit.org/show_bug.cgi?id=50764
+
+ Test: fast/dom/node-iterator-reference-node-moved-crash.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::moveNodeIteratorsToNewDocument): change referenceNode to root.
+
+2010-12-08 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Detach node iterator and move to new document when node gets moved.
+ https://bugs.webkit.org/show_bug.cgi?id=50697
+
+ Test: fast/dom/node-iterator-document-moved-crash.html
+
+ * dom/Document.cpp: Method that takes a node and new document as argument.
+ It detaches the node iterators belonging to the current document and attaches
+ them to the new document.
+ (WebCore::Document::moveNodeIteratorsToNewDocument):
+ * dom/Document.h: Function definition.
+ * dom/Node.cpp: When node is moved to another document, call the function to move
+ the iterators appropriately.
+ (WebCore::Node::setDocument):
+
+2010-11-30 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler and Geoff Garen.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44152
+ <rdar://problem/8324423> CSSOM should match DOM in discarding wrapper-less parents.
+
+ We have existing behaviors where parent objects in detached subtrees are not preserved:
+ - if a root of a node tree doesn't have a wrapper, it's immediately destroyed, making
+ its children parentNode attribute null;
+ - relationship between a <style> or <link> node and its stylesheet is immediately broken
+ when the node is removed from document (in this case, regardless of wrapper existence).
+
+ Both match Firefox. For consistency, CSSOM should do the same. In fact, it already partially
+ does - CSSRule.parentRule gets zeroed out when the parent rule is destroyed.
+
+ Tests: fast/dom/StyleSheet/detached-parent-rule-without-wrapper.html
+ fast/dom/StyleSheet/detached-stylesheet-without-wrapper.html
+
+ * css/StyleSheet.cpp: (WebCore::StyleSheet::~StyleSheet): Clear out child rule parent.
+
+ * svg/SVGFontFaceElement.cpp: (WebCore::SVGFontFaceElement::insertedIntoDocument): Keep
+ the new assertion from firing. This function was adding a rule to style sheet, without
+ telling the rule about it.
+
+2010-11-29 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=50165
+ CSS style rules don't GC protect parents
+
+ Tests: fast/dom/StyleSheet/gc-parent-rule.html
+ fast/dom/StyleSheet/gc-parent-stylesheet.html
+
+ * bindings/js/JSCSSRuleCustom.cpp: (WebCore::JSCSSRule::markChildren): Mark parents. The code
+ is super naive compared to what we have for nodes - but CSSOM has shallow hierarchies, so
+ it should be OK.
+
+ * css/CSSRule.idl: Added CustomMarkFunction.
+
+2010-11-23 Cris Neckar <cdn@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Removed unneeded conversions to RenderBlock.
+ https://bugs.webkit.org/show_bug.cgi?id=49896
+
+ Test: fast/css/input-search-table-column-crash.html
+
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight):
+
+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-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-10-12 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Prevent block logical height of a root inline box from overflowing by clamping it
+ at INT_MAX. Otherwise, we will not be able to properly dirty the set of lines during
+ removal a floating object.
+ https://bugs.webkit.org/show_bug.cgi?id=45611
+
+ Test: fast/overflow/overflow-block-logical-height-crash.html
+
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::alignBoxesInBlockDirection):
+
+2010-10-12 Roland Steiner <rolandsteiner@chromium.org>
+
+ Reviewed by David Hyatt.
+
+ Bug 41040 - :before/:after content should not become part of a ruby base
+ https://bugs.webkit.org/show_bug.cgi?id=41040
+
+ Also related to:
+ https://bugs.webkit.org/show_bug.cgi?id=40895.
+ https://bugs.webkit.org/show_bug.cgi?id=43722.
+
+ Explicitly handle :before and :after content in the default way.
+
+ Test: fast/ruby/ruby-beforeafter.html
+ fast/ruby/after-doesnt-crash.html
+
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isBeforeContent):
+ * rendering/RenderRuby.cpp:
+ (WebCore::lastRubyRun):
+ (WebCore::RenderRubyAsInline::addChild):
+ (WebCore::RenderRubyAsInline::removeChild):
+ (WebCore::RenderRubyAsBlock::addChild):
+ (WebCore::RenderRubyAsBlock::removeChild):
+
+2010-10-06 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Darin Adler.
+
+ ASSERTION FAILURE: Attempt to cast RenderObject to RenderFrameSet
+ when <frameset> has CSS content property
+ https://bugs.webkit.org/show_bug.cgi?id=47314
+
+ Fixes an issue where sending a mouse event to an HTML Frameset Element that
+ whose content was replaced via the CSS content property causes an assertion
+ failure.
+
+ By default, HTMLFrameSetElement forwards mouse events to RenderFrameSet so as
+ to support resizing a frame within the set. When a <frameset> specifies an
+ image in its CSS content property we create a generic render object (RenderObject)
+ for the frame set instead of a RenderFrameSet object. The event handler code
+ in HTMLFrameSetElement calls WebCore::toRenderFrameSet() to cast its renderer
+ to type RenderFrameSet, which fails. To correct this, HTMLFrameSetElement
+ must check that its renderer is of type RenderFrameSet before casting to this type.
+
+ Test: fast/frames/crash-frameset-CSS-content-property.html
+
+ * html/HTMLFrameSetElement.cpp:
+ (WebCore::HTMLFrameSetElement::defaultEventHandler): Check that our renderer is
+ of type RenderFrameSet before casting it as such.
+
+2010-09-30 Cris Neckar <cdn@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Added check to test for removed counter node when calling findPlaceForCounter() in updateCounters().
+ Added refcounting to counternodes in countermaps.
+ https://bugs.webkit.org/show_bug.cgi?id=46387
+
+ Test: fast/css/counters/counter-traverse-table-cell.html
+
+ * rendering/CounterNode.cpp:
+ (WebCore::CounterNode::create):
+ * rendering/CounterNode.h:
+ * rendering/RenderCounter.cpp:
+ (WebCore::makeCounterNode):
+ (WebCore::destroyCounterNodeWithoutMapRemoval):
+ (WebCore::RenderCounter::destroyCounterNodes):
+ (WebCore::RenderCounter::destroyCounterNode):
+ (WebCore::updateCounters):
+
+2010-09-30 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Dan Bernstein.
+
+ While updating :before and :after content, make sure that the generated
+ container is allowed to add the child type.
+ https://bugs.webkit.org/show_bug.cgi?id=46106
+
+ Test: fast/css-generated-content/text-before-table-col-crash.html
+
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::RenderObjectChildList::updateBeforeAfterContent):
+
+2010-09-28 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Canvas: Crash when setting a font with size in 'ex' units
+ https://bugs.webkit.org/show_bug.cgi?id=46538
+
+ update() the style's font after setting the style's font description.
+ Needed because CSSPrimitiveValue::computeLengthDouble() later assumes
+ that the style's font is properly initialized (for xHeight().)
+
+ Fixes crash on IE test center's canvas-text-font-002 test.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::setFont):
+
+2010-09-27 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Dan Bernstein.
+
+ When the block RunIn is destroyed, its line box tree is not deleted. As a result, it
+ gets later used during dirtying of inline text boxes step where this deleted parent is
+ accessed. The fix is to delete the line box tree before destroying the runin block.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46376
+
+ Test: fast/text/dirty-inline-textbox-crash.html
+
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::dirtyLineBoxes):
+
+2010-09-27 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Dave Hyatt.
+
+ Fix memory safety issue during positioning list marker as a result of assuming
+ that list item's parent can always be casted to a RenderBox. The display of the parent
+ can be manipluated using css as Inline which causes a bad cast.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46384
+
+ Test: fast/lists/parent-box-not-box-crash.html
+
+ * rendering/RenderListItem.cpp:
+ (WebCore::RenderListItem::positionListMarker):
+ * rendering/RenderListMarker.cpp:
+ (WebCore::RenderListMarker::layout):
+
+2010-09-23 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46326
+ Crash when trying to create a NodeIterator rooted at a document-less DocumentType node
+
+ Test: fast/dom/node-iterator-with-doctype-root.html
+
+ * dom/Document.cpp: (WebCore::Document::detachNodeIterator): Added a comment explaining that
+ attach/detach may not always be paired.
+
+ * dom/NodeIterator.cpp:
+ (WebCore::NodeIterator::NodeIterator): Don't try to register with the document if there is none.
+ (WebCore::NodeIterator::~NodeIterator): Ditto.
+ (WebCore::NodeIterator::detach): Ditto.
+ (WebCore::NodeIterator::updateForNodeRemoval): There should be a document if we're getting a
+ notification.
+
+2010-09-22 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Adam Barth.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46222
+ <rdar://problem/8461701> Document.getElementById() malfunctions if ID was changed via Attr node modification.
+
+ Test: fast/dom/Attr/change-id-via-attr-node-value.html
+
+ * dom/Attr.h:
+ * dom/Attr.cpp:
+ (WebCore::Attr::setValue): Separated a version callable from WebCore from one avaiable to JS.
+ Attr::setValue() can be called from Element::setAttribute(), and we don't want to update
+ m_elementsById (or to call attributeChanged()) twice in that case.
+ (WebCore::Attr::childrenChanged): If Attr's node children change, id changes.
+
+ * dom/Document.cpp: (WebCore::Document::removeElementById): Added an assertion that we are
+ not trying to remove something that isn't there. If we are, we probably failed to update
+ m_elementsById earlier.
+
+ * dom/Element.cpp: (WebCore::Element::setAttribute): If the attribute has an Attr node, its
+ children should be updated to match attribute value.
+
+2010-09-21 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/7729077> Extending the selection to sentence boundary after a line break may select extra character
+ https://bugs.webkit.org/show_bug.cgi?id=46232
+
+ Test: editing/selection/extend-by-sentence-002.html
+
+ * editing/visible_units.cpp:
+ (WebCore::nextBoundary): The text iterator\81fs range end can be the position after
+ the line break, in which case the next visible is actually after the first character
+ of the next sentence. Instead, advance the text iterator past the newline character
+ and return the beginning of its range, which is guaranteed to still be before the
+ next sentence.
+
+2010-09-16 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Adam Barth.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45852
+ Range::selectNode and selectNodeContents misbehave when argument is in another document
+
+ Test: fast/dom/Range/select-node-different-document.html
+
+ There is nothing in DOM Traversal spec that says this shouldn't work, and it does work in
+ Firefox.
+
+ * dom/Range.cpp:
+ (WebCore::Range::setDocument):
+ (WebCore::Range::selectNode):
+ (WebCore::Range::selectNodeContents):
+ * dom/Range.h:
+
+2010-09-16 Tony Gentilcore <tonyg@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Crash in WebCore::FrameLoader::shouldInterruptLoadForXFrameOptions
+ https://bugs.webkit.org/show_bug.cgi?id=45833
+
+ Test: fast/parser/x-frame-options-detached-document-crash.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::processHttpEquiv): Other branches in this method already test for a null frame. So it seems to make sense to test that here as well.
+
+2010-09-14 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Hang processing href attribute containing a million slashes
+ https://bugs.webkit.org/show_bug.cgi?id=45767
+
+ Test: fast/css/visited-link-hang.html
+
+ * platform/LinkHash.cpp:
+ (WebCore::findSlashDotDotSlash): Added a start position argument and
+ changed types to use size_t consistently instead of a mix.
+ (WebCore::findSlashSlash): Ditto.
+ (WebCore::findSlashDotSlash): Ditto.
+ (WebCore::squeezeOutNullCharacters): Added.
+ (WebCore::cleanSlashDotDotSlashes): Added. Factored out part
+ of cleanPath (see below).
+ (WebCore::mergeDoubleSlashes): Ditto.
+ (WebCore::cleanSlashDotSlashes): Ditto.
+ (WebCore::cleanPath): Changed algorithm to not remove as we go to
+ avoid N^2 behavior; instead replace with null characters and then
+ do a squeeze operation after the fact. Also moved the body of the
+ function out of line since we normally don't have to do any cleaning.
+ This whole thing should go at some point -- it's not the right
+ algorithm -- but this should eliminate the performance problems
+ without changing behavior.
+
+2010-09-07 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Remove redundant bounds check in originalText(). Add bounds check
+ to previousCharacter(). No need of start() > 0 check since m_start
+ is unsigned and we already do start() null check inside function.
+ https://bugs.webkit.org/show_bug.cgi?id=45303
+
+ Test: fast/text/one-letter-transform-crash.html
+
+ * rendering/RenderTextFragment.cpp:
+ (WebCore::RenderTextFragment::originalText):
+ (WebCore::RenderTextFragment::previousCharacter):
+
+2010-08-30 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ WebCore::RenderBlock::addChild* NULL ptrs
+ https://bugs.webkit.org/show_bug.cgi?id=43722
+
+ Also includes some cleanup of comments and ASSERTs.
+
+ Test: fast/ruby/before-doesnt-crash.html
+
+ * rendering/RenderRuby.cpp:
+ (WebCore::RenderRubyAsInline::addChild):
+
+2010-08-18 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Adele Peterson.
+
+ Null dereference in DOMSelection::deleteFromDocument
+ https://bugs.webkit.org/show_bug.cgi?id=44153
+
+ deleteFromDocument checks selection->isNone() before calling
+ selection->selection().toNormalizedRange(), but toNormalizedRange()
+ notes that it needs to updateLayout(), which can make the selection
+ isNone() again. In that case, we crash on a NULL pointer in
+ deleteFromDocument. I don't know how to trigger that situation in a
+ test, but cross_fuzz was able to hit it, so we should fix it.
+
+ * page/DOMSelection.cpp:
+ (WebCore::DOMSelection::deleteFromDocument):
+
+2010-08-17 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by David Levin.
+
+ MessagePort.close() crashes if the owning context was destroyed.
+ https://bugs.webkit.org/show_bug.cgi?id=43140
+
+ Test: fast/events/message-port-context-destroyed.html
+
+ * dom/MessagePort.cpp:
+ (WebCore::MessagePort::postMessage):
+ (WebCore::MessagePort::start):
+ (WebCore::MessagePort::close):
+ (WebCore::MessagePort::contextDestroyed):
+ Use isEntangled() method to gate various operations on MessagePort. This method also takes into account m_closed bit.
+
+ * dom/ScriptExecutionContext.cpp:
+ (WebCore::ScriptExecutionContext::stopActiveDOMObjects):
+ (WebCore::ScriptExecutionContext::closeMessagePorts):
+ * dom/ScriptExecutionContext.h:
+ Add closeMessagePorts() method that closes message ports at the same moments when other ActiveDOMObjects are stopped.
+
+2010-08-17 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Make DocumentParser safer to use
+ https://bugs.webkit.org/show_bug.cgi?id=43055
+
+ Make DocumentParser and its subclasses RefCounted, and protect
+ HTMLDocumentParser during parsing. It's possible for a parser to
+ get deleted if certain actions (e.g., a document.write()) occur
+ synchronously.
+
+ The original version of this patch was written by Nate Chapin.
+
+ DocumentParser doesn't actually have to be fully RefCounted, since
+ the only two things which should ever hold a reference to it are
+ Document and DocumentParser itself. However using RefCounted and
+ RefPtr was easier/cleaner than inventing a custom ref() scheme.
+
+ This deploys a new "detach()" method throughout the parsing
+ framework. detach() causes the parser to disconnect from the
+ document so that no further modifications will be made to the
+ document while any possible DocumentParser stacks are unwound.
+
+ The irony of this patch is that the new detach() system is never
+ used, since Document always outlives the DocumentParser in all of
+ our layout tests. There is an ASSERT in ~Document() to verify
+ that the DocumentParser will not outlive the Document.
+
+ However I expect that we will soon either find new test cases, or change
+ the architecture in such a way that DocumentParser will outlive
+ Document. At which point, the detach() plumbing will be crucial.
+ Right now detach() serves as a safe-guard against use-after-free bugs
+ for any case where DocumentParser does outlive the Document.
+
+ This also fixes test cases attached to:
+ https://bugs.webkit.org/show_bug.cgi?id=42099
+
+ Tests: fast/frames/document-write-in-iframe-onload.html
+ fast/frames/set-parent-src-synchronously.html
+ fast/parser/document-close-iframe-load.html
+ fast/parser/document-close-nested-iframe-load.html
+ fast/parser/iframe-sets-parent-to-javascript-url.html
+
+ * dom/Document.cpp:
+ - Added a new detachParser() call to be used anywhere we
+ used to call m_parser.clear().
+ There is an ASSERT in ~DocumentParser which ensures that
+ we get this right.
+ (WebCore::Document::removedLastRef):
+ (WebCore::Document::~Document):
+ (WebCore::Document::createParser):
+ (WebCore::Document::detachParser):
+ (WebCore::Document::cancelParsing):
+ (WebCore::Document::implicitOpen):
+ - removed redundant m_parser.clear()
+ (WebCore::Document::implicitClose):
+ * dom/Document.h:
+ * dom/DocumentParser.cpp:
+ (WebCore::DocumentParser::~DocumentParser):
+ - ASSERT that callers always call detach() before destruction.
+ - This ASSERT might prove too cumbersome, but for now it's useful.
+ (WebCore::DocumentParser::detach):
+ * dom/DocumentParser.h:
+ * dom/RawDataDocumentParser.h:
+ * dom/XMLDocumentParser.cpp:
+ (WebCore::XMLDocumentParser::finish):
+ - Add a FIXME explaining part of the reason why
+ stopParsing() and detach() are separate concepts.
+ * dom/XMLDocumentParser.h:
+ (WebCore::XMLDocumentParser::create):
+ * dom/XMLDocumentParserLibxml2.cpp:
+ (WebCore::XMLDocumentParser::parseDocumentFragment):
+ * dom/XMLDocumentParserQt.cpp:
+ (WebCore::XMLDocumentParser::parseDocumentFragment):
+ * html/HTMLConstructionSite.cpp:
+ (WebCore::HTMLConstructionSite::detach):
+ (WebCore::HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded):
+ * html/HTMLConstructionSite.h:
+ * html/HTMLDocument.cpp:
+ (WebCore::HTMLDocument::createParser):
+ * html/HTMLDocument.h:
+ * html/HTMLDocumentParser.cpp:
+ - We need to protect(this) before calling into any code
+ which might cause the parser to be destroyed.
+ (WebCore::HTMLDocumentParser::~HTMLDocumentParser):
+ (WebCore::HTMLDocumentParser::detach):
+ (WebCore::HTMLDocumentParser::resumeParsingAfterYield):
+ (WebCore::HTMLDocumentParser::pumpTokenizer):
+ (WebCore::HTMLDocumentParser::insert):
+ (WebCore::HTMLDocumentParser::append):
+ (WebCore::HTMLDocumentParser::end):
+ (WebCore::HTMLDocumentParser::finish):
+ (WebCore::HTMLDocumentParser::notifyFinished):
+ (WebCore::HTMLDocumentParser::executeScriptsWaitingForStylesheets):
+ (WebCore::HTMLDocumentParser::parseDocumentFragment):
+ * html/HTMLDocumentParser.h:
+ (WebCore::HTMLDocumentParser::create):
+ * html/HTMLScriptRunner.cpp:
+ (WebCore::HTMLScriptRunner::detach):
+ (WebCore::HTMLScriptRunner::executeParsingBlockingScript):
+ (WebCore::HTMLScriptRunner::executeScript):
+ (WebCore::HTMLScriptRunner::executeScriptsWaitingForStylesheets):
+ (WebCore::HTMLScriptRunner::runScript):
+ * html/HTMLScriptRunner.h:
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::detach):
+ (WebCore::HTMLTreeBuilder::passTokenToLegacyParser):
+ (WebCore::HTMLTreeBuilder::finished):
+ * html/HTMLTreeBuilder.h:
+ * html/HTMLViewSourceDocument.cpp:
+ (WebCore::HTMLViewSourceDocument::createParser):
+ * html/HTMLViewSourceDocument.h:
+ * html/HTMLViewSourceParser.cpp:
+ (WebCore::HTMLViewSourceParser::HTMLViewSourceParser):
+ * html/HTMLViewSourceParser.h:
+ (WebCore::HTMLViewSourceParser::create):
+ * loader/FTPDirectoryDocument.cpp:
+ (WebCore::FTPDirectoryDocumentParser::create):
+ (WebCore::FTPDirectoryDocument::createParser):
+ * loader/FTPDirectoryDocument.h:
+ * loader/ImageDocument.cpp:
+ (WebCore::ImageDocumentParser::create):
+ (WebCore::ImageDocumentParser::ImageDocumentParser):
+ (WebCore::ImageDocument::createParser):
+ * loader/ImageDocument.h:
+ * loader/MediaDocument.cpp:
+ (WebCore::MediaDocumentParser::create):
+ (WebCore::MediaDocument::createParser):
+ * loader/MediaDocument.h:
+ * loader/PluginDocument.cpp:
+ (WebCore::PluginDocumentParser::create):
+ (WebCore::PluginDocument::createParser):
+ * loader/PluginDocument.h:
+ * loader/SinkDocument.cpp:
+ (WebCore::SinkDocumentParser::create):
+ (WebCore::SinkDocument::createParser):
+ * loader/SinkDocument.h:
+ * loader/TextDocument.cpp:
+ (WebCore::TextDocumentParser::create):
+ (WebCore::TextDocument::createParser):
+ (WebCore::createTextDocumentParser):
+ * loader/TextDocument.h:
+
+2010-08-15 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Don't try to replace a non-existent document after executing JavaScript URLs
+ https://bugs.webkit.org/show_bug.cgi?id=44024
+
+ Synchronous JavaScript execution is evil. Previously, the frame was
+ deleted after executing the JavaScript URL, so we'd get confused when
+ we tried to replace its document.
+
+ Test: fast/frames/javascript-url-for-deleted-frame.html
+
+ * bindings/ScriptControllerBase.cpp:
+ (WebCore::ScriptController::executeIfJavaScriptURL):
+
+2010-08-13 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Session history should skip over JS redirects
+ https://bugs.webkit.org/show_bug.cgi?id=42861
+
+ Lock the back/forward list for location changes and form submits that
+ happen before the onload event fires that are not the result of user
+ gestures.
+
+ Made form submission (at the ScheduledFormSubmission level) more similar
+ to ScheduledURLNavigation by having it call clientRedirected too, fixing
+ a long-standing FIXME.
+
+ Test: fast/history/gesture-before-onload-location-href.html,
+ fast/history/gesture-before-onload-form-submit.html and updated
+ expectations for http/tests/history tests that used to fail.
+
+ * loader/FormSubmission.cpp:
+ (WebCore::FormSubmission::requestURL):
+ (WebCore::FormSubmission::populateFrameLoadRequest):
+ * loader/FormSubmission.h:
+ * loader/RedirectScheduler.cpp:
+ (WebCore::ScheduledFormSubmission::ScheduledFormSubmission):
+ (WebCore::ScheduledFormSubmission::fire):
+ (WebCore::ScheduledFormSubmission::didStartTimer):
+ (WebCore::ScheduledFormSubmission::didStopTimer):
+ (WebCore::RedirectScheduler::scheduleRedirect):
+ (WebCore::RedirectScheduler::mustLockBackForwardList):
+ (WebCore::RedirectScheduler::scheduleLocationChange):
+ (WebCore::RedirectScheduler::scheduleFormSubmission):
+ * loader/RedirectScheduler.h:
+
+2010-08-12 Justin Schuh <jschuh@chromium.org>
+
+ Reviewed by Dumitru Daniliuc.
+
+ Clear PluginData's page pointer on page refresh
+ https://bugs.webkit.org/show_bug.cgi?id=43888
+
+ Test: plugins/access-after-page-destroyed.html
+
+ * page/Page.cpp:
+ (WebCore::Page::refreshPlugins):
+
+2010-08-08 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ cross_fuzz WebCore::SelectionController::isFocusedAndActive ReadAV@NULL (9e865de49b1800ec790dcc35d8ebd069)
+ https://bugs.webkit.org/show_bug.cgi?id=43040
+
+ The pointer from Document to Frame can be null. See http://webkit.org/coding/major-objects.html.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+
+2010-06-23 Andy Estes <aestes@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ <rdar://problem/8107855> Prevent a crash in WebCore when removing an
+ object element with an invalid data URL in in a listener to its
+ beforeload event.
+ https://bugs.webkit.org/show_bug.cgi?id=41054
+
+ Tests: fast/dom/beforeload/remove-bad-object-in-beforeload-listener.html
+
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::renderFallbackContent): Exit early if the
+ object element is not in the document.
+ * rendering/RenderEmbeddedObject.cpp:
+ (WebCore::RenderEmbeddedObject::updateWidget): If RenderWidget::destroy()
+ was called during processing of onbeforeload, do not proceed with loading
+ the object.
+
+2010-06-18 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Convert column span from an unsigned short type to an unsigned int
+ type. Fixes a divide-by-zero crash arising from using a zero colspan
+ value coming from a narrow cast of an int to an unsigned short.
+ https://bugs.webkit.org/show_bug.cgi?id=40812
+
+ Test: fast/table/zero-colspan-crash.html
+
+ * rendering/RenderTable.h: Change span from unsigned short to unsigned int.
+ * rendering/RenderTableSection.cpp: Fix a compiler warning with comparing
+ unsigned int with signed int. Value of an unsigned int here cannot be
+ greater than maximum positive value of a signed int.
+ (WebCore::RenderTableSection::addCell):
+
+2010-06-17 Andy Estes <aestes@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ <rdar://problem/8091385> Prevent a crash in WebCore when removing a stylesheet link element in
+ in a listener to its beforeload event.
+ https://bugs.webkit.org/show_bug.cgi?id=40742
+
+ Postpone loading of link elements until after they have been inserted into the DOM and
+ attached. This prevents DOM mutations triggered by beforeload handlers from firing in the
+ midst of DOM insertion, which can lead to assertion failures and crashes.
+
+ Test: fast/dom/beforeload/remove-link-in-beforeload-listener.html
+
+ * html/HTMLLinkElement.cpp:
+ (WebCore::HTMLLinkElement::HTMLLinkElement): Initialize m_shouldProcessAfterAttach to false.
+ (WebCore::HTMLLinkElement::processCallback): Add a static callback function which calls
+ HTMLLinkElement::process().
+ (WebCore::HTMLLinkElement::insertedIntoDocument): Instead of calling process() directly, set
+ m_shouldProcessAfterAttach to true to indicate that process() should be called after attach().
+ (WebCore::HTMLLinkElement::removedFromDocument): Set m_shouldProcessAfterAttach to false.
+ (WebCore::HTMLLinkElement::attach): If m_shouldProcessAfterAttach is true, register
+ HTMLLinkElement::processCallback() as a post-attach callback.
+ * html/HTMLLinkElement.h: Add m_shouldProcessAfterAttach.
+ (WebCore::HTMLLinkElement::canLazyAttach): Override canLazyAttach() to return false to
+ indicate that a full attach should be performed. This ensures the post-attach callbacks are
+ fired.
+
+2010-05-31 Tony Chang <tony@chromium.org>
+
+ Reviewed by Dan Bernstein.
+
+ REGRESSION (r58665): Infinite recursion in Position::getInlineBoxAndOffset()
+ https://bugs.webkit.org/show_bug.cgi?id=39946
+
+ r58665 added an infinite recursion check, but didn't take into consideration recursion between two
+ Positions. This adds a check for when
+ downstreamIgnoringEditingBoundaries(p1) == p2 and upstreamIgnoringEditingBoundaries(p2) == p1
+
+ Test: editing/selection/mixed-editability-12.html
+
+ * dom/Position.cpp:
+ (WebCore::Position::getInlineBoxAndOffset):
+
+2010-05-12 Yuzo Fujishima <yuzo@google.com>
+
+ Reviewed by Darin Adler.
+
+ Fix Bug 35014 - Modifying UA rules from page JS crashes
+ Added a NULL check.
+ https://bugs.webkit.org/show_bug.cgi?id=35014
+
+ Test: fast/css/modify-ua-rules-from-javascript.html
+
+ * css/CSSMutableStyleDeclaration.cpp:
+ (WebCore::CSSMutableStyleDeclaration::setNeedsStyleRecalc):
+
+2010-05-02 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Another case of <rdar://problem/7552959> REGRESSION: Infinite recursion in Position::getInlineBoxAndOffset()
+ https://bugs.webkit.org/show_bug.cgi?id=38445
+
+ Test: editing/selection/mixed-editability-11.html
+
+ * dom/Position.cpp:
+ (WebCore::downstreamIgnoringEditingBoundaries): Added. Returns the furthest visually equivalent
+ position downstream, crossing any editability boundaries.
+ (WebCore::upstreamIgnoringEditingBoundaries): Similarly for upstream.
+ (WebCore::Position::getInlineBoxAndOffset): Changed the logic for finding an inline box for positions
+ whose node is a block flow. Instead of traversing the DOM, advance downstream or upstream as far as
+ possible, crossing any editability boudaries. Infinite recursion is avoided by advancing all the way
+ and checking that the new position is different from the starting position. Also replaced the specific
+ test for buttons with the generic and more comprehensive canHaveChildrenForEditing().
+
+2010-04-28 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ [XHR] Cross-Origin synchronous request with credential raises NETWORK_ERR
+ https://bugs.webkit.org/show_bug.cgi?id=37781
+ <rdar://problem/7905150>
+
+ Tests: http/tests/xmlhttprequest/access-control-preflight-credential-async.html
+ http/tests/xmlhttprequest/access-control-preflight-credential-sync.html
+
+ Rolling the patch in as I could not reproduce Qt results locally.
+
+ * loader/DocumentThreadableLoader.cpp:
+ (WebCore::DocumentThreadableLoader::DocumentThreadableLoader): Now we remove the
+ credential from the request here to avoid forgetting to do so in the different code path.
+ (WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest): Just add the
+ "Origin" header.
+ (WebCore::DocumentThreadableLoader::loadRequest): Check here the the credential have
+ been removed so that we don't leak them. Also tweaked a comment to make it clear that
+ the URL check has issue when credential is involved.
+
+2010-04-09 Darin Adler <darin@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ https://bugs.webkit.org/show_bug.cgi?id=37370
+ Division by 0 in RenderBoxModelObject::calculateFillTileSize
+
+ Test: fast/backgrounds/background-fill-zero-area-crash.html
+
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::calculateFillTileSize): Added checks for
+ zero before doing division. These come up when the area to fill is zero.
+
+2010-04-08 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Manipulating document fragment members while adding it to tree may result in loss of tree integrity.
+ https://bugs.webkit.org/show_bug.cgi?id=36031
+
+ Changes the logic of appending/inserting document fragment to first stashing all of its children
+ to a vector, then processing the vector. This avoids ghastliness that would be caused by mutation
+ events mucking with the document fragment while it's being appended/inserted.
+
+ Test: fast/dom/Node/fragment-mutation.html
+
+ * dom/ContainerNode.cpp:
+ (WebCore::targetNodes): Added method to populate a vector of nodes (targets) to be used in
+ inserting/appending operation.
+ (WebCore::ContainerNode::insertBefore): Changed to use vector-based iteration.
+ (WebCore::ContainerNode::appendChild): Ditto.
+ * dom/Node.cpp:
+ (WebCore::Node::checkReplaceChild): Cleaned up comments.
+ (WebCore::Node::checkAddChild): Ditto.
+
+2010-04-02 Justin Schuh <jschuh@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ XHR allows arbitrary XSRF across domains
+ https://bugs.webkit.org/show_bug.cgi?id=36843
+
+ Added a one-line change to prevent bypassing the XDC check on
+ synchronous preflighted requests. Added layout tests to cover
+ variations of this problem.
+
+ Tests: http/tests/xmlhttprequest/access-control-preflight-async-header-denied.html
+ http/tests/xmlhttprequest/access-control-preflight-async-method-denied.html
+ http/tests/xmlhttprequest/access-control-preflight-sync-header-denied.html
+ http/tests/xmlhttprequest/access-control-preflight-sync-method-denied.html
+
+ * loader/DocumentThreadableLoader.cpp:
+ (WebCore::DocumentThreadableLoader::preflightFailure):
+
+2010-04-01 MORITA Hajime <morrita@google.com>
+
+ Reviewed by Darin Adler.
+
+ WebCore::Document::updateLayoutIgnorePendingStylesheets NULL pointer
+ https://bugs.webkit.org/show_bug.cgi?id=31680
+ Ownerless nodes leads a crash on DOMSelection APIs
+ https://bugs.webkit.org/show_bug.cgi?id=36800
+
+ Added guards nodes from foreign documents to DOMSelection APIs.
+
+ Tests: editing/selection/DOMSelection-DocumentType.html
+ editing/selection/DOMSelection-crossing-document.html
+
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::canonicalPosition):
+ * page/DOMSelection.cpp:
+ (WebCore::DOMSelection::collapse):
+ (WebCore::DOMSelection::setBaseAndExtent):
+ (WebCore::DOMSelection::setPosition):
+ (WebCore::DOMSelection::extend):
+ (WebCore::DOMSelection::containsNode):
+ (WebCore::DOMSelection::isValidForPosition):
+ * page/DOMSelection.h:
+
+2010-03-31 MORITA Hajime <morrita@google.com>
+
+ Reviewed by Darin Adler.
+
+ Crash when writing into a detached TITLE element
+ https://bugs.webkit.org/show_bug.cgi?id=25567
+
+ Document::setTitle() invoked HTMLTitleElement::setText(), which
+ contains DOM tree modification, even when setTitle() is called
+ from HTMLTitleElement::childrenChanged(). Fix to skip setText()
+ when setTitle() is called childrenChanged() to avoid cascading
+ DOM mutations between Document and HTMLTitleElement.
+
+ Test: fast/dom/title-content-write-set.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::setTitle):
+
+2010-03-31 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Crash submitting display:none textarea in a form
+ https://bugs.webkit.org/show_bug.cgi?id=36905
+
+ Test: fast/forms/textarea-submit-crash.html
+
+ * html/HTMLTextAreaElement.cpp:
+ (WebCore::HTMLTextAreaElement::appendFormData): Do update layout before
+ asking our renderer for its text, since we can't rely on our renderer's
+ text if layout is needed.
+
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::textWithHardLineBreaks): Don't update layout
+ while being asked for our text, since doing so may delete us, causing a crash.
+
+2010-03-04 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Handles setting HTMLSelectElement.length with mutation handlers present
+ https://bugs.webkit.org/show_bug.cgi?id=33983
+
+ When setting an HTMLSelectElement's length attribute, option elements have to be added or removed to the select
+ as appropriate. This is a little tricky with mutation events since they might add, remove, or reorder elements
+ while option elements are being added or deleted.
+
+ Tests: fast/forms/select-set-length-optgroup.html
+ fast/forms/select-set-length-with-mutation-remove.html
+ fast/forms/select-set-length-with-mutation-reorder.html
+ fast/forms/select-set-length-with-mutation-reparent.html
+ fast/forms/select-set-length-with-mutation.html
+ fast/forms/select-set-length.html
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::setLength):
+
+2010-02-16 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by NOBODY (OOPS!).
+
+ Bug 34974: Leak of ScheduledAction during layout tests
+ <https://bugs.webkit.org/show_bug.cgi?id=34974>
+
+ ScheduledAction::create was returning a raw pointer which was threaded down through to an OwnPtr in DOMTimer.
+ If any of the code paths in between hit an error case and returned early the raw pointer would be leaked. We
+ can avoid this by passing it as a PassOwnPtr. This will ensure that the ScheduledAction is cleaned up should
+ an error case be hit.
+
+ * bindings/js/JSDOMWindowCustom.cpp:
+ (WebCore::JSDOMWindow::setTimeout): Store the newly-created ScheduledAction in an OwnPtr and then hand it off
+ as the function argument.
+ (WebCore::JSDOMWindow::setInterval): Ditto.
+ * bindings/js/JSWorkerContextCustom.cpp:
+ (WebCore::JSWorkerContext::setTimeout): Ditto.
+ (WebCore::JSWorkerContext::setInterval): Ditto.
+ * bindings/js/ScheduledAction.cpp:
+ (WebCore::ScheduledAction::create): Return a PassOwnPtr.
+ * bindings/js/ScheduledAction.h:
+ * page/DOMTimer.cpp:
+ (WebCore::DOMTimer::DOMTimer): Update argument type.
+ (WebCore::DOMTimer::install): Ditto.
+ * page/DOMTimer.h:
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::setTimeout): Ditto.
+ (WebCore::DOMWindow::setInterval): Ditto.
+ * page/DOMWindow.h:
+
+2010-01-26 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ <rdar://problem/7576663> Crash caused by anonymous list item
+ https://bugs.webkit.org/show_bug.cgi?id=34183
+
+ Test: fast/lists/anonymous-items.html
+
+ enclosingList() and previousListItem() were DOM-based, but in order to work with anonymous
+ list items, they need to work with rthe render tree.
+
+ * rendering/RenderListItem.cpp:
+ (WebCore::isList): Factored out.
+ (WebCore::enclosingList): Added this variant that takes a RenderObject.
+ (WebCore::previousListItem): Changed to travers the render tree.
+ (WebCore::RenderListItem::calcValue): Use the RenderObject version of enclosingList()
+ (WebCore::RenderListItem::setExplicitValue): Added an assertion.
+ (WebCore::RenderListItem::clearExplicitValue): Ditto.
+
+2010-01-24 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Content with heavily nested residual style is so slow, it seems like a hang
+ https://bugs.webkit.org/show_bug.cgi?id=34059
+ <rdar://problem/7292906>
+
+ Test cast: fast/parser/residual-style-hang.html
+
+ * html/HTMLParser.cpp:
+ (WebCore::HTMLParser::handleResidualStyleCloseTagAcrossBlocks):
+ Limit the number of iterations of the main loop to 5.
+
+ The reason this limit is necessary is that otherwise, N misnested open tags followed
+ by N misnested close tags will cause O(N^2) of work due to cloning and attaching subtrees;
+ at a fixed limit, the cost is at worst O(N).
+
+ The code that was in the loop originally ran exactly once - the loop was added in
+ r21472 to fix <https://bugs.webkit.org/show_bug.cgi?id=13603>. I have verified that
+ with the iteration limit, the bug is still fixed, both with the original test case
+ and with the layout tests tht were added.
+
+2010-01-22 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34008
+ Assertion failure in KURL::setProtocol when running DOM Fuzzer
+
+ Test: fast/dom/Window/invalid-protocol.html
+
+ * bindings/js/JSLocationCustom.cpp: (WebCore::JSLocation::setProtocol): Raise an exception
+ if KURL::setProtocol fails.
+
+ * html/HTMLAnchorElement.cpp: (WebCore::HTMLAnchorElement::setProtocol): Move argument
+ tweaking logic into KURL. This way, the ':' trick applies to both JSLocation and
+ HTMLAnchorElement, matching IE (but not Firefox). IE behavior is more permissive, and even
+ more logical in my opinion.
+
+ * loader/FrameLoader.cpp: (WebCore::FrameLoader::iconURL): Assert that setting protocol
+ succeeded.
+
+ * platform/KURL.cpp: (WebCore::KURL::setProtocol): Remove everything past ':', if present.
+ Return false if the protocol to set is not valid.
+ (WebCore::isValidProtocol): Made this work correctly for empty strings.
+
+ * platform/KURL.h: isValidProtocol() is now static in KURL.cpp, it's only used in setProtocol().
+
+ * platform/KURLGoogle.cpp:
+ (WebCore::KURL::setProtocol): Always return true. This should hopefully prevent Chromium build
+ breakage, alhough tests will likely fail.
+ (WebCore::isValidProtocol): Removed, as this isn't used at the moment.
+
+ * websockets/WebSocketHandshake.cpp: (WebCore::WebSocketHandshake::httpURLForAuthenticationAndCookies):
+ Assert that setting protocol succeeded.
+
+2010-01-18 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33815
+ Crash when using DOMTimer from a detached frame
+
+ Test: fast/dom/Window/timer-null-script-execution-context.html
+
+ * bindings/js/JSDOMWindowCustom.cpp:
+ (WebCore::JSDOMWindow::setTimeout):
+ (WebCore::JSDOMWindow::setInterval):
+ * page/DOMWindow.h:
+ * page/DOMWindow.idl:
+ Make setTimer and setInterval raise an exception. It is not specified in HTML5, but both
+ IE and Firefox do raise an exception in this situation, although different ones.
+
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::setTimeout): Raise INVALID_ACCESS_ERR if script execution context is
+ null (meaning that the window is detached).
+ (WebCore::DOMWindow::setInterval): Ditto.
+ (WebCore::DOMWindow::clearTimeout): Silently return early if there is no script execution
+ context.
+ (WebCore::DOMWindow::clearInterval): Ditto.
+ Raise INVALID_ACCESS_ERR if script execution context is null (meaning .
+
+2010-01-04 Darin Adler <darin@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Reentrancy problem with selection in some edge cases.
+ https://bugs.webkit.org/show_bug.cgi?id=32842
+ rdar://problem/7449974
+
+ Test: fast/forms/selection-layout-reentry-strange-case.html
+
+ Move the selection display update process done in the
+ selectionLayoutChanged function into the layout timer
+ instead of doing it immediately when selection changes occur.
+
+ * dom/Document.cpp:
+ (WebCore::Document::updateLayout): Changed this to use the
+ definition of needsLayout from FrameView rather than rolling
+ its own.
+
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::SelectionController):
+ Initialize m_needsDisplayUpdate to false.
+ (WebCore::SelectionController::setSelection): Call
+ the new setNeedsDisplayUpdate function instead of the old
+ badly named Frame::selectionLayoutChanged function.
+ (WebCore::SelectionController::setNeedsDisplayUpdate):
+ Set m_needsDisplayUpdate. If it is just becoming true, then
+ call FrameView::scheduleRelayout.
+
+ * editing/SelectionController.h: Added setNeedsDisplayUpdate,
+ needsDisplayUpdate, and m_needsDisplayUpdate.
+
+ * page/Frame.cpp:
+ (WebCore::Frame::setCaretVisible): Call setNeedsDisplayUpdate.
+ (WebCore::Frame::selectionLayoutChanged): Call
+ setNeedsDisplayUpdate to set it to false, since this is the
+ function that performs "selection display update". Later I want
+ to rename this function. Also added a global reentrancy check
+ since that's the easiest way I could think of to prevent infinite
+ recursion in the case where recomputeCaretRect ends up triggering
+ a layout. As a side effect, fixed theoretical problems in
+ TEXT_CARET builds by improving the ifdef.
+ (WebCore::Frame::caretBlinkTimerFired): Loosen assertions a
+ bit. Later we might want to decouple caret rect from caret state
+ a bit more and add these assertions back.
+ (WebCore::Frame::selectionBounds): Call Document::updateLayout.
+ This function is for external clients and they do not currently
+ do anything to make sure layout is up to date.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::needsLayout): Add a new clause, since
+ we need a call to layout if needsDisplayUpdate is true.
+
+2009-10-02 Vitaly Repeshko <vitalyr@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ [V8] Recursion guard for V8Proxy::callFunction.
+ Fixes http://crbug.com/23278.
+ https://bugs.webkit.org/show_bug.cgi?id=29974
+
+ Test: fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html
+
+ * bindings/v8/V8Proxy.cpp:
+ (WebCore::V8Proxy::callFunction):
+
+2009-12-23 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/7487164> First line of text cannot be selected
+ https://bugs.webkit.org/show_bug.cgi?id=32749
+
+ Test: fast/text/remove-zero-length-run.html
+
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::positionLineBox): Changed code that assumed that if a box was being
+ removed, it was the only box in the RenderText. Instead, correctly preserve the list of
+ text boxes.
+ (WebCore::RenderText::checkConsistency): Updated for earlier rename.
+
2009-12-21 Anders Carlsson <andersca@apple.com>
Reviewed by Sam Weinig.
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/ScriptControllerBase.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/ScriptControllerBase.cpp
index 72c9f45..71eb971 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/ScriptControllerBase.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/ScriptControllerBase.cpp
@@ -59,12 +59,19 @@ bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture,
if (!protocolIsJavaScript(url))
return false;
- if (m_frame->page() && !m_frame->page()->javaScriptURLsAreAllowed())
+ if (!m_frame->page())
+ return true;
+
+ if (!m_frame->page()->javaScriptURLsAreAllowed())
return true;
if (m_frame->inViewSourceMode())
return true;
+ // We need to hold onto the Frame here because executing script can
+ // destroy the frame.
+ RefPtr<Frame> protector(m_frame);
+
const int javascriptSchemeLength = sizeof("javascript:") - 1;
String script = decodeURLEscapeSequences(url.string().substring(javascriptSchemeLength));
@@ -72,6 +79,11 @@ bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture,
if (xssAuditor()->canEvaluateJavaScriptURL(script))
result = executeScript(script, userGesture);
+ // If executing script caused this frame to be removed from the page, we
+ // don't want to try to replace its document!
+ if (!m_frame->page())
+ return true;
+
String scriptResult;
#if USE(JSC)
JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld());
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSCSSRuleCustom.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSCSSRuleCustom.cpp
index b0adf15..ec4fe9e 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSCSSRuleCustom.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSCSSRuleCustom.cpp
@@ -49,6 +49,17 @@ using namespace JSC;
namespace WebCore {
+void JSCSSRule::markChildren(MarkStack& markStack)
+{
+ Base::markChildren(markStack);
+
+ if (CSSStyleSheet* parentStyleSheet = impl()->parentStyleSheet())
+ markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), parentStyleSheet);
+
+ if (CSSRule* parentRule = impl()->parentRule())
+ markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), parentRule);
+}
+
JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSRule* rule)
{
if (!rule)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp
index 5b90fac..5297340 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -929,20 +929,30 @@ JSValue JSDOMWindow::postMessage(ExecState* exec, const ArgList& args)
JSValue JSDOMWindow::setTimeout(ExecState* exec, const ArgList& args)
{
- ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec));
+ OwnPtr<ScheduledAction> action = ScheduledAction::create(exec, args, currentWorld(exec));
if (exec->hadException())
return jsUndefined();
int delay = args.at(1).toInt32(exec);
- return jsNumber(exec, impl()->setTimeout(action, delay));
+
+ ExceptionCode ec = 0;
+ int result = impl()->setTimeout(action.release(), delay, ec);
+ setDOMException(exec, ec);
+
+ return jsNumber(exec, result);
}
JSValue JSDOMWindow::setInterval(ExecState* exec, const ArgList& args)
{
- ScheduledAction* action = ScheduledAction::create(exec, args, currentWorld(exec));
+ OwnPtr<ScheduledAction> action = ScheduledAction::create(exec, args, currentWorld(exec));
if (exec->hadException())
return jsUndefined();
int delay = args.at(1).toInt32(exec);
- return jsNumber(exec, impl()->setInterval(action, delay));
+
+ ExceptionCode ec = 0;
+ int result = impl()->setInterval(action.release(), delay, ec);
+ setDOMException(exec, ec);
+
+ return jsNumber(exec, result);
}
JSValue JSDOMWindow::atob(ExecState* exec, const ArgList& args)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSDocumentCustom.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSDocumentCustom.cpp
index 9366399..8b09cd1 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSDocumentCustom.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSDocumentCustom.cpp
@@ -60,16 +60,16 @@ void JSDocument::markChildren(MarkStack& markStack)
JSValue JSDocument::location(ExecState* exec) const
{
- Frame* frame = static_cast<Document*>(impl())->frame();
+ RefPtr<Frame> frame = impl()->frame();
if (!frame)
return jsNull();
- Location* location = frame->domWindow()->location();
- if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, location))
+ RefPtr<Location> location = frame->domWindow()->location();
+ if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, location.get()))
return wrapper;
- JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, globalObject()), globalObject(), location);
- cacheDOMObjectWrapper(exec, location, jsLocation);
+ JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, globalObject()), globalObject(), location.get());
+ cacheDOMObjectWrapper(exec, location.get(), jsLocation);
return jsLocation;
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSEventListener.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSEventListener.cpp
index ad4624d..4f255d1 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSEventListener.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSEventListener.cpp
@@ -82,6 +82,9 @@ void JSEventListener::invalidateJSFunction(JSC::JSObject* wrapper)
void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event)
{
+#if PLATFORM(WKC)
+ CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT*2);
+#endif
ASSERT(scriptExecutionContext);
if (!scriptExecutionContext)
return;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSLocationCustom.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSLocationCustom.cpp
index 6c8e032..802adef 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/JSLocationCustom.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/JSLocationCustom.cpp
@@ -24,6 +24,7 @@
#include "JSLocationCustom.h"
#include "DOMWindow.h"
+#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "JSDOMBinding.h"
@@ -214,7 +215,10 @@ void JSLocation::setProtocol(ExecState* exec, JSValue value)
ASSERT(frame);
KURL url = frame->loader()->url();
- url.setProtocol(value.toString(exec));
+ if (!url.setProtocol(value.toString(exec))) {
+ setDOMException(exec, SYNTAX_ERR);
+ return;
+ }
navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/ScheduledAction.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/ScheduledAction.cpp
index 3223e53..d24e55a 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/ScheduledAction.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/ScheduledAction.cpp
@@ -47,7 +47,7 @@ using namespace JSC;
namespace WebCore {
-ScheduledAction* ScheduledAction::create(ExecState* exec, const ArgList& args, DOMWrapperWorld* isolatedWorld)
+PassOwnPtr<ScheduledAction> ScheduledAction::create(ExecState* exec, const ArgList& args, DOMWrapperWorld* isolatedWorld)
{
JSValue v = args.at(0);
CallData callData;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/ScheduledAction.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/ScheduledAction.h
index dd13ab1..2a011f4 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/bindings/js/ScheduledAction.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/bindings/js/ScheduledAction.h
@@ -42,7 +42,7 @@ namespace WebCore {
*/
class ScheduledAction : public Noncopyable {
public:
- static ScheduledAction* create(JSC::ExecState*, const JSC::ArgList&, DOMWrapperWorld* isolatedWorld);
+ static PassOwnPtr<ScheduledAction> create(JSC::ExecState*, const JSC::ArgList&, DOMWrapperWorld* isolatedWorld);
void execute(ScriptExecutionContext*);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSFontFaceRule.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSFontFaceRule.cpp
index 75e9a36..8db46ae 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSFontFaceRule.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSFontFaceRule.cpp
@@ -33,6 +33,8 @@ CSSFontFaceRule::CSSFontFaceRule(CSSStyleSheet* parent)
CSSFontFaceRule::~CSSFontFaceRule()
{
+ if (m_style)
+ m_style->setParent(0);
}
void CSSFontFaceRule::setDeclaration(PassRefPtr<CSSMutableStyleDeclaration> style)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSGradientValue.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSGradientValue.cpp
index 5946d7a..06a2836 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSGradientValue.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSGradientValue.cpp
@@ -104,7 +104,8 @@ PassRefPtr<Gradient> CSSGradientValue::createGradient(RenderObject* renderer, co
Image* CSSGradientValue::image(RenderObject* renderer, const IntSize& size)
{
- ASSERT(m_clients.contains(renderer));
+ if (!m_clients.contains(renderer))
+ return 0;
// Need to look up our size. Create a string of width*height to use as a hash key.
Image* result = getImage(renderer, size);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSMutableStyleDeclaration.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSMutableStyleDeclaration.cpp
index 31c7507..8baae22 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSMutableStyleDeclaration.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSMutableStyleDeclaration.cpp
@@ -330,27 +330,31 @@ 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())
- yValue = static_cast<CSSValueList*>(nextValue.get())->itemWithoutBoundsCheck(i);
- else
- yValue = nextValue;
+ if (nextValue) {
+ if (nextValue->isValueList())
+ yValue = static_cast<CSSValueList*>(nextValue.get())->itemWithoutBoundsCheck(i);
+ else
+ yValue = nextValue;
- int xId = static_cast<CSSPrimitiveValue*>(value.get())->getIdent();
- int yId = static_cast<CSSPrimitiveValue*>(yValue.get())->getIdent();
- if (xId != yId) {
- if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) {
- useRepeatXShorthand = true;
+ int xId = static_cast<CSSPrimitiveValue*>(value.get())->getIdent();
+ int yId = static_cast<CSSPrimitiveValue*>(yValue.get())->getIdent();
+ if (xId != yId) {
+ if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) {
+ useRepeatXShorthand = true;
+ ++j;
+ } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) {
+ useRepeatYShorthand = true;
+ continue;
+ }
+ } else {
+ useSingleWordShorthand = true;
++j;
- } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) {
- useRepeatYShorthand = true;
- continue;
}
- } else {
- useSingleWordShorthand = true;
- ++j;
}
}
}
@@ -484,7 +488,8 @@ void CSSMutableStyleDeclaration::setNeedsStyleRecalc()
while (StyleBase* parent = root->parent())
root = parent;
if (root->isCSSStyleSheet())
- static_cast<CSSStyleSheet*>(root)->doc()->updateStyleSelector();
+ if (Document* doc = static_cast<CSSStyleSheet*>(root)->doc())
+ doc->updateStyleSelector();
}
bool CSSMutableStyleDeclaration::getPropertyPriority(int propertyID) const
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSPrimitiveValue.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSPrimitiveValue.h
index 87ca09a..22c5eae 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSPrimitiveValue.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSPrimitiveValue.h
@@ -207,7 +207,7 @@ private:
virtual unsigned short cssValueType() const;
- int m_type;
+ signed m_type;
union {
int ident;
double num;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSProperty.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSProperty.h
index 08c71d9..02ef3e5 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSProperty.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSProperty.h
@@ -62,8 +62,8 @@ public:
friend bool operator==(const CSSProperty&, const CSSProperty&);
// Make sure the following fits in 4 bytes. Really.
- int m_id : 15;
- int m_shorthandID : 15; // If this property was set as part of a shorthand, gives the shorthand.
+ signed m_id : 15;
+ signed m_shorthandID : 15; // If this property was set as part of a shorthand, gives the shorthand.
bool m_important : 1;
bool m_implicit : 1; // Whether or not the property was set implicitly as the result of a shorthand.
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSRule.idl b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSRule.idl
index bc57e55..0f8d0f3 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSRule.idl
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSRule.idl
@@ -22,6 +22,7 @@ module css {
// Introduced in DOM Level 2:
interface [
+ CustomMarkFunction,
CustomToJS,
GenerateConstructor,
Polymorphic,
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSStyleSelector.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSStyleSelector.cpp
index 41f997b..08258ad 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/CSSStyleSelector.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/CSSStyleSelector.cpp
@@ -2528,7 +2528,7 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
break;
}
case CSSSelector::PseudoFocus:
- if (e && e->focused() && e->document()->frame()->selection()->isFocusedAndActive())
+ if (e && e->focused() && e->document()->frame() && e->document()->frame()->selection()->isFocusedAndActive())
return true;
break;
case CSSSelector::PseudoHover: {
@@ -3114,7 +3114,8 @@ void CSSStyleSelector::applyPropertyToStyle(int id, CSSValue *value, RenderStyle
initElementAndPseudoState(0);
initForStyleResolve(0, style);
m_style = style;
- applyProperty(id, value);
+ if (value)
+ applyProperty(id, value);
}
void CSSStyleSelector::applyProperty(int id, CSSValue *value)
@@ -4670,6 +4671,11 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
applyProperty(CSSPropertyFontStyle, font->style.get());
applyProperty(CSSPropertyFontVariant, font->variant.get());
applyProperty(CSSPropertyFontWeight, font->weight.get());
+ // The previous properties can dirty our font but they don't try to read the font's
+ // properties back, which is safe. However if font-size is using the 'ex' unit, it will
+ // need query the dirtied font's x-height to get the computed size. To be safe in this
+ // case, let's just update the font now.
+ updateFont();
applyProperty(CSSPropertyFontSize, font->size.get());
m_lineHeightValue = font->lineHeight.get();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/StyleSheet.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/StyleSheet.cpp
index 88e904c..58a1f59 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/css/StyleSheet.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/css/StyleSheet.cpp
@@ -86,6 +86,14 @@ StyleSheet::~StyleSheet()
{
if (m_media)
m_media->setParent(0);
+
+ // For style rules outside the document, .parentStyleSheet can become null even if the style rule
+ // is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but
+ // it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection.
+ for (unsigned i = 0; i < length(); ++i) {
+ ASSERT(item(i)->parent() == this);
+ item(i)->setParent(0);
+ }
}
StyleSheet* StyleSheet::parentStyleSheet() const
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Attr.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Attr.cpp
index 8a0b51f..629e74f 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Attr.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Attr.cpp
@@ -110,13 +110,21 @@ String Attr::nodeValue() const
return value();
}
-void Attr::setValue(const AtomicString& value, ExceptionCode&)
+void Attr::setValue(const AtomicString& value)
{
m_ignoreChildrenChanged++;
removeChildren();
m_attribute->setValue(value);
createTextChild();
m_ignoreChildrenChanged--;
+}
+
+void Attr::setValue(const AtomicString& value, ExceptionCode&)
+{
+ if (m_element && m_element->isIdAttributeName(m_attribute->name()))
+ m_element->updateId(m_element->getIDAttribute(), value);
+
+ setValue(value);
if (m_element)
m_element->attributeChanged(m_attribute.get());
@@ -160,6 +168,9 @@ void Attr::childrenChanged(bool changedByParser, Node* beforeChange, Node* after
if (n->isTextNode())
val += static_cast<Text *>(n)->data();
}
+
+ if (m_element && m_element->isIdAttributeName(m_attribute->name()))
+ m_element->updateId(m_attribute->value(), val);
m_attribute->setValue(val.impl());
if (m_element)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Attr.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Attr.h
index 2e02a02..e76d2fa 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Attr.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Attr.h
@@ -48,6 +48,7 @@ public:
const AtomicString& value() const { return m_attribute->value(); }
void setValue(const AtomicString&, ExceptionCode&);
+ void setValue(const AtomicString&);
Attribute* attr() const { return m_attribute.get(); }
const QualifiedName& qualifiedName() const { return m_attribute->name(); }
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/ContainerNode.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/ContainerNode.cpp
index 38abdf7..8c21836 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/ContainerNode.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/ContainerNode.cpp
@@ -1,467 +1,521 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (c) 2010 ACCESS CO., LTD. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "ContainerNode.h"
-
-#include "BeforeLoadEvent.h"
-#include "Cache.h"
-#include "ContainerNodeAlgorithms.h"
-#include "DeleteButtonController.h"
-#include "EventNames.h"
-#include "ExceptionCode.h"
-#include "FloatRect.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "InlineTextBox.h"
-#include "MutationEvent.h"
-#include "Page.h"
-#include "RenderTheme.h"
-#include "RootInlineBox.h"
-#include "loader.h"
-#include <wtf/CurrentTime.h>
-
-namespace WebCore {
-
-static void dispatchChildInsertionEvents(Node*);
-static void dispatchChildRemovalEvents(Node*);
-
-typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
-static NodeCallbackQueue* s_postAttachCallbackQueue;
-
-static size_t s_attachDepth;
-static bool s_shouldReEnableMemoryCacheCallsAfterAttach;
-
-void ContainerNode::removeAllChildren()
-{
- removeAllChildrenInContainer<Node, ContainerNode>(this);
-}
-
-ContainerNode::~ContainerNode()
-{
- removeAllChildren();
-}
-
-bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
-{
- // Check that this node is not "floating".
- // If it is, it can be deleted as a side effect of sending mutation events.
- ASSERT(refCount() || parent());
-
- ec = 0;
-
- // insertBefore(node, 0) is equivalent to appendChild(node)
- if (!refChild)
- return appendChild(newChild, ec, shouldLazyAttach);
-
- // Make sure adding the new child is OK.
- checkAddChild(newChild.get(), ec);
- if (ec)
- return false;
-
- // NOT_FOUND_ERR: Raised if refChild is not a child of this node
- if (refChild->parentNode() != this) {
- ec = NOT_FOUND_ERR;
- return false;
- }
-
- bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE;
-
- // If newChild is a DocumentFragment with no children; there's nothing to do.
- // Just return true
- if (isFragment && !newChild->firstChild())
- return true;
-
- // Now actually add the child(ren)
- if (refChild->previousSibling() == newChild || refChild == newChild) // nothing to do
- return true;
-
- RefPtr<Node> next = refChild;
- RefPtr<Node> refChildPreviousSibling = refChild->previousSibling();
-
- RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
- while (child) {
- RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
-
- // If child is already present in the tree, first remove it from the old location.
- if (Node* oldParent = child->parentNode())
- oldParent->removeChild(child.get(), ec);
- if (ec)
- return 0;
-
- // FIXME: After sending the mutation events, "this" could be destroyed.
- // We can prevent that by doing a "ref", but first we have to make sure
- // that no callers call with ref count == 0 and parent = 0 (as of this
- // writing, there are definitely callers who call that way).
-
- // Due to arbitrary code running in response to a DOM mutation event it's
- // possible that "next" is no longer a child of "this".
- // It's also possible that "child" has been inserted elsewhere.
- // In either of those cases, we'll just stop.
- if (next->parentNode() != this)
- break;
- if (child->parentNode())
- break;
-
- ASSERT(!child->nextSibling());
- ASSERT(!child->previousSibling());
-
- // Add child before "next".
- forbidEventDispatch();
- Node* prev = next->previousSibling();
- ASSERT(m_lastChild != prev);
- next->setPreviousSibling(child.get());
- if (prev) {
- ASSERT(m_firstChild != next);
- ASSERT(prev->nextSibling() == next);
- prev->setNextSibling(child.get());
- } else {
- ASSERT(m_firstChild == next);
- m_firstChild = child.get();
- }
- child->setParent(this);
- child->setPreviousSibling(prev);
- child->setNextSibling(next.get());
- allowEventDispatch();
-
- // Dispatch the mutation events.
- childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
- dispatchChildInsertionEvents(child.get());
-
- // Add child to the rendering tree.
- if (attached() && !child->attached() && child->parent() == this) {
- if (shouldLazyAttach)
- child->lazyAttach();
- else
- child->attach();
- }
-
- child = nextChild.release();
- }
-
- dispatchSubtreeModifiedEvent();
- return true;
-}
-
-bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
-{
- // Check that this node is not "floating".
- // If it is, it can be deleted as a side effect of sending mutation events.
- ASSERT(refCount() || parent());
-
- ec = 0;
-
- if (oldChild == newChild) // nothing to do
- return true;
-
- // Make sure replacing the old child with the new is ok
- checkReplaceChild(newChild.get(), oldChild, ec);
- if (ec)
- return false;
-
- // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
- if (!oldChild || oldChild->parentNode() != this) {
- ec = NOT_FOUND_ERR;
- return false;
- }
-
- RefPtr<Node> prev = oldChild->previousSibling();
- RefPtr<Node> next = oldChild->nextSibling();
-
- // Remove the node we're replacing
- RefPtr<Node> removedChild = oldChild;
- removeChild(oldChild, ec);
- if (ec)
- return false;
-
- // FIXME: After sending the mutation events, "this" could be destroyed.
- // We can prevent that by doing a "ref", but first we have to make sure
- // that no callers call with ref count == 0 and parent = 0 (as of this
- // writing, there are definitely callers who call that way).
-
- bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE;
-
- // Add the new child(ren)
- int childCountDelta = 0;
- RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
- while (child) {
- // If the new child is already in the right place, we're done.
- if (prev && (prev == child || prev == child->previousSibling()))
- break;
-
- // For a fragment we have more children to do.
- RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
-
- // Remove child from its old position.
- if (Node* oldParent = child->parentNode())
- oldParent->removeChild(child.get(), ec);
- if (ec)
- return false;
-
- // Due to arbitrary code running in response to a DOM mutation event it's
- // possible that "prev" is no longer a child of "this".
- // It's also possible that "child" has been inserted elsewhere.
- // In either of those cases, we'll just stop.
- if (prev && prev->parentNode() != this)
- break;
- if (child->parentNode())
- break;
-
- childCountDelta++;
-
- ASSERT(!child->nextSibling());
- ASSERT(!child->previousSibling());
-
- // Add child after "prev".
- forbidEventDispatch();
- Node* next;
- if (prev) {
- next = prev->nextSibling();
- ASSERT(m_firstChild != next);
- prev->setNextSibling(child.get());
- } else {
- next = m_firstChild;
- m_firstChild = child.get();
- }
- if (next) {
- ASSERT(m_lastChild != prev);
- ASSERT(next->previousSibling() == prev);
- next->setPreviousSibling(child.get());
- } else {
- ASSERT(m_lastChild == prev);
- m_lastChild = child.get();
- }
- child->setParent(this);
- child->setPreviousSibling(prev.get());
- child->setNextSibling(next);
- allowEventDispatch();
-
- // Dispatch the mutation events
- dispatchChildInsertionEvents(child.get());
-
- // Add child to the rendering tree
- if (attached() && !child->attached() && child->parent() == this) {
- if (shouldLazyAttach)
- child->lazyAttach();
- else
- child->attach();
- }
-
- prev = child;
- child = nextChild.release();
- }
-
- if (childCountDelta)
- childrenChanged(false, prev.get(), next.get(), childCountDelta);
- dispatchSubtreeModifiedEvent();
- return true;
-}
-
-void ContainerNode::willRemove()
-{
- for (Node *n = m_firstChild; n != 0; n = n->nextSibling())
- n->willRemove();
- Node::willRemove();
-}
-
-static ExceptionCode willRemoveChild(Node *child)
-{
- ExceptionCode ec = 0;
-
- // fire removed from document mutation events.
- dispatchChildRemovalEvents(child);
- if (ec)
- return ec;
-
- if (child->attached())
- child->willRemove();
-
- return 0;
-}
-
-bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
-{
- // Check that this node is not "floating".
- // If it is, it can be deleted as a side effect of sending mutation events.
- ASSERT(refCount() || parent());
-
- ec = 0;
-
- // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
- if (isReadOnlyNode()) {
- ec = NO_MODIFICATION_ALLOWED_ERR;
- return false;
- }
-
- // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
- if (!oldChild || oldChild->parentNode() != this) {
- ec = NOT_FOUND_ERR;
- return false;
- }
-
- RefPtr<Node> child = oldChild;
-
- ec = willRemoveChild(child.get());
- if (ec)
- return false;
-
- // Mutation events might have moved this child into a different parent.
- if (child->parentNode() != this) {
- ec = NOT_FOUND_ERR;
- return false;
- }
-
- document()->removeFocusedNodeOfSubtree(child.get());
-
-#if 1
- // added at webkit.org trunk r55783
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2010 ACCESS CO., LTD. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "ContainerNode.h"
+
+#include "BeforeLoadEvent.h"
+#include "Cache.h"
+#include "ContainerNodeAlgorithms.h"
+#include "DeleteButtonController.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
+#include "FloatRect.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "InlineTextBox.h"
+#include "MutationEvent.h"
+#include "Page.h"
+#include "RenderTheme.h"
+#include "RootInlineBox.h"
+#include "loader.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+static void dispatchChildInsertionEvents(Node*);
+static void dispatchChildRemovalEvents(Node*);
+
+typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
+typedef Vector<RefPtr<Node>, 1> NodeVector;
+static NodeCallbackQueue* s_postAttachCallbackQueue;
+
+static size_t s_attachDepth;
+static bool s_shouldReEnableMemoryCacheCallsAfterAttach;
+
+static void collectTargetNodes(Node* node, NodeVector& nodes)
+{
+ if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
+ nodes.append(node);
+ return;
+ }
+
+ for (Node* child = node->firstChild(); child; child = child->nextSibling())
+ nodes.append(child);
+}
+
+void ContainerNode::removeAllChildren()
+{
+ removeAllChildrenInContainer<Node, ContainerNode>(this);
+}
+
+ContainerNode::~ContainerNode()
+{
+ removeAllChildren();
+}
+
+static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode* newParent, Node* newChild, ExceptionCode& ec)
+{
+ ASSERT(!newParent->isReadOnlyNode());
+ if (newChild->contains(newParent)) {
+ ec = HIERARCHY_REQUEST_ERR;
+ return false;
+ }
+
+ return true;
+}
+
+bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
+{
+ // Check that this node is not "floating".
+ // If it is, it can be deleted as a side effect of sending mutation events.
+ ASSERT(refCount() || parent());
+
+ RefPtr<Node> protect(this);
+
+ ec = 0;
+
+ // insertBefore(node, 0) is equivalent to appendChild(node)
+ if (!refChild)
+ return appendChild(newChild, ec, shouldLazyAttach);
+
+ // Make sure adding the new child is OK.
+ checkAddChild(newChild.get(), ec);
+ if (ec)
+ return false;
+
+ // NOT_FOUND_ERR: Raised if refChild is not a child of this node
+ if (refChild->parentNode() != this) {
+ ec = NOT_FOUND_ERR;
+ return false;
+ }
+
+ NodeVector targets;
+ collectTargetNodes(newChild.get(), targets);
+ if (targets.isEmpty())
+ return true;
+
+ // We need this extra check because collectTargetNodes() can fire mutation events.
+ if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), ec))
+ return false;
+
+ // Now actually add the child(ren)
+ if (refChild->previousSibling() == newChild || refChild == newChild) // nothing to do
+ return true;
+
+ RefPtr<Node> next = refChild;
+ RefPtr<Node> refChildPreviousSibling = refChild->previousSibling();
+
+ for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
+ Node* child = it->get();
+
+ // If child is already present in the tree, first remove it from the old location.
+ if (Node* oldParent = child->parentNode())
+ oldParent->removeChild(child, ec);
+ if (ec)
+ return false;
+
+ // We need this extra check because removeChild() can fire mutation events.
+ if (!checkAcceptChildGuaranteedNodeTypes(this, child, ec))
+ return false;
+
+ // FIXME: After sending the mutation events, "this" could be destroyed.
+ // We can prevent that by doing a "ref", but first we have to make sure
+ // that no callers call with ref count == 0 and parent = 0 (as of this
+ // writing, there are definitely callers who call that way).
+
+ // Due to arbitrary code running in response to a DOM mutation event it's
+ // possible that "next" is no longer a child of "this".
+ // It's also possible that "child" has been inserted elsewhere.
+ // In either of those cases, we'll just stop.
+ if (next->parentNode() != this)
+ break;
+ if (child->parentNode())
+ break;
+
+ ASSERT(!child->nextSibling());
+ ASSERT(!child->previousSibling());
+
+ // Add child before "next".
+ forbidEventDispatch();
+ Node* prev = next->previousSibling();
+ ASSERT(m_lastChild != prev);
+ next->setPreviousSibling(child);
+ if (prev) {
+ ASSERT(m_firstChild != next);
+ ASSERT(prev->nextSibling() == next);
+ prev->setNextSibling(child);
+ } else {
+ ASSERT(m_firstChild == next);
+ m_firstChild = child;
+ }
+ child->setParent(this);
+ child->setPreviousSibling(prev);
+ child->setNextSibling(next.get());
+ allowEventDispatch();
+
+ // Dispatch the mutation events.
+ childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
+ dispatchChildInsertionEvents(child);
+
+ // Add child to the rendering tree.
+ if (attached() && !child->attached() && child->parent() == this) {
+ if (shouldLazyAttach)
+ child->lazyAttach();
+ else
+ child->attach();
+ }
+ }
+
+ dispatchSubtreeModifiedEvent();
+ return true;
+}
+
+bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
+{
+ // Check that this node is not "floating".
+ // If it is, it can be deleted as a side effect of sending mutation events.
+ ASSERT(refCount() || parent());
+
+ RefPtr<Node> protect(this);
+
+ ec = 0;
+
+ if (oldChild == newChild) // nothing to do
+ return true;
+
+ // Make sure replacing the old child with the new is ok
+ checkReplaceChild(newChild.get(), oldChild, ec);
+ if (ec)
+ return false;
+
+ // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
+ if (!oldChild || oldChild->parentNode() != this) {
+ ec = NOT_FOUND_ERR;
+ return false;
+ }
+
+ RefPtr<Node> prev = oldChild->previousSibling();
+ RefPtr<Node> next = oldChild->nextSibling();
+
+ // Remove the node we're replacing
+ RefPtr<Node> removedChild = oldChild;
+ removeChild(oldChild, ec);
+ if (ec)
+ return false;
+
+ // Does this one more time because removeChild() fires a MutationEvent.
+ checkReplaceChild(newChild.get(), oldChild, ec);
+ if (ec)
+ return false;
+
+ // FIXME: After sending the mutation events, "this" could be destroyed.
+ // We can prevent that by doing a "ref", but first we have to make sure
+ // that no callers call with ref count == 0 and parent = 0 (as of this
+ // writing, there are definitely callers who call that way).
+
+ bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE;
+
+ // Add the new child(ren)
+ int childCountDelta = 0;
+ RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
+ while (child) {
+ // If the new child is already in the right place, we're done.
+ if (prev && (prev == child || prev == child->previousSibling()))
+ break;
+
+ // For a fragment we have more children to do.
+ RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
+
+ // Remove child from its old position.
+ if (Node* oldParent = child->parentNode())
+ oldParent->removeChild(child.get(), ec);
+ if (ec)
+ return false;
+
+ // Does this one more time because removeChild() fires a MutationEvent.
+ checkReplaceChild(child.get(), oldChild, ec);
+ if (ec)
+ return false;
+
+ // Due to arbitrary code running in response to a DOM mutation event it's
+ // possible that "prev" is no longer a child of "this".
+ // It's also possible that "child" has been inserted elsewhere.
+ // In either of those cases, we'll just stop.
+ if (prev && prev->parentNode() != this)
+ break;
+ if (child->parentNode())
+ break;
+
+ childCountDelta++;
+
+ ASSERT(!child->nextSibling());
+ ASSERT(!child->previousSibling());
+
+ // Add child after "prev".
+ forbidEventDispatch();
+ Node* next;
+ if (prev) {
+ next = prev->nextSibling();
+ ASSERT(m_firstChild != next);
+ prev->setNextSibling(child.get());
+ } else {
+ next = m_firstChild;
+ m_firstChild = child.get();
+ }
+ if (next) {
+ ASSERT(m_lastChild != prev);
+ ASSERT(next->previousSibling() == prev);
+ next->setPreviousSibling(child.get());
+ } else {
+ ASSERT(m_lastChild == prev);
+ m_lastChild = child.get();
+ }
+ child->setParent(this);
+ child->setPreviousSibling(prev.get());
+ child->setNextSibling(next);
+ allowEventDispatch();
+
+ checkReplaceChild(child.get(), oldChild, ec);
+ if (ec)
+ return false;
+
+ // Dispatch the mutation events
+ dispatchChildInsertionEvents(child.get());
+
+ // Add child to the rendering tree
+ if (attached() && !child->attached() && child->parent() == this) {
+ if (shouldLazyAttach)
+ child->lazyAttach();
+ else
+ child->attach();
+ }
+
+ prev = child;
+ child = nextChild.release();
+ }
+
+ if (childCountDelta)
+ childrenChanged(false, prev.get(), next.get(), childCountDelta);
+ dispatchSubtreeModifiedEvent();
+ return true;
+}
+
+void ContainerNode::willRemove()
+{
+ RefPtr<Node> protect(this);
+
+ for (Node *n = m_firstChild; n != 0; n = n->nextSibling())
+ n->willRemove();
+ Node::willRemove();
+}
+
+static ExceptionCode willRemoveChild(Node *child)
+{
+ ExceptionCode ec = 0;
+
+ // fire removed from document mutation events.
+ dispatchChildRemovalEvents(child);
+ if (ec)
+ return ec;
+
+ if (child->attached())
+ child->willRemove();
+
+ return 0;
+}
+
+bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
+{
+ // Check that this node is not "floating".
+ // If it is, it can be deleted as a side effect of sending mutation events.
+ ASSERT(refCount() || parent());
+
+ RefPtr<Node> protect(this);
+
+ ec = 0;
+
+ // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ if (isReadOnlyNode()) {
+ ec = NO_MODIFICATION_ALLOWED_ERR;
+ return false;
+ }
+
+ // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
+ if (!oldChild || oldChild->parentNode() != this) {
+ ec = NOT_FOUND_ERR;
+ return false;
+ }
+
+ RefPtr<Node> child = oldChild;
+
+ ec = willRemoveChild(child.get());
+ if (ec)
+ return false;
+
+ // Mutation events might have moved this child into a different parent.
+ if (child->parentNode() != this) {
+ ec = NOT_FOUND_ERR;
+ return false;
+ }
+
+ document()->removeFocusedNodeOfSubtree(child.get());
+
+#if 1
+ // added at webkit.org trunk r55783
// Events fired when blurring currently focused node might have moved this
// child into a different parent.
if (child->parentNode() != this) {
ec = NOT_FOUND_ERR;
return false;
- }
-#endif
-
- // FIXME: After sending the mutation events, "this" could be destroyed.
- // We can prevent that by doing a "ref", but first we have to make sure
- // that no callers call with ref count == 0 and parent = 0 (as of this
- // writing, there are definitely callers who call that way).
-
- forbidEventDispatch();
-
- // Remove from rendering tree
- if (child->attached())
- child->detach();
-
- // Remove the child
- Node *prev, *next;
- prev = child->previousSibling();
- next = child->nextSibling();
-
- if (next)
- next->setPreviousSibling(prev);
- if (prev)
- prev->setNextSibling(next);
- if (m_firstChild == child)
- m_firstChild = next;
- if (m_lastChild == child)
- m_lastChild = prev;
-
- child->setPreviousSibling(0);
- child->setNextSibling(0);
- child->setParent(0);
-
- allowEventDispatch();
-
- // Dispatch post-removal mutation events
- childrenChanged(false, prev, next, -1);
- dispatchSubtreeModifiedEvent();
-
- if (child->inDocument())
- child->removedFromDocument();
- else
- child->removedFromTree(true);
-
- return child;
-}
-
-// this differs from other remove functions because it forcibly removes all the children,
-// regardless of read-only status or event exceptions, e.g.
-bool ContainerNode::removeChildren()
-{
- if (!m_firstChild)
- return false;
-
- // The container node can be removed from event handlers.
- RefPtr<Node> protect(this);
-
- // Do any prep work needed before actually starting to detach
- // and remove... e.g. stop loading frames, fire unload events.
- // FIXME: Adding new children from event handlers can cause an infinite loop here.
- for (RefPtr<Node> n = m_firstChild; n; n = n->nextSibling())
- willRemoveChild(n.get());
-
- // exclude this node when looking for removed focusedNode since only children will be removed
- document()->removeFocusedNodeOfSubtree(this, true);
-
- forbidEventDispatch();
-#if 1
- // modified at webkit.org trunk r55462
- Vector<RefPtr<Node> > removedChildren;
-#else
- int childCountDelta = 0;
-#endif
- while (RefPtr<Node> n = m_firstChild) {
-#if 0
- // removed at webkit.org trunk r55462
- childCountDelta--;
-#endif
- Node* next = n->nextSibling();
-
- // Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744).
-#if 1
- // added at webkit.org trunk r55462
+ }
+#endif
+
+ // FIXME: After sending the mutation events, "this" could be destroyed.
+ // We can prevent that by doing a "ref", but first we have to make sure
+ // that no callers call with ref count == 0 and parent = 0 (as of this
+ // writing, there are definitely callers who call that way).
+
+ forbidEventDispatch();
+
+ // Remove from rendering tree
+ if (child->attached())
+ child->detach();
+
+ // Remove the child
+ Node *prev, *next;
+ prev = child->previousSibling();
+ next = child->nextSibling();
+
+ if (next)
+ next->setPreviousSibling(prev);
+ if (prev)
+ prev->setNextSibling(next);
+ if (m_firstChild == child)
+ m_firstChild = next;
+ if (m_lastChild == child)
+ m_lastChild = prev;
+
+ child->setPreviousSibling(0);
+ child->setNextSibling(0);
+ child->setParent(0);
+
+ allowEventDispatch();
+
+ // Dispatch post-removal mutation events
+ childrenChanged(false, prev, next, -1);
+ dispatchSubtreeModifiedEvent();
+
+ if (child->inDocument())
+ child->removedFromDocument();
+ else
+ child->removedFromTree(true);
+
+ return child;
+}
+
+// this differs from other remove functions because it forcibly removes all the children,
+// regardless of read-only status or event exceptions, e.g.
+bool ContainerNode::removeChildren()
+{
+ if (!m_firstChild)
+ return false;
+
+ // The container node can be removed from event handlers.
+ RefPtr<Node> protect(this);
+
+ // Do any prep work needed before actually starting to detach
+ // and remove... e.g. stop loading frames, fire unload events.
+ NodeVector children;
+ for (Node* n = m_firstChild; n; n = n->nextSibling())
+ children.append(n);
+
+ for (NodeVector::const_iterator it = children.begin(); it != children.end(); ++it) {
+ Node* child = it->get();
+ willRemoveChild(child);
+ }
+
+ // exclude this node when looking for removed focusedNode since only children will be removed
+ document()->removeFocusedNodeOfSubtree(this, true);
+
+ forbidEventDispatch();
+#if 1
+ // modified at webkit.org trunk r55462
+ Vector<RefPtr<Node> > removedChildren;
+#else
+ int childCountDelta = 0;
+#endif
+ while (RefPtr<Node> n = m_firstChild) {
+#if 0
+ // removed at webkit.org trunk r55462
+ childCountDelta--;
+#endif
+ Node* next = n->nextSibling();
+
+ // Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744).
+#if 1
+ // added at webkit.org trunk r55462
// removeChild() does this after calling detach(). There is no explanation for
- // this discrepancy between removeChild() and its optimized version removeChildren().
-#endif
- n->setPreviousSibling(0);
- n->setNextSibling(0);
- n->setParent(0);
-
- m_firstChild = next;
- if (n == m_lastChild)
- m_lastChild = 0;
-
- if (n->attached())
- n->detach();
-
-#if 1
- // modified at webkit.org trunk r55462
- removedChildren.append(n.release());
-#else
- if (n->inDocument())
- n->removedFromDocument();
-#endif
- }
- allowEventDispatch();
-
-#if 1
- // added at webkit.org trunk r55462
- size_t removedChildrenCount = removedChildren.size();
-#endif
-
- // Dispatch a single post-removal mutation event denoting a modified subtree.
-#if 1
- // modified at webkit.org trunk r55462 and r55465
- childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount));
-#else
- childrenChanged(false, 0, 0, childCountDelta);
-#endif
- dispatchSubtreeModifiedEvent();
-
-#if 1
- // added at webkit.org trunk r55462
+ // this discrepancy between removeChild() and its optimized version removeChildren().
+#endif
+ n->setPreviousSibling(0);
+ n->setNextSibling(0);
+ n->setParent(0);
+
+ m_firstChild = next;
+ if (n == m_lastChild)
+ m_lastChild = 0;
+
+ if (n->attached())
+ n->detach();
+
+#if 1
+ // modified at webkit.org trunk r55462
+ removedChildren.append(n.release());
+#else
+ if (n->inDocument())
+ n->removedFromDocument();
+#endif
+ }
+ allowEventDispatch();
+
+#if 1
+ // added at webkit.org trunk r55462
+ size_t removedChildrenCount = removedChildren.size();
+#endif
+
+ // Dispatch a single post-removal mutation event denoting a modified subtree.
+#if 1
+ // modified at webkit.org trunk r55462 and r55465
+ childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount));
+#else
+ childrenChanged(false, 0, 0, childCountDelta);
+#endif
+ dispatchSubtreeModifiedEvent();
+
+#if 1
+ // added at webkit.org trunk r55462
for (size_t i = 0; i < removedChildrenCount; ++i) {
Node* removedChild = removedChildren[i].get();
if (removedChild->inDocument())
@@ -469,520 +523,529 @@ bool ContainerNode::removeChildren()
// removeChild() calls removedFromTree(true) if the child was not in the
// document. There is no explanation for this discrepancy between removeChild()
// and its optimized version removeChildren().
- }
-#endif
-
- return true;
-}
-
-bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
-{
- // Check that this node is not "floating".
- // If it is, it can be deleted as a side effect of sending mutation events.
- ASSERT(refCount() || parent());
-
- ec = 0;
-
- // Make sure adding the new child is ok
- checkAddChild(newChild.get(), ec);
- if (ec)
- return 0;
-
- if (newChild == m_lastChild) // nothing to do
- return newChild;
-
- bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE;
-
- // If newChild is a DocumentFragment with no children.... there's nothing to do.
- // Just return the document fragment
- if (isFragment && !newChild->firstChild())
- return true;
-
- // Now actually add the child(ren)
- RefPtr<Node> prev = lastChild();
- RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
- while (child) {
- // For a fragment we have more children to do.
- RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
-
- // If child is already present in the tree, first remove it
- if (Node* oldParent = child->parentNode()) {
- oldParent->removeChild(child.get(), ec);
- if (ec)
- return 0;
-
- // If the child has a parent again, just stop what we're doing, because
- // that means someone is doing something with DOM mutation -- can't re-parent
- // a child that already has a parent.
- if (child->parentNode())
- break;
- }
-
- // Append child to the end of the list
- forbidEventDispatch();
- child->setParent(this);
- if (m_lastChild) {
- child->setPreviousSibling(m_lastChild);
- m_lastChild->setNextSibling(child.get());
- } else
- m_firstChild = child.get();
- m_lastChild = child.get();
- allowEventDispatch();
-
- // Dispatch the mutation events
- childrenChanged(false, prev.get(), 0, 1);
- dispatchChildInsertionEvents(child.get());
-
- // Add child to the rendering tree
- if (attached() && !child->attached() && child->parent() == this) {
- if (shouldLazyAttach)
- child->lazyAttach();
- else
- child->attach();
- }
-
- child = nextChild.release();
- }
-
- dispatchSubtreeModifiedEvent();
- return true;
-}
-
-ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild)
-{
- ASSERT(newChild);
- // This function is only used during parsing.
- // It does not send any DOM mutation events.
-
- // Check for consistency with DTD, but only when parsing HTML.
- if (document()->isHTMLDocument() && !childAllowed(newChild.get()))
- return 0;
-
- forbidEventDispatch();
- Node* last = m_lastChild;
- appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
- allowEventDispatch();
-
- document()->incDOMTreeVersion();
- if (inDocument())
- newChild->insertedIntoDocument();
- childrenChanged(true, last, 0, 1);
-
- if (newChild->isElementNode())
- return static_cast<ContainerNode*>(newChild.get());
- return this;
-}
-
-void ContainerNode::suspendPostAttachCallbacks()
-{
- if (!s_attachDepth) {
- ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);
- if (Page* page = document()->page()) {
- if (page->areMemoryCacheClientCallsEnabled()) {
- page->setMemoryCacheClientCallsEnabled(false);
- s_shouldReEnableMemoryCacheCallsAfterAttach = true;
- }
- }
- cache()->loader()->suspendPendingRequests();
- }
- ++s_attachDepth;
-}
-
-void ContainerNode::resumePostAttachCallbacks()
-{
- if (s_attachDepth == 1) {
- if (s_postAttachCallbackQueue)
- dispatchPostAttachCallbacks();
- if (s_shouldReEnableMemoryCacheCallsAfterAttach) {
- s_shouldReEnableMemoryCacheCallsAfterAttach = false;
- if (Page* page = document()->page())
- page->setMemoryCacheClientCallsEnabled(true);
- }
- cache()->loader()->resumePendingRequests();
- }
- --s_attachDepth;
-}
-
-void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
-{
- if (!s_postAttachCallbackQueue)
- s_postAttachCallbackQueue = new NodeCallbackQueue;
-
- s_postAttachCallbackQueue->append(std::pair<NodeCallback, RefPtr<Node> >(callback, node));
-}
-
-void ContainerNode::dispatchPostAttachCallbacks()
-{
- // We recalculate size() each time through the loop because a callback
- // can add more callbacks to the end of the queue.
- for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
- std::pair<NodeCallback, RefPtr<Node> >& pair = (*s_postAttachCallbackQueue)[i];
- NodeCallback callback = pair.first;
- Node* node = pair.second.get();
-
- callback(node);
- }
- s_postAttachCallbackQueue->clear();
-}
-
-void ContainerNode::attach()
-{
- for (Node* child = m_firstChild; child; child = child->nextSibling())
- child->attach();
- Node::attach();
-}
-
-void ContainerNode::detach()
-{
- for (Node* child = m_firstChild; child; child = child->nextSibling())
- child->detach();
- setChildNeedsStyleRecalc(false);
- Node::detach();
-}
-
-void ContainerNode::insertedIntoDocument()
-{
- Node::insertedIntoDocument();
- insertedIntoTree(false);
- for (Node* child = m_firstChild; child; child = child->nextSibling())
- child->insertedIntoDocument();
-}
-
-void ContainerNode::removedFromDocument()
-{
- Node::removedFromDocument();
- if (document()->cssTarget() == this)
- document()->setCSSTarget(0);
- setInDocument(false);
- removedFromTree(false);
- for (Node* child = m_firstChild; child; child = child->nextSibling())
- child->removedFromDocument();
-}
-
-void ContainerNode::insertedIntoTree(bool deep)
-{
- if (!deep)
- return;
- for (Node* child = m_firstChild; child; child = child->nextSibling())
- child->insertedIntoTree(true);
-}
-
-void ContainerNode::removedFromTree(bool deep)
-{
- if (!deep)
- return;
- for (Node* child = m_firstChild; child; child = child->nextSibling())
- child->removedFromTree(true);
-}
-
-void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
-{
- Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser && childCountDelta)
- document()->nodeChildrenChanged(this);
- if (document()->hasNodeListCaches())
- notifyNodeListsChildrenChanged();
-}
-
-void ContainerNode::cloneChildNodes(ContainerNode *clone)
-{
- // disable the delete button so it's elements are not serialized into the markup
- if (document()->frame())
- document()->frame()->editor()->deleteButtonController()->disable();
- ExceptionCode ec = 0;
- for (Node* n = firstChild(); n && !ec; n = n->nextSibling())
- clone->appendChild(n->cloneNode(true), ec);
- if (document()->frame())
- document()->frame()->editor()->deleteButtonController()->enable();
-}
-
-// FIXME: This doesn't work correctly with transforms.
-bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
-{
- if (!renderer())
- return false;
- // What is this code really trying to do?
- RenderObject *o = renderer();
- RenderObject *p = o;
-
- if (!o->isInline() || o->isReplaced()) {
- point = o->localToAbsolute();
- return true;
- }
-
- // find the next text/image child, to get a position
- while (o) {
- p = o;
- if (o->firstChild())
- o = o->firstChild();
- else if (o->nextSibling())
- o = o->nextSibling();
- else {
- RenderObject *next = 0;
- while (!next && o->parent()) {
- o = o->parent();
- next = o->nextSibling();
- }
- o = next;
-
- if (!o)
- break;
- }
- ASSERT(o);
-
- if (!o->isInline() || o->isReplaced()) {
- point = o->localToAbsolute();
- return true;
- }
-
- if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
- // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
- } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
- point = o->container()->localToAbsolute();
- if (o->isText() && toRenderText(o)->firstTextBox()) {
- point.move(toRenderText(o)->linesBoundingBox().x(),
- toRenderText(o)->firstTextBox()->root()->lineTop());
- } else if (o->isBox()) {
- RenderBox* box = toRenderBox(o);
- point.move(box->x(), box->y());
- }
- return true;
- }
- }
-
- // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
- // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling?
- if (!o && document()->view()) {
- point = FloatPoint(0, document()->view()->contentsHeight());
- return true;
- }
- return false;
-}
-
-// FIXME: This doesn't work correctly with transforms.
-bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
-{
- if (!renderer())
- return false;
-
- RenderObject* o = renderer();
- if (!o->isInline() || o->isReplaced()) {
- RenderBox* box = toRenderBox(o);
- point = o->localToAbsolute();
- point.move(box->width(), box->height());
- return true;
- }
-
- // find the last text/image child, to get a position
- while (o) {
- if (o->lastChild())
- o = o->lastChild();
- else if (o->previousSibling())
- o = o->previousSibling();
- else {
- RenderObject* prev = 0;
- while (!prev) {
- o = o->parent();
- if (!o)
- return false;
- prev = o->previousSibling();
- }
- o = prev;
- }
- ASSERT(o);
- if (o->isText() || o->isReplaced()) {
- point = o->container()->localToAbsolute();
- if (o->isText()) {
- RenderText* text = toRenderText(o);
- IntRect linesBox = text->linesBoundingBox();
- point.move(linesBox.x() + linesBox.width(), linesBox.y() + linesBox.height());
- } else {
- RenderBox* box = toRenderBox(o);
- point.move(box->x() + box->width(), box->y() + box->height());
- }
- return true;
- }
- }
- return true;
-}
-
-IntRect ContainerNode::getRect() const
-{
- FloatPoint upperLeft, lowerRight;
- bool foundUpperLeft = getUpperLeftCorner(upperLeft);
- bool foundLowerRight = getLowerRightCorner(lowerRight);
-
- // If we've found one corner, but not the other,
- // then we should just return a point at the corner that we did find.
- if (foundUpperLeft != foundLowerRight) {
- if (foundUpperLeft)
- lowerRight = upperLeft;
- else
- upperLeft = lowerRight;
- }
-
- lowerRight.setX(max(upperLeft.x(), lowerRight.x()));
- lowerRight.setY(max(upperLeft.y(), lowerRight.y()));
-
- return enclosingIntRect(FloatRect(upperLeft, lowerRight - upperLeft));
-}
-
-void ContainerNode::setFocus(bool received)
-{
- if (focused() == received)
- return;
-
- Node::setFocus(received);
-
- // note that we need to recalc the style
- setNeedsStyleRecalc();
-}
-
-void ContainerNode::setActive(bool down, bool pause)
-{
- if (down == active()) return;
-
- Node::setActive(down);
-
- // note that we need to recalc the style
- // FIXME: Move to Element
- if (renderer()) {
- bool reactsToPress = renderer()->style()->affectedByActiveRules();
- if (reactsToPress)
- setNeedsStyleRecalc();
- if (renderer() && renderer()->style()->hasAppearance()) {
- if (renderer()->theme()->stateChanged(renderer(), PressedState))
- reactsToPress = true;
- }
- if (reactsToPress && pause) {
- // The delay here is subtle. It relies on an assumption, namely that the amount of time it takes
- // to repaint the "down" state of the control is about the same time as it would take to repaint the
- // "up" state. Once you assume this, you can just delay for 100ms - that time (assuming that after you
- // leave this method, it will be about that long before the flush of the up state happens again).
-#ifdef HAVE_FUNC_USLEEP
- double startTime = currentTime();
-#endif
-
- // Ensure there are no pending changes
- Document::updateStyleForAllDocuments();
- // Do an immediate repaint.
- if (renderer())
- renderer()->repaint(true);
-
- // FIXME: Find a substitute for usleep for Win32.
- // Better yet, come up with a way of doing this that doesn't use this sort of thing at all.
-#ifdef HAVE_FUNC_USLEEP
- // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)
- double remainingTime = 0.1 - (currentTime() - startTime);
- if (remainingTime > 0)
- usleep(static_cast<useconds_t>(remainingTime * 1000000.0));
-#endif
- }
- }
-}
-
-void ContainerNode::setHovered(bool over)
-{
- if (over == hovered()) return;
-
- Node::setHovered(over);
-
- // note that we need to recalc the style
- // FIXME: Move to Element
- if (renderer()) {
- if (renderer()->style()->affectedByHoverRules())
- setNeedsStyleRecalc();
- if (renderer() && renderer()->style()->hasAppearance())
- renderer()->theme()->stateChanged(renderer(), HoverState);
- }
-}
-
-unsigned ContainerNode::childNodeCount() const
-{
- unsigned count = 0;
- Node *n;
- for (n = firstChild(); n; n = n->nextSibling())
- count++;
- return count;
-}
-
-Node *ContainerNode::childNode(unsigned index) const
-{
- unsigned i;
- Node *n = firstChild();
- for (i = 0; n != 0 && i < index; i++)
- n = n->nextSibling();
- return n;
-}
-
-static void dispatchChildInsertionEvents(Node* child)
-{
- ASSERT(!eventDispatchForbidden());
-
- RefPtr<Node> c = child;
- RefPtr<Document> document = child->document();
-
- if (c->parentNode() && c->parentNode()->inDocument())
- c->insertedIntoDocument();
- else
- c->insertedIntoTree(true);
-
- document->incDOMTreeVersion();
-
- if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
- c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode()));
-
- // dispatch the DOMNodeInsertedIntoDocument event to all descendants
- if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
- for (; c; c = c->traverseNextNode(child))
- c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false));
- }
-}
-
-static void dispatchChildRemovalEvents(Node* child)
-{
- RefPtr<Node> c = child;
- RefPtr<Document> document = child->document();
-
- // update auxiliary doc info (e.g. iterators) to note that node is being removed
- document->nodeWillBeRemoved(child);
-
- document->incDOMTreeVersion();
-
- // dispatch pre-removal mutation events
- if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
- c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
-
- // dispatch the DOMNodeRemovedFromDocument event to all descendants
- if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
- for (; c; c = c->traverseNextNode(child))
- c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false));
- }
-}
-
-bool ContainerNode::dispatchBeforeLoadEvent(const String& sourceURL)
-{
- if (!document()->hasListenerType(Document::BEFORELOAD_LISTENER))
- return true;
-
- RefPtr<ContainerNode> protector(this);
- RefPtr<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL);
- dispatchEvent(beforeLoadEvent.get());
- return !beforeLoadEvent->defaultPrevented();
-}
-
-#if PLATFORM(WKC)
-void ContainerNode::deleteSharedInstance()
-{
- delete s_postAttachCallbackQueue;
-}
-
-void ContainerNode::resetVariables()
-{
- s_postAttachCallbackQueue = 0;
- s_attachDepth = 0;
- s_shouldReEnableMemoryCacheCallsAfterAttach = false;
-}
-#endif
-
-} // namespace WebCore
+ }
+#endif
+
+ return true;
+}
+
+bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
+{
+ RefPtr<ContainerNode> protect(this);
+
+ // Check that this node is not "floating".
+ // If it is, it can be deleted as a side effect of sending mutation events.
+ ASSERT(refCount() || parent());
+
+ ec = 0;
+
+ // Make sure adding the new child is ok
+ checkAddChild(newChild.get(), ec);
+ if (ec)
+ return false;
+
+ if (newChild == m_lastChild) // nothing to do
+ return newChild;
+
+ NodeVector targets;
+ collectTargetNodes(newChild.get(), targets);
+ if (targets.isEmpty())
+ return true;
+
+ // We need this extra check because collectTargetNodes() can fire mutation events.
+ if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), ec))
+ return false;
+
+ // Now actually add the child(ren)
+ RefPtr<Node> prev = lastChild();
+ for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
+ Node* child = it->get();
+
+ // If child is already present in the tree, first remove it
+ if (Node* oldParent = child->parentNode()) {
+ oldParent->removeChild(child, ec);
+ if (ec)
+ return false;
+
+ // We need this extra check because removeChild() can fire mutation events.
+ if (!checkAcceptChildGuaranteedNodeTypes(this, child, ec))
+ return false;
+
+ // If the child has a parent again, just stop what we're doing, because
+ // that means someone is doing something with DOM mutation -- can't re-parent
+ // a child that already has a parent.
+ if (child->parentNode())
+ break;
+ }
+
+ // Append child to the end of the list
+ forbidEventDispatch();
+ child->setParent(this);
+ if (m_lastChild) {
+ child->setPreviousSibling(m_lastChild);
+ m_lastChild->setNextSibling(child);
+ } else
+ m_firstChild = child;
+ m_lastChild = child;
+ allowEventDispatch();
+
+ // Dispatch the mutation events
+ childrenChanged(false, prev.get(), 0, 1);
+ dispatchChildInsertionEvents(child);
+
+ // Add child to the rendering tree
+ if (attached() && !child->attached() && child->parent() == this) {
+ if (shouldLazyAttach)
+ child->lazyAttach();
+ else
+ child->attach();
+ }
+ }
+
+ dispatchSubtreeModifiedEvent();
+ return true;
+}
+
+ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild)
+{
+ ASSERT(newChild);
+ // This function is only used during parsing.
+ // It does not send any DOM mutation events.
+
+ // Check for consistency with DTD, but only when parsing HTML.
+ if (document()->isHTMLDocument() && !childAllowed(newChild.get()))
+ return 0;
+
+ forbidEventDispatch();
+ Node* last = m_lastChild;
+ appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
+ allowEventDispatch();
+
+ document()->incDOMTreeVersion();
+ if (inDocument())
+ newChild->insertedIntoDocument();
+ childrenChanged(true, last, 0, 1);
+
+ if (newChild->isElementNode())
+ return static_cast<ContainerNode*>(newChild.get());
+ return this;
+}
+
+void ContainerNode::suspendPostAttachCallbacks()
+{
+ if (!s_attachDepth) {
+ ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);
+ if (Page* page = document()->page()) {
+ if (page->areMemoryCacheClientCallsEnabled()) {
+ page->setMemoryCacheClientCallsEnabled(false);
+ s_shouldReEnableMemoryCacheCallsAfterAttach = true;
+ }
+ }
+ cache()->loader()->suspendPendingRequests();
+ }
+ ++s_attachDepth;
+}
+
+void ContainerNode::resumePostAttachCallbacks()
+{
+ if (s_attachDepth == 1) {
+ if (s_postAttachCallbackQueue)
+ dispatchPostAttachCallbacks();
+ if (s_shouldReEnableMemoryCacheCallsAfterAttach) {
+ s_shouldReEnableMemoryCacheCallsAfterAttach = false;
+ if (Page* page = document()->page())
+ page->setMemoryCacheClientCallsEnabled(true);
+ }
+ cache()->loader()->resumePendingRequests();
+ }
+ --s_attachDepth;
+}
+
+void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
+{
+ if (!s_postAttachCallbackQueue)
+ s_postAttachCallbackQueue = new NodeCallbackQueue;
+
+ s_postAttachCallbackQueue->append(std::pair<NodeCallback, RefPtr<Node> >(callback, node));
+}
+
+void ContainerNode::dispatchPostAttachCallbacks()
+{
+ // We recalculate size() each time through the loop because a callback
+ // can add more callbacks to the end of the queue.
+ for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
+ std::pair<NodeCallback, RefPtr<Node> >& pair = (*s_postAttachCallbackQueue)[i];
+ NodeCallback callback = pair.first;
+ Node* node = pair.second.get();
+
+ callback(node);
+ }
+ s_postAttachCallbackQueue->clear();
+}
+
+void ContainerNode::attach()
+{
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->attach();
+ Node::attach();
+}
+
+void ContainerNode::detach()
+{
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->detach();
+ setChildNeedsStyleRecalc(false);
+ Node::detach();
+}
+
+void ContainerNode::insertedIntoDocument()
+{
+ RefPtr<Node> protect(this);
+
+ Node::insertedIntoDocument();
+ insertedIntoTree(false);
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->insertedIntoDocument();
+}
+
+void ContainerNode::removedFromDocument()
+{
+ Node::removedFromDocument();
+ if (document()->cssTarget() == this)
+ document()->setCSSTarget(0);
+ setInDocument(false);
+ removedFromTree(false);
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->removedFromDocument();
+}
+
+void ContainerNode::insertedIntoTree(bool deep)
+{
+#if PLATFORM(WKC)
+ CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT);
+#endif
+ if (!deep)
+ return;
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->insertedIntoTree(true);
+}
+
+void ContainerNode::removedFromTree(bool deep)
+{
+ if (!deep)
+ return;
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->removedFromTree(true);
+}
+
+void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+ if (!changedByParser && childCountDelta)
+ document()->nodeChildrenChanged(this);
+ if (document()->hasNodeListCaches())
+ notifyNodeListsChildrenChanged();
+}
+
+void ContainerNode::cloneChildNodes(ContainerNode *clone)
+{
+ // disable the delete button so it's elements are not serialized into the markup
+ if (document()->frame())
+ document()->frame()->editor()->deleteButtonController()->disable();
+ ExceptionCode ec = 0;
+ for (Node* n = firstChild(); n && !ec; n = n->nextSibling())
+ clone->appendChild(n->cloneNode(true), ec);
+ if (document()->frame())
+ document()->frame()->editor()->deleteButtonController()->enable();
+}
+
+// FIXME: This doesn't work correctly with transforms.
+bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
+{
+ if (!renderer())
+ return false;
+ // What is this code really trying to do?
+ RenderObject *o = renderer();
+ RenderObject *p = o;
+
+ if (!o->isInline() || o->isReplaced()) {
+ point = o->localToAbsolute();
+ return true;
+ }
+
+ // find the next text/image child, to get a position
+ while (o) {
+ p = o;
+ if (o->firstChild())
+ o = o->firstChild();
+ else if (o->nextSibling())
+ o = o->nextSibling();
+ else {
+ RenderObject *next = 0;
+ while (!next && o->parent()) {
+ o = o->parent();
+ next = o->nextSibling();
+ }
+ o = next;
+
+ if (!o)
+ break;
+ }
+ ASSERT(o);
+
+ if (!o->isInline() || o->isReplaced()) {
+ point = o->localToAbsolute();
+ return true;
+ }
+
+ if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
+ // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
+ } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
+ point = o->container()->localToAbsolute();
+ if (o->isText() && toRenderText(o)->firstTextBox()) {
+ point.move(toRenderText(o)->linesBoundingBox().x(),
+ toRenderText(o)->firstTextBox()->root()->lineTop());
+ } else if (o->isBox()) {
+ RenderBox* box = toRenderBox(o);
+ point.move(box->x(), box->y());
+ }
+ return true;
+ }
+ }
+
+ // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
+ // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling?
+ if (!o && document()->view()) {
+ point = FloatPoint(0, document()->view()->contentsHeight());
+ return true;
+ }
+ return false;
+}
+
+// FIXME: This doesn't work correctly with transforms.
+bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
+{
+ if (!renderer())
+ return false;
+
+ RenderObject* o = renderer();
+ if (!o->isInline() || o->isReplaced()) {
+ RenderBox* box = toRenderBox(o);
+ point = o->localToAbsolute();
+ point.move(box->width(), box->height());
+ return true;
+ }
+
+ // find the last text/image child, to get a position
+ while (o) {
+ if (o->lastChild())
+ o = o->lastChild();
+ else if (o->previousSibling())
+ o = o->previousSibling();
+ else {
+ RenderObject* prev = 0;
+ while (!prev) {
+ o = o->parent();
+ if (!o)
+ return false;
+ prev = o->previousSibling();
+ }
+ o = prev;
+ }
+ ASSERT(o);
+ if (o->isText() || o->isReplaced()) {
+ point = o->container()->localToAbsolute();
+ if (o->isText()) {
+ RenderText* text = toRenderText(o);
+ IntRect linesBox = text->linesBoundingBox();
+ point.move(linesBox.x() + linesBox.width(), linesBox.y() + linesBox.height());
+ } else {
+ RenderBox* box = toRenderBox(o);
+ point.move(box->x() + box->width(), box->y() + box->height());
+ }
+ return true;
+ }
+ }
+ return true;
+}
+
+IntRect ContainerNode::getRect() const
+{
+ FloatPoint upperLeft, lowerRight;
+ bool foundUpperLeft = getUpperLeftCorner(upperLeft);
+ bool foundLowerRight = getLowerRightCorner(lowerRight);
+
+ // If we've found one corner, but not the other,
+ // then we should just return a point at the corner that we did find.
+ if (foundUpperLeft != foundLowerRight) {
+ if (foundUpperLeft)
+ lowerRight = upperLeft;
+ else
+ upperLeft = lowerRight;
+ }
+
+ lowerRight.setX(max(upperLeft.x(), lowerRight.x()));
+ lowerRight.setY(max(upperLeft.y(), lowerRight.y()));
+
+ return enclosingIntRect(FloatRect(upperLeft, lowerRight - upperLeft));
+}
+
+void ContainerNode::setFocus(bool received)
+{
+ if (focused() == received)
+ return;
+
+ Node::setFocus(received);
+
+ // note that we need to recalc the style
+ setNeedsStyleRecalc();
+}
+
+void ContainerNode::setActive(bool down, bool pause)
+{
+ if (down == active()) return;
+
+ Node::setActive(down);
+
+ // note that we need to recalc the style
+ // FIXME: Move to Element
+ if (renderer()) {
+ bool reactsToPress = renderer()->style()->affectedByActiveRules();
+ if (reactsToPress)
+ setNeedsStyleRecalc();
+ if (renderer() && renderer()->style()->hasAppearance()) {
+ if (renderer()->theme()->stateChanged(renderer(), PressedState))
+ reactsToPress = true;
+ }
+ if (reactsToPress && pause) {
+ // The delay here is subtle. It relies on an assumption, namely that the amount of time it takes
+ // to repaint the "down" state of the control is about the same time as it would take to repaint the
+ // "up" state. Once you assume this, you can just delay for 100ms - that time (assuming that after you
+ // leave this method, it will be about that long before the flush of the up state happens again).
+#ifdef HAVE_FUNC_USLEEP
+ double startTime = currentTime();
+#endif
+
+ // Ensure there are no pending changes
+ Document::updateStyleForAllDocuments();
+ // Do an immediate repaint.
+ if (renderer())
+ renderer()->repaint(true);
+
+ // FIXME: Find a substitute for usleep for Win32.
+ // Better yet, come up with a way of doing this that doesn't use this sort of thing at all.
+#ifdef HAVE_FUNC_USLEEP
+ // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)
+ double remainingTime = 0.1 - (currentTime() - startTime);
+ if (remainingTime > 0)
+ usleep(static_cast<useconds_t>(remainingTime * 1000000.0));
+#endif
+ }
+ }
+}
+
+void ContainerNode::setHovered(bool over)
+{
+ if (over == hovered()) return;
+
+ Node::setHovered(over);
+
+ // note that we need to recalc the style
+ // FIXME: Move to Element
+ if (renderer()) {
+ if (renderer()->style()->affectedByHoverRules())
+ setNeedsStyleRecalc();
+ if (renderer() && renderer()->style()->hasAppearance())
+ renderer()->theme()->stateChanged(renderer(), HoverState);
+ }
+}
+
+unsigned ContainerNode::childNodeCount() const
+{
+ unsigned count = 0;
+ Node *n;
+ for (n = firstChild(); n; n = n->nextSibling())
+ count++;
+ return count;
+}
+
+Node *ContainerNode::childNode(unsigned index) const
+{
+ unsigned i;
+ Node *n = firstChild();
+ for (i = 0; n != 0 && i < index; i++)
+ n = n->nextSibling();
+ return n;
+}
+
+static void dispatchChildInsertionEvents(Node* child)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ RefPtr<Node> c = child;
+ RefPtr<Document> document = child->document();
+
+ if (c->parentNode() && c->parentNode()->inDocument())
+ c->insertedIntoDocument();
+ else
+ c->insertedIntoTree(true);
+
+ document->incDOMTreeVersion();
+
+ if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode()));
+
+ // dispatch the DOMNodeInsertedIntoDocument event to all descendants
+ if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
+ for (; c; c = c->traverseNextNode(child))
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false));
+ }
+}
+
+static void dispatchChildRemovalEvents(Node* child)
+{
+ RefPtr<Node> c = child;
+ RefPtr<Document> document = child->document();
+
+ // update auxiliary doc info (e.g. iterators) to note that node is being removed
+ document->nodeWillBeRemoved(child);
+
+ document->incDOMTreeVersion();
+
+ // dispatch pre-removal mutation events
+ if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
+
+ // dispatch the DOMNodeRemovedFromDocument event to all descendants
+ if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
+ for (; c; c = c->traverseNextNode(child))
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false));
+ }
+}
+
+bool ContainerNode::dispatchBeforeLoadEvent(const String& sourceURL)
+{
+ if (!document()->hasListenerType(Document::BEFORELOAD_LISTENER))
+ return true;
+
+ RefPtr<ContainerNode> protector(this);
+ RefPtr<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL);
+ dispatchEvent(beforeLoadEvent.get());
+ return !beforeLoadEvent->defaultPrevented();
+}
+
+#if PLATFORM(WKC)
+void ContainerNode::deleteSharedInstance()
+{
+ delete s_postAttachCallbackQueue;
+}
+
+void ContainerNode::resetVariables()
+{
+ s_postAttachCallbackQueue = 0;
+ s_attachDepth = 0;
+ s_shouldReEnableMemoryCacheCallsAfterAttach = false;
+}
+#endif
+
+} // namespace WebCore
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Document.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Document.cpp
index c67cb7f..0b784eb 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Document.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Document.cpp
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2008, 2009 Google Inc. All rights reserved.
* Copyright (c) 2010-2013 ACCESS CO., LTD. All rights reserved.
@@ -204,6 +204,25 @@ using namespace HTMLNames;
// #define INSTRUMENT_LAYOUT_SCHEDULING 1
+static const unsigned cMaxWriteRecursionDepth = 21;
+
+class NestingLevelIncrementer {
+public:
+ explicit NestingLevelIncrementer(unsigned& nestingLevel)
+ : m_nestingLevel(&nestingLevel)
+ {
+ ++(*m_nestingLevel);
+ }
+
+ ~NestingLevelIncrementer()
+ {
+ --(*m_nestingLevel);
+ }
+
+private:
+ unsigned* m_nestingLevel;
+};
+
// This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
// FIXME: For faster machines this value can really be lowered to 200. 250 is adequate, but a little high
// for dual G5s. :)
@@ -364,9 +383,12 @@ Document::Document(Frame* frame, bool isXHTML)
, m_hasOpenDatabases(false)
#endif
, m_usingGeolocation(false)
+ , m_idAttributeName(idAttr)
#if ENABLE(WML)
, m_containsWMLContent(false)
#endif
+ , m_writeRecursionIsTooDeep(false)
+ , m_writeRecursionDepth(0)
{
m_document = this;
@@ -458,12 +480,7 @@ void Document::removedLastRef()
deleteAllValues(m_markers);
m_markers.clear();
-#if PLATFORM(WKC)
- // cf. webkit.org trunk r65692
detachTokenizer();
-#else
- m_tokenizer.clear();
-#endif
m_cssCanvasElements.clear();
@@ -497,13 +514,8 @@ Document::~Document()
forgetAllDOMNodesForDocument(this);
#endif
-#if PLATFORM(WKC)
- // cf. webkit.org trunk r65692
ASSERT(!m_tokenizer);
detachTokenizer();
-#else
- m_tokenizer.clear();
-#endif
m_document = 0;
delete m_styleSelector;
m_docLoader.clear();
@@ -708,8 +720,14 @@ PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo
return createComment(importedNode->nodeValue());
case ELEMENT_NODE: {
Element* oldElement = static_cast<Element*>(importedNode);
- RefPtr<Element> newElement = createElementNS(oldElement->namespaceURI(), oldElement->tagQName().toString(), ec);
-
+ // FIXME: The following check might be unnecessary. Is it possible that
+ // oldElement has mismatched prefix/namespace?
+ if (hasPrefixNamespaceMismatch(oldElement->tagQName())) {
+ ec = NAMESPACE_ERR;
+ return 0;
+ }
+ RefPtr<Element> newElement = createElement(oldElement->tagQName(), ec);
+
if (ec)
return 0;
@@ -1153,8 +1171,10 @@ void Document::removeElementById(const AtomicString& elementId, Element* element
{
if (m_elementsById.get(elementId.impl()) == element)
m_elementsById.remove(elementId.impl());
- else
+ else {
+ ASSERT(m_inRemovedLastRefFunction || m_duplicateIds.contains(elementId.impl()));
m_duplicateIds.remove(elementId.impl());
+ }
}
Element* Document::getElementByAccessKey(const String& key) const
@@ -1209,7 +1229,7 @@ void Document::setTitle(const String& title, Element* titleElement)
m_title = title;
updateTitle();
- if (m_titleSetExplicitly && m_titleElement && m_titleElement->hasTagName(titleTag))
+ if (m_titleSetExplicitly && m_titleElement && m_titleElement->hasTagName(titleTag) && !titleElement)
static_cast<HTMLTitleElement*>(m_titleElement.get())->setText(m_title);
}
@@ -1460,9 +1480,8 @@ void Document::updateLayout()
updateStyleIfNeeded();
- // Only do a layout if changes have occurred that make it necessary.
FrameView* v = view();
- if (v && renderer() && (v->layoutPending() || renderer()->needsLayout()))
+ if (v && v->needsLayout())
v->layout();
}
@@ -1663,10 +1682,10 @@ void Document::setVisuallyOrdered()
renderer()->style()->setVisuallyOrdered(true);
}
-Tokenizer* Document::createTokenizer()
+PassRefPtr<Tokenizer> Document::createTokenizer()
{
// FIXME: this should probably pass the frame instead
- return new XMLTokenizer(this, view());
+ return XMLTokenizer::create(this, view());
}
void Document::open(Document* ownerDocument)
@@ -1694,20 +1713,13 @@ void Document::open(Document* ownerDocument)
m_frame->loader()->didExplicitOpen();
}
-#if PLATFORM(WKC)
-// cf. webkit.org trunk r65692
void Document::detachTokenizer()
{
if (!m_tokenizer)
return;
- bool detached = m_tokenizer->detach();
- if (detached) {
- m_tokenizer.clear();
- } else {
- m_tokenizer.release();
- }
+ m_tokenizer->detach();
+ m_tokenizer.clear();
}
-#endif
void Document::cancelParsing()
{
@@ -1716,12 +1728,7 @@ void Document::cancelParsing()
// the onload handler when closing as a side effect of a cancel-style
// change, such as opening a new document or closing the window while
// still parsing
-#if PLATFORM(WKC)
- // cf. webkit.org trunk r65692
detachTokenizer();
-#else
- m_tokenizer.clear();
-#endif
close();
}
}
@@ -1730,11 +1737,6 @@ void Document::implicitOpen()
{
cancelParsing();
-#if 0
- // cf. webkit.org trunk r65692
- m_tokenizer.clear();
-#endif
-
removeChildren();
m_tokenizer = createTokenizer();
@@ -1834,12 +1836,7 @@ void Document::implicitClose()
// We have to clear the tokenizer, in case someone document.write()s from the
// onLoad event handler, as in Radar 3206524.
-#if PLATFORM(WKC)
- // cf. webkit.org trunk r65692
detachTokenizer();
-#else
- m_tokenizer.clear();
-#endif
// Parser should have picked up all preloads by now
m_docLoader->clearPreloads();
@@ -1982,6 +1979,14 @@ int Document::elapsedTime() const
void Document::write(const SegmentedString& text, Document* ownerDocument)
{
+ NestingLevelIncrementer nestingLevelIncrementer(m_writeRecursionDepth);
+
+ m_writeRecursionIsTooDeep = (m_writeRecursionDepth > 1) && m_writeRecursionIsTooDeep;
+ m_writeRecursionIsTooDeep = (m_writeRecursionDepth > cMaxWriteRecursionDepth) || m_writeRecursionIsTooDeep;
+
+ if (m_writeRecursionIsTooDeep)
+ return;
+
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!ownerElement())
printf("Beginning a document.write at %d\n", elapsedTime());
@@ -2425,10 +2430,12 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
parseDNSPrefetchControlHeader(content);
else if (equalIgnoringCase(equiv, "x-frame-options")) {
- FrameLoader* frameLoader = frame->loader();
- if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) {
- frameLoader->stopAllLoaders();
- frame->redirectScheduler()->scheduleLocationChange(blankURL(), String());
+ if (frame) {
+ FrameLoader* frameLoader = frame->loader();
+ if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) {
+ frameLoader->stopAllLoaders();
+ frame->redirectScheduler()->scheduleLocationChange(blankURL(), String());
+ }
}
}
}
@@ -3022,9 +3029,23 @@ void Document::attachNodeIterator(NodeIterator *ni)
void Document::detachNodeIterator(NodeIterator *ni)
{
+ // The node iterator can be detached without having been attached if its root node didn't have a document
+ // when the iterator was created, but has it now.
m_nodeIterators.remove(ni);
}
+void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
+{
+ HashSet<NodeIterator*> nodeIteratorsList = m_nodeIterators;
+ HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
+ for (HashSet<NodeIterator*>::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
+ if ((*it)->root() == node) {
+ detachNodeIterator(*it);
+ newDocument->attachNodeIterator(*it);
+ }
+ }
+}
+
void Document::nodeChildrenChanged(ContainerNode* container)
{
if (!disableRangeMutation(page())) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Document.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Document.h
index 6468edd..70df114 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Document.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Document.h
@@ -36,6 +36,7 @@
#include "DocumentMarker.h"
#include "ScriptExecutionContext.h"
#include "Timer.h"
+#include "QualifiedName.h"
#if USE(JSC)
#include <runtime/WeakGCMap.h>
#endif
@@ -514,7 +515,7 @@ public:
CSSStyleSheet* elementSheet();
CSSStyleSheet* mappedElementSheet();
- virtual Tokenizer* createTokenizer();
+ virtual PassRefPtr<Tokenizer> createTokenizer();
Tokenizer* tokenizer() { return m_tokenizer.get(); }
bool printing() const { return m_printing; }
@@ -600,6 +601,7 @@ public:
void attachNodeIterator(NodeIterator*);
void detachNodeIterator(NodeIterator*);
+ void moveNodeIteratorsToNewDocument(Node*, Document*);
void attachRange(Range*);
void detachRange(Range*);
@@ -927,6 +929,8 @@ public:
bool processingLoadEvent() const { return m_processingLoadEvent; }
+ const QualifiedName& idAttributeName() const { return m_idAttributeName; }
+
#if ENABLE(DATABASE)
void addOpenDatabase(Database*);
void removeOpenDatabase(Database*);
@@ -960,10 +964,7 @@ protected:
void clearXMLVersion() { m_xmlVersion = String(); }
private:
-#if PLATFORM(WKC)
- // cf. webkit.org trunk r65692
void detachTokenizer();
-#endif
virtual bool isDocument() const { return true; }
virtual void removedLastRef();
@@ -1000,7 +1001,7 @@ private:
Frame* m_frame;
OwnPtr<DocLoader> m_docLoader;
- OwnPtr<Tokenizer> m_tokenizer;
+ RefPtr<Tokenizer> m_tokenizer;
bool m_wellFormed;
// Document URLs.
@@ -1219,9 +1220,13 @@ private:
bool m_usingGeolocation;
+ QualifiedName m_idAttributeName;
+
#if ENABLE(WML)
bool m_containsWMLContent;
#endif
+ bool m_writeRecursionIsTooDeep;
+ unsigned m_writeRecursionDepth;
};
inline bool Document::hasElementWithId(AtomicStringImpl* id) const
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Element.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Element.cpp
index adaba4d..b9db249 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Element.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Element.cpp
@@ -237,6 +237,15 @@ Node::NodeType Element::nodeType() const
return ELEMENT_NODE;
}
+bool Element::isIdAttributeName(const QualifiedName& attributeName) const
+{
+ // FIXME: This check is probably not correct for the case where the document has an id attribute
+ // with a non-null namespace, because it will return false, a false negative, if the prefixes
+ // don't match but the local name and namespace both do. However, since this has been like this
+ // for a while and the code paths may be hot, we'll have to measure performance if we fix it.
+ return attributeName == document()->idAttributeName();
+}
+
const AtomicString& Element::getIDAttribute() const
{
return namedAttrMap ? namedAttrMap->id() : nullAtom;
@@ -598,7 +607,10 @@ void Element::setAttribute(const AtomicString& name, const AtomicString& value,
else if (!old && !value.isNull())
namedAttrMap->addAttribute(createAttribute(QualifiedName(nullAtom, localName, nullAtom), value));
else if (old && !value.isNull()) {
- old->setValue(value);
+ if (Attr* attrNode = old->attr())
+ attrNode->setValue(value);
+ else
+ old->setValue(value);
attributeChanged(old);
}
}
@@ -618,7 +630,10 @@ void Element::setAttribute(const QualifiedName& name, const AtomicString& value,
else if (!old && !value.isNull())
namedAttrMap->addAttribute(createAttribute(name, value));
else if (old) {
- old->setValue(value);
+ if (Attr* attrNode = old->attr())
+ attrNode->setValue(value);
+ else
+ old->setValue(value);
attributeChanged(old);
}
}
@@ -970,6 +985,15 @@ bool Element::childTypeAllowed(NodeType type)
}
}
+static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
+{
+ if (!style)
+ return;
+
+ if (style->affectedByEmpty() && (!style->emptyState() || element->hasChildNodes()))
+ element->setNeedsStyleRecalc();
+}
+
static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
Node* beforeChange, Node* afterChange, int childCountDelta)
{
@@ -1046,14 +1070,15 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
e->setNeedsStyleRecalc();
// :empty selector.
- if (style->affectedByEmpty() && (!style->emptyState() || e->hasChildNodes()))
- e->setNeedsStyleRecalc();
+ checkForEmptyStyleChange(e, style);
}
void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser)
+ if (changedByParser)
+ checkForEmptyStyleChange(this, renderStyle());
+ else
checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Element.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Element.h
index cd9bbc6..9b063bc 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Element.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Element.h
@@ -104,6 +104,7 @@ public:
virtual PassRefPtr<DocumentFragment> createContextualFragment(const String&);
#endif
+ bool isIdAttributeName(const QualifiedName&) const;
const AtomicString& getIDAttribute() const;
bool hasAttribute(const QualifiedName&) const;
const AtomicString& getAttribute(const QualifiedName&) const;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/MessagePort.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/MessagePort.cpp
index 1051920..8e37ad9 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/MessagePort.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/MessagePort.cpp
@@ -20,7 +20,7 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
@@ -72,7 +72,7 @@ void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, Excepti
void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionCode& ec)
{
- if (!m_entangledChannel)
+ if (!isEntangled())
return;
ASSERT(m_scriptExecutionContext);
@@ -118,8 +118,8 @@ void MessagePort::messageAvailable()
void MessagePort::start()
{
- // Do nothing if we've been cloned
- if (!m_entangledChannel)
+ // Do nothing if we've been cloned or closed.
+ if (!isEntangled())
return;
ASSERT(m_scriptExecutionContext);
@@ -133,7 +133,7 @@ void MessagePort::start()
void MessagePort::close()
{
m_closed = true;
- if (!m_entangledChannel)
+ if (!isEntangled())
return;
m_entangledChannel->close();
}
@@ -152,8 +152,9 @@ void MessagePort::entangle(PassOwnPtr<MessagePortChannel> remote)
void MessagePort::contextDestroyed()
{
ASSERT(m_scriptExecutionContext);
- // Must close port before blowing away the cached context, to ensure that we get no more calls to messageAvailable().
- close();
+ // Must be closed before blowing away the cached context, to ensure that we get no more calls to messageAvailable().
+ // ScriptExecutionContext::closeMessagePorts() takes care of that.
+ ASSERT(m_closed);
m_scriptExecutionContext = 0;
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Node.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Node.cpp
index deaad9d..5419f62 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Node.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Node.cpp
@@ -559,8 +559,10 @@ void Node::setDocument(Document* document)
updateDOMNodeDocument(this, m_document, document);
#endif
- if (m_document)
+ if (m_document) {
+ m_document->moveNodeIteratorsToNewDocument(this, document);
m_document->selfOnlyDeref();
+ }
m_document = document;
@@ -994,8 +996,18 @@ void Node::notifyLocalNodeListsChildrenChanged()
void Node::notifyNodeListsChildrenChanged()
{
+#if !PLATFORM(WKC)
for (Node* n = this; n; n = n->parentNode())
n->notifyLocalNodeListsChildrenChanged();
+#else
+ Vector<Node*> visited;
+ for (Node* n = this; n; n = n->parentNode()) {
+ if (visited.find(n)!=notFound)
+ break;
+ n->notifyLocalNodeListsChildrenChanged();
+ visited.append(n);
+ }
+#endif
}
Node *Node::traverseNextNode(const Node *stayWithin) const
@@ -1127,8 +1139,7 @@ bool Node::canReplaceChild(Node* newChild, Node*)
void Node::checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode& ec)
{
- // Perform error checking as required by spec for adding a new child. Used by
- // appendChild(), replaceChild() and insertBefore()
+ // Perform error checking as required by spec for adding a new child. Used by replaceChild().
// Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null
if (!newChild) {
@@ -1183,8 +1194,7 @@ void Node::checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode& ec)
void Node::checkAddChild(Node *newChild, ExceptionCode& ec)
{
- // Perform error checking as required by spec for adding a new child. Used by
- // appendChild(), replaceChild() and insertBefore()
+ // Perform error checking as required by spec for adding a new child. Used by appendChild() and insertBefore().
// Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null
if (!newChild) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/NodeIterator.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/NodeIterator.cpp
index af07f42..ce3103c 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/NodeIterator.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/NodeIterator.cpp
@@ -76,12 +76,16 @@ NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassR
, m_referenceNode(root(), true)
, m_detached(false)
{
- root()->document()->attachNodeIterator(this);
+ // Document type nodes may have a null document. But since they can't have children, there is no need to listen for modifications to these.
+ ASSERT(root()->document() || root()->nodeType() == Node::DOCUMENT_TYPE_NODE);
+ if (Document* ownerDocument = root()->document())
+ ownerDocument->attachNodeIterator(this);
}
NodeIterator::~NodeIterator()
{
- root()->document()->detachNodeIterator(this);
+ if (Document* ownerDocument = root()->document())
+ ownerDocument->detachNodeIterator(this);
}
PassRefPtr<Node> NodeIterator::nextNode(ScriptState* state, ExceptionCode& ec)
@@ -144,7 +148,8 @@ PassRefPtr<Node> NodeIterator::previousNode(ScriptState* state, ExceptionCode& e
void NodeIterator::detach()
{
- root()->document()->detachNodeIterator(this);
+ if (Document* ownerDocument = root()->document())
+ ownerDocument->detachNodeIterator(this);
m_detached = true;
m_referenceNode.node.clear();
}
@@ -159,6 +164,7 @@ void NodeIterator::updateForNodeRemoval(Node* removedNode, NodePointer& referenc
{
ASSERT(!m_detached);
ASSERT(removedNode);
+ ASSERT(root()->document());
ASSERT(root()->document() == removedNode->document());
// Iterator is not affected if the removed node is the reference node and is the root.
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Position.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Position.cpp
index c83965b..0a05b4c 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Position.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Position.cpp
@@ -482,6 +482,9 @@ Position Position::upstream(EditingBoundaryCrossingRule rule) const
bool startEditable = startNode->isContentEditable();
Node* lastNode = startNode;
bool boundaryCrossed = false;
+#if PLATFORM(WKC)
+ int loops = 0;
+#endif
for (; !currentPos.atStart(); currentPos.decrement()) {
Node* currentNode = currentPos.node();
@@ -579,6 +582,11 @@ Position Position::upstream(EditingBoundaryCrossingRule rule) const
return currentPos;
}
}
+#if PLATFORM(WKC)
+ loops++;
+ if (loops > 16383)
+ return Position();
+#endif
}
return lastVisible;
@@ -989,29 +997,56 @@ static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
return 0;
}
+static Position downstreamIgnoringEditingBoundaries(Position position)
+{
+ Position lastPosition;
+ while (position != lastPosition) {
+ lastPosition = position;
+ position = position.downstream(Position::CanCrossEditingBoundary);
+ }
+ return position;
+}
+
+static Position upstreamIgnoringEditingBoundaries(Position position)
+{
+ Position lastPosition;
+ while (position != lastPosition) {
+ lastPosition = position;
+ position = position.upstream(Position::CanCrossEditingBoundary);
+ }
+ return position;
+}
+
void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
{
caretOffset = m_offset;
RenderObject* renderer = node()->renderer();
if (!renderer->isText()) {
- if (!renderer->isRenderButton() && renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
- bool lastPosition = caretOffset == lastOffsetInNode(node());
- Node* startNode = lastPosition ? node()->childNode(caretOffset - 1) : node()->childNode(caretOffset);
- while (startNode && (!startNode->renderer() || (startNode->isTextNode() && toRenderText(startNode->renderer())->isAllCollapsibleWhitespace())))
- startNode = (lastPosition)? startNode->previousSibling(): startNode->nextSibling();
- if (startNode) {
- Position pos(startNode, 0);
- pos = pos.downstream(CanCrossEditingBoundary);
- pos.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
- if (lastPosition && inlineBox)
- caretOffset = inlineBox->caretMaxOffset();
- return;
+ inlineBox = 0;
+ if (canHaveChildrenForEditing(node()) && renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
+ // Try a visually equivalent position with possibly opposite editability. This helps in case |this| is in
+ // an editable block but surrounded by non-editable positions. It acts to negate the logic at the beginning
+ // of RenderObject::createVisiblePosition().
+ Position equivalent = downstreamIgnoringEditingBoundaries(*this);
+ if (equivalent == *this) {
+ equivalent = upstreamIgnoringEditingBoundaries(*this);
+ if (equivalent == *this || downstreamIgnoringEditingBoundaries(equivalent) == *this)
+ return;
}
+
+ equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
+ return;
}
- inlineBox = renderer->isBox() ? toRenderBox(renderer)->inlineBoxWrapper() : 0;
- if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
+ if (renderer->isBox()) {
+ inlineBox = toRenderBox(renderer)->inlineBoxWrapper();
+ if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
+ return;
+ } else if (!node()->isLink() && node()->isContentEditable()) {
+ Position pos = positionInParentBeforeNode(node()).upstream();
+ pos.getInlineBoxAndOffset(DOWNSTREAM, primaryDirection, inlineBox, caretOffset);
return;
+ }
} else {
RenderText* textRenderer = toRenderText(renderer);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Range.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Range.cpp
index a72edcc..2b46e29 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Range.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Range.cpp
@@ -3,7 +3,7 @@
* (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
* (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
* (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (c) 2010 ACCESS CO., LTD. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -42,9 +42,12 @@
#include "visible_units.h"
#include <stdio.h>
#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/Vector.h>
namespace WebCore {
+typedef Vector<RefPtr<Node> > NodeVector;
+
using namespace std;
#ifndef NDEBUG
@@ -99,9 +102,7 @@ inline Range::Range(PassRefPtr<Document> ownerDocument, PassRefPtr<Node> startCo
// that setStart and setEnd do, so we call those functions.
ExceptionCode ec = 0;
setStart(startContainer, startOffset, ec);
- ASSERT(!ec);
setEnd(endContainer, endOffset, ec);
- ASSERT(!ec);
}
PassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset)
@@ -128,6 +129,17 @@ Range::~Range()
#endif
}
+void Range::setDocument(Document* document)
+{
+ ASSERT(m_ownerDocument != document);
+ if (m_ownerDocument)
+ m_ownerDocument->detachRange(this);
+ m_ownerDocument = document;
+ m_start.setToStartOfNode(document);
+ m_end.setToStartOfNode(document);
+ m_ownerDocument->attachRange(this);
+}
+
Node* Range::startContainer(ExceptionCode& ec) const
{
if (!m_start.container()) {
@@ -603,11 +615,66 @@ bool Range::intersectsNode(Node* refNode, ExceptionCode& ec)
return true; // all other cases
}
-PassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionCode& ec)
+static inline Node* highestAncestorUnderCommonRoot(Node* node, Node* commonRoot)
+{
+ if (node == commonRoot)
+ return 0;
+
+ ASSERT(commonRoot->contains(node));
+
+ while (node->parentNode() != commonRoot)
+ node = node->parentNode();
+
+ return node;
+}
+
+static inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offset, Node* commonRoot)
{
- // FIXME: To work properly with mutation events, we will have to take into account
- // situations where the tree is being transformed while we work on it - ugh!
+ ASSERT(container);
+ ASSERT(commonRoot);
+
+ if (!commonRoot->contains(container))
+ return 0;
+
+ if (container == commonRoot) {
+ container = container->firstChild();
+ for (unsigned i = 0; container && i < offset; i++)
+ container = container->nextSibling();
+ } else {
+ while (container->parentNode() != commonRoot)
+ container = container->parentNode();
+ }
+
+ return container;
+}
+
+static inline unsigned lengthOfContentsInNode(Node* node)
+{
+ // This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
+ switch (node->nodeType()) {
+ case Node::TEXT_NODE:
+ case Node::CDATA_SECTION_NODE:
+ case Node::COMMENT_NODE:
+ return static_cast<CharacterData*>(node)->length();
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ return static_cast<ProcessingInstruction*>(node)->data().length();
+ case Node::ELEMENT_NODE:
+ case Node::ATTRIBUTE_NODE:
+ case Node::ENTITY_REFERENCE_NODE:
+ case Node::ENTITY_NODE:
+ case Node::DOCUMENT_NODE:
+ case Node::DOCUMENT_TYPE_NODE:
+ case Node::DOCUMENT_FRAGMENT_NODE:
+ case Node::NOTATION_NODE:
+ case Node::XPATH_NAMESPACE_NODE:
+ return node->childNodeCount();
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+PassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionCode& ec)
+{
RefPtr<DocumentFragment> fragment;
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
fragment = DocumentFragment::create(m_ownerDocument.get());
@@ -618,75 +685,18 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
if (ec)
return 0;
- Node* commonRoot = commonAncestorContainer(ec);
+ RefPtr<Node> commonRoot = commonAncestorContainer(ec);
if (ec)
return 0;
ASSERT(commonRoot);
// what is the highest node that partially selects the start of the range?
- Node* partialStart = 0;
- if (m_start.container() != commonRoot) {
- partialStart = m_start.container();
- while (partialStart->parentNode() != commonRoot)
- partialStart = partialStart->parentNode();
- }
-
- // what is the highest node that partially selects the end of the range?
- Node* partialEnd = 0;
- if (m_end.container() != commonRoot) {
- partialEnd = m_end.container();
- while (partialEnd->parentNode() != commonRoot)
- partialEnd = partialEnd->parentNode();
- }
-
- // Simple case: the start and end containers are the same. We just grab
- // everything >= start offset and < end offset
- if (m_start.container() == m_end.container()) {
- Node::NodeType startNodeType = m_start.container()->nodeType();
- if (startNodeType == Node::TEXT_NODE || startNodeType == Node::CDATA_SECTION_NODE || startNodeType == Node::COMMENT_NODE) {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(m_start.container()->cloneNode(true));
- c->deleteData(m_end.offset(), c->length() - m_end.offset(), ec);
- c->deleteData(0, m_start.offset(), ec);
- fragment->appendChild(c.release(), ec);
- }
- if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS)
- static_cast<CharacterData*>(m_start.container())->deleteData(m_start.offset(), m_end.offset() - m_start.offset(), ec);
- } else if (startNodeType == Node::PROCESSING_INSTRUCTION_NODE) {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(m_start.container()->cloneNode(true));
- c->setData(c->data().substring(m_start.offset(), m_end.offset() - m_start.offset()), ec);
- fragment->appendChild(c.release(), ec);
- }
- if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
- ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(m_start.container());
- String data(pi->data());
- data.remove(m_start.offset(), m_end.offset() - m_start.offset());
- pi->setData(data, ec);
- }
- } else {
- Node* n = m_start.container()->firstChild();
- int i;
- for (i = 0; n && i < m_start.offset(); i++) // skip until start offset
- n = n->nextSibling();
- int endOffset = m_end.offset();
- while (n && i < endOffset) { // delete until end offset
- Node* next = n->nextSibling();
- if (action == EXTRACT_CONTENTS)
- fragment->appendChild(n, ec); // will remove n from its parent
- else if (action == CLONE_CONTENTS)
- fragment->appendChild(n->cloneNode(true), ec);
- else
- m_start.container()->removeChild(n, ec);
- n = next;
- i++;
- }
- }
- return fragment.release();
- }
+ // what is the highest node that partially selects the start / end of the range?
+ RefPtr<Node> partialStart = highestAncestorUnderCommonRoot(m_start.container(), commonRoot.get());
+ RefPtr<Node> partialEnd = highestAncestorUnderCommonRoot(m_end.container(), commonRoot.get());
- // Complex case: Start and end containers are different.
- // There are three possiblities here:
+ // Start and end containers are different.
+ // There are three possibilities here:
// 1. Start container == commonRoot (End container must be a descendant)
// 2. End container == commonRoot (Start container must be a descendant)
// 3. Neither is commonRoot, they are both descendants
@@ -702,170 +712,32 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
//
// These are deleted, cloned, or extracted (i.e. both) depending on action.
- RefPtr<Node> leftContents;
- if (m_start.container() != commonRoot) {
- // process the left-hand side of the range, up until the last ancestor of
- // start container before commonRoot
- Node::NodeType startNodeType = m_start.container()->nodeType();
- if (startNodeType == Node::TEXT_NODE || startNodeType == Node::CDATA_SECTION_NODE || startNodeType == Node::COMMENT_NODE) {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(m_start.container()->cloneNode(true));
- c->deleteData(0, m_start.offset(), ec);
- leftContents = c.release();
- }
- if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS)
- static_cast<CharacterData*>(m_start.container())->deleteData(
- m_start.offset(), static_cast<CharacterData*>(m_start.container())->length() - m_start.offset(), ec);
- } else if (startNodeType == Node::PROCESSING_INSTRUCTION_NODE) {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(m_start.container()->cloneNode(true));
- c->setData(c->data().substring(m_start.offset()), ec);
- leftContents = c.release();
- }
- if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
- ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(m_start.container());
- String data(pi->data());
- pi->setData(data.left(m_start.offset()), ec);
- }
- } else {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
- leftContents = m_start.container()->cloneNode(false);
- Node* n = m_start.container()->firstChild();
- for (int i = 0; n && i < m_start.offset(); i++) // skip until start offset
- n = n->nextSibling();
- while (n) { // process until end
- Node* next = n->nextSibling();
- if (action == EXTRACT_CONTENTS)
- leftContents->appendChild(n, ec); // will remove n from start container
- else if (action == CLONE_CONTENTS)
- leftContents->appendChild(n->cloneNode(true), ec);
- else
- m_start.container()->removeChild(n, ec);
- n = next;
- }
- }
-
- Node* leftParent = m_start.container()->parentNode();
- Node* n = m_start.container()->nextSibling();
- for (; leftParent != commonRoot; leftParent = leftParent->parentNode()) {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<Node> leftContentsParent = leftParent->cloneNode(false);
- leftContentsParent->appendChild(leftContents, ec);
- leftContents = leftContentsParent;
- }
+ // Note that we are verifying that our common root hierarchy is still intact
+ // after any DOM mutation event, at various stages below. See webkit bug 60350.
- Node* next;
- for (; n; n = next) {
- next = n->nextSibling();
- if (action == EXTRACT_CONTENTS)
- leftContents->appendChild(n, ec); // will remove n from leftParent
- else if (action == CLONE_CONTENTS)
- leftContents->appendChild(n->cloneNode(true), ec);
- else
- leftParent->removeChild(n, ec);
- }
- n = leftParent->nextSibling();
- }
+ RefPtr<Node> leftContents;
+ if (m_start.container() != commonRoot && commonRoot->contains(m_start.container())) {
+ leftContents = processContentsBetweenOffsets(action, 0, m_start.container(), m_start.offset(), lengthOfContentsInNode(m_start.container()), ec);
+ leftContents = processAncestorsAndTheirSiblings(action, m_start.container(), ProcessContentsForward, leftContents, commonRoot.get(), ec);
}
RefPtr<Node> rightContents;
- if (m_end.container() != commonRoot) {
- // delete the right-hand side of the range, up until the last ancestor of
- // end container before commonRoot
- Node::NodeType endNodeType = m_end.container()->nodeType();
- if (endNodeType == Node::TEXT_NODE || endNodeType == Node::CDATA_SECTION_NODE || endNodeType == Node::COMMENT_NODE) {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(m_end.container()->cloneNode(true));
- c->deleteData(m_end.offset(), static_cast<CharacterData*>(m_end.container())->length() - m_end.offset(), ec);
- rightContents = c;
- }
- if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS)
- static_cast<CharacterData*>(m_end.container())->deleteData(0, m_end.offset(), ec);
- } else if (endNodeType == Node::PROCESSING_INSTRUCTION_NODE) {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(m_end.container()->cloneNode(true));
- c->setData(c->data().left(m_end.offset()), ec);
- rightContents = c.release();
- }
- if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
- ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(m_end.container());
- pi->setData(pi->data().substring(m_end.offset()), ec);
- }
- } else {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
- rightContents = m_end.container()->cloneNode(false);
- Node* n = m_end.container()->firstChild();
- if (n && m_end.offset()) {
- for (int i = 0; i + 1 < m_end.offset(); i++) { // skip to end.offset()
- Node* next = n->nextSibling();
- if (!next)
- break;
- n = next;
- }
- Node* prev;
- for (; n; n = prev) {
- prev = n->previousSibling();
- if (action == EXTRACT_CONTENTS)
- rightContents->insertBefore(n, rightContents->firstChild(), ec); // will remove n from its parent
- else if (action == CLONE_CONTENTS)
- rightContents->insertBefore(n->cloneNode(true), rightContents->firstChild(), ec);
- else
- m_end.container()->removeChild(n, ec);
- }
- }
- }
-
- Node* rightParent = m_end.container()->parentNode();
- Node* n = m_end.container()->previousSibling();
- for (; rightParent != commonRoot; rightParent = rightParent->parentNode()) {
- if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<Node> rightContentsParent = rightParent->cloneNode(false);
- rightContentsParent->appendChild(rightContents, ec);
- rightContents = rightContentsParent;
- }
- Node* prev;
- for (; n; n = prev) {
- prev = n->previousSibling();
- if (action == EXTRACT_CONTENTS)
- rightContents->insertBefore(n, rightContents->firstChild(), ec); // will remove n from its parent
- else if (action == CLONE_CONTENTS)
- rightContents->insertBefore(n->cloneNode(true), rightContents->firstChild(), ec);
- else
- rightParent->removeChild(n, ec);
- }
- n = rightParent->previousSibling();
- }
+ if (m_end.container() != commonRoot && commonRoot->contains(m_end.container())) {
+ rightContents = processContentsBetweenOffsets(action, 0, m_end.container(), 0, m_end.offset(), ec);
+ rightContents = processAncestorsAndTheirSiblings(action, m_end.container(), ProcessContentsBackward, rightContents, commonRoot.get(), ec);
}
// delete all children of commonRoot between the start and end container
-
- Node* processStart; // child of commonRoot
- if (m_start.container() == commonRoot) {
- processStart = m_start.container()->firstChild();
- for (int i = 0; i < m_start.offset(); i++)
- processStart = processStart->nextSibling();
- } else {
- processStart = m_start.container();
- while (processStart->parentNode() != commonRoot)
- processStart = processStart->parentNode();
+ RefPtr<Node> processStart = childOfCommonRootBeforeOffset(m_start.container(), m_start.offset(), commonRoot.get());
+ if (processStart && m_start.container() != commonRoot) // processStart contains nodes before m_start.
processStart = processStart->nextSibling();
- }
- Node* processEnd; // child of commonRoot
- if (m_end.container() == commonRoot) {
- processEnd = m_end.container()->firstChild();
- for (int i = 0; i < m_end.offset(); i++)
- processEnd = processEnd->nextSibling();
- } else {
- processEnd = m_end.container();
- while (processEnd->parentNode() != commonRoot)
- processEnd = processEnd->parentNode();
- }
+ RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(m_end.container(), m_end.offset(), commonRoot.get());
// Collapse the range, making sure that the result is not within a node that was partially selected.
if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
- if (partialStart)
+ if (partialStart && commonRoot->contains(partialStart.get()))
setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1, ec);
- else if (partialEnd)
+ else if (partialEnd && commonRoot->contains(partialEnd.get()))
setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), ec);
if (ec)
return 0;
@@ -878,18 +750,11 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents)
fragment->appendChild(leftContents, ec);
- Node* next;
- Node* n;
if (processStart) {
- for (n = processStart; n && n != processEnd; n = next) {
- next = n->nextSibling();
- if (action == EXTRACT_CONTENTS)
- fragment->appendChild(n, ec); // will remove from commonRoot
- else if (action == CLONE_CONTENTS)
- fragment->appendChild(n->cloneNode(true), ec);
- else
- commonRoot->removeChild(n, ec);
- }
+ NodeVector nodes;
+ for (Node* n = processStart.get(); n && n != processEnd; n = n->nextSibling())
+ nodes.append(n);
+ processNodes(action, nodes, commonRoot, fragment, ec);
}
if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && rightContents)
@@ -898,6 +763,153 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
return fragment.release();
}
+static inline void deleteCharacterData(PassRefPtr<CharacterData> data, unsigned startOffset, unsigned endOffset, ExceptionCode& ec)
+{
+ if (data->length() - endOffset)
+ data->deleteData(endOffset, data->length() - endOffset, ec);
+ if (startOffset)
+ data->deleteData(0, startOffset, ec);
+}
+
+PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRefPtr<DocumentFragment> fragment,
+ Node* container, unsigned startOffset, unsigned endOffset, ExceptionCode& ec)
+{
+ ASSERT(container);
+ ASSERT(startOffset <= endOffset);
+
+ // This switch statement must be consistent with that of lengthOfContentsInNode.
+ RefPtr<Node> result;
+ switch (container->nodeType()) {
+ case Node::TEXT_NODE:
+ case Node::CDATA_SECTION_NODE:
+ case Node::COMMENT_NODE:
+ ASSERT(endOffset <= static_cast<CharacterData*>(container)->length());
+ if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
+ RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true));
+ deleteCharacterData(c, startOffset, endOffset, ec);
+ if (fragment) {
+ result = fragment;
+ result->appendChild(c.release(), ec);
+ } else
+ result = c.release();
+ }
+ if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS)
+ static_cast<CharacterData*>(container)->deleteData(startOffset, endOffset - startOffset, ec);
+ break;
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ ASSERT(endOffset <= static_cast<ProcessingInstruction*>(container)->data().length());
+ if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
+ RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true));
+ c->setData(c->data().substring(startOffset, endOffset - startOffset), ec);
+ if (fragment) {
+ result = fragment;
+ result->appendChild(c.release(), ec);
+ } else
+ result = c.release();
+ }
+ if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
+ ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(container);
+ String data(pi->data());
+ data.remove(startOffset, endOffset - startOffset);
+ pi->setData(data, ec);
+ }
+ break;
+ case Node::ELEMENT_NODE:
+ case Node::ATTRIBUTE_NODE:
+ case Node::ENTITY_REFERENCE_NODE:
+ case Node::ENTITY_NODE:
+ case Node::DOCUMENT_NODE:
+ case Node::DOCUMENT_TYPE_NODE:
+ case Node::DOCUMENT_FRAGMENT_NODE:
+ case Node::NOTATION_NODE:
+ case Node::XPATH_NAMESPACE_NODE:
+ // FIXME: Should we assert that some nodes never appear here?
+ if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
+ if (fragment)
+ result = fragment;
+ else
+ result = container->cloneNode(false);
+ }
+
+ Node* n = container->firstChild();
+ Vector<RefPtr<Node> > nodes;
+ for (unsigned i = startOffset; n && i; i--)
+ n = n->nextSibling();
+ for (unsigned i = startOffset; n && i < endOffset; i++, n = n->nextSibling())
+ nodes.append(n);
+
+ processNodes(action, nodes, container, result, ec);
+ break;
+ }
+
+ return result.release();
+}
+
+void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode& ec)
+{
+ for (unsigned i = 0; i < nodes.size(); i++) {
+ switch (action) {
+ case DELETE_CONTENTS:
+ oldContainer->removeChild(nodes[i].get(), ec);
+ break;
+ case EXTRACT_CONTENTS:
+ newContainer->appendChild(nodes[i].release(), ec); // will remove n from its parent
+ break;
+ case CLONE_CONTENTS:
+ newContainer->appendChild(nodes[i]->cloneNode(true), ec);
+ break;
+ }
+ }
+}
+
+PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node* container, ContentsProcessDirection direction, PassRefPtr<Node> passedClonedContainer, Node* commonRoot, ExceptionCode& ec)
+{
+ RefPtr<Node> clonedContainer = passedClonedContainer;
+ Vector<RefPtr<Node> > ancestors;
+ for (Node* n = container->parentNode(); n && n != commonRoot; n = n->parentNode())
+ ancestors.append(n);
+
+ RefPtr<Node> firstChildInAncestorToProcess = direction == ProcessContentsForward ? container->nextSibling() : container->previousSibling();
+ for (Vector<RefPtr<Node> >::const_iterator it = ancestors.begin(); it != ancestors.end(); ++it) {
+ RefPtr<Node> ancestor = *it;
+ if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
+ if (RefPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // Might have been removed already during mutation event.
+ clonedAncestor->appendChild(clonedContainer, ec);
+ clonedContainer = clonedAncestor;
+ }
+ }
+
+ // Copy siblings of an ancestor of start/end containers
+ // FIXME: This assertion may fail if DOM is modified during mutation event
+ // FIXME: Share code with Range::processNodes
+ ASSERT(!firstChildInAncestorToProcess || firstChildInAncestorToProcess->parentNode() == ancestor);
+ RefPtr<Node> next;
+ for (Node* child = firstChildInAncestorToProcess.get(); child; child = next.get()) {
+ next = direction == ProcessContentsForward ? child->nextSibling() : child->previousSibling();
+ switch (action) {
+ case DELETE_CONTENTS:
+ ancestor->removeChild(child, ec);
+ break;
+ case EXTRACT_CONTENTS: // will remove child from ancestor
+ if (direction == ProcessContentsForward)
+ clonedContainer->appendChild(child, ec);
+ else
+ clonedContainer->insertBefore(child, clonedContainer->firstChild(), ec);
+ break;
+ case CLONE_CONTENTS:
+ if (direction == ProcessContentsForward)
+ clonedContainer->appendChild(child->cloneNode(true), ec);
+ else
+ clonedContainer->insertBefore(child->cloneNode(true), clonedContainer->firstChild(), ec);
+ break;
+ }
+ }
+ firstChildInAncestorToProcess = direction == ProcessContentsForward ? ancestor->nextSibling() : ancestor->previousSibling();
+ }
+
+ return clonedContainer.release();
+}
+
PassRefPtr<DocumentFragment> Range::extractContents(ExceptionCode& ec)
{
checkDeleteExtract(ec);
@@ -1024,7 +1036,7 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionCode& ec)
// This special case doesn't seem to match the DOM specification, but it's currently required
// to pass Acid3. We might later decide to remove this.
- if (collapsed)
+ if (collapsed && numNewChildren)
m_end.set(m_start.container(), startOffset + numNewChildren, lastChild.get());
}
}
@@ -1334,6 +1346,9 @@ void Range::selectNode(Node* refNode, ExceptionCode& ec)
return;
}
+ if (m_ownerDocument != refNode->document())
+ setDocument(refNode->document());
+
ec = 0;
setStartBefore(refNode, ec);
if (ec)
@@ -1376,6 +1391,9 @@ void Range::selectNodeContents(Node* refNode, ExceptionCode& ec)
}
}
+ if (m_ownerDocument != refNode->document())
+ setDocument(refNode->document());
+
m_start.setToStartOfNode(refNode);
m_end.setToEndOfNode(refNode);
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Range.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Range.h
index 946095e..958e536 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Range.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Range.h
@@ -140,6 +140,8 @@ private:
Range(PassRefPtr<Document>);
Range(PassRefPtr<Document>, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset);
+ void setDocument(Document*);
+
Node* checkNodeWOffset(Node*, int offset, ExceptionCode&) const;
void checkNodeBA(Node*, ExceptionCode&) const;
void checkDeleteExtract(ExceptionCode&);
@@ -149,6 +151,14 @@ private:
enum ActionType { DELETE_CONTENTS, EXTRACT_CONTENTS, CLONE_CONTENTS };
PassRefPtr<DocumentFragment> processContents(ActionType, ExceptionCode&);
+ PassRefPtr<Node> processContentsBetweenOffsets(ActionType action, PassRefPtr<DocumentFragment> fragment, Node* container, unsigned startOffset, unsigned endOffset, ExceptionCode& ec);
+ void processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode& ec);
+#if !PLATFORM(WKC)
+ enum ContentsProcessDirection { ProcessContentsForward, ProcessContentsBackward };
+#else
+ enum ContentsProcessDirection { ProcessContentsForward, ProcessContentsBackward, ContentsProcessDirections=0x7fffffff };
+#endif
+ PassRefPtr<Node> processAncestorsAndTheirSiblings(ActionType action, Node* container, ContentsProcessDirection direction, PassRefPtr<Node> passedClonedContainer, Node* commonRoot, ExceptionCode& ec);
void getBorderAndTextQuads(Vector<FloatQuad>&) const;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/RangeBoundaryPoint.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/RangeBoundaryPoint.h
index 1bbbe1a..2e91843 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/RangeBoundaryPoint.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/RangeBoundaryPoint.h
@@ -59,7 +59,7 @@ private:
RefPtr<Node> m_containerNode;
mutable int m_offsetInContainer;
- Node* m_childBeforeBoundary;
+ RefPtr<Node> m_childBeforeBoundary;
};
inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
@@ -77,7 +77,7 @@ inline Node* RangeBoundaryPoint::container() const
inline Node* RangeBoundaryPoint::childBefore() const
{
- return m_childBeforeBoundary;
+ return m_childBeforeBoundary.get();
}
inline void RangeBoundaryPoint::ensureOffsetIsValid() const
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/ScriptElement.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/ScriptElement.cpp
index 78eb667..c04e978 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/ScriptElement.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/ScriptElement.cpp
@@ -155,19 +155,20 @@ ScriptElementData::~ScriptElementData()
void ScriptElementData::requestScript(const String& sourceUrl)
{
- Document* document = m_element->document();
-
// FIXME: Eventually we'd like to evaluate scripts which are inserted into a
// viewless document but this'll do for now.
// See http://bugs.webkit.org/show_bug.cgi?id=5727
- if (!document->frame())
+ if (!m_element->document()->frame())
return;
+ RefPtr<Document> originalDocument = m_element->document();
if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
return;
+ if (!m_element->inDocument() || m_element->document() != originalDocument)
+ return;
ASSERT(!m_cachedScript);
- m_cachedScript = document->docLoader()->requestScript(sourceUrl, scriptCharset());
+ m_cachedScript = m_element->document()->docLoader()->requestScript(sourceUrl, scriptCharset());
m_requested = true;
// m_createdByParser is never reset - always resied at the initial value set while parsing.
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/ScriptExecutionContext.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/ScriptExecutionContext.cpp
index bc71084..62e4aeb 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/ScriptExecutionContext.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/ScriptExecutionContext.cpp
@@ -20,7 +20,7 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
@@ -159,6 +159,9 @@ void ScriptExecutionContext::stopActiveDOMObjects()
ASSERT(iter->first->scriptExecutionContext() == this);
iter->first->stop();
}
+
+ // Also close MessagePorts. If they were ActiveDOMObjects (they could be) then they could be stopped instead.
+ closeMessagePorts();
}
void ScriptExecutionContext::createdActiveDOMObject(ActiveDOMObject* object, void* upcastPointer)
@@ -174,6 +177,14 @@ void ScriptExecutionContext::destroyedActiveDOMObject(ActiveDOMObject* object)
m_activeDOMObjects.remove(object);
}
+void ScriptExecutionContext::closeMessagePorts() {
+ HashSet<MessagePort*>::iterator messagePortsEnd = m_messagePorts.end();
+ for (HashSet<MessagePort*>::iterator iter = m_messagePorts.begin(); iter != messagePortsEnd; ++iter) {
+ ASSERT((*iter)->scriptExecutionContext() == this);
+ (*iter)->close();
+ }
+}
+
void ScriptExecutionContext::setSecurityOrigin(PassRefPtr<SecurityOrigin> securityOrigin)
{
m_securityOrigin = securityOrigin;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/ScriptExecutionContext.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/ScriptExecutionContext.h
index cf332c3..d4bc745 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/ScriptExecutionContext.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/ScriptExecutionContext.h
@@ -20,7 +20,7 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
@@ -119,6 +119,8 @@ namespace WebCore {
virtual const KURL& virtualURL() const = 0;
virtual KURL virtualCompleteURL(const String&) const = 0;
+ void closeMessagePorts();
+
RefPtr<SecurityOrigin> m_securityOrigin;
HashSet<MessagePort*> m_messagePorts;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/SelectElement.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/SelectElement.cpp
index 2d00350..ad49228 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/SelectElement.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/SelectElement.cpp
@@ -82,6 +82,8 @@ void SelectElement::selectAll(SelectElementData& data, Element* element)
data.setActiveSelectionState(true);
setActiveSelectionAnchorIndex(data, element, nextSelectableListIndex(data, element, -1));
setActiveSelectionEndIndex(data, previousSelectableListIndex(data, element, -1));
+ if (data.activeSelectionAnchorIndex() < 0)
+ return;
updateListBoxSelection(data, element, false);
listBoxOnChange(data, element);
@@ -670,6 +672,10 @@ void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element*
if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
element->focus();
+ // Calling focus() may remove or change our renderer, in which case we don't want to handle the event further.
+ if (!element->renderer() || !element->renderer()->isListBox())
+ return;
+
// Convert to coords relative to the list box if needed.
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
IntPoint localOffset = roundedIntPoint(element->renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Tokenizer.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Tokenizer.h
index bed3b14..bda1720 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/Tokenizer.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/Tokenizer.h
@@ -24,14 +24,18 @@
#ifndef Tokenizer_h
#define Tokenizer_h
+#include <wtf/RefCounted.h>
+
namespace WebCore {
class SegmentedString;
class XSSAuditor;
- class Tokenizer : public Noncopyable {
+ class Tokenizer : public RefCounted<Tokenizer> {
public:
- virtual ~Tokenizer() { }
+ virtual ~Tokenizer()
+ {
+ }
// Script output must be prepended, while new data
// received during executing a script must be appended, hence the
@@ -62,10 +66,9 @@ namespace WebCore {
XSSAuditor* xssAuditor() const { return m_XSSAuditor; }
void setXSSAuditor(XSSAuditor* auditor) { m_XSSAuditor = auditor; }
-#if PLATFORM(WKC)
- // cf. webkit.org trunk r65692
- virtual bool detach() { return true; }
-#endif
+ virtual void detach()
+ {
+ }
protected:
Tokenizer(bool viewSourceMode = false)
@@ -78,6 +81,7 @@ namespace WebCore {
// The tokenizer has buffers, so parsing may continue even after
// it stops receiving data. We use m_parserStopped to stop the tokenizer
// even when it has buffered data.
+ // FIXME: m_document = 0 could be changed to mean "parser stopped".
bool m_parserStopped;
bool m_inViewSourceMode;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/XMLTokenizer.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/XMLTokenizer.cpp
index 25a9aae..47e1427 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/XMLTokenizer.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/XMLTokenizer.cpp
@@ -204,19 +204,15 @@ void XMLTokenizer::exitText()
popCurrentNode();
}
-#if PLATFORM(WKC)
-// cf. webkit.org trunk r65958
-bool XMLTokenizer::detach()
+void XMLTokenizer::detach()
{
clearCurrentNodeStack();
if (m_refCount > 0) {
// An unexpected error occurred.
wkcMemoryNotifyNoMemoryPeer(0x7fffffff, false);
- return false;
+ return;
}
- return true;
}
-#endif
void XMLTokenizer::end()
{
@@ -245,6 +241,11 @@ void XMLTokenizer::end()
void XMLTokenizer::finish()
{
+ // FIXME: We should ASSERT(!m_parserStopped) here, since it does not
+ // makes sense to call any methods on DocumentParser once it's been stopped.
+ // However, FrameLoader::stop calls Document::finishParsing unconditionally
+ // which in turn calls m_parser->finish().
+
if (m_parserPaused)
m_finishCalled = true;
else
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/XMLTokenizer.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/XMLTokenizer.h
index bdb8505..40452f1 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/XMLTokenizer.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/XMLTokenizer.h
@@ -72,8 +72,14 @@ namespace WebCore {
class XMLTokenizer : public Tokenizer, public CachedResourceClient {
public:
- XMLTokenizer(Document*, FrameView* = 0);
- XMLTokenizer(DocumentFragment*, Element*);
+ static PassRefPtr<XMLTokenizer> create(Document* document, FrameView* view)
+ {
+ return adoptRef(new XMLTokenizer(document, view));
+ }
+ static PassRefPtr<XMLTokenizer> create(DocumentFragment* fragment, Element* element)
+ {
+ return adoptRef(new XMLTokenizer(fragment, element));
+ }
~XMLTokenizer();
enum ErrorType { warning, nonFatal, fatal };
@@ -84,10 +90,7 @@ namespace WebCore {
virtual bool isWaitingForScripts() const;
virtual void stopParsing();
-#if PLATFORM(WKC)
- // cf. webkit.org trunk r65958
- virtual bool detach();
-#endif
+ virtual void detach();
void end();
@@ -146,6 +149,9 @@ public:
private:
friend bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* parent);
+ XMLTokenizer(Document*, FrameView* = 0);
+ XMLTokenizer(DocumentFragment*, Element*);
+
void initializeParserContext(const char* chunk = 0);
void pushCurrentNode(Node*);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp
index 55a20ed..a2c3e41 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp
@@ -883,6 +883,10 @@ void XMLTokenizer::endElementNs()
exitText();
+#if PLATFORM(WKC)
+ if (!m_currentNode)
+ return;
+#endif
Node* n = m_currentNode;
n->finishParsingChildren();
@@ -1462,27 +1466,24 @@ bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, E
if (!chunk.length())
return true;
- XMLTokenizer tokenizer(fragment, parent);
+ RefPtr<XMLTokenizer> tokenizer = XMLTokenizer::create(fragment, parent);
CString chunkAsUtf8 = chunk.utf8();
- tokenizer.initializeParserContext(chunkAsUtf8.data());
+ tokenizer->initializeParserContext(chunkAsUtf8.data());
- xmlParseContent(tokenizer.context());
+ xmlParseContent(tokenizer->context());
- tokenizer.endDocument();
+ tokenizer->endDocument();
// Check if all the chunk has been processed.
- long bytesProcessed = xmlByteConsumed(tokenizer.context());
+ long bytesProcessed = xmlByteConsumed(tokenizer->context());
if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) != chunkAsUtf8.length())
return false;
-#if PLATFORM(WKC)
- // cf. webkit.org trunk r65692
- tokenizer.detach();
-#endif
+ tokenizer->detach();
// No error if the chunk is well formed or it is not but we have no error.
- return tokenizer.context()->wellFormed || xmlCtxtGetLastError(tokenizer.context()) == 0;
+ return tokenizer->context()->wellFormed || !xmlCtxtGetLastError(tokenizer->context());
}
// --------------------------------
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/CompositeEditCommand.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/CompositeEditCommand.cpp
index 4c858d0..897af0a 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/CompositeEditCommand.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/CompositeEditCommand.cpp
@@ -799,10 +799,10 @@ void CompositeEditCommand::cloneParagraphUnderNewElement(Position& start, Positi
// Deleting a paragraph will leave a placeholder. Remove it (and prune
// empty or unrendered parents).
-void CompositeEditCommand::cleanupAfterDeletion()
+void CompositeEditCommand::cleanupAfterDeletion(VisiblePosition destination)
{
VisiblePosition caretAfterDelete = endingSelection().visibleStart();
- if (isStartOfParagraph(caretAfterDelete) && isEndOfParagraph(caretAfterDelete)) {
+ if (caretAfterDelete != destination && isStartOfParagraph(caretAfterDelete) && isEndOfParagraph(caretAfterDelete)) {
// Note: We want the rightmost candidate.
Position position = caretAfterDelete.deepEquivalent().downstream();
Node* node = position.node();
@@ -813,9 +813,15 @@ void CompositeEditCommand::cleanupAfterDeletion()
// doesn't require a placeholder to prop itself open (like a bordered
// div or an li), remove it during the move (the list removal code
// expects this behavior).
- else if (isBlock(node))
+ else if (isBlock(node)) {
+ // If caret position after deletion and destination position coincides,
+ // node should not be removed.
+ if (!position.rendersInDifferentPosition(destination.deepEquivalent())) {
+ prune(node);
+ return;
+ }
removeNodeAndPruneAncestors(node);
- else if (lineBreakExistsAtPosition(position)) {
+ } else if (lineBreakExistsAtPosition(position)) {
// There is a preserved '\n' at caretAfterDelete.
// We can safely assume this is a text node.
Text* textNode = static_cast<Text*>(node);
@@ -949,7 +955,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
ASSERT(destination.deepEquivalent().node()->inDocument());
- cleanupAfterDeletion();
+ cleanupAfterDeletion(destination);
// Add a br if pruning an empty block level element caused a collapse. For example:
// foo^
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/CompositeEditCommand.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/CompositeEditCommand.h
index 0cceaaa..9c80ca8 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/CompositeEditCommand.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/CompositeEditCommand.h
@@ -104,7 +104,7 @@ protected:
void moveParagraphs(const VisiblePosition&, const VisiblePosition&, const VisiblePosition&, bool preserveSelection = false, bool preserveStyle = true);
void moveParagraphWithClones(const VisiblePosition& startOfParagraphToMove, const VisiblePosition& endOfParagraphToMove, Element* blockElement, Node* outerNode);
void cloneParagraphUnderNewElement(Position& start, Position& end, Node* outerNode, Element* blockElement);
- void cleanupAfterDeletion();
+ void cleanupAfterDeletion(VisiblePosition destination = VisiblePosition());
bool breakOutOfEmptyListItem();
bool breakOutOfEmptyMailBlockquotedParagraph();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/DeleteButtonController.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/DeleteButtonController.cpp
index c5a4a7d..2aadc3b 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/DeleteButtonController.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/DeleteButtonController.cpp
@@ -112,8 +112,12 @@ static bool isDeletableElement(const Node* node)
return false;
// Allow blocks that have background images
- if (style->hasBackgroundImage() && style->backgroundImage()->canRender(1.0f))
- return true;
+ if (style->hasBackgroundImage()) {
+ for (const FillLayer* background = style->backgroundLayers(); background; background = background->next()) {
+ if (background->image() && background->image()->canRender(1))
+ return true;
+ }
+ }
// Allow blocks with a minimum number of non-transparent borders
unsigned visibleBorders = style->borderTop().isVisible() + style->borderBottom().isVisible() + style->borderLeft().isVisible() + style->borderRight().isVisible();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/SelectionController.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/SelectionController.cpp
index 8d24eae..4fd6287 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/SelectionController.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/SelectionController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (c) 2011 ACCESS CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -71,6 +71,7 @@ SelectionController::SelectionController(Frame* frame, bool isDragCaretControlle
, m_isDragCaretController(isDragCaretController)
, m_isCaretBlinkingSuspended(false)
, m_focused(frame && frame->page() && frame->page()->focusController()->focusedFrame() == frame)
+ , m_needsDisplayUpdate(false)
{
}
@@ -146,7 +147,8 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
if (!s.isNone())
m_frame->setFocusedNodeIfNeeded();
- m_frame->selectionLayoutChanged();
+ setNeedsDisplayUpdate();
+
// Always clear the x position used for vertical arrow navigation.
// It will be restored by the vertical arrow navigation code if necessary.
m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;
@@ -1305,6 +1307,20 @@ bool SelectionController::isFocusedAndActive() const
return m_focused && m_frame->page() && m_frame->page()->focusController()->isActive();
}
+void SelectionController::setNeedsDisplayUpdate(bool needsUpdate)
+{
+ if (m_needsDisplayUpdate == needsUpdate)
+ return;
+ m_needsDisplayUpdate = needsUpdate;
+
+ if (!m_needsDisplayUpdate)
+ return;
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+ view->scheduleRelayout();
+}
+
#ifndef NDEBUG
void SelectionController::formatForDebugger(char* buffer, unsigned length) const
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/SelectionController.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/SelectionController.h
index d03df52..05ee1dc 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/SelectionController.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/SelectionController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -124,6 +124,10 @@ public:
bool isFocusedAndActive() const;
void pageActivationChanged();
+ // Selection display machinery
+ void setNeedsDisplayUpdate(bool = true);
+ bool needsDisplayUpdate() const { return m_needsDisplayUpdate; }
+
#ifndef NDEBUG
void formatForDebugger(char* buffer, unsigned length) const;
void showTreeForThis() const;
@@ -175,6 +179,7 @@ private:
bool m_isCaretBlinkingSuspended : 1;
bool m_focused : 1;
+ bool m_needsDisplayUpdate : 1;
};
inline bool operator==(const SelectionController& a, const SelectionController& b)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/TextIterator.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/TextIterator.cpp
index 886b858..b3b397c 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/TextIterator.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/TextIterator.cpp
@@ -1951,6 +1951,9 @@ tryAgain:
PassRefPtr<Range> findPlainText(const Range* range, const String& target, bool forward, bool caseSensitive)
{
+ // CharacterIterator requires renderers to be up-to-date
+ range->ownerDocument()->updateLayout();
+
// First, find the text.
size_t matchStart;
size_t matchLength;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/VisiblePosition.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/VisiblePosition.cpp
index 2db6d31..99167ef 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/VisiblePosition.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/VisiblePosition.cpp
@@ -462,6 +462,8 @@ Position VisiblePosition::canonicalPosition(const Position& position)
if (!node)
return Position();
+ ASSERT(node->document());
+
node->document()->updateLayoutIgnorePendingStylesheets();
Position candidate = position.upstream();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/visible_units.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/visible_units.cpp
index 84ace83..ed1b550 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/editing/visible_units.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/editing/visible_units.cpp
@@ -235,17 +235,20 @@ static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
if (it.atEnd() && next == string.size()) {
pos = it.range()->startPosition();
- } else if (next != prefixLength) {
+ } else if (next != prefixLength && next!=0xffffffff) {
// Use the character iterator to translate the next value into a DOM position.
CharacterIterator charIt(searchRange.get(), true);
charIt.advance(next - prefixLength - 1);
- pos = charIt.range()->endPosition();
+ RefPtr<Range> characterRange = charIt.range();
+ pos = characterRange->endPosition();
if (*charIt.characters() == '\n') {
// FIXME: workaround for collapsed range (where only start position is correct) emitted for some emitted newlines (see rdar://5192593)
VisiblePosition visPos = VisiblePosition(pos);
- if (visPos == VisiblePosition(charIt.range()->startPosition()))
- pos = visPos.next(true).deepEquivalent();
+ if (visPos == VisiblePosition(charIt.range()->startPosition())) {
+ charIt.advance(1);
+ pos = charIt.range()->startPosition();
+ }
}
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLAnchorElement.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLAnchorElement.cpp
index 1d5d569..58c9ea3 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLAnchorElement.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLAnchorElement.cpp
@@ -497,19 +497,8 @@ String HTMLAnchorElement::protocol() const
void HTMLAnchorElement::setProtocol(const String& value)
{
- int separator = value.find(':');
-
- if (!separator)
- return;
- if (value.isEmpty())
- return;
-
KURL url = href();
- // Following Firefox 3.5.2 which removes anything after the first ":"
- String newProtocol = value.substring(0, separator);
- if (!isValidProtocol(newProtocol))
- return;
- url.setProtocol(newProtocol);
+ (void)url.setProtocol(value);
setHref(url.string());
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLDocument.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLDocument.cpp
index 0d1cb19..4d19124 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLDocument.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLDocument.cpp
@@ -281,7 +281,7 @@ void HTMLDocument::releaseEvents()
{
}
-Tokenizer *HTMLDocument::createTokenizer()
+PassRefPtr<Tokenizer> HTMLDocument::createTokenizer()
{
bool reportErrors = false;
#if ENABLE(INSPECTOR)
@@ -289,7 +289,7 @@ Tokenizer *HTMLDocument::createTokenizer()
reportErrors = page->inspectorController()->windowVisible();
#endif
- return new HTMLTokenizer(this, reportErrors);
+ return HTMLTokenizer::create(this, reportErrors);
}
// --------------------------------------------------------------------------
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLDocument.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLDocument.h
index 4b14d0c..02156d6 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLDocument.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLDocument.h
@@ -89,7 +89,7 @@ private:
virtual bool isHTMLDocument() const { return true; }
virtual bool isFrameSet() const;
- virtual Tokenizer* createTokenizer();
+ virtual PassRefPtr<Tokenizer> createTokenizer();
virtual void determineParseMode();
HashCountedSet<AtomicStringImpl*> m_namedItemCounts;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLFrameElementBase.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLFrameElementBase.cpp
index 9551b6e..2b37d6f 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLFrameElementBase.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLFrameElementBase.cpp
@@ -57,6 +57,9 @@ HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Documen
bool HTMLFrameElementBase::isURLAllowed() const
{
+ if (document() && document()->page() && document()->page()->frameCount() >= 200)
+ return false;
+
if (m_URL.isEmpty())
return true;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLFrameSetElement.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLFrameSetElement.cpp
index 6c1630b..67ba1a0 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLFrameSetElement.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLFrameSetElement.cpp
@@ -198,7 +198,7 @@ void HTMLFrameSetElement::attach()
void HTMLFrameSetElement::defaultEventHandler(Event* evt)
{
- if (evt->isMouseEvent() && !noresize && renderer()) {
+ if (evt->isMouseEvent() && !noresize && renderer() && renderer()->isFrameSet()) {
if (toRenderFrameSet(renderer())->userResize(static_cast<MouseEvent*>(evt))) {
evt->setDefaultHandled();
return;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLLinkElement.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLLinkElement.cpp
index 66aa6c8..d896aaf 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLLinkElement.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLLinkElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2009 Rob Buis (rwlbuis@gmail.com)
* Copyright (c) 2010 ACCESS CO., LTD. All rights reserved.
*
@@ -57,6 +57,7 @@ HTMLLinkElement::HTMLLinkElement(const QualifiedName& qName, Document *doc, bool
, m_isIcon(false)
, m_isDNSPrefetch(false)
, m_createdByParser(createdByParser)
+ , m_shouldProcessAfterAttach(false)
{
ASSERT(hasTagName(linkTag));
}
@@ -235,11 +236,23 @@ void HTMLLinkElement::process()
}
}
+void HTMLLinkElement::processCallback(Node* node)
+{
+ ASSERT_ARG(node, node && node->hasTagName(linkTag));
+ static_cast<HTMLLinkElement*>(node)->process();
+}
+
void HTMLLinkElement::insertedIntoDocument()
{
HTMLElement::insertedIntoDocument();
document()->addStyleSheetCandidateNode(this, m_createdByParser);
- process();
+
+ // Since processing a stylesheet link causes a beforeload event
+ // to fire, it is possible for JavaScript to remove the element in the midst
+ // of it being inserted into the DOM, which can lead to assertion failures
+ // and crashes. Avoid this by postponing the beforeload/load until after
+ // attach.
+ m_shouldProcessAfterAttach = true;
}
void HTMLLinkElement::removedFromDocument()
@@ -251,8 +264,19 @@ void HTMLLinkElement::removedFromDocument()
// FIXME: It's terrible to do a synchronous update of the style selector just because a <style> or <link> element got removed.
if (document()->renderer())
document()->updateStyleSelector();
+
+ m_shouldProcessAfterAttach = false;
}
+void HTMLLinkElement::attach()
+{
+ if (m_shouldProcessAfterAttach) {
+ m_shouldProcessAfterAttach = false;
+ queuePostAttachCallback(&HTMLLinkElement::processCallback, this);
+ }
+
+ HTMLElement::attach();
+}
void HTMLLinkElement::finishParsingChildren()
{
m_createdByParser = false;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLLinkElement.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLLinkElement.h
index ad96e99..7813b14 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLLinkElement.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLLinkElement.h
@@ -75,6 +75,7 @@ public:
virtual void parseMappedAttribute(MappedAttribute*);
void process();
+ static void processCallback(Node*);
virtual void insertedIntoDocument();
virtual void removedFromDocument();
@@ -93,6 +94,9 @@ public:
bool isDisabled() const { return m_disabledState == 2; }
bool isEnabledViaScript() const { return m_disabledState == 1; }
bool isIcon() const { return m_isIcon; }
+
+ virtual void attach();
+ virtual bool canLazyAttach() { return false; }
int disabledState() { return m_disabledState; }
void setDisabledState(bool _disabled);
@@ -123,6 +127,7 @@ protected:
bool m_isIcon;
bool m_isDNSPrefetch;
bool m_createdByParser;
+ bool m_shouldProcessAfterAttach;
};
} //namespace
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLObjectElement.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLObjectElement.cpp
index 7a6a14d..be05d34 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLObjectElement.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLObjectElement.cpp
@@ -246,6 +246,9 @@ void HTMLObjectElement::renderFallbackContent()
if (m_useFallbackContent)
return;
+ if (!inDocument())
+ return;
+
// Before we give up and use fallback content, check to see if this is a MIME type issue.
if (m_imageLoader && m_imageLoader->image()) {
m_serviceType = m_imageLoader->image()->response().mimeType();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLParser.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLParser.cpp
index 3e686de..070e649 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLParser.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLParser.cpp
@@ -66,6 +66,7 @@ using namespace HTMLNames;
static const unsigned cMaxRedundantTagDepth = 20;
static const unsigned cResidualStyleMaxDepth = 200;
+static const unsigned cResidualStyleIterationLimit = 5;
static const int minBlockLevelTagPriority = 3;
@@ -125,6 +126,10 @@ struct HTMLStackElem : Noncopyable {
*
*/
+#if PLATFORM(WKC)
+static Vector<HTMLParser*>* gValidParsers = 0;
+#endif
+
HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
: m_document(doc)
, m_current(doc)
@@ -141,6 +146,11 @@ HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
, m_inStrayTableContent(0)
, m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0)
{
+#if PLATFORM(WKC)
+ if (!gValidParsers)
+ gValidParsers = new Vector<HTMLParser*>();
+ gValidParsers->append(this);
+#endif
}
HTMLParser::HTMLParser(DocumentFragment* frag)
@@ -161,6 +171,11 @@ HTMLParser::HTMLParser(DocumentFragment* frag)
{
if (frag)
frag->ref();
+#if PLATFORM(WKC)
+ if (!gValidParsers)
+ gValidParsers = new Vector<HTMLParser*>();
+ gValidParsers->append(this);
+#endif
}
HTMLParser::~HTMLParser()
@@ -168,6 +183,18 @@ HTMLParser::~HTMLParser()
freeBlock();
if (m_didRefCurrent)
m_current->deref();
+#if PLATFORM(WKC)
+ size_t pos = gValidParsers->find(this);
+ if (pos!=notFound)
+ gValidParsers->remove(pos);
+#endif
+}
+
+void HTMLParser::detach()
+{
+ // This call makes little sense in fragment mode, but for consistency
+ // HTMLParser expects detach() to always be called before it's destroyed.
+ m_document = 0;
}
void HTMLParser::reset()
@@ -575,6 +602,10 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
#endif
createHead();
+#if PLATFORM(WKC)
+ if (gValidParsers->find(this)==notFound)
+ return false;
+#endif
popBlock(headTag);
e = new HTMLBodyElement(bodyTag, m_document);
startBody();
@@ -1197,8 +1228,10 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
bool finished = false;
bool strayTableContent = elem->strayTableContent;
+ unsigned iterationCount = 0;
+
m_handlingResidualStyleAcrossBlocks = true;
- while (!finished) {
+ while (!finished && (iterationCount++ < cResidualStyleIterationLimit)) {
// Find the outermost element that crosses over to a higher level. If there exists another higher-level
// element, we will do another pass, until we have corrected the innermost one.
ExceptionCode ec = 0;
@@ -1683,6 +1716,11 @@ void HTMLParser::createHead()
m_document->documentElement()->insertBefore(m_head.get(), body, ec);
if (ec)
m_head = 0;
+
+#if PLATFORM(WKC)
+ if (gValidParsers->find(this)==notFound)
+ return;
+#endif
// If the body does not exist yet, then the <head> should be pushed as the current block.
if (m_head && !body) {
@@ -1739,7 +1777,7 @@ void HTMLParser::finished()
freeBlock();
setCurrent(0);
- // Warning, this may delete the tokenizer and parser, so don't try to do anything else after this.
+ // Warning, this may detach the tokenizer and parser, so don't try to do anything else after this.
if (!m_isParsingFragment)
m_document->finishedParsing();
}
@@ -1821,6 +1859,7 @@ void HTMLParser::resetVariables()
gHeaderTags = 0;
gResidualStyleTags = 0;
gUnaffectedTags = 0;
+ gValidParsers = 0;
}
#endif
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLParser.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLParser.h
index 1ec1055..f9f3f6b 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLParser.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLParser.h
@@ -56,6 +56,8 @@ public:
HTMLParser(DocumentFragment*);
virtual ~HTMLParser();
+ void detach();
+
/**
* parses one token delivered by the tokenizer
*/
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLSelectElement.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLSelectElement.cpp
index 2ca9f03..11e49d8 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLSelectElement.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLSelectElement.cpp
@@ -422,11 +422,21 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
} else {
const Vector<Element*>& items = listItems();
+ // Removing children fires mutation events, which might mutate the DOM further, so we first copy out a list
+ // of elements that we intend to remove then attempt to remove them one at a time.
+ Vector<RefPtr<Element> > itemsToRemove;
size_t optionIndex = 0;
- for (size_t listIndex = 0; listIndex < items.size(); listIndex++) {
- if (items[listIndex]->hasLocalName(optionTag) && optionIndex++ >= newLen) {
- Element *item = items[listIndex];
+ for (size_t i = 0; i < items.size(); ++i) {
+ Element* item = items[i];
+ if (item->hasLocalName(optionTag) && optionIndex++ >= newLen) {
ASSERT(item->parentNode());
+ itemsToRemove.append(item);
+ }
+ }
+
+ for (size_t i = 0; i < itemsToRemove.size(); ++i) {
+ Element* item = itemsToRemove[i].get();
+ if (item->parentNode()) {
item->parentNode()->removeChild(item, ec);
}
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLTextAreaElement.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLTextAreaElement.cpp
index e0bd8c5..3e1a5b0 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLTextAreaElement.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLTextAreaElement.cpp
@@ -184,6 +184,8 @@ bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool)
if (name().isEmpty())
return false;
+ document()->updateLayout();
+
// FIXME: It's not acceptable to ignore the HardWrap setting when there is no renderer.
// While we have no evidence this has ever been a practical problem, it would be best to fix it some day.
RenderTextControl* control = toRenderTextControl(renderer());
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLTokenizer.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLTokenizer.cpp
index 9363ddb..89a0db9 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLTokenizer.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLTokenizer.cpp
@@ -8,7 +8,7 @@
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
Copyright (C) 2005, 2006 Alexey Proskuryakov (ap@nypop.com)
Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- Copyright (c) 2011 ACCESS CO., LTD. All rights reserved.
+ Copyright (c) 2011, 2015 ACCESS CO., LTD. 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
@@ -155,6 +155,10 @@ inline void Token::addAttribute(AtomicString& attrName, const AtomicString& attr
attrName = emptyAtom;
}
+#if PLATFORM(WKC)
+static Vector<HTMLTokenizer*>* gValidInstances = 0;
+#endif
+
// ----------------------------------------------------------------------------
HTMLTokenizer::HTMLTokenizer(HTMLDocument* doc, bool reportErrors)
@@ -174,6 +178,11 @@ HTMLTokenizer::HTMLTokenizer(HTMLDocument* doc, bool reportErrors)
, m_inWrite(false)
, m_fragment(false)
{
+#if PLATFORM(WKC)
+ if (!gValidInstances)
+ gValidInstances = new Vector<HTMLTokenizer*>();
+ gValidInstances->append(this);
+#endif
begin();
}
@@ -194,6 +203,11 @@ HTMLTokenizer::HTMLTokenizer(HTMLViewSourceDocument* doc)
, m_inWrite(false)
, m_fragment(false)
{
+#if PLATFORM(WKC)
+ if (!gValidInstances)
+ gValidInstances = new Vector<HTMLTokenizer*>();
+ gValidInstances->append(this);
+#endif
begin();
}
@@ -213,9 +227,24 @@ HTMLTokenizer::HTMLTokenizer(DocumentFragment* frag)
, m_inWrite(false)
, m_fragment(true)
{
+#if PLATFORM(WKC)
+ if (!gValidInstances)
+ gValidInstances = new Vector<HTMLTokenizer*>();
+ gValidInstances->append(this);
+#endif
begin();
}
+void HTMLTokenizer::detach()
+{
+ Tokenizer::detach();
+ // FIXME: It seems wrong that we would have a preload scanner here.
+ // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do.
+ m_preloadScanner.clear();
+ m_timer.stop();
+ m_pendingScripts.clear();
+}
+
void HTMLTokenizer::reset()
{
ASSERT(m_executingScript == 0);
@@ -1631,6 +1660,8 @@ void HTMLTokenizer::write(const SegmentedString& str, bool appendData)
if (m_parserStopped)
return;
+ RefPtr<HTMLTokenizer> protect(this);
+
SegmentedString source(str);
if (m_executingScript)
source.setExcludeLineNumbers();
@@ -1853,6 +1884,8 @@ void HTMLTokenizer::timerFired(Timer<HTMLTokenizer>*)
void HTMLTokenizer::end()
{
ASSERT(!m_timer.isActive());
+ RefPtr<HTMLTokenizer> protect(this);
+
m_timer.stop(); // Only helps if assertion above fires, but do it anyway.
if (m_buffer) {
@@ -1860,6 +1893,11 @@ void HTMLTokenizer::end()
if (!m_state.hasTagState())
processToken();
+#if PLATFORM(WKC)
+ if (gValidInstances->find(this)==notFound)
+ return;
+#endif
+
fastFree(m_scriptCode);
m_scriptCode = 0;
m_scriptCodeSize = m_scriptCodeCapacity = m_scriptCodeResync = 0;
@@ -1947,6 +1985,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
// pass the token over to the parser, the parser DOES NOT delete the token
n = m_parser->parseToken(&m_currentToken);
}
+
m_currentToken.reset();
if (scriptController)
scriptController->setEventHandlerLineNumber(0);
@@ -1965,6 +2004,9 @@ void HTMLTokenizer::processDoctypeToken()
HTMLTokenizer::~HTMLTokenizer()
{
#if PLATFORM(WKC)
+ size_t pos = gValidInstances->find(this);
+ if (pos!=notFound)
+ gValidInstances->remove(pos);
if (m_inWrite && !wkcMemoryIsCrashingPeer()) {
// An unexpected error occurred.
// This is workaround for issue http://code.google.com/p/chromium/issues/detail?id=50250
@@ -2029,6 +2071,7 @@ void HTMLTokenizer::executeScriptsWaitingForStylesheets()
void HTMLTokenizer::notifyFinished(CachedResource*)
{
+ RefPtr<HTMLTokenizer> protect(this);
executeExternalScriptsIfReady();
}
@@ -2047,6 +2090,8 @@ void HTMLTokenizer::executeExternalScriptsIfReady()
if (m_hasScriptsWaitingForStylesheets)
return;
+ RefPtr<HTMLTokenizer> protect(this);
+
bool finished = false;
double startTime = currentTime();
@@ -2150,11 +2195,12 @@ void HTMLTokenizer::setSrc(const SegmentedString& source)
void parseHTMLDocumentFragment(const String& source, DocumentFragment* fragment)
{
- HTMLTokenizer tok(fragment);
- tok.setForceSynchronous(true);
- tok.write(source, true);
- tok.finish();
- ASSERT(!tok.processingData()); // make sure we're done (see 3963151)
+ RefPtr<HTMLTokenizer> tok = HTMLTokenizer::create(fragment);
+ tok->setForceSynchronous(true);
+ tok->write(source, true);
+ tok->finish();
+ ASSERT(!tok->processingData()); // make sure we're done (see 3963151)
+ tok->detach();
}
UChar decodeNamedEntity(const char* name)
@@ -2163,4 +2209,12 @@ UChar decodeNamedEntity(const char* name)
return e ? e->code : 0;
}
+#if PLATFORM(WKC)
+void
+HTMLTokenizer::resetVariables()
+{
+ gValidInstances = 0;
+}
+#endif
+
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLTokenizer.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLTokenizer.h
index 2516eda..c6d734d 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLTokenizer.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLTokenizer.h
@@ -133,9 +133,18 @@ public:
class HTMLTokenizer : public Tokenizer, public CachedResourceClient {
public:
- HTMLTokenizer(HTMLDocument*, bool reportErrors);
- HTMLTokenizer(HTMLViewSourceDocument*);
- HTMLTokenizer(DocumentFragment*);
+ static PassRefPtr<HTMLTokenizer> create(HTMLDocument* document, bool reportErrors)
+ {
+ return adoptRef(new HTMLTokenizer(document, reportErrors));
+ }
+ static PassRefPtr<HTMLTokenizer> create(HTMLViewSourceDocument* document)
+ {
+ return adoptRef(new HTMLTokenizer(document));
+ }
+ static PassRefPtr<HTMLTokenizer> create(DocumentFragment* fragment)
+ {
+ return adoptRef(new HTMLTokenizer(fragment));
+ }
virtual ~HTMLTokenizer();
virtual void write(const SegmentedString&, bool appendData);
@@ -156,7 +165,16 @@ public:
virtual bool isHTMLTokenizer() const { return true; }
HTMLParser* htmlParser() const { return m_parser.get(); }
+#if PLATFORM(WKC)
+ static void resetVariables();
+#endif
+ virtual void detach();
+
private:
+ HTMLTokenizer(HTMLDocument*, bool reportErrors);
+ HTMLTokenizer(HTMLViewSourceDocument*);
+ HTMLTokenizer(DocumentFragment*);
+
class State;
// Where we are in parsing a tag
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLViewSourceDocument.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLViewSourceDocument.cpp
index ba718d1..36e8a35 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLViewSourceDocument.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLViewSourceDocument.cpp
@@ -51,7 +51,7 @@ HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const String& mimeT
setUsesBeforeAfterRules(true);
}
-Tokenizer* HTMLViewSourceDocument::createTokenizer()
+PassRefPtr<Tokenizer> HTMLViewSourceDocument::createTokenizer()
{
// Use HTMLTokenizer if applicable, otherwise use TextTokenizer.
if (m_type == "text/html" || m_type == "application/xhtml+xml" || m_type == "image/svg+xml" || implementation()->isXMLMIMEType(m_type)
@@ -59,7 +59,7 @@ Tokenizer* HTMLViewSourceDocument::createTokenizer()
|| m_type == "application/vnd.wap.xhtml+xml"
#endif
) {
- return new HTMLTokenizer(this);
+ return HTMLTokenizer::create(this);
}
return createTextTokenizer(this);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLViewSourceDocument.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLViewSourceDocument.h
index e4eadb0..87bc730 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/HTMLViewSourceDocument.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/HTMLViewSourceDocument.h
@@ -50,7 +50,7 @@ private:
HTMLViewSourceDocument(Frame*, const String& mimeType);
// Returns HTMLTokenizer or TextTokenizer based on m_type.
- virtual Tokenizer* createTokenizer();
+ virtual PassRefPtr<Tokenizer> createTokenizer();
void createContainingTable();
PassRefPtr<Element> addSpanWithClassName(const String&);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 4ba9c1b..cc8da50 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -1236,7 +1236,7 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageEleme
PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
const String& repetitionType, ExceptionCode& ec)
{
- if (!canvas->width() || !canvas->height()) {
+ if (!canvas->width() || !canvas->height() || !canvas->buffer()) {
ec = INVALID_STATE_ERR;
return 0;
}
@@ -1305,6 +1305,13 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float
scaledSize.setWidth(1);
if (scaledSize.height() < 1)
scaledSize.setHeight(1);
+
+#if PLATFORM(WKC)
+ if (scaledSize.width() > 32767 || scaledSize.height() > 32767) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+#endif
return createEmptyImageData(scaledSize);
}
@@ -1403,6 +1410,7 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
RefPtr<RenderStyle> newStyle = RenderStyle::create();
if (canvas()->computedStyle())
newStyle->setFontDescription(canvas()->computedStyle()->fontDescription());
+ newStyle->font().update(newStyle->font().fontSelector());
// Now map the font property into the style.
CSSStyleSelector* styleSelector = canvas()->document()->styleSelector();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/DocumentThreadableLoader.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/DocumentThreadableLoader.cpp
index de0a0b0..8a4b665 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/DocumentThreadableLoader.cpp
@@ -81,16 +81,18 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document* document, Threadabl
ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
- if (!m_options.forcePreflight && isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()))
- makeSimpleCrossOriginAccessRequest(request);
- else {
- m_actualRequest.set(new ResourceRequest(request));
- m_actualRequest->setAllowCookies(m_options.allowCredentials);
+ OwnPtr<ResourceRequest> crossOriginRequest(new ResourceRequest(request));
+ crossOriginRequest->removeCredentials();
+ crossOriginRequest->setAllowCookies(m_options.allowCredentials);
- if (CrossOriginPreflightResultCache::shared().canSkipPreflight(document->securityOrigin()->toString(), request.url(), m_options.allowCredentials, request.httpMethod(), request.httpHeaderFields()))
+ if (!m_options.forcePreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFields()))
+ makeSimpleCrossOriginAccessRequest(*crossOriginRequest);
+ else {
+ m_actualRequest.set(crossOriginRequest.release());
+ if (CrossOriginPreflightResultCache::shared().canSkipPreflight(document->securityOrigin()->toString(), m_actualRequest->url(), m_options.allowCredentials, m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields()))
preflightSuccess();
else
- makeCrossOriginAccessRequestWithPreflight(request);
+ makeCrossOriginAccessRequestWithPreflight(*m_actualRequest);
}
}
@@ -106,8 +108,6 @@ void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(const Resource
// Make a copy of the passed request so that we can modify some details.
ResourceRequest crossOriginRequest(request);
- crossOriginRequest.removeCredentials();
- crossOriginRequest.setAllowCookies(m_options.allowCredentials);
crossOriginRequest.setHTTPOrigin(m_document->securityOrigin()->toString());
loadRequest(crossOriginRequest, DoSecurityCheck);
@@ -155,6 +155,9 @@ void DocumentThreadableLoader::cancel()
return;
m_loader->cancel();
+#if PLATFORM(WKC)
+ if (m_loader)
+#endif
m_loader->clearClient();
m_loader = 0;
m_client = 0;
@@ -287,11 +290,17 @@ void DocumentThreadableLoader::preflightSuccess()
void DocumentThreadableLoader::preflightFailure()
{
+ m_actualRequest = 0; // Prevent didFinishLoading() from bypassing access check.
m_client->didFail(ResourceError());
}
void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, SecurityCheckPolicy securityCheck)
{
+ // Any credential should have been removed from the cross-site requests.
+ const KURL& requestURL = request.url();
+ ASSERT(m_sameOriginRequest || requestURL.user().isEmpty());
+ ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty());
+
if (m_async) {
// Don't sniff content or send load callbacks for the preflight request.
bool sendLoadCallbacks = m_options.sendLoadCallbacks && !m_actualRequest;
@@ -315,15 +324,15 @@ void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Secur
// No exception for file:/// resources, see <rdar://problem/4962298>.
// Also, if we have an HTTP response, then it wasn't a network error in fact.
- if (!error.isNull() && !request.url().isLocalFile() && response.httpStatusCode() <= 0) {
+ if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode() <= 0) {
m_client->didFail(error);
return;
}
// FIXME: FrameLoader::loadSynchronously() does not tell us whether a redirect happened or not, so we guess by comparing the
// request and response URLs. This isn't a perfect test though, since a server can serve a redirect to the same URL that was
- // requested.
- if (request.url() != response.url() && !isAllowedRedirect(response.url())) {
+ // requested. Also comparing the request and response URLs as strings will fail if the requestURL still has its credentials.
+ if (requestURL != response.url() && !isAllowedRedirect(response.url())) {
m_client->didFailRedirectCheck();
return;
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/FTPDirectoryDocument.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/FTPDirectoryDocument.cpp
index ee0f4ca..01da51d 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/FTPDirectoryDocument.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/FTPDirectoryDocument.cpp
@@ -55,7 +55,10 @@ using namespace HTMLNames;
class FTPDirectoryTokenizer : public HTMLTokenizer {
public:
- FTPDirectoryTokenizer(HTMLDocument*);
+ passRefPtr<FTPDirectoryTokenizer> create(HTMLDocument* document)
+ {
+ return adoptRef(new FTPDirectoryTokenizer(document));
+ }
virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
@@ -75,6 +78,8 @@ public:
}
private:
+ FTPDirectoryTokenizer(HTMLDocument*);
+
// The tokenizer will attempt to load the document template specified via the preference
// Failing that, it will fall back and create the basic document which will have a minimal
// table for presenting the FTP directory in a useful manner
@@ -489,9 +494,9 @@ FTPDirectoryDocument::FTPDirectoryDocument(Frame* frame)
#endif
}
-Tokenizer* FTPDirectoryDocument::createTokenizer()
+PassRefPtr<Tokenizer> FTPDirectoryDocument::createTokenizer()
{
- return new FTPDirectoryTokenizer(this);
+ return adoptRef(new FTPDirectoryTokenizer(this));
}
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/FTPDirectoryDocument.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/FTPDirectoryDocument.h
index b208c4e..5e30816 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/FTPDirectoryDocument.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/FTPDirectoryDocument.h
@@ -40,7 +40,7 @@ public:
private:
FTPDirectoryDocument(Frame*);
- virtual Tokenizer* createTokenizer();
+ virtual PassRefPtr<Tokenizer> createTokenizer();
};
} // namespace WebCore
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/FrameLoader.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/FrameLoader.cpp
index 16ebe9c..575f14e 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/FrameLoader.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/FrameLoader.cpp
@@ -218,7 +218,8 @@ FrameLoader::~FrameLoader()
void FrameLoader::init()
{
- // this somewhat odd set of steps is needed to give the frame an initial empty document
+ // This somewhat odd set of steps gives the frame an initial empty document.
+ // It would be better if this could be done with even fewer steps.
m_isDisplayingInitialEmptyDocument = false;
m_creatingInitialEmptyDocument = true;
setPolicyDocumentLoader(m_client->createDocumentLoader(ResourceRequest(KURL(ParsedURLString, "")), SubstituteData()).get());
@@ -488,9 +489,7 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F
if (!m_outgoingReferrer.isEmpty())
frameRequest.resourceRequest().setHTTPReferrer(m_outgoingReferrer);
- if (strcmp(action, "GET") == 0)
- u.setQuery(formData->flattenToString());
- else {
+ if (strcmp(action, "POST") == 0) {
frameRequest.resourceRequest().setHTTPMethod("POST");
frameRequest.resourceRequest().setHTTPBody(formData);
@@ -499,9 +498,13 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F
frameRequest.resourceRequest().setHTTPContentType(contentType);
else // contentType must be "multipart/form-data"
frameRequest.resourceRequest().setHTTPContentType(contentType + "; boundary=" + boundary);
+ frameRequest.resourceRequest().setURL(u);
+ } else {
+ KURL requestURL(u);
+ requestURL.setQuery(formData->flattenToString());
+ frameRequest.resourceRequest().setURL(requestURL);
}
- frameRequest.resourceRequest().setURL(u);
addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin());
targetFrame->redirectScheduler()->scheduleFormSubmission(frameRequest, lockHistory, event, formState);
@@ -621,7 +624,8 @@ KURL FrameLoader::iconURL()
return KURL();
KURL url;
- url.setProtocol(m_URL.protocol());
+ bool couldSetProtocol = url.setProtocol(m_URL.protocol());
+ ASSERT_UNUSED(couldSetProtocol, couldSetProtocol);
url.setHost(m_URL.host());
if (m_URL.hasPort())
url.setPort(m_URL.port());
@@ -2843,10 +2847,8 @@ void FrameLoader::didReceiveServerRedirectForProvisionalLoadForFrame()
void FrameLoader::finishedLoadingDocument(DocumentLoader* loader)
{
// FIXME: Platforms shouldn't differ here!
-#if PLATFORM(WIN) || PLATFORM(CHROMIUM)
if (m_creatingInitialEmptyDocument)
return;
-#endif
// If loading a webarchive, run through webarchive machinery
const String& responseMIMEType = loader->responseMIMEType();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/ImageDocument.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/ImageDocument.cpp
index 9b5598d..f9e29b4 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/ImageDocument.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/ImageDocument.cpp
@@ -77,7 +77,10 @@ private:
class ImageTokenizer : public Tokenizer {
public:
- ImageTokenizer(ImageDocument* doc) : m_doc(doc) {}
+ static PassRefPtr<ImageTokenizer> create(ImageDocument* doc)
+ {
+ return adoptRef(new ImageTokenizer(doc));
+ }
virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
@@ -87,6 +90,8 @@ public:
virtual bool writeRawData(const char* data, int len);
private:
+ ImageTokenizer(ImageDocument* doc) : m_doc(doc) {}
+private:
ImageDocument* m_doc;
};
@@ -173,9 +178,9 @@ ImageDocument::ImageDocument(Frame* frame)
setParseMode(Compat);
}
-Tokenizer* ImageDocument::createTokenizer()
+PassRefPtr<Tokenizer> ImageDocument::createTokenizer()
{
- return new ImageTokenizer(this);
+ return ImageTokenizer::create(this);
}
void ImageDocument::createDocumentStructure()
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/ImageDocument.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/ImageDocument.h
index 080b250..2aec3b8 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/ImageDocument.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/ImageDocument.h
@@ -49,7 +49,7 @@ public:
private:
ImageDocument(Frame*);
- virtual Tokenizer* createTokenizer();
+ virtual PassRefPtr<Tokenizer> createTokenizer();
virtual bool isImageDocument() const { return true; }
void createDocumentStructure();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/MediaDocument.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/MediaDocument.cpp
index 656d0a0..c162770 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/MediaDocument.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/MediaDocument.cpp
@@ -53,9 +53,14 @@ using namespace HTMLNames;
class MediaTokenizer : public Tokenizer {
public:
- MediaTokenizer(Document* doc) : m_doc(doc), m_mediaElement(0) {}
+ static PassRefPtr<MediaTokenizer> create(Document* doc)
+ {
+ return adoptRef(new MediaTokenizer(doc));
+ }
private:
+ MediaTokenizer(Document* doc) : m_doc(doc), m_mediaElement(0) {}
+
virtual void write(const SegmentedString&, bool appendData);
virtual void stopParsing();
virtual void finish();
@@ -145,9 +150,9 @@ MediaDocument::~MediaDocument()
ASSERT(!m_replaceMediaElementTimer.isActive());
}
-Tokenizer* MediaDocument::createTokenizer()
+PassRefPtr<Tokenizer> MediaDocument::createTokenizer()
{
- return new MediaTokenizer(this);
+ return MediaTokenizer::create(this);
}
void MediaDocument::defaultEventHandler(Event* event)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/MediaDocument.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/MediaDocument.h
index aa751ab..398fb3f 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/MediaDocument.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/MediaDocument.h
@@ -46,7 +46,7 @@ private:
MediaDocument(Frame*);
virtual bool isMediaDocument() const { return true; }
- virtual Tokenizer* createTokenizer();
+ virtual PassRefPtr<Tokenizer> createTokenizer();
virtual void defaultEventHandler(Event*);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/PluginDocument.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/PluginDocument.cpp
index 788691f..dcdb7e7 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/PluginDocument.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/PluginDocument.cpp
@@ -46,9 +46,14 @@ using namespace HTMLNames;
class PluginTokenizer : public Tokenizer {
public:
- PluginTokenizer(Document* doc) : m_doc(doc), m_embedElement(0) {}
+ static PassRefPtr<PluginTokenizer> create(Document* doc)
+ {
+ return adoptRef(new PluginTokenizer(doc));
+ }
private:
+ PluginTokenizer(Document* doc) : m_doc(doc), m_embedElement(0) {}
+
virtual void write(const SegmentedString&, bool appendData);
virtual void stopParsing();
virtual void finish();
@@ -142,9 +147,9 @@ PluginDocument::PluginDocument(Frame* frame)
setParseMode(Compat);
}
-Tokenizer* PluginDocument::createTokenizer()
+PassRefPtr<Tokenizer> PluginDocument::createTokenizer()
{
- return new PluginTokenizer(this);
+ return PluginTokenizer::create(this);
}
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/PluginDocument.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/PluginDocument.h
index 1d5c964..62231bd 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/PluginDocument.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/PluginDocument.h
@@ -40,7 +40,7 @@ private:
PluginDocument(Frame*);
virtual bool isPluginDocument() const { return true; }
- virtual Tokenizer* createTokenizer();
+ virtual PassRefPtr<Tokenizer> createTokenizer();
};
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/RedirectScheduler.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/RedirectScheduler.cpp
index e53a1db..d0a03dc 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/RedirectScheduler.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/RedirectScheduler.cpp
@@ -160,17 +160,21 @@ void RedirectScheduler::scheduleRedirect(double delay, const String& url)
if (url.isEmpty())
return;
- // We want a new history item if the refresh timeout is > 1 second.
+ // We want a new back/forward list item if the refresh timeout is > 1 second.
if (!m_scheduledRedirection || delay <= m_scheduledRedirection->delay)
schedule(new ScheduledRedirection(delay, url, true, delay <= 1, false, false));
}
-bool RedirectScheduler::mustLockBackForwardList(Frame* targetFrame)
+bool RedirectScheduler::mustLockBackForwardList(Frame* targetFrame, bool wasUserGesture)
{
+ // Non-user navigation before the page has loaded should not create a new back/forward item.
+ // See https://webkit.org/b/42861 for the original motivation for this.
+ if (!wasUserGesture && targetFrame->loader()->documentLoader() && targetFrame->loader()->documentLoader()->isLoadingInAPISense())
+ return true;
+
// Navigation of a subframe during loading of an ancestor frame does not create a new back/forward item.
// The definition of "during load" is any time before all handlers for the load event have been run.
// See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation for this.
-
for (Frame* ancestor = targetFrame->tree()->parent(); ancestor; ancestor = ancestor->tree()->parent()) {
Document* document = ancestor->document();
if (!ancestor->loader()->isComplete() || (document && document->processingLoadEvent()))
@@ -187,7 +191,7 @@ void RedirectScheduler::scheduleLocationChange(const String& url, const String&
if (url.isEmpty())
return;
- lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame);
+ lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame, wasUserGesture);
FrameLoader* loader = m_frame->loader();
@@ -223,7 +227,7 @@ void RedirectScheduler::scheduleFormSubmission(const FrameLoadRequest& frameRequ
// to match IE and Opera.
// See https://bugs.webkit.org/show_bug.cgi?id=32383 for the original motivation for this.
- bool lockBackForwardList = mustLockBackForwardList(m_frame) || (formState->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent());
+ bool lockBackForwardList = mustLockBackForwardList(m_frame, m_frame->script()->processingUserGesture()) || (formState->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent());
schedule(new ScheduledRedirection(frameRequest, lockHistory, lockBackForwardList, event, formState, duringLoad));
}
@@ -365,9 +369,13 @@ void RedirectScheduler::startTimer()
m_scheduledRedirection->lockBackForwardList);
return;
case ScheduledRedirection::formSubmission:
- // FIXME: It would make sense to report form submissions as client redirects too.
- // But we didn't do that in the past when form submission used a separate delay
- // mechanism, so doing it will be a behavior change.
+ if (m_scheduledRedirection->toldClient)
+ return;
+ m_scheduledRedirection->toldClient = true;
+ loader->clientRedirected(m_scheduledRedirection->frameRequest.resourceRequest().url(),
+ m_scheduledRedirection->delay,
+ currentTime() + m_timer.nextFireInterval(),
+ m_scheduledRedirection->lockBackForwardList);
return;
case ScheduledRedirection::historyNavigation:
// Don't report history navigations.
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/RedirectScheduler.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/RedirectScheduler.h
index 005a173..6e9a5f8 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/RedirectScheduler.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/RedirectScheduler.h
@@ -69,7 +69,7 @@ private:
void timerFired(Timer<RedirectScheduler>*);
void schedule(PassOwnPtr<ScheduledRedirection>);
- static bool mustLockBackForwardList(Frame* targetFrame);
+ static bool mustLockBackForwardList(Frame* targetFrame, bool mustLockIfDuringLoad);
Frame* m_frame;
Timer<RedirectScheduler> m_timer;
@@ -78,4 +78,4 @@ private:
} // namespace WebCore
-#endif // FrameLoader_h
+#endif // RedirectScheduler_h
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/TextDocument.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/TextDocument.cpp
index a3d7061..258dfeb 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/TextDocument.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/TextDocument.cpp
@@ -40,9 +40,15 @@ using namespace HTMLNames;
class TextTokenizer : public Tokenizer {
public:
- TextTokenizer(Document*);
+ static PassRefPtr<TextTokenizer> create(Document* document)
+ {
+ return adoptRef(new TextTokenizer(document));
+ }
+ static PassRefPtr<TextTokenizer> create(HTMLViewSourceDocument* document)
+ {
+ return adoptRef(new TextTokenizer(document));
+ }
virtual ~TextTokenizer();
- TextTokenizer(HTMLViewSourceDocument*);
virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
@@ -59,7 +65,11 @@ public:
m_size = newSize;
}
}
-
+
+private:
+ TextTokenizer(Document*);
+ TextTokenizer(HTMLViewSourceDocument*);
+
private:
Document* m_doc;
Element* m_preElement;
@@ -183,14 +193,14 @@ TextDocument::TextDocument(Frame* frame)
{
}
-Tokenizer* TextDocument::createTokenizer()
+PassRefPtr<Tokenizer> TextDocument::createTokenizer()
{
- return new TextTokenizer(this);
+ return TextTokenizer::create(this);
}
-Tokenizer* createTextTokenizer(HTMLViewSourceDocument* document)
+PassRefPtr<Tokenizer> createTextTokenizer(HTMLViewSourceDocument* document)
{
- return new TextTokenizer(document);
+ return TextTokenizer::create(document);
}
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/TextDocument.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/TextDocument.h
index 53e3074..42cfd82 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/loader/TextDocument.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/loader/TextDocument.h
@@ -41,10 +41,10 @@ public:
private:
TextDocument(Frame*);
- virtual Tokenizer* createTokenizer();
+ virtual PassRefPtr<Tokenizer> createTokenizer();
};
-Tokenizer* createTextTokenizer(HTMLViewSourceDocument*);
+PassRefPtr<Tokenizer> createTextTokenizer(HTMLViewSourceDocument*);
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMSelection.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMSelection.cpp
index 0d21c56..d4576a1 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMSelection.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMSelection.cpp
@@ -207,6 +207,10 @@ void DOMSelection::collapse(Node* node, int offset, ExceptionCode& ec)
ec = INDEX_SIZE_ERR;
return;
}
+
+ if (!isValidForPosition(node))
+ return;
+
m_frame->selection()->moveTo(VisiblePosition(node, offset, DOWNSTREAM));
}
@@ -244,6 +248,10 @@ void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extent
ec = INDEX_SIZE_ERR;
return;
}
+
+ if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode))
+ return;
+
VisiblePosition visibleBase = VisiblePosition(baseNode, baseOffset, DOWNSTREAM);
VisiblePosition visibleExtent = VisiblePosition(extentNode, extentOffset, DOWNSTREAM);
@@ -258,6 +266,10 @@ void DOMSelection::setPosition(Node* node, int offset, ExceptionCode& ec)
ec = INDEX_SIZE_ERR;
return;
}
+
+ if (!isValidForPosition(node))
+ return;
+
m_frame->selection()->moveTo(VisiblePosition(node, offset, DOWNSTREAM));
}
@@ -320,14 +332,16 @@ void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec)
ec = TYPE_MISMATCH_ERR;
return;
}
+
if (offset < 0 || offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->childNodeCount())) {
ec = INDEX_SIZE_ERR;
return;
}
- SelectionController* selection = m_frame->selection();
- selection->expandUsingGranularity(CharacterGranularity);
- selection->setExtent(VisiblePosition(node, offset, DOWNSTREAM));
+ if (!isValidForPosition(node))
+ return;
+
+ m_frame->selection()->setExtent(VisiblePosition(node, offset, DOWNSTREAM));
}
PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
@@ -413,6 +427,8 @@ void DOMSelection::deleteFromDocument()
selection->modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity);
RefPtr<Range> selectedRange = selection->selection().toNormalizedRange();
+ if (!selectedRange)
+ return;
ExceptionCode ec = 0;
selectedRange->deleteContents(ec);
@@ -429,7 +445,7 @@ bool DOMSelection::containsNode(const Node* n, bool allowPartial) const
SelectionController* selection = m_frame->selection();
- if (!n || selection->isNone())
+ if (!n || m_frame->document() != n->document() || selection->isNone())
return false;
Node* parentNode = n->parentNode();
@@ -472,4 +488,12 @@ String DOMSelection::toString()
return plainText(m_frame->selection()->selection().toNormalizedRange().get());
}
+bool DOMSelection::isValidForPosition(Node* node) const
+{
+ ASSERT(m_frame);
+ if (!node)
+ return true;
+ return node->document() == m_frame->document();
+}
+
} // namespace WebCore
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMSelection.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMSelection.h
index e0fe1e3..0287e44 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMSelection.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMSelection.h
@@ -96,6 +96,7 @@ namespace WebCore {
// Convenience method for accessors, does not NULL check m_frame.
const VisibleSelection& visibleSelection() const;
+ bool isValidForPosition(Node*) const;
Frame* m_frame;
};
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMTimer.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMTimer.cpp
index d6e15f7..12b53d7 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMTimer.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMTimer.cpp
@@ -48,7 +48,7 @@ static int timerNestingLevel = 0;
static int lastUsedTimeoutId = 0;
#endif
-DOMTimer::DOMTimer(ScriptExecutionContext* context, ScheduledAction* action, int timeout, bool singleShot)
+DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot)
: ActiveDOMObject(context, this)
, m_action(action)
, m_nextFireInterval(0)
@@ -89,7 +89,7 @@ DOMTimer::~DOMTimer()
scriptExecutionContext()->removeTimeout(m_timeoutId);
}
-int DOMTimer::install(ScriptExecutionContext* context, ScheduledAction* action, int timeout, bool singleShot)
+int DOMTimer::install(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot)
{
// DOMTimer constructor links the new timer into a list of ActiveDOMObjects held by the 'context'.
// The timer is deleted when context is deleted (DOMTimer::contextDestroyed) or explicitly via DOMTimer::removeById(),
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMTimer.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMTimer.h
index 14a343e..aa0d677 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMTimer.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMTimer.h
@@ -29,20 +29,21 @@
#define DOMTimer_h
#include "ActiveDOMObject.h"
+#include "ScheduledAction.h"
#include "Timer.h"
#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
class InspectorTimelineAgent;
- class ScheduledAction;
class DOMTimer : public TimerBase, public ActiveDOMObject {
public:
virtual ~DOMTimer();
// Creates a new timer owned by specified ScriptExecutionContext, starts it
// and returns its Id.
- static int install(ScriptExecutionContext*, ScheduledAction*, int timeout, bool singleShot);
+ static int install(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
static void removeById(ScriptExecutionContext*, int timeoutId);
// ActiveDOMObject
@@ -64,7 +65,7 @@ namespace WebCore {
#endif
private:
- DOMTimer(ScriptExecutionContext*, ScheduledAction*, int timeout, bool singleShot);
+ DOMTimer(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
virtual void fired();
int m_timeoutId;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMWindow.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMWindow.cpp
index ad922b5..6136c59 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMWindow.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMWindow.cpp
@@ -1185,7 +1185,7 @@ void DOMWindow::scrollTo(int x, int y) const
m_frame->document()->updateLayoutIgnorePendingStylesheets();
- FrameView* view = m_frame->view();
+ RefPtr<FrameView> view = m_frame->view();
if (!view)
return;
@@ -1274,24 +1274,40 @@ void DOMWindow::resizeTo(float width, float height) const
page->chrome()->setWindowRect(fr);
}
-int DOMWindow::setTimeout(ScheduledAction* action, int timeout)
+int DOMWindow::setTimeout(PassOwnPtr<ScheduledAction> action, int timeout, ExceptionCode& ec)
{
- return DOMTimer::install(scriptExecutionContext(), action, timeout, true);
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context) {
+ ec = INVALID_ACCESS_ERR;
+ return -1;
+ }
+ return DOMTimer::install(context, action, timeout, true);
}
void DOMWindow::clearTimeout(int timeoutId)
{
- DOMTimer::removeById(scriptExecutionContext(), timeoutId);
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context)
+ return;
+ DOMTimer::removeById(context, timeoutId);
}
-int DOMWindow::setInterval(ScheduledAction* action, int timeout)
+int DOMWindow::setInterval(PassOwnPtr<ScheduledAction> action, int timeout, ExceptionCode& ec)
{
- return DOMTimer::install(scriptExecutionContext(), action, timeout, false);
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context) {
+ ec = INVALID_ACCESS_ERR;
+ return -1;
+ }
+ return DOMTimer::install(context, action, timeout, false);
}
void DOMWindow::clearInterval(int timeoutId)
{
- DOMTimer::removeById(scriptExecutionContext(), timeoutId);
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context)
+ return;
+ DOMTimer::removeById(context, timeoutId);
}
bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMWindow.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMWindow.h
index 50dade0..7371581 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/DOMWindow.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/DOMWindow.h
@@ -238,9 +238,9 @@ namespace WebCore {
void resizeTo(float width, float height) const;
// Timers
- int setTimeout(ScheduledAction*, int timeout);
+ int setTimeout(PassOwnPtr<ScheduledAction>, int timeout, ExceptionCode&);
void clearTimeout(int timeoutId);
- int setInterval(ScheduledAction*, int timeout);
+ int setInterval(PassOwnPtr<ScheduledAction>, int timeout, ExceptionCode&);
void clearInterval(int timeoutId);
// Events
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/FocusController.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/FocusController.cpp
index 4e296c0..11f7c96 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/FocusController.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/FocusController.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nuanti Ltd.
- * Copyright (c) 2010, 2011 ACCESS CO., LTD. All rights reserved.
+ * Copyright (c) 2010, 2011, 2013 ACCESS CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -416,8 +416,15 @@ void FocusController::findFocusableNodeInDirection(Node* outer, Node* focusedNod
candidate.enclosingScrollableBox = candidateParent.node;
} else if (!isInRootDocument(outer)) {
+#if PLATFORM(WKC)
+ if (outer->parent() && outer->parent()->isDocumentNode()) {
+ Document* document = static_cast<Document*>(outer->parent());
+ candidate.enclosingScrollableBox = static_cast<Node*>(document->ownerElement());
+ }
+#else
if (Document* document = static_cast<Document*>(outer->parent()))
candidate.enclosingScrollableBox = static_cast<Node*>(document->ownerElement());
+#endif
} else if (isScrollableContainerNode(outer->parent()))
candidate.enclosingScrollableBox = outer->parent();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/Frame.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/Frame.cpp
index 0f31f90..5a871c2 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/Frame.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/Frame.cpp
@@ -1,1978 +1,1992 @@
-/*
- * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
- * 1999 Lars Knoll <knoll@kde.org>
- * 1999 Antti Koivisto <koivisto@kde.org>
- * 2000 Simon Hausmann <hausmann@kde.org>
- * 2000 Stefan Schimanski <1Stein@gmx.de>
- * 2001 George Staikos <staikos@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
- * Copyright (c) 2010 ACCESS CO., LTD. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "Frame.h"
-
-#include "ApplyStyleCommand.h"
-#include "BeforeUnloadEvent.h"
-#include "CSSComputedStyleDeclaration.h"
-#include "CSSMutableStyleDeclaration.h"
-#include "CSSProperty.h"
-#include "CSSPropertyNames.h"
-#include "CachedCSSStyleSheet.h"
-#include "Chrome.h"
-#include "DOMWindow.h"
-#include "DocLoader.h"
-#include "DocumentType.h"
-#include "EditingText.h"
-#include "EditorClient.h"
-#include "EventNames.h"
-#include "FloatQuad.h"
-#include "FocusController.h"
-#include "FrameLoader.h"
-#include "FrameLoaderClient.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "HTMLDocument.h"
-#include "HTMLFormControlElement.h"
-#include "HTMLFormElement.h"
-#include "HTMLFrameElementBase.h"
-#include "HTMLNames.h"
-#include "HTMLTableCellElement.h"
-#include "HitTestResult.h"
-#include "Logging.h"
-#include "MediaFeatureNames.h"
-#include "Navigator.h"
-#include "NodeList.h"
-#include "Page.h"
-#include "PageGroup.h"
-#include "RegularExpression.h"
-#include "RenderPart.h"
-#include "RenderTableCell.h"
-#include "RenderTextControl.h"
-#include "RenderTheme.h"
-#include "RenderView.h"
-#include "ScriptController.h"
-#include "ScriptSourceCode.h"
-#include "ScriptValue.h"
-#include "Settings.h"
-#include "TextIterator.h"
-#include "TextResourceDecoder.h"
-#include "UserContentURLPattern.h"
-#include "XMLNames.h"
-#include "htmlediting.h"
-#include "markup.h"
-#include "npruntime_impl.h"
-#include "visible_units.h"
-#include <wtf/RefCountedLeakCounter.h>
-#include <wtf/StdLibExtras.h>
-
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
-#import <Carbon/Carbon.h>
-#endif
-
-#if USE(JSC)
-#include "JSDOMWindowShell.h"
-#include "runtime_root.h"
-#endif
-
-#if ENABLE(SVG)
-#include "SVGDocument.h"
-#include "SVGDocumentExtensions.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-#endif
-
-#if ENABLE(WML)
-#include "WMLNames.h"
-#endif
-
-#if ENABLE(MATHML)
-#include "MathMLNames.h"
-#endif
-
-using namespace std;
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-#ifndef NDEBUG
-#if PLATFORM(WKC)
-static WTF::RefCountedLeakCounter* gFrameCounter = 0;
-#else
-static WTF::RefCountedLeakCounter frameCounter("Frame");
-#endif
-#endif
-
-static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement)
-{
- if (!ownerElement)
- return 0;
- return ownerElement->document()->frame();
-}
-
-Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* frameLoaderClient)
- : m_page(page)
- , m_treeNode(this, parentFromOwnerElement(ownerElement))
- , m_loader(this, frameLoaderClient)
- , m_redirectScheduler(this)
- , m_ownerElement(ownerElement)
- , m_script(this)
- , m_selectionGranularity(CharacterGranularity)
- , m_selectionController(this)
- , m_caretBlinkTimer(this, &Frame::caretBlinkTimerFired)
- , m_editor(this)
- , m_eventHandler(this)
- , m_animationController(this)
- , m_lifeSupportTimer(this, &Frame::lifeSupportTimerFired)
-#if ENABLE(ORIENTATION_EVENTS)
- , m_orientation(0)
-#endif
- , m_caretVisible(false)
- , m_caretPaint(true)
- , m_highlightTextMatches(false)
- , m_inViewSourceMode(false)
- , m_needsReapplyStyles(false)
- , m_isDisconnected(false)
- , m_excludeFromTextSearch(false)
-{
- Frame* parent = parentFromOwnerElement(ownerElement);
- m_zoomFactor = parent ? parent->m_zoomFactor : 1.0f;
-
- AtomicString::init();
- HTMLNames::init();
- QualifiedName::init();
- MediaFeatureNames::init();
-
-#if ENABLE(SVG)
- SVGNames::init();
- XLinkNames::init();
-#endif
-
-#if ENABLE(WML)
- WMLNames::init();
-#endif
-
-#if ENABLE(MATHML)
- MathMLNames::init();
-#endif
-
- XMLNames::init();
-
- if (!ownerElement)
- page->setMainFrame(this);
- else {
- page->incrementFrameCount();
- // Make sure we will not end up with two frames referencing the same owner element.
- ASSERT((!(ownerElement->m_contentFrame)) || (ownerElement->m_contentFrame->ownerElement() != ownerElement));
- ownerElement->m_contentFrame = this;
- }
-
-#ifndef NDEBUG
-#if PLATFORM(WKC)
- if (!gFrameCounter) {
- gFrameCounter = new WTF::RefCountedLeakCounter("Frame");
- }
- WTF::RefCountedLeakCounter& frameCounter = *gFrameCounter;
-#endif
- frameCounter.increment();
-#endif
-}
-
-Frame::~Frame()
-{
- setView(0);
- loader()->cancelAndClear();
-
- // FIXME: We should not be doing all this work inside the destructor
-
- ASSERT(!m_lifeSupportTimer.isActive());
-
-#ifndef NDEBUG
-#if PLATFORM(WKC)
- WTF::RefCountedLeakCounter& frameCounter = *gFrameCounter;
-#endif
- frameCounter.decrement();
-#endif
-
- disconnectOwnerElement();
-
- if (m_domWindow)
- m_domWindow->disconnectFrame();
- script()->clearWindowShell();
-
- HashSet<DOMWindow*>::iterator end = m_liveFormerWindows.end();
- for (HashSet<DOMWindow*>::iterator it = m_liveFormerWindows.begin(); it != end; ++it)
- (*it)->disconnectFrame();
-
- if (m_view) {
- m_view->hide();
- m_view->clearFrame();
- }
-
- ASSERT(!m_lifeSupportTimer.isActive());
-}
-
-void Frame::init()
-{
- m_loader.init();
-}
-
-FrameLoader* Frame::loader() const
-{
- return &m_loader;
-}
-
-RedirectScheduler* Frame::redirectScheduler() const
-{
- return &m_redirectScheduler;
-}
-
-FrameView* Frame::view() const
-{
- return m_view.get();
-}
-
-void Frame::setView(PassRefPtr<FrameView> view)
-{
- // We the custom scroll bars as early as possible to prevent m_doc->detach()
- // from messing with the view such that its scroll bars won't be torn down.
- // FIXME: We should revisit this.
- if (m_view)
- m_view->detachCustomScrollbars();
-
- // Detach the document now, so any onUnload handlers get run - if
- // we wait until the view is destroyed, then things won't be
- // hooked up enough for some JavaScript calls to work.
- if (!view && m_doc && m_doc->attached() && !m_doc->inPageCache()) {
- // FIXME: We don't call willRemove here. Why is that OK?
- m_doc->detach();
- if (m_view)
- m_view->unscheduleRelayout();
- }
- eventHandler()->clear();
-
- m_view = view;
-
- // Only one form submission is allowed per view of a part.
- // Since this part may be getting reused as a result of being
- // pulled from the back/forward cache, reset this flag.
- loader()->resetMultipleFormSubmissionProtection();
-}
-
-ScriptController* Frame::script()
-{
- return &m_script;
-}
-
-Document* Frame::document() const
-{
- return m_doc.get();
-}
-
-void Frame::setDocument(PassRefPtr<Document> newDoc)
-{
- if (m_doc && m_doc->attached() && !m_doc->inPageCache()) {
- // FIXME: We don't call willRemove here. Why is that OK?
- m_doc->detach();
- }
-
- m_doc = newDoc;
- if (m_doc && selection()->isFocusedAndActive())
- setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
-
- if (m_doc && !m_doc->attached())
- m_doc->attach();
-
- // Update the cached 'document' property, which is now stale.
- m_script.updateDocument();
-}
-
-#if ENABLE(ORIENTATION_EVENTS)
-void Frame::sendOrientationChangeEvent(int orientation)
-{
- m_orientation = orientation;
- if (Document* doc = document())
- doc->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false));
-}
-#endif // ENABLE(ORIENTATION_EVENTS)
-
-Settings* Frame::settings() const
-{
- return m_page ? m_page->settings() : 0;
-}
-
-String Frame::selectedText() const
-{
- return plainText(selection()->toNormalizedRange().get());
-}
-
-IntRect Frame::firstRectForRange(Range* range) const
-{
- int extraWidthToEndOfLine = 0;
- ExceptionCode ec = 0;
- ASSERT(range->startContainer(ec));
- ASSERT(range->endContainer(ec));
-
- InlineBox* startInlineBox;
- int startCaretOffset;
- range->startPosition().getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);
-
- RenderObject* startRenderer = range->startContainer(ec)->renderer();
- IntRect startCaretRect = startRenderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
- if (startCaretRect != IntRect())
- startCaretRect = startRenderer->localToAbsoluteQuad(FloatRect(startCaretRect)).enclosingBoundingBox();
-
- InlineBox* endInlineBox;
- int endCaretOffset;
- range->endPosition().getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);
-
- RenderObject* endRenderer = range->endContainer(ec)->renderer();
- IntRect endCaretRect = endRenderer->localCaretRect(endInlineBox, endCaretOffset);
- if (endCaretRect != IntRect())
- endCaretRect = endRenderer->localToAbsoluteQuad(FloatRect(endCaretRect)).enclosingBoundingBox();
-
- if (startCaretRect.y() == endCaretRect.y()) {
- // start and end are on the same line
- return IntRect(min(startCaretRect.x(), endCaretRect.x()),
- startCaretRect.y(),
- abs(endCaretRect.x() - startCaretRect.x()),
- max(startCaretRect.height(), endCaretRect.height()));
- }
-
- // start and end aren't on the same line, so go from start to the end of its line
- return IntRect(startCaretRect.x(),
- startCaretRect.y(),
- startCaretRect.width() + extraWidthToEndOfLine,
- startCaretRect.height());
-}
-
-SelectionController* Frame::selection() const
-{
- return &m_selectionController;
-}
-
-Editor* Frame::editor() const
-{
- return &m_editor;
-}
-
-TextGranularity Frame::selectionGranularity() const
-{
- return m_selectionGranularity;
-}
-
-void Frame::setSelectionGranularity(TextGranularity granularity)
-{
- m_selectionGranularity = granularity;
-}
-
-SelectionController* Frame::dragCaretController() const
-{
- return m_page->dragCaretController();
-}
-
-
-AnimationController* Frame::animation() const
-{
- return &m_animationController;
-}
-
-#if PLATFORM(WKC)
-static RegularExpression* gWordRegExp = 0;
-#endif
-
-static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
-{
- // REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being
- // the same across calls. We can't do that.
-
-#if PLATFORM(WKC)
- if (!gWordRegExp) {
- gWordRegExp = new RegularExpression("\\w", TextCaseSensitive);
- }
- RegularExpression& wordRegExp = *gWordRegExp;
-#else
- DEFINE_STATIC_LOCAL(RegularExpression, wordRegExp, ("\\w", TextCaseSensitive));
-#endif
- String pattern("(");
- unsigned int numLabels = labels.size();
- unsigned int i;
- for (i = 0; i < numLabels; i++) {
- String label = labels[i];
-
- bool startsWithWordChar = false;
- bool endsWithWordChar = false;
- if (label.length()) {
- startsWithWordChar = wordRegExp.match(label.substring(0, 1)) >= 0;
- endsWithWordChar = wordRegExp.match(label.substring(label.length() - 1, 1)) >= 0;
- }
-
- if (i)
- pattern.append("|");
- // Search for word boundaries only if label starts/ends with "word characters".
- // If we always searched for word boundaries, this wouldn't work for languages
- // such as Japanese.
- if (startsWithWordChar)
- pattern.append("\\b");
- pattern.append(label);
- if (endsWithWordChar)
- pattern.append("\\b");
- }
- pattern.append(")");
- return new RegularExpression(pattern, TextCaseInsensitive);
-}
-
-String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell)
-{
- RenderObject* cellRenderer = cell->renderer();
-
- if (cellRenderer && cellRenderer->isTableCell()) {
- RenderTableCell* tableCellRenderer = toRenderTableCell(cellRenderer);
- RenderTableCell* cellAboveRenderer = tableCellRenderer->table()->cellAbove(tableCellRenderer);
-
- if (cellAboveRenderer) {
- HTMLTableCellElement* aboveCell =
- static_cast<HTMLTableCellElement*>(cellAboveRenderer->node());
-
- if (aboveCell) {
- // search within the above cell we found for a match
- for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) {
- if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
- // For each text chunk, run the regexp
- String nodeString = n->nodeValue();
- int pos = regExp->searchRev(nodeString);
- if (pos >= 0)
- return nodeString.substring(pos, regExp->matchedLength());
- }
- }
- }
- }
- }
- // Any reason in practice to search all cells in that are above cell?
- return String();
-}
-
-String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element)
-{
- OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
- // We stop searching after we've seen this many chars
- const unsigned int charsSearchedThreshold = 500;
- // This is the absolute max we search. We allow a little more slop than
- // charsSearchedThreshold, to make it more likely that we'll search whole nodes.
- const unsigned int maxCharsSearched = 600;
- // If the starting element is within a table, the cell that contains it
- HTMLTableCellElement* startingTableCell = 0;
- bool searchedCellAbove = false;
-
- // walk backwards in the node tree, until another element, or form, or end of tree
- int unsigned lengthSearched = 0;
- Node* n;
- for (n = element->traversePreviousNode();
- n && lengthSearched < charsSearchedThreshold;
- n = n->traversePreviousNode())
- {
- if (n->hasTagName(formTag)
- || (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement()))
- {
- // We hit another form element or the start of the form - bail out
- break;
- } else if (n->hasTagName(tdTag) && !startingTableCell) {
- startingTableCell = static_cast<HTMLTableCellElement*>(n);
- } else if (n->hasTagName(trTag) && startingTableCell) {
- String result = searchForLabelsAboveCell(regExp.get(), startingTableCell);
- if (!result.isEmpty())
- return result;
- searchedCellAbove = true;
- } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
- // For each text chunk, run the regexp
- String nodeString = n->nodeValue();
- // add 100 for slop, to make it more likely that we'll search whole nodes
- if (lengthSearched + nodeString.length() > maxCharsSearched)
- nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
- int pos = regExp->searchRev(nodeString);
- if (pos >= 0)
- return nodeString.substring(pos, regExp->matchedLength());
- lengthSearched += nodeString.length();
- }
- }
-
- // If we started in a cell, but bailed because we found the start of the form or the
- // previous element, we still might need to search the row above us for a label.
- if (startingTableCell && !searchedCellAbove)
- return searchForLabelsAboveCell(regExp.get(), startingTableCell);
- return String();
-}
-
-String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element)
-{
- String name = element->getAttribute(nameAttr);
- if (name.isEmpty())
- return String();
-
- // Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
- replace(name, RegularExpression("\\d", TextCaseSensitive), " ");
- name.replace('_', ' ');
-
- OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
- // Use the largest match we can find in the whole name string
- int pos;
- int length;
- int bestPos = -1;
- int bestLength = -1;
- int start = 0;
- do {
- pos = regExp->match(name, start);
- if (pos != -1) {
- length = regExp->matchedLength();
- if (length >= bestLength) {
- bestPos = pos;
- bestLength = length;
- }
- start = pos + 1;
- }
- } while (pos != -1);
-
- if (bestPos != -1)
- return name.substring(bestPos, bestLength);
- return String();
-}
-
-const VisibleSelection& Frame::mark() const
-{
- return m_mark;
-}
-
-void Frame::setMark(const VisibleSelection& s)
-{
- ASSERT(!s.base().node() || s.base().node()->document() == document());
- ASSERT(!s.extent().node() || s.extent().node()->document() == document());
- ASSERT(!s.start().node() || s.start().node()->document() == document());
- ASSERT(!s.end().node() || s.end().node()->document() == document());
-
- m_mark = s;
-}
-
-void Frame::notifyRendererOfSelectionChange(bool userTriggered)
-{
- RenderObject* renderer = 0;
- if (selection()->rootEditableElement())
- renderer = selection()->rootEditableElement()->shadowAncestorNode()->renderer();
-
- // If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
- if (renderer && renderer->isTextControl())
- toRenderTextControl(renderer)->selectionChanged(userTriggered);
-}
-
-void Frame::setCaretVisible(bool flag)
-{
- if (m_caretVisible == flag)
- return;
- clearCaretRectIfNeeded();
- m_caretVisible = flag;
- selectionLayoutChanged();
-}
-
-void Frame::clearCaretRectIfNeeded()
-{
-#if ENABLE(TEXT_CARET)
- if (m_caretPaint) {
- m_caretPaint = false;
- selection()->invalidateCaretRect();
- }
-#endif
-}
-
-// Helper function that tells whether a particular node is an element that has an entire
-// Frame and FrameView, a <frame>, <iframe>, or <object>.
-static bool isFrameElement(const Node *n)
-{
- if (!n)
- return false;
- RenderObject *renderer = n->renderer();
- if (!renderer || !renderer->isWidget())
- return false;
- Widget* widget = toRenderWidget(renderer)->widget();
- return widget && widget->isFrameView();
-}
-
-void Frame::setFocusedNodeIfNeeded()
-{
- if (selection()->isNone() || !selection()->isFocused())
- return;
-
- bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
- if (caretBrowsing) {
- Node* anchor = enclosingAnchorElement(selection()->base());
- if (anchor) {
- page()->focusController()->setFocusedNode(anchor, this);
- return;
- }
- }
-
- Node* target = selection()->rootEditableElement();
- if (target) {
- RenderObject* renderer = target->renderer();
-
- // Walk up the render tree to search for a node to focus.
- // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
- while (renderer) {
- // We don't want to set focus on a subframe when selecting in a parent frame,
- // so add the !isFrameElement check here. There's probably a better way to make this
- // work in the long term, but this is the safest fix at this time.
- if (target && target->isMouseFocusable() && !isFrameElement(target)) {
- page()->focusController()->setFocusedNode(target, this);
- return;
- }
- renderer = renderer->parent();
- if (renderer)
- target = renderer->node();
- }
- document()->setFocusedNode(0);
- }
-
- if (caretBrowsing)
- page()->focusController()->setFocusedNode(0, this);
-}
-
-void Frame::selectionLayoutChanged()
-{
- bool caretRectChanged = selection()->recomputeCaretRect();
-
-#if ENABLE(TEXT_CARET)
- bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
- bool shouldBlink = m_caretVisible
- && selection()->isCaret() && (selection()->isContentEditable() || caretBrowsing);
-
- // If the caret moved, stop the blink timer so we can restart with a
- // black caret in the new location.
- if (caretRectChanged || !shouldBlink)
- m_caretBlinkTimer.stop();
-
- // Start blinking with a black caret. Be sure not to restart if we're
- // already blinking in the right location.
- if (shouldBlink && !m_caretBlinkTimer.isActive()) {
- if (double blinkInterval = page()->theme()->caretBlinkInterval())
- m_caretBlinkTimer.startRepeating(blinkInterval);
-
- if (!m_caretPaint) {
- m_caretPaint = true;
- selection()->invalidateCaretRect();
- }
- }
-#else
- if (!caretRectChanged)
- return;
-#endif
-
-#if 1
- // added at webkit.org trunk r62873 (the fix is modified for this revision)
+/*
+ * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+ * 1999 Lars Knoll <knoll@kde.org>
+ * 1999 Antti Koivisto <koivisto@kde.org>
+ * 2000 Simon Hausmann <hausmann@kde.org>
+ * 2000 Stefan Schimanski <1Stein@gmx.de>
+ * 2001 George Staikos <staikos@kde.org>
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (c) 2010 ACCESS CO., LTD. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "Frame.h"
+
+#include "ApplyStyleCommand.h"
+#include "BeforeUnloadEvent.h"
+#include "CSSComputedStyleDeclaration.h"
+#include "CSSMutableStyleDeclaration.h"
+#include "CSSProperty.h"
+#include "CSSPropertyNames.h"
+#include "CachedCSSStyleSheet.h"
+#include "Chrome.h"
+#include "DOMWindow.h"
+#include "DocLoader.h"
+#include "DocumentType.h"
+#include "EditingText.h"
+#include "EditorClient.h"
+#include "EventNames.h"
+#include "FloatQuad.h"
+#include "FocusController.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "HTMLDocument.h"
+#include "HTMLFormControlElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLFrameElementBase.h"
+#include "HTMLNames.h"
+#include "HTMLTableCellElement.h"
+#include "HitTestResult.h"
+#include "Logging.h"
+#include "MediaFeatureNames.h"
+#include "Navigator.h"
+#include "NodeList.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "RegularExpression.h"
+#include "RenderPart.h"
+#include "RenderTableCell.h"
+#include "RenderTextControl.h"
+#include "RenderTheme.h"
+#include "RenderView.h"
+#include "ScriptController.h"
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
+#include "Settings.h"
+#include "TextIterator.h"
+#include "TextResourceDecoder.h"
+#include "UserContentURLPattern.h"
+#include "XMLNames.h"
+#include "htmlediting.h"
+#include "markup.h"
+#include "npruntime_impl.h"
+#include "visible_units.h"
+#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/StdLibExtras.h>
+
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+#import <Carbon/Carbon.h>
+#endif
+
+#if USE(JSC)
+#include "JSDOMWindowShell.h"
+#include "runtime_root.h"
+#endif
+
+#if ENABLE(SVG)
+#include "SVGDocument.h"
+#include "SVGDocumentExtensions.h"
+#include "SVGNames.h"
+#include "XLinkNames.h"
+#endif
+
+#if ENABLE(WML)
+#include "WMLNames.h"
+#endif
+
+#if ENABLE(MATHML)
+#include "MathMLNames.h"
+#endif
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+#ifndef NDEBUG
+#if PLATFORM(WKC)
+static WTF::RefCountedLeakCounter* gFrameCounter = 0;
+#else
+static WTF::RefCountedLeakCounter frameCounter("Frame");
+#endif
+#endif
+
+static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement)
+{
+ if (!ownerElement)
+ return 0;
+ return ownerElement->document()->frame();
+}
+
+Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* frameLoaderClient)
+ : m_page(page)
+ , m_treeNode(this, parentFromOwnerElement(ownerElement))
+ , m_loader(this, frameLoaderClient)
+ , m_redirectScheduler(this)
+ , m_ownerElement(ownerElement)
+ , m_script(this)
+ , m_selectionGranularity(CharacterGranularity)
+ , m_selectionController(this)
+ , m_caretBlinkTimer(this, &Frame::caretBlinkTimerFired)
+ , m_editor(this)
+ , m_eventHandler(this)
+ , m_animationController(this)
+ , m_lifeSupportTimer(this, &Frame::lifeSupportTimerFired)
+#if ENABLE(ORIENTATION_EVENTS)
+ , m_orientation(0)
+#endif
+ , m_caretVisible(false)
+ , m_caretPaint(true)
+ , m_highlightTextMatches(false)
+ , m_inViewSourceMode(false)
+ , m_needsReapplyStyles(false)
+ , m_isDisconnected(false)
+ , m_excludeFromTextSearch(false)
+{
+ Frame* parent = parentFromOwnerElement(ownerElement);
+ m_zoomFactor = parent ? parent->m_zoomFactor : 1.0f;
+
+ AtomicString::init();
+ HTMLNames::init();
+ QualifiedName::init();
+ MediaFeatureNames::init();
+
+#if ENABLE(SVG)
+ SVGNames::init();
+ XLinkNames::init();
+#endif
+
+#if ENABLE(WML)
+ WMLNames::init();
+#endif
+
+#if ENABLE(MATHML)
+ MathMLNames::init();
+#endif
+
+ XMLNames::init();
+
+ if (!ownerElement)
+ page->setMainFrame(this);
+ else {
+ page->incrementFrameCount();
+ // Make sure we will not end up with two frames referencing the same owner element.
+ ASSERT((!(ownerElement->m_contentFrame)) || (ownerElement->m_contentFrame->ownerElement() != ownerElement));
+ ownerElement->m_contentFrame = this;
+ }
+
+#ifndef NDEBUG
+#if PLATFORM(WKC)
+ if (!gFrameCounter) {
+ gFrameCounter = new WTF::RefCountedLeakCounter("Frame");
+ }
+ WTF::RefCountedLeakCounter& frameCounter = *gFrameCounter;
+#endif
+ frameCounter.increment();
+#endif
+}
+
+Frame::~Frame()
+{
+ setView(0);
+ loader()->cancelAndClear();
+
+ // FIXME: We should not be doing all this work inside the destructor
+
+ ASSERT(!m_lifeSupportTimer.isActive());
+
+#ifndef NDEBUG
+#if PLATFORM(WKC)
+ WTF::RefCountedLeakCounter& frameCounter = *gFrameCounter;
+#endif
+ frameCounter.decrement();
+#endif
+
+ disconnectOwnerElement();
+
+ if (m_domWindow)
+ m_domWindow->disconnectFrame();
+ script()->clearWindowShell();
+
+ HashSet<DOMWindow*>::iterator end = m_liveFormerWindows.end();
+ for (HashSet<DOMWindow*>::iterator it = m_liveFormerWindows.begin(); it != end; ++it)
+ (*it)->disconnectFrame();
+
+ if (m_view) {
+ m_view->hide();
+ m_view->clearFrame();
+ }
+
+ ASSERT(!m_lifeSupportTimer.isActive());
+}
+
+void Frame::init()
+{
+ m_loader.init();
+}
+
+FrameLoader* Frame::loader() const
+{
+ return &m_loader;
+}
+
+RedirectScheduler* Frame::redirectScheduler() const
+{
+ return &m_redirectScheduler;
+}
+
+FrameView* Frame::view() const
+{
+ return m_view.get();
+}
+
+void Frame::setView(PassRefPtr<FrameView> view)
+{
+ // We the custom scroll bars as early as possible to prevent m_doc->detach()
+ // from messing with the view such that its scroll bars won't be torn down.
+ // FIXME: We should revisit this.
+ if (m_view)
+ m_view->detachCustomScrollbars();
+
+ // Detach the document now, so any onUnload handlers get run - if
+ // we wait until the view is destroyed, then things won't be
+ // hooked up enough for some JavaScript calls to work.
+ if (!view && m_doc && m_doc->attached() && !m_doc->inPageCache()) {
+ // FIXME: We don't call willRemove here. Why is that OK?
+ m_doc->detach();
+ if (m_view)
+ m_view->unscheduleRelayout();
+ }
+ eventHandler()->clear();
+
+ m_view = view;
+
+ // Only one form submission is allowed per view of a part.
+ // Since this part may be getting reused as a result of being
+ // pulled from the back/forward cache, reset this flag.
+ loader()->resetMultipleFormSubmissionProtection();
+}
+
+ScriptController* Frame::script()
+{
+ return &m_script;
+}
+
+Document* Frame::document() const
+{
+ return m_doc.get();
+}
+
+void Frame::setDocument(PassRefPtr<Document> newDoc)
+{
+ if (m_doc && m_doc->attached() && !m_doc->inPageCache()) {
+ // FIXME: We don't call willRemove here. Why is that OK?
+ m_doc->detach();
+ }
+
+ m_doc = newDoc;
+ if (m_doc && selection()->isFocusedAndActive())
+ setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
+
+ if (m_doc && !m_doc->attached())
+ m_doc->attach();
+
+ // Update the cached 'document' property, which is now stale.
+ m_script.updateDocument();
+}
+
+#if ENABLE(ORIENTATION_EVENTS)
+void Frame::sendOrientationChangeEvent(int orientation)
+{
+ m_orientation = orientation;
+ if (Document* doc = document())
+ doc->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false));
+}
+#endif // ENABLE(ORIENTATION_EVENTS)
+
+Settings* Frame::settings() const
+{
+ return m_page ? m_page->settings() : 0;
+}
+
+String Frame::selectedText() const
+{
+ return plainText(selection()->toNormalizedRange().get());
+}
+
+IntRect Frame::firstRectForRange(Range* range) const
+{
+ int extraWidthToEndOfLine = 0;
+ ExceptionCode ec = 0;
+ ASSERT(range->startContainer(ec));
+ ASSERT(range->endContainer(ec));
+
+ InlineBox* startInlineBox;
+ int startCaretOffset;
+ range->startPosition().getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);
+
+ RenderObject* startRenderer = range->startContainer(ec)->renderer();
+ IntRect startCaretRect = startRenderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
+ if (startCaretRect != IntRect())
+ startCaretRect = startRenderer->localToAbsoluteQuad(FloatRect(startCaretRect)).enclosingBoundingBox();
+
+ InlineBox* endInlineBox;
+ int endCaretOffset;
+ range->endPosition().getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);
+
+ RenderObject* endRenderer = range->endContainer(ec)->renderer();
+ IntRect endCaretRect = endRenderer->localCaretRect(endInlineBox, endCaretOffset);
+ if (endCaretRect != IntRect())
+ endCaretRect = endRenderer->localToAbsoluteQuad(FloatRect(endCaretRect)).enclosingBoundingBox();
+
+ if (startCaretRect.y() == endCaretRect.y()) {
+ // start and end are on the same line
+ return IntRect(min(startCaretRect.x(), endCaretRect.x()),
+ startCaretRect.y(),
+ abs(endCaretRect.x() - startCaretRect.x()),
+ max(startCaretRect.height(), endCaretRect.height()));
+ }
+
+ // start and end aren't on the same line, so go from start to the end of its line
+ return IntRect(startCaretRect.x(),
+ startCaretRect.y(),
+ startCaretRect.width() + extraWidthToEndOfLine,
+ startCaretRect.height());
+}
+
+SelectionController* Frame::selection() const
+{
+ return &m_selectionController;
+}
+
+Editor* Frame::editor() const
+{
+ return &m_editor;
+}
+
+TextGranularity Frame::selectionGranularity() const
+{
+ return m_selectionGranularity;
+}
+
+void Frame::setSelectionGranularity(TextGranularity granularity)
+{
+ m_selectionGranularity = granularity;
+}
+
+SelectionController* Frame::dragCaretController() const
+{
+ return m_page->dragCaretController();
+}
+
+
+AnimationController* Frame::animation() const
+{
+ return &m_animationController;
+}
+
+#if PLATFORM(WKC)
+static RegularExpression* gWordRegExp = 0;
+#endif
+
+static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
+{
+ // REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being
+ // the same across calls. We can't do that.
+
+#if PLATFORM(WKC)
+ if (!gWordRegExp) {
+ gWordRegExp = new RegularExpression("\\w", TextCaseSensitive);
+ }
+ RegularExpression& wordRegExp = *gWordRegExp;
+#else
+ DEFINE_STATIC_LOCAL(RegularExpression, wordRegExp, ("\\w", TextCaseSensitive));
+#endif
+ String pattern("(");
+ unsigned int numLabels = labels.size();
+ unsigned int i;
+ for (i = 0; i < numLabels; i++) {
+ String label = labels[i];
+
+ bool startsWithWordChar = false;
+ bool endsWithWordChar = false;
+ if (label.length()) {
+ startsWithWordChar = wordRegExp.match(label.substring(0, 1)) >= 0;
+ endsWithWordChar = wordRegExp.match(label.substring(label.length() - 1, 1)) >= 0;
+ }
+
+ if (i)
+ pattern.append("|");
+ // Search for word boundaries only if label starts/ends with "word characters".
+ // If we always searched for word boundaries, this wouldn't work for languages
+ // such as Japanese.
+ if (startsWithWordChar)
+ pattern.append("\\b");
+ pattern.append(label);
+ if (endsWithWordChar)
+ pattern.append("\\b");
+ }
+ pattern.append(")");
+ return new RegularExpression(pattern, TextCaseInsensitive);
+}
+
+String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell)
+{
+ RenderObject* cellRenderer = cell->renderer();
+
+ if (cellRenderer && cellRenderer->isTableCell()) {
+ RenderTableCell* tableCellRenderer = toRenderTableCell(cellRenderer);
+ RenderTableCell* cellAboveRenderer = tableCellRenderer->table()->cellAbove(tableCellRenderer);
+
+ if (cellAboveRenderer) {
+ HTMLTableCellElement* aboveCell =
+ static_cast<HTMLTableCellElement*>(cellAboveRenderer->node());
+
+ if (aboveCell) {
+ // search within the above cell we found for a match
+ for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) {
+ if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
+ // For each text chunk, run the regexp
+ String nodeString = n->nodeValue();
+ int pos = regExp->searchRev(nodeString);
+ if (pos >= 0)
+ return nodeString.substring(pos, regExp->matchedLength());
+ }
+ }
+ }
+ }
+ }
+ // Any reason in practice to search all cells in that are above cell?
+ return String();
+}
+
+String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element)
+{
+ OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
+ // We stop searching after we've seen this many chars
+ const unsigned int charsSearchedThreshold = 500;
+ // This is the absolute max we search. We allow a little more slop than
+ // charsSearchedThreshold, to make it more likely that we'll search whole nodes.
+ const unsigned int maxCharsSearched = 600;
+ // If the starting element is within a table, the cell that contains it
+ HTMLTableCellElement* startingTableCell = 0;
+ bool searchedCellAbove = false;
+
+ // walk backwards in the node tree, until another element, or form, or end of tree
+ int unsigned lengthSearched = 0;
+ Node* n;
+ for (n = element->traversePreviousNode();
+ n && lengthSearched < charsSearchedThreshold;
+ n = n->traversePreviousNode())
+ {
+ if (n->hasTagName(formTag)
+ || (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement()))
+ {
+ // We hit another form element or the start of the form - bail out
+ break;
+ } else if (n->hasTagName(tdTag) && !startingTableCell) {
+ startingTableCell = static_cast<HTMLTableCellElement*>(n);
+ } else if (n->hasTagName(trTag) && startingTableCell) {
+ String result = searchForLabelsAboveCell(regExp.get(), startingTableCell);
+ if (!result.isEmpty())
+ return result;
+ searchedCellAbove = true;
+ } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
+ // For each text chunk, run the regexp
+ String nodeString = n->nodeValue();
+ // add 100 for slop, to make it more likely that we'll search whole nodes
+ if (lengthSearched + nodeString.length() > maxCharsSearched)
+ nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
+ int pos = regExp->searchRev(nodeString);
+ if (pos >= 0)
+ return nodeString.substring(pos, regExp->matchedLength());
+ lengthSearched += nodeString.length();
+ }
+ }
+
+ // If we started in a cell, but bailed because we found the start of the form or the
+ // previous element, we still might need to search the row above us for a label.
+ if (startingTableCell && !searchedCellAbove)
+ return searchForLabelsAboveCell(regExp.get(), startingTableCell);
+ return String();
+}
+
+String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element)
+{
+ String name = element->getAttribute(nameAttr);
+ if (name.isEmpty())
+ return String();
+
+ // Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
+ replace(name, RegularExpression("\\d", TextCaseSensitive), " ");
+ name.replace('_', ' ');
+
+ OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
+ // Use the largest match we can find in the whole name string
+ int pos;
+ int length;
+ int bestPos = -1;
+ int bestLength = -1;
+ int start = 0;
+ do {
+ pos = regExp->match(name, start);
+ if (pos != -1) {
+ length = regExp->matchedLength();
+ if (length >= bestLength) {
+ bestPos = pos;
+ bestLength = length;
+ }
+ start = pos + 1;
+ }
+ } while (pos != -1);
+
+ if (bestPos != -1)
+ return name.substring(bestPos, bestLength);
+ return String();
+}
+
+const VisibleSelection& Frame::mark() const
+{
+ return m_mark;
+}
+
+void Frame::setMark(const VisibleSelection& s)
+{
+ ASSERT(!s.base().node() || s.base().node()->document() == document());
+ ASSERT(!s.extent().node() || s.extent().node()->document() == document());
+ ASSERT(!s.start().node() || s.start().node()->document() == document());
+ ASSERT(!s.end().node() || s.end().node()->document() == document());
+
+ m_mark = s;
+}
+
+void Frame::notifyRendererOfSelectionChange(bool userTriggered)
+{
+ RenderObject* renderer = 0;
+ if (selection()->rootEditableElement())
+ renderer = selection()->rootEditableElement()->shadowAncestorNode()->renderer();
+
+ // If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
+ if (renderer && renderer->isTextControl())
+ toRenderTextControl(renderer)->selectionChanged(userTriggered);
+}
+
+void Frame::setCaretVisible(bool flag)
+{
+ if (m_caretVisible == flag)
+ return;
+ clearCaretRectIfNeeded();
+ m_caretVisible = flag;
+ selection()->setNeedsDisplayUpdate();
+}
+
+void Frame::clearCaretRectIfNeeded()
+{
+#if ENABLE(TEXT_CARET)
+ if (m_caretPaint) {
+ m_caretPaint = false;
+ selection()->invalidateCaretRect();
+ }
+#endif
+}
+
+// Helper function that tells whether a particular node is an element that has an entire
+// Frame and FrameView, a <frame>, <iframe>, or <object>.
+static bool isFrameElement(const Node *n)
+{
+ if (!n)
+ return false;
+ RenderObject *renderer = n->renderer();
+ if (!renderer || !renderer->isWidget())
+ return false;
+ Widget* widget = toRenderWidget(renderer)->widget();
+ return widget && widget->isFrameView();
+}
+
+void Frame::setFocusedNodeIfNeeded()
+{
+ if (selection()->isNone() || !selection()->isFocused())
+ return;
+
+ bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
+ if (caretBrowsing) {
+ Node* anchor = enclosingAnchorElement(selection()->base());
+ if (anchor) {
+ page()->focusController()->setFocusedNode(anchor, this);
+ return;
+ }
+ }
+
+ Node* target = selection()->rootEditableElement();
+ if (target) {
+ RenderObject* renderer = target->renderer();
+
+ // Walk up the render tree to search for a node to focus.
+ // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
+ while (renderer) {
+ // We don't want to set focus on a subframe when selecting in a parent frame,
+ // so add the !isFrameElement check here. There's probably a better way to make this
+ // work in the long term, but this is the safest fix at this time.
+ if (target && target->isMouseFocusable() && !isFrameElement(target)) {
+ page()->focusController()->setFocusedNode(target, this);
+ return;
+ }
+ renderer = renderer->parent();
+ if (renderer)
+ target = renderer->node();
+ }
+ document()->setFocusedNode(0);
+ }
+
+ if (caretBrowsing)
+ page()->focusController()->setFocusedNode(0, this);
+}
+
+#if PLATFORM(WKC)
+static bool gAlreadyInSelectionLayoutChanged;
+#endif
+
+void Frame::selectionLayoutChanged()
+{
+ selection()->setNeedsDisplayUpdate(false);
+
+#if ENABLE(TEXT_CARET)
+ if (gAlreadyInSelectionLayoutChanged)
+ return;
+
+ gAlreadyInSelectionLayoutChanged = true;
+
+ bool caretRectChanged = selection()->recomputeCaretRect();
+
+ bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
+ bool shouldBlink = m_caretVisible
+ && selection()->isCaret() && (selection()->isContentEditable() || caretBrowsing);
+
+ // If the caret moved, stop the blink timer so we can restart with a
+ // black caret in the new location.
+ if (caretRectChanged || !shouldBlink)
+ m_caretBlinkTimer.stop();
+
+ // Start blinking with a black caret. Be sure not to restart if we're
+ // already blinking in the right location.
+ if (shouldBlink && !m_caretBlinkTimer.isActive()) {
+ if (double blinkInterval = page()->theme()->caretBlinkInterval())
+ m_caretBlinkTimer.startRepeating(blinkInterval);
+
+ if (!m_caretPaint) {
+ m_caretPaint = true;
+ selection()->invalidateCaretRect();
+ }
+ }
+ gAlreadyInSelectionLayoutChanged = false;
+#endif
+
+#if 1
+ // added at webkit.org trunk r62873 (the fix is modified for this revision)
// We need to update style in case the node containing the selection is made display:none.
- document()->updateStyleIfNeeded();
-#endif
-
- RenderView* view = contentRenderer();
- if (!view)
- return;
-
- VisibleSelection selection = this->selection()->selection();
-
- if (!selection.isRange())
- view->clearSelection();
- else {
- // Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection.
- // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', and that 'bar' is selected. If we pass [foo, 3]
- // as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected
- // and will fill the gap before 'bar'.
- Position startPos = selection.start();
- if (startPos.downstream().isCandidate())
- startPos = startPos.downstream();
- Position endPos = selection.end();
- if (endPos.upstream().isCandidate())
- endPos = endPos.upstream();
-
- // We can get into a state where the selection endpoints map to the same VisiblePosition when a selection is deleted
- // because we don't yet notify the SelectionController of text removal.
- if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
- RenderObject *startRenderer = startPos.node()->renderer();
- RenderObject *endRenderer = endPos.node()->renderer();
- view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset());
- }
- }
-}
-
-void Frame::caretBlinkTimerFired(Timer<Frame>*)
-{
-#if ENABLE(TEXT_CARET)
- ASSERT(m_caretVisible);
- ASSERT(selection()->isCaret());
- bool caretPaint = m_caretPaint;
- if (selection()->isCaretBlinkingSuspended() && caretPaint)
- return;
- m_caretPaint = !caretPaint;
- selection()->invalidateCaretRect();
-#endif
-}
-
-void Frame::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
-{
-#if ENABLE(TEXT_CARET)
- if (m_caretPaint && m_caretVisible)
- selection()->paintCaret(p, tx, ty, clipRect);
-#endif
-}
-
-void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
-{
-#if ENABLE(TEXT_CARET)
- SelectionController* dragCaretController = m_page->dragCaretController();
- ASSERT(dragCaretController->selection().isCaret());
- if (dragCaretController->selection().start().node()->document()->frame() == this)
- dragCaretController->paintCaret(p, tx, ty, clipRect);
-#endif
-}
-
-float Frame::zoomFactor() const
-{
- return m_zoomFactor;
-}
-
-bool Frame::isZoomFactorTextOnly() const
-{
- return m_page->settings()->zoomsTextOnly();
-}
-
-bool Frame::shouldApplyTextZoom() const
-{
- if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
- return false;
-#if ENABLE(SVG)
- if (m_doc->isSVGDocument())
- return false;
-#endif
- return true;
-}
-
-bool Frame::shouldApplyPageZoom() const
-{
- if (m_zoomFactor == 1.0f || isZoomFactorTextOnly())
- return false;
-#if ENABLE(SVG)
- if (m_doc->isSVGDocument())
- return false;
-#endif
- return true;
-}
-
-void Frame::setZoomFactor(float percent, bool isTextOnly)
-{
- if (m_zoomFactor == percent && isZoomFactorTextOnly() == isTextOnly)
- return;
-
-#if ENABLE(SVG)
- // SVG doesn't care if the zoom factor is text only. It will always apply a
- // zoom to the whole SVG.
- if (m_doc->isSVGDocument()) {
- if (!static_cast<SVGDocument*>(m_doc.get())->zoomAndPanEnabled())
- return;
- m_zoomFactor = percent;
- m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom.
- if (m_doc->renderer())
- m_doc->renderer()->repaint();
- return;
- }
-#endif
-
- m_zoomFactor = percent;
- m_page->settings()->setZoomsTextOnly(isTextOnly);
-
- m_doc->recalcStyle(Node::Force);
-
- for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
- child->setZoomFactor(m_zoomFactor, isTextOnly);
-
- if (m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout())
- view()->layout();
-}
-
-void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
-{
- m_doc->setPrinting(printing);
- view()->setMediaType(printing ? "print" : "screen");
- m_doc->updateStyleSelector();
- view()->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize);
-
- for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
- child->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize);
-}
-
-void Frame::setJSStatusBarText(const String& text)
-{
- ASSERT(m_doc); // Client calls shouldn't be made when the frame is in inconsistent state.
- m_kjsStatusBarText = text;
- if (m_page)
- m_page->chrome()->setStatusbarText(this, m_kjsStatusBarText);
-}
-
-void Frame::setJSDefaultStatusBarText(const String& text)
-{
- ASSERT(m_doc); // Client calls shouldn't be made when the frame is in inconsistent state.
- m_kjsDefaultStatusBarText = text;
- if (m_page)
- m_page->chrome()->setStatusbarText(this, m_kjsDefaultStatusBarText);
-}
-
-String Frame::jsStatusBarText() const
-{
- return m_kjsStatusBarText;
-}
-
-String Frame::jsDefaultStatusBarText() const
-{
- return m_kjsDefaultStatusBarText;
-}
-
-void Frame::setNeedsReapplyStyles()
-{
- // When the frame is not showing web content, it doesn't make sense to apply styles.
- // If we tried, we'd end up doing things with the document, but the document, if one
- // exists, is not currently shown and should be in the page cache.
- if (!m_loader.client()->hasHTMLView())
- return;
-
- if (m_needsReapplyStyles)
- return;
-
- m_needsReapplyStyles = true;
-
- // FrameView's "layout" timer includes reapplyStyles, so despite its
- // name, it's what we want to call here.
- if (view())
- view()->scheduleRelayout();
-}
-
-bool Frame::needsReapplyStyles() const
-{
- return m_needsReapplyStyles;
-}
-
-void Frame::reapplyStyles()
-{
- m_needsReapplyStyles = false;
-
- // FIXME: This call doesn't really make sense in a function called reapplyStyles.
- // We should probably eventually move it into its own function.
- m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically());
-
- // FIXME: It's not entirely clear why the following is needed.
- // The document automatically does this as required when you set the style sheet.
- // But we had problems when this code was removed. Details are in
- // <http://bugs.webkit.org/show_bug.cgi?id=8079>.
- m_doc->updateStyleSelector();
-}
-
-void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
-{
- if (!m_page)
- return;
-
- // Walk the hashtable. Inject by world.
- const UserScriptMap* userScripts = m_page->group().userScripts();
- if (!userScripts)
- return;
- UserScriptMap::const_iterator end = userScripts->end();
- for (UserScriptMap::const_iterator it = userScripts->begin(); it != end; ++it)
- injectUserScriptsForWorld(it->first.get(), *it->second, injectionTime);
-}
-
-void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime)
-{
- if (userScripts.isEmpty())
- return;
-
- Document* doc = document();
- if (!doc)
- return;
-
- Vector<ScriptSourceCode> sourceCode;
- unsigned count = userScripts.size();
- for (unsigned i = 0; i < count; ++i) {
- UserScript* script = userScripts[i].get();
- if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->whitelist(), script->blacklist()))
- m_script.evaluateInWorld(ScriptSourceCode(script->source(), script->url()), world);
- }
-}
-
-bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const
-{
- return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
-}
-
-bool Frame::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const
-{
- return editor()->client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(),
- affinity, stillSelecting);
-}
-
-bool Frame::shouldDeleteSelection(const VisibleSelection& selection) const
-{
- return editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());
-}
-
-bool Frame::isContentEditable() const
-{
- if (m_editor.clientIsEditable())
- return true;
- return m_doc->inDesignMode();
-}
-
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
-const short enableRomanKeyboardsOnly = -23;
-#endif
-void Frame::setUseSecureKeyboardEntry(bool enable)
-{
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
- if (enable == IsSecureEventInputEnabled())
- return;
- if (enable) {
- EnableSecureEventInput();
-#ifdef BUILDING_ON_TIGER
- KeyScript(enableRomanKeyboardsOnly);
-#else
- // WebKit substitutes nil for input context when in password field, which corresponds to null TSMDocument. So, there is
- // no need to call TSMGetActiveDocument(), which may return an incorrect result when selection hasn't been yet updated
- // after focusing a node.
- CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
- TSMSetDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag, sizeof(CFArrayRef), &inputSources);
- CFRelease(inputSources);
-#endif
- } else {
- DisableSecureEventInput();
-#ifdef BUILDING_ON_TIGER
- KeyScript(smKeyEnableKybds);
-#else
- TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag);
-#endif
- }
-#endif
-}
-
-void Frame::updateSecureKeyboardEntryIfActive()
-{
- if (selection()->isFocusedAndActive())
- setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
-}
-
-CSSMutableStyleDeclaration *Frame::typingStyle() const
-{
- return m_typingStyle.get();
-}
-
-void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
-{
- m_typingStyle = style;
-}
-
-void Frame::clearTypingStyle()
-{
- m_typingStyle = 0;
-}
-
-void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
-{
- if (!style || !style->length()) {
- clearTypingStyle();
- return;
- }
-
- // Calculate the current typing style.
- RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
- if (typingStyle()) {
- typingStyle()->merge(mutableStyle.get());
- mutableStyle = typingStyle();
- }
-
- RefPtr<CSSValue> unicodeBidi;
- RefPtr<CSSValue> direction;
- if (editingAction == EditActionSetWritingDirection) {
- unicodeBidi = mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
- direction = mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
- }
-
- Node* node = selection()->selection().visibleStart().deepEquivalent().node();
- computedStyle(node)->diff(mutableStyle.get());
-
- if (editingAction == EditActionSetWritingDirection && unicodeBidi) {
- ASSERT(unicodeBidi->isPrimitiveValue());
- mutableStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
- if (direction) {
- ASSERT(direction->isPrimitiveValue());
- mutableStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
- }
- }
-
- // Handle block styles, substracting these from the typing style.
- RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
- blockStyle->diff(mutableStyle.get());
- if (blockStyle->length() > 0)
- applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
-
- // Set the remaining style as the typing style.
- m_typingStyle = mutableStyle.release();
-}
-
-String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
-{
- Node *nodeToRemove;
- RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
- if (!selectionStyle)
- return String();
-
- String value = selectionStyle->getPropertyValue(stylePropertyID);
-
- if (nodeToRemove) {
- ExceptionCode ec = 0;
- nodeToRemove->remove(ec);
- ASSERT(!ec);
- }
-
- return value;
-}
-
-PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nodeToRemove) const
-{
- nodeToRemove = 0;
-
- if (selection()->isNone())
- return 0;
-
- RefPtr<Range> range(selection()->toNormalizedRange());
- Position pos = range->editingStartPosition();
-
- Element *elem = pos.element();
- if (!elem)
- return 0;
-
- RefPtr<Element> styleElement = elem;
- ExceptionCode ec = 0;
-
- if (m_typingStyle) {
- styleElement = document()->createElement(spanTag, false);
-
- styleElement->setAttribute(styleAttr, m_typingStyle->cssText().impl(), ec);
- ASSERT(!ec);
-
- styleElement->appendChild(document()->createEditingTextNode(""), ec);
- ASSERT(!ec);
-
- if (elem->renderer() && elem->renderer()->canHaveChildren()) {
- elem->appendChild(styleElement, ec);
- } else {
- Node *parent = elem->parent();
- Node *next = elem->nextSibling();
-
- if (next)
- parent->insertBefore(styleElement, next, ec);
- else
- parent->appendChild(styleElement, ec);
- }
- ASSERT(!ec);
-
- nodeToRemove = styleElement.get();
- }
-
- return computedStyle(styleElement.release());
-}
-
-void Frame::textFieldDidBeginEditing(Element* e)
-{
- if (editor()->client())
- editor()->client()->textFieldDidBeginEditing(e);
-}
-
-void Frame::textFieldDidEndEditing(Element* e)
-{
- if (editor()->client())
- editor()->client()->textFieldDidEndEditing(e);
-}
-
-void Frame::textDidChangeInTextField(Element* e)
-{
- if (editor()->client())
- editor()->client()->textDidChangeInTextField(e);
-}
-
-bool Frame::doTextFieldCommandFromEvent(Element* e, KeyboardEvent* ke)
-{
- if (editor()->client())
- return editor()->client()->doTextFieldCommandFromEvent(e, ke);
-
- return false;
-}
-
-void Frame::textWillBeDeletedInTextField(Element* input)
-{
- if (editor()->client())
- editor()->client()->textWillBeDeletedInTextField(input);
-}
-
-void Frame::textDidChangeInTextArea(Element* e)
-{
- if (editor()->client())
- editor()->client()->textDidChangeInTextArea(e);
-}
-
-void Frame::applyEditingStyleToBodyElement() const
-{
- RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
- unsigned len = list->length();
- for (unsigned i = 0; i < len; i++)
- applyEditingStyleToElement(static_cast<Element*>(list->item(i)));
-}
-
-void Frame::removeEditingStyleFromBodyElement() const
-{
- RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
- unsigned len = list->length();
- for (unsigned i = 0; i < len; i++)
- removeEditingStyleFromElement(static_cast<Element*>(list->item(i)));
-}
-
-void Frame::applyEditingStyleToElement(Element* element) const
-{
- if (!element)
- return;
-
- CSSStyleDeclaration* style = element->style();
- ASSERT(style);
-
- ExceptionCode ec = 0;
- style->setProperty(CSSPropertyWordWrap, "break-word", false, ec);
- ASSERT(!ec);
- style->setProperty(CSSPropertyWebkitNbspMode, "space", false, ec);
- ASSERT(!ec);
- style->setProperty(CSSPropertyWebkitLineBreak, "after-white-space", false, ec);
- ASSERT(!ec);
-}
-
-void Frame::removeEditingStyleFromElement(Element*) const
-{
-}
-
-#ifndef NDEBUG
-#if PLATFORM(WKC)
-static HashSet<Frame*>* gStaticKeepAliveSet = 0;
-static HashSet<Frame*>& keepAliveSet()
-{
- if (!gStaticKeepAliveSet) {
- gStaticKeepAliveSet = new HashSet<Frame*>();
- }
- HashSet<Frame*>& staticKeepAliveSet = *gStaticKeepAliveSet;
- return staticKeepAliveSet;
-}
-#else
-static HashSet<Frame*>& keepAliveSet()
-{
- DEFINE_STATIC_LOCAL(HashSet<Frame*>, staticKeepAliveSet, ());
- return staticKeepAliveSet;
-}
-#endif
-#endif
-
-void Frame::keepAlive()
-{
- if (m_lifeSupportTimer.isActive())
- return;
-#ifndef NDEBUG
- keepAliveSet().add(this);
-#endif
- ref();
- m_lifeSupportTimer.startOneShot(0);
-}
-
-#ifndef NDEBUG
-void Frame::cancelAllKeepAlive()
-{
- HashSet<Frame*>::iterator end = keepAliveSet().end();
- for (HashSet<Frame*>::iterator it = keepAliveSet().begin(); it != end; ++it) {
- Frame* frame = *it;
- frame->m_lifeSupportTimer.stop();
- frame->deref();
- }
- keepAliveSet().clear();
-}
-#endif
-
-void Frame::lifeSupportTimerFired(Timer<Frame>*)
-{
-#ifndef NDEBUG
- keepAliveSet().remove(this);
-#endif
- deref();
-}
-
-void Frame::clearDOMWindow()
-{
- if (m_domWindow) {
- m_liveFormerWindows.add(m_domWindow.get());
- m_domWindow->clear();
- }
- m_domWindow = 0;
-}
-
-RenderView* Frame::contentRenderer() const
-{
- Document* doc = document();
- if (!doc)
- return 0;
- RenderObject* object = doc->renderer();
- if (!object)
- return 0;
- ASSERT(object->isRenderView());
- return toRenderView(object);
-}
-
-HTMLFrameOwnerElement* Frame::ownerElement() const
-{
- return m_ownerElement;
-}
-
-RenderPart* Frame::ownerRenderer() const
-{
- HTMLFrameOwnerElement* ownerElement = m_ownerElement;
- if (!ownerElement)
- return 0;
- RenderObject* object = ownerElement->renderer();
- if (!object)
- return 0;
- // FIXME: If <object> is ever fixed to disassociate itself from frames
- // that it has started but canceled, then this can turn into an ASSERT
- // since m_ownerElement would be 0 when the load is canceled.
- // https://bugs.webkit.org/show_bug.cgi?id=18585
- if (!object->isRenderPart())
- return 0;
- return toRenderPart(object);
-}
-
-bool Frame::isDisconnected() const
-{
- return m_isDisconnected;
-}
-
-void Frame::setIsDisconnected(bool isDisconnected)
-{
- m_isDisconnected = isDisconnected;
-}
-
-bool Frame::excludeFromTextSearch() const
-{
- return m_excludeFromTextSearch;
-}
-
-void Frame::setExcludeFromTextSearch(bool exclude)
-{
- m_excludeFromTextSearch = exclude;
-}
-
-// returns FloatRect because going through IntRect would truncate any floats
-FloatRect Frame::selectionBounds(bool clipToVisibleContent) const
-{
- RenderView* root = contentRenderer();
- FrameView* view = m_view.get();
- if (!root || !view)
- return IntRect();
-
- IntRect selectionRect = root->selectionBounds(clipToVisibleContent);
- return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
-}
-
-void Frame::selectionTextRects(Vector<FloatRect>& rects, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent) const
-{
- RenderView* root = contentRenderer();
- if (!root)
- return;
-
- RefPtr<Range> selectedRange = selection()->toNormalizedRange();
-
- FloatRect visibleContentRect = m_view->visibleContentRect();
-
- // FIMXE: we are appending empty rects to the list for those that fall outside visibleContentRect.
- // We may not want to do that.
- if (respectTransforms) {
- Vector<FloatQuad> quads;
- selectedRange->textQuads(quads, true);
-
- unsigned size = quads.size();
- for (unsigned i = 0; i < size; ++i) {
- IntRect currRect = quads[i].enclosingBoundingBox();
- if (clipToVisibleContent)
- rects.append(intersection(currRect, visibleContentRect));
- else
- rects.append(currRect);
- }
- } else {
- Vector<IntRect> intRects;
- selectedRange->textRects(intRects, true);
-
- unsigned size = intRects.size();
- for (unsigned i = 0; i < size; ++i) {
- if (clipToVisibleContent)
- rects.append(intersection(intRects[i], visibleContentRect));
- else
- rects.append(intRects[i]);
- }
- }
-}
-
-// Scans logically forward from "start", including any child frames
-static HTMLFormElement *scanForForm(Node *start)
-{
- Node *n;
- for (n = start; n; n = n->traverseNextNode()) {
- if (n->hasTagName(formTag))
- return static_cast<HTMLFormElement*>(n);
- else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())
- return static_cast<HTMLFormControlElement*>(n)->form();
- else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
- Node *childDoc = static_cast<HTMLFrameElementBase*>(n)->contentDocument();
- if (HTMLFormElement *frameResult = scanForForm(childDoc))
- return frameResult;
- }
- }
- return 0;
-}
-
-// We look for either the form containing the current focus, or for one immediately after it
-HTMLFormElement *Frame::currentForm() const
-{
- // start looking either at the active (first responder) node, or where the selection is
- Node *start = m_doc ? m_doc->focusedNode() : 0;
- if (!start)
- start = selection()->start().node();
-
- // try walking up the node tree to find a form element
- Node *n;
- for (n = start; n; n = n->parentNode()) {
- if (n->hasTagName(formTag))
- return static_cast<HTMLFormElement*>(n);
- else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())
- return static_cast<HTMLFormControlElement*>(n)->form();
- }
-
- // try walking forward in the node tree to find a form element
- return start ? scanForForm(start) : 0;
-}
-
-void Frame::revealSelection(const ScrollAlignment& alignment, bool revealExtent)
-{
- IntRect rect;
-
- switch (selection()->selectionType()) {
- case VisibleSelection::NoSelection:
- return;
- case VisibleSelection::CaretSelection:
- rect = selection()->absoluteCaretBounds();
- break;
- case VisibleSelection::RangeSelection:
- rect = revealExtent ? VisiblePosition(selection()->extent()).absoluteCaretBounds() : enclosingIntRect(selectionBounds(false));
- break;
- }
-
- Position start = selection()->start();
- ASSERT(start.node());
- if (start.node() && start.node()->renderer()) {
- // FIXME: This code only handles scrolling the startContainer's layer, but
- // the selection rect could intersect more than just that.
- // See <rdar://problem/4799899>.
- if (RenderLayer* layer = start.node()->renderer()->enclosingLayer())
- layer->scrollRectToVisible(rect, false, alignment, alignment);
- }
-}
-
-Frame* Frame::frameForWidget(const Widget* widget)
-{
- ASSERT_ARG(widget, widget);
-
- if (RenderWidget* renderer = RenderWidget::find(widget))
- if (Node* node = renderer->node())
- return node->document()->frame();
-
- // Assume all widgets are either a FrameView or owned by a RenderWidget.
- // FIXME: That assumption is not right for scroll bars!
- ASSERT(widget->isFrameView());
- return static_cast<const FrameView*>(widget)->frame();
-}
-
-void Frame::clearTimers(FrameView *view, Document *document)
-{
- if (view) {
- view->unscheduleRelayout();
- if (view->frame()) {
- view->frame()->animation()->suspendAnimations(document);
- view->frame()->eventHandler()->stopAutoscrollTimer();
- }
- }
-}
-
-void Frame::clearTimers()
-{
- clearTimers(m_view.get(), document());
-}
-
-RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
-{
- nodeToRemove = 0;
-
- if (selection()->isNone())
- return 0;
-
- Position pos = selection()->selection().visibleStart().deepEquivalent();
- if (!pos.isCandidate())
- return 0;
- Node *node = pos.node();
- if (!node)
- return 0;
-
- if (!m_typingStyle)
- return node->renderer()->style();
-
- RefPtr<Element> styleElement = document()->createElement(spanTag, false);
-
- ExceptionCode ec = 0;
- String styleText = m_typingStyle->cssText() + " display: inline";
- styleElement->setAttribute(styleAttr, styleText.impl(), ec);
- ASSERT(!ec);
-
- styleElement->appendChild(document()->createEditingTextNode(""), ec);
- ASSERT(!ec);
-
- node->parentNode()->appendChild(styleElement, ec);
- ASSERT(!ec);
-
- nodeToRemove = styleElement.get();
- return styleElement->renderer() ? styleElement->renderer()->style() : 0;
-}
-
-void Frame::setSelectionFromNone()
-{
- // Put a caret inside the body if the entire frame is editable (either the
- // entire WebView is editable or designMode is on for this document).
- Document *doc = document();
- bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
- if (!selection()->isNone() || !(isContentEditable() || caretBrowsing))
- return;
-
- Node* node = doc->documentElement();
- while (node && !node->hasTagName(bodyTag))
- node = node->traverseNextNode();
- if (node)
- selection()->setSelection(VisibleSelection(Position(node, 0), DOWNSTREAM));
-}
-
-bool Frame::inViewSourceMode() const
-{
- return m_inViewSourceMode;
-}
-
-void Frame::setInViewSourceMode(bool mode)
-{
- m_inViewSourceMode = mode;
-}
-
-// Searches from the beginning of the document if nothing is selected.
-bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection)
-{
- if (target.isEmpty())
- return false;
-
- if (excludeFromTextSearch())
- return false;
-
- // Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge
- // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
- RefPtr<Range> searchRange(rangeOfContents(document()));
- VisibleSelection selection = this->selection()->selection();
-
- if (forward)
- setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
- else
- setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
-
- Node* shadowTreeRoot = selection.shadowTreeRootNode();
- if (shadowTreeRoot) {
- ExceptionCode ec = 0;
- if (forward)
- searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
- else
- searchRange->setStart(shadowTreeRoot, 0, ec);
- }
-
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
- // If we started in the selection and the found range exactly matches the existing selection, find again.
- // Build a selection with the found range to remove collapsed whitespace.
- // Compare ranges instead of selection objects to ignore the way that the current selection was made.
- if (startInSelection && *VisibleSelection(resultRange.get()).toNormalizedRange() == *selection.toNormalizedRange()) {
- searchRange = rangeOfContents(document());
- if (forward)
- setStart(searchRange.get(), selection.visibleEnd());
- else
- setEnd(searchRange.get(), selection.visibleStart());
-
- if (shadowTreeRoot) {
- ExceptionCode ec = 0;
- if (forward)
- searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
- else
- searchRange->setStart(shadowTreeRoot, 0, ec);
- }
-
- resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
- }
-
- ExceptionCode exception = 0;
-
- // If nothing was found in the shadow tree, search in main content following the shadow tree.
- if (resultRange->collapsed(exception) && shadowTreeRoot) {
- searchRange = rangeOfContents(document());
- if (forward)
- searchRange->setStartAfter(shadowTreeRoot->shadowParentNode(), exception);
- else
- searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception);
-
- resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
- }
-
- if (!editor()->insideVisibleArea(resultRange.get())) {
- resultRange = editor()->nextVisibleRange(resultRange.get(), target, forward, caseFlag, wrapFlag);
- if (!resultRange)
- return false;
- }
-
- // If we didn't find anything and we're wrapping, search again in the entire document (this will
- // redundantly re-search the area already searched in some cases).
- if (resultRange->collapsed(exception) && wrapFlag) {
- searchRange = rangeOfContents(document());
- resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
- // We used to return false here if we ended up with the same range that we started with
- // (e.g., the selection was already the only instance of this text). But we decided that
- // this should be a success case instead, so we'll just fall through in that case.
- }
-
- if (resultRange->collapsed(exception))
- return false;
-
- this->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
- revealSelection();
- return true;
-}
-
-unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsigned limit)
-{
- if (target.isEmpty())
- return 0;
-
- RefPtr<Range> searchRange(rangeOfContents(document()));
-
- ExceptionCode exception = 0;
- unsigned matchCount = 0;
- do {
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
- if (resultRange->collapsed(exception)) {
- if (!resultRange->startContainer()->isInShadowTree())
- break;
-
- searchRange = rangeOfContents(document());
- searchRange->setStartAfter(resultRange->startContainer()->shadowAncestorNode(), exception);
- continue;
- }
-
- // A non-collapsed result range can in some funky whitespace cases still not
- // advance the range's start position (4509328). Break to avoid infinite loop.
- VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
- if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
- break;
-
- // Only treat the result as a match if it is visible
- if (editor()->insideVisibleArea(resultRange.get())) {
- ++matchCount;
- document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
- }
-
- // Stop looking if we hit the specified limit. A limit of 0 means no limit.
- if (limit > 0 && matchCount >= limit)
- break;
-
- setStart(searchRange.get(), newStart);
- Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
- if (searchRange->collapsed(exception) && shadowTreeRoot)
- searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception);
- } while (true);
-
- // Do a "fake" paint in order to execute the code that computes the rendered rect for
- // each text match.
- Document* doc = document();
- if (m_view && contentRenderer()) {
- doc->updateLayout(); // Ensure layout is up to date.
- IntRect visibleRect = m_view->visibleContentRect();
- if (!visibleRect.isEmpty()) {
- GraphicsContext context((PlatformGraphicsContext*)0);
- context.setPaintingDisabled(true);
- m_view->paintContents(&context, visibleRect);
- }
- }
-
- return matchCount;
-}
-
-bool Frame::markedTextMatchesAreHighlighted() const
-{
- return m_highlightTextMatches;
-}
-
-void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
-{
- if (flag == m_highlightTextMatches)
- return;
-
- m_highlightTextMatches = flag;
- document()->repaintMarkers(DocumentMarker::TextMatch);
-}
-
-FrameTree* Frame::tree() const
-{
- return &m_treeNode;
-}
-
-void Frame::setDOMWindow(DOMWindow* domWindow)
-{
- if (m_domWindow) {
- m_liveFormerWindows.add(m_domWindow.get());
- m_domWindow->clear();
- }
- m_domWindow = domWindow;
-}
-
-DOMWindow* Frame::domWindow() const
-{
- if (!m_domWindow)
- m_domWindow = DOMWindow::create(const_cast<Frame*>(this));
-
- return m_domWindow.get();
-}
-
-void Frame::clearFormerDOMWindow(DOMWindow* window)
-{
- m_liveFormerWindows.remove(window);
-}
-
-Page* Frame::page() const
-{
- return m_page;
-}
-
-void Frame::detachFromPage()
-{
- m_page = 0;
-}
-
-EventHandler* Frame::eventHandler() const
-{
- return &m_eventHandler;
-}
-
-void Frame::pageDestroyed()
-{
- if (Frame* parent = tree()->parent())
- parent->loader()->checkLoadComplete();
-
- // FIXME: It's unclear as to why this is called more than once, but it is,
- // so page() could be NULL.
- if (page() && page()->focusController()->focusedFrame() == this)
- page()->focusController()->setFocusedFrame(0);
-
- script()->clearWindowShell();
- script()->clearScriptObjects();
- script()->updatePlatformScriptObjects();
-
- detachFromPage();
-}
-
-void Frame::disconnectOwnerElement()
-{
- if (m_ownerElement) {
- if (Document* doc = document())
- doc->clearAXObjectCache();
- m_ownerElement->m_contentFrame = 0;
- if (m_page)
- m_page->decrementFrameCount();
- }
- m_ownerElement = 0;
-}
-
-String Frame::documentTypeString() const
-{
- if (DocumentType* doctype = document()->doctype())
- return createMarkup(doctype);
-
- return String();
-}
-
-void Frame::focusWindow()
-{
- if (!page())
- return;
-
- // If we're a top level window, bring the window to the front.
- if (!tree()->parent())
- page()->chrome()->focus();
-
- eventHandler()->focusDocumentView();
-}
-
-void Frame::unfocusWindow()
-{
- if (!page())
- return;
-
- // If we're a top level window, deactivate the window.
- if (!tree()->parent())
- page()->chrome()->unfocus();
-}
-
-bool Frame::shouldClose()
-{
- Chrome* chrome = page() ? page()->chrome() : 0;
- if (!chrome || !chrome->canRunBeforeUnloadConfirmPanel())
- return true;
-
- if (!m_domWindow)
- return true;
-
- RefPtr<Document> doc = document();
- HTMLElement* body = doc->body();
- if (!body)
- return true;
-
- RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
- m_domWindow->dispatchEvent(beforeUnloadEvent.get(), m_domWindow->document());
-
- if (!beforeUnloadEvent->defaultPrevented())
- doc->defaultEventHandler(beforeUnloadEvent.get());
- if (beforeUnloadEvent->result().isNull())
- return true;
-
- String text = doc->displayStringModifiedByEncoding(beforeUnloadEvent->result());
- return chrome->runBeforeUnloadConfirmPanel(text, this);
-}
-
-void Frame::scheduleClose()
-{
- if (!shouldClose())
- return;
-
- Chrome* chrome = page() ? page()->chrome() : 0;
- if (chrome)
- chrome->closeWindowSoon();
-}
-
-void Frame::respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping)
-{
- bool isContinuousSpellCheckingEnabled = editor()->isContinuousSpellCheckingEnabled();
- bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && editor()->isGrammarCheckingEnabled();
- if (isContinuousSpellCheckingEnabled) {
- VisibleSelection newAdjacentWords;
- VisibleSelection newSelectedSentence;
- bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
- if (selection()->selection().isContentEditable() || caretBrowsing) {
- VisiblePosition newStart(selection()->selection().visibleStart());
- newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
- if (isContinuousGrammarCheckingEnabled)
- newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart));
- }
-
- // When typing we check spelling elsewhere, so don't redo it here.
- // If this is a change in selection resulting from a delete operation,
- // oldSelection may no longer be in the document.
- if (closeTyping && oldSelection.isContentEditable() && oldSelection.start().node() && oldSelection.start().node()->inDocument()) {
- VisiblePosition oldStart(oldSelection.visibleStart());
- VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
- if (oldAdjacentWords != newAdjacentWords) {
- if (isContinuousGrammarCheckingEnabled) {
- VisibleSelection oldSelectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart));
- editor()->markMisspellingsAndBadGrammar(oldAdjacentWords, oldSelectedSentence != newSelectedSentence, oldSelectedSentence);
- } else
- editor()->markMisspellingsAndBadGrammar(oldAdjacentWords, false, oldAdjacentWords);
- }
- }
-
- // This only erases markers that are in the first unit (word or sentence) of the selection.
- // Perhaps peculiar, but it matches AppKit.
- if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange())
- document()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
- if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
- document()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
- }
-
- // When continuous spell checking is off, existing markers disappear after the selection changes.
- if (!isContinuousSpellCheckingEnabled)
- document()->removeMarkers(DocumentMarker::Spelling);
- if (!isContinuousGrammarCheckingEnabled)
- document()->removeMarkers(DocumentMarker::Grammar);
-
- editor()->respondToChangedSelection(oldSelection);
-}
-
-VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
-{
- HitTestResult result = eventHandler()->hitTestResultAtPoint(framePoint, true);
- Node* node = result.innerNode();
- if (!node)
- return VisiblePosition();
- RenderObject* renderer = node->renderer();
- if (!renderer)
- return VisiblePosition();
- VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint());
- if (visiblePos.isNull())
- visiblePos = VisiblePosition(Position(node, 0));
- return visiblePos;
-}
-
-Document* Frame::documentAtPoint(const IntPoint& point)
-{
- if (!view())
- return 0;
-
- IntPoint pt = view()->windowToContents(point);
- HitTestResult result = HitTestResult(pt);
-
- if (contentRenderer())
- result = eventHandler()->hitTestResultAtPoint(pt, false);
- return result.innerNode() ? result.innerNode()->document() : 0;
-}
-
-void Frame::createView(const IntSize& viewportSize,
- const Color& backgroundColor, bool transparent,
- const IntSize& fixedLayoutSize, bool useFixedLayout,
- ScrollbarMode horizontalScrollbarMode, ScrollbarMode verticalScrollbarMode)
-{
- ASSERT(this);
- ASSERT(m_page);
-
- bool isMainFrame = this == m_page->mainFrame();
-
- if (isMainFrame && view())
- view()->setParentVisible(false);
-
- setView(0);
-
- RefPtr<FrameView> frameView;
- if (isMainFrame) {
- frameView = FrameView::create(this, viewportSize);
- frameView->setFixedLayoutSize(fixedLayoutSize);
- frameView->setUseFixedLayout(useFixedLayout);
- } else
- frameView = FrameView::create(this);
-
- frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode);
-
- setView(frameView);
-
- if (backgroundColor.isValid())
- frameView->updateBackgroundRecursively(backgroundColor, transparent);
-
- if (isMainFrame)
- frameView->setParentVisible(true);
-
- if (ownerRenderer())
- ownerRenderer()->setWidget(frameView);
-
- if (HTMLFrameOwnerElement* owner = ownerElement())
- view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
-}
-
-#if PLATFORM(WKC)
-void Frame::deleteSharedInstance()
-{
- HTMLNames::finalize();
-#if ENABLE(SVG)
- SVGNames::finalize();
- XLinkNames::finalize();
-#endif
-
-#if ENABLE(WML)
- WMLNames::finalize();
-#endif
-
-#if ENABLE(MATHML)
- MathMLNames::finalize();
-#endif
- XMLNames::finalize();
-
- delete gWordRegExp;
-#ifndef NDEBUG
- delete gStaticKeepAliveSet;
- delete gFrameCounter;
-#endif
-}
-
-void Frame::resetVariables()
-{
- HTMLNames::finalize();
-#if ENABLE(SVG)
- SVGNames::finalize();
- XLinkNames::finalize();
-#endif
-
-#if ENABLE(WML)
- WMLNames::finalize();
-#endif
-
-#if ENABLE(MATHML)
- MathMLNames::finalize();
-#endif
- XMLNames::finalize();
-
- gWordRegExp = 0;
-#ifndef NDEBUG
- gStaticKeepAliveSet = 0;
- gFrameCounter = 0;
-#endif
-}
-#endif
-
-#if ENABLE(WKC_FRAME_FLATTENING)
-void Frame::invalidateOwnerRendererLayoutIfNeeded()
-{
- if (settings() && settings()->flatFrameSetLayoutEnabled() && ownerRenderer())
- ownerRenderer()->setNeedsLayout(true, true);
-}
-
-bool Frame::isFrameSet() const
-{
- Document* doc = m_doc.get();
- if (!doc || !doc->isHTMLDocument())
- return false;
- Node *body = static_cast<HTMLDocument*>(doc)->body();
- return body && body->renderer() && body->hasTagName(framesetTag);
-}
-
-#endif
-} // namespace WebCore
+ document()->updateStyleIfNeeded();
+#endif
+
+ RenderView* view = contentRenderer();
+ if (!view)
+ return;
+
+ VisibleSelection selection = this->selection()->selection();
+
+ if (!selection.isRange())
+ view->clearSelection();
+ else {
+ // Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection.
+ // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', and that 'bar' is selected. If we pass [foo, 3]
+ // as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected
+ // and will fill the gap before 'bar'.
+ Position startPos = selection.start();
+ if (startPos.downstream().isCandidate())
+ startPos = startPos.downstream();
+ Position endPos = selection.end();
+ if (endPos.upstream().isCandidate())
+ endPos = endPos.upstream();
+
+ // We can get into a state where the selection endpoints map to the same VisiblePosition when a selection is deleted
+ // because we don't yet notify the SelectionController of text removal.
+ if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
+ RenderObject *startRenderer = startPos.node()->renderer();
+ RenderObject *endRenderer = endPos.node()->renderer();
+ view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset());
+ }
+ }
+}
+
+void Frame::caretBlinkTimerFired(Timer<Frame>*)
+{
+#if ENABLE(TEXT_CARET)
+ if (!m_caretVisible || !selection()->isCaret()) {
+ ASSERT(selection()->needsDisplayUpdate());
+ return;
+ }
+ bool caretPaint = m_caretPaint;
+ if (selection()->isCaretBlinkingSuspended() && caretPaint)
+ return;
+ m_caretPaint = !caretPaint;
+ selection()->invalidateCaretRect();
+#endif
+}
+
+void Frame::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
+{
+#if ENABLE(TEXT_CARET)
+ if (m_caretPaint && m_caretVisible)
+ selection()->paintCaret(p, tx, ty, clipRect);
+#endif
+}
+
+void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
+{
+#if ENABLE(TEXT_CARET)
+ SelectionController* dragCaretController = m_page->dragCaretController();
+ ASSERT(dragCaretController->selection().isCaret());
+ if (dragCaretController->selection().start().node()->document()->frame() == this)
+ dragCaretController->paintCaret(p, tx, ty, clipRect);
+#endif
+}
+
+float Frame::zoomFactor() const
+{
+ return m_zoomFactor;
+}
+
+bool Frame::isZoomFactorTextOnly() const
+{
+ return m_page->settings()->zoomsTextOnly();
+}
+
+bool Frame::shouldApplyTextZoom() const
+{
+ if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
+ return false;
+#if ENABLE(SVG)
+ if (m_doc->isSVGDocument())
+ return false;
+#endif
+ return true;
+}
+
+bool Frame::shouldApplyPageZoom() const
+{
+ if (m_zoomFactor == 1.0f || isZoomFactorTextOnly())
+ return false;
+#if ENABLE(SVG)
+ if (m_doc->isSVGDocument())
+ return false;
+#endif
+ return true;
+}
+
+void Frame::setZoomFactor(float percent, bool isTextOnly)
+{
+ if (m_zoomFactor == percent && isZoomFactorTextOnly() == isTextOnly)
+ return;
+
+#if ENABLE(SVG)
+ // SVG doesn't care if the zoom factor is text only. It will always apply a
+ // zoom to the whole SVG.
+ if (m_doc->isSVGDocument()) {
+ if (!static_cast<SVGDocument*>(m_doc.get())->zoomAndPanEnabled())
+ return;
+ m_zoomFactor = percent;
+ m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom.
+ if (m_doc->renderer())
+ m_doc->renderer()->repaint();
+ return;
+ }
+#endif
+
+ m_zoomFactor = percent;
+ m_page->settings()->setZoomsTextOnly(isTextOnly);
+
+ m_doc->recalcStyle(Node::Force);
+
+ for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
+ child->setZoomFactor(m_zoomFactor, isTextOnly);
+
+ if (m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout())
+ view()->layout();
+}
+
+void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
+{
+ m_doc->setPrinting(printing);
+ view()->setMediaType(printing ? "print" : "screen");
+ m_doc->updateStyleSelector();
+ view()->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize);
+
+ for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
+ child->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize);
+}
+
+void Frame::setJSStatusBarText(const String& text)
+{
+ ASSERT(m_doc); // Client calls shouldn't be made when the frame is in inconsistent state.
+ m_kjsStatusBarText = text;
+ if (m_page)
+ m_page->chrome()->setStatusbarText(this, m_kjsStatusBarText);
+}
+
+void Frame::setJSDefaultStatusBarText(const String& text)
+{
+ ASSERT(m_doc); // Client calls shouldn't be made when the frame is in inconsistent state.
+ m_kjsDefaultStatusBarText = text;
+ if (m_page)
+ m_page->chrome()->setStatusbarText(this, m_kjsDefaultStatusBarText);
+}
+
+String Frame::jsStatusBarText() const
+{
+ return m_kjsStatusBarText;
+}
+
+String Frame::jsDefaultStatusBarText() const
+{
+ return m_kjsDefaultStatusBarText;
+}
+
+void Frame::setNeedsReapplyStyles()
+{
+ // When the frame is not showing web content, it doesn't make sense to apply styles.
+ // If we tried, we'd end up doing things with the document, but the document, if one
+ // exists, is not currently shown and should be in the page cache.
+ if (!m_loader.client()->hasHTMLView())
+ return;
+
+ if (m_needsReapplyStyles)
+ return;
+
+ m_needsReapplyStyles = true;
+
+ // FrameView's "layout" timer includes reapplyStyles, so despite its
+ // name, it's what we want to call here.
+ if (view())
+ view()->scheduleRelayout();
+}
+
+bool Frame::needsReapplyStyles() const
+{
+ return m_needsReapplyStyles;
+}
+
+void Frame::reapplyStyles()
+{
+ m_needsReapplyStyles = false;
+
+ // FIXME: This call doesn't really make sense in a function called reapplyStyles.
+ // We should probably eventually move it into its own function.
+ m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically());
+
+ // FIXME: It's not entirely clear why the following is needed.
+ // The document automatically does this as required when you set the style sheet.
+ // But we had problems when this code was removed. Details are in
+ // <http://bugs.webkit.org/show_bug.cgi?id=8079>.
+ m_doc->updateStyleSelector();
+}
+
+void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
+{
+ if (!m_page)
+ return;
+
+ // Walk the hashtable. Inject by world.
+ const UserScriptMap* userScripts = m_page->group().userScripts();
+ if (!userScripts)
+ return;
+ UserScriptMap::const_iterator end = userScripts->end();
+ for (UserScriptMap::const_iterator it = userScripts->begin(); it != end; ++it)
+ injectUserScriptsForWorld(it->first.get(), *it->second, injectionTime);
+}
+
+void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime)
+{
+ if (userScripts.isEmpty())
+ return;
+
+ Document* doc = document();
+ if (!doc)
+ return;
+
+ Vector<ScriptSourceCode> sourceCode;
+ unsigned count = userScripts.size();
+ for (unsigned i = 0; i < count; ++i) {
+ UserScript* script = userScripts[i].get();
+ if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->whitelist(), script->blacklist()))
+ m_script.evaluateInWorld(ScriptSourceCode(script->source(), script->url()), world);
+ }
+}
+
+bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const
+{
+ return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
+}
+
+bool Frame::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const
+{
+ return editor()->client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(),
+ affinity, stillSelecting);
+}
+
+bool Frame::shouldDeleteSelection(const VisibleSelection& selection) const
+{
+ return editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());
+}
+
+bool Frame::isContentEditable() const
+{
+ if (m_editor.clientIsEditable())
+ return true;
+ return m_doc->inDesignMode();
+}
+
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+const short enableRomanKeyboardsOnly = -23;
+#endif
+void Frame::setUseSecureKeyboardEntry(bool enable)
+{
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+ if (enable == IsSecureEventInputEnabled())
+ return;
+ if (enable) {
+ EnableSecureEventInput();
+#ifdef BUILDING_ON_TIGER
+ KeyScript(enableRomanKeyboardsOnly);
+#else
+ // WebKit substitutes nil for input context when in password field, which corresponds to null TSMDocument. So, there is
+ // no need to call TSMGetActiveDocument(), which may return an incorrect result when selection hasn't been yet updated
+ // after focusing a node.
+ CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
+ TSMSetDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag, sizeof(CFArrayRef), &inputSources);
+ CFRelease(inputSources);
+#endif
+ } else {
+ DisableSecureEventInput();
+#ifdef BUILDING_ON_TIGER
+ KeyScript(smKeyEnableKybds);
+#else
+ TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag);
+#endif
+ }
+#endif
+}
+
+void Frame::updateSecureKeyboardEntryIfActive()
+{
+ if (selection()->isFocusedAndActive())
+ setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
+}
+
+CSSMutableStyleDeclaration *Frame::typingStyle() const
+{
+ return m_typingStyle.get();
+}
+
+void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
+{
+ m_typingStyle = style;
+}
+
+void Frame::clearTypingStyle()
+{
+ m_typingStyle = 0;
+}
+
+void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
+{
+ if (!style || !style->length()) {
+ clearTypingStyle();
+ return;
+ }
+
+ // Calculate the current typing style.
+ RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
+ if (typingStyle()) {
+ typingStyle()->merge(mutableStyle.get());
+ mutableStyle = typingStyle();
+ }
+
+ RefPtr<CSSValue> unicodeBidi;
+ RefPtr<CSSValue> direction;
+ if (editingAction == EditActionSetWritingDirection) {
+ unicodeBidi = mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+ direction = mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
+ }
+
+ Node* node = selection()->selection().visibleStart().deepEquivalent().node();
+ computedStyle(node)->diff(mutableStyle.get());
+
+ if (editingAction == EditActionSetWritingDirection && unicodeBidi) {
+ ASSERT(unicodeBidi->isPrimitiveValue());
+ mutableStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
+ if (direction) {
+ ASSERT(direction->isPrimitiveValue());
+ mutableStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
+ }
+ }
+
+ // Handle block styles, substracting these from the typing style.
+ RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
+ blockStyle->diff(mutableStyle.get());
+ if (blockStyle->length() > 0)
+ applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
+
+ // Set the remaining style as the typing style.
+ m_typingStyle = mutableStyle.release();
+}
+
+String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
+{
+ Node *nodeToRemove;
+ RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
+ if (!selectionStyle)
+ return String();
+
+ String value = selectionStyle->getPropertyValue(stylePropertyID);
+
+ if (nodeToRemove) {
+ ExceptionCode ec = 0;
+ nodeToRemove->remove(ec);
+ ASSERT(!ec);
+ }
+
+ return value;
+}
+
+PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nodeToRemove) const
+{
+ nodeToRemove = 0;
+
+ if (selection()->isNone())
+ return 0;
+
+ RefPtr<Range> range(selection()->toNormalizedRange());
+ Position pos = range->editingStartPosition();
+
+ Element *elem = pos.element();
+ if (!elem)
+ return 0;
+
+ RefPtr<Element> styleElement = elem;
+ ExceptionCode ec = 0;
+
+ if (m_typingStyle) {
+ styleElement = document()->createElement(spanTag, false);
+
+ styleElement->setAttribute(styleAttr, m_typingStyle->cssText().impl(), ec);
+ ASSERT(!ec);
+
+ styleElement->appendChild(document()->createEditingTextNode(""), ec);
+ ASSERT(!ec);
+
+ if (elem->renderer() && elem->renderer()->canHaveChildren()) {
+ elem->appendChild(styleElement, ec);
+ } else {
+ Node *parent = elem->parent();
+ Node *next = elem->nextSibling();
+
+ if (next)
+ parent->insertBefore(styleElement, next, ec);
+ else
+ parent->appendChild(styleElement, ec);
+ }
+ ASSERT(!ec);
+
+ nodeToRemove = styleElement.get();
+ }
+
+ return computedStyle(styleElement.release());
+}
+
+void Frame::textFieldDidBeginEditing(Element* e)
+{
+ if (editor()->client())
+ editor()->client()->textFieldDidBeginEditing(e);
+}
+
+void Frame::textFieldDidEndEditing(Element* e)
+{
+ if (editor()->client())
+ editor()->client()->textFieldDidEndEditing(e);
+}
+
+void Frame::textDidChangeInTextField(Element* e)
+{
+ if (editor()->client())
+ editor()->client()->textDidChangeInTextField(e);
+}
+
+bool Frame::doTextFieldCommandFromEvent(Element* e, KeyboardEvent* ke)
+{
+ if (editor()->client())
+ return editor()->client()->doTextFieldCommandFromEvent(e, ke);
+
+ return false;
+}
+
+void Frame::textWillBeDeletedInTextField(Element* input)
+{
+ if (editor()->client())
+ editor()->client()->textWillBeDeletedInTextField(input);
+}
+
+void Frame::textDidChangeInTextArea(Element* e)
+{
+ if (editor()->client())
+ editor()->client()->textDidChangeInTextArea(e);
+}
+
+void Frame::applyEditingStyleToBodyElement() const
+{
+ RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
+ unsigned len = list->length();
+ for (unsigned i = 0; i < len; i++)
+ applyEditingStyleToElement(static_cast<Element*>(list->item(i)));
+}
+
+void Frame::removeEditingStyleFromBodyElement() const
+{
+ RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
+ unsigned len = list->length();
+ for (unsigned i = 0; i < len; i++)
+ removeEditingStyleFromElement(static_cast<Element*>(list->item(i)));
+}
+
+void Frame::applyEditingStyleToElement(Element* element) const
+{
+ if (!element)
+ return;
+
+ CSSStyleDeclaration* style = element->style();
+ ASSERT(style);
+
+ ExceptionCode ec = 0;
+ style->setProperty(CSSPropertyWordWrap, "break-word", false, ec);
+ ASSERT(!ec);
+ style->setProperty(CSSPropertyWebkitNbspMode, "space", false, ec);
+ ASSERT(!ec);
+ style->setProperty(CSSPropertyWebkitLineBreak, "after-white-space", false, ec);
+ ASSERT(!ec);
+}
+
+void Frame::removeEditingStyleFromElement(Element*) const
+{
+}
+
+#ifndef NDEBUG
+#if PLATFORM(WKC)
+static HashSet<Frame*>* gStaticKeepAliveSet = 0;
+static HashSet<Frame*>& keepAliveSet()
+{
+ if (!gStaticKeepAliveSet) {
+ gStaticKeepAliveSet = new HashSet<Frame*>();
+ }
+ HashSet<Frame*>& staticKeepAliveSet = *gStaticKeepAliveSet;
+ return staticKeepAliveSet;
+}
+#else
+static HashSet<Frame*>& keepAliveSet()
+{
+ DEFINE_STATIC_LOCAL(HashSet<Frame*>, staticKeepAliveSet, ());
+ return staticKeepAliveSet;
+}
+#endif
+#endif
+
+void Frame::keepAlive()
+{
+ if (m_lifeSupportTimer.isActive())
+ return;
+#ifndef NDEBUG
+ keepAliveSet().add(this);
+#endif
+ ref();
+ m_lifeSupportTimer.startOneShot(0);
+}
+
+#ifndef NDEBUG
+void Frame::cancelAllKeepAlive()
+{
+ HashSet<Frame*>::iterator end = keepAliveSet().end();
+ for (HashSet<Frame*>::iterator it = keepAliveSet().begin(); it != end; ++it) {
+ Frame* frame = *it;
+ frame->m_lifeSupportTimer.stop();
+ frame->deref();
+ }
+ keepAliveSet().clear();
+}
+#endif
+
+void Frame::lifeSupportTimerFired(Timer<Frame>*)
+{
+#ifndef NDEBUG
+ keepAliveSet().remove(this);
+#endif
+ deref();
+}
+
+void Frame::clearDOMWindow()
+{
+ if (m_domWindow) {
+ m_liveFormerWindows.add(m_domWindow.get());
+ m_domWindow->clear();
+ }
+ m_domWindow = 0;
+}
+
+RenderView* Frame::contentRenderer() const
+{
+ Document* doc = document();
+ if (!doc)
+ return 0;
+ RenderObject* object = doc->renderer();
+ if (!object)
+ return 0;
+ ASSERT(object->isRenderView());
+ return toRenderView(object);
+}
+
+HTMLFrameOwnerElement* Frame::ownerElement() const
+{
+ return m_ownerElement;
+}
+
+RenderPart* Frame::ownerRenderer() const
+{
+ HTMLFrameOwnerElement* ownerElement = m_ownerElement;
+ if (!ownerElement)
+ return 0;
+ RenderObject* object = ownerElement->renderer();
+ if (!object)
+ return 0;
+ // FIXME: If <object> is ever fixed to disassociate itself from frames
+ // that it has started but canceled, then this can turn into an ASSERT
+ // since m_ownerElement would be 0 when the load is canceled.
+ // https://bugs.webkit.org/show_bug.cgi?id=18585
+ if (!object->isRenderPart())
+ return 0;
+ return toRenderPart(object);
+}
+
+bool Frame::isDisconnected() const
+{
+ return m_isDisconnected;
+}
+
+void Frame::setIsDisconnected(bool isDisconnected)
+{
+ m_isDisconnected = isDisconnected;
+}
+
+bool Frame::excludeFromTextSearch() const
+{
+ return m_excludeFromTextSearch;
+}
+
+void Frame::setExcludeFromTextSearch(bool exclude)
+{
+ m_excludeFromTextSearch = exclude;
+}
+
+// returns FloatRect because going through IntRect would truncate any floats
+FloatRect Frame::selectionBounds(bool clipToVisibleContent) const
+{
+ m_doc->updateLayout();
+
+ RenderView* root = contentRenderer();
+ FrameView* view = m_view.get();
+ if (!root || !view)
+ return IntRect();
+
+ IntRect selectionRect = root->selectionBounds(clipToVisibleContent);
+ return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
+}
+
+void Frame::selectionTextRects(Vector<FloatRect>& rects, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent) const
+{
+ RenderView* root = contentRenderer();
+ if (!root)
+ return;
+
+ RefPtr<Range> selectedRange = selection()->toNormalizedRange();
+
+ FloatRect visibleContentRect = m_view->visibleContentRect();
+
+ // FIMXE: we are appending empty rects to the list for those that fall outside visibleContentRect.
+ // We may not want to do that.
+ if (respectTransforms) {
+ Vector<FloatQuad> quads;
+ selectedRange->textQuads(quads, true);
+
+ unsigned size = quads.size();
+ for (unsigned i = 0; i < size; ++i) {
+ IntRect currRect = quads[i].enclosingBoundingBox();
+ if (clipToVisibleContent)
+ rects.append(intersection(currRect, visibleContentRect));
+ else
+ rects.append(currRect);
+ }
+ } else {
+ Vector<IntRect> intRects;
+ selectedRange->textRects(intRects, true);
+
+ unsigned size = intRects.size();
+ for (unsigned i = 0; i < size; ++i) {
+ if (clipToVisibleContent)
+ rects.append(intersection(intRects[i], visibleContentRect));
+ else
+ rects.append(intRects[i]);
+ }
+ }
+}
+
+// Scans logically forward from "start", including any child frames
+static HTMLFormElement *scanForForm(Node *start)
+{
+ Node *n;
+ for (n = start; n; n = n->traverseNextNode()) {
+ if (n->hasTagName(formTag))
+ return static_cast<HTMLFormElement*>(n);
+ else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())
+ return static_cast<HTMLFormControlElement*>(n)->form();
+ else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
+ Node *childDoc = static_cast<HTMLFrameElementBase*>(n)->contentDocument();
+ if (HTMLFormElement *frameResult = scanForForm(childDoc))
+ return frameResult;
+ }
+ }
+ return 0;
+}
+
+// We look for either the form containing the current focus, or for one immediately after it
+HTMLFormElement *Frame::currentForm() const
+{
+ // start looking either at the active (first responder) node, or where the selection is
+ Node *start = m_doc ? m_doc->focusedNode() : 0;
+ if (!start)
+ start = selection()->start().node();
+
+ // try walking up the node tree to find a form element
+ Node *n;
+ for (n = start; n; n = n->parentNode()) {
+ if (n->hasTagName(formTag))
+ return static_cast<HTMLFormElement*>(n);
+ else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())
+ return static_cast<HTMLFormControlElement*>(n)->form();
+ }
+
+ // try walking forward in the node tree to find a form element
+ return start ? scanForForm(start) : 0;
+}
+
+void Frame::revealSelection(const ScrollAlignment& alignment, bool revealExtent)
+{
+ IntRect rect;
+
+ switch (selection()->selectionType()) {
+ case VisibleSelection::NoSelection:
+ return;
+ case VisibleSelection::CaretSelection:
+ rect = selection()->absoluteCaretBounds();
+ break;
+ case VisibleSelection::RangeSelection:
+ rect = revealExtent ? VisiblePosition(selection()->extent()).absoluteCaretBounds() : enclosingIntRect(selectionBounds(false));
+ break;
+ }
+
+ Position start = selection()->start();
+ ASSERT(start.node());
+ if (start.node() && start.node()->renderer()) {
+ // FIXME: This code only handles scrolling the startContainer's layer, but
+ // the selection rect could intersect more than just that.
+ // See <rdar://problem/4799899>.
+ if (RenderLayer* layer = start.node()->renderer()->enclosingLayer())
+ layer->scrollRectToVisible(rect, false, alignment, alignment);
+ }
+}
+
+Frame* Frame::frameForWidget(const Widget* widget)
+{
+ ASSERT_ARG(widget, widget);
+
+ if (RenderWidget* renderer = RenderWidget::find(widget))
+ if (Node* node = renderer->node())
+ return node->document()->frame();
+
+ // Assume all widgets are either a FrameView or owned by a RenderWidget.
+ // FIXME: That assumption is not right for scroll bars!
+ ASSERT(widget->isFrameView());
+ return static_cast<const FrameView*>(widget)->frame();
+}
+
+void Frame::clearTimers(FrameView *view, Document *document)
+{
+ if (view) {
+ view->unscheduleRelayout();
+ if (view->frame()) {
+ view->frame()->animation()->suspendAnimations(document);
+ view->frame()->eventHandler()->stopAutoscrollTimer();
+ }
+ }
+}
+
+void Frame::clearTimers()
+{
+ clearTimers(m_view.get(), document());
+}
+
+RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
+{
+ nodeToRemove = 0;
+
+ if (selection()->isNone())
+ return 0;
+
+ Position pos = selection()->selection().visibleStart().deepEquivalent();
+ if (!pos.isCandidate())
+ return 0;
+ Node *node = pos.node();
+ if (!node)
+ return 0;
+
+ if (!m_typingStyle)
+ return node->renderer()->style();
+
+ RefPtr<Element> styleElement = document()->createElement(spanTag, false);
+
+ ExceptionCode ec = 0;
+ String styleText = m_typingStyle->cssText() + " display: inline";
+ styleElement->setAttribute(styleAttr, styleText.impl(), ec);
+ ASSERT(!ec);
+
+ styleElement->appendChild(document()->createEditingTextNode(""), ec);
+ ASSERT(!ec);
+
+ node->parentNode()->appendChild(styleElement, ec);
+ ASSERT(!ec);
+
+ nodeToRemove = styleElement.get();
+ return styleElement->renderer() ? styleElement->renderer()->style() : 0;
+}
+
+void Frame::setSelectionFromNone()
+{
+ // Put a caret inside the body if the entire frame is editable (either the
+ // entire WebView is editable or designMode is on for this document).
+ Document *doc = document();
+ bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
+ if (!selection()->isNone() || !(isContentEditable() || caretBrowsing))
+ return;
+
+ Node* node = doc->documentElement();
+ while (node && !node->hasTagName(bodyTag))
+ node = node->traverseNextNode();
+ if (node)
+ selection()->setSelection(VisibleSelection(Position(node, 0), DOWNSTREAM));
+}
+
+bool Frame::inViewSourceMode() const
+{
+ return m_inViewSourceMode;
+}
+
+void Frame::setInViewSourceMode(bool mode)
+{
+ m_inViewSourceMode = mode;
+}
+
+// Searches from the beginning of the document if nothing is selected.
+bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection)
+{
+ if (target.isEmpty())
+ return false;
+
+ if (excludeFromTextSearch())
+ return false;
+
+ // Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge
+ // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
+ RefPtr<Range> searchRange(rangeOfContents(document()));
+ VisibleSelection selection = this->selection()->selection();
+
+ if (forward)
+ setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
+ else
+ setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
+
+ Node* shadowTreeRoot = selection.shadowTreeRootNode();
+ if (shadowTreeRoot) {
+ ExceptionCode ec = 0;
+ if (forward)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
+ else
+ searchRange->setStart(shadowTreeRoot, 0, ec);
+ }
+
+ RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
+ // If we started in the selection and the found range exactly matches the existing selection, find again.
+ // Build a selection with the found range to remove collapsed whitespace.
+ // Compare ranges instead of selection objects to ignore the way that the current selection was made.
+ if (startInSelection && *VisibleSelection(resultRange.get()).toNormalizedRange() == *selection.toNormalizedRange()) {
+ searchRange = rangeOfContents(document());
+ if (forward)
+ setStart(searchRange.get(), selection.visibleEnd());
+ else
+ setEnd(searchRange.get(), selection.visibleStart());
+
+ if (shadowTreeRoot) {
+ ExceptionCode ec = 0;
+ if (forward)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
+ else
+ searchRange->setStart(shadowTreeRoot, 0, ec);
+ }
+
+ resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
+ }
+
+ ExceptionCode exception = 0;
+
+ // If nothing was found in the shadow tree, search in main content following the shadow tree.
+ if (resultRange->collapsed(exception) && shadowTreeRoot) {
+ searchRange = rangeOfContents(document());
+ if (forward)
+ searchRange->setStartAfter(shadowTreeRoot->shadowParentNode(), exception);
+ else
+ searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception);
+
+ resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
+ }
+
+ if (!editor()->insideVisibleArea(resultRange.get())) {
+ resultRange = editor()->nextVisibleRange(resultRange.get(), target, forward, caseFlag, wrapFlag);
+ if (!resultRange)
+ return false;
+ }
+
+ // If we didn't find anything and we're wrapping, search again in the entire document (this will
+ // redundantly re-search the area already searched in some cases).
+ if (resultRange->collapsed(exception) && wrapFlag) {
+ searchRange = rangeOfContents(document());
+ resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
+ // We used to return false here if we ended up with the same range that we started with
+ // (e.g., the selection was already the only instance of this text). But we decided that
+ // this should be a success case instead, so we'll just fall through in that case.
+ }
+
+ if (resultRange->collapsed(exception))
+ return false;
+
+ this->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
+ revealSelection();
+ return true;
+}
+
+unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsigned limit)
+{
+ if (target.isEmpty())
+ return 0;
+
+ RefPtr<Range> searchRange(rangeOfContents(document()));
+
+ ExceptionCode exception = 0;
+ unsigned matchCount = 0;
+ do {
+ RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
+ if (resultRange->collapsed(exception)) {
+ if (!resultRange->startContainer()->isInShadowTree())
+ break;
+
+ searchRange = rangeOfContents(document());
+ searchRange->setStartAfter(resultRange->startContainer()->shadowAncestorNode(), exception);
+ continue;
+ }
+
+ // A non-collapsed result range can in some funky whitespace cases still not
+ // advance the range's start position (4509328). Break to avoid infinite loop.
+ VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
+ if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
+ break;
+
+ // Only treat the result as a match if it is visible
+ if (editor()->insideVisibleArea(resultRange.get())) {
+ ++matchCount;
+ document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
+ }
+
+ // Stop looking if we hit the specified limit. A limit of 0 means no limit.
+ if (limit > 0 && matchCount >= limit)
+ break;
+
+ setStart(searchRange.get(), newStart);
+ Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
+ if (searchRange->collapsed(exception) && shadowTreeRoot)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception);
+ } while (true);
+
+ // Do a "fake" paint in order to execute the code that computes the rendered rect for
+ // each text match.
+ Document* doc = document();
+ if (m_view && contentRenderer()) {
+ doc->updateLayout(); // Ensure layout is up to date.
+ IntRect visibleRect = m_view->visibleContentRect();
+ if (!visibleRect.isEmpty()) {
+ GraphicsContext context((PlatformGraphicsContext*)0);
+ context.setPaintingDisabled(true);
+ m_view->paintContents(&context, visibleRect);
+ }
+ }
+
+ return matchCount;
+}
+
+bool Frame::markedTextMatchesAreHighlighted() const
+{
+ return m_highlightTextMatches;
+}
+
+void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
+{
+ if (flag == m_highlightTextMatches)
+ return;
+
+ m_highlightTextMatches = flag;
+ document()->repaintMarkers(DocumentMarker::TextMatch);
+}
+
+FrameTree* Frame::tree() const
+{
+ return &m_treeNode;
+}
+
+void Frame::setDOMWindow(DOMWindow* domWindow)
+{
+ if (m_domWindow) {
+ m_liveFormerWindows.add(m_domWindow.get());
+ m_domWindow->clear();
+ }
+ m_domWindow = domWindow;
+}
+
+DOMWindow* Frame::domWindow() const
+{
+ if (!m_domWindow)
+ m_domWindow = DOMWindow::create(const_cast<Frame*>(this));
+
+ return m_domWindow.get();
+}
+
+void Frame::clearFormerDOMWindow(DOMWindow* window)
+{
+ m_liveFormerWindows.remove(window);
+}
+
+Page* Frame::page() const
+{
+ return m_page;
+}
+
+void Frame::detachFromPage()
+{
+ m_page = 0;
+}
+
+EventHandler* Frame::eventHandler() const
+{
+ return &m_eventHandler;
+}
+
+void Frame::pageDestroyed()
+{
+ if (Frame* parent = tree()->parent())
+ parent->loader()->checkLoadComplete();
+
+ // FIXME: It's unclear as to why this is called more than once, but it is,
+ // so page() could be NULL.
+ if (page() && page()->focusController()->focusedFrame() == this)
+ page()->focusController()->setFocusedFrame(0);
+
+ script()->clearWindowShell();
+ script()->clearScriptObjects();
+ script()->updatePlatformScriptObjects();
+
+ detachFromPage();
+}
+
+void Frame::disconnectOwnerElement()
+{
+ if (m_ownerElement) {
+ if (Document* doc = document())
+ doc->clearAXObjectCache();
+ m_ownerElement->m_contentFrame = 0;
+ if (m_page)
+ m_page->decrementFrameCount();
+ }
+ m_ownerElement = 0;
+}
+
+String Frame::documentTypeString() const
+{
+ if (DocumentType* doctype = document()->doctype())
+ return createMarkup(doctype);
+
+ return String();
+}
+
+void Frame::focusWindow()
+{
+ if (!page())
+ return;
+
+ // If we're a top level window, bring the window to the front.
+ if (!tree()->parent())
+ page()->chrome()->focus();
+
+ eventHandler()->focusDocumentView();
+}
+
+void Frame::unfocusWindow()
+{
+ if (!page())
+ return;
+
+ // If we're a top level window, deactivate the window.
+ if (!tree()->parent())
+ page()->chrome()->unfocus();
+}
+
+bool Frame::shouldClose()
+{
+ Chrome* chrome = page() ? page()->chrome() : 0;
+ if (!chrome || !chrome->canRunBeforeUnloadConfirmPanel())
+ return true;
+
+ if (!m_domWindow)
+ return true;
+
+ RefPtr<Document> doc = document();
+ HTMLElement* body = doc->body();
+ if (!body)
+ return true;
+
+ RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
+ m_domWindow->dispatchEvent(beforeUnloadEvent.get(), m_domWindow->document());
+
+ if (!beforeUnloadEvent->defaultPrevented())
+ doc->defaultEventHandler(beforeUnloadEvent.get());
+ if (beforeUnloadEvent->result().isNull())
+ return true;
+
+ String text = doc->displayStringModifiedByEncoding(beforeUnloadEvent->result());
+ return chrome->runBeforeUnloadConfirmPanel(text, this);
+}
+
+void Frame::scheduleClose()
+{
+ if (!shouldClose())
+ return;
+
+ Chrome* chrome = page() ? page()->chrome() : 0;
+ if (chrome)
+ chrome->closeWindowSoon();
+}
+
+void Frame::respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping)
+{
+ bool isContinuousSpellCheckingEnabled = editor()->isContinuousSpellCheckingEnabled();
+ bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && editor()->isGrammarCheckingEnabled();
+ if (isContinuousSpellCheckingEnabled) {
+ VisibleSelection newAdjacentWords;
+ VisibleSelection newSelectedSentence;
+ bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
+ if (selection()->selection().isContentEditable() || caretBrowsing) {
+ VisiblePosition newStart(selection()->selection().visibleStart());
+ newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
+ if (isContinuousGrammarCheckingEnabled)
+ newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart));
+ }
+
+ // When typing we check spelling elsewhere, so don't redo it here.
+ // If this is a change in selection resulting from a delete operation,
+ // oldSelection may no longer be in the document.
+ if (closeTyping && oldSelection.isContentEditable() && oldSelection.start().node() && oldSelection.start().node()->inDocument()) {
+ VisiblePosition oldStart(oldSelection.visibleStart());
+ VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
+ if (oldAdjacentWords != newAdjacentWords) {
+ if (isContinuousGrammarCheckingEnabled) {
+ VisibleSelection oldSelectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart));
+ editor()->markMisspellingsAndBadGrammar(oldAdjacentWords, oldSelectedSentence != newSelectedSentence, oldSelectedSentence);
+ } else
+ editor()->markMisspellingsAndBadGrammar(oldAdjacentWords, false, oldAdjacentWords);
+ }
+ }
+
+ // This only erases markers that are in the first unit (word or sentence) of the selection.
+ // Perhaps peculiar, but it matches AppKit.
+ if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange())
+ document()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
+ if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
+ document()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
+ }
+
+ // When continuous spell checking is off, existing markers disappear after the selection changes.
+ if (!isContinuousSpellCheckingEnabled)
+ document()->removeMarkers(DocumentMarker::Spelling);
+ if (!isContinuousGrammarCheckingEnabled)
+ document()->removeMarkers(DocumentMarker::Grammar);
+
+ editor()->respondToChangedSelection(oldSelection);
+}
+
+VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
+{
+ HitTestResult result = eventHandler()->hitTestResultAtPoint(framePoint, true);
+ Node* node = result.innerNode();
+ if (!node)
+ return VisiblePosition();
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return VisiblePosition();
+ VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint());
+ if (visiblePos.isNull())
+ visiblePos = VisiblePosition(Position(node, 0));
+ return visiblePos;
+}
+
+Document* Frame::documentAtPoint(const IntPoint& point)
+{
+ if (!view())
+ return 0;
+
+ IntPoint pt = view()->windowToContents(point);
+ HitTestResult result = HitTestResult(pt);
+
+ if (contentRenderer())
+ result = eventHandler()->hitTestResultAtPoint(pt, false);
+ return result.innerNode() ? result.innerNode()->document() : 0;
+}
+
+void Frame::createView(const IntSize& viewportSize,
+ const Color& backgroundColor, bool transparent,
+ const IntSize& fixedLayoutSize, bool useFixedLayout,
+ ScrollbarMode horizontalScrollbarMode, ScrollbarMode verticalScrollbarMode)
+{
+ ASSERT(this);
+ ASSERT(m_page);
+
+ bool isMainFrame = this == m_page->mainFrame();
+
+ if (isMainFrame && view())
+ view()->setParentVisible(false);
+
+ setView(0);
+
+ RefPtr<FrameView> frameView;
+ if (isMainFrame) {
+ frameView = FrameView::create(this, viewportSize);
+ frameView->setFixedLayoutSize(fixedLayoutSize);
+ frameView->setUseFixedLayout(useFixedLayout);
+ } else
+ frameView = FrameView::create(this);
+
+ frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode);
+
+ setView(frameView);
+
+ if (backgroundColor.isValid())
+ frameView->updateBackgroundRecursively(backgroundColor, transparent);
+
+ if (isMainFrame)
+ frameView->setParentVisible(true);
+
+ if (ownerRenderer())
+ ownerRenderer()->setWidget(frameView);
+
+ if (HTMLFrameOwnerElement* owner = ownerElement())
+ view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
+}
+
+#if PLATFORM(WKC)
+void Frame::deleteSharedInstance()
+{
+ HTMLNames::finalize();
+#if ENABLE(SVG)
+ SVGNames::finalize();
+ XLinkNames::finalize();
+#endif
+
+#if ENABLE(WML)
+ WMLNames::finalize();
+#endif
+
+#if ENABLE(MATHML)
+ MathMLNames::finalize();
+#endif
+ XMLNames::finalize();
+
+ delete gWordRegExp;
+#ifndef NDEBUG
+ delete gStaticKeepAliveSet;
+ delete gFrameCounter;
+#endif
+}
+
+void Frame::resetVariables()
+{
+ HTMLNames::finalize();
+#if ENABLE(SVG)
+ SVGNames::finalize();
+ XLinkNames::finalize();
+#endif
+
+#if ENABLE(WML)
+ WMLNames::finalize();
+#endif
+
+#if ENABLE(MATHML)
+ MathMLNames::finalize();
+#endif
+ XMLNames::finalize();
+
+ gWordRegExp = 0;
+ gAlreadyInSelectionLayoutChanged = 0;
+#ifndef NDEBUG
+ gStaticKeepAliveSet = 0;
+ gFrameCounter = 0;
+#endif
+}
+#endif
+
+#if ENABLE(WKC_FRAME_FLATTENING)
+void Frame::invalidateOwnerRendererLayoutIfNeeded()
+{
+ if (settings() && settings()->flatFrameSetLayoutEnabled() && ownerRenderer())
+ ownerRenderer()->setNeedsLayout(true, true);
+}
+
+bool Frame::isFrameSet() const
+{
+ Document* doc = m_doc.get();
+ if (!doc || !doc->isHTMLDocument())
+ return false;
+ Node *body = static_cast<HTMLDocument*>(doc)->body();
+ return body && body->renderer() && body->hasTagName(framesetTag);
+}
+
+#endif
+} // namespace WebCore
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/FrameView.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/FrameView.cpp
index a850d7c..7f024b9 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/FrameView.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/FrameView.cpp
@@ -3,7 +3,7 @@
* 1999 Lars Knoll <knoll@kde.org>
* 1999 Antti Koivisto <koivisto@kde.org>
* 2000 Dirk Mueller <mueller@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* (C) 2006 Graham Dennis (graham.dennis@gmail.com)
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2009 Google Inc. All rights reserved.
@@ -568,7 +568,9 @@ void FrameView::layout(bool allowSubtree)
m_layoutRoot = 0;
}
+#if !PLATFORM(WKC)
ASSERT(m_frame->view() == this);
+#endif
// This early return should be removed when rdar://5598072 is resolved. In the meantime, there is a
// gigantic CrashTracer because of this issue, and the early return will hopefully cause graceful
// failure instead.
@@ -1326,7 +1328,8 @@ bool FrameView::needsLayout() const
|| m_layoutRoot
|| (document && document->childNeedsStyleRecalc()) // can occur when using WebKit ObjC interface
|| m_frame->needsReapplyStyles()
- || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
+ || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred)
+ || m_frame->selection()->needsDisplayUpdate();
}
void FrameView::setNeedsLayout()
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/History.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/History.cpp
index e45ae6e..c31735f 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/History.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/History.cpp
@@ -104,7 +104,12 @@ void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const Str
{
if (!m_frame)
return;
+#if !PLATFORM(WKC)
ASSERT(m_frame->page());
+#else
+ if (!m_frame->page())
+ return;
+#endif
KURL fullURL = urlForState(urlString);
#if 1
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/Page.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/Page.cpp
index 04b46c1..3ef92fb 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/page/Page.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/page/Page.cpp
@@ -406,7 +406,10 @@ void Page::refreshPlugins(bool reload)
HashSet<Page*>::iterator end = allPages->end();
for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
- (*it)->m_pluginData = 0;
+ if ((*it)->m_pluginData) {
+ (*it)->m_pluginData->disconnectPage();
+ (*it)->m_pluginData = 0;
+ }
if (reload) {
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/KURL.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/KURL.cpp
index a6b5bc6..bc579f1 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/KURL.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/KURL.cpp
@@ -221,6 +221,7 @@ static const unsigned invalidPortNumber = 0xFFFF;
static int copyPathRemovingDots(char* dst, const char* src, int srcStart, int srcEnd);
static void encodeRelativeString(const String& rel, const TextEncoding&, CharBuffer& ouput);
static String substituteBackslashes(const String&);
+static bool isValidProtocol(const String&);
static inline bool isSchemeFirstChar(char c) { return characterClassTable[static_cast<unsigned char>(c)] & SchemeFirstChar; }
static inline bool isSchemeFirstChar(UChar c) { return c <= 0xff && (characterClassTable[c] & SchemeFirstChar); }
@@ -581,9 +582,9 @@ unsigned short KURL::port() const
{
#if 1
// modified at webkit.org trunk r56879
- // We return a port of 0 if there is no port specified. This can happen in two situations:
- // 1) The URL contains no colon after the host name and before the path component of the URL.
- // 2) The URL contains a colon but there's no port number before the path component of the URL begins.
+ // We return a port of 0 if there is no port specified. This can happen in two situations:
+ // 1) The URL contains no colon after the host name and before the path component of the URL.
+ // 2) The URL contains a colon but there's no port number before the path component of the URL begins.
if (m_hostEnd == m_portEnd || m_hostEnd == m_portEnd - 1)
#else
if (m_hostEnd == m_portEnd)
@@ -592,10 +593,10 @@ unsigned short KURL::port() const
#if 1
// modified at webkit.org trunk r56489 and r56492
- const UChar* stringData = m_string.characters();
- bool ok = false;
- unsigned number = charactersToUIntStrict(stringData + m_hostEnd + 1, m_portEnd - m_hostEnd - 1, &ok);
- if (!ok || number > maximumValidPortNumber)
+ const UChar* stringData = m_string.characters();
+ bool ok = false;
+ unsigned number = charactersToUIntStrict(stringData + m_hostEnd + 1, m_portEnd - m_hostEnd - 1, &ok);
+ if (!ok || number > maximumValidPortNumber)
return invalidPortNumber;
#else
int number = m_string.substring(m_hostEnd + 1, m_portEnd - m_hostEnd - 1).toInt();
@@ -687,17 +688,22 @@ String KURL::path() const
return decodeURLEscapeSequences(m_string.substring(m_portEnd, m_pathEnd - m_portEnd));
}
-void KURL::setProtocol(const String& s)
+bool KURL::setProtocol(const String& s)
{
- // FIXME: Non-ASCII characters must be encoded and escaped to match parse() expectations,
- // and to avoid changing more than just the protocol.
+ // Firefox and IE remove everything after the first ':'.
+ int separatorPosition = s.find(':');
+ String newProtocol = s.substring(0, separatorPosition);
+
+ if (!isValidProtocol(newProtocol))
+ return false;
if (!m_isValid) {
- parse(s + ":" + m_string);
- return;
+ parse(newProtocol + ":" + m_string);
+ return true;
}
- parse(s + m_string.substring(m_schemeEnd));
+ parse(newProtocol + m_string.substring(m_schemeEnd));
+ return true;
}
void KURL::setHost(const String& s)
@@ -1658,6 +1664,9 @@ bool protocolIsJavaScript(const String& url)
bool isValidProtocol(const String& protocol)
{
+ // RFC3986: ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ if (protocol.isEmpty())
+ return false;
if (!isSchemeFirstChar(protocol[0]))
return false;
unsigned protocolLength = protocol.length();
@@ -1772,10 +1781,10 @@ bool portAllowed(const KURL& url)
6000, // X11
#if 1
// added at webkit.org trunk r54193
- 6665, // Alternate IRC [Apple addition]
- 6666, // Alternate IRC [Apple addition]
- 6667, // Standard IRC [Apple addition]
- 6668, // Alternate IRC [Apple addition]
+ 6665, // Alternate IRC [Apple addition]
+ 6666, // Alternate IRC [Apple addition]
+ 6667, // Standard IRC [Apple addition]
+ 6668, // Alternate IRC [Apple addition]
6669, // Alternate IRC [Apple addition]
// added at webkit.org trunk r56489
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/KURL.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/KURL.h
index c4429ea..197d2cb 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/KURL.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/KURL.h
@@ -149,7 +149,7 @@ public:
bool protocolInHTTPFamily() const;
bool isLocalFile() const;
- void setProtocol(const String&);
+ bool setProtocol(const String&);
void setHost(const String&);
void removePort();
@@ -278,7 +278,6 @@ const KURL& blankURL();
bool protocolIs(const String& url, const char* protocol);
bool protocolIsJavaScript(const String& url);
-bool isValidProtocol(const String& protocol);
bool isDefaultPortForProtocol(unsigned short port, const String& protocol);
bool portAllowed(const KURL&); // Blacklist ports that should never be used for Web resources.
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/LinkHash.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/LinkHash.cpp
index 878933a..5a93413 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/LinkHash.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/LinkHash.cpp
@@ -31,36 +31,36 @@
namespace WebCore {
-static inline int findSlashDotDotSlash(const UChar* characters, size_t length)
+static inline int findSlashDotDotSlash(const UChar* characters, size_t length, size_t position)
{
if (length < 4)
return -1;
- unsigned loopLimit = length - 3;
- for (unsigned i = 0; i < loopLimit; ++i) {
+ size_t loopLimit = length - 3;
+ for (size_t i = position; i < loopLimit; ++i) {
if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '.' && characters[i + 3] == '/')
return i;
}
return -1;
}
-static inline int findSlashSlash(const UChar* characters, size_t length, int position)
+static inline int findSlashSlash(const UChar* characters, size_t length, size_t position)
{
if (length < 2)
return -1;
- unsigned loopLimit = length - 1;
- for (unsigned i = position; i < loopLimit; ++i) {
+ size_t loopLimit = length - 1;
+ for (size_t i = position; i < loopLimit; ++i) {
if (characters[i] == '/' && characters[i + 1] == '/')
return i;
}
return -1;
}
-static inline int findSlashDotSlash(const UChar* characters, size_t length)
+static inline int findSlashDotSlash(const UChar* characters, size_t length, size_t position)
{
if (length < 3)
return -1;
- unsigned loopLimit = length - 2;
- for (unsigned i = 0; i < loopLimit; ++i) {
+ size_t loopLimit = length - 2;
+ for (size_t i = position; i < loopLimit; ++i) {
if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '/')
return i;
}
@@ -79,42 +79,90 @@ static inline bool containsColonSlashSlash(const UChar* characters, unsigned len
return false;
}
-static inline void cleanPath(Vector<UChar, 512>& path)
+static inline void squeezeOutNullCharacters(Vector<UChar, 512>& string)
{
- // FIXME: Shold not do this in the query or anchor part.
- int pos;
- while ((pos = findSlashDotDotSlash(path.data(), path.size())) != -1) {
- int prev = reverseFind(path.data(), path.size(), '/', pos - 1);
- // don't remove the host, i.e. http://foo.org/../foo.html
- if (prev < 0 || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/'))
- path.remove(pos, 3);
- else
- path.remove(prev, pos - prev + 3);
+ size_t size = string.size();
+ size_t i = 0;
+ for (i = 0; i < size; ++i) {
+ if (!string[i])
+ break;
}
+ if (i == size)
+ return;
+ size_t j = i;
+ for (++i; i < size; ++i) {
+ if (UChar character = string[i])
+ string[j++] = character;
+ }
+ ASSERT(j < size);
+ string.shrink(j);
+}
- // FIXME: Shold not do this in the query part.
- // Set refPos to -2 to mean "I haven't looked for the anchor yet".
- // We don't want to waste a function call on the search for the the anchor
- // in the vast majority of cases where there is no "//" in the path.
- pos = 0;
- int refPos = -2;
- while ((pos = findSlashSlash(path.data(), path.size(), pos)) != -1) {
- if (refPos == -2)
- refPos = find(path.data(), path.size(), '#');
- if (refPos > 0 && pos >= refPos)
- break;
+static void cleanSlashDotDotSlashes(Vector<UChar, 512>& path, size_t firstSlash)
+{
+ size_t slash = firstSlash;
+ do {
+ size_t previousSlash = slash ? reverseFind(path.data(), path.size(), '/', slash - 1) : notFound;
+ // Don't remove the host, i.e. http://foo.org/../foo.html
+ if (previousSlash == notFound || (previousSlash > 3 && path[previousSlash - 2] == ':' && path[previousSlash - 1] == '/')) {
+ path[slash] = 0;
+ path[slash + 1] = 0;
+ path[slash + 2] = 0;
+ } else {
+ for (size_t i = previousSlash; i < slash + 3; ++i)
+ path[i] = 0;
+ }
+ slash += 3;
+ } while ((slash = findSlashDotDotSlash(path.data(), path.size(), slash)) != notFound);
+ squeezeOutNullCharacters(path);
+}
+
+static void mergeDoubleSlashes(Vector<UChar, 512>& path, size_t firstSlash)
+{
+ size_t refPos = find(path.data(), path.size(), '#');
+ if (!refPos || refPos == notFound)
+ refPos = path.size();
- if (pos == 0 || path[pos - 1] != ':')
- path.remove(pos);
+ size_t slash = firstSlash;
+ while (slash < refPos) {
+ if (!slash || path[slash - 1] != ':')
+ path[slash++] = 0;
else
- pos += 2;
+ slash += 2;
+ if ((slash = findSlashSlash(path.data(), path.size(), slash)) == notFound)
+ break;
}
+ squeezeOutNullCharacters(path);
+}
- // FIXME: Shold not do this in the query or anchor part.
- while ((pos = findSlashDotSlash(path.data(), path.size())) != -1)
- path.remove(pos, 2);
+static void cleanSlashDotSlashes(Vector<UChar, 512>& path, size_t firstSlash)
+{
+ size_t slash = firstSlash;
+ do {
+ path[slash] = 0;
+ path[slash + 1] = 0;
+ slash += 2;
+ } while ((slash = findSlashDotSlash(path.data(), path.size(), slash)) != notFound);
+ squeezeOutNullCharacters(path);
}
+static inline void cleanPath(Vector<UChar, 512>& path)
+{
+ // FIXME: Should not do this in the query or anchor part of the URL.
+ size_t firstSlash = findSlashDotDotSlash(path.data(), path.size(), 0);
+ if (firstSlash != notFound)
+ cleanSlashDotDotSlashes(path, firstSlash);
+
+ // FIXME: Should not do this in the query part.
+ firstSlash = findSlashSlash(path.data(), path.size(), 0);
+ if (firstSlash != notFound)
+ mergeDoubleSlashes(path, firstSlash);
+
+ // FIXME: Should not do this in the query or anchor part.
+ firstSlash = findSlashDotSlash(path.data(), path.size(), 0);
+ if (firstSlash != notFound)
+ cleanSlashDotSlashes(path, firstSlash);
+}
static inline bool matchLetter(UChar c, UChar lowercaseLetter)
{
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/graphics/Font.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/graphics/Font.h
index 175cd07..ca504b1 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/graphics/Font.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/graphics/Font.h
@@ -107,6 +107,7 @@ public:
bool isPlatformFont() const { return m_isPlatformFont; }
// Metrics that we query the FontFallbackList for.
+#if !PLATFORM(WKC)
int ascent() const { return primaryFont()->ascent(); }
int descent() const { return primaryFont()->descent(); }
int height() const { return ascent() + descent(); }
@@ -115,6 +116,16 @@ public:
float xHeight() const { return primaryFont()->xHeight(); }
unsigned unitsPerEm() const { return primaryFont()->unitsPerEm(); }
int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); }
+#else
+ int ascent() const { return m_fontList ? primaryFont()->ascent() : 0; }
+ int descent() const { return m_fontList ? primaryFont()->descent() : 0; }
+ int height() const { return ascent() + descent(); }
+ int lineSpacing() const { return m_fontList ? primaryFont()->lineSpacing() : 0; }
+ int lineGap() const { return m_fontList ? primaryFont()->lineGap() : 0; }
+ float xHeight() const { return m_fontList ? primaryFont()->xHeight() : 0; }
+ unsigned unitsPerEm() const { return m_fontList ? primaryFont()->unitsPerEm() : 0; }
+ int spaceWidth() const { return m_fontList ? (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing) : 0; }
+#endif
int tabWidth() const { return 8 * spaceWidth(); }
const SimpleFontData* primaryFont() const;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/text/BidiResolver.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/text/BidiResolver.h
index 13e935e..c066948 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/text/BidiResolver.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/text/BidiResolver.h
@@ -361,14 +361,13 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire
if (!emptyRun && eor != last) {
ASSERT(m_status.eor != OtherNeutral || eor.atEnd());
// bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last
- ASSERT(m_status.last == EuropeanNumberSeparator
- || m_status.last == EuropeanNumberTerminator
- || m_status.last == CommonNumberSeparator
- || m_status.last == BoundaryNeutral
- || m_status.last == BlockSeparator
- || m_status.last == SegmentSeparator
- || m_status.last == WhiteSpaceNeutral
- || m_status.last == OtherNeutral);
+ ASSERT(m_status.last != NonSpacingMark
+ && m_status.last != BoundaryNeutral
+ && m_status.last != RightToLeftEmbedding
+ && m_status.last != LeftToRightEmbedding
+ && m_status.last != RightToLeftOverride
+ && m_status.last != LeftToRightOverride
+ && m_status.last != PopDirectionalFormat);
if (m_direction == OtherNeutral)
m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightToLeft;
if (to == LeftToRight) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/text/StringBuffer.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/text/StringBuffer.h
index 353a44a..aec6099 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/platform/text/StringBuffer.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/platform/text/StringBuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 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
@@ -32,6 +32,7 @@
#include <wtf/Assertions.h>
#include <wtf/Noncopyable.h>
#include <wtf/unicode/Unicode.h>
+#include <limits>
namespace WebCore {
@@ -39,8 +40,10 @@ class StringBuffer : public Noncopyable {
public:
explicit StringBuffer(unsigned length)
: m_length(length)
- , m_data(static_cast<UChar*>(fastMalloc(length * sizeof(UChar))))
{
+ if (m_length > std::numeric_limits<unsigned>::max() / sizeof(UChar))
+ CRASH();
+ m_data = static_cast<UChar*>(fastMalloc(m_length * sizeof(UChar)));
}
~StringBuffer()
{
@@ -55,8 +58,11 @@ public:
void resize(unsigned newLength)
{
- if (newLength > m_length)
+ if (newLength > m_length) {
+ if (newLength > std::numeric_limits<unsigned>::max() / sizeof(UChar))
+ CRASH();
m_data = static_cast<UChar*>(fastRealloc(m_data, newLength * sizeof(UChar)));
+ }
m_length = newLength;
}
@@ -72,6 +78,6 @@ private:
UChar* m_data;
};
-}
+} // namespace WTF
-#endif
+#endif // StringBuffer_h
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/CounterNode.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/CounterNode.cpp
index 28196d6..30aecce 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/CounterNode.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/CounterNode.cpp
@@ -54,6 +54,11 @@ CounterNode::CounterNode(RenderObject* o, bool hasResetType, int value)
{
}
+PassRefPtr<CounterNode> CounterNode::create(RenderObject* renderer, bool hasResetType, int value)
+{
+ return adoptRef(new CounterNode(renderer, hasResetType, value));
+}
+
CounterNode* CounterNode::nextInPreOrderAfterChildren(const CounterNode* stayWithin) const
{
if (this == stayWithin)
@@ -149,7 +154,10 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, cons
ASSERT(!newChild->m_parent);
ASSERT(!newChild->m_previousSibling);
ASSERT(!newChild->m_nextSibling);
- ASSERT(!refChild || refChild->m_parent == this);
+ // If the refChild is not our child we can not complete the request. This hardens against bugs in RenderCounter.
+ // When renderers are reparented it may request that we insert counter nodes improperly.
+ if (refChild && refChild->m_parent != this)
+ return;
#if 1
// modified at webkit.org trunk r53355
if (newChild->m_hasResetType) {
@@ -204,32 +212,43 @@ void CounterNode::insertAfter(CounterNode* newChild, CounterNode* refChild, cons
next->recount(identifier);
return;
}
+ // If the new child is the last in the sibling list we must set the parent's lastChild.
+ if (!newChild->m_nextSibling)
+ m_lastChild = newChild;
// The code below handles the case when a formerly root increment counter is loosing its root position
// and therefore its children become next siblings.
CounterNode* last = newChild->m_lastChild;
CounterNode* first = newChild->m_firstChild;
- newChild->m_nextSibling = first;
- first->m_previousSibling = newChild;
- // The case when the original next sibling of the inserted node becomes a child of
- // one of the former children of the inserted node is not handled as it is believed
- // to be impossible since:
- // 1. if the increment counter node lost it's root position as a result of another
- // counter node being created, it will be inserted as the last child so next is null.
- // 2. if the increment counter node lost it's root position as a result of a renderer being
- // inserted into the document's render tree, all its former children counters are attached
- // to children of the inserted renderer and hence cannot be in scope for counter nodes
- // attached to renderers that were already in the document's render tree.
- last->m_nextSibling = next;
- if (next)
- next->m_previousSibling = last;
- else
- m_lastChild = last;
- for (next = first; ; next = next->m_nextSibling) {
- next->m_parent = this;
- if (last == next)
- break;
+ if (first) {
+ ASSERT(last);
+ newChild->m_nextSibling = first;
+ if (m_lastChild == newChild)
+ m_lastChild = last;
+
+ first->m_previousSibling = newChild;
+
+ // The case when the original next sibling of the inserted node becomes a child of
+ // one of the former children of the inserted node is not handled as it is believed
+ // to be impossible since:
+ // 1. if the increment counter node lost it's root position as a result of another
+ // counter node being created, it will be inserted as the last child so next is null.
+ // 2. if the increment counter node lost it's root position as a result of a renderer being
+ // inserted into the document's render tree, all its former children counters are attached
+ // to children of the inserted renderer and hence cannot be in scope for counter nodes
+ // attached to renderers that were already in the document's render tree.
+ last->m_nextSibling = next;
+ if (next) {
+ ASSERT(next->m_previousSibling == newChild);
+ next->m_previousSibling = last;
+ } else
+ m_lastChild = last;
+ for (next = first; ; next = next->m_nextSibling) {
+ next->m_parent = this;
+ if (last == next)
+ break;
+ }
}
newChild->m_firstChild = 0;
newChild->m_lastChild = 0;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/CounterNode.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/CounterNode.h
index 15f2eb8..c942408 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/CounterNode.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/CounterNode.h
@@ -22,7 +22,9 @@
#ifndef CounterNode_h
#define CounterNode_h
+#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
+#include <wtf/RefCounted.h>
// This implements a counter tree that is used for finding parents in counters() lookup,
// and for propagating count changes when nodes are added or removed.
@@ -38,9 +40,9 @@ namespace WebCore {
class AtomicString;
class RenderObject;
-class CounterNode : public Noncopyable {
+class CounterNode : public RefCounted<CounterNode> {
public:
- CounterNode(RenderObject*, bool isReset, int value);
+ static PassRefPtr<CounterNode> create(RenderObject*, bool isReset, int value);
bool actsAsReset() const { return m_hasResetType || !m_parent; }
bool hasResetType() const { return m_hasResetType; }
@@ -64,6 +66,7 @@ public:
void removeChild(CounterNode*, const AtomicString& identifier);
private:
+ CounterNode(RenderObject*, bool isReset, int value);
int computeCountInParent() const;
void recount(const AtomicString& identifier);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/InlineBox.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/InlineBox.cpp
index 3b44271..118dfb8 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/InlineBox.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/InlineBox.cpp
@@ -72,7 +72,8 @@ void InlineBox::destroy(RenderArena* renderArena)
// Recover the size left there for us by operator delete and free the memory.
#if defined(ENABLE_REPLACEMENT_FASTMALLOC) || defined(_CRTDBG_MAP_ALLOC)
- renderArena->renderarena_free(*(size_t *)this, this);
+ if (renderArena)
+ renderArena->renderarena_free(*(size_t *)this, this);
#else
renderArena->free(*(size_t *)this, this);
#endif
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/InlineBox.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/InlineBox.h
index 4b2cce8..7fba416 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/InlineBox.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/InlineBox.h
@@ -116,6 +116,8 @@ public:
virtual void paint(RenderObject::PaintInfo&, int tx, int ty);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
+ InlineBox* next() const { return m_next; }
+
// Overloaded new operator.
#if PLATFORM(WKC) && COMPILER(RVCT)
void* operator new(size_t, RenderArena*);
@@ -161,8 +163,6 @@ public:
CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT);
#endif
m_constructed = true;
- if (m_next)
- m_next->setConstructed();
}
void setExtracted(bool b = true) { m_extracted = b; }
@@ -297,7 +297,7 @@ protected:
mutable bool m_determinedIfPrevOnLineExists : 1;
mutable bool m_nextOnLineExists : 1;
mutable bool m_prevOnLineExists : 1;
- int m_toAdd : 12; // for justified text
+ signed m_toAdd : 12; // for justified text
#ifndef NDEBUG
private:
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/InlineFlowBox.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/InlineFlowBox.h
index 23b5cc9..669d8bb 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/InlineFlowBox.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/InlineFlowBox.h
@@ -68,8 +68,8 @@ public:
virtual void setConstructed()
{
InlineBox::setConstructed();
- if (firstChild())
- firstChild()->setConstructed();
+ for (InlineBox* child = firstChild(); child; child = child->next())
+ child->setConstructed();
}
void addToLine(InlineBox* child);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBlock.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBlock.cpp
index d05a412..9ce54ba 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBlock.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBlock.cpp
@@ -129,6 +129,7 @@ RenderBlock::RenderBlock(Node* node)
, m_inlineContinuation(0)
, m_maxMargin(0)
, m_lineHeight(-1)
+ , m_beingDestroyed(false)
{
setChildrenInline(true);
}
@@ -164,6 +165,9 @@ RenderBlock::~RenderBlock()
void RenderBlock::destroy()
{
+ // Mark as being destroyed to avoid trouble with merges in removeChild().
+ m_beingDestroyed = true;
+
// Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
// properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
children()->destroyLeftoverChildren();
@@ -267,8 +271,13 @@ void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
// Make sure we don't append things after :after-generated content if we have it.
- if (!beforeChild && isAfterContent(lastChild()))
- beforeChild = lastChild();
+ if (!beforeChild) {
+ RenderObject* lastRenderer = lastChild();
+ while (lastRenderer && lastRenderer->isAnonymous() && !isAfterContent(lastRenderer))
+ lastRenderer = lastRenderer->lastChild();
+ if (lastRenderer && isAfterContent(lastRenderer))
+ beforeChild = lastRenderer;
+ }
bool madeBoxesNonInline = false;
@@ -552,6 +561,10 @@ void RenderBlock::removeChild(RenderObject* oldChild)
&& !(prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
#endif
;
+ if (canDeleteAnonymousBlocks) {
+ canDeleteAnonymousBlocks = !(((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->inlineContinuation() || toRenderBlock(prev)->beingDestroyed()))
+ || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->inlineContinuation() || toRenderBlock(next)->beingDestroyed()))));
+ }
if (canDeleteAnonymousBlocks && prev && next) {
// Take all the children out of the |next| block and put them in
// the |prev| block.
@@ -1049,7 +1062,8 @@ bool RenderBlock::handleRunInChild(RenderBox* child)
if (runInNode)
runInNode->setRenderer(inlineRunIn);
- // Destroy the block run-in.
+ // Destroy the block run-in, which includes deleting its line box tree.
+ blockRunIn->deleteLineBoxTree();
blockRunIn->destroy();
// The block acts like an inline, so just null out its
@@ -4845,9 +4859,8 @@ void RenderBlock::updateFirstLetter()
if (remainingText->node())
remainingText->node()->setRenderer(remainingText);
- RenderObject* nextObj = textObj->nextSibling();
+ firstLetterContainer->addChild(remainingText, textObj);
firstLetterContainer->removeChild(textObj);
- firstLetterContainer->addChild(remainingText, nextObj);
remainingText->setFirstLetter(firstLetter);
#else
if (currChild->isText() && !currChild->isBR() && currChild->parent()->style()->styleType() != FIRST_LETTER) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBlock.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBlock.h
index 9b00dee..7523e9c 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBlock.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBlock.h
@@ -64,6 +64,7 @@ public:
RenderObjectChildList* children() { return &m_children; }
virtual void destroy();
+ bool beingDestroyed() const { return m_beingDestroyed; }
// These two functions are overridden for inline-block.
virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
@@ -157,7 +158,7 @@ protected:
void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child);
#if 1
// added at webkit.org trunk r53525
- void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList);
+ void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList);
void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild);
#endif
@@ -263,12 +264,12 @@ private:
};
// The following functions' implementations are in RenderBlockLineLayout.cpp.
+ void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end, bool previousLineBrokeCleanly);
RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
- RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart,
- BidiStatus& cleanLineBidiStatus,
- int& yPos);
+ RootInlineBox* determineEndPosition(RootInlineBox* startBox, Vector<FloatWithRect>& floats, size_t floatIndex, InlineIterator& cleanLineStart,
+ BidiStatus& cleanLineBidiStatus, int& yPos);
bool matchedEndLine(const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus,
RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop);
@@ -533,12 +534,13 @@ private:
RenderObjectChildList m_children;
RenderLineBoxList m_lineBoxes; // All of the root line boxes created for this block flow. For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
- mutable int m_lineHeight;
+ mutable signed m_lineHeight : 31;
+ bool m_beingDestroyed : 1;
#if 1
// added at webkit.org trunk r53525
- // RenderRubyBase objects need to be able to split and merge, moving their children around
- // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
+ // RenderRubyBase objects need to be able to split and merge, moving their children around
+ // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
friend class RenderRubyBase;
#endif
};
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBlockLineLayout.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBlockLineLayout.cpp
index d7013ba..419510a 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -1035,9 +1035,9 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
// if we determine that we're able to synchronize after handling all our dirty lines.
InlineIterator cleanLineStart;
BidiStatus cleanLineBidiStatus;
- int endLineYPos = 0;
+ int endLineLogicalTop = 0;
RootInlineBox* endLine = (fullLayout || !startLine) ?
- 0 : determineEndPosition(startLine, cleanLineStart, cleanLineBidiStatus, endLineYPos);
+ 0 : determineEndPosition(startLine, floats, floatIndex, cleanLineStart, cleanLineBidiStatus, endLineLogicalTop);
if (startLine) {
useRepaintBounds = true;
@@ -1081,7 +1081,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
while (!end.atEnd()) {
// FIXME: Is this check necessary before the first iteration or can it be moved to the end?
- if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineYPos, repaintBottom, repaintTop)))
+ if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineLogicalTop, repaintBottom, repaintTop)))
break;
lineMidpointState.reset();
@@ -1097,7 +1097,10 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
}
ASSERT(end != resolver.position());
- if (!isLineEmpty) {
+ if (isLineEmpty) {
+ if (lastRootBox())
+ lastRootBox()->setLineBreakInfo(end.obj, end.pos, resolver.status());
+ } else {
bidiReorderLine(resolver, end, previousLineBrokeCleanly);
ASSERT(resolver.position() == end);
@@ -1219,7 +1222,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
if (endLine) {
if (endLineMatched) {
// Attach all the remaining lines, and then adjust their y-positions as needed.
- int delta = height() - endLineYPos;
+ int delta = height() - endLineLogicalTop;
for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) {
line->attachLine();
if (delta) {
@@ -1292,6 +1295,34 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
checkLinesForTextOverflow();
}
+void RenderBlock::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWithRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat)
+{
+ Vector<RenderBox*>* cleanLineFloats = line->floatsPtr();
+ if (!cleanLineFloats)
+ return;
+
+ Vector<RenderBox*>::iterator end = cleanLineFloats->end();
+ for (Vector<RenderBox*>::iterator it = cleanLineFloats->begin(); it != end; ++it) {
+ RenderBox* floatingBox = *it;
+ floatingBox->layoutIfNeeded();
+ IntSize newSize(floatingBox->width() + floatingBox->marginLeft() + floatingBox->marginRight(), floatingBox->height() + floatingBox->marginTop() + floatingBox->marginBottom());
+ ASSERT(floatIndex < floats.size());
+ if (floats[floatIndex].object != floatingBox) {
+ encounteredNewFloat = true;
+ return;
+ }
+ if (floats[floatIndex].rect.size() != newSize) {
+ int floatTop = floats[floatIndex].rect.y();
+ int floatHeight = max(floats[floatIndex].rect.height(), newSize.height());
+ line->markDirty();
+ markLinesDirtyInVerticalRange(line->blockHeight(), floatTop + floatHeight);
+ floats[floatIndex].rect.setSize(newSize);
+ dirtiedByFloat = true;
+ }
+ floatIndex++;
+ }
+}
+
RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats)
{
@@ -1302,28 +1333,8 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLa
if (!fullLayout) {
size_t floatIndex = 0;
for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
- if (Vector<RenderBox*>* cleanLineFloats = curr->floatsPtr()) {
- Vector<RenderBox*>::iterator end = cleanLineFloats->end();
- for (Vector<RenderBox*>::iterator o = cleanLineFloats->begin(); o != end; ++o) {
- RenderBox* f = *o;
- IntSize newSize(f->width() + f->marginLeft() +f->marginRight(), f->height() + f->marginTop() + f->marginBottom());
- ASSERT(floatIndex < floats.size());
- if (floats[floatIndex].object != f) {
- // A new float has been inserted before this line or before its last known float.
- // Just do a full layout.
- fullLayout = true;
- break;
- }
- if (floats[floatIndex].rect.size() != newSize) {
- int floatTop = floats[floatIndex].rect.y();
- curr->markDirty();
- markLinesDirtyInVerticalRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()));
- floats[floatIndex].rect.setSize(newSize);
- dirtiedByFloat = true;
- }
- floatIndex++;
- }
- }
+ // If a new float has been inserted before this line or before its last known float,just do a full layout.
+ checkFloatsInCleanLine(curr, floats, floatIndex, fullLayout, dirtiedByFloat);
if (dirtiedByFloat || fullLayout)
break;
}
@@ -1349,7 +1360,7 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLa
// We have a dirty line.
if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
// We have a previous line.
- if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength())))
+ if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength())))
// The previous line didn't break cleanly or broke at a newline
// that has been deleted, so treat it as dirty too.
curr = prevRootBox;
@@ -1417,27 +1428,33 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLa
return curr;
}
-RootInlineBox* RenderBlock::determineEndPosition(RootInlineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus, int& yPos)
+RootInlineBox* RenderBlock::determineEndPosition(RootInlineBox* startLine, Vector<FloatWithRect>& floats, size_t floatIndex, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus, int& logicalTop)
{
RootInlineBox* last = 0;
- if (!startLine)
- last = 0;
- else {
- for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) {
- if (curr->isDirty())
- last = 0;
- else if (!last)
- last = curr;
+ for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) {
+ if (!curr->isDirty()) {
+ bool encounteredNewFloat = false;
+ bool dirtiedByFloat = false;
+ checkFloatsInCleanLine(curr, floats, floatIndex, encounteredNewFloat, dirtiedByFloat);
+ if (encounteredNewFloat)
+ return 0;
}
+ if (curr->isDirty())
+ last = 0;
+ else if (!last)
+ last = curr;
}
if (!last)
return 0;
+ // At this point, |last| is the first line in a run of clean lines that ends with the last line
+ // in the block.
+
RootInlineBox* prev = last->prevRootBox();
cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakPos());
cleanLineBidiStatus = prev->lineBreakBidiStatus();
- yPos = prev->blockHeight();
+ logicalTop = prev->blockHeight();
for (RootInlineBox* line = last; line; line = line->nextRootBox())
line->extractLine(); // Disconnect all line boxes from their render objects while preserving
@@ -1819,6 +1836,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
if (floatsFitOnLine && floatBox->width() + floatBox->marginLeft() + floatBox->marginRight() + w + tmpW <= width) {
positionNewFloats();
width = lineWidth(height(), firstLine);
+ if (lBreak.obj == o) {
+ ASSERT(!lBreak.pos);
+ lBreak.increment();
+ }
} else
floatsFitOnLine = false;
} else if (o->isPositioned()) {
@@ -2075,7 +2096,9 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
lBreak.increment();
previousLineBrokeCleanly = true;
}
- goto end; // Didn't fit. Jump to the end.
+ // Didn't fit. Jump to the end unless there's still an opportunity to collapse whitespace.
+ if (ignoringSpaces || !o->style()->collapseWhiteSpace() || !currentCharacterIsSpace || !previousCharacterIsSpace)
+ goto end;
} else {
if (!betweenWords || (midWordBreak && !autoWrap))
tmpW -= additionalTmpW;
@@ -2183,17 +2206,17 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
checkForBreak = true;
else if (next && o->isText() && next->isText() && !next->isBR()) {
if (autoWrap || (next->style()->autoWrap())) {
- if (currentCharacterIsSpace)
+ if (autoWrap && currentCharacterIsSpace)
checkForBreak = true;
else {
checkForBreak = false;
RenderText* nextText = toRenderText(next);
if (nextText->textLength()) {
UChar c = nextText->characters()[0];
- if (c == ' ' || c == '\t' || (c == '\n' && !shouldPreserveNewline(next)))
+ if (!currentCharacterIsSpace && (c == ' ' || c == '\t' || (c == '\n' && !shouldPreserveNewline(next))))
// If the next item on the line is text, and if we did not end with
// a space, then the next text run continues our word (and so it needs to
- // keep adding to |tmpW|. Just update and continue.
+ // keep adding to the uncommitted width. Just update and continue.
checkForBreak = true;
} else if (nextText->isWordBreak())
checkForBreak = true;
@@ -2264,16 +2287,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
end:
if (lBreak == resolver.position() && (!lBreak.obj || !lBreak.obj->isBR())) {
// we just add as much as possible
- if (style()->whiteSpace() == PRE) {
- // FIXME: Don't really understand this case.
- if (pos != 0) {
- lBreak.obj = o;
- lBreak.pos = pos - 1;
- } else {
- lBreak.obj = last;
- lBreak.pos = last->isText() ? last->length() : 0;
- lBreak.nextBreakablePosition = -1;
- }
+ if (style()->whiteSpace() == PRE && !pos) {
+ lBreak.obj = last;
+ lBreak.pos = last->isText() ? last->length() : 0;
+ lBreak.nextBreakablePosition = -1;
} else if (lBreak.obj) {
if (last != o && !last->isListMarker()) {
// better to break between object boundaries than in the middle of a word (except for list markers)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBox.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBox.cpp
index d03403e..068ef22 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBox.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBox.cpp
@@ -730,9 +730,10 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int tx, int ty, int
if (!compositedMask) {
StyleImage* maskBoxImage = style()->maskBoxImage().image();
- if (maskBoxImage && style()->maskLayers()->hasImage()) {
+ bool hasMaskLayerWithImage = style()->maskLayers()->hasImage();
+ if (maskBoxImage && hasMaskLayerWithImage) {
pushTransparencyLayer = true;
- } else {
+ } else if (hasMaskLayerWithImage) {
// We have to use an extra image buffer to hold the mask. Multiple mask images need
// to composite together using source-over so that they can then combine into a single unified mask that
// can be composited with the content using destination-in. SVG images need to be able to set compositing modes
@@ -741,7 +742,7 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, int tx, int ty, int
// We have to check that the mask images to be rendered contain at least one image that can be actually used in rendering
// before pushing the transparency layer.
for (const FillLayer* fillLayer = style()->maskLayers()->next(); fillLayer; fillLayer = fillLayer->next()) {
- if (fillLayer->hasImage() && fillLayer->image()->canRender(style()->effectiveZoom())) {
+ if (fillLayer->image() && fillLayer->image()->canRender(style()->effectiveZoom())) {
pushTransparencyLayer = true;
// We found one image that can be used in rendering, exit the loop
break;
@@ -1615,7 +1616,7 @@ void RenderBox::calcHeight()
// height since we don't set a height in RenderView when we're printing. So without this quirk, the
// height has nothing to be a percentage of, and it ends up being 0. That is bad.
bool printingNeedsBaseHeight = document()->printing() && h.isPercent()
- && (isRoot() || (isBody() && document()->documentElement()->renderer()->style()->height().isPercent()));
+ && (isRoot() || (isBody() && document()->documentElement()->renderer()->style()->height().isPercent())) && !isInline();
if (stretchesToViewHeight() || printingNeedsBaseHeight) {
int margins = collapsedMarginTop() + collapsedMarginBottom();
int visHeight = document()->printing() ? view()->frameView()->visibleHeight() : view()->viewHeight();
@@ -2939,7 +2940,7 @@ bool RenderBox::shrinkToAvoidFloats() const
bool RenderBox::avoidsFloats() const
{
- return isReplaced() || hasOverflowClip() || isHR();
+ return isReplaced() || hasOverflowClip() || isHR() || isDeprecatedFlexItem();
}
void RenderBox::addShadowOverflow()
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBox.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBox.h
index 5ed271a..f3af681 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBox.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBox.h
@@ -217,7 +217,7 @@ public:
bool stretchesToViewHeight() const
{
- return style()->htmlHacks() && style()->height().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody());
+ return style()->htmlHacks() && style()->height().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody()) && !isInline();
}
virtual IntSize intrinsicSize() const { return IntSize(); }
@@ -297,6 +297,8 @@ public:
bool shrinkToAvoidFloats() const;
virtual bool avoidsFloats() const;
+ bool isDeprecatedFlexItem() const { return !isInline() && !isFloatingOrPositioned() && parent() && parent()->isFlexibleBox(); }
+
#if ENABLE(SVG)
virtual TransformationMatrix localTransform() const;
#endif
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBoxModelObject.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBoxModelObject.cpp
index 2b0b857..59df760 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderBoxModelObject.cpp
@@ -527,6 +527,7 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
case SizeLength: {
int w = positioningAreaSize.width();
int h = positioningAreaSize.height();
+
Length layerWidth = fillLayer->size().size.width();
Length layerHeight = fillLayer->size().size.height();
@@ -542,15 +543,19 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
// If one of the values is auto we have to use the appropriate
// scale to maintain our aspect ratio.
- if (layerWidth.isAuto() && !layerHeight.isAuto())
- w = image->imageSize(this, style()->effectiveZoom()).width() * h / image->imageSize(this, style()->effectiveZoom()).height();
- else if (!layerWidth.isAuto() && layerHeight.isAuto())
- h = image->imageSize(this, style()->effectiveZoom()).height() * w / image->imageSize(this, style()->effectiveZoom()).width();
- else if (layerWidth.isAuto() && layerHeight.isAuto()) {
- // If both width and height are auto, we just want to use the image's
- // intrinsic size.
- w = image->imageSize(this, style()->effectiveZoom()).width();
- h = image->imageSize(this, style()->effectiveZoom()).height();
+ if (layerWidth.isAuto() && !layerHeight.isAuto()) {
+ IntSize imageIntrinsicSize = image->imageSize(this, style()->effectiveZoom());
+ if (imageIntrinsicSize.height())
+ w = imageIntrinsicSize.width() * h / imageIntrinsicSize.height();
+ } else if (!layerWidth.isAuto() && layerHeight.isAuto()) {
+ IntSize imageIntrinsicSize = image->imageSize(this, style()->effectiveZoom());
+ if (imageIntrinsicSize.width())
+ h = imageIntrinsicSize.height() * w / imageIntrinsicSize.width();
+ } else if (layerWidth.isAuto() && layerHeight.isAuto()) {
+ // If both width and height are auto, use the image's intrinsic size.
+ IntSize imageIntrinsicSize = image->imageSize(this, style()->effectiveZoom());
+ w = imageIntrinsicSize.width();
+ h = imageIntrinsicSize.height();
}
return IntSize(max(1, w), max(1, h));
@@ -558,8 +563,10 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
case Contain:
case Cover: {
IntSize imageIntrinsicSize = image->imageSize(this, 1);
- float horizontalScaleFactor = static_cast<float>(positioningAreaSize.width()) / imageIntrinsicSize.width();
- float verticalScaleFactor = static_cast<float>(positioningAreaSize.height()) / imageIntrinsicSize.height();
+ float horizontalScaleFactor = imageIntrinsicSize.width()
+ ? static_cast<float>(positioningAreaSize.width()) / imageIntrinsicSize.width() : 1;
+ float verticalScaleFactor = imageIntrinsicSize.height()
+ ? static_cast<float>(positioningAreaSize.height()) / imageIntrinsicSize.height() : 1;
float scaleFactor = type == Contain ? min(horizontalScaleFactor, verticalScaleFactor) : max(horizontalScaleFactor, verticalScaleFactor);
return IntSize(max<int>(1, imageIntrinsicSize.width() * scaleFactor), max<int>(1, imageIntrinsicSize.height() * scaleFactor));
@@ -567,6 +574,7 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
case SizeNone:
break;
}
+
return image->imageSize(this, style()->effectiveZoom());
}
@@ -815,6 +823,11 @@ void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx,
#if PLATFORM(WKC)
CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT);
#endif
+ if (graphicsContext->paintingDisabled())
+ return;
+ if (w<=0 || h<=0)
+ return;
+
if (paintNinePieceImage(graphicsContext, tx, ty, w, h, style, style->borderImage()))
return;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderCounter.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderCounter.cpp
index fb9ba9d..d05e65b 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderCounter.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderCounter.cpp
@@ -36,7 +36,7 @@ namespace WebCore {
using namespace HTMLNames;
-typedef HashMap<RefPtr<AtomicStringImpl>, CounterNode*> CounterMap;
+typedef HashMap<RefPtr<AtomicStringImpl>, RefPtr<CounterNode> > CounterMap;
typedef HashMap<const RenderObject*, CounterMap*> CounterMaps;
static CounterNode* makeCounterNode(RenderObject*, const AtomicString& identifier, bool alwaysCreateCounter);
@@ -149,7 +149,7 @@ static bool planCounter(RenderObject* object, const AtomicString& identifier, bo
// reset node.
// - Non-reset CounterNodes cannot have descendants.
-static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString& identifier, bool isReset, CounterNode*& parent, CounterNode*& previousSibling)
+static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString& identifier, bool isReset, RefPtr<CounterNode>& parent, RefPtr<CounterNode>& previousSibling)
{
// We cannot stop searching for counters with the same identifier before we also
// check this renderer, because it may affect the positioning in the tree of our counter.
@@ -179,14 +179,20 @@ static bool findPlaceForCounter(RenderObject* counterOwner, const AtomicString&
// We are not a reset node or the previous reset must be on an ancestor of our renderer
// hence we must be a child of that reset counter.
parent = currentCounter;
- ASSERT(previousSibling->parent() == currentCounter);
+ // In some cases renders can be reparented (ex. nodes inside a table but not in a column or row).
+ // In these cases the identified previousSibling will be invalid as its parent is different from
+ // our identified parent.
+ if (previousSibling->parent() != currentCounter)
+ previousSibling = 0;
return true;
}
// CurrentCounter, the counter at the EndSearchRenderer, is not reset.
if (!isReset || currentRenderer->parent() != counterOwner->parent()) {
// If the node we are placing is not reset or we have found a counter that is attached
// to an ancestor of the placed counter's renderer we know we are a sibling of that node.
- ASSERT(currentCounter->parent() == previousSibling->parent());
+ if (currentCounter->parent() != previousSibling->parent())
+ return false;
+
parent = currentCounter->parent();
return true;
}
@@ -254,21 +260,23 @@ static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& id
{
ASSERT(object);
- if (object->m_hasCounterNodeMap)
- if (CounterMap* nodeMap = counterMaps().get(object))
- if (CounterNode* node = nodeMap->get(identifier.impl()))
+ if (object->m_hasCounterNodeMap) {
+ if (CounterMap* nodeMap = counterMaps().get(object)) {
+ if (CounterNode* node = nodeMap->get(identifier.impl()).get())
return node;
+ }
+ }
bool isReset = false;
int value = 0;
if (!planCounter(object, identifier, isReset, value) && !alwaysCreateCounter)
return 0;
- CounterNode* newParent = 0;
- CounterNode* newPreviousSibling = 0;
- CounterNode* newNode = new CounterNode(object, isReset, value);
+ RefPtr<CounterNode> newParent = 0;
+ RefPtr<CounterNode> newPreviousSibling = 0;
+ RefPtr<CounterNode> newNode = CounterNode::create(object, isReset, value);
if (findPlaceForCounter(object, identifier, isReset, newParent, newPreviousSibling))
- newParent->insertAfter(newNode, newPreviousSibling, identifier);
+ newParent->insertAfter(newNode.get(), newPreviousSibling.get(), identifier);
CounterMap* nodeMap;
if (object->m_hasCounterNodeMap)
nodeMap = counterMaps().get(object);
@@ -281,7 +289,7 @@ static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& id
#if 1
// modified at webkit.org trunk r53355
if (newNode->parent() || !object->nextInPreOrder(object->parent()))
- return newNode;
+ return newNode.get();
// Checking if some nodes that were previously counter tree root nodes
// should become children of this node now.
CounterMaps& maps = counterMaps();
@@ -289,11 +297,10 @@ static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& id
for (RenderObject* currentRenderer = object->nextInPreOrder(stayWithin); currentRenderer; currentRenderer = currentRenderer->nextInPreOrder(stayWithin)) {
if (!currentRenderer->m_hasCounterNodeMap)
continue;
- CounterNode* currentCounter = maps.get(currentRenderer)->get(identifier.impl());
+ CounterNode* currentCounter = maps.get(currentRenderer)->get(identifier.impl()).get();
if (!currentCounter)
continue;
if (currentCounter->parent()) {
- ASSERT(newNode->firstChild());
if (currentRenderer->lastChild())
currentRenderer = currentRenderer->lastChild();
continue;
@@ -304,7 +311,7 @@ static CounterNode* makeCounterNode(RenderObject* object, const AtomicString& id
currentRenderer = currentRenderer->lastChild();
}
#endif
- return newNode;
+ return newNode.get();
}
RenderCounter::RenderCounter(Document* node, const CounterContent& counter)
@@ -371,9 +378,9 @@ static void destroyCounterNodeChildren(const AtomicString& identifier, CounterNo
#endif
{
CounterNode* previous;
- for (CounterNode* child = node->lastDescendant(); child && child != node; child = previous) {
+ for (RefPtr<CounterNode> child = node->lastDescendant(); child && child != node; child = previous) {
previous = child->previousInPreOrder();
- child->parent()->removeChild(child, identifier);
+ child->parent()->removeChild(child.get(), identifier);
ASSERT(counterMaps().get(child->renderer())->get(identifier.impl()) == child);
counterMaps().get(child->renderer())->remove(identifier.impl());
if (!child->renderer()->documentBeingDestroyed()) {
@@ -381,7 +388,6 @@ static void destroyCounterNodeChildren(const AtomicString& identifier, CounterNo
if (children)
children->invalidateCounters(child->renderer(), identifier);
}
- delete child;
}
#if 1
// modified at webkit.org trunk r53355
@@ -392,7 +398,6 @@ static void destroyCounterNodeChildren(const AtomicString& identifier, CounterNo
}
if (CounterNode* parent = node->parent())
parent->removeChild(node, identifier);
- delete node;
}
void RenderCounter::destroyCounterNodes(RenderObject* renderer)
@@ -433,7 +438,7 @@ void RenderCounter::destroyCounterNodes(RenderObject* object)
#endif
#if 1
// modified at webkit.org trunk r53355
- destroyCounterNodeWithoutMapRemoval(identifier, it->second);
+ destroyCounterNodeWithoutMapRemoval(identifier, it->second.get());
}
maps.remove(mapsIterator);
#endif
@@ -454,7 +459,7 @@ void RenderCounter::destroyCounterNode(RenderObject* renderer, const AtomicStrin
CounterMap::iterator mapIterator = map->find(identifier.impl());
if (mapIterator == map->end())
return;
- destroyCounterNodeWithoutMapRemoval(identifier, mapIterator->second);
+ destroyCounterNodeWithoutMapRemoval(identifier, mapIterator->second.get());
map->remove(mapIterator);
// We do not delete "map" here even if empty because we expect to reuse
// it soon. In order for a renderer to lose all its counters permanently,
@@ -484,23 +489,26 @@ static void updateCounters(RenderObject* renderer)
CounterMap* counterMap = counterMaps().get(renderer);
ASSERT(counterMap);
for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it) {
- CounterNode* node = counterMap->get(it->first.get());
+ RefPtr<CounterNode> node = counterMap->get(it->first.get());
if (!node) {
makeCounterNode(renderer, AtomicString(it->first.get()), false);
continue;
}
- CounterNode* newParent = 0;
- CounterNode* newPreviousSibling;
+ RefPtr<CounterNode> newParent = 0;
+ RefPtr<CounterNode> newPreviousSibling;
+
findPlaceForCounter(renderer, AtomicString(it->first.get()), node->hasResetType(), newParent, newPreviousSibling);
+ if (node != counterMap->get(it->first.get()))
+ continue;
CounterNode* parent = node->parent();
if (newParent == parent && newPreviousSibling == node->previousSibling())
continue;
if (parent)
- parent->removeChild(node, it->first.get());
+ parent->removeChild(node.get(), it->first.get());
#if 1
// added at webkit.org trunk r54317
if (newParent)
- newParent->insertAfter(node, newPreviousSibling, it->first.get());
+ newParent->insertAfter(node.get(), newPreviousSibling.get(), it->first.get());
#else
newParent->insertAfter(node, newPreviousSibling, it->first.get());
#endif
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderFlexibleBox.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderFlexibleBox.cpp
index 9649b17..69a6879 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderFlexibleBox.cpp
@@ -43,19 +43,20 @@ namespace WebCore {
class FlexBoxIterator {
public:
FlexBoxIterator(RenderFlexibleBox* parent)
+ : m_box(parent)
+ , m_largestOrdinal(1)
{
- box = parent;
- if (box->style()->boxOrient() == HORIZONTAL && box->style()->direction() == RTL)
- forward = box->style()->boxDirection() != BNORMAL;
+ if (m_box->style()->boxOrient() == HORIZONTAL && m_box->style()->direction() == RTL)
+ m_forward = m_box->style()->boxDirection() != BNORMAL;
else
- forward = box->style()->boxDirection() == BNORMAL;
- lastOrdinal = 1;
- if (!forward) {
+ m_forward = m_box->style()->boxDirection() == BNORMAL;
+ m_largestOrdinal = 1;
+ if (!m_forward) {
// No choice, since we're going backwards, we have to find out the highest ordinal up front.
- RenderBox* child = box->firstChildBox();
+ RenderBox* child = m_box->firstChildBox();
while (child) {
- if (child->style()->boxOrdinalGroup() > lastOrdinal)
- lastOrdinal = child->style()->boxOrdinalGroup();
+ if (child->style()->boxOrdinalGroup() > m_largestOrdinal)
+ m_largestOrdinal = child->style()->boxOrdinalGroup();
child = child->nextSiblingBox();
}
}
@@ -65,8 +66,8 @@ public:
void reset()
{
- current = 0;
- currentOrdinal = forward ? 0 : lastOrdinal+1;
+ m_currentChild = 0;
+ m_ordinalIteration = -1;
}
RenderBox* first()
@@ -77,35 +78,50 @@ public:
RenderBox* next()
{
- do {
- if (!current) {
- if (forward) {
- currentOrdinal++;
- if (currentOrdinal > lastOrdinal)
- return 0;
- current = box->firstChildBox();
- } else {
- currentOrdinal--;
- if (currentOrdinal == 0)
+ do {
+ if (!m_currentChild) {
+ ++m_ordinalIteration;
+
+ if (!m_ordinalIteration)
+ m_currentOrdinal = m_forward ? 1 : m_largestOrdinal;
+ else {
+ if (m_ordinalIteration >= m_ordinalValues.size() + 1)
return 0;
- current = box->lastChildBox();
+
+ // Only copy+sort the values once per layout even if the iterator is reset.
+ if (static_cast<size_t>(m_ordinalValues.size()) != m_sortedOrdinalValues.size()) {
+ copyToVector(m_ordinalValues, m_sortedOrdinalValues);
+ sort(m_sortedOrdinalValues.begin(), m_sortedOrdinalValues.end());
+ }
+ m_currentOrdinal = m_forward ? m_sortedOrdinalValues[m_ordinalIteration - 1] : m_sortedOrdinalValues[m_sortedOrdinalValues.size() - m_ordinalIteration];
}
- }
- else
- current = forward ? current->nextSiblingBox() : current->previousSiblingBox();
- if (current && current->style()->boxOrdinalGroup() > lastOrdinal)
- lastOrdinal = current->style()->boxOrdinalGroup();
- } while (!current || current->style()->boxOrdinalGroup() != currentOrdinal ||
- current->style()->visibility() == COLLAPSE);
- return current;
+
+ m_currentChild = m_forward ? m_box->firstChildBox() : m_box->lastChildBox();
+ } else
+ m_currentChild = m_forward ? m_currentChild->nextSiblingBox() : m_currentChild->previousSiblingBox();
+
+ if (m_currentChild && notFirstOrdinalValue())
+ m_ordinalValues.add(m_currentChild->style()->boxOrdinalGroup());
+ } while (!m_currentChild || (!m_currentChild->isAnonymous()
+ && (m_currentChild->style()->boxOrdinalGroup() != m_currentOrdinal || m_currentChild->style()->visibility() == COLLAPSE)));
+ return m_currentChild;
}
private:
- RenderFlexibleBox* box;
- RenderBox* current;
- bool forward;
- unsigned int currentOrdinal;
- unsigned int lastOrdinal;
+ bool notFirstOrdinalValue()
+ {
+ unsigned int firstOrdinalValue = m_forward ? 1 : m_largestOrdinal;
+ return m_currentOrdinal == firstOrdinalValue && m_currentChild->style()->boxOrdinalGroup() != firstOrdinalValue;
+ }
+
+ RenderFlexibleBox* m_box;
+ RenderBox* m_currentChild;
+ bool m_forward;
+ unsigned int m_currentOrdinal;
+ unsigned int m_largestOrdinal;
+ HashSet<unsigned int> m_ordinalValues;
+ Vector<unsigned int> m_sortedOrdinalValues;
+ int m_ordinalIteration;
};
RenderFlexibleBox::RenderFlexibleBox(Node* node)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderFrameSet.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderFrameSet.cpp
index 22fe93f..eb2d2ac 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderFrameSet.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderFrameSet.cpp
@@ -144,14 +144,14 @@ void RenderFrameSet::paint(PaintInfo& paintInfo, int tx, int ty)
tx += x();
ty += y();
- int rows = frameSet()->totalRows();
- int cols = frameSet()->totalCols();
+ size_t rows = m_rows.m_sizes.size();
+ size_t cols = m_cols.m_sizes.size();
int borderThickness = frameSet()->border();
int yPos = 0;
- for (int r = 0; r < rows; r++) {
+ for (size_t r = 0; r < rows; r++) {
int xPos = 0;
- for (int c = 0; c < cols; c++) {
+ for (size_t c = 0; c < cols; c++) {
child->paint(paintInfo, tx, ty);
xPos += m_cols.m_sizes[c];
if (borderThickness && m_cols.m_allowBorder[c + 1]) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderImage.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderImage.cpp
index 57dd03b..bdce452 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderImage.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderImage.cpp
@@ -271,6 +271,9 @@ bool RenderImage::setImageSizeForAltText(CachedImage* newImage /* = 0 */)
void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
{
+ if (!containingBlock())
+ return;
+
if (documentBeingDestroyed())
return;
@@ -296,7 +299,7 @@ void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
// In the case of generated image content using :before/:after, we might not be in the
// render tree yet. In that case, we don't need to worry about check for layout, since we'll get a
// layout when we get added in to the render tree hierarchy later.
- if (containingBlock()) {
+ if (!prefWidthsDirty()) {
// lets see if we need to relayout at all..
int oldwidth = width();
int oldheight = height();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderInline.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderInline.cpp
index 77ddd3c..609610b 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderInline.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderInline.cpp
@@ -1054,6 +1054,10 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx,
int l = tx + thisline.x() - offset;
int b = ty + thisline.bottom() + offset;
int r = tx + thisline.right() + offset;
+
+ IntRect box(l, t, b-t, r-l);
+ if (box.isEmpty())
+ return;
// left edge
drawLineForBoxSide(graphicsContext,
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderLayer.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderLayer.cpp
index 3cb5adb..230d823 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderLayer.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderLayer.cpp
@@ -334,12 +334,12 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags)
#if 1
// added at webkit.org trunk r61686
-IntRect RenderLayer::repaintRectIncludingDescendants() const
-{
- IntRect repaintRect = m_repaintRect;
- for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
- repaintRect.unite(child->repaintRectIncludingDescendants());
- return repaintRect;
+IntRect RenderLayer::repaintRectIncludingDescendants() const
+{
+ IntRect repaintRect = m_repaintRect;
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+ repaintRect.unite(child->repaintRectIncludingDescendants());
+ return repaintRect;
}
#endif
@@ -1251,7 +1251,8 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
// Schedule the scroll DOM event.
if (view) {
if (FrameView* frameView = view->frameView())
- frameView->scheduleEvent(Event::create(eventNames().scrollEvent, false, false), renderer()->node());
+ if (renderer()->node())
+ frameView->scheduleEvent(Event::create(eventNames().scrollEvent, false, false), renderer()->node());
}
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderListItem.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderListItem.cpp
index 9734326..6d84cc2 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderListItem.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderListItem.cpp
@@ -1,7 +1,7 @@
/**
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
* Copyright (c) 2010,2011 ACCESS CO., LTD. All rights reserved.
*
@@ -76,11 +76,16 @@ void RenderListItem::destroy()
RenderBlock::destroy();
}
+static bool isList(Node* node)
+{
+ return (node->hasTagName(ulTag) || node->hasTagName(olTag));
+}
+
static Node* enclosingList(Node* node)
{
Node* parent = node->parentNode();
for (Node* n = parent; n; n = n->parentNode())
- if (n->hasTagName(ulTag) || n->hasTagName(olTag))
+ if (isList(n))
return n;
// If there's no actual <ul> or <ol> list element, then our parent acts as
// our list for purposes of determining what other list items should be
@@ -88,22 +93,38 @@ static Node* enclosingList(Node* node)
return parent;
}
+static Node* enclosingList(const RenderObject* renderer)
+{
+ Node* node = renderer->node();
+ if (node)
+ return enclosingList(node);
+
+ renderer = renderer->parent();
+ while (renderer && !renderer->node())
+ renderer = renderer->parent();
+
+ node = renderer->node();
+ if (isList(node))
+ return node;
+
+ return enclosingList(node);
+}
+
static RenderListItem* previousListItem(Node* list, const RenderListItem* item)
{
- for (Node* node = item->node()->traversePreviousNode(); node != list; node = node->traversePreviousNode()) {
- RenderObject* renderer = node->renderer();
- if (!renderer || !renderer->isListItem())
+ for (RenderObject* renderer = item->previousInPreOrder(); renderer != list->renderer(); renderer = renderer->previousInPreOrder()) {
+ if (!renderer->isListItem())
continue;
- Node* otherList = enclosingList(node);
+ Node* otherList = enclosingList(renderer);
// This item is part of our current list, so it's what we're looking for.
if (list == otherList)
return toRenderListItem(renderer);
// We found ourself inside another list; lets skip the rest of it.
- // Use traverseNextNode() here because the other list itself may actually
+ // Use nextInPreOrder() here because the other list itself may actually
// be a list item itself. We need to examine it, so we do this to counteract
- // the traversePreviousNode() that will be done by the loop.
+ // the previousInPreOrder() that will be done by the loop.
if (otherList)
- node = otherList->traverseNextNode();
+ renderer = otherList->renderer()->nextInPreOrder();
}
return 0;
}
@@ -112,7 +133,7 @@ inline int RenderListItem::calcValue() const
{
if (m_hasExplicitValue)
return m_explicitValue;
- Node* list = enclosingList(node());
+ Node* list = enclosingList(this);
// FIXME: This recurses to a possible depth of the length of the list.
// That's not good -- we need to change this to an iterative algorithm.
if (RenderListItem* previousItem = previousListItem(list, this))
@@ -233,7 +254,7 @@ void RenderListItem::layout()
void RenderListItem::positionListMarker()
{
- if (m_marker && !m_marker->isInside() && m_marker->inlineBoxWrapper()) {
+ if (m_marker && m_marker->parent()->isBox() && !m_marker->isInside() && m_marker->inlineBoxWrapper()) {
int markerOldX = m_marker->x();
int yOffset = 0;
int xOffset = 0;
@@ -350,6 +371,8 @@ void RenderListItem::explicitValueChanged()
void RenderListItem::setExplicitValue(int value)
{
+ ASSERT(node());
+
if (m_hasExplicitValue && m_explicitValue == value)
return;
m_explicitValue = value;
@@ -360,6 +383,8 @@ void RenderListItem::setExplicitValue(int value)
void RenderListItem::clearExplicitValue()
{
+ ASSERT(node());
+
if (!m_hasExplicitValue)
return;
m_hasExplicitValue = false;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderListMarker.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderListMarker.cpp
index 0c3f83c..12f20f4 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderListMarker.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderListMarker.cpp
@@ -649,7 +649,6 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderListMarker::layout()
{
ASSERT(needsLayout());
- ASSERT(!prefWidthsDirty());
if (isImage()) {
setWidth(m_image->imageSize(this, style()->effectiveZoom()).width());
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderObject.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderObject.cpp
index 54f1500..92e37fa 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderObject.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderObject.cpp
@@ -2079,7 +2079,8 @@ void RenderObject::destroy()
document()->axObjectCache()->childrenChanged(this->parent());
document()->axObjectCache()->remove(this);
}
- animation()->cancelAnimations(this);
+ if (document()->frame())
+ animation()->cancelAnimations(this);
// By default no ref-counting. RenderWidget::destroy() doesn't call
// this function because it needs to do ref-counting. If anything
@@ -2127,7 +2128,8 @@ void RenderObject::arenaDelete(RenderArena* arena, void* base)
// Recover the size left there for us by operator delete and free the memory.
#if defined(ENABLE_REPLACEMENT_FASTMALLOC) || defined(_CRTDBG_MAP_ALLOC)
- arena->renderarena_free(*(size_t*)base, base);
+ if (arena)
+ arena->renderarena_free(*(size_t*)base, base);
#else
arena->free(*(size_t*)base, base);
#endif
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderObject.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderObject.h
index d161293..763b506 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderObject.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderObject.h
@@ -314,7 +314,9 @@ public:
bool isHTMLMarquee() const;
+ inline bool isBeforeContent() const;
inline bool isAfterContent() const;
+ static inline bool isBeforeContent(const RenderObject* obj) { return obj && obj->isBeforeContent(); }
static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); }
bool childrenInline() const { return m_childrenInline; }
@@ -895,6 +897,16 @@ inline bool RenderObject::documentBeingDestroyed() const
return !document()->renderer();
}
+inline bool RenderObject::isBeforeContent() const
+{
+ if (style()->styleType() != BEFORE)
+ return false;
+ // Text nodes don't have their own styles, so ignore the style on a text node.
+ if (isText() && !isBR())
+ return false;
+ return true;
+}
+
inline bool RenderObject::isAfterContent() const
{
if (style()->styleType() != AFTER)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderObjectChildList.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderObjectChildList.cpp
index be525c4..4fd4f29 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderObjectChildList.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderObjectChildList.cpp
@@ -54,10 +54,10 @@ void RenderObjectChildList::destroyLeftoverChildren()
firstChild()->remove(); // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
#if 1
// modified at webkit.org trunk r63772
- else if (firstChild()->isRunIn() && firstChild()->node()) {
- firstChild()->node()->setRenderer(0);
- firstChild()->node()->setNeedsStyleRecalc();
- firstChild()->destroy();
+ else if (firstChild()->isRunIn() && firstChild()->node()) {
+ firstChild()->node()->setRenderer(0);
+ firstChild()->node()->setNeedsStyleRecalc();
+ firstChild()->destroy();
} else {
#else
else {
@@ -372,6 +372,21 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
if (!beforeAfterParent)
return;
+ // When beforeAfterParent is not equal to child (e.g. in tables),
+ // we need to create new styles inheriting from pseudoElementStyle
+ // on all the intermediate parents (leaving their display same).
+ if (beforeAfterParent != child) {
+ RenderObject* curr = beforeAfterParent;
+ while (curr && curr != child) {
+ ASSERT(curr->isAnonymous());
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(pseudoElementStyle);
+ newStyle->setDisplay(curr->style()->display());
+ curr->setStyle(newStyle);
+ curr = curr->parent();
+ }
+ }
+
// Note that if we ever support additional types of generated content (which should be way off
// in the future), this code will need to be patched.
for (RenderObject* genChild = beforeAfterParent->firstChild(); genChild; genChild = genChild->nextSibling()) {
@@ -431,9 +446,18 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
// to find the original content properly.
generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle);
generatedContentContainer->setStyle(pseudoElementStyle);
+ if (!owner->isChildAllowed(generatedContentContainer, pseudoElementStyle)) {
+ // The generated content container is not allowed here -> abort.
+ generatedContentContainer->destroy();
+ renderer->destroy();
+ return;
+ }
owner->addChild(generatedContentContainer, insertBefore);
}
- generatedContentContainer->addChild(renderer);
+ if (generatedContentContainer->isChildAllowed(renderer, pseudoElementStyle))
+ generatedContentContainer->addChild(renderer);
+ else
+ renderer->destroy();
}
}
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderPartObject.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderPartObject.cpp
index de51d20..d260f42 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderPartObject.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderPartObject.cpp
@@ -281,8 +281,16 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
return;
}
- bool success = o->dispatchBeforeLoadEvent(url) &&
- frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues);
+ bool beforeLoadAllowedLoad = o->dispatchBeforeLoadEvent(url);
+
+ // beforeload events can modify the DOM, potentially causing
+ // RenderWidget::destroy() to be called. Ensure we haven't been
+ // destroyed before continuing.
+ if (!node())
+ return;
+
+ bool success = beforeLoadAllowedLoad && frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues);
+
if (!success && m_hasFallbackContent)
o->renderFallbackContent();
} else if (node()->hasTagName(embedTag)) {
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderRuby.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderRuby.cpp
index 8d113f9..c2f80be 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderRuby.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderRuby.cpp
@@ -32,18 +32,71 @@
#include "RenderRuby.h"
#include "RenderRubyRun.h"
+#include "RenderStyle.h"
+#include <wtf/RefPtr.h>
namespace WebCore {
//=== generic helper functions to avoid excessive code duplication ===
+static inline bool isAnonymousRubyInlineBlock(const RenderObject* object)
+{
+ ASSERT(!object
+ || !object->parent()->isRuby()
+ || object->isRubyRun()
+ || (object->isInline() && (object->isBeforeContent() || object->isAfterContent()))
+ || (object->isAnonymous() && object->isRenderBlock() && object->style()->display() == INLINE_BLOCK));
+
+ return object
+ && object->parent()->isRuby()
+ && object->isRenderBlock()
+ && !object->isRubyRun();
+}
+
+static inline bool isRubyBeforeBlock(const RenderObject* object)
+{
+ return isAnonymousRubyInlineBlock(object)
+ && !object->previousSibling()
+ && object->firstChild()
+ && object->firstChild()->style()->styleType() == BEFORE;
+}
+
+static inline bool isRubyAfterBlock(const RenderObject* object)
+{
+ return isAnonymousRubyInlineBlock(object)
+ && !object->nextSibling()
+ && object->firstChild()
+ && object->firstChild()->style()->styleType() == AFTER;
+}
+
+static inline RenderBlock* rubyBeforeBlock(const RenderObject* ruby)
+{
+ RenderObject* child = ruby->firstChild();
+ return isRubyBeforeBlock(child) ? static_cast<RenderBlock*>(child) : 0;
+}
+
+static inline RenderBlock* rubyAfterBlock(const RenderObject* ruby)
+{
+ RenderObject* child = ruby->lastChild();
+ return isRubyAfterBlock(child) ? static_cast<RenderBlock*>(child) : 0;
+}
+
+static RenderBlock* createAnonymousRubyInlineBlock(RenderObject* ruby)
+{
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(ruby->style());
+ newStyle->setDisplay(INLINE_BLOCK);
+
+ RenderBlock* newBlock = new (ruby->renderArena()) RenderBlock(ruby->document() /* anonymous box */);
+ newBlock->setStyle(newStyle.release());
+ return newBlock;
+}
static RenderRubyRun* lastRubyRun(const RenderObject* ruby)
{
RenderObject* child = ruby->lastChild();
- if (child && ruby->isAfterContent(child))
+ if (child && !child->isRubyRun())
child = child->previousSibling();
- ASSERT(!child || child->isRubyRun());
- return static_cast<RenderRubyRun*>(child);
+ ASSERT(!child || child->isRubyRun() || child->isBeforeContent() || child == rubyBeforeBlock(ruby));
+ return child && child->isRubyRun() ? static_cast<RenderRubyRun*>(child) : 0;
}
static inline RenderRubyRun* findRubyRunParent(RenderObject* child)
@@ -64,18 +117,41 @@ RenderRubyAsInline::~RenderRubyAsInline()
{
}
-bool RenderRubyAsInline::isChildAllowed(RenderObject* child, RenderStyle*) const
-{
- return child->isRubyText()
- || child->isRubyRun()
- || child->isInline();
-}
-
void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild)
{
- // Note: ':after' content is handled implicitely below
+ // Insert :before and :after content before/after the RenderRubyRun(s)
+ if (child->isBeforeContent()) {
+ if (child->isInline()) {
+ // Add generated inline content normally
+ RenderInline::addChild(child, firstChild());
+ } else {
+ // Wrap non-inline content with an anonymous inline-block.
+ RenderBlock* beforeBlock = rubyBeforeBlock(this);
+ if (!beforeBlock) {
+ beforeBlock = createAnonymousRubyInlineBlock(this);
+ RenderInline::addChild(beforeBlock, firstChild());
+ }
+ beforeBlock->addChild(child);
+ }
+ return;
+ }
+ if (child->isAfterContent()) {
+ if (child->isInline()) {
+ // Add generated inline content normally
+ RenderInline::addChild(child);
+ } else {
+ // Wrap non-inline content with an anonymous inline-block.
+ RenderBlock* afterBlock = rubyAfterBlock(this);
+ if (!afterBlock) {
+ afterBlock = createAnonymousRubyInlineBlock(this);
+ RenderInline::addChild(afterBlock);
+ }
+ afterBlock->addChild(child);
+ }
+ return;
+ }
- // if child is a ruby run, just add it normally
+ // If the child is a ruby run, just add it normally.
if (child->isRubyRun()) {
RenderInline::addChild(child, beforeChild);
return;
@@ -84,13 +160,14 @@ void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild
if (beforeChild && !isAfterContent(beforeChild)) {
// insert child into run
ASSERT(!beforeChild->isRubyRun());
- RenderRubyRun* run = findRubyRunParent(beforeChild);
- ASSERT(run); // beforeChild should always have a run as parent
+ RenderObject* run = beforeChild;
+ while (run && !run->isRubyRun())
+ run = run->parent();
if (run) {
run->addChild(child, beforeChild);
return;
}
- ASSERT(false); // beforeChild should always have a run as parent!
+ ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
// Emergency fallback: fall through and just append.
}
@@ -107,15 +184,24 @@ void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild
void RenderRubyAsInline::removeChild(RenderObject* child)
{
- // If the child's parent is *this, i.e. a ruby run or ':after' content,
+ // If the child's parent is *this (must be a ruby run or generated content or anonymous block),
// just use the normal remove method.
if (child->parent() == this) {
- ASSERT(child->isRubyRun() || child->isAfterContent());
+ ASSERT(child->isRubyRun() || child->isBeforeContent() || child->isAfterContent() || isAnonymousRubyInlineBlock(child));
RenderInline::removeChild(child);
return;
}
+ // If the child's parent is an anoymous block (must be generated :before/:after content)
+ // just use the block's remove method.
+ if (isAnonymousRubyInlineBlock(child->parent())) {
+ ASSERT(child->isBeforeContent() || child->isAfterContent());
+ child->parent()->removeChild(child);
+ removeChild(child->parent());
+ return;
+ }
- // Find the containing run
+ // Otherwise find the containing run and remove it from there.
+ ASSERT(child->parent() != this);
RenderRubyRun* run = findRubyRunParent(child);
ASSERT(run);
run->removeChild(child);
@@ -133,18 +219,41 @@ RenderRubyAsBlock::~RenderRubyAsBlock()
{
}
-bool RenderRubyAsBlock::isChildAllowed(RenderObject* child, RenderStyle*) const
-{
- return child->isRubyText()
- || child->isRubyRun()
- || child->isInline();
-}
-
void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
{
- // Note: ':after' content is handled implicitely below
+ // Insert :before and :after content before/after the RenderRubyRun(s)
+ if (child->isBeforeContent()) {
+ if (child->isInline()) {
+ // Add generated inline content normally
+ RenderBlock::addChild(child, firstChild());
+ } else {
+ // Wrap non-inline content with an anonymous inline-block.
+ RenderBlock* beforeBlock = rubyBeforeBlock(this);
+ if (!beforeBlock) {
+ beforeBlock = createAnonymousRubyInlineBlock(this);
+ RenderBlock::addChild(beforeBlock, firstChild());
+ }
+ beforeBlock->addChild(child);
+ }
+ return;
+ }
+ if (child->isAfterContent()) {
+ if (child->isInline()) {
+ // Add generated inline content normally
+ RenderBlock::addChild(child);
+ } else {
+ // Wrap non-inline content with an anonymous inline-block.
+ RenderBlock* afterBlock = rubyAfterBlock(this);
+ if (!afterBlock) {
+ afterBlock = createAnonymousRubyInlineBlock(this);
+ RenderBlock::addChild(afterBlock);
+ }
+ afterBlock->addChild(child);
+ }
+ return;
+ }
- // if child is a ruby run, just add it normally
+ // If the child is a ruby run, just add it normally.
if (child->isRubyRun()) {
RenderBlock::addChild(child, beforeChild);
return;
@@ -160,7 +269,7 @@ void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
run->addChild(child, beforeChild);
return;
}
- ASSERT(false); // beforeChild should always have a run as parent!
+ ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
// Emergency fallback: fall through and just append.
}
@@ -177,14 +286,23 @@ void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
void RenderRubyAsBlock::removeChild(RenderObject* child)
{
- // If the child's parent is *this, just use the normal remove method.
+ // If the child's parent is *this (must be a ruby run or generated content or anonymous block),
+ // just use the normal remove method.
if (child->parent() == this) {
- // This should happen only during destruction of the whole ruby element, though.
+ ASSERT(child->isRubyRun() || child->isBeforeContent() || child->isAfterContent() || isAnonymousRubyInlineBlock(child));
RenderBlock::removeChild(child);
return;
}
+ // If the child's parent is an anoymous block (must be generated :before/:after content)
+ // just use the block's remove method.
+ if (isAnonymousRubyInlineBlock(child->parent())) {
+ ASSERT(child->isBeforeContent() || child->isAfterContent());
+ child->parent()->removeChild(child);
+ removeChild(child->parent());
+ return;
+ }
- // Find the containing run
+ // Otherwise find the containing run and remove it from there.
RenderRubyRun* run = findRubyRunParent(child);
ASSERT(run);
run->removeChild(child);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderRuby.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderRuby.h
index 49a84d8..24ac0db 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderRuby.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderRuby.h
@@ -47,6 +47,8 @@ namespace WebCore {
// 1-n inline object(s)
//
// Note: <rp> elements are defined as having 'display:none' and thus normally are not assigned a renderer.
+//
+// Generated :before/:after content is shunted into anonymous inline blocks
// <ruby> when used as 'display:inline'
class RenderRubyAsInline : public RenderInline {
@@ -54,7 +56,6 @@ public:
RenderRubyAsInline(Node*);
virtual ~RenderRubyAsInline();
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void removeChild(RenderObject* child);
@@ -71,7 +72,6 @@ public:
RenderRubyAsBlock(Node*);
virtual ~RenderRubyAsBlock();
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void removeChild(RenderObject* child);
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderRubyBase.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderRubyBase.cpp
index da28953..9956f97 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderRubyBase.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderRubyBase.cpp
@@ -50,139 +50,81 @@ bool RenderRubyBase::isChildAllowed(RenderObject* child, RenderStyle*) const
#if 1
// modified at webkit.org trunk r53525
-bool RenderRubyBase::hasOnlyWrappedInlineChildren(RenderObject* beforeChild) const
-{
- // Tests whether all children in the base before beforeChild are either floated/positioned,
- // or inline objects wrapped in anonymous blocks.
- // Note that beforeChild may be 0, in which case all children are looked at.
- for (RenderObject* child = firstChild(); child != beforeChild; child = child->nextSibling()) {
- if (!child->isFloatingOrPositioned() && !(child->isAnonymousBlock() && child->childrenInline()))
- return false;
- }
- return true;
-}
-
-void RenderRubyBase::moveChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
-{
- // This function removes all children that are before (!) beforeChild
- // and appends them to toBase.
- ASSERT(toBase);
-
- // First make sure that beforeChild (if set) is indeed a direct child of this.
- // Inline children might be wrapped in an anonymous block if there's a continuation.
- // Theoretically, in ruby bases, this can happen with only the first such a child,
- // so it should be OK to just climb the tree.
- while (fromBeforeChild && fromBeforeChild->parent() != this)
- fromBeforeChild = fromBeforeChild->parent();
-
- if (childrenInline())
- moveInlineChildren(toBase, fromBeforeChild);
- else
- moveBlockChildren(toBase, fromBeforeChild);
-
- setNeedsLayoutAndPrefWidthsRecalc();
- toBase->setNeedsLayoutAndPrefWidthsRecalc();
-}
-
-void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
-{
- RenderBlock* toBlock;
-
- if (toBase->childrenInline()) {
- // The standard and easy case: move the children into the target base
- toBlock = toBase;
- } else {
- // We need to wrap the inline objects into an anonymous block.
- // If toBase has a suitable block, we re-use it, otherwise create a new one.
- RenderObject* lastChild = toBase->lastChild();
- if (lastChild && lastChild->isAnonymousBlock() && lastChild->childrenInline())
- toBlock = toRenderBlock(lastChild);
- else {
- toBlock = toBase->createAnonymousBlock();
- toBase->children()->appendChildNode(toBase, toBlock);
- }
- }
- // Move our inline children into the target block we determined above.
- for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild())
- moveChildTo(toBlock, toBlock->children(), child);
-}
-
-void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
-{
- if (toBase->childrenInline()) {
- // First check whether we move only wrapped inline objects.
- if (hasOnlyWrappedInlineChildren(fromBeforeChild)) {
- // The reason why the base is in block flow must be after beforeChild.
- // We therefore can extract the inline objects and move them to toBase.
- for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild()) {
- if (child->isAnonymousBlock()) {
- RenderBlock* anonBlock = toRenderBlock(child);
- ASSERT(anonBlock->childrenInline());
- ASSERT(!anonBlock->inlineContinuation());
- anonBlock->moveAllChildrenTo(toBase, toBase->children());
- anonBlock->deleteLineBoxTree();
- anonBlock->destroy();
- } else {
- ASSERT(child->isFloatingOrPositioned());
- moveChildTo(toBase, toBase->children(), child);
- }
- }
- } else {
- // Moving block children -> have to set toBase as block flow
- toBase->makeChildrenNonInline();
- // Move children, potentially collapsing anonymous block wrappers.
- mergeBlockChildren(toBase, fromBeforeChild);
-
- // Now we need to check if the leftover children are all inline.
- // If so, make this base inline again.
- if (hasOnlyWrappedInlineChildren()) {
- RenderObject* next = 0;
- for (RenderObject* child = firstChild(); child; child = next) {
- next = child->nextSibling();
- if (child->isFloatingOrPositioned())
- continue;
- ASSERT(child->isAnonymousBlock());
-
- RenderBlock* anonBlock = toRenderBlock(child);
- ASSERT(anonBlock->childrenInline());
- ASSERT(!anonBlock->inlineContinuation());
- // Move inline children out of anonymous block.
- anonBlock->moveAllChildrenTo(this, children(), anonBlock);
- anonBlock->deleteLineBoxTree();
- anonBlock->destroy();
- }
- setChildrenInline(true);
- }
- }
- } else
- mergeBlockChildren(toBase, fromBeforeChild);
-}
-
-void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
-{
- // This function removes all children that are before fromBeforeChild and appends them to toBase.
- ASSERT(!childrenInline());
- ASSERT(toBase);
- ASSERT(!toBase->childrenInline());
-
- // Quick check whether we have anything to do, to simplify the following code.
- if (fromBeforeChild != firstChild())
- return;
-
- // If an anonymous block would be put next to another such block, then merge those.
- RenderObject* firstChildHere = firstChild();
- RenderObject* lastChildThere = toBase->lastChild();
- if (firstChildHere && firstChildHere->isAnonymousBlock() && firstChildHere->childrenInline()
- && lastChildThere && lastChildThere->isAnonymousBlock() && lastChildThere->childrenInline()) {
- RenderBlock* anonBlockHere = toRenderBlock(firstChildHere);
- RenderBlock* anonBlockThere = toRenderBlock(lastChildThere);
- anonBlockHere->moveAllChildrenTo(anonBlockThere, anonBlockThere->children());
- anonBlockHere->deleteLineBoxTree();
- anonBlockHere->destroy();
- }
- // Move all remaining children normally.
- for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild())
- moveChildTo(toBase, toBase->children(), child);
+void RenderRubyBase::moveChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
+{
+ // This function removes all children that are before (!) beforeChild
+ // and appends them to toBase.
+ ASSERT_ARG(toBase, toBase);
+
+ // First make sure that beforeChild (if set) is indeed a direct child of this.
+ // Inline children might be wrapped in an anonymous block if there's a continuation.
+ // Theoretically, in ruby bases, this can happen with only the first such a child,
+ // so it should be OK to just climb the tree.
+ while (fromBeforeChild && fromBeforeChild->parent() != this)
+ fromBeforeChild = fromBeforeChild->parent();
+
+ if (childrenInline())
+ moveInlineChildren(toBase, fromBeforeChild);
+ else
+ moveBlockChildren(toBase, fromBeforeChild);
+
+ setNeedsLayoutAndPrefWidthsRecalc();
+ toBase->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
+{
+ ASSERT(childrenInline());
+ ASSERT_ARG(toBase, toBase);
+
+ if (!firstChild())
+ return;
+
+ RenderBlock* toBlock;
+ if (toBase->childrenInline()) {
+ // The standard and easy case: move the children into the target base
+ toBlock = toBase;
+ } else {
+ // We need to wrap the inline objects into an anonymous block.
+ // If toBase has a suitable block, we re-use it, otherwise create a new one.
+ RenderObject* lastChild = toBase->lastChild();
+ if (lastChild && lastChild->isAnonymousBlock() && lastChild->childrenInline())
+ toBlock = toRenderBlock(lastChild);
+ else {
+ toBlock = toBase->createAnonymousBlock();
+ toBase->children()->appendChildNode(toBase, toBlock);
+ }
+ }
+ // Move our inline children into the target block we determined above.
+ for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild())
+ moveChildTo(toBlock, toBlock->children(), child);
+}
+
+void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild)
+{
+ ASSERT(!childrenInline());
+ ASSERT_ARG(toBase, toBase);
+
+ if (!firstChild())
+ return;
+
+ if (toBase->childrenInline())
+ toBase->makeChildrenNonInline();
+
+ // If an anonymous block would be put next to another such block, then merge those.
+ RenderObject* firstChildHere = firstChild();
+ RenderObject* lastChildThere = toBase->lastChild();
+ if (firstChildHere->isAnonymousBlock() && firstChildHere->childrenInline()
+ && lastChildThere && lastChildThere->isAnonymousBlock() && lastChildThere->childrenInline()) {
+ RenderBlock* anonBlockHere = toRenderBlock(firstChildHere);
+ RenderBlock* anonBlockThere = toRenderBlock(lastChildThere);
+ anonBlockHere->moveAllChildrenTo(anonBlockThere, anonBlockThere->children());
+ anonBlockHere->deleteLineBoxTree();
+ anonBlockHere->destroy();
+ }
+ // Move all remaining children normally.
+ for (RenderObject* child = firstChild(); child != fromBeforeChild; child = firstChild())
+ moveChildTo(toBase, toBase->children(), child);
}
#else
void RenderRubyBase::splitToLeft(RenderBlock* leftBase, RenderObject* beforeChild)
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderRubyBase.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderRubyBase.h
index 408aeda..959d590 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderRubyBase.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderRubyBase.h
@@ -51,15 +51,12 @@ public:
void mergeWithRight(RenderBlock* rightBase);
#else
// modified at webkit.org trunk r53525
-private:
- bool hasOnlyWrappedInlineChildren(RenderObject* beforeChild = 0) const;
-
- void moveChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
- void moveInlineChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
- void moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
- void mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
-
- // Allow RenderRubyRun to manipulate the children within ruby bases.
+private:
+ void moveChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
+ void moveInlineChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
+ void moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild = 0);
+
+ // Allow RenderRubyRun to manipulate the children within ruby bases.
friend class RenderRubyRun;
#endif
};
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderSlider.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderSlider.cpp
index 1dd3dbd..58ace33 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderSlider.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderSlider.cpp
@@ -212,25 +212,47 @@ void SliderThumbElement::detach()
HTMLDivElement::detach();
}
+#if PLATFORM(WKC)
+static Vector<RenderSlider*>* gValidInstances = 0;
+#define ISVALIDINSTANCE() (gValidInstances->find(this)!=notFound)
+#endif
+
RenderSlider::RenderSlider(HTMLInputElement* element)
: RenderBlock(element)
{
+#if PLATFORM(WKC)
+ if (!gValidInstances)
+ gValidInstances = new Vector<RenderSlider*>();
+ gValidInstances->append(this);
+#endif
}
RenderSlider::~RenderSlider()
{
if (m_thumb)
m_thumb->detach();
- m_thumb = 0;
+#if PLATFORM(WKC)
+ size_t p = gValidInstances->find(this);
+ if (p!=notFound)
+ gValidInstances->remove(p);
+#endif
}
int RenderSlider::baselinePosition(bool, bool) const
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return 0;
+#endif
return height() + marginTop();
}
void RenderSlider::calcPrefWidths()
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return;
+#endif
m_minPrefWidth = 0;
m_maxPrefWidth = 0;
@@ -261,6 +283,10 @@ void RenderSlider::calcPrefWidths()
void RenderSlider::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return;
+#endif
RenderBlock::styleDidChange(diff, oldStyle);
if (m_thumb)
@@ -271,6 +297,10 @@ void RenderSlider::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
PassRefPtr<RenderStyle> RenderSlider::createThumbStyle(const RenderStyle* parentStyle)
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return 0;
+#endif
RefPtr<RenderStyle> style;
RenderStyle* pseudoStyle = getCachedPseudoStyle(SLIDER_THUMB);
if (pseudoStyle)
@@ -298,6 +328,10 @@ PassRefPtr<RenderStyle> RenderSlider::createThumbStyle(const RenderStyle* parent
IntRect RenderSlider::thumbRect()
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return IntRect();
+#endif
if (!m_thumb)
return IntRect();
@@ -322,6 +356,10 @@ IntRect RenderSlider::thumbRect()
void RenderSlider::layout()
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return;
+#endif
ASSERT(needsLayout());
RenderBox* thumb = m_thumb ? toRenderBox(m_thumb->renderer()) : 0;
@@ -373,6 +411,10 @@ void RenderSlider::layout()
void RenderSlider::updateFromElement()
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return;
+#endif
HTMLInputElement* element = static_cast<HTMLInputElement*>(node());
// Send the value back to the element if the range changes it.
@@ -397,6 +439,10 @@ void RenderSlider::updateFromElement()
bool RenderSlider::mouseEventIsInThumb(MouseEvent* evt)
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return false;
+#endif
if (!m_thumb || !m_thumb->renderer())
return false;
@@ -414,6 +460,10 @@ bool RenderSlider::mouseEventIsInThumb(MouseEvent* evt)
FloatPoint RenderSlider::mouseEventOffsetToThumb(MouseEvent* evt)
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return FloatPoint();
+#endif
ASSERT(m_thumb && m_thumb->renderer());
FloatPoint localPoint = m_thumb->renderBox()->absoluteToLocal(evt->absoluteLocation(), false, true);
IntRect thumbBounds = m_thumb->renderBox()->borderBoxRect();
@@ -425,6 +475,10 @@ FloatPoint RenderSlider::mouseEventOffsetToThumb(MouseEvent* evt)
void RenderSlider::setValueForPosition(int position)
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return;
+#endif
if (!m_thumb || !m_thumb->renderer())
return;
@@ -450,6 +504,10 @@ void RenderSlider::setValueForPosition(int position)
int RenderSlider::positionForOffset(const IntPoint& p)
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return 0;
+#endif
if (!m_thumb || !m_thumb->renderer())
return 0;
@@ -464,6 +522,10 @@ int RenderSlider::positionForOffset(const IntPoint& p)
int RenderSlider::currentPosition()
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return 0;
+#endif
ASSERT(m_thumb);
ASSERT(m_thumb->renderer());
@@ -474,6 +536,10 @@ int RenderSlider::currentPosition()
int RenderSlider::trackSize()
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return 0;
+#endif
ASSERT(m_thumb);
ASSERT(m_thumb->renderer());
@@ -484,6 +550,10 @@ int RenderSlider::trackSize()
void RenderSlider::forwardEvent(Event* event)
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return;
+#endif
if (event->isMouseEvent()) {
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
if (event->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
@@ -494,13 +564,25 @@ void RenderSlider::forwardEvent(Event* event)
}
}
- if (m_thumb)
- m_thumb->defaultEventHandler(event);
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return;
+#endif
+ m_thumb->defaultEventHandler(event);
}
bool RenderSlider::inDragMode() const
{
+#if PLATFORM(WKC)
+ if (!ISVALIDINSTANCE())
+ return false;
+#endif
return m_thumb && m_thumb->inDragMode();
}
+void RenderSlider_resetVariables()
+{
+ gValidInstances = 0;
+}
+
} // namespace WebCore
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTable.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTable.h
index 9b6f318..e8fa216 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTable.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTable.h
@@ -74,7 +74,7 @@ public:
{
}
- unsigned short span;
+ unsigned span;
unsigned width; // the calculated position of the column
};
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTableRow.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTableRow.cpp
index 7afc3be..1cf0d1d 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTableRow.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTableRow.cpp
@@ -73,13 +73,13 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
RenderObject* last = beforeChild;
if (!last)
last = lastChild();
- if (last && last->isAnonymous() && last->isTableCell()) {
+ if (last && last->isAnonymous() && last->isTableCell() && !isAfterContent(last) && !isBeforeContent(last)) {
last->addChild(child);
return;
}
// If beforeChild is inside an anonymous cell, insert into the cell.
- if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous()) {
+ if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous() && !isAfterContent(last->parent()) && !isBeforeContent(last->parent())) {
last->parent()->addChild(child, beforeChild);
return;
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTableSection.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTableSection.cpp
index 427f56f..4f68165 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTableSection.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTableSection.cpp
@@ -98,7 +98,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
RenderObject* last = beforeChild;
if (!last)
last = lastChild();
- if (last && last->isAnonymous()) {
+ if (last && last->isAnonymous() && !isAfterContent(last) && !isBeforeContent(last)) {
last->addChild(child);
return;
}
@@ -108,7 +108,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
RenderObject* lastBox = last;
while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableRow())
lastBox = lastBox->parent();
- if (lastBox && lastBox->isAnonymous()) {
+ if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox) && !isBeforeContent(lastBox)) {
lastBox->addChild(child, beforeChild);
return;
}
@@ -236,7 +236,7 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row)
table()->appendColumn(cSpan);
currentSpan = cSpan;
} else {
- if (cSpan < columns[m_cCol].span)
+ if (cSpan < static_cast<int>(columns[m_cCol].span))
table()->splitColumn(m_cCol, cSpan);
currentSpan = columns[m_cCol].span;
}
@@ -1217,6 +1217,13 @@ void RenderTableSection::recalcCells()
setNeedsLayout(true);
}
+void RenderTableSection::setNeedsCellRecalc()
+{
+ m_needsCellRecalc = true;
+ if (RenderTable* t = table())
+ t->setNeedsSectionRecalc();
+}
+
void RenderTableSection::clearGrid()
{
int rows = m_gridRows;
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTableSection.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTableSection.h
index 9f6d5ea..97ce8c4 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTableSection.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTableSection.h
@@ -94,11 +94,7 @@ public:
}
bool needsCellRecalc() const { return m_needsCellRecalc; }
- void setNeedsCellRecalc()
- {
- m_needsCellRecalc = true;
- table()->setNeedsSectionRecalc();
- }
+ void setNeedsCellRecalc();
int getBaseline(int row) { return m_grid[row].baseline; }
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderText.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderText.cpp
index 6399ce2..f2acf0c 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderText.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderText.cpp
@@ -4,7 +4,7 @@
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
* Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
- * Copyright (c) 2011 ACCESS CO., LTD. All rights reserved.
+ * Copyright (c) 2011 ACCESS CO., LTD. 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
@@ -1027,9 +1027,9 @@ int RenderText::lineHeight(bool firstLine, bool) const
void RenderText::dirtyLineBoxes(bool fullLayout)
{
-#if PLATFORM(WKC)
- CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT);
-#endif
+#if PLATFORM(WKC)
+ CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT);
+#endif
if (fullLayout)
deleteTextBoxes();
else if (!m_linesDirty) {
@@ -1068,13 +1068,13 @@ void RenderText::positionLineBox(InlineBox* box)
s->remove();
#if 1
// webkit trunk r52527
- if (m_firstTextBox == s)
- m_firstTextBox = s->nextTextBox();
- else
- s->prevTextBox()->setNextLineBox(s->nextTextBox());
- if (m_lastTextBox == s)
- m_lastTextBox = s->prevTextBox();
- else
+ if (m_firstTextBox == s)
+ m_firstTextBox = s->nextTextBox();
+ else
+ s->prevTextBox()->setNextLineBox(s->nextTextBox());
+ if (m_lastTextBox == s)
+ m_lastTextBox = s->prevTextBox();
+ else
s->nextTextBox()->setPreviousLineBox(s->prevTextBox());
#endif
s->destroy(renderArena());
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTextControl.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTextControl.cpp
index cea155e..194f385 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTextControl.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTextControl.cpp
@@ -373,8 +373,6 @@ String RenderTextControl::textWithHardLineBreaks()
if (!firstChild)
return "";
- document()->updateLayout();
-
RenderObject* renderer = firstChild->renderer();
if (!renderer)
return "";
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp
index be09d01..46c5aea 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -415,7 +415,7 @@ int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
void RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
{
if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0) {
- toRenderBlock(resultsRenderer)->calcHeight();
+ resultsRenderer->calcHeight();
setHeight(max(height(),
resultsRenderer->borderTop() + resultsRenderer->borderBottom() +
resultsRenderer->paddingTop() + resultsRenderer->paddingBottom() +
@@ -424,7 +424,7 @@ void RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight(int lineH
}
if (RenderBox* cancelRenderer = m_cancelButton ? m_cancelButton->renderBox() : 0) {
- toRenderBlock(cancelRenderer)->calcHeight();
+ cancelRenderer->calcHeight();
setHeight(max(height(),
cancelRenderer->borderTop() + cancelRenderer->borderBottom() +
cancelRenderer->paddingTop() + cancelRenderer->paddingBottom() +
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTextFragment.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTextFragment.cpp
index f35cbc0..f5386d6 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RenderTextFragment.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RenderTextFragment.cpp
@@ -47,12 +47,10 @@ RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str)
PassRefPtr<StringImpl> RenderTextFragment::originalText() const
{
Node* e = node();
-// RefPtr<StringImpl> result = (e ? static_cast<Text*>(e)->dataImpl() : contentString());
- // r59795
RefPtr<StringImpl> result = ((e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : contentString());
- if (result && (start() > 0 || start() < result->length()))
- result = result->substring(start(), end());
- return result.release();
+ if (!result)
+ return 0;
+ return result->substring(start(), end());
}
void RenderTextFragment::destroy()
@@ -73,9 +71,9 @@ void RenderTextFragment::setTextInternal(PassRefPtr<StringImpl> text)
m_end = textLength();
#if 1
// added at webkit.org trunk r55196
- if (Node* t = node()) {
- ASSERT(!t->renderer());
- t->setRenderer(this);
+ if (Node* t = node()) {
+ ASSERT(!t->renderer());
+ t->setRenderer(this);
}
#endif
}
@@ -88,7 +86,7 @@ UChar RenderTextFragment::previousCharacter()
// StringImpl* original = (e ? static_cast<Text*>(e)->dataImpl() : contentString());
// r59795
StringImpl* original = ((e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : contentString());
- if (original)
+ if (original && start() <= original->length())
return (*original)[start() - 1];
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RootInlineBox.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RootInlineBox.cpp
index 2919c14..13bf41f 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/RootInlineBox.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/RootInlineBox.cpp
@@ -250,7 +250,11 @@ int RootInlineBox::verticallyAlignBoxes(int heightOfBlock)
computeVerticalOverflow(lineTop, lineBottom, strictMode);
setLineTopBottomPositions(lineTop, lineBottom);
- heightOfBlock += maxHeight;
+ // Detect integer overflow.
+ if (heightOfBlock > numeric_limits<int>::max() - maxHeight)
+ return numeric_limits<int>::max();
+
+ heightOfBlock = heightOfBlock + maxHeight;
return heightOfBlock;
}
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/style/RenderStyle.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/style/RenderStyle.cpp
index 5d8fb25..6eb320e 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/style/RenderStyle.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/style/RenderStyle.cpp
@@ -64,6 +64,13 @@ PassRefPtr<RenderStyle> RenderStyle::createDefaultStyle()
return adoptRef(new RenderStyle(true));
}
+PassRefPtr<RenderStyle> RenderStyle::createAnonymousStyle(const RenderStyle* parentStyle)
+{
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(parentStyle);
+ return newStyle;
+}
+
PassRefPtr<RenderStyle> RenderStyle::clone(const RenderStyle* other)
{
return adoptRef(new RenderStyle(*other));
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/style/RenderStyle.h b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/style/RenderStyle.h
index 319760a..b687fa1 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/rendering/style/RenderStyle.h
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/rendering/style/RenderStyle.h
@@ -298,6 +298,7 @@ protected:
public:
static PassRefPtr<RenderStyle> create();
static PassRefPtr<RenderStyle> createDefaultStyle();
+ static PassRefPtr<RenderStyle> createAnonymousStyle(const RenderStyle* parentStyle);
static PassRefPtr<RenderStyle> clone(const RenderStyle*);
~RenderStyle();
diff --git a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/websockets/WebSocketHandshake.cpp b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/websockets/WebSocketHandshake.cpp
index a568c2b..b91e6aa 100644
--- a/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.2.0/webkit/WebCore/websockets/WebSocketHandshake.cpp
+++ b/3DS_InternetBrowser_OpenSources_JP_US_EU_KR_TW_HK_CN_10.6.0/webkit/WebCore/websockets/WebSocketHandshake.cpp
@@ -350,7 +350,8 @@ void WebSocketHandshake::setServerSetCookie2(const String& setCookie2)
KURL WebSocketHandshake::httpURLForAuthenticationAndCookies() const
{
KURL url = m_url.copy();
- url.setProtocol(m_secure ? "https" : "http");
+ bool couldSetProtocol = url.setProtocol(m_secure ? "https" : "http");
+ ASSERT_UNUSED(couldSetProtocol, couldSetProtocol);
return url;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment