diff options
author | Russell Brenner <russellbrenner@google.com> | 2010-11-18 17:33:13 -0800 |
---|---|---|
committer | Russell Brenner <russellbrenner@google.com> | 2010-12-02 13:47:21 -0800 |
commit | 6b70adc33054f8aee8c54d0f460458a9df11b8a5 (patch) | |
tree | 103a13998c33944d6ab3b8318c509a037e639460 /WebKit/chromium/src | |
parent | bdf4ebc8e70b2d221b6ee7a65660918ecb1d33aa (diff) | |
download | external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.zip external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.gz external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.bz2 |
Merge WebKit at r72274: Initial merge by git.
Change-Id: Ie51f0b4a16da82942bd516dce59cfb79ebbe25fb
Diffstat (limited to 'WebKit/chromium/src')
27 files changed, 869 insertions, 163 deletions
diff --git a/WebKit/chromium/src/AutoFillPopupMenuClient.cpp b/WebKit/chromium/src/AutoFillPopupMenuClient.cpp index b14840c..32abd6f 100644 --- a/WebKit/chromium/src/AutoFillPopupMenuClient.cpp +++ b/WebKit/chromium/src/AutoFillPopupMenuClient.cpp @@ -115,10 +115,10 @@ void AutoFillPopupMenuClient::removeSuggestionAtIndex(unsigned listIndex) bool AutoFillPopupMenuClient::canRemoveSuggestionAtIndex(unsigned listIndex) { - // Only allow deletion of items before the separator and those that don't - // have a label (autocomplete). + // Only allow deletion of items before the separator that have unique id 0 + // (i.e. are autocomplete rather than autofill items). int index = convertListIndexToInternalIndex(listIndex); - return m_labels[index].isEmpty() && (m_separatorIndex == -1 || listIndex < static_cast<unsigned>(m_separatorIndex)); + return !m_uniqueIDs[index] && (m_separatorIndex == -1 || listIndex < static_cast<unsigned>(m_separatorIndex)); } void AutoFillPopupMenuClient::valueChanged(unsigned listIndex, bool fireEvents) @@ -194,14 +194,19 @@ String AutoFillPopupMenuClient::itemIcon(unsigned listIndex) const return getIcon(listIndex); } +bool AutoFillPopupMenuClient::itemIsEnabled(unsigned listIndex) const +{ + return !itemIsWarning(listIndex); +} + PopupMenuStyle AutoFillPopupMenuClient::itemStyle(unsigned listIndex) const { - return *m_style; + return itemIsWarning(listIndex) ? *m_warningStyle : *m_regularStyle; } PopupMenuStyle AutoFillPopupMenuClient::menuStyle() const { - return *m_style; + return *m_regularStyle; } int AutoFillPopupMenuClient::clientPaddingLeft() const @@ -239,6 +244,16 @@ bool AutoFillPopupMenuClient::itemIsSeparator(unsigned listIndex) const return (m_separatorIndex != -1 && static_cast<unsigned>(m_separatorIndex) == listIndex); } +bool AutoFillPopupMenuClient::itemIsWarning(unsigned listIndex) const +{ + int index = convertListIndexToInternalIndex(listIndex); + if (index == -1) + return false; + + ASSERT(index >= 0 && static_cast<size_t>(index) < m_uniqueIDs.size()); + return m_uniqueIDs[index] < 0; +} + void AutoFillPopupMenuClient::setTextFromItem(unsigned listIndex) { m_textField->setValue(getSuggestion(listIndex)); @@ -282,19 +297,31 @@ void AutoFillPopupMenuClient::initialize( // AutoFillPopupMenuClient. setSuggestions(names, labels, icons, uniqueIDs, separatorIndex); - FontDescription fontDescription; + FontDescription regularFontDescription; RenderTheme::defaultTheme()->systemFont(CSSValueWebkitControl, - fontDescription); + regularFontDescription); RenderStyle* style = m_textField->computedStyle(); - fontDescription.setComputedSize(style->fontDescription().computedSize()); + regularFontDescription.setComputedSize(style->fontDescription().computedSize()); - Font font(fontDescription, 0, 0); - font.update(textField->document()->styleSelector()->fontSelector()); + Font regularFont(regularFontDescription, 0, 0); + regularFont.update(textField->document()->styleSelector()->fontSelector()); // The direction of text in popup menu is set the same as the direction of // the input element: textField. - m_style.set(new PopupMenuStyle(Color::black, Color::white, font, true, - Length(WebCore::Fixed), - textField->renderer()->style()->direction())); + m_regularStyle.set(new PopupMenuStyle(Color::black, Color::white, regularFont, + true, false, Length(WebCore::Fixed), + textField->renderer()->style()->direction())); + + FontDescription warningFontDescription = regularFont.fontDescription(); + warningFontDescription.setItalic(true); + Font warningFont(warningFontDescription, regularFont.letterSpacing(), regularFont.wordSpacing()); + warningFont.update(regularFont.fontSelector()); + m_warningStyle.set(new PopupMenuStyle(Color::darkGray, + m_regularStyle->backgroundColor(), + warningFont, + m_regularStyle->isVisible(), + m_regularStyle->isDisplayNone(), + m_regularStyle->textIndent(), + m_regularStyle->textDirection())); } void AutoFillPopupMenuClient::setSuggestions(const WebVector<WebString>& names, diff --git a/WebKit/chromium/src/AutoFillPopupMenuClient.h b/WebKit/chromium/src/AutoFillPopupMenuClient.h index a946e34..e3edfd3 100644 --- a/WebKit/chromium/src/AutoFillPopupMenuClient.h +++ b/WebKit/chromium/src/AutoFillPopupMenuClient.h @@ -78,7 +78,7 @@ public: virtual WTF::String itemIcon(unsigned listIndex) const; virtual WTF::String itemToolTip(unsigned lastIndex) const { return WTF::String(); } virtual WTF::String itemAccessibilityText(unsigned lastIndex) const { return WTF::String(); } - virtual bool itemIsEnabled(unsigned listIndex) const { return true; } + virtual bool itemIsEnabled(unsigned listIndex) const; virtual WebCore::PopupMenuStyle itemStyle(unsigned listIndex) const; virtual WebCore::PopupMenuStyle menuStyle() const; virtual int clientInsetLeft() const { return 0; } @@ -130,6 +130,8 @@ private: int getSelectedIndex() const { return m_selectedIndex; } void setSelectedIndex(int index) { m_selectedIndex = index; } + bool itemIsWarning(unsigned listIndex) const; + // The names, labels and icons that make up the contents of the menu items. Vector<WTF::String> m_names; Vector<WTF::String> m_labels; @@ -143,7 +145,8 @@ private: int m_selectedIndex; RefPtr<WebCore::HTMLInputElement> m_textField; - OwnPtr<WebCore::PopupMenuStyle> m_style; + OwnPtr<WebCore::PopupMenuStyle> m_regularStyle; + OwnPtr<WebCore::PopupMenuStyle> m_warningStyle; // DEPRECATED: Will be removed once Autocomplete and AutoFill merge is // complete. diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp b/WebKit/chromium/src/ChromeClientImpl.cpp index 18f7a02..c43a0b0 100644 --- a/WebKit/chromium/src/ChromeClientImpl.cpp +++ b/WebKit/chromium/src/ChromeClientImpl.cpp @@ -841,7 +841,7 @@ PassRefPtr<PopupMenu> ChromeClientImpl::createPopupMenu(PopupMenuClient* client) { if (WebViewImpl::useExternalPopupMenus()) return adoptRef(new ExternalPopupMenu(client, m_webView->client())); - + return adoptRef(new PopupMenuChromium(client)); } diff --git a/WebKit/chromium/src/ChromiumBridge.cpp b/WebKit/chromium/src/ChromiumBridge.cpp index 39d2566..074c982 100644 --- a/WebKit/chromium/src/ChromiumBridge.cpp +++ b/WebKit/chromium/src/ChromiumBridge.cpp @@ -514,6 +514,12 @@ PassRefPtr<IDBFactoryBackendInterface> ChromiumBridge::idbFactory() return IDBFactoryBackendProxy::create(); } +void ChromiumBridge::idbShutdown() +{ + // In the browser process, this shuts down the utility process. In the renderer process, it does nothing. + webKitClient()->idbShutdown(); +} + void ChromiumBridge::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const String& keyPath, Vector<RefPtr<IDBKey> >& keys) { WebVector<WebSerializedScriptValue> webValues = values; diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.cpp b/WebKit/chromium/src/FrameLoaderClientImpl.cpp index ef28981..9d79599 100644 --- a/WebKit/chromium/src/FrameLoaderClientImpl.cpp +++ b/WebKit/chromium/src/FrameLoaderClientImpl.cpp @@ -51,6 +51,7 @@ #include "PlatformString.h" #include "PluginData.h" #include "PluginDataChromium.h" +#include "ProgressTracker.h" #include "Settings.h" #include "StringExtras.h" #include "WebDataSourceImpl.h" @@ -1010,7 +1011,12 @@ void FrameLoaderClientImpl::postProgressStartedNotification() void FrameLoaderClientImpl::postProgressEstimateChangedNotification() { - // FIXME + WebViewImpl* webview = m_webFrame->viewImpl(); + if (webview && webview->client()) { + webview->client()->didChangeLoadProgress( + m_webFrame, m_webFrame->frame()->page()->progress()->estimatedProgress()); + } + } void FrameLoaderClientImpl::postProgressFinishedNotification() diff --git a/WebKit/chromium/src/GraphicsContext3DChromium.cpp b/WebKit/chromium/src/GraphicsContext3DChromium.cpp index 4d9e40b..8cfe8c0 100644 --- a/WebKit/chromium/src/GraphicsContext3DChromium.cpp +++ b/WebKit/chromium/src/GraphicsContext3DChromium.cpp @@ -365,16 +365,6 @@ bool GraphicsContext3DInternal::isGLES2Compliant() const return m_impl->isGLES2Compliant(); } -bool GraphicsContext3DInternal::isGLES2NPOTStrict() const -{ - return m_impl->isGLES2NPOTStrict(); -} - -bool GraphicsContext3DInternal::isErrorGeneratedOnOutOfBoundsAccesses() const -{ - return m_impl->isErrorGeneratedOnOutOfBoundsAccesses(); -} - DELEGATE_TO_IMPL_1(activeTexture, unsigned long) DELEGATE_TO_IMPL_2(attachShader, Platform3DObject, Platform3DObject) @@ -1051,16 +1041,6 @@ bool GraphicsContext3D::isGLES2Compliant() const return m_internal->isGLES2Compliant(); } -bool GraphicsContext3D::isGLES2NPOTStrict() const -{ - return m_internal->isGLES2NPOTStrict(); -} - -bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const -{ - return m_internal->isErrorGeneratedOnOutOfBoundsAccesses(); -} - } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebKit/chromium/src/GraphicsContext3DInternal.h b/WebKit/chromium/src/GraphicsContext3DInternal.h index 17163a4..4453d28 100644 --- a/WebKit/chromium/src/GraphicsContext3DInternal.h +++ b/WebKit/chromium/src/GraphicsContext3DInternal.h @@ -75,8 +75,6 @@ public: WebGLLayerChromium* platformLayer() const; #endif bool isGLES2Compliant() const; - bool isGLES2NPOTStrict() const; - bool isErrorGeneratedOnOutOfBoundsAccesses() const; //---------------------------------------------------------------------- // Entry points for WebGL. diff --git a/WebKit/chromium/src/LocalizedStrings.cpp b/WebKit/chromium/src/LocalizedStrings.cpp index fbc35ce..947e732 100644 --- a/WebKit/chromium/src/LocalizedStrings.cpp +++ b/WebKit/chromium/src/LocalizedStrings.cpp @@ -296,44 +296,56 @@ String localizedMediaTimeDescription(float /*time*/) String validationMessageValueMissingText() { - notImplemented(); - return String(); + return query(WebLocalizedString::ValidationValueMissing); } String validationMessageTypeMismatchText() { - notImplemented(); - return String(); + return query(WebLocalizedString::ValidationTypeMismatch); +} + +String validationMessageTypeMismatchForEmailText() +{ + return query(WebLocalizedString::ValidationTypeMismatchForEmail); +} + +String validationMessageTypeMismatchForMultipleEmailText() +{ + return query(WebLocalizedString::ValidationTypeMismatchForMultipleEmail); +} + +String validationMessageTypeMismatchForURLText() +{ + return query(WebLocalizedString::ValidationTypeMismatchForURL); } String validationMessagePatternMismatchText() { - notImplemented(); - return String(); + return query(WebLocalizedString::ValidationPatternMismatch); } -String validationMessageTooLongText() +String validationMessageTooLongText(int, int) { - notImplemented(); - return String(); + // FIXME: pass the arguments. + return query(WebLocalizedString::ValidationTooLong); } -String validationMessageRangeUnderflowText() +String validationMessageRangeUnderflowText(const String&) { - notImplemented(); - return String(); + // FIXME: pass the arguments. + return query(WebLocalizedString::ValidationRangeUnderflow); } -String validationMessageRangeOverflowText() +String validationMessageRangeOverflowText(const String&) { - notImplemented(); - return String(); + // FIXME: pass the arguments. + return query(WebLocalizedString::ValidationRangeOverflow); } -String validationMessageStepMismatchText() +String validationMessageStepMismatchText(const String&, const String&) { - notImplemented(); - return String(); + // FIXME: pass the arguments. + return query(WebLocalizedString::ValidationStepMismatch); } } // namespace WebCore diff --git a/WebKit/chromium/src/WebBindings.cpp b/WebKit/chromium/src/WebBindings.cpp index c25c31b..d0a20d3 100644 --- a/WebKit/chromium/src/WebBindings.cpp +++ b/WebKit/chromium/src/WebBindings.cpp @@ -323,6 +323,17 @@ static NPObject* makeIntArrayImpl(const WebVector<int>& data) return npCreateV8ScriptObject(0, result, window); } +static NPObject* makeStringArrayImpl(const WebVector<WebString>& data) +{ + v8::HandleScope handleScope; + v8::Handle<v8::Array> result = v8::Array::New(data.size()); + for (size_t i = 0; i < data.size(); ++i) + result->Set(i, data[i].data() ? v8::String::New(reinterpret_cast<const uint16_t*>((data[i].data()))) : v8::String::New("")); + + WebCore::DOMWindow* window = WebCore::V8Proxy::retrieveWindow(WebCore::V8Proxy::currentContext()); + return npCreateV8ScriptObject(0, result, window); +} + #endif bool WebBindings::getDragData(NPObject* event, int* eventId, WebDragData* data) @@ -371,6 +382,16 @@ NPObject* WebBindings::makeIntArray(const WebVector<int> & data) #endif } +NPObject* WebBindings::makeStringArray(const WebVector<WebString>& data) +{ +#if USE(V8) + return makeStringArrayImpl(data); +#else + // Not supported on other ports (JSC, etc.). + return 0; +#endif +} + void WebBindings::pushExceptionHandler(ExceptionHandler handler, void* data) { WebCore::pushExceptionHandler(handler, data); diff --git a/WebKit/chromium/src/WebDataSourceImpl.cpp b/WebKit/chromium/src/WebDataSourceImpl.cpp index d5b1d79..65147fa 100644 --- a/WebKit/chromium/src/WebDataSourceImpl.cpp +++ b/WebKit/chromium/src/WebDataSourceImpl.cpp @@ -96,7 +96,7 @@ double WebDataSourceImpl::triggeringEventTime() const return 0.0; // DOMTimeStamp uses units of milliseconds. - return triggeringAction().event()->timeStamp() / 1000.0; + return convertDOMTimeStampToSeconds(triggeringAction().event()->timeStamp()); } WebDataSource::ExtraData* WebDataSourceImpl::extraData() const diff --git a/WebKit/chromium/src/WebFrameImpl.cpp b/WebKit/chromium/src/WebFrameImpl.cpp index 41b8321..adaab61 100644 --- a/WebKit/chromium/src/WebFrameImpl.cpp +++ b/WebKit/chromium/src/WebFrameImpl.cpp @@ -287,11 +287,11 @@ public: { } - virtual void begin(float width) + virtual void begin(float width, float height) { ASSERT(!m_printedPageWidth); m_printedPageWidth = width; - PrintContext::begin(m_printedPageWidth); + PrintContext::begin(m_printedPageWidth, height); } virtual void end() @@ -753,8 +753,9 @@ void WebFrameImpl::bindToWindowObject(const WebString& name, NPObject* object) void WebFrameImpl::executeScript(const WebScriptSource& source) { + TextPosition1 position(WTF::OneBasedNumber::fromOneBasedInt(source.startLine), WTF::OneBasedNumber::base()); m_frame->script()->executeScript( - ScriptSourceCode(source.code, source.url, source.startLine)); + ScriptSourceCode(source.code, source.url, position)); } void WebFrameImpl::executeScriptInIsolatedWorld( @@ -764,8 +765,9 @@ void WebFrameImpl::executeScriptInIsolatedWorld( Vector<ScriptSourceCode> sources; for (unsigned i = 0; i < numSources; ++i) { + TextPosition1 position(WTF::OneBasedNumber::fromOneBasedInt(sourcesIn[i].startLine), WTF::OneBasedNumber::base()); sources.append(ScriptSourceCode( - sourcesIn[i].code, sourcesIn[i].url, sourcesIn[i].startLine)); + sourcesIn[i].code, sourcesIn[i].url, position)); } m_frame->script()->evaluateInIsolatedWorld(worldId, sources, extensionGroup); @@ -817,8 +819,9 @@ void WebFrameImpl::collectGarbage() v8::Handle<v8::Value> WebFrameImpl::executeScriptAndReturnValue( const WebScriptSource& source) { + TextPosition1 position(WTF::OneBasedNumber::fromOneBasedInt(source.startLine), WTF::OneBasedNumber::base()); return m_frame->script()->executeScript( - ScriptSourceCode(source.code, source.url, source.startLine)).v8Value(); + ScriptSourceCode(source.code, source.url, position)).v8Value(); } // Returns the V8 context for this frame, or an empty handle if there is none. @@ -845,7 +848,7 @@ bool WebFrameImpl::insertStyleText( if (!id.isEmpty()) { Element* oldElement = document->getElementById(id); if (oldElement) { - Node* parent = oldElement->parent(); + Node* parent = oldElement->parentNode(); if (!parent) return false; parent->removeChild(oldElement, err); @@ -1283,7 +1286,7 @@ int WebFrameImpl::printBegin(const WebSize& pageSize, int printerDPI, bool *useB FloatRect rect(0, 0, static_cast<float>(pageSize.width), static_cast<float>(pageSize.height)); - m_printContext->begin(rect.width()); + m_printContext->begin(rect.width(), rect.height()); float pageHeight; // We ignore the overlays calculation for now since they are generated in the // browser. pageHeight is actually an output parameter. @@ -2003,7 +2006,7 @@ void WebFrameImpl::setFindEndstateFocusAndSelection() // example, focus links if we have found text within the link. Node* node = m_activeMatch->firstNode(); while (node && !node->isFocusable() && node != frame()->document()) - node = node->parent(); + node = node->parentNode(); if (node && node != frame()->document()) { // Found a focusable parent node. Set focus to it. diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp index 4cb701f..bd070c6 100644 --- a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp @@ -36,6 +36,7 @@ #include "app/gfx/gl/gl_bindings.h" #include "app/gfx/gl/gl_context.h" +#include "app/gfx/gl/gl_implementation.h" #include "NotImplemented.h" #include "WebView.h" #include <wtf/OwnArrayPtr.h> @@ -69,6 +70,10 @@ WebGraphicsContext3DDefaultImpl::VertexAttribPointerState::VertexAttribPointerSt WebGraphicsContext3DDefaultImpl::WebGraphicsContext3DDefaultImpl() : m_initialized(false) , m_renderDirectlyToWebView(false) + , m_isGLES2(false) + , m_haveEXTFramebufferObject(false) + , m_haveEXTFramebufferMultisample(false) + , m_haveANGLEFramebufferMultisample(false) , m_texture(0) , m_fbo(0) , m_depthStencilBuffer(0) @@ -166,10 +171,18 @@ bool WebGraphicsContext3DDefaultImpl::initialize(WebGraphicsContext3D::Attribute if (renderDirectlyToWebView) m_attributes.antialias = false; + m_isGLES2 = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; + const char* extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); + m_haveEXTFramebufferObject = strstr(extensions, "GL_EXT_framebuffer_object"); + m_haveEXTFramebufferMultisample = strstr(extensions, "GL_EXT_framebuffer_multisample"); + m_haveANGLEFramebufferMultisample = strstr(extensions, "GL_ANGLE_framebuffer_multisample"); + validateAttributes(); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_POINT_SPRITE); + if (!m_isGLES2) { + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); + } if (!angleCreateCompilers()) { angleDestroyCompilers(); @@ -187,7 +200,8 @@ void WebGraphicsContext3DDefaultImpl::validateAttributes() const char* extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); if (m_attributes.stencil) { - if (strstr(extensions, "GL_EXT_packed_depth_stencil")) { + if (strstr(extensions, "GL_OES_packed_depth_stencil") + || strstr(extensions, "GL_EXT_packed_depth_stencil")) { if (!m_attributes.depth) m_attributes.depth = true; } else @@ -201,7 +215,9 @@ void WebGraphicsContext3DDefaultImpl::validateAttributes() if (!strstr(vendor, "NVIDIA")) isValidVendor = false; #endif - if (!isValidVendor || !strstr(extensions, "GL_EXT_framebuffer_multisample")) + if (!(isValidVendor + && (m_haveEXTFramebufferMultisample + || (m_haveANGLEFramebufferMultisample && strstr(extensions, "GL_OES_rgb8_rgba8"))))) m_attributes.antialias = false; // Don't antialias when using Mesa to ensure more reliable testing and @@ -220,7 +236,12 @@ void WebGraphicsContext3DDefaultImpl::resolveMultisampledFramebuffer(unsigned x, if (m_attributes.antialias) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); - glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + if (m_haveEXTFramebufferMultisample) + glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + else { + ASSERT(m_haveANGLEFramebufferMultisample); + glBlitFramebufferANGLE(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); } } @@ -263,17 +284,7 @@ int WebGraphicsContext3DDefaultImpl::sizeInBytes(int type) bool WebGraphicsContext3DDefaultImpl::isGLES2Compliant() { - return false; -} - -bool WebGraphicsContext3DDefaultImpl::isGLES2NPOTStrict() -{ - return false; -} - -bool WebGraphicsContext3DDefaultImpl::isErrorGeneratedOnOutOfBoundsAccesses() -{ - return false; + return m_isGLES2; } unsigned int WebGraphicsContext3DDefaultImpl::getPlatformTextureId() @@ -328,12 +339,16 @@ void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) } } - GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; + GLint internalMultisampledColorFormat, internalColorFormat, colorFormat, internalDepthStencilFormat = 0; if (m_attributes.alpha) { - internalColorFormat = GL_RGBA8; + // GL_RGBA8_OES == GL_RGBA8 + internalMultisampledColorFormat = GL_RGBA8; + internalColorFormat = m_isGLES2 ? GL_RGBA : GL_RGBA8; colorFormat = GL_RGBA; } else { - internalColorFormat = GL_RGB8; + // GL_RGB8_OES == GL_RGB8 + internalMultisampledColorFormat = GL_RGB8; + internalColorFormat = m_isGLES2 ? GL_RGB : GL_RGB8; colorFormat = GL_RGB; } if (m_attributes.stencil || m_attributes.depth) { @@ -341,8 +356,12 @@ void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) // See GraphicsContext3DInternal constructor. if (m_attributes.stencil && m_attributes.depth) internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; - else - internalDepthStencilFormat = GL_DEPTH_COMPONENT; + else { + if (m_isGLES2) + internalDepthStencilFormat = GL_DEPTH_COMPONENT16; + else + internalDepthStencilFormat = GL_DEPTH_COMPONENT; + } } bool mustRestoreFBO = false; @@ -357,11 +376,21 @@ void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); } glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height); + if (m_haveEXTFramebufferMultisample) + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalMultisampledColorFormat, width, height); + else { + ASSERT(m_haveANGLEFramebufferMultisample); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT, sampleCount, internalMultisampledColorFormat, width, height); + } glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); if (m_attributes.stencil || m_attributes.depth) { glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + if (m_haveEXTFramebufferMultisample) + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + else { + ASSERT(m_haveANGLEFramebufferMultisample); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + } if (m_attributes.stencil) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); if (m_attributes.depth) @@ -508,9 +537,15 @@ bool WebGraphicsContext3DDefaultImpl::readBackFramebuffer(unsigned char* pixels, mustRestorePackAlignment = true; } - // FIXME: OpenGL ES 2 does not support GL_BGRA so this fails when - // using that backend. - glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); + if (m_isGLES2) { + // FIXME: consider testing for presence of GL_OES_read_format + // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here + // directly. + glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + for (size_t i = 0; i < bufferSize; i += 4) + std::swap(pixels[i], pixels[i + 2]); + } else + glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); if (mustRestorePackAlignment) glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); @@ -845,7 +880,7 @@ DELEGATE_TO_GL_1(frontFace, FrontFace, unsigned long) void WebGraphicsContext3DDefaultImpl::generateMipmap(unsigned long target) { makeContextCurrent(); - if (glGenerateMipmapEXT) + if (m_isGLES2 || m_haveEXTFramebufferObject) glGenerateMipmapEXT(target); // FIXME: provide alternative code path? This will be unpleasant // to implement if glGenerateMipmapEXT is not available -- it will @@ -951,11 +986,15 @@ void WebGraphicsContext3DDefaultImpl::getFramebufferAttachmentParameteriv(unsign void WebGraphicsContext3DDefaultImpl::getIntegerv(unsigned long pname, int* value) { + makeContextCurrent(); + if (m_isGLES2) { + glGetIntegerv(pname, value); + return; + } // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS // because desktop GL's corresponding queries return the number of components // whereas GLES2 return the number of vectors (each vector has 4 components). // Therefore, the value returned by desktop GL needs to be divided by 4. - makeContextCurrent(); switch (pname) { case MAX_FRAGMENT_UNIFORM_VECTORS: glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); @@ -1096,10 +1135,10 @@ WebString WebGraphicsContext3DDefaultImpl::getString(unsigned long name) StringBuilder result; result.append(reinterpret_cast<const char*>(glGetString(name))); if (name == GL_EXTENSIONS) { - // GL_CHROMIUM_copy_texture_to_parent_texture requires this - // desktopGL-only function (GLES2 doesn't support it), so - // check for its existence here. - if (glGetTexLevelParameteriv) + // GL_CHROMIUM_copy_texture_to_parent_texture requires the + // desktopGL-only function glGetTexLevelParameteriv (GLES2 + // doesn't support it). + if (!m_isGLES2) result.append(" GL_CHROMIUM_copy_texture_to_parent_texture"); } return WebString(result.toString()); @@ -1551,11 +1590,21 @@ bool WebGraphicsContext3DDefaultImpl::angleValidateShaderSource(ShaderSourceEntr } int length = 0; - ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &length); + if (m_isGLES2) { + // ANGLE does not yet have a GLSL ES backend. Therefore if the + // compile succeeds we send the original source down. + length = strlen(entry.source); + if (length > 0) + ++length; // Add null terminator + } else + ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &length); if (length > 1) { if (!tryFastMalloc(length * sizeof(char)).getValue(entry.translatedSource)) return false; - ShGetObjectCode(compiler, entry.translatedSource); + if (m_isGLES2) + strncpy(entry.translatedSource, entry.source, length); + else + ShGetObjectCode(compiler, entry.translatedSource); } entry.isValid = true; return true; diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h index c1de77c..e865710 100644 --- a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h @@ -70,8 +70,6 @@ public: virtual int sizeInBytes(int type); virtual bool isGLES2Compliant(); - virtual bool isGLES2NPOTStrict(); - virtual bool isErrorGeneratedOnOutOfBoundsAccesses(); virtual void reshape(int width, int height); @@ -271,6 +269,10 @@ private: WebGraphicsContext3D::Attributes m_attributes; bool m_initialized; bool m_renderDirectlyToWebView; + bool m_isGLES2; + bool m_haveEXTFramebufferObject; + bool m_haveEXTFramebufferMultisample; + bool m_haveANGLEFramebufferMultisample; unsigned int m_texture; unsigned int m_fbo; diff --git a/WebKit/chromium/src/WebImageDecoder.cpp b/WebKit/chromium/src/WebImageDecoder.cpp index 160deee..0cfd458 100644 --- a/WebKit/chromium/src/WebImageDecoder.cpp +++ b/WebKit/chromium/src/WebImageDecoder.cpp @@ -56,10 +56,10 @@ void WebImageDecoder::init(Type type) { switch (type) { case TypeBMP: - m_private = new BMPImageDecoder(true); + m_private = new BMPImageDecoder(true, false); break; case TypeICO: - m_private = new ICOImageDecoder(true); + m_private = new ICOImageDecoder(true, false); break; } } diff --git a/WebKit/chromium/src/WebPerformance.cpp b/WebKit/chromium/src/WebPerformance.cpp index f019793..de9c1f6 100644 --- a/WebKit/chromium/src/WebPerformance.cpp +++ b/WebKit/chromium/src/WebPerformance.cpp @@ -37,6 +37,11 @@ using namespace WebCore; namespace WebKit { +static double millisecondsToSeconds(unsigned long long milliseconds) +{ + return static_cast<double>(milliseconds / 1000.0); +} + void WebPerformance::reset() { m_private.reset(); @@ -50,11 +55,11 @@ void WebPerformance::assign(const WebPerformance& other) WebNavigationType WebPerformance::navigationType() const { switch (m_private->navigation()->type()) { - case Navigation::NAVIGATE: + case PerformanceNavigation::NAVIGATE: return WebNavigationTypeOther; - case Navigation::RELOAD: + case PerformanceNavigation::RELOAD: return WebNavigationTypeReload; - case Navigation::BACK_FORWARD: + case PerformanceNavigation::BACK_FORWARD: return WebNavigationTypeBackForward; } ASSERT_NOT_REACHED(); @@ -63,22 +68,22 @@ WebNavigationType WebPerformance::navigationType() const double WebPerformance::navigationStart() const { - return static_cast<double>(m_private->timing()->navigationStart()); + return millisecondsToSeconds(m_private->timing()->navigationStart()); } double WebPerformance::unloadEventEnd() const { - return static_cast<double>(m_private->timing()->unloadEventEnd()); + return millisecondsToSeconds(m_private->timing()->unloadEventEnd()); } double WebPerformance::redirectStart() const { - return static_cast<double>(m_private->timing()->redirectStart()); + return millisecondsToSeconds(m_private->timing()->redirectStart()); } double WebPerformance::redirectEnd() const { - return static_cast<double>(m_private->timing()->redirectEnd()); + return millisecondsToSeconds(m_private->timing()->redirectEnd()); } unsigned short WebPerformance::redirectCount() const @@ -88,57 +93,52 @@ unsigned short WebPerformance::redirectCount() const double WebPerformance::fetchStart() const { - return static_cast<double>(m_private->timing()->fetchStart()); + return millisecondsToSeconds(m_private->timing()->fetchStart()); } double WebPerformance::domainLookupStart() const { - return static_cast<double>(m_private->timing()->domainLookupStart()); + return millisecondsToSeconds(m_private->timing()->domainLookupStart()); } double WebPerformance::domainLookupEnd() const { - return static_cast<double>(m_private->timing()->domainLookupEnd()); + return millisecondsToSeconds(m_private->timing()->domainLookupEnd()); } double WebPerformance::connectStart() const { - return static_cast<double>(m_private->timing()->connectStart()); + return millisecondsToSeconds(m_private->timing()->connectStart()); } double WebPerformance::connectEnd() const { - return static_cast<double>(m_private->timing()->connectEnd()); + return millisecondsToSeconds(m_private->timing()->connectEnd()); } double WebPerformance::requestStart() const { - return static_cast<double>(m_private->timing()->requestStart()); -} - -double WebPerformance::requestEnd() const -{ - return static_cast<double>(m_private->timing()->requestEnd()); + return millisecondsToSeconds(m_private->timing()->requestStart()); } double WebPerformance::responseStart() const { - return static_cast<double>(m_private->timing()->responseStart()); + return millisecondsToSeconds(m_private->timing()->responseStart()); } double WebPerformance::responseEnd() const { - return static_cast<double>(m_private->timing()->responseEnd()); + return millisecondsToSeconds(m_private->timing()->responseEnd()); } double WebPerformance::loadEventStart() const { - return static_cast<double>(m_private->timing()->loadEventStart()); + return millisecondsToSeconds(m_private->timing()->loadEventStart()); } double WebPerformance::loadEventEnd() const { - return static_cast<double>(m_private->timing()->loadEventEnd()); + return millisecondsToSeconds(m_private->timing()->loadEventEnd()); } WebPerformance::WebPerformance(const PassRefPtr<Performance>& performance) diff --git a/WebKit/chromium/src/WebSettingsImpl.cpp b/WebKit/chromium/src/WebSettingsImpl.cpp index 9953b5c..1bea259 100644 --- a/WebKit/chromium/src/WebSettingsImpl.cpp +++ b/WebKit/chromium/src/WebSettingsImpl.cpp @@ -223,6 +223,11 @@ void WebSettingsImpl::setEditableLinkBehaviorNeverLive() m_settings->setEditableLinkBehavior(WebCore::EditableLinkNeverLive); } +void WebSettingsImpl::setFrameFlatteningEnabled(bool enabled) +{ + m_settings->setFrameFlatteningEnabled(enabled); +} + void WebSettingsImpl::setFontRenderingModeNormal() { // FIXME: If you ever need more behaviors than this, then we should probably diff --git a/WebKit/chromium/src/WebSettingsImpl.h b/WebKit/chromium/src/WebSettingsImpl.h index 6d40b4f..081188f 100644 --- a/WebKit/chromium/src/WebSettingsImpl.h +++ b/WebKit/chromium/src/WebSettingsImpl.h @@ -77,6 +77,7 @@ public: virtual void setXSSAuditorEnabled(bool); virtual void setLocalStorageEnabled(bool); virtual void setEditableLinkBehaviorNeverLive(); + virtual void setFrameFlatteningEnabled(bool); virtual void setFontRenderingModeNormal(); virtual void setShouldPaintCustomScrollbars(bool); virtual void setAllowUniversalAccessFromFileURLs(bool); diff --git a/WebKit/chromium/src/WebSpeechInputControllerMockImpl.cpp b/WebKit/chromium/src/WebSpeechInputControllerMockImpl.cpp index ce8eba6..8cf7848 100644 --- a/WebKit/chromium/src/WebSpeechInputControllerMockImpl.cpp +++ b/WebKit/chromium/src/WebSpeechInputControllerMockImpl.cpp @@ -60,6 +60,11 @@ void WebSpeechInputControllerMockImpl::setMockRecognitionResult(const WebString& m_webcoreMock->setRecognitionResult(result, language); } +void WebSpeechInputControllerMockImpl::clearResults() +{ + m_webcoreMock->clearResults(); +} + void WebSpeechInputControllerMockImpl::didCompleteRecording(int requestId) { m_listener->didCompleteRecording(requestId); diff --git a/WebKit/chromium/src/WebSpeechInputControllerMockImpl.h b/WebKit/chromium/src/WebSpeechInputControllerMockImpl.h index 7b50a8b..7680873 100644 --- a/WebKit/chromium/src/WebSpeechInputControllerMockImpl.h +++ b/WebKit/chromium/src/WebSpeechInputControllerMockImpl.h @@ -63,6 +63,7 @@ public: // WebSpeechInputControllerMock methods. void setMockRecognitionResult(const WebString& result, const WebString& language); + void clearResults(); private: OwnPtr<WebCore::SpeechInputClientMock> m_webcoreMock; diff --git a/WebKit/chromium/src/WebURLRequest.cpp b/WebKit/chromium/src/WebURLRequest.cpp index b243420..7a77ca3 100644 --- a/WebKit/chromium/src/WebURLRequest.cpp +++ b/WebKit/chromium/src/WebURLRequest.cpp @@ -221,6 +221,16 @@ WebURLRequest::TargetType WebURLRequest::targetType() const return static_cast<TargetType>(m_private->m_resourceRequest->targetType()); } +bool WebURLRequest::hasUserGesture() const +{ + return m_private->m_resourceRequest->hasUserGesture(); +} + +void WebURLRequest::setHasUserGesture(bool hasUserGesture) +{ + m_private->m_resourceRequest->setHasUserGesture(hasUserGesture); +} + void WebURLRequest::setTargetType(TargetType targetType) { m_private->m_resourceRequest->setTargetType( diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp index 490c620..6625949 100644 --- a/WebKit/chromium/src/WebViewImpl.cpp +++ b/WebKit/chromium/src/WebViewImpl.cpp @@ -178,7 +178,7 @@ static const PopupContainerSettings autoFillPopupSettings = { false, // acceptOnAbandon true, // loopSelectionNavigation false, // restrictWidthOfListBox (For security reasons show the entire entry - // so the user doesn't enter information it did not intend to.) + // so the user doesn't enter information he did not intend to.) // For suggestions, we use the direction of the input field as the direction // of the popup items. The main reason is to keep the display of items in // drop-down the same as the items in the input field. @@ -571,13 +571,13 @@ bool WebViewImpl::keyEvent(const WebKeyboardEvent& event) WebInputEvent::RawKeyDown; #endif - if (((!event.modifiers && (event.windowsKeyCode == VKEY_APPS)) - || ((event.modifiers == WebInputEvent::ShiftKey) && (event.windowsKeyCode == VKEY_F10))) - && event.type == contextMenuTriggeringEventType) { + bool isUnmodifiedMenuKey = !(event.modifiers & WebInputEvent::InputModifiers) && event.windowsKeyCode == VKEY_APPS; + bool isShiftF10 = event.modifiers == WebInputEvent::ShiftKey && event.windowsKeyCode == VKEY_F10; + if ((isUnmodifiedMenuKey || isShiftF10) && event.type == contextMenuTriggeringEventType) { sendContextMenuEvent(event); return true; } -#endif +#endif // OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) // It's not clear if we should continue after detecting a capslock keypress. // I'll err on the side of continuing, which is the pre-existing behaviour. @@ -936,10 +936,10 @@ void WebViewImpl::resize(const WebSize& newSize) m_client->didInvalidateRect(damagedRect); } -#if USE(ACCELERATED_COMPOSITING) && OS(DARWIN) +#if USE(ACCELERATED_COMPOSITING) if (m_layerRenderer) { - m_layerRenderer->resizeOnscreenContent(WebCore::IntSize(std::max(1, m_size.width), - std::max(1, m_size.height))); + m_layerRenderer->resizeOnscreenContent(IntSize(std::max(1, m_size.width), + std::max(1, m_size.height))); } #endif } @@ -1016,10 +1016,6 @@ void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect) resizeRect.intersect(IntRect(IntPoint(), m_layerRenderer->rootLayerTextureSize())); doPixelReadbackToCanvas(canvas, resizeRect); } - - // Temporarily present so the downstream Chromium renderwidget still renders. - // FIXME: remove this call once the changes to Chromium's renderwidget have landed. - m_layerRenderer->present(); #endif } else { WebFrameImpl* webframe = mainFrameImpl(); @@ -1100,7 +1096,7 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent) node->dispatchMouseEvent( PlatformMouseEventBuilder(mainFrameImpl()->frameView(), *static_cast<const WebMouseEvent*>(&inputEvent)), - eventType); + eventType, static_cast<const WebMouseEvent*>(&inputEvent)->clickCount); m_currentInputEvent = 0; return true; } @@ -1943,12 +1939,9 @@ void WebViewImpl::applyAutoFillSuggestions( } if (m_autoFillPopupShowing) { - m_autoFillPopupClient->setSuggestions( - names, labels, icons, uniqueIDs, separatorIndex); refreshAutoFillPopup(); } else { - m_autoFillPopup->show(focusedNode->getRect(), - focusedNode->ownerDocument()->view(), 0); + m_autoFillPopup->show(focusedNode->getRect(), focusedNode->ownerDocument()->view(), 0); m_autoFillPopupShowing = true; } @@ -2274,22 +2267,11 @@ void WebViewImpl::setRootGraphicsLayer(WebCore::PlatformLayer* layer) void WebViewImpl::setRootLayerNeedsDisplay() { m_client->scheduleComposite(); - // FIXME: To avoid breaking the downstream Chrome render_widget while downstream - // changes land, we also have to pass a 1x1 invalidate up to the client - { - WebRect damageRect(0, 0, 1, 1); - m_client->didInvalidateRect(damageRect); - } } void WebViewImpl::scrollRootLayerRect(const IntSize& scrollDelta, const IntRect& clipRect) { - // FIXME: To avoid breaking the Chrome render_widget when the new compositor render - // path is not checked in, we must still pass scroll damage up to the client. This - // code will be backed out in a followup CL once the Chromium changes have landed. - m_client->didScrollRect(scrollDelta.width(), scrollDelta.height(), clipRect); - ASSERT(m_layerRenderer); // Compute the damage rect in viewport space. WebFrameImpl* webframe = mainFrameImpl(); @@ -2346,7 +2328,7 @@ void WebViewImpl::scrollRootLayerRect(const IntSize& scrollDelta, const IntRect& // Move the damage innerDamage.move(scrollDelta.width(), scrollDelta.height()); - + // Merge it back into the damaged rect m_rootLayerDirtyRect.unite(innerDamage); } @@ -2356,17 +2338,12 @@ void WebViewImpl::scrollRootLayerRect(const IntSize& scrollDelta, const IntRect& void WebViewImpl::invalidateRootLayerRect(const IntRect& rect) { - // FIXME: To avoid breaking the Chrome render_widget when the new compositor render - // path is not checked in, we must still pass damage up to the client. This - // code will be backed out in a followup CL once the Chromium changes have landed. - m_client->didInvalidateRect(rect); - ASSERT(m_layerRenderer); if (!page()) return; - // FIXME: add a smarter damage aggregation logic and/or unify with + // FIXME: add a smarter damage aggregation logic and/or unify with // LayerChromium's damage logic m_rootLayerDirtyRect.unite(rect); setRootLayerNeedsDisplay(); @@ -2380,16 +2357,23 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active) if (!active) { m_isAcceleratedCompositingActive = false; + m_layerRenderer->finish(); // finish all GL rendering before we hide the window? + m_client->didActivateAcceleratedCompositing(false); return; } if (m_layerRenderer) { m_isAcceleratedCompositingActive = true; + m_layerRenderer->resizeOnscreenContent(WebCore::IntSize(std::max(1, m_size.width), + std::max(1, m_size.height))); + + m_client->didActivateAcceleratedCompositing(true); return; } RefPtr<GraphicsContext3D> context = m_temporaryOnscreenGraphicsContext3D.release(); if (!context) { + m_client->didActivateAcceleratedCompositing(true); context = GraphicsContext3D::create(GraphicsContext3D::Attributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow); if (context) context->reshape(std::max(1, m_size.width), std::max(1, m_size.height)); @@ -2400,6 +2384,7 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active) m_compositorCreationFailed = false; } else { m_isAcceleratedCompositingActive = false; + m_client->didActivateAcceleratedCompositing(false); m_compositorCreationFailed = true; } } diff --git a/WebKit/chromium/src/WorkerAsyncFileSystemChromium.cpp b/WebKit/chromium/src/WorkerAsyncFileSystemChromium.cpp index 1e70619..058e947 100644 --- a/WebKit/chromium/src/WorkerAsyncFileSystemChromium.cpp +++ b/WebKit/chromium/src/WorkerAsyncFileSystemChromium.cpp @@ -34,13 +34,16 @@ #if ENABLE(FILE_SYSTEM) #include "AsyncFileSystemCallbacks.h" +#include "FileMetadata.h" #include "FileSystem.h" #include "NotImplemented.h" #include "WebFileSystem.h" #include "WebFileSystemCallbacksImpl.h" +#include "WebFileWriter.h" #include "WebKit.h" #include "WebKitClient.h" #include "WebWorkerBase.h" +#include "WorkerAsyncFileWriterChromium.h" #include "WorkerContext.h" #include "WorkerFileSystemCallbacksBridge.h" #include "WorkerScriptController.h" @@ -134,9 +137,76 @@ void WorkerAsyncFileSystemChromium::readDirectory(const String& path, PassOwnPtr createWorkerFileSystemCallbacksBridge(callbacks)->postReadDirectoryToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); } -void WorkerAsyncFileSystemChromium::createWriter(AsyncFileWriterClient*, const String&, PassOwnPtr<AsyncFileSystemCallbacks>) +class WorkerFileWriterHelperCallbacks : public AsyncFileSystemCallbacks { +public: + static PassOwnPtr<WorkerFileWriterHelperCallbacks> create(AsyncFileWriterClient* client, const String& path, WebKit::WebFileSystem* webFileSystem, PassOwnPtr<WebCore::AsyncFileSystemCallbacks> callbacks, WorkerContext* workerContext) + { + return adoptPtr(new WorkerFileWriterHelperCallbacks(client, path, webFileSystem, callbacks, workerContext)); + } + + virtual void didSucceed() + { + ASSERT_NOT_REACHED(); + } + + virtual void didReadMetadata(const FileMetadata& metadata) + { + ASSERT(m_callbacks); + if (metadata.type != FileMetadata::TypeFile || metadata.length < 0) + m_callbacks->didFail(WebKit::WebFileErrorInvalidState); + else { + OwnPtr<WorkerAsyncFileWriterChromium> asyncFileWriterChromium = WorkerAsyncFileWriterChromium::create(m_webFileSystem, m_path, m_workerContext, m_client, WorkerAsyncFileWriterChromium::Asynchronous); + m_callbacks->didCreateFileWriter(asyncFileWriterChromium.release(), metadata.length); + } + } + + virtual void didReadDirectoryEntry(const String& name, bool isDirectory) + { + ASSERT_NOT_REACHED(); + } + + virtual void didReadDirectoryEntries(bool hasMore) + { + ASSERT_NOT_REACHED(); + } + + virtual void didOpenFileSystem(const String&, PassOwnPtr<AsyncFileSystem>) + { + ASSERT_NOT_REACHED(); + } + + // Called when an AsyncFileWrter has been created successfully. + virtual void didCreateFileWriter(PassOwnPtr<AsyncFileWriter>, long long) + { + ASSERT_NOT_REACHED(); + } + + virtual void didFail(int code) + { + ASSERT(m_callbacks); + m_callbacks->didFail(code); + } + +private: + WorkerFileWriterHelperCallbacks(AsyncFileWriterClient* client, const String& path, WebKit::WebFileSystem* webFileSystem, PassOwnPtr<WebCore::AsyncFileSystemCallbacks> callbacks, WorkerContext* workerContext) + : m_client(client) + , m_path(path) + , m_webFileSystem(webFileSystem) + , m_callbacks(callbacks) + , m_workerContext(workerContext) + { + } + + AsyncFileWriterClient* m_client; + String m_path; + WebKit::WebFileSystem* m_webFileSystem; + OwnPtr<WebCore::AsyncFileSystemCallbacks> m_callbacks; + WorkerContext* m_workerContext; +}; + +void WorkerAsyncFileSystemChromium::createWriter(AsyncFileWriterClient* client, const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) { - notImplemented(); + createWorkerFileSystemCallbacksBridge(WorkerFileWriterHelperCallbacks::create(client, path, m_webFileSystem, callbacks, m_workerContext))->postReadMetadataToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); } PassRefPtr<WorkerFileSystemCallbacksBridge> WorkerAsyncFileSystemChromium::createWorkerFileSystemCallbacksBridge(PassOwnPtr<AsyncFileSystemCallbacks> callbacks) diff --git a/WebKit/chromium/src/WorkerAsyncFileWriterChromium.cpp b/WebKit/chromium/src/WorkerAsyncFileWriterChromium.cpp new file mode 100644 index 0000000..8d8e469 --- /dev/null +++ b/WebKit/chromium/src/WorkerAsyncFileWriterChromium.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WorkerAsyncFileWriterChromium.h" + +#if ENABLE(FILE_SYSTEM) + +#include "AsyncFileSystem.h" +#include "Blob.h" +#include "ScriptExecutionContext.h" +#include "WebFileSystem.h" +#include "WebFileWriter.h" +#include "WebURL.h" +#include "WebWorkerBase.h" +#include "WorkerContext.h" +#include "WorkerFileWriterCallbacksBridge.h" +#include "WorkerLoaderProxy.h" +#include "WorkerThread.h" +#include <wtf/Assertions.h> + +using namespace WebKit; + +namespace WebCore { + +WorkerAsyncFileWriterChromium::WorkerAsyncFileWriterChromium(WebFileSystem* webFileSystem, const String& path, WorkerContext* workerContext, AsyncFileWriterClient* client, WriterType type) + : m_type(type) +{ + ASSERT(m_type == Asynchronous); // Synchronous is not implemented yet. + + WorkerLoaderProxy* proxy = &workerContext->thread()->workerLoaderProxy(); + m_bridge = WorkerFileWriterCallbacksBridge::create(path, proxy, workerContext, client); +} + +WorkerAsyncFileWriterChromium::~WorkerAsyncFileWriterChromium() +{ + m_bridge->postShutdownToMainThread(m_bridge); +} + +void WorkerAsyncFileWriterChromium::write(long long position, Blob* data) +{ + m_bridge->postWriteToMainThread(position, data->url()); +} + +void WorkerAsyncFileWriterChromium::truncate(long long length) +{ + m_bridge->postTruncateToMainThread(length); +} + +void WorkerAsyncFileWriterChromium::abort() +{ + m_bridge->postAbortToMainThread(); +} + +} + +#endif // ENABLE(FILE_SYSTEM) diff --git a/WebKit/chromium/src/WorkerAsyncFileWriterChromium.h b/WebKit/chromium/src/WorkerAsyncFileWriterChromium.h new file mode 100644 index 0000000..55d8d24 --- /dev/null +++ b/WebKit/chromium/src/WorkerAsyncFileWriterChromium.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WorkerAsyncFileWriterChromium_h +#define WorkerAsyncFileWriterChromium_h + +#if ENABLE(FILE_SYSTEM) + +#include "AsyncFileWriter.h" +#include <wtf/PassOwnPtr.h> + +namespace WebKit { + class WebFileSystem; + class WebFileWriter; + class WorkerFileWriterCallbacksBridge; +} + +namespace WTF { + class String; +} +using WTF::String; + +namespace WebCore { + +class AsyncFileSystem; +class AsyncFileWriterClient; +class Blob; +class WorkerContext; + +class WorkerAsyncFileWriterChromium : public AsyncFileWriter { +public: + enum WriterType { + Asynchronous, + Synchronous, + }; + + static PassOwnPtr<WorkerAsyncFileWriterChromium> create(WebKit::WebFileSystem* webFileSystem, const String& path, WorkerContext* workerContext, AsyncFileWriterClient* client, WriterType type) + { + return adoptPtr(new WorkerAsyncFileWriterChromium(webFileSystem, path, workerContext, client, type)); + } + ~WorkerAsyncFileWriterChromium(); + + // FileWriter + virtual void write(long long position, Blob* data); + virtual void truncate(long long length); + virtual void abort(); + +private: + + WorkerAsyncFileWriterChromium(WebKit::WebFileSystem*, const String& path, WorkerContext*, AsyncFileWriterClient*, WriterType); + RefPtr<WebKit::WorkerFileWriterCallbacksBridge> m_bridge; + WriterType m_type; +}; + +} // namespace + +#endif // ENABLE(FILE_SYSTEM) + +#endif // AsyncFileWriterChromium_h diff --git a/WebKit/chromium/src/WorkerFileWriterCallbacksBridge.cpp b/WebKit/chromium/src/WorkerFileWriterCallbacksBridge.cpp new file mode 100644 index 0000000..827c011 --- /dev/null +++ b/WebKit/chromium/src/WorkerFileWriterCallbacksBridge.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WorkerFileWriterCallbacksBridge.h" + +#if ENABLE(FILE_SYSTEM) + +#include "AsyncFileWriterClient.h" +#include "CrossThreadTask.h" +#include "WebCString.h" +#include "WebFileSystem.h" +#include "WebFileWriter.h" +#include "WebKit.h" +#include "WebKitClient.h" +#include "WebWorkerBase.h" +#include "WorkerContext.h" +#include "WorkerLoaderProxy.h" +#include "WorkerThread.h" +#include <wtf/MainThread.h> +#include <wtf/Threading.h> + +using namespace WebCore; + +namespace WebKit { + +void WorkerFileWriterCallbacksBridge::notifyStop() +{ + ASSERT(m_workerContext->isContextThread()); + m_clientOnWorkerThread = 0; +} + +void WorkerFileWriterCallbacksBridge::postWriteToMainThread(long long position, const KURL& data) +{ + dispatchTaskToMainThread(createCallbackTask(&writeOnMainThread, this, position, data)); +} + +void WorkerFileWriterCallbacksBridge::postTruncateToMainThread(long long length) +{ + dispatchTaskToMainThread(createCallbackTask(&truncateOnMainThread, this, length)); +} + +void WorkerFileWriterCallbacksBridge::postAbortToMainThread() +{ + dispatchTaskToMainThread(createCallbackTask(&abortOnMainThread, this)); +} + +void WorkerFileWriterCallbacksBridge::postShutdownToMainThread(PassRefPtr<WorkerFileWriterCallbacksBridge> bridge) +{ + ASSERT(m_workerContext->isContextThread()); + m_clientOnWorkerThread = 0; + dispatchTaskToMainThread(createCallbackTask(&shutdownOnMainThread, bridge)); +} + +void WorkerFileWriterCallbacksBridge::writeOnMainThread(ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge, long long position, const KURL& data) +{ + bridge->m_writer->write(position, WebURL(data)); +} + +void WorkerFileWriterCallbacksBridge::truncateOnMainThread(ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge, long long length) +{ + bridge->m_writer->truncate(length); +} + +void WorkerFileWriterCallbacksBridge::abortOnMainThread(ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge) +{ + bridge->m_writer->cancel(); +} + +void WorkerFileWriterCallbacksBridge::initOnMainThread(ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge, const String& path) +{ + ASSERT(!bridge->m_writer); + bridge->m_writer = webKitClient()->fileSystem()->createFileWriter(path, bridge.get()); +} + +void WorkerFileWriterCallbacksBridge::shutdownOnMainThread(ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge) +{ + bridge->m_writerDeleted = true; + bridge->m_writer.clear(); +} + +void WorkerFileWriterCallbacksBridge::didWrite(long long bytes, bool complete) +{ + dispatchTaskToWorkerThread(createCallbackTask(&didWriteOnWorkerThread, this, bytes, complete)); +} + +void WorkerFileWriterCallbacksBridge::didFail(WebFileError error) +{ + dispatchTaskToWorkerThread(createCallbackTask(&didFailOnWorkerThread, this, error)); +} + +void WorkerFileWriterCallbacksBridge::didTruncate() +{ + dispatchTaskToWorkerThread(createCallbackTask(&didTruncateOnWorkerThread, this)); +} + +WorkerFileWriterCallbacksBridge::WorkerFileWriterCallbacksBridge(const String& path, WorkerLoaderProxy* proxy, ScriptExecutionContext* scriptExecutionContext, AsyncFileWriterClient* client) + : WorkerContext::Observer(static_cast<WorkerContext*>(scriptExecutionContext)) + , m_proxy(proxy) + , m_workerContext(scriptExecutionContext) + , m_clientOnWorkerThread(client) + , m_writerDeleted(false) +{ + ASSERT(m_workerContext->isContextThread()); + postInitToMainThread(path); +} + +void WorkerFileWriterCallbacksBridge::postInitToMainThread(const String& path) +{ + dispatchTaskToMainThread(createCallbackTask(&initOnMainThread, this, path)); +} + +WorkerFileWriterCallbacksBridge::~WorkerFileWriterCallbacksBridge() +{ + ASSERT(!m_clientOnWorkerThread); + ASSERT(!m_writer); +} + +// We know m_clientOnWorkerThread is still valid because it is only cleared on the context thread, and because we check in runTaskOnWorkerThread before calling any of these methods. +void WorkerFileWriterCallbacksBridge::didWriteOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge, long long length, bool complete) +{ + ASSERT(bridge->m_workerContext->isContextThread()); + bridge->m_clientOnWorkerThread->didWrite(length, complete); +} + +void WorkerFileWriterCallbacksBridge::didFailOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge, WebFileError error) +{ + ASSERT(bridge->m_workerContext->isContextThread()); + bridge->m_clientOnWorkerThread->didFail(static_cast<FileError::ErrorCode>(error)); +} + +void WorkerFileWriterCallbacksBridge::didTruncateOnWorkerThread(ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge) +{ + ASSERT(bridge->m_workerContext->isContextThread()); + bridge->m_clientOnWorkerThread->didTruncate(); +} + +void WorkerFileWriterCallbacksBridge::runTaskOnMainThread(ScriptExecutionContext* scriptExecutionContext, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge, PassOwnPtr<ScriptExecutionContext::Task> taskToRun) +{ + ASSERT(isMainThread()); + if (!bridge->m_writerDeleted) + taskToRun->performTask(scriptExecutionContext); +} + +void WorkerFileWriterCallbacksBridge::runTaskOnWorkerThread(ScriptExecutionContext* scriptExecutionContext, PassRefPtr<WorkerFileWriterCallbacksBridge> bridge, PassOwnPtr<ScriptExecutionContext::Task> taskToRun) +{ + ASSERT(bridge->m_workerContext->isContextThread()); + if (bridge->m_clientOnWorkerThread) + taskToRun->performTask(scriptExecutionContext); +} + +void WorkerFileWriterCallbacksBridge::dispatchTaskToMainThread(PassOwnPtr<ScriptExecutionContext::Task> task) +{ + ASSERT(m_workerContext->isContextThread()); + WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&runTaskOnMainThread, this, task)); +} + +void WorkerFileWriterCallbacksBridge::dispatchTaskToWorkerThread(PassOwnPtr<ScriptExecutionContext::Task> task) +{ + ASSERT(isMainThread()); + m_proxy->postTaskForModeToWorkerContext(createCallbackTask(&runTaskOnWorkerThread, this, task), WorkerRunLoop::defaultMode()); +} + +} + +#endif // ENABLE(FILE_SYSTEM) diff --git a/WebKit/chromium/src/WorkerFileWriterCallbacksBridge.h b/WebKit/chromium/src/WorkerFileWriterCallbacksBridge.h new file mode 100644 index 0000000..d2e416e --- /dev/null +++ b/WebKit/chromium/src/WorkerFileWriterCallbacksBridge.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WorkerFileWriterCallbacksBridge_h +#define WorkerFileWriterCallbacksBridge_h + +#if ENABLE(FILE_SYSTEM) + +#include "WebFileError.h" +#include "WebFileWriterClient.h" +#include "WorkerContext.h" +#include <wtf/PassOwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/ThreadSafeShared.h> + +namespace WebCore { + class AsyncFileWriterClient; + class KURL; + class WorkerLoaderProxy; +} + +namespace WTF { + class String; +} +using WTF::String; + +namespace WebKit { + +class WebFileSystem; +class WebFileWriter; +class WebFileWriterClient; +class WebWorkerBase; + +// This class is used as a mechanism to bridge calls between threads. +// Calls to a WebFileWriter must happen on the main thread, but they come from +// the context thread. The responses through the WebFileWriterClient interface +// start on the main thread, but must be sent via the worker context thread. +// +// A typical flow for write would look like this: +// Bridge::postWriteToMainThread() on WorkerThread +// --> Bridge::writeOnMainThread() is called on MainThread +// --> WebFileWriter::write() +// This makes an IPC; the actual operation is down in the browser. +// --> Bridge::didWrite is called on MainThread +// --> Bridge::didWriteOnWorkerThread is called on WorkerThread +// This calls the original client (m_clientOnWorkerThread). +// +// The bridge object is refcounted, so that it doesn't get deleted while there +// are cross-thread calls in flight. Each CrossThreadTask carries a reference +// to the bridge, which guarantees that the bridge will still be valid when the +// task is executed. In order to shut down the bridge, the WebFileWriterClient +// should call postShutdownToMainThread before dropping its reference to the +// bridge. This ensures that the WebFileWriter will be cleared on the main +// thread and that no further calls to the WebFileWriterClient will be made. +class WorkerFileWriterCallbacksBridge : public ThreadSafeShared<WorkerFileWriterCallbacksBridge>, public WebCore::WorkerContext::Observer, public WebFileWriterClient { +public: + ~WorkerFileWriterCallbacksBridge(); + + // WorkerContext::Observer method. + virtual void notifyStop(); + + static PassRefPtr<WorkerFileWriterCallbacksBridge> create(const String& path, WebCore::WorkerLoaderProxy* proxy, WebCore::ScriptExecutionContext* workerContext, WebCore::AsyncFileWriterClient* client) + { + return adoptRef(new WorkerFileWriterCallbacksBridge(path, proxy, workerContext, client)); + } + + // Methods that create an instance and post an initial request task to the main thread. They must be called on the worker thread. + void postWriteToMainThread(long long position, const WebCore::KURL& data); + void postTruncateToMainThread(long long length); + void postAbortToMainThread(); + + // The owning WorkerAsyncFileWriterChromium should call this method before dropping its last reference to the bridge, on the context thread. + // The actual deletion of the WorkerFileWriterCallbacksBridge may happen on either the main or context thread, depending on where the last reference goes away; that's safe as long as this is called first. + void postShutdownToMainThread(PassRefPtr<WorkerFileWriterCallbacksBridge>); + + // Callback methods that are called on the main thread. + // These are the implementation of WebKit::WebFileWriterClient. + void didWrite(long long bytes, bool complete); + void didFail(WebFileError); + void didTruncate(); + +private: + WorkerFileWriterCallbacksBridge(const String& path, WebCore::WorkerLoaderProxy*, WebCore::ScriptExecutionContext*, WebCore::AsyncFileWriterClient*); + + void postInitToMainThread(const String& path); + + // Methods that are to be called on the main thread. + static void writeOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, long long position, const WebCore::KURL& data); + static void truncateOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, long long length); + static void abortOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>); + static void initOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, const String& path); + static void shutdownOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>); + + // Methods that dispatch to AsyncFileWriterClient on the worker threads. + static void didWriteOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, long long length, bool complete); + static void didFailOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, WebFileError); + static void didTruncateOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>); + + // Called on the main thread to run the supplied task. + static void runTaskOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, PassOwnPtr<WebCore::ScriptExecutionContext::Task>); + // Called on the worker thread to run the supplied task. + static void runTaskOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerFileWriterCallbacksBridge>, PassOwnPtr<WebCore::ScriptExecutionContext::Task>); + + // Called on the worker thread to dispatch to the main thread. + void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>); + // Called on the main thread to dispatch to the worker thread. + void dispatchTaskToWorkerThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>); + + // Used from the main thread to post tasks to the context thread. + WebCore::WorkerLoaderProxy* m_proxy; + + // Used on the context thread, only to check that we're running on the context thread. + WebCore::ScriptExecutionContext* m_workerContext; + + // Created and destroyed from the main thread. + OwnPtr<WebKit::WebFileWriter> m_writer; + + // Used on the context thread to call back into the client. + WebCore::AsyncFileWriterClient* m_clientOnWorkerThread; + + // Used to indicate that shutdown has started on the main thread, and hence the writer has been deleted. + bool m_writerDeleted; +}; + +} // namespace WebCore + +#endif + +#endif // WorkerFileWriterCallbacksBridge_h diff --git a/WebKit/chromium/src/mac/WebInputEventFactory.mm b/WebKit/chromium/src/mac/WebInputEventFactory.mm index 015409e..55883c9 100644 --- a/WebKit/chromium/src/mac/WebInputEventFactory.mm +++ b/WebKit/chromium/src/mac/WebInputEventFactory.mm @@ -1016,14 +1016,17 @@ WebMouseEvent WebInputEventFactory::mouseEvent(NSEvent* event, NSView* view) break; case NSLeftMouseUp: result.type = WebInputEvent::MouseUp; + result.clickCount = [event clickCount]; result.button = WebMouseEvent::ButtonLeft; break; case NSOtherMouseUp: result.type = WebInputEvent::MouseUp; + result.clickCount = [event clickCount]; result.button = WebMouseEvent::ButtonMiddle; break; case NSRightMouseUp: result.type = WebInputEvent::MouseUp; + result.clickCount = [event clickCount]; result.button = WebMouseEvent::ButtonRight; break; case NSMouseMoved: |