Commit 07fa4599 authored by Alberto Garcia's avatar Alberto Garcia
Browse files

Imported Upstream version 2.8.5+dfsg1

parent 554176f8
......@@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">WebKit2GTK+ Reference Manual</p></th></tr></table></div>
<div><p class="releaseinfo">for WebKit2GTK+ 2.8.4</p></div>
<div><p class="releaseinfo">for WebKit2GTK+ 2.8.5</p></div>
</div>
<hr>
</div>
......
......@@ -127,7 +127,7 @@ against at application run time.</p>
<hr>
<div class="refsect2">
<a name="WEBKIT-MICRO-VERSION:CAPS"></a><h3>WEBKIT_MICRO_VERSION</h3>
<pre class="programlisting">#define WEBKIT_MICRO_VERSION (4)
<pre class="programlisting">#define WEBKIT_MICRO_VERSION (5)
</pre>
<p>Like <a class="link" href="webkit2gtk-4.0-WebKitVersion.html#webkit-get-micro-version" title="webkit_get_micro_version ()"><code class="function">webkit_get_micro_version()</code></a>, but from the headers used at
application compile time, rather than from the library linked
......
......@@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">WebKitDOMGTK+ Reference Manual</p></th></tr></table></div>
<div><p class="releaseinfo">for WebKitDOMGTK+ 2.8.4</p></div>
<div><p class="releaseinfo">for WebKitDOMGTK+ 2.8.5</p></div>
</div>
<hr>
</div>
......
=================
WebKitGTK+ 2.8.5
=================
What's new in WebKitGTK+ 2.8.5?
- Fix the window size reported when the web view isn't realized yet. This fixes the layout of
some websites when opening new tabs in the browser and anchor links when opened in new tabs too.
- Prevent clipboard contents from being lost when web process finishes.
- Always allow font matching for strong aliases.
- Move GStreamer missing plugins installer to the UI process.
- Fix a crash when spell checker returns no guesses.
- Fix a crash when SoupSession is destroyed in exit handler.
- Fix a crash closing a page when default context menu is open.
- Several crashes and rendering issues fixed.
- Translation updates: Swedish.
=================
WebKitGTK+ 2.8.4
=================
......
......@@ -84,9 +84,7 @@ private:
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
return;
// FIXME: It's likely that this can be improved, for static analyses that use
// HashSets. https://bugs.webkit.org/show_bug.cgi?id=118455
m_live = block->ssa->liveAtTail;
for (unsigned nodeIndex = block->size(); nodeIndex--;) {
......@@ -134,9 +132,9 @@ private:
return;
m_changed = true;
block->ssa->liveAtHead = m_live;
for (unsigned i = block->predecessors.size(); i--;)
block->predecessors[i]->ssa->liveAtTail.add(m_live.begin(), m_live.end());
block->ssa->liveAtHead = WTF::move(m_live);
}
void addChildUse(Node*, Edge& edge)
......
......@@ -469,14 +469,6 @@ LLINT_SLOW_PATH_DECL(stack_check)
#endif
#endif
// This stack check is done in the prologue for a function call, and the
// CallFrame is not completely set up yet. For example, if the frame needs
// a lexical environment object, the lexical environment object will only be
// set up after we start executing the function. If we need to throw a
// StackOverflowError here, then we need to tell the prologue to start the
// stack unwinding from the caller frame (which is fully set up) instead.
// To do that, we return the caller's CallFrame in the second return value.
//
// If the stack check succeeds and we don't need to throw the error, then
// we'll return 0 instead. The prologue will check for a non-zero value
// when determining whether to set the callFrame or not.
......@@ -490,7 +482,6 @@ LLINT_SLOW_PATH_DECL(stack_check)
LLINT_RETURN_TWO(pc, 0);
#endif
exec = exec->callerFrame(vm.topVMEntryFrame);
vm.topCallFrame = exec;
ErrorHandlingScope errorScope(vm);
CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
......
......@@ -1072,7 +1072,13 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec)
JSObject* object = jsCast<JSObject*>(thisValue.toThis(exec, NotStrictMode));
if (exec->hadException())
return JSValue::encode(jsNull());
JSValue timeValue = object->toPrimitive(exec, PreferNumber);
if (exec->hadException())
return JSValue::encode(jsNull());
if (timeValue.isNumber() && !(timeValue.isInt32() || std::isfinite(timeValue.asDouble())))
return JSValue::encode(jsNull());
JSValue toISOValue = object->get(exec, exec->vm().propertyNames->toISOString);
if (exec->hadException())
return JSValue::encode(jsNull());
......
......@@ -30,6 +30,7 @@
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
#include <wtf/HashTraits.h>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
#include <wtf/ValueCheck.h>
......@@ -431,6 +432,8 @@ namespace WTF {
template<typename HashTranslator, typename T> FullLookupType fullLookupForWriting(const T&);
template<typename HashTranslator, typename T> LookupType lookupForWriting(const T&);
template<typename HashTranslator, typename T, typename Extra> void addUniqueForInitialization(T&& key, Extra&&);
template<typename HashTranslator, typename T> void checkKey(const T&);
void removeAndInvalidateWithoutEntryConsistencyCheck(ValueType*);
......@@ -761,6 +764,59 @@ namespace WTF {
}
}
template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
template<typename HashTranslator, typename T, typename Extra>
ALWAYS_INLINE void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::addUniqueForInitialization(T&& key, Extra&& extra)
{
ASSERT(m_table);
checkKey<HashTranslator>(key);
invalidateIterators();
internalCheckTableConsistency();
unsigned k = 0;
ValueType* table = m_table;
unsigned sizeMask = m_tableSizeMask;
unsigned h = HashTranslator::hash(key);
unsigned i = h & sizeMask;
#if DUMP_HASHTABLE_STATS
++HashTableStats::numAccesses;
unsigned probeCount = 0;
#endif
#if DUMP_HASHTABLE_STATS_PER_TABLE
++m_stats->numAccesses;
#endif
ValueType* entry;
while (1) {
entry = table + i;
if (isEmptyBucket(*entry))
break;
#if DUMP_HASHTABLE_STATS
++probeCount;
HashTableStats::recordCollisionAtCount(probeCount);
#endif
#if DUMP_HASHTABLE_STATS_PER_TABLE
m_stats->recordCollisionAtCount(probeCount);
#endif
if (k == 0)
k = 1 | doubleHash(h);
i = (i + k) & sizeMask;
}
HashTranslator::translate(*entry, std::forward<T>(key), std::forward<Extra>(extra));
internalCheckTableConsistency();
}
template<bool emptyValueIsZero> struct HashTableBucketInitializer;
template<> struct HashTableBucketInitializer<false> {
......@@ -1155,26 +1211,40 @@ namespace WTF {
template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::HashTable(const HashTable& other)
: m_table(0)
: m_table(nullptr)
, m_tableSize(0)
, m_tableSizeMask(0)
, m_keyCount(0)
, m_deletedCount(0)
#if CHECK_HASHTABLE_ITERATORS
, m_iterators(0)
, m_iterators(nullptr)
, m_mutex(std::make_unique<std::mutex>())
#endif
#if DUMP_HASHTABLE_STATS_PER_TABLE
, m_stats(std::make_unique<Stats>(*other.m_stats))
#endif
{
// Copy the hash table the dumb way, by adding each element to the new table.
// It might be more efficient to copy the table slots, but it's not clear that efficiency is needed.
// FIXME: It's likely that this can be improved, for static analyses that use
// HashSets. https://bugs.webkit.org/show_bug.cgi?id=118455
const_iterator end = other.end();
for (const_iterator it = other.begin(); it != end; ++it)
add(*it);
unsigned otherKeyCount = other.size();
if (!otherKeyCount)
return;
unsigned bestTableSize = WTF::roundUpToPowerOfTwo(otherKeyCount) * 2;
// With maxLoad at 1/2 and minLoad at 1/6, our average load is 2/6.
// If we are getting halfway between 2/6 and 1/2 (past 5/12), we double the size to avoid being too close to
// loadMax and bring the ratio close to 2/6. This give us a load in the bounds [3/12, 5/12).
bool aboveThreeQuarterLoad = otherKeyCount * 12 >= bestTableSize * 5;
if (aboveThreeQuarterLoad)
bestTableSize *= 2;
unsigned minimumTableSize = KeyTraits::minimumTableSize;
m_tableSize = std::max<unsigned>(bestTableSize, minimumTableSize);
m_tableSizeMask = m_tableSize - 1;
m_keyCount = otherKeyCount;
m_table = allocateTable(m_tableSize);
for (const auto& otherValue : other)
addUniqueForInitialization<IdentityTranslatorType>(Extractor::extract(otherValue), otherValue);
}
template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
......@@ -1197,8 +1267,6 @@ namespace WTF {
template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
auto HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::operator=(const HashTable& other) -> HashTable&
{
// FIXME: It's likely that this can be improved, for static analyses that use
// HashSets. https://bugs.webkit.org/show_bug.cgi?id=118455
HashTable tmp(other);
swap(tmp);
return *this;
......
......@@ -984,7 +984,13 @@ void AudioContext::pageMutedStateDidChange()
void AudioContext::isPlayingAudioDidChange()
{
document()->updateIsPlayingAudio();
// Make sure to call Document::updateIsPlayingAudio() on the main thread, since
// we could be on the audio I/O thread here and the call into WebCore could block.
RefPtr<AudioContext> strongThis(this);
callOnMainThread([strongThis] {
if (strongThis->document())
strongThis->document()->updateIsPlayingAudio();
});
}
void AudioContext::fireCompletionEvent()
......
......@@ -248,11 +248,15 @@ JSDOMWindow* toJSDOMWindow(JSValue value)
{
if (!value.isObject())
return 0;
const ClassInfo* classInfo = asObject(value)->classInfo();
if (classInfo == JSDOMWindow::info())
return jsCast<JSDOMWindow*>(asObject(value));
if (classInfo == JSDOMWindowShell::info())
return jsCast<JSDOMWindowShell*>(asObject(value))->window();
while (!value.isNull()) {
JSObject* object = asObject(value);
const ClassInfo* classInfo = object->classInfo();
if (classInfo == JSDOMWindow::info())
return jsCast<JSDOMWindow*>(object);
if (classInfo == JSDOMWindowShell::info())
return jsCast<JSDOMWindowShell*>(object)->window();
value = object->prototype();
}
return 0;
}
......
......@@ -1053,10 +1053,10 @@ Ref<RenderStyle> StyleResolver::defaultStyleForElement()
{
m_state.setStyle(RenderStyle::create());
// Make sure our fonts are initialized if we don't inherit them from our parent style.
if (Settings* settings = documentSettings()) {
initializeFontStyle(settings);
initializeFontStyle(documentSettings());
if (documentSettings())
m_state.style()->fontCascade().update(&document().fontSelector());
} else
else
m_state.style()->fontCascade().update(nullptr);
return m_state.takeStyle();
......@@ -2111,7 +2111,8 @@ void StyleResolver::checkForGenericFamilyChange(RenderStyle* style, RenderStyle*
void StyleResolver::initializeFontStyle(Settings* settings)
{
FontDescription fontDescription;
fontDescription.setRenderingMode(settings->fontRenderingMode());
if (settings)
fontDescription.setRenderingMode(settings->fontRenderingMode());
fontDescription.setOneFamily(standardFamily);
fontDescription.setKeywordSizeFromIdentifier(CSSValueMedium);
setFontSize(fontDescription, Style::fontSizeForKeyword(CSSValueMedium, false, document()));
......
......@@ -233,7 +233,11 @@ bool StyleSheetContents::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsig
if (is<StyleRuleImport>(*rule))
return false;
childVectorIndex -= m_importRules.size();
// If the number of selectors would overflow RuleData, we drop the operation.
if (is<StyleRule>(*rule) && downcast<StyleRule>(*rule).selectorList().componentCount() > RuleData::maximumSelectorComponentCount)
return false;
m_childRules.insert(childVectorIndex, rule);
return true;
}
......
......@@ -1998,10 +1998,14 @@ void FrameSelection::getClippedVisibleTextRectangles(Vector<FloatRect>& rectangl
if (!root)
return;
RefPtr<Range> range = toNormalizedRange();
if (!range)
return;
FloatRect visibleContentRect = m_frame->view()->visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect);
Vector<FloatQuad> quads;
toNormalizedRange()->textQuads(quads, true);
range->textQuads(quads, true);
size_t size = quads.size();
for (size_t i = 0; i < size; ++i) {
......
......@@ -5821,6 +5821,16 @@ double HTMLMediaElement::mediaPlayerRequestedPlaybackRate() const
return potentiallyPlaying() ? requestedPlaybackRate() : 0;
}
#if USE(GSTREAMER)
void HTMLMediaElement::requestInstallMissingPlugins(const String& details, MediaPlayerRequestInstallMissingPluginsCallback& callback)
{
if (!document().page())
return;
document().page()->chrome().client().requestInstallMissingMediaPlugins(details, callback);
}
#endif
void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
{
m_mediaSession->removeBehaviorRestriction(HTMLMediaSession::RequireUserGestureForLoad);
......
......@@ -616,6 +616,11 @@ private:
virtual double mediaPlayerRequestedPlaybackRate() const override final;
void loadTimerFired();
#if USE(GSTREAMER)
virtual void requestInstallMissingPlugins(const String&, MediaPlayerRequestInstallMissingPluginsCallback&) override final;
#endif
void progressEventTimerFired();
void playbackProgressTimerFired();
void scanTimerFired();
......
......@@ -190,6 +190,7 @@ void RenderSliderContainer::layout()
else
thumbLocation.setX(thumbLocation.x() - offset);
thumb->setLocation(thumbLocation);
thumb->repaint();
}
// --------------------------------
......
......@@ -553,8 +553,11 @@ void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource
// We checked application cache for initial URL, now we need to check it for redirected one.
ASSERT(!m_substituteData.isValid());
m_applicationCacheHost->maybeLoadMainResourceForRedirect(newRequest, m_substituteData);
if (m_substituteData.isValid())
m_identifierForLoadWithoutResourceLoader = mainResourceLoader()->identifier();
if (m_substituteData.isValid()) {
RELEASE_ASSERT(m_mainResource);
ResourceLoader* loader = m_mainResource->loader();
m_identifierForLoadWithoutResourceLoader = loader ? loader->identifier() : m_mainResource->identifierForLoadWithoutResourceLoader();
}
}
// FIXME: Ideally we'd stop the I/O until we hear back from the navigation policy delegate
......@@ -584,10 +587,15 @@ void DocumentLoader::continueAfterNavigationPolicy(const ResourceRequest&, bool
// However, from an API perspective, this isn't a cancellation. Therefore, sever our relationship with the network load,
// but prevent the ResourceLoader from sending ResourceLoadNotifier callbacks.
RefPtr<ResourceLoader> resourceLoader = mainResourceLoader();
ASSERT(resourceLoader->shouldSendResourceLoadCallbacks());
resourceLoader->setSendCallbackPolicy(DoNotSendCallbacks);
if (resourceLoader) {
ASSERT(resourceLoader->shouldSendResourceLoadCallbacks());
resourceLoader->setSendCallbackPolicy(DoNotSendCallbacks);
}
clearMainResource();
resourceLoader->setSendCallbackPolicy(SendCallbacks);
if (resourceLoader)
resourceLoader->setSendCallbackPolicy(SendCallbacks);
handleSubstituteDataLoadSoon();
}
}
......@@ -648,6 +656,7 @@ void DocumentLoader::responseReceived(CachedResource* resource, const ResourceRe
}
ASSERT(!m_waitingForContentPolicy);
ASSERT(frameLoader());
m_waitingForContentPolicy = true;
// Always show content with valid substitute data.
......@@ -922,13 +931,14 @@ void DocumentLoader::checkLoadComplete()
m_frame->document()->domWindow()->finishedLoading();
}
void DocumentLoader::setFrame(Frame* frame)
void DocumentLoader::attachToFrame(Frame& frame)
{
if (m_frame == frame)
if (m_frame == &frame)
return;
ASSERT(frame && !m_frame);
m_frame = frame;
m_writer.setFrame(frame);
ASSERT(!m_frame);
m_frame = &frame;
m_writer.setFrame(&frame);
attachToFrame();
}
......@@ -950,10 +960,17 @@ void DocumentLoader::detachFromFrame()
m_mainResource->removeClient(this);
m_applicationCacheHost->setDOMApplicationCache(nullptr);
InspectorInstrumentation::loaderDetachedFromFrame(*m_frame, *this);
cancelPolicyCheckIfNeeded();
// Even though we ASSERT at the top of this method that we have an m_frame, we're seeing crashes where m_frame is null.
// This means either that a DocumentLoader is detaching twice, or is detaching before ever having attached.
// Until we figure out how that is happening, null check m_frame before dereferencing it here.
// <rdar://problem/21293082> and https://bugs.webkit.org/show_bug.cgi?id=146786
if (m_frame)
InspectorInstrumentation::loaderDetachedFromFrame(*m_frame, *this);
m_frame = nullptr;
// The call to stopLoading() above should have canceled any pending content policy check.
ASSERT_WITH_MESSAGE(!m_waitingForContentPolicy, "The content policy callback needs a valid frame.");
}
void DocumentLoader::clearMainResourceLoader()
......@@ -1470,17 +1487,24 @@ void DocumentLoader::startLoadingMainResource()
setRequest(request);
}
void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
void DocumentLoader::cancelPolicyCheckIfNeeded()
{
Ref<DocumentLoader> protect(*this);
ResourceError error = resourceError.isNull() ? frameLoader()->cancelledError(m_request) : resourceError;
RELEASE_ASSERT(frameLoader());
m_dataLoadTimer.stop();
if (m_waitingForContentPolicy) {
frameLoader()->policyChecker().cancelCheck();
ASSERT(m_waitingForContentPolicy);
m_waitingForContentPolicy = false;
}
}
void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
{
Ref<DocumentLoader> protect(*this);
ResourceError error = resourceError.isNull() ? frameLoader()->cancelledError(m_request) : resourceError;
m_dataLoadTimer.stop();
cancelPolicyCheckIfNeeded();
if (mainResourceLoader())
mainResourceLoader()->cancel(error);
......
......@@ -84,10 +84,9 @@ namespace WebCore {
}
WEBCORE_EXPORT virtual ~DocumentLoader();
WEBCORE_EXPORT void setFrame(Frame*);
void attachToFrame(Frame&);
Frame* frame() const { return m_frame; }
WEBCORE_EXPORT virtual void attachToFrame();
WEBCORE_EXPORT virtual void detachFromFrame();
WEBCORE_EXPORT FrameLoader* frameLoader() const;
......@@ -270,6 +269,8 @@ namespace WebCore {
protected:
WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&);
WEBCORE_EXPORT virtual void attachToFrame();
bool m_deferMainResourceDataLoad;
private:
......@@ -324,6 +325,8 @@ namespace WebCore {
void clearMainResource();
void cancelPolicyCheckIfNeeded();
Frame* m_frame;
Ref<CachedResourceLoader> m_cachedResourceLoader;
......
......@@ -274,7 +274,7 @@ void FrameLoader::initForSynthesizedDocument(const URL&)
// FrameLoader::checkCompleted() will overwrite the URL of the document to be activeDocumentLoader()->documentURL().
RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(ResourceRequest(URL(ParsedURLString, emptyString())), SubstituteData());
loader->setFrame(&m_frame);
loader->attachToFrame(m_frame);
loader->setResponse(ResourceResponse(URL(), ASCIILiteral("text/html"), 0, String()));
loader->setCommitted(true);
setDocumentLoader(loader.get());
......@@ -1685,7 +1685,7 @@ void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
return;
if (loader)
loader->setFrame(&m_frame);
loader->attachToFrame(m_frame);
if (m_policyDocumentLoader
&& m_policyDocumentLoader != m_provisionalDocumentLoader
&& m_policyDocumentLoader != m_documentLoader)
......@@ -1925,7 +1925,7 @@ void FrameLoader::transitionToCommitted(CachedPage* cachedPage)
if (cachedPage) {
DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader();
ASSERT(cachedDocumentLoader);
cachedDocumentLoader->setFrame(&m_frame);
cachedDocumentLoader->attachToFrame(m_frame);
m_client.transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame());
} else
m_client.transitionToCommittedForNewPage();
......@@ -3134,7 +3134,7 @@ void FrameLoader::loadSameDocumentItem(HistoryItem& item)
if (FrameView* view = m_frame.view())
view->setWasScrolledByUser(false);
history().setCurrentItem(item);
history().setCurrentItem(&item);
// loadInSameDocument() actually changes the URL and notifies load delegates of a "fake" load
loadInSameDocument(item.url(), item.stateObject(), false);
......
......@@ -342,6 +342,9 @@ void HistoryController::updateForReload()
if (m_frame.loader().loadType() == FrameLoadType::Reload || m_frame.loader().loadType() == FrameLoadType::ReloadFromOrigin)
saveScrollPositionAndViewStateToItem(m_currentItem.get());
// Rebuild the history item tree when reloading as trying to re-associate everything is too error-prone.
m_currentItem->clearChildren();
}
// When reloading the page, we may end up redirecting to a different URL
......@@ -470,8 +473,13 @@ void HistoryController::updateForCommit()
// the provisional item for restoring state.
// Note previousItem must be set before we close the URL, which will
// happen when the data source is made non-provisional below
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=146842
// We should always have a provisional item when committing, but we sometimes don't.
// Not having one leads to us not having a m_currentItem later, which is also a terrible known issue.
// We should get to the bottom of this.
ASSERT(m_provisionalItem);
setCurrentItem(*m_provisionalItem);
setCurrentItem(m_provisionalItem.get());
m_provisionalItem = nullptr;
// Tell all other frames in the tree to commit their provisional items and
......@@ -512,7 +520,7 @@ void HistoryController::recursiveUpdateForCommit()
view->setWasScrolledByUser(false);
// Now commit the provisional item
setCurrentItem(*m_provisionalItem);
setCurrentItem(m_provisionalItem.get());
m_provisionalItem = nullptr;
// Restore form state (works from currentItem)
......@@ -561,7 +569,7 @@ void HistoryController::recursiveUpdateForSameDocumentNavigation()
return;
// Commit the provisional item.
setCurrentItem(*m_provisionalItem);
setCurrentItem(m_provisionalItem.get());
m_provisionalItem = nullptr;
// Iterate over the rest of the tree.
......@@ -577,11 +585,11 @@ void HistoryController::updateForFrameLoadCompleted()