diff options
Diffstat (limited to 'WebKit/chromium/src')
184 files changed, 12693 insertions, 7043 deletions
diff --git a/WebKit/chromium/src/ApplicationCacheHost.cpp b/WebKit/chromium/src/ApplicationCacheHost.cpp index 5fa4a66..dfd4754 100644 --- a/WebKit/chromium/src/ApplicationCacheHost.cpp +++ b/WebKit/chromium/src/ApplicationCacheHost.cpp @@ -37,10 +37,15 @@ #include "DocumentLoader.h" #include "DOMApplicationCache.h" #include "Frame.h" +#include "InspectorApplicationCacheAgent.h" +#include "InspectorController.h" +#include "Page.h" +#include "ProgressEvent.h" #include "Settings.h" #include "WebURL.h" #include "WebURLError.h" #include "WebURLResponse.h" +#include "WebVector.h" #include "WrappedResourceRequest.h" #include "WrappedResourceResponse.h" @@ -195,34 +200,68 @@ void ApplicationCacheHost::setDOMApplicationCache(DOMApplicationCache* domApplic m_domApplicationCache = domApplicationCache; } -void ApplicationCacheHost::notifyDOMApplicationCache(EventID id) +void ApplicationCacheHost::notifyDOMApplicationCache(EventID id, int total, int done) { if (m_defersEvents) { - m_deferredEvents.append(id); + // Event dispatching is deferred until document.onload has fired. + m_deferredEvents.append(DeferredEvent(id, total, done)); return; } - if (m_domApplicationCache) { - ExceptionCode ec = 0; - m_domApplicationCache->dispatchEvent(Event::create(DOMApplicationCache::toEventType(id), false, false), ec); - ASSERT(!ec); + dispatchDOMEvent(id, total, done); +} + +#if ENABLE(INSPECTOR) +ApplicationCacheHost::CacheInfo ApplicationCacheHost::applicationCacheInfo() +{ + if (!m_internal) + return CacheInfo(KURL(), 0, 0, 0); + + WebKit::WebApplicationCacheHost::CacheInfo webInfo; + m_internal->m_outerHost->getAssociatedCacheInfo(&webInfo); + return CacheInfo(webInfo.manifestURL, webInfo.creationTime, webInfo.updateTime, webInfo.totalSize); +} + +void ApplicationCacheHost::fillResourceList(ResourceInfoList* resources) +{ + if (!m_internal) + return; + + WebKit::WebVector<WebKit::WebApplicationCacheHost::ResourceInfo> webResources; + m_internal->m_outerHost->getResourceList(&webResources); + for (size_t i = 0; i < webResources.size(); ++i) { + resources->append(ResourceInfo( + webResources[i].url, webResources[i].isMaster, webResources[i].isManifest, webResources[i].isFallback, + webResources[i].isForeign, webResources[i].isExplicit, webResources[i].size)); } } +#endif void ApplicationCacheHost::stopDeferringEvents() { RefPtr<DocumentLoader> protect(documentLoader()); for (unsigned i = 0; i < m_deferredEvents.size(); ++i) { - EventID id = m_deferredEvents[i]; - if (m_domApplicationCache) { - ExceptionCode ec = 0; - m_domApplicationCache->dispatchEvent(Event::create(DOMApplicationCache::toEventType(id), false, false), ec); - ASSERT(!ec); - } + const DeferredEvent& deferred = m_deferredEvents[i]; + dispatchDOMEvent(deferred.eventID, deferred.progressTotal, deferred.progressDone); } m_deferredEvents.clear(); m_defersEvents = false; } +void ApplicationCacheHost::dispatchDOMEvent(EventID id, int total, int done) +{ + if (m_domApplicationCache) { + const AtomicString& eventType = DOMApplicationCache::toEventType(id); + ExceptionCode ec = 0; + RefPtr<Event> event; + if (id == PROGRESS_EVENT) + event = ProgressEvent::create(eventType, true, done, total); + else + event = Event::create(eventType, false, false); + m_domApplicationCache->dispatchEvent(event, ec); + ASSERT(!ec); + } +} + ApplicationCacheHost::Status ApplicationCacheHost::status() const { return m_internal ? static_cast<Status>(m_internal->m_outerHost->status()) : UNCACHED; diff --git a/WebKit/chromium/src/ApplicationCacheHostInternal.h b/WebKit/chromium/src/ApplicationCacheHostInternal.h index 3e52c1b..c88420b 100644 --- a/WebKit/chromium/src/ApplicationCacheHostInternal.h +++ b/WebKit/chromium/src/ApplicationCacheHostInternal.h @@ -33,9 +33,13 @@ #if ENABLE(OFFLINE_WEB_APPLICATIONS) +#include "DocumentLoader.h" #include "WebApplicationCacheHostClient.h" +#include "WebFrameClient.h" +#include "WebFrameImpl.h" #include "WebKit.h" #include "WebKitClient.h" +#include "WebURL.h" namespace WebCore { @@ -44,12 +48,24 @@ public: ApplicationCacheHostInternal(ApplicationCacheHost* host) : m_innerHost(host) { - m_outerHost.set(WebKit::webKitClient()->createApplicationCacheHost(this)); + WebKit::WebFrameImpl* webFrame = WebKit::WebFrameImpl::fromFrame(host->m_documentLoader->frame()); + ASSERT(webFrame); + m_outerHost.set(webFrame->client()->createApplicationCacheHost(webFrame, this)); + } + + virtual void didChangeCacheAssociation() + { + // FIXME: Prod the inspector to update it's notion of what cache the page is using. } virtual void notifyEventListener(WebKit::WebApplicationCacheHost::EventID eventID) { - m_innerHost->notifyDOMApplicationCache(static_cast<ApplicationCacheHost::EventID>(eventID)); + m_innerHost->notifyDOMApplicationCache(static_cast<ApplicationCacheHost::EventID>(eventID), 0, 0); + } + + virtual void notifyProgressEventListener(const WebKit::WebURL&, int progressTotal, int progressDone) + { + m_innerHost->notifyDOMApplicationCache(ApplicationCacheHost::PROGRESS_EVENT, progressTotal, progressDone); } static WebKit::WebApplicationCacheHost* toWebApplicationCacheHost(ApplicationCacheHost* innerHost) diff --git a/WebKit/chromium/src/AssertMatchingEnums.cpp b/WebKit/chromium/src/AssertMatchingEnums.cpp index 1d2948f..093ac11 100644 --- a/WebKit/chromium/src/AssertMatchingEnums.cpp +++ b/WebKit/chromium/src/AssertMatchingEnums.cpp @@ -36,23 +36,34 @@ #include "AccessibilityObject.h" #include "ApplicationCacheHost.h" #include "EditorInsertAction.h" +#include "FontDescription.h" +#include "FontSmoothingMode.h" #include "HTMLInputElement.h" +#include "IDBKey.h" #include "MediaPlayer.h" #include "NotificationPresenter.h" #include "PasteboardPrivate.h" #include "PlatformCursor.h" +#include "Settings.h" #include "StringImpl.h" #include "TextAffinity.h" +#include "UserContentTypes.h" +#include "UserScriptTypes.h" #include "WebAccessibilityObject.h" #include "WebApplicationCacheHost.h" #include "WebClipboard.h" #include "WebCursorInfo.h" #include "WebEditingAction.h" +#include "WebFontDescription.h" +#include "WebIDBKey.h" #include "WebInputElement.h" #include "WebMediaPlayer.h" #include "WebNotificationPresenter.h" +#include "WebScrollbar.h" +#include "WebSettings.h" #include "WebTextAffinity.h" #include "WebTextCaseSensitivity.h" +#include "WebView.h" #include <wtf/Assertions.h> #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, webcore_name) \ @@ -124,6 +135,7 @@ COMPILE_ASSERT_MATCHING_ENUM(WebAccessibilityRoleDefinitionListDefinition, Defin COMPILE_ASSERT_MATCHING_ENUM(WebAccessibilityRoleAnnotation, AnnotationRole); COMPILE_ASSERT_MATCHING_ENUM(WebAccessibilityRoleSliderThumb, SliderThumbRole); COMPILE_ASSERT_MATCHING_ENUM(WebAccessibilityRoleIgnored, IgnoredRole); +COMPILE_ASSERT_MATCHING_ENUM(WebAccessibilityRolePresentational, PresentationalRole); COMPILE_ASSERT_MATCHING_ENUM(WebAccessibilityRoleTab, TabRole); COMPILE_ASSERT_MATCHING_ENUM(WebAccessibilityRoleTabList, TabListRole); COMPILE_ASSERT_MATCHING_ENUM(WebAccessibilityRoleTabPanel, TabPanelRole); @@ -177,6 +189,7 @@ COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::FormatSmartPaste, PasteboardPrivate:: COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::BufferStandard, PasteboardPrivate::StandardBuffer); COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::BufferSelection, PasteboardPrivate::SelectionBuffer); +COMPILE_ASSERT_MATCHING_ENUM(WebClipboard::BufferDrag, PasteboardPrivate::DragBuffer); COMPILE_ASSERT_MATCHING_ENUM(WebCursorInfo::TypePointer, PlatformCursor::TypePointer); COMPILE_ASSERT_MATCHING_ENUM(WebCursorInfo::TypeCross, PlatformCursor::TypeCross); @@ -225,6 +238,31 @@ COMPILE_ASSERT_MATCHING_ENUM(WebEditingActionTyped, EditorInsertActionTyped); COMPILE_ASSERT_MATCHING_ENUM(WebEditingActionPasted, EditorInsertActionPasted); COMPILE_ASSERT_MATCHING_ENUM(WebEditingActionDropped, EditorInsertActionDropped); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::GenericFamilyNone, FontDescription::NoFamily); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::GenericFamilyStandard, FontDescription::StandardFamily); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::GenericFamilySerif, FontDescription::SerifFamily); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::GenericFamilySansSerif, FontDescription::SansSerifFamily); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::GenericFamilyMonospace, FontDescription::MonospaceFamily); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::GenericFamilyCursive, FontDescription::CursiveFamily); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::GenericFamilyFantasy, FontDescription::FantasyFamily); + +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::SmoothingAuto, AutoSmoothing); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::SmoothingNone, NoSmoothing); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::SmoothingGrayscale, Antialiased); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::SmoothingSubpixel, SubpixelAntialiased); + +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight100, FontWeight100); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight200, FontWeight200); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight300, FontWeight300); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight400, FontWeight400); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight500, FontWeight500); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight600, FontWeight600); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight700, FontWeight700); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight800, FontWeight800); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::Weight900, FontWeight900); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::WeightNormal, FontWeightNormal); +COMPILE_ASSERT_MATCHING_ENUM(WebFontDescription::WeightBold, FontWeightBold); + COMPILE_ASSERT_MATCHING_ENUM(WebInputElement::Text, HTMLInputElement::TEXT); COMPILE_ASSERT_MATCHING_ENUM(WebInputElement::Password, HTMLInputElement::PASSWORD); COMPILE_ASSERT_MATCHING_ENUM(WebInputElement::IsIndex, HTMLInputElement::ISINDEX); @@ -291,8 +329,30 @@ COMPILE_ASSERT_MATCHING_ENUM(WebNotificationPresenter::PermissionNotAllowed, Not COMPILE_ASSERT_MATCHING_ENUM(WebNotificationPresenter::PermissionDenied, NotificationPresenter::PermissionDenied); #endif +COMPILE_ASSERT_MATCHING_ENUM(WebScrollbar::Horizontal, HorizontalScrollbar); +COMPILE_ASSERT_MATCHING_ENUM(WebScrollbar::Vertical, VerticalScrollbar); + +COMPILE_ASSERT_MATCHING_ENUM(WebScrollbar::ScrollByLine, ScrollByLine); +COMPILE_ASSERT_MATCHING_ENUM(WebScrollbar::ScrollByPage, ScrollByPage); +COMPILE_ASSERT_MATCHING_ENUM(WebScrollbar::ScrollByDocument, ScrollByDocument); +COMPILE_ASSERT_MATCHING_ENUM(WebScrollbar::ScrollByPixel, ScrollByPixel); + +COMPILE_ASSERT_MATCHING_ENUM(WebSettings::EditingBehaviorMac, EditingMacBehavior); +COMPILE_ASSERT_MATCHING_ENUM(WebSettings::EditingBehaviorWin, EditingWindowsBehavior); + COMPILE_ASSERT_MATCHING_ENUM(WebTextAffinityUpstream, UPSTREAM); COMPILE_ASSERT_MATCHING_ENUM(WebTextAffinityDownstream, DOWNSTREAM); COMPILE_ASSERT_MATCHING_ENUM(WebTextCaseSensitive, TextCaseSensitive); COMPILE_ASSERT_MATCHING_ENUM(WebTextCaseInsensitive, TextCaseInsensitive); + +COMPILE_ASSERT_MATCHING_ENUM(WebView::UserScriptInjectAtDocumentStart, InjectAtDocumentStart); +COMPILE_ASSERT_MATCHING_ENUM(WebView::UserScriptInjectAtDocumentEnd, InjectAtDocumentEnd); +COMPILE_ASSERT_MATCHING_ENUM(WebView::UserContentInjectInAllFrames, InjectInAllFrames); +COMPILE_ASSERT_MATCHING_ENUM(WebView::UserContentInjectInTopFrameOnly, InjectInTopFrameOnly); + +COMPILE_ASSERT_MATCHING_ENUM(WebIDBKey::NullType, IDBKey::NullType); +COMPILE_ASSERT_MATCHING_ENUM(WebIDBKey::StringType, IDBKey::StringType); +COMPILE_ASSERT_MATCHING_ENUM(WebIDBKey::NumberType, IDBKey::NumberType); + + diff --git a/WebKit/chromium/src/AutoFillPopupMenuClient.cpp b/WebKit/chromium/src/AutoFillPopupMenuClient.cpp index 8e6cab4..b14840c 100644 --- a/WebKit/chromium/src/AutoFillPopupMenuClient.cpp +++ b/WebKit/chromium/src/AutoFillPopupMenuClient.cpp @@ -31,65 +31,335 @@ #include "config.h" #include "AutoFillPopupMenuClient.h" +#include "CSSStyleSelector.h" +#include "CSSValueKeywords.h" +#include "Chrome.h" +#include "FrameView.h" #include "HTMLInputElement.h" +#include "RenderTheme.h" +#include "WebNode.h" #include "WebString.h" #include "WebVector.h" +#include "WebViewClient.h" +#include "WebViewImpl.h" using namespace WebCore; namespace WebKit { +AutoFillPopupMenuClient::AutoFillPopupMenuClient() + : m_separatorIndex(-1) + , m_selectedIndex(-1) + , m_textField(0) + , m_AutocompleteModeEnabled(false) +{ +} + +AutoFillPopupMenuClient::~AutoFillPopupMenuClient() +{ +} + unsigned AutoFillPopupMenuClient::getSuggestionsCount() const { - return m_names.size(); + return m_names.size() + ((m_separatorIndex == -1) ? 0 : 1); } WebString AutoFillPopupMenuClient::getSuggestion(unsigned listIndex) const { - // FIXME: Modify the PopupMenu to add the label in gray right-justified. - ASSERT(listIndex >= 0 && listIndex < m_names.size()); - return m_names[listIndex] + String(" (") + m_labels[listIndex] + String(")"); + int index = convertListIndexToInternalIndex(listIndex); + if (index == -1) + return WebString(); + + ASSERT(index >= 0 && static_cast<size_t>(index) < m_names.size()); + return m_names[index]; +} + +WebString AutoFillPopupMenuClient::getLabel(unsigned listIndex) const +{ + int index = convertListIndexToInternalIndex(listIndex); + if (index == -1) + return WebString(); + + ASSERT(index >= 0 && static_cast<size_t>(index) < m_labels.size()); + return m_labels[index]; +} + +WebString AutoFillPopupMenuClient::getIcon(unsigned listIndex) const +{ + int index = convertListIndexToInternalIndex(listIndex); + if (index == -1) + return WebString(); + + ASSERT(index >= 0 && static_cast<size_t>(index) < m_icons.size()); + return m_icons[index]; } void AutoFillPopupMenuClient::removeSuggestionAtIndex(unsigned listIndex) { - // FIXME: Do we want to remove AutoFill suggestions? - ASSERT(listIndex >= 0 && listIndex < m_names.size()); - m_names.remove(listIndex); - m_labels.remove(listIndex); + if (!canRemoveSuggestionAtIndex(listIndex)) + return; + + int index = convertListIndexToInternalIndex(listIndex); + + ASSERT(static_cast<unsigned>(index) < m_names.size()); + + m_names.remove(index); + m_labels.remove(index); + m_icons.remove(index); + m_uniqueIDs.remove(index); + + // Shift the separator index if necessary. + if (m_separatorIndex != -1) + m_separatorIndex--; +} + +bool AutoFillPopupMenuClient::canRemoveSuggestionAtIndex(unsigned listIndex) +{ + // Only allow deletion of items before the separator and those that don't + // have a label (autocomplete). + int index = convertListIndexToInternalIndex(listIndex); + return m_labels[index].isEmpty() && (m_separatorIndex == -1 || listIndex < static_cast<unsigned>(m_separatorIndex)); +} + +void AutoFillPopupMenuClient::valueChanged(unsigned listIndex, bool fireEvents) +{ + // DEPRECATED: Will be removed once AutoFill and Autocomplete merge is + // completed. + if (m_AutocompleteModeEnabled) { + m_textField->setValue(getSuggestion(listIndex)); + + WebViewImpl* webView = getWebView(); + if (!webView) + return; + + EditorClientImpl* editor = + static_cast<EditorClientImpl*>(webView->page()->editorClient()); + ASSERT(editor); + editor->onAutocompleteSuggestionAccepted( + static_cast<HTMLInputElement*>(m_textField.get())); + } else { + WebViewImpl* webView = getWebView(); + if (!webView) + return; + + if (m_separatorIndex != -1 && listIndex > static_cast<unsigned>(m_separatorIndex)) + --listIndex; + + ASSERT(listIndex < m_names.size()); + + webView->client()->didAcceptAutoFillSuggestion(WebNode(getTextField()), + m_names[listIndex], + m_labels[listIndex], + m_uniqueIDs[listIndex], + listIndex); + } +} + +void AutoFillPopupMenuClient::selectionChanged(unsigned listIndex, bool fireEvents) +{ + WebViewImpl* webView = getWebView(); + if (!webView) + return; + + if (m_separatorIndex != -1 && listIndex > static_cast<unsigned>(m_separatorIndex)) + --listIndex; + + ASSERT(listIndex < m_names.size()); + + webView->client()->didSelectAutoFillSuggestion(WebNode(getTextField()), + m_names[listIndex], + m_labels[listIndex], + m_uniqueIDs[listIndex]); +} + +void AutoFillPopupMenuClient::selectionCleared() +{ + WebViewImpl* webView = getWebView(); + if (webView) + webView->client()->didClearAutoFillSelection(WebNode(getTextField())); +} + +String AutoFillPopupMenuClient::itemText(unsigned listIndex) const +{ + return getSuggestion(listIndex); +} + +String AutoFillPopupMenuClient::itemLabel(unsigned listIndex) const +{ + return getLabel(listIndex); +} + +String AutoFillPopupMenuClient::itemIcon(unsigned listIndex) const +{ + return getIcon(listIndex); +} + +PopupMenuStyle AutoFillPopupMenuClient::itemStyle(unsigned listIndex) const +{ + return *m_style; +} + +PopupMenuStyle AutoFillPopupMenuClient::menuStyle() const +{ + return *m_style; +} + +int AutoFillPopupMenuClient::clientPaddingLeft() const +{ + // Bug http://crbug.com/7708 seems to indicate the style can be 0. + RenderStyle* style = textFieldStyle(); + if (!style) + return 0; + + return RenderTheme::defaultTheme()->popupInternalPaddingLeft(style); +} + +int AutoFillPopupMenuClient::clientPaddingRight() const +{ + // Bug http://crbug.com/7708 seems to indicate the style can be 0. + RenderStyle* style = textFieldStyle(); + if (!style) + return 0; + + return RenderTheme::defaultTheme()->popupInternalPaddingRight(style); +} + +void AutoFillPopupMenuClient::popupDidHide() +{ + WebViewImpl* webView = getWebView(); + if (!webView) + return; + + webView->autoFillPopupDidHide(); + webView->client()->didClearAutoFillSelection(WebNode(getTextField())); +} + +bool AutoFillPopupMenuClient::itemIsSeparator(unsigned listIndex) const +{ + return (m_separatorIndex != -1 && static_cast<unsigned>(m_separatorIndex) == listIndex); +} + +void AutoFillPopupMenuClient::setTextFromItem(unsigned listIndex) +{ + m_textField->setValue(getSuggestion(listIndex)); +} + +FontSelector* AutoFillPopupMenuClient::fontSelector() const +{ + return m_textField->document()->styleSelector()->fontSelector(); +} + +HostWindow* AutoFillPopupMenuClient::hostWindow() const +{ + return m_textField->document()->view()->hostWindow(); +} + +PassRefPtr<Scrollbar> AutoFillPopupMenuClient::createScrollbar( + ScrollbarClient* client, + ScrollbarOrientation orientation, + ScrollbarControlSize size) +{ + return Scrollbar::createNativeScrollbar(client, orientation, size); } void AutoFillPopupMenuClient::initialize( HTMLInputElement* textField, const WebVector<WebString>& names, const WebVector<WebString>& labels, - int defaultSuggestionIndex) + const WebVector<WebString>& icons, + const WebVector<int>& uniqueIDs, + int separatorIndex) { ASSERT(names.size() == labels.size()); - ASSERT(defaultSuggestionIndex < static_cast<int>(names.size())); + ASSERT(names.size() == icons.size()); + ASSERT(names.size() == uniqueIDs.size()); + ASSERT(separatorIndex < static_cast<int>(names.size())); + + m_selectedIndex = -1; + m_textField = textField; // The suggestions must be set before initializing the - // SuggestionsPopupMenuClient. - setSuggestions(names, labels); + // AutoFillPopupMenuClient. + setSuggestions(names, labels, icons, uniqueIDs, separatorIndex); - SuggestionsPopupMenuClient::initialize(textField, defaultSuggestionIndex); + FontDescription fontDescription; + RenderTheme::defaultTheme()->systemFont(CSSValueWebkitControl, + fontDescription); + RenderStyle* style = m_textField->computedStyle(); + fontDescription.setComputedSize(style->fontDescription().computedSize()); + + Font font(fontDescription, 0, 0); + font.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())); } void AutoFillPopupMenuClient::setSuggestions(const WebVector<WebString>& names, - const WebVector<WebString>& labels) + const WebVector<WebString>& labels, + const WebVector<WebString>& icons, + const WebVector<int>& uniqueIDs, + int separatorIndex) { ASSERT(names.size() == labels.size()); + ASSERT(names.size() == icons.size()); + ASSERT(names.size() == uniqueIDs.size()); + ASSERT(separatorIndex < static_cast<int>(names.size())); m_names.clear(); m_labels.clear(); + m_icons.clear(); + m_uniqueIDs.clear(); for (size_t i = 0; i < names.size(); ++i) { m_names.append(names[i]); m_labels.append(labels[i]); + m_icons.append(icons[i]); + m_uniqueIDs.append(uniqueIDs[i]); } + m_separatorIndex = separatorIndex; + // Try to preserve selection if possible. if (getSelectedIndex() >= static_cast<int>(names.size())) setSelectedIndex(-1); } +int AutoFillPopupMenuClient::convertListIndexToInternalIndex(unsigned listIndex) const +{ + if (listIndex == static_cast<unsigned>(m_separatorIndex)) + return -1; + + if (m_separatorIndex == -1 || listIndex < static_cast<unsigned>(m_separatorIndex)) + return listIndex; + return listIndex - 1; +} + +WebViewImpl* AutoFillPopupMenuClient::getWebView() const +{ + Frame* frame = m_textField->document()->frame(); + if (!frame) + return 0; + + Page* page = frame->page(); + if (!page) + return 0; + + return static_cast<ChromeClientImpl*>(page->chrome()->client())->webView(); +} + +RenderStyle* AutoFillPopupMenuClient::textFieldStyle() const +{ + RenderStyle* style = m_textField->computedStyle(); + if (!style) { + // It seems we can only have a 0 style in a TextField if the + // node is detached, in which case we the popup should not be + // showing. Please report this in http://crbug.com/7708 and + // include the page you were visiting. + ASSERT_NOT_REACHED(); + } + return style; +} + } // namespace WebKit diff --git a/WebKit/chromium/src/AutoFillPopupMenuClient.h b/WebKit/chromium/src/AutoFillPopupMenuClient.h index 1912fa3..223cf16 100644 --- a/WebKit/chromium/src/AutoFillPopupMenuClient.h +++ b/WebKit/chromium/src/AutoFillPopupMenuClient.h @@ -31,36 +31,123 @@ #ifndef AutoFillPopupMenuClient_h #define AutoFillPopupMenuClient_h -#include "SuggestionsPopupMenuClient.h" +#include "PopupMenuClient.h" namespace WebCore { class HTMLInputElement; +class PopupMenuStyle; +class RenderStyle; } namespace WebKit { class WebString; +class WebViewImpl; template <typename T> class WebVector; // The AutoFill suggestions popup menu client, used to display name suggestions // with right-justified labels. -class AutoFillPopupMenuClient : public SuggestionsPopupMenuClient { +class AutoFillPopupMenuClient : public WebCore::PopupMenuClient { public: - // SuggestionsPopupMenuClient implementation: + AutoFillPopupMenuClient(); + virtual ~AutoFillPopupMenuClient(); + + // Returns the number of suggestions available. virtual unsigned getSuggestionsCount() const; + + // Returns the suggestion at |listIndex|. virtual WebString getSuggestion(unsigned listIndex) const; + + // Returns the label at |listIndex|. + virtual WebString getLabel(unsigned listIndex) const; + + // Returns the icon at |listIndex|. + virtual WebString getIcon(unsigned listIndex) const; + + // Removes the suggestion at |listIndex| from the list of suggestions. virtual void removeSuggestionAtIndex(unsigned listIndex); + // Returns true if the suggestion at |listIndex| can be removed. + bool canRemoveSuggestionAtIndex(unsigned listIndex); + + // WebCore::PopupMenuClient methods: + virtual void valueChanged(unsigned listIndex, bool fireEvents = true); + virtual void selectionChanged(unsigned, bool); + virtual void selectionCleared(); + virtual WebCore::String itemText(unsigned listIndex) const; + virtual WebCore::String itemLabel(unsigned listIndex) const; + virtual WebCore::String itemIcon(unsigned listIndex) const; + virtual WebCore::String itemToolTip(unsigned lastIndex) const { return WebCore::String(); } + virtual WebCore::String itemAccessibilityText(unsigned lastIndex) const { return WebCore::String(); } + virtual bool itemIsEnabled(unsigned listIndex) const { return true; } + virtual WebCore::PopupMenuStyle itemStyle(unsigned listIndex) const; + virtual WebCore::PopupMenuStyle menuStyle() const; + virtual int clientInsetLeft() const { return 0; } + virtual int clientInsetRight() const { return 0; } + virtual int clientPaddingLeft() const; + virtual int clientPaddingRight() const; + virtual int listSize() const { return getSuggestionsCount(); } + virtual int selectedIndex() const { return m_selectedIndex; } + virtual void popupDidHide(); + virtual bool itemIsSeparator(unsigned listIndex) const; + virtual bool itemIsLabel(unsigned listIndex) const { return false; } + virtual bool itemIsSelected(unsigned listIndex) const { return false; } + virtual bool shouldPopOver() const { return false; } + virtual bool valueShouldChangeOnHotTrack() const { return false; } + virtual void setTextFromItem(unsigned listIndex); + virtual WebCore::FontSelector* fontSelector() const; + virtual WebCore::HostWindow* hostWindow() const; + virtual PassRefPtr<WebCore::Scrollbar> createScrollbar( + WebCore::ScrollbarClient* client, + WebCore::ScrollbarOrientation orientation, + WebCore::ScrollbarControlSize size); + void initialize(WebCore::HTMLInputElement*, const WebVector<WebString>& names, const WebVector<WebString>& labels, - int defaultSuggestionIndex); + const WebVector<WebString>& icons, + const WebVector<int>& uniqueIDs, + int separatorIndex); void setSuggestions(const WebVector<WebString>& names, - const WebVector<WebString>& labels); + const WebVector<WebString>& labels, + const WebVector<WebString>& icons, + const WebVector<int>& uniqueIDs, + int separatorIndex); + + // DEPRECATED: Will be removed once Autocomplete and AutoFill merge is + // complete. + void setAutocompleteMode(bool enabled) { m_AutocompleteModeEnabled = enabled; } private: + // Convert the specified index from an index into the visible list (which might + // include a separator entry) to an index to |m_names| and |m_labels|. + // Returns -1 if the given index points to the separator. + int convertListIndexToInternalIndex(unsigned) const; + WebViewImpl* getWebView() const; + WebCore::HTMLInputElement* getTextField() const { return m_textField.get(); } + WebCore::RenderStyle* textFieldStyle() const; + + int getSelectedIndex() const { return m_selectedIndex; } + void setSelectedIndex(int index) { m_selectedIndex = index; } + + // The names, labels and icons that make up the contents of the menu items. Vector<WebCore::String> m_names; Vector<WebCore::String> m_labels; + Vector<WebCore::String> m_icons; + Vector<int> m_uniqueIDs; + + // The index of the separator. -1 if there is no separator. + int m_separatorIndex; + + // The index of the selected item. -1 if there is no selected item. + int m_selectedIndex; + + RefPtr<WebCore::HTMLInputElement> m_textField; + OwnPtr<WebCore::PopupMenuStyle> m_style; + + // DEPRECATED: Will be removed once Autocomplete and AutoFill merge is + // complete. + bool m_AutocompleteModeEnabled; }; } // namespace WebKit diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp b/WebKit/chromium/src/ChromeClientImpl.cpp index ce2f00c..d43d88a 100644 --- a/WebKit/chromium/src/ChromeClientImpl.cpp +++ b/WebKit/chromium/src/ChromeClientImpl.cpp @@ -31,8 +31,8 @@ #include "config.h" #include "ChromeClientImpl.h" -#include "AccessibilityObject.h" #include "AXObjectCache.h" +#include "AccessibilityObject.h" #include "CharacterNames.h" #include "Console.h" #include "Cursor.h" @@ -43,6 +43,12 @@ #include "FloatRect.h" #include "FrameLoadRequest.h" #include "FrameView.h" +#include "GLES2Context.h" +#include "Geolocation.h" +#include "GeolocationService.h" +#include "GeolocationServiceChromium.h" +#include "GraphicsLayer.h" +#include "HTMLNames.h" #include "HitTestResult.h" #include "IntRect.h" #include "Node.h" @@ -50,6 +56,7 @@ #include "Page.h" #include "PopupMenuChromium.h" #include "ScriptController.h" +#include "WebGeolocationService.h" #if USE(V8) #include "V8Proxy.h" #endif @@ -61,13 +68,16 @@ #include "WebFrameImpl.h" #include "WebInputEvent.h" #include "WebKit.h" +#include "WebNode.h" #include "WebPopupMenuImpl.h" #include "WebPopupMenuInfo.h" +#include "WebPopupType.h" #include "WebRect.h" #include "WebTextDirection.h" #include "WebURLRequest.h" #include "WebViewClient.h" #include "WebViewImpl.h" +#include "WebWindowFeatures.h" #include "WindowFeatures.h" #include "WrappedResourceRequest.h" @@ -75,6 +85,20 @@ using namespace WebCore; namespace WebKit { +// Converts a WebCore::PopupContainerType to a WebKit::WebPopupType. +static WebPopupType convertPopupType(PopupContainer::PopupType type) +{ + switch (type) { + case PopupContainer::Select: + return WebPopupTypeSelect; + case PopupContainer::Suggestion: + return WebPopupTypeSuggestion; + default: + ASSERT_NOT_REACHED(); + return WebPopupTypeNone; + } +} + ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView) : m_webView(webView) , m_toolbarsVisible(true) @@ -82,7 +106,6 @@ ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView) , m_scrollbarsVisible(true) , m_menubarVisible(true) , m_resizable(true) - , m_ignoreNextSetCursor(false) { } @@ -138,35 +161,8 @@ float ChromeClientImpl::scaleFactor() void ChromeClientImpl::focus() { - if (!m_webView->client()) - return; - - m_webView->client()->didFocus(); - - // If accessibility is enabled, we should notify assistive technology that - // the active AccessibilityObject changed. - const Frame* frame = m_webView->focusedWebCoreFrame(); - if (!frame) - return; - - Document* doc = frame->document(); - - if (doc && doc->axObjectCache()->accessibilityEnabled()) { - Node* focusedNode = m_webView->focusedWebCoreNode(); - - if (!focusedNode) { - // Could not retrieve focused Node. - return; - } - - // Retrieve the focused AccessibilityObject. - AccessibilityObject* focusedAccObj = - doc->axObjectCache()->getOrCreate(focusedNode->renderer()); - - // Alert assistive technology that focus changed. - if (focusedAccObj) - m_webView->client()->focusAccessibilityObject(WebAccessibilityObject(focusedAccObj)); - } + if (m_webView->client()) + m_webView->client()->didFocus(); } void ChromeClientImpl::unfocus() @@ -194,17 +190,39 @@ void ChromeClientImpl::takeFocus(FocusDirection direction) void ChromeClientImpl::focusedNodeChanged(Node* node) { - WebURL focus_url; + m_webView->client()->focusedNodeChanged(WebNode(node)); + + WebURL focusURL; if (node && node->isLink()) { // This HitTestResult hack is the easiest way to get a link URL out of a // WebCore::Node. - HitTestResult hit_test(IntPoint(0, 0)); + HitTestResult hitTest(IntPoint(0, 0)); // This cast must be valid because of the isLink() check. - hit_test.setURLElement(reinterpret_cast<Element*>(node)); - if (hit_test.isLiveLink()) - focus_url = hit_test.absoluteLinkURL(); + hitTest.setURLElement(static_cast<Element*>(node)); + if (hitTest.isLiveLink()) + focusURL = hitTest.absoluteLinkURL(); + } + m_webView->client()->setKeyboardFocusURL(focusURL); + + if (!node) + return; + + // If accessibility is enabled, we should notify assistive technology that + // the active AccessibilityObject changed. + Document* document = node->document(); + if (!document) { + ASSERT_NOT_REACHED(); + return; + } + if (document && document->axObjectCache()->accessibilityEnabled()) { + // Retrieve the focused AccessibilityObject. + AccessibilityObject* focusedAccObj = + document->axObjectCache()->getOrCreate(node->renderer()); + + // Alert assistive technology that focus changed. + if (focusedAccObj) + m_webView->client()->focusAccessibilityObject(WebAccessibilityObject(focusedAccObj)); } - m_webView->client()->setKeyboardFocusURL(focus_url); } Page* ChromeClientImpl::createWindow( @@ -214,7 +232,7 @@ Page* ChromeClientImpl::createWindow( return 0; WebViewImpl* newView = static_cast<WebViewImpl*>( - m_webView->client()->createView(WebFrameImpl::fromFrame(frame))); + m_webView->client()->createView(WebFrameImpl::fromFrame(frame), features, r.frameName())); if (!newView) return 0; @@ -323,7 +341,7 @@ void ChromeClientImpl::setScrollbarsVisible(bool value) m_scrollbarsVisible = value; WebFrameImpl* web_frame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); if (web_frame) - web_frame->setAllowsScrolling(value); + web_frame->setCanHaveScrollbars(value); } bool ChromeClientImpl::scrollbarsVisible() @@ -462,21 +480,30 @@ IntRect ChromeClientImpl::windowResizerRect() const return result; } -void ChromeClientImpl::repaint( - const IntRect& paintRect, bool contentChanged, bool immediate, - bool repaintContentOnly) +void ChromeClientImpl::invalidateWindow(const IntRect&, bool) { - // Ignore spurious calls. - if (!contentChanged || paintRect.isEmpty()) + notImplemented(); +} + +void ChromeClientImpl::invalidateContentsAndWindow(const IntRect& updateRect, bool /*immediate*/) +{ + if (updateRect.isEmpty()) return; if (m_webView->client()) - m_webView->client()->didInvalidateRect(paintRect); + m_webView->client()->didInvalidateRect(updateRect); +} + +void ChromeClientImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) +{ + m_webView->hidePopups(); + invalidateContentsAndWindow(updateRect, immediate); } void ChromeClientImpl::scroll( const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect) { + m_webView->hidePopups(); if (m_webView->client()) { int dx = scrollDelta.width(); int dy = scrollDelta.height(); @@ -562,6 +589,11 @@ void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileCh WebFileChooserParams params; params.multiSelect = fileChooser->allowsMultipleFiles(); +#if ENABLE(DIRECTORY_UPLOAD) + params.directory = fileChooser->allowsDirectoryUpload(); +#else + params.directory = false; +#endif params.acceptTypes = fileChooser->acceptTypes(); params.selectedFiles = fileChooser->filenames(); if (params.selectedFiles.size() > 0) @@ -576,9 +608,13 @@ void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileCh chooserCompletion->didChooseFile(WebVector<WebString>()); } +void ChromeClientImpl::chooseIconForFiles(const Vector<WebCore::String>&, WebCore::FileChooser*) +{ + notImplemented(); +} + void ChromeClientImpl::popupOpened(PopupContainer* popupContainer, const IntRect& bounds, - bool activatable, bool handleExternally) { if (!m_webView->client()) @@ -589,19 +625,24 @@ void ChromeClientImpl::popupOpened(PopupContainer* popupContainer, WebPopupMenuInfo popupInfo; getPopupMenuInfo(popupContainer, &popupInfo); webwidget = m_webView->client()->createPopupMenu(popupInfo); - } else - webwidget = m_webView->client()->createPopupMenu(activatable); - + } else { + webwidget = m_webView->client()->createPopupMenu( + convertPopupType(popupContainer->popupType())); + // We only notify when the WebView has to handle the popup, as when + // the popup is handled externally, the fact that a popup is showing is + // transparent to the WebView. + m_webView->popupOpened(popupContainer); + } static_cast<WebPopupMenuImpl*>(webwidget)->Init(popupContainer, bounds); } -void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) +void ChromeClientImpl::popupClosed(WebCore::PopupContainer* popupContainer) { - if (m_ignoreNextSetCursor) { - m_ignoreNextSetCursor = false; - return; - } + m_webView->popupClosed(popupContainer); +} +void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) +{ if (m_webView->client()) m_webView->client()->didChangeCursor(cursor); } @@ -609,11 +650,6 @@ void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor) { setCursor(cursor); - - // Currently, Widget::setCursor is always called after this function in - // EventHandler.cpp and since we don't want that we set a flag indicating - // that the next SetCursor call is to be ignored. - m_ignoreNextSetCursor = true; } void ChromeClientImpl::formStateDidChange(const Node* node) @@ -655,8 +691,10 @@ void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer, } info->itemHeight = popupContainer->menuItemHeight(); + info->itemFontSize = popupContainer->menuItemFontSize(); info->selectedIndex = popupContainer->selectedIndex(); info->items.swap(outputItems); + info->rightAligned = popupContainer->menuStyle().textDirection() == RTL; } void ChromeClientImpl::didChangeAccessibilityObjectState(AccessibilityObject* obj) @@ -666,7 +704,6 @@ void ChromeClientImpl::didChangeAccessibilityObjectState(AccessibilityObject* ob m_webView->client()->didChangeAccessibilityObjectState(WebAccessibilityObject(obj)); } - #if ENABLE(NOTIFICATIONS) NotificationPresenter* ChromeClientImpl::notificationPresenter() const { @@ -674,4 +711,58 @@ NotificationPresenter* ChromeClientImpl::notificationPresenter() const } #endif +void ChromeClientImpl::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation) +{ + GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); + geolocationService->geolocationServiceBridge()->attachBridgeIfNeeded(); + m_webView->client()->geolocationService()->requestPermissionForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); +} + +void ChromeClientImpl::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation* geolocation) +{ + GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); + m_webView->client()->geolocationService()->cancelPermissionRequestForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); +} + +#if USE(ACCELERATED_COMPOSITING) +void ChromeClientImpl::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer) +{ + m_webView->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0); +} + +void ChromeClientImpl::scheduleCompositingLayerSync() +{ + m_webView->setRootLayerNeedsDisplay(); +} + +PassOwnPtr<GLES2Context> ChromeClientImpl::getOnscreenGLES2Context() +{ + return m_webView->getOnscreenGLES2Context(); +} + +PassOwnPtr<GLES2Context> ChromeClientImpl::getOffscreenGLES2Context() +{ + return m_webView->getOffscreenGLES2Context(); +} +#endif + +bool ChromeClientImpl::supportsFullscreenForNode(const WebCore::Node* node) +{ + if (m_webView->client() && node->hasTagName(WebCore::HTMLNames::videoTag)) + return m_webView->client()->supportsFullscreen(); + return false; +} + +void ChromeClientImpl::enterFullscreenForNode(WebCore::Node* node) +{ + if (m_webView->client()) + m_webView->client()->enterFullscreenForNode(WebNode(node)); +} + +void ChromeClientImpl::exitFullscreenForNode(WebCore::Node* node) +{ + if (m_webView->client()) + m_webView->client()->exitFullscreenForNode(WebNode(node)); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/ChromeClientImpl.h b/WebKit/chromium/src/ChromeClientImpl.h index 9e8c2e3..e824381 100644 --- a/WebKit/chromium/src/ChromeClientImpl.h +++ b/WebKit/chromium/src/ChromeClientImpl.h @@ -35,6 +35,7 @@ namespace WebCore { class AccessibilityObject; +class FileChooser; class HTMLParserQuirks; class PopupContainer; class SecurityOrigin; @@ -96,9 +97,9 @@ public: virtual bool shouldInterruptJavaScript(); virtual bool tabsToLinks() const; virtual WebCore::IntRect windowResizerRect() const; - virtual void repaint( - const WebCore::IntRect&, bool contentChanged, bool immediate = false, - bool repaintContentOnly = false); + virtual void invalidateWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsAndWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool); virtual void scroll( const WebCore::IntSize& scrollDelta, const WebCore::IntRect& rectToScroll, const WebCore::IntRect& clipRect); @@ -121,18 +122,43 @@ public: #if ENABLE(NOTIFICATIONS) virtual WebCore::NotificationPresenter* notificationPresenter() const; #endif - virtual void requestGeolocationPermissionForFrame( - WebCore::Frame*, WebCore::Geolocation*) { } + virtual void requestGeolocationPermissionForFrame(WebCore::Frame*, WebCore::Geolocation*); + virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*); virtual void runOpenPanel(WebCore::Frame*, PassRefPtr<WebCore::FileChooser>); - virtual bool setCursor(WebCore::PlatformCursorHandle) { return false; } + virtual void chooseIconForFiles(const Vector<WebCore::String>&, WebCore::FileChooser*); + virtual void setCursor(const WebCore::Cursor&) { } virtual void formStateDidChange(const WebCore::Node*); virtual PassOwnPtr<WebCore::HTMLParserQuirks> createHTMLParserQuirks() { return 0; } +#if ENABLE(TOUCH_EVENTS) + // FIXME: All touch events are forwarded regardless of whether or not they are needed. + virtual void needTouchEvents(bool needTouchEvents) { } +#endif + +#if USE(ACCELERATED_COMPOSITING) + // Pass 0 as the GraphicsLayer to detatch the root layer. + virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*); + + // Sets a flag to specify that the next time content is drawn to the window, + // the changes appear on the screen in synchrony with updates to GraphicsLayers. + virtual void setNeedsOneShotDrawingSynchronization() { } + + // Sets a flag to specify that the view needs to be updated, so we need + // to do an eager layout before the drawing. + virtual void scheduleCompositingLayerSync(); + + virtual PassOwnPtr<WebCore::GLES2Context> getOnscreenGLES2Context(); + virtual PassOwnPtr<WebCore::GLES2Context> getOffscreenGLES2Context(); +#endif + + virtual bool supportsFullscreenForNode(const WebCore::Node*); + virtual void enterFullscreenForNode(WebCore::Node*); + virtual void exitFullscreenForNode(WebCore::Node*); // ChromeClientChromium methods: virtual void popupOpened(WebCore::PopupContainer* popupContainer, const WebCore::IntRect& bounds, - bool activatable, bool handleExternally); + virtual void popupClosed(WebCore::PopupContainer* popupContainer); virtual void didChangeAccessibilityObjectState(WebCore::AccessibilityObject*); // ChromeClientImpl: @@ -148,8 +174,6 @@ private: bool m_scrollbarsVisible; bool m_menubarVisible; bool m_resizable; - // Set to true if the next SetCursor is to be ignored. - bool m_ignoreNextSetCursor; }; } // namespace WebKit diff --git a/WebKit/chromium/src/ChromiumBridge.cpp b/WebKit/chromium/src/ChromiumBridge.cpp index 0fd0825..78e0693 100644 --- a/WebKit/chromium/src/ChromiumBridge.cpp +++ b/WebKit/chromium/src/ChromiumBridge.cpp @@ -37,8 +37,11 @@ #include "ChromeClientImpl.h" #include "WebClipboard.h" #include "WebCookie.h" +#include "WebCookieJar.h" #include "WebCursorInfo.h" #include "WebData.h" +#include "WebDragData.h" +#include "WebFileSystem.h" #include "WebFrameClient.h" #include "WebFrameImpl.h" #include "WebImage.h" @@ -47,6 +50,7 @@ #include "WebMimeRegistry.h" #include "WebPluginContainerImpl.h" #include "WebPluginListBuilderImpl.h" +#include "WebSandboxSupport.h" #include "WebScreenInfo.h" #include "WebString.h" #include "WebURL.h" @@ -57,13 +61,12 @@ #if OS(WINDOWS) #include "WebRect.h" -#include "WebSandboxSupport.h" #include "WebThemeEngine.h" #endif #if OS(LINUX) -#include "WebSandboxSupport.h" #include "WebFontInfo.h" +#include "WebFontRenderStyle.h" #endif #if WEBKIT_USING_SKIA @@ -74,10 +77,13 @@ #include "Cookie.h" #include "FrameView.h" #include "GraphicsContext.h" +#include "IndexedDatabaseProxy.h" #include "KURL.h" #include "NotImplemented.h" #include "PlatformContextSkia.h" #include "PluginData.h" +#include "SharedBuffer.h" +#include "WebGeolocationServiceBridgeImpl.h" #include "Worker.h" #include "WorkerContextProxy.h" #include <wtf/Assertions.h> @@ -89,6 +95,9 @@ namespace WebCore { static ChromeClientImpl* toChromeClientImpl(Widget* widget) { + if (!widget) + return 0; + FrameView* view; if (widget->isFrameView()) view = static_cast<FrameView*>(widget); @@ -112,6 +121,24 @@ static WebWidgetClient* toWebWidgetClient(Widget* widget) return chromeClientImpl->webView()->client(); } +static WebCookieJar* getCookieJar(const Document* document) +{ + WebFrameImpl* frameImpl = WebFrameImpl::fromFrame(document->frame()); + if (!frameImpl || !frameImpl->client()) + return 0; + WebCookieJar* cookieJar = frameImpl->client()->cookieJar(); + if (!cookieJar) + cookieJar = webKitClient()->cookieJar(); + return cookieJar; +} + +// Cache ---------------------------------------------------------------------- + +void ChromiumBridge::cacheMetadata(const KURL& url, double responseTime, const Vector<char>& data) +{ + webKitClient()->cacheMetadata(url, responseTime, data.data(), data.size()); +} + // Clipboard ------------------------------------------------------------------ bool ChromiumBridge::clipboardIsFormatAvailable( @@ -171,27 +198,85 @@ void ChromiumBridge::clipboardWriteImage(NativeImagePtr image, webKitClient()->clipboard()->writeImage(webImage, sourceURL, title); } +void ChromiumBridge::clipboardWriteData(ClipboardData* data) +{ + notImplemented(); + WebDragData dragData; // FIXME: Define the conversion from ClipboardData to WebDragData. + webKitClient()->clipboard()->writeData(dragData); +} + +HashSet<String> ChromiumBridge::clipboardReadAvailableTypes( + PasteboardPrivate::ClipboardBuffer buffer, bool* containsFilenames) +{ + WebVector<WebString> result = webKitClient()->clipboard()->readAvailableTypes( + static_cast<WebClipboard::Buffer>(buffer), containsFilenames); + HashSet<String> types; + for (size_t i = 0; i < result.size(); ++i) + types.add(result[i]); + return types; +} + +bool ChromiumBridge::clipboardReadData(PasteboardPrivate::ClipboardBuffer buffer, + const String& type, String& data, String& metadata) +{ + WebString resultData; + WebString resultMetadata; + bool succeeded = webKitClient()->clipboard()->readData( + static_cast<WebClipboard::Buffer>(buffer), type, &resultData, &resultMetadata); + if (succeeded) { + data = resultData; + metadata = resultMetadata; + } + return succeeded; +} + +Vector<String> ChromiumBridge::clipboardReadFilenames(PasteboardPrivate::ClipboardBuffer buffer) +{ + WebVector<WebString> result = webKitClient()->clipboard()->readFilenames( + static_cast<WebClipboard::Buffer>(buffer)); + Vector<String> convertedResult; + for (size_t i = 0; i < result.size(); ++i) + convertedResult.append(result[i]); + return convertedResult; +} + // Cookies -------------------------------------------------------------------- -void ChromiumBridge::setCookies(const KURL& url, - const KURL& firstPartyForCookies, - const String& cookie) +void ChromiumBridge::setCookies(const Document* document, const KURL& url, + const String& value) { - webKitClient()->setCookies(url, firstPartyForCookies, cookie); + WebCookieJar* cookieJar = getCookieJar(document); + if (cookieJar) + cookieJar->setCookie(url, document->firstPartyForCookies(), value); } -String ChromiumBridge::cookies(const KURL& url, - const KURL& firstPartyForCookies) +String ChromiumBridge::cookies(const Document* document, const KURL& url) { - return webKitClient()->cookies(url, firstPartyForCookies); + String result; + WebCookieJar* cookieJar = getCookieJar(document); + if (cookieJar) + result = cookieJar->cookies(url, document->firstPartyForCookies()); + return result; } -bool ChromiumBridge::rawCookies(const KURL& url, const KURL& firstPartyForCookies, Vector<Cookie>* rawCookies) +String ChromiumBridge::cookieRequestHeaderFieldValue(const Document* document, + const KURL& url) { - rawCookies->clear(); + String result; + WebCookieJar* cookieJar = getCookieJar(document); + if (cookieJar) + result = cookieJar->cookieRequestHeaderFieldValue(url, document->firstPartyForCookies()); + return result; +} + +bool ChromiumBridge::rawCookies(const Document* document, const KURL& url, Vector<Cookie>& rawCookies) +{ + rawCookies.clear(); WebVector<WebCookie> webCookies; - if (!webKitClient()->rawCookies(url, firstPartyForCookies, &webCookies)) - return false; + + WebCookieJar* cookieJar = getCookieJar(document); + if (cookieJar) + cookieJar->rawCookies(url, document->firstPartyForCookies(), webCookies); for (unsigned i = 0; i < webCookies.size(); ++i) { const WebCookie& webCookie = webCookies[i]; @@ -203,20 +288,25 @@ bool ChromiumBridge::rawCookies(const KURL& url, const KURL& firstPartyForCookie webCookie.httpOnly, webCookie.secure, webCookie.session); - rawCookies->append(cookie); + rawCookies.append(cookie); } return true; } -void ChromiumBridge::deleteCookie(const KURL& url, const String& cookieName) +void ChromiumBridge::deleteCookie(const Document* document, const KURL& url, const String& cookieName) { - webKitClient()->deleteCookie(url, cookieName); + WebCookieJar* cookieJar = getCookieJar(document); + if (cookieJar) + cookieJar->deleteCookie(url, cookieName); } -bool ChromiumBridge::cookiesEnabled(const KURL& url, - const KURL& firstPartyForCookies) +bool ChromiumBridge::cookiesEnabled(const Document* document) { - return webKitClient()->cookiesEnabled(url, firstPartyForCookies); + bool result = false; + WebCookieJar* cookieJar = getCookieJar(document); + if (cookieJar) + result = cookieJar->cookiesEnabled(document->cookieURL(), document->firstPartyForCookies()); + return result; } // DNS ------------------------------------------------------------------------ @@ -230,57 +320,91 @@ void ChromiumBridge::prefetchDNS(const String& hostname) bool ChromiumBridge::fileExists(const String& path) { - return webKitClient()->fileExists(path); + return webKitClient()->fileSystem()->fileExists(path); } bool ChromiumBridge::deleteFile(const String& path) { - return webKitClient()->deleteFile(path); + return webKitClient()->fileSystem()->deleteFile(path); } bool ChromiumBridge::deleteEmptyDirectory(const String& path) { - return webKitClient()->deleteEmptyDirectory(path); + return webKitClient()->fileSystem()->deleteEmptyDirectory(path); } bool ChromiumBridge::getFileSize(const String& path, long long& result) { - return webKitClient()->getFileSize(path, result); + return webKitClient()->fileSystem()->getFileSize(path, result); } bool ChromiumBridge::getFileModificationTime(const String& path, time_t& result) { - return webKitClient()->getFileModificationTime(path, result); + double modificationTime; + if (!webKitClient()->fileSystem()->getFileModificationTime(path, modificationTime)) + return false; + result = static_cast<time_t>(modificationTime); + return true; } String ChromiumBridge::directoryName(const String& path) { - return webKitClient()->directoryName(path); + return webKitClient()->fileSystem()->directoryName(path); } String ChromiumBridge::pathByAppendingComponent(const String& path, const String& component) { - return webKitClient()->pathByAppendingComponent(path, component); + return webKitClient()->fileSystem()->pathByAppendingComponent(path, component); } bool ChromiumBridge::makeAllDirectories(const String& path) { - return webKitClient()->makeAllDirectories(path); + return webKitClient()->fileSystem()->makeAllDirectories(path); } String ChromiumBridge::getAbsolutePath(const String& path) { - return webKitClient()->getAbsolutePath(path); + return webKitClient()->fileSystem()->getAbsolutePath(path); } bool ChromiumBridge::isDirectory(const String& path) { - return webKitClient()->isDirectory(path); + return webKitClient()->fileSystem()->isDirectory(path); } KURL ChromiumBridge::filePathToURL(const String& path) { - return webKitClient()->filePathToURL(path); + return webKitClient()->fileSystem()->filePathToURL(path); +} + +PlatformFileHandle ChromiumBridge::openFile(const String& path, FileOpenMode mode) +{ + return webKitClient()->fileSystem()->openFile(path, mode); +} + +void ChromiumBridge::closeFile(PlatformFileHandle& handle) +{ + webKitClient()->fileSystem()->closeFile(handle); +} + +long long ChromiumBridge::seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin) +{ + return webKitClient()->fileSystem()->seekFile(handle, offset, origin); +} + +bool ChromiumBridge::truncateFile(PlatformFileHandle handle, long long offset) +{ + return webKitClient()->fileSystem()->truncateFile(handle, offset); +} + +int ChromiumBridge::readFromFile(PlatformFileHandle handle, char* data, int length) +{ + return webKitClient()->fileSystem()->readFromFile(handle, data, length); +} + +int ChromiumBridge::writeToFile(PlatformFileHandle handle, const char* data, int length) +{ + return webKitClient()->fileSystem()->writeToFile(handle, data, length); } // Font ----------------------------------------------------------------------- @@ -308,14 +432,48 @@ String ChromiumBridge::getFontFamilyForCharacters(const UChar* characters, size_ return WebString(); } + +void ChromiumBridge::getRenderStyleForStrike(const char* font, int sizeAndStyle, FontRenderStyle* result) +{ + WebFontRenderStyle style; + + if (webKitClient()->sandboxSupport()) + webKitClient()->sandboxSupport()->getRenderStyleForStrike(font, sizeAndStyle, &style); + else + WebFontInfo::renderStyleForStrike(font, sizeAndStyle, &style); + + style.toFontRenderStyle(result); +} +#endif + +#if OS(DARWIN) +bool ChromiumBridge::loadFont(NSFont* srcFont, ATSFontContainerRef* out) +{ + WebSandboxSupport* ss = webKitClient()->sandboxSupport(); + if (ss) + return ss->loadFont(srcFont, out); + + // This function should only be called in response to an error loading a + // font due to being blocked by the sandbox. + // This by definition shouldn't happen if there is no sandbox support. + ASSERT_NOT_REACHED(); + *out = 0; + return false; +} #endif -// HTML5 DB ------------------------------------------------------------------- +// Geolocation ---------------------------------------------------------------- -#if ENABLE(DATABASE) -PlatformFileHandle ChromiumBridge::databaseOpenFile(const String& vfsFileName, int desiredFlags, PlatformFileHandle* dirHandle) +GeolocationServiceBridge* ChromiumBridge::createGeolocationServiceBridge(GeolocationServiceChromium* geolocationServiceChromium) { - return webKitClient()->databaseOpenFile(WebString(vfsFileName), desiredFlags, dirHandle); + return createGeolocationServiceBridgeImpl(geolocationServiceChromium); +} + +// Databases ------------------------------------------------------------------ + +PlatformFileHandle ChromiumBridge::databaseOpenFile(const String& vfsFileName, int desiredFlags) +{ + return webKitClient()->databaseOpenFile(WebString(vfsFileName), desiredFlags); } int ChromiumBridge::databaseDeleteFile(const String& vfsFileName, bool syncDir) @@ -332,7 +490,15 @@ long long ChromiumBridge::databaseGetFileSize(const String& vfsFileName) { return webKitClient()->databaseGetFileSize(WebString(vfsFileName)); } -#endif + +// Indexed Database ----------------------------------------------------------- + +PassRefPtr<IndexedDatabase> ChromiumBridge::indexedDatabase() +{ + // There's no reason why we need to allocate a new proxy each time, but + // there's also no strong reason not to. + return IndexedDatabaseProxy::create(); +} // Keygen --------------------------------------------------------------------- @@ -395,7 +561,7 @@ String ChromiumBridge::preferredExtensionForMIMEType(const String& mimeType) // Plugin --------------------------------------------------------------------- -bool ChromiumBridge::plugins(bool refresh, Vector<PluginInfo*>* results) +bool ChromiumBridge::plugins(bool refresh, Vector<PluginInfo>* results) { WebPluginListBuilderImpl builder(results); webKitClient()->getPluginList(refresh, &builder); @@ -523,6 +689,14 @@ void ChromiumBridge::paintScrollbarTrack( alignRect); } +void ChromiumBridge::paintSpinButton( + GraphicsContext* gc, int part, int state, int classicState, + const IntRect& rect) +{ + webKitClient()->themeEngine()->paintSpinButton( + gc->platformContext()->canvas(), part, state, classicState, rect); +} + void ChromiumBridge::paintTextField( GraphicsContext* gc, int part, int state, int classicState, const IntRect& rect, const Color& color, bool fillContentArea, @@ -544,6 +718,13 @@ void ChromiumBridge::paintTrackbar( gc->platformContext()->canvas(), part, state, classicState, rect); } +void ChromiumBridge::paintProgressBar( + GraphicsContext* gc, const IntRect& barRect, const IntRect& valueRect, bool determinate, double animatedSeconds) +{ + webKitClient()->themeEngine()->paintProgressBar( + gc->platformContext()->canvas(), barRect, valueRect, determinate, animatedSeconds); +} + #endif // Trace Event ---------------------------------------------------------------- diff --git a/WebKit/chromium/src/ChromiumThreading.cpp b/WebKit/chromium/src/ChromiumThreading.cpp index 902a433..c6fefac 100644 --- a/WebKit/chromium/src/ChromiumThreading.cpp +++ b/WebKit/chromium/src/ChromiumThreading.cpp @@ -38,13 +38,9 @@ namespace WTF { -void ChromiumThreading::initializeMainThread() +void ChromiumThreading::callOnMainThread(void (*func)(void*), void* context) { -} - -void ChromiumThreading::scheduleDispatchFunctionsOnMainThread() -{ - WebKit::webKitClient()->callOnMainThread(&WTF::dispatchFunctionsFromMainThread); + WebKit::webKitClient()->callOnMainThread(func, context); } } // namespace WTF diff --git a/WebKit/chromium/src/CompositionUnderlineBuilder.h b/WebKit/chromium/src/CompositionUnderlineBuilder.h new file mode 100644 index 0000000..ce62474 --- /dev/null +++ b/WebKit/chromium/src/CompositionUnderlineBuilder.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CompositionUnderlineBuilder_h +#define CompositionUnderlineBuilder_h + +#include "Editor.h" +#include "Vector.h" +#include "WebCompositionUnderline.h" +#include "WebVector.h" + +namespace WebKit { + +// This class is used for converting from WebCompositionUnderline to +// WebCore::CompositionUnderline. + +class CompositionUnderlineBuilder : public WebCore::CompositionUnderline { +public: + CompositionUnderlineBuilder(const WebCompositionUnderline& u) + : WebCore::CompositionUnderline(u.startOffset, u.endOffset, + WebCore::Color(u.color), u.thick) { } +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/CompositionUnderlineVectorBuilder.cpp b/WebKit/chromium/src/CompositionUnderlineVectorBuilder.cpp new file mode 100644 index 0000000..55dca85 --- /dev/null +++ b/WebKit/chromium/src/CompositionUnderlineVectorBuilder.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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 "CompositionUnderlineVectorBuilder.h" + +#include "CompositionUnderlineBuilder.h" + +using namespace WebCore; + +namespace WebKit { + +CompositionUnderlineVectorBuilder::CompositionUnderlineVectorBuilder( + const WebVector<WebCompositionUnderline>& underlines) +{ + size_t size = underlines.size(); + reserveCapacity(size); + for (size_t i = 0; i < size; ++i) + append(CompositionUnderlineBuilder(underlines[i])); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/CompositionUnderlineVectorBuilder.h b/WebKit/chromium/src/CompositionUnderlineVectorBuilder.h new file mode 100644 index 0000000..8050f02 --- /dev/null +++ b/WebKit/chromium/src/CompositionUnderlineVectorBuilder.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CompositionUnderlineVectorBuilder_h +#define CompositionUnderlineVectorBuilder_h + +#include "Editor.h" +#include "Vector.h" +#include "WebCompositionUnderline.h" +#include "WebVector.h" + +namespace WebKit { + +// This classes are used for converting from std::vector<WebCompositionUnderline> +// to Vector<WebCore::CompositionUnderline>. + +class CompositionUnderlineVectorBuilder : + public Vector<WebCore::CompositionUnderline> { +public: + CompositionUnderlineVectorBuilder( + const WebVector<WebCompositionUnderline>&); +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/ContextMenuClientImpl.cpp b/WebKit/chromium/src/ContextMenuClientImpl.cpp index 8472082..1dc2ee7 100644 --- a/WebKit/chromium/src/ContextMenuClientImpl.cpp +++ b/WebKit/chromium/src/ContextMenuClientImpl.cpp @@ -46,6 +46,7 @@ #include "KURL.h" #include "MediaError.h" #include "PlatformString.h" +#include "RenderWidget.h" #include "TextBreakIterator.h" #include "Widget.h" @@ -53,6 +54,8 @@ #include "WebDataSourceImpl.h" #include "WebFrameImpl.h" #include "WebMenuItemInfo.h" +#include "WebPlugin.h" +#include "WebPluginContainerImpl.h" #include "WebPoint.h" #include "WebString.h" #include "WebURL.h" @@ -147,13 +150,28 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems( WebContextMenuData data; data.mousePosition = selectedFrame->view()->contentsToWindow(r.point()); + // Compute edit flags. + data.editFlags = WebContextMenuData::CanDoNone; + if (m_webView->focusedWebCoreFrame()->editor()->canUndo()) + data.editFlags |= WebContextMenuData::CanUndo; + if (m_webView->focusedWebCoreFrame()->editor()->canRedo()) + data.editFlags |= WebContextMenuData::CanRedo; + if (m_webView->focusedWebCoreFrame()->editor()->canCut()) + data.editFlags |= WebContextMenuData::CanCut; + if (m_webView->focusedWebCoreFrame()->editor()->canCopy()) + data.editFlags |= WebContextMenuData::CanCopy; + if (m_webView->focusedWebCoreFrame()->editor()->canPaste()) + data.editFlags |= WebContextMenuData::CanPaste; + if (m_webView->focusedWebCoreFrame()->editor()->canDelete()) + data.editFlags |= WebContextMenuData::CanDelete; + // We can always select all... + data.editFlags |= WebContextMenuData::CanSelectAll; + data.editFlags |= WebContextMenuData::CanTranslate; + // Links, Images, Media tags, and Image/Media-Links take preference over // all else. data.linkURL = r.absoluteLinkURL(); - data.mediaType = WebContextMenuData::MediaTypeNone; - data.mediaFlags = WebContextMenuData::MediaNone; - if (!r.absoluteImageURL().isEmpty()) { data.srcURL = r.absoluteImageURL(); data.mediaType = WebContextMenuData::MediaTypeImage; @@ -181,10 +199,33 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems( data.mediaFlags |= WebContextMenuData::MediaCanSave; if (mediaElement->hasAudio()) data.mediaFlags |= WebContextMenuData::MediaHasAudio; + if (mediaElement->hasVideo()) + data.mediaFlags |= WebContextMenuData::MediaHasVideo; + if (mediaElement->controls()) + data.mediaFlags |= WebContextMenuData::MediaControls; + } else if (r.innerNonSharedNode()->hasTagName(HTMLNames::objectTag) + || r.innerNonSharedNode()->hasTagName(HTMLNames::embedTag)) { + RenderObject* object = r.innerNonSharedNode()->renderer(); + if (object && object->isWidget()) { + Widget* widget = toRenderWidget(object)->widget(); + if (widget) { + WebPluginContainerImpl* plugin = static_cast<WebPluginContainerImpl*>(widget); + WebString text = plugin->plugin()->selectionAsText(); + if (!text.isEmpty()) { + data.selectedText = text; + data.editFlags |= WebContextMenuData::CanCopy; + } + data.editFlags &= ~WebContextMenuData::CanTranslate; + } + } } + + data.isImageBlocked = + (data.mediaType == WebContextMenuData::MediaTypeImage) && !r.image(); + // If it's not a link, an image, a media element, or an image/media link, // show a selection menu or a more generic page menu. - data.frameEncoding = selectedFrame->loader()->encoding(); + data.frameEncoding = selectedFrame->loader()->writer()->encoding(); // Send the frame and page URLs in any case. data.pageURL = urlFromFrame(m_webView->mainFrameImpl()->frame()); @@ -194,21 +235,17 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems( if (r.isSelected()) data.selectedText = selectedFrame->selectedText().stripWhiteSpace(); - data.isEditable = false; if (r.isContentEditable()) { data.isEditable = true; if (m_webView->focusedWebCoreFrame()->editor()->isContinuousSpellCheckingEnabled()) { data.isSpellCheckingEnabled = true; - data.misspelledWord = selectMisspelledWord(defaultMenu, selectedFrame); + // Spellchecking might be enabled for the field, but could be disabled on the node. + if (m_webView->focusedWebCoreFrame()->editor()->spellCheckingEnabledInFocusedNode()) + data.misspelledWord = selectMisspelledWord(defaultMenu, selectedFrame); } } #if OS(DARWIN) - // Writing direction context menu. - data.writingDirectionDefault = WebContextMenuData::CheckableMenuItemDisabled; - data.writingDirectionLeftToRight = WebContextMenuData::CheckableMenuItemEnabled; - data.writingDirectionRightToLeft = WebContextMenuData::CheckableMenuItemEnabled; - ExceptionCode ec = 0; RefPtr<CSSStyleDeclaration> style = selectedFrame->document()->createCSSStyleDeclaration(); style->setProperty(CSSPropertyDirection, "ltr", false, ec); @@ -225,23 +262,6 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems( if (ds) data.securityInfo = ds->response().securityInfo(); - // Compute edit flags. - data.editFlags = WebContextMenuData::CanDoNone; - if (m_webView->focusedWebCoreFrame()->editor()->canUndo()) - data.editFlags |= WebContextMenuData::CanUndo; - if (m_webView->focusedWebCoreFrame()->editor()->canRedo()) - data.editFlags |= WebContextMenuData::CanRedo; - if (m_webView->focusedWebCoreFrame()->editor()->canCut()) - data.editFlags |= WebContextMenuData::CanCut; - if (m_webView->focusedWebCoreFrame()->editor()->canCopy()) - data.editFlags |= WebContextMenuData::CanCopy; - if (m_webView->focusedWebCoreFrame()->editor()->canPaste()) - data.editFlags |= WebContextMenuData::CanPaste; - if (m_webView->focusedWebCoreFrame()->editor()->canDelete()) - data.editFlags |= WebContextMenuData::CanDelete; - // We can always select all... - data.editFlags |= WebContextMenuData::CanSelectAll; - // Filter out custom menu elements and add them into the data. populateCustomMenuItems(defaultMenu, &data); @@ -257,7 +277,7 @@ void ContextMenuClientImpl::populateCustomMenuItems(WebCore::ContextMenu* defaul Vector<WebMenuItemInfo> customItems; for (size_t i = 0; i < defaultMenu->itemCount(); ++i) { ContextMenuItem* inputItem = defaultMenu->itemAtIndex(i, defaultMenu->platformDescription()); - if (inputItem->action() < ContextMenuItemBaseCustomTag || inputItem->action() >= ContextMenuItemBaseApplicationTag) + if (inputItem->action() < ContextMenuItemBaseCustomTag || inputItem->action() > ContextMenuItemLastCustomTag) continue; WebMenuItemInfo outputItem; diff --git a/WebKit/chromium/src/DatabaseObserver.cpp b/WebKit/chromium/src/DatabaseObserver.cpp index 54e93e1..f43c9bd 100644 --- a/WebKit/chromium/src/DatabaseObserver.cpp +++ b/WebKit/chromium/src/DatabaseObserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,30 +31,60 @@ #include "config.h" #include "DatabaseObserver.h" -#include "Database.h" +#if ENABLE(DATABASE) + +#include "AbstractDatabase.h" +#include "Document.h" +#include "ScriptExecutionContext.h" #include "WebDatabase.h" #include "WebDatabaseObserver.h" +#include "WebFrameClient.h" +#include "WebFrameImpl.h" +#include "WebSecurityOrigin.h" +#include "WebWorkerImpl.h" +#include "WorkerContext.h" +#include "WorkerThread.h" using namespace WebKit; namespace WebCore { -void DatabaseObserver::databaseOpened(Database* database) +bool DatabaseObserver::canEstablishDatabase(ScriptExecutionContext* scriptExecutionContext, const String& name, const String& displayName, unsigned long estimatedSize) +{ + ASSERT(scriptExecutionContext->isContextThread()); + ASSERT(scriptExecutionContext->isDocument() || scriptExecutionContext->isWorkerContext()); + if (scriptExecutionContext->isDocument()) { + Document* document = static_cast<Document*>(scriptExecutionContext); + WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); + return webFrame->client()->allowDatabase(webFrame, name, displayName, estimatedSize); + } else { + WorkerContext* workerContext = static_cast<WorkerContext*>(scriptExecutionContext); + WorkerLoaderProxy* workerLoaderProxy = &workerContext->thread()->workerLoaderProxy(); + WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerLoaderProxy); + return webWorker->allowDatabase(0, name, displayName, estimatedSize); + } + + return true; +} + +void DatabaseObserver::databaseOpened(AbstractDatabase* database) { - ASSERT(isMainThread()); + ASSERT(database->scriptExecutionContext()->isContextThread()); WebDatabase::observer()->databaseOpened(WebDatabase(database)); } -void DatabaseObserver::databaseModified(Database* database) +void DatabaseObserver::databaseModified(AbstractDatabase* database) { - ASSERT(isMainThread()); + ASSERT(database->scriptExecutionContext()->isContextThread()); WebDatabase::observer()->databaseModified(WebDatabase(database)); } -void DatabaseObserver::databaseClosed(Database* database) +void DatabaseObserver::databaseClosed(AbstractDatabase* database) { - ASSERT(isMainThread()); + ASSERT(database->scriptExecutionContext()->isContextThread()); WebDatabase::observer()->databaseClosed(WebDatabase(database)); } } // namespace WebCore + +#endif // ENABLE(DATABASE) diff --git a/WebKit/chromium/src/DebuggerAgentImpl.cpp b/WebKit/chromium/src/DebuggerAgentImpl.cpp index d592710..dde9e1d 100644 --- a/WebKit/chromium/src/DebuggerAgentImpl.cpp +++ b/WebKit/chromium/src/DebuggerAgentImpl.cpp @@ -35,10 +35,8 @@ #include "Document.h" #include "Frame.h" #include "Page.h" +#include "ScriptDebugServer.h" #include "V8Binding.h" -#include "V8DOMWindow.h" -#include "V8Index.h" -#include "V8Proxy.h" #include "WebDevToolsAgentImpl.h" #include "WebViewImpl.h" #include <wtf/HashSet.h> @@ -50,10 +48,6 @@ using WebCore::Document; using WebCore::Frame; using WebCore::Page; using WebCore::String; -using WebCore::V8ClassIndex; -using WebCore::V8DOMWindow; -using WebCore::V8DOMWrapper; -using WebCore::V8Proxy; namespace WebKit { @@ -91,58 +85,6 @@ void DebuggerAgentImpl::debuggerOutput(const String& command) m_webdevtoolsAgent->forceRepaint(); } -// static -void DebuggerAgentImpl::createUtilityContext(Frame* frame, v8::Persistent<v8::Context>* context) -{ - v8::HandleScope scope; - bool canExecuteScripts = frame->script()->canExecuteScripts(); - - // Set up the DOM window as the prototype of the new global object. - v8::Handle<v8::Context> windowContext = V8Proxy::context(frame); - v8::Handle<v8::Object> windowGlobal; - v8::Handle<v8::Object> windowWrapper; - if (canExecuteScripts) { - // FIXME: This check prevents renderer from crashing, while providing limited capabilities for - // DOM inspection, Resources tracking, no scripts support, some timeline profiling. Console will - // result in exceptions for each evaluation. There is still some work that needs to be done in - // order to polish the script-less experience. - windowGlobal = windowContext->Global(); - windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), windowGlobal); - ASSERT(V8DOMWindow::toNative(windowWrapper) == frame->domWindow()); - } - - v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New(); - - // TODO(yurys): provide a function in v8 bindings that would make the - // utility context more like main world context of the inspected frame, - // otherwise we need to manually make it satisfy various invariants - // that V8Proxy::getEntered and some other V8Proxy methods expect to find - // on v8 contexts on the contexts stack. - // See V8Proxy::createNewContext. - // - // Install a security handler with V8. - globalTemplate->SetAccessCheckCallbacks( - V8DOMWindow::namedSecurityCheck, - V8DOMWindow::indexedSecurityCheck, - v8::Integer::New(V8ClassIndex::DOMWINDOW)); - // We set number of internal fields to match that in V8DOMWindow wrapper. - // See http://crbug.com/28961 - globalTemplate->SetInternalFieldCount(V8DOMWindow::internalFieldCount); - - *context = v8::Context::New(0 /* no extensions */, globalTemplate, v8::Handle<v8::Object>()); - v8::Context::Scope contextScope(*context); - v8::Handle<v8::Object> global = (*context)->Global(); - - v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__"); - if (canExecuteScripts) - global->Set(implicitProtoString, windowWrapper); - - // Give the code running in the new context a way to get access to the - // original context. - if (canExecuteScripts) - global->Set(v8::String::New("contentWindow"), windowGlobal); -} - String DebuggerAgentImpl::executeUtilityFunction( v8::Handle<v8::Context> context, int callId, diff --git a/WebKit/chromium/src/DebuggerAgentImpl.h b/WebKit/chromium/src/DebuggerAgentImpl.h index 6eaf576..0e6e6af 100644 --- a/WebKit/chromium/src/DebuggerAgentImpl.h +++ b/WebKit/chromium/src/DebuggerAgentImpl.h @@ -52,9 +52,6 @@ class WebViewImpl; class DebuggerAgentImpl : public DebuggerAgent { public: - // Creates utility context with injected js agent. - static void createUtilityContext(WebCore::Frame* frame, v8::Persistent<v8::Context>* context); - DebuggerAgentImpl(WebKit::WebViewImpl* webViewImpl, DebuggerAgentDelegate* delegate, WebDevToolsAgentImpl* webdevtoolsAgent); diff --git a/WebKit/chromium/src/DebuggerAgentManager.cpp b/WebKit/chromium/src/DebuggerAgentManager.cpp index faafaff..1cc6740 100644 --- a/WebKit/chromium/src/DebuggerAgentManager.cpp +++ b/WebKit/chromium/src/DebuggerAgentManager.cpp @@ -34,6 +34,7 @@ #include "DebuggerAgentImpl.h" #include "Frame.h" #include "PageGroupLoadDeferrer.h" +#include "ScriptDebugServer.h" #include "V8Proxy.h" #include "WebDevToolsAgentImpl.h" #include "WebFrameImpl.h" @@ -53,6 +54,8 @@ bool DebuggerAgentManager::s_inUtilityContext = false; bool DebuggerAgentManager::s_debugBreakDelayed = false; +bool DebuggerAgentManager::s_exposeV8DebuggerProtocol = false; + namespace { class CallerIdWrapper : public v8::Debug::ClientData, public Noncopyable { @@ -116,6 +119,8 @@ DebuggerAgentManager::AttachedAgentsMap* DebuggerAgentManager::s_attachedAgentsM void DebuggerAgentManager::debugAttach(DebuggerAgentImpl* debuggerAgent) { + if (!s_exposeV8DebuggerProtocol) + return; if (!s_attachedAgentsMap) { s_attachedAgentsMap = new AttachedAgentsMap(); v8::Debug::SetMessageHandler2(&DebuggerAgentManager::onV8DebugMessage); @@ -128,6 +133,8 @@ void DebuggerAgentManager::debugAttach(DebuggerAgentImpl* debuggerAgent) void DebuggerAgentManager::debugDetach(DebuggerAgentImpl* debuggerAgent) { + if (!s_exposeV8DebuggerProtocol) + return; if (!s_attachedAgentsMap) { ASSERT_NOT_REACHED(); return; @@ -251,6 +258,12 @@ void DebuggerAgentManager::setMessageLoopDispatchHandler(WebDevToolsAgent::Messa s_messageLoopDispatchHandler = handler; } +void DebuggerAgentManager::setExposeV8DebuggerProtocol(bool value) +{ + s_exposeV8DebuggerProtocol = value; + WebCore::ScriptDebugServer::shared().setEnabled(!s_exposeV8DebuggerProtocol); +} + void DebuggerAgentManager::setHostId(WebFrameImpl* webframe, int hostId) { ASSERT(hostId > 0); diff --git a/WebKit/chromium/src/DebuggerAgentManager.h b/WebKit/chromium/src/DebuggerAgentManager.h index a2e9030..dbb600a 100644 --- a/WebKit/chromium/src/DebuggerAgentManager.h +++ b/WebKit/chromium/src/DebuggerAgentManager.h @@ -31,12 +31,15 @@ #ifndef DebuggerAgentManager_h #define DebuggerAgentManager_h +#include "WebCString.h" #include "WebDevToolsAgent.h" #include <v8-debug.h> #include <wtf/HashMap.h> #include <wtf/Noncopyable.h> +#include <wtf/Vector.h> namespace WebCore { +class Page; class PageGroupLoadDeferrer; class String; } @@ -67,6 +70,7 @@ public: static void pauseScript(); static void executeDebuggerCommand(const WebCore::String& command, int callerId); static void setMessageLoopDispatchHandler(WebDevToolsAgent::MessageLoopDispatchHandler handler); + static void setExposeV8DebuggerProtocol(bool); // Sets |hostId| as the frame context data. This id is used to filter scripts // related to the inspected page. @@ -116,6 +120,7 @@ private: static bool s_inUtilityContext; static bool s_debugBreakDelayed; + static bool s_exposeV8DebuggerProtocol; }; } // namespace WebKit diff --git a/WebKit/chromium/src/DragClientImpl.cpp b/WebKit/chromium/src/DragClientImpl.cpp index 671e7ca..9874401 100644 --- a/WebKit/chromium/src/DragClientImpl.cpp +++ b/WebKit/chromium/src/DragClientImpl.cpp @@ -30,11 +30,14 @@ #include "config.h" #include "DragClientImpl.h" - +#include "DragImageRef.h" #include "ChromiumDataObject.h" #include "ClipboardChromium.h" #include "Frame.h" +#include "NativeImageSkia.h" +#include "WebCommon.h" #include "WebDragData.h" +#include "WebImage.h" #include "WebViewClient.h" #include "WebViewImpl.h" @@ -81,8 +84,16 @@ void DragClientImpl::startDrag(DragImageRef dragImage, DragOperation dragOperationMask = clipboard->sourceOperation(); + IntSize offsetSize(eventPos - dragImageOrigin); + WebPoint offsetPoint(offsetSize.width(), offsetSize.height()); m_webView->startDragging( - eventPos, dragData, static_cast<WebDragOperationsMask>(dragOperationMask)); + dragData, static_cast<WebDragOperationsMask>(dragOperationMask), +#if WEBKIT_USING_SKIA + dragImage ? WebImage(*dragImage) : WebImage(), +#else + dragImage ? WebImage(dragImage) : WebImage(), +#endif + offsetPoint); } DragImageRef DragClientImpl::createDragImageForLink(KURL&, const String& label, Frame*) diff --git a/WebKit/chromium/src/DragScrollTimer.cpp b/WebKit/chromium/src/DragScrollTimer.cpp new file mode 100644 index 0000000..83b81b7 --- /dev/null +++ b/WebKit/chromium/src/DragScrollTimer.cpp @@ -0,0 +1,126 @@ +/* + * 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 "DragScrollTimer.h" + +#include "FrameView.h" + +using namespace WebCore; + +namespace WebKit { + +// Computes the distance from a point outside a rect to the nearest edge of the rect. +static IntSize distanceToRect(const IntPoint& point, const IntRect& rect) +{ + int dx = 0, dy = 0; + if (point.x() < rect.x()) + dx = point.x() - rect.x(); + else if (rect.right() < point.x()) + dx = point.x() - rect.right(); + if (point.y() < rect.y()) + dy = point.y() - rect.y(); + else if (rect.bottom() < point.y()) + dy = point.y() - rect.bottom(); + return IntSize(dx, dy); +} + +DragScrollTimer::DragScrollTimer() + : m_timer(this, &DragScrollTimer::fired) + , m_view(0) + , m_scrolling(false) +{ +} + +DragScrollTimer::~DragScrollTimer() +{ + // We do this for detecting dead object earlier + stop(); +} + +void DragScrollTimer::stop() +{ + m_timer.stop(); + m_view = 0; + m_scrolling = false; +} + +void DragScrollTimer::scroll() +{ + m_view->scrollBy(m_lastDistance); + m_scrolling = true; +} + +void DragScrollTimer::update() +{ + if (shouldScroll()) + scroll(); + else + stop(); +} + +void DragScrollTimer::triggerScroll(FrameView* view, const WebPoint& location) +{ + if (!view) + return; + + // Approximates Safari + static const double scrollStartDelay = 0.2; + + m_view = view; + m_lastDistance = scrollDistanceFor(view, location); + + if (m_scrolling) + update(); + else if (shouldScroll() && !m_timer.isActive()) + m_timer.startOneShot(scrollStartDelay); +} + +IntSize DragScrollTimer::scrollDistanceFor(FrameView* view, const WebPoint& location) const +{ + static const int scrollMargin = 30; + + IntRect bounds(0, 0, view->visibleWidth(), view->visibleHeight()); + if (!bounds.contains(location)) + return IntSize(0, 0); // The location is outside the border belt. + + bounds.setY(bounds.y() + scrollMargin); + bounds.setHeight(bounds.height() - scrollMargin * 2); + bounds.setX(bounds.x() + scrollMargin); + bounds.setWidth(bounds.width() - scrollMargin * 2); + + if (bounds.contains(location)) + return IntSize(0, 0); // The location is inside the border belt. + + // The location is over the border belt. + return distanceToRect(location, bounds); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/AutocompletePopupMenuClient.h b/WebKit/chromium/src/DragScrollTimer.h index 16a3771..a4090e0 100644 --- a/WebKit/chromium/src/AutocompletePopupMenuClient.h +++ b/WebKit/chromium/src/DragScrollTimer.h @@ -28,36 +28,40 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef AutocompletePopupMenuClient_h -#define AutocompletePopupMenuClient_h - -#include "SuggestionsPopupMenuClient.h" +#ifndef DragScrollTimer_h +#define DragScrollTimer_h -namespace WebCore { -class HTMLInputElement; -} +#include "IntSize.h" +#include "Timer.h" +#include "WebPoint.h" + +namespace WebCore { class FrameView; } namespace WebKit { -class WebString; -template <typename T> class WebVector; -// The Autocomplete suggestions popup menu client, used to display a list of -// autocomplete suggestions. -class AutocompletePopupMenuClient : public SuggestionsPopupMenuClient { +// +// Encapsulating a timer and associated state management for +// scroll-on-drag behaviour. +// +class DragScrollTimer { public: - // SuggestionsPopupMenuClient implementation: - virtual unsigned getSuggestionsCount() const; - virtual WebString getSuggestion(unsigned listIndex) const; - virtual void removeSuggestionAtIndex(unsigned listIndex); - - void initialize(WebCore::HTMLInputElement*, - const WebVector<WebString>& suggestions, - int defaultSuggestionIndex); + DragScrollTimer(); + ~DragScrollTimer(); - void setSuggestions(const WebVector<WebString>&); + void fired(WebCore::Timer<DragScrollTimer>*) { update(); } + void triggerScroll(WebCore::FrameView*, const WebPoint&); + void stop(); private: - Vector<WebCore::String> m_suggestions; + void scroll(); + void update(); + WebCore::IntSize scrollDistanceFor(WebCore::FrameView*, const WebPoint&) const; + bool shouldScroll() const { return !m_lastDistance.isZero(); } + + WebCore::Timer<DragScrollTimer> m_timer; + WebCore::FrameView* m_view; + WebCore::IntSize m_lastDistance; + bool m_scrolling; }; } // namespace WebKit diff --git a/WebKit/chromium/src/EditorClientImpl.cpp b/WebKit/chromium/src/EditorClientImpl.cpp index d5bddc5..11977b6 100644 --- a/WebKit/chromium/src/EditorClientImpl.cpp +++ b/WebKit/chromium/src/EditorClientImpl.cpp @@ -43,9 +43,11 @@ #include "DOMUtilitiesPrivate.h" #include "WebEditingAction.h" +#include "WebElement.h" #include "WebFrameImpl.h" #include "WebKit.h" #include "WebInputElement.h" +#include "WebInputEventConversion.h" #include "WebNode.h" #include "WebPasswordAutocompleteListener.h" #include "WebRange.h" @@ -90,7 +92,7 @@ bool EditorClientImpl::shouldShowDeleteInterface(HTMLElement* elem) // Normally, we don't care to show WebCore's deletion UI, so we only enable // it if in testing mode and the test specifically requests it by using this // magic class name. - return WebKit::layoutTestMode() + return layoutTestMode() && elem->getAttribute(HTMLNames::classAttr) == "needsDeletionUI"; } @@ -413,8 +415,10 @@ static const KeyDownEntry keyDownEntries[] = { { VKEY_DOWN, 0, "MoveDown" }, { VKEY_DOWN, ShiftKey, "MoveDownAndModifySelection" }, { VKEY_NEXT, ShiftKey, "MovePageDownAndModifySelection" }, +#if !OS(DARWIN) { VKEY_PRIOR, 0, "MovePageUp" }, { VKEY_NEXT, 0, "MovePageDown" }, +#endif { VKEY_HOME, 0, "MoveToBeginningOfLine" }, { VKEY_HOME, ShiftKey, "MoveToBeginningOfLineAndModifySelection" }, @@ -422,6 +426,8 @@ static const KeyDownEntry keyDownEntries[] = { { VKEY_LEFT, CommandKey, "MoveToBeginningOfLine" }, { VKEY_LEFT, CommandKey | ShiftKey, "MoveToBeginningOfLineAndModifySelection" }, + { VKEY_PRIOR, OptionKey, "MovePageUp" }, + { VKEY_NEXT, OptionKey, "MovePageDown" }, #endif #if OS(DARWIN) { VKEY_UP, CommandKey, "MoveToBeginningOfDocument" }, @@ -640,12 +646,19 @@ void EditorClientImpl::handleInputMethodKeydown(KeyboardEvent* keyEvent) // We handle IME within chrome. } -void EditorClientImpl::textFieldDidBeginEditing(Element*) +void EditorClientImpl::textFieldDidBeginEditing(Element* element) { + HTMLInputElement* inputElement = toHTMLInputElement(element); + if (m_webView->client() && inputElement) + m_webView->client()->textFieldDidBeginEditing(WebInputElement(inputElement)); } void EditorClientImpl::textFieldDidEndEditing(Element* element) { + HTMLInputElement* inputElement = toHTMLInputElement(element); + if (m_webView->client() && inputElement) + m_webView->client()->textFieldDidEndEditing(WebInputElement(inputElement)); + // Notification that focus was lost. Be careful with this, it's also sent // when the page is being closed. @@ -654,13 +667,12 @@ void EditorClientImpl::textFieldDidEndEditing(Element* element) m_autofillTimer.stop(); // Hide any showing popup. - m_webView->hideSuggestionsPopup(); + m_webView->hideAutoFillPopup(); if (!m_webView->client()) return; // The page is getting closed, don't fill the password. // Notify any password-listener of the focus change. - HTMLInputElement* inputElement = WebKit::toHTMLInputElement(element); if (!inputElement) return; @@ -678,15 +690,18 @@ void EditorClientImpl::textFieldDidEndEditing(Element* element) void EditorClientImpl::textDidChangeInTextField(Element* element) { ASSERT(element->hasLocalName(HTMLNames::inputTag)); + HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element); + if (m_webView->client()) + m_webView->client()->textFieldDidChange(WebInputElement(inputElement)); + // Note that we only show the autofill popup in this case if the caret is at // the end. This matches FireFox and Safari but not IE. - autofill(static_cast<HTMLInputElement*>(element), false, false, - true); + autofill(inputElement, false, false, true); } bool EditorClientImpl::showFormAutofillForNode(Node* node) { - HTMLInputElement* inputElement = WebKit::toHTMLInputElement(node); + HTMLInputElement* inputElement = toHTMLInputElement(node); if (inputElement) return autofill(inputElement, true, true, false); return false; @@ -701,10 +716,12 @@ bool EditorClientImpl::autofill(HTMLInputElement* inputElement, m_autofillArgs.clear(); m_autofillTimer.stop(); + // FIXME: Remove the extraneous isEnabledFormControl call below. // Let's try to trigger autofill for that field, if applicable. if (!inputElement->isEnabledFormControl() || !inputElement->isTextField() - || inputElement->isPasswordField() - || !inputElement->autoComplete()) + || inputElement->isPasswordField() || !inputElement->autoComplete() + || !inputElement->isEnabledFormControl() + || inputElement->isReadOnlyFormControl()) return false; WebString name = WebInputElement(inputElement).nameForAutofill(); @@ -748,7 +765,7 @@ void EditorClientImpl::doAutofill(Timer<EditorClientImpl>* timer) && inputElement->selectionEnd() == static_cast<int>(value.length()); if ((!args->autofillOnEmptyValue && value.isEmpty()) || !isCaretAtEnd) { - m_webView->hideSuggestionsPopup(); + m_webView->hideAutoFillPopup(); return; } @@ -784,22 +801,27 @@ void EditorClientImpl::cancelPendingAutofill() m_autofillTimer.stop(); } -void EditorClientImpl::onAutofillSuggestionAccepted(HTMLInputElement* textField) +void EditorClientImpl::onAutocompleteSuggestionAccepted(HTMLInputElement* textField) { + if (m_webView->client()) + m_webView->client()->didAcceptAutocompleteSuggestion(WebInputElement(textField)); + WebFrameImpl* webframe = WebFrameImpl::fromFrame(textField->document()->frame()); if (!webframe) return; - WebPasswordAutocompleteListener* listener = webframe->getPasswordListener(textField); - // Password listeners need to autocomplete other fields that depend on the - // input element with autofill suggestions. - if (listener) - listener->performInlineAutocomplete(textField->value(), false, false); + webframe->notifiyPasswordListenerOfAutocomplete(WebInputElement(textField)); } bool EditorClientImpl::doTextFieldCommandFromEvent(Element* element, KeyboardEvent* event) { + HTMLInputElement* inputElement = toHTMLInputElement(element); + if (m_webView->client() && inputElement) { + m_webView->client()->textFieldDidReceiveKeyDown(WebInputElement(inputElement), + WebKeyboardEventBuilder(*event)); + } + // Remember if backspace was pressed for the autofill. It is not clear how to // find if backspace was pressed from textFieldDidBeginEditing and // textDidChangeInTextField as when these methods are called the value of the @@ -913,10 +935,14 @@ void EditorClientImpl::getGuessesForWord(const String&, notImplemented(); } -void EditorClientImpl::setInputMethodState(bool enabled) +void EditorClientImpl::willSetInputMethodState() { if (m_webView->client()) - m_webView->client()->setInputMethodEnabled(enabled); + m_webView->client()->resetInputMethod(); +} + +void EditorClientImpl::setInputMethodState(bool) +{ } } // namesace WebKit diff --git a/WebKit/chromium/src/EditorClientImpl.h b/WebKit/chromium/src/EditorClientImpl.h index fd08b4d..549a512 100644 --- a/WebKit/chromium/src/EditorClientImpl.h +++ b/WebKit/chromium/src/EditorClientImpl.h @@ -108,6 +108,7 @@ public: virtual bool spellingUIIsShowing(); virtual void getGuessesForWord(const WebCore::String& word, WTF::Vector<WebCore::String>& guesses); + virtual void willSetInputMethodState(); virtual void setInputMethodState(bool enabled); // Shows the form autofill popup for |node| if it is an HTMLInputElement and @@ -118,10 +119,10 @@ public: virtual bool showFormAutofillForNode(WebCore::Node*); // Notification that the text changed due to acceptance of a suggestion - // provided by an autofill popup. Having a separate callback in this case - // is a simple way to break the cycle that would otherwise occur if + // provided by an Autocomplete popup. Having a separate callback in this + // case is a simple way to break the cycle that would otherwise occur if // textDidChangeInTextField was called. - virtual void onAutofillSuggestionAccepted(WebCore::HTMLInputElement*); + virtual void onAutocompleteSuggestionAccepted(WebCore::HTMLInputElement*); private: void modifySelection(WebCore::Frame*, WebCore::KeyboardEvent*); diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.cpp b/WebKit/chromium/src/FrameLoaderClientImpl.cpp index b984308..dae9348 100644 --- a/WebKit/chromium/src/FrameLoaderClientImpl.cpp +++ b/WebKit/chromium/src/FrameLoaderClientImpl.cpp @@ -32,12 +32,13 @@ #include "FrameLoaderClientImpl.h" #include "Chrome.h" -#include "CString.h" #include "Document.h" #include "DocumentLoader.h" #include "FormState.h" #include "FrameLoader.h" #include "FrameLoadRequest.h" +#include "HTTPParsers.h" +#include "HistoryItem.h" #include "HitTestResult.h" #include "HTMLAppletElement.h" #include "HTMLFormElement.h" // needed by FormState.h @@ -71,6 +72,7 @@ #include "WindowFeatures.h" #include "WrappedResourceRequest.h" #include "WrappedResourceResponse.h" +#include <wtf/text/CString.h> using namespace WebCore; @@ -180,6 +182,18 @@ bool FrameLoaderClientImpl::allowImages(bool enabledPerSettings) return enabledPerSettings; } +void FrameLoaderClientImpl::didNotAllowScript() +{ + if (m_webFrame->client()) + m_webFrame->client()->didNotAllowScript(m_webFrame); +} + +void FrameLoaderClientImpl::didNotAllowPlugins() +{ + if (m_webFrame->client()) + m_webFrame->client()->didNotAllowPlugins(m_webFrame); +} + bool FrameLoaderClientImpl::hasWebView() const { return m_webFrame->viewImpl(); @@ -235,7 +249,7 @@ void FrameLoaderClientImpl::detachedFromParent3() // Stop communicating with the WebFrameClient at this point since we are no // longer associated with the Page. - m_webFrame->dropClient(); + m_webFrame->setClient(0); } // This function is responsible for associating the |identifier| with a given @@ -392,12 +406,6 @@ bool FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache( return false; // Do not suppress remaining notifications } -void FrameLoaderClientImpl::dispatchDidLoadResourceByXMLHttpRequest( - unsigned long identifier, - const ScriptString& source) -{ -} - void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents() { if (m_webFrame->client()) @@ -556,7 +564,7 @@ void FrameLoaderClientImpl::dispatchWillPerformClientRedirect( } } -void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() +void FrameLoaderClientImpl::dispatchDidNavigateWithinPage() { // Anchor fragment navigations are not normal loads, so we need to synthesize // some events for our delegate. @@ -567,12 +575,17 @@ void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() // them for fragment redirection that happens in window.onload handler. // See https://bugs.webkit.org/show_bug.cgi?id=31838 bool loaderCompleted = - !m_webFrame->frame()->page()->mainFrame()->loader()->isLoading(); + !webView->page()->mainFrame()->loader()->activeDocumentLoader()->isLoadingInAPISense(); // Generate didStartLoading if loader is completed. if (webView->client() && loaderCompleted) webView->client()->didStartLoading(); + // We need to classify some hash changes as client redirects. + // FIXME: It seems wrong that the currentItem can sometimes be null. + HistoryItem* currentItem = m_webFrame->frame()->loader()->history()->currentItem(); + bool isHashChange = !currentItem || !currentItem->stateObject(); + WebDataSourceImpl* ds = m_webFrame->dataSourceImpl(); ASSERT(ds); // Should not be null when navigating to a reference fragment! if (ds) { @@ -583,27 +596,29 @@ void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() ds->clearRedirectChain(); } - // Figure out if this location change is because of a JS-initiated - // client redirect (e.g onload/setTimeout document.location.href=). - // FIXME: (bugs 1085325, 1046841) We don't get proper redirect - // performed/cancelled notifications across anchor navigations, so the - // other redirect-tracking code in this class (see - // dispatch*ClientRedirect() and dispatchDidStartProvisionalLoad) is - // insufficient to catch and properly flag these transitions. Once a - // proper fix for this bug is identified and applied the following - // block may no longer be required. - bool wasClientRedirect = - (url == m_expectedClientRedirectDest && chainEnd == m_expectedClientRedirectSrc) - || !m_webFrame->isProcessingUserGesture(); - - if (wasClientRedirect) { - if (m_webFrame->client()) - m_webFrame->client()->didCompleteClientRedirect(m_webFrame, chainEnd); - ds->appendRedirect(chainEnd); - // Make sure we clear the expected redirect since we just effectively - // completed it. - m_expectedClientRedirectSrc = KURL(); - m_expectedClientRedirectDest = KURL(); + if (isHashChange) { + // Figure out if this location change is because of a JS-initiated + // client redirect (e.g onload/setTimeout document.location.href=). + // FIXME: (b/1085325, b/1046841) We don't get proper redirect + // performed/cancelled notifications across anchor navigations, so the + // other redirect-tracking code in this class (see + // dispatch*ClientRedirect() and dispatchDidStartProvisionalLoad) is + // insufficient to catch and properly flag these transitions. Once a + // proper fix for this bug is identified and applied the following + // block may no longer be required. + bool wasClientRedirect = + (url == m_expectedClientRedirectDest && chainEnd == m_expectedClientRedirectSrc) + || !m_webFrame->isProcessingUserGesture(); + + if (wasClientRedirect) { + if (m_webFrame->client()) + m_webFrame->client()->didCompleteClientRedirect(m_webFrame, chainEnd); + ds->appendRedirect(chainEnd); + // Make sure we clear the expected redirect since we just effectively + // completed it. + m_expectedClientRedirectSrc = KURL(); + m_expectedClientRedirectDest = KURL(); + } } // Regardless of how we got here, we are navigating to a URL so we need to @@ -614,26 +629,32 @@ void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() bool isNewNavigation; webView->didCommitLoad(&isNewNavigation); if (m_webFrame->client()) - m_webFrame->client()->didChangeLocationWithinPage(m_webFrame, isNewNavigation); + m_webFrame->client()->didNavigateWithinPage(m_webFrame, isNewNavigation); // Generate didStopLoading if loader is completed. if (webView->client() && loaderCompleted) webView->client()->didStopLoading(); } +void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() +{ + if (m_webFrame) + m_webFrame->client()->didChangeLocationWithinPage(m_webFrame); +} + void FrameLoaderClientImpl::dispatchDidPushStateWithinPage() { - // FIXME + dispatchDidNavigateWithinPage(); } void FrameLoaderClientImpl::dispatchDidReplaceStateWithinPage() { - // FIXME + dispatchDidNavigateWithinPage(); } void FrameLoaderClientImpl::dispatchDidPopStateWithinPage() { - // FIXME + // Ignored since dispatchDidNavigateWithinPage was already called. } void FrameLoaderClientImpl::dispatchWillClose() @@ -700,6 +721,12 @@ void FrameLoaderClientImpl::dispatchDidReceiveTitle(const String& title) m_webFrame->client()->didReceiveTitle(m_webFrame, title); } +void FrameLoaderClientImpl::dispatchDidChangeIcons() +{ + if (m_webFrame->client()) + m_webFrame->client()->didChangeIcons(m_webFrame); +} + void FrameLoaderClientImpl::dispatchDidCommitLoad() { WebViewImpl* webview = m_webFrame->viewImpl(); @@ -708,9 +735,6 @@ void FrameLoaderClientImpl::dispatchDidCommitLoad() if (m_webFrame->client()) m_webFrame->client()->didCommitProvisionalLoad(m_webFrame, isNewNavigation); - - if (webview->devToolsAgentPrivate()) - webview->devToolsAgentPrivate()->didCommitProvisionalLoad(m_webFrame, isNewNavigation); } void FrameLoaderClientImpl::dispatchDidFailProvisionalLoad( @@ -762,12 +786,14 @@ void FrameLoaderClientImpl::dispatchDidFinishLoad() void FrameLoaderClientImpl::dispatchDidFirstLayout() { + if (m_webFrame->client()) + m_webFrame->client()->didFirstLayout(m_webFrame); } void FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout() { - // FIXME: called when webkit finished layout of a page that was visually non-empty. - // All resources have not necessarily finished loading. + if (m_webFrame->client()) + m_webFrame->client()->didFirstVisuallyNonEmptyLayout(m_webFrame); } Frame* FrameLoaderClientImpl::dispatchCreatePage() @@ -797,38 +823,6 @@ void FrameLoaderClientImpl::dispatchShow() webView->client()->show(webView->initialNavigationPolicy()); } -static bool shouldTreatAsAttachment(const ResourceResponse& response) -{ - const String& contentDisposition = - response.httpHeaderField("Content-Disposition"); - if (contentDisposition.isEmpty()) - return false; - - // Some broken sites just send - // Content-Disposition: ; filename="file" - // screen those out here. - if (contentDisposition.startsWith(";")) - return false; - - if (contentDisposition.startsWith("inline", false)) - return false; - - // Some broken sites just send - // Content-Disposition: filename="file" - // without a disposition token... screen those out. - if (contentDisposition.startsWith("filename", false)) - return false; - - // Also in use is Content-Disposition: name="file" - if (contentDisposition.startsWith("name", false)) - return false; - - // We have a content-disposition of "attachment" or unknown. - // RFC 2183, section 2.8 says that an unknown disposition - // value should be treated as "attachment" - return true; -} - void FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType( FramePolicyFunction function, const String& mimeType, @@ -843,7 +837,7 @@ void FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType( if (statusCode == 204 || statusCode == 205) { // The server does not want us to replace the page contents. action = PolicyIgnore; - } else if (shouldTreatAsAttachment(response)) { + } else if (WebCore::contentDispositionType(response.httpHeaderField("Content-Disposition")) == WebCore::ContentDispositionAttachment) { // The server wants us to download instead of replacing the page contents. // Downloading is handled by the embedder, but we still get the initial // response so that we can ignore it and clean up properly. @@ -898,51 +892,48 @@ void FrameLoaderClientImpl::dispatchDecidePolicyForNavigationAction( // The null check here is to fix a crash that seems strange // (see - https://bugs.webkit.org/show_bug.cgi?id=23554). if (m_webFrame->client() && !request.url().isNull()) { - WebNavigationPolicy navigationPolicy = WebNavigationPolicyCurrentTab; - actionSpecifiesNavigationPolicy(action, &navigationPolicy); - - // Give the delegate a chance to change the navigation policy. - const WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl(); - if (ds) { - KURL url = ds->request().url(); - if (url.protocolIs(backForwardNavigationScheme)) { - handleBackForwardNavigation(url); - navigationPolicy = WebNavigationPolicyIgnore; - } else { - bool isRedirect = ds->hasRedirectChain(); - - WebNavigationType webnavType = - WebDataSourceImpl::toWebNavigationType(action.type()); - - RefPtr<Node> node; - for (const Event* event = action.event(); event; event = event->underlyingEvent()) { - if (event->isMouseEvent()) { - const MouseEvent* mouseEvent = - static_cast<const MouseEvent*>(event); - node = m_webFrame->frame()->eventHandler()->hitTestResultAtPoint( - mouseEvent->absoluteLocation(), false).innerNonSharedNode(); - break; - } - } - WebNode originatingNode(node); - - navigationPolicy = m_webFrame->client()->decidePolicyForNavigation( - m_webFrame, ds->request(), webnavType, originatingNode, - navigationPolicy, isRedirect); - } - } - - if (navigationPolicy == WebNavigationPolicyCurrentTab) - policyAction = PolicyUse; - else if (navigationPolicy == WebNavigationPolicyDownload) - policyAction = PolicyDownload; - else { - if (navigationPolicy != WebNavigationPolicyIgnore) { - WrappedResourceRequest webreq(request); - m_webFrame->client()->loadURLExternally(m_webFrame, webreq, navigationPolicy); - } - policyAction = PolicyIgnore; - } + WebNavigationPolicy navigationPolicy = WebNavigationPolicyCurrentTab; + actionSpecifiesNavigationPolicy(action, &navigationPolicy); + + // Give the delegate a chance to change the navigation policy. + const WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl(); + if (ds) { + KURL url = ds->request().url(); + ASSERT(!url.protocolIs(backForwardNavigationScheme)); + + bool isRedirect = ds->hasRedirectChain(); + + WebNavigationType webnavType = + WebDataSourceImpl::toWebNavigationType(action.type()); + + RefPtr<Node> node; + for (const Event* event = action.event(); event; event = event->underlyingEvent()) { + if (event->isMouseEvent()) { + const MouseEvent* mouseEvent = + static_cast<const MouseEvent*>(event); + node = m_webFrame->frame()->eventHandler()->hitTestResultAtPoint( + mouseEvent->absoluteLocation(), false).innerNonSharedNode(); + break; + } + } + WebNode originatingNode(node); + + navigationPolicy = m_webFrame->client()->decidePolicyForNavigation( + m_webFrame, ds->request(), webnavType, originatingNode, + navigationPolicy, isRedirect); + } + + if (navigationPolicy == WebNavigationPolicyCurrentTab) + policyAction = PolicyUse; + else if (navigationPolicy == WebNavigationPolicyDownload) + policyAction = PolicyDownload; + else { + if (navigationPolicy != WebNavigationPolicyIgnore) { + WrappedResourceRequest webreq(request); + m_webFrame->client()->loadURLExternally(m_webFrame, webreq, navigationPolicy); + } + policyAction = PolicyIgnore; + } } (m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction); @@ -958,6 +949,12 @@ void FrameLoaderClientImpl::dispatchUnableToImplementPolicy(const ResourceError& m_webFrame->client()->unableToImplementPolicyWithError(m_webFrame, error); } +void FrameLoaderClientImpl::dispatchWillSendSubmitEvent(HTMLFormElement* form) +{ + if (m_webFrame->client()) + m_webFrame->client()->willSendSubmitEvent(m_webFrame, WebFormElement(form)); +} + void FrameLoaderClientImpl::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState) { @@ -1075,7 +1072,7 @@ void FrameLoaderClientImpl::finishedLoading(DocumentLoader* dl) // However, we only want to do this if makeRepresentation has been called, to // match the behavior on the Mac. if (m_hasRepresentation) - dl->frameLoader()->setEncoding("", false); + dl->frameLoader()->writer()->setEncoding("", false); } } @@ -1087,10 +1084,28 @@ void FrameLoaderClientImpl::updateGlobalHistoryRedirectLinks() { } -bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem*) const +bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem* item) const { - // FIXME - return true; + const KURL& url = item->url(); + if (!url.protocolIs(backForwardNavigationScheme)) + return true; + + // Else, we'll punt this history navigation to the embedder. It is + // necessary that we intercept this here, well before the FrameLoader + // has made any state changes for this history traversal. + + bool ok; + int offset = url.lastPathComponent().toIntStrict(&ok); + if (!ok) { + ASSERT_NOT_REACHED(); + return false; + } + + WebViewImpl* webview = m_webFrame->viewImpl(); + if (webview->client()) + webview->client()->navigateBackForwardSoon(offset); + + return false; } void FrameLoaderClientImpl::dispatchDidAddBackForwardItem(HistoryItem*) const @@ -1332,6 +1347,19 @@ PassRefPtr<Frame> FrameLoaderClientImpl::createFrame( return m_webFrame->createChildFrame(frameRequest, ownerElement); } +void FrameLoaderClientImpl::didTransferChildFrameToNewDocument() +{ + ASSERT(m_webFrame->frame()->ownerElement()); + + WebFrameImpl* newParent = static_cast<WebFrameImpl*>(m_webFrame->parent()); + if (!newParent || !newParent->client()) + return; + + // Replace the client since the old client may be destroyed when the + // previous page is closed. + m_webFrame->setClient(newParent->client()); +} + PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin( const IntSize& size, // FIXME: how do we use this? HTMLPlugInElement* element, @@ -1341,20 +1369,6 @@ PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin( const String& mimeType, bool loadManually) { -#if !OS(WINDOWS) - // WebCore asks us to make a plugin even if we don't have a - // registered handler, with a comment saying it's so we can display - // the broken plugin icon. In Chromium, we normally register a - // fallback plugin handler that allows you to install a missing - // plugin. Since we don't yet have a default plugin handler, we - // need to return null here rather than going through all the - // plugin-creation IPCs only to discover we don't have a plugin - // registered, which causes a crash. - // FIXME: remove me once we have a default plugin. - if (objectContentType(url, mimeType) != ObjectContentNetscapePlugin) - return 0; -#endif - if (!m_webFrame->client()) return 0; @@ -1452,29 +1466,24 @@ bool FrameLoaderClientImpl::actionSpecifiesNavigationPolicy( const NavigationAction& action, WebNavigationPolicy* policy) { - if ((action.type() != NavigationTypeLinkClicked) || !action.event()->isMouseEvent()) + const MouseEvent* event = 0; + if (action.type() == NavigationTypeLinkClicked + && action.event()->isMouseEvent()) + event = static_cast<const MouseEvent*>(action.event()); + else if (action.type() == NavigationTypeFormSubmitted + && action.event() + && action.event()->underlyingEvent() + && action.event()->underlyingEvent()->isMouseEvent()) + event = static_cast<const MouseEvent*>(action.event()->underlyingEvent()); + + if (!event) return false; - const MouseEvent* event = static_cast<const MouseEvent*>(action.event()); return WebViewImpl::navigationPolicyFromMouseEvent( event->button(), event->ctrlKey(), event->shiftKey(), event->altKey(), event->metaKey(), policy); } -void FrameLoaderClientImpl::handleBackForwardNavigation(const KURL& url) -{ - ASSERT(url.protocolIs(backForwardNavigationScheme)); - - bool ok; - int offset = url.lastPathComponent().toIntStrict(&ok); - if (!ok) - return; - - WebViewImpl* webview = m_webFrame->viewImpl(); - if (webview->client()) - webview->client()->navigateBackForwardSoon(offset); -} - PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver() { WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader( diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.h b/WebKit/chromium/src/FrameLoaderClientImpl.h index 901600c..25be623 100644 --- a/WebKit/chromium/src/FrameLoaderClientImpl.h +++ b/WebKit/chromium/src/FrameLoaderClientImpl.h @@ -31,14 +31,12 @@ #ifndef FrameLoaderClientImpl_h #define FrameLoaderClientImpl_h -// FIXME: remove this relative path once consumers from glue are removed. -#include "../public/WebNavigationPolicy.h" #include "FrameLoaderClient.h" #include "KURL.h" +#include "WebNavigationPolicy.h" #include <wtf/PassOwnPtr.h> #include <wtf/RefPtr.h> - namespace WebKit { class WebFrameImpl; @@ -89,11 +87,11 @@ public: virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier); virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&); virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int length); - virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const WebCore::ScriptString&); virtual void dispatchDidHandleOnloadEvents(); virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); virtual void dispatchDidCancelClientRedirect(); virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate); + virtual void dispatchDidNavigateWithinPage(); virtual void dispatchDidChangeLocationWithinPage(); virtual void dispatchDidPushStateWithinPage(); virtual void dispatchDidReplaceStateWithinPage(); @@ -102,6 +100,7 @@ public: virtual void dispatchDidReceiveIcon(); virtual void dispatchDidStartProvisionalLoad(); virtual void dispatchDidReceiveTitle(const WebCore::String& title); + virtual void dispatchDidChangeIcons(); virtual void dispatchDidCommitLoad(); virtual void dispatchDidFailProvisionalLoad(const WebCore::ResourceError&); virtual void dispatchDidFailLoad(const WebCore::ResourceError&); @@ -116,6 +115,7 @@ public: virtual void dispatchDecidePolicyForNavigationAction(WebCore::FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState> form_state); virtual void cancelPolicyCheck(); virtual void dispatchUnableToImplementPolicy(const WebCore::ResourceError&); + virtual void dispatchWillSendSubmitEvent(WebCore::HTMLFormElement*); virtual void dispatchWillSubmitForm(WebCore::FramePolicyFunction, PassRefPtr<WebCore::FormState>); virtual void dispatchDidLoadMainResource(WebCore::DocumentLoader*); virtual void revertToProvisionalState(WebCore::DocumentLoader*); @@ -174,6 +174,7 @@ public: WebCore::HTMLFrameOwnerElement* ownerElement, const WebCore::String& referrer, bool allowsScrolling, int marginWidth, int marginHeight); + virtual void didTransferChildFrameToNewDocument(); virtual PassRefPtr<WebCore::Widget> createPlugin( const WebCore::IntSize&, WebCore::HTMLPlugInElement*, const WebCore::KURL&, const Vector<WebCore::String>&, const Vector<WebCore::String>&, @@ -194,6 +195,8 @@ public: virtual bool allowJavaScript(bool enabledPerSettings); virtual bool allowPlugins(bool enabledPerSettings); virtual bool allowImages(bool enabledPerSettings); + virtual void didNotAllowScript(); + virtual void didNotAllowPlugins(); private: void makeDocumentView(); @@ -203,9 +206,6 @@ private: static bool actionSpecifiesNavigationPolicy( const WebCore::NavigationAction& action, WebNavigationPolicy* policy); - // Called when a dummy back-forward navigation is intercepted. - void handleBackForwardNavigation(const WebCore::KURL&); - PassOwnPtr<WebPluginLoadObserver> pluginLoadObserver(); // The WebFrame that owns this object and manages its lifetime. Therefore, diff --git a/WebKit/chromium/src/GLES2Context.cpp b/WebKit/chromium/src/GLES2Context.cpp new file mode 100644 index 0000000..b4b4bb2 --- /dev/null +++ b/WebKit/chromium/src/GLES2Context.cpp @@ -0,0 +1,115 @@ +/* + * 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 "GLES2Context.h" +#include "GLES2ContextInternal.h" +#include "IntSize.h" +#include "WebGLES2Context.h" +#include "WebKit.h" +#include "WebKitClient.h" +#include "WebViewImpl.h" +#include <wtf/OwnPtr.h> + +// There are two levels of delegation in this file: +// +// 1. GLES2Context delegates to GLES2ContextInternal. This is done +// so that we have some place to store data members common among +// implementations. +// +// 2. GLES2ContextInternal delegates to an implementation of +// WebGLES2Context. This is done so we have a place to inject an +// implementation which creates the GL ES context. + +using namespace WebKit; + +namespace WebCore { + +PassOwnPtr<GLES2ContextInternal> GLES2ContextInternal::create(WebGLES2Context* impl, bool owns) +{ + PassOwnPtr<GLES2ContextInternal> result = new GLES2ContextInternal(impl, owns); + return result; +} + +PassOwnPtr<GLES2Context> GLES2Context::create(PassOwnPtr<GLES2ContextInternal> internal) +{ + PassOwnPtr<GLES2Context> result = new GLES2Context(); + result->m_internal = internal; + return result; +} + +GLES2Context::GLES2Context() +{ +} + +GLES2Context::~GLES2Context() +{ +} + +bool GLES2Context::makeCurrent() +{ + WebGLES2Context* webContext = m_internal->getWebGLES2Context(); + if (!webContext) + return false; + return webContext->makeCurrent(); +} + +bool GLES2Context::destroy() +{ + WebGLES2Context* webContext = m_internal->getWebGLES2Context(); + if (!webContext) + return false; + return webContext->destroy(); +} + +bool GLES2Context::swapBuffers() +{ + WebGLES2Context* webContext = m_internal->getWebGLES2Context(); + if (!webContext) + return false; + return webContext->swapBuffers(); +} + +void GLES2Context::resizeOffscreenContent(const IntSize& size) +{ + WebGLES2Context* webContext = m_internal->getWebGLES2Context(); + ASSERT(webContext); + webContext->resizeOffscreenContent(size); +} + +unsigned GLES2Context::getOffscreenContentParentTextureId() +{ + WebGLES2Context* webContext = m_internal->getWebGLES2Context(); + ASSERT(webContext); + return webContext->getOffscreenContentParentTextureId(); +} + +} // namespace WebCore diff --git a/WebKit/chromium/src/GLES2ContextInternal.cpp b/WebKit/chromium/src/GLES2ContextInternal.cpp new file mode 100644 index 0000000..33eb602 --- /dev/null +++ b/WebKit/chromium/src/GLES2ContextInternal.cpp @@ -0,0 +1,52 @@ +/* + * 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 "GLES2ContextInternal.h" + +#include "WebGLES2Context.h" + +namespace WebCore { + +GLES2ContextInternal::GLES2ContextInternal(WebKit::WebGLES2Context* impl, bool owns) + : m_impl(impl) + , m_owns(owns) +{ +} + +GLES2ContextInternal::~GLES2ContextInternal() +{ + if (m_owns) + delete m_impl; +} + +} // namespace WebCore + diff --git a/WebKit/chromium/src/GLES2ContextInternal.h b/WebKit/chromium/src/GLES2ContextInternal.h new file mode 100644 index 0000000..4668311 --- /dev/null +++ b/WebKit/chromium/src/GLES2ContextInternal.h @@ -0,0 +1,55 @@ +/* + * 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 <wtf/PassOwnPtr.h> + +namespace WebKit { +class WebGLES2Context; +} + +namespace WebCore { + +class GLES2ContextInternal { +public: + // If 'owns' is set to true, this GLES2ContextInternal takes ownership of the passed in WebKit::WebGLES2Context. + static PassOwnPtr<GLES2ContextInternal> create(WebKit::WebGLES2Context* impl, bool owns); + + WebKit::WebGLES2Context* getWebGLES2Context() { return m_impl; } + + ~GLES2ContextInternal(); + +private: + GLES2ContextInternal(WebKit::WebGLES2Context* impl, bool owns); + + WebKit::WebGLES2Context* m_impl; + bool m_owns; +}; + +} diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp index 83574da..fec0b20 100644 --- a/WebKit/chromium/src/GraphicsContext3D.cpp +++ b/WebKit/chromium/src/GraphicsContext3D.cpp @@ -35,61 +35,61 @@ #include "GraphicsContext3D.h" #include "CachedImage.h" -#include "CString.h" +#include "Chrome.h" +#include "ChromeClientImpl.h" #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" #include "ImageBuffer.h" #include "ImageData.h" -#include "NotImplemented.h" #include "WebGLBuffer.h" -#include "WebGLByteArray.h" -#include "WebGLFloatArray.h" +#include "Int8Array.h" +#include "Float32Array.h" #include "WebGLFramebuffer.h" -#include "WebGLIntArray.h" +#include "Int32Array.h" #include "WebGLProgram.h" #include "WebGLRenderbuffer.h" #include "WebGLRenderingContext.h" #include "WebGLShader.h" #include "WebGLTexture.h" -#include "WebGLUnsignedByteArray.h" +#include "Uint8Array.h" +#include "WebGLLayerChromium.h" +#include "WebGraphicsContext3D.h" +#include "WebGraphicsContext3DDefaultImpl.h" +#include "WebKit.h" +#include "WebKitClient.h" +#include "WebViewImpl.h" #include <stdio.h> #include <wtf/FastMalloc.h> - -#if OS(WINDOWS) -#include <windows.h> -#endif - -#include "GL/glew.h" +#include <wtf/text/CString.h> #if PLATFORM(CG) #include "GraphicsContext.h" #include <CoreGraphics/CGContext.h> -#include <CoreGraphics/CGBitmapContext.h> #include <CoreGraphics/CGImage.h> -#include <OpenGL/OpenGL.h> -#else -#define FLIP_FRAMEBUFFER_VERTICALLY -#endif - -#if PLATFORM(SKIA) -#include "NativeImageSkia.h" -#endif - -#if OS(DARWIN) -#define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER -#endif - -#if OS(LINUX) -#include <dlfcn.h> -#include "GL/glxew.h" #endif -using namespace std; +// using namespace std; + +// There are two levels of delegation in this file: +// +// 1. GraphicsContext3D delegates to GraphicsContext3DInternal. This is done +// so that we have some place to store data members common among +// implementations; GraphicsContext3D only provides us the m_internal +// pointer. We always delegate to the GraphicsContext3DInternal. While we +// could sidestep it and go directly to the WebGraphicsContext3D in some +// cases, it is better for consistency to always delegate through it. +// +// 2. GraphicsContext3DInternal delegates to an implementation of +// WebGraphicsContext3D. This is done so we have a place to inject an +// implementation which remotes the OpenGL calls across processes. +// +// The legacy, in-process, implementation uses WebGraphicsContext3DDefaultImpl. namespace WebCore { -// GraphicsContext3DInternal ----------------------------------------------------- +//---------------------------------------------------------------------- +// GraphicsContext3DInternal // Uncomment this to render to a separate window for debugging // #define RENDER_TO_DEBUGGING_WINDOW @@ -98,2121 +98,1235 @@ namespace WebCore { class GraphicsContext3DInternal { public: - GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs); + GraphicsContext3DInternal(); ~GraphicsContext3DInternal(); - bool makeContextCurrent(); + bool initialize(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow); PlatformGraphicsContext3D platformGraphicsContext3D() const; Platform3DObject platformTexture() const; + bool makeContextCurrent(); + + int sizeInBytes(int type); + void reshape(int width, int height); + void paintRenderingResultsToCanvas(WebGLRenderingContext* context); void beginPaint(WebGLRenderingContext* context); + void endPaint(); - bool validateTextureTarget(int target); - bool validateTextureParameter(int param); + void prepareTexture(); +#if USE(ACCELERATED_COMPOSITING) + WebGLLayerChromium* platformLayer() const; +#endif + bool isGLES2Compliant() const; + + //---------------------------------------------------------------------- + // Entry points for WebGL. + // void activeTexture(unsigned long texture); - void bindBuffer(unsigned long target, - WebGLBuffer* buffer); - void bindFramebuffer(unsigned long target, - WebGLFramebuffer* framebuffer); - void bindTexture(unsigned long target, - WebGLTexture* texture); - void bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage); + void attachShader(WebGLProgram* program, WebGLShader* shader); + void bindAttribLocation(WebGLProgram*, unsigned long index, const String& name); + void bindBuffer(unsigned long target, WebGLBuffer*); + void bindFramebuffer(unsigned long target, WebGLFramebuffer*); + void bindRenderbuffer(unsigned long target, WebGLRenderbuffer*); + void bindTexture(unsigned long target, WebGLTexture* texture); + void blendColor(double red, double green, double blue, double alpha); + void blendEquation(unsigned long mode); + void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha); + void blendFunc(unsigned long sfactor, unsigned long dfactor); + void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha); + + void bufferData(unsigned long target, int size, unsigned long usage); + void bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage); + void bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage); + void bufferSubData(unsigned long target, long offset, ArrayBuffer* data); + void bufferSubData(unsigned long target, long offset, ArrayBufferView* data); + + unsigned long checkFramebufferStatus(unsigned long target); + void clear(unsigned long mask); + void clearColor(double red, double green, double blue, double alpha); + void clearDepth(double depth); + void clearStencil(long s); + void colorMask(bool red, bool green, bool blue, bool alpha); + void compileShader(WebGLShader*); + + void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border); + void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height); + void cullFace(unsigned long mode); + void depthFunc(unsigned long func); + void depthMask(bool flag); + void depthRange(double zNear, double zFar); + void detachShader(WebGLProgram*, WebGLShader*); + void disable(unsigned long cap); void disableVertexAttribArray(unsigned long index); + void drawArrays(unsigned long mode, long first, long count); + void drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset); + + void enable(unsigned long cap); void enableVertexAttribArray(unsigned long index); - unsigned long getError(); + void finish(); + void flush(); + void framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer*); + void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture*, long level); + void frontFace(unsigned long mode); + void generateMipmap(unsigned long target); + + bool getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo&); + bool getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo&); + + void getAttachedShaders(WebGLProgram* program, int maxCount, int* count, unsigned int* shaders); + + int getAttribLocation(WebGLProgram*, const String& name); + + void getBooleanv(unsigned long pname, unsigned char* value); + + void getBufferParameteriv(unsigned long target, unsigned long pname, int* value); + GraphicsContext3D::Attributes getContextAttributes(); + + unsigned long getError(); + + void getFloatv(unsigned long pname, float* value); + + void getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value); + + void getIntegerv(unsigned long pname, int* value); + + void getProgramiv(WebGLProgram* program, unsigned long pname, int* value); + + String getProgramInfoLog(WebGLProgram*); + + void getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value); + + void getShaderiv(WebGLShader*, unsigned long pname, int* value); + + String getShaderInfoLog(WebGLShader*); + + String getShaderSource(WebGLShader*); + String getString(unsigned long name); + + void getTexParameterfv(unsigned long target, unsigned long pname, float* value); + void getTexParameteriv(unsigned long target, unsigned long pname, int* value); + + void getUniformfv(WebGLProgram* program, long location, float* value); + void getUniformiv(WebGLProgram* program, long location, int* value); + + long getUniformLocation(WebGLProgram*, const String& name); + + void getVertexAttribfv(unsigned long index, unsigned long pname, float* value); + void getVertexAttribiv(unsigned long index, unsigned long pname, int* value); + + long getVertexAttribOffset(unsigned long index, unsigned long pname); + + void hint(unsigned long target, unsigned long mode); + bool isBuffer(WebGLBuffer*); + bool isEnabled(unsigned long cap); + bool isFramebuffer(WebGLFramebuffer*); + bool isProgram(WebGLProgram*); + bool isRenderbuffer(WebGLRenderbuffer*); + bool isShader(WebGLShader*); + bool isTexture(WebGLTexture*); + void lineWidth(double); + void linkProgram(WebGLProgram*); + void pixelStorei(unsigned long pname, long param); + void polygonOffset(double factor, double units); + + void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data); + + void releaseShaderCompiler(); + void renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height); + void sampleCoverage(double value, bool invert); + void scissor(long x, long y, unsigned long width, unsigned long height); + void shaderSource(WebGLShader*, const String& string); + void stencilFunc(unsigned long func, long ref, unsigned long mask); + void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask); + void stencilMask(unsigned long mask); + void stencilMaskSeparate(unsigned long face, unsigned long mask); + void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass); + void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass); + + // These next several functions return an error code (0 if no errors) rather than using an ExceptionCode. + // Currently they return -1 on any error. + int texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels); + + void texParameterf(unsigned target, unsigned pname, float param); + void texParameteri(unsigned target, unsigned pname, int param); + + int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels); + + void uniform1f(long location, float x); + void uniform1fv(long location, float* v, int size); + void uniform1i(long location, int x); + void uniform1iv(long location, int* v, int size); + void uniform2f(long location, float x, float y); + void uniform2fv(long location, float* v, int size); + void uniform2i(long location, int x, int y); + void uniform2iv(long location, int* v, int size); + void uniform3f(long location, float x, float y, float z); + void uniform3fv(long location, float* v, int size); + void uniform3i(long location, int x, int y, int z); + void uniform3iv(long location, int* v, int size); + void uniform4f(long location, float x, float y, float z, float w); + void uniform4fv(long location, float* v, int size); + void uniform4i(long location, int x, int y, int z, int w); + void uniform4iv(long location, int* v, int size); + void uniformMatrix2fv(long location, bool transpose, float* value, int size); + void uniformMatrix3fv(long location, bool transpose, float* value, int size); + void uniformMatrix4fv(long location, bool transpose, float* value, int size); + + void useProgram(WebGLProgram*); + void validateProgram(WebGLProgram*); + + void vertexAttrib1f(unsigned long indx, float x); + void vertexAttrib1fv(unsigned long indx, float* values); + void vertexAttrib2f(unsigned long indx, float x, float y); + void vertexAttrib2fv(unsigned long indx, float* values); + void vertexAttrib3f(unsigned long indx, float x, float y, float z); + void vertexAttrib3fv(unsigned long indx, float* values); + void vertexAttrib4f(unsigned long indx, float x, float y, float z, float w); + void vertexAttrib4fv(unsigned long indx, float* values); void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, unsigned long stride, unsigned long offset); - void viewportImpl(long x, long y, unsigned long width, unsigned long height); - void synthesizeGLError(unsigned long error); + void viewport(long x, long y, unsigned long width, unsigned long height); -private: - GraphicsContext3D::Attributes m_attrs; + unsigned createBuffer(); + unsigned createFramebuffer(); + unsigned createProgram(); + unsigned createRenderbuffer(); + unsigned createShader(unsigned long); + unsigned createTexture(); - unsigned int m_texture; - unsigned int m_fbo; - unsigned int m_depthBuffer; - unsigned int m_cachedWidth, m_cachedHeight; + void deleteBuffer(unsigned); + void deleteFramebuffer(unsigned); + void deleteProgram(unsigned); + void deleteRenderbuffer(unsigned); + void deleteShader(unsigned); + void deleteTexture(unsigned); - // For tracking which FBO is bound - unsigned int m_boundFBO; + void synthesizeGLError(unsigned long error); -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - unsigned char* m_scanline; - void flipVertically(unsigned char* framebuffer, - unsigned int width, - unsigned int height); +private: + OwnPtr<WebKit::WebGraphicsContext3D> m_impl; +#if USE(ACCELERATED_COMPOSITING) + RefPtr<WebGLLayerChromium> m_compositingLayer; #endif - - // Note: we aren't currently using this information, but we will - // need to in order to verify that all enabled vertex arrays have - // a valid buffer bound -- to avoid crashes on certain cards. - unsigned int m_boundArrayBuffer; - class VertexAttribPointerState { - public: - VertexAttribPointerState(); - - bool enabled; - unsigned long buffer; - unsigned long indx; - int size; - int type; - bool normalized; - unsigned long stride; - unsigned long offset; - }; - - enum { - NumTrackedPointerStates = 2 - }; - VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates]; - - // Errors raised by synthesizeGLError(). - ListHashSet<unsigned long> m_syntheticErrors; - #if PLATFORM(SKIA) // If the width and height of the Canvas's backing store don't // match those that we were given in the most recent call to // reshape(), then we need an intermediate bitmap to read back the // frame buffer into. This seems to happen when CSS styles are // used to resize the Canvas. - SkBitmap* m_resizingBitmap; + SkBitmap m_resizingBitmap; #endif - static bool s_initializedGLEW; -#if OS(WINDOWS) - HWND m_canvasWindow; - HDC m_canvasDC; - HGLRC m_contextObj; -#elif PLATFORM(CG) - CGLPBufferObj m_pbuffer; - CGLContextObj m_contextObj; +#if PLATFORM(CG) unsigned char* m_renderOutput; -#elif OS(LINUX) - GLXContext m_contextObj; - GLXPbuffer m_pbuffer; - - // In order to avoid problems caused by linking against libGL, we - // dynamically look up all the symbols we need. - // http://code.google.com/p/chromium/issues/detail?id=16800 - class GLConnection { - public: - ~GLConnection(); - - static GLConnection* create(); - - GLXFBConfig* chooseFBConfig(int screen, const int *attrib_list, int *nelements) - { - return m_glXChooseFBConfig(m_display, screen, attrib_list, nelements); - } - - GLXContext createNewContext(GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) - { - return m_glXCreateNewContext(m_display, config, renderType, shareList, direct); - } - - GLXPbuffer createPbuffer(GLXFBConfig config, const int *attribList) - { - return m_glXCreatePbuffer(m_display, config, attribList); - } - - void destroyPbuffer(GLXPbuffer pbuf) - { - m_glXDestroyPbuffer(m_display, pbuf); - } - - Bool makeCurrent(GLXDrawable drawable, GLXContext ctx) - { - return m_glXMakeCurrent(m_display, drawable, ctx); - } - - void destroyContext(GLXContext ctx) - { - m_glXDestroyContext(m_display, ctx); - } - - GLXContext getCurrentContext() - { - return m_glXGetCurrentContext(); - } - - private: - Display* m_display; - void* m_libGL; - PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig; - PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext; - PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer; - PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer; - typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx); - PFNGLXMAKECURRENTPROC m_glXMakeCurrent; - typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx); - PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext; - typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void); - PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext; - - GLConnection(Display* display, - void* libGL, - PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig, - PFNGLXCREATENEWCONTEXTPROC createNewContext, - PFNGLXCREATEPBUFFERPROC createPbuffer, - PFNGLXDESTROYPBUFFERPROC destroyPbuffer, - PFNGLXMAKECURRENTPROC makeCurrent, - PFNGLXDESTROYCONTEXTPROC destroyContext, - PFNGLXGETCURRENTCONTEXTPROC getCurrentContext) - : m_libGL(libGL) - , m_display(display) - , m_glXChooseFBConfig(chooseFBConfig) - , m_glXCreateNewContext(createNewContext) - , m_glXCreatePbuffer(createPbuffer) - , m_glXDestroyPbuffer(destroyPbuffer) - , m_glXMakeCurrent(makeCurrent) - , m_glXDestroyContext(destroyContext) - , m_glXGetCurrentContext(getCurrentContext) - { - } - }; - - static GLConnection* s_gl; -#else - #error Must port GraphicsContext3D to your platform #endif }; -bool GraphicsContext3DInternal::s_initializedGLEW = false; - -#if OS(LINUX) -GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::s_gl = 0; - -GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::GLConnection::create() -{ - Display* dpy = XOpenDisplay(0); - if (!dpy) { - printf("GraphicsContext3D: error opening X display\n"); - return 0; - } - - // We use RTLD_GLOBAL semantics so that GLEW initialization works; - // GLEW expects to be able to open the current process's handle - // and do dlsym's of GL entry points from there. - void* libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); - if (!libGL) { - XCloseDisplay(dpy); - printf("GraphicsContext3D: error opening libGL.so.1: %s\n", dlerror()); - return 0; - } - - PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(libGL, "glXChooseFBConfig"); - PFNGLXCREATENEWCONTEXTPROC createNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(libGL, "glXCreateNewContext"); - PFNGLXCREATEPBUFFERPROC createPbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(libGL, "glXCreatePbuffer"); - PFNGLXDESTROYPBUFFERPROC destroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(libGL, "glXDestroyPbuffer"); - PFNGLXMAKECURRENTPROC makeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(libGL, "glXMakeCurrent"); - PFNGLXDESTROYCONTEXTPROC destroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(libGL, "glXDestroyContext"); - PFNGLXGETCURRENTCONTEXTPROC getCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(libGL, "glXGetCurrentContext"); - if (!chooseFBConfig || !createNewContext || !createPbuffer - || !destroyPbuffer || !makeCurrent || !destroyContext - || !getCurrentContext) { - XCloseDisplay(dpy); - dlclose(libGL); - printf("GraphicsContext3D: error looking up bootstrapping entry points\n"); - return 0; - } - return new GLConnection(dpy, - libGL, - chooseFBConfig, - createNewContext, - createPbuffer, - destroyPbuffer, - makeCurrent, - destroyContext, - getCurrentContext); -} - -GraphicsContext3DInternal::GLConnection::~GLConnection() -{ - XCloseDisplay(m_display); - dlclose(m_libGL); -} - -#endif // OS(LINUX) - -GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState() - : enabled(false) - , buffer(0) - , indx(0) - , size(0) - , type(0) - , normalized(false) - , stride(0) - , offset(0) -{ -} - -GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs) - : m_attrs(attrs) - , m_texture(0) - , m_fbo(0) - , m_depthBuffer(0) - , m_boundFBO(0) -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - , m_scanline(0) -#endif - , m_boundArrayBuffer(0) +GraphicsContext3DInternal::GraphicsContext3DInternal() #if PLATFORM(SKIA) - , m_resizingBitmap(0) -#endif -#if OS(WINDOWS) - , m_canvasWindow(0) - , m_canvasDC(0) - , m_contextObj(0) #elif PLATFORM(CG) - , m_pbuffer(0) - , m_contextObj(0) - , m_renderOutput(0) -#elif OS(LINUX) - , m_contextObj(0) - , m_pbuffer(0) + : m_renderOutput(0) #else #error Must port to your platform #endif { - // FIXME: we need to take into account the user's requested - // context creation attributes, in particular stencil and - // antialias, and determine which could and could not be honored - // based on the capabilities of the OpenGL implementation. - m_attrs.alpha = true; - m_attrs.depth = true; - m_attrs.stencil = false; - m_attrs.antialias = false; - m_attrs.premultipliedAlpha = true; - -#if OS(WINDOWS) - WNDCLASS wc; - if (!GetClassInfo(GetModuleHandle(0), L"CANVASGL", &wc)) { - ZeroMemory(&wc, sizeof(WNDCLASS)); - wc.style = CS_OWNDC; - wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = DefWindowProc; - wc.lpszClassName = L"CANVASGL"; - - if (!RegisterClass(&wc)) { - printf("GraphicsContext3D: RegisterClass failed\n"); - return; - } - } - - m_canvasWindow = CreateWindow(L"CANVASGL", L"CANVASGL", - WS_CAPTION, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0); - if (!m_canvasWindow) { - printf("GraphicsContext3DInternal: CreateWindow failed\n"); - return; - } - - // get the device context - m_canvasDC = GetDC(m_canvasWindow); - if (!m_canvasDC) { - printf("GraphicsContext3DInternal: GetDC failed\n"); - return; - } - - // find default pixel format - PIXELFORMATDESCRIPTOR pfd; - ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL -#ifdef RENDER_TO_DEBUGGING_WINDOW - | PFD_DOUBLEBUFFER -#endif // RENDER_TO_DEBUGGING_WINDOW - ; - int pixelformat = ChoosePixelFormat(m_canvasDC, &pfd); - - // set the pixel format for the dc - if (!SetPixelFormat(m_canvasDC, pixelformat, &pfd)) { - printf("GraphicsContext3D: SetPixelFormat failed\n"); - return; - } - - // create rendering context - m_contextObj = wglCreateContext(m_canvasDC); - if (!m_contextObj) { - printf("GraphicsContext3D: wglCreateContext failed\n"); - return; - } - - if (!wglMakeCurrent(m_canvasDC, m_contextObj)) { - printf("GraphicsContext3D: wglMakeCurrent failed\n"); - return; - } - -#ifdef RENDER_TO_DEBUGGING_WINDOW - typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); - PFNWGLSWAPINTERVALEXTPROC setSwapInterval = 0; - setSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT"); - if (setSwapInterval) - setSwapInterval(1); -#endif // RENDER_TO_DEBUGGING_WINDOW - -#elif PLATFORM(CG) - // Create a 1x1 pbuffer and associated context to bootstrap things - CGLPixelFormatAttribute attribs[] = { - (CGLPixelFormatAttribute) kCGLPFAPBuffer, - (CGLPixelFormatAttribute) 0 - }; - CGLPixelFormatObj pixelFormat; - GLint numPixelFormats; - if (CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats) != kCGLNoError) { - printf("GraphicsContext3D: error choosing pixel format\n"); - return; - } - if (!pixelFormat) { - printf("GraphicsContext3D: no pixel format selected\n"); - return; - } - CGLContextObj context; - CGLError res = CGLCreateContext(pixelFormat, 0, &context); - CGLDestroyPixelFormat(pixelFormat); - if (res != kCGLNoError) { - printf("GraphicsContext3D: error creating context\n"); - return; - } - CGLPBufferObj pbuffer; - if (CGLCreatePBuffer(1, 1, GL_TEXTURE_2D, GL_RGBA, 0, &pbuffer) != kCGLNoError) { - CGLDestroyContext(context); - printf("GraphicsContext3D: error creating pbuffer\n"); - return; - } - if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) { - CGLDestroyContext(context); - CGLDestroyPBuffer(pbuffer); - printf("GraphicsContext3D: error attaching pbuffer to context\n"); - return; - } - if (CGLSetCurrentContext(context) != kCGLNoError) { - CGLDestroyContext(context); - CGLDestroyPBuffer(pbuffer); - printf("GraphicsContext3D: error making context current\n"); - return; - } - m_pbuffer = pbuffer; - m_contextObj = context; -#elif OS(LINUX) - if (!s_gl) { - s_gl = GLConnection::create(); - if (!s_gl) - return; - } - - int configAttrs[] = { - GLX_DRAWABLE_TYPE, - GLX_PBUFFER_BIT, - GLX_RENDER_TYPE, - GLX_RGBA_BIT, - GLX_DOUBLEBUFFER, - 0, - 0 - }; - int nelements = 0; - GLXFBConfig* config = s_gl->chooseFBConfig(0, configAttrs, &nelements); - if (!config) { - printf("GraphicsContext3D: glXChooseFBConfig failed\n"); - return; - } - if (!nelements) { - printf("GraphicsContext3D: glXChooseFBConfig returned 0 elements\n"); - XFree(config); - return; - } - GLXContext context = s_gl->createNewContext(config[0], GLX_RGBA_TYPE, 0, True); - if (!context) { - printf("GraphicsContext3D: glXCreateNewContext failed\n"); - XFree(config); - return; - } - int pbufferAttrs[] = { - GLX_PBUFFER_WIDTH, - 1, - GLX_PBUFFER_HEIGHT, - 1, - 0 - }; - GLXPbuffer pbuffer = s_gl->createPbuffer(config[0], pbufferAttrs); - XFree(config); - if (!pbuffer) { - printf("GraphicsContext3D: glxCreatePbuffer failed\n"); - return; - } - if (!s_gl->makeCurrent(pbuffer, context)) { - printf("GraphicsContext3D: glXMakeCurrent failed\n"); - return; - } - m_contextObj = context; - m_pbuffer = pbuffer; -#else -#error Must port to your platform -#endif - - if (!s_initializedGLEW) { - // Initialize GLEW and check for GL 2.0 support by the drivers. - GLenum glewInitResult = glewInit(); - if (glewInitResult != GLEW_OK) { - printf("GraphicsContext3D: GLEW initialization failed\n"); - return; - } - if (!glewIsSupported("GL_VERSION_2_0")) { - printf("GraphicsContext3D: OpenGL 2.0 not supported\n"); - return; - } - s_initializedGLEW = true; - } } GraphicsContext3DInternal::~GraphicsContext3DInternal() { - makeContextCurrent(); -#ifndef RENDER_TO_DEBUGGING_WINDOW - glDeleteRenderbuffersEXT(1, &m_depthBuffer); - glDeleteTextures(1, &m_texture); -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (m_scanline) - delete[] m_scanline; -#endif - glDeleteFramebuffersEXT(1, &m_fbo); -#endif // !RENDER_TO_DEBUGGING_WINDOW -#if PLATFORM(SKIA) - if (m_resizingBitmap) - delete m_resizingBitmap; -#endif -#if OS(WINDOWS) - wglMakeCurrent(0, 0); - wglDeleteContext(m_contextObj); - ReleaseDC(m_canvasWindow, m_canvasDC); - DestroyWindow(m_canvasWindow); -#elif PLATFORM(CG) - CGLSetCurrentContext(0); - CGLDestroyContext(m_contextObj); - CGLDestroyPBuffer(m_pbuffer); +#if PLATFORM(CG) if (m_renderOutput) delete[] m_renderOutput; -#elif OS(LINUX) - s_gl->makeCurrent(0, 0); - s_gl->destroyContext(m_contextObj); - s_gl->destroyPbuffer(m_pbuffer); -#else -#error Must port to your platform #endif - m_contextObj = 0; } -bool GraphicsContext3DInternal::makeContextCurrent() +bool GraphicsContext3DInternal::initialize(GraphicsContext3D::Attributes attrs, + HostWindow* hostWindow) { -#if OS(WINDOWS) - if (wglGetCurrentContext() != m_contextObj) - if (wglMakeCurrent(m_canvasDC, m_contextObj)) - return true; -#elif PLATFORM(CG) - if (CGLGetCurrentContext() != m_contextObj) - if (CGLSetCurrentContext(m_contextObj) == kCGLNoError) - return true; -#elif OS(LINUX) - if (s_gl->getCurrentContext() != m_contextObj) - if (s_gl->makeCurrent(m_pbuffer, m_contextObj)) - return true; -#else -#error Must port to your platform + WebKit::WebGraphicsContext3D::Attributes webAttributes; + webAttributes.alpha = attrs.alpha; + webAttributes.depth = attrs.depth; + webAttributes.stencil = attrs.stencil; + webAttributes.antialias = attrs.antialias; + webAttributes.premultipliedAlpha = attrs.premultipliedAlpha; + WebKit::WebGraphicsContext3D* webContext = WebKit::webKitClient()->createGraphicsContext3D(); + if (!webContext) + return false; + + Chrome* chrome = static_cast<Chrome*>(hostWindow); + WebKit::ChromeClientImpl* chromeClientImpl = static_cast<WebKit::ChromeClientImpl*>(chrome->client()); + + WebKit::WebViewImpl* webView = chromeClientImpl->webView(); + + if (!webView) + return false; + if (!webContext->initialize(webAttributes, webView)) { + delete webContext; + return false; + } + m_impl.set(webContext); + +#if USE(ACCELERATED_COMPOSITING) + m_compositingLayer = WebGLLayerChromium::create(0); #endif - return false; + return true; } PlatformGraphicsContext3D GraphicsContext3DInternal::platformGraphicsContext3D() const { - return m_contextObj; + return m_impl.get(); } Platform3DObject GraphicsContext3DInternal::platformTexture() const { - return m_texture; + return m_impl->getPlatformTextureId(); } -static int createTextureObject(GLenum target) +void GraphicsContext3DInternal::prepareTexture() { - GLuint texture = 0; - glGenTextures(1, &texture); - glBindTexture(target, texture); - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - return texture; -} - -void GraphicsContext3DInternal::reshape(int width, int height) -{ -#ifdef RENDER_TO_DEBUGGING_WINDOW - SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height, - SWP_NOMOVE); - ShowWindow(m_canvasWindow, SW_SHOW); -#endif - - m_cachedWidth = width; - m_cachedHeight = height; - makeContextCurrent(); - -#ifndef RENDER_TO_DEBUGGING_WINDOW -#ifdef USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER - // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on Mac OS X - GLenum target = GL_TEXTURE_RECTANGLE_ARB; -#else - GLenum target = GL_TEXTURE_2D; -#endif - if (!m_texture) { - // Generate the texture object - m_texture = createTextureObject(target); - // Generate the framebuffer object - glGenFramebuffersEXT(1, &m_fbo); - // Generate the depth buffer - glGenRenderbuffersEXT(1, &m_depthBuffer); - } - - // Reallocate the color and depth buffers - glBindTexture(target, m_texture); - glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glBindTexture(target, 0); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - m_boundFBO = m_fbo; - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - printf("GraphicsContext3D: framebuffer was incomplete\n"); - - // FIXME: cleanup. - notImplemented(); - } -#endif // RENDER_TO_DEBUGGING_WINDOW - -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (m_scanline) { - delete[] m_scanline; - m_scanline = 0; - } - m_scanline = new unsigned char[width * 4]; -#endif // FLIP_FRAMEBUFFER_VERTICALLY - - glClear(GL_COLOR_BUFFER_BIT); - -#if PLATFORM(CG) - // Need to reallocate the client-side backing store. - // FIXME: make this more efficient. - if (m_renderOutput) { - delete[] m_renderOutput; - m_renderOutput = 0; - } - int rowBytes = width * 4; - m_renderOutput = new unsigned char[height * rowBytes]; -#endif // PLATFORM(CG) + m_impl->prepareTexture(); } -#ifdef FLIP_FRAMEBUFFER_VERTICALLY -void GraphicsContext3DInternal::flipVertically(unsigned char* framebuffer, - unsigned int width, - unsigned int height) +#if USE(ACCELERATED_COMPOSITING) +WebGLLayerChromium* GraphicsContext3DInternal::platformLayer() const { - unsigned char* scanline = m_scanline; - if (!scanline) - return; - unsigned int rowBytes = width * 4; - unsigned int count = height / 2; - for (unsigned int i = 0; i < count; i++) { - unsigned char* rowA = framebuffer + i * rowBytes; - unsigned char* rowB = framebuffer + (height - i - 1) * rowBytes; - // FIXME: this is where the multiplication of the alpha - // channel into the color buffer will need to occur if the - // user specifies the "premultiplyAlpha" flag in the context - // creation attributes. - memcpy(scanline, rowB, rowBytes); - memcpy(rowB, rowA, rowBytes); - memcpy(rowA, scanline, rowBytes); - } + return m_compositingLayer.get(); } #endif -void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context) +void GraphicsContext3DInternal::paintRenderingResultsToCanvas(WebGLRenderingContext* context) { - makeContextCurrent(); - -#ifdef RENDER_TO_DEBUGGING_WINDOW - SwapBuffers(m_canvasDC); -#else - // Earlier versions of this code used the GPU to flip the - // framebuffer vertically before reading it back for compositing - // via software. This code was quite complicated, used a lot of - // GPU memory, and didn't provide an obvious speedup. Since this - // vertical flip is only a temporary solution anyway until Chrome - // is fully GPU composited, it wasn't worth the complexity. - HTMLCanvasElement* canvas = context->canvas(); ImageBuffer* imageBuffer = canvas->buffer(); unsigned char* pixels = 0; - bool mustRestoreFBO = (m_boundFBO != m_fbo); - if (mustRestoreFBO) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); #if PLATFORM(SKIA) const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap(); const SkBitmap* readbackBitmap = 0; ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); - if (canvasBitmap->width() == m_cachedWidth && canvasBitmap->height() == m_cachedHeight) { + if (canvasBitmap->width() == m_impl->width() && canvasBitmap->height() == m_impl->height()) { // This is the fastest and most common case. We read back // directly into the canvas's backing store. readbackBitmap = canvasBitmap; - if (m_resizingBitmap) { - delete m_resizingBitmap; - m_resizingBitmap = 0; - } + m_resizingBitmap.reset(); } else { // We need to allocate a temporary bitmap for reading back the // pixel data. We will then use Skia to rescale this bitmap to // the size of the canvas's backing store. - if (m_resizingBitmap && (m_resizingBitmap->width() != m_cachedWidth || m_resizingBitmap->height() != m_cachedHeight)) { - delete m_resizingBitmap; - m_resizingBitmap = 0; - } - if (!m_resizingBitmap) { - m_resizingBitmap = new SkBitmap(); - m_resizingBitmap->setConfig(SkBitmap::kARGB_8888_Config, - m_cachedWidth, - m_cachedHeight); - if (!m_resizingBitmap->allocPixels()) { - delete m_resizingBitmap; - m_resizingBitmap = 0; + if (m_resizingBitmap.width() != m_impl->width() || m_resizingBitmap.height() != m_impl->height()) { + m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, + m_impl->width(), + m_impl->height()); + if (!m_resizingBitmap.allocPixels()) { return; } } - readbackBitmap = m_resizingBitmap; + readbackBitmap = &m_resizingBitmap; } // Read back the frame buffer. SkAutoLockPixels bitmapLock(*readbackBitmap); pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); - glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); #elif PLATFORM(CG) - if (m_renderOutput) { + if (m_renderOutput) pixels = m_renderOutput; - glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels); - } #else #error Must port to your platform #endif - if (mustRestoreFBO) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); - -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (pixels) - flipVertically(pixels, m_cachedWidth, m_cachedHeight); -#endif + m_impl->readBackFramebuffer(pixels, 4 * m_impl->width() * m_impl->height()); #if PLATFORM(SKIA) - if (m_resizingBitmap) { + if (m_resizingBitmap.readyToDraw()) { // We need to draw the resizing bitmap into the canvas's backing store. SkCanvas canvas(*canvasBitmap); SkRect dst; - dst.set(0, 0, canvasBitmap->width(), canvasBitmap->height()); - canvas.drawBitmapRect(*m_resizingBitmap, 0, dst); + dst.set(SkIntToScalar(0), SkIntToScalar(0), canvasBitmap->width(), canvasBitmap->height()); + canvas.drawBitmapRect(m_resizingBitmap, 0, dst); } #elif PLATFORM(CG) - if (m_renderOutput) { - int rowBytes = m_cachedWidth * 4; - CGDataProviderRef dataProvider = CGDataProviderCreateWithData(0, m_renderOutput, rowBytes * m_cachedHeight, 0); - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef cgImage = CGImageCreate(m_cachedWidth, - m_cachedHeight, - 8, - 32, - rowBytes, - colorSpace, - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, - dataProvider, - 0, - false, - kCGRenderingIntentDefault); - // CSS styling may cause the canvas's content to be resized on - // the page. Go back to the Canvas to figure out the correct - // width and height to draw. - CGRect rect = CGRectMake(0, 0, - context->canvas()->width(), - context->canvas()->height()); - // We want to completely overwrite the previous frame's - // rendering results. - CGContextSetBlendMode(imageBuffer->context()->platformContext(), - kCGBlendModeCopy); - CGContextSetInterpolationQuality(imageBuffer->context()->platformContext(), - kCGInterpolationNone); - CGContextDrawImage(imageBuffer->context()->platformContext(), - rect, cgImage); - CGImageRelease(cgImage); - CGColorSpaceRelease(colorSpace); - CGDataProviderRelease(dataProvider); - } + if (m_renderOutput) + context->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(), + canvas->width(), canvas->height(), + imageBuffer->context()->platformContext()); #else #error Must port to your platform #endif - -#endif // RENDER_TO_DEBUGGING_WINDOW } -void GraphicsContext3DInternal::activeTexture(unsigned long texture) -{ - // FIXME: query number of textures available. - if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) - // FIXME: raise exception. - return; - - makeContextCurrent(); - glActiveTexture(texture); -} - -void GraphicsContext3DInternal::bindBuffer(unsigned long target, - WebGLBuffer* buffer) -{ - makeContextCurrent(); - GLuint bufID = EXTRACT(buffer); - if (target == GL_ARRAY_BUFFER) - m_boundArrayBuffer = bufID; - glBindBuffer(target, bufID); -} - -void GraphicsContext3DInternal::bindFramebuffer(unsigned long target, - WebGLFramebuffer* framebuffer) +void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context) { - makeContextCurrent(); - GLuint id = EXTRACT(framebuffer); - if (!id) - id = m_fbo; - glBindFramebufferEXT(target, id); - m_boundFBO = id; + paintRenderingResultsToCanvas(context); } -// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps, -// we could just use: -// GL_SAME_METHOD_2_X2(BindTexture, bindTexture, unsigned long, WebGLTexture*) -void GraphicsContext3DInternal::bindTexture(unsigned long target, - WebGLTexture* texture) +void GraphicsContext3DInternal::endPaint() { - makeContextCurrent(); - unsigned int textureObject = EXTRACT(texture); - - glBindTexture(target, textureObject); - - // FIXME: GL_TEXTURE_WRAP_R isn't exposed in the OpenGL ES 2.0 - // API. On desktop OpenGL implementations it seems necessary to - // set this wrap mode to GL_CLAMP_TO_EDGE to get correct behavior - // of cube maps. - if (texture) { - if (target == GL_TEXTURE_CUBE_MAP) { - if (!texture->isCubeMapRWrapModeInitialized()) { - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - texture->setCubeMapRWrapModeInitialized(true); - } - } else - texture->setCubeMapRWrapModeInitialized(false); - } } -void GraphicsContext3DInternal::bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage) +void GraphicsContext3DInternal::reshape(int width, int height) { - makeContextCurrent(); - // FIXME: make this verification more efficient. - GLint binding = 0; - GLenum binding_target = GL_ARRAY_BUFFER_BINDING; - if (target == GL_ELEMENT_ARRAY_BUFFER) - binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING; - glGetIntegerv(binding_target, &binding); - if (binding <= 0) { - // FIXME: raise exception. - // LogMessagef(("bufferData: no buffer bound")); + if (width == m_impl->width() && height == m_impl->height()) return; - } - - glBufferData(target, - size, - data, - usage); -} -void GraphicsContext3DInternal::disableVertexAttribArray(unsigned long index) -{ - makeContextCurrent(); - if (index < NumTrackedPointerStates) - m_vertexAttribPointerState[index].enabled = false; - glDisableVertexAttribArray(index); -} + m_impl->reshape(width, height); -void GraphicsContext3DInternal::enableVertexAttribArray(unsigned long index) -{ - makeContextCurrent(); - if (index < NumTrackedPointerStates) - m_vertexAttribPointerState[index].enabled = true; - glEnableVertexAttribArray(index); -} - -unsigned long GraphicsContext3DInternal::getError() -{ - if (m_syntheticErrors.size() > 0) { - ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin(); - unsigned long err = *iter; - m_syntheticErrors.remove(iter); - return err; +#if PLATFORM(CG) + // Need to reallocate the client-side backing store. + // FIXME: make this more efficient. + if (m_renderOutput) { + delete[] m_renderOutput; + m_renderOutput = 0; } - - makeContextCurrent(); - return glGetError(); + int rowBytes = width * 4; + m_renderOutput = new unsigned char[height * rowBytes]; +#endif // PLATFORM(CG) } -GraphicsContext3D::Attributes GraphicsContext3DInternal::getContextAttributes() -{ - return m_attrs; -} +// Macros to assist in delegating from GraphicsContext3DInternal to +// WebGraphicsContext3D. -void GraphicsContext3DInternal::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, - unsigned long stride, unsigned long offset) -{ - makeContextCurrent(); - - if (m_boundArrayBuffer <= 0) { - // FIXME: raise exception. - // LogMessagef(("bufferData: no buffer bound")); - return; - } - - if (indx < NumTrackedPointerStates) { - VertexAttribPointerState& state = m_vertexAttribPointerState[indx]; - state.buffer = m_boundArrayBuffer; - state.indx = indx; - state.size = size; - state.type = type; - state.normalized = normalized; - state.stride = stride; - state.offset = offset; - } - - glVertexAttribPointer(indx, size, type, normalized, stride, - reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +#define DELEGATE_TO_IMPL(name) \ +void GraphicsContext3DInternal::name() \ +{ \ + m_impl->name(); \ } -void GraphicsContext3DInternal::viewportImpl(long x, long y, unsigned long width, unsigned long height) -{ - glViewport(x, y, width, height); +#define DELEGATE_TO_IMPL_R(name, rt) \ +rt GraphicsContext3DInternal::name() \ +{ \ + return m_impl->name(); \ } -void GraphicsContext3DInternal::synthesizeGLError(unsigned long error) -{ - m_syntheticErrors.add(error); +#define DELEGATE_TO_IMPL_1(name, t1) \ +void GraphicsContext3DInternal::name(t1 a1) \ +{ \ + m_impl->name(a1); \ } -// GraphicsContext3D ----------------------------------------------------- - -/* Helper macros for when we're just wrapping a gl method, so that - * we can avoid having to type this 500 times. Note that these MUST - * NOT BE USED if we need to check any of the parameters. - */ - -#define GL_SAME_METHOD_0(glname, name) \ -void GraphicsContext3D::name() \ -{ \ - makeContextCurrent(); \ - gl##glname(); \ +#define DELEGATE_TO_IMPL_1_X(name, t1) \ +void GraphicsContext3DInternal::name(t1 a1) \ +{ \ + m_impl->name(EXTRACT(a1)); \ } -#define GL_SAME_METHOD_1(glname, name, t1) \ -void GraphicsContext3D::name(t1 a1) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1); \ +#define DELEGATE_TO_IMPL_1R(name, t1, rt) \ +rt GraphicsContext3DInternal::name(t1 a1) \ +{ \ + return m_impl->name(a1); \ } -#define GL_SAME_METHOD_1_X(glname, name, t1) \ -void GraphicsContext3D::name(t1 a1) \ -{ \ - makeContextCurrent(); \ - gl##glname(EXTRACT(a1)); \ +#define DELEGATE_TO_IMPL_1R_X(name, t1, rt) \ +rt GraphicsContext3DInternal::name(t1 a1) \ +{ \ + return m_impl->name(EXTRACT(a1)); \ } -#define GL_SAME_METHOD_2(glname, name, t1, t2) \ -void GraphicsContext3D::name(t1 a1, t2 a2) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2); \ +#define DELEGATE_TO_IMPL_2(name, t1, t2) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2) \ +{ \ + m_impl->name(a1, a2); \ } -#define GL_SAME_METHOD_2_X12(glname, name, t1, t2) \ -void GraphicsContext3D::name(t1 a1, t2 a2) \ -{ \ - makeContextCurrent(); \ - gl##glname(EXTRACT(a1), EXTRACT(a2)); \ +#define DELEGATE_TO_IMPL_2_X12(name, t1, t2) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2) \ +{ \ + m_impl->name(EXTRACT(a1), EXTRACT(a2)); \ } -#define GL_SAME_METHOD_2_X2(glname, name, t1, t2) \ -void GraphicsContext3D::name(t1 a1, t2 a2) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, EXTRACT(a2)); \ +#define DELEGATE_TO_IMPL_2_X2(name, t1, t2) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2) \ +{ \ + m_impl->name(a1, EXTRACT(a2)); \ } -#define GL_SAME_METHOD_3(glname, name, t1, t2, t3) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3); \ +#define DELEGATE_TO_IMPL_2R(name, t1, t2, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2) \ +{ \ + return m_impl->name(a1, a2); \ } -#define GL_SAME_METHOD_3_X12(glname, name, t1, t2, t3) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ -{ \ - makeContextCurrent(); \ - gl##glname(EXTRACT(a1), EXTRACT(a2), a3); \ +#define DELEGATE_TO_IMPL_3(name, t1, t2, t3) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3) \ +{ \ + m_impl->name(a1, a2, a3); \ } -#define GL_SAME_METHOD_3_X2(glname, name, t1, t2, t3) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, EXTRACT(a2), a3); \ +#define DELEGATE_TO_IMPL_3_X1(name, t1, t2, t3) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3) \ +{ \ + m_impl->name(EXTRACT(a1), a2, a3); \ } -#define GL_SAME_METHOD_4(glname, name, t1, t2, t3, t4) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4); \ +#define DELEGATE_TO_IMPL_3R(name, t1, t2, t3, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3) \ +{ \ + return m_impl->name(a1, a2, a3); \ } -#define GL_SAME_METHOD_4_X4(glname, name, t1, t2, t3, t4) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, EXTRACT(a4)); \ +#define DELEGATE_TO_IMPL_4(name, t1, t2, t3, t4) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + m_impl->name(a1, a2, a3, a4); \ } -#define GL_SAME_METHOD_5(glname, name, t1, t2, t3, t4, t5) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5); \ +#define DELEGATE_TO_IMPL_4_X1(name, t1, t2, t3, t4) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + m_impl->name(EXTRACT(a1), a2, a3, a4); \ } -#define GL_SAME_METHOD_5_X4(glname, name, t1, t2, t3, t4, t5) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, EXTRACT(a4), a5); \ +#define DELEGATE_TO_IMPL_4_X4(name, t1, t2, t3, t4) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + m_impl->name(a1, a2, a3, EXTRACT(a4)); \ } -#define GL_SAME_METHOD_6(glname, name, t1, t2, t3, t4, t5, t6) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5, a6); \ +#define DELEGATE_TO_IMPL_5(name, t1, t2, t3, t4, t5) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + m_impl->name(a1, a2, a3, a4, a5); \ } -#define GL_SAME_METHOD_8(glname, name, t1, t2, t3, t4, t5, t6, t7, t8) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \ +#define DELEGATE_TO_IMPL_5_X4(name, t1, t2, t3, t4, t5) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + m_impl->name(a1, a2, a3, EXTRACT(a4), a5); \ } -PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs) -{ - PassOwnPtr<GraphicsContext3D> context = new GraphicsContext3D(attrs); - // FIXME: add error checking - return context; +#define DELEGATE_TO_IMPL_5R(name, t1, t2, t3, t4, t5, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + return m_impl->name(a1, a2, a3, a4, a5); \ } -GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs) - : m_currentWidth(0) - , m_currentHeight(0) - , m_internal(new GraphicsContext3DInternal(attrs)) -{ +#define DELEGATE_TO_IMPL_6(name, t1, t2, t3, t4, t5, t6) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + m_impl->name(a1, a2, a3, a4, a5, a6); \ } -GraphicsContext3D::~GraphicsContext3D() -{ +#define DELEGATE_TO_IMPL_6R(name, t1, t2, t3, t4, t5, t6, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + return m_impl->name(a1, a2, a3, a4, a5, a6); \ } -PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const -{ - return m_internal->platformGraphicsContext3D(); -} - -Platform3DObject GraphicsContext3D::platformTexture() const -{ - return m_internal->platformTexture(); +#define DELEGATE_TO_IMPL_7(name, t1, t2, t3, t4, t5, t6, t7) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ } -void GraphicsContext3D::makeContextCurrent() -{ - m_internal->makeContextCurrent(); +#define DELEGATE_TO_IMPL_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + return m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ } -void GraphicsContext3D::reshape(int width, int height) -{ - if (width == m_currentWidth && height == m_currentHeight) - return; - - m_currentWidth = width; - m_currentHeight = height; - - m_internal->reshape(width, height); +#define DELEGATE_TO_IMPL_8(name, t1, t2, t3, t4, t5, t6, t7, t8) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ +{ \ + m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8); \ } -void GraphicsContext3D::beginPaint(WebGLRenderingContext* context) -{ - m_internal->beginPaint(context); +#define DELEGATE_TO_IMPL_9R(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \ +{ \ + return m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ } -void GraphicsContext3D::endPaint() -{ -} +DELEGATE_TO_IMPL_R(makeContextCurrent, bool) +DELEGATE_TO_IMPL_1R(sizeInBytes, int, int) -int GraphicsContext3D::sizeInBytes(int type) +bool GraphicsContext3DInternal::isGLES2Compliant() const { - switch (type) { - case GL_BYTE: - return sizeof(GLbyte); - case GL_UNSIGNED_BYTE: - return sizeof(GLubyte); - case GL_SHORT: - return sizeof(GLshort); - case GL_UNSIGNED_SHORT: - return sizeof(GLushort); - case GL_INT: - return sizeof(GLint); - case GL_UNSIGNED_INT: - return sizeof(GLuint); - case GL_FLOAT: - return sizeof(GLfloat); - default: // FIXME: default cases are discouraged in WebKit. - return 0; - } + return m_impl->isGLES2Compliant(); } -unsigned GraphicsContext3D::createBuffer() -{ - makeContextCurrent(); - GLuint o; - glGenBuffers(1, &o); - return o; -} +DELEGATE_TO_IMPL_1(activeTexture, unsigned long) +DELEGATE_TO_IMPL_2_X12(attachShader, WebGLProgram*, WebGLShader*) -unsigned GraphicsContext3D::createFramebuffer() +void GraphicsContext3DInternal::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name) { - makeContextCurrent(); - GLuint o = 0; - glGenFramebuffersEXT(1, &o); - return o; + m_impl->bindAttribLocation(EXTRACT(program), index, name.utf8().data()); } -unsigned GraphicsContext3D::createProgram() -{ - makeContextCurrent(); - return glCreateProgram(); -} +DELEGATE_TO_IMPL_2_X2(bindBuffer, unsigned long, WebGLBuffer*) +DELEGATE_TO_IMPL_2_X2(bindFramebuffer, unsigned long, WebGLFramebuffer*) +DELEGATE_TO_IMPL_2_X2(bindRenderbuffer, unsigned long, WebGLRenderbuffer*) -unsigned GraphicsContext3D::createRenderbuffer() -{ - makeContextCurrent(); - GLuint o; - glGenRenderbuffersEXT(1, &o); - return o; -} +static const int kTextureWrapR = 0x8072; -unsigned GraphicsContext3D::createShader(unsigned long type) +// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps, +// we could just use: +// DELEGATE_TO_IMPL_2_X2(bindTexture, unsigned long, WebGLTexture*) +void GraphicsContext3DInternal::bindTexture(unsigned long target, + WebGLTexture* texture) { - makeContextCurrent(); - return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER); -} + unsigned int textureObject = EXTRACT(texture); -unsigned GraphicsContext3D::createTexture() -{ - makeContextCurrent(); - GLuint o; - glGenTextures(1, &o); - return o; -} + m_impl->bindTexture(target, textureObject); -void GraphicsContext3D::deleteBuffer(unsigned buffer) -{ - makeContextCurrent(); - glDeleteBuffers(1, &buffer); + // FIXME: GL_TEXTURE_WRAP_R isn't exposed in the OpenGL ES 2.0 + // API. On desktop OpenGL implementations it seems necessary to + // set this wrap mode to GL_CLAMP_TO_EDGE to get correct behavior + // of cube maps. + if (texture) + if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) { + if (!texture->isCubeMapRWrapModeInitialized()) { + m_impl->texParameteri(GraphicsContext3D::TEXTURE_CUBE_MAP, kTextureWrapR, GraphicsContext3D::CLAMP_TO_EDGE); + texture->setCubeMapRWrapModeInitialized(true); + } + } else + texture->setCubeMapRWrapModeInitialized(false); } -void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer) -{ - makeContextCurrent(); - glDeleteFramebuffersEXT(1, &framebuffer); -} +DELEGATE_TO_IMPL_4(blendColor, double, double, double, double) +DELEGATE_TO_IMPL_1(blendEquation, unsigned long) +DELEGATE_TO_IMPL_2(blendEquationSeparate, unsigned long, unsigned long) +DELEGATE_TO_IMPL_2(blendFunc, unsigned long, unsigned long) +DELEGATE_TO_IMPL_4(blendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) -void GraphicsContext3D::deleteProgram(unsigned program) +void GraphicsContext3DInternal::bufferData(unsigned long target, int size, unsigned long usage) { - makeContextCurrent(); - glDeleteProgram(program); + m_impl->bufferData(target, size, 0, usage); } -void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer) +void GraphicsContext3DInternal::bufferData(unsigned long target, ArrayBuffer* array, unsigned long usage) { - makeContextCurrent(); - glDeleteRenderbuffersEXT(1, &renderbuffer); + m_impl->bufferData(target, array->byteLength(), array->data(), usage); } -void GraphicsContext3D::deleteShader(unsigned shader) +void GraphicsContext3DInternal::bufferData(unsigned long target, ArrayBufferView* array, unsigned long usage) { - makeContextCurrent(); - glDeleteShader(shader); + m_impl->bufferData(target, array->byteLength(), array->baseAddress(), usage); } -void GraphicsContext3D::deleteTexture(unsigned texture) +void GraphicsContext3DInternal::bufferSubData(unsigned long target, long offset, ArrayBuffer* array) { - makeContextCurrent(); - glDeleteTextures(1, &texture); + m_impl->bufferSubData(target, offset, array->byteLength(), array->data()); } -void GraphicsContext3D::activeTexture(unsigned long texture) +void GraphicsContext3DInternal::bufferSubData(unsigned long target, long offset, ArrayBufferView* array) { - m_internal->activeTexture(texture); + m_impl->bufferSubData(target, offset, array->byteLength(), array->baseAddress()); } -GL_SAME_METHOD_2_X12(AttachShader, attachShader, WebGLProgram*, WebGLShader*) +DELEGATE_TO_IMPL_1R(checkFramebufferStatus, unsigned long, unsigned long) +DELEGATE_TO_IMPL_1(clear, unsigned long) +DELEGATE_TO_IMPL_4(clearColor, double, double, double, double) +DELEGATE_TO_IMPL_1(clearDepth, double) +DELEGATE_TO_IMPL_1(clearStencil, long) +DELEGATE_TO_IMPL_4(colorMask, bool, bool, bool, bool) +DELEGATE_TO_IMPL_1_X(compileShader, WebGLShader*) -void GraphicsContext3D::bindAttribLocation(WebGLProgram* program, - unsigned long index, - const String& name) -{ - if (!program) - return; - makeContextCurrent(); - glBindAttribLocation(EXTRACT(program), index, name.utf8().data()); -} +DELEGATE_TO_IMPL_8(copyTexImage2D, unsigned long, long, unsigned long, long, long, unsigned long, unsigned long, long) +DELEGATE_TO_IMPL_8(copyTexSubImage2D, unsigned long, long, long, long, long, long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_1(cullFace, unsigned long) +DELEGATE_TO_IMPL_1(depthFunc, unsigned long) +DELEGATE_TO_IMPL_1(depthMask, bool) +DELEGATE_TO_IMPL_2(depthRange, double, double) +DELEGATE_TO_IMPL_2_X12(detachShader, WebGLProgram*, WebGLShader*) +DELEGATE_TO_IMPL_1(disable, unsigned long) +DELEGATE_TO_IMPL_1(disableVertexAttribArray, unsigned long) +DELEGATE_TO_IMPL_3(drawArrays, unsigned long, long, long) +DELEGATE_TO_IMPL_4(drawElements, unsigned long, unsigned long, unsigned long, long) -void GraphicsContext3D::bindBuffer(unsigned long target, - WebGLBuffer* buffer) -{ - m_internal->bindBuffer(target, buffer); -} +DELEGATE_TO_IMPL_1(enable, unsigned long) +DELEGATE_TO_IMPL_1(enableVertexAttribArray, unsigned long) +DELEGATE_TO_IMPL(finish) +DELEGATE_TO_IMPL(flush) +DELEGATE_TO_IMPL_4_X4(framebufferRenderbuffer, unsigned long, unsigned long, unsigned long, WebGLRenderbuffer*) +DELEGATE_TO_IMPL_5_X4(framebufferTexture2D, unsigned long, unsigned long, unsigned long, WebGLTexture*, long) +DELEGATE_TO_IMPL_1(frontFace, unsigned long) +DELEGATE_TO_IMPL_1(generateMipmap, unsigned long) -void GraphicsContext3D::bindFramebuffer(unsigned long target, WebGLFramebuffer* framebuffer) +bool GraphicsContext3DInternal::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info) { - m_internal->bindFramebuffer(target, framebuffer); + WebKit::WebGraphicsContext3D::ActiveInfo webInfo; + if (!m_impl->getActiveAttrib(EXTRACT(program), index, webInfo)) + return false; + info.name = webInfo.name; + info.type = webInfo.type; + info.size = webInfo.size; + return true; } -GL_SAME_METHOD_2_X2(BindRenderbufferEXT, bindRenderbuffer, unsigned long, WebGLRenderbuffer*) - -// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps, -// we could just use: -// GL_SAME_METHOD_2_X2(BindTexture, bindTexture, unsigned long, WebGLTexture*) -void GraphicsContext3D::bindTexture(unsigned long target, - WebGLTexture* texture) +bool GraphicsContext3DInternal::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info) { - m_internal->bindTexture(target, texture); + WebKit::WebGraphicsContext3D::ActiveInfo webInfo; + if (!m_impl->getActiveUniform(EXTRACT(program), index, webInfo)) + return false; + info.name = webInfo.name; + info.type = webInfo.type; + info.size = webInfo.size; + return true; } -GL_SAME_METHOD_4(BlendColor, blendColor, double, double, double, double) - -GL_SAME_METHOD_1(BlendEquation, blendEquation, unsigned long) - -GL_SAME_METHOD_2(BlendEquationSeparate, blendEquationSeparate, unsigned long, unsigned long) - -GL_SAME_METHOD_2(BlendFunc, blendFunc, unsigned long, unsigned long) - -GL_SAME_METHOD_4(BlendFuncSeparate, blendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_4_X1(getAttachedShaders, WebGLProgram*, int, int*, unsigned int*) -void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage) +int GraphicsContext3DInternal::getAttribLocation(WebGLProgram* program, const String& name) { - m_internal->bufferDataImpl(target, size, 0, usage); + return m_impl->getAttribLocation(EXTRACT(program), name.utf8().data()); } -void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsigned long usage) -{ - m_internal->bufferDataImpl(target, array->byteLength(), array->baseAddress(), usage); -} +DELEGATE_TO_IMPL_2(getBooleanv, unsigned long, unsigned char*) -void GraphicsContext3D::bufferSubData(unsigned long target, long offset, WebGLArray* array) -{ - if (!array || !array->length()) - return; - - makeContextCurrent(); - // FIXME: make this verification more efficient. - GLint binding = 0; - GLenum binding_target = GL_ARRAY_BUFFER_BINDING; - if (target == GL_ELEMENT_ARRAY_BUFFER) - binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING; - glGetIntegerv(binding_target, &binding); - if (binding <= 0) { - // FIXME: raise exception. - // LogMessagef(("bufferSubData: no buffer bound")); - return; - } - glBufferSubData(target, offset, array->byteLength(), array->baseAddress()); -} +DELEGATE_TO_IMPL_3(getBufferParameteriv, unsigned long, unsigned long, int*) -unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target) +GraphicsContext3D::Attributes GraphicsContext3DInternal::getContextAttributes() { - makeContextCurrent(); - return glCheckFramebufferStatusEXT(target); + WebKit::WebGraphicsContext3D::Attributes webAttributes = m_impl->getContextAttributes(); + GraphicsContext3D::Attributes attributes; + attributes.alpha = webAttributes.alpha; + attributes.depth = webAttributes.depth; + attributes.stencil = webAttributes.stencil; + attributes.antialias = webAttributes.antialias; + attributes.premultipliedAlpha = webAttributes.premultipliedAlpha; + return attributes; } -GL_SAME_METHOD_1(Clear, clear, unsigned long) - -GL_SAME_METHOD_4(ClearColor, clearColor, double, double, double, double) - -GL_SAME_METHOD_1(ClearDepth, clearDepth, double) - -GL_SAME_METHOD_1(ClearStencil, clearStencil, long) - -GL_SAME_METHOD_4(ColorMask, colorMask, bool, bool, bool, bool) - -GL_SAME_METHOD_1_X(CompileShader, compileShader, WebGLShader*) - -GL_SAME_METHOD_8(CopyTexImage2D, copyTexImage2D, unsigned long, long, unsigned long, long, long, unsigned long, unsigned long, long) +DELEGATE_TO_IMPL_R(getError, unsigned long) -GL_SAME_METHOD_8(CopyTexSubImage2D, copyTexSubImage2D, unsigned long, long, long, long, long, long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_2(getFloatv, unsigned long, float*) -GL_SAME_METHOD_1(CullFace, cullFace, unsigned long) +DELEGATE_TO_IMPL_4(getFramebufferAttachmentParameteriv, unsigned long, unsigned long, unsigned long, int*) -GL_SAME_METHOD_1(DepthFunc, depthFunc, unsigned long) +DELEGATE_TO_IMPL_2(getIntegerv, unsigned long, int*) -GL_SAME_METHOD_1(DepthMask, depthMask, bool) +DELEGATE_TO_IMPL_3_X1(getProgramiv, WebGLProgram*, unsigned long, int*) -GL_SAME_METHOD_2(DepthRange, depthRange, double, double) - -void GraphicsContext3D::detachShader(WebGLProgram* program, WebGLShader* shader) +String GraphicsContext3DInternal::getProgramInfoLog(WebGLProgram* program) { - if (!program || !shader) - return; - - makeContextCurrent(); - glDetachShader(EXTRACT(program), EXTRACT(shader)); + return m_impl->getProgramInfoLog(EXTRACT(program)); } -GL_SAME_METHOD_1(Disable, disable, unsigned long) +DELEGATE_TO_IMPL_3(getRenderbufferParameteriv, unsigned long, unsigned long, int*) -void GraphicsContext3D::disableVertexAttribArray(unsigned long index) -{ - m_internal->disableVertexAttribArray(index); -} +DELEGATE_TO_IMPL_3_X1(getShaderiv, WebGLShader*, unsigned long, int*) -void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count) +String GraphicsContext3DInternal::getShaderInfoLog(WebGLShader* shader) { - switch (mode) { - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - case GL_POINTS: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - case GL_LINES: - break; - default: // FIXME: default cases are discouraged in WebKit. - // FIXME: output log message, raise exception. - // LogMessage(NS_LITERAL_CSTRING("drawArrays: invalid mode")); - // return NS_ERROR_DOM_SYNTAX_ERR; - return; - } - - if (first+count < first || first+count < count) { - // FIXME: output log message, raise exception. - // LogMessage(NS_LITERAL_CSTRING("drawArrays: overflow in first+count")); - // return NS_ERROR_INVALID_ARG; - return; - } - - // FIXME: validate against currently bound buffer. - // if (!ValidateBuffers(first+count)) - // return NS_ERROR_INVALID_ARG; - - makeContextCurrent(); - glDrawArrays(mode, first, count); + return m_impl->getShaderInfoLog(EXTRACT(shader)); } -void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset) +String GraphicsContext3DInternal::getShaderSource(WebGLShader* shader) { - makeContextCurrent(); - // FIXME: make this verification more efficient. - GLint binding = 0; - GLenum binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING; - glGetIntegerv(binding_target, &binding); - if (binding <= 0) { - // FIXME: raise exception. - // LogMessagef(("bufferData: no buffer bound")); - return; - } - glDrawElements(mode, count, type, - reinterpret_cast<void*>(static_cast<intptr_t>(offset))); + return m_impl->getShaderSource(EXTRACT(shader)); } -GL_SAME_METHOD_1(Enable, enable, unsigned long) - -void GraphicsContext3D::enableVertexAttribArray(unsigned long index) +String GraphicsContext3DInternal::getString(unsigned long name) { - m_internal->enableVertexAttribArray(index); + return m_impl->getString(name); } -GL_SAME_METHOD_0(Finish, finish) +DELEGATE_TO_IMPL_3(getTexParameterfv, unsigned long, unsigned long, float*) +DELEGATE_TO_IMPL_3(getTexParameteriv, unsigned long, unsigned long, int*) -GL_SAME_METHOD_0(Flush, flush) +DELEGATE_TO_IMPL_3_X1(getUniformfv, WebGLProgram*, long, float*) +DELEGATE_TO_IMPL_3_X1(getUniformiv, WebGLProgram*, long, int*) -GL_SAME_METHOD_4_X4(FramebufferRenderbufferEXT, framebufferRenderbuffer, unsigned long, unsigned long, unsigned long, WebGLRenderbuffer*) - -GL_SAME_METHOD_5_X4(FramebufferTexture2DEXT, framebufferTexture2D, unsigned long, unsigned long, unsigned long, WebGLTexture*, long) - -GL_SAME_METHOD_1(FrontFace, frontFace, unsigned long) - -void GraphicsContext3D::generateMipmap(unsigned long target) +long GraphicsContext3DInternal::getUniformLocation(WebGLProgram* program, const String& name) { - makeContextCurrent(); - if (glGenerateMipmapEXT) - glGenerateMipmapEXT(target); - // FIXME: provide alternative code path? This will be unpleasant - // to implement if glGenerateMipmapEXT is not available -- it will - // require a texture readback and re-upload. -} - -bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info) -{ - if (!program) { - synthesizeGLError(INVALID_VALUE); - return false; - } - GLint maxNameLength = -1; - glGetProgramiv(EXTRACT(program), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); - if (maxNameLength < 0) - return false; - GLchar* name = 0; - if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { - synthesizeGLError(OUT_OF_MEMORY); - return false; - } - GLsizei length = 0; - GLint size = -1; - GLenum type = 0; - glGetActiveAttrib(EXTRACT(program), index, maxNameLength, - &length, &size, &type, name); - if (size < 0) { - fastFree(name); - return false; - } - info.name = String(name, length); - info.type = type; - info.size = size; - fastFree(name); - return true; + return m_impl->getUniformLocation(EXTRACT(program), name.utf8().data()); } -bool GraphicsContext3D::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info) -{ - if (!program) { - synthesizeGLError(INVALID_VALUE); - return false; - } - GLint maxNameLength = -1; - glGetProgramiv(EXTRACT(program), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); - if (maxNameLength < 0) - return false; - GLchar* name = 0; - if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { - synthesizeGLError(OUT_OF_MEMORY); - return false; - } - GLsizei length = 0; - GLint size = -1; - GLenum type = 0; - glGetActiveUniform(EXTRACT(program), index, maxNameLength, - &length, &size, &type, name); - if (size < 0) { - fastFree(name); - return false; - } - info.name = String(name, length); - info.type = type; - info.size = size; - fastFree(name); - return true; -} +DELEGATE_TO_IMPL_3(getVertexAttribfv, unsigned long, unsigned long, float*) +DELEGATE_TO_IMPL_3(getVertexAttribiv, unsigned long, unsigned long, int*) -int GraphicsContext3D::getAttribLocation(WebGLProgram* program, const String& name) -{ - if (!program) - return -1; +DELEGATE_TO_IMPL_2R(getVertexAttribOffset, unsigned long, unsigned long, long) - makeContextCurrent(); - return glGetAttribLocation(EXTRACT(program), name.utf8().data()); -} +DELEGATE_TO_IMPL_2(hint, unsigned long, unsigned long) +DELEGATE_TO_IMPL_1R_X(isBuffer, WebGLBuffer*, bool) +DELEGATE_TO_IMPL_1R(isEnabled, unsigned long, bool) +DELEGATE_TO_IMPL_1R_X(isFramebuffer, WebGLFramebuffer*, bool) +DELEGATE_TO_IMPL_1R_X(isProgram, WebGLProgram*, bool) +DELEGATE_TO_IMPL_1R_X(isRenderbuffer, WebGLRenderbuffer*, bool) +DELEGATE_TO_IMPL_1R_X(isShader, WebGLShader*, bool) +DELEGATE_TO_IMPL_1R_X(isTexture, WebGLTexture*, bool) +DELEGATE_TO_IMPL_1(lineWidth, double) +DELEGATE_TO_IMPL_1_X(linkProgram, WebGLProgram*) +DELEGATE_TO_IMPL_2(pixelStorei, unsigned long, long) +DELEGATE_TO_IMPL_2(polygonOffset, double, double) +DELEGATE_TO_IMPL_7(readPixels, long, long, unsigned long, unsigned long, unsigned long, unsigned long, void*) +DELEGATE_TO_IMPL(releaseShaderCompiler) +DELEGATE_TO_IMPL_4(renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_2(sampleCoverage, double, bool) +DELEGATE_TO_IMPL_4(scissor, long, long, unsigned long, unsigned long) -void GraphicsContext3D::getBooleanv(unsigned long pname, unsigned char* value) +void GraphicsContext3DInternal::shaderSource(WebGLShader* shader, const String& string) { - makeContextCurrent(); - glGetBooleanv(pname, value); + m_impl->shaderSource(EXTRACT(shader), string.utf8().data()); } -void GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname, int* value) -{ - makeContextCurrent(); - glGetBufferParameteriv(target, pname, value); -} +DELEGATE_TO_IMPL_3(stencilFunc, unsigned long, long, unsigned long) +DELEGATE_TO_IMPL_4(stencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) +DELEGATE_TO_IMPL_1(stencilMask, unsigned long) +DELEGATE_TO_IMPL_2(stencilMaskSeparate, unsigned long, unsigned long) +DELEGATE_TO_IMPL_3(stencilOp, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_4(stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) -GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes() +int GraphicsContext3DInternal::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels) { - return m_internal->getContextAttributes(); + m_impl->texImage2D(target, level, internalformat, width, height, border, format, type, pixels); + return 0; } -unsigned long GraphicsContext3D::getError() -{ - return m_internal->getError(); -} +DELEGATE_TO_IMPL_3(texParameterf, unsigned, unsigned, float) +DELEGATE_TO_IMPL_3(texParameteri, unsigned, unsigned, int) -void GraphicsContext3D::getFloatv(unsigned long pname, float* value) +int GraphicsContext3DInternal::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels) { - makeContextCurrent(); - glGetFloatv(pname, value); + m_impl->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + return 0; } -void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, - unsigned long attachment, - unsigned long pname, - int* value) -{ - makeContextCurrent(); - glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); -} +DELEGATE_TO_IMPL_2(uniform1f, long, float) -void GraphicsContext3D::getIntegerv(unsigned long pname, int* value) +void GraphicsContext3DInternal::uniform1fv(long location, float* v, int size) { - makeContextCurrent(); - glGetIntegerv(pname, value); + m_impl->uniform1fv(location, size, v); } -void GraphicsContext3D::getProgramiv(WebGLProgram* program, - unsigned long pname, - int* value) -{ - makeContextCurrent(); - glGetProgramiv(EXTRACT(program), pname, value); -} +DELEGATE_TO_IMPL_2(uniform1i, long, int) -String GraphicsContext3D::getProgramInfoLog(WebGLProgram* program) -{ - makeContextCurrent(); - GLuint programID = EXTRACT(program); - GLint logLength; - glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLength); - if (!logLength) - return String(); - GLchar* log = 0; - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) - return String(); - GLsizei returnedLogLength; - glGetProgramInfoLog(programID, logLength, &returnedLogLength, log); - ASSERT(logLength == returnedLogLength + 1); - String res = String(log, returnedLogLength); - fastFree(log); - return res; -} - -void GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, - unsigned long pname, - int* value) +void GraphicsContext3DInternal::uniform1iv(long location, int* v, int size) { - makeContextCurrent(); - glGetRenderbufferParameterivEXT(target, pname, value); + m_impl->uniform1iv(location, size, v); } -void GraphicsContext3D::getShaderiv(WebGLShader* shader, - unsigned long pname, - int* value) -{ - makeContextCurrent(); - glGetShaderiv(EXTRACT(shader), pname, value); -} +DELEGATE_TO_IMPL_3(uniform2f, long, float, float) -String GraphicsContext3D::getShaderInfoLog(WebGLShader* shader) -{ - makeContextCurrent(); - GLuint shaderID = EXTRACT(shader); - GLint logLength; - glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength); - if (!logLength) - return String(); - GLchar* log = 0; - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) - return String(); - GLsizei returnedLogLength; - glGetShaderInfoLog(shaderID, logLength, &returnedLogLength, log); - ASSERT(logLength == returnedLogLength + 1); - String res = String(log, returnedLogLength); - fastFree(log); - return res; -} - -String GraphicsContext3D::getShaderSource(WebGLShader* shader) -{ - makeContextCurrent(); - GLuint shaderID = EXTRACT(shader); - GLint logLength; - glGetShaderiv(shaderID, GL_SHADER_SOURCE_LENGTH, &logLength); - if (!logLength) - return String(); - GLchar* log = 0; - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) - return String(); - GLsizei returnedLogLength; - glGetShaderSource(shaderID, logLength, &returnedLogLength, log); - ASSERT(logLength == returnedLogLength + 1); - String res = String(log, returnedLogLength); - fastFree(log); - return res; -} - -String GraphicsContext3D::getString(unsigned long name) +void GraphicsContext3DInternal::uniform2fv(long location, float* v, int size) { - makeContextCurrent(); - return String(reinterpret_cast<const char*>(glGetString(name))); + m_impl->uniform2fv(location, size, v); } -void GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname, float* value) -{ - makeContextCurrent(); - glGetTexParameterfv(target, pname, value); -} +DELEGATE_TO_IMPL_3(uniform2i, long, int, int) -void GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname, int* value) +void GraphicsContext3DInternal::uniform2iv(long location, int* v, int size) { - makeContextCurrent(); - glGetTexParameteriv(target, pname, value); + m_impl->uniform2iv(location, size, v); } -void GraphicsContext3D::getUniformfv(WebGLProgram* program, long location, float* value) -{ - makeContextCurrent(); - glGetUniformfv(EXTRACT(program), location, value); -} +DELEGATE_TO_IMPL_4(uniform3f, long, float, float, float) -void GraphicsContext3D::getUniformiv(WebGLProgram* program, long location, int* value) +void GraphicsContext3DInternal::uniform3fv(long location, float* v, int size) { - makeContextCurrent(); - glGetUniformiv(EXTRACT(program), location, value); + m_impl->uniform3fv(location, size, v); } -long GraphicsContext3D::getUniformLocation(WebGLProgram* program, const String& name) -{ - if (!program) - return -1; - - makeContextCurrent(); - return glGetUniformLocation(EXTRACT(program), name.utf8().data()); -} +DELEGATE_TO_IMPL_4(uniform3i, long, int, int, int) -void GraphicsContext3D::getVertexAttribfv(unsigned long index, - unsigned long pname, - float* value) +void GraphicsContext3DInternal::uniform3iv(long location, int* v, int size) { - makeContextCurrent(); - glGetVertexAttribfv(index, pname, value); + m_impl->uniform3iv(location, size, v); } -void GraphicsContext3D::getVertexAttribiv(unsigned long index, - unsigned long pname, - int* value) -{ - makeContextCurrent(); - glGetVertexAttribiv(index, pname, value); -} +DELEGATE_TO_IMPL_5(uniform4f, long, float, float, float, float) -long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname) +void GraphicsContext3DInternal::uniform4fv(long location, float* v, int size) { - // FIXME: implement. - notImplemented(); - return 0; + m_impl->uniform4fv(location, size, v); } -GL_SAME_METHOD_2(Hint, hint, unsigned long, unsigned long); - -bool GraphicsContext3D::isBuffer(WebGLBuffer* buffer) -{ - makeContextCurrent(); - return glIsBuffer(EXTRACT(buffer)); -} +DELEGATE_TO_IMPL_5(uniform4i, long, int, int, int, int) -bool GraphicsContext3D::isEnabled(unsigned long cap) +void GraphicsContext3DInternal::uniform4iv(long location, int* v, int size) { - makeContextCurrent(); - return glIsEnabled(cap); + m_impl->uniform4iv(location, size, v); } -bool GraphicsContext3D::isFramebuffer(WebGLFramebuffer* framebuffer) +void GraphicsContext3DInternal::uniformMatrix2fv(long location, bool transpose, float* value, int size) { - makeContextCurrent(); - return glIsFramebufferEXT(EXTRACT(framebuffer)); + m_impl->uniformMatrix2fv(location, size, transpose, value); } -bool GraphicsContext3D::isProgram(WebGLProgram* program) +void GraphicsContext3DInternal::uniformMatrix3fv(long location, bool transpose, float* value, int size) { - makeContextCurrent(); - return glIsProgram(EXTRACT(program)); + m_impl->uniformMatrix3fv(location, size, transpose, value); } -bool GraphicsContext3D::isRenderbuffer(WebGLRenderbuffer* renderbuffer) +void GraphicsContext3DInternal::uniformMatrix4fv(long location, bool transpose, float* value, int size) { - makeContextCurrent(); - return glIsRenderbufferEXT(EXTRACT(renderbuffer)); + m_impl->uniformMatrix4fv(location, size, transpose, value); } -bool GraphicsContext3D::isShader(WebGLShader* shader) -{ - makeContextCurrent(); - return glIsShader(EXTRACT(shader)); -} +DELEGATE_TO_IMPL_1_X(useProgram, WebGLProgram*) +DELEGATE_TO_IMPL_1_X(validateProgram, WebGLProgram*) -bool GraphicsContext3D::isTexture(WebGLTexture* texture) -{ - makeContextCurrent(); - return glIsTexture(EXTRACT(texture)); -} +DELEGATE_TO_IMPL_2(vertexAttrib1f, unsigned long, float) +DELEGATE_TO_IMPL_2(vertexAttrib1fv, unsigned long, float*) +DELEGATE_TO_IMPL_3(vertexAttrib2f, unsigned long, float, float) +DELEGATE_TO_IMPL_2(vertexAttrib2fv, unsigned long, float*) +DELEGATE_TO_IMPL_4(vertexAttrib3f, unsigned long, float, float, float) +DELEGATE_TO_IMPL_2(vertexAttrib3fv, unsigned long, float*) +DELEGATE_TO_IMPL_5(vertexAttrib4f, unsigned long, float, float, float, float) +DELEGATE_TO_IMPL_2(vertexAttrib4fv, unsigned long, float*) +DELEGATE_TO_IMPL_6(vertexAttribPointer, unsigned long, int, int, bool, unsigned long, unsigned long) -GL_SAME_METHOD_1(LineWidth, lineWidth, double) +DELEGATE_TO_IMPL_4(viewport, long, long, unsigned long, unsigned long) -GL_SAME_METHOD_1_X(LinkProgram, linkProgram, WebGLProgram*) +DELEGATE_TO_IMPL_R(createBuffer, unsigned) +DELEGATE_TO_IMPL_R(createFramebuffer, unsigned) +DELEGATE_TO_IMPL_R(createProgram, unsigned) +DELEGATE_TO_IMPL_R(createRenderbuffer, unsigned) +DELEGATE_TO_IMPL_1R(createShader, unsigned long, unsigned) +DELEGATE_TO_IMPL_R(createTexture, unsigned) -void GraphicsContext3D::pixelStorei(unsigned long pname, long param) -{ - if (pname != GL_PACK_ALIGNMENT && pname != GL_UNPACK_ALIGNMENT) { - // FIXME: Create a fake GL error and throw an exception. - return; - } +DELEGATE_TO_IMPL_1(deleteBuffer, unsigned) +DELEGATE_TO_IMPL_1(deleteFramebuffer, unsigned) +DELEGATE_TO_IMPL_1(deleteProgram, unsigned) +DELEGATE_TO_IMPL_1(deleteRenderbuffer, unsigned) +DELEGATE_TO_IMPL_1(deleteShader, unsigned) +DELEGATE_TO_IMPL_1(deleteTexture, unsigned) - makeContextCurrent(); - glPixelStorei(pname, param); -} +DELEGATE_TO_IMPL_1(synthesizeGLError, unsigned long) -GL_SAME_METHOD_2(PolygonOffset, polygonOffset, double, double) +//---------------------------------------------------------------------- +// GraphicsContext3D +// -PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y, - unsigned long width, unsigned long height, - unsigned long format, unsigned long type) { - // FIXME: support more pixel formats and types. - if (!((format == GL_RGBA) && (type == GL_UNSIGNED_BYTE))) - return 0; +// Macros to assist in delegating from GraphicsContext3D to +// GraphicsContext3DInternal. - // FIXME: take into account pack alignment. - RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4); - glReadPixels(x, y, width, height, format, type, array->baseAddress()); - return array; +#define DELEGATE_TO_INTERNAL(name) \ +void GraphicsContext3D::name() \ +{ \ + m_internal->name(); \ } -void GraphicsContext3D::releaseShaderCompiler() -{ +#define DELEGATE_TO_INTERNAL_R(name, rt) \ +rt GraphicsContext3D::name() \ +{ \ + return m_internal->name(); \ } -GL_SAME_METHOD_4(RenderbufferStorageEXT, renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long) - -GL_SAME_METHOD_2(SampleCoverage, sampleCoverage, double, bool) - -GL_SAME_METHOD_4(Scissor, scissor, long, long, unsigned long, unsigned long) - -void GraphicsContext3D::shaderSource(WebGLShader* shader, const String& source) -{ - makeContextCurrent(); - CString str = source.utf8(); - const char* data = str.data(); - GLint length = str.length(); - glShaderSource(EXTRACT(shader), 1, &data, &length); +#define DELEGATE_TO_INTERNAL_1(name, t1) \ +void GraphicsContext3D::name(t1 a1) \ +{ \ + m_internal->name(a1); \ } -GL_SAME_METHOD_3(StencilFunc, stencilFunc, unsigned long, long, unsigned long) - -GL_SAME_METHOD_4(StencilFuncSeparate, stencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) - -GL_SAME_METHOD_1(StencilMask, stencilMask, unsigned long) - -GL_SAME_METHOD_2(StencilMaskSeparate, stencilMaskSeparate, unsigned long, unsigned long) - -GL_SAME_METHOD_3(StencilOp, stencilOp, unsigned long, unsigned long, unsigned long) - -GL_SAME_METHOD_4(StencilOpSeparate, stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) - -void GraphicsContext3D::synthesizeGLError(unsigned long error) -{ - m_internal->synthesizeGLError(error); -} - -int GraphicsContext3D::texImage2D(unsigned target, - unsigned level, - unsigned internalformat, - unsigned width, - unsigned height, - unsigned border, - unsigned format, - unsigned type, - void* pixels) -{ - // FIXME: must do validation similar to JOGL's to ensure that - // the incoming array is of the appropriate length. - glTexImage2D(target, - level, - internalformat, - width, - height, - border, - format, - type, - pixels); - return 0; +#define DELEGATE_TO_INTERNAL_1R(name, t1, rt) \ +rt GraphicsContext3D::name(t1 a1) \ +{ \ + return m_internal->name(a1); \ } -// Remove premultiplied alpha from color channels. -// FIXME: this is lossy. Must retrieve original values from HTMLImageElement. -static void unmultiplyAlpha(unsigned char* rgbaData, int numPixels) -{ - for (int j = 0; j < numPixels; j++) { - float b = rgbaData[4*j+0] / 255.0f; - float g = rgbaData[4*j+1] / 255.0f; - float r = rgbaData[4*j+2] / 255.0f; - float a = rgbaData[4*j+3] / 255.0f; - if (a > 0.0f) { - b /= a; - g /= a; - r /= a; - b = (b > 1.0f) ? 1.0f : b; - g = (g > 1.0f) ? 1.0f : g; - r = (r > 1.0f) ? 1.0f : r; - rgbaData[4*j+0] = (unsigned char) (b * 255.0f); - rgbaData[4*j+1] = (unsigned char) (g * 255.0f); - rgbaData[4*j+2] = (unsigned char) (r * 255.0f); - } - } +#define DELEGATE_TO_INTERNAL_2(name, t1, t2) \ +void GraphicsContext3D::name(t1 a1, t2 a2) \ +{ \ + m_internal->name(a1, a2); \ } -// FIXME: this must be changed to refer to the original image data -// rather than unmultiplying the alpha channel. -static int texImage2DHelper(unsigned target, unsigned level, - int width, int height, - int rowBytes, - bool flipY, - bool premultiplyAlpha, - GLenum format, - bool skipAlpha, - unsigned char* pixels) -{ - ASSERT(format == GL_RGBA || format == GL_BGRA); - GLint internalFormat = GL_RGBA8; - if (skipAlpha) { - internalFormat = GL_RGB8; - // Ignore the alpha channel - premultiplyAlpha = true; - } - if (flipY) { - // Need to flip images vertically. To avoid making a copy of - // the entire image, we perform a ton of glTexSubImage2D - // calls. FIXME: should rethink this strategy for efficiency. - glTexImage2D(target, level, internalFormat, - width, - height, - 0, - format, - GL_UNSIGNED_BYTE, - 0); - unsigned char* row = 0; - bool allocatedRow = false; - if (!premultiplyAlpha) { - row = new unsigned char[rowBytes]; - allocatedRow = true; - } - for (int i = 0; i < height; i++) { - if (premultiplyAlpha) - row = pixels + (rowBytes * i); - else { - memcpy(row, pixels + (rowBytes * i), rowBytes); - unmultiplyAlpha(row, width); - } - glTexSubImage2D(target, level, 0, height - i - 1, - width, 1, - format, - GL_UNSIGNED_BYTE, - row); - } - if (allocatedRow) - delete[] row; - } else { - // The pixels of cube maps' faces are defined with a top-down - // scanline ordering, unlike GL_TEXTURE_2D, so when uploading - // these, the above vertical flip is the wrong thing to do. - if (premultiplyAlpha) - glTexImage2D(target, level, internalFormat, - width, - height, - 0, - format, - GL_UNSIGNED_BYTE, - pixels); - else { - glTexImage2D(target, level, internalFormat, - width, - height, - 0, - format, - GL_UNSIGNED_BYTE, - 0); - unsigned char* row = new unsigned char[rowBytes]; - for (int i = 0; i < height; i++) { - memcpy(row, pixels + (rowBytes * i), rowBytes); - unmultiplyAlpha(row, width); - glTexSubImage2D(target, level, 0, i, - width, 1, - format, - GL_UNSIGNED_BYTE, - row); - } - delete[] row; - } - } - return 0; +#define DELEGATE_TO_INTERNAL_2R(name, t1, t2, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2) \ +{ \ + return m_internal->name(a1, a2); \ } -int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image, - bool flipY, bool premultiplyAlpha) -{ - ASSERT(image); - - int res = -1; -#if PLATFORM(SKIA) - NativeImageSkia* skiaImage = image->nativeImageForCurrentFrame(); - if (!skiaImage) { - ASSERT_NOT_REACHED(); - return -1; - } - SkBitmap::Config skiaConfig = skiaImage->config(); - // FIXME: must support more image configurations. - if (skiaConfig != SkBitmap::kARGB_8888_Config) { - ASSERT_NOT_REACHED(); - return -1; - } - SkBitmap& skiaImageRef = *skiaImage; - SkAutoLockPixels lock(skiaImageRef); - int width = skiaImage->width(); - int height = skiaImage->height(); - unsigned char* pixels = - reinterpret_cast<unsigned char*>(skiaImage->getPixels()); - int rowBytes = skiaImage->rowBytes(); - res = texImage2DHelper(target, level, - width, height, - rowBytes, - flipY, premultiplyAlpha, - GL_BGRA, - false, - pixels); -#elif PLATFORM(CG) - CGImageRef cgImage = image->nativeImageForCurrentFrame(); - if (!cgImage) { - ASSERT_NOT_REACHED(); - return -1; - } - int width = CGImageGetWidth(cgImage); - int height = CGImageGetHeight(cgImage); - int rowBytes = width * 4; - CGImageAlphaInfo info = CGImageGetAlphaInfo(cgImage); - bool skipAlpha = (info == kCGImageAlphaNone - || info == kCGImageAlphaNoneSkipLast - || info == kCGImageAlphaNoneSkipFirst); - unsigned char* imageData = new unsigned char[height * rowBytes]; - CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - CGContextRef tmpContext = CGBitmapContextCreate(imageData, width, height, 8, rowBytes, - colorSpace, - kCGImageAlphaPremultipliedLast); - CGColorSpaceRelease(colorSpace); - CGContextSetBlendMode(tmpContext, kCGBlendModeCopy); - CGContextDrawImage(tmpContext, - CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)), - cgImage); - CGContextRelease(tmpContext); - res = texImage2DHelper(target, level, width, height, rowBytes, - flipY, premultiplyAlpha, GL_RGBA, skipAlpha, imageData); - delete[] imageData; -#else -#error Must port to your platform -#endif - return res; +#define DELEGATE_TO_INTERNAL_3(name, t1, t2, t3) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ +{ \ + m_internal->name(a1, a2, a3); \ } -GL_SAME_METHOD_3(TexParameterf, texParameterf, unsigned, unsigned, float); - -GL_SAME_METHOD_3(TexParameteri, texParameteri, unsigned, unsigned, int); - -int GraphicsContext3D::texSubImage2D(unsigned target, - unsigned level, - unsigned xoffset, - unsigned yoffset, - unsigned width, - unsigned height, - unsigned format, - unsigned type, - void* pixels) -{ - glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); - return 0; +#define DELEGATE_TO_INTERNAL_3R(name, t1, t2, t3, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ +{ \ + return m_internal->name(a1, a2, a3); \ } -int GraphicsContext3D::texSubImage2D(unsigned target, - unsigned level, - unsigned xoffset, - unsigned yoffset, - Image* image, - bool flipY, - bool premultiplyAlpha) -{ - // FIXME: implement. - notImplemented(); - return -1; +#define DELEGATE_TO_INTERNAL_4(name, t1, t2, t3, t4) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + m_internal->name(a1, a2, a3, a4); \ } -GL_SAME_METHOD_2(Uniform1f, uniform1f, long, float) - -void GraphicsContext3D::uniform1fv(long location, float* v, int size) -{ - makeContextCurrent(); - glUniform1fv(location, size, v); +#define DELEGATE_TO_INTERNAL_5(name, t1, t2, t3, t4, t5) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + m_internal->name(a1, a2, a3, a4, a5); \ } -GL_SAME_METHOD_2(Uniform1i, uniform1i, long, int) - -void GraphicsContext3D::uniform1iv(long location, int* v, int size) -{ - makeContextCurrent(); - glUniform1iv(location, size, v); +#define DELEGATE_TO_INTERNAL_6(name, t1, t2, t3, t4, t5, t6) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + m_internal->name(a1, a2, a3, a4, a5, a6); \ } -GL_SAME_METHOD_3(Uniform2f, uniform2f, long, float, float) - -void GraphicsContext3D::uniform2fv(long location, float* v, int size) -{ - makeContextCurrent(); - glUniform2fv(location, size, v); +#define DELEGATE_TO_INTERNAL_6R(name, t1, t2, t3, t4, t5, t6, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + return m_internal->name(a1, a2, a3, a4, a5, a6); \ } -GL_SAME_METHOD_3(Uniform2i, uniform2i, long, int, int) - -void GraphicsContext3D::uniform2iv(long location, int* v, int size) -{ - makeContextCurrent(); - glUniform2iv(location, size, v); +#define DELEGATE_TO_INTERNAL_7(name, t1, t2, t3, t4, t5, t6, t7) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + m_internal->name(a1, a2, a3, a4, a5, a6, a7); \ } -GL_SAME_METHOD_4(Uniform3f, uniform3f, long, float, float, float) - -void GraphicsContext3D::uniform3fv(long location, float* v, int size) -{ - makeContextCurrent(); - glUniform3fv(location, size, v); +#define DELEGATE_TO_INTERNAL_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + return m_internal->name(a1, a2, a3, a4, a5, a6, a7); \ } -GL_SAME_METHOD_4(Uniform3i, uniform3i, long, int, int, int) - -void GraphicsContext3D::uniform3iv(long location, int* v, int size) -{ - makeContextCurrent(); - glUniform3iv(location, size, v); +#define DELEGATE_TO_INTERNAL_8(name, t1, t2, t3, t4, t5, t6, t7, t8) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ +{ \ + m_internal->name(a1, a2, a3, a4, a5, a6, a7, a8); \ } -GL_SAME_METHOD_5(Uniform4f, uniform4f, long, float, float, float, float) +#define DELEGATE_TO_INTERNAL_9R(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \ +{ \ + return m_internal->name(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ +} -void GraphicsContext3D::uniform4fv(long location, float* v, int size) +GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes, HostWindow*) { - makeContextCurrent(); - glUniform4fv(location, size, v); } -GL_SAME_METHOD_5(Uniform4i, uniform4i, long, int, int, int, int) - -void GraphicsContext3D::uniform4iv(long location, int* v, int size) +GraphicsContext3D::~GraphicsContext3D() { - makeContextCurrent(); - glUniform4iv(location, size, v); } -void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* value, int size) +PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) { - makeContextCurrent(); - glUniformMatrix2fv(location, size, transpose, value); + GraphicsContext3DInternal* internal = new GraphicsContext3DInternal(); + if (!internal->initialize(attrs, hostWindow)) { + delete internal; + return 0; + } + PassOwnPtr<GraphicsContext3D> result = new GraphicsContext3D(attrs, hostWindow); + result->m_internal.set(internal); + return result; } -void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* value, int size) +PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const { - makeContextCurrent(); - glUniformMatrix3fv(location, size, transpose, value); + return m_internal->platformGraphicsContext3D(); } -void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* value, int size) +Platform3DObject GraphicsContext3D::platformTexture() const { - makeContextCurrent(); - glUniformMatrix4fv(location, size, transpose, value); + return m_internal->platformTexture(); } -GL_SAME_METHOD_1_X(UseProgram, useProgram, WebGLProgram*) - -GL_SAME_METHOD_1_X(ValidateProgram, validateProgram, WebGLProgram*) - -GL_SAME_METHOD_2(VertexAttrib1f, vertexAttrib1f, unsigned long, float) - -void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* values) +void GraphicsContext3D::prepareTexture() { - makeContextCurrent(); - glVertexAttrib1fv(indx, values); + return m_internal->prepareTexture(); } -GL_SAME_METHOD_3(VertexAttrib2f, vertexAttrib2f, unsigned long, float, float) - -void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* values) +#if USE(ACCELERATED_COMPOSITING) +PlatformLayer* GraphicsContext3D::platformLayer() const { - makeContextCurrent(); - glVertexAttrib2fv(indx, values); + WebGLLayerChromium* webGLLayer = m_internal->platformLayer(); + webGLLayer->setContext(this); + return webGLLayer; } +#endif -GL_SAME_METHOD_4(VertexAttrib3f, vertexAttrib3f, unsigned long, float, float, float) +DELEGATE_TO_INTERNAL(makeContextCurrent) +DELEGATE_TO_INTERNAL_1R(sizeInBytes, int, int) +DELEGATE_TO_INTERNAL_2(reshape, int, int) -void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* values) -{ - makeContextCurrent(); - glVertexAttrib3fv(indx, values); -} +DELEGATE_TO_INTERNAL_1(activeTexture, unsigned long) +DELEGATE_TO_INTERNAL_2(attachShader, WebGLProgram*, WebGLShader*) +DELEGATE_TO_INTERNAL_3(bindAttribLocation, WebGLProgram*, unsigned long, const String&) -GL_SAME_METHOD_5(VertexAttrib4f, vertexAttrib4f, unsigned long, float, float, float, float) +DELEGATE_TO_INTERNAL_2(bindBuffer, unsigned long, WebGLBuffer*) +DELEGATE_TO_INTERNAL_2(bindFramebuffer, unsigned long, WebGLFramebuffer*) +DELEGATE_TO_INTERNAL_2(bindRenderbuffer, unsigned long, WebGLRenderbuffer*) +DELEGATE_TO_INTERNAL_2(bindTexture, unsigned long, WebGLTexture*) +DELEGATE_TO_INTERNAL_4(blendColor, double, double, double, double) +DELEGATE_TO_INTERNAL_1(blendEquation, unsigned long) +DELEGATE_TO_INTERNAL_2(blendEquationSeparate, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_2(blendFunc, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_4(blendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) -void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* values) -{ - makeContextCurrent(); - glVertexAttrib4fv(indx, values); -} +DELEGATE_TO_INTERNAL_3(bufferData, unsigned long, int, unsigned long) +DELEGATE_TO_INTERNAL_3(bufferData, unsigned long, ArrayBuffer*, unsigned long) +DELEGATE_TO_INTERNAL_3(bufferData, unsigned long, ArrayBufferView*, unsigned long) +DELEGATE_TO_INTERNAL_3(bufferSubData, unsigned long, long, ArrayBuffer*) +DELEGATE_TO_INTERNAL_3(bufferSubData, unsigned long, long, ArrayBufferView*) -void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, - unsigned long stride, unsigned long offset) -{ - m_internal->vertexAttribPointer(indx, size, type, normalized, stride, offset); -} +DELEGATE_TO_INTERNAL_1R(checkFramebufferStatus, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_1(clear, unsigned long) +DELEGATE_TO_INTERNAL_4(clearColor, double, double, double, double) +DELEGATE_TO_INTERNAL_1(clearDepth, double) +DELEGATE_TO_INTERNAL_1(clearStencil, long) +DELEGATE_TO_INTERNAL_4(colorMask, bool, bool, bool, bool) +DELEGATE_TO_INTERNAL_1(compileShader, WebGLShader*) -void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height) -{ - makeContextCurrent(); - m_internal->viewportImpl(x, y, width, height); -} +DELEGATE_TO_INTERNAL_8(copyTexImage2D, unsigned long, long, unsigned long, long, long, unsigned long, unsigned long, long) +DELEGATE_TO_INTERNAL_8(copyTexSubImage2D, unsigned long, long, long, long, long, long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_1(cullFace, unsigned long) +DELEGATE_TO_INTERNAL_1(depthFunc, unsigned long) +DELEGATE_TO_INTERNAL_1(depthMask, bool) +DELEGATE_TO_INTERNAL_2(depthRange, double, double) +DELEGATE_TO_INTERNAL_2(detachShader, WebGLProgram*, WebGLShader*) +DELEGATE_TO_INTERNAL_1(disable, unsigned long) +DELEGATE_TO_INTERNAL_1(disableVertexAttribArray, unsigned long) +DELEGATE_TO_INTERNAL_3(drawArrays, unsigned long, long, long) +DELEGATE_TO_INTERNAL_4(drawElements, unsigned long, unsigned long, unsigned long, long) + +DELEGATE_TO_INTERNAL_1(enable, unsigned long) +DELEGATE_TO_INTERNAL_1(enableVertexAttribArray, unsigned long) +DELEGATE_TO_INTERNAL(finish) +DELEGATE_TO_INTERNAL(flush) +DELEGATE_TO_INTERNAL_4(framebufferRenderbuffer, unsigned long, unsigned long, unsigned long, WebGLRenderbuffer*) +DELEGATE_TO_INTERNAL_5(framebufferTexture2D, unsigned long, unsigned long, unsigned long, WebGLTexture*, long) +DELEGATE_TO_INTERNAL_1(frontFace, unsigned long) +DELEGATE_TO_INTERNAL_1(generateMipmap, unsigned long) + +DELEGATE_TO_INTERNAL_3R(getActiveAttrib, WebGLProgram*, unsigned long, ActiveInfo&, bool) +DELEGATE_TO_INTERNAL_3R(getActiveUniform, WebGLProgram*, unsigned long, ActiveInfo&, bool) + +DELEGATE_TO_INTERNAL_4(getAttachedShaders, WebGLProgram*, int, int*, unsigned int*) + +DELEGATE_TO_INTERNAL_2R(getAttribLocation, WebGLProgram*, const String&, int) + +DELEGATE_TO_INTERNAL_2(getBooleanv, unsigned long, unsigned char*) + +DELEGATE_TO_INTERNAL_3(getBufferParameteriv, unsigned long, unsigned long, int*) + +DELEGATE_TO_INTERNAL_R(getContextAttributes, GraphicsContext3D::Attributes) + +DELEGATE_TO_INTERNAL_R(getError, unsigned long) + +DELEGATE_TO_INTERNAL_2(getFloatv, unsigned long, float*) + +DELEGATE_TO_INTERNAL_4(getFramebufferAttachmentParameteriv, unsigned long, unsigned long, unsigned long, int*) + +DELEGATE_TO_INTERNAL_2(getIntegerv, unsigned long, int*) + +DELEGATE_TO_INTERNAL_3(getProgramiv, WebGLProgram*, unsigned long, int*) + +DELEGATE_TO_INTERNAL_1R(getProgramInfoLog, WebGLProgram*, String) + +DELEGATE_TO_INTERNAL_3(getRenderbufferParameteriv, unsigned long, unsigned long, int*) + +DELEGATE_TO_INTERNAL_3(getShaderiv, WebGLShader*, unsigned long, int*) + +DELEGATE_TO_INTERNAL_1R(getShaderInfoLog, WebGLShader*, String) + +DELEGATE_TO_INTERNAL_1R(getShaderSource, WebGLShader*, String) +DELEGATE_TO_INTERNAL_1R(getString, unsigned long, String) + +DELEGATE_TO_INTERNAL_3(getTexParameterfv, unsigned long, unsigned long, float*) +DELEGATE_TO_INTERNAL_3(getTexParameteriv, unsigned long, unsigned long, int*) + +DELEGATE_TO_INTERNAL_3(getUniformfv, WebGLProgram*, long, float*) +DELEGATE_TO_INTERNAL_3(getUniformiv, WebGLProgram*, long, int*) + +DELEGATE_TO_INTERNAL_2R(getUniformLocation, WebGLProgram*, const String&, long) + +DELEGATE_TO_INTERNAL_3(getVertexAttribfv, unsigned long, unsigned long, float*) +DELEGATE_TO_INTERNAL_3(getVertexAttribiv, unsigned long, unsigned long, int*) + +DELEGATE_TO_INTERNAL_2R(getVertexAttribOffset, unsigned long, unsigned long, long) + +DELEGATE_TO_INTERNAL_2(hint, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_1R(isBuffer, WebGLBuffer*, bool) +DELEGATE_TO_INTERNAL_1R(isEnabled, unsigned long, bool) +DELEGATE_TO_INTERNAL_1R(isFramebuffer, WebGLFramebuffer*, bool) +DELEGATE_TO_INTERNAL_1R(isProgram, WebGLProgram*, bool) +DELEGATE_TO_INTERNAL_1R(isRenderbuffer, WebGLRenderbuffer*, bool) +DELEGATE_TO_INTERNAL_1R(isShader, WebGLShader*, bool) +DELEGATE_TO_INTERNAL_1R(isTexture, WebGLTexture*, bool) +DELEGATE_TO_INTERNAL_1(lineWidth, double) +DELEGATE_TO_INTERNAL_1(linkProgram, WebGLProgram*) +DELEGATE_TO_INTERNAL_2(pixelStorei, unsigned long, long) +DELEGATE_TO_INTERNAL_2(polygonOffset, double, double) + +DELEGATE_TO_INTERNAL_7(readPixels, long, long, unsigned long, unsigned long, unsigned long, unsigned long, void*) + +DELEGATE_TO_INTERNAL(releaseShaderCompiler) +DELEGATE_TO_INTERNAL_4(renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_2(sampleCoverage, double, bool) +DELEGATE_TO_INTERNAL_4(scissor, long, long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_2(shaderSource, WebGLShader*, const String&) +DELEGATE_TO_INTERNAL_3(stencilFunc, unsigned long, long, unsigned long) +DELEGATE_TO_INTERNAL_4(stencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) +DELEGATE_TO_INTERNAL_1(stencilMask, unsigned long) +DELEGATE_TO_INTERNAL_2(stencilMaskSeparate, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_3(stencilOp, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_4(stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) + +DELEGATE_TO_INTERNAL_9R(texImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, void*, int) +DELEGATE_TO_INTERNAL_3(texParameterf, unsigned, unsigned, float) +DELEGATE_TO_INTERNAL_3(texParameteri, unsigned, unsigned, int) +DELEGATE_TO_INTERNAL_9R(texSubImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, void*, int) + +DELEGATE_TO_INTERNAL_2(uniform1f, long, float) +DELEGATE_TO_INTERNAL_3(uniform1fv, long, float*, int) +DELEGATE_TO_INTERNAL_2(uniform1i, long, int) +DELEGATE_TO_INTERNAL_3(uniform1iv, long, int*, int) +DELEGATE_TO_INTERNAL_3(uniform2f, long, float, float) +DELEGATE_TO_INTERNAL_3(uniform2fv, long, float*, int) +DELEGATE_TO_INTERNAL_3(uniform2i, long, int, int) +DELEGATE_TO_INTERNAL_3(uniform2iv, long, int*, int) +DELEGATE_TO_INTERNAL_4(uniform3f, long, float, float, float) +DELEGATE_TO_INTERNAL_3(uniform3fv, long, float*, int) +DELEGATE_TO_INTERNAL_4(uniform3i, long, int, int, int) +DELEGATE_TO_INTERNAL_3(uniform3iv, long, int*, int) +DELEGATE_TO_INTERNAL_5(uniform4f, long, float, float, float, float) +DELEGATE_TO_INTERNAL_3(uniform4fv, long, float*, int) +DELEGATE_TO_INTERNAL_5(uniform4i, long, int, int, int, int) +DELEGATE_TO_INTERNAL_3(uniform4iv, long, int*, int) +DELEGATE_TO_INTERNAL_4(uniformMatrix2fv, long, bool, float*, int) +DELEGATE_TO_INTERNAL_4(uniformMatrix3fv, long, bool, float*, int) +DELEGATE_TO_INTERNAL_4(uniformMatrix4fv, long, bool, float*, int) -} +DELEGATE_TO_INTERNAL_1(useProgram, WebGLProgram*) +DELEGATE_TO_INTERNAL_1(validateProgram, WebGLProgram*) + +DELEGATE_TO_INTERNAL_2(vertexAttrib1f, unsigned long, float) +DELEGATE_TO_INTERNAL_2(vertexAttrib1fv, unsigned long, float*) +DELEGATE_TO_INTERNAL_3(vertexAttrib2f, unsigned long, float, float) +DELEGATE_TO_INTERNAL_2(vertexAttrib2fv, unsigned long, float*) +DELEGATE_TO_INTERNAL_4(vertexAttrib3f, unsigned long, float, float, float) +DELEGATE_TO_INTERNAL_2(vertexAttrib3fv, unsigned long, float*) +DELEGATE_TO_INTERNAL_5(vertexAttrib4f, unsigned long, float, float, float, float) +DELEGATE_TO_INTERNAL_2(vertexAttrib4fv, unsigned long, float*) +DELEGATE_TO_INTERNAL_6(vertexAttribPointer, unsigned long, int, int, bool, unsigned long, unsigned long) + +DELEGATE_TO_INTERNAL_4(viewport, long, long, unsigned long, unsigned long) + +DELEGATE_TO_INTERNAL_1(paintRenderingResultsToCanvas, WebGLRenderingContext*) +DELEGATE_TO_INTERNAL_1(beginPaint, WebGLRenderingContext*) +DELEGATE_TO_INTERNAL(endPaint) + +DELEGATE_TO_INTERNAL_R(createBuffer, unsigned) +DELEGATE_TO_INTERNAL_R(createFramebuffer, unsigned) +DELEGATE_TO_INTERNAL_R(createProgram, unsigned) +DELEGATE_TO_INTERNAL_R(createRenderbuffer, unsigned) +DELEGATE_TO_INTERNAL_1R(createShader, unsigned long, unsigned) +DELEGATE_TO_INTERNAL_R(createTexture, unsigned) + +DELEGATE_TO_INTERNAL_1(deleteBuffer, unsigned) +DELEGATE_TO_INTERNAL_1(deleteFramebuffer, unsigned) +DELEGATE_TO_INTERNAL_1(deleteProgram, unsigned) +DELEGATE_TO_INTERNAL_1(deleteRenderbuffer, unsigned) +DELEGATE_TO_INTERNAL_1(deleteShader, unsigned) +DELEGATE_TO_INTERNAL_1(deleteTexture, unsigned) + +DELEGATE_TO_INTERNAL_1(synthesizeGLError, unsigned long) + +bool GraphicsContext3D::isGLES2Compliant() const +{ + return m_internal->isGLES2Compliant(); +} + +} // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebKit/chromium/src/IDBCallbacksProxy.cpp b/WebKit/chromium/src/IDBCallbacksProxy.cpp new file mode 100644 index 0000000..3591bee --- /dev/null +++ b/WebKit/chromium/src/IDBCallbacksProxy.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IDBCallbacksProxy.h" + +#include "IDBDatabaseError.h" +#include "IDBDatabaseProxy.h" +#include "WebIDBCallbacks.h" +#include "WebIDBDatabaseImpl.h" +#include "WebIDBDatabaseError.h" +#include "WebIDBIndexImpl.h" +#include "WebIDBKey.h" +#include "WebIDBObjectStoreImpl.h" +#include "WebSerializedScriptValue.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +PassRefPtr<IDBCallbacksProxy> IDBCallbacksProxy::create(PassOwnPtr<WebKit::WebIDBCallbacks> callbacks) +{ + return adoptRef(new IDBCallbacksProxy(callbacks)); +} + +IDBCallbacksProxy::IDBCallbacksProxy(PassOwnPtr<WebKit::WebIDBCallbacks> callbacks) + : m_callbacks(callbacks) +{ +} + +IDBCallbacksProxy::~IDBCallbacksProxy() +{ +} + +void IDBCallbacksProxy::onError(PassRefPtr<IDBDatabaseError> idbDatabaseError) +{ + m_callbacks->onError(WebKit::WebIDBDatabaseError(idbDatabaseError)); + m_callbacks.clear(); +} + +void IDBCallbacksProxy::onSuccess() +{ + m_callbacks->onSuccess(); + m_callbacks.clear(); +} + +void IDBCallbacksProxy::onSuccess(PassRefPtr<IDBDatabase> idbDatabase) +{ + m_callbacks->onSuccess(new WebKit::WebIDBDatabaseImpl(idbDatabase)); + m_callbacks.clear(); +} + +void IDBCallbacksProxy::onSuccess(PassRefPtr<IDBIndex> idbIndex) +{ + m_callbacks->onSuccess(new WebKit::WebIDBIndexImpl(idbIndex)); + m_callbacks.clear(); +} + +void IDBCallbacksProxy::onSuccess(PassRefPtr<IDBKey> idbKey) +{ + m_callbacks->onSuccess(WebKit::WebIDBKey(idbKey)); + m_callbacks.clear(); +} + +void IDBCallbacksProxy::onSuccess(PassRefPtr<IDBObjectStore> idbObjectStore) +{ + m_callbacks->onSuccess(new WebKit::WebIDBObjectStoreImpl(idbObjectStore)); + m_callbacks.clear(); +} + +void IDBCallbacksProxy::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptValue) +{ + m_callbacks->onSuccess(WebKit::WebSerializedScriptValue(serializedScriptValue)); + m_callbacks.clear(); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/IDBCallbacksProxy.h b/WebKit/chromium/src/IDBCallbacksProxy.h new file mode 100644 index 0000000..c5a8858 --- /dev/null +++ b/WebKit/chromium/src/IDBCallbacksProxy.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IDBCallbacksProxy_h +#define IDBCallbacksProxy_h + +#include "IDBCallbacks.h" +#include <wtf/PassOwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +namespace WebKit { +class WebIDBCallbacks; +} + +namespace WebCore { + +class IDBCallbacksProxy : public IDBCallbacks { +public: + static PassRefPtr<IDBCallbacksProxy> create(PassOwnPtr<WebKit::WebIDBCallbacks>); + virtual ~IDBCallbacksProxy(); + + virtual void onError(PassRefPtr<IDBDatabaseError>); + virtual void onSuccess(); // For "null". + virtual void onSuccess(PassRefPtr<IDBDatabase>); + virtual void onSuccess(PassRefPtr<IDBIndex>); + virtual void onSuccess(PassRefPtr<IDBKey>); + virtual void onSuccess(PassRefPtr<IDBObjectStore>); + virtual void onSuccess(PassRefPtr<SerializedScriptValue>); + +private: + IDBCallbacksProxy(PassOwnPtr<WebKit::WebIDBCallbacks>); + + OwnPtr<WebKit::WebIDBCallbacks> m_callbacks; +}; + + +} // namespace WebCore + +#endif + +#endif // IDBCallbacksProxy_h diff --git a/WebKit/chromium/src/IDBDatabaseProxy.cpp b/WebKit/chromium/src/IDBDatabaseProxy.cpp new file mode 100644 index 0000000..9d009c0 --- /dev/null +++ b/WebKit/chromium/src/IDBDatabaseProxy.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IDBDatabaseProxy.h" + +#include "DOMStringList.h" +#include "IDBCallbacks.h" +#include "IDBObjectStoreProxy.h" +#include "WebFrameImpl.h" +#include "WebIDBCallbacksImpl.h" +#include "WebIDBDatabase.h" +#include "WebIDBDatabaseError.h" +#include "WebIDBObjectStore.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +PassRefPtr<IDBDatabase> IDBDatabaseProxy::create(PassOwnPtr<WebKit::WebIDBDatabase> database) +{ + return adoptRef(new IDBDatabaseProxy(database)); +} + +IDBDatabaseProxy::IDBDatabaseProxy(PassOwnPtr<WebKit::WebIDBDatabase> database) + : m_webIDBDatabase(database) +{ +} + +IDBDatabaseProxy::~IDBDatabaseProxy() +{ +} + +String IDBDatabaseProxy::name() const +{ + return m_webIDBDatabase->name(); +} + +String IDBDatabaseProxy::description() const +{ + return m_webIDBDatabase->description(); +} + +String IDBDatabaseProxy::version() const +{ + return m_webIDBDatabase->version(); +} + +PassRefPtr<DOMStringList> IDBDatabaseProxy::objectStores() const +{ + return m_webIDBDatabase->objectStores(); +} + +void IDBDatabaseProxy::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks> callbacks) +{ + m_webIDBDatabase->createObjectStore(name, keyPath, autoIncrement, new WebIDBCallbacksImpl(callbacks)); +} + +PassRefPtr<IDBObjectStore> IDBDatabaseProxy::objectStore(const String& name, unsigned short mode) +{ + WebKit::WebIDBObjectStore* objectStore = m_webIDBDatabase->objectStore(name, mode); + if (!objectStore) + return 0; + return IDBObjectStoreProxy::create(objectStore); +} + +void IDBDatabaseProxy::removeObjectStore(const String& name, PassRefPtr<IDBCallbacks> callbacks) +{ + m_webIDBDatabase->removeObjectStore(name, new WebIDBCallbacksImpl(callbacks)); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/IDBDatabaseProxy.h b/WebKit/chromium/src/IDBDatabaseProxy.h new file mode 100644 index 0000000..36588f0 --- /dev/null +++ b/WebKit/chromium/src/IDBDatabaseProxy.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IDBDatabaseProxy_h +#define IDBDatabaseProxy_h + +#include "IDBDatabase.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/PassRefPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +namespace WebKit { class WebIDBDatabase; } + +namespace WebCore { + +class IDBDatabaseProxy : public IDBDatabase { +public: + static PassRefPtr<IDBDatabase> create(PassOwnPtr<WebKit::WebIDBDatabase>); + virtual ~IDBDatabaseProxy(); + + virtual String name() const; + virtual String description() const; + virtual String version() const; + virtual PassRefPtr<DOMStringList> objectStores() const; + + // FIXME: Add transaction and setVersion. + + virtual void createObjectStore(const String& name, const String& keyPath, bool autoIncrement, PassRefPtr<IDBCallbacks>); + virtual PassRefPtr<IDBObjectStore> objectStore(const String& name, unsigned short mode); + virtual void removeObjectStore(const String& name, PassRefPtr<IDBCallbacks>); + +private: + IDBDatabaseProxy(PassOwnPtr<WebKit::WebIDBDatabase>); + + OwnPtr<WebKit::WebIDBDatabase> m_webIDBDatabase; +}; + +} // namespace WebCore + +#endif + +#endif // IDBDatabaseProxy_h diff --git a/WebKit/chromium/src/IDBIndexProxy.cpp b/WebKit/chromium/src/IDBIndexProxy.cpp new file mode 100644 index 0000000..f80eff3 --- /dev/null +++ b/WebKit/chromium/src/IDBIndexProxy.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IDBIndexProxy.h" + +#include "WebIDBDatabaseError.h" +#include "WebIDBIndex.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +PassRefPtr<IDBIndex> IDBIndexProxy::create(PassOwnPtr<WebKit::WebIDBIndex> Index) +{ + return adoptRef(new IDBIndexProxy(Index)); +} + +IDBIndexProxy::IDBIndexProxy(PassOwnPtr<WebKit::WebIDBIndex> Index) + : m_webIDBIndex(Index) +{ +} + +IDBIndexProxy::~IDBIndexProxy() +{ +} + +String IDBIndexProxy::name() +{ + return m_webIDBIndex->name(); +} + +String IDBIndexProxy::keyPath() +{ + return m_webIDBIndex->keyPath(); +} + +bool IDBIndexProxy::unique() +{ + return m_webIDBIndex->unique(); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/IDBIndexProxy.h b/WebKit/chromium/src/IDBIndexProxy.h new file mode 100644 index 0000000..35e6b30 --- /dev/null +++ b/WebKit/chromium/src/IDBIndexProxy.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IDBIndexProxy_h +#define IDBIndexProxy_h + +#include "IDBIndex.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/PassRefPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +namespace WebKit { class WebIDBIndex; } + +namespace WebCore { + +class IDBIndexProxy : public IDBIndex { +public: + static PassRefPtr<IDBIndex> create(PassOwnPtr<WebKit::WebIDBIndex>); + virtual ~IDBIndexProxy(); + + virtual String name(); + virtual String keyPath(); + virtual bool unique(); + + // FIXME: Add other methods. + +private: + IDBIndexProxy(PassOwnPtr<WebKit::WebIDBIndex>); + + OwnPtr<WebKit::WebIDBIndex> m_webIDBIndex; +}; + +} // namespace WebCore + +#endif + +#endif // IDBIndexProxy_h diff --git a/WebKit/chromium/src/IDBObjectStoreProxy.cpp b/WebKit/chromium/src/IDBObjectStoreProxy.cpp new file mode 100755 index 0000000..cec4ed3 --- /dev/null +++ b/WebKit/chromium/src/IDBObjectStoreProxy.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IDBObjectStoreProxy.h" + +#include "DOMStringList.h" +#include "IDBCallbacks.h" +#include "IDBIndexProxy.h" +#include "WebIDBCallbacksImpl.h" +#include "WebIDBIndex.h" +#include "WebIDBKey.h" +#include "WebIDBObjectStore.h" +#include "WebSerializedScriptValue.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +PassRefPtr<IDBObjectStore> IDBObjectStoreProxy::create(PassOwnPtr<WebKit::WebIDBObjectStore> objectStore) +{ + return adoptRef(new IDBObjectStoreProxy(objectStore)); +} + +IDBObjectStoreProxy::IDBObjectStoreProxy(PassOwnPtr<WebKit::WebIDBObjectStore> objectStore) + : m_webIDBObjectStore(objectStore) +{ +} + +IDBObjectStoreProxy::~IDBObjectStoreProxy() +{ +} + +String IDBObjectStoreProxy::name() const +{ + return m_webIDBObjectStore->name(); +} + +String IDBObjectStoreProxy::keyPath() const +{ + return m_webIDBObjectStore->keyPath(); +} + +PassRefPtr<DOMStringList> IDBObjectStoreProxy::indexNames() const +{ + return m_webIDBObjectStore->indexNames(); +} + +void IDBObjectStoreProxy::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) +{ + m_webIDBObjectStore->get(key, new WebIDBCallbacksImpl(callbacks)); +} + +void IDBObjectStoreProxy::put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks> callbacks) +{ + m_webIDBObjectStore->put(value, key, addOnly, new WebIDBCallbacksImpl(callbacks)); +} + +void IDBObjectStoreProxy::remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) +{ + m_webIDBObjectStore->remove(key, new WebIDBCallbacksImpl(callbacks)); +} + +void IDBObjectStoreProxy::createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks> callbacks) +{ + m_webIDBObjectStore->createIndex(name, keyPath, unique, new WebIDBCallbacksImpl(callbacks)); +} + +PassRefPtr<IDBIndex> IDBObjectStoreProxy::index(const String& name) +{ + WebKit::WebIDBIndex* index = m_webIDBObjectStore->index(name); + if (!index) + return 0; + return IDBIndexProxy::create(index); +} + +void IDBObjectStoreProxy::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks) +{ + m_webIDBObjectStore->removeIndex(name, new WebIDBCallbacksImpl(callbacks)); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/IDBObjectStoreProxy.h b/WebKit/chromium/src/IDBObjectStoreProxy.h new file mode 100755 index 0000000..b8e4a01 --- /dev/null +++ b/WebKit/chromium/src/IDBObjectStoreProxy.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IDBObjectStoreProxy_h +#define IDBObjectStoreProxy_h + +#include "IDBObjectStore.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/PassRefPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +namespace WebKit { class WebIDBObjectStore; } + +namespace WebCore { + +class DOMStringList; +class IDBIndex; + +class IDBObjectStoreProxy : public IDBObjectStore { +public: + static PassRefPtr<IDBObjectStore> create(PassOwnPtr<WebKit::WebIDBObjectStore>); + ~IDBObjectStoreProxy(); + + String name() const; + String keyPath() const; + PassRefPtr<DOMStringList> indexNames() const; + + void get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>); + void put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, bool addOnly, PassRefPtr<IDBCallbacks>); + void remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks>); + + void createIndex(const String& name, const String& keyPath, bool unique, PassRefPtr<IDBCallbacks>); + PassRefPtr<IDBIndex> index(const String& name); + void removeIndex(const String& name, PassRefPtr<IDBCallbacks>); + +private: + IDBObjectStoreProxy(PassOwnPtr<WebKit::WebIDBObjectStore>); + + OwnPtr<WebKit::WebIDBObjectStore> m_webIDBObjectStore; +}; + +} // namespace WebCore + +#endif + +#endif // IDBObjectStoreProxy_h + diff --git a/WebKit/chromium/src/IndexedDatabaseProxy.cpp b/WebKit/chromium/src/IndexedDatabaseProxy.cpp new file mode 100644 index 0000000..bee99b2 --- /dev/null +++ b/WebKit/chromium/src/IndexedDatabaseProxy.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IndexedDatabaseProxy.h" + +#include "IDBDatabaseError.h" +#include "IDBDatabaseProxy.h" +#include "WebFrameImpl.h" +#include "WebIDBCallbacksImpl.h" +#include "WebIDBDatabase.h" +#include "WebIDBDatabaseError.h" +#include "WebIndexedDatabase.h" +#include "WebKit.h" +#include "WebKitClient.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +PassRefPtr<IndexedDatabase> IndexedDatabaseProxy::create() +{ + return adoptRef(new IndexedDatabaseProxy()); +} + +IndexedDatabaseProxy::IndexedDatabaseProxy() + : m_webIndexedDatabase(WebKit::webKitClient()->indexedDatabase()) +{ +} + +IndexedDatabaseProxy::~IndexedDatabaseProxy() +{ +} + +void IndexedDatabaseProxy::open(const String& name, const String& description, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> origin, Frame* frame) +{ + WebKit::WebFrame* webFrame = WebKit::WebFrameImpl::fromFrame(frame); + m_webIndexedDatabase->open(name, description, new WebIDBCallbacksImpl(callbacks), origin, webFrame); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) + diff --git a/WebKit/chromium/src/IndexedDatabaseProxy.h b/WebKit/chromium/src/IndexedDatabaseProxy.h new file mode 100644 index 0000000..53097f0 --- /dev/null +++ b/WebKit/chromium/src/IndexedDatabaseProxy.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IndexedDatabaseProxy_h +#define IndexedDatabaseProxy_h + +#include "IndexedDatabase.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebKit { class WebIndexedDatabase; } + +namespace WebCore { + +class IndexedDatabaseProxy : public IndexedDatabase { +public: + static PassRefPtr<IndexedDatabase> create(); + virtual ~IndexedDatabaseProxy(); + + virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*); + +private: + IndexedDatabaseProxy(); + + // We don't own this pointer (unlike all the other proxy classes which do). + WebKit::WebIndexedDatabase* m_webIndexedDatabase; +}; + +} // namespace WebCore + +#endif + +#endif // IndexedDatabaseProxy_h + diff --git a/WebKit/chromium/src/InspectorClientImpl.cpp b/WebKit/chromium/src/InspectorClientImpl.cpp index 54550d1..cf491f7 100644 --- a/WebKit/chromium/src/InspectorClientImpl.cpp +++ b/WebKit/chromium/src/InspectorClientImpl.cpp @@ -33,10 +33,10 @@ #include "DOMWindow.h" #include "FloatRect.h" -#include "InspectorController.h" #include "NotImplemented.h" #include "Page.h" -#include "Settings.h" +#include "WebDevToolsAgentImpl.h" +#include "WebDevToolsMessageData.h" #include "WebRect.h" #include "WebURL.h" #include "WebURLRequest.h" @@ -60,159 +60,74 @@ InspectorClientImpl::~InspectorClientImpl() void InspectorClientImpl::inspectorDestroyed() { - // Our lifetime is bound to the WebViewImpl. + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->inspectorDestroyed(); } -Page* InspectorClientImpl::createPage() +void InspectorClientImpl::openInspectorFrontend(InspectorController* controller) { - // This method should never be called in Chrome as inspector front-end lives - // in a separate process. - ASSERT_NOT_REACHED(); - return 0; -} - -void InspectorClientImpl::showWindow() -{ - ASSERT(m_inspectedWebView->devToolsAgentPrivate()); - m_inspectedWebView->page()->inspectorController()->setWindowVisible(true); -} - -void InspectorClientImpl::closeWindow() -{ - if (m_inspectedWebView->page()) - m_inspectedWebView->page()->inspectorController()->setWindowVisible(false); -} - -bool InspectorClientImpl::windowVisible() -{ - ASSERT(m_inspectedWebView->devToolsAgentPrivate()); - return false; -} - -void InspectorClientImpl::attachWindow() -{ - // FIXME: Implement this -} - -void InspectorClientImpl::detachWindow() -{ - // FIXME: Implement this -} - -void InspectorClientImpl::setAttachedWindowHeight(unsigned int height) -{ - // FIXME: Implement this - notImplemented(); -} - -static void invalidateNodeBoundingRect(WebViewImpl* webView) -{ - // FIXME: Is it important to just invalidate the rect of the node region - // given that this is not on a critical codepath? In order to do so, we'd - // have to take scrolling into account. - const WebSize& size = webView->size(); - WebRect damagedRect(0, 0, size.width, size.height); - if (webView->client()) - webView->client()->didInvalidateRect(damagedRect); + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->openInspectorFrontend(controller); } void InspectorClientImpl::highlight(Node* node) { - // InspectorController does the actually tracking of the highlighted node - // and the drawing of the highlight. Here we just make sure to invalidate - // the rects of the old and new nodes. - hideHighlight(); + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->highlight(node); } void InspectorClientImpl::hideHighlight() { - // FIXME: able to invalidate a smaller rect. - invalidateNodeBoundingRect(m_inspectedWebView); + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->hideHighlight(); } -void InspectorClientImpl::inspectedURLChanged(const String& newURL) +void InspectorClientImpl::populateSetting(const String& key, String* value) { - // FIXME: Implement this + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->populateSetting(key, value); } -String InspectorClientImpl::localizedStringsURL() +void InspectorClientImpl::storeSetting(const String& key, const String& value) { - notImplemented(); - return String(); + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->storeSetting(key, value); } -String InspectorClientImpl::hiddenPanels() +bool InspectorClientImpl::sendMessageToFrontend(const WebCore::String& message) { - notImplemented(); - return ""; + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + return agent->sendMessageToFrontend(message); + return false; } -void InspectorClientImpl::populateSetting(const String& key, String* value) +void InspectorClientImpl::resourceTrackingWasEnabled() { - loadSettings(); - if (m_settings->contains(key)) - *value = m_settings->get(key); + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->resourceTrackingWasEnabled(); } -void InspectorClientImpl::storeSetting(const String& key, const String& value) +void InspectorClientImpl::resourceTrackingWasDisabled() { - loadSettings(); - m_settings->set(key, value); - saveSettings(); + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->resourceTrackingWasDisabled(); } -void InspectorClientImpl::inspectorWindowObjectCleared() +void InspectorClientImpl::timelineProfilerWasStarted() { - notImplemented(); + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->timelineProfilerWasStarted(); } -void InspectorClientImpl::loadSettings() +void InspectorClientImpl::timelineProfilerWasStopped() { - if (m_settings) - return; - - m_settings.set(new SettingsMap); - String data = m_inspectedWebView->inspectorSettings(); - if (data.isEmpty()) - return; - - Vector<String> entries; - data.split("\n", entries); - for (Vector<String>::iterator it = entries.begin(); it != entries.end(); ++it) { - Vector<String> tokens; - it->split(":", tokens); - if (tokens.size() < 3) - continue; - - String name = decodeURLEscapeSequences(tokens[0]); - String type = tokens[1]; - String value = tokens[2]; - for (size_t i = 3; i < tokens.size(); ++i) - value += ":" + tokens[i]; - - if (type == "string") - value = decodeURLEscapeSequences(value); - - m_settings->set(name, value); - } + if (WebDevToolsAgentImpl* agent = devToolsAgent()) + agent->timelineProfilerWasStopped(); } -void InspectorClientImpl::saveSettings() +WebDevToolsAgentImpl* InspectorClientImpl::devToolsAgent() { - String data; - for (SettingsMap::iterator it = m_settings->begin(); it != m_settings->end(); ++it) { - String name = encodeWithURLEscapeSequences(it->first); - String value = it->second; - String entry = String::format( - "%s:string:%s", - name.utf8().data(), - encodeWithURLEscapeSequences(value).utf8().data()); - data.append(entry); - data.append("\n"); - } - m_inspectedWebView->setInspectorSettings(data); - if (m_inspectedWebView->client()) - m_inspectedWebView->client()->didUpdateInspectorSettings(); + return static_cast<WebDevToolsAgentImpl*>(m_inspectedWebView->devToolsAgent()); } } // namespace WebKit diff --git a/WebKit/chromium/src/InspectorClientImpl.h b/WebKit/chromium/src/InspectorClientImpl.h index 6f7f8b1..0605ccd 100644 --- a/WebKit/chromium/src/InspectorClientImpl.h +++ b/WebKit/chromium/src/InspectorClientImpl.h @@ -36,6 +36,9 @@ #include <wtf/OwnPtr.h> namespace WebKit { + +class WebDevToolsAgentClient; +class WebDevToolsAgentImpl; class WebViewImpl; class InspectorClientImpl : public WebCore::InspectorClient { @@ -45,35 +48,25 @@ public: // InspectorClient methods: virtual void inspectorDestroyed(); - virtual WebCore::Page* createPage(); - virtual WebCore::String localizedStringsURL(); - virtual WebCore::String hiddenPanels(); - virtual void showWindow(); - virtual void closeWindow(); - virtual bool windowVisible(); - virtual void attachWindow(); - virtual void detachWindow(); - virtual void setAttachedWindowHeight(unsigned height); + virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual void highlight(WebCore::Node*); virtual void hideHighlight(); - virtual void inspectedURLChanged(const WebCore::String& newURL); - virtual void populateSetting( - const WebCore::String& key, - WebCore::String* value); - virtual void storeSetting( - const WebCore::String& key, - const WebCore::String& value); - virtual void inspectorWindowObjectCleared(); + virtual void populateSetting(const WebCore::String& key, WebCore::String* value); + virtual void storeSetting(const WebCore::String& key, const WebCore::String& value); + + virtual bool sendMessageToFrontend(const WebCore::String&); + + virtual void resourceTrackingWasEnabled(); + virtual void resourceTrackingWasDisabled(); + virtual void timelineProfilerWasStarted(); + virtual void timelineProfilerWasStopped(); private: - void loadSettings(); - void saveSettings(); + WebDevToolsAgentImpl* devToolsAgent(); // The WebViewImpl of the page being inspected; gets passed to the constructor WebViewImpl* m_inspectedWebView; - - typedef HashMap<WebCore::String, WebCore::String> SettingsMap; - OwnPtr<SettingsMap> m_settings; }; } // namespace WebKit diff --git a/WebKit/chromium/src/InspectorFrontendClientImpl.cpp b/WebKit/chromium/src/InspectorFrontendClientImpl.cpp new file mode 100644 index 0000000..870bdee --- /dev/null +++ b/WebKit/chromium/src/InspectorFrontendClientImpl.cpp @@ -0,0 +1,138 @@ +/* + * 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 "InspectorFrontendClientImpl.h" + +#include "Document.h" +#include "Frame.h" +#include "InspectorFrontendHost.h" +#include "Page.h" +#include "PlatformString.h" +#include "V8InspectorFrontendHost.h" +#include "V8Proxy.h" +#include "WebDevToolsFrontendClient.h" +#include "WebDevToolsFrontendImpl.h" + +using namespace WebCore; + +namespace WebKit { + +InspectorFrontendClientImpl::InspectorFrontendClientImpl(Page* frontendPage, WebDevToolsFrontendClient* client, WebDevToolsFrontendImpl* frontend) + : m_frontendPage(frontendPage) + , m_client(client) + , m_frontend(frontend) +{ +} + +InspectorFrontendClientImpl::~InspectorFrontendClientImpl() +{ + if (m_frontendHost) + m_frontendHost->disconnectClient(); + m_client = 0; +} + +void InspectorFrontendClientImpl::windowObjectCleared() +{ + v8::HandleScope handleScope; + v8::Handle<v8::Context> frameContext = V8Proxy::context(m_frontendPage->mainFrame()); + v8::Context::Scope contextScope(frameContext); + + ASSERT(!m_frontendHost); + m_frontendHost = InspectorFrontendHost::create(this, m_frontendPage); + v8::Handle<v8::Value> frontendHostObj = toV8(m_frontendHost.get()); + v8::Handle<v8::Object> global = frameContext->Global(); + + global->Set(v8::String::New("InspectorFrontendHost"), frontendHostObj); +} + +void InspectorFrontendClientImpl::frontendLoaded() +{ + m_frontend->frontendLoaded(); +} + +void InspectorFrontendClientImpl::moveWindowBy(float x, float y) +{ +} + +String InspectorFrontendClientImpl::localizedStringsURL() +{ + return ""; +} + +String InspectorFrontendClientImpl::hiddenPanels() +{ + if (m_client->shouldHideScriptsPanel()) + return "scripts"; + return ""; +} + +void InspectorFrontendClientImpl::bringToFront() +{ + m_client->activateWindow(); +} + +void InspectorFrontendClientImpl::closeWindow() +{ + m_client->closeWindow(); +} + +void InspectorFrontendClientImpl::requestAttachWindow() +{ + m_client->requestDockWindow(); +} + +void InspectorFrontendClientImpl::requestDetachWindow() +{ + m_client->requestUndockWindow(); +} + +void InspectorFrontendClientImpl::changeAttachedWindowHeight(unsigned) +{ + // Do nothing; +} + +void InspectorFrontendClientImpl::inspectedURLChanged(const String& url) +{ + m_frontendPage->mainFrame()->document()->setTitle("Developer Tools - " + url); +} + +void InspectorFrontendClientImpl::sendMessageToBackend(const String& message) +{ + WebDevToolsMessageData messageData; + messageData.className = "ToolsAgent"; + messageData.methodName = "dispatchOnInspectorController"; + WebVector<WebString> args(static_cast<size_t>(1)); + args[0] = message; + messageData.arguments.swap(args); + m_client->sendMessageToAgent(messageData); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/InspectorFrontendClientImpl.h b/WebKit/chromium/src/InspectorFrontendClientImpl.h new file mode 100644 index 0000000..f7174ce --- /dev/null +++ b/WebKit/chromium/src/InspectorFrontendClientImpl.h @@ -0,0 +1,81 @@ +/* + * 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 InspectorFrontendClientImpl_h +#define InspectorFrontendClientImpl_h + +#include "InspectorFrontendClient.h" +#include <wtf/Noncopyable.h> + +namespace WebCore { +class InspectorFrontendHost; +class Page; +} + +namespace WebKit { + +class WebDevToolsFrontendClient; +class WebDevToolsFrontendImpl; + +class InspectorFrontendClientImpl : public WebCore::InspectorFrontendClient + , public Noncopyable { +public: + InspectorFrontendClientImpl(WebCore::Page*, WebDevToolsFrontendClient*, WebDevToolsFrontendImpl*); + virtual ~InspectorFrontendClientImpl(); + + // InspectorFrontendClient methods: + virtual void windowObjectCleared(); + virtual void frontendLoaded(); + + virtual void moveWindowBy(float x, float y); + + virtual WebCore::String localizedStringsURL(); + virtual WebCore::String hiddenPanels(); + + virtual void bringToFront(); + virtual void closeWindow(); + + virtual void requestAttachWindow(); + virtual void requestDetachWindow(); + virtual void changeAttachedWindowHeight(unsigned); + + virtual void inspectedURLChanged(const WebCore::String&); + + virtual void sendMessageToBackend(const WebCore::String&); +private: + WebCore::Page* m_frontendPage; + WebDevToolsFrontendClient* m_client; + WebDevToolsFrontendImpl* m_frontend; + RefPtr<WebCore::InspectorFrontendHost> m_frontendHost; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/LocalizedStrings.cpp b/WebKit/chromium/src/LocalizedStrings.cpp index 4e01848..74ff699 100644 --- a/WebKit/chromium/src/LocalizedStrings.cpp +++ b/WebKit/chromium/src/LocalizedStrings.cpp @@ -174,6 +174,18 @@ String AXMenuListActionVerb() { return String(); } + +String missingPluginText() +{ + notImplemented(); + return String("Missing Plug-in"); +} + +String crashedPluginText() +{ + notImplemented(); + return String("Plug-in Failure"); +} String multipleFileUploadText(unsigned numberOfFiles) { diff --git a/WebKit/chromium/src/NotificationPresenterImpl.cpp b/WebKit/chromium/src/NotificationPresenterImpl.cpp index a38b8b5..1931465 100644 --- a/WebKit/chromium/src/NotificationPresenterImpl.cpp +++ b/WebKit/chromium/src/NotificationPresenterImpl.cpp @@ -33,11 +33,11 @@ #if ENABLE(NOTIFICATIONS) -#include "Document.h" +#include "KURL.h" #include "Notification.h" +#include "ScriptExecutionContext.h" #include "SecurityOrigin.h" -#include "WebDocument.h" #include "WebNotification.h" #include "WebNotificationPermissionCallback.h" #include "WebNotificationPresenter.h" @@ -92,19 +92,15 @@ void NotificationPresenterImpl::notificationObjectDestroyed(Notification* notifi m_presenter->objectDestroyed(PassRefPtr<Notification>(notification)); } -NotificationPresenter::Permission NotificationPresenterImpl::checkPermission(const KURL& url, Document* document) +NotificationPresenter::Permission NotificationPresenterImpl::checkPermission(ScriptExecutionContext* context) { - WebDocument webDocument; - if (document) - webDocument = document; - - int result = m_presenter->checkPermission(url, document ? &webDocument : 0); + int result = m_presenter->checkPermission(context->url()); return static_cast<NotificationPresenter::Permission>(result); } -void NotificationPresenterImpl::requestPermission(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback) +void NotificationPresenterImpl::requestPermission(ScriptExecutionContext* context, PassRefPtr<VoidCallback> callback) { - m_presenter->requestPermission(origin->toString(), new VoidCallbackClient(callback)); + m_presenter->requestPermission(WebSecurityOrigin(context->securityOrigin()), new VoidCallbackClient(callback)); } } // namespace WebKit diff --git a/WebKit/chromium/src/NotificationPresenterImpl.h b/WebKit/chromium/src/NotificationPresenterImpl.h index 8e3799c..bb156dd 100644 --- a/WebKit/chromium/src/NotificationPresenterImpl.h +++ b/WebKit/chromium/src/NotificationPresenterImpl.h @@ -54,8 +54,9 @@ public: virtual bool show(WebCore::Notification* object); virtual void cancel(WebCore::Notification* object); virtual void notificationObjectDestroyed(WebCore::Notification* object); - virtual WebCore::NotificationPresenter::Permission checkPermission(const WebCore::KURL& url, WebCore::Document* document); - virtual void requestPermission(WebCore::SecurityOrigin* origin, WTF::PassRefPtr<WebCore::VoidCallback> callback); + virtual WebCore::NotificationPresenter::Permission checkPermission(WebCore::ScriptExecutionContext*); + virtual void requestPermission(WebCore::ScriptExecutionContext* , WTF::PassRefPtr<WebCore::VoidCallback> callback); + virtual void cancelRequestsForPermission(WebCore::ScriptExecutionContext*) {} private: // WebNotificationPresenter that this object delegates to. diff --git a/WebKit/chromium/src/PlatformMessagePortChannel.h b/WebKit/chromium/src/PlatformMessagePortChannel.h index 05e8397..5416145 100644 --- a/WebKit/chromium/src/PlatformMessagePortChannel.h +++ b/WebKit/chromium/src/PlatformMessagePortChannel.h @@ -31,12 +31,9 @@ #ifndef PlatformMessagePortChannel_h #define PlatformMessagePortChannel_h -// FIXME: This relative path is a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebMessagePortChannelClient.h" +#include "WebMessagePortChannelClient.h" #include "MessagePortChannel.h" - #include <wtf/PassRefPtr.h> #include <wtf/Threading.h> diff --git a/WebKit/chromium/src/ResourceHandle.cpp b/WebKit/chromium/src/ResourceHandle.cpp index bf6910f..88f7f39 100644 --- a/WebKit/chromium/src/ResourceHandle.cpp +++ b/WebKit/chromium/src/ResourceHandle.cpp @@ -31,8 +31,10 @@ #include "config.h" #include "ResourceHandle.h" +#include "ChromiumBridge.h" #include "ResourceHandleClient.h" #include "ResourceRequest.h" +#include "SharedBuffer.h" #include "WebKit.h" #include "WebKitClient.h" @@ -56,6 +58,7 @@ public: : m_request(request) , m_owner(0) , m_client(client) + , m_state(ConnectionStateNew) { } @@ -70,17 +73,36 @@ public: WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent); virtual void didReceiveResponse(WebURLLoader*, const WebURLResponse&); virtual void didReceiveData(WebURLLoader*, const char* data, int dataLength); + virtual void didReceiveCachedMetadata(WebURLLoader*, const char* data, int dataLength); virtual void didFinishLoading(WebURLLoader*); virtual void didFail(WebURLLoader*, const WebURLError&); + enum ConnectionState { + ConnectionStateNew, + ConnectionStateStarted, + ConnectionStateReceivedResponse, + ConnectionStateReceivingData, + ConnectionStateFinishedLoading, + ConnectionStateCanceled, + ConnectionStateFailed, + }; + ResourceRequest m_request; ResourceHandle* m_owner; ResourceHandleClient* m_client; OwnPtr<WebURLLoader> m_loader; + + // Used for sanity checking to make sure we don't experience illegal state + // transitions. + ConnectionState m_state; }; void ResourceHandleInternal::start() { + if (m_state != ConnectionStateNew) + CRASH(); + m_state = ConnectionStateStarted; + m_loader.set(webKitClient()->createURLLoader()); ASSERT(m_loader.get()); @@ -91,6 +113,7 @@ void ResourceHandleInternal::start() void ResourceHandleInternal::cancel() { + m_state = ConnectionStateCanceled; m_loader->cancel(); // Do not make any further calls to the client. @@ -127,6 +150,12 @@ void ResourceHandleInternal::didReceiveResponse(WebURLLoader*, const WebURLRespo { ASSERT(m_client); ASSERT(!response.isNull()); + bool isMultipart = response.isMultipartPayload(); + bool isValidStateTransition = (m_state == ConnectionStateStarted || m_state == ConnectionStateReceivedResponse); + // In the case of multipart loads, calls to didReceiveData & didReceiveResponse can be interleaved. + if (!isMultipart && !isValidStateTransition) + CRASH(); + m_state = ConnectionStateReceivedResponse; m_client->didReceiveResponse(m_owner, response.toResourceResponse()); } @@ -134,6 +163,9 @@ void ResourceHandleInternal::didReceiveData( WebURLLoader*, const char* data, int dataLength) { ASSERT(m_client); + if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData) + CRASH(); + m_state = ConnectionStateReceivingData; // FIXME(yurys): it looks like lengthReceived is always the same as // dataLength and that the latter parameter can be eliminated. @@ -141,15 +173,28 @@ void ResourceHandleInternal::didReceiveData( m_client->didReceiveData(m_owner, data, dataLength, dataLength); } +void ResourceHandleInternal::didReceiveCachedMetadata(WebURLLoader*, const char* data, int dataLength) +{ + ASSERT(m_client); + if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData) + CRASH(); + + m_client->didReceiveCachedMetadata(m_owner, data, dataLength); +} + void ResourceHandleInternal::didFinishLoading(WebURLLoader*) { ASSERT(m_client); + if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData) + CRASH(); + m_state = ConnectionStateFinishedLoading; m_client->didFinishLoading(m_owner); } void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error) { ASSERT(m_client); + m_state = ConnectionStateFailed; m_client->didFail(m_owner, error); } @@ -158,8 +203,7 @@ void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error) ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, - bool shouldContentSniff, - bool mightDownloadFromHandle) + bool shouldContentSniff) : d(new ResourceHandleInternal(request, client)) { d->m_owner = this; @@ -171,11 +215,10 @@ PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request ResourceHandleClient* client, Frame* deprecated, bool defersLoading, - bool shouldContentSniff, - bool mightDownloadFromHandle) + bool shouldContentSniff) { RefPtr<ResourceHandle> newHandle = adoptRef(new ResourceHandle( - request, client, defersLoading, shouldContentSniff, mightDownloadFromHandle)); + request, client, defersLoading, shouldContentSniff)); if (newHandle->start(deprecated)) return newHandle.release(); @@ -183,7 +226,7 @@ PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request return 0; } -const ResourceRequest& ResourceHandle::request() const +ResourceRequest& ResourceHandle::firstRequest() { return d->m_request; } @@ -209,6 +252,11 @@ bool ResourceHandle::start(Frame* deprecated) return true; } +bool ResourceHandle::hasAuthenticationChallenge() const +{ + return false; +} + void ResourceHandle::clearAuthentication() { } @@ -279,4 +327,10 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*) return true; } +// static +void ResourceHandle::cacheMetadata(const ResourceResponse& response, const Vector<char>& data) +{ + ChromiumBridge::cacheMetadata(response.url(), response.responseTime(), data); +} + } // namespace WebCore diff --git a/WebKit/chromium/src/SharedWorkerRepository.cpp b/WebKit/chromium/src/SharedWorkerRepository.cpp index c803aac..88d3ec5 100644 --- a/WebKit/chromium/src/SharedWorkerRepository.cpp +++ b/WebKit/chromium/src/SharedWorkerRepository.cpp @@ -36,6 +36,7 @@ #include "Event.h" #include "EventNames.h" +#include "InspectorController.h" #include "MessagePortChannel.h" #include "PlatformMessagePortChannel.h" #include "ScriptExecutionContext.h" @@ -69,7 +70,9 @@ public: , m_name(name) , m_webWorker(webWorker) , m_port(port) + , m_scriptLoader(ResourceRequestBase::TargetIsSharedWorker) , m_loading(false) + , m_responseAppCacheID(0) { } @@ -79,6 +82,7 @@ public: private: // WorkerScriptLoaderClient callback + virtual void didReceiveResponse(const ResourceResponse&); virtual void notifyFinished(); virtual void connected(); @@ -94,6 +98,7 @@ private: OwnPtr<MessagePortChannel> m_port; WorkerScriptLoader m_scriptLoader; bool m_loading; + long long m_responseAppCacheID; }; static Vector<SharedWorkerScriptLoader*>& pendingLoaders() @@ -146,14 +151,23 @@ static WebMessagePortChannel* getWebPort(PassOwnPtr<MessagePortChannel> port) return webPort; } +void SharedWorkerScriptLoader::didReceiveResponse(const ResourceResponse& response) +{ + m_responseAppCacheID = response.appCacheID(); +} + void SharedWorkerScriptLoader::notifyFinished() { if (m_scriptLoader.failed()) { m_worker->dispatchEvent(Event::create(eventNames().errorEvent, false, true)); delete this; } else { +#if ENABLE(INSPECTOR) + if (InspectorController* inspector = m_worker->scriptExecutionContext()->inspectorController()) + inspector->scriptImported(m_scriptLoader.identifier(), m_scriptLoader.script()); +#endif // Pass the script off to the worker, then send a connect event. - m_webWorker->startWorkerContext(m_url, m_name, m_worker->scriptExecutionContext()->userAgent(m_url), m_scriptLoader.script()); + m_webWorker->startWorkerContext(m_url, m_name, m_worker->scriptExecutionContext()->userAgent(m_url), m_scriptLoader.script(), m_responseAppCacheID); sendConnect(); } } @@ -206,7 +220,7 @@ void SharedWorkerRepository::connect(PassRefPtr<SharedWorker> worker, PassOwnPtr // The loader object manages its own lifecycle (and the lifecycles of the two worker objects). // It will free itself once loading is completed. - SharedWorkerScriptLoader* loader = new SharedWorkerScriptLoader(worker, url, name, port.release(), webWorker.release()); + SharedWorkerScriptLoader* loader = new SharedWorkerScriptLoader(worker, url, name, port, webWorker.release()); loader->load(); } diff --git a/WebKit/chromium/src/SpeechInputClientImpl.cpp b/WebKit/chromium/src/SpeechInputClientImpl.cpp new file mode 100644 index 0000000..8bccacf --- /dev/null +++ b/WebKit/chromium/src/SpeechInputClientImpl.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SpeechInputClientImpl.h" + +#include "PlatformString.h" +#include "WebSpeechInputController.h" +#include "WebString.h" +#include "WebViewClient.h" +#include "page/SpeechInputListener.h" + +#if ENABLE(INPUT_SPEECH) + +namespace WebKit { + +SpeechInputClientImpl::SpeechInputClientImpl(WebViewClient* web_view_client) + : m_controller(web_view_client->speechInputController(this)) + , m_listener(0) +{ + ASSERT(m_controller); +} + +SpeechInputClientImpl::~SpeechInputClientImpl() +{ +} + +bool SpeechInputClientImpl::startRecognition(WebCore::SpeechInputListener* listener) +{ + m_listener = listener; + return m_controller->startRecognition(); +} + +void SpeechInputClientImpl::stopRecording() +{ + ASSERT(m_listener); + m_controller->stopRecording(); +} + +void SpeechInputClientImpl::cancelRecognition() +{ + ASSERT(m_listener); + m_controller->cancelRecognition(); +} + +void SpeechInputClientImpl::didCompleteRecording() +{ + ASSERT(m_listener); + m_listener->didCompleteRecording(); +} + +void SpeechInputClientImpl::didCompleteRecognition() +{ + ASSERT(m_listener); + m_listener->didCompleteRecognition(); + m_listener = 0; +} + +void SpeechInputClientImpl::setRecognitionResult(const WebString& result) +{ + ASSERT(m_listener); + m_listener->setRecognitionResult(result); +} + +} // namespace WebKit + +#endif // ENABLE(INPUT_SPEECH) diff --git a/WebKit/chromium/src/SpeechInputClientImpl.h b/WebKit/chromium/src/SpeechInputClientImpl.h new file mode 100644 index 0000000..5762da8 --- /dev/null +++ b/WebKit/chromium/src/SpeechInputClientImpl.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 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 SpeechInputClientImpl_h +#define SpeechInputClientImpl_h + +#if ENABLE(INPUT_SPEECH) + +#include "WebSpeechInputListener.h" +#include "page/SpeechInputClient.h" + +namespace WebCore { +class SpeechInputListener; +} + +namespace WebKit { + +class WebSpeechInputController; +class WebViewClient; + +class SpeechInputClientImpl + : public WebCore::SpeechInputClient, + public WebSpeechInputListener { +public: + SpeechInputClientImpl(WebViewClient*); + virtual ~SpeechInputClientImpl(); + + // SpeechInputClient methods. + bool startRecognition(WebCore::SpeechInputListener*); + void stopRecording(); + void cancelRecognition(); + + // WebSpeechInputListener methods. + void didCompleteRecording(); + void setRecognitionResult(const WebString&); + void didCompleteRecognition(); + +private: + WebSpeechInputController* m_controller; // To call into the embedder. + WebCore::SpeechInputListener* m_listener; // Valid when recognition is in progress. +}; + +} // namespace WebKit + +#endif // ENABLE(INPUT_SPEECH) + +#endif // SpeechInputClientImpl_h diff --git a/WebKit/chromium/src/StorageAreaProxy.cpp b/WebKit/chromium/src/StorageAreaProxy.cpp index c9185fe..5311b65 100644 --- a/WebKit/chromium/src/StorageAreaProxy.cpp +++ b/WebKit/chromium/src/StorageAreaProxy.cpp @@ -40,6 +40,7 @@ #include "StorageAreaImpl.h" #include "StorageEvent.h" +#include "WebFrameImpl.h" #include "WebStorageArea.h" #include "WebString.h" #include "WebURL.h" @@ -73,12 +74,13 @@ String StorageAreaProxy::getItem(const String& key) const String StorageAreaProxy::setItem(const String& key, const String& value, ExceptionCode& ec, Frame* frame) { - bool quotaException = false; + WebKit::WebStorageArea::Result result = WebKit::WebStorageArea::ResultOK; WebKit::WebString oldValue; - m_storageArea->setItem(key, value, frame->document()->url(), quotaException, oldValue); - ec = quotaException ? QUOTA_EXCEEDED_ERR : 0; + WebKit::WebFrame* webFrame = WebKit::WebFrameImpl::fromFrame(frame); + m_storageArea->setItem(key, value, frame->document()->url(), result, oldValue, webFrame); + ec = (result == WebKit::WebStorageArea::ResultOK) ? 0 : QUOTA_EXCEEDED_ERR; String oldValueString = oldValue; - if (oldValueString != value) + if (oldValueString != value && result == WebKit::WebStorageArea::ResultOK) storageEvent(key, oldValue, value, m_storageType, frame->document()->securityOrigin(), frame); return oldValue; } @@ -123,8 +125,12 @@ void StorageAreaProxy::storageEvent(const String& key, const String& oldValue, c frames.append(frame); } - for (unsigned i = 0; i < frames.size(); ++i) - frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage())); + for (unsigned i = 0; i < frames.size(); ++i) { + ExceptionCode ec = 0; + Storage* storage = frames[i]->domWindow()->sessionStorage(ec); + if (!ec) + frames[i]->document()->enqueueEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), storage)); + } } else { // Send events to every page. const HashSet<Page*>& pages = page->group().pages(); @@ -136,8 +142,12 @@ void StorageAreaProxy::storageEvent(const String& key, const String& oldValue, c } } - for (unsigned i = 0; i < frames.size(); ++i) - frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->localStorage())); + for (unsigned i = 0; i < frames.size(); ++i) { + ExceptionCode ec = 0; + Storage* storage = frames[i]->domWindow()->localStorage(ec); + if (!ec) + frames[i]->document()->enqueueEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), storage)); + } } } diff --git a/WebKit/chromium/src/StorageEventDispatcherImpl.cpp b/WebKit/chromium/src/StorageEventDispatcherImpl.cpp index 3518796..631753b 100644 --- a/WebKit/chromium/src/StorageEventDispatcherImpl.cpp +++ b/WebKit/chromium/src/StorageEventDispatcherImpl.cpp @@ -71,10 +71,11 @@ void StorageEventDispatcherImpl::dispatchStorageEvent(const String& key, const S } } - // FIXME: Figure out how to pass in the document URI. for (unsigned i = 0; i < frames.size(); ++i) { - frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, - url, frames[i]->domWindow()->localStorage())); + ExceptionCode ec = 0; + Storage* storage = frames[i]->domWindow()->localStorage(ec); + if (!ec) + frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, storage)); } } diff --git a/WebKit/chromium/src/StorageNamespaceProxy.cpp b/WebKit/chromium/src/StorageNamespaceProxy.cpp index 1be1967..ec0dbce 100644 --- a/WebKit/chromium/src/StorageNamespaceProxy.cpp +++ b/WebKit/chromium/src/StorageNamespaceProxy.cpp @@ -47,11 +47,11 @@ PassRefPtr<StorageNamespace> StorageNamespace::localStorageNamespace(const Strin return adoptRef(new StorageNamespaceProxy(WebKit::webKitClient()->createLocalStorageNamespace(path, quota), LocalStorage)); } -PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace(Page* page) +PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace(Page* page, unsigned quota) { WebKit::ChromeClientImpl* chromeClientImpl = static_cast<WebKit::ChromeClientImpl*>(page->chrome()->client()); WebKit::WebViewClient* webViewClient = chromeClientImpl->webView()->client(); - return adoptRef(new StorageNamespaceProxy(webViewClient->createSessionStorageNamespace(), SessionStorage)); + return adoptRef(new StorageNamespaceProxy(webViewClient->createSessionStorageNamespace(quota), SessionStorage)); } StorageNamespaceProxy::StorageNamespaceProxy(WebKit::WebStorageNamespace* storageNamespace, StorageType storageType) @@ -67,13 +67,14 @@ StorageNamespaceProxy::~StorageNamespaceProxy() PassRefPtr<StorageNamespace> StorageNamespaceProxy::copy() { ASSERT(m_storageType == SessionStorage); - // The WebViewClient knows what its session storage namespace id is but we - // do not. Returning 0 here causes it to be fetched (via the WebViewClient) - // on its next use. Note that it is WebViewClient::createView's - // responsibility to clone the session storage namespace id and that the - // only time copy() is called is directly after the createView call...which - // is why all of this is safe. - return 0; + WebKit::WebStorageNamespace* newNamespace = m_storageNamespace->copy(); + // Some embedders hook into WebViewClient::createView to make the copy of + // session storage and then return the object lazily. Other embedders + // choose to make the copy now and return a pointer immediately. So handle + // both cases. + if (!newNamespace) + return 0; + return adoptRef(new StorageNamespaceProxy(newNamespace, m_storageType)); } PassRefPtr<StorageArea> StorageNamespaceProxy::storageArea(PassRefPtr<SecurityOrigin> origin) diff --git a/WebKit/chromium/src/SuggestionsPopupMenuClient.cpp b/WebKit/chromium/src/SuggestionsPopupMenuClient.cpp deleted file mode 100644 index b4a77a3..0000000 --- a/WebKit/chromium/src/SuggestionsPopupMenuClient.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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 "SuggestionsPopupMenuClient.h" - -#include "CSSStyleSelector.h" -#include "CSSValueKeywords.h" -#include "Chrome.h" -#include "FrameView.h" -#include "HTMLInputElement.h" -#include "RenderTheme.h" -#include "WebViewImpl.h" - -using namespace WebCore; - -namespace WebKit { - -SuggestionsPopupMenuClient::SuggestionsPopupMenuClient() - : m_textField(0) - , m_selectedIndex(0) -{ -} - -SuggestionsPopupMenuClient::~SuggestionsPopupMenuClient() -{ -} - -// FIXME: Implement this per-derived class? -void SuggestionsPopupMenuClient::valueChanged(unsigned listIndex, bool fireEvents) -{ - m_textField->setValue(getSuggestion(listIndex)); - - WebViewImpl* webView = getWebView(); - if (!webView) - return; - - EditorClientImpl* editor = - static_cast<EditorClientImpl*>(webView->page()->editorClient()); - ASSERT(editor); - editor->onAutofillSuggestionAccepted( - static_cast<HTMLInputElement*>(m_textField.get())); -} - -String SuggestionsPopupMenuClient::itemText(unsigned listIndex) const -{ - return getSuggestion(listIndex); -} - -PopupMenuStyle SuggestionsPopupMenuClient::itemStyle(unsigned listIndex) const -{ - return *m_style; -} - -PopupMenuStyle SuggestionsPopupMenuClient::menuStyle() const -{ - return *m_style; -} - -int SuggestionsPopupMenuClient::clientPaddingLeft() const -{ - // Bug http://crbug.com/7708 seems to indicate the style can be 0. - RenderStyle* style = textFieldStyle(); - if (!style) - return 0; - - return RenderTheme::defaultTheme()->popupInternalPaddingLeft(style); -} - -int SuggestionsPopupMenuClient::clientPaddingRight() const -{ - // Bug http://crbug.com/7708 seems to indicate the style can be 0. - RenderStyle* style = textFieldStyle(); - if (!style) - return 0; - - return RenderTheme::defaultTheme()->popupInternalPaddingRight(style); -} - -void SuggestionsPopupMenuClient::popupDidHide() -{ - WebViewImpl* webView = getWebView(); - if (webView) - webView->suggestionsPopupDidHide(); -} - -void SuggestionsPopupMenuClient::setTextFromItem(unsigned listIndex) -{ - m_textField->setValue(getSuggestion(listIndex)); -} - -FontSelector* SuggestionsPopupMenuClient::fontSelector() const -{ - return m_textField->document()->styleSelector()->fontSelector(); -} - -HostWindow* SuggestionsPopupMenuClient::hostWindow() const -{ - return m_textField->document()->view()->hostWindow(); -} - -PassRefPtr<Scrollbar> SuggestionsPopupMenuClient::createScrollbar( - ScrollbarClient* client, - ScrollbarOrientation orientation, - ScrollbarControlSize size) -{ - return Scrollbar::createNativeScrollbar(client, orientation, size); -} - -RenderStyle* SuggestionsPopupMenuClient::textFieldStyle() const -{ - RenderStyle* style = m_textField->computedStyle(); - if (!style) { - // It seems we can only have a 0 style in a TextField if the - // node is detached, in which case we the popup shoud not be - // showing. Please report this in http://crbug.com/7708 and - // include the page you were visiting. - ASSERT_NOT_REACHED(); - } - return style; -} - -void SuggestionsPopupMenuClient::initialize(HTMLInputElement* textField, - int defaultSuggestionIndex) -{ - m_textField = textField; - m_selectedIndex = defaultSuggestionIndex; - - FontDescription fontDescription; - RenderTheme::defaultTheme()->systemFont(CSSValueWebkitControl, - fontDescription); - - // Use a smaller font size to match IE/Firefox. - // FIXME: http://crbug.com/7376 use the system size instead of a - // fixed font size value. - fontDescription.setComputedSize(12.0); - Font font(fontDescription, 0, 0); - font.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())); -} - -WebViewImpl* SuggestionsPopupMenuClient::getWebView() const -{ - Frame* frame = m_textField->document()->frame(); - if (!frame) - return 0; - - Page* page = frame->page(); - if (!page) - return 0; - - return static_cast<ChromeClientImpl*>(page->chrome()->client())->webView(); -} - -} // namespace WebKit diff --git a/WebKit/chromium/src/SuggestionsPopupMenuClient.h b/WebKit/chromium/src/SuggestionsPopupMenuClient.h deleted file mode 100644 index edc4c09..0000000 --- a/WebKit/chromium/src/SuggestionsPopupMenuClient.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 "PopupMenuClient.h" - -#ifndef SuggestionsPopupMenuClient_h -#define SuggestionsPopupMenuClient_h - -namespace WebCore { -class HTMLInputElement; -class PopupMenuStyle; -class RenderStyle; -} - -namespace WebKit { -class WebString; -class WebViewImpl; -template <typename T> class WebVector; - -// The Suggestions popup menu client, used to display a list of suggestions. -class SuggestionsPopupMenuClient : public WebCore::PopupMenuClient { -public: - SuggestionsPopupMenuClient(); - virtual ~SuggestionsPopupMenuClient(); - - // Returns the number of suggestions available. - virtual unsigned getSuggestionsCount() const = 0; - - // Returns the suggestion at |listIndex|. - virtual WebString getSuggestion(unsigned listIndex) const = 0; - - // Removes the suggestion at |listIndex| from the list of suggestions. - virtual void removeSuggestionAtIndex(unsigned listIndex) = 0; - - // WebCore::PopupMenuClient methods: - virtual void valueChanged(unsigned listIndex, bool fireEvents = true); - virtual WebCore::String itemText(unsigned listIndex) const; - virtual WebCore::String itemToolTip(unsigned lastIndex) const { return WebCore::String(); } - virtual bool itemIsEnabled(unsigned listIndex) const { return true; } - virtual WebCore::PopupMenuStyle itemStyle(unsigned listIndex) const; - virtual WebCore::PopupMenuStyle menuStyle() const; - virtual int clientInsetLeft() const { return 0; } - virtual int clientInsetRight() const { return 0; } - virtual int clientPaddingLeft() const; - virtual int clientPaddingRight() const; - virtual int listSize() const { return getSuggestionsCount(); } - virtual int selectedIndex() const { return m_selectedIndex; } - virtual void popupDidHide(); - virtual bool itemIsSeparator(unsigned listIndex) const { return false; } - virtual bool itemIsLabel(unsigned listIndex) const { return false; } - virtual bool itemIsSelected(unsigned listIndex) const { return false; } - virtual bool shouldPopOver() const { return false; } - virtual bool valueShouldChangeOnHotTrack() const { return false; } - virtual void setTextFromItem(unsigned listIndex); - virtual WebCore::FontSelector* fontSelector() const; - virtual WebCore::HostWindow* hostWindow() const; - virtual PassRefPtr<WebCore::Scrollbar> createScrollbar( - WebCore::ScrollbarClient* client, - WebCore::ScrollbarOrientation orientation, - WebCore::ScrollbarControlSize size); - -protected: - void initialize(WebCore::HTMLInputElement* textField, - int defaultSuggestionIndex); - - int getSelectedIndex() const { return m_selectedIndex; } - void setSelectedIndex(int index) { m_selectedIndex = index; } - - WebViewImpl* getWebView() const; - WebCore::HTMLInputElement* getTextField() const { return m_textField.get(); } - -private: - WebCore::RenderStyle* textFieldStyle() const; - - RefPtr<WebCore::HTMLInputElement> m_textField; - int m_selectedIndex; - OwnPtr<WebCore::PopupMenuStyle> m_style; -}; - -} // namespace WebKit - -#endif diff --git a/WebKit/chromium/src/ToolsAgent.h b/WebKit/chromium/src/ToolsAgent.h index ab48153..937fcf0 100644 --- a/WebKit/chromium/src/ToolsAgent.h +++ b/WebKit/chromium/src/ToolsAgent.h @@ -39,20 +39,11 @@ namespace WebKit { // API for auxiliary UI functions such as dom elements highlighting. #define TOOLS_AGENT_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \ /* Dispatches given function on the InspectorController object */ \ - METHOD3(dispatchOnInspectorController, int /* call_id */, \ - String /* function_name */, String /* json_args */) \ - \ - /* Dispatches given function on the InjectedScript object */ \ - METHOD5(dispatchOnInjectedScript, int /* call_id */, \ - int /* injected_script_id */, String /* function_name */, \ - String /* json_args */, bool /* async */) + METHOD1(dispatchOnInspectorController, String /* message */) \ DEFINE_RPC_CLASS(ToolsAgent, TOOLS_AGENT_STRUCT) #define TOOLS_AGENT_DELEGATE_STRUCT(METHOD0, METHOD1, METHOD2, METHOD3, METHOD4, METHOD5) \ - /* Updates focused node on the client. */ \ - METHOD1(frameNavigate, String /* url */) \ - \ /* Response to the DispatchOn*. */ \ METHOD3(didDispatchOn, int /* call_id */, String /* result */, String /* exception */) \ \ diff --git a/WebKit/chromium/src/WebAccessibilityCacheImpl.cpp b/WebKit/chromium/src/WebAccessibilityCacheImpl.cpp index 03e5f46..abb63cc 100644 --- a/WebKit/chromium/src/WebAccessibilityCacheImpl.cpp +++ b/WebKit/chromium/src/WebAccessibilityCacheImpl.cpp @@ -64,14 +64,15 @@ WebAccessibilityCache* WebAccessibilityCache::create() PassRefPtr<WebAccessibilityCacheImpl::WeakHandle> WebAccessibilityCacheImpl::WeakHandle::create(AccessibilityObject* object) { // FIXME: Remove resetting ref-count from AccessibilityObjectWrapper - // and convert to use adoptRef. - return new WebAccessibilityCacheImpl::WeakHandle(object); + RefPtr<WebAccessibilityCacheImpl::WeakHandle> weakHandle = adoptRef(new WebAccessibilityCacheImpl::WeakHandle(object)); + weakHandle->m_object->setWrapper(weakHandle.get()); + + return weakHandle.release(); } WebAccessibilityCacheImpl::WeakHandle::WeakHandle(AccessibilityObject* object) : AccessibilityObjectWrapper(object) { - m_object->setWrapper(this); } // WebAccessibilityCacheImpl ---------------------------------------- diff --git a/WebKit/chromium/src/WebAccessibilityObject.cpp b/WebKit/chromium/src/WebAccessibilityObject.cpp index c386d44..4263e8b 100644 --- a/WebKit/chromium/src/WebAccessibilityObject.cpp +++ b/WebKit/chromium/src/WebAccessibilityObject.cpp @@ -32,9 +32,15 @@ #include "WebAccessibilityObject.h" #include "AccessibilityObject.h" +#include "CSSPrimitiveValueMappings.h" +#include "Document.h" #include "EventHandler.h" #include "FrameView.h" +#include "Node.h" #include "PlatformKeyboardEvent.h" +#include "RenderStyle.h" +#include "WebDocument.h" +#include "WebNode.h" #include "WebPoint.h" #include "WebRect.h" #include "WebString.h" @@ -303,6 +309,15 @@ WebString WebAccessibilityObject::helpText() const return m_private->helpText(); } +int WebAccessibilityObject::headingLevel() const +{ + if (!m_private) + return 0; + + m_private->updateBackingStore(); + return m_private->headingLevel(); +} + WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const { if (!m_private) @@ -368,6 +383,12 @@ WebAccessibilityRole WebAccessibilityObject::roleValue() const return static_cast<WebAccessibilityRole>(m_private->roleValue()); } +void WebAccessibilityObject::setFocused(bool on) const +{ + if (m_private) + m_private->setFocused(on); +} + WebString WebAccessibilityObject::stringValue() const { if (!m_private) @@ -386,6 +407,65 @@ WebString WebAccessibilityObject::title() const return m_private->title(); } + +WebNode WebAccessibilityObject::node() const +{ + if (!m_private) + return WebNode(); + + m_private->updateBackingStore(); + + Node* node = m_private->node(); + if (!node) + return WebNode(); + + return WebNode(node); +} + +WebDocument WebAccessibilityObject::document() const +{ + if (!m_private) + return WebDocument(); + + m_private->updateBackingStore(); + + Document* document = m_private->document(); + if (!document) + return WebDocument(); + + return WebDocument(document); +} + +bool WebAccessibilityObject::hasComputedStyle() const +{ + Document* document = m_private->document(); + if (document) + document->updateStyleIfNeeded(); + + Node* node = m_private->node(); + if (!node) + return false; + + return node->computedStyle(); +} + +WebString WebAccessibilityObject::computedStyleDisplay() const +{ + Document* document = m_private->document(); + if (document) + document->updateStyleIfNeeded(); + + Node* node = m_private->node(); + if (!node) + return WebString(); + + RenderStyle* renderStyle = node->computedStyle(); + if (!renderStyle) + return WebString(); + + return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue()); +} + WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) : m_private(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())) { diff --git a/WebKit/chromium/src/WebAnimationControllerImpl.h b/WebKit/chromium/src/WebAnimationControllerImpl.h index 8b0676e..66dfe98 100644 --- a/WebKit/chromium/src/WebAnimationControllerImpl.h +++ b/WebKit/chromium/src/WebAnimationControllerImpl.h @@ -31,9 +31,7 @@ #ifndef WebAnimationControllerImpl_h #define WebAnimationControllerImpl_h -// FIXME: This relative path is a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebAnimationController.h" +#include "WebAnimationController.h" namespace WebCore { class AnimationController; diff --git a/WebKit/chromium/src/WebAttribute.cpp b/WebKit/chromium/src/WebAttribute.cpp new file mode 100644 index 0000000..0bc3b91 --- /dev/null +++ b/WebKit/chromium/src/WebAttribute.cpp @@ -0,0 +1,68 @@ +/* + * 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 "WebAttribute.h" + +#include "Attribute.h" +#include <wtf/PassRefPtr.h> + +#include "WebString.h" + +using namespace WebCore; + +namespace WebKit { + +void WebAttribute::reset() +{ + m_private.reset(); +} + +void WebAttribute::assign(const WebAttribute& other) +{ + m_private = other.m_private; +} + +WebAttribute::WebAttribute(const PassRefPtr<Attribute>& other) + : m_private(other) +{ +} + +WebString WebAttribute::localName() const +{ + return WebString(m_private->localName()); +} + +WebString WebAttribute::value() const +{ + return WebString(m_private->value()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebBindings.cpp b/WebKit/chromium/src/WebBindings.cpp index 04f2f85..3aaebfd 100644 --- a/WebKit/chromium/src/WebBindings.cpp +++ b/WebKit/chromium/src/WebBindings.cpp @@ -34,9 +34,6 @@ #include "npruntime_impl.h" #include "npruntime_priv.h" -#include "../public/WebDragData.h" -#include "../public/WebRange.h" - #if USE(V8) #include "ChromiumDataObject.h" #include "ClipboardChromium.h" @@ -48,11 +45,15 @@ #include "V8DOMWrapper.h" #include "V8Event.h" #include "V8Helpers.h" +#include "V8HiddenPropertyName.h" +#include "V8NPUtils.h" #include "V8Proxy.h" #include "V8Range.h" #elif USE(JSC) #include "bridge/c/c_utility.h" #endif +#include "WebDragData.h" +#include "WebRange.h" #if USE(JAVASCRIPTCORE_BINDINGS) using JSC::Bindings::PrivateIdentifier; @@ -208,8 +209,7 @@ void WebBindings::extractIdentifierData(const NPIdentifier& identifier, const NP static v8::Local<v8::Value> getEvent(const v8::Handle<v8::Context>& context) { - static v8::Persistent<v8::String> eventSymbol(v8::Persistent<v8::String>::New(v8::String::NewSymbol("event"))); - return context->Global()->GetHiddenValue(eventSymbol); + return context->Global()->GetHiddenValue(V8HiddenPropertyName::event()); } static bool getDragDataImpl(NPObject* npobj, int* eventId, WebDragData* data) @@ -284,7 +284,7 @@ static bool getRangeImpl(NPObject* npobj, WebRange* range) { V8NPObject* v8npobject = reinterpret_cast<V8NPObject*>(npobj); v8::Handle<v8::Object> v8object(v8npobject->v8Object); - if (V8ClassIndex::RANGE != V8DOMWrapper::domWrapperType(v8object)) + if (!V8Range::info.equals(V8DOMWrapper::domWrapperType(v8object))) return false; Range* native = V8Range::toNative(v8object); @@ -323,4 +323,14 @@ bool WebBindings::getRange(NPObject* range, WebRange* webrange) #endif } +void WebBindings::pushExceptionHandler(ExceptionHandler handler, void* data) +{ + WebCore::pushExceptionHandler(handler, data); +} + +void WebBindings::popExceptionHandler() +{ + WebCore::popExceptionHandler(); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebCString.cpp b/WebKit/chromium/src/WebCString.cpp index 82fbac0..f81d7f4 100644 --- a/WebKit/chromium/src/WebCString.cpp +++ b/WebKit/chromium/src/WebCString.cpp @@ -31,16 +31,28 @@ #include "config.h" #include "WebCString.h" -#include "CString.h" #include "TextEncoding.h" +#include <wtf/text/CString.h> #include "WebString.h" namespace WebKit { -class WebCStringPrivate : public WebCore::CStringBuffer { +class WebCStringPrivate : public WTF::CStringBuffer { }; +int WebCString::compare(const WebCString& other) const +{ + // A null string is always less than a non null one. + if (isNull() != other.isNull()) + return isNull() ? -1 : 1; + + if (isNull()) + return 0; // Both WebStrings are null. + + return strcmp(m_private->data(), other.m_private->data()); +} + void WebCString::reset() { if (m_private) { @@ -57,8 +69,8 @@ void WebCString::assign(const WebCString& other) void WebCString::assign(const char* data, size_t length) { char* newData; - RefPtr<WebCore::CStringBuffer> buffer = - WebCore::CString::newUninitialized(length, newData).buffer(); + RefPtr<WTF::CStringBuffer> buffer = + WTF::CString::newUninitialized(length, newData).buffer(); memcpy(newData, data, length); assign(static_cast<WebCStringPrivate*>(buffer.get())); } @@ -97,20 +109,20 @@ WebCString WebCString::fromUTF16(const WebUChar* data) return fromUTF16(data, len); } -WebCString::WebCString(const WebCore::CString& s) +WebCString::WebCString(const WTF::CString& s) : m_private(static_cast<WebCStringPrivate*>(s.buffer())) { if (m_private) m_private->ref(); } -WebCString& WebCString::operator=(const WebCore::CString& s) +WebCString& WebCString::operator=(const WTF::CString& s) { assign(static_cast<WebCStringPrivate*>(s.buffer())); return *this; } -WebCString::operator WebCore::CString() const +WebCString::operator WTF::CString() const { return m_private; } diff --git a/WebKit/chromium/src/WebCommon.cpp b/WebKit/chromium/src/WebCommon.cpp new file mode 100644 index 0000000..f9457fb --- /dev/null +++ b/WebKit/chromium/src/WebCommon.cpp @@ -0,0 +1,44 @@ +/* + * 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 "WebCommon.h" + +#include <wtf/Assertions.h> + +namespace WebKit { + +void failedAssertion(const char* file, int line, const char* function, const char* assertion) +{ + WTFReportAssertionFailure(file, line, function, assertion); + CRASH(); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/AutocompletePopupMenuClient.cpp b/WebKit/chromium/src/WebDOMStringList.cpp index 9620ffc..4be7fab 100644 --- a/WebKit/chromium/src/AutocompletePopupMenuClient.cpp +++ b/WebKit/chromium/src/WebDOMStringList.cpp @@ -29,56 +29,59 @@ */ #include "config.h" -#include "AutocompletePopupMenuClient.h" +#include "WebDOMStringList.h" -#include "HTMLInputElement.h" +#include "DOMStringList.h" #include "WebString.h" -#include "WebVector.h" using namespace WebCore; namespace WebKit { -unsigned AutocompletePopupMenuClient::getSuggestionsCount() const +WebDOMStringList::WebDOMStringList() { - return m_suggestions.size(); + m_private = WebCore::DOMStringList::create(); } -WebString AutocompletePopupMenuClient::getSuggestion(unsigned listIndex) const +void WebDOMStringList::reset() { - ASSERT(listIndex >= 0 && listIndex < m_suggestions.size()); - return m_suggestions[listIndex]; + m_private.reset(); } -void AutocompletePopupMenuClient::removeSuggestionAtIndex(unsigned listIndex) +void WebDOMStringList::assign(const WebDOMStringList& other) { - ASSERT(listIndex >= 0 && listIndex < m_suggestions.size()); - m_suggestions.remove(listIndex); + m_private = other.m_private; } -void AutocompletePopupMenuClient::initialize( - HTMLInputElement* textField, - const WebVector<WebString>& suggestions, - int defaultSuggestionIndex) +void WebDOMStringList::append(const WebString& string) { - ASSERT(defaultSuggestionIndex < static_cast<int>(suggestions.size())); + m_private->append(string); +} - // The suggestions must be set before initializing the - // SuggestionsPopupMenuClient. - setSuggestions(suggestions); +unsigned WebDOMStringList::length() const +{ + return m_private->length(); +} - SuggestionsPopupMenuClient::initialize(textField, defaultSuggestionIndex); +WebString WebDOMStringList::item(unsigned index) const +{ + return m_private->item(index); } -void AutocompletePopupMenuClient::setSuggestions(const WebVector<WebString>& suggestions) +WebDOMStringList::WebDOMStringList(const WTF::PassRefPtr<WebCore::DOMStringList>& item) + : m_private(item) { - m_suggestions.clear(); - for (size_t i = 0; i < suggestions.size(); ++i) - m_suggestions.append(suggestions[i]); +} - // Try to preserve selection if possible. - if (getSelectedIndex() >= static_cast<int>(suggestions.size())) - setSelectedIndex(-1); +WebDOMStringList& WebDOMStringList::operator=(const WTF::PassRefPtr<WebCore::DOMStringList>& item) +{ + m_private = item; + return *this; +} + +WebDOMStringList::operator WTF::PassRefPtr<WebCore::DOMStringList>() const +{ + return m_private.get(); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebDataSourceImpl.cpp b/WebKit/chromium/src/WebDataSourceImpl.cpp index 5a315cf..ac2a02d 100644 --- a/WebKit/chromium/src/WebDataSourceImpl.cpp +++ b/WebKit/chromium/src/WebDataSourceImpl.cpp @@ -156,7 +156,7 @@ void WebDataSourceImpl::setNextPluginLoadObserver(PassOwnPtr<WebPluginLoadObserv { // This call should always be followed up with the creation of a // WebDataSourceImpl, so we should never leak this object. - m_nextPluginLoadObserver = observer.release(); + m_nextPluginLoadObserver = observer.leakPtr(); } WebDataSourceImpl::WebDataSourceImpl(const ResourceRequest& request, const SubstituteData& data) diff --git a/WebKit/chromium/src/WebDataSourceImpl.h b/WebKit/chromium/src/WebDataSourceImpl.h index f868e95..be32217 100644 --- a/WebKit/chromium/src/WebDataSourceImpl.h +++ b/WebKit/chromium/src/WebDataSourceImpl.h @@ -31,17 +31,12 @@ #ifndef WebDataSourceImpl_h #define WebDataSourceImpl_h -// FIXME: This relative path is a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebDataSource.h" - #include "DocumentLoader.h" #include "KURL.h" - +#include "WebDataSource.h" #include "WebPluginLoadObserver.h" #include "WrappedResourceRequest.h" #include "WrappedResourceResponse.h" - #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> diff --git a/WebKit/chromium/src/WebDatabase.cpp b/WebKit/chromium/src/WebDatabase.cpp index 50b9220..561d7c4 100644 --- a/WebKit/chromium/src/WebDatabase.cpp +++ b/WebKit/chromium/src/WebDatabase.cpp @@ -31,12 +31,8 @@ #include "config.h" #include "WebDatabase.h" -#include "Database.h" -#include "DatabaseTask.h" -#include "DatabaseThread.h" +#include "AbstractDatabase.h" #include "DatabaseTracker.h" -#include "Document.h" -#include "KURL.h" #include "QuotaTracker.h" #include "SecurityOrigin.h" #include "WebDatabaseObserver.h" @@ -44,50 +40,46 @@ #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> +#if !ENABLE(DATABASE) +namespace WebCore { +class AbstractDatabase { +public: + String stringIdentifier() const { return String(); } + String displayName() const { return String(); } + unsigned long long estimatedSize() const { return 0; } + SecurityOrigin* securityOrigin() const { return 0; } +}; +} +#endif // !ENABLE(DATABASE) + using namespace WebCore; namespace WebKit { static WebDatabaseObserver* databaseObserver = 0; -class WebDatabasePrivate : public Database { -}; - -void WebDatabase::reset() -{ - assign(0); -} - -void WebDatabase::assign(const WebDatabase& other) -{ - WebDatabasePrivate* d = const_cast<WebDatabasePrivate*>(other.m_private); - if (d) - d->ref(); - assign(d); -} - WebString WebDatabase::name() const { - ASSERT(m_private); - return m_private->stringIdentifier(); + ASSERT(m_database); + return m_database->stringIdentifier(); } WebString WebDatabase::displayName() const { - ASSERT(m_private); - return m_private->displayName(); + ASSERT(m_database); + return m_database->displayName(); } unsigned long WebDatabase::estimatedSize() const { - ASSERT(m_private); - return m_private->estimatedSize(); + ASSERT(m_database); + return m_database->estimatedSize(); } WebSecurityOrigin WebDatabase::securityOrigin() const { - ASSERT(m_private); - return WebSecurityOrigin(m_private->securityOrigin()); + ASSERT(m_database); + return WebSecurityOrigin(m_database->securityOrigin()); } void WebDatabase::setObserver(WebDatabaseObserver* observer) @@ -104,48 +96,26 @@ void WebDatabase::updateDatabaseSize( const WebString& originIdentifier, const WebString& databaseName, unsigned long long databaseSize, unsigned long long spaceAvailable) { +#if ENABLE(DATABASE) WebCore::QuotaTracker::instance().updateDatabaseSizeAndSpaceAvailableToOrigin( originIdentifier, databaseName, databaseSize, spaceAvailable); +#endif // ENABLE(DATABASE) } void WebDatabase::closeDatabaseImmediately(const WebString& originIdentifier, const WebString& databaseName) { - HashSet<RefPtr<Database> > databaseHandles; - PassRefPtr<SecurityOrigin> originPrp(*WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier)); - RefPtr<SecurityOrigin> origin = originPrp; +#if ENABLE(DATABASE) + HashSet<RefPtr<AbstractDatabase> > databaseHandles; + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier); DatabaseTracker::tracker().getOpenDatabases(origin.get(), databaseName, &databaseHandles); - for (HashSet<RefPtr<Database> >::iterator it = databaseHandles.begin(); it != databaseHandles.end(); ++it) { - Database* database = it->get(); - DatabaseThread* databaseThread = database->scriptExecutionContext()->databaseThread(); - if (databaseThread && !databaseThread->terminationRequested()) { - database->stop(); - databaseThread->scheduleTask(DatabaseCloseTask::create(database, 0)); - } - } -} - -WebDatabase::WebDatabase(const WTF::PassRefPtr<Database>& database) - : m_private(static_cast<WebDatabasePrivate*>(database.releaseRef())) -{ -} - -WebDatabase& WebDatabase::operator=(const WTF::PassRefPtr<Database>& database) -{ - assign(static_cast<WebDatabasePrivate*>(database.releaseRef())); - return *this; -} - -WebDatabase::operator WTF::PassRefPtr<Database>() const -{ - return PassRefPtr<Database>(const_cast<WebDatabasePrivate*>(m_private)); + for (HashSet<RefPtr<AbstractDatabase> >::iterator it = databaseHandles.begin(); it != databaseHandles.end(); ++it) + it->get()->closeImmediately(); +#endif // ENABLE(DATABASE) } -void WebDatabase::assign(WebDatabasePrivate* d) +WebDatabase::WebDatabase(const AbstractDatabase* database) + : m_database(database) { - // d is already ref'd for us by the caller - if (m_private) - m_private->deref(); - m_private = d; } } // namespace WebKit diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp index 9ce35b4..1a65bfe 100644 --- a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp +++ b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp @@ -38,32 +38,37 @@ #include "EventListener.h" #include "InjectedScriptHost.h" #include "InspectorBackend.h" +#include "InspectorBackendDispatcher.h" #include "InspectorController.h" #include "InspectorFrontend.h" #include "InspectorResource.h" #include "Node.h" #include "Page.h" +#include "PageGroup.h" #include "PlatformString.h" #include "ProfilerAgentImpl.h" #include "ResourceError.h" #include "ResourceRequest.h" #include "ResourceResponse.h" +#include "ScriptDebugServer.h" #include "ScriptObject.h" #include "ScriptState.h" #include "ScriptValue.h" #include "V8Binding.h" -#include "V8InspectorBackend.h" #include "V8Proxy.h" #include "V8Utilities.h" #include "WebDataSource.h" #include "WebDevToolsAgentClient.h" #include "WebDevToolsMessageData.h" +#include "WebDevToolsMessageTransport.h" #include "WebFrameImpl.h" +#include "WebRect.h" #include "WebString.h" #include "WebURL.h" #include "WebURLError.h" #include "WebURLRequest.h" #include "WebURLResponse.h" +#include "WebViewClient.h" #include "WebViewImpl.h" #include <wtf/Noncopyable.h> #include <wtf/OwnPtr.h> @@ -86,9 +91,7 @@ using WebCore::ScriptObject; using WebCore::ScriptState; using WebCore::ScriptValue; using WebCore::String; -using WebCore::V8ClassIndex; using WebCore::V8DOMWrapper; -using WebCore::V8InspectorBackend; using WebCore::V8Proxy; namespace WebKit { @@ -102,34 +105,109 @@ void InspectorBackendWeakReferenceCallback(v8::Persistent<v8::Value> object, voi object.Dispose(); } -void SetApuAgentEnabledInUtilityContext(v8::Handle<v8::Context> context, bool enabled) -{ - v8::HandleScope handleScope; - v8::Context::Scope contextScope(context); - v8::Handle<v8::Object> dispatcher = v8::Local<v8::Object>::Cast( - context->Global()->Get(v8::String::New("ApuAgentDispatcher"))); - if (dispatcher.IsEmpty()) - return; - dispatcher->Set(v8::String::New("enabled"), v8::Boolean::New(enabled)); -} - -// TODO(pfeldman): Make this public in WebDevToolsAgent API. -static const char kApuAgentFeatureName[] = "apu-agent"; - -// Keep these in sync with the ones in inject_dispatch.js. -static const char kTimelineFeatureName[] = "timeline-profiler"; static const char kResourceTrackingFeatureName[] = "resource-tracking"; +static const char kTimelineFeatureName[] = "timeline-profiler"; +static const char kApuAgentFeatureName[] = "apu-agent"; class IORPCDelegate : public DevToolsRPC::Delegate, public Noncopyable { public: - IORPCDelegate() { } + IORPCDelegate() : m_transport(0) { } + explicit IORPCDelegate(WebDevToolsMessageTransport* transport) : m_transport(transport) { } virtual ~IORPCDelegate() { } virtual void sendRpcMessage(const WebDevToolsMessageData& data) { - WebDevToolsAgentClient::sendMessageToFrontendOnIOThread(data); + if (m_transport) + m_transport->sendMessageToFrontendOnIOThread(data); + } + +private: + WebDevToolsMessageTransport* m_transport; +}; + +class ClientMessageLoopAdapter : public WebCore::ScriptDebugServer::ClientMessageLoop { +public: + static void ensureClientMessageLoopCreated(WebDevToolsAgentClient* client) + { + if (s_instance) + return; + s_instance = new ClientMessageLoopAdapter(client->createClientMessageLoop()); + WebCore::ScriptDebugServer::shared().setClientMessageLoop(s_instance); + } + + static void inspectedViewClosed(WebViewImpl* view) + { + if (s_instance) + s_instance->m_frozenViews.remove(view); + } + + static void didNavigate() + { + // Release render thread if necessary. + if (s_instance && s_instance->m_running) + WebCore::ScriptDebugServer::shared().continueProgram(); + } + +private: + ClientMessageLoopAdapter(PassOwnPtr<WebKit::WebDevToolsAgentClient::WebKitClientMessageLoop> messageLoop) + : m_running(false) + , m_messageLoop(messageLoop) { } + + + virtual void run(Page* page) + { + if (m_running) + return; + m_running = true; + + Vector<WebViewImpl*> views; + + // 1. Disable input events. + HashSet<Page*>::const_iterator end = page->group().pages().end(); + for (HashSet<Page*>::const_iterator it = page->group().pages().begin(); it != end; ++it) { + WebViewImpl* view = WebViewImpl::fromPage(*it); + m_frozenViews.add(view); + views.append(view); + view->setIgnoreInputEvents(true); + } + + // 2. Disable active objects + WebView::willEnterModalLoop(); + + // 3. Process messages until quitNow is called. + m_messageLoop->run(); + + // 4. Resume active objects + WebView::didExitModalLoop(); + + // 5. Resume input events. + for (Vector<WebViewImpl*>::iterator it = views.begin(); it != views.end(); ++it) { + if (m_frozenViews.contains(*it)) { + // The view was not closed during the dispatch. + (*it)->setIgnoreInputEvents(false); + } + } + + // 6. All views have been resumed, clear the set. + m_frozenViews.clear(); + + m_running = false; + } + + virtual void quitNow() + { + m_messageLoop->quitNow(); } + + bool m_running; + OwnPtr<WebKit::WebDevToolsAgentClient::WebKitClientMessageLoop> m_messageLoop; + typedef HashSet<WebViewImpl*> FrozenViewsSet; + FrozenViewsSet m_frozenViews; + static ClientMessageLoopAdapter* s_instance; + }; +ClientMessageLoopAdapter* ClientMessageLoopAdapter::s_instance = 0; + } // namespace WebDevToolsAgentImpl::WebDevToolsAgentImpl( @@ -142,6 +220,8 @@ WebDevToolsAgentImpl::WebDevToolsAgentImpl( , m_resourceTrackingWasEnabled(false) , m_attached(false) { + DebuggerAgentManager::setExposeV8DebuggerProtocol( + client->exposeV8DebuggerProtocol()); m_debuggerAgentDelegateStub.set(new DebuggerAgentDelegateStub(this)); m_toolsAgentDelegateStub.set(new ToolsAgentDelegateStub(this)); m_apuAgentDelegateStub.set(new ApuAgentDelegateStub(this)); @@ -150,6 +230,7 @@ WebDevToolsAgentImpl::WebDevToolsAgentImpl( WebDevToolsAgentImpl::~WebDevToolsAgentImpl() { DebuggerAgentManager::onWebViewClosed(m_webViewImpl); + ClientMessageLoopAdapter::inspectedViewClosed(m_webViewImpl); disposeUtilityContext(); } @@ -161,25 +242,20 @@ void WebDevToolsAgentImpl::disposeUtilityContext() } } -void WebDevToolsAgentImpl::unhideResourcesPanelIfNecessary() -{ - InspectorController* ic = m_webViewImpl->page()->inspectorController(); - ic->ensureResourceTrackingSettingsLoaded(); - String command = String::format("[\"setResourcesPanelEnabled\", %s]", - ic->resourceTrackingEnabled() ? "true" : "false"); - m_toolsAgentDelegateStub->dispatchOnClient(command); -} - void WebDevToolsAgentImpl::attach() { if (m_attached) return; + + if (!m_client->exposeV8DebuggerProtocol()) + ClientMessageLoopAdapter::ensureClientMessageLoopCreated(m_client); + m_debuggerAgentImpl.set( new DebuggerAgentImpl(m_webViewImpl, m_debuggerAgentDelegateStub.get(), this)); - resetInspectorFrontendProxy(); - unhideResourcesPanelIfNecessary(); + createInspectorFrontendProxy(); + // Allow controller to send messages to the frontend. InspectorController* ic = inspectorController(); @@ -194,7 +270,7 @@ void WebDevToolsAgentImpl::attach() } } - ic->setWindowVisible(true, false); + setInspectorFrontendProxyToInspectorController(); m_attached = true; } @@ -202,6 +278,7 @@ void WebDevToolsAgentImpl::detach() { // Prevent controller from sending messages to the frontend. InspectorController* ic = m_webViewImpl->page()->inspectorController(); + ic->disconnectFrontend(); ic->hideHighlight(); ic->close(); disposeUtilityContext(); @@ -212,26 +289,10 @@ void WebDevToolsAgentImpl::detach() void WebDevToolsAgentImpl::didNavigate() { + ClientMessageLoopAdapter::didNavigate(); DebuggerAgentManager::onNavigate(); } -void WebDevToolsAgentImpl::didCommitProvisionalLoad(WebFrameImpl* webframe, bool isNewNavigation) -{ - if (!m_attached) - return; - WebDataSource* ds = webframe->dataSource(); - const WebURLRequest& request = ds->request(); - WebURL url = ds->hasUnreachableURL() ? - ds->unreachableURL() : - request.url(); - if (!webframe->parent()) { - resetInspectorFrontendProxy(); - m_toolsAgentDelegateStub->frameNavigate(WebCore::KURL(url).string()); - SetApuAgentEnabledInUtilityContext(m_utilityContext, m_apuAgentEnabled); - unhideResourcesPanelIfNecessary(); - } -} - void WebDevToolsAgentImpl::didClearWindowObject(WebFrameImpl* webframe) { DebuggerAgentManager::setHostId(webframe, m_hostId); @@ -246,23 +307,9 @@ void WebDevToolsAgentImpl::forceRepaint() m_client->forceRepaint(); } -void WebDevToolsAgentImpl::dispatchOnInspectorController(int callId, const String& functionName, const String& jsonArgs) +void WebDevToolsAgentImpl::dispatchOnInspectorController(const String& message) { - String result; - String exception; - result = m_debuggerAgentImpl->executeUtilityFunction(m_utilityContext, callId, - "InspectorControllerDispatcher", functionName, jsonArgs, false /* is sync */, &exception); - m_toolsAgentDelegateStub->didDispatchOn(callId, result, exception); -} - -void WebDevToolsAgentImpl::dispatchOnInjectedScript(int callId, int injectedScriptId, const String& functionName, const String& jsonArgs, bool async) -{ - inspectorController()->inspectorBackend()->dispatchOnInjectedScript( - callId, - injectedScriptId, - functionName, - jsonArgs, - async); + inspectorController()->inspectorBackendDispatcher()->dispatch(message); } void WebDevToolsAgentImpl::dispatchMessageFromFrontend(const WebDevToolsMessageData& data) @@ -323,70 +370,32 @@ void WebDevToolsAgentImpl::initDevToolsAgentHost() devtoolsAgentHost.addProtoFunction( "dispatch", WebDevToolsAgentImpl::jsDispatchOnClient); - devtoolsAgentHost.addProtoFunction( - "dispatchToApu", - WebDevToolsAgentImpl::jsDispatchToApu); - devtoolsAgentHost.addProtoFunction( - "evaluateOnSelf", - WebDevToolsAgentImpl::jsEvaluateOnSelf); - devtoolsAgentHost.addProtoFunction( - "runtimeFeatureStateChanged", - WebDevToolsAgentImpl::jsOnRuntimeFeatureStateChanged); devtoolsAgentHost.build(); - - v8::HandleScope scope; - v8::Context::Scope utilityScope(m_utilityContext); - // Call custom code to create inspector backend wrapper in the utility context - // instead of calling V8DOMWrapper::convertToV8Object that would create the - // wrapper in the Page main frame context. - v8::Handle<v8::Object> backendWrapper = createInspectorBackendV8Wrapper(); - if (backendWrapper.IsEmpty()) - return; - m_utilityContext->Global()->Set(v8::String::New("InspectorBackend"), backendWrapper); -} - -v8::Local<v8::Object> WebDevToolsAgentImpl::createInspectorBackendV8Wrapper() -{ - V8ClassIndex::V8WrapperType descriptorType = V8ClassIndex::INSPECTORBACKEND; - v8::Handle<v8::Function> function = V8InspectorBackend::GetTemplate()->GetFunction(); - if (function.IsEmpty()) { - // Return if allocation failed. - return v8::Local<v8::Object>(); - } - v8::Local<v8::Object> instance = SafeAllocation::newInstance(function); - if (instance.IsEmpty()) { - // Avoid setting the wrapper if allocation failed. - return v8::Local<v8::Object>(); - } - InspectorBackend* backend = m_webViewImpl->page()->inspectorController()->inspectorBackend(); - V8DOMWrapper::setDOMWrapper(instance, V8ClassIndex::ToInt(descriptorType), backend); - // Create a weak reference to the v8 wrapper of InspectorBackend to deref - // InspectorBackend when the wrapper is garbage collected. - backend->ref(); - v8::Persistent<v8::Object> weakHandle = v8::Persistent<v8::Object>::New(instance); - weakHandle.MakeWeak(backend, &InspectorBackendWeakReferenceCallback); - return instance; } -void WebDevToolsAgentImpl::resetInspectorFrontendProxy() +void WebDevToolsAgentImpl::createInspectorFrontendProxy() { disposeUtilityContext(); - m_debuggerAgentImpl->createUtilityContext(m_webViewImpl->page()->mainFrame(), &m_utilityContext); + m_utilityContext = v8::Context::New(); compileUtilityScripts(); initDevToolsAgentHost(); + WebCString debuggerScriptJs = m_client->debuggerScriptSource(); + WebCore::ScriptDebugServer::shared().setDebuggerScriptSource( + WebCore::String(debuggerScriptJs.data(), debuggerScriptJs.length())); +} +void WebDevToolsAgentImpl::setInspectorFrontendProxyToInspectorController() +{ v8::HandleScope scope; - v8::Context::Scope contextScope(m_utilityContext); ScriptState* state = ScriptState::forContext( v8::Local<v8::Context>::New(m_utilityContext)); InspectorController* ic = inspectorController(); - ic->setFrontendProxyObject(state, ScriptObject(state, m_utilityContext->Global())); + ic->connectFrontend(ScriptObject(state, m_utilityContext->Global())); } void WebDevToolsAgentImpl::setApuAgentEnabled(bool enabled) { m_apuAgentEnabled = enabled; - SetApuAgentEnabledInUtilityContext(m_utilityContext, enabled); InspectorController* ic = m_webViewImpl->page()->inspectorController(); if (enabled) { m_resourceTrackingWasEnabled = ic->resourceTrackingEnabled(); @@ -415,55 +424,25 @@ v8::Handle<v8::Value> WebDevToolsAgentImpl::jsDispatchOnClient(const v8::Argumen String message = WebCore::toWebCoreStringWithNullCheck(args[0]); if (message.isEmpty() || exceptionCatcher.HasCaught()) return v8::Undefined(); + WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value()); - agent->m_toolsAgentDelegateStub->dispatchOnClient(message); - return v8::Undefined(); -} -// static -v8::Handle<v8::Value> WebDevToolsAgentImpl::jsDispatchToApu(const v8::Arguments& args) -{ - v8::TryCatch exceptionCatcher; - String message = WebCore::toWebCoreStringWithNullCheck(args[0]); - if (message.isEmpty() || exceptionCatcher.HasCaught()) + if (!agent->m_apuAgentEnabled) { + agent->m_toolsAgentDelegateStub->dispatchOnClient(message); return v8::Undefined(); - WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>( - v8::External::Cast(*args.Data())->Value()); - agent->m_apuAgentDelegateStub->dispatchToApu(message); - return v8::Undefined(); -} - -// static -v8::Handle<v8::Value> WebDevToolsAgentImpl::jsEvaluateOnSelf(const v8::Arguments& args) -{ - String code; - { - v8::TryCatch exceptionCatcher; - code = WebCore::toWebCoreStringWithNullCheck(args[0]); - if (code.isEmpty() || exceptionCatcher.HasCaught()) - return v8::Undefined(); } - WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value()); - v8::Context::Scope(agent->m_utilityContext); - V8Proxy* proxy = V8Proxy::retrieve(agent->m_webViewImpl->page()->mainFrame()); - v8::Local<v8::Value> result = proxy->runScript(v8::Script::Compile(v8::String::New(code.utf8().data())), true); - return result; -} -// static -v8::Handle<v8::Value> WebDevToolsAgentImpl::jsOnRuntimeFeatureStateChanged(const v8::Arguments& args) -{ - v8::TryCatch exceptionCatcher; - String feature = WebCore::toWebCoreStringWithNullCheck(args[0]); - bool enabled = args[1]->ToBoolean()->Value(); - if (feature.isEmpty() || exceptionCatcher.HasCaught()) + String method = WebCore::toWebCoreStringWithNullCheck(args[1]); + if (method.isEmpty() || exceptionCatcher.HasCaught()) return v8::Undefined(); - WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value()); - agent->m_client->runtimeFeatureStateChanged(feature, enabled); + + if (method != "addRecordToTimeline" && method != "updateResource" && method != "addResource") + return v8::Undefined(); + + agent->m_apuAgentDelegateStub->dispatchToApu(message); return v8::Undefined(); } - WebCore::InspectorController* WebDevToolsAgentImpl::inspectorController() { if (Page* page = m_webViewImpl->page()) @@ -486,10 +465,10 @@ void WebDevToolsAgentImpl::identifierForInitialRequest( } } -void WebDevToolsAgentImpl::willSendRequest(unsigned long resourceId, const WebURLRequest& request) +void WebDevToolsAgentImpl::willSendRequest(unsigned long resourceId, WebURLRequest& request) { if (InspectorController* ic = inspectorController()) - ic->willSendRequest(resourceId, request.toResourceRequest(), ResourceResponse()); + ic->willSendRequest(resourceId, request.toMutableResourceRequest(), ResourceResponse()); } void WebDevToolsAgentImpl::didReceiveData(unsigned long resourceId, int length) @@ -517,6 +496,88 @@ void WebDevToolsAgentImpl::didFailLoading(unsigned long resourceId, const WebURL ic->didFailLoading(resourceId, resourceError); } +void WebDevToolsAgentImpl::inspectorDestroyed() +{ + // Our lifetime is bound to the WebViewImpl. +} + +void WebDevToolsAgentImpl::openInspectorFrontend(InspectorController*) +{ +} + +void WebDevToolsAgentImpl::highlight(Node* node) +{ + // InspectorController does the actuall tracking of the highlighted node + // and the drawing of the highlight. Here we just make sure to invalidate + // the rects of the old and new nodes. + hideHighlight(); +} + +void WebDevToolsAgentImpl::hideHighlight() +{ + // FIXME: able to invalidate a smaller rect. + // FIXME: Is it important to just invalidate the rect of the node region + // given that this is not on a critical codepath? In order to do so, we'd + // have to take scrolling into account. + const WebSize& size = m_webViewImpl->size(); + WebRect damagedRect(0, 0, size.width, size.height); + if (m_webViewImpl->client()) + m_webViewImpl->client()->didInvalidateRect(damagedRect); +} + +void WebDevToolsAgentImpl::populateSetting(const String& key, String* value) +{ + WebString string; + m_webViewImpl->inspectorSetting(key, &string); + *value = string; +} + +void WebDevToolsAgentImpl::storeSetting(const String& key, const String& value) +{ + m_webViewImpl->setInspectorSetting(key, value); +} + +bool WebDevToolsAgentImpl::sendMessageToFrontend(const WebCore::String& message) +{ + WebDevToolsAgentImpl* devToolsAgent = static_cast<WebDevToolsAgentImpl*>(m_webViewImpl->devToolsAgent()); + if (!devToolsAgent) + return false; + + if (devToolsAgent->m_apuAgentEnabled && devToolsAgent->m_apuAgentDelegateStub) { + devToolsAgent->m_apuAgentDelegateStub->dispatchToApu(message); + return true; + } + + WebVector<WebString> arguments(size_t(1)); + arguments[0] = message; + WebDevToolsMessageData data; + data.className = "ToolsAgentDelegate"; + data.methodName = "dispatchOnClient"; + data.arguments.swap(arguments); + devToolsAgent->sendRpcMessage(data); + return true; +} + +void WebDevToolsAgentImpl::resourceTrackingWasEnabled() +{ + m_client->runtimeFeatureStateChanged(kResourceTrackingFeatureName, true); +} + +void WebDevToolsAgentImpl::resourceTrackingWasDisabled() +{ + m_client->runtimeFeatureStateChanged(kResourceTrackingFeatureName, false); +} + +void WebDevToolsAgentImpl::timelineProfilerWasStarted() +{ + m_client->runtimeFeatureStateChanged(kTimelineFeatureName, true); +} + +void WebDevToolsAgentImpl::timelineProfilerWasStopped() +{ + m_client->runtimeFeatureStateChanged(kTimelineFeatureName, false); +} + void WebDevToolsAgentImpl::evaluateInWebInspector(long callId, const WebString& script) { InspectorController* ic = inspectorController(); @@ -532,11 +593,6 @@ void WebDevToolsAgentImpl::setTimelineProfilingEnabled(bool enabled) ic->stopTimelineProfiler(); } -WebDevToolsAgent* WebDevToolsAgent::create(WebView* webview, WebDevToolsAgentClient* client) -{ - return new WebDevToolsAgentImpl(static_cast<WebViewImpl*>(webview), client); -} - void WebDevToolsAgent::executeDebuggerCommand(const WebString& command, int callerId) { DebuggerAgentManager::executeDebuggerCommand(command, callerId); @@ -552,10 +608,10 @@ void WebDevToolsAgent::setMessageLoopDispatchHandler(MessageLoopDispatchHandler DebuggerAgentManager::setMessageLoopDispatchHandler(handler); } -bool WebDevToolsAgent::dispatchMessageFromFrontendOnIOThread(const WebDevToolsMessageData& data) +bool WebDevToolsAgent::dispatchMessageFromFrontendOnIOThread(WebDevToolsMessageTransport* transport, const WebDevToolsMessageData& data) { - IORPCDelegate transport; - ProfilerAgentDelegateStub stub(&transport); + IORPCDelegate delegate(transport); + ProfilerAgentDelegateStub stub(&delegate); ProfilerAgentImpl agent(&stub); return ProfilerAgentDispatch::dispatch(&agent, data); } diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.h b/WebKit/chromium/src/WebDevToolsAgentImpl.h index 1f81c6d..c8e22b0 100644 --- a/WebKit/chromium/src/WebDevToolsAgentImpl.h +++ b/WebKit/chromium/src/WebDevToolsAgentImpl.h @@ -31,6 +31,8 @@ #ifndef WebDevToolsAgentImpl_h #define WebDevToolsAgentImpl_h +#include "InspectorClient.h" + #include "APUAgentDelegate.h" #include "DevToolsRPC.h" #include "ToolsAgent.h" @@ -41,6 +43,7 @@ namespace WebCore { class Document; +class InspectorClient; class InspectorController; class Node; class String; @@ -62,18 +65,17 @@ struct WebDevToolsMessageData; class WebDevToolsAgentImpl : public WebDevToolsAgentPrivate, public ToolsAgent, - public DevToolsRPC::Delegate { + public DevToolsRPC::Delegate, + public WebCore::InspectorClient { public: WebDevToolsAgentImpl(WebViewImpl* webViewImpl, WebDevToolsAgentClient* client); virtual ~WebDevToolsAgentImpl(); // ToolsAgent implementation. - virtual void dispatchOnInspectorController(int callId, const WebCore::String& functionName, const WebCore::String& jsonArgs); - virtual void dispatchOnInjectedScript(int callId, int injectedScriptId, const WebCore::String& functionName, const WebCore::String& jsonArgs, bool async); + virtual void dispatchOnInspectorController(const WebCore::String& message); // WebDevToolsAgentPrivate implementation. virtual void didClearWindowObject(WebFrameImpl* frame); - virtual void didCommitProvisionalLoad(WebFrameImpl* frame, bool isNewNavigation); // WebDevToolsAgent implementation. virtual void attach(); @@ -86,12 +88,25 @@ public: virtual void setTimelineProfilingEnabled(bool enable); virtual void identifierForInitialRequest(unsigned long, WebFrame*, const WebURLRequest&); - virtual void willSendRequest(unsigned long, const WebURLRequest&); + virtual void willSendRequest(unsigned long, WebURLRequest&); virtual void didReceiveData(unsigned long, int length); virtual void didReceiveResponse(unsigned long, const WebURLResponse&); virtual void didFinishLoading(unsigned long); virtual void didFailLoading(unsigned long, const WebURLError&); + // InspectorClient implementation. + virtual void inspectorDestroyed(); + virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual void highlight(WebCore::Node*); + virtual void hideHighlight(); + virtual void populateSetting(const WebCore::String& key, WebCore::String* value); + virtual void storeSetting(const WebCore::String& key, const WebCore::String& value); + virtual void resourceTrackingWasEnabled(); + virtual void resourceTrackingWasDisabled(); + virtual void timelineProfilerWasStarted(); + virtual void timelineProfilerWasStopped(); + virtual bool sendMessageToFrontend(const WebCore::String&); + // DevToolsRPC::Delegate implementation. virtual void sendRpcMessage(const WebDevToolsMessageData& data); @@ -101,26 +116,17 @@ public: private: static v8::Handle<v8::Value> jsDispatchOnClient(const v8::Arguments& args); - static v8::Handle<v8::Value> jsDispatchToApu(const v8::Arguments& args); - static v8::Handle<v8::Value> jsEvaluateOnSelf(const v8::Arguments& args); - static v8::Handle<v8::Value> jsOnRuntimeFeatureStateChanged(const v8::Arguments& args); void disposeUtilityContext(); - void unhideResourcesPanelIfNecessary(); void compileUtilityScripts(); void initDevToolsAgentHost(); - void resetInspectorFrontendProxy(); + void createInspectorFrontendProxy(); + void setInspectorFrontendProxyToInspectorController(); void setApuAgentEnabled(bool enabled); WebCore::InspectorController* inspectorController(); - // Creates InspectorBackend v8 wrapper in the utility context so that it's - // methods prototype is Function.protoype object from the utility context. - // Otherwise some useful methods defined on Function.prototype(such as bind) - // are missing for InspectorController native methods. - v8::Local<v8::Object> createInspectorBackendV8Wrapper(); - int m_hostId; WebDevToolsAgentClient* m_client; WebViewImpl* m_webViewImpl; diff --git a/WebKit/chromium/src/WebDevToolsAgentPrivate.h b/WebKit/chromium/src/WebDevToolsAgentPrivate.h index 0c1c67e..7038a5e 100644 --- a/WebKit/chromium/src/WebDevToolsAgentPrivate.h +++ b/WebKit/chromium/src/WebDevToolsAgentPrivate.h @@ -31,9 +31,7 @@ #ifndef WebDevToolsAgentPrivate_h #define WebDevToolsAgentPrivate_h -// FIXME: This relative path is a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebDevToolsAgent.h" +#include "WebDevToolsAgent.h" namespace WebKit { class WebFrameImpl; @@ -45,11 +43,6 @@ public: // The window object for the frame has been cleared of any extra properties // that may have been set by script from the previously loaded document. virtual void didClearWindowObject(WebFrameImpl*) = 0; - - // The provisional datasource is now committed. The first part of the - // response body has been received, and the encoding of the response body - // is known. - virtual void didCommitProvisionalLoad(WebFrameImpl*, bool isNewNavigation) = 0; }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp index 89fa6e7..592a532 100644 --- a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp +++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp @@ -42,6 +42,7 @@ #include "Frame.h" #include "InspectorBackend.h" #include "InspectorController.h" +#include "InspectorFrontendClientImpl.h" #include "InspectorFrontendHost.h" #include "Node.h" #include "Page.h" @@ -54,6 +55,7 @@ #include "V8Binding.h" #include "V8DOMWrapper.h" #include "V8InspectorFrontendHost.h" +#include "V8MouseEvent.h" #include "V8Node.h" #include "V8Proxy.h" #include "V8Utilities.h" @@ -100,6 +102,13 @@ WebDevToolsFrontendImpl::WebDevToolsFrontendImpl( , m_applicationLocale(applicationLocale) , m_loaded(false) { + InspectorController* ic = m_webViewImpl->page()->inspectorController(); + ic->setInspectorFrontendClient(new InspectorFrontendClientImpl(m_webViewImpl->page(), m_client, this)); + + // Put each DevTools frontend Page into its own (single page) group so that it's not + // deferred along with the inspected page. + m_webViewImpl->page()->setGroupName(String()); + WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); v8::HandleScope scope; v8::Handle<v8::Context> frameContext = V8Proxy::context(frame->frame()); @@ -117,57 +126,10 @@ WebDevToolsFrontendImpl::WebDevToolsFrontendImpl( "DebuggerPauseScript", WebDevToolsFrontendImpl::jsDebuggerPauseScript); debuggerCommandExecutorObj.build(); - - BoundObject devToolsHost(frameContext, this, "InspectorFrontendHost"); - devToolsHost.addProtoFunction( - "loaded", - WebDevToolsFrontendImpl::jsLoaded); - devToolsHost.addProtoFunction( - "platform", - WebDevToolsFrontendImpl::jsPlatform); - devToolsHost.addProtoFunction( - "port", - WebDevToolsFrontendImpl::jsPort); - devToolsHost.addProtoFunction( - "copyText", - WebDevToolsFrontendImpl::jsCopyText); - devToolsHost.addProtoFunction( - "activateWindow", - WebDevToolsFrontendImpl::jsActivateWindow); - devToolsHost.addProtoFunction( - "closeWindow", - WebDevToolsFrontendImpl::jsCloseWindow); - devToolsHost.addProtoFunction( - "attach", - WebDevToolsFrontendImpl::jsDockWindow); - devToolsHost.addProtoFunction( - "detach", - WebDevToolsFrontendImpl::jsUndockWindow); - devToolsHost.addProtoFunction( - "localizedStringsURL", - WebDevToolsFrontendImpl::jsLocalizedStringsURL); - devToolsHost.addProtoFunction( - "hiddenPanels", - WebDevToolsFrontendImpl::jsHiddenPanels); - devToolsHost.addProtoFunction( - "setting", - WebDevToolsFrontendImpl::jsSetting); - devToolsHost.addProtoFunction( - "setSetting", - WebDevToolsFrontendImpl::jsSetSetting); - devToolsHost.addProtoFunction( - "windowUnloading", - WebDevToolsFrontendImpl::jsWindowUnloading); - devToolsHost.addProtoFunction( - "showContextMenu", - WebDevToolsFrontendImpl::jsShowContextMenu); - devToolsHost.build(); } WebDevToolsFrontendImpl::~WebDevToolsFrontendImpl() { - if (m_menuProvider) - m_menuProvider->disconnect(); } void WebDevToolsFrontendImpl::dispatchMessageFromAgent(const WebDevToolsMessageData& data) @@ -184,6 +146,18 @@ void WebDevToolsFrontendImpl::dispatchMessageFromAgent(const WebDevToolsMessageD executeScript(v); } +void WebDevToolsFrontendImpl::frontendLoaded() +{ + m_loaded = true; + + for (Vector<Vector<String> >::iterator it = m_pendingIncomingMessages.begin(); + it != m_pendingIncomingMessages.end(); + ++it) { + executeScript(*it); + } + m_pendingIncomingMessages.clear(); +} + void WebDevToolsFrontendImpl::executeScript(const Vector<String>& v) { WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); @@ -196,128 +170,16 @@ void WebDevToolsFrontendImpl::executeScript(const Vector<String>& v) Vector< v8::Handle<v8::Value> > args; for (size_t i = 0; i < v.size(); i++) args.append(ToV8String(v.at(i))); + v8::TryCatch tryCatch; + tryCatch.SetVerbose(true); function->Call(frameContext->Global(), args.size(), args.data()); } -void WebDevToolsFrontendImpl::dispatchOnWebInspector(const String& methodName, const String& param) -{ - WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); - v8::HandleScope scope; - v8::Handle<v8::Context> frameContext = V8Proxy::context(frame->frame()); - v8::Context::Scope contextScope(frameContext); - - v8::Handle<v8::Value> webInspector = frameContext->Global()->Get(v8::String::New("WebInspector")); - ASSERT(webInspector->IsObject()); - v8::Handle<v8::Object> webInspectorObj = v8::Handle<v8::Object>::Cast(webInspector); - - v8::Handle<v8::Value> method = webInspectorObj->Get(ToV8String(methodName)); - ASSERT(method->IsFunction()); - v8::Handle<v8::Function> methodFunc = v8::Handle<v8::Function>::Cast(method); - v8::Handle<v8::Value> args[] = { - ToV8String(param) - }; - methodFunc->Call(frameContext->Global(), 1, args); -} - void WebDevToolsFrontendImpl::sendRpcMessage(const WebDevToolsMessageData& data) { m_client->sendMessageToAgent(data); } -void WebDevToolsFrontendImpl::contextMenuItemSelected(ContextMenuItem* item) -{ - int itemNumber = item->action() - ContextMenuItemBaseCustomTag; - dispatchOnWebInspector("contextMenuItemSelected", String::number(itemNumber)); -} - -void WebDevToolsFrontendImpl::contextMenuCleared() -{ - dispatchOnWebInspector("contextMenuCleared", ""); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsLoaded(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_loaded = true; - - // Grant the devtools page the ability to have source view iframes. - Page* page = V8Proxy::retrieveFrameForEnteredContext()->page(); - SecurityOrigin* origin = page->mainFrame()->domWindow()->securityOrigin(); - origin->grantUniversalAccess(); - - for (Vector<Vector<String> >::iterator it = frontend->m_pendingIncomingMessages.begin(); - it != frontend->m_pendingIncomingMessages.end(); - ++it) { - frontend->executeScript(*it); - } - frontend->m_pendingIncomingMessages.clear(); - return v8::Undefined(); -} - -// static -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsPlatform(const v8::Arguments& args) -{ -#if defined(OS_MACOSX) - return v8String("mac"); -#elif defined(OS_LINUX) - return v8String("linux"); -#elif defined(OS_WIN) - return v8String("windows"); -#else - return v8String("unknown"); -#endif -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsPort(const v8::Arguments& args) -{ - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsCopyText(const v8::Arguments& args) -{ - String text = WebCore::toWebCoreStringWithNullCheck(args[0]); - Pasteboard::generalPasteboard()->writePlainText(text); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsActivateWindow(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_client->activateWindow(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsCloseWindow(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_client->closeWindow(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDockWindow(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_client->dockWindow(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsUndockWindow(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_client->undockWindow(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsLocalizedStringsURL(const v8::Arguments& args) -{ - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsHiddenPanels(const v8::Arguments& args) -{ - return v8String(""); -} - v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerCommand(const v8::Arguments& args) { WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); @@ -326,16 +188,6 @@ v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerCommand(const v8::Argum return v8::Undefined(); } -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsSetting(const v8::Arguments& args) -{ - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsSetSetting(const v8::Arguments& args) -{ - return v8::Undefined(); -} - v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerPauseScript(const v8::Arguments& args) { WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); @@ -343,53 +195,4 @@ v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerPauseScript(const v8::A return v8::Undefined(); } -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsWindowUnloading(const v8::Arguments& args) -{ - // TODO(pfeldman): Implement this. - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsShowContextMenu(const v8::Arguments& args) -{ - if (args.Length() < 2) - return v8::Undefined(); - - v8::Local<v8::Object> eventWrapper = v8::Local<v8::Object>::Cast(args[0]); - if (V8DOMWrapper::domWrapperType(eventWrapper) != V8ClassIndex::MOUSEEVENT) - return v8::Undefined(); - - Event* event = V8Event::toNative(eventWrapper); - if (!args[1]->IsArray()) - return v8::Undefined(); - - v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[1]); - Vector<ContextMenuItem*> items; - - for (size_t i = 0; i < array->Length(); ++i) { - v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(array->Get(v8::Integer::New(i))); - v8::Local<v8::Value> label = item->Get(v8::String::New("label")); - v8::Local<v8::Value> id = item->Get(v8::String::New("id")); - if (label->IsUndefined() || id->IsUndefined()) { - items.append(new ContextMenuItem(SeparatorType, - ContextMenuItemTagNoAction, - String())); - } else { - ContextMenuAction typedId = static_cast<ContextMenuAction>( - ContextMenuItemBaseCustomTag + id->ToInt32()->Value()); - items.append(new ContextMenuItem(ActionType, - typedId, - toWebCoreStringWithNullCheck(label))); - } - } - - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - - frontend->m_menuProvider = MenuProvider::create(frontend, items); - - ContextMenuController* menuController = frontend->m_webViewImpl->page()->contextMenuController(); - menuController->showContextMenu(event, frontend->m_menuProvider); - - return v8::Undefined(); -} - } // namespace WebKit diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.h b/WebKit/chromium/src/WebDevToolsFrontendImpl.h index 62b34da..fa4707d 100644 --- a/WebKit/chromium/src/WebDevToolsFrontendImpl.h +++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.h @@ -31,8 +31,6 @@ #ifndef WebDevToolsFrontendImpl_h #define WebDevToolsFrontendImpl_h -#include "ContextMenu.h" -#include "ContextMenuProvider.h" #include "DevToolsRPC.h" #include "WebDevToolsFrontend.h" #include <v8.h> @@ -74,76 +72,13 @@ public: // WebDevToolsFrontend implementation. virtual void dispatchMessageFromAgent(const WebKit::WebDevToolsMessageData& data); -private: - class MenuProvider : public WebCore::ContextMenuProvider { - public: - static PassRefPtr<MenuProvider> create(WebDevToolsFrontendImpl* frontendHost, const Vector<WebCore::ContextMenuItem*>& items) - { - return adoptRef(new MenuProvider(frontendHost, items)); - } - - virtual ~MenuProvider() - { - contextMenuCleared(); - } - - void disconnect() - { - m_frontendHost = 0; - } - - virtual void populateContextMenu(WebCore::ContextMenu* menu) - { - for (size_t i = 0; i < m_items.size(); ++i) - menu->appendItem(*m_items[i]); - } - - virtual void contextMenuItemSelected(WebCore::ContextMenuItem* item) - { - if (m_frontendHost) - m_frontendHost->contextMenuItemSelected(item); - } - - virtual void contextMenuCleared() - { - if (m_frontendHost) - m_frontendHost->contextMenuCleared(); - deleteAllValues(m_items); - m_items.clear(); - } - - private: - MenuProvider(WebDevToolsFrontendImpl* frontendHost, const Vector<WebCore::ContextMenuItem*>& items) - : m_frontendHost(frontendHost) - , m_items(items) { } - WebDevToolsFrontendImpl* m_frontendHost; - Vector<WebCore::ContextMenuItem*> m_items; - }; + void frontendLoaded(); +private: void executeScript(const Vector<String>& v); - void dispatchOnWebInspector(const String& method, const String& param); - - // friend class MenuSelectionHandler; - void contextMenuItemSelected(WebCore::ContextMenuItem* menuItem); - void contextMenuCleared(); - - static v8::Handle<v8::Value> jsLoaded(const v8::Arguments& args); - static v8::Handle<v8::Value> jsPlatform(const v8::Arguments& args); - static v8::Handle<v8::Value> jsPort(const v8::Arguments& args); - static v8::Handle<v8::Value> jsCopyText(const v8::Arguments& args); - static v8::Handle<v8::Value> jsActivateWindow(const v8::Arguments& args); - static v8::Handle<v8::Value> jsCloseWindow(const v8::Arguments& args); - static v8::Handle<v8::Value> jsDockWindow(const v8::Arguments& args); - static v8::Handle<v8::Value> jsUndockWindow(const v8::Arguments& args); - static v8::Handle<v8::Value> jsLocalizedStringsURL(const v8::Arguments& args); - static v8::Handle<v8::Value> jsHiddenPanels(const v8::Arguments& args); static v8::Handle<v8::Value> jsDebuggerCommand(const v8::Arguments& args); - static v8::Handle<v8::Value> jsSetting(const v8::Arguments& args); - static v8::Handle<v8::Value> jsSetSetting(const v8::Arguments& args); static v8::Handle<v8::Value> jsDebuggerPauseScript(const v8::Arguments& args); - static v8::Handle<v8::Value> jsWindowUnloading(const v8::Arguments& args); - static v8::Handle<v8::Value> jsShowContextMenu(const v8::Arguments& args); WebKit::WebViewImpl* m_webViewImpl; WebKit::WebDevToolsFrontendClient* m_client; @@ -153,7 +88,6 @@ private: OwnPtr<JSToolsAgentBoundObj> m_toolsAgentObj; bool m_loaded; Vector<Vector<String> > m_pendingIncomingMessages; - RefPtr<MenuProvider> m_menuProvider; }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebDocument.cpp b/WebKit/chromium/src/WebDocument.cpp index 84f3004..a983bf7 100644 --- a/WebKit/chromium/src/WebDocument.cpp +++ b/WebKit/chromium/src/WebDocument.cpp @@ -32,7 +32,7 @@ #include "WebDocument.h" #include "Document.h" -#include "DocumentLoader.h" +#include "DocumentType.h" #include "Element.h" #include "HTMLAllCollection.h" #include "HTMLBodyElement.h" @@ -41,9 +41,11 @@ #include "HTMLHeadElement.h" #include "NodeList.h" +#include "WebDocumentType.h" #include "WebElement.h" #include "WebFrameImpl.h" #include "WebNodeCollection.h" +#include "WebNodeList.h" #include "WebURL.h" #include <wtf/PassRefPtr.h> @@ -52,30 +54,24 @@ using namespace WebCore; namespace WebKit { -WebDocument::WebDocument(const PassRefPtr<Document>& elem) - : WebNode(elem.releaseRef()) -{ -} - -WebDocument& WebDocument::operator=(const PassRefPtr<Document>& elem) +WebFrame* WebDocument::frame() const { - WebNode::assign(elem.releaseRef()); - return *this; + return WebFrameImpl::fromFrame(constUnwrap<Document>()->frame()); } -WebDocument::operator PassRefPtr<Document>() const -{ - return PassRefPtr<Document>(static_cast<Document*>(m_private)); +bool WebDocument::isHTMLDocument() const +{ + return constUnwrap<Document>()->isHTMLDocument(); } -WebFrame* WebDocument::frame() const +bool WebDocument::isXHTMLDocument() const { - return WebFrameImpl::fromFrame(constUnwrap<Document>()->frame()); + return constUnwrap<Document>()->isXHTMLDocument(); } -bool WebDocument::isHTMLDocument() const +bool WebDocument::isPluginDocument() const { - return constUnwrap<Document>()->isHTMLDocument(); + return constUnwrap<Document>()->isPluginDocument(); } WebURL WebDocument::baseURL() const @@ -83,6 +79,11 @@ WebURL WebDocument::baseURL() const return constUnwrap<Document>()->baseURL(); } +WebURL WebDocument::firstPartyForCookies() const +{ + return constUnwrap<Document>()->firstPartyForCookies(); +} + WebElement WebDocument::documentElement() const { return WebElement(constUnwrap<Document>()->documentElement()); @@ -98,6 +99,11 @@ WebElement WebDocument::head() return WebElement(unwrap<Document>()->head()); } +WebString WebDocument::title() const +{ + return WebString(constUnwrap<Document>()->title()); +} + WebNodeCollection WebDocument::all() { return WebNodeCollection(unwrap<Document>()->all()); @@ -113,38 +119,30 @@ WebElement WebDocument::getElementById(const WebString& id) const return WebElement(constUnwrap<Document>()->getElementById(id)); } -WebString WebDocument::applicationID() const +WebNode WebDocument::focusedNode() const { - const char* kChromeApplicationHeader = "x-chrome-application"; - - // First check if the document's response included a header indicating the - // application it should go with. - const Document* document = constUnwrap<Document>(); - Frame* frame = document->frame(); - if (!frame) - return WebString(); + return WebNode(constUnwrap<Document>()->focusedNode()); +} - DocumentLoader* loader = frame->loader()->documentLoader(); - if (!loader) - return WebString(); +WebDocumentType WebDocument::doctype() const +{ + return WebDocumentType(constUnwrap<Document>()->doctype()); +} - WebString headerValue = - loader->response().httpHeaderField(kChromeApplicationHeader); - if (!headerValue.isEmpty()) - return headerValue; +WebDocument::WebDocument(const PassRefPtr<Document>& elem) + : WebNode(elem) +{ +} - // Otherwise, fall back to looking for the meta tag. - RefPtr<NodeList> metaTags = - const_cast<Document*>(document)->getElementsByTagName("meta"); - for (unsigned i = 0; i < metaTags->length(); ++i) { - Element* element = static_cast<Element*>(metaTags->item(i)); - if (element->getAttribute("http-equiv").lower() == - kChromeApplicationHeader) { - return element->getAttribute("value"); - } - } +WebDocument& WebDocument::operator=(const PassRefPtr<Document>& elem) +{ + m_private = elem; + return *this; +} - return WebString(); +WebDocument::operator PassRefPtr<Document>() const +{ + return static_cast<Document*>(m_private.get()); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebDocumentType.cpp b/WebKit/chromium/src/WebDocumentType.cpp new file mode 100644 index 0000000..bbf28e7 --- /dev/null +++ b/WebKit/chromium/src/WebDocumentType.cpp @@ -0,0 +1,64 @@ +/* + * 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 "WebDocumentType.h" + +#include "DocumentType.h" +#include "WebString.h" + +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +WebString WebDocumentType::name() const +{ + return WebString(constUnwrap<DocumentType>()->name()); +} + +WebDocumentType::WebDocumentType(const PassRefPtr<DocumentType>& elem) + : WebNode(elem) +{ +} + +WebDocumentType& WebDocumentType::operator=(const PassRefPtr<DocumentType>& elem) +{ + m_private = elem; + return *this; +} + +WebDocumentType::operator PassRefPtr<DocumentType>() const +{ + return static_cast<DocumentType*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebDragData.cpp b/WebKit/chromium/src/WebDragData.cpp index b18ab1b..643c35d 100644 --- a/WebKit/chromium/src/WebDragData.cpp +++ b/WebKit/chromium/src/WebDragData.cpp @@ -67,13 +67,13 @@ void WebDragData::assign(const WebDragData& other) WebURL WebDragData::url() const { ASSERT(!isNull()); - return m_private->url; + return m_private->getURL(); } void WebDragData::setURL(const WebURL& url) { ensureMutable(); - m_private->url = url; + m_private->setURL(url); } WebString WebDragData::urlTitle() const @@ -88,18 +88,6 @@ void WebDragData::setURLTitle(const WebString& urlTitle) m_private->urlTitle = urlTitle; } -WebURL WebDragData::downloadURL() const -{ - ASSERT(!isNull()); - return m_private->downloadURL; -} - -void WebDragData::setDownloadURL(const WebURL& downloadURL) -{ - ensureMutable(); - m_private->downloadURL = downloadURL; -} - WebString WebDragData::downloadMetadata() const { ASSERT(!isNull()); diff --git a/WebKit/chromium/src/WebElement.cpp b/WebKit/chromium/src/WebElement.cpp index d0a0862..f45cba9 100644 --- a/WebKit/chromium/src/WebElement.cpp +++ b/WebKit/chromium/src/WebElement.cpp @@ -32,26 +32,19 @@ #include "WebElement.h" #include "Element.h" +#include "RenderBoxModelObject.h" +#include "RenderObject.h" #include <wtf/PassRefPtr.h> +#include "WebNamedNodeMap.h" + using namespace WebCore; namespace WebKit { -WebElement::WebElement(const WTF::PassRefPtr<WebCore::Element>& elem) - : WebNode(elem.releaseRef()) -{ -} - -WebElement& WebElement::operator=(const WTF::PassRefPtr<WebCore::Element>& elem) +bool WebElement::isFormControlElement() const { - WebNode::assign(elem.releaseRef()); - return *this; -} - -WebElement::operator WTF::PassRefPtr<Element>() const -{ - return PassRefPtr<Element>(static_cast<Element*>(m_private)); + return constUnwrap<Element>()->isFormControlElement(); } WebString WebElement::tagName() const @@ -62,7 +55,7 @@ WebString WebElement::tagName() const bool WebElement::hasTagName(const WebString& tagName) const { return equalIgnoringCase(constUnwrap<Element>()->tagName(), - tagName.operator WebCore::String()); + tagName.operator String()); } bool WebElement::hasAttribute(const WebString& attrName) const @@ -82,10 +75,30 @@ bool WebElement::setAttribute(const WebString& attrName, const WebString& attrVa return !exceptionCode; } +WebNamedNodeMap WebElement::attributes() const +{ + return WebNamedNodeMap(m_private->attributes()); +} + WebString WebElement::innerText() const { return constUnwrap<Element>()->innerText(); } -} // namespace WebKit +WebElement::WebElement(const PassRefPtr<Element>& elem) + : WebNode(elem) +{ +} +WebElement& WebElement::operator=(const PassRefPtr<Element>& elem) +{ + m_private = elem; + return *this; +} + +WebElement::operator PassRefPtr<Element>() const +{ + return static_cast<Element*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebEntities.cpp b/WebKit/chromium/src/WebEntities.cpp index b9143d9..665d8d9 100644 --- a/WebKit/chromium/src/WebEntities.cpp +++ b/WebKit/chromium/src/WebEntities.cpp @@ -42,12 +42,12 @@ using namespace WebCore; namespace { -// Note that this file is also included by HTMLTokenizer.cpp so we are getting +// Note that this file is also included by LegacyHTMLDocumentParser.cpp so we are getting // two copies of the data in memory. We can fix this by changing the script // that generated the array to create a static const that is its length, but // this is low priority since the data is less than 4K. We use anonymous // namespace to prevent name collisions. -#include "HTMLEntityNames.c" // NOLINT +#include "HTMLEntityNames.cpp" // NOLINT } namespace WebKit { diff --git a/WebKit/chromium/src/WebFileChooserCompletionImpl.h b/WebKit/chromium/src/WebFileChooserCompletionImpl.h index fe759e0..147d1f7 100644 --- a/WebKit/chromium/src/WebFileChooserCompletionImpl.h +++ b/WebKit/chromium/src/WebFileChooserCompletionImpl.h @@ -31,14 +31,11 @@ #ifndef WebFileChooserCompletionImpl_h #define WebFileChooserCompletionImpl_h -// FIXME: These relative paths are a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebFileChooserCompletion.h" -#include "../public/WebString.h" -#include "../public/WebVector.h" +#include "WebFileChooserCompletion.h" +#include "WebString.h" +#include "WebVector.h" #include "FileChooser.h" - #include <wtf/PassRefPtr.h> using WebKit::WebFileChooserCompletion; diff --git a/WebKit/chromium/src/WebFontDescription.cpp b/WebKit/chromium/src/WebFontDescription.cpp new file mode 100644 index 0000000..18f6830 --- /dev/null +++ b/WebKit/chromium/src/WebFontDescription.cpp @@ -0,0 +1,71 @@ +/* + * 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 "WebFontDescription.h" + +#include "FontDescription.h" + +using namespace WebCore; + +namespace WebKit { + +WebFontDescription::WebFontDescription(const FontDescription& desc, + short fontLetterSpacing, short fontWordSpacing) +{ + family = desc.family().family(); + genericFamily = static_cast<GenericFamily>(desc.genericFamily()); + size = desc.specifiedSize(); + italic = desc.italic(); + smallCaps = desc.smallCaps(); + weight = static_cast<Weight>(desc.weight()); + smoothing = static_cast<Smoothing>(desc.fontSmoothing()); + letterSpacing = fontLetterSpacing; + wordSpacing = fontWordSpacing; +} + +WebFontDescription::operator WebCore::FontDescription() const +{ + FontFamily fontFamily; + fontFamily.setFamily(family); + + FontDescription desc; + desc.setFamily(fontFamily); + desc.setGenericFamily(static_cast<FontDescription::GenericFamilyType>(genericFamily)); + desc.setSpecifiedSize(size); + desc.setComputedSize(size); + desc.setItalic(italic); + desc.setSmallCaps(smallCaps); + desc.setWeight(static_cast<FontWeight>(weight)); + desc.setFontSmoothing(static_cast<FontSmoothingMode>(smoothing)); + return desc; +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebFontImpl.cpp b/WebKit/chromium/src/WebFontImpl.cpp new file mode 100644 index 0000000..6fa5494 --- /dev/null +++ b/WebKit/chromium/src/WebFontImpl.cpp @@ -0,0 +1,126 @@ +/* + * 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 "WebFontImpl.h" + +#include "Font.h" +#include "FontDescription.h" +#include "GraphicsContext.h" +#include "PlatformContextSkia.h" +#include "WebFloatPoint.h" +#include "WebFloatRect.h" +#include "WebFontDescription.h" +#include "WebRect.h" +#include "WebTextRun.h" + +using namespace WebCore; + +namespace WebKit { + +WebFont* WebFont::create(const WebFontDescription& desc) +{ + return new WebFontImpl(desc, desc.letterSpacing, desc.wordSpacing); +} + +WebFontImpl::WebFontImpl(const FontDescription& desc, short letterSpacing, short wordSpacing) + : m_font(desc, letterSpacing, wordSpacing) +{ + m_font.update(0); +} + +WebFontDescription WebFontImpl::fontDescription() const +{ + return WebFontDescription(m_font.fontDescription(), m_font.letterSpacing(), m_font.wordSpacing()); +} + +int WebFontImpl::ascent() const +{ + return m_font.ascent(); +} + +int WebFontImpl::descent() const +{ + return m_font.descent(); +} + +int WebFontImpl::height() const +{ + return m_font.height(); +} + +int WebFontImpl::lineSpacing() const +{ + return m_font.lineSpacing(); +} + +float WebFontImpl::xHeight() const +{ + return m_font.xHeight(); +} + +void WebFontImpl::drawText(WebCanvas* canvas, const WebTextRun& run, const WebFloatPoint& leftBaseline, + WebColor color, const WebRect& clip, bool canvasIsOpaque, + int from, int to) const +{ + // FIXME hook canvasIsOpaque up to the platform-specific indicators for + // whether subpixel AA can be used for this draw. On Windows, this is + // PlatformContextSkia::setDrawingToImageBuffer. +#if WEBKIT_USING_CG + GraphicsContext gc(canvas); +#elif WEBKIT_USING_SKIA + PlatformContextSkia context(canvas); + // PlatformGraphicsContext is actually a pointer to PlatformContextSkia. + GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context)); +#else + notImplemented(); +#endif + + gc.setFillColor(color, DeviceColorSpace); + gc.clip(WebCore::FloatRect(clip)); + m_font.drawText(&gc, run, leftBaseline, from, to); +} + +int WebFontImpl::calculateWidth(const WebTextRun& run) const +{ + return m_font.width(run, 0); +} + +int WebFontImpl::offsetForPosition(const WebTextRun& run, float position) const +{ + return m_font.offsetForPosition(run, position, true); +} + +WebFloatRect WebFontImpl::selectionRectForText(const WebTextRun& run, const WebFloatPoint& leftBaseline, int height, int from, int to) const +{ + return m_font.selectionRectForText(run, leftBaseline, height, from, to); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebFontImpl.h b/WebKit/chromium/src/WebFontImpl.h new file mode 100644 index 0000000..3ac9031 --- /dev/null +++ b/WebKit/chromium/src/WebFontImpl.h @@ -0,0 +1,66 @@ +/* + * 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 WebFontImpl_h +#define WebFontImpl_h + +#include "Font.h" +#include "WebFont.h" + +namespace WebCore { class FontDescription; } + +namespace WebKit { + +class WebFontImpl : public WebFont { +public: + WebFontImpl(const WebCore::FontDescription&, short letterSpacing, short wordSpacing); + + virtual WebFontDescription fontDescription() const; + + virtual int ascent() const; + virtual int descent() const; + virtual int height() const; + virtual int lineSpacing() const; + virtual float xHeight() const; + + virtual void drawText(WebCanvas*, const WebTextRun&, const WebFloatPoint& leftBaseline, WebColor, + const WebRect& clip, bool canvasIsOpaque, int from = 0, int to = -1) const; + virtual int calculateWidth(const WebTextRun&) const; + virtual int offsetForPosition(const WebTextRun&, float position) const; + virtual WebFloatRect selectionRectForText(const WebTextRun&, const WebFloatPoint& leftBaseline, + int height, int from = 0, int to = -1) const; + +private: + WebCore::Font m_font; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/WebFormControlElement.cpp b/WebKit/chromium/src/WebFormControlElement.cpp new file mode 100644 index 0000000..a75fe5c --- /dev/null +++ b/WebKit/chromium/src/WebFormControlElement.cpp @@ -0,0 +1,85 @@ +/* + * 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 "WebFormControlElement.h" + +#include "HTMLFormControlElement.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +bool WebFormControlElement::isEnabled() const +{ + return constUnwrap<HTMLFormControlElement>()->isEnabledFormControl(); +} + +WebString WebFormControlElement::formControlName() const +{ + return constUnwrap<HTMLFormControlElement>()->name(); +} + +WebString WebFormControlElement::formControlType() const +{ + return constUnwrap<HTMLFormControlElement>()->type(); +} + +WebString WebFormControlElement::nameForAutofill() const +{ + String name = constUnwrap<HTMLFormControlElement>()->name(); + String trimmedName = name.stripWhiteSpace(); + if (!trimmedName.isEmpty()) + return trimmedName; + name = constUnwrap<HTMLFormControlElement>()->getIdAttribute(); + trimmedName = name.stripWhiteSpace(); + if (!trimmedName.isEmpty()) + return trimmedName; + return String(); +} + +WebFormControlElement::WebFormControlElement(const PassRefPtr<HTMLFormControlElement>& elem) + : WebElement(elem) +{ +} + +WebFormControlElement& WebFormControlElement::operator=(const PassRefPtr<HTMLFormControlElement>& elem) +{ + m_private = elem; + return *this; +} + +WebFormControlElement::operator PassRefPtr<HTMLFormControlElement>() const +{ + return static_cast<HTMLFormControlElement*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebFormElement.cpp b/WebKit/chromium/src/WebFormElement.cpp index 5471608..9c77732 100644 --- a/WebKit/chromium/src/WebFormElement.cpp +++ b/WebKit/chromium/src/WebFormElement.cpp @@ -31,10 +31,13 @@ #include "config.h" #include "WebFormElement.h" +#include "FormState.h" #include "HTMLFormControlElement.h" #include "HTMLFormElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" +#include "WebFormControlElement.h" +#include "WebInputElement.h" #include "WebString.h" #include "WebURL.h" #include <wtf/PassRefPtr.h> @@ -43,25 +46,6 @@ using namespace WebCore; namespace WebKit { -class WebFormPrivate : public HTMLFormElement { -}; - -WebFormElement::WebFormElement(const WTF::PassRefPtr<HTMLFormElement>& e) - : WebElement(e.releaseRef()) -{ -} - -WebFormElement& WebFormElement::operator=(const WTF::PassRefPtr<HTMLFormElement>& e) -{ - WebNode::assign(e.releaseRef()); - return *this; -} - -WebFormElement::operator WTF::PassRefPtr<WebCore::HTMLFormElement>() const -{ - return PassRefPtr<HTMLFormElement>(static_cast<HTMLFormElement*>(m_private)); -} - bool WebFormElement::autoComplete() const { return constUnwrap<HTMLFormElement>()->autoComplete(); @@ -72,16 +56,21 @@ WebString WebFormElement::action() const return constUnwrap<HTMLFormElement>()->action(); } -WebString WebFormElement::name() const +WebString WebFormElement::name() const { return constUnwrap<HTMLFormElement>()->name(); } -WebString WebFormElement::method() const +WebString WebFormElement::method() const { return constUnwrap<HTMLFormElement>()->method(); } - + +bool WebFormElement::wasUserSubmitted() const +{ + return constUnwrap<HTMLFormElement>()->submissionTrigger() == NotSubmittedByJavaScript; +} + void WebFormElement::submit() { unwrap<HTMLFormElement>()->submit(); @@ -94,17 +83,36 @@ void WebFormElement::getNamedElements(const WebString& name, unwrap<HTMLFormElement>()->getNamedElements(name, tempVector); result.assign(tempVector); } - -void WebFormElement::getInputElements(WebVector<WebInputElement>& result) const + +void WebFormElement::getFormControlElements(WebVector<WebFormControlElement>& result) const { const HTMLFormElement* form = constUnwrap<HTMLFormElement>(); - Vector<RefPtr<HTMLInputElement> > tempVector; - for (size_t i = 0; i < form->formElements.size(); i++) { - if (form->formElements[i]->hasLocalName(HTMLNames::inputTag)) - tempVector.append(static_cast<HTMLInputElement*>( - form->formElements[i])); + Vector<RefPtr<HTMLFormControlElement> > tempVector; + // FIXME: We should move the for-loop condition into a variable instead of + // re-evaluating size each time. Also, consider refactoring this code so that + // we don't call form->associatedElements() multiple times. + for (size_t i = 0; i < form->associatedElements().size(); i++) { + if (form->associatedElements()[i]->hasLocalName(HTMLNames::inputTag) + || form->associatedElements()[i]->hasLocalName(HTMLNames::selectTag)) + tempVector.append(form->associatedElements()[i]); } result.assign(tempVector); } +WebFormElement::WebFormElement(const PassRefPtr<HTMLFormElement>& e) + : WebElement(e) +{ +} + +WebFormElement& WebFormElement::operator=(const PassRefPtr<HTMLFormElement>& e) +{ + m_private = e; + return *this; +} + +WebFormElement::operator PassRefPtr<HTMLFormElement>() const +{ + return static_cast<HTMLFormElement*>(m_private.get()); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebFrameImpl.cpp b/WebKit/chromium/src/WebFrameImpl.cpp index 2f911f1..f1c30e2 100644 --- a/WebKit/chromium/src/WebFrameImpl.cpp +++ b/WebKit/chromium/src/WebFrameImpl.cpp @@ -75,21 +75,20 @@ #include "ChromiumBridge.h" #include "ClipboardUtilitiesChromium.h" #include "Console.h" +#include "DOMUtilitiesPrivate.h" +#include "DOMWindow.h" #include "Document.h" #include "DocumentFragment.h" // Only needed for ReplaceSelectionCommand.h :( #include "DocumentLoader.h" #include "DocumentMarker.h" -#include "DOMUtilitiesPrivate.h" -#include "DOMWindow.h" #include "Editor.h" #include "EventHandler.h" #include "FormState.h" -#include "FrameLoader.h" #include "FrameLoadRequest.h" +#include "FrameLoader.h" #include "FrameTree.h" #include "FrameView.h" #include "GraphicsContext.h" -#include "HistoryItem.h" #include "HTMLCollection.h" #include "HTMLFormElement.h" #include "HTMLFrameOwnerElement.h" @@ -97,10 +96,11 @@ #include "HTMLInputElement.h" #include "HTMLLinkElement.h" #include "HTMLNames.h" +#include "HistoryItem.h" #include "InspectorController.h" -#include "markup.h" #include "Page.h" #include "PlatformContextSkia.h" +#include "PluginDocument.h" #include "PrintContext.h" #include "RenderFrame.h" #include "RenderTreeAsText.h" @@ -112,8 +112,8 @@ #include "ScriptController.h" #include "ScriptSourceCode.h" #include "ScriptValue.h" -#include "ScrollbarTheme.h" #include "ScrollTypes.h" +#include "ScrollbarTheme.h" #include "SelectionController.h" #include "Settings.h" #include "SkiaUtils.h" @@ -130,6 +130,8 @@ #include "WebHistoryItem.h" #include "WebInputElement.h" #include "WebPasswordAutocompleteListener.h" +#include "WebPlugin.h" +#include "WebPluginContainerImpl.h" #include "WebRange.h" #include "WebRect.h" #include "WebScriptSource.h" @@ -139,6 +141,7 @@ #include "WebVector.h" #include "WebViewImpl.h" #include "XPathResult.h" +#include "markup.h" #include <algorithm> #include <wtf/CurrentTime.h> @@ -246,7 +249,18 @@ static void frameContentAsPlainText(size_t maxChars, Frame* frame, } } -// Simple class to override some of PrintContext behavior. +WebPluginContainerImpl* WebFrameImpl::pluginContainerFromFrame(Frame* frame) +{ + if (!frame) + return 0; + if (!frame->document() || !frame->document()->isPluginDocument()) + return 0; + PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document()); + return static_cast<WebPluginContainerImpl *>(pluginDocument->pluginWidget()); +} + +// Simple class to override some of PrintContext behavior. Some of the methods +// made virtual so that they can be overriden by ChromePluginPrintContext. class ChromePrintContext : public PrintContext, public Noncopyable { public: ChromePrintContext(Frame* frame) @@ -255,28 +269,38 @@ public: { } - void begin(float width) + virtual void begin(float width) { ASSERT(!m_printedPageWidth); m_printedPageWidth = width; PrintContext::begin(m_printedPageWidth); } - float getPageShrink(int pageNumber) const + virtual void end() + { + PrintContext::end(); + } + + virtual float getPageShrink(int pageNumber) const { IntRect pageRect = m_pageRects[pageNumber]; return m_printedPageWidth / pageRect.width(); } - // Spools the printed page, a subrect of m_frame. Skip the scale step. + // Spools the printed page, a subrect of m_frame. Skip the scale step. // NativeTheme doesn't play well with scaling. Scaling is done browser side - // instead. Returns the scale to be applied. - float spoolPage(GraphicsContext& ctx, int pageNumber) + // instead. Returns the scale to be applied. + // On Linux, we don't have the problem with NativeTheme, hence we let WebKit + // do the scaling and ignore the return value. + virtual float spoolPage(GraphicsContext& ctx, int pageNumber) { IntRect pageRect = m_pageRects[pageNumber]; float scale = m_printedPageWidth / pageRect.width(); ctx.save(); +#if OS(LINUX) + ctx.scale(WebCore::FloatSize(scale, scale)); +#endif ctx.translate(static_cast<float>(-pageRect.x()), static_cast<float>(-pageRect.y())); ctx.clip(pageRect); @@ -285,11 +309,95 @@ public: return scale; } + virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) + { + return PrintContext::computePageRects(printRect, headerHeight, footerHeight, userScaleFactor, outPageHeight); + } + + virtual int pageCount() const + { + return PrintContext::pageCount(); + } + + virtual bool shouldUseBrowserOverlays() const + { + return true; + } + private: // Set when printing. float m_printedPageWidth; }; +// Simple class to override some of PrintContext behavior. This is used when +// the frame hosts a plugin that supports custom printing. In this case, we +// want to delegate all printing related calls to the plugin. +class ChromePluginPrintContext : public ChromePrintContext { +public: + ChromePluginPrintContext(Frame* frame, int printerDPI) + : ChromePrintContext(frame), m_pageCount(0), m_printerDPI(printerDPI) + { + // This HAS to be a frame hosting a full-mode plugin + ASSERT(frame->document()->isPluginDocument()); + } + + virtual void begin(float width) + { + } + + virtual void end() + { + WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + pluginContainer->printEnd(); + else + ASSERT_NOT_REACHED(); + } + + virtual float getPageShrink(int pageNumber) const + { + // We don't shrink the page (maybe we should ask the widget ??) + return 1.0; + } + + virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) + { + WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + m_pageCount = pluginContainer->printBegin(IntRect(printRect), m_printerDPI); + else + ASSERT_NOT_REACHED(); + } + + virtual int pageCount() const + { + return m_pageCount; + } + + // Spools the printed page, a subrect of m_frame. Skip the scale step. + // NativeTheme doesn't play well with scaling. Scaling is done browser side + // instead. Returns the scale to be applied. + virtual float spoolPage(GraphicsContext& ctx, int pageNumber) + { + WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + pluginContainer->printPage(pageNumber, &ctx); + else + ASSERT_NOT_REACHED(); + return 1.0; + } + + virtual bool shouldUseBrowserOverlays() const + { + return false; + } + +private: + // Set when printing. + int m_pageCount; + int m_printerDPI; +}; + static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) { return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0; @@ -363,9 +471,9 @@ WebString WebFrameImpl::name() const return m_frame->tree()->name(); } -void WebFrameImpl::clearName() +void WebFrameImpl::setName(const WebString& name) { - m_frame->tree()->clearName(); + m_frame->tree()->setName(name); } WebURL WebFrameImpl::url() const @@ -413,7 +521,7 @@ WebURL WebFrameImpl::openSearchDescriptionURL() const WebString WebFrameImpl::encoding() const { - return frame()->loader()->encoding(); + return frame()->loader()->writer()->encoding(); } WebSize WebFrameImpl::scrollOffset() const @@ -553,13 +661,18 @@ void WebFrameImpl::forms(WebVector<WebFormElement>& results) const return; RefPtr<HTMLCollection> forms = m_frame->document()->forms(); - size_t formCount = forms->length(); + size_t formCount = 0; + for (size_t i = 0; i < forms->length(); ++i) { + Node* node = forms->item(i); + if (node && node->isHTMLElement()) + ++formCount; + } WebVector<WebFormElement> temp(formCount); for (size_t i = 0; i < formCount; ++i) { Node* node = forms->item(i); // Strange but true, sometimes item can be 0. - if (node) + if (node && node->isHTMLElement()) temp[i] = static_cast<HTMLFormElement*>(node); } results.swap(temp); @@ -596,7 +709,7 @@ NPObject* WebFrameImpl::windowObject() const void WebFrameImpl::bindToWindowObject(const WebString& name, NPObject* object) { ASSERT(m_frame); - if (!m_frame || !m_frame->script()->canExecuteScripts()) + if (!m_frame || !m_frame->script()->canExecuteScripts(NotAboutToExecuteScript)) return; String key = name; @@ -670,6 +783,13 @@ void WebFrameImpl::collectGarbage() } #if USE(V8) +v8::Handle<v8::Value> WebFrameImpl::executeScriptAndReturnValue( + const WebScriptSource& source) +{ + return m_frame->script()->executeScript( + ScriptSourceCode(source.code, source.url, source.startLine)).v8Value(); +} + // Returns the V8 context for this frame, or an empty handle if there is none. v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const { @@ -713,12 +833,10 @@ bool WebFrameImpl::insertStyleText( return success; } -void WebFrameImpl::reload() +void WebFrameImpl::reload(bool ignoreCache) { m_frame->loader()->history()->saveDocumentAndScrollState(); - - stopLoading(); // Make sure existing activity stops. - m_frame->loader()->reload(); + m_frame->loader()->reload(ignoreCache); } void WebFrameImpl::loadRequest(const WebURLRequest& request) @@ -731,7 +849,6 @@ void WebFrameImpl::loadRequest(const WebURLRequest& request) return; } - stopLoading(); // Make sure existing activity stops. m_frame->loader()->load(resourceRequest, false); } @@ -740,8 +857,6 @@ void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item) RefPtr<HistoryItem> historyItem = PassRefPtr<HistoryItem>(item); ASSERT(historyItem.get()); - stopLoading(); // Make sure existing activity stops. - // If there is no currentItem, which happens when we are navigating in // session history after a crash, we need to manufacture one otherwise WebKit // hoarks. This is probably the wrong thing to do, but it seems to work. @@ -778,8 +893,6 @@ void WebFrameImpl::loadData(const WebData& data, request = m_frame->loader()->originalRequest(); request.setURL(baseURL); - stopLoading(); // Make sure existing activity stops. - m_frame->loader()->load(request, substData, false); if (replace) { // Do this to force WebKit to treat the load as replacing the currently @@ -847,7 +960,12 @@ WebHistoryItem WebFrameImpl::previousHistoryItem() const WebHistoryItem WebFrameImpl::currentHistoryItem() const { - m_frame->loader()->history()->saveDocumentAndScrollState(); + // If we are still loading, then we don't want to clobber the current + // history item as this could cause us to lose the scroll position and + // document state. However, it is OK for new navigations. + if (m_frame->loader()->loadType() == FrameLoadTypeStandard + || !m_frame->loader()->activeDocumentLoader()->isLoadingInAPISense()) + m_frame->loader()->history()->saveDocumentAndScrollState(); return WebHistoryItem(m_frame->page()->backForwardList()->currentItem()); } @@ -897,7 +1015,7 @@ void WebFrameImpl::commitDocumentData(const char* data, size_t dataLen) userChosen = false; encoding = documentLoader->response().textEncodingName(); } - m_frame->loader()->setEncoding(encoding, userChosen); + m_frame->loader()->writer()->setEncoding(encoding, userChosen); // NOTE: mac only does this if there is a document m_frame->loader()->addData(data, dataLen); @@ -975,17 +1093,25 @@ bool WebFrameImpl::executeCommand(const WebString& name) if (command[command.length() - 1] == UChar(':')) command = command.substring(0, command.length() - 1); + if (command == "Copy") { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer) { + pluginContainer->copy(); + return true; + } + } + bool rv = true; // Specially handling commands that Editor::execCommand does not directly // support. if (command == "DeleteToEndOfParagraph") { Editor* editor = frame()->editor(); - if (!editor->deleteWithDirection(SelectionController::FORWARD, + if (!editor->deleteWithDirection(SelectionController::DirectionForward, ParagraphBoundary, true, false)) { - editor->deleteWithDirection(SelectionController::FORWARD, + editor->deleteWithDirection(SelectionController::DirectionForward, CharacterGranularity, true, false); @@ -1045,6 +1171,10 @@ bool WebFrameImpl::isContinuousSpellCheckingEnabled() const bool WebFrameImpl::hasSelection() const { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer) + return pluginContainer->plugin()->hasSelection(); + // frame()->selection()->isNone() never returns true. return (frame()->selection()->start() != frame()->selection()->end()); } @@ -1056,6 +1186,10 @@ WebRange WebFrameImpl::selectionRange() const WebString WebFrameImpl::selectionAsText() const { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer) + return pluginContainer->plugin()->selectionAsText(); + RefPtr<Range> range = frame()->selection()->toNormalizedRange(); if (!range.get()) return WebString(); @@ -1070,6 +1204,10 @@ WebString WebFrameImpl::selectionAsText() const WebString WebFrameImpl::selectionAsMarkup() const { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer) + return pluginContainer->plugin()->selectionAsMarkup(); + RefPtr<Range> range = frame()->selection()->toNormalizedRange(); if (!range.get()) return WebString(); @@ -1082,11 +1220,10 @@ void WebFrameImpl::selectWordAroundPosition(Frame* frame, VisiblePosition pos) VisibleSelection selection(pos); selection.expandUsingGranularity(WordGranularity); - if (selection.isRange()) - frame->setSelectionGranularity(WordGranularity); - - if (frame->shouldChangeSelection(selection)) - frame->selection()->setSelection(selection); + if (frame->shouldChangeSelection(selection)) { + TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity; + frame->selection()->setSelection(selection, granularity); + } } bool WebFrameImpl::selectWordAroundCaret() @@ -1099,11 +1236,17 @@ bool WebFrameImpl::selectWordAroundCaret() return true; } -int WebFrameImpl::printBegin(const WebSize& pageSize) +int WebFrameImpl::printBegin(const WebSize& pageSize, int printerDPI, bool *useBrowserOverlays) { ASSERT(!frame()->document()->isFrameSet()); + // If this is a plugin document, check if the plugin supports its own + // printing. If it does, we will delegate all printing to that. + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + m_printContext.set(new ChromePluginPrintContext(frame(), printerDPI)); + else + m_printContext.set(new ChromePrintContext(frame())); - m_printContext.set(new ChromePrintContext(frame())); FloatRect rect(0, 0, static_cast<float>(pageSize.width), static_cast<float>(pageSize.height)); m_printContext->begin(rect.width()); @@ -1111,6 +1254,9 @@ int WebFrameImpl::printBegin(const WebSize& pageSize) // We ignore the overlays calculation for now since they are generated in the // browser. pageHeight is actually an output parameter. m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight); + if (useBrowserOverlays) + *useBrowserOverlays = m_printContext->shouldUseBrowserOverlays(); + return m_printContext->pageCount(); } @@ -1133,7 +1279,7 @@ float WebFrameImpl::printPage(int page, WebCanvas* canvas) return 0; } -#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) +#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) || OS(SOLARIS) PlatformContextSkia context(canvas); GraphicsContext spool(&context); #elif OS(DARWIN) @@ -1152,6 +1298,28 @@ void WebFrameImpl::printEnd() m_printContext.clear(); } +bool WebFrameImpl::isPageBoxVisible(int pageIndex) +{ + return frame()->document()->isPageBoxVisible(pageIndex); +} + +void WebFrameImpl::pageSizeAndMarginsInPixels(int pageIndex, + WebSize& pageSize, + int& marginTop, + int& marginRight, + int& marginBottom, + int& marginLeft) +{ + IntSize size(pageSize.width, pageSize.height); + frame()->document()->pageSizeAndMarginsInPixels(pageIndex, + size, + marginTop, + marginRight, + marginBottom, + marginLeft); + pageSize = size; +} + bool WebFrameImpl::find(int identifier, const WebString& searchText, const WebFindOptions& options, @@ -1163,7 +1331,7 @@ bool WebFrameImpl::find(int identifier, if (!options.findNext) frame()->page()->unmarkAllTextMatches(); else - setMarkerActive(m_activeMatch.get(), false); // Active match is changing. + setMarkerActive(m_activeMatch.get(), false); // Active match is changing. // Starts the search from the current selection. bool startInSelection = true; @@ -1203,11 +1371,14 @@ bool WebFrameImpl::find(int identifier, else { m_activeMatch = newSelection.toNormalizedRange(); currSelectionRect = m_activeMatch->boundingBox(); - setMarkerActive(m_activeMatch.get(), true); // Active. + setMarkerActive(m_activeMatch.get(), true); // Active. // WebKit draws the highlighting for all matches. executeCommand(WebString::fromUTF8("Unselect")); } + // Make sure no node is focused. See http://crbug.com/38700. + frame()->document()->setFocusedNode(0); + if (!options.findNext || activeSelection) { // This is either a Find operation or a Find-next from a new start point // due to a selection, so we set the flag to ask the scoping effort @@ -1295,7 +1466,7 @@ void WebFrameImpl::scopeStringMatches(int identifier, identifier, searchText, options, - false); // false=we just reset, so don't do it again. + false); // false=we just reset, so don't do it again. return; } @@ -1309,7 +1480,7 @@ void WebFrameImpl::scopeStringMatches(int identifier, m_resumeScopingFromRange->startOffset(ec2) + 1, ec); if (ec || ec2) { - if (ec2) // A non-zero |ec| happens when navigating during search. + if (ec2) // A non-zero |ec| happens when navigating during search. ASSERT_NOT_REACHED(); return; } @@ -1318,7 +1489,7 @@ void WebFrameImpl::scopeStringMatches(int identifier, // This timeout controls how long we scope before releasing control. This // value does not prevent us from running for longer than this, but it is // periodically checked to see if we have exceeded our allocated time. - const double maxScopingDuration = 0.1; // seconds + const double maxScopingDuration = 0.1; // seconds int matchCount = 0; bool timedOut = false; @@ -1425,8 +1596,8 @@ void WebFrameImpl::scopeStringMatches(int identifier, identifier, searchText, options, - false); // don't reset. - return; // Done for now, resume work later. + false); // don't reset. + return; // Done for now, resume work later. } // This frame has no further scoping left, so it is done. Other frames might, @@ -1478,14 +1649,6 @@ void WebFrameImpl::resetMatchCount() m_framesScopingCount = 0; } -WebURL WebFrameImpl::completeURL(const WebString& url) const -{ - if (!m_frame || !m_frame->document()) - return WebURL(); - - return m_frame->document()->completeURL(url); -} - WebString WebFrameImpl::contentAsText(size_t maxChars) const { if (!m_frame) @@ -1533,6 +1696,14 @@ int WebFrameImpl::pageNumberForElementById(const WebString& id, return PrintContext::pageNumberForElement(element, pageSize); } +WebRect WebFrameImpl::selectionBoundsRect() const +{ + if (hasSelection()) + return IntRect(frame()->selectionBounds(false)); + + return WebRect(); +} + // WebFrameImpl public --------------------------------------------------------- PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) @@ -1608,7 +1779,7 @@ PassRefPtr<Frame> WebFrameImpl::createChildFrame( // it is necessary to check the value after calling init() and // return without loading URL. // (b:791612) - childFrame->init(); // create an empty document + childFrame->init(); // create an empty document if (!childFrame->tree()->parent()) return 0; @@ -1634,11 +1805,23 @@ void WebFrameImpl::layout() view->layoutIfNeededRecursive(); } +void WebFrameImpl::paintWithContext(GraphicsContext& gc, const WebRect& rect) +{ + IntRect dirtyRect(rect); + gc.save(); + if (m_frame->document() && frameView()) { + gc.clip(dirtyRect); + frameView()->paint(&gc, dirtyRect); + m_frame->page()->inspectorController()->drawNodeHighlight(gc); + } else + gc.fillRect(dirtyRect, Color::white, DeviceColorSpace); + gc.restore(); +} + void WebFrameImpl::paint(WebCanvas* canvas, const WebRect& rect) { if (rect.isEmpty()) return; - IntRect dirtyRect(rect); #if WEBKIT_USING_CG GraphicsContext gc(canvas); LocalCurrentGraphicsContext localContext(&gc); @@ -1650,14 +1833,7 @@ void WebFrameImpl::paint(WebCanvas* canvas, const WebRect& rect) #else notImplemented(); #endif - gc.save(); - if (m_frame->document() && frameView()) { - gc.clip(dirtyRect); - frameView()->paint(&gc, dirtyRect); - m_frame->page()->inspectorController()->drawNodeHighlight(gc); - } else - gc.fillRect(dirtyRect, Color::white, DeviceColorSpace); - gc.restore(); + paintWithContext(gc, rect); } void WebFrameImpl::createFrameView() @@ -1719,7 +1895,7 @@ WebFrameImpl* WebFrameImpl::fromFrameOwnerElement(Element* element) static_cast<HTMLFrameOwnerElement*>(element); return fromFrame(frameElement->contentFrame()); } - + WebViewImpl* WebFrameImpl::viewImpl() const { if (!m_frame) @@ -1794,24 +1970,38 @@ void WebFrameImpl::didFail(const ResourceError& error, bool wasProvisional) client()->didFailLoad(this, webError); } -void WebFrameImpl::setAllowsScrolling(bool flag) +void WebFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars) { - m_frame->view()->setCanHaveScrollbars(flag); + m_frame->view()->setCanHaveScrollbars(canHaveScrollbars); } -void WebFrameImpl::registerPasswordListener( +bool WebFrameImpl::registerPasswordListener( WebInputElement inputElement, WebPasswordAutocompleteListener* listener) { - RefPtr<HTMLInputElement> element = inputElement.operator PassRefPtr<HTMLInputElement>(); - ASSERT(m_passwordListeners.find(element) == m_passwordListeners.end()); - m_passwordListeners.set(element, listener); + RefPtr<HTMLInputElement> element(inputElement.unwrap<HTMLInputElement>()); + if (!m_passwordListeners.add(element, listener).second) { + delete listener; + return false; + } + return true; +} + +void WebFrameImpl::notifiyPasswordListenerOfAutocomplete( + const WebInputElement& inputElement) +{ + const HTMLInputElement* element = inputElement.constUnwrap<HTMLInputElement>(); + WebPasswordAutocompleteListener* listener = getPasswordListener(element); + // Password listeners need to autocomplete other fields that depend on the + // input element with autofill suggestions. + if (listener) + listener->performInlineAutocomplete(element->value(), false, false); } WebPasswordAutocompleteListener* WebFrameImpl::getPasswordListener( - HTMLInputElement* inputElement) + const HTMLInputElement* inputElement) { - return m_passwordListeners.get(RefPtr<HTMLInputElement>(inputElement)); + return m_passwordListeners.get(RefPtr<HTMLInputElement>(const_cast<HTMLInputElement*>(inputElement))); } // WebFrameImpl private -------------------------------------------------------- @@ -1832,6 +2022,8 @@ void WebFrameImpl::invalidateArea(AreaToInvalidate area) if ((area & InvalidateContentArea) == InvalidateContentArea) { IntRect contentArea( view->x(), view->y(), view->visibleWidth(), view->visibleHeight()); + IntRect frameRect = view->frameRect(); + contentArea.move(-frameRect.topLeft().x(), -frameRect.topLeft().y()); view->invalidateRect(contentArea); } @@ -1841,6 +2033,8 @@ void WebFrameImpl::invalidateArea(AreaToInvalidate area) view->x() + view->visibleWidth(), view->y(), ScrollbarTheme::nativeTheme()->scrollbarThickness(), view->visibleHeight()); + IntRect frameRect = view->frameRect(); + scrollBarVert.move(-frameRect.topLeft().x(), -frameRect.topLeft().y()); view->invalidateRect(scrollBarVert); } } @@ -1883,7 +2077,8 @@ void WebFrameImpl::addMarker(Range* range, bool activeMatch) void WebFrameImpl::setMarkerActive(Range* range, bool active) { - if (!range) + WebCore::ExceptionCode ec; + if (!range || range->collapsed(ec)) return; frame()->document()->setMarkersActive(range, active); @@ -1906,9 +2101,9 @@ int WebFrameImpl::ordinalOfFirstMatchForFrame(WebFrameImpl* frame) const bool WebFrameImpl::shouldScopeMatches(const String& searchText) { - // Don't scope if we can't find a frame or if the frame is not visible. + // Don't scope if we can't find a frame or a view or if the frame is not visible. // The user may have closed the tab/application, so abort. - if (!frame() || !hasVisibleContent()) + if (!frame() || !frame()->view() || !hasVisibleContent()) return false; ASSERT(frame()->document() && frame()->view()); @@ -1922,7 +2117,7 @@ bool WebFrameImpl::shouldScopeMatches(const String& searchText) searchText.substring(0, m_lastSearchString.length()); if (previousSearchPrefix == m_lastSearchString) - return false; // Don't search this frame, it will be fruitless. + return false; // Don't search this frame, it will be fruitless. } return true; @@ -1974,12 +2169,13 @@ void WebFrameImpl::clearPasswordListeners() void WebFrameImpl::loadJavaScriptURL(const KURL& url) { - // This is copied from FrameLoader::executeIfJavaScriptURL. Unfortunately, - // we cannot just use that method since it is private, and it also doesn't - // quite behave as we require it to for bookmarklets. The key difference is - // that we need to suppress loading the string result from evaluating the JS - // URL if executing the JS URL resulted in a location change. We also allow - // a JS URL to be loaded even if scripts on the page are otherwise disabled. + // This is copied from ScriptController::executeIfJavaScriptURL. + // Unfortunately, we cannot just use that method since it is private, and + // it also doesn't quite behave as we require it to for bookmarklets. The + // key difference is that we need to suppress loading the string result + // from evaluating the JS URL if executing the JS URL resulted in a + // location change. We also allow a JS URL to be loaded even if scripts on + // the page are otherwise disabled. if (!m_frame->document() || !m_frame->page()) return; @@ -1991,14 +2187,8 @@ void WebFrameImpl::loadJavaScriptURL(const KURL& url) if (!result.getString(scriptResult)) return; - SecurityOrigin* securityOrigin = m_frame->document()->securityOrigin(); - - if (!m_frame->redirectScheduler()->locationChangePending()) { - m_frame->loader()->stopAllLoaders(); - m_frame->loader()->begin(m_frame->loader()->url(), true, securityOrigin); - m_frame->loader()->write(scriptResult); - m_frame->loader()->end(); - } + if (!m_frame->redirectScheduler()->locationChangePending()) + m_frame->loader()->writer()->replaceDocument(scriptResult); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebFrameImpl.h b/WebKit/chromium/src/WebFrameImpl.h index ccba6d4..2511fce 100644 --- a/WebKit/chromium/src/WebFrameImpl.h +++ b/WebKit/chromium/src/WebFrameImpl.h @@ -31,17 +31,17 @@ #ifndef WebFrameImpl_h #define WebFrameImpl_h -// FIXME: remove this relative path once consumers from glue are removed. -#include "../public/WebFrame.h" +#include "WebAnimationControllerImpl.h" +#include "WebFrame.h" + #include "Frame.h" #include "FrameLoaderClientImpl.h" #include "PlatformString.h" #include <wtf/OwnPtr.h> #include <wtf/RefCounted.h> -#include "WebAnimationControllerImpl.h" - namespace WebCore { +class GraphicsContext; class HistoryItem; class KURL; class Node; @@ -56,6 +56,7 @@ class WebDataSourceImpl; class WebInputElement; class WebFrameClient; class WebPasswordAutocompleteListener; +class WebPluginContainerImpl; class WebView; class WebViewImpl; @@ -64,7 +65,7 @@ class WebFrameImpl : public WebFrame, public RefCounted<WebFrameImpl> { public: // WebFrame methods: virtual WebString name() const; - virtual void clearName(); + virtual void setName(const WebString&); virtual WebURL url() const; virtual WebURL favIconURL() const; virtual WebURL openSearchDescriptionURL() const; @@ -88,7 +89,7 @@ public: virtual WebFrame* findChildByExpression(const WebString&) const; virtual WebDocument document() const; virtual void forms(WebVector<WebFormElement>&) const; - virtual WebAnimationController* animationController(); + virtual WebAnimationController* animationController(); virtual WebSecurityOrigin securityOrigin() const; virtual void grantUniversalAccess(); virtual NPObject* windowObject() const; @@ -100,10 +101,12 @@ public: virtual void addMessageToConsole(const WebConsoleMessage&); virtual void collectGarbage(); #if WEBKIT_USING_V8 + virtual v8::Handle<v8::Value> executeScriptAndReturnValue( + const WebScriptSource&); virtual v8::Local<v8::Context> mainWorldScriptContext() const; #endif virtual bool insertStyleText(const WebString& css, const WebString& id); - virtual void reload(); + virtual void reload(bool ignoreCache); virtual void loadRequest(const WebURLRequest&); virtual void loadHistoryItem(const WebHistoryItem&); virtual void loadData( @@ -142,10 +145,18 @@ public: virtual WebString selectionAsText() const; virtual WebString selectionAsMarkup() const; virtual bool selectWordAroundCaret(); - virtual int printBegin(const WebSize& pageSize); + virtual int printBegin(const WebSize& pageSize, int printerDPI, + bool* useBrowserOverlays); virtual float printPage(int pageToPrint, WebCanvas*); virtual float getPrintPageShrink(int page); virtual void printEnd(); + virtual bool isPageBoxVisible(int pageIndex); + virtual void pageSizeAndMarginsInPixels(int pageIndex, + WebSize& pageSize, + int& marginTop, + int& marginRight, + int& marginBottom, + int& marginLeft); virtual bool find( int identifier, const WebString& searchText, const WebFindOptions&, bool wrapWithinFrame, WebRect* selectionRect); @@ -156,10 +167,11 @@ public: virtual void cancelPendingScopingEffort(); virtual void increaseMatchCount(int count, int identifier); virtual void resetMatchCount(); - virtual void registerPasswordListener( + virtual bool registerPasswordListener( WebInputElement, WebPasswordAutocompleteListener*); + virtual void notifiyPasswordListenerOfAutocomplete( + const WebInputElement&); - virtual WebURL completeURL(const WebString& url) const; virtual WebString contentAsText(size_t maxChars) const; virtual WebString contentAsMarkup() const; virtual WebString renderTreeAsText() const; @@ -167,6 +179,7 @@ public: virtual int pageNumberForElementById(const WebString& id, float pageWidthInPixels, float pageHeightInPixels) const; + virtual WebRect selectionBoundsRect() const; static PassRefPtr<WebFrameImpl> create(WebFrameClient* client); ~WebFrameImpl(); @@ -179,11 +192,16 @@ public: void layout(); void paint(WebCanvas*, const WebRect&); + void paintWithContext(WebCore::GraphicsContext&, const WebRect&); void createFrameView(); static WebFrameImpl* fromFrame(WebCore::Frame* frame); static WebFrameImpl* fromFrameOwnerElement(WebCore::Element* element); + // If the frame hosts a PluginDocument, this method returns the WebPluginContainerImpl + // that hosts the plugin. + static WebPluginContainerImpl* pluginContainerFromFrame(WebCore::Frame*); + WebViewImpl* viewImpl() const; WebCore::Frame* frame() const { return m_frame; } @@ -212,16 +230,16 @@ public: // Sets whether the WebFrameImpl allows its document to be scrolled. // If the parameter is true, allow the document to be scrolled. // Otherwise, disallow scrolling. - void setAllowsScrolling(bool); + void setCanHaveScrollbars(bool); // Returns the password autocomplete listener associated with the passed // user name input element, or 0 if none available. // Note that the returned listener is owner by the WebFrameImpl and should not // be kept around as it is deleted when the page goes away. - WebPasswordAutocompleteListener* getPasswordListener(WebCore::HTMLInputElement*); + WebPasswordAutocompleteListener* getPasswordListener(const WebCore::HTMLInputElement*); WebFrameClient* client() const { return m_client; } - void dropClient() { m_client = 0; } + void setClient(WebFrameClient* client) { m_client = client; } static void selectWordAroundPosition(WebCore::Frame*, WebCore::VisiblePosition); diff --git a/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp new file mode 100644 index 0000000..265ef4f --- /dev/null +++ b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp @@ -0,0 +1,181 @@ +/* + * 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 "WebGeolocationServiceBridgeImpl.h" + +#include "Chrome.h" +#include "ChromeClientImpl.h" +#include "Frame.h" +#include "Geolocation.h" +#include "GeolocationServiceChromium.h" +#include "Geoposition.h" +#include "Page.h" +#include "PositionError.h" +#include "PositionOptions.h" +#include "WebFrame.h" +#include "WebFrameImpl.h" +#include "WebGeolocationService.h" +#include "WebGeolocationServiceBridge.h" +#include "WebViewClient.h" +#include "WebViewImpl.h" + +#if ENABLE(GEOLOCATION) + +using WebCore::Coordinates; +using WebCore::Frame; +using WebCore::Geolocation; +using WebCore::GeolocationServiceBridge; +using WebCore::GeolocationServiceChromium; +using WebCore::GeolocationServiceClient; +using WebCore::Geoposition; +using WebCore::PositionError; +using WebCore::PositionOptions; +using WebCore::String; + +namespace WebKit { + +class WebGeolocationServiceBridgeImpl : public GeolocationServiceBridge, public WebGeolocationServiceBridge { +public: + explicit WebGeolocationServiceBridgeImpl(GeolocationServiceChromium*); + virtual ~WebGeolocationServiceBridgeImpl(); + + // GeolocationServiceBridge + virtual bool startUpdating(PositionOptions*); + virtual void stopUpdating(); + virtual void suspend(); + virtual void resume(); + virtual int getBridgeId() const; + virtual void attachBridgeIfNeeded(); + + // WebGeolocationServiceBridge + virtual void setIsAllowed(bool allowed); + virtual void setLastPosition(double latitude, double longitude, bool providesAltitude, double altitude, double accuracy, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed, long long timestamp); + virtual void setLastError(int errorCode, const WebString& message); + +private: + WebViewClient* getWebViewClient(); + + // GeolocationServiceChromium owns us, we only have a pointer back to it. + GeolocationServiceChromium* m_GeolocationServiceChromium; + int m_bridgeId; +}; + +GeolocationServiceBridge* createGeolocationServiceBridgeImpl(GeolocationServiceChromium* geolocationServiceChromium) +{ + return new WebGeolocationServiceBridgeImpl(geolocationServiceChromium); +} + +WebGeolocationServiceBridgeImpl::WebGeolocationServiceBridgeImpl(GeolocationServiceChromium* geolocationServiceChromium) + : m_GeolocationServiceChromium(geolocationServiceChromium) + , m_bridgeId(0) +{ +} + +WebGeolocationServiceBridgeImpl::~WebGeolocationServiceBridgeImpl() +{ + WebKit::WebViewClient* webViewClient = getWebViewClient(); + // Geolocation has an OwnPtr to us, and it's destroyed after the frame has + // been potentially disconnected. In this case, it calls stopUpdating() + // has been called and we have already detached ourselves. + if (!webViewClient) + ASSERT(!m_bridgeId); + else if (m_bridgeId) + webViewClient->geolocationService()->detachBridge(m_bridgeId); +} + +bool WebGeolocationServiceBridgeImpl::startUpdating(PositionOptions* positionOptions) +{ + attachBridgeIfNeeded(); + getWebViewClient()->geolocationService()->startUpdating(m_bridgeId, m_GeolocationServiceChromium->frame()->document()->url(), positionOptions->enableHighAccuracy()); + return true; +} + +void WebGeolocationServiceBridgeImpl::stopUpdating() +{ + WebViewClient* webViewClient = getWebViewClient(); + if (m_bridgeId && webViewClient) { + WebGeolocationService* geolocationService = webViewClient->geolocationService(); + geolocationService->stopUpdating(m_bridgeId); + geolocationService->detachBridge(m_bridgeId); + } + m_bridgeId = 0; +} + +void WebGeolocationServiceBridgeImpl::suspend() +{ + getWebViewClient()->geolocationService()->suspend(m_bridgeId); +} + +void WebGeolocationServiceBridgeImpl::resume() +{ + getWebViewClient()->geolocationService()->resume(m_bridgeId); +} + +int WebGeolocationServiceBridgeImpl::getBridgeId() const +{ + return m_bridgeId; +} + +void WebGeolocationServiceBridgeImpl::attachBridgeIfNeeded() +{ + if (!m_bridgeId) + m_bridgeId = getWebViewClient()->geolocationService()->attachBridge(this); +} + +void WebGeolocationServiceBridgeImpl::setIsAllowed(bool allowed) +{ + m_GeolocationServiceChromium->setIsAllowed(allowed); +} + +void WebGeolocationServiceBridgeImpl::setLastPosition(double latitude, double longitude, bool providesAltitude, double altitude, double accuracy, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed, long long timestamp) +{ + RefPtr<Geoposition> geoposition = Geoposition::create(Coordinates::create(latitude, longitude, providesAltitude, altitude, accuracy, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed), timestamp); + m_GeolocationServiceChromium->setLastPosition(geoposition); +} + +void WebGeolocationServiceBridgeImpl::setLastError(int errorCode, const WebString& message) +{ + m_GeolocationServiceChromium->setLastError(errorCode, message); +} + +WebViewClient* WebGeolocationServiceBridgeImpl::getWebViewClient() +{ + Frame* frame = m_GeolocationServiceChromium->frame(); + if (!frame || !frame->page()) + return 0; + WebKit::ChromeClientImpl* chromeClientImpl = static_cast<WebKit::ChromeClientImpl*>(frame->page()->chrome()->client()); + WebKit::WebViewClient* webViewClient = chromeClientImpl->webView()->client(); + return webViewClient; +} + +} // namespace WebKit + +#endif // ENABLE(GEOLOCATION) diff --git a/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.h b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.h new file mode 100644 index 0000000..2c37bcb --- /dev/null +++ b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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 WebGeolocationServiceBridgeImpl_h +#define WebGeolocationServiceBridgeImpl_h + +namespace WebCore { +class GeolocationServiceBridge; +class GeolocationServiceChromium; +} + +namespace WebKit { +WebCore::GeolocationServiceBridge* createGeolocationServiceBridgeImpl(WebCore::GeolocationServiceChromium*); +} // namespace WebKit + +#endif // WebGeolocationServiceBridgeImpl_h diff --git a/WebKit/chromium/src/WebGeolocationServiceMock.cpp b/WebKit/chromium/src/WebGeolocationServiceMock.cpp new file mode 100644 index 0000000..00d819b --- /dev/null +++ b/WebKit/chromium/src/WebGeolocationServiceMock.cpp @@ -0,0 +1,188 @@ +/* + * 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 "WebGeolocationServiceMock.h" + +#include "GeolocationService.h" +#include "GeolocationServiceChromium.h" +#include "GeolocationServiceMock.h" +#include "WebString.h" +#include <wtf/CurrentTime.h> +#include <wtf/HashMap.h> + +#if ENABLE(GEOLOCATION) + +using WebCore::Coordinates; +using WebCore::Frame; +using WebCore::Geolocation; +using WebCore::GeolocationServiceBridge; +using WebCore::GeolocationServiceChromium; +using WebCore::GeolocationServiceClient; +using WebCore::GeolocationServiceMock; +using WebCore::Geoposition; +using WebCore::PositionError; +using WebCore::PositionOptions; +using WebCore::String; + +namespace WebCore { +class GeolocationServiceChromiumMock : public GeolocationServiceChromium, public GeolocationServiceClient { +public: + static GeolocationService* create(GeolocationServiceClient*); + virtual bool startUpdating(PositionOptions*); + virtual void stopUpdating(); + virtual Geoposition* lastPosition() const; + virtual PositionError* lastError() const; + + virtual void geolocationServicePositionChanged(GeolocationService*); + virtual void geolocationServiceErrorOccurred(GeolocationService*); + +private: + explicit GeolocationServiceChromiumMock(GeolocationServiceClient*); + + GeolocationServiceClient* m_geolocationServiceClient; + OwnPtr<GeolocationService> m_geolocationServiceMock; +}; + +GeolocationService* GeolocationServiceChromiumMock::create(GeolocationServiceClient* geolocationServiceClient) +{ + return new GeolocationServiceChromiumMock(geolocationServiceClient); +} + +GeolocationServiceChromiumMock::GeolocationServiceChromiumMock(GeolocationServiceClient* geolocationServiceClient) + : GeolocationServiceChromium(geolocationServiceClient), + m_geolocationServiceClient(geolocationServiceClient) +{ + m_geolocationServiceMock.set(GeolocationServiceMock::create(this)); +} + +bool GeolocationServiceChromiumMock::startUpdating(PositionOptions* positionOptions) +{ + GeolocationServiceChromium::startUpdating(positionOptions); + return m_geolocationServiceMock->startUpdating(positionOptions); +} + +void GeolocationServiceChromiumMock::stopUpdating() +{ + GeolocationServiceChromium::stopUpdating(); + m_geolocationServiceMock->stopUpdating(); +} + +Geoposition* GeolocationServiceChromiumMock::lastPosition() const +{ + return m_geolocationServiceMock->lastPosition(); +} + +PositionError* GeolocationServiceChromiumMock::lastError() const +{ + return m_geolocationServiceMock->lastError(); +} + +void GeolocationServiceChromiumMock::geolocationServicePositionChanged(GeolocationService* geolocationService) +{ + ASSERT_UNUSED(geolocationService, geolocationService == m_geolocationServiceMock); + m_geolocationServiceClient->geolocationServicePositionChanged(this); + +} + +void GeolocationServiceChromiumMock::geolocationServiceErrorOccurred(GeolocationService* geolocationService) +{ + ASSERT_UNUSED(geolocationService, geolocationService == m_geolocationServiceMock); + m_geolocationServiceClient->geolocationServiceErrorOccurred(this); +} + +} // namespace WebCore + +namespace WebKit { + +class WebGeolocationServiceMockImpl : public WebGeolocationServiceMock { +public: + virtual ~WebGeolocationServiceMockImpl() { } + virtual void requestPermissionForFrame(int bridgeId, const WebURL& url); + virtual int attachBridge(WebGeolocationServiceBridge*); + virtual void detachBridge(int bridgeId); + +private: + typedef HashMap<int, WebGeolocationServiceBridge*> IdToBridgeMap; + IdToBridgeMap m_idToBridgeMap; +}; + +bool WebGeolocationServiceMock::s_mockGeolocationPermission = false; + +WebGeolocationServiceMock* WebGeolocationServiceMock::createWebGeolocationServiceMock() +{ + return new WebGeolocationServiceMockImpl; +} + +void WebGeolocationServiceMock::setMockGeolocationPermission(bool allowed) +{ + s_mockGeolocationPermission = allowed; +} + +void WebGeolocationServiceMock::setMockGeolocationPosition(double latitude, double longitude, double accuracy) +{ + WebCore::GeolocationService::setCustomMockFactory(&WebCore::GeolocationServiceChromiumMock::create); + RefPtr<Geoposition> geoposition = Geoposition::create(Coordinates::create(latitude, longitude, false, 0, accuracy, true, 0, false, 0, false, 0), currentTime() * 1000.0); + GeolocationServiceMock::setPosition(geoposition); +} + +void WebGeolocationServiceMock::setMockGeolocationError(int errorCode, const WebString& message) +{ + WebCore::GeolocationService::setCustomMockFactory(&WebCore::GeolocationServiceChromiumMock::create); + RefPtr<PositionError> positionError = PositionError::create(static_cast<PositionError::ErrorCode>(errorCode), message); + GeolocationServiceMock::setError(positionError); +} + +void WebGeolocationServiceMockImpl::requestPermissionForFrame(int bridgeId, const WebURL& url) +{ + IdToBridgeMap::iterator iter = m_idToBridgeMap.find(bridgeId); + if (iter == m_idToBridgeMap.end()) + return; + iter->second->setIsAllowed(s_mockGeolocationPermission); +} + +int WebGeolocationServiceMockImpl::attachBridge(WebGeolocationServiceBridge* bridge) +{ + static int nextAvailableWatchId = 1; + // In case of overflow, make sure the ID remains positive, but reuse the ID values. + if (nextAvailableWatchId < 1) + nextAvailableWatchId = 1; + m_idToBridgeMap.set(nextAvailableWatchId, bridge); + return nextAvailableWatchId++; +} + +void WebGeolocationServiceMockImpl::detachBridge(int bridgeId) +{ + m_idToBridgeMap.remove(bridgeId); +} + +} // namespace WebKit + +#endif // ENABLE(GEOLOCATION) diff --git a/WebKit/chromium/src/WebGraphicsContext3D.cpp b/WebKit/chromium/src/WebGraphicsContext3D.cpp new file mode 100644 index 0000000..ce6f55d --- /dev/null +++ b/WebKit/chromium/src/WebGraphicsContext3D.cpp @@ -0,0 +1,47 @@ +/* + * 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 "WebGraphicsContext3D.h" + +#include "WebGraphicsContext3DDefaultImpl.h" + +namespace WebKit { + +WebGraphicsContext3D* WebGraphicsContext3D::createDefault() +{ +#if ENABLE(3D_CANVAS) + return new WebGraphicsContext3DDefaultImpl(); +#else + return 0; +#endif +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp new file mode 100644 index 0000000..47bb5a0 --- /dev/null +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp @@ -0,0 +1,1508 @@ +/* + * 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" + +#if ENABLE(3D_CANVAS) + +#include <stdio.h> +#include <string.h> + +#include "WebGraphicsContext3DDefaultImpl.h" + +#include "NotImplemented.h" + +#if OS(LINUX) +#include <dlfcn.h> +#endif + +namespace WebKit { + +// Uncomment this to render to a separate window for debugging +// #define RENDER_TO_DEBUGGING_WINDOW + +#if OS(DARWIN) +#define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER +#endif + +bool WebGraphicsContext3DDefaultImpl::s_initializedGLEW = false; + +#if OS(LINUX) +WebGraphicsContext3DDefaultImpl::GLConnection* WebGraphicsContext3DDefaultImpl::s_gl = 0; + +WebGraphicsContext3DDefaultImpl::GLConnection* WebGraphicsContext3DDefaultImpl::GLConnection::create() +{ + Display* dpy = XOpenDisplay(0); + if (!dpy) { + printf("GraphicsContext3D: error opening X display\n"); + return 0; + } + + // We use RTLD_GLOBAL semantics so that GLEW initialization works; + // GLEW expects to be able to open the current process's handle + // and do dlsym's of GL entry points from there. + void* libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); + if (!libGL) { + XCloseDisplay(dpy); + printf("GraphicsContext3D: error opening libGL.so.1: %s\n", dlerror()); + return 0; + } + + PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(libGL, "glXChooseFBConfig"); + PFNGLXCREATENEWCONTEXTPROC createNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(libGL, "glXCreateNewContext"); + PFNGLXCREATEPBUFFERPROC createPbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(libGL, "glXCreatePbuffer"); + PFNGLXDESTROYPBUFFERPROC destroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(libGL, "glXDestroyPbuffer"); + PFNGLXMAKECURRENTPROC makeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(libGL, "glXMakeCurrent"); + PFNGLXDESTROYCONTEXTPROC destroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(libGL, "glXDestroyContext"); + PFNGLXGETCURRENTCONTEXTPROC getCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(libGL, "glXGetCurrentContext"); + if (!chooseFBConfig || !createNewContext || !createPbuffer + || !destroyPbuffer || !makeCurrent || !destroyContext + || !getCurrentContext) { + XCloseDisplay(dpy); + dlclose(libGL); + printf("GraphicsContext3D: error looking up bootstrapping entry points\n"); + return 0; + } + return new GLConnection(dpy, + libGL, + chooseFBConfig, + createNewContext, + createPbuffer, + destroyPbuffer, + makeCurrent, + destroyContext, + getCurrentContext); +} + +WebGraphicsContext3DDefaultImpl::GLConnection::~GLConnection() +{ + XCloseDisplay(m_display); + dlclose(m_libGL); +} + +#endif // OS(LINUX) + +WebGraphicsContext3DDefaultImpl::VertexAttribPointerState::VertexAttribPointerState() + : enabled(false) + , buffer(0) + , indx(0) + , size(0) + , type(0) + , normalized(false) + , stride(0) + , offset(0) +{ +} + +WebGraphicsContext3DDefaultImpl::WebGraphicsContext3DDefaultImpl() + : m_initialized(false) + , m_texture(0) + , m_fbo(0) + , m_depthStencilBuffer(0) + , m_multisampleFBO(0) + , m_multisampleDepthStencilBuffer(0) + , m_multisampleColorBuffer(0) + , m_boundFBO(0) +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + , m_scanline(0) +#endif + , m_boundArrayBuffer(0) +#if OS(WINDOWS) + , m_canvasWindow(0) + , m_canvasDC(0) + , m_contextObj(0) +#elif PLATFORM(CG) + , m_pbuffer(0) + , m_contextObj(0) + , m_renderOutput(0) +#elif OS(LINUX) + , m_contextObj(0) + , m_pbuffer(0) +#else +#error Must port to your platform +#endif +{ +} + +WebGraphicsContext3DDefaultImpl::~WebGraphicsContext3DDefaultImpl() +{ + if (m_initialized) { + makeContextCurrent(); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias) { + glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer); + if (m_attributes.depth || m_attributes.stencil) + glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); + glDeleteFramebuffersEXT(1, &m_multisampleFBO); + } else { + if (m_attributes.depth || m_attributes.stencil) + glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer); + } + glDeleteTextures(1, &m_texture); +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + if (m_scanline) + delete[] m_scanline; +#endif + glDeleteFramebuffersEXT(1, &m_fbo); +#endif // !RENDER_TO_DEBUGGING_WINDOW +#if OS(WINDOWS) + wglewMakeCurrent(0, 0); + wglewDeleteContext(m_contextObj); + ReleaseDC(m_canvasWindow, m_canvasDC); + DestroyWindow(m_canvasWindow); +#elif PLATFORM(CG) + CGLSetCurrentContext(0); + CGLDestroyContext(m_contextObj); + CGLDestroyPBuffer(m_pbuffer); + if (m_renderOutput) + delete[] m_renderOutput; +#elif OS(LINUX) + s_gl->makeCurrent(0, 0); + s_gl->destroyContext(m_contextObj); + s_gl->destroyPbuffer(m_pbuffer); +#else +#error Must port to your platform +#endif + m_contextObj = 0; + } +} + +bool WebGraphicsContext3DDefaultImpl::initialize(WebGraphicsContext3D::Attributes attributes, WebView* webView) +{ +#if OS(WINDOWS) + if (!s_initializedGLEW) { + // Do this only the first time through. + if (!wglewInit()) { + printf("WebGraphicsContext3DDefaultImpl: wglewInit failed\n"); + return false; + } + } + + WNDCLASS wc; + if (!GetClassInfo(GetModuleHandle(0), L"CANVASGL", &wc)) { + ZeroMemory(&wc, sizeof(WNDCLASS)); + wc.style = CS_OWNDC; + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = DefWindowProc; + wc.lpszClassName = L"CANVASGL"; + + if (!RegisterClass(&wc)) { + printf("WebGraphicsContext3DDefaultImpl: RegisterClass failed\n"); + return false; + } + } + + m_canvasWindow = CreateWindow(L"CANVASGL", L"CANVASGL", + WS_CAPTION, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0); + if (!m_canvasWindow) { + printf("WebGraphicsContext3DDefaultImpl: CreateWindow failed\n"); + return false; + } + + // get the device context + m_canvasDC = GetDC(m_canvasWindow); + if (!m_canvasDC) { + printf("WebGraphicsContext3DDefaultImpl: GetDC failed\n"); + return false; + } + + // find default pixel format + PIXELFORMATDESCRIPTOR pfd; + ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; +#ifdef RENDER_TO_DEBUGGING_WINDOW + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; +#else + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; +#endif + int pixelformat = ChoosePixelFormat(m_canvasDC, &pfd); + + // set the pixel format for the dc + if (!SetPixelFormat(m_canvasDC, pixelformat, &pfd)) { + printf("WebGraphicsContext3DDefaultImpl: SetPixelFormat failed\n"); + return false; + } + + // create rendering context + m_contextObj = wglewCreateContext(m_canvasDC); + if (!m_contextObj) { + printf("WebGraphicsContext3DDefaultImpl: wglCreateContext failed\n"); + return false; + } + + if (!wglewMakeCurrent(m_canvasDC, m_contextObj)) { + printf("WebGraphicsContext3DDefaultImpl: wglMakeCurrent failed\n"); + return false; + } + +#ifdef RENDER_TO_DEBUGGING_WINDOW + typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + PFNWGLSWAPINTERVALEXTPROC setSwapInterval = 0; + setSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglewGetProcAddress("wglSwapIntervalEXT"); + if (setSwapInterval) + setSwapInterval(1); +#endif // RENDER_TO_DEBUGGING_WINDOW + +#elif PLATFORM(CG) + // Create a 1x1 pbuffer and associated context to bootstrap things + CGLPixelFormatAttribute attribs[] = { + (CGLPixelFormatAttribute) kCGLPFAPBuffer, + (CGLPixelFormatAttribute) 0 + }; + CGLPixelFormatObj pixelFormat; + GLint numPixelFormats; + if (CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats) != kCGLNoError) { + printf("WebGraphicsContext3DDefaultImpl: error choosing pixel format\n"); + return false; + } + if (!pixelFormat) { + printf("WebGraphicsContext3DDefaultImpl: no pixel format selected\n"); + return false; + } + CGLContextObj context; + CGLError res = CGLCreateContext(pixelFormat, 0, &context); + CGLDestroyPixelFormat(pixelFormat); + if (res != kCGLNoError) { + printf("WebGraphicsContext3DDefaultImpl: error creating context\n"); + return false; + } + CGLPBufferObj pbuffer; + if (CGLCreatePBuffer(1, 1, GL_TEXTURE_2D, GL_RGBA, 0, &pbuffer) != kCGLNoError) { + CGLDestroyContext(context); + printf("WebGraphicsContext3DDefaultImpl: error creating pbuffer\n"); + return false; + } + if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) { + CGLDestroyContext(context); + CGLDestroyPBuffer(pbuffer); + printf("WebGraphicsContext3DDefaultImpl: error attaching pbuffer to context\n"); + return false; + } + if (CGLSetCurrentContext(context) != kCGLNoError) { + CGLDestroyContext(context); + CGLDestroyPBuffer(pbuffer); + printf("WebGraphicsContext3DDefaultImpl: error making context current\n"); + return false; + } + m_pbuffer = pbuffer; + m_contextObj = context; +#elif OS(LINUX) + if (!s_gl) { + s_gl = GLConnection::create(); + if (!s_gl) + return false; + } + + int configAttrs[] = { + GLX_DRAWABLE_TYPE, + GLX_PBUFFER_BIT, + GLX_RENDER_TYPE, + GLX_RGBA_BIT, + GLX_DOUBLEBUFFER, + 0, + 0 + }; + int nelements = 0; + GLXFBConfig* config = s_gl->chooseFBConfig(0, configAttrs, &nelements); + if (!config) { + printf("WebGraphicsContext3DDefaultImpl: glXChooseFBConfig failed\n"); + return false; + } + if (!nelements) { + printf("WebGraphicsContext3DDefaultImpl: glXChooseFBConfig returned 0 elements\n"); + XFree(config); + return false; + } + GLXContext context = s_gl->createNewContext(config[0], GLX_RGBA_TYPE, 0, True); + if (!context) { + printf("WebGraphicsContext3DDefaultImpl: glXCreateNewContext failed\n"); + XFree(config); + return false; + } + int pbufferAttrs[] = { + GLX_PBUFFER_WIDTH, + 1, + GLX_PBUFFER_HEIGHT, + 1, + 0 + }; + GLXPbuffer pbuffer = s_gl->createPbuffer(config[0], pbufferAttrs); + XFree(config); + if (!pbuffer) { + printf("WebGraphicsContext3DDefaultImpl: glxCreatePbuffer failed\n"); + return false; + } + if (!s_gl->makeCurrent(pbuffer, context)) { + printf("WebGraphicsContext3DDefaultImpl: glXMakeCurrent failed\n"); + return false; + } + m_contextObj = context; + m_pbuffer = pbuffer; +#else +#error Must port to your platform +#endif + + if (!s_initializedGLEW) { + // Initialize GLEW and check for GL 2.0 support by the drivers. + GLenum glewInitResult = glewInit(); + if (glewInitResult != GLEW_OK) { + printf("WebGraphicsContext3DDefaultImpl: GLEW initialization failed\n"); + return false; + } + if (!glewIsSupported("GL_VERSION_2_0")) { + printf("WebGraphicsContext3DDefaultImpl: OpenGL 2.0 not supported\n"); + return false; + } + s_initializedGLEW = true; + } + + m_attributes = attributes; + validateAttributes(); + + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + m_initialized = true; + return true; +} + +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 (!m_attributes.depth) + m_attributes.depth = true; + } else + m_attributes.stencil = false; + } + if (m_attributes.antialias) { + bool isValidVendor = true; +#if PLATFORM(CG) + // Currently in Mac we only turn on antialias if vendor is NVIDIA. + const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); + if (!strstr(vendor, "NVIDIA")) + isValidVendor = false; +#endif + if (!isValidVendor || !strstr(extensions, "GL_EXT_framebuffer_multisample")) + m_attributes.antialias = false; + } + // FIXME: instead of enforcing premultipliedAlpha = true, implement the + // correct behavior when premultipliedAlpha = false is requested. + m_attributes.premultipliedAlpha = true; +} + +bool WebGraphicsContext3DDefaultImpl::makeContextCurrent() +{ +#if OS(WINDOWS) + if (wglewGetCurrentContext() != m_contextObj) + if (wglewMakeCurrent(m_canvasDC, m_contextObj)) + return true; +#elif PLATFORM(CG) + if (CGLGetCurrentContext() != m_contextObj) + if (CGLSetCurrentContext(m_contextObj) == kCGLNoError) + return true; +#elif OS(LINUX) + if (s_gl->getCurrentContext() != m_contextObj) + if (s_gl->makeCurrent(m_pbuffer, m_contextObj)) + return true; +#else +#error Must port to your platform +#endif + return false; +} + +int WebGraphicsContext3DDefaultImpl::width() +{ + return m_cachedWidth; +} + +int WebGraphicsContext3DDefaultImpl::height() +{ + return m_cachedHeight; +} + +int WebGraphicsContext3DDefaultImpl::sizeInBytes(int type) +{ + switch (type) { + case GL_BYTE: + return sizeof(GLbyte); + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + case GL_SHORT: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_INT: + return sizeof(GLint); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + case GL_FLOAT: + return sizeof(GLfloat); + } + return 0; +} + +bool WebGraphicsContext3DDefaultImpl::isGLES2Compliant() +{ + return false; +} + +unsigned int WebGraphicsContext3DDefaultImpl::getPlatformTextureId() +{ + ASSERT_NOT_REACHED(); + return 0; +} + +void WebGraphicsContext3DDefaultImpl::prepareTexture() +{ + ASSERT_NOT_REACHED(); +} + +static int createTextureObject(GLenum target) +{ + GLuint texture = 0; + glGenTextures(1, &texture); + glBindTexture(target, texture); + glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + return texture; +} + +void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) +{ +#ifdef RENDER_TO_DEBUGGING_WINDOW + SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height, + SWP_NOMOVE); + ShowWindow(m_canvasWindow, SW_SHOW); +#endif + + m_cachedWidth = width; + m_cachedHeight = height; + makeContextCurrent(); + +#ifndef RENDER_TO_DEBUGGING_WINDOW +#ifdef USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER + // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on Mac OS X + GLenum target = GL_TEXTURE_RECTANGLE_ARB; +#else + GLenum target = GL_TEXTURE_2D; +#endif + if (!m_texture) { + // Generate the texture object + m_texture = createTextureObject(target); + // Generate the framebuffer object + glGenFramebuffersEXT(1, &m_fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + m_boundFBO = m_fbo; + if (m_attributes.depth || m_attributes.stencil) + glGenRenderbuffersEXT(1, &m_depthStencilBuffer); + // Generate the multisample framebuffer object + if (m_attributes.antialias) { + glGenFramebuffersEXT(1, &m_multisampleFBO); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + m_boundFBO = m_multisampleFBO; + glGenRenderbuffersEXT(1, &m_multisampleColorBuffer); + if (m_attributes.depth || m_attributes.stencil) + glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); + } + } + + GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; + if (m_attributes.alpha) { + internalColorFormat = GL_RGBA8; + colorFormat = GL_RGBA; + } else { + internalColorFormat = GL_RGB8; + colorFormat = GL_RGB; + } + if (m_attributes.stencil || m_attributes.depth) { + // We don't allow the logic where stencil is required and depth is not. + // See GraphicsContext3DInternal constructor. + if (m_attributes.stencil && m_attributes.depth) + internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; + else + internalDepthStencilFormat = GL_DEPTH_COMPONENT; + } + + bool mustRestoreFBO = false; + + // Resize multisampling FBO + if (m_attributes.antialias) { + GLint maxSampleCount; + glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount); + GLint sampleCount = std::min(8, maxSampleCount); + if (m_boundFBO != m_multisampleFBO) { + mustRestoreFBO = true; + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + } + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, 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_attributes.stencil) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + if (m_attributes.depth) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + } + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + printf("GraphicsContext3D: multisampling framebuffer was incomplete\n"); + + // FIXME: cleanup. + notImplemented(); + } + } + + // Resize regular FBO + if (m_boundFBO != m_fbo) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + mustRestoreFBO = true; + } + glBindTexture(target, m_texture); + glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0); + glBindTexture(target, 0); + if (!m_attributes.antialias && (m_attributes.stencil || m_attributes.depth)) { + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height); + if (m_attributes.stencil) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + if (m_attributes.depth) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + printf("WebGraphicsContext3DDefaultImpl: framebuffer was incomplete\n"); + + // FIXME: cleanup. + notImplemented(); + } + + if (m_attributes.antialias) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + if (m_boundFBO == m_multisampleFBO) + mustRestoreFBO = false; + } + + // Initialize renderbuffers to 0. + GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE, stencilMask = GL_TRUE; + GLboolean isScissorEnabled = GL_FALSE; + GLboolean isDitherEnabled = GL_FALSE; + GLbitfield clearMask = GL_COLOR_BUFFER_BIT; + glGetBooleanv(GL_COLOR_WRITEMASK, colorMask); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + if (m_attributes.depth) { + glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); + glDepthMask(GL_TRUE); + clearMask |= GL_DEPTH_BUFFER_BIT; + } + if (m_attributes.stencil) { + glGetBooleanv(GL_STENCIL_WRITEMASK, &stencilMask); + glStencilMask(GL_TRUE); + clearMask |= GL_STENCIL_BUFFER_BIT; + } + isScissorEnabled = glIsEnabled(GL_SCISSOR_TEST); + glDisable(GL_SCISSOR_TEST); + isDitherEnabled = glIsEnabled(GL_DITHER); + glDisable(GL_DITHER); + + glClear(clearMask); + + glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); + if (m_attributes.depth) + glDepthMask(depthMask); + if (m_attributes.stencil) + glStencilMask(stencilMask); + if (isScissorEnabled) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); + if (isDitherEnabled) + glEnable(GL_DITHER); + else + glDisable(GL_DITHER); + + if (mustRestoreFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); +#endif // RENDER_TO_DEBUGGING_WINDOW + +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + if (m_scanline) { + delete[] m_scanline; + m_scanline = 0; + } + m_scanline = new unsigned char[width * 4]; +#endif // FLIP_FRAMEBUFFER_VERTICALLY +} + +#ifdef FLIP_FRAMEBUFFER_VERTICALLY +void WebGraphicsContext3DDefaultImpl::flipVertically(unsigned char* framebuffer, + unsigned int width, + unsigned int height) +{ + unsigned char* scanline = m_scanline; + if (!scanline) + return; + unsigned int rowBytes = width * 4; + unsigned int count = height / 2; + for (unsigned int i = 0; i < count; i++) { + unsigned char* rowA = framebuffer + i * rowBytes; + unsigned char* rowB = framebuffer + (height - i - 1) * rowBytes; + // FIXME: this is where the multiplication of the alpha + // channel into the color buffer will need to occur if the + // user specifies the "premultiplyAlpha" flag in the context + // creation attributes. + memcpy(scanline, rowB, rowBytes); + memcpy(rowB, rowA, rowBytes); + memcpy(rowA, scanline, rowBytes); + } +} +#endif + +bool WebGraphicsContext3DDefaultImpl::readBackFramebuffer(unsigned char* pixels, size_t bufferSize) +{ + if (bufferSize != static_cast<size_t>(4 * width() * height())) + return false; + + makeContextCurrent(); + +#ifdef RENDER_TO_DEBUGGING_WINDOW + SwapBuffers(m_canvasDC); +#else + // Earlier versions of this code used the GPU to flip the + // framebuffer vertically before reading it back for compositing + // via software. This code was quite complicated, used a lot of + // GPU memory, and didn't provide an obvious speedup. Since this + // vertical flip is only a temporary solution anyway until Chrome + // is fully GPU composited, it wasn't worth the complexity. + + bool mustRestoreFBO = false; + if (m_attributes.antialias) { + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + mustRestoreFBO = true; + } else { + if (m_boundFBO != m_fbo) { + mustRestoreFBO = true; + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } + } + + GLint packAlignment = 4; + bool mustRestorePackAlignment = false; + glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); + if (packAlignment > 4) { + glPixelStorei(GL_PACK_ALIGNMENT, 4); + mustRestorePackAlignment = true; + } + +#if PLATFORM(SKIA) + glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); +#elif PLATFORM(CG) + glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels); +#else +#error Must port to your platform +#endif + + if (mustRestorePackAlignment) + glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); + + if (mustRestoreFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); + +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + if (pixels) + flipVertically(pixels, m_cachedWidth, m_cachedHeight); +#endif + +#endif // RENDER_TO_DEBUGGING_WINDOW + return true; +} + +void WebGraphicsContext3DDefaultImpl::synthesizeGLError(unsigned long error) +{ + m_syntheticErrors.add(error); +} + +// Helper macros to reduce the amount of code. + +#define DELEGATE_TO_GL(name, glname) \ +void WebGraphicsContext3DDefaultImpl::name() \ +{ \ + makeContextCurrent(); \ + gl##glname(); \ +} + +#define DELEGATE_TO_GL_1(name, glname, t1) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1); \ +} + +#define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ +rt WebGraphicsContext3DDefaultImpl::name(t1 a1) \ +{ \ + makeContextCurrent(); \ + return gl##glname(a1); \ +} + +#define DELEGATE_TO_GL_2(name, glname, t1, t2) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2); \ +} + +#define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ +rt WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2) \ +{ \ + makeContextCurrent(); \ + return gl##glname(a1, a2); \ +} + +#define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3); \ +} + +#define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4); \ +} + +#define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5); \ +} + +#define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5, a6); \ +} + +#define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5, a6, a7); \ +} + +#define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \ +} + +#define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ +} + +void WebGraphicsContext3DDefaultImpl::activeTexture(unsigned long texture) +{ + // FIXME: query number of textures available. + if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) + // FIXME: raise exception. + return; + + makeContextCurrent(); + glActiveTexture(texture); +} + +DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) + +DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId, unsigned long, const char*) + +void WebGraphicsContext3DDefaultImpl::bindBuffer(unsigned long target, WebGLId buffer) +{ + makeContextCurrent(); + if (target == GL_ARRAY_BUFFER) + m_boundArrayBuffer = buffer; + glBindBuffer(target, buffer); +} + +void WebGraphicsContext3DDefaultImpl::bindFramebuffer(unsigned long target, WebGLId framebuffer) +{ + makeContextCurrent(); + if (!framebuffer) + framebuffer = (m_attributes.antialias ? m_multisampleFBO : m_fbo); + if (framebuffer != m_boundFBO) { + glBindFramebufferEXT(target, framebuffer); + m_boundFBO = framebuffer; + } +} + +DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbufferEXT, unsigned long, WebGLId) + +DELEGATE_TO_GL_2(bindTexture, BindTexture, unsigned long, WebGLId) + +DELEGATE_TO_GL_4(blendColor, BlendColor, double, double, double, double) + +DELEGATE_TO_GL_1(blendEquation, BlendEquation, unsigned long) + +DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, unsigned long, unsigned long) + +DELEGATE_TO_GL_2(blendFunc, BlendFunc, unsigned long, unsigned long) + +DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) + +DELEGATE_TO_GL_4(bufferData, BufferData, unsigned long, int, const void*, unsigned long) + +DELEGATE_TO_GL_4(bufferSubData, BufferSubData, unsigned long, long, int, const void*) + +DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatusEXT, unsigned long, unsigned long) + +DELEGATE_TO_GL_1(clear, Clear, unsigned long) + +DELEGATE_TO_GL_4(clearColor, ClearColor, double, double, double, double) + +DELEGATE_TO_GL_1(clearDepth, ClearDepth, double) + +DELEGATE_TO_GL_1(clearStencil, ClearStencil, long) + +DELEGATE_TO_GL_4(colorMask, ColorMask, bool, bool, bool, bool) + +DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId) + +void WebGraphicsContext3DDefaultImpl::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, + long x, long y, unsigned long width, unsigned long height, long border) +{ + makeContextCurrent(); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { + 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); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } +#endif + glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); +#endif +} + +void WebGraphicsContext3DDefaultImpl::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, + long x, long y, unsigned long width, unsigned long height) +{ + makeContextCurrent(); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { + 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); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } +#endif + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); +#endif +} + +DELEGATE_TO_GL_1(cullFace, CullFace, unsigned long) + +DELEGATE_TO_GL_1(depthFunc, DepthFunc, unsigned long) + +DELEGATE_TO_GL_1(depthMask, DepthMask, bool) + +DELEGATE_TO_GL_2(depthRange, DepthRange, double, double) + +DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) + +DELEGATE_TO_GL_1(disable, Disable, unsigned long) + +void WebGraphicsContext3DDefaultImpl::disableVertexAttribArray(unsigned long index) +{ + makeContextCurrent(); + if (index < NumTrackedPointerStates) + m_vertexAttribPointerState[index].enabled = false; + glDisableVertexAttribArray(index); +} + +DELEGATE_TO_GL_3(drawArrays, DrawArrays, unsigned long, long, long) + +void WebGraphicsContext3DDefaultImpl::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset) +{ + makeContextCurrent(); + glDrawElements(mode, count, type, + reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +} + +DELEGATE_TO_GL_1(enable, Enable, unsigned long) + +void WebGraphicsContext3DDefaultImpl::enableVertexAttribArray(unsigned long index) +{ + makeContextCurrent(); + if (index < NumTrackedPointerStates) + m_vertexAttribPointerState[index].enabled = true; + glEnableVertexAttribArray(index); +} + +DELEGATE_TO_GL(finish, Finish) + +DELEGATE_TO_GL(flush, Flush) + +void WebGraphicsContext3DDefaultImpl::framebufferRenderbuffer(unsigned long target, unsigned long attachment, + unsigned long renderbuffertarget, WebGLId buffer) +{ + makeContextCurrent(); + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { + glFramebufferRenderbufferEXT(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, buffer); + glFramebufferRenderbufferEXT(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, buffer); + } else + glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer); +} + +DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT, unsigned long, unsigned long, unsigned long, WebGLId, long) + +DELEGATE_TO_GL_1(frontFace, FrontFace, unsigned long) + +void WebGraphicsContext3DDefaultImpl::generateMipmap(unsigned long target) +{ + makeContextCurrent(); + if (glGenerateMipmapEXT) + glGenerateMipmapEXT(target); + // FIXME: provide alternative code path? This will be unpleasant + // to implement if glGenerateMipmapEXT is not available -- it will + // require a texture readback and re-upload. +} + +bool WebGraphicsContext3DDefaultImpl::getActiveAttrib(WebGLId program, unsigned long index, ActiveInfo& info) +{ + makeContextCurrent(); + if (!program) { + synthesizeGLError(GL_INVALID_VALUE); + return false; + } + GLint maxNameLength = -1; + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); + if (maxNameLength < 0) + return false; + GLchar* name = 0; + if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { + synthesizeGLError(GL_OUT_OF_MEMORY); + return false; + } + GLsizei length = 0; + GLint size = -1; + GLenum type = 0; + glGetActiveAttrib(program, index, maxNameLength, + &length, &size, &type, name); + if (size < 0) { + fastFree(name); + return false; + } + info.name = WebString::fromUTF8(name, length); + info.type = type; + info.size = size; + fastFree(name); + return true; +} + +bool WebGraphicsContext3DDefaultImpl::getActiveUniform(WebGLId program, unsigned long index, ActiveInfo& info) +{ + makeContextCurrent(); + GLint maxNameLength = -1; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); + if (maxNameLength < 0) + return false; + GLchar* name = 0; + if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { + synthesizeGLError(GL_OUT_OF_MEMORY); + return false; + } + GLsizei length = 0; + GLint size = -1; + GLenum type = 0; + glGetActiveUniform(program, index, maxNameLength, + &length, &size, &type, name); + if (size < 0) { + fastFree(name); + return false; + } + info.name = WebString::fromUTF8(name, length); + info.type = type; + info.size = size; + fastFree(name); + return true; +} + +DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, WebGLId, int, int*, unsigned int*) + +DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, WebGLId, const char*, int) + +DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, unsigned long, unsigned char*) + +DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, unsigned long, unsigned long, int*) + +WebGraphicsContext3D::Attributes WebGraphicsContext3DDefaultImpl::getContextAttributes() +{ + return m_attributes; +} + +unsigned long WebGraphicsContext3DDefaultImpl::getError() +{ + if (m_syntheticErrors.size() > 0) { + ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin(); + unsigned long err = *iter; + m_syntheticErrors.remove(iter); + return err; + } + + makeContextCurrent(); + return glGetError(); +} + +DELEGATE_TO_GL_2(getFloatv, GetFloatv, unsigned long, float*) + +void WebGraphicsContext3DDefaultImpl::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, + unsigned long pname, int* value) +{ + makeContextCurrent(); + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) + attachment = GL_DEPTH_ATTACHMENT; // Or GL_STENCIL_ATTACHMENT, either works. + glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); +} + +void WebGraphicsContext3DDefaultImpl::getIntegerv(unsigned long pname, int* value) +{ + // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid + // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most + // useful for desktop WebGL users. + // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS + // because desktop GL's corresponding queries return the number of components + // whereas GLES2 return the number of vectors (each vector has 4 components). + // Therefore, the value returned by desktop GL needs to be divided by 4. + makeContextCurrent(); + switch (pname) { + case 0x8B9B: // IMPLEMENTATION_COLOR_READ_FORMAT + *value = GL_RGB; + break; + case 0x8B9A: // IMPLEMENTATION_COLOR_READ_TYPE + *value = GL_UNSIGNED_BYTE; + break; + case 0x8DFD: // MAX_FRAGMENT_UNIFORM_VECTORS + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); + *value /= 4; + break; + case 0x8DFB: // MAX_VERTEX_UNIFORM_VECTORS + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value); + *value /= 4; + break; + case 0x8DFC: // MAX_VARYING_VECTORS + glGetIntegerv(GL_MAX_VARYING_FLOATS, value); + *value /= 4; + break; + default: + glGetIntegerv(pname, value); + } +} + +DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, unsigned long, int*) + +WebString WebGraphicsContext3DDefaultImpl::getProgramInfoLog(WebGLId program) +{ + makeContextCurrent(); + GLint logLength; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); + if (!logLength) + return WebString(); + GLchar* log = 0; + if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) + return WebString(); + GLsizei returnedLogLength; + glGetProgramInfoLog(program, logLength, &returnedLogLength, log); + ASSERT(logLength == returnedLogLength + 1); + WebString res = WebString::fromUTF8(log, returnedLogLength); + fastFree(log); + return res; +} + +DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameterivEXT, unsigned long, unsigned long, int*) + +DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, unsigned long, int*) + +WebString WebGraphicsContext3DDefaultImpl::getShaderInfoLog(WebGLId shader) +{ + makeContextCurrent(); + GLint logLength; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); + if (!logLength) + return WebString(); + GLchar* log = 0; + if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) + return WebString(); + GLsizei returnedLogLength; + glGetShaderInfoLog(shader, logLength, &returnedLogLength, log); + ASSERT(logLength == returnedLogLength + 1); + WebString res = WebString::fromUTF8(log, returnedLogLength); + fastFree(log); + return res; +} + +WebString WebGraphicsContext3DDefaultImpl::getShaderSource(WebGLId shader) +{ + makeContextCurrent(); + GLint logLength; + glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength); + if (!logLength) + return WebString(); + GLchar* log = 0; + if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) + return WebString(); + GLsizei returnedLogLength; + glGetShaderSource(shader, logLength, &returnedLogLength, log); + ASSERT(logLength == returnedLogLength + 1); + WebString res = WebString::fromUTF8(log, returnedLogLength); + fastFree(log); + return res; +} + +WebString WebGraphicsContext3DDefaultImpl::getString(unsigned long name) +{ + makeContextCurrent(); + return WebString::fromUTF8(reinterpret_cast<const char*>(glGetString(name))); +} + +DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, unsigned long, unsigned long, float*) + +DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, unsigned long, unsigned long, int*) + +DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, long, float*) + +DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, long, int*) + +DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, WebGLId, const char*, long) + +DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, unsigned long, unsigned long, float*) + +DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, unsigned long, unsigned long, int*) + +long WebGraphicsContext3DDefaultImpl::getVertexAttribOffset(unsigned long index, unsigned long pname) +{ + // FIXME: implement. + notImplemented(); + return 0; +} + +DELEGATE_TO_GL_2(hint, Hint, unsigned long, unsigned long) + +DELEGATE_TO_GL_1R(isBuffer, IsBuffer, WebGLId, bool) + +DELEGATE_TO_GL_1R(isEnabled, IsEnabled, unsigned long, bool) + +DELEGATE_TO_GL_1R(isFramebuffer, IsFramebuffer, WebGLId, bool) + +DELEGATE_TO_GL_1R(isProgram, IsProgram, WebGLId, bool) + +DELEGATE_TO_GL_1R(isRenderbuffer, IsRenderbuffer, WebGLId, bool) + +DELEGATE_TO_GL_1R(isShader, IsShader, WebGLId, bool) + +DELEGATE_TO_GL_1R(isTexture, IsTexture, WebGLId, bool) + +DELEGATE_TO_GL_1(lineWidth, LineWidth, double) + +DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) + +DELEGATE_TO_GL_2(pixelStorei, PixelStorei, unsigned long, long) + +DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, double, double) + +void WebGraphicsContext3DDefaultImpl::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels) +{ + makeContextCurrent(); + // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., + // all previous rendering calls should be done before reading pixels. + glFlush(); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { + 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); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + glFlush(); + } +#endif + glReadPixels(x, y, width, height, format, type, pixels); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); +#endif +} + +void WebGraphicsContext3DDefaultImpl::releaseShaderCompiler() +{ +} + +void WebGraphicsContext3DDefaultImpl::renderbufferStorage(unsigned long target, + unsigned long internalformat, + unsigned long width, + unsigned long height) +{ + makeContextCurrent(); + switch (internalformat) { + case GL_DEPTH_STENCIL: + internalformat = GL_DEPTH24_STENCIL8_EXT; + break; + case GL_DEPTH_COMPONENT16: + internalformat = GL_DEPTH_COMPONENT; + break; + case GL_RGBA4: + case GL_RGB5_A1: + internalformat = GL_RGBA; + break; + case 0x8D62: // GL_RGB565 + internalformat = GL_RGB; + break; + } + glRenderbufferStorageEXT(target, internalformat, width, height); +} + +DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, double, bool) + +DELEGATE_TO_GL_4(scissor, Scissor, long, long, unsigned long, unsigned long) + +void WebGraphicsContext3DDefaultImpl::shaderSource(WebGLId shader, const char* string) +{ + makeContextCurrent(); + GLint length = strlen(string); + glShaderSource(shader, 1, &string, &length); +} + +DELEGATE_TO_GL_3(stencilFunc, StencilFunc, unsigned long, long, unsigned long) + +DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) + +DELEGATE_TO_GL_1(stencilMask, StencilMask, unsigned long) + +DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, unsigned long, unsigned long) + +DELEGATE_TO_GL_3(stencilOp, StencilOp, unsigned long, unsigned long, unsigned long) + +DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) + +DELEGATE_TO_GL_9(texImage2D, TexImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, const void*) + +DELEGATE_TO_GL_3(texParameterf, TexParameterf, unsigned, unsigned, float); + +DELEGATE_TO_GL_3(texParameteri, TexParameteri, unsigned, unsigned, int); + +DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, const void*) + +DELEGATE_TO_GL_2(uniform1f, Uniform1f, long, float) + +DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, long, int, float*) + +DELEGATE_TO_GL_2(uniform1i, Uniform1i, long, int) + +DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, long, int, int*) + +DELEGATE_TO_GL_3(uniform2f, Uniform2f, long, float, float) + +DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, long, int, float*) + +DELEGATE_TO_GL_3(uniform2i, Uniform2i, long, int, int) + +DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, long, int, int*) + +DELEGATE_TO_GL_4(uniform3f, Uniform3f, long, float, float, float) + +DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, long, int, float*) + +DELEGATE_TO_GL_4(uniform3i, Uniform3i, long, int, int, int) + +DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, long, int, int*) + +DELEGATE_TO_GL_5(uniform4f, Uniform4f, long, float, float, float, float) + +DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, long, int, float*) + +DELEGATE_TO_GL_5(uniform4i, Uniform4i, long, int, int, int, int) + +DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, long, int, int*) + +DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, long, int, bool, const float*) + +DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, long, int, bool, const float*) + +DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, long, int, bool, const float*) + +DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) + +DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) + +DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, unsigned long, float) + +DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, unsigned long, const float*) + +DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, unsigned long, float, float) + +DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, unsigned long, const float*) + +DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, unsigned long, float, float, float) + +DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, unsigned long, const float*) + +DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, unsigned long, float, float, float, float) + +DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, unsigned long, const float*) + +void WebGraphicsContext3DDefaultImpl::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, + unsigned long stride, unsigned long offset) +{ + makeContextCurrent(); + + if (m_boundArrayBuffer <= 0) { + // FIXME: raise exception. + // LogMessagef(("bufferData: no buffer bound")); + return; + } + + if (indx < NumTrackedPointerStates) { + VertexAttribPointerState& state = m_vertexAttribPointerState[indx]; + state.buffer = m_boundArrayBuffer; + state.indx = indx; + state.size = size; + state.type = type; + state.normalized = normalized; + state.stride = stride; + state.offset = offset; + } + + glVertexAttribPointer(indx, size, type, normalized, stride, + reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +} + +DELEGATE_TO_GL_4(viewport, Viewport, long, long, unsigned long, unsigned long) + +unsigned WebGraphicsContext3DDefaultImpl::createBuffer() +{ + makeContextCurrent(); + GLuint o; + glGenBuffers(1, &o); + return o; +} + +unsigned WebGraphicsContext3DDefaultImpl::createFramebuffer() +{ + makeContextCurrent(); + GLuint o = 0; + glGenFramebuffersEXT(1, &o); + return o; +} + +unsigned WebGraphicsContext3DDefaultImpl::createProgram() +{ + makeContextCurrent(); + return glCreateProgram(); +} + +unsigned WebGraphicsContext3DDefaultImpl::createRenderbuffer() +{ + makeContextCurrent(); + GLuint o; + glGenRenderbuffersEXT(1, &o); + return o; +} + +DELEGATE_TO_GL_1R(createShader, CreateShader, unsigned long, unsigned); + +unsigned WebGraphicsContext3DDefaultImpl::createTexture() +{ + makeContextCurrent(); + GLuint o; + glGenTextures(1, &o); + return o; +} + +void WebGraphicsContext3DDefaultImpl::deleteBuffer(unsigned buffer) +{ + makeContextCurrent(); + glDeleteBuffers(1, &buffer); +} + +void WebGraphicsContext3DDefaultImpl::deleteFramebuffer(unsigned framebuffer) +{ + makeContextCurrent(); + glDeleteFramebuffersEXT(1, &framebuffer); +} + +void WebGraphicsContext3DDefaultImpl::deleteProgram(unsigned program) +{ + makeContextCurrent(); + glDeleteProgram(program); +} + +void WebGraphicsContext3DDefaultImpl::deleteRenderbuffer(unsigned renderbuffer) +{ + makeContextCurrent(); + glDeleteRenderbuffersEXT(1, &renderbuffer); +} + +void WebGraphicsContext3DDefaultImpl::deleteShader(unsigned shader) +{ + makeContextCurrent(); + glDeleteShader(shader); +} + +void WebGraphicsContext3DDefaultImpl::deleteTexture(unsigned texture) +{ + makeContextCurrent(); + glDeleteTextures(1, &texture); +} + +} // namespace WebKit + +#endif // ENABLE(3D_CANVAS) diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h new file mode 100644 index 0000000..e409bf5 --- /dev/null +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h @@ -0,0 +1,429 @@ +/* + * 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 WebGraphicsContext3DDefaultImpl_h +#define WebGraphicsContext3DDefaultImpl_h + +#if ENABLE(3D_CANVAS) + +#include "WebGraphicsContext3D.h" + +#include <wtf/ListHashSet.h> + +#if OS(WINDOWS) +#include <windows.h> +#endif + +#include "GL/glew.h" +#if OS(WINDOWS) +#include "GL/wglew.h" +#endif + +#if PLATFORM(CG) +#include <OpenGL/OpenGL.h> +#else +#define FLIP_FRAMEBUFFER_VERTICALLY +#endif + +#if OS(LINUX) +#include "GL/glxew.h" +#endif + +namespace WebKit { + +// The default implementation of WebGL. In Chromium, using this class +// requires the sandbox to be disabled, which is strongly discouraged. +// It is provided for support of test_shell and any Chromium ports +// where an in-renderer WebGL implementation would be helpful. + +class WebGraphicsContext3DDefaultImpl : public WebGraphicsContext3D { +public: + WebGraphicsContext3DDefaultImpl(); + virtual ~WebGraphicsContext3DDefaultImpl(); + + //---------------------------------------------------------------------- + // WebGraphicsContext3D methods + virtual bool initialize(WebGraphicsContext3D::Attributes attributes, WebView*); + virtual bool makeContextCurrent(); + + virtual int width(); + virtual int height(); + + virtual int sizeInBytes(int type); + + virtual bool isGLES2Compliant(); + + virtual void reshape(int width, int height); + + virtual bool readBackFramebuffer(unsigned char* pixels, size_t bufferSize); + + virtual unsigned int getPlatformTextureId(); + virtual void prepareTexture(); + + virtual void synthesizeGLError(unsigned long error); + + virtual void activeTexture(unsigned long texture); + virtual void attachShader(WebGLId program, WebGLId shader); + virtual void bindAttribLocation(WebGLId program, unsigned long index, const char* name); + virtual void bindBuffer(unsigned long target, WebGLId buffer); + virtual void bindFramebuffer(unsigned long target, WebGLId framebuffer); + virtual void bindRenderbuffer(unsigned long target, WebGLId renderbuffer); + virtual void bindTexture(unsigned long target, WebGLId texture); + virtual void blendColor(double red, double green, double blue, double alpha); + virtual void blendEquation(unsigned long mode); + virtual void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha); + virtual void blendFunc(unsigned long sfactor, unsigned long dfactor); + virtual void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha); + + virtual void bufferData(unsigned long target, int size, const void* data, unsigned long usage); + virtual void bufferSubData(unsigned long target, long offset, int size, const void* data); + + virtual unsigned long checkFramebufferStatus(unsigned long target); + virtual void clear(unsigned long mask); + virtual void clearColor(double red, double green, double blue, double alpha); + virtual void clearDepth(double depth); + virtual void clearStencil(long s); + virtual void colorMask(bool red, bool green, bool blue, bool alpha); + virtual void compileShader(WebGLId shader); + + virtual void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border); + virtual void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height); + virtual void cullFace(unsigned long mode); + virtual void depthFunc(unsigned long func); + virtual void depthMask(bool flag); + virtual void depthRange(double zNear, double zFar); + virtual void detachShader(WebGLId program, WebGLId shader); + virtual void disable(unsigned long cap); + virtual void disableVertexAttribArray(unsigned long index); + virtual void drawArrays(unsigned long mode, long first, long count); + virtual void drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset); + + virtual void enable(unsigned long cap); + virtual void enableVertexAttribArray(unsigned long index); + virtual void finish(); + virtual void flush(); + virtual void framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLId renderbuffer); + virtual void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLId texture, long level); + virtual void frontFace(unsigned long mode); + virtual void generateMipmap(unsigned long target); + + virtual bool getActiveAttrib(WebGLId program, unsigned long index, ActiveInfo&); + virtual bool getActiveUniform(WebGLId program, unsigned long index, ActiveInfo&); + + virtual void getAttachedShaders(WebGLId program, int maxCount, int* count, unsigned int* shaders); + + virtual int getAttribLocation(WebGLId program, const char* name); + + virtual void getBooleanv(unsigned long pname, unsigned char* value); + + virtual void getBufferParameteriv(unsigned long target, unsigned long pname, int* value); + + virtual Attributes getContextAttributes(); + + virtual unsigned long getError(); + + virtual void getFloatv(unsigned long pname, float* value); + + virtual void getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value); + + virtual void getIntegerv(unsigned long pname, int* value); + + virtual void getProgramiv(WebGLId program, unsigned long pname, int* value); + + virtual WebString getProgramInfoLog(WebGLId program); + + virtual void getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value); + + virtual void getShaderiv(WebGLId shader, unsigned long pname, int* value); + + virtual WebString getShaderInfoLog(WebGLId shader); + + // TBD + // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); + + virtual WebString getShaderSource(WebGLId shader); + virtual WebString getString(unsigned long name); + + virtual void getTexParameterfv(unsigned long target, unsigned long pname, float* value); + virtual void getTexParameteriv(unsigned long target, unsigned long pname, int* value); + + virtual void getUniformfv(WebGLId program, long location, float* value); + virtual void getUniformiv(WebGLId program, long location, int* value); + + virtual long getUniformLocation(WebGLId program, const char* name); + + virtual void getVertexAttribfv(unsigned long index, unsigned long pname, float* value); + virtual void getVertexAttribiv(unsigned long index, unsigned long pname, int* value); + + virtual long getVertexAttribOffset(unsigned long index, unsigned long pname); + + virtual void hint(unsigned long target, unsigned long mode); + virtual bool isBuffer(WebGLId buffer); + virtual bool isEnabled(unsigned long cap); + virtual bool isFramebuffer(WebGLId framebuffer); + virtual bool isProgram(WebGLId program); + virtual bool isRenderbuffer(WebGLId renderbuffer); + virtual bool isShader(WebGLId shader); + virtual bool isTexture(WebGLId texture); + virtual void lineWidth(double); + virtual void linkProgram(WebGLId program); + virtual void pixelStorei(unsigned long pname, long param); + virtual void polygonOffset(double factor, double units); + + virtual void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels); + + virtual void releaseShaderCompiler(); + virtual void renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height); + virtual void sampleCoverage(double value, bool invert); + virtual void scissor(long x, long y, unsigned long width, unsigned long height); + virtual void shaderSource(WebGLId shader, const char* string); + virtual void stencilFunc(unsigned long func, long ref, unsigned long mask); + virtual void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask); + virtual void stencilMask(unsigned long mask); + virtual void stencilMaskSeparate(unsigned long face, unsigned long mask); + virtual void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass); + virtual void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass); + + virtual void texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, const void* pixels); + + virtual void texParameterf(unsigned target, unsigned pname, float param); + virtual void texParameteri(unsigned target, unsigned pname, int param); + + virtual void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, const void* pixels); + + virtual void uniform1f(long location, float x); + virtual void uniform1fv(long location, int count, float* v); + virtual void uniform1i(long location, int x); + virtual void uniform1iv(long location, int count, int* v); + virtual void uniform2f(long location, float x, float y); + virtual void uniform2fv(long location, int count, float* v); + virtual void uniform2i(long location, int x, int y); + virtual void uniform2iv(long location, int count, int* v); + virtual void uniform3f(long location, float x, float y, float z); + virtual void uniform3fv(long location, int count, float* v); + virtual void uniform3i(long location, int x, int y, int z); + virtual void uniform3iv(long location, int count, int* v); + virtual void uniform4f(long location, float x, float y, float z, float w); + virtual void uniform4fv(long location, int count, float* v); + virtual void uniform4i(long location, int x, int y, int z, int w); + virtual void uniform4iv(long location, int count, int* v); + virtual void uniformMatrix2fv(long location, int count, bool transpose, const float* value); + virtual void uniformMatrix3fv(long location, int count, bool transpose, const float* value); + virtual void uniformMatrix4fv(long location, int count, bool transpose, const float* value); + + virtual void useProgram(WebGLId program); + virtual void validateProgram(WebGLId program); + + virtual void vertexAttrib1f(unsigned long indx, float x); + virtual void vertexAttrib1fv(unsigned long indx, const float* values); + virtual void vertexAttrib2f(unsigned long indx, float x, float y); + virtual void vertexAttrib2fv(unsigned long indx, const float* values); + virtual void vertexAttrib3f(unsigned long indx, float x, float y, float z); + virtual void vertexAttrib3fv(unsigned long indx, const float* values); + virtual void vertexAttrib4f(unsigned long indx, float x, float y, float z, float w); + virtual void vertexAttrib4fv(unsigned long indx, const float* values); + virtual void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, + unsigned long stride, unsigned long offset); + + virtual void viewport(long x, long y, unsigned long width, unsigned long height); + + // Support for buffer creation and deletion + virtual unsigned createBuffer(); + virtual unsigned createFramebuffer(); + virtual unsigned createProgram(); + virtual unsigned createRenderbuffer(); + virtual unsigned createShader(unsigned long); + virtual unsigned createTexture(); + + virtual void deleteBuffer(unsigned); + virtual void deleteFramebuffer(unsigned); + virtual void deleteProgram(unsigned); + virtual void deleteRenderbuffer(unsigned); + virtual void deleteShader(unsigned); + virtual void deleteTexture(unsigned); + +private: + WebGraphicsContext3D::Attributes m_attributes; + bool m_initialized; + unsigned int m_texture; + unsigned int m_fbo; + unsigned int m_depthStencilBuffer; + unsigned int m_cachedWidth, m_cachedHeight; + + // For multisampling + unsigned int m_multisampleFBO; + unsigned int m_multisampleDepthStencilBuffer; + unsigned int m_multisampleColorBuffer; + + // For tracking which FBO is bound + unsigned int m_boundFBO; + +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + unsigned char* m_scanline; + void flipVertically(unsigned char* framebuffer, + unsigned int width, + unsigned int height); +#endif + + // Take into account the user's requested context creation attributes, in + // particular stencil and antialias, and determine which could or could + // not be honored based on the capabilities of the OpenGL implementation. + void validateAttributes(); + + // Note: we aren't currently using this information, but we will + // need to in order to verify that all enabled vertex arrays have + // a valid buffer bound -- to avoid crashes on certain cards. + unsigned int m_boundArrayBuffer; + class VertexAttribPointerState { + public: + VertexAttribPointerState(); + + bool enabled; + unsigned long buffer; + unsigned long indx; + int size; + int type; + bool normalized; + unsigned long stride; + unsigned long offset; + }; + + enum { + NumTrackedPointerStates = 2 + }; + VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates]; + + // Errors raised by synthesizeGLError(). + ListHashSet<unsigned long> m_syntheticErrors; + + static bool s_initializedGLEW; +#if OS(WINDOWS) + HWND m_canvasWindow; + HDC m_canvasDC; + HGLRC m_contextObj; +#elif PLATFORM(CG) + CGLPBufferObj m_pbuffer; + CGLContextObj m_contextObj; + unsigned char* m_renderOutput; +#elif OS(LINUX) + GLXContext m_contextObj; + GLXPbuffer m_pbuffer; + + // In order to avoid problems caused by linking against libGL, we + // dynamically look up all the symbols we need. + // http://code.google.com/p/chromium/issues/detail?id=16800 + class GLConnection { + public: + ~GLConnection(); + + static GLConnection* create(); + + GLXFBConfig* chooseFBConfig(int screen, const int *attrib_list, int *nelements) + { + return m_glXChooseFBConfig(m_display, screen, attrib_list, nelements); + } + + GLXContext createNewContext(GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) + { + return m_glXCreateNewContext(m_display, config, renderType, shareList, direct); + } + + GLXPbuffer createPbuffer(GLXFBConfig config, const int *attribList) + { + return m_glXCreatePbuffer(m_display, config, attribList); + } + + void destroyPbuffer(GLXPbuffer pbuf) + { + m_glXDestroyPbuffer(m_display, pbuf); + } + + Bool makeCurrent(GLXDrawable drawable, GLXContext ctx) + { + return m_glXMakeCurrent(m_display, drawable, ctx); + } + + void destroyContext(GLXContext ctx) + { + m_glXDestroyContext(m_display, ctx); + } + + GLXContext getCurrentContext() + { + return m_glXGetCurrentContext(); + } + + private: + Display* m_display; + void* m_libGL; + PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig; + PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext; + PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer; + PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer; + typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx); + PFNGLXMAKECURRENTPROC m_glXMakeCurrent; + typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx); + PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext; + typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void); + PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext; + + GLConnection(Display* display, + void* libGL, + PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig, + PFNGLXCREATENEWCONTEXTPROC createNewContext, + PFNGLXCREATEPBUFFERPROC createPbuffer, + PFNGLXDESTROYPBUFFERPROC destroyPbuffer, + PFNGLXMAKECURRENTPROC makeCurrent, + PFNGLXDESTROYCONTEXTPROC destroyContext, + PFNGLXGETCURRENTCONTEXTPROC getCurrentContext) + : m_libGL(libGL) + , m_display(display) + , m_glXChooseFBConfig(chooseFBConfig) + , m_glXCreateNewContext(createNewContext) + , m_glXCreatePbuffer(createPbuffer) + , m_glXDestroyPbuffer(destroyPbuffer) + , m_glXMakeCurrent(makeCurrent) + , m_glXDestroyContext(destroyContext) + , m_glXGetCurrentContext(getCurrentContext) + { + } + }; + + static GLConnection* s_gl; +#else + #error Must port WebGraphicsContext3DDefaultImpl to your platform +#endif +}; + +} // namespace WebKit + +#endif // ENABLE(3D_CANVAS) + +#endif diff --git a/WebKit/chromium/src/WebHTTPBody.cpp b/WebKit/chromium/src/WebHTTPBody.cpp index 3d40869..d062576 100644 --- a/WebKit/chromium/src/WebHTTPBody.cpp +++ b/WebKit/chromium/src/WebHTTPBody.cpp @@ -79,17 +79,25 @@ bool WebHTTPBody::elementAt(size_t index, Element& result) const result.type = Element::TypeData; result.data.assign(element.m_data.data(), element.m_data.size()); result.filePath.reset(); +#if ENABLE(BLOB_SLICE) result.fileStart = 0; result.fileLength = 0; result.fileInfo.modificationTime = 0.0; +#endif break; case FormDataElement::encodedFile: result.type = Element::TypeFile; result.data.reset(); result.filePath = element.m_filename; - result.fileStart = 0; // FIXME: to be set from FormData. - result.fileLength = -1; // FIXME: to be set from FormData. - result.fileInfo.modificationTime = 0.0; // FIXME: to be set from FormData. +#if ENABLE(BLOB_SLICE) + result.fileStart = element.m_fileStart; + result.fileLength = element.m_fileLength; + result.fileInfo.modificationTime = element.m_expectedFileModificationTime; +#else + result.fileStart = 0; + result.fileLength = -1; + result.fileInfo.modificationTime = 0.0; +#endif break; default: ASSERT_NOT_REACHED(); @@ -113,9 +121,12 @@ void WebHTTPBody::appendFile(const WebString& filePath) m_private->appendFile(filePath); } -void WebHTTPBody::appendFile(const WebString& filePath, long long fileStart, long long fileLength, const WebFileInfo& fileInfo) +void WebHTTPBody::appendFileRange(const WebString& filePath, long long fileStart, long long fileLength, const WebFileInfo& fileInfo) { - // FIXME: to be implemented. +#if ENABLE(BLOB_SLICE) + ensureMutable(); + m_private->appendFileRange(filePath, fileStart, fileLength, fileInfo.modificationTime); +#endif } long long WebHTTPBody::identifier() const diff --git a/WebKit/chromium/src/WebHistoryItem.cpp b/WebKit/chromium/src/WebHistoryItem.cpp index 4ca8cc7..99ebce8 100644 --- a/WebKit/chromium/src/WebHistoryItem.cpp +++ b/WebKit/chromium/src/WebHistoryItem.cpp @@ -37,6 +37,7 @@ #include "WebHTTPBody.h" #include "WebPoint.h" +#include "WebSerializedScriptValue.h" #include "WebString.h" #include "WebVector.h" @@ -44,30 +45,23 @@ using namespace WebCore; namespace WebKit { -class WebHistoryItemPrivate : public HistoryItem { -}; - void WebHistoryItem::initialize() { - assign(static_cast<WebHistoryItemPrivate*>(HistoryItem::create().releaseRef())); + m_private = HistoryItem::create(); } void WebHistoryItem::reset() { - assign(0); + m_private.reset(); } void WebHistoryItem::assign(const WebHistoryItem& other) { - WebHistoryItemPrivate* p = const_cast<WebHistoryItemPrivate*>(other.m_private); - if (p) - p->ref(); - assign(p); + m_private = other.m_private; } WebString WebHistoryItem::urlString() const { - ASSERT(!isNull()); return m_private->urlString(); } @@ -79,7 +73,6 @@ void WebHistoryItem::setURLString(const WebString& url) WebString WebHistoryItem::originalURLString() const { - ASSERT(!isNull()); return m_private->originalURLString(); } @@ -91,7 +84,6 @@ void WebHistoryItem::setOriginalURLString(const WebString& originalURLString) WebString WebHistoryItem::referrer() const { - ASSERT(!isNull()); return m_private->referrer(); } @@ -103,7 +95,6 @@ void WebHistoryItem::setReferrer(const WebString& referrer) WebString WebHistoryItem::target() const { - ASSERT(!isNull()); return m_private->target(); } @@ -115,7 +106,6 @@ void WebHistoryItem::setTarget(const WebString& target) WebString WebHistoryItem::parent() const { - ASSERT(!isNull()); return m_private->parent(); } @@ -127,7 +117,6 @@ void WebHistoryItem::setParent(const WebString& parent) WebString WebHistoryItem::title() const { - ASSERT(!isNull()); return m_private->title(); } @@ -139,7 +128,6 @@ void WebHistoryItem::setTitle(const WebString& title) WebString WebHistoryItem::alternateTitle() const { - ASSERT(!isNull()); return m_private->alternateTitle(); } @@ -151,7 +139,6 @@ void WebHistoryItem::setAlternateTitle(const WebString& alternateTitle) double WebHistoryItem::lastVisitedTime() const { - ASSERT(!isNull()); return m_private->lastVisitedTime(); } @@ -168,7 +155,6 @@ void WebHistoryItem::setLastVisitedTime(double lastVisitedTime) WebPoint WebHistoryItem::scrollOffset() const { - ASSERT(!isNull()); return m_private->scrollPoint(); } @@ -180,7 +166,6 @@ void WebHistoryItem::setScrollOffset(const WebPoint& scrollOffset) bool WebHistoryItem::isTargetItem() const { - ASSERT(!isNull()); return m_private->isTargetItem(); } @@ -192,7 +177,6 @@ void WebHistoryItem::setIsTargetItem(bool isTargetItem) int WebHistoryItem::visitCount() const { - ASSERT(!isNull()); return m_private->visitCount(); } @@ -204,7 +188,6 @@ void WebHistoryItem::setVisitCount(int count) WebVector<WebString> WebHistoryItem::documentState() const { - ASSERT(!isNull()); return m_private->documentState(); } @@ -218,9 +201,19 @@ void WebHistoryItem::setDocumentState(const WebVector<WebString>& state) m_private->setDocumentState(ds); } +long long WebHistoryItem::itemSequenceNumber() const +{ + return m_private->itemSequenceNumber(); +} + +void WebHistoryItem::setItemSequenceNumber(long long itemSequenceNumber) +{ + ensureMutable(); + m_private->setItemSequenceNumber(itemSequenceNumber); +} + long long WebHistoryItem::documentSequenceNumber() const { - ASSERT(!isNull()); return m_private->documentSequenceNumber(); } @@ -230,9 +223,19 @@ void WebHistoryItem::setDocumentSequenceNumber(long long documentSequenceNumber) m_private->setDocumentSequenceNumber(documentSequenceNumber); } +WebSerializedScriptValue WebHistoryItem::stateObject() const +{ + return WebSerializedScriptValue(m_private->stateObject()); +} + +void WebHistoryItem::setStateObject(const WebSerializedScriptValue& object) +{ + ensureMutable(); + m_private->setStateObject(object); +} + WebString WebHistoryItem::httpContentType() const { - ASSERT(!isNull()); return m_private->formContentType(); } @@ -244,7 +247,6 @@ void WebHistoryItem::setHTTPContentType(const WebString& httpContentType) WebHTTPBody WebHistoryItem::httpBody() const { - ASSERT(!isNull()); return WebHTTPBody(m_private->formData()); } @@ -256,7 +258,6 @@ void WebHistoryItem::setHTTPBody(const WebHTTPBody& httpBody) WebVector<WebHistoryItem> WebHistoryItem::children() const { - ASSERT(!isNull()); return m_private->children(); } @@ -275,34 +276,25 @@ void WebHistoryItem::appendToChildren(const WebHistoryItem& item) } WebHistoryItem::WebHistoryItem(const PassRefPtr<HistoryItem>& item) - : m_private(static_cast<WebHistoryItemPrivate*>(item.releaseRef())) + : m_private(item) { } WebHistoryItem& WebHistoryItem::operator=(const PassRefPtr<HistoryItem>& item) { - assign(static_cast<WebHistoryItemPrivate*>(item.releaseRef())); + m_private = item; return *this; } WebHistoryItem::operator PassRefPtr<HistoryItem>() const { - return m_private; -} - -void WebHistoryItem::assign(WebHistoryItemPrivate* p) -{ - // p is already ref'd for us by the caller - if (m_private) - m_private->deref(); - m_private = p; + return m_private.get(); } void WebHistoryItem::ensureMutable() { - ASSERT(!isNull()); if (!m_private->hasOneRef()) - assign(static_cast<WebHistoryItemPrivate*>(m_private->copy().releaseRef())); + m_private = m_private->copy(); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebIDBCallbacksImpl.cpp b/WebKit/chromium/src/WebIDBCallbacksImpl.cpp new file mode 100644 index 0000000..21c9eed --- /dev/null +++ b/WebKit/chromium/src/WebIDBCallbacksImpl.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebIDBCallbacksImpl.h" + +#include "IDBCallbacks.h" +#include "IDBDatabaseError.h" +#include "IDBDatabaseProxy.h" +#include "IDBIndexProxy.h" +#include "IDBKey.h" +#include "IDBObjectStoreProxy.h" +#include "WebIDBCallbacks.h" +#include "WebIDBDatabase.h" +#include "WebIDBDatabaseError.h" +#include "WebIDBIndex.h" +#include "WebIDBKey.h" +#include "WebIDBObjectStore.h" +#include "WebSerializedScriptValue.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +WebIDBCallbacksImpl::WebIDBCallbacksImpl(PassRefPtr<IDBCallbacks> callbacks) + : m_callbacks(callbacks) +{ +} + +WebIDBCallbacksImpl::~WebIDBCallbacksImpl() +{ +} + +void WebIDBCallbacksImpl::onError(const WebKit::WebIDBDatabaseError& error) +{ + m_callbacks->onError(error); + m_callbacks.clear(); +} + +void WebIDBCallbacksImpl::onSuccess() +{ + m_callbacks->onSuccess(); + m_callbacks.clear(); +} + +void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBDatabase* webKitInstance) +{ + m_callbacks->onSuccess(IDBDatabaseProxy::create(webKitInstance)); + m_callbacks.clear(); +} + +void WebIDBCallbacksImpl::onSuccess(const WebKit::WebIDBKey& key) +{ + m_callbacks->onSuccess(key); + m_callbacks.clear(); +} + +void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBIndex* webKitInstance) +{ + m_callbacks->onSuccess(IDBIndexProxy::create(webKitInstance)); + m_callbacks.clear(); +} + +void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBObjectStore* webKitInstance) +{ + m_callbacks->onSuccess(IDBObjectStoreProxy::create(webKitInstance)); + m_callbacks.clear(); +} + +void WebIDBCallbacksImpl::onSuccess(const WebKit::WebSerializedScriptValue& serializedScriptValue) +{ + m_callbacks->onSuccess(serializedScriptValue); + m_callbacks.clear(); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebIDBCallbacksImpl.h b/WebKit/chromium/src/WebIDBCallbacksImpl.h new file mode 100644 index 0000000..a4d53b5 --- /dev/null +++ b/WebKit/chromium/src/WebIDBCallbacksImpl.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebIDBCallbacksImpl_h +#define WebIDBCallbacksImpl_h + +#include "WebIDBCallbacks.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +class IDBCallbacks; + +class WebIDBCallbacksImpl : public WebKit::WebIDBCallbacks { +public: + WebIDBCallbacksImpl(PassRefPtr<IDBCallbacks>); + virtual ~WebIDBCallbacksImpl(); + + virtual void onError(const WebKit::WebIDBDatabaseError&); + virtual void onSuccess(); // For "null". + virtual void onSuccess(WebKit::WebIDBDatabase*); + virtual void onSuccess(const WebKit::WebIDBKey&); + virtual void onSuccess(WebKit::WebIDBIndex*); + virtual void onSuccess(WebKit::WebIDBObjectStore*); + virtual void onSuccess(const WebKit::WebSerializedScriptValue&); + +private: + RefPtr<IDBCallbacks> m_callbacks; +}; + +} // namespace WebCore + +#endif + +#endif // WebIDBCallbacksImpl_h diff --git a/WebKit/chromium/src/WebIDBDatabaseError.cpp b/WebKit/chromium/src/WebIDBDatabaseError.cpp new file mode 100644 index 0000000..cbbe14a --- /dev/null +++ b/WebKit/chromium/src/WebIDBDatabaseError.cpp @@ -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. + */ + +#include "config.h" +#include "WebIDBDatabaseError.h" + +#include "IDBDatabaseError.h" +#include "WebString.h" + +#if ENABLE(INDEXED_DATABASE) + +using namespace WebCore; + +namespace WebKit { + +void WebIDBDatabaseError::assign(const WebIDBDatabaseError& value) +{ + m_private = value.m_private; +} + +void WebIDBDatabaseError::assign(unsigned short code, const WebString& message) +{ + m_private = IDBDatabaseError::create(code, message); +} + +void WebIDBDatabaseError::reset() +{ + m_private.reset(); +} + +unsigned short WebIDBDatabaseError::code() const +{ + return m_private->code(); +} + +WebString WebIDBDatabaseError::message() const +{ + return m_private->message(); +} + +WebIDBDatabaseError::WebIDBDatabaseError(const PassRefPtr<IDBDatabaseError>& value) + : m_private(value) +{ +} + +WebIDBDatabaseError& WebIDBDatabaseError::operator=(const PassRefPtr<IDBDatabaseError>& value) +{ + m_private = value; + return *this; +} + +WebIDBDatabaseError::operator PassRefPtr<IDBDatabaseError>() const +{ + return m_private.get(); +} + +} // namespace WebKit + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebIDBDatabaseImpl.cpp b/WebKit/chromium/src/WebIDBDatabaseImpl.cpp new file mode 100644 index 0000000..e2f771a --- /dev/null +++ b/WebKit/chromium/src/WebIDBDatabaseImpl.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebIDBDatabaseImpl.h" + +#include "DOMStringList.h" +#include "IDBCallbacksProxy.h" +#include "IDBDatabase.h" +#include "WebIDBCallbacks.h" +#include "WebIDBObjectStoreImpl.h" + +#if ENABLE(INDEXED_DATABASE) + +using namespace WebCore; + +namespace WebKit { + +WebIDBDatabaseImpl::WebIDBDatabaseImpl(PassRefPtr<IDBDatabase> database) + : m_database(database) +{ +} + +WebIDBDatabaseImpl::~WebIDBDatabaseImpl() +{ +} + +WebString WebIDBDatabaseImpl::name() const +{ + return m_database->name(); +} + +WebString WebIDBDatabaseImpl::description() const +{ + return m_database->description(); +} + +WebString WebIDBDatabaseImpl::version() const +{ + return m_database->version(); +} + +WebDOMStringList WebIDBDatabaseImpl::objectStores() const +{ + return m_database->objectStores(); +} + +void WebIDBDatabaseImpl::createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, WebIDBCallbacks* callbacks) +{ + m_database->createObjectStore(name, keyPath, autoIncrement, IDBCallbacksProxy::create(callbacks)); +} + +WebIDBObjectStore* WebIDBDatabaseImpl::objectStore(const WebString& name, unsigned short mode) +{ + RefPtr<IDBObjectStore> objectStore = m_database->objectStore(name, mode); + if (!objectStore) + return 0; + return new WebIDBObjectStoreImpl(objectStore); +} + +void WebIDBDatabaseImpl::removeObjectStore(const WebString& name, WebIDBCallbacks* callbacks) +{ + m_database->removeObjectStore(name, IDBCallbacksProxy::create(callbacks)); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebIDBDatabaseImpl.h b/WebKit/chromium/src/WebIDBDatabaseImpl.h new file mode 100644 index 0000000..c83d8d7 --- /dev/null +++ b/WebKit/chromium/src/WebIDBDatabaseImpl.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebIDBDatabaseImpl_h +#define WebIDBDatabaseImpl_h + +#include "WebCommon.h" +#include "WebIDBDatabase.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { class IDBDatabase; } + +namespace WebKit { + +class WebIDBObjectStore; + +// See comment in WebIndexedDatabase for a high level overview these classes. +class WebIDBDatabaseImpl : public WebIDBDatabase { +public: + WebIDBDatabaseImpl(WTF::PassRefPtr<WebCore::IDBDatabase> database); + virtual ~WebIDBDatabaseImpl(); + + virtual WebString name() const; + virtual WebString description() const; + virtual WebString version() const; + virtual WebDOMStringList objectStores() const; + + virtual void createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, WebIDBCallbacks* callbacks); + virtual WebIDBObjectStore* objectStore(const WebString& name, unsigned short mode); + virtual void removeObjectStore(const WebString& name, WebIDBCallbacks* callbacks); + +private: + WTF::RefPtr<WebCore::IDBDatabase> m_database; +}; + +} // namespace WebKit + +#endif // WebIDBDatabaseImpl_h diff --git a/WebKit/chromium/src/WebIDBIndexImpl.cpp b/WebKit/chromium/src/WebIDBIndexImpl.cpp new file mode 100644 index 0000000..304217c --- /dev/null +++ b/WebKit/chromium/src/WebIDBIndexImpl.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebIDBIndexImpl.h" + +#include "IDBIndex.h" + +#if ENABLE(INDEXED_DATABASE) + +using namespace WebCore; + +namespace WebKit { + +WebIDBIndexImpl::WebIDBIndexImpl(PassRefPtr<IDBIndex> idbIndex) + : m_idbIndex(idbIndex) +{ +} + +WebIDBIndexImpl::~WebIDBIndexImpl() +{ +} + +WebString WebIDBIndexImpl::name() const +{ + return m_idbIndex->name(); +} + +WebString WebIDBIndexImpl::keyPath() const +{ + return m_idbIndex->keyPath(); +} + +bool WebIDBIndexImpl::unique() const +{ + return m_idbIndex->unique(); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebIDBIndexImpl.h b/WebKit/chromium/src/WebIDBIndexImpl.h new file mode 100644 index 0000000..e1f0538 --- /dev/null +++ b/WebKit/chromium/src/WebIDBIndexImpl.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebIDBIndexImpl_h +#define WebIDBIndexImpl_h + +#include "WebCommon.h" +#include "WebIDBIndex.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { class IDBIndex; } + +namespace WebKit { + +// See comment in WebIndexedDatabase for a high level overview these classes. +class WebIDBIndexImpl : public WebIDBIndex { +public: + WebIDBIndexImpl(WTF::PassRefPtr<WebCore::IDBIndex> idbIndex); + virtual ~WebIDBIndexImpl(); + + virtual WebString name() const; + virtual WebString keyPath() const; + virtual bool unique() const; + +private: + WTF::RefPtr<WebCore::IDBIndex> m_idbIndex; +}; + +} // namespace WebKit + +#endif // WebIDBIndexImpl_h diff --git a/WebKit/chromium/src/WebIDBKey.cpp b/WebKit/chromium/src/WebIDBKey.cpp new file mode 100644 index 0000000..1c4c685 --- /dev/null +++ b/WebKit/chromium/src/WebIDBKey.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebIDBKey.h" + +#if ENABLE(INDEXED_DATABASE) + +#include "IDBKey.h" + +using namespace WebCore; + +namespace WebKit { + +WebIDBKey WebIDBKey::createNull() +{ + WebIDBKey key; + key.assignNull(); + return key; +} + +WebIDBKey WebIDBKey::createInvalid() +{ + WebIDBKey key; + key.assignInvalid(); + return key; +} + +void WebIDBKey::assign(const WebIDBKey& value) +{ + m_private = value.m_private; +} + +void WebIDBKey::assignNull() +{ + m_private = IDBKey::create(); +} + +void WebIDBKey::assign(const WebString& string) +{ + m_private = IDBKey::create(string); +} + +void WebIDBKey::assign(int32_t number) +{ + m_private = IDBKey::create(number); +} + +void WebIDBKey::assignInvalid() +{ + m_private = 0; +} + +void WebIDBKey::reset() +{ + m_private.reset(); +} + +WebIDBKey::Type WebIDBKey::type() const +{ + if (!m_private.get()) + return InvalidType; + return Type(m_private->type()); +} + +WebString WebIDBKey::string() const +{ + return m_private->string(); +} + +int32_t WebIDBKey::number() const +{ + return m_private->number(); +} + +WebIDBKey::WebIDBKey(const PassRefPtr<IDBKey>& value) + : m_private(value) +{ +} + +WebIDBKey& WebIDBKey::operator=(const PassRefPtr<IDBKey>& value) +{ + m_private = value; + return *this; +} + +WebIDBKey::operator PassRefPtr<IDBKey>() const +{ + return m_private.get(); +} + +} // namespace WebKit + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp b/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp new file mode 100755 index 0000000..d8e98db --- /dev/null +++ b/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebIDBObjectStoreImpl.h" + +#include "DOMStringList.h" +#include "IDBCallbacksProxy.h" +#include "IDBObjectStore.h" +#include "WebIDBIndexImpl.h" +#include "WebIDBKey.h" +#include "WebSerializedScriptValue.h" + +#if ENABLE(INDEXED_DATABASE) + +using namespace WebCore; + +namespace WebKit { + +WebIDBObjectStoreImpl::WebIDBObjectStoreImpl(PassRefPtr<IDBObjectStore> objectStore) + : m_objectStore(objectStore) +{ +} + +WebIDBObjectStoreImpl::~WebIDBObjectStoreImpl() +{ +} + +WebString WebIDBObjectStoreImpl::name() const +{ + return m_objectStore->name(); +} + +WebString WebIDBObjectStoreImpl::keyPath() const +{ + return m_objectStore->keyPath(); +} + +WebDOMStringList WebIDBObjectStoreImpl::indexNames() const +{ + return m_objectStore->indexNames(); +} + +void WebIDBObjectStoreImpl::get(const WebIDBKey& key, WebIDBCallbacks* callbacks) +{ + m_objectStore->get(key, IDBCallbacksProxy::create(callbacks)); +} + +void WebIDBObjectStoreImpl::put(const WebSerializedScriptValue& value, const WebIDBKey& key, bool addOnly, WebIDBCallbacks* callbacks) +{ + m_objectStore->put(value, key, addOnly, IDBCallbacksProxy::create(callbacks)); +} + +void WebIDBObjectStoreImpl::remove(const WebIDBKey& key, WebIDBCallbacks* callbacks) +{ + m_objectStore->remove(key, IDBCallbacksProxy::create(callbacks)); +} + +void WebIDBObjectStoreImpl::createIndex(const WebString& name, const WebString& keyPath, bool unique, WebIDBCallbacks* callbacks) +{ + m_objectStore->createIndex(name, keyPath, unique, IDBCallbacksProxy::create(callbacks)); +} + +WebIDBIndex* WebIDBObjectStoreImpl::index(const WebString& name) +{ + RefPtr<IDBIndex> index = m_objectStore->index(name); + if (!index) + return 0; + return new WebIDBIndexImpl(index); +} + +void WebIDBObjectStoreImpl::removeIndex(const WebString& name, WebIDBCallbacks* callbacks) +{ + m_objectStore->removeIndex(name, IDBCallbacksProxy::create(callbacks)); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebIDBObjectStoreImpl.h b/WebKit/chromium/src/WebIDBObjectStoreImpl.h new file mode 100755 index 0000000..4064b7f --- /dev/null +++ b/WebKit/chromium/src/WebIDBObjectStoreImpl.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebIDBObjectStoreImpl_h +#define WebIDBObjectStoreImpl_h + +#include "WebCommon.h" +#include "WebIDBObjectStore.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { class IDBObjectStore; } + +namespace WebKit { + +class WebIDBIndex; + +// See comment in WebIndexedObjectStore for a high level overview these classes. +class WebIDBObjectStoreImpl : public WebIDBObjectStore { +public: + WebIDBObjectStoreImpl(WTF::PassRefPtr<WebCore::IDBObjectStore> objectStore); + ~WebIDBObjectStoreImpl(); + + WebString name() const; + WebString keyPath() const; + WebDOMStringList indexNames() const; + + void get(const WebIDBKey& key, WebIDBCallbacks*); + void put(const WebSerializedScriptValue& value, const WebIDBKey& key, bool addOnly, WebIDBCallbacks*); + void remove(const WebIDBKey& key, WebIDBCallbacks*); + + void createIndex(const WebString& name, const WebString& keyPath, bool unique, WebIDBCallbacks* callbacks); + WebIDBIndex* index(const WebString& name); + void removeIndex(const WebString& name, WebIDBCallbacks* callbacks); + + private: + WTF::RefPtr<WebCore::IDBObjectStore> m_objectStore; +}; + +} // namespace WebKit + +#endif // WebIDBObjectStoreImpl_h diff --git a/WebKit/chromium/src/WebImageCG.cpp b/WebKit/chromium/src/WebImageCG.cpp index 60b2449..045c8be 100644 --- a/WebKit/chromium/src/WebImageCG.cpp +++ b/WebKit/chromium/src/WebImageCG.cpp @@ -89,14 +89,16 @@ WebSize WebImage::size() const WebImage::WebImage(const PassRefPtr<Image>& image) : m_imageRef(0) { - if (image.get()) - assign(image->nativeImageForCurrentFrame()); + NativeImagePtr p; + if (image.get() && (p = image->nativeImageForCurrentFrame())) + assign(p); } WebImage& WebImage::operator=(const PassRefPtr<Image>& image) { - if (image.get()) - assign(image->nativeImageForCurrentFrame()); + NativeImagePtr p; + if (image.get() && (p = image->nativeImageForCurrentFrame())) + assign(p); else reset(); return *this; diff --git a/WebKit/chromium/src/WebImageDecoder.cpp b/WebKit/chromium/src/WebImageDecoder.cpp new file mode 100644 index 0000000..9e1d1f4 --- /dev/null +++ b/WebKit/chromium/src/WebImageDecoder.cpp @@ -0,0 +1,121 @@ +/* + * 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 "WebImageDecoder.h" + +#include "BMPImageDecoder.h" +#include "ICOImageDecoder.h" +#include "SharedBuffer.h" +#include "WebData.h" +#include "WebImage.h" +#include "WebSize.h" + +#if WEBKIT_USING_SKIA +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +void WebImageDecoder::reset() +{ + delete m_private; +} + +void WebImageDecoder::init(Type type) +{ + switch (type) { + case TypeBMP: + m_private = new BMPImageDecoder(); + break; + case TypeICO: + m_private = new ICOImageDecoder(); + break; + } +} + +void WebImageDecoder::setData(const WebData& data, bool allDataReceived) +{ + ASSERT(m_private); + m_private->setData(PassRefPtr<SharedBuffer>(data).get(), allDataReceived); +} + +bool WebImageDecoder::isFailed() const +{ + ASSERT(m_private); + return m_private->failed(); +} + +bool WebImageDecoder::isSizeAvailable() const +{ + ASSERT(m_private); + return m_private->isSizeAvailable(); +} + +WebSize WebImageDecoder::size() const +{ + ASSERT(m_private); + return m_private->size(); +} + +size_t WebImageDecoder::frameCount() const +{ + ASSERT(m_private); + return m_private->frameCount(); +} + +bool WebImageDecoder::isFrameCompleteAtIndex(int index) const +{ + ASSERT(m_private); + RGBA32Buffer* const frameBuffer = m_private->frameBufferAtIndex(index); + if (!frameBuffer) + return false; + return (frameBuffer->status() == RGBA32Buffer::FrameComplete); +} + +WebImage WebImageDecoder::getFrameAtIndex(int index = 0) const +{ + ASSERT(m_private); + RGBA32Buffer* const frameBuffer = m_private->frameBufferAtIndex(index); + if (!frameBuffer) + return WebImage(); +#if WEBKIT_USING_SKIA + OwnPtr<NativeImageSkia>image(frameBuffer->asNewNativeImage()); + return WebImage(*image); +#elif WEBKIT_USING_CG + // FIXME: Implement CG side of this. + return WebImage(frameBuffer->asNewNativeImage()); +#endif +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebIndexedDatabaseImpl.cpp b/WebKit/chromium/src/WebIndexedDatabaseImpl.cpp new file mode 100644 index 0000000..27a6247 --- /dev/null +++ b/WebKit/chromium/src/WebIndexedDatabaseImpl.cpp @@ -0,0 +1,67 @@ +/* + * 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 "WebIndexedDatabaseImpl.h" + +#include "IDBCallbacksProxy.h" +#include "IndexedDatabaseImpl.h" +#include "SecurityOrigin.h" +#include "WebIDBDatabaseError.h" +#include <wtf/OwnPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +using namespace WebCore; + +namespace WebKit { + +WebIndexedDatabase* WebIndexedDatabase::create() +{ + return new WebIndexedDatabaseImpl(); +} + +WebIndexedDatabaseImpl::WebIndexedDatabaseImpl() + : m_indexedDatabase(WebCore::IndexedDatabaseImpl::create()) +{ +} + +WebIndexedDatabaseImpl::~WebIndexedDatabaseImpl() +{ +} + +void WebIndexedDatabaseImpl::open(const WebString& name, const WebString& description, WebIDBCallbacks* callbacks, const WebSecurityOrigin& origin, WebFrame*) +{ + m_indexedDatabase->open(name, description, IDBCallbacksProxy::create(callbacks), origin, 0); +} + +} // namespace WebKit + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebIndexedDatabaseImpl.h b/WebKit/chromium/src/WebIndexedDatabaseImpl.h new file mode 100644 index 0000000..76781e5 --- /dev/null +++ b/WebKit/chromium/src/WebIndexedDatabaseImpl.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebIndexedDatabaseImpl_h +#define WebIndexedDatabaseImpl_h + +#include "WebIndexedDatabase.h" +#include <wtf/RefPtr.h> + +namespace WebCore { class IndexedDatabase; } + +namespace WebKit { + +class WebIndexedDatabaseImpl : public WebIndexedDatabase { +public: + WebIndexedDatabaseImpl(); + virtual ~WebIndexedDatabaseImpl(); + + virtual void open(const WebString& name, const WebString& description, WebIDBCallbacks*, const WebSecurityOrigin&, WebFrame*); + +private: + WTF::RefPtr<WebCore::IndexedDatabase> m_indexedDatabase; +}; + +} // namespace WebKit + +#endif // WebIndexedDatabaseImpl_h diff --git a/WebKit/chromium/src/WebInputElement.cpp b/WebKit/chromium/src/WebInputElement.cpp index 9fd317f..3b88335 100644 --- a/WebKit/chromium/src/WebInputElement.cpp +++ b/WebKit/chromium/src/WebInputElement.cpp @@ -40,25 +40,14 @@ using namespace WebCore; namespace WebKit { -WebInputElement::WebInputElement(const WTF::PassRefPtr<HTMLInputElement>& elem) - : WebElement(elem.releaseRef()) -{ -} - -WebInputElement& WebInputElement::operator=(const WTF::PassRefPtr<HTMLInputElement>& elem) -{ - WebNode::assign(elem.releaseRef()); - return *this; -} - -WebInputElement::operator WTF::PassRefPtr<HTMLInputElement>() const +bool WebInputElement::autoComplete() const { - return PassRefPtr<HTMLInputElement>(static_cast<HTMLInputElement*>(m_private)); + return constUnwrap<HTMLInputElement>()->autoComplete(); } -bool WebInputElement::autoComplete() const +bool WebInputElement::isReadOnly() const { - return constUnwrap<HTMLInputElement>()->autoComplete(); + return constUnwrap<HTMLInputElement>()->readOnly(); } bool WebInputElement::isEnabledFormControl() const @@ -71,9 +60,9 @@ WebInputElement::InputType WebInputElement::inputType() const return static_cast<InputType>(constUnwrap<HTMLInputElement>()->inputType()); } -WebString WebInputElement::formControlType() const +int WebInputElement::maxLength() const { - return constUnwrap<HTMLInputElement>()->formControlType(); + return constUnwrap<HTMLInputElement>()->maxLength(); } bool WebInputElement::isActivatedSubmit() const @@ -86,6 +75,11 @@ void WebInputElement::setActivatedSubmit(bool activated) unwrap<HTMLInputElement>()->setActivatedSubmit(activated); } +int WebInputElement::size() const +{ + return constUnwrap<HTMLInputElement>()->size(); +} + void WebInputElement::setValue(const WebString& value) { unwrap<HTMLInputElement>()->setValue(value); @@ -96,6 +90,31 @@ WebString WebInputElement::value() const return constUnwrap<HTMLInputElement>()->value(); } +void WebInputElement::setSuggestedValue(const WebString& value) +{ + unwrap<HTMLInputElement>()->setSuggestedValue(value); +} + +WebString WebInputElement::suggestedValue() const +{ + return constUnwrap<HTMLInputElement>()->suggestedValue(); +} + +void WebInputElement::setPlaceholder(const WebString& value) +{ + unwrap<HTMLInputElement>()->setPlaceholder(value); +} + +WebString WebInputElement::placeholder() const +{ + return constUnwrap<HTMLInputElement>()->placeholder(); +} + +bool WebInputElement::isAutofilled() const +{ + return constUnwrap<HTMLInputElement>()->isAutofilled(); +} + void WebInputElement::setAutofilled(bool autoFilled) { unwrap<HTMLInputElement>()->setAutofilled(autoFilled); @@ -110,23 +129,31 @@ void WebInputElement::setSelectionRange(int start, int end) { unwrap<HTMLInputElement>()->setSelectionRange(start, end); } - -WebString WebInputElement::name() const + +int WebInputElement::selectionStart() +{ + return unwrap<HTMLInputElement>()->selectionStart(); +} + +int WebInputElement::selectionEnd() +{ + return unwrap<HTMLInputElement>()->selectionEnd(); +} + +WebInputElement::WebInputElement(const PassRefPtr<HTMLInputElement>& elem) + : WebFormControlElement(elem) +{ +} + +WebInputElement& WebInputElement::operator=(const PassRefPtr<HTMLInputElement>& elem) { - return constUnwrap<HTMLInputElement>()->name(); + m_private = elem; + return *this; } - -WebString WebInputElement::nameForAutofill() const + +WebInputElement::operator PassRefPtr<HTMLInputElement>() const { - String name = constUnwrap<HTMLInputElement>()->name(); - String trimmedName = name.stripWhiteSpace(); - if (!trimmedName.isEmpty()) - return trimmedName; - name = constUnwrap<HTMLInputElement>()->getAttribute(HTMLNames::idAttr); - trimmedName = name.stripWhiteSpace(); - if (!trimmedName.isEmpty()) - return trimmedName; - return String(); + return static_cast<HTMLInputElement*>(m_private.get()); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebInputEvent.cpp b/WebKit/chromium/src/WebInputEvent.cpp index b5c56fa..c00200e 100644 --- a/WebKit/chromium/src/WebInputEvent.cpp +++ b/WebKit/chromium/src/WebInputEvent.cpp @@ -86,6 +86,8 @@ static const char* staticKeyIdentifiers(unsigned short keyCode) case VKEY_F9: return "F9"; case VKEY_F10: + return "F10"; + case VKEY_F11: return "F11"; case VKEY_F12: return "F12"; diff --git a/WebKit/chromium/src/WebInputEventConversion.cpp b/WebKit/chromium/src/WebInputEventConversion.cpp index 147f88b..1c6d59c 100644 --- a/WebKit/chromium/src/WebInputEventConversion.cpp +++ b/WebKit/chromium/src/WebInputEventConversion.cpp @@ -40,6 +40,7 @@ #include "PlatformWheelEvent.h" #include "ScrollView.h" #include "WebInputEvent.h" +#include "WheelEvent.h" #include "Widget.h" using namespace WebCore; @@ -168,6 +169,64 @@ bool PlatformKeyboardEventBuilder::isCharacterKey() const return true; } +#if ENABLE(TOUCH_EVENTS) +static inline TouchEventType toPlatformTouchEventType(const WebInputEvent::Type type) +{ + switch (type) { + case WebInputEvent::TouchStart: + return TouchStart; + case WebInputEvent::TouchMove: + return TouchMove; + case WebInputEvent::TouchEnd: + return TouchEnd; + case WebInputEvent::TouchCancel: + return TouchCancel; + default: + ASSERT_NOT_REACHED(); + } + return TouchStart; +} + +static inline PlatformTouchPoint::State toPlatformTouchPointState(const WebTouchPoint::State state) +{ + switch (state) { + case WebTouchPoint::StateReleased: + return PlatformTouchPoint::TouchReleased; + case WebTouchPoint::StatePressed: + return PlatformTouchPoint::TouchPressed; + case WebTouchPoint::StateMoved: + return PlatformTouchPoint::TouchMoved; + case WebTouchPoint::StateStationary: + return PlatformTouchPoint::TouchStationary; + case WebTouchPoint::StateCancelled: + return PlatformTouchPoint::TouchCancelled; + case WebTouchPoint::StateUndefined: + ASSERT_NOT_REACHED(); + } + return PlatformTouchPoint::TouchReleased; +} + +PlatformTouchPointBuilder::PlatformTouchPointBuilder(Widget* widget, const WebTouchPoint& point) +{ + m_id = point.id; + m_state = toPlatformTouchPointState(point.state); + m_pos = widget->convertFromContainingWindow(point.position); + m_screenPos = point.screenPosition; +} + +PlatformTouchEventBuilder::PlatformTouchEventBuilder(Widget* widget, const WebTouchEvent& event) +{ + m_type = toPlatformTouchEventType(event.type); + m_ctrlKey = event.modifiers & WebInputEvent::ControlKey; + m_altKey = event.modifiers & WebInputEvent::AltKey; + m_shiftKey = event.modifiers & WebInputEvent::ShiftKey; + m_metaKey = event.modifiers & WebInputEvent::MetaKey; + + for (int i = 0; i < event.touchPointsLength; ++i) + m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touchPoints[i])); +} +#endif + static int getWebInputModifiers(const UIEventWithKeyState& event) { int modifiers = 0; @@ -182,7 +241,7 @@ static int getWebInputModifiers(const UIEventWithKeyState& event) return modifiers; } -WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEvent& event) +WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const MouseEvent& event) { if (event.type() == eventNames().mousemoveEvent) type = WebInputEvent::MouseMove; @@ -194,6 +253,8 @@ WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEv type = WebInputEvent::MouseDown; else if (event.type() == eventNames().mouseupEvent) type = WebInputEvent::MouseUp; + else if (event.type() == eventNames().contextmenuEvent) + type = WebInputEvent::ContextMenu; else return; // Skip all other mouse events. timeStampSeconds = event.timeStamp() * 1.0e-3; @@ -222,16 +283,42 @@ WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEv break; } } - IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY())); + ScrollView* view = widget->parent(); + IntPoint p = view->contentsToWindow( + IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y())); globalX = event.screenX(); globalY = event.screenY(); windowX = p.x(); windowY = p.y(); - x = event.offsetX(); - y = event.offsetY(); + x = event.absoluteLocation().x() - widget->pos().x(); + y = event.absoluteLocation().y() - widget->pos().y(); clickCount = event.detail(); } +WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const Widget* widget, const WheelEvent& event) +{ + if (event.type() != eventNames().mousewheelEvent) + return; + type = WebInputEvent::MouseWheel; + timeStampSeconds = event.timeStamp() * 1.0e-3; + modifiers = getWebInputModifiers(event); + ScrollView* view = widget->parent(); + IntPoint p = view->contentsToWindow( + IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y())); + globalX = event.screenX(); + globalY = event.screenY(); + windowX = p.x(); + windowY = p.y(); + x = event.absoluteLocation().x() - widget->pos().x(); + y = event.absoluteLocation().y() - widget->pos().y(); + deltaX = static_cast<float>(event.rawDeltaX()); + deltaY = static_cast<float>(event.rawDeltaY()); + // The 120 is from WheelEvent::initWheelEvent(). + wheelTicksX = static_cast<float>(event.wheelDeltaX()) / 120; + wheelTicksY = static_cast<float>(event.wheelDeltaY()) / 120; + scrollByPage = event.granularity() == WheelEvent::Page; +} + WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event) { if (event.type() == eventNames().keydownEvent) diff --git a/WebKit/chromium/src/WebInputEventConversion.h b/WebKit/chromium/src/WebInputEventConversion.h index 4c9cf82..63991a9 100644 --- a/WebKit/chromium/src/WebInputEventConversion.h +++ b/WebKit/chromium/src/WebInputEventConversion.h @@ -31,18 +31,18 @@ #ifndef WebInputEventConversion_h #define WebInputEventConversion_h -// FIXME: This relative path is a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebInputEvent.h" +#include "WebInputEvent.h" #include "PlatformKeyboardEvent.h" #include "PlatformMouseEvent.h" +#include "PlatformTouchEvent.h" #include "PlatformWheelEvent.h" namespace WebCore { class KeyboardEvent; class MouseEvent; class ScrollView; +class WheelEvent; class Widget; } @@ -72,20 +72,38 @@ public: bool isCharacterKey() const; }; +#if ENABLE(TOUCH_EVENTS) +class PlatformTouchPointBuilder : public WebCore::PlatformTouchPoint { +public: + PlatformTouchPointBuilder(WebCore::Widget*, const WebTouchPoint&); +}; + +class PlatformTouchEventBuilder : public WebCore::PlatformTouchEvent { +public: + PlatformTouchEventBuilder(WebCore::Widget*, const WebTouchEvent&); +}; +#endif + // Converts a WebCore::MouseEvent to a corresponding WebMouseEvent. view is -// the ScrollView corresponding to the event. Returns true if successful. +// the ScrollView corresponding to the event. // NOTE: This is only implemented for mousemove, mouseover, mouseout, // mousedown and mouseup. If the event mapping fails, the event type will // be set to Undefined. class WebMouseEventBuilder : public WebMouseEvent { public: - WebMouseEventBuilder(const WebCore::ScrollView*, const WebCore::MouseEvent&); + WebMouseEventBuilder(const WebCore::Widget*, const WebCore::MouseEvent&); +}; + +// Converts a WebCore::WheelEvent to a corresponding WebMouseWheelEvent. +// If the event mapping fails, the event type will be set to Undefined. +class WebMouseWheelEventBuilder : public WebMouseWheelEvent { +public: + WebMouseWheelEventBuilder(const WebCore::Widget*, const WebCore::WheelEvent&); }; // Converts a WebCore::KeyboardEvent to a corresponding WebKeyboardEvent. -// Returns true if successful. NOTE: This is only implemented for keydown -// and keyup. If the event mapping fails, the event type will be set to -// Undefined. +// NOTE: This is only implemented for keydown and keyup. If the event mapping +// fails, the event type will be set to Undefined. class WebKeyboardEventBuilder : public WebKeyboardEvent { public: WebKeyboardEventBuilder(const WebCore::KeyboardEvent&); diff --git a/WebKit/chromium/src/WebKit.cpp b/WebKit/chromium/src/WebKit.cpp index a8e1851..8346ef8 100644 --- a/WebKit/chromium/src/WebKit.cpp +++ b/WebKit/chromium/src/WebKit.cpp @@ -56,6 +56,7 @@ void initialize(WebKitClient* webKitClient) s_webKitClient = webKitClient; WTF::initializeThreading(); + WTF::initializeMainThread(); WebCore::AtomicString::init(); // Chromium sets the minimum interval timeout to 4ms, overriding the diff --git a/WebKit/chromium/src/WebLabelElement.cpp b/WebKit/chromium/src/WebLabelElement.cpp new file mode 100644 index 0000000..ef2c698 --- /dev/null +++ b/WebKit/chromium/src/WebLabelElement.cpp @@ -0,0 +1,64 @@ +/* + * 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 "WebLabelElement.h" + +#include "HTMLLabelElement.h" +#include "HTMLNames.h" +#include "WebString.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +WebElement WebLabelElement::correspondingControl() +{ + return WebElement(unwrap<HTMLLabelElement>()->control()); +} + +WebLabelElement::WebLabelElement(const PassRefPtr<HTMLLabelElement>& elem) + : WebElement(elem) +{ +} + +WebLabelElement& WebLabelElement::operator=(const PassRefPtr<HTMLLabelElement>& elem) +{ + m_private = elem; + return *this; +} + +WebLabelElement::operator PassRefPtr<HTMLLabelElement>() const +{ + return static_cast<HTMLLabelElement*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebMediaElement.cpp b/WebKit/chromium/src/WebMediaElement.cpp new file mode 100644 index 0000000..4adda1e --- /dev/null +++ b/WebKit/chromium/src/WebMediaElement.cpp @@ -0,0 +1,64 @@ +/* + * 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 "WebMediaElement.h" + +#include "HTMLMediaElement.h" +#include "MediaPlayer.h" +#include "WebMediaPlayer.h" +#include "WebMediaPlayerClientImpl.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +WebMediaPlayer* WebMediaElement::player() const +{ + return WebMediaPlayerClientImpl::fromMediaElement(this)->mediaPlayer(); +} + +WebMediaElement::WebMediaElement(const PassRefPtr<HTMLMediaElement>& elem) + : WebElement(elem) +{ +} + +WebMediaElement& WebMediaElement::operator=(const PassRefPtr<HTMLMediaElement>& elem) +{ + m_private = elem; + return *this; +} + +WebMediaElement::operator PassRefPtr<HTMLMediaElement>() const +{ + return static_cast<HTMLMediaElement*>(m_private.get()); +} +} // namespace WebKit diff --git a/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp b/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp index b1f1f03..2b0c9a7 100644 --- a/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp +++ b/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp @@ -7,7 +7,6 @@ #if ENABLE(VIDEO) -#include "CString.h" #include "Frame.h" #include "GraphicsContext.h" #include "HTMLMediaElement.h" @@ -15,7 +14,13 @@ #include "KURL.h" #include "MediaPlayer.h" #include "NotImplemented.h" +#include "RenderView.h" #include "TimeRanges.h" +#include "VideoLayerChromium.h" + +#if USE(ACCELERATED_COMPOSITING) +#include "RenderLayerCompositor.h" +#endif #include "WebCanvas.h" #include "WebCString.h" @@ -23,12 +28,14 @@ #include "WebFrameImpl.h" #include "WebKit.h" #include "WebKitClient.h" +#include "WebMediaElement.h" #include "WebMediaPlayer.h" #include "WebMimeRegistry.h" #include "WebRect.h" #include "WebSize.h" #include "WebString.h" #include "WebURL.h" +#include "WebViewImpl.h" // WebCommon.h defines WEBKIT_USING_SKIA so this has to be included last. #if WEBKIT_USING_SKIA @@ -36,6 +43,7 @@ #endif #include <wtf/Assertions.h> +#include <wtf/text/CString.h> using namespace WebCore; @@ -45,6 +53,7 @@ static WebMediaPlayer* createWebMediaPlayer( WebMediaPlayerClient* client, Frame* frame) { WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame); + if (!webFrame->client()) return 0; return webFrame->client()->createMediaPlayer(webFrame, client); @@ -71,6 +80,17 @@ void WebMediaPlayerClientImpl::registerSelf(MediaEngineRegistrar registrar) } } +WebMediaPlayerClientImpl* WebMediaPlayerClientImpl::fromMediaElement(const WebMediaElement* element) +{ + PlatformMedia pm = element->constUnwrap<HTMLMediaElement>()->platformMedia(); + return static_cast<WebMediaPlayerClientImpl*>(pm.media.chromiumMediaPlayer); +} + +WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const +{ + return m_webMediaPlayer.get(); +} + // WebMediaPlayerClient -------------------------------------------------------- void WebMediaPlayerClientImpl::networkStateChanged() @@ -133,12 +153,20 @@ void WebMediaPlayerClientImpl::sawUnsupportedTracks() m_mediaPlayer->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_mediaPlayer); } +float WebMediaPlayerClientImpl::volume() const +{ + if (m_mediaPlayer) + return m_mediaPlayer->volume(); + return 0.0f; +} + // MediaPlayerPrivateInterface ------------------------------------------------- void WebMediaPlayerClientImpl::load(const String& url) { Frame* frame = static_cast<HTMLMediaElement*>( m_mediaPlayer->mediaPlayerClient())->document()->frame(); + m_webMediaPlayer.set(createWebMediaPlayer(this, frame)); if (m_webMediaPlayer.get()) m_webMediaPlayer->load(KURL(ParsedURLString, url)); @@ -150,6 +178,22 @@ void WebMediaPlayerClientImpl::cancelLoad() m_webMediaPlayer->cancelLoad(); } +#if USE(ACCELERATED_COMPOSITING) +PlatformLayer* WebMediaPlayerClientImpl::platformLayer() const +{ + ASSERT(m_supportsAcceleratedCompositing); + return m_videoLayer.get(); +} +#endif + +PlatformMedia WebMediaPlayerClientImpl::platformMedia() const +{ + PlatformMedia pm; + pm.type = PlatformMedia::ChromiumMediaPlayerType; + pm.media.chromiumMediaPlayer = const_cast<WebMediaPlayerClientImpl*>(this); + return pm; +} + void WebMediaPlayerClientImpl::play() { if (m_webMediaPlayer.get()) @@ -353,6 +397,13 @@ bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const return false; } +#if USE(ACCELERATED_COMPOSITING) +bool WebMediaPlayerClientImpl::supportsAcceleratedRendering() const +{ + return m_supportsAcceleratedCompositing; +} +#endif + MediaPlayer::MovieLoadType WebMediaPlayerClientImpl::movieLoadType() const { if (m_webMediaPlayer.get()) @@ -365,6 +416,22 @@ MediaPlayerPrivateInterface* WebMediaPlayerClientImpl::create(MediaPlayer* playe { WebMediaPlayerClientImpl* client = new WebMediaPlayerClientImpl(); client->m_mediaPlayer = player; + +#if USE(ACCELERATED_COMPOSITING) + Frame* frame = static_cast<HTMLMediaElement*>( + client->m_mediaPlayer->mediaPlayerClient())->document()->frame(); + + // This does not actually check whether the hardware can support accelerated + // compositing, but only if the flag is set. However, this is checked lazily + // in WebViewImpl::setIsAcceleratedCompositingActive() and will fail there + // if necessary. + client->m_supportsAcceleratedCompositing = + frame->contentRenderer()->compositor()->hasAcceleratedCompositing(); + + if (client->m_supportsAcceleratedCompositing) + client->m_videoLayer = VideoLayerChromium::create(0); +#endif + return client; } @@ -395,6 +462,10 @@ MediaPlayer::SupportsType WebMediaPlayerClientImpl::supportsType(const String& t WebMediaPlayerClientImpl::WebMediaPlayerClientImpl() : m_mediaPlayer(0) +#if USE(ACCELERATED_COMPOSITING) + , m_videoLayer(0) + , m_supportsAcceleratedCompositing(false) +#endif { } diff --git a/WebKit/chromium/src/WebMediaPlayerClientImpl.h b/WebKit/chromium/src/WebMediaPlayerClientImpl.h index 4adbed2..0faac26 100644 --- a/WebKit/chromium/src/WebMediaPlayerClientImpl.h +++ b/WebKit/chromium/src/WebMediaPlayerClientImpl.h @@ -39,6 +39,7 @@ namespace WebKit { +class WebMediaElement; class WebMediaPlayer; // This class serves as a bridge between WebCore::MediaPlayer and @@ -50,6 +51,11 @@ public: static void setIsEnabled(bool); static void registerSelf(WebCore::MediaEngineRegistrar); + static WebMediaPlayerClientImpl* fromMediaElement(const WebMediaElement* element); + + // Returns the encapsulated WebKit::WebMediaPlayer. + WebMediaPlayer* mediaPlayer() const; + // WebMediaPlayerClient methods: virtual void networkStateChanged(); virtual void readyStateChanged(); @@ -61,10 +67,15 @@ public: virtual void rateChanged(); virtual void sizeChanged(); virtual void sawUnsupportedTracks(); + virtual float volume() const; // MediaPlayerPrivateInterface methods: virtual void load(const WebCore::String& url); virtual void cancelLoad(); +#if USE(ACCELERATED_COMPOSITING) + virtual WebCore::PlatformLayer* platformLayer() const; +#endif + virtual WebCore::PlatformMedia platformMedia() const; virtual void play(); virtual void pause(); virtual bool supportsFullscreen() const; @@ -93,6 +104,10 @@ public: virtual void setSize(const WebCore::IntSize&); virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect&); virtual bool hasSingleSecurityOrigin() const; +#if USE(ACCELERATED_COMPOSITING) + virtual bool supportsAcceleratedRendering() const; +#endif + virtual WebCore::MediaPlayer::MovieLoadType movieLoadType() const; private: @@ -105,6 +120,10 @@ private: WebCore::MediaPlayer* m_mediaPlayer; OwnPtr<WebMediaPlayer> m_webMediaPlayer; +#if USE(ACCELERATED_COMPOSITING) + RefPtr<WebCore::PlatformLayer> m_videoLayer; + bool m_supportsAcceleratedCompositing; +#endif static bool m_isEnabled; }; diff --git a/WebKit/chromium/src/WebNamedNodeMap.cpp b/WebKit/chromium/src/WebNamedNodeMap.cpp new file mode 100644 index 0000000..e2455e6 --- /dev/null +++ b/WebKit/chromium/src/WebNamedNodeMap.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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 "WebNamedNodeMap.h" + +#include "NamedNodeMap.h" +#include "Node.h" +#include "WebAttribute.h" +#include "WebNode.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +void WebNamedNodeMap::reset() +{ + m_private.reset(); +} + +void WebNamedNodeMap::assign(const WebNamedNodeMap& other) +{ + m_private = other.m_private; +} + +WebNamedNodeMap::WebNamedNodeMap(const PassRefPtr<NamedNodeMap>& other) + : m_private(other) +{ +} + +unsigned WebNamedNodeMap::length() const +{ + return m_private->length(); +} + +WebAttribute WebNamedNodeMap::attributeItem(unsigned index) const +{ + return WebAttribute(m_private->attributeItem(index)); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebNode.cpp b/WebKit/chromium/src/WebNode.cpp index 9fbf573..69c35e7 100644 --- a/WebKit/chromium/src/WebNode.cpp +++ b/WebKit/chromium/src/WebNode.cpp @@ -48,26 +48,28 @@ #include "markup.h" -#include <wtf/PassRefPtr.h> - using namespace WebCore; namespace WebKit { -class WebNodePrivate : public Node { -}; - void WebNode::reset() { - assign(0); + m_private.reset(); } void WebNode::assign(const WebNode& other) { - WebNodePrivate* p = const_cast<WebNodePrivate*>(other.m_private); - if (p) - p->ref(); - assign(p); + m_private = other.m_private; +} + +bool WebNode::equals(const WebNode& n) const +{ + return (m_private.get() == n.m_private.get()); +} + +bool WebNode::lessThan(const WebNode& n) const +{ + return (m_private.get() < n.m_private.get()); } WebNode::NodeType WebNode::nodeType() const @@ -77,7 +79,7 @@ WebNode::NodeType WebNode::nodeType() const WebNode WebNode::parentNode() const { - return PassRefPtr<Node>(const_cast<Node*>(m_private->parentNode())); + return WebNode(const_cast<Node*>(m_private->parentNode())); } WebString WebNode::nodeName() const @@ -97,35 +99,6 @@ bool WebNode::setNodeValue(const WebString& value) return !exceptionCode; } -WebNode::WebNode(const PassRefPtr<Node>& node) - : m_private(static_cast<WebNodePrivate*>(node.releaseRef())) -{ -} - -WebNode& WebNode::operator=(const PassRefPtr<Node>& node) -{ - assign(static_cast<WebNodePrivate*>(node.releaseRef())); - return *this; -} - -WebNode::operator PassRefPtr<Node>() const -{ - return PassRefPtr<Node>(const_cast<WebNodePrivate*>(m_private)); -} - -void WebNode::assign(WebNodePrivate* p) -{ - // p is already ref'd for us by the caller - if (m_private) - m_private->deref(); - m_private = p; -} - -WebFrame* WebNode::frame() const -{ - return WebFrameImpl::fromFrame(m_private->document()->frame()); -} - WebDocument WebNode::document() const { return WebDocument(m_private->document()); @@ -163,7 +136,7 @@ WebNodeList WebNode::childNodes() WebString WebNode::createMarkup() const { - return WebCore::createMarkup(m_private); + return WebCore::createMarkup(m_private.get()); } bool WebNode::isTextNode() const @@ -179,7 +152,7 @@ bool WebNode::isElementNode() const void WebNode::addEventListener(const WebString& eventType, WebEventListener* listener, bool useCapture) { EventListenerWrapper* listenerWrapper = - listener->createEventListenerWrapper(eventType, useCapture, m_private); + listener->createEventListenerWrapper(eventType, useCapture, m_private.get()); // The listenerWrapper is only referenced by the actual Node. Once it goes // away, the wrapper notifies the WebEventListener so it can clear its // pointer to it. @@ -189,9 +162,41 @@ void WebNode::addEventListener(const WebString& eventType, WebEventListener* lis void WebNode::removeEventListener(const WebString& eventType, WebEventListener* listener, bool useCapture) { EventListenerWrapper* listenerWrapper = - listener->getEventListenerWrapper(eventType, useCapture, m_private); + listener->getEventListenerWrapper(eventType, useCapture, m_private.get()); m_private->removeEventListener(eventType, listenerWrapper, useCapture); // listenerWrapper is now deleted. } +void WebNode::simulateClick() +{ + RefPtr<Event> noEvent; + m_private->dispatchSimulatedClick(noEvent); +} + +WebNodeList WebNode::getElementsByTagName(const WebString& tag) const +{ + return WebNodeList(m_private->getElementsByTagName(tag)); +} + +bool WebNode::hasNonEmptyBoundingBox() const +{ + return m_private->hasNonEmptyBoundingBox(); +} + +WebNode::WebNode(const PassRefPtr<Node>& node) + : m_private(node) +{ +} + +WebNode& WebNode::operator=(const PassRefPtr<Node>& node) +{ + m_private = node; + return *this; +} + +WebNode::operator PassRefPtr<Node>() const +{ + return m_private.get(); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebNotification.cpp b/WebKit/chromium/src/WebNotification.cpp index 1f6916e..38d91df 100644 --- a/WebKit/chromium/src/WebNotification.cpp +++ b/WebKit/chromium/src/WebNotification.cpp @@ -36,6 +36,7 @@ #include "Notification.h" #include "WebString.h" +#include "WebTextDirection.h" #include "WebURL.h" #include <wtf/PassRefPtr.h> @@ -76,10 +77,10 @@ WebURL WebNotification::url() const return m_private->url(); } -WebString WebNotification::icon() const +WebURL WebNotification::iconURL() const { ASSERT(!isHTML()); - return m_private->contents().icon(); + return m_private->iconURL(); } WebString WebNotification::title() const @@ -94,6 +95,24 @@ WebString WebNotification::body() const return m_private->contents().body(); } +// FIXME: remove dir() when unreferenced. Being replaced by direction(). +WebString WebNotification::dir() const +{ + return m_private->dir(); +} + +WebTextDirection WebNotification::direction() const +{ + return (m_private->direction() == RTL) ? + WebTextDirectionRightToLeft : + WebTextDirectionLeftToRight; +} + +WebString WebNotification::replaceId() const +{ + return m_private->replaceId(); +} + void WebNotification::dispatchDisplayEvent() { RefPtr<Event> event = Event::create("display", false, true); diff --git a/WebKit/chromium/src/WebOptionElement.cpp b/WebKit/chromium/src/WebOptionElement.cpp new file mode 100644 index 0000000..49bff3b --- /dev/null +++ b/WebKit/chromium/src/WebOptionElement.cpp @@ -0,0 +1,100 @@ +/* + * 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 "WebOptionElement.h" + +#include "HTMLNames.h" +#include "HTMLOptionElement.h" +#include "HTMLSelectElement.h" +#include "WebString.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +void WebOptionElement::setValue(const WebString& newValue) +{ + return unwrap<HTMLOptionElement>()->setValue(newValue); +} + +WebString WebOptionElement::value() const +{ + return constUnwrap<HTMLOptionElement>()->value(); +} + +int WebOptionElement::index() const +{ + return constUnwrap<HTMLOptionElement>()->index(); +} + +WebString WebOptionElement::text() const +{ + return constUnwrap<HTMLOptionElement>()->text(); +} + +bool WebOptionElement::defaultSelected() const +{ + return constUnwrap<HTMLOptionElement>()->defaultSelected(); +} + +void WebOptionElement::setDefaultSelected(bool newSelected) +{ + return unwrap<HTMLOptionElement>()->setDefaultSelected(newSelected); +} + +WebString WebOptionElement::label() const +{ + return constUnwrap<HTMLOptionElement>()->label(); +} + +bool WebOptionElement::isEnabled() const +{ + return !(constUnwrap<HTMLOptionElement>()->disabled()); +} + +WebOptionElement::WebOptionElement(const PassRefPtr<HTMLOptionElement>& elem) + : WebFormControlElement(elem) +{ +} + +WebOptionElement& WebOptionElement::operator=(const PassRefPtr<HTMLOptionElement>& elem) +{ + m_private = elem; + return *this; +} + +WebOptionElement::operator PassRefPtr<HTMLOptionElement>() const +{ + return static_cast<HTMLOptionElement*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebPageSerializer.cpp b/WebKit/chromium/src/WebPageSerializer.cpp index 1010285..4f93702 100644 --- a/WebKit/chromium/src/WebPageSerializer.cpp +++ b/WebKit/chromium/src/WebPageSerializer.cpp @@ -59,7 +59,7 @@ bool WebPageSerializer::serialize(WebFrame* frame, WebString WebPageSerializer::generateMetaCharsetDeclaration(const WebString& charset) { - return String::format("<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">", + return String::format("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">", charset.utf8().data()); } @@ -75,7 +75,7 @@ WebString WebPageSerializer::generateBaseTagDeclaration(const WebString& baseTar String targetDeclaration; if (!baseTarget.isEmpty()) targetDeclaration = String::format(" target=\"%s\"", baseTarget.utf8().data()); - return String::format("<BASE href=\".\"%s>", targetDeclaration.utf8().data()); + return String::format("<base href=\".\"%s>", targetDeclaration.utf8().data()); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebPageSerializerImpl.cpp b/WebKit/chromium/src/WebPageSerializerImpl.cpp index d5b2b7f..e65af85 100644 --- a/WebKit/chromium/src/WebPageSerializerImpl.cpp +++ b/WebKit/chromium/src/WebPageSerializerImpl.cpp @@ -170,7 +170,7 @@ String WebPageSerializerImpl::preActionBeforeSerializeOpenTag( // Get encoding info. String xmlEncoding = param->doc->xmlEncoding(); if (xmlEncoding.isEmpty()) - xmlEncoding = param->doc->frame()->loader()->encoding(); + xmlEncoding = param->doc->frame()->loader()->writer()->encoding(); if (xmlEncoding.isEmpty()) xmlEncoding = UTF8Encoding().name(); result.append("<?xml version=\""); @@ -306,7 +306,7 @@ void WebPageSerializerImpl::openTagToString(const Element* element, if (needSkip) return; // Add open tag - result += "<" + element->nodeName(); + result += "<" + element->nodeName().lower(); // Go through all attributes and serialize them. const NamedNodeMap *attrMap = element->attributes(true); if (attrMap) { @@ -374,7 +374,7 @@ void WebPageSerializerImpl::endTagToString(const Element* element, // Write end tag when element has child/children. if (element->hasChildNodes() || param->hasAddedContentsBeforeEnd) { result += "</"; - result += element->nodeName(); + result += element->nodeName().lower(); result += ">"; } else { // Check whether we have to write end tag for empty element. @@ -385,7 +385,7 @@ void WebPageSerializerImpl::endTagToString(const Element* element, if (htmlElement->endTagRequirement() == TagStatusRequired) { // We need to write end tag when it is required. result += "</"; - result += element->nodeName(); + result += element->nodeName().lower(); result += ">"; } } else { @@ -510,11 +510,11 @@ bool WebPageSerializerImpl::serialize() const KURL& currentFrameURL = currentFrame->frame()->loader()->url(); // Check whether we have done this document. - if (m_localLinks.contains(currentFrameURL.string())) { + if (currentFrameURL.isValid() && m_localLinks.contains(currentFrameURL.string())) { // A new document, we will serialize it. didSerialization = true; // Get target encoding for current document. - String encoding = currentFrame->frame()->loader()->encoding(); + String encoding = currentFrame->frame()->loader()->writer()->encoding(); // Create the text encoding object with target encoding. TextEncoding textEncoding(encoding); // Construct serialize parameter for late processing document. diff --git a/WebKit/chromium/src/WebPasswordFormData.cpp b/WebKit/chromium/src/WebPasswordFormData.cpp index 64b1754..eb230d5 100644 --- a/WebKit/chromium/src/WebPasswordFormData.cpp +++ b/WebKit/chromium/src/WebPasswordFormData.cpp @@ -162,7 +162,10 @@ WebPasswordFormData::WebPasswordFormData(const WebFormElement& webForm) KURL fullOrigin(ParsedURLString, form->document()->documentURI()); // Calculate the canonical action URL - KURL fullAction = frame->loader()->completeURL(form->action()); + String action = form->action(); + if (action.isNull()) + action = ""; // missing 'action' attribute implies current URL + KURL fullAction = frame->loader()->completeURL(action); if (!fullAction.isValid()) return; diff --git a/WebKit/chromium/src/WebPasswordFormUtils.cpp b/WebKit/chromium/src/WebPasswordFormUtils.cpp index 766dc63..e5d5411 100644 --- a/WebKit/chromium/src/WebPasswordFormUtils.cpp +++ b/WebKit/chromium/src/WebPasswordFormUtils.cpp @@ -65,7 +65,7 @@ void findPasswordFormFields(HTMLFormElement* form, PasswordFormFields* fields) int firstPasswordIndex = 0; // First, find the password fields and activated submit button - const Vector<HTMLFormControlElement*>& formElements = form->formElements; + const Vector<HTMLFormControlElement*>& formElements = form->associatedElements(); for (size_t i = 0; i < formElements.size(); i++) { HTMLFormControlElement* formElement = formElements[i]; if (formElement->isActivatedSubmit()) diff --git a/WebKit/chromium/src/WebPluginContainerImpl.cpp b/WebKit/chromium/src/WebPluginContainerImpl.cpp index 86cac26..7f74db2 100644 --- a/WebKit/chromium/src/WebPluginContainerImpl.cpp +++ b/WebKit/chromium/src/WebPluginContainerImpl.cpp @@ -33,13 +33,18 @@ #include "Chrome.h" #include "ChromeClientImpl.h" +#include "WebClipboard.h" #include "WebCursorInfo.h" #include "WebDataSourceImpl.h" +#include "WebElement.h" #include "WebInputEvent.h" #include "WebInputEventConversion.h" #include "WebKit.h" +#include "WebKitClient.h" #include "WebPlugin.h" #include "WebRect.h" +#include "WebString.h" +#include "WebURL.h" #include "WebURLError.h" #include "WebURLRequest.h" #include "WebVector.h" @@ -56,10 +61,13 @@ #include "HTMLFormElement.h" #include "HTMLNames.h" #include "HTMLPlugInElement.h" +#include "KeyboardCodes.h" #include "KeyboardEvent.h" #include "MouseEvent.h" #include "Page.h" +#include "RenderBox.h" #include "ScrollView.h" +#include "WheelEvent.h" #if WEBKIT_USING_SKIA #include "PlatformContextSkia.h" @@ -124,13 +132,13 @@ void WebPluginContainerImpl::invalidateRect(const IntRect& rect) IntRect clipRect = parent()->windowClipRect(); damageRect.intersect(clipRect); - parent()->hostWindow()->repaint(damageRect, true); + parent()->hostWindow()->invalidateContentsAndWindow(damageRect, false /*immediate*/); } -void WebPluginContainerImpl::setFocus() +void WebPluginContainerImpl::setFocus(bool focused) { - Widget::setFocus(); - m_webPlugin->updateFocus(true); + Widget::setFocus(focused); + m_webPlugin->updateFocus(focused); } void WebPluginContainerImpl::show() @@ -160,8 +168,15 @@ void WebPluginContainerImpl::handleEvent(Event* event) // where mozilla behaves differently than the spec. if (event->isMouseEvent()) handleMouseEvent(static_cast<MouseEvent*>(event)); + else if (event->isWheelEvent()) + handleWheelEvent(static_cast<WheelEvent*>(event)); else if (event->isKeyboardEvent()) handleKeyboardEvent(static_cast<KeyboardEvent*>(event)); + + // FIXME: it would be cleaner if Widget::handleEvent returned true/false and + // HTMLPluginElement called setDefaultHandled or defaultEventHandler. + if (!event->defaultHandled()) + m_element->Node::defaultEventHandler(event); } void WebPluginContainerImpl::frameRectsChanged() @@ -170,6 +185,12 @@ void WebPluginContainerImpl::frameRectsChanged() reportGeometry(); } +void WebPluginContainerImpl::widgetPositionsUpdated() +{ + Widget::widgetPositionsUpdated(); + reportGeometry(); +} + void WebPluginContainerImpl::setParentVisible(bool parentVisible) { // We override this function to make sure that geometry updates are sent @@ -200,6 +221,49 @@ void WebPluginContainerImpl::setParent(ScrollView* view) reportGeometry(); } +bool WebPluginContainerImpl::supportsPaginatedPrint() const +{ + return m_webPlugin->supportsPaginatedPrint(); +} + +int WebPluginContainerImpl::printBegin(const IntRect& printableArea, + int printerDPI) const +{ + return m_webPlugin->printBegin(printableArea, printerDPI); +} + +bool WebPluginContainerImpl::printPage(int pageNumber, + WebCore::GraphicsContext* gc) +{ + gc->save(); +#if WEBKIT_USING_SKIA + WebCanvas* canvas = gc->platformContext()->canvas(); +#elif WEBKIT_USING_CG + WebCanvas* canvas = gc->platformContext(); +#endif + bool ret = m_webPlugin->printPage(pageNumber, canvas); + gc->restore(); + return ret; +} + +void WebPluginContainerImpl::printEnd() +{ + return m_webPlugin->printEnd(); +} + +void WebPluginContainerImpl::copy() +{ + if (!plugin()->hasSelection()) + return; + + webKitClient()->clipboard()->writeHTML(plugin()->selectionAsMarkup(), WebURL(), plugin()->selectionAsText(), false); +} + +WebElement WebPluginContainerImpl::element() +{ + return WebElement(m_element); +} + void WebPluginContainerImpl::invalidate() { Widget::invalidate(); @@ -339,7 +403,7 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event) // in the call to HandleEvent. See http://b/issue?id=1362948 FrameView* parentView = static_cast<FrameView*>(parent()); - WebMouseEventBuilder webEvent(parentView, *event); + WebMouseEventBuilder webEvent(this, *event); if (webEvent.type == WebInputEvent::Undefined) return; @@ -353,22 +417,7 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event) } WebCursorInfo cursorInfo; - bool handled = m_webPlugin->handleInputEvent(webEvent, cursorInfo); -#if !OS(DARWIN) - // TODO(pkasting): http://b/1119691 This conditional seems exactly - // backwards, but if I reverse it, giving focus to a transparent - // (windowless) plugin fails. - handled = !handled; - // TODO(awalker): oddly, the above is not true in Mac builds. Looking - // at Apple's corresponding code for Mac and Windows (PluginViewMac and - // PluginViewWin), setDefaultHandled() gets called when handleInputEvent() - // returns true, which then indicates to WebCore that the plugin wants to - // swallow the event--which is what we want. Calling setDefaultHandled() - // fixes several Mac Chromium bugs, but does indeed prevent windowless plugins - // from getting focus in Windows builds, as pkasting notes above. So for - // now, we only do so in Mac builds. -#endif - if (handled) + if (m_webPlugin->handleInputEvent(webEvent, cursorInfo)) event->setDefaultHandled(); // A windowless plugin can change the cursor in response to a mouse move @@ -382,19 +431,38 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event) chromeClient->setCursorForPlugin(cursorInfo); } +void WebPluginContainerImpl::handleWheelEvent(WheelEvent* event) +{ + WebMouseWheelEventBuilder webEvent(this, *event); + if (webEvent.type == WebInputEvent::Undefined) + return; + + WebCursorInfo cursorInfo; + if (m_webPlugin->handleInputEvent(webEvent, cursorInfo)) + event->setDefaultHandled(); +} + void WebPluginContainerImpl::handleKeyboardEvent(KeyboardEvent* event) { WebKeyboardEventBuilder webEvent(*event); if (webEvent.type == WebInputEvent::Undefined) return; - WebCursorInfo cursor_info; - bool handled = m_webPlugin->handleInputEvent(webEvent, cursor_info); -#if !OS(DARWIN) - // TODO(pkasting): http://b/1119691 See above. - handled = !handled; + if (webEvent.type == WebInputEvent::KeyDown) { +#if defined(OS_MACOSX) + if (webEvent.modifiers == WebInputEvent::MetaKey +#else + if (webEvent.modifiers == WebInputEvent::ControlKey #endif - if (handled) + && webEvent.windowsKeyCode == VKEY_C) { + copy(); + event->setDefaultHandled(); + return; + } + } + + WebCursorInfo cursorInfo; + if (m_webPlugin->handleInputEvent(webEvent, cursorInfo)) event->setDefaultHandled(); } diff --git a/WebKit/chromium/src/WebPluginContainerImpl.h b/WebKit/chromium/src/WebPluginContainerImpl.h index 00450bb..2a46e00 100644 --- a/WebKit/chromium/src/WebPluginContainerImpl.h +++ b/WebKit/chromium/src/WebPluginContainerImpl.h @@ -31,9 +31,7 @@ #ifndef WebPluginContainerImpl_h #define WebPluginContainerImpl_h -// FIXME: This relative path is a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebPluginContainer.h" +#include "WebPluginContainer.h" #include "Widget.h" #include <wtf/PassRefPtr.h> @@ -48,6 +46,7 @@ class KeyboardEvent; class MouseEvent; class ResourceError; class ResourceResponse; +class WheelEvent; } namespace WebKit { @@ -66,15 +65,17 @@ public: virtual void setFrameRect(const WebCore::IntRect&); virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect&); virtual void invalidateRect(const WebCore::IntRect&); - virtual void setFocus(); + virtual void setFocus(bool); virtual void show(); virtual void hide(); virtual void handleEvent(WebCore::Event*); virtual void frameRectsChanged(); virtual void setParentVisible(bool); virtual void setParent(WebCore::ScrollView*); + virtual void widgetPositionsUpdated(); // WebPluginContainer methods + virtual WebElement element(); virtual void invalidate(); virtual void invalidateRect(const WebRect&); virtual void reportGeometry(); @@ -83,6 +84,27 @@ public: virtual WebString executeScriptURL(const WebURL&, bool popupsAllowed); virtual void loadFrameRequest(const WebURLRequest&, const WebString& target, bool notifyNeeded, void* notifyData); + // This cannot be null. + WebPlugin* plugin() { return m_webPlugin; } + void setPlugin(WebPlugin* plugin) { m_webPlugin = plugin; } + + // Printing interface. The plugin can support custom printing + // (which means it controls the layout, number of pages etc). + // Whether the plugin supports its own paginated print. The other print + // interface methods are called only if this method returns true. + bool supportsPaginatedPrint() const; + // Sets up printing at the given print rect and printer DPI. printableArea + // is in points (a point is 1/72 of an inch).Returns the number of pages to + // be printed at these settings. + int printBegin(const WebCore::IntRect& printableArea, int printerDPI) const; + // Prints the page specified by pageNumber (0-based index) into the supplied canvas. + bool printPage(int pageNumber, WebCore::GraphicsContext* gc); + // Ends the print operation. + void printEnd(); + + // Copy the selected text. + void copy(); + // Resource load events for the plugin's source data: void didReceiveResponse(const WebCore::ResourceResponse&); void didReceiveData(const char *data, int dataLength); @@ -91,9 +113,6 @@ public: NPObject* scriptableObject(); - // This cannot be null. - WebPlugin* plugin() { return m_webPlugin; } - void willDestroyPluginLoadObserver(WebPluginLoadObserver*); private: @@ -103,6 +122,7 @@ private: ~WebPluginContainerImpl(); void handleMouseEvent(WebCore::MouseEvent*); + void handleWheelEvent(WebCore::WheelEvent*); void handleKeyboardEvent(WebCore::KeyboardEvent*); void calculateGeometry(const WebCore::IntRect& frameRect, diff --git a/WebKit/chromium/src/WebPluginDocument.cpp b/WebKit/chromium/src/WebPluginDocument.cpp new file mode 100644 index 0000000..8f794ad --- /dev/null +++ b/WebKit/chromium/src/WebPluginDocument.cpp @@ -0,0 +1,72 @@ +/* + * 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 "WebPluginDocument.h" + +#include "Document.h" +#include "PluginDocument.h" + +#include "WebPluginContainerImpl.h" + +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + + +WebPlugin* WebPluginDocument::plugin() +{ + if (!isPluginDocument()) + return 0; + PluginDocument* doc = unwrap<PluginDocument>(); + WebPluginContainerImpl* container = static_cast<WebPluginContainerImpl*>(static_cast<PluginDocument*>(doc)->pluginWidget()); + return container->plugin(); +} + + +WebPluginDocument::WebPluginDocument(const PassRefPtr<PluginDocument>& elem) + : WebDocument(elem) +{ +} + +WebPluginDocument& WebPluginDocument::operator=(const PassRefPtr<PluginDocument>& elem) +{ + m_private = elem; + return *this; +} + +WebPluginDocument::operator PassRefPtr<PluginDocument>() const +{ + return static_cast<PluginDocument*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebPluginListBuilderImpl.cpp b/WebKit/chromium/src/WebPluginListBuilderImpl.cpp index 6926a2d..d0f7324 100644 --- a/WebKit/chromium/src/WebPluginListBuilderImpl.cpp +++ b/WebKit/chromium/src/WebPluginListBuilderImpl.cpp @@ -41,27 +41,25 @@ namespace WebKit { void WebPluginListBuilderImpl::addPlugin(const WebString& name, const WebString& description, const WebString& fileName) { - PluginInfo* info = new PluginInfo(); - info->name = name; - info->desc = description; - info->file = fileName; + PluginInfo info; + info.name = name; + info.desc = description; + info.file = fileName; m_results->append(info); } void WebPluginListBuilderImpl::addMediaTypeToLastPlugin(const WebString& name, const WebString& description) { - MimeClassInfo* info = new MimeClassInfo(); - info->type = name; - info->desc = description; - m_results->last()->mimes.append(info); + MimeClassInfo info; + info.type = name; + info.desc = description; + m_results->last().mimes.append(info); } void WebPluginListBuilderImpl::addFileExtensionToLastMediaType(const WebString& extension) { - MimeClassInfo* info = m_results->last()->mimes.last(); - if (!info->suffixes.isEmpty()) - info->suffixes.append(','); - info->suffixes.append(extension); + MimeClassInfo& info = m_results->last().mimes.last(); + info.extensions.append(extension); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebPluginListBuilderImpl.h b/WebKit/chromium/src/WebPluginListBuilderImpl.h index 7a8a497..3d7977a 100644 --- a/WebKit/chromium/src/WebPluginListBuilderImpl.h +++ b/WebKit/chromium/src/WebPluginListBuilderImpl.h @@ -40,7 +40,7 @@ namespace WebKit { class WebPluginListBuilderImpl : public WebPluginListBuilder { public: - WebPluginListBuilderImpl(Vector<WebCore::PluginInfo*>* results) : m_results(results) { } + WebPluginListBuilderImpl(Vector<WebCore::PluginInfo>* results) : m_results(results) { } // WebPluginListBuilder methods: virtual void addPlugin(const WebString& name, const WebString& description, const WebString& fileName); @@ -48,7 +48,7 @@ public: virtual void addFileExtensionToLastMediaType(const WebString& extension); private: - Vector<WebCore::PluginInfo*>* m_results; + Vector<WebCore::PluginInfo>* m_results; }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebPluginLoadObserver.h b/WebKit/chromium/src/WebPluginLoadObserver.h index 097d08d..7bd06eb 100644 --- a/WebKit/chromium/src/WebPluginLoadObserver.h +++ b/WebKit/chromium/src/WebPluginLoadObserver.h @@ -31,7 +31,7 @@ #ifndef WebPluginLoadObserver_h #define WebPluginLoadObserver_h -#include "../public/WebURL.h" +#include "WebURL.h" namespace WebKit { diff --git a/WebKit/chromium/src/WebPopupMenuImpl.cpp b/WebKit/chromium/src/WebPopupMenuImpl.cpp index f6d360e..75d6cc1 100644 --- a/WebKit/chromium/src/WebPopupMenuImpl.cpp +++ b/WebKit/chromium/src/WebPopupMenuImpl.cpp @@ -56,7 +56,8 @@ namespace WebKit { WebPopupMenu* WebPopupMenu::create(WebWidgetClient* client) { - return new WebPopupMenuImpl(client); + // Pass the WebPopupMenuImpl's self-reference to the caller. + return adoptRef(new WebPopupMenuImpl(client)).leakRef(); } // WebWidget ------------------------------------------------------------------ @@ -230,18 +231,28 @@ void WebPopupMenuImpl::setFocus(bool enable) { } -bool WebPopupMenuImpl::handleCompositionEvent( - WebCompositionCommand command, int cursorPosition, int targetStart, - int targetEnd, const WebString& imeString) +bool WebPopupMenuImpl::setComposition( + const WebString& text, const WebVector<WebCompositionUnderline>& underlines, + int selectionStart, int selectionEnd) { return false; } -bool WebPopupMenuImpl::queryCompositionStatus(bool* enabled, WebRect* caretRect) +bool WebPopupMenuImpl::confirmComposition() { return false; } +WebTextInputType WebPopupMenuImpl::textInputType() +{ + return WebTextInputTypeNone; +} + +WebRect WebPopupMenuImpl::caretOrSelectionBounds() +{ + return WebRect(); +} + void WebPopupMenuImpl::setTextDirection(WebTextDirection direction) { } @@ -250,18 +261,29 @@ void WebPopupMenuImpl::setTextDirection(WebTextDirection direction) //----------------------------------------------------------------------------- // WebCore::HostWindow -void WebPopupMenuImpl::repaint(const IntRect& paintRect, - bool contentChanged, - bool immediate, - bool repaintContentOnly) +void WebPopupMenuImpl::invalidateContents(const IntRect&, bool) +{ + notImplemented(); +} + +void WebPopupMenuImpl::invalidateWindow(const IntRect&, bool) { - // Ignore spurious calls. - if (!contentChanged || paintRect.isEmpty()) + notImplemented(); +} + +void WebPopupMenuImpl::invalidateContentsAndWindow(const IntRect& paintRect, bool /*immediate*/) +{ + if (paintRect.isEmpty()) return; if (m_client) m_client->didInvalidateRect(paintRect); } +void WebPopupMenuImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) +{ + invalidateContentsAndWindow(updateRect, immediate); +} + void WebPopupMenuImpl::scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect) @@ -296,6 +318,10 @@ void WebPopupMenuImpl::scrollbarsModeDidChange() const // Nothing to be done since we have no concept of different scrollbar modes. } +void WebPopupMenuImpl::setCursor(const WebCore::Cursor&) +{ +} + //----------------------------------------------------------------------------- // WebCore::FramelessScrollViewClient diff --git a/WebKit/chromium/src/WebPopupMenuImpl.h b/WebKit/chromium/src/WebPopupMenuImpl.h index 13eb674..edbb4ab 100644 --- a/WebKit/chromium/src/WebPopupMenuImpl.h +++ b/WebKit/chromium/src/WebPopupMenuImpl.h @@ -31,14 +31,10 @@ #ifndef WebPopupMenuImpl_h #define WebPopupMenuImpl_h -// FIXME: Add this to FramelessScrollViewClient.h -namespace WebCore { class FramelessScrollView; } - #include "FramelessScrollViewClient.h" -// FIXME: remove the relative paths once glue/ consumers are removed. -#include "../public/WebPoint.h" -#include "../public/WebPopupMenu.h" -#include "../public/WebSize.h" +#include "WebPoint.h" +#include "WebPopupMenu.h" +#include "WebSize.h" #include <wtf/RefCounted.h> namespace WebCore { @@ -70,11 +66,15 @@ public: virtual bool handleInputEvent(const WebInputEvent&); virtual void mouseCaptureLost(); virtual void setFocus(bool enable); - virtual bool handleCompositionEvent( - WebCompositionCommand command, int cursorPosition, - int targetStart, int targetEnd, const WebString& text); - virtual bool queryCompositionStatus(bool* enabled, WebRect* caretRect); + virtual bool setComposition( + const WebString& text, + const WebVector<WebCompositionUnderline>& underlines, + int selectionStart, int selectionEnd); + virtual bool confirmComposition(); + virtual WebTextInputType textInputType(); + virtual WebRect caretOrSelectionBounds(); virtual void setTextDirection(WebTextDirection direction); + virtual bool isAcceleratedCompositingActive() const { return false; } // WebPopupMenuImpl void Init(WebCore::FramelessScrollView* widget, @@ -98,9 +98,10 @@ public: ~WebPopupMenuImpl(); // WebCore::HostWindow methods: - virtual void repaint( - const WebCore::IntRect&, bool contentChanged, bool immediate = false, - bool repaintContentOnly = false); + virtual void invalidateContents(const WebCore::IntRect&, bool); + virtual void invalidateWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsAndWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool); virtual void scroll( const WebCore::IntSize& scrollDelta, const WebCore::IntRect& scrollRect, const WebCore::IntRect& clipRect); @@ -109,6 +110,7 @@ public: virtual PlatformPageClient platformPageClient() const { return 0; } virtual void scrollRectIntoView(const WebCore::IntRect&, const WebCore::ScrollView*) const; virtual void scrollbarsModeDidChange() const; + virtual void setCursor(const WebCore::Cursor&); // WebCore::FramelessScrollViewClient methods: virtual void popupClosed(WebCore::FramelessScrollView*); diff --git a/WebKit/chromium/src/WebRuntimeFeatures.cpp b/WebKit/chromium/src/WebRuntimeFeatures.cpp index ad84764..efb287c 100644 --- a/WebKit/chromium/src/WebRuntimeFeatures.cpp +++ b/WebKit/chromium/src/WebRuntimeFeatures.cpp @@ -31,7 +31,7 @@ #include "config.h" #include "WebRuntimeFeatures.h" -#include "Database.h" +#include "AbstractDatabase.h" #include "RuntimeEnabledFeatures.h" #include "WebMediaPlayerClientImpl.h" #include "WebSocket.h" @@ -43,14 +43,14 @@ namespace WebKit { void WebRuntimeFeatures::enableDatabase(bool enable) { #if ENABLE(DATABASE) - Database::setIsAvailable(enable); + AbstractDatabase::setIsAvailable(enable); #endif } bool WebRuntimeFeatures::isDatabaseEnabled() { #if ENABLE(DATABASE) - return Database::isAvailable(); + return AbstractDatabase::isAvailable(); #else return false; #endif @@ -184,4 +184,56 @@ bool WebRuntimeFeatures::isIndexedDatabaseEnabled() #endif } +void WebRuntimeFeatures::enableWebGL(bool enable) +{ +#if ENABLE(3D_CANVAS) + RuntimeEnabledFeatures::setWebGLEnabled(enable); +#endif +} + +bool WebRuntimeFeatures::isWebGLEnabled() +{ +#if ENABLE(3D_CANVAS) + return RuntimeEnabledFeatures::webGLRenderingContextEnabled(); +#else + return false; +#endif +} + +void WebRuntimeFeatures::enablePushState(bool enable) +{ + RuntimeEnabledFeatures::setPushStateEnabled(enable); +} + +bool WebRuntimeFeatures::isPushStateEnabled(bool enable) +{ + return RuntimeEnabledFeatures::pushStateEnabled(); +} + +void WebRuntimeFeatures::enableTouch(bool enable) +{ +#if ENABLE(TOUCH_EVENTS) + RuntimeEnabledFeatures::setTouchEnabled(enable); +#endif +} + +bool WebRuntimeFeatures::isTouchEnabled() +{ +#if ENABLE(TOUCH_EVENTS) + return RuntimeEnabledFeatures::touchEnabled(); +#else + return false; +#endif +} + +void WebRuntimeFeatures::enableDeviceOrientation(bool enable) +{ + RuntimeEnabledFeatures::setDeviceOrientationEnabled(enable); +} + +bool WebRuntimeFeatures::isDeviceOrientationEnabled() +{ + return RuntimeEnabledFeatures::deviceOrientationEnabled(); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebScrollbarImpl.cpp b/WebKit/chromium/src/WebScrollbarImpl.cpp new file mode 100644 index 0000000..8bf5340 --- /dev/null +++ b/WebKit/chromium/src/WebScrollbarImpl.cpp @@ -0,0 +1,297 @@ +/* + * 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 "WebScrollbarImpl.h" + +#include "GraphicsContext.h" +#include "KeyboardCodes.h" +#include "PlatformContextSkia.h" +#include "Scrollbar.h" +#include "ScrollbarTheme.h" +#include "ScrollTypes.h" +#include "WebCanvas.h" +#include "WebInputEvent.h" +#include "WebInputEventConversion.h" +#include "WebRect.h" +#include "WebScrollbarClient.h" +#include "WebVector.h" +#include "WebViewImpl.h" + +using namespace std; +using namespace WebCore; + +namespace WebKit { + +WebScrollbar* WebScrollbar::create(WebScrollbarClient* client, Orientation orientation) +{ + return new WebScrollbarImpl(client, orientation); +} + +int WebScrollbar::defaultThickness() +{ + return ScrollbarTheme::nativeTheme()->scrollbarThickness(); +} + +WebScrollbarImpl::WebScrollbarImpl(WebScrollbarClient* client, Orientation orientation) + : m_client(client) +{ + m_scrollbar = Scrollbar::createNativeScrollbar( + static_cast<ScrollbarClient*>(this), + static_cast<ScrollbarOrientation>(orientation), + RegularScrollbar); +} + +WebScrollbarImpl::~WebScrollbarImpl() +{ +} + +void WebScrollbarImpl::setLocation(const WebRect& rect) +{ + WebCore::IntRect oldRect = m_scrollbar->frameRect(); + m_scrollbar->setFrameRect(rect); + if (WebRect(oldRect) != rect) + m_scrollbar->invalidate(); + + int length = m_scrollbar->orientation() == HorizontalScrollbar ? m_scrollbar->width() : m_scrollbar->height(); + int pageStep = max(max<int>(length * Scrollbar::minFractionToStepWhenPaging(), length - Scrollbar::maxOverlapBetweenPages()), 1); + m_scrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep); + m_scrollbar->setEnabled(m_scrollbar->totalSize() > length); + m_scrollbar->setProportion(length, m_scrollbar->totalSize()); +} + +int WebScrollbarImpl::value() const +{ + return m_scrollbar->value(); +} + +void WebScrollbarImpl::setValue(int position) +{ + m_scrollbar->setValue(position); +} + +void WebScrollbarImpl::setDocumentSize(int size) +{ + int length = m_scrollbar->orientation() == HorizontalScrollbar ? m_scrollbar->width() : m_scrollbar->height(); + m_scrollbar->setEnabled(size > length); + m_scrollbar->setProportion(length, size); +} + +void WebScrollbarImpl::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier) +{ + WebCore::ScrollDirection dir; + bool horizontal = m_scrollbar->orientation() == HorizontalScrollbar; + if (direction == ScrollForward) + dir = horizontal ? ScrollRight : ScrollDown; + else + dir = horizontal ? ScrollLeft : ScrollUp; + m_scrollbar->scroll(dir, static_cast<WebCore::ScrollGranularity>(granularity), multiplier); +} + +void WebScrollbarImpl::paint(WebCanvas* canvas, const WebRect& rect) +{ +#if WEBKIT_USING_CG + GraphicsContext gc(canvas); +#elif WEBKIT_USING_SKIA + PlatformContextSkia context(canvas); + + // PlatformGraphicsContext is actually a pointer to PlatformContextSkia + GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context)); +#else + notImplemented(); +#endif + + m_scrollbar->paint(&gc, rect); +} + +bool WebScrollbarImpl::handleInputEvent(const WebInputEvent& event) +{ + switch (event.type) { + case WebInputEvent::MouseDown: + return onMouseDown(event); + case WebInputEvent::MouseUp: + return onMouseUp(event); + case WebInputEvent::MouseMove: + return onMouseMove(event); + case WebInputEvent::MouseLeave: + return onMouseLeave(event); + case WebInputEvent::MouseWheel: + return onMouseWheel(event); + case WebInputEvent::KeyDown: + return onKeyDown(event); + case WebInputEvent::Undefined: + case WebInputEvent::MouseEnter: + case WebInputEvent::RawKeyDown: + case WebInputEvent::KeyUp: + case WebInputEvent::Char: + case WebInputEvent::TouchStart: + case WebInputEvent::TouchMove: + case WebInputEvent::TouchEnd: + case WebInputEvent::TouchCancel: + default: + break; + } + return false; +} + +bool WebScrollbarImpl::onMouseDown(const WebInputEvent& event) +{ + WebMouseEvent mousedown = *static_cast<const WebMouseEvent*>(&event); + if (!m_scrollbar->frameRect().contains(mousedown.x, mousedown.y)) + return false; + + mousedown.x -= m_scrollbar->x(); + mousedown.y -= m_scrollbar->y(); + m_scrollbar->mouseDown(PlatformMouseEventBuilder(m_scrollbar.get(), mousedown)); + return true; + } + +bool WebScrollbarImpl::onMouseUp(const WebInputEvent& event) +{ + if (m_scrollbar->pressedPart() == NoPart) + return false; + + return m_scrollbar->mouseUp(); +} + +bool WebScrollbarImpl::onMouseMove(const WebInputEvent& event) +{ + WebMouseEvent mousemove = *static_cast<const WebMouseEvent*>(&event); + if (m_scrollbar->frameRect().contains(mousemove.x, mousemove.y) + || m_scrollbar->pressedPart() != NoPart) { + mousemove.x -= m_scrollbar->x(); + mousemove.y -= m_scrollbar->y(); + return m_scrollbar->mouseMoved(PlatformMouseEventBuilder(m_scrollbar.get(), mousemove)); + } + + if (m_scrollbar->hoveredPart() != NoPart) + m_scrollbar->mouseExited(); + return false; +} + +bool WebScrollbarImpl::onMouseLeave(const WebInputEvent& event) +{ + if (m_scrollbar->hoveredPart() == NoPart) + return false; + + return m_scrollbar->mouseExited(); +} + +bool WebScrollbarImpl::onMouseWheel(const WebInputEvent& event) +{ + // Same logic as in Scrollview.cpp. If we can move at all, we'll accept the event. + WebMouseWheelEvent mousewheel = *static_cast<const WebMouseWheelEvent*>(&event); + int maxScrollDelta = m_scrollbar->maximum() - m_scrollbar->value(); + float delta = m_scrollbar->orientation() == HorizontalScrollbar ? mousewheel.deltaX : mousewheel.deltaY; + if ((delta < 0 && maxScrollDelta > 0) || (delta > 0 && m_scrollbar->value() > 0)) { + if (mousewheel.scrollByPage) { + ASSERT(m_scrollbar->orientation() == VerticalScrollbar); + bool negative = delta < 0; + delta = max(max<int>(m_scrollbar->visibleSize() * Scrollbar::minFractionToStepWhenPaging(), m_scrollbar->visibleSize() - Scrollbar::maxOverlapBetweenPages()), 1); + if (negative) + delta *= -1; + } + m_scrollbar->setValue(m_scrollbar->value() - delta); + return true; + } + + return false; + } + +bool WebScrollbarImpl::onKeyDown(const WebInputEvent& event) +{ + WebKeyboardEvent keyboard = *static_cast<const WebKeyboardEvent*>(&event); + int keyCode; + // We have to duplicate this logic from WebViewImpl because there it uses + // Char and RawKeyDown events, which don't exist at this point. + if (keyboard.windowsKeyCode == VKEY_SPACE) + keyCode = ((keyboard.modifiers & WebInputEvent::ShiftKey) ? VKEY_PRIOR : VKEY_NEXT); + else { + if (keyboard.modifiers == WebInputEvent::ControlKey) { + // Match FF behavior in the sense that Ctrl+home/end are the only Ctrl + // key combinations which affect scrolling. Safari is buggy in the + // sense that it scrolls the page for all Ctrl+scrolling key + // combinations. For e.g. Ctrl+pgup/pgdn/up/down, etc. + switch (keyboard.windowsKeyCode) { + case VKEY_HOME: + case VKEY_END: + break; + default: + return false; + } + } + + if (keyboard.isSystemKey || (keyboard.modifiers & WebInputEvent::ShiftKey)) + return false; + + keyCode = keyboard.windowsKeyCode; + } + WebCore::ScrollDirection scrollDirection; + WebCore::ScrollGranularity scrollGranularity; + if (WebViewImpl::mapKeyCodeForScroll(keyCode, &scrollDirection, &scrollGranularity)) { + // Will return false if scroll direction wasn't compatible with this scrollbar. + return m_scrollbar->scroll(scrollDirection, scrollGranularity); + } + return false; +} + +void WebScrollbarImpl::valueChanged(WebCore::Scrollbar*) +{ + m_client->valueChanged(this); +} + +void WebScrollbarImpl::invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect& rect) +{ + WebRect webrect(rect); + webrect.x += m_scrollbar->x(); + webrect.y += m_scrollbar->y(); + m_client->invalidateScrollbarRect(this, webrect); +} + +bool WebScrollbarImpl::isActive() const +{ + return true; +} + +bool WebScrollbarImpl::scrollbarCornerPresent() const +{ + return false; +} + +void WebScrollbarImpl::getTickmarks(Vector<WebCore::IntRect>& tickmarks) const +{ + WebVector<WebRect> ticks; + m_client->getTickmarks(const_cast<WebScrollbarImpl*>(this), &ticks); + tickmarks.resize(ticks.size()); + for (size_t i = 0; i < ticks.size(); ++i) + tickmarks[i] = ticks[i]; +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebScrollbarImpl.h b/WebKit/chromium/src/WebScrollbarImpl.h new file mode 100644 index 0000000..a041ccc --- /dev/null +++ b/WebKit/chromium/src/WebScrollbarImpl.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * 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 WebScrollbarImpl_h +#define WebScrollbarImpl_h + +#include "ScrollbarClient.h" +#include "WebScrollbar.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { +class Scrollbar; +} + +namespace WebKit { + +class WebScrollbarImpl : public WebScrollbar, + public WebCore::ScrollbarClient { +public: + WebScrollbarImpl(WebScrollbarClient*, Orientation orientation); + ~WebScrollbarImpl(); + + // WebKit::WebScrollbar methods + virtual void setLocation(const WebRect&); + virtual int value() const; + virtual void setValue(int position); + virtual void setDocumentSize(int size); + virtual void scroll(ScrollDirection, ScrollGranularity, float multiplier); + virtual void paint(WebCanvas*, const WebRect&); + virtual bool handleInputEvent(const WebInputEvent&); + + // WebCore::ScrollbarClient methods + virtual void valueChanged(WebCore::Scrollbar*); + virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&); + virtual bool isActive() const; + virtual bool scrollbarCornerPresent() const; + virtual void getTickmarks(Vector<WebCore::IntRect>&) const; + +private: + bool onMouseDown(const WebInputEvent& event); + bool onMouseUp(const WebInputEvent& event); + bool onMouseMove(const WebInputEvent& event); + bool onMouseLeave(const WebInputEvent& event); + bool onMouseWheel(const WebInputEvent& event); + bool onKeyDown(const WebInputEvent& event); + + WebScrollbarClient* m_client; + + RefPtr<WebCore::Scrollbar> m_scrollbar; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/WebSearchableFormData.cpp b/WebKit/chromium/src/WebSearchableFormData.cpp index eddaffe..14ece13 100644 --- a/WebKit/chromium/src/WebSearchableFormData.cpp +++ b/WebKit/chromium/src/WebSearchableFormData.cpp @@ -62,7 +62,7 @@ void GetFormEncoding(const HTMLFormElement* form, TextEncoding* encoding) return; } const Frame* frame = form->document()->frame(); - *encoding = frame ? TextEncoding(frame->loader()->encoding()) : Latin1Encoding(); + *encoding = frame ? TextEncoding(frame->loader()->writer()->encoding()) : Latin1Encoding(); } // Returns true if the submit request results in an HTTP URL. @@ -77,7 +77,8 @@ bool IsHTTPFormSubmit(const HTMLFormElement* form) HTMLFormControlElement* GetButtonToActivate(HTMLFormElement* form) { HTMLFormControlElement* firstSubmitButton = 0; - for (Vector<HTMLFormControlElement*>::const_iterator i(form->formElements.begin()); i != form->formElements.end(); ++i) { + // FIXME: Consider refactoring this code so that we don't call form->associatedElements() twice. + for (Vector<HTMLFormControlElement*>::const_iterator i(form->associatedElements().begin()); i != form->associatedElements().end(); ++i) { HTMLFormControlElement* formElement = *i; if (formElement->isActivatedSubmit()) // There's a button that is already activated for submit, return 0. @@ -154,7 +155,8 @@ bool HasSuitableTextElement(const HTMLFormElement* form, Vector<char>* encodedSt *encodingName = encoding.name(); HTMLInputElement* textElement = 0; - for (Vector<HTMLFormControlElement*>::const_iterator i(form->formElements.begin()); i != form->formElements.end(); ++i) { + // FIXME: Consider refactoring this code so that we don't call form->associatedElements() twice. + for (Vector<HTMLFormControlElement*>::const_iterator i(form->associatedElements().begin()); i != form->associatedElements().end(); ++i) { HTMLFormControlElement* formElement = *i; if (formElement->disabled() || formElement->name().isNull()) continue; @@ -185,8 +187,8 @@ bool HasSuitableTextElement(const HTMLFormElement* form, Vector<char>* encodedSt if (!formElement->appendFormData(dataList, false)) continue; - const Vector<FormDataList::Item>& itemList = dataList.list(); - if (isTextElement && !itemList.isEmpty()) { + const BlobItemList& items = dataList.items(); + if (isTextElement && !items.isEmpty()) { if (textElement) { // The auto-complete bar only knows how to fill in one value. // This form has multiple fields; don't treat it as searchable. @@ -194,20 +196,22 @@ bool HasSuitableTextElement(const HTMLFormElement* form, Vector<char>* encodedSt } textElement = static_cast<HTMLInputElement*>(formElement); } - for (Vector<FormDataList::Item>::const_iterator j(itemList.begin()); j != itemList.end(); ++j) { + for (BlobItemList::const_iterator j(items.begin()); j != items.end(); ++j) { + const StringBlobItem* item = (*j)->toStringBlobItem(); + ASSERT(item); // Handle ISINDEX / <input name=isindex> specially, but only if it's // the first entry. - if (!encodedString->isEmpty() || j->data() != "isindex") { + if (!encodedString->isEmpty() || item->cstr() != "isindex") { if (!encodedString->isEmpty()) encodedString->append('&'); - FormDataBuilder::encodeStringAsFormData(*encodedString, j->data()); + FormDataBuilder::encodeStringAsFormData(*encodedString, item->cstr()); encodedString->append('='); } ++j; if (formElement == textElement) encodedString->append("{searchTerms}", 13); else - FormDataBuilder::encodeStringAsFormData(*encodedString, j->data()); + FormDataBuilder::encodeStringAsFormData(*encodedString, item->cstr()); } } diff --git a/WebKit/chromium/src/WebSecurityOrigin.cpp b/WebKit/chromium/src/WebSecurityOrigin.cpp index 81546da..8685738 100644 --- a/WebKit/chromium/src/WebSecurityOrigin.cpp +++ b/WebKit/chromium/src/WebSecurityOrigin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,8 +31,10 @@ #include "config.h" #include "WebSecurityOrigin.h" +#include "KURL.h" #include "SecurityOrigin.h" #include "WebString.h" +#include "WebURL.h" #include <wtf/PassRefPtr.h> using namespace WebCore; @@ -42,9 +44,9 @@ namespace WebKit { class WebSecurityOriginPrivate : public SecurityOrigin { }; -WebSecurityOrigin* WebSecurityOrigin::createFromDatabaseIdentifier(const WebString& databaseIdentifier) +WebSecurityOrigin WebSecurityOrigin::createFromDatabaseIdentifier(const WebString& databaseIdentifier) { - return new WebSecurityOrigin(SecurityOrigin::createFromDatabaseIdentifier(databaseIdentifier)); + return WebSecurityOrigin(SecurityOrigin::createFromDatabaseIdentifier(databaseIdentifier)); } WebSecurityOrigin WebSecurityOrigin::createFromString(const WebString& origin) @@ -52,6 +54,11 @@ WebSecurityOrigin WebSecurityOrigin::createFromString(const WebString& origin) return WebSecurityOrigin(SecurityOrigin::createFromString(origin)); } +WebSecurityOrigin WebSecurityOrigin::create(const WebURL& url) +{ + return WebSecurityOrigin(SecurityOrigin::create(url)); +} + void WebSecurityOrigin::reset() { assign(0); @@ -89,18 +96,37 @@ bool WebSecurityOrigin::isEmpty() const return m_private->isEmpty(); } +bool WebSecurityOrigin::canAccess(const WebSecurityOrigin& other) const +{ + ASSERT(m_private); + ASSERT(other.m_private); + return m_private->canAccess(other.m_private); +} + +bool WebSecurityOrigin::canRequest(const WebURL& url) const +{ + ASSERT(m_private); + return m_private->canRequest(url); +} + WebString WebSecurityOrigin::toString() const { ASSERT(m_private); return m_private->toString(); } -WebString WebSecurityOrigin::databaseIdentifier() +WebString WebSecurityOrigin::databaseIdentifier() const { ASSERT(m_private); return m_private->databaseIdentifier(); } +bool WebSecurityOrigin::canAccessPasswordManager() const +{ + ASSERT(m_private); + return m_private->canAccessPasswordManager(); +} + WebSecurityOrigin::WebSecurityOrigin(const WTF::PassRefPtr<WebCore::SecurityOrigin>& origin) : m_private(static_cast<WebSecurityOriginPrivate*>(origin.releaseRef())) { diff --git a/WebKit/chromium/src/WebSecurityPolicy.cpp b/WebKit/chromium/src/WebSecurityPolicy.cpp index 48b445c..58d0893 100644 --- a/WebKit/chromium/src/WebSecurityPolicy.cpp +++ b/WebKit/chromium/src/WebSecurityPolicy.cpp @@ -32,6 +32,7 @@ #include "WebSecurityPolicy.h" #include "FrameLoader.h" +#include "SchemeRegistry.h" #include "SecurityOrigin.h" #include "WebString.h" @@ -43,27 +44,44 @@ namespace WebKit { void WebSecurityPolicy::registerURLSchemeAsLocal(const WebString& scheme) { - SecurityOrigin::registerURLSchemeAsLocal(scheme); + SchemeRegistry::registerURLSchemeAsLocal(scheme); } void WebSecurityPolicy::registerURLSchemeAsNoAccess(const WebString& scheme) { - SecurityOrigin::registerURLSchemeAsNoAccess(scheme); + SchemeRegistry::registerURLSchemeAsNoAccess(scheme); } -void WebSecurityPolicy::whiteListAccessFromOrigin(const WebURL& sourceOrigin, +void WebSecurityPolicy::registerURLSchemeAsSecure(const WebString& scheme) +{ + SchemeRegistry::registerURLSchemeAsSecure(scheme); +} + +void WebSecurityPolicy::addOriginAccessWhitelistEntry( + const WebURL& sourceOrigin, + const WebString& destinationProtocol, + const WebString& destinationHost, + bool allowDestinationSubdomains) +{ + SecurityOrigin::addOriginAccessWhitelistEntry( + *SecurityOrigin::create(sourceOrigin), destinationProtocol, + destinationHost, allowDestinationSubdomains); +} + +void WebSecurityPolicy::removeOriginAccessWhitelistEntry( + const WebURL& sourceOrigin, const WebString& destinationProtocol, const WebString& destinationHost, bool allowDestinationSubdomains) { - SecurityOrigin::whiteListAccessFromOrigin( + SecurityOrigin::removeOriginAccessWhitelistEntry( *SecurityOrigin::create(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); } -void WebSecurityPolicy::resetOriginAccessWhiteLists() +void WebSecurityPolicy::resetOriginAccessWhitelists() { - SecurityOrigin::resetOriginAccessWhiteLists(); + SecurityOrigin::resetOriginAccessWhitelists(); } bool WebSecurityPolicy::shouldHideReferrer(const WebURL& url, const WebString& referrer) diff --git a/WebKit/chromium/src/WebSelectElement.cpp b/WebKit/chromium/src/WebSelectElement.cpp new file mode 100644 index 0000000..79a4d85 --- /dev/null +++ b/WebKit/chromium/src/WebSelectElement.cpp @@ -0,0 +1,80 @@ +/* + * 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 "WebSelectElement.h" + +#include "HTMLNames.h" +#include "HTMLOptionElement.h" +#include "HTMLSelectElement.h" +#include "WebString.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +void WebSelectElement::setValue(const WebString& value) +{ + unwrap<HTMLSelectElement>()->setValue(value); +} + +WebString WebSelectElement::value() +{ + return unwrap<HTMLSelectElement>()->value(); +} + +WebVector<WebElement> WebSelectElement::listItems() +{ + const Vector<Element*>& sourceItems = unwrap<HTMLSelectElement>()->listItems(); + WebVector<WebElement> items(sourceItems.size()); + for (size_t i = 0; i < sourceItems.size(); ++i) + items[i] = WebElement(static_cast<HTMLElement*>(sourceItems[i])); + + return items; +} + +WebSelectElement::WebSelectElement(const PassRefPtr<HTMLSelectElement>& elem) + : WebFormControlElement(elem) +{ +} + +WebSelectElement& WebSelectElement::operator=(const PassRefPtr<HTMLSelectElement>& elem) +{ + m_private = elem; + return *this; +} + +WebSelectElement::operator PassRefPtr<HTMLSelectElement>() const +{ + return static_cast<HTMLSelectElement*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebSerializedScriptValue.cpp b/WebKit/chromium/src/WebSerializedScriptValue.cpp new file mode 100644 index 0000000..7149a4d --- /dev/null +++ b/WebKit/chromium/src/WebSerializedScriptValue.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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 "WebSerializedScriptValue.h" + +#include "SerializedScriptValue.h" +#include "WebString.h" + +using namespace WebCore; + +namespace WebKit { + +WebSerializedScriptValue WebSerializedScriptValue::fromString(const WebString& s) +{ + return SerializedScriptValue::createFromWire(s); +} + +WebSerializedScriptValue WebSerializedScriptValue::createInvalid() +{ + return SerializedScriptValue::create(); +} + +void WebSerializedScriptValue::reset() +{ + m_private.reset(); +} + +void WebSerializedScriptValue::assign(const WebSerializedScriptValue& other) +{ + m_private = other.m_private; +} + +WebString WebSerializedScriptValue::toString() const +{ + return m_private->toWireString(); +} + +WebSerializedScriptValue::WebSerializedScriptValue(const PassRefPtr<SerializedScriptValue>& value) + : m_private(value) +{ +} + +WebSerializedScriptValue& WebSerializedScriptValue::operator=(const PassRefPtr<SerializedScriptValue>& value) +{ + m_private = value; + return *this; +} + +WebSerializedScriptValue::operator PassRefPtr<SerializedScriptValue>() const +{ + return m_private.get(); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebSettingsImpl.cpp b/WebKit/chromium/src/WebSettingsImpl.cpp index 5cfbd4f..6569e2e 100644 --- a/WebKit/chromium/src/WebSettingsImpl.cpp +++ b/WebKit/chromium/src/WebSettingsImpl.cpp @@ -185,6 +185,11 @@ void WebSettingsImpl::setUserStyleSheetLocation(const WebURL& location) m_settings->setUserStyleSheetLocation(location); } +void WebSettingsImpl::setAuthorAndUserStylesEnabled(bool enabled) +{ + m_settings->setAuthorAndUserStylesEnabled(enabled); +} + void WebSettingsImpl::setUsesPageCache(bool usesPageCache) { m_settings->setUsesPageCache(usesPageCache); @@ -195,6 +200,11 @@ void WebSettingsImpl::setDownloadableBinaryFontsEnabled(bool enabled) m_settings->setDownloadableBinaryFontsEnabled(enabled); } +void WebSettingsImpl::setJavaScriptCanAccessClipboard(bool enabled) +{ + m_settings->setJavaScriptCanAccessClipboard(enabled); +} + void WebSettingsImpl::setXSSAuditorEnabled(bool enabled) { m_settings->setXSSAuditorEnabled(enabled); @@ -226,14 +236,14 @@ void WebSettingsImpl::setShouldPaintCustomScrollbars(bool enabled) m_settings->setShouldPaintCustomScrollbars(enabled); } -void WebSettingsImpl::setDatabasesEnabled(bool enabled) +void WebSettingsImpl::setAllowUniversalAccessFromFileURLs(bool allow) { - m_settings->setDatabasesEnabled(enabled); + m_settings->setAllowUniversalAccessFromFileURLs(allow); } -void WebSettingsImpl::setAllowUniversalAccessFromFileURLs(bool allow) +void WebSettingsImpl::setAllowFileAccessFromFileURLs(bool allow) { - m_settings->setAllowUniversalAccessFromFileURLs(allow); + m_settings->setAllowFileAccessFromFileURLs(allow); } void WebSettingsImpl::setTextDirectionSubmenuInclusionBehaviorNeverIncluded() @@ -254,9 +264,34 @@ void WebSettingsImpl::setExperimentalWebGLEnabled(bool enabled) m_settings->setWebGLEnabled(enabled); } -void WebSettingsImpl::setGeolocationEnabled(bool enabled) +void WebSettingsImpl::setShowDebugBorders(bool show) +{ + m_settings->setShowDebugBorders(show); +} + +void WebSettingsImpl::setEditingBehavior(EditingBehavior behavior) +{ + m_settings->setEditingBehaviorType(static_cast<WebCore::EditingBehaviorType>(behavior)); +} + +void WebSettingsImpl::setAcceleratedCompositingEnabled(bool enabled) +{ + m_settings->setAcceleratedCompositingEnabled(enabled); +} + +void WebSettingsImpl::setAccelerated2dCanvasEnabled(bool enabled) +{ + m_settings->setAccelerated2dCanvasEnabled(enabled); +} + +void WebSettingsImpl::setHTML5ParserEnabled(bool enabled) +{ + m_settings->setHTML5ParserEnabled(enabled); +} + +void WebSettingsImpl::setMemoryInfoEnabled(bool enabled) { - m_settings->setGeolocationEnabled(enabled); + m_settings->setMemoryInfoEnabled(enabled); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebSettingsImpl.h b/WebKit/chromium/src/WebSettingsImpl.h index 3b69fe6..9eedba8 100644 --- a/WebKit/chromium/src/WebSettingsImpl.h +++ b/WebKit/chromium/src/WebSettingsImpl.h @@ -31,8 +31,7 @@ #ifndef WebSettingsImpl_h #define WebSettingsImpl_h -// TODO(jorlow): Remove this hack once WebView is free of glue. -#include "../public/WebSettings.h" +#include "WebSettings.h" namespace WebCore { class Settings; @@ -71,19 +70,26 @@ public: virtual void setJavaEnabled(bool); virtual void setAllowScriptsToCloseWindows(bool); virtual void setUserStyleSheetLocation(const WebURL&); + virtual void setAuthorAndUserStylesEnabled(bool); virtual void setUsesPageCache(bool); virtual void setDownloadableBinaryFontsEnabled(bool); + virtual void setJavaScriptCanAccessClipboard(bool); virtual void setXSSAuditorEnabled(bool); virtual void setLocalStorageEnabled(bool); virtual void setEditableLinkBehaviorNeverLive(); virtual void setFontRenderingModeNormal(); virtual void setShouldPaintCustomScrollbars(bool); - virtual void setDatabasesEnabled(bool); virtual void setAllowUniversalAccessFromFileURLs(bool); + virtual void setAllowFileAccessFromFileURLs(bool); virtual void setTextDirectionSubmenuInclusionBehaviorNeverIncluded(); virtual void setOfflineWebApplicationCacheEnabled(bool); virtual void setExperimentalWebGLEnabled(bool); - virtual void setGeolocationEnabled(bool); + virtual void setShowDebugBorders(bool); + virtual void setEditingBehavior(EditingBehavior); + virtual void setAcceleratedCompositingEnabled(bool); + virtual void setAccelerated2dCanvasEnabled(bool); + virtual void setHTML5ParserEnabled(bool); + virtual void setMemoryInfoEnabled(bool); private: WebCore::Settings* m_settings; diff --git a/WebKit/chromium/src/WebSharedWorkerImpl.cpp b/WebKit/chromium/src/WebSharedWorkerImpl.cpp index 4547336..e73c0f4 100644 --- a/WebKit/chromium/src/WebSharedWorkerImpl.cpp +++ b/WebKit/chromium/src/WebSharedWorkerImpl.cpp @@ -31,7 +31,7 @@ #include "config.h" #include "WebSharedWorkerImpl.h" -#include "GenericWorkerTask.h" +#include "CrossThreadTask.h" #include "KURL.h" #include "MessageEvent.h" #include "MessagePortChannel.h" @@ -85,14 +85,14 @@ void WebSharedWorkerImpl::connectTask(ScriptExecutionContext* context, WebShared { // Wrap the passed-in channel in a MessagePort, and send it off via a connect event. RefPtr<MessagePort> port = MessagePort::create(*context); - port->entangle(channel.release()); + port->entangle(channel); ASSERT(context->isWorkerContext()); WorkerContext* workerContext = static_cast<WorkerContext*>(context); ASSERT(workerContext->isSharedWorkerContext()); workerContext->toSharedWorkerContext()->dispatchEvent(createConnectEvent(port)); } -void WebSharedWorkerImpl::startWorkerContext(const WebURL& url, const WebString& name, const WebString& userAgent, const WebString& sourceCode) +void WebSharedWorkerImpl::startWorkerContext(const WebURL& url, const WebString& name, const WebString& userAgent, const WebString& sourceCode, long long) { initializeLoader(url); setWorkerThread(SharedWorkerThread::create(name, url, userAgent, sourceCode, *this, *this)); diff --git a/WebKit/chromium/src/WebSharedWorkerImpl.h b/WebKit/chromium/src/WebSharedWorkerImpl.h index 7c10d76..b591c7b 100644 --- a/WebKit/chromium/src/WebSharedWorkerImpl.h +++ b/WebKit/chromium/src/WebSharedWorkerImpl.h @@ -51,7 +51,7 @@ public: // WebSharedWorker methods: virtual bool isStarted(); - virtual void startWorkerContext(const WebURL&, const WebString& name, const WebString& userAgent, const WebString& sourceCode); + virtual void startWorkerContext(const WebURL&, const WebString& name, const WebString& userAgent, const WebString& sourceCode, long long); virtual void connect(WebMessagePortChannel*, ConnectListener*); virtual void terminateWorkerContext(); virtual void clientDestroyed(); diff --git a/WebKit/chromium/src/WebStorageAreaImpl.cpp b/WebKit/chromium/src/WebStorageAreaImpl.cpp index 9a7fd5c..2cecfe9 100644 --- a/WebKit/chromium/src/WebStorageAreaImpl.cpp +++ b/WebKit/chromium/src/WebStorageAreaImpl.cpp @@ -66,7 +66,7 @@ WebString WebStorageAreaImpl::getItem(const WebString& key) return m_storageArea->getItem(key); } -void WebStorageAreaImpl::setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue) +void WebStorageAreaImpl::setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue, WebFrame*) { int exceptionCode = 0; diff --git a/WebKit/chromium/src/WebStorageAreaImpl.h b/WebKit/chromium/src/WebStorageAreaImpl.h index e9a11c2..2869fc9 100644 --- a/WebKit/chromium/src/WebStorageAreaImpl.h +++ b/WebKit/chromium/src/WebStorageAreaImpl.h @@ -45,7 +45,7 @@ public: virtual unsigned length(); virtual WebString key(unsigned index); virtual WebString getItem(const WebString& key); - virtual void setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue); + virtual void setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue, WebFrame*); virtual void removeItem(const WebString& key, const WebURL& url, WebString& oldValue); virtual void clear(const WebURL& url, bool& somethingCleared); diff --git a/WebKit/chromium/src/WebStorageNamespaceImpl.cpp b/WebKit/chromium/src/WebStorageNamespaceImpl.cpp index e6f6548..5fc6e16 100644 --- a/WebKit/chromium/src/WebStorageNamespaceImpl.cpp +++ b/WebKit/chromium/src/WebStorageNamespaceImpl.cpp @@ -45,9 +45,9 @@ WebStorageNamespace* WebStorageNamespace::createLocalStorageNamespace(const WebS return new WebStorageNamespaceImpl(WebCore::StorageNamespaceImpl::localStorageNamespace(path, quota)); } -WebStorageNamespace* WebStorageNamespace::createSessionStorageNamespace() +WebStorageNamespace* WebStorageNamespace::createSessionStorageNamespace(unsigned quota) { - return new WebStorageNamespaceImpl(WebCore::StorageNamespaceImpl::sessionStorageNamespace()); + return new WebStorageNamespaceImpl(WebCore::StorageNamespaceImpl::sessionStorageNamespace(quota)); } WebStorageNamespaceImpl::WebStorageNamespaceImpl(PassRefPtr<WebCore::StorageNamespace> storageNamespace) diff --git a/WebKit/chromium/src/WebString.cpp b/WebKit/chromium/src/WebString.cpp index 36d5f86..a61a059 100644 --- a/WebKit/chromium/src/WebString.cpp +++ b/WebKit/chromium/src/WebString.cpp @@ -32,8 +32,8 @@ #include "WebString.h" #include "AtomicString.h" -#include "CString.h" #include "PlatformString.h" +#include <wtf/text/CString.h> #include "WebCString.h" diff --git a/WebKit/chromium/src/WebTextRun.cpp b/WebKit/chromium/src/WebTextRun.cpp new file mode 100644 index 0000000..58d9fac --- /dev/null +++ b/WebKit/chromium/src/WebTextRun.cpp @@ -0,0 +1,45 @@ +/* + * 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 "WebTextRun.h" + +#include "TextRun.h" + +using namespace WebCore; + +namespace WebKit { + +WebTextRun::operator WebCore::TextRun() const +{ + return TextRun(text, false, 0, 0, rtl, directionalOverride); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebURLError.cpp b/WebKit/chromium/src/WebURLError.cpp index a038aee..ef32b5c 100644 --- a/WebKit/chromium/src/WebURLError.cpp +++ b/WebKit/chromium/src/WebURLError.cpp @@ -31,9 +31,9 @@ #include "config.h" #include "WebURLError.h" -#include "CString.h" #include "KURL.h" #include "ResourceError.h" +#include <wtf/text/CString.h> using namespace WebCore; diff --git a/WebKit/chromium/src/WebURLLoadTiming.cpp b/WebKit/chromium/src/WebURLLoadTiming.cpp new file mode 100644 index 0000000..27ed362 --- /dev/null +++ b/WebKit/chromium/src/WebURLLoadTiming.cpp @@ -0,0 +1,192 @@ +/* + * 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 "WebURLLoadTiming.h" + +#include "ResourceLoadTiming.h" +#include "WebString.h" + +using namespace WebCore; + +namespace WebKit { + +void WebURLLoadTiming::initialize() +{ + m_private = ResourceLoadTiming::create(); +} + +void WebURLLoadTiming::reset() +{ + m_private.reset(); +} + +void WebURLLoadTiming::assign(const WebURLLoadTiming& other) +{ + m_private = other.m_private; +} + +double WebURLLoadTiming::requestTime() const +{ + return m_private->requestTime; +} + +void WebURLLoadTiming::setRequestTime(double time) +{ + m_private->requestTime = time; +} + +int WebURLLoadTiming::proxyStart() const +{ + return m_private->proxyStart; +} + +void WebURLLoadTiming::setProxyStart(int start) +{ + m_private->proxyStart = start; +} + +int WebURLLoadTiming::proxyEnd() const +{ + return m_private->proxyEnd; +} + +void WebURLLoadTiming::setProxyEnd(int end) +{ + m_private->proxyEnd = end; +} + +int WebURLLoadTiming::dnsStart() const +{ + return m_private->dnsStart; +} + +void WebURLLoadTiming::setDNSStart(int start) +{ + m_private->dnsStart = start; +} + +int WebURLLoadTiming::dnsEnd() const +{ + return m_private->dnsEnd; +} + +void WebURLLoadTiming::setDNSEnd(int end) +{ + m_private->dnsEnd = end; +} + +int WebURLLoadTiming::connectStart() const +{ + return m_private->connectStart; +} + +void WebURLLoadTiming::setConnectStart(int start) +{ + m_private->connectStart = start; +} + +int WebURLLoadTiming::connectEnd() const +{ + return m_private->connectEnd; +} + +void WebURLLoadTiming::setConnectEnd(int end) +{ + m_private->connectEnd = end; +} + +int WebURLLoadTiming::sendStart() const +{ + return m_private->sendStart; +} + +void WebURLLoadTiming::setSendStart(int start) +{ + m_private->sendStart = start; +} + +int WebURLLoadTiming::sendEnd() const +{ + return m_private->sendEnd; +} + +void WebURLLoadTiming::setSendEnd(int end) +{ + m_private->sendEnd = end; +} + +int WebURLLoadTiming::receiveHeadersEnd() const +{ + return m_private->receiveHeadersEnd; +} + +void WebURLLoadTiming::setReceiveHeadersEnd(int end) +{ + m_private->receiveHeadersEnd = end; +} + +int WebURLLoadTiming::sslStart() const +{ + return m_private->sslStart; +} + +void WebURLLoadTiming::setSSLStart(int start) +{ + m_private->sslStart = start; +} + +int WebURLLoadTiming::sslEnd() const +{ + return m_private->sslEnd; +} + +void WebURLLoadTiming::setSSLEnd(int end) +{ + m_private->sslEnd = end; +} + +WebURLLoadTiming::WebURLLoadTiming(const PassRefPtr<ResourceLoadTiming>& value) + : m_private(value) +{ +} + +WebURLLoadTiming& WebURLLoadTiming::operator=(const PassRefPtr<ResourceLoadTiming>& value) +{ + m_private = value; + return *this; +} + +WebURLLoadTiming::operator PassRefPtr<ResourceLoadTiming>() const +{ + return m_private.get(); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebURLRequest.cpp b/WebKit/chromium/src/WebURLRequest.cpp index 46fa842..69dfac4 100644 --- a/WebKit/chromium/src/WebURLRequest.cpp +++ b/WebKit/chromium/src/WebURLRequest.cpp @@ -194,6 +194,16 @@ void WebURLRequest::setReportUploadProgress(bool reportUploadProgress) m_private->m_resourceRequest->setReportUploadProgress(reportUploadProgress); } +bool WebURLRequest::reportLoadTiming() const +{ + return m_private->m_resourceRequest->reportLoadTiming(); +} + +void WebURLRequest::setReportLoadTiming(bool reportLoadTiming) +{ + m_private->m_resourceRequest->setReportLoadTiming(reportLoadTiming); +} + WebURLRequest::TargetType WebURLRequest::targetType() const { return static_cast<TargetType>(m_private->m_resourceRequest->targetType()); @@ -235,6 +245,16 @@ void WebURLRequest::setAppCacheHostID(int appCacheHostID) m_private->m_resourceRequest->setAppCacheHostID(appCacheHostID); } +bool WebURLRequest::downloadToFile() const +{ + return m_private->m_downloadToFile; +} + +void WebURLRequest::setDownloadToFile(bool downloadToFile) +{ + m_private->m_downloadToFile = downloadToFile; +} + ResourceRequest& WebURLRequest::toMutableResourceRequest() { ASSERT(m_private); diff --git a/WebKit/chromium/src/WebURLRequestPrivate.h b/WebKit/chromium/src/WebURLRequestPrivate.h index 2f7c25f..79f6451 100644 --- a/WebKit/chromium/src/WebURLRequestPrivate.h +++ b/WebKit/chromium/src/WebURLRequestPrivate.h @@ -37,13 +37,19 @@ namespace WebKit { class WebURLRequestPrivate { public: - WebURLRequestPrivate() : m_resourceRequest(0), m_allowStoredCredentials(true) { } + WebURLRequestPrivate() + : m_resourceRequest(0) + , m_allowStoredCredentials(true) + , m_downloadToFile(false) { } // Called by WebURLRequest when it no longer needs this object. virtual void dispose() = 0; WebCore::ResourceRequest* m_resourceRequest; bool m_allowStoredCredentials; + + // FIXME: Move this to ResourceRequest once we have an internal consumer. + bool m_downloadToFile; }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebURLResponse.cpp b/WebKit/chromium/src/WebURLResponse.cpp index 95e0be2..0511f8d 100644 --- a/WebKit/chromium/src/WebURLResponse.cpp +++ b/WebKit/chromium/src/WebURLResponse.cpp @@ -32,12 +32,16 @@ #include "WebURLResponse.h" #include "ResourceResponse.h" +#include "ResourceLoadTiming.h" #include "WebHTTPHeaderVisitor.h" #include "WebString.h" #include "WebURL.h" +#include "WebURLLoadTiming.h" #include "WebURLResponsePrivate.h" +#include <wtf/RefPtr.h> + using namespace WebCore; namespace WebKit { @@ -93,6 +97,47 @@ void WebURLResponse::setURL(const WebURL& url) m_private->m_resourceResponse->setURL(url); } +unsigned WebURLResponse::connectionID() const +{ + return m_private->m_resourceResponse->connectionID(); +} + +void WebURLResponse::setConnectionID(unsigned connectionID) +{ + m_private->m_resourceResponse->setConnectionID(connectionID); +} + +bool WebURLResponse::connectionReused() const +{ + return m_private->m_resourceResponse->connectionReused(); +} + +void WebURLResponse::setConnectionReused(bool connectionReused) +{ + m_private->m_resourceResponse->setConnectionReused(connectionReused); +} + +WebURLLoadTiming WebURLResponse::loadTiming() +{ + return WebURLLoadTiming(m_private->m_resourceResponse->resourceLoadTiming()); +} + +void WebURLResponse::setLoadTiming(const WebURLLoadTiming& timing) +{ + RefPtr<ResourceLoadTiming> loadTiming = PassRefPtr<ResourceLoadTiming>(timing); + m_private->m_resourceResponse->setResourceLoadTiming(loadTiming.release()); +} + +double WebURLResponse::responseTime() const +{ + return m_private->m_resourceResponse->responseTime(); +} + +void WebURLResponse::setResponseTime(double responseTime) +{ + m_private->m_resourceResponse->setResponseTime(responseTime); +} + WebString WebURLResponse::mimeType() const { return m_private->m_resourceResponse->mimeType(); @@ -165,6 +210,8 @@ void WebURLResponse::setHTTPHeaderField(const WebString& name, const WebString& void WebURLResponse::addHTTPHeaderField(const WebString& name, const WebString& value) { + if (name.isNull() || value.isNull()) + return; // FIXME: Add an addHTTPHeaderField method to ResourceResponse. const HTTPHeaderMap& map = m_private->m_resourceResponse->httpHeaderFields(); String valueStr(value); @@ -255,6 +302,16 @@ const ResourceResponse& WebURLResponse::toResourceResponse() const return *m_private->m_resourceResponse; } +bool WebURLResponse::wasCached() const +{ + return m_private->m_resourceResponse->wasCached(); +} + +void WebURLResponse::setWasCached(bool value) +{ + m_private->m_resourceResponse->setWasCached(value); +} + bool WebURLResponse::wasFetchedViaSPDY() const { return m_private->m_resourceResponse->wasFetchedViaSPDY(); @@ -265,6 +322,56 @@ void WebURLResponse::setWasFetchedViaSPDY(bool value) m_private->m_resourceResponse->setWasFetchedViaSPDY(value); } +bool WebURLResponse::wasNpnNegotiated() const +{ + return m_private->m_resourceResponse->wasNpnNegotiated(); +} + +void WebURLResponse::setWasNpnNegotiated(bool value) +{ + m_private->m_resourceResponse->setWasNpnNegotiated(value); +} + +bool WebURLResponse::wasAlternateProtocolAvailable() const +{ + return m_private->m_resourceResponse->wasAlternateProtocolAvailable(); +} + +void WebURLResponse::setWasAlternateProtocolAvailable(bool value) +{ + m_private->m_resourceResponse->setWasAlternateProtocolAvailable(value); +} + +bool WebURLResponse::wasFetchedViaProxy() const +{ + return m_private->m_resourceResponse->wasFetchedViaProxy(); +} + +void WebURLResponse::setWasFetchedViaProxy(bool value) +{ + m_private->m_resourceResponse->setWasFetchedViaProxy(value); +} + +bool WebURLResponse::isMultipartPayload() const +{ + return m_private->m_resourceResponse->isMultipartPayload(); +} + +void WebURLResponse::setIsMultipartPayload(bool value) +{ + m_private->m_resourceResponse->setIsMultipartPayload(value); +} + +WebString WebURLResponse::downloadFilePath() const +{ + return m_private->m_downloadFilePath; +} + +void WebURLResponse::setDownloadFilePath(const WebString& downloadFilePath) +{ + m_private->m_downloadFilePath = downloadFilePath; +} + void WebURLResponse::assign(WebURLResponsePrivate* p) { // Subclasses may call this directly so a self-assignment check is needed diff --git a/WebKit/chromium/src/WebURLResponsePrivate.h b/WebKit/chromium/src/WebURLResponsePrivate.h index 716c8db..dc5ce22 100644 --- a/WebKit/chromium/src/WebURLResponsePrivate.h +++ b/WebKit/chromium/src/WebURLResponsePrivate.h @@ -31,6 +31,8 @@ #ifndef WebURLResponsePrivate_h #define WebURLResponsePrivate_h +#include "WebString.h" + namespace WebCore { class ResourceResponse; } namespace WebKit { @@ -43,6 +45,9 @@ public: virtual void dispose() = 0; WebCore::ResourceResponse* m_resourceResponse; + + // FIXME: Move this to ResourceResponse once we have an internal consumer. + WebString m_downloadFilePath; }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp index ce03523..bb6d07c 100644 --- a/WebKit/chromium/src/WebViewImpl.cpp +++ b/WebKit/chromium/src/WebViewImpl.cpp @@ -32,9 +32,9 @@ #include "WebViewImpl.h" #include "AutoFillPopupMenuClient.h" -#include "AutocompletePopupMenuClient.h" #include "AXObjectCache.h" #include "Chrome.h" +#include "CompositionUnderlineVectorBuilder.h" #include "ContextMenu.h" #include "ContextMenuController.h" #include "ContextMenuItem.h" @@ -45,6 +45,7 @@ #include "DocumentLoader.h" #include "DOMUtilitiesPrivate.h" #include "DragController.h" +#include "DragScrollTimer.h" #include "DragData.h" #include "Editor.h" #include "EventHandler.h" @@ -53,10 +54,12 @@ #include "FrameLoader.h" #include "FrameTree.h" #include "FrameView.h" +#include "GLES2Context.h" +#include "GLES2ContextInternal.h" #include "GraphicsContext.h" -#include "HitTestResult.h" #include "HTMLInputElement.h" #include "HTMLMediaElement.h" +#include "HitTestResult.h" #include "HTMLNames.h" #include "Image.h" #include "InspectorController.h" @@ -72,8 +75,8 @@ #include "PlatformContextSkia.h" #include "PlatformKeyboardEvent.h" #include "PlatformMouseEvent.h" +#include "PlatformThemeChromiumGtk.h" #include "PlatformWheelEvent.h" -#include "PluginInfoStore.h" #include "PopupMenuChromium.h" #include "PopupMenuClient.h" #include "ProgressTracker.h" @@ -82,15 +85,24 @@ #include "SecurityOrigin.h" #include "SelectionController.h" #include "Settings.h" +#include "Timer.h" #include "TypingCommand.h" +#include "Vector.h" #include "WebAccessibilityObject.h" #include "WebDevToolsAgentPrivate.h" +#include "WebDevToolsAgentImpl.h" #include "WebDragData.h" #include "WebFrameImpl.h" +#include "WebImage.h" +#include "WebInputElement.h" #include "WebInputEvent.h" #include "WebInputEventConversion.h" +#include "WebKit.h" +#include "WebKitClient.h" #include "WebMediaPlayerAction.h" #include "WebNode.h" +#include "WebPlugin.h" +#include "WebPluginContainerImpl.h" #include "WebPoint.h" #include "WebPopupMenuImpl.h" #include "WebRect.h" @@ -98,15 +110,14 @@ #include "WebString.h" #include "WebVector.h" #include "WebViewClient.h" +#include "wtf/OwnPtr.h" #if OS(WINDOWS) -#include "KeyboardCodesWin.h" #include "RenderThemeChromiumWin.h" #else #if OS(LINUX) #include "RenderThemeChromiumLinux.h" #endif -#include "KeyboardCodesPosix.h" #include "RenderTheme.h" #endif @@ -133,8 +144,8 @@ static const double maxTextSizeMultiplier = 3.0; const char* pageGroupName = "default"; // Used to defer all page activity in cases where the embedder wishes to run -// a nested event loop. -static PageGroupLoadDeferrer* pageGroupLoadDeferrer; +// a nested event loop. Using a stack enables nesting of message loop invocations. +static Vector<PageGroupLoadDeferrer*> pageGroupLoadDeferrerStack; // Ensure that the WebDragOperation enum values stay in sync with the original // DragOperation constants. @@ -149,15 +160,12 @@ COMPILE_ASSERT_MATCHING_ENUM(DragOperationMove); COMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete); COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery); -// Note that focusOnShow is false so that the suggestions popup is shown not -// activated. We need the page to still have focus so the user can keep typing -// while the popup is showing. -static const PopupContainerSettings suggestionsPopupSettings = { - false, // focusOnShow - false, // setTextOnIndexChange - false, // acceptOnAbandon - true, // loopSelectionNavigation - true, // restrictWidthOfListBox. Same as other browser (Fx, IE, and safari) +static const PopupContainerSettings autoFillPopupSettings = { + false, // setTextOnIndexChange + 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.) // 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. @@ -166,9 +174,10 @@ static const PopupContainerSettings suggestionsPopupSettings = { // WebView ---------------------------------------------------------------- -WebView* WebView::create(WebViewClient* client) +WebView* WebView::create(WebViewClient* client, WebDevToolsAgentClient* devToolsClient) { - return new WebViewImpl(client); + // Pass the WebViewImpl's self-reference to the caller. + return adoptRef(new WebViewImpl(client, devToolsClient)).leakRef(); } void WebView::updateVisitedLinkState(unsigned long long linkHash) @@ -183,24 +192,23 @@ void WebView::resetVisitedLinkState() void WebView::willEnterModalLoop() { - // It is not valid to nest more than once. - ASSERT(!pageGroupLoadDeferrer); - PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); ASSERT(pageGroup); - ASSERT(!pageGroup->pages().isEmpty()); - // Pick any page in the page group since we are deferring all pages. - pageGroupLoadDeferrer = new PageGroupLoadDeferrer(*pageGroup->pages().begin(), true); + if (pageGroup->pages().isEmpty()) + pageGroupLoadDeferrerStack.append(static_cast<PageGroupLoadDeferrer*>(0)); + else { + // Pick any page in the page group since we are deferring all pages. + pageGroupLoadDeferrerStack.append(new PageGroupLoadDeferrer(*pageGroup->pages().begin(), true)); + } } void WebView::didExitModalLoop() { - // The embedder must have called willEnterNestedEventLoop. - ASSERT(pageGroupLoadDeferrer); + ASSERT(pageGroupLoadDeferrerStack.size()); - delete pageGroupLoadDeferrer; - pageGroupLoadDeferrer = 0; + delete pageGroupLoadDeferrerStack.last(); + pageGroupLoadDeferrerStack.removeLast(); } void WebViewImpl::initializeMainFrame(WebFrameClient* frameClient) @@ -216,7 +224,7 @@ void WebViewImpl::initializeMainFrame(WebFrameClient* frameClient) SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForLocalOnly); } -WebViewImpl::WebViewImpl(WebViewClient* client) +WebViewImpl::WebViewImpl(WebViewClient* client, WebDevToolsAgentClient* devToolsClient) : m_client(client) , m_backForwardListClientImpl(this) , m_chromeClientImpl(this) @@ -240,31 +248,50 @@ WebViewImpl::WebViewImpl(WebViewClient* client) , m_dropEffect(DropEffectDefault) , m_operationsAllowed(WebDragOperationNone) , m_dragOperation(WebDragOperationNone) - , m_suggestionsPopupShowing(false) - , m_suggestionsPopupClient(0) - , m_suggestionsPopup(0) + , m_autoFillPopupShowing(false) + , m_autoFillPopupClient(0) + , m_autoFillPopup(0) , m_isTransparent(false) , m_tabsToLinks(false) + , m_dragScrollTimer(new DragScrollTimer()) +#if USE(ACCELERATED_COMPOSITING) + , m_layerRenderer(0) + , m_isAcceleratedCompositingActive(false) +#endif +#if ENABLE(INPUT_SPEECH) + , m_speechInputClient(client) +#endif + , m_gles2Context(0) { // WebKit/win/WebView.cpp does the same thing, except they call the // KJS specific wrapper around this method. We need to have threading // initialized because CollatorICU requires it. WTF::initializeThreading(); + WTF::initializeMainThread(); // set to impossible point so we always get the first mouse pos m_lastMousePosition = WebPoint(-1, -1); + if (devToolsClient) + m_devToolsAgent = new WebDevToolsAgentImpl(this, devToolsClient); + + Page::PageClients pageClients; + pageClients.chromeClient = &m_chromeClientImpl; + pageClients.contextMenuClient = &m_contextMenuClientImpl; + pageClients.editorClient = &m_editorClientImpl; + pageClients.dragClient = &m_dragClientImpl; + pageClients.inspectorClient = &m_inspectorClientImpl; +#if ENABLE(INPUT_SPEECH) + pageClients.speechInputClient = &m_speechInputClient; +#endif + m_page.set(new Page(pageClients)); + // the page will take ownership of the various clients - m_page.set(new Page(&m_chromeClientImpl, - &m_contextMenuClientImpl, - &m_editorClientImpl, - &m_dragClientImpl, - &m_inspectorClientImpl, - 0, - 0)); m_page->backForwardList()->setClient(&m_backForwardListClientImpl); m_page->setGroupName(pageGroupName); + + m_inspectorSettingsMap.set(new SettingsMap); } WebViewImpl::~WebViewImpl() @@ -326,19 +353,34 @@ void WebViewImpl::mouseDown(const WebMouseEvent& event) if (!mainFrameImpl() || !mainFrameImpl()->frameView()) return; + // If there is a select popup open, close it as the user is clicking on + // the page (outside of the popup). We also save it so we can prevent a + // click on the select element from immediately reopening the popup. + RefPtr<WebCore::PopupContainer> selectPopup; + if (event.button == WebMouseEvent::ButtonLeft) { + selectPopup = m_selectPopup; + hideSelectPopup(); + ASSERT(!m_selectPopup); + } + m_lastMouseDownPoint = WebPoint(event.x, event.y); - // If a text field that has focus is clicked again, we should display the - // suggestions popup. RefPtr<Node> clickedNode; if (event.button == WebMouseEvent::ButtonLeft) { + IntPoint point(event.x, event.y); + point = m_page->mainFrame()->view()->windowToContents(point); + HitTestResult result(m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, false)); + Node* hitNode = result.innerNonSharedNode(); + + // Take capture on a mouse down on a plugin so we can send it mouse events. + if (hitNode && hitNode->renderer() && hitNode->renderer()->isEmbeddedObject()) + m_mouseCaptureNode = hitNode; + + // If a text field that has focus is clicked again, we should display the + // AutoFill popup. RefPtr<Node> focusedNode = focusedWebCoreNode(); if (focusedNode.get() && toHTMLInputElement(focusedNode.get())) { - IntPoint point(event.x, event.y); - point = m_page->mainFrame()->view()->windowToContents(point); - HitTestResult result(point); - result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, false); - if (result.innerNonSharedNode() == focusedNode) { + if (hitNode == focusedNode) { // Already focused text field was clicked, let's remember this. If // focus has not changed after the mouse event is processed, we'll // trigger the autocomplete. @@ -347,14 +389,23 @@ void WebViewImpl::mouseDown(const WebMouseEvent& event) } } + mainFrameImpl()->frame()->loader()->resetMultipleFormSubmissionProtection(); + mainFrameImpl()->frame()->eventHandler()->handleMousePressEvent( PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event)); if (clickedNode.get() && clickedNode == focusedWebCoreNode()) { - // Focus has not changed, show the suggestions popup. + // Focus has not changed, show the AutoFill popup. static_cast<EditorClientImpl*>(m_page->editorClient())-> showFormAutofillForNode(clickedNode.get()); } + if (m_selectPopup && m_selectPopup == selectPopup) { + // That click triggered a select popup which is the same as the one that + // was showing before the click. It means the user clicked the select + // while the popup was showing, and as a result we first closed then + // immediately reopened the select popup. It needs to be closed. + hideSelectPopup(); + } // Dispatch the contextmenu event regardless of if the click was swallowed. // On Windows, we handle it on mouse up, not down. @@ -426,7 +477,7 @@ void WebViewImpl::mouseUp(const WebMouseEvent& event) IntPoint contentPoint = view->windowToContents(clickPoint); HitTestResult hitTestResult = focused->eventHandler()->hitTestResultAtPoint(contentPoint, false, false, ShouldHitTestScrollbars); // We don't want to send a paste when middle clicking a scroll bar or a - // link (which will navigate later in the code). The main scrollbars + // link (which will navigate later in the code). The main scrollbars // have to be handled separately. if (!hitTestResult.scrollbar() && !hitTestResult.isLiveLink() && focused && !view->scrollbarAtPoint(clickPoint)) { Editor* editor = focused->editor(); @@ -439,7 +490,6 @@ void WebViewImpl::mouseUp(const WebMouseEvent& event) } #endif - mouseCaptureLost(); mainFrameImpl()->frame()->eventHandler()->handleMouseReleaseEvent( PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event)); @@ -451,10 +501,10 @@ void WebViewImpl::mouseUp(const WebMouseEvent& event) #endif } -void WebViewImpl::mouseWheel(const WebMouseWheelEvent& event) +bool WebViewImpl::mouseWheel(const WebMouseWheelEvent& event) { PlatformWheelEventBuilder platformEvent(mainFrameImpl()->frameView(), event); - mainFrameImpl()->frame()->eventHandler()->handleWheelEvent(platformEvent); + return mainFrameImpl()->frame()->eventHandler()->handleWheelEvent(platformEvent); } bool WebViewImpl::keyEvent(const WebKeyboardEvent& event) @@ -471,6 +521,10 @@ bool WebViewImpl::keyEvent(const WebKeyboardEvent& event) // event. m_suppressNextKeypressEvent = false; + // Give any select popup a chance at consuming the key event. + if (selectPopupHandleKeyEvent(event)) + return true; + // Give Autocomplete a chance to consume the key events it is interested in. if (autocompleteHandleKeyEvent(event)) return true; @@ -507,17 +561,30 @@ bool WebViewImpl::keyEvent(const WebKeyboardEvent& event) PlatformKeyboardEventBuilder evt(event); if (handler->keyEvent(evt)) { - if (WebInputEvent::RawKeyDown == event.type) - m_suppressNextKeypressEvent = true; + if (WebInputEvent::RawKeyDown == event.type) { + // Suppress the next keypress event unless the focused node is a plug-in node. + // (Flash needs these keypress events to handle non-US keyboards.) + Node* node = frame->document()->focusedNode(); + if (!node || !node->renderer() || !node->renderer()->isEmbeddedObject()) + m_suppressNextKeypressEvent = true; + } return true; } return keyEventDefault(event); } +bool WebViewImpl::selectPopupHandleKeyEvent(const WebKeyboardEvent& event) +{ + if (!m_selectPopup) + return false; + + return m_selectPopup->handleKeyEvent(PlatformKeyboardEventBuilder(event)); +} + bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event) { - if (!m_suggestionsPopupShowing + if (!m_autoFillPopupShowing // Home and End should be left to the text field to process. || event.windowsKeyCode == VKEY_HOME || event.windowsKeyCode == VKEY_END) @@ -525,7 +592,7 @@ bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event) // Pressing delete triggers the removal of the selected suggestion from the DB. if (event.windowsKeyCode == VKEY_DELETE - && m_suggestionsPopup->selectedIndex() != -1) { + && m_autoFillPopup->selectedIndex() != -1) { Node* node = focusedWebCoreNode(); if (!node || (node->nodeType() != Node::ELEMENT_NODE)) { ASSERT_NOT_REACHED(); @@ -537,22 +604,25 @@ bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event) return false; } - int selectedIndex = m_suggestionsPopup->selectedIndex(); - HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element); - WebString name = inputElement->name(); - WebString value = m_autocompletePopupClient->itemText(selectedIndex); + int selectedIndex = m_autoFillPopup->selectedIndex(); + + if (!m_autoFillPopupClient->canRemoveSuggestionAtIndex(selectedIndex)) + return false; + + WebString name = WebInputElement(static_cast<HTMLInputElement*>(element)).nameForAutofill(); + WebString value = m_autoFillPopupClient->itemText(selectedIndex); m_client->removeAutofillSuggestions(name, value); // Update the entries in the currently showing popup to reflect the // deletion. - m_autocompletePopupClient->removeSuggestionAtIndex(selectedIndex); - refreshSuggestionsPopup(); + m_autoFillPopupClient->removeSuggestionAtIndex(selectedIndex); + refreshAutoFillPopup(); return false; } - if (!m_suggestionsPopup->isInterestedInEventForKey(event.windowsKeyCode)) + if (!m_autoFillPopup->isInterestedInEventForKey(event.windowsKeyCode)) return false; - if (m_suggestionsPopup->handleKeyEvent(PlatformKeyboardEventBuilder(event))) { + if (m_autoFillPopup->handleKeyEvent(PlatformKeyboardEventBuilder(event))) { // We need to ignore the next Char event after this otherwise pressing // enter when selecting an item in the menu will go to the page. if (WebInputEvent::RawKeyDown == event.type) @@ -604,62 +674,21 @@ bool WebViewImpl::charEvent(const WebKeyboardEvent& event) return true; } -// The WebViewImpl::SendContextMenuEvent function is based on the Webkit -// function -// bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam) in -// webkit\webkit\win\WebView.cpp. The only significant change in this -// function is the code to convert from a Keyboard event to the Right -// Mouse button up event. -// -// This function is an ugly copy/paste and should be cleaned up when the -// WebKitWin version is cleaned: https://bugs.webkit.org/show_bug.cgi?id=20438 -#if OS(WINDOWS) || OS(LINUX) -// FIXME: implement on Mac -bool WebViewImpl::sendContextMenuEvent(const WebKeyboardEvent& event) +#if ENABLE(TOUCH_EVENTS) +bool WebViewImpl::touchEvent(const WebTouchEvent& event) { - static const int kContextMenuMargin = 1; - Frame* mainFrameImpl = page()->mainFrame(); - FrameView* view = mainFrameImpl->view(); - if (!view) + if (!mainFrameImpl() || !mainFrameImpl()->frameView()) return false; - IntPoint coords(-1, -1); -#if OS(WINDOWS) - int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT); -#else - int rightAligned = 0; + PlatformTouchEventBuilder touchEventBuilder(mainFrameImpl()->frameView(), event); + return mainFrameImpl()->frame()->eventHandler()->handleTouchEvent(touchEventBuilder); +} #endif - IntPoint location; - - - Frame* focusedFrame = page()->focusController()->focusedOrMainFrame(); - Node* focusedNode = focusedFrame->document()->focusedNode(); - Position start = mainFrameImpl->selection()->selection().start(); - - if (focusedFrame->editor() && focusedFrame->editor()->canEdit() && start.node()) { - RenderObject* renderer = start.node()->renderer(); - if (!renderer) - return false; - - RefPtr<Range> selection = mainFrameImpl->selection()->toNormalizedRange(); - IntRect firstRect = mainFrameImpl->firstRectForRange(selection.get()); - - int x = rightAligned ? firstRect.right() : firstRect.x(); - location = IntPoint(x, firstRect.bottom()); - } else if (focusedNode) - location = focusedNode->getRect().bottomLeft(); - else { - location = IntPoint( - rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin, - kContextMenuMargin); - } - - location = view->contentsToWindow(location); - // FIXME: The IntSize(0, -1) is a hack to get the hit-testing to result in - // the selected element. Ideally we'd have the position of a context menu - // event be separate from its target node. - coords = location + IntSize(0, -1); +#if OS(WINDOWS) || OS(LINUX) +// Mac has no way to open a context menu based on a keyboard event. +bool WebViewImpl::sendContextMenuEvent(const WebKeyboardEvent& event) +{ // The contextMenuController() holds onto the last context menu that was // popped up on the page until a new one is created. We need to clear // this menu before propagating the event through the DOM so that we can @@ -668,17 +697,9 @@ bool WebViewImpl::sendContextMenuEvent(const WebKeyboardEvent& event) // not run. page()->contextMenuController()->clearContextMenu(); - focusedFrame->view()->setCursor(pointerCursor()); - WebMouseEvent mouseEvent; - mouseEvent.button = WebMouseEvent::ButtonRight; - mouseEvent.x = coords.x(); - mouseEvent.y = coords.y(); - mouseEvent.type = WebInputEvent::MouseUp; - - PlatformMouseEventBuilder platformEvent(view, mouseEvent); - m_contextMenuAllowed = true; - bool handled = focusedFrame->eventHandler()->sendContextMenuEvent(platformEvent); + Frame* focusedFrame = page()->focusController()->focusedOrMainFrame(); + bool handled = focusedFrame->eventHandler()->sendContextMenuEventForKey(); m_contextMenuAllowed = false; return handled; } @@ -733,45 +754,59 @@ bool WebViewImpl::scrollViewWithKeyboard(int keyCode, int modifiers) { ScrollDirection scrollDirection; ScrollGranularity scrollGranularity; + if (!mapKeyCodeForScroll(keyCode, &scrollDirection, &scrollGranularity)) + return false; + return propagateScroll(scrollDirection, scrollGranularity); +} +bool WebViewImpl::mapKeyCodeForScroll(int keyCode, + WebCore::ScrollDirection* scrollDirection, + WebCore::ScrollGranularity* scrollGranularity) +{ switch (keyCode) { case VKEY_LEFT: - scrollDirection = ScrollLeft; - scrollGranularity = ScrollByLine; + *scrollDirection = ScrollLeft; + *scrollGranularity = ScrollByLine; break; case VKEY_RIGHT: - scrollDirection = ScrollRight; - scrollGranularity = ScrollByLine; + *scrollDirection = ScrollRight; + *scrollGranularity = ScrollByLine; break; case VKEY_UP: - scrollDirection = ScrollUp; - scrollGranularity = ScrollByLine; + *scrollDirection = ScrollUp; + *scrollGranularity = ScrollByLine; break; case VKEY_DOWN: - scrollDirection = ScrollDown; - scrollGranularity = ScrollByLine; + *scrollDirection = ScrollDown; + *scrollGranularity = ScrollByLine; break; case VKEY_HOME: - scrollDirection = ScrollUp; - scrollGranularity = ScrollByDocument; + *scrollDirection = ScrollUp; + *scrollGranularity = ScrollByDocument; break; case VKEY_END: - scrollDirection = ScrollDown; - scrollGranularity = ScrollByDocument; + *scrollDirection = ScrollDown; + *scrollGranularity = ScrollByDocument; break; case VKEY_PRIOR: // page up - scrollDirection = ScrollUp; - scrollGranularity = ScrollByPage; + *scrollDirection = ScrollUp; + *scrollGranularity = ScrollByPage; break; case VKEY_NEXT: // page down - scrollDirection = ScrollDown; - scrollGranularity = ScrollByPage; + *scrollDirection = ScrollDown; + *scrollGranularity = ScrollByPage; break; default: return false; } - return propagateScroll(scrollDirection, scrollGranularity); + return true; +} + +void WebViewImpl::hideSelectPopup() +{ + if (m_selectPopup.get()) + m_selectPopup->hidePopup(); } bool WebViewImpl::propagateScroll(ScrollDirection scrollDirection, @@ -793,6 +828,30 @@ bool WebViewImpl::propagateScroll(ScrollDirection scrollDirection, return scrollHandled; } +void WebViewImpl::popupOpened(WebCore::PopupContainer* popupContainer) +{ + if (popupContainer->popupType() == WebCore::PopupContainer::Select) { + ASSERT(!m_selectPopup); + m_selectPopup = popupContainer; + } +} + +void WebViewImpl::popupClosed(WebCore::PopupContainer* popupContainer) +{ + if (popupContainer->popupType() == WebCore::PopupContainer::Select) { + ASSERT(m_selectPopup.get()); + m_selectPopup = 0; + } +} + +void WebViewImpl::hideAutoFillPopup() +{ + if (m_autoFillPopupShowing) { + m_autoFillPopup->hidePopup(); + m_autoFillPopupShowing = false; + } +} + Frame* WebViewImpl::focusedWebCoreFrame() { return m_page.get() ? m_page->focusController()->focusedOrMainFrame() : 0; @@ -873,9 +932,33 @@ void WebViewImpl::layout() void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect) { - WebFrameImpl* webframe = mainFrameImpl(); - if (webframe) - webframe->paint(canvas, rect); + +#if USE(ACCELERATED_COMPOSITING) + if (!isAcceleratedCompositingActive()) { +#endif + WebFrameImpl* webframe = mainFrameImpl(); + if (webframe) + webframe->paint(canvas, rect); +#if USE(ACCELERATED_COMPOSITING) + } else { + // Draw the contents of the root layer. + updateRootLayerContents(rect); + + WebFrameImpl* webframe = mainFrameImpl(); + if (!webframe) + return; + FrameView* view = webframe->frameView(); + if (!view) + return; + + // The visibleRect includes scrollbars whereas the contentRect doesn't. + IntRect visibleRect = view->visibleContentRect(true); + IntRect contentRect = view->visibleContentRect(false); + + // Ask the layer compositor to redraw all the layers. + m_layerRenderer->drawLayers(rect, visibleRect, contentRect, IntPoint(view->scrollX(), view->scrollY())); + } +#endif } // FIXME: m_currentInputEvent should be removed once ChromeClient::show() can @@ -892,6 +975,38 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent) if (m_ignoreInputEvents) return true; + if (m_mouseCaptureNode.get() && WebInputEvent::isMouseEventType(inputEvent.type)) { + // Save m_mouseCaptureNode since mouseCaptureLost() will clear it. + RefPtr<Node> node = m_mouseCaptureNode; + + // Not all platforms call mouseCaptureLost() directly. + if (inputEvent.type == WebInputEvent::MouseUp) + mouseCaptureLost(); + + AtomicString eventType; + switch (inputEvent.type) { + case WebInputEvent::MouseMove: + eventType = eventNames().mousemoveEvent; + break; + case WebInputEvent::MouseLeave: + eventType = eventNames().mouseoutEvent; + break; + case WebInputEvent::MouseDown: + eventType = eventNames().mousedownEvent; + break; + case WebInputEvent::MouseUp: + eventType = eventNames().mouseupEvent; + break; + default: + ASSERT_NOT_REACHED(); + } + + node->dispatchMouseEvent( + PlatformMouseEventBuilder(mainFrameImpl()->frameView(), *static_cast<const WebMouseEvent*>(&inputEvent)), + eventType); + return true; + } + // FIXME: Remove m_currentInputEvent. // This only exists to allow ChromeClient::show() to know which mouse button // triggered a window.open event. @@ -915,7 +1030,7 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent) break; case WebInputEvent::MouseWheel: - mouseWheel(*static_cast<const WebMouseWheelEvent*>(&inputEvent)); + handled = mouseWheel(*static_cast<const WebMouseWheelEvent*>(&inputEvent)); break; case WebInputEvent::MouseDown: @@ -936,6 +1051,15 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent) handled = charEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent)); break; +#if ENABLE(TOUCH_EVENTS) + case WebInputEvent::TouchStart: + case WebInputEvent::TouchMove: + case WebInputEvent::TouchEnd: + case WebInputEvent::TouchCancel: + handled = touchEvent(*static_cast<const WebTouchEvent*>(&inputEvent)); + break; +#endif + default: handled = false; } @@ -947,6 +1071,7 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent) void WebViewImpl::mouseCaptureLost() { + m_mouseCaptureNode = 0; } void WebViewImpl::setFocus(bool enable) @@ -981,7 +1106,8 @@ void WebViewImpl::setFocus(bool enable) } m_imeAcceptEvents = true; } else { - hideSuggestionsPopup(); + hideAutoFillPopup(); + hideSelectPopup(); // Clear focus on the currently focused frame if any. if (!m_page.get()) @@ -1002,11 +1128,11 @@ void WebViewImpl::setFocus(bool enable) } } -bool WebViewImpl::handleCompositionEvent(WebCompositionCommand command, - int cursorPosition, - int targetStart, - int targetEnd, - const WebString& imeString) +bool WebViewImpl::setComposition( + const WebString& text, + const WebVector<WebCompositionUnderline>& underlines, + int selectionStart, + int selectionEnd) { Frame* focused = focusedWebCoreFrame(); if (!focused || !m_imeAcceptEvents) @@ -1014,13 +1140,12 @@ bool WebViewImpl::handleCompositionEvent(WebCompositionCommand command, Editor* editor = focused->editor(); if (!editor) return false; - if (!editor->canEdit()) { - // The input focus has been moved to another WebWidget object. - // We should use this |editor| object only to complete the ongoing - // composition. - if (!editor->hasComposition()) - return false; - } + + // The input focus has been moved to another WebWidget object. + // We should use this |editor| object only to complete the ongoing + // composition. + if (!editor->canEdit() && !editor->hasComposition()) + return false; // We should verify the parent node of this IME composition node are // editable because JavaScript may delete a parent node of the composition @@ -1033,7 +1158,9 @@ bool WebViewImpl::handleCompositionEvent(WebCompositionCommand command, return false; } - if (command == WebCompositionCommandDiscard) { + // If we're not going to fire a keypress event, then the keydown event was + // canceled. In that case, cancel any existing composition. + if (text.isEmpty() || m_suppressNextKeypressEvent) { // A browser process sent an IPC message which does not contain a valid // string, which means an ongoing composition has been canceled. // If the ongoing composition has been canceled, replace the ongoing @@ -1041,81 +1168,102 @@ bool WebViewImpl::handleCompositionEvent(WebCompositionCommand command, String emptyString; Vector<CompositionUnderline> emptyUnderlines; editor->setComposition(emptyString, emptyUnderlines, 0, 0); - } else { - // A browser process sent an IPC message which contains a string to be - // displayed in this Editor object. - // To display the given string, set the given string to the - // m_compositionNode member of this Editor object and display it. - if (targetStart < 0) - targetStart = 0; - if (targetEnd < 0) - targetEnd = static_cast<int>(imeString.length()); - String compositionString(imeString); - // Create custom underlines. - // To emphasize the selection, the selected region uses a solid black - // for its underline while other regions uses a pale gray for theirs. - Vector<CompositionUnderline> underlines(3); - underlines[0].startOffset = 0; - underlines[0].endOffset = targetStart; - underlines[0].thick = true; - underlines[0].color.setRGB(0xd3, 0xd3, 0xd3); - underlines[1].startOffset = targetStart; - underlines[1].endOffset = targetEnd; - underlines[1].thick = true; - underlines[1].color.setRGB(0x00, 0x00, 0x00); - underlines[2].startOffset = targetEnd; - underlines[2].endOffset = static_cast<int>(imeString.length()); - underlines[2].thick = true; - underlines[2].color.setRGB(0xd3, 0xd3, 0xd3); - // When we use custom underlines, WebKit ("InlineTextBox.cpp" Line 282) - // prevents from writing a text in between 'selectionStart' and - // 'selectionEnd' somehow. - // Therefore, we use the 'cursorPosition' for these arguments so that - // there are not any characters in the above region. - editor->setComposition(compositionString, underlines, - cursorPosition, cursorPosition); - // The given string is a result string, which means the ongoing - // composition has been completed. I have to call the - // Editor::confirmCompletion() and complete this composition. - if (command == WebCompositionCommandConfirm) - editor->confirmComposition(); + return text.isEmpty(); } + // When the range of composition underlines overlap with the range between + // selectionStart and selectionEnd, WebKit somehow won't paint the selection + // at all (see InlineTextBox::paint() function in InlineTextBox.cpp). + // But the selection range actually takes effect. + editor->setComposition(String(text), + CompositionUnderlineVectorBuilder(underlines), + selectionStart, selectionEnd); + return editor->hasComposition(); } -bool WebViewImpl::queryCompositionStatus(bool* enableIME, WebRect* caretRect) +bool WebViewImpl::confirmComposition() +{ + Frame* focused = focusedWebCoreFrame(); + if (!focused || !m_imeAcceptEvents) + return false; + Editor* editor = focused->editor(); + if (!editor || !editor->hasComposition()) + return false; + + // We should verify the parent node of this IME composition node are + // editable because JavaScript may delete a parent node of the composition + // node. In this case, WebKit crashes while deleting texts from the parent + // node, which doesn't exist any longer. + PassRefPtr<Range> range = editor->compositionRange(); + if (range) { + const Node* node = range->startPosition().node(); + if (!node || !node->isContentEditable()) + return false; + } + + editor->confirmComposition(); + return true; +} + +WebTextInputType WebViewImpl::textInputType() { - // Store whether the selected node needs IME and the caret rectangle. - // This process consists of the following four steps: - // 1. Retrieve the selection controller of the focused frame; - // 2. Retrieve the caret rectangle from the controller; - // 3. Convert the rectangle, which is relative to the parent view, to the - // one relative to the client window, and; - // 4. Store the converted rectangle. + WebTextInputType type = WebTextInputTypeNone; const Frame* focused = focusedWebCoreFrame(); if (!focused) - return false; + return type; const Editor* editor = focused->editor(); if (!editor || !editor->canEdit()) - return false; + return type; SelectionController* controller = focused->selection(); if (!controller) - return false; + return type; const Node* node = controller->start().node(); if (!node) - return false; + return type; + + // FIXME: Support more text input types when necessary, eg. Number, + // Date, Email, URL, etc. + if (controller->isInPasswordField()) + type = WebTextInputTypePassword; + else if (node->shouldUseInputMethod()) + type = WebTextInputTypeText; + + return type; +} + +WebRect WebViewImpl::caretOrSelectionBounds() +{ + WebRect rect; + const Frame* focused = focusedWebCoreFrame(); + if (!focused) + return rect; + + SelectionController* controller = focused->selection(); + if (!controller) + return rect; - *enableIME = node->shouldUseInputMethod() && !controller->isInPasswordField(); - const FrameView* view = node->document()->view(); + const FrameView* view = focused->view(); if (!view) - return false; + return rect; - *caretRect = view->contentsToWindow(controller->absoluteCaretBounds()); - return true; + const Node* node = controller->start().node(); + if (!node || !node->renderer()) + return rect; + + if (controller->isCaret()) + rect = view->contentsToWindow(controller->absoluteCaretBounds()); + else if (controller->isRange()) { + node = controller->end().node(); + if (!node || !node->renderer()) + return rect; + RefPtr<Range> range = controller->toNormalizedRange(); + rect = view->contentsToWindow(focused->firstRectForRange(range.get())); + } + return rect; } void WebViewImpl::setTextDirection(WebTextDirection direction) @@ -1151,6 +1299,15 @@ void WebViewImpl::setTextDirection(WebTextDirection direction) } } +bool WebViewImpl::isAcceleratedCompositingActive() const +{ +#if USE(ACCELERATED_COMPOSITING) + return m_isAcceleratedCompositingActive; +#else + return false; +#endif +} + // WebView -------------------------------------------------------------------- WebSettings* WebViewImpl::settings() @@ -1166,7 +1323,7 @@ WebString WebViewImpl::pageEncoding() const if (!m_page.get()) return WebString(); - return m_page->mainFrame()->loader()->encoding(); + return m_page->mainFrame()->loader()->writer()->encoding(); } void WebViewImpl::setPageEncoding(const WebString& encodingName) @@ -1191,7 +1348,7 @@ bool WebViewImpl::dispatchBeforeUnloadEvent() if (!frame) return true; - return frame->shouldClose(); + return frame->loader()->shouldClose(); } void WebViewImpl::dispatchUnloadEvent() @@ -1300,9 +1457,15 @@ int WebViewImpl::setZoomLevel(bool textOnly, int zoomLevel) maxTextSizeMultiplier), minTextSizeMultiplier)); Frame* frame = mainFrameImpl()->frame(); - if (zoomFactor != frame->zoomFactor()) { + FrameView* view = frame->view(); + if (!view) + return m_zoomLevel; + if (zoomFactor != view->zoomFactor()) { + view->setZoomFactor(zoomFactor, textOnly ? ZoomTextOnly : ZoomPage); + WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(frame); + if (pluginContainer) + pluginContainer->plugin()->setZoomFactor(zoomFactor, textOnly); m_zoomLevel = zoomLevel; - frame->setZoomFactor(zoomFactor, textOnly); } return m_zoomLevel; } @@ -1331,6 +1494,9 @@ void WebViewImpl::performMediaPlayerAction(const WebMediaPlayerAction& action, case WebMediaPlayerAction::Loop: mediaElement->setLoop(action.enable); break; + case WebMediaPlayerAction::Controls: + mediaElement->setControls(action.enable); + break; default: ASSERT_NOT_REACHED(); } @@ -1368,6 +1534,15 @@ void WebViewImpl::dragSourceEndedAt( false, 0); m_page->mainFrame()->eventHandler()->dragSourceEndedAt(pme, static_cast<DragOperation>(operation)); + m_dragScrollTimer->stop(); +} + +void WebViewImpl::dragSourceMovedTo( + const WebPoint& clientPoint, + const WebPoint& screenPoint, + WebDragOperation operation) +{ + m_dragScrollTimer->triggerScroll(mainFrameImpl()->frameView(), clientPoint); } void WebViewImpl::dragSourceSystemDragEnded() @@ -1392,26 +1567,7 @@ WebDragOperation WebViewImpl::dragTargetDragEnter( m_dragIdentity = identity; m_operationsAllowed = operationsAllowed; - DragData dragData( - m_currentDragData.get(), - clientPoint, - screenPoint, - static_cast<DragOperation>(operationsAllowed)); - - m_dropEffect = DropEffectDefault; - m_dragTargetDispatch = true; - DragOperation effect = m_page->dragController()->dragEntered(&dragData); - // Mask the operation against the drag source's allowed operations. - if ((effect & dragData.draggingSourceOperationMask()) != effect) - effect = DragOperationNone; - m_dragTargetDispatch = false; - - if (m_dropEffect != DropEffectDefault) { - m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy - : WebDragOperationNone; - } else - m_dragOperation = static_cast<WebDragOperation>(effect); - return m_dragOperation; + return dragTargetDragEnterOrOver(clientPoint, screenPoint, DragEnter); } WebDragOperation WebViewImpl::dragTargetDragOver( @@ -1419,29 +1575,9 @@ WebDragOperation WebViewImpl::dragTargetDragOver( const WebPoint& screenPoint, WebDragOperationsMask operationsAllowed) { - ASSERT(m_currentDragData.get()); - m_operationsAllowed = operationsAllowed; - DragData dragData( - m_currentDragData.get(), - clientPoint, - screenPoint, - static_cast<DragOperation>(operationsAllowed)); - - m_dropEffect = DropEffectDefault; - m_dragTargetDispatch = true; - DragOperation effect = m_page->dragController()->dragUpdated(&dragData); - // Mask the operation against the drag source's allowed operations. - if ((effect & dragData.draggingSourceOperationMask()) != effect) - effect = DragOperationNone; - m_dragTargetDispatch = false; - if (m_dropEffect != DropEffectDefault) { - m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy - : WebDragOperationNone; - } else - m_dragOperation = static_cast<WebDragOperation>(effect); - return m_dragOperation; + return dragTargetDragEnterOrOver(clientPoint, screenPoint, DragOver); } void WebViewImpl::dragTargetDragLeave() @@ -1495,6 +1631,7 @@ void WebViewImpl::dragTargetDrop(const WebPoint& clientPoint, m_dropEffect = DropEffectDefault; m_dragOperation = WebDragOperationNone; m_dragIdentity = 0; + m_dragScrollTimer->stop(); } int WebViewImpl::dragIdentity() @@ -1504,7 +1641,42 @@ int WebViewImpl::dragIdentity() return 0; } -unsigned long WebViewImpl::createUniqueIdentifierForRequest() { +WebDragOperation WebViewImpl::dragTargetDragEnterOrOver(const WebPoint& clientPoint, const WebPoint& screenPoint, DragAction dragAction) +{ + ASSERT(m_currentDragData.get()); + + DragData dragData( + m_currentDragData.get(), + clientPoint, + screenPoint, + static_cast<DragOperation>(m_operationsAllowed)); + + m_dropEffect = DropEffectDefault; + m_dragTargetDispatch = true; + DragOperation effect = dragAction == DragEnter ? m_page->dragController()->dragEntered(&dragData) + : m_page->dragController()->dragUpdated(&dragData); + // Mask the operation against the drag source's allowed operations. + if (!(effect & dragData.draggingSourceOperationMask())) + effect = DragOperationNone; + m_dragTargetDispatch = false; + + if (m_dropEffect != DropEffectDefault) { + m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy + : WebDragOperationNone; + } else + m_dragOperation = static_cast<WebDragOperation>(effect); + + if (dragAction == DragOver) + m_dragScrollTimer->triggerScroll(mainFrameImpl()->frameView(), clientPoint); + else + m_dragScrollTimer->stop(); + + + return m_dragOperation; +} + +unsigned long WebViewImpl::createUniqueIdentifierForRequest() +{ if (m_page) return m_page->progress()->createUniqueIdentifier(); return 0; @@ -1537,15 +1709,24 @@ void WebViewImpl::setInspectorSettings(const WebString& settings) m_inspectorSettings = settings; } -WebDevToolsAgent* WebViewImpl::devToolsAgent() +bool WebViewImpl::inspectorSetting(const WebString& key, WebString* value) const { - return m_devToolsAgent.get(); + if (!m_inspectorSettingsMap->contains(key)) + return false; + *value = m_inspectorSettingsMap->get(key); + return true; } -void WebViewImpl::setDevToolsAgent(WebDevToolsAgent* devToolsAgent) +void WebViewImpl::setInspectorSetting(const WebString& key, + const WebString& value) { - ASSERT(!m_devToolsAgent.get()); // May only set once! - m_devToolsAgent.set(static_cast<WebDevToolsAgentPrivate*>(devToolsAgent)); + m_inspectorSettingsMap->set(key, value); + client()->didUpdateInspectorSetting(key, value); +} + +WebDevToolsAgent* WebViewImpl::devToolsAgent() +{ + return m_devToolsAgent.get(); } WebAccessibilityObject WebViewImpl::accessibilityObject() @@ -1558,25 +1739,31 @@ WebAccessibilityObject WebViewImpl::accessibilityObject() document->axObjectCache()->getOrCreate(document->renderer())); } -void WebViewImpl::applyAutofillSuggestions( +void WebViewImpl::applyAutoFillSuggestions( const WebNode& node, - const WebVector<WebString>& suggestions, - int defaultSuggestionIndex) + const WebVector<WebString>& names, + const WebVector<WebString>& labels, + const WebVector<int>& uniqueIDs, + int separatorIndex) { - applyAutocompleteSuggestions(node, suggestions, defaultSuggestionIndex); + WebVector<WebString> icons(names.size()); + applyAutoFillSuggestions(node, names, labels, icons, uniqueIDs, separatorIndex); } void WebViewImpl::applyAutoFillSuggestions( const WebNode& node, const WebVector<WebString>& names, const WebVector<WebString>& labels, - int defaultSuggestionIndex) + const WebVector<WebString>& icons, + const WebVector<int>& uniqueIDs, + int separatorIndex) { ASSERT(names.size() == labels.size()); - ASSERT(defaultSuggestionIndex < static_cast<int>(names.size())); + ASSERT(names.size() == uniqueIDs.size()); + ASSERT(separatorIndex < static_cast<int>(names.size())); if (names.isEmpty()) { - hideSuggestionsPopup(); + hideAutoFillPopup(); return; } @@ -1585,7 +1772,7 @@ void WebViewImpl::applyAutoFillSuggestions( // focused node, then we have nothing to do. FIXME: also check the // caret is at the end and that the text has not changed. if (!focusedNode || focusedNode != PassRefPtr<Node>(node)) { - hideSuggestionsPopup(); + hideAutoFillPopup(); return; } @@ -1597,98 +1784,54 @@ void WebViewImpl::applyAutoFillSuggestions( if (!m_autoFillPopupClient.get()) m_autoFillPopupClient.set(new AutoFillPopupMenuClient); - m_autoFillPopupClient->initialize(inputElem, names, labels, - defaultSuggestionIndex); - - if (m_suggestionsPopupClient != m_autoFillPopupClient.get()) { - hideSuggestionsPopup(); - m_suggestionsPopupClient = m_autoFillPopupClient.get(); - } + m_autoFillPopupClient->initialize( + inputElem, names, labels, icons, uniqueIDs, separatorIndex); if (!m_autoFillPopup.get()) { - m_autoFillPopup = PopupContainer::create(m_suggestionsPopupClient, - suggestionsPopupSettings); + m_autoFillPopup = PopupContainer::create(m_autoFillPopupClient.get(), + PopupContainer::Suggestion, + autoFillPopupSettings); } - if (m_suggestionsPopup != m_autoFillPopup.get()) - m_suggestionsPopup = m_autoFillPopup.get(); - - if (m_suggestionsPopupShowing) { - m_autoFillPopupClient->setSuggestions(names, labels); - refreshSuggestionsPopup(); + if (m_autoFillPopupShowing) { + m_autoFillPopupClient->setSuggestions( + names, labels, icons, uniqueIDs, separatorIndex); + refreshAutoFillPopup(); } else { - m_suggestionsPopup->show(focusedNode->getRect(), + m_autoFillPopup->show(focusedNode->getRect(), focusedNode->ownerDocument()->view(), 0); - m_suggestionsPopupShowing = true; + m_autoFillPopupShowing = true; } + + // DEPRECATED: This special mode will go away once AutoFill and Autocomplete + // merge is complete. + if (m_autoFillPopupClient) + m_autoFillPopupClient->setAutocompleteMode(false); } +// DEPRECATED: replacing with applyAutoFillSuggestions. void WebViewImpl::applyAutocompleteSuggestions( const WebNode& node, const WebVector<WebString>& suggestions, int defaultSuggestionIndex) { - ASSERT(defaultSuggestionIndex < static_cast<int>(suggestions.size())); - - if (!m_page.get() || suggestions.isEmpty()) { - hideSuggestionsPopup(); - return; - } - - RefPtr<Node> focusedNode = focusedWebCoreNode(); - // If the node for which we queried the Autocomplete suggestions is not the - // focused node, then we have nothing to do. FIXME: also check the - // caret is at the end and that the text has not changed. - if (!focusedNode || focusedNode != PassRefPtr<Node>(node)) { - hideSuggestionsPopup(); - return; - } - - HTMLInputElement* inputElem = - static_cast<HTMLInputElement*>(focusedNode.get()); - - // The first time the Autocomplete is shown we'll create the client and the - // popup. - if (!m_autocompletePopupClient.get()) - m_autocompletePopupClient.set(new AutocompletePopupMenuClient); - - m_autocompletePopupClient->initialize(inputElem, suggestions, - defaultSuggestionIndex); + WebVector<WebString> names(suggestions.size()); + WebVector<WebString> labels(suggestions.size()); + WebVector<WebString> icons(suggestions.size()); + WebVector<int> uniqueIDs(suggestions.size()); - if (m_suggestionsPopupClient != m_autocompletePopupClient.get()) { - hideSuggestionsPopup(); - m_suggestionsPopupClient = m_autocompletePopupClient.get(); - } - - if (!m_autocompletePopup.get()) { - m_autocompletePopup = PopupContainer::create(m_suggestionsPopupClient, - suggestionsPopupSettings); - } - - if (m_suggestionsPopup != m_autocompletePopup.get()) - m_suggestionsPopup = m_autocompletePopup.get(); - - if (m_suggestionsPopupShowing) { - m_autocompletePopupClient->setSuggestions(suggestions); - refreshSuggestionsPopup(); - } else { - m_suggestionsPopup->show(focusedNode->getRect(), - focusedNode->ownerDocument()->view(), 0); - m_suggestionsPopupShowing = true; - } -} + for (size_t i = 0; i < suggestions.size(); ++i) + names[i] = suggestions[i]; -void WebViewImpl::hideAutofillPopup() -{ - hideSuggestionsPopup(); + applyAutoFillSuggestions(node, names, labels, icons, uniqueIDs, -1); + if (m_autoFillPopupClient) + m_autoFillPopupClient->setAutocompleteMode(true); } -void WebViewImpl::hideSuggestionsPopup() +void WebViewImpl::hidePopups() { - if (m_suggestionsPopupShowing) { - m_suggestionsPopup->hidePopup(); - m_suggestionsPopupShowing = false; - } + hideSelectPopup(); + hideAutoFillPopup(); } void WebViewImpl::performCustomContextMenuAction(unsigned action) @@ -1748,7 +1891,7 @@ void WebViewImpl::setScrollbarColors(unsigned inactiveColor, unsigned activeColor, unsigned trackColor) { #if OS(LINUX) - RenderThemeChromiumLinux::setScrollbarColors(inactiveColor, + PlatformThemeChromiumGtk::setScrollbarColors(inactiveColor, activeColor, trackColor); #endif @@ -1767,15 +1910,37 @@ void WebViewImpl::setSelectionColors(unsigned activeBackgroundColor, #endif } -void WebViewImpl::addUserScript(const WebString& sourceCode, bool runAtStart) +void WebView::addUserScript(const WebString& sourceCode, + const WebVector<WebString>& patternsIn, + WebView::UserScriptInjectAt injectAt, + WebView::UserContentInjectIn injectIn) +{ + OwnPtr<Vector<String> > patterns(new Vector<String>); + for (size_t i = 0; i < patternsIn.size(); ++i) + patterns->append(patternsIn[i]); + + PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); + RefPtr<DOMWrapperWorld> world(DOMWrapperWorld::create()); + pageGroup->addUserScriptToWorld(world.get(), sourceCode, WebURL(), patterns.release(), 0, + static_cast<UserScriptInjectionTime>(injectAt), + static_cast<UserContentInjectedFrames>(injectIn)); +} + +void WebView::addUserStyleSheet(const WebString& sourceCode, + const WebVector<WebString>& patternsIn, + WebView::UserContentInjectIn injectIn) { + OwnPtr<Vector<String> > patterns(new Vector<String>); + for (size_t i = 0; i < patternsIn.size(); ++i) + patterns->append(patternsIn[i]); + PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); RefPtr<DOMWrapperWorld> world(DOMWrapperWorld::create()); - pageGroup->addUserScriptToWorld(world.get(), sourceCode, WebURL(), 0, 0, - runAtStart ? InjectAtDocumentStart : InjectAtDocumentEnd); + pageGroup->addUserStyleSheetToWorld(world.get(), sourceCode, WebURL(), patterns.release(), 0, + static_cast<UserContentInjectedFrames>(injectIn)); } -void WebViewImpl::removeAllUserContent() +void WebView::removeAllUserContent() { PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); pageGroup->removeAllUserContent(); @@ -1799,7 +1964,7 @@ bool WebViewImpl::navigationPolicyFromMouseEvent(unsigned short button, bool alt, bool meta, WebNavigationPolicy* policy) { -#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) +#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) || OS(SOLARIS) const bool newTabModifier = (button == 1) || ctrl; #elif OS(DARWIN) const bool newTabModifier = (button == 1) || meta; @@ -1822,15 +1987,16 @@ bool WebViewImpl::navigationPolicyFromMouseEvent(unsigned short button, return true; } -void WebViewImpl::startDragging(const WebPoint& eventPos, - const WebDragData& dragData, - WebDragOperationsMask mask) +void WebViewImpl::startDragging(const WebDragData& dragData, + WebDragOperationsMask mask, + const WebImage& dragImage, + const WebPoint& dragImageOffset) { if (!m_client) return; ASSERT(!m_doingDragAndDrop); m_doingDragAndDrop = true; - m_client->startDragging(eventPos, dragData, mask); + m_client->startDragging(dragData, mask, dragImage, dragImageOffset); } void WebViewImpl::setCurrentHistoryItem(HistoryItem* item) @@ -1866,24 +2032,25 @@ NotificationPresenterImpl* WebViewImpl::notificationPresenterImpl() } #endif -void WebViewImpl::refreshSuggestionsPopup() +void WebViewImpl::refreshAutoFillPopup() { - ASSERT(m_suggestionsPopupShowing); + ASSERT(m_autoFillPopupShowing); // Hide the popup if it has become empty. - if (!m_autocompletePopupClient->listSize()) { - hideSuggestionsPopup(); + if (!m_autoFillPopupClient->listSize()) { + hideAutoFillPopup(); return; } - IntRect oldBounds = m_suggestionsPopup->boundsRect(); - m_suggestionsPopup->refresh(); - IntRect newBounds = m_suggestionsPopup->boundsRect(); + IntRect oldBounds = m_autoFillPopup->boundsRect(); + m_autoFillPopup->refresh(); + IntRect newBounds = m_autoFillPopup->boundsRect(); // Let's resize the backing window if necessary. if (oldBounds != newBounds) { WebPopupMenuImpl* popupMenu = - static_cast<WebPopupMenuImpl*>(m_suggestionsPopup->client()); - popupMenu->client()->setWindowRect(newBounds); + static_cast<WebPopupMenuImpl*>(m_autoFillPopup->client()); + if (popupMenu) + popupMenu->client()->setWindowRect(newBounds); } } @@ -1916,4 +2083,124 @@ bool WebViewImpl::tabsToLinks() const return m_tabsToLinks; } +#if USE(ACCELERATED_COMPOSITING) +void WebViewImpl::setRootGraphicsLayer(WebCore::PlatformLayer* layer) +{ + setIsAcceleratedCompositingActive(layer ? true : false); + if (m_layerRenderer) + m_layerRenderer->setRootLayer(layer); +} + +void WebViewImpl::setIsAcceleratedCompositingActive(bool active) +{ + if (m_isAcceleratedCompositingActive == active) + return; + + if (active) { + m_layerRenderer = LayerRendererChromium::create(getOnscreenGLES2Context()); + if (m_layerRenderer->hardwareCompositing()) + m_isAcceleratedCompositingActive = true; + else { + m_layerRenderer.clear(); + m_isAcceleratedCompositingActive = false; + } + } else { + m_layerRenderer = 0; + m_isAcceleratedCompositingActive = false; + } +} + +void WebViewImpl::updateRootLayerContents(const WebRect& rect) +{ + if (!isAcceleratedCompositingActive()) + return; + + // FIXME: The accelerated compositing path invalidates a 1x1 rect at (0, 0) + // in order to get the renderer to ask the compositor to redraw. This is only + // temporary until we get the compositor to render directly from its own thread. + if (!rect.x && !rect.y && rect.width == 1 && rect.height == 1) + return; + + WebFrameImpl* webframe = mainFrameImpl(); + if (!webframe) + return; + FrameView* view = webframe->frameView(); + if (!view) + return; + + LayerChromium* rootLayer = m_layerRenderer->rootLayer(); + if (rootLayer) { + IntRect visibleRect = view->visibleContentRect(true); + + m_layerRenderer->setRootLayerCanvasSize(IntSize(rect.width, rect.height)); + GraphicsContext* rootLayerContext = m_layerRenderer->rootLayerGraphicsContext(); + +#if PLATFORM(SKIA) + PlatformContextSkia* skiaContext = rootLayerContext->platformContext(); + skia::PlatformCanvas* platformCanvas = skiaContext->canvas(); + + platformCanvas->save(); + + // Bring the canvas into the coordinate system of the paint rect. + platformCanvas->translate(static_cast<SkScalar>(-rect.x), static_cast<SkScalar>(-rect.y)); + + rootLayerContext->save(); + + webframe->paintWithContext(*rootLayerContext, rect); + rootLayerContext->restore(); + + platformCanvas->restore(); +#endif + } +} + +void WebViewImpl::setRootLayerNeedsDisplay() +{ + // FIXME: For now we're posting a repaint event for the entire page which is an overkill. + if (WebFrameImpl* webframe = mainFrameImpl()) { + if (FrameView* view = webframe->frameView()) { + // FIXME: Temporary hack to invalidate part of the page so that we get called to render + // again. + IntRect visibleRect = view->visibleContentRect(true); + m_client->didInvalidateRect(IntRect(0, 0, 1, 1)); + } + } + + if (m_layerRenderer) + m_layerRenderer->setNeedsDisplay(); +} +#endif // USE(ACCELERATED_COMPOSITING) + +PassOwnPtr<GLES2Context> WebViewImpl::getOnscreenGLES2Context() +{ + return GLES2Context::create(GLES2ContextInternal::create(gles2Context(), false)); +} + +PassOwnPtr<GLES2Context> WebViewImpl::getOffscreenGLES2Context() +{ + WebGLES2Context* context = webKitClient()->createGLES2Context(); + if (!context) + return 0; + if (!context->initialize(0, gles2Context())) + return 0; + return GLES2Context::create(GLES2ContextInternal::create(context, true)); +} + +// Returns the GLES2 context associated with this View. If one doesn't exist +// it will get created first. +WebGLES2Context* WebViewImpl::gles2Context() +{ + if (!m_gles2Context) { + m_gles2Context = webKitClient()->createGLES2Context(); + if (!m_gles2Context) + return 0; + + if (!m_gles2Context->initialize(this, 0)) { + m_gles2Context.clear(); + return 0; + } + } + return m_gles2Context.get(); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebViewImpl.h b/WebKit/chromium/src/WebViewImpl.h index 286ac43..530fbf5 100644 --- a/WebKit/chromium/src/WebViewImpl.h +++ b/WebKit/chromium/src/WebViewImpl.h @@ -31,27 +31,30 @@ #ifndef WebViewImpl_h #define WebViewImpl_h -// FIXME: Remove these relative paths once consumers from glue are removed. -#include "../public/WebNavigationPolicy.h" -#include "../public/WebPoint.h" -#include "../public/WebSize.h" -#include "../public/WebString.h" -#include "../public/WebView.h" +#include "WebGLES2Context.h" +#include "WebNavigationPolicy.h" +#include "WebPoint.h" +#include "WebSize.h" +#include "WebString.h" +#include "WebView.h" #include "BackForwardListClientImpl.h" #include "ChromeClientImpl.h" #include "ContextMenuClientImpl.h" #include "DragClientImpl.h" #include "EditorClientImpl.h" +#include "GraphicsLayer.h" #include "InspectorClientImpl.h" +#include "LayerRendererChromium.h" #include "NotificationPresenterImpl.h" - +#include "SpeechInputClientImpl.h" #include <wtf/OwnPtr.h> #include <wtf/RefCounted.h> namespace WebCore { class ChromiumDataObject; class Frame; +class GLES2Context; class HistoryItem; class HitTestResult; class KeyboardEvent; @@ -68,14 +71,17 @@ namespace WebKit { class AutocompletePopupMenuClient; class AutoFillPopupMenuClient; class ContextMenuClientImpl; -class SuggestionsPopupMenuClient; +class DragScrollTimer; class WebAccessibilityObject; +class WebDevToolsAgentClient; class WebDevToolsAgentPrivate; class WebFrameImpl; +class WebImage; class WebKeyboardEvent; class WebMouseEvent; class WebMouseWheelEvent; class WebSettingsImpl; +class WebTouchEvent; class WebViewImpl : public WebView, public RefCounted<WebViewImpl> { public: @@ -88,14 +94,16 @@ public: virtual bool handleInputEvent(const WebInputEvent&); virtual void mouseCaptureLost(); virtual void setFocus(bool enable); - virtual bool handleCompositionEvent(WebCompositionCommand command, - int cursorPosition, - int targetStart, - int targetEnd, - const WebString& text); - virtual bool queryCompositionStatus(bool* enabled, - WebRect* caretRect); + virtual bool setComposition( + const WebString& text, + const WebVector<WebCompositionUnderline>& underlines, + int selectionStart, + int selectionEnd); + virtual bool confirmComposition(); + virtual WebTextInputType textInputType(); + virtual WebRect caretOrSelectionBounds(); virtual void setTextDirection(WebTextDirection direction); + virtual bool isAcceleratedCompositingActive() const; // WebView methods: virtual void initializeMainFrame(WebFrameClient*); @@ -129,6 +137,10 @@ public: const WebPoint& clientPoint, const WebPoint& screenPoint, WebDragOperation operation); + virtual void dragSourceMovedTo( + const WebPoint& clientPoint, + const WebPoint& screenPoint, + WebDragOperation operation); virtual void dragSourceSystemDragEnded(); virtual WebDragOperation dragTargetDragEnter( const WebDragData& dragData, int identity, @@ -149,24 +161,31 @@ public: virtual void inspectElementAt(const WebPoint& point); virtual WebString inspectorSettings() const; virtual void setInspectorSettings(const WebString& settings); + virtual bool inspectorSetting(const WebString& key, WebString* value) const; + virtual void setInspectorSetting(const WebString& key, + const WebString& value); virtual WebDevToolsAgent* devToolsAgent(); - virtual void setDevToolsAgent(WebDevToolsAgent*); virtual WebAccessibilityObject accessibilityObject(); - virtual void applyAutofillSuggestions( + // DEPRECATED. + virtual void applyAutoFillSuggestions( const WebNode&, - const WebVector<WebString>& suggestions, - int defaultSuggestionIndex); + const WebVector<WebString>& names, + const WebVector<WebString>& labels, + const WebVector<int>& uniqueIDs, + int separatorIndex); virtual void applyAutoFillSuggestions( const WebNode&, const WebVector<WebString>& names, const WebVector<WebString>& labels, - int defaultSuggestionIndex); + const WebVector<WebString>& icons, + const WebVector<int>& uniqueIDs, + int separatorIndex); + // DEPRECATED: replacing with applyAutoFillSuggestions. virtual void applyAutocompleteSuggestions( const WebNode&, const WebVector<WebString>& suggestions, int defaultSuggestionIndex); - virtual void hideAutofillPopup(); - virtual void hideSuggestionsPopup(); + virtual void hidePopups(); virtual void setScrollbarColors(unsigned inactiveColor, unsigned activeColor, unsigned trackColor); @@ -175,9 +194,6 @@ public: unsigned inactiveBackgroundColor, unsigned inactiveForegroundColor); virtual void performCustomContextMenuAction(unsigned action); - virtual void addUserScript(const WebString& sourceCode, - bool runAtStart); - virtual void removeAllUserContent(); // WebViewImpl @@ -201,7 +217,7 @@ public: return m_client; } - // Returns the page object associated with this view. This may be null when + // Returns the page object associated with this view. This may be null when // the page is shutting down, but will be valid at all other times. WebCore::Page* page() const { @@ -210,7 +226,7 @@ public: WebCore::RenderTheme* theme() const; - // Returns the main frame associated with this view. This may be null when + // Returns the main frame associated with this view. This may be null when // the page is shutting down, but will be valid at all other times. WebFrameImpl* mainFrameImpl(); @@ -226,19 +242,20 @@ public: void mouseUp(const WebMouseEvent&); void mouseContextMenu(const WebMouseEvent&); void mouseDoubleClick(const WebMouseEvent&); - void mouseWheel(const WebMouseWheelEvent&); + bool mouseWheel(const WebMouseWheelEvent&); bool keyEvent(const WebKeyboardEvent&); bool charEvent(const WebKeyboardEvent&); + bool touchEvent(const WebTouchEvent&); // Handles context menu events orignated via the the keyboard. These - // include the VK_APPS virtual key and the Shift+F10 combine. Code is + // include the VK_APPS virtual key and the Shift+F10 combine. Code is // based on the Webkit function bool WebView::handleContextMenuEvent(WPARAM // wParam, LPARAM lParam) in webkit\webkit\win\WebView.cpp. The only // significant change in this function is the code to convert from a // Keyboard event to the Right Mouse button down event. bool sendContextMenuEvent(const WebKeyboardEvent&); - // Notifies the WebView that a load has been committed. isNewNavigation + // Notifies the WebView that a load has been committed. isNewNavigation // will be true if a new session history item should be created for that // load. void didCommitLoad(bool* isNewNavigation); @@ -270,13 +287,14 @@ public: // Start a system drag and drop operation. void startDragging( - const WebPoint& eventPos, const WebDragData& dragData, - WebDragOperationsMask dragSourceOperationMask); + WebDragOperationsMask mask, + const WebImage& dragImage, + const WebPoint& dragImageOffset); - void suggestionsPopupDidHide() + void autoFillPopupDidHide() { - m_suggestionsPopupShowing = false; + m_autoFillPopupShowing = false; } #if ENABLE(NOTIFICATIONS) @@ -288,6 +306,12 @@ public: // was scrolled. bool propagateScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); + // Notification that a popup was opened/closed. + void popupOpened(WebCore::PopupContainer* popupContainer); + void popupClosed(WebCore::PopupContainer* popupContainer); + + void hideAutoFillPopup(); + // HACK: currentInputEvent() is for ChromeClientImpl::show(), until we can // fix WebKit to pass enough information up into ChromeClient::show() so we // can decide if the window.open event was caused by a middle-mouse click @@ -296,31 +320,73 @@ public: return m_currentInputEvent; } +#if USE(ACCELERATED_COMPOSITING) + void setRootLayerNeedsDisplay(); + void setRootGraphicsLayer(WebCore::PlatformLayer*); +#endif + // Onscreen contexts display to the screen associated with this view. + // Offscreen contexts render offscreen but can share resources with the + // onscreen context and thus can be composited. + PassOwnPtr<WebCore::GLES2Context> getOnscreenGLES2Context(); + PassOwnPtr<WebCore::GLES2Context> getOffscreenGLES2Context(); + + // Returns an onscreen context + virtual WebGLES2Context* gles2Context(); + + WebCore::PopupContainer* selectPopup() const { return m_selectPopup.get(); } + + // Returns true if the event leads to scrolling. + static bool mapKeyCodeForScroll(int keyCode, + WebCore::ScrollDirection* scrollDirection, + WebCore::ScrollGranularity* scrollGranularity); + private: friend class WebView; // So WebView::Create can call our constructor friend class WTF::RefCounted<WebViewImpl>; - WebViewImpl(WebViewClient* client); + enum DragAction { + DragEnter, + DragOver + }; + + WebViewImpl(WebViewClient* client, WebDevToolsAgentClient* devToolsClient); ~WebViewImpl(); // Returns true if the event was actually processed. bool keyEventDefault(const WebKeyboardEvent&); + // Returns true if the select popup has consumed the event. + bool selectPopupHandleKeyEvent(const WebKeyboardEvent&); + // Returns true if the autocomple has consumed the event. bool autocompleteHandleKeyEvent(const WebKeyboardEvent&); - // Repaints the suggestions popup. Should be called when the suggestions - // have changed. Note that this should only be called when the suggestions + // Repaints the AutoFill popup. Should be called when the suggestions + // have changed. Note that this should only be called when the AutoFill // popup is showing. - void refreshSuggestionsPopup(); + void refreshAutoFillPopup(); // Returns true if the view was scrolled. bool scrollViewWithKeyboard(int keyCode, int modifiers); + void hideSelectPopup(); + // Converts |pos| from window coordinates to contents coordinates and gets // the HitTestResult for it. WebCore::HitTestResult hitTestResultForWindowPos(const WebCore::IntPoint&); + // Consolidate some common code between starting a drag over a target and + // updating a drag over a target. If we're starting a drag, |isEntering| + // should be true. + WebDragOperation dragTargetDragEnterOrOver(const WebPoint& clientPoint, + const WebPoint& screenPoint, + DragAction); + +#if USE(ACCELERATED_COMPOSITING) + void setIsAcceleratedCompositingActive(bool); + void updateRootLayerContents(const WebRect&); +#endif + WebViewClient* m_client; BackForwardListClientImpl m_backForwardListClientImpl; @@ -335,7 +401,7 @@ private: WebPoint m_lastMousePosition; OwnPtr<WebCore::Page> m_page; - // This flag is set when a new navigation is detected. It is used to satisfy + // This flag is set when a new navigation is detected. It is used to satisfy // the corresponding argument to WebFrameClient::didCommitProvisionalLoad. bool m_observedNewNavigation; #ifndef NDEBUG @@ -345,7 +411,7 @@ private: #endif // An object that can be used to manipulate m_page->settings() without linking - // against WebCore. This is lazily allocated the first time GetWebSettings() + // against WebCore. This is lazily allocated the first time GetWebSettings() // is called. OwnPtr<WebSettingsImpl> m_webSettings; @@ -361,7 +427,7 @@ private: // dragged by the time a drag is initiated. WebPoint m_lastMouseDownPoint; - // Keeps track of the current zoom level. 0 means no zoom, positive numbers + // Keeps track of the current zoom level. 0 means no zoom, positive numbers // mean zoom in, negative numbers mean zoom out. int m_zoomLevel; @@ -391,7 +457,7 @@ private: // copied from the WebDropData object sent from the browser process. int m_dragIdentity; - // Valid when m_dragTargetDispatch is true. Used to override the default + // Valid when m_dragTargetDispatch is true. Used to override the default // browser drop effect with the effects "none" or "copy". enum DragTargetDropEffect { DropEffectDefault = -1, @@ -407,28 +473,17 @@ private: // current drop target in this WebView (the drop target can accept the drop). WebDragOperation m_dragOperation; - // Whether a suggestions popup is currently showing. - bool m_suggestionsPopupShowing; - - // A pointer to the current suggestions popup menu client. This can be - // either an AutoFillPopupMenuClient or an AutocompletePopupMenuClient. We - // do not own this pointer. - SuggestionsPopupMenuClient* m_suggestionsPopupClient; + // Whether an AutoFill popup is currently showing. + bool m_autoFillPopupShowing; // The AutoFill popup client. OwnPtr<AutoFillPopupMenuClient> m_autoFillPopupClient; - // The Autocomplete popup client. - OwnPtr<AutocompletePopupMenuClient> m_autocompletePopupClient; - - // A pointer to the current suggestions popup. We do not own this pointer. - WebCore::PopupContainer* m_suggestionsPopup; - - // The AutoFill suggestions popup. + // The AutoFill popup. RefPtr<WebCore::PopupContainer> m_autoFillPopup; - // The AutoComplete suggestions popup. - RefPtr<WebCore::PopupContainer> m_autocompletePopup; + // The popup associated with a select element. + RefPtr<WebCore::PopupContainer> m_selectPopup; OwnPtr<WebDevToolsAgentPrivate> m_devToolsAgent; @@ -441,12 +496,29 @@ private: // Inspector settings. WebString m_inspectorSettings; + typedef HashMap<WebCore::String, WebCore::String> SettingsMap; + OwnPtr<SettingsMap> m_inspectorSettingsMap; + OwnPtr<DragScrollTimer> m_dragScrollTimer; + #if ENABLE(NOTIFICATIONS) // The provider of desktop notifications; NotificationPresenterImpl m_notificationPresenter; #endif + // If set, the (plugin) node which has mouse capture. + RefPtr<WebCore::Node> m_mouseCaptureNode; + +#if USE(ACCELERATED_COMPOSITING) + OwnPtr<WebCore::LayerRendererChromium> m_layerRenderer; + bool m_isAcceleratedCompositingActive; +#endif static const WebInputEvent* m_currentInputEvent; + +#if ENABLE(INPUT_SPEECH) + SpeechInputClientImpl m_speechInputClient; +#endif + + OwnPtr<WebGLES2Context> m_gles2Context; }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebWorkerBase.cpp b/WebKit/chromium/src/WebWorkerBase.cpp index 40019e8..9593f5f 100644 --- a/WebKit/chromium/src/WebWorkerBase.cpp +++ b/WebKit/chromium/src/WebWorkerBase.cpp @@ -31,7 +31,8 @@ #include "config.h" #include "WebWorkerBase.h" -#include "GenericWorkerTask.h" +#include "CrossThreadTask.h" +#include "DatabaseTask.h" #include "MessagePortChannel.h" #include "PlatformMessagePortChannel.h" @@ -39,9 +40,12 @@ #include "WebFrameClient.h" #include "WebFrameImpl.h" #include "WebMessagePortChannel.h" +#include "WebRuntimeFeatures.h" +#include "WebSettings.h" #include "WebView.h" #include "WebWorkerClient.h" +#include "WorkerScriptController.h" #include "WorkerThread.h" #include <wtf/MainThread.h> @@ -51,29 +55,66 @@ namespace WebKit { #if ENABLE(WORKERS) -// Dummy WebViewDelegate - we only need it in Worker process to load a -// 'shadow page' which will initialize WebCore loader. -class WorkerWebFrameClient : public WebFrameClient { +static const char allowDatabaseMode[] = "allowDatabaseMode"; + +namespace { + +// This class is used to route the result of the WebWorkerBase::allowDatabase +// call back to the worker context. +class AllowDatabaseMainThreadBridge : public ThreadSafeShared<AllowDatabaseMainThreadBridge> { public: - // Tell the loader to load the data into the 'shadow page' synchronously, - // so we can grab the resulting Document right after load. - virtual void didCreateDataSource(WebFrame* frame, WebDataSource* ds) + static PassRefPtr<AllowDatabaseMainThreadBridge> create(WebWorkerBase* worker, const WebCore::String& mode, WebCommonWorkerClient* commonClient, WebFrame* frame, const WebCore::String& name, const WebCore::String& displayName, unsigned long estimatedSize) + { + return adoptRef(new AllowDatabaseMainThreadBridge(worker, mode, commonClient, frame, name, displayName, estimatedSize)); + } + + // These methods are invoked on the worker context. + void cancel() + { + MutexLocker locker(m_mutex); + m_worker = 0; + } + + bool result() { - static_cast<WebDataSourceImpl*>(ds)->setDeferMainResourceDataLoad(false); + return m_result; } - // Lazy allocate and leak this instance. - static WorkerWebFrameClient* sharedInstance() + // This method is invoked on the main thread. + void signalCompleted(bool result) { - static WorkerWebFrameClient client; - return &client; + MutexLocker locker(m_mutex); + if (m_worker) + m_worker->postTaskForModeToWorkerContext(createCallbackTask(&didComplete, this, result), m_mode); } private: - WorkerWebFrameClient() + AllowDatabaseMainThreadBridge(WebWorkerBase* worker, const WebCore::String& mode, WebCommonWorkerClient* commonClient, WebFrame* frame, const WebCore::String& name, const WebCore::String& displayName, unsigned long estimatedSize) + : m_worker(worker) + , m_mode(mode) { + worker->dispatchTaskToMainThread(createCallbackTask(&allowDatabaseTask, commonClient, frame, String(name), String(displayName), estimatedSize, this)); } + + static void allowDatabaseTask(WebCore::ScriptExecutionContext* context, WebCommonWorkerClient* commonClient, WebFrame* frame, const WebCore::String name, const WebCore::String displayName, unsigned long estimatedSize, PassRefPtr<AllowDatabaseMainThreadBridge> bridge) + { + if (!commonClient) + bridge->signalCompleted(false); + else + bridge->signalCompleted(commonClient->allowDatabase(frame, name, displayName, estimatedSize)); + } + + static void didComplete(WebCore::ScriptExecutionContext* context, PassRefPtr<AllowDatabaseMainThreadBridge> bridge, bool result) + { + bridge->m_result = result; + } + + bool m_result; + Mutex m_mutex; + WebWorkerBase* m_worker; + WebCore::String m_mode; }; +} // This function is called on the main thread to force to initialize some static // values used in WebKit before any worker thread is started. This is because in @@ -103,6 +144,9 @@ WebWorkerBase::WebWorkerBase() WebWorkerBase::~WebWorkerBase() { ASSERT(m_webView); + WebFrameImpl* webFrame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); + if (webFrame) + webFrame->setClient(0); m_webView->close(); } @@ -121,8 +165,9 @@ void WebWorkerBase::initializeLoader(const WebURL& url) // loading requests from the worker context to the rest of WebKit and Chromium // infrastructure. ASSERT(!m_webView); - m_webView = WebView::create(0); - m_webView->initializeMainFrame(WorkerWebFrameClient::sharedInstance()); + m_webView = WebView::create(0, 0); + m_webView->settings()->setOfflineWebApplicationCacheEnabled(WebRuntimeFeatures::isApplicationCacheEnabled()); + m_webView->initializeMainFrame(this); WebFrameImpl* webFrame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); @@ -140,7 +185,7 @@ void WebWorkerBase::initializeLoader(const WebURL& url) void WebWorkerBase::dispatchTaskToMainThread(PassOwnPtr<ScriptExecutionContext::Task> task) { - return callOnMainThread(invokeTaskMethod, task.release()); + callOnMainThread(invokeTaskMethod, task.leakPtr()); } void WebWorkerBase::invokeTaskMethod(void* param) @@ -151,6 +196,41 @@ void WebWorkerBase::invokeTaskMethod(void* param) delete task; } +void WebWorkerBase::didCreateDataSource(WebFrame*, WebDataSource* ds) +{ + // Tell the loader to load the data into the 'shadow page' synchronously, + // so we can grab the resulting Document right after load. + static_cast<WebDataSourceImpl*>(ds)->setDeferMainResourceDataLoad(false); +} + +WebApplicationCacheHost* WebWorkerBase::createApplicationCacheHost(WebFrame*, WebApplicationCacheHostClient* appcacheHostClient) +{ + if (commonClient()) + return commonClient()->createApplicationCacheHost(appcacheHostClient); + return 0; +} + +bool WebWorkerBase::allowDatabase(WebFrame*, const WebString& name, const WebString& displayName, unsigned long estimatedSize) +{ + WorkerRunLoop& runLoop = m_workerThread->runLoop(); + WorkerScriptController* controller = WorkerScriptController::controllerForContext(); + WorkerContext* workerContext = controller->workerContext(); + + // Create a unique mode just for this synchronous call. + String mode = allowDatabaseMode; + mode.append(String::number(runLoop.createUniqueId())); + + RefPtr<AllowDatabaseMainThreadBridge> bridge = AllowDatabaseMainThreadBridge::create(this, mode, commonClient(), m_webView->mainFrame(), String(name), String(displayName), estimatedSize); + + // Either the bridge returns, or the queue gets terminated. + if (runLoop.runInMode(workerContext, mode) == MessageQueueTerminated) { + bridge->cancel(); + return false; + } + + return bridge->result(); +} + // WorkerObjectProxy ----------------------------------------------------------- void WebWorkerBase::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message, @@ -199,8 +279,7 @@ void WebWorkerBase::postExceptionTask(ScriptExecutionContext* context, sourceURL); } -void WebWorkerBase::postConsoleMessageToWorkerObject(MessageDestination destination, - MessageSource source, +void WebWorkerBase::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, @@ -208,16 +287,13 @@ void WebWorkerBase::postConsoleMessageToWorkerObject(MessageDestination destinat const String& sourceURL) { dispatchTaskToMainThread(createCallbackTask(&postConsoleMessageTask, this, - static_cast<int>(destination), - static_cast<int>(source), - static_cast<int>(type), - static_cast<int>(level), + source, type, level, message, lineNumber, sourceURL)); } void WebWorkerBase::postConsoleMessageTask(ScriptExecutionContext* context, WebWorkerBase* thisPtr, - int destination, int source, + int source, int type, int level, const String& message, int lineNumber, @@ -225,7 +301,7 @@ void WebWorkerBase::postConsoleMessageTask(ScriptExecutionContext* context, { if (!thisPtr->commonClient()) return; - thisPtr->commonClient()->postConsoleMessageToWorkerObject(destination, source, + thisPtr->commonClient()->postConsoleMessageToWorkerObject(source, type, level, message, lineNumber, sourceURL); } diff --git a/WebKit/chromium/src/WebWorkerBase.h b/WebKit/chromium/src/WebWorkerBase.h index 0217401..15e8013 100644 --- a/WebKit/chromium/src/WebWorkerBase.h +++ b/WebKit/chromium/src/WebWorkerBase.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -34,6 +34,7 @@ #if ENABLE(WORKERS) #include "ScriptExecutionContext.h" +#include "WebFrameClient.h" #include "WorkerLoaderProxy.h" #include "WorkerObjectProxy.h" #include <wtf/PassOwnPtr.h> @@ -44,16 +45,22 @@ class WorkerThread; } namespace WebKit { +class WebApplicationCacheHost; +class WebApplicationCacheHostClient; class WebCommonWorkerClient; +class WebSecurityOrigin; +class WebString; class WebURL; class WebView; +class WebWorker; class WebWorkerClient; // Base class for WebSharedWorkerImpl and WebWorkerImpl. It contains common // code used by both implementation classes, including implementations of the // WorkerObjectProxy and WorkerLoaderProxy interfaces. class WebWorkerBase : public WebCore::WorkerObjectProxy - , public WebCore::WorkerLoaderProxy { + , public WebCore::WorkerLoaderProxy + , public WebFrameClient { public: WebWorkerBase(); virtual ~WebWorkerBase(); @@ -65,7 +72,7 @@ public: virtual void postExceptionToWorkerObject( const WebCore::String&, int, const WebCore::String&); virtual void postConsoleMessageToWorkerObject( - WebCore::MessageDestination, WebCore::MessageSource, WebCore::MessageType, + WebCore::MessageSource, WebCore::MessageType, WebCore::MessageLevel, const WebCore::String&, int, const WebCore::String&); virtual void confirmMessageFromWorkerObject(bool); virtual void reportPendingActivity(bool); @@ -77,6 +84,13 @@ public: virtual void postTaskForModeToWorkerContext( PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const WebCore::String& mode); + // WebFrameClient methods to support resource loading thru the 'shadow page'. + virtual void didCreateDataSource(WebFrame*, WebDataSource*); + virtual WebApplicationCacheHost* createApplicationCacheHost(WebFrame*, WebApplicationCacheHostClient*); + + // Controls whether access to Web Databases is allowed for this worker. + virtual bool allowDatabase(WebFrame*, const WebString& name, const WebString& displayName, unsigned long estimatedSize); + // Executes the given task on the main thread. static void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>); @@ -112,7 +126,6 @@ private: static void postConsoleMessageTask( WebCore::ScriptExecutionContext* context, WebWorkerBase* thisPtr, - int destination, int source, int type, int level, diff --git a/WebKit/chromium/src/WebWorkerClientImpl.cpp b/WebKit/chromium/src/WebWorkerClientImpl.cpp index 598a078..18282e3 100644 --- a/WebKit/chromium/src/WebWorkerClientImpl.cpp +++ b/WebKit/chromium/src/WebWorkerClientImpl.cpp @@ -33,11 +33,11 @@ #if ENABLE(WORKERS) +#include "CrossThreadTask.h" #include "DedicatedWorkerThread.h" #include "ErrorEvent.h" #include "Frame.h" #include "FrameLoaderClient.h" -#include "GenericWorkerTask.h" #include "MessageEvent.h" #include "MessagePort.h" #include "MessagePortChannel.h" @@ -45,6 +45,7 @@ #include "Worker.h" #include "WorkerContext.h" #include "WorkerContextExecutionProxy.h" +#include "WorkerScriptController.h" #include "WorkerMessagingProxy.h" #include <wtf/Threading.h> @@ -94,15 +95,13 @@ WorkerContextProxy* WebWorkerClientImpl::createWorkerContextProxy(Worker* worker WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); webWorker = webFrame->client()->createWorker(webFrame, proxy); } else { - WorkerContextExecutionProxy* currentContext = - WorkerContextExecutionProxy::retrieve(); - if (!currentContext) { + WorkerScriptController* controller = WorkerScriptController::controllerForContext(); + if (!controller) { ASSERT_NOT_REACHED(); return 0; } - DedicatedWorkerThread* thread = - static_cast<DedicatedWorkerThread*>(currentContext->workerContext()->thread()); + DedicatedWorkerThread* thread = static_cast<DedicatedWorkerThread*>(controller->workerContext()->thread()); WorkerObjectProxy* workerObjectProxy = &thread->workerObjectProxy(); WebWorkerImpl* impl = reinterpret_cast<WebWorkerImpl*>(workerObjectProxy); webWorker = impl->client()->createWorker(proxy); @@ -244,15 +243,14 @@ void WebWorkerClientImpl::postExceptionToWorkerObject(const WebString& errorMess return; } - bool handled = false; - handled = m_worker->dispatchEvent(ErrorEvent::create(errorMessage, - sourceURL, - lineNumber)); - if (!handled) + bool unhandled = m_worker->dispatchEvent(ErrorEvent::create(errorMessage, + sourceURL, + lineNumber)); + if (unhandled) m_scriptExecutionContext->reportException(errorMessage, lineNumber, sourceURL); } -void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destinationId, +void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destination, int sourceId, int messageType, int messageLevel, @@ -263,7 +261,6 @@ void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destinationId, if (currentThread() != m_workerThreadId) { m_scriptExecutionContext->postTask(createCallbackTask(&postConsoleMessageToWorkerObjectTask, this, - destinationId, sourceId, messageType, messageLevel, @@ -273,14 +270,23 @@ void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destinationId, return; } - m_scriptExecutionContext->addMessage(static_cast<MessageDestination>(destinationId), - static_cast<MessageSource>(sourceId), + m_scriptExecutionContext->addMessage(static_cast<MessageSource>(sourceId), static_cast<MessageType>(messageType), static_cast<MessageLevel>(messageLevel), String(message), lineNumber, String(sourceURL)); } +void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int sourceId, + int messageType, + int messageLevel, + const WebString& message, + int lineNumber, + const WebString& sourceURL) +{ + postConsoleMessageToWorkerObject(0, sourceId, messageType, messageLevel, message, lineNumber, sourceURL); +} + void WebWorkerClientImpl::confirmMessageFromWorkerObject(bool hasPendingActivity) { // unconfirmed_message_count_ can only be updated on the thread where it's @@ -354,7 +360,7 @@ void WebWorkerClientImpl::postMessageToWorkerObjectTask( if (thisPtr->m_worker) { OwnPtr<MessagePortArray> ports = - MessagePort::entanglePorts(*context, channels.release()); + MessagePort::entanglePorts(*context, channels); RefPtr<SerializedScriptValue> serializedMessage = SerializedScriptValue::createFromWire(message); thisPtr->m_worker->dispatchEvent(MessageEvent::create(ports.release(), @@ -382,7 +388,6 @@ void WebWorkerClientImpl::postExceptionToWorkerObjectTask( void WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask(ScriptExecutionContext* context, WebWorkerClientImpl* thisPtr, - int destinationId, int sourceId, int messageType, int messageLevel, @@ -390,8 +395,7 @@ void WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask(ScriptExecutionCo int lineNumber, const String& sourceURL) { - thisPtr->m_scriptExecutionContext->addMessage(static_cast<MessageDestination>(destinationId), - static_cast<MessageSource>(sourceId), + thisPtr->m_scriptExecutionContext->addMessage(static_cast<MessageSource>(sourceId), static_cast<MessageType>(messageType), static_cast<MessageLevel>(messageLevel), message, lineNumber, diff --git a/WebKit/chromium/src/WebWorkerClientImpl.h b/WebKit/chromium/src/WebWorkerClientImpl.h index 63acebc..758c376 100644 --- a/WebKit/chromium/src/WebWorkerClientImpl.h +++ b/WebKit/chromium/src/WebWorkerClientImpl.h @@ -33,8 +33,7 @@ #if ENABLE(WORKERS) -// FIXME: fix to just "WebWorkerClient.h" once nobody in glue depends on us. -#include "../public/WebWorkerClient.h" +#include "WebWorkerClient.h" #include "WorkerContextProxy.h" #include <wtf/PassOwnPtr.h> @@ -78,8 +77,12 @@ public: // These are called on the main WebKit thread. virtual void postMessageToWorkerObject(const WebString&, const WebMessagePortChannelArray&); virtual void postExceptionToWorkerObject(const WebString&, int, const WebString&); - virtual void postConsoleMessageToWorkerObject(int, int, int, int, const WebString&, - int, const WebString&); + + // FIXME: the below is for compatibility only and should be + // removed once Chromium is updated to remove message + // destination parameter <http://webkit.org/b/37155>. + virtual void postConsoleMessageToWorkerObject(int, int, int, int, const WebString&, int, const WebString&); + virtual void postConsoleMessageToWorkerObject(int, int, int, const WebString&, int, const WebString&); virtual void confirmMessageFromWorkerObject(bool); virtual void reportPendingActivity(bool); virtual void workerContextClosed(); @@ -90,6 +93,12 @@ public: // FIXME: Notifications not yet supported in workers. return 0; } + virtual WebApplicationCacheHost* createApplicationCacheHost(WebApplicationCacheHostClient*) { return 0; } + virtual bool allowDatabase(WebFrame*, const WebString& name, const WebString& displayName, unsigned long estimatedSize) + { + ASSERT_NOT_REACHED(); + return true; + } private: virtual ~WebWorkerClientImpl(); @@ -125,7 +134,6 @@ private: const WebCore::String& sourceURL); static void postConsoleMessageToWorkerObjectTask(WebCore::ScriptExecutionContext* context, WebWorkerClientImpl* thisPtr, - int destinationId, int sourceId, int messageType, int messageLevel, diff --git a/WebKit/chromium/src/WebWorkerImpl.cpp b/WebKit/chromium/src/WebWorkerImpl.cpp index 5b5e053..165af68 100644 --- a/WebKit/chromium/src/WebWorkerImpl.cpp +++ b/WebKit/chromium/src/WebWorkerImpl.cpp @@ -31,9 +31,9 @@ #include "config.h" #include "WebWorkerImpl.h" +#include "CrossThreadTask.h" #include "DedicatedWorkerContext.h" #include "DedicatedWorkerThread.h" -#include "GenericWorkerTask.h" #include "KURL.h" #include "MessageEvent.h" #include "MessagePort.h" @@ -86,7 +86,7 @@ void WebWorkerImpl::postMessageToWorkerContextTask(WebCore::ScriptExecutionConte static_cast<DedicatedWorkerContext*>(context); OwnPtr<MessagePortArray> ports = - MessagePort::entanglePorts(*context, channels.release()); + MessagePort::entanglePorts(*context, channels); RefPtr<SerializedScriptValue> serializedMessage = SerializedScriptValue::createFromWire(message); workerContext->dispatchEvent(MessageEvent::create( diff --git a/WebKit/chromium/src/WrappedResourceRequest.h b/WebKit/chromium/src/WrappedResourceRequest.h index 97311db..3057387 100644 --- a/WebKit/chromium/src/WrappedResourceRequest.h +++ b/WebKit/chromium/src/WrappedResourceRequest.h @@ -31,9 +31,7 @@ #ifndef WrappedResourceRequest_h #define WrappedResourceRequest_h -// FIXME: This relative path is a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebURLRequest.h" +#include "WebURLRequest.h" #include "WebURLRequestPrivate.h" namespace WebKit { diff --git a/WebKit/chromium/src/WrappedResourceResponse.h b/WebKit/chromium/src/WrappedResourceResponse.h index af4f88f..927582d 100644 --- a/WebKit/chromium/src/WrappedResourceResponse.h +++ b/WebKit/chromium/src/WrappedResourceResponse.h @@ -31,9 +31,7 @@ #ifndef WrappedResourceResponse_h #define WrappedResourceResponse_h -// FIXME: This relative path is a temporary hack to support using this -// header from webkit/glue. -#include "../public/WebURLResponse.h" +#include "WebURLResponse.h" #include "WebURLResponsePrivate.h" namespace WebKit { diff --git a/WebKit/chromium/src/gtk/WebFontInfo.cpp b/WebKit/chromium/src/gtk/WebFontInfo.cpp index 76ed618..dd25eb1 100644 --- a/WebKit/chromium/src/gtk/WebFontInfo.cpp +++ b/WebKit/chromium/src/gtk/WebFontInfo.cpp @@ -30,6 +30,7 @@ #include "config.h" #include "WebFontInfo.h" +#include "WebFontRenderStyle.h" #include <fontconfig/fontconfig.h> #include <string.h> @@ -55,11 +56,11 @@ WebCString WebFontInfo::familyForChars(const WebUChar* characters, size_t numCha FcValue fcvalue; fcvalue.type = FcTypeCharSet; fcvalue.u.c = cset; - FcPatternAdd(pattern, FC_CHARSET, fcvalue, 0); + FcPatternAdd(pattern, FC_CHARSET, fcvalue, FcFalse); fcvalue.type = FcTypeBool; fcvalue.u.b = FcTrue; - FcPatternAdd(pattern, FC_SCALABLE, fcvalue, 0); + FcPatternAdd(pattern, FC_SCALABLE, fcvalue, FcFalse); FcConfigSubstitute(0, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); @@ -104,4 +105,85 @@ WebCString WebFontInfo::familyForChars(const WebUChar* characters, size_t numCha return WebCString(); } +void WebFontInfo::renderStyleForStrike(const char* family, int sizeAndStyle, WebFontRenderStyle* out) +{ + bool isBold = sizeAndStyle & 1; + bool isItalic = sizeAndStyle & 2; + int pixelSize = sizeAndStyle >> 2; + + FcPattern* pattern = FcPatternCreate(); + FcValue fcvalue; + + fcvalue.type = FcTypeString; + fcvalue.u.s = reinterpret_cast<const FcChar8 *>(family); + FcPatternAdd(pattern, FC_FAMILY, fcvalue, FcFalse); + + fcvalue.type = FcTypeInteger; + fcvalue.u.i = isBold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL; + FcPatternAdd(pattern, FC_WEIGHT, fcvalue, FcFalse); + + fcvalue.type = FcTypeInteger; + fcvalue.u.i = isItalic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN; + FcPatternAdd(pattern, FC_SLANT, fcvalue, FcFalse); + + fcvalue.type = FcTypeBool; + fcvalue.u.b = FcTrue; + FcPatternAdd(pattern, FC_SCALABLE, fcvalue, FcFalse); + + fcvalue.type = FcTypeDouble; + fcvalue.u.d = pixelSize; + FcPatternAdd(pattern, FC_SIZE, fcvalue, FcFalse); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + // Some versions of fontconfig don't actually write a value into result. + // However, it's not clear from the documentation if result should be a + // non-0 pointer: future versions might expect to be able to write to + // it. So we pass in a valid pointer and ignore it. + FcPattern* match = FcFontMatch(0, pattern, &result); + FcPatternDestroy(pattern); + + out->setDefaults(); + + if (!match) { + FcPatternDestroy(match); + return; + } + + FcBool b; + int i; + + if (FcPatternGetBool(match, FC_ANTIALIAS, 0, &b) == FcResultMatch) + out->useAntiAlias = b; + if (FcPatternGetBool(match, FC_EMBEDDED_BITMAP, 0, &b) == FcResultMatch) + out->useBitmaps = b; + if (FcPatternGetBool(match, FC_AUTOHINT, 0, &b) == FcResultMatch) + out->useAutoHint = b; + if (FcPatternGetBool(match, FC_HINTING, 0, &b) == FcResultMatch) + out->useHinting = b; + if (FcPatternGetInteger(match, FC_HINT_STYLE, 0, &i) == FcResultMatch) + out->hintStyle = i; + if (FcPatternGetInteger(match, FC_RGBA, 0, &i) == FcResultMatch) { + switch (i) { + case FC_RGBA_NONE: + out->useSubpixel = 0; + break; + case FC_RGBA_RGB: + case FC_RGBA_BGR: + case FC_RGBA_VRGB: + case FC_RGBA_VBGR: + out->useSubpixel = 1; + break; + default: + // This includes FC_RGBA_UNKNOWN. + out->useSubpixel = 2; + break; + } + } + + FcPatternDestroy(match); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/gtk/WebInputEventFactory.cpp b/WebKit/chromium/src/gtk/WebInputEventFactory.cpp index 7125a16..dc46b07 100644 --- a/WebKit/chromium/src/gtk/WebInputEventFactory.cpp +++ b/WebKit/chromium/src/gtk/WebInputEventFactory.cpp @@ -49,7 +49,7 @@ gint getDoubleClickTime() { static GtkSettings* settings = gtk_settings_get_default(); gint doubleClickTime = 250; - g_object_get(G_OBJECT(settings), "gtk-double-click-time", &doubleClickTime, 0); + g_object_get(G_OBJECT(settings), "gtk-double-click-time", &doubleClickTime, NULL); return doubleClickTime; } @@ -151,6 +151,60 @@ static int gdkEventToWindowsKeyCode(const GdkEventKey* event) GDK_period, // 0x3C: GDK_period GDK_slash, // 0x3D: GDK_slash 0, // 0x3E: GDK_Shift_R + 0, // 0x3F: + 0, // 0x40: + 0, // 0x41: + 0, // 0x42: + 0, // 0x43: + 0, // 0x44: + 0, // 0x45: + 0, // 0x46: + 0, // 0x47: + 0, // 0x48: + 0, // 0x49: + 0, // 0x4A: + 0, // 0x4B: + 0, // 0x4C: + 0, // 0x4D: + 0, // 0x4E: + 0, // 0x4F: + 0, // 0x50: + 0, // 0x51: + 0, // 0x52: + 0, // 0x53: + 0, // 0x54: + 0, // 0x55: + 0, // 0x56: + 0, // 0x57: + 0, // 0x58: + 0, // 0x59: + 0, // 0x5A: + 0, // 0x5B: + 0, // 0x5C: + 0, // 0x5D: + 0, // 0x5E: + 0, // 0x5F: + 0, // 0x60: + 0, // 0x61: + 0, // 0x62: + 0, // 0x63: + 0, // 0x64: + 0, // 0x65: + 0, // 0x66: + 0, // 0x67: + 0, // 0x68: + 0, // 0x69: + 0, // 0x6A: + 0, // 0x6B: + 0, // 0x6C: + 0, // 0x6D: + 0, // 0x6E: + 0, // 0x6F: + 0, // 0x70: + 0, // 0x71: + 0, // 0x72: + GDK_Super_L, // 0x73: GDK_Super_L + GDK_Super_R, // 0x74: GDK_Super_R }; // |windowsKeyCode| has to include a valid virtual-key code even when we diff --git a/WebKit/chromium/src/js/DebuggerAgent.js b/WebKit/chromium/src/js/DebuggerAgent.js deleted file mode 100644 index 301620a..0000000 --- a/WebKit/chromium/src/js/DebuggerAgent.js +++ /dev/null @@ -1,1528 +0,0 @@ -/* - * 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. - */ - -/** - * @fileoverview Provides communication interface to remote v8 debugger. See - * protocol decription at http://code.google.com/p/v8/wiki/DebuggerProtocol - */ - -/** - * FIXME: change field naming style to use trailing underscore. - * @constructor - */ -devtools.DebuggerAgent = function() -{ - RemoteDebuggerAgent.debuggerOutput = this.handleDebuggerOutput_.bind(this); - RemoteDebuggerAgent.setContextId = this.setContextId_.bind(this); - - /** - * Id of the inspected page global context. It is used for filtering scripts. - * @type {number} - */ - this.contextId_ = null; - - /** - * Mapping from script id to script info. - * @type {Object} - */ - this.parsedScripts_ = null; - - /** - * Mapping from the request id to the devtools.BreakpointInfo for the - * breakpoints whose v8 ids are not set yet. These breakpoints are waiting for - * "setbreakpoint" responses to learn their ids in the v8 debugger. - * @see #handleSetBreakpointResponse_ - * @type {Object} - */ - this.requestNumberToBreakpointInfo_ = null; - - /** - * Information on current stack frames. - * @type {Array.<devtools.CallFrame>} - */ - this.callFrames_ = []; - - /** - * Whether to stop in the debugger on the exceptions. - * @type {boolean} - */ - this.pauseOnExceptions_ = false; - - /** - * Mapping: request sequence number->callback. - * @type {Object} - */ - this.requestSeqToCallback_ = null; - - /** - * Whether the scripts panel has been shown and initialilzed. - * @type {boolean} - */ - this.scriptsPanelInitialized_ = false; - - /** - * Whether the scripts list should be requested next time when context id is - * set. - * @type {boolean} - */ - this.requestScriptsWhenContextIdSet_ = false; - - /** - * Whether the agent is waiting for initial scripts response. - * @type {boolean} - */ - this.waitingForInitialScriptsResponse_ = false; - - /** - * If backtrace response is received when initial scripts response - * is not yet processed the backtrace handling will be postponed until - * after the scripts response processing. The handler bound to its arguments - * and this agent will be stored in this field then. - * @type {?function()} - */ - this.pendingBacktraceResponseHandler_ = null; - - /** - * Container of all breakpoints set using resource URL. These breakpoints - * survive page reload. Breakpoints set by script id(for scripts that don't - * have URLs) are stored in ScriptInfo objects. - * @type {Object} - */ - this.urlToBreakpoints_ = {}; - - - /** - * Exception message that is shown to user while on exception break. - * @type {WebInspector.ConsoleMessage} - */ - this.currentExceptionMessage_ = null; -}; - - -/** - * A copy of the scope types from v8/src/mirror-delay.js - * @enum {number} - */ -devtools.DebuggerAgent.ScopeType = { - Global: 0, - Local: 1, - With: 2, - Closure: 3, - Catch: 4 -}; - - -/** - * Resets debugger agent to its initial state. - */ -devtools.DebuggerAgent.prototype.reset = function() -{ - this.contextId_ = null; - // No need to request scripts since they all will be pushed in AfterCompile - // events. - this.requestScriptsWhenContextIdSet_ = false; - this.waitingForInitialScriptsResponse_ = false; - - this.parsedScripts_ = {}; - this.requestNumberToBreakpointInfo_ = {}; - this.callFrames_ = []; - this.requestSeqToCallback_ = {}; -}; - - -/** - * Initializes scripts UI. This method is called every time Scripts panel - * is shown. It will send request for context id if it's not set yet. - */ -devtools.DebuggerAgent.prototype.initUI = function() -{ - // Initialize scripts cache when Scripts panel is shown first time. - if (this.scriptsPanelInitialized_) - return; - this.scriptsPanelInitialized_ = true; - if (this.contextId_) { - // We already have context id. This means that we are here from the - // very beginning of the page load cycle and hence will get all scripts - // via after-compile events. No need to request scripts for this session. - // - // There can be a number of scripts from after-compile events that are - // pending addition into the UI. - for (var scriptId in this.parsedScripts_) { - var script = this.parsedScripts_[scriptId]; - WebInspector.parsedScriptSource(scriptId, script.getUrl(), undefined /* script source */, script.getLineOffset()); - } - return; - } - this.waitingForInitialScriptsResponse_ = true; - // Script list should be requested only when current context id is known. - RemoteDebuggerAgent.getContextId(); - this.requestScriptsWhenContextIdSet_ = true; -}; - - -/** - * Asynchronously requests the debugger for the script source. - * @param {number} scriptId Id of the script whose source should be resolved. - * @param {function(source:?string):void} callback Function that will be called - * when the source resolution is completed. "source" parameter will be null - * if the resolution fails. - */ -devtools.DebuggerAgent.prototype.resolveScriptSource = function(scriptId, callback) -{ - var script = this.parsedScripts_[scriptId]; - if (!script || script.isUnresolved()) { - callback(null); - return; - } - - var cmd = new devtools.DebugCommand("scripts", { - "ids": [scriptId], - "includeSource": true - }); - devtools.DebuggerAgent.sendCommand_(cmd); - // Force v8 execution so that it gets to processing the requested command. - RemoteDebuggerAgent.processDebugCommands(); - - this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { - if (msg.isSuccess()) { - var scriptJson = msg.getBody()[0]; - if (scriptJson) - callback(scriptJson.source); - else - callback(null); - } else - callback(null); - }; -}; - - -/** - * Tells the v8 debugger to stop on as soon as possible. - */ -devtools.DebuggerAgent.prototype.pauseExecution = function() -{ - RemoteDebuggerCommandExecutor.DebuggerPauseScript(); -}; - - -/** - * @param {number} sourceId Id of the script fot the breakpoint. - * @param {number} line Number of the line for the breakpoint. - * @param {?string} condition The breakpoint condition. - */ -devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line, condition) -{ - var script = this.parsedScripts_[sourceId]; - if (!script) - return; - - line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); - - var commandArguments; - if (script.getUrl()) { - var breakpoints = this.urlToBreakpoints_[script.getUrl()]; - if (breakpoints && breakpoints[line]) - return; - if (!breakpoints) { - breakpoints = {}; - this.urlToBreakpoints_[script.getUrl()] = breakpoints; - } - - var breakpointInfo = new devtools.BreakpointInfo(line); - breakpoints[line] = breakpointInfo; - - commandArguments = { - "groupId": this.contextId_, - "type": "script", - "target": script.getUrl(), - "line": line, - "condition": condition - }; - } else { - var breakpointInfo = script.getBreakpointInfo(line); - if (breakpointInfo) - return; - - breakpointInfo = new devtools.BreakpointInfo(line); - script.addBreakpointInfo(breakpointInfo); - - commandArguments = { - "groupId": this.contextId_, - "type": "scriptId", - "target": sourceId, - "line": line, - "condition": condition - }; - } - - var cmd = new devtools.DebugCommand("setbreakpoint", commandArguments); - - this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo; - - devtools.DebuggerAgent.sendCommand_(cmd); - // Force v8 execution so that it gets to processing the requested command. - // It is necessary for being able to change a breakpoint just after it - // has been created (since we need an existing breakpoint id for that). - RemoteDebuggerAgent.processDebugCommands(); -}; - - -/** - * @param {number} sourceId Id of the script for the breakpoint. - * @param {number} line Number of the line for the breakpoint. - */ -devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) -{ - var script = this.parsedScripts_[sourceId]; - if (!script) - return; - - line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); - - var breakpointInfo; - if (script.getUrl()) { - var breakpoints = this.urlToBreakpoints_[script.getUrl()]; - breakpointInfo = breakpoints[line]; - delete breakpoints[line]; - } else { - breakpointInfo = script.getBreakpointInfo(line); - if (breakpointInfo) - script.removeBreakpointInfo(breakpointInfo); - } - - if (!breakpointInfo) - return; - - breakpointInfo.markAsRemoved(); - - var id = breakpointInfo.getV8Id(); - - // If we don't know id of this breakpoint in the v8 debugger we cannot send - // "clearbreakpoint" request. In that case it will be removed in - // "setbreakpoint" response handler when we learn the id. - if (id !== -1) { - this.requestClearBreakpoint_(id); - } -}; - - -/** - * @param {number} sourceId Id of the script for the breakpoint. - * @param {number} line Number of the line for the breakpoint. - * @param {?string} condition New breakpoint condition. - */ -devtools.DebuggerAgent.prototype.updateBreakpoint = function(sourceId, line, condition) -{ - var script = this.parsedScripts_[sourceId]; - if (!script) - return; - - line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); - - var breakpointInfo; - if (script.getUrl()) { - var breakpoints = this.urlToBreakpoints_[script.getUrl()]; - breakpointInfo = breakpoints[line]; - } else - breakpointInfo = script.getBreakpointInfo(line); - - var id = breakpointInfo.getV8Id(); - - // If we don't know id of this breakpoint in the v8 debugger we cannot send - // the "changebreakpoint" request. - if (id !== -1) { - // TODO(apavlov): make use of the real values for "enabled" and - // "ignoreCount" when appropriate. - this.requestChangeBreakpoint_(id, true, condition, null); - } -}; - - -/** - * Tells the v8 debugger to step into the next statement. - */ -devtools.DebuggerAgent.prototype.stepIntoStatement = function() -{ - this.stepCommand_("in"); -}; - - -/** - * Tells the v8 debugger to step out of current function. - */ -devtools.DebuggerAgent.prototype.stepOutOfFunction = function() -{ - this.stepCommand_("out"); -}; - - -/** - * Tells the v8 debugger to step over the next statement. - */ -devtools.DebuggerAgent.prototype.stepOverStatement = function() -{ - this.stepCommand_("next"); -}; - - -/** - * Tells the v8 debugger to continue execution after it has been stopped on a - * breakpoint or an exception. - */ -devtools.DebuggerAgent.prototype.resumeExecution = function() -{ - this.clearExceptionMessage_(); - var cmd = new devtools.DebugCommand("continue"); - devtools.DebuggerAgent.sendCommand_(cmd); -}; - - -/** - * Creates exception message and schedules it for addition to the resource upon - * backtrace availability. - * @param {string} url Resource url. - * @param {number} line Resource line number. - * @param {string} message Exception text. - */ -devtools.DebuggerAgent.prototype.createExceptionMessage_ = function(url, line, message) -{ - this.currentExceptionMessage_ = new WebInspector.ConsoleMessage( - WebInspector.ConsoleMessage.MessageSource.JS, - WebInspector.ConsoleMessage.MessageType.Log, - WebInspector.ConsoleMessage.MessageLevel.Error, - line, - url, - 0 /* group level */, - 1 /* repeat count */, - "[Exception] " + message); -}; - - -/** - * Shows pending exception message that is created with createExceptionMessage_ - * earlier. - */ -devtools.DebuggerAgent.prototype.showPendingExceptionMessage_ = function() -{ - if (!this.currentExceptionMessage_) - return; - var msg = this.currentExceptionMessage_; - var resource = WebInspector.resourceURLMap[msg.url]; - if (resource) { - msg.resource = resource; - WebInspector.panels.resources.addMessageToResource(resource, msg); - } else - this.currentExceptionMessage_ = null; -}; - - -/** - * Clears exception message from the resource. - */ -devtools.DebuggerAgent.prototype.clearExceptionMessage_ = function() -{ - if (this.currentExceptionMessage_) { - var messageElement = this.currentExceptionMessage_._resourceMessageLineElement; - var bubble = messageElement.parentElement; - bubble.removeChild(messageElement); - if (!bubble.firstChild) { - // Last message in bubble removed. - bubble.parentElement.removeChild(bubble); - } - this.currentExceptionMessage_ = null; - } -}; - - -/** - * @return {boolean} True iff the debugger will pause execution on the - * exceptions. - */ -devtools.DebuggerAgent.prototype.pauseOnExceptions = function() -{ - return this.pauseOnExceptions_; -}; - - -/** - * Tells whether to pause in the debugger on the exceptions or not. - * @param {boolean} value True iff execution should be stopped in the debugger - * on the exceptions. - */ -devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) -{ - this.pauseOnExceptions_ = value; -}; - - -/** - * Sends "evaluate" request to the debugger. - * @param {Object} arguments Request arguments map. - * @param {function(devtools.DebuggerMessage)} callback Callback to be called - * when response is received. - */ -devtools.DebuggerAgent.prototype.requestEvaluate = function(arguments, callback) -{ - var cmd = new devtools.DebugCommand("evaluate", arguments); - devtools.DebuggerAgent.sendCommand_(cmd); - this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; -}; - - -/** - * Sends "lookup" request for each unresolved property of the object. When - * response is received the properties will be changed with their resolved - * values. - * @param {Object} object Object whose properties should be resolved. - * @param {function(devtools.DebuggerMessage)} Callback to be called when all - * children are resolved. - * @param {boolean} noIntrinsic Whether intrinsic properties should be included. - */ -devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback, noIntrinsic) -{ - if ("handle" in object) { - var result = []; - devtools.DebuggerAgent.formatObjectProperties_(object, result, noIntrinsic); - callback(result); - } else { - this.requestLookup_([object.ref], function(msg) { - var result = []; - if (msg.isSuccess()) { - var handleToObject = msg.getBody(); - var resolved = handleToObject[object.ref]; - devtools.DebuggerAgent.formatObjectProperties_(resolved, result, noIntrinsic); - callback(result); - } else - callback([]); - }); - } -}; - - -/** - * Sends "scope" request for the scope object to resolve its variables. - * @param {Object} scope Scope to be resolved. - * @param {function(Array.<WebInspector.ObjectPropertyProxy>)} callback - * Callback to be called when all scope variables are resolved. - */ -devtools.DebuggerAgent.prototype.resolveScope = function(scope, callback) -{ - var cmd = new devtools.DebugCommand("scope", { - "frameNumber": scope.frameNumber, - "number": scope.index, - "compactFormat": true - }); - devtools.DebuggerAgent.sendCommand_(cmd); - this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { - var result = []; - if (msg.isSuccess()) { - var scopeObjectJson = msg.getBody().object; - devtools.DebuggerAgent.formatObjectProperties_(scopeObjectJson, result, true /* no intrinsic */); - } - callback(result); - }; -}; - - -/** - * Sends "scopes" request for the frame object to resolve all variables - * available in the frame. - * @param {number} callFrameId Id of call frame whose variables need to - * be resolved. - * @param {function(Object)} callback Callback to be called when all frame - * variables are resolved. - */ -devtools.DebuggerAgent.prototype.resolveFrameVariables_ = function(callFrameId, callback) -{ - var result = {}; - - var frame = this.callFrames_[callFrameId]; - if (!frame) { - callback(result); - return; - } - - var waitingResponses = 0; - function scopeResponseHandler(msg) { - waitingResponses--; - - if (msg.isSuccess()) { - var properties = msg.getBody().object.properties; - for (var j = 0; j < properties.length; j++) - result[properties[j].name] = true; - } - - // When all scopes are resolved invoke the callback. - if (waitingResponses === 0) - callback(result); - }; - - for (var i = 0; i < frame.scopeChain.length; i++) { - var scope = frame.scopeChain[i].objectId; - if (scope.type === devtools.DebuggerAgent.ScopeType.Global) { - // Do not resolve global scope since it takes for too long. - // TODO(yurys): allow to send only property names in the response. - continue; - } - var cmd = new devtools.DebugCommand("scope", { - "frameNumber": scope.frameNumber, - "number": scope.index, - "compactFormat": true - }); - devtools.DebuggerAgent.sendCommand_(cmd); - this.requestSeqToCallback_[cmd.getSequenceNumber()] = scopeResponseHandler; - waitingResponses++; - } -}; - -/** - * Evaluates the expressionString to an object in the call frame and reports - * all its properties. - * @param{string} expressionString Expression whose properties should be - * collected. - * @param{number} callFrameId The frame id. - * @param{function(Object result,bool isException)} reportCompletions Callback - * function. - */ -devtools.DebuggerAgent.prototype.resolveCompletionsOnFrame = function(expressionString, callFrameId, reportCompletions) -{ - if (expressionString) { - expressionString = "var obj = " + expressionString + - "; var names = {}; for (var n in obj) { names[n] = true; };" + - "names;"; - this.evaluateInCallFrame( - callFrameId, - expressionString, - function(result) { - var names = {}; - if (!result.isException) { - var props = result.value.objectId.properties; - // Put all object properties into the map. - for (var i = 0; i < props.length; i++) - names[props[i].name] = true; - } - reportCompletions(names, result.isException); - }); - } else { - this.resolveFrameVariables_(callFrameId, - function(result) { - reportCompletions(result, false /* isException */); - }); - } -}; - - -/** - * @param{number} scriptId - * @return {string} Type of the context of the script with specified id. - */ -devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) -{ - return this.parsedScripts_[scriptId].getContextType(); -}; - - -/** - * Removes specified breakpoint from the v8 debugger. - * @param {number} breakpointId Id of the breakpoint in the v8 debugger. - */ -devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function(breakpointId) -{ - var cmd = new devtools.DebugCommand("clearbreakpoint", { - "breakpoint": breakpointId - }); - devtools.DebuggerAgent.sendCommand_(cmd); -}; - - -/** - * Changes breakpoint parameters in the v8 debugger. - * @param {number} breakpointId Id of the breakpoint in the v8 debugger. - * @param {boolean} enabled Whether to enable the breakpoint. - * @param {?string} condition New breakpoint condition. - * @param {number} ignoreCount New ignore count for the breakpoint. - */ -devtools.DebuggerAgent.prototype.requestChangeBreakpoint_ = function(breakpointId, enabled, condition, ignoreCount) -{ - var cmd = new devtools.DebugCommand("changebreakpoint", { - "breakpoint": breakpointId, - "enabled": enabled, - "condition": condition, - "ignoreCount": ignoreCount - }); - devtools.DebuggerAgent.sendCommand_(cmd); -}; - - -/** - * Sends "backtrace" request to v8. - */ -devtools.DebuggerAgent.prototype.requestBacktrace_ = function() -{ - var cmd = new devtools.DebugCommand("backtrace", { - "compactFormat":true - }); - devtools.DebuggerAgent.sendCommand_(cmd); -}; - - -/** - * Sends command to v8 debugger. - * @param {devtools.DebugCommand} cmd Command to execute. - */ -devtools.DebuggerAgent.sendCommand_ = function(cmd) -{ - RemoteDebuggerCommandExecutor.DebuggerCommand(cmd.toJSONProtocol()); -}; - - -/** - * Tells the v8 debugger to make the next execution step. - * @param {string} action "in", "out" or "next" action. - */ -devtools.DebuggerAgent.prototype.stepCommand_ = function(action) -{ - this.clearExceptionMessage_(); - var cmd = new devtools.DebugCommand("continue", { - "stepaction": action, - "stepcount": 1 - }); - devtools.DebuggerAgent.sendCommand_(cmd); -}; - - -/** - * Sends "lookup" request to v8. - * @param {number} handle Handle to the object to lookup. - */ -devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) -{ - var cmd = new devtools.DebugCommand("lookup", { - "compactFormat":true, - "handles": handles - }); - devtools.DebuggerAgent.sendCommand_(cmd); - this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; -}; - - -/** - * Sets debugger context id for scripts filtering. - * @param {number} contextId Id of the inspected page global context. - */ -devtools.DebuggerAgent.prototype.setContextId_ = function(contextId) -{ - this.contextId_ = contextId; - - // If it's the first time context id is set request scripts list. - if (this.requestScriptsWhenContextIdSet_) { - this.requestScriptsWhenContextIdSet_ = false; - var cmd = new devtools.DebugCommand("scripts", { - "includeSource": false - }); - devtools.DebuggerAgent.sendCommand_(cmd); - // Force v8 execution so that it gets to processing the requested command. - RemoteDebuggerAgent.processDebugCommands(); - - var debuggerAgent = this; - this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { - // Handle the response iff the context id hasn't changed since the request - // was issued. Otherwise if the context id did change all up-to-date - // scripts will be pushed in after compile events and there is no need to - // handle the response. - if (contextId === debuggerAgent.contextId_) - debuggerAgent.handleScriptsResponse_(msg); - - // We received initial scripts response so flush the flag and - // see if there is an unhandled backtrace response. - debuggerAgent.waitingForInitialScriptsResponse_ = false; - if (debuggerAgent.pendingBacktraceResponseHandler_) { - debuggerAgent.pendingBacktraceResponseHandler_(); - debuggerAgent.pendingBacktraceResponseHandler_ = null; - } - }; - } -}; - - -/** - * Handles output sent by v8 debugger. The output is either asynchronous event - * or response to a previously sent request. See protocol definitioun for more - * details on the output format. - * @param {string} output - */ -devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) -{ - var msg; - try { - msg = new devtools.DebuggerMessage(output); - } catch(e) { - debugPrint("Failed to handle debugger response:\n" + e); - throw e; - } - - if (msg.getType() === "event") { - if (msg.getEvent() === "break") - this.handleBreakEvent_(msg); - else if (msg.getEvent() === "exception") - this.handleExceptionEvent_(msg); - else if (msg.getEvent() === "afterCompile") - this.handleAfterCompileEvent_(msg); - } else if (msg.getType() === "response") { - if (msg.getCommand() === "scripts") - this.invokeCallbackForResponse_(msg); - else if (msg.getCommand() === "setbreakpoint") - this.handleSetBreakpointResponse_(msg); - else if (msg.getCommand() === "clearbreakpoint") - this.handleClearBreakpointResponse_(msg); - else if (msg.getCommand() === "backtrace") - this.handleBacktraceResponse_(msg); - else if (msg.getCommand() === "lookup") - this.invokeCallbackForResponse_(msg); - else if (msg.getCommand() === "evaluate") - this.invokeCallbackForResponse_(msg); - else if (msg.getCommand() === "scope") - this.invokeCallbackForResponse_(msg); - } -}; - - -/** - * @param {devtools.DebuggerMessage} msg - */ -devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) -{ - // Force scrips panel to be shown first. - WebInspector.currentPanel = WebInspector.panels.scripts; - - var body = msg.getBody(); - - var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); - this.requestBacktrace_(); -}; - - -/** - * @param {devtools.DebuggerMessage} msg - */ -devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) -{ - // Force scrips panel to be shown first. - WebInspector.currentPanel = WebInspector.panels.scripts; - - var body = msg.getBody(); - // No script field in the body means that v8 failed to parse the script. We - // resume execution on parser errors automatically. - if (this.pauseOnExceptions_ && body.script) { - var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); - this.createExceptionMessage_(body.script.name, line, body.exception.text); - this.requestBacktrace_(); - } else - this.resumeExecution(); -}; - - -/** - * @param {devtools.DebuggerMessage} msg - */ -devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) -{ - var scripts = msg.getBody(); - for (var i = 0; i < scripts.length; i++) { - var script = scripts[i]; - - // Skip scripts from other tabs. - if (!this.isScriptFromInspectedContext_(script, msg)) - continue; - - // We may already have received the info in an afterCompile event. - if (script.id in this.parsedScripts_) - continue; - this.addScriptInfo_(script, msg); - } -}; - - -/** - * @param {Object} script Json object representing script. - * @param {devtools.DebuggerMessage} msg Debugger response. - */ -devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function(script, msg) -{ - if (!script.context) { - // Always ignore scripts from the utility context. - return false; - } - var context = msg.lookup(script.context.ref); - var scriptContextId = context.data; - if (typeof scriptContextId === "undefined") - return false; // Always ignore scripts from the utility context. - if (this.contextId_ === null) - return true; - // Find the id from context data. The context data has the format "type,id". - var comma = context.data.indexOf(","); - if (comma < 0) - return false; - return (context.data.substring(comma + 1) == this.contextId_); -}; - - -/** - * @param {devtools.DebuggerMessage} msg - */ -devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) -{ - var requestSeq = msg.getRequestSeq(); - var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq]; - if (!breakpointInfo) { - // TODO(yurys): handle this case - return; - } - delete this.requestNumberToBreakpointInfo_[requestSeq]; - if (!msg.isSuccess()) { - // TODO(yurys): handle this case - return; - } - var idInV8 = msg.getBody().breakpoint; - breakpointInfo.setV8Id(idInV8); - - if (breakpointInfo.isRemoved()) - this.requestClearBreakpoint_(idInV8); -}; - - -/** - * @param {devtools.DebuggerMessage} msg - */ -devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) -{ - if (!this.contextId_) { - // Ignore scripts delta if main request has not been issued yet. - return; - } - var script = msg.getBody().script; - - // Ignore scripts from other tabs. - if (!this.isScriptFromInspectedContext_(script, msg)) - return; - this.addScriptInfo_(script, msg); -}; - - -/** - * Adds the script info to the local cache. This method assumes that the script - * is not in the cache yet. - * @param {Object} script Script json object from the debugger message. - * @param {devtools.DebuggerMessage} msg Debugger message containing the script - * data. - */ -devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) -{ - var context = msg.lookup(script.context.ref); - var contextType; - // Find the type from context data. The context data has the format - // "type,id". - var comma = context.data.indexOf(","); - if (comma < 0) - return - contextType = context.data.substring(0, comma); - this.parsedScripts_[script.id] = new devtools.ScriptInfo(script.id, script.name, script.lineOffset, contextType); - if (this.scriptsPanelInitialized_) { - // Only report script as parsed after scripts panel has been shown. - WebInspector.parsedScriptSource(script.id, script.name, script.source, script.lineOffset); - } -}; - - -/** - * @param {devtools.DebuggerMessage} msg - */ -devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function(msg) -{ - // Do nothing. -}; - - -/** - * Handles response to "backtrace" command. - * @param {devtools.DebuggerMessage} msg - */ -devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) -{ - if (this.waitingForInitialScriptsResponse_) - this.pendingBacktraceResponseHandler_ = this.doHandleBacktraceResponse_.bind(this, msg); - else - this.doHandleBacktraceResponse_(msg); -}; - - -/** - * @param {devtools.DebuggerMessage} msg - */ -devtools.DebuggerAgent.prototype.doHandleBacktraceResponse_ = function(msg) -{ - var frames = msg.getBody().frames; - this.callFrames_ = []; - for (var i = 0; i < frames.length; ++i) - this.callFrames_.push(this.formatCallFrame_(frames[i])); - WebInspector.pausedScript(this.callFrames_); - this.showPendingExceptionMessage_(); - InspectorFrontendHost.activateWindow(); -}; - - -/** - * Evaluates code on given callframe. - */ -devtools.DebuggerAgent.prototype.evaluateInCallFrame = function(callFrameId, code, callback) -{ - var callFrame = this.callFrames_[callFrameId]; - callFrame.evaluate_(code, callback); -}; - - -/** - * Handles response to a command by invoking its callback (if any). - * @param {devtools.DebuggerMessage} msg - * @return {boolean} Whether a callback for the given message was found and - * excuted. - */ -devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg) -{ - var callback = this.requestSeqToCallback_[msg.getRequestSeq()]; - if (!callback) { - // It may happend if reset was called. - return false; - } - delete this.requestSeqToCallback_[msg.getRequestSeq()]; - callback(msg); - return true; -}; - - -/** - * @param {Object} stackFrame Frame json object from "backtrace" response. - * @return {!devtools.CallFrame} Object containing information related to the - * call frame in the format expected by ScriptsPanel and its panes. - */ -devtools.DebuggerAgent.prototype.formatCallFrame_ = function(stackFrame) -{ - var func = stackFrame.func; - var sourceId = func.scriptId; - - // Add service script if it does not exist. - var existingScript = this.parsedScripts_[sourceId]; - if (!existingScript) { - this.parsedScripts_[sourceId] = new devtools.ScriptInfo(sourceId, null /* name */, 0 /* line */, "unknown" /* type */, true /* unresolved */); - WebInspector.parsedScriptSource(sourceId, null, null, 0); - } - - var funcName = func.name || func.inferredName || "(anonymous function)"; - var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line); - - // Add basic scope chain info with scope variables. - var scopeChain = []; - var ScopeType = devtools.DebuggerAgent.ScopeType; - for (var i = 0; i < stackFrame.scopes.length; i++) { - var scope = stackFrame.scopes[i]; - scope.frameNumber = stackFrame.index; - var scopeObjectProxy = new WebInspector.ObjectProxy(0, scope, [], 0, "", true); - scopeObjectProxy.isScope = true; - switch(scope.type) { - case ScopeType.Global: - scopeObjectProxy.isDocument = true; - break; - case ScopeType.Local: - scopeObjectProxy.isLocal = true; - scopeObjectProxy.thisObject = devtools.DebuggerAgent.formatObjectProxy_(stackFrame.receiver); - break; - case ScopeType.With: - // Catch scope is treated as a regular with scope by WebKit so we - // also treat it this way. - case ScopeType.Catch: - scopeObjectProxy.isWithBlock = true; - break; - case ScopeType.Closure: - scopeObjectProxy.isClosure = true; - break; - } - scopeChain.push(scopeObjectProxy); - } - return new devtools.CallFrame(stackFrame.index, "function", funcName, sourceId, line, scopeChain); -}; - - -/** - * Collects properties for an object from the debugger response. - * @param {Object} object An object from the debugger protocol response. - * @param {Array.<WebInspector.ObjectPropertyProxy>} result An array to put the - * properties into. - * @param {boolean} noIntrinsic Whether intrinsic properties should be - * included. - */ -devtools.DebuggerAgent.formatObjectProperties_ = function(object, result, noIntrinsic) -{ - devtools.DebuggerAgent.propertiesToProxies_(object.properties, result); - if (noIntrinsic) - return; - - result.push(new WebInspector.ObjectPropertyProxy("__proto__", devtools.DebuggerAgent.formatObjectProxy_(object.protoObject))); - result.push(new WebInspector.ObjectPropertyProxy("constructor", devtools.DebuggerAgent.formatObjectProxy_(object.constructorFunction))); - // Don't add 'prototype' property since it is one of the regualar properties. -}; - - -/** - * For each property in "properties" creates its proxy representative. - * @param {Array.<Object>} properties Receiver properties or locals array from - * "backtrace" response. - * @param {Array.<WebInspector.ObjectPropertyProxy>} Results holder. - */ -devtools.DebuggerAgent.propertiesToProxies_ = function(properties, result) -{ - var map = {}; - for (var i = 0; i < properties.length; ++i) { - var property = properties[i]; - var name = String(property.name); - if (name in map) - continue; - map[name] = true; - var value = devtools.DebuggerAgent.formatObjectProxy_(property.value); - var propertyProxy = new WebInspector.ObjectPropertyProxy(name, value); - result.push(propertyProxy); - } -}; - - -/** - * @param {Object} v An object reference from the debugger response. - * @return {*} The value representation expected by ScriptsPanel. - */ -devtools.DebuggerAgent.formatObjectProxy_ = function(v) -{ - var description; - var hasChildren = false; - if (v.type === "object") { - description = v.className; - hasChildren = true; - } else if (v.type === "function") { - if (v.source) - description = v.source; - else - description = "function " + v.name + "()"; - hasChildren = true; - } else if (v.type === "undefined") - description = "undefined"; - else if (v.type === "null") - description = "null"; - else if (typeof v.value !== "undefined") { - // Check for undefined and null types before checking the value, otherwise - // null/undefined may have blank value. - description = v.value; - } else - description = "<unresolved ref: " + v.ref + ", type: " + v.type + ">"; - - var proxy = new WebInspector.ObjectProxy(0, v, [], 0, description, hasChildren); - proxy.type = v.type; - proxy.isV8Ref = true; - return proxy; -}; - - -/** - * Converts line number from Web Inspector UI(1-based) to v8(0-based). - * @param {number} line Resource line number in Web Inspector UI. - * @return {number} The line number in v8. - */ -devtools.DebuggerAgent.webkitToV8LineNumber_ = function(line) -{ - return line - 1; -}; - - -/** - * Converts line number from v8(0-based) to Web Inspector UI(1-based). - * @param {number} line Resource line number in v8. - * @return {number} The line number in Web Inspector. - */ -devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) -{ - return line + 1; -}; - - -/** - * @param {number} scriptId Id of the script. - * @param {?string} url Script resource URL if any. - * @param {number} lineOffset First line 0-based offset in the containing - * document. - * @param {string} contextType Type of the script's context: - * "page" - regular script from html page - * "injected" - extension content script - * @param {bool} opt_isUnresolved If true, script will not be resolved. - * @constructor - */ -devtools.ScriptInfo = function(scriptId, url, lineOffset, contextType, opt_isUnresolved) -{ - this.scriptId_ = scriptId; - this.lineOffset_ = lineOffset; - this.contextType_ = contextType; - this.url_ = url; - this.isUnresolved_ = opt_isUnresolved; - - this.lineToBreakpointInfo_ = {}; -}; - - -/** - * @return {number} - */ -devtools.ScriptInfo.prototype.getLineOffset = function() -{ - return this.lineOffset_; -}; - - -/** - * @return {string} - */ -devtools.ScriptInfo.prototype.getContextType = function() -{ - return this.contextType_; -}; - - -/** - * @return {?string} - */ -devtools.ScriptInfo.prototype.getUrl = function() -{ - return this.url_; -}; - - -/** - * @return {?bool} - */ -devtools.ScriptInfo.prototype.isUnresolved = function() -{ - return this.isUnresolved_; -}; - - -/** - * @param {number} line 0-based line number in the script. - * @return {?devtools.BreakpointInfo} Information on a breakpoint at the - * specified line in the script or undefined if there is no breakpoint at - * that line. - */ -devtools.ScriptInfo.prototype.getBreakpointInfo = function(line) -{ - return this.lineToBreakpointInfo_[line]; -}; - - -/** - * Adds breakpoint info to the script. - * @param {devtools.BreakpointInfo} breakpoint - */ -devtools.ScriptInfo.prototype.addBreakpointInfo = function(breakpoint) -{ - this.lineToBreakpointInfo_[breakpoint.getLine()] = breakpoint; -}; - - -/** - * @param {devtools.BreakpointInfo} breakpoint Breakpoint info to be removed. - */ -devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) -{ - var line = breakpoint.getLine(); - delete this.lineToBreakpointInfo_[line]; -}; - - - -/** - * @param {number} line Breakpoint 0-based line number in the containing script. - * @constructor - */ -devtools.BreakpointInfo = function(line) -{ - this.line_ = line; - this.v8id_ = -1; - this.removed_ = false; -}; - - -/** - * @return {number} - */ -devtools.BreakpointInfo.prototype.getLine = function(n) -{ - return this.line_; -}; - - -/** - * @return {number} Unique identifier of this breakpoint in the v8 debugger. - */ -devtools.BreakpointInfo.prototype.getV8Id = function(n) -{ - return this.v8id_; -}; - - -/** - * Sets id of this breakpoint in the v8 debugger. - * @param {number} id - */ -devtools.BreakpointInfo.prototype.setV8Id = function(id) -{ - this.v8id_ = id; -}; - - -/** - * Marks this breakpoint as removed from the front-end. - */ -devtools.BreakpointInfo.prototype.markAsRemoved = function() -{ - this.removed_ = true; -}; - - -/** - * @return {boolean} Whether this breakpoint has been removed from the - * front-end. - */ -devtools.BreakpointInfo.prototype.isRemoved = function() -{ - return this.removed_; -}; - - -/** - * Call stack frame data. - * @param {string} id CallFrame id. - * @param {string} type CallFrame type. - * @param {string} functionName CallFrame type. - * @param {string} sourceID Source id. - * @param {number} line Source line. - * @param {Array.<Object>} scopeChain Array of scoped objects. - * @construnctor - */ -devtools.CallFrame = function(id, type, functionName, sourceID, line, scopeChain) -{ - this.id = id; - this.type = type; - this.functionName = functionName; - this.sourceID = sourceID; - this.line = line; - this.scopeChain = scopeChain; -}; - - -/** - * This method issues asynchronous evaluate request, reports result to the - * callback. - * @param {string} expression An expression to be evaluated in the context of - * this call frame. - * @param {function(Object):undefined} callback Callback to report result to. - */ -devtools.CallFrame.prototype.evaluate_ = function(expression, callback) -{ - devtools.tools.getDebuggerAgent().requestEvaluate({ - "expression": expression, - "frame": this.id, - "global": false, - "disable_break": false, - "compactFormat": true - }, - function(response) { - var result = {}; - if (response.isSuccess()) - result.value = devtools.DebuggerAgent.formatObjectProxy_(response.getBody()); - else { - result.value = response.getMessage(); - result.isException = true; - } - callback(result); - }); -}; - - -/** - * JSON based commands sent to v8 debugger. - * @param {string} command Name of the command to execute. - * @param {Object} opt_arguments Command-specific arguments map. - * @constructor - */ -devtools.DebugCommand = function(command, opt_arguments) -{ - this.command_ = command; - this.type_ = "request"; - this.seq_ = ++devtools.DebugCommand.nextSeq_; - if (opt_arguments) - this.arguments_ = opt_arguments; -}; - - -/** - * Next unique number to be used as debugger request sequence number. - * @type {number} - */ -devtools.DebugCommand.nextSeq_ = 1; - - -/** - * @return {number} - */ -devtools.DebugCommand.prototype.getSequenceNumber = function() -{ - return this.seq_; -}; - - -/** - * @return {string} - */ -devtools.DebugCommand.prototype.toJSONProtocol = function() -{ - var json = { - "seq": this.seq_, - "type": this.type_, - "command": this.command_ - } - if (this.arguments_) - json.arguments = this.arguments_; - return JSON.stringify(json); -}; - - -/** - * JSON messages sent from v8 debugger. See protocol definition for more - * details: http://code.google.com/p/v8/wiki/DebuggerProtocol - * @param {string} msg Raw protocol packet as JSON string. - * @constructor - */ -devtools.DebuggerMessage = function(msg) -{ - this.packet_ = JSON.parse(msg); - this.refs_ = []; - if (this.packet_.refs) { - for (var i = 0; i < this.packet_.refs.length; i++) - this.refs_[this.packet_.refs[i].handle] = this.packet_.refs[i]; - } -}; - - -/** - * @return {string} The packet type. - */ -devtools.DebuggerMessage.prototype.getType = function() -{ - return this.packet_.type; -}; - - -/** - * @return {?string} The packet event if the message is an event. - */ -devtools.DebuggerMessage.prototype.getEvent = function() -{ - return this.packet_.event; -}; - - -/** - * @return {?string} The packet command if the message is a response to a - * command. - */ -devtools.DebuggerMessage.prototype.getCommand = function() -{ - return this.packet_.command; -}; - - -/** - * @return {number} The packet request sequence. - */ -devtools.DebuggerMessage.prototype.getRequestSeq = function() -{ - return this.packet_.request_seq; -}; - - -/** - * @return {number} Whether the v8 is running after processing the request. - */ -devtools.DebuggerMessage.prototype.isRunning = function() -{ - return this.packet_.running ? true : false; -}; - - -/** - * @return {boolean} Whether the request succeeded. - */ -devtools.DebuggerMessage.prototype.isSuccess = function() -{ - return this.packet_.success ? true : false; -}; - - -/** - * @return {string} - */ -devtools.DebuggerMessage.prototype.getMessage = function() -{ - return this.packet_.message; -}; - - -/** - * @return {Object} Parsed message body json. - */ -devtools.DebuggerMessage.prototype.getBody = function() -{ - return this.packet_.body; -}; - - -/** - * @param {number} handle Object handle. - * @return {?Object} Returns the object with the handle if it was sent in this - * message(some objects referenced by handles may be missing in the message). - */ -devtools.DebuggerMessage.prototype.lookup = function(handle) -{ - return this.refs_[handle]; -}; diff --git a/WebKit/chromium/src/js/DebuggerScript.js b/WebKit/chromium/src/js/DebuggerScript.js new file mode 100644 index 0000000..51787f6 --- /dev/null +++ b/WebKit/chromium/src/js/DebuggerScript.js @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +(function () { + +var DebuggerScript = {}; +DebuggerScript._breakpoints = {}; +DebuggerScript._breakpointsActivated = true; + +DebuggerScript.PauseOnExceptionsState = { + DontPauseOnExceptions : 0, + PauseOnAllExceptions : 1, + PauseOnUncaughtExceptions: 2 +}; + +DebuggerScript.ScriptWorldType = { + MainWorld : 0, + ExtensionsWorld : 1 +}; + +DebuggerScript._pauseOnExceptionsState = DebuggerScript.PauseOnExceptionsState.DontPauseOnExceptions; +Debug.clearBreakOnException(); +Debug.clearBreakOnUncaughtException(); + +DebuggerScript.getAfterCompileScript = function(eventData) +{ + return DebuggerScript._formatScript(eventData.script_.script_); +} + +DebuggerScript.getScripts = function(contextData) +{ + var result = []; + + if (!contextData) + return result; + var comma = contextData.indexOf(","); + if (comma === -1) + return result; + // Context data is a string in the following format: + // ("page"|"injected")","<page id> + var idSuffix = contextData.substring(comma); // including the comma + + var scripts = Debug.scripts(); + for (var i = 0; i < scripts.length; ++i) { + var script = scripts[i]; + if (script.context_data && script.context_data.lastIndexOf(idSuffix) != -1) + result.push(DebuggerScript._formatScript(script)); + } + return result; +} + +DebuggerScript._formatScript = function(script) +{ + var scriptWorldType = DebuggerScript.ScriptWorldType.MainWorld; + if (script.context_data && script.context_data.indexOf("injected") == 0) + scriptWorldType = DebuggerScript.ScriptWorldType.ExtensionsWorld; + return { + id: script.id, + name: script.nameOrSourceURL(), + source: script.source, + lineOffset: DebuggerScript._v8ToWebkitLineNumber(script.line_offset), + lineCount: script.lineCount(), + scriptWorldType: scriptWorldType + }; +} + +DebuggerScript.setBreakpoint = function(execState, args) +{ + args.lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber); + var breakId = Debug.setScriptBreakPointById(args.scriptId, args.lineNumber, 0 /* column */, args.condition); + if (!args.enabled || !DebuggerScript._breakpointsActivated) + Debug.disableScriptBreakPoint(breakId); + + var locations = Debug.findBreakPointActualLocations(breakId); + var actualLineNumber = locations.length ? locations[0].line : args.lineNumber; + + var key = args.scriptId + ":" + actualLineNumber; + if (key in DebuggerScript._breakpoints) { + // Remove old breakpoint. + Debug.findBreakPoint(DebuggerScript._breakpoints[key], true); + } + DebuggerScript._breakpoints[key] = breakId; + return DebuggerScript._v8ToWebkitLineNumber(actualLineNumber); +} + +DebuggerScript.removeBreakpoint = function(execState, args) +{ + args.lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber); + var key = args.scriptId + ":" + args.lineNumber; + var breakId = DebuggerScript._breakpoints[key]; + if (breakId) + Debug.findBreakPoint(breakId, true); + delete DebuggerScript._breakpoints[key]; +} + +DebuggerScript.pauseOnExceptionsState = function() +{ + return DebuggerScript._pauseOnExceptionsState; +} + +DebuggerScript.setPauseOnExceptionsState = function(newState) +{ + DebuggerScript._pauseOnExceptionsState = newState; + + if (DebuggerScript.PauseOnExceptionsState.PauseOnAllExceptions === newState) + Debug.setBreakOnException(); + else + Debug.clearBreakOnException(); + + if (DebuggerScript.PauseOnExceptionsState.PauseOnUncaughtExceptions === newState) + Debug.setBreakOnUncaughtException(); + else + Debug.clearBreakOnUncaughtException(); +} + +DebuggerScript.currentCallFrame = function(execState, args) +{ + var frameCount = execState.frameCount(); + if (frameCount === 0) + return undefined; + + var topFrame; + for (var i = frameCount - 1; i >= 0; i--) { + var frameMirror = execState.frame(i); + topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFrame); + } + return topFrame; +} + +DebuggerScript.stepIntoStatement = function(execState) +{ + execState.prepareStep(Debug.StepAction.StepIn, 1); +} + +DebuggerScript.stepOverStatement = function(execState) +{ + execState.prepareStep(Debug.StepAction.StepNext, 1); +} + +DebuggerScript.stepOutOfFunction = function(execState) +{ + execState.prepareStep(Debug.StepAction.StepOut, 1); +} + +DebuggerScript.editScriptSource = function(scriptId, newSource) +{ + var scripts = Debug.scripts(); + var scriptToEdit = null; + for (var i = 0; i < scripts.length; i++) { + if (scripts[i].id == scriptId) { + scriptToEdit = scripts[i]; + break; + } + } + if (!scriptToEdit) + throw("Script not found"); + + var changeLog = []; + Debug.LiveEdit.SetScriptSource(scriptToEdit, newSource, false, changeLog); + return scriptToEdit.source; +} + +DebuggerScript.clearBreakpoints = function(execState, args) +{ + for (var key in DebuggerScript._breakpoints) { + var breakId = DebuggerScript._breakpoints[key]; + Debug.findBreakPoint(breakId, true); + } + DebuggerScript._breakpoints = {}; +} + +DebuggerScript.setBreakpointsActivated = function(execState, args) +{ + for (var key in DebuggerScript._breakpoints) { + var breakId = DebuggerScript._breakpoints[key]; + if (args.enabled) + Debug.enableScriptBreakPoint(breakId); + else + Debug.disableScriptBreakPoint(breakId); + } + DebuggerScript._breakpointsActivated = args.enabled; +} + +DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame) +{ + // Get function name. + var func; + try { + func = frameMirror.func(); + } catch(e) { + } + var functionName; + if (func) + functionName = func.name() || func.inferredName(); + + // Get script ID. + var script = func.script(); + var sourceID = script && script.id(); + + // Get line number. + var line = DebuggerScript._v8ToWebkitLineNumber(frameMirror.sourceLine()); + + // Get this object. + var thisObject = frameMirror.details_.receiver(); + + // Get scope chain array in format: [<scope type>, <scope object>, <scope type>, <scope object>,...] + var scopeChain = []; + var scopeType = []; + for (var i = 0; i < frameMirror.scopeCount(); i++) { + var scopeMirror = frameMirror.scope(i); + var scopeObjectMirror = scopeMirror.scopeObject(); + var properties = scopeObjectMirror.properties(); + var scopeObject = {}; + for (var j = 0; j < properties.length; j++) + scopeObject[properties[j].name()] = properties[j].value_; + // Reset scope object prototype to null so that the proto properties + // don't appear in th local scope section. + scopeObject.__proto__ = null; + scopeType.push(scopeMirror.scopeType()); + scopeChain.push(scopeObject); + } + + function evaluate(expression) { + return frameMirror.evaluate(expression, false).value(); + } + + return { + "sourceID": sourceID, + "line": line, + "functionName": functionName, + "type": "function", + "thisObject": thisObject, + "scopeChain": scopeChain, + "scopeType": scopeType, + "evaluate": evaluate, + "caller": callerFrame + }; +} + +DebuggerScript._webkitToV8LineNumber = function(line) +{ + return line - 1; +}; + +DebuggerScript._v8ToWebkitLineNumber = function(line) +{ + return line + 1; +}; + +return DebuggerScript; + +})(); diff --git a/WebKit/chromium/src/js/DevTools.js b/WebKit/chromium/src/js/DevTools.js index dcb181b..640474b 100644 --- a/WebKit/chromium/src/js/DevTools.js +++ b/WebKit/chromium/src/js/DevTools.js @@ -61,23 +61,12 @@ devtools$$dispatch = function(remoteName, methodName, param1, param2, param3) devtools.ToolsAgent = function() { RemoteToolsAgent.didDispatchOn = WebInspector.Callback.processCallback; - RemoteToolsAgent.frameNavigate = this.frameNavigate_.bind(this); RemoteToolsAgent.dispatchOnClient = this.dispatchOnClient_.bind(this); - this.debuggerAgent_ = new devtools.DebuggerAgent(); this.profilerAgent_ = new devtools.ProfilerAgent(); }; /** - * Resets tools agent to its initial state. - */ -devtools.ToolsAgent.prototype.reset = function() -{ - this.debuggerAgent_.reset(); -}; - - -/** * @param {string} script Script exression to be evaluated in the context of the * inspected page. * @param {function(Object|string, boolean):undefined} opt_callback Function to @@ -90,15 +79,6 @@ devtools.ToolsAgent.prototype.evaluateJavaScript = function(script, opt_callback /** - * @return {devtools.DebuggerAgent} Debugger agent instance. - */ -devtools.ToolsAgent.prototype.getDebuggerAgent = function() -{ - return this.debuggerAgent_; -}; - - -/** * @return {devtools.ProfilerAgent} Profiler agent instance. */ devtools.ToolsAgent.prototype.getProfilerAgent = function() @@ -108,32 +88,12 @@ devtools.ToolsAgent.prototype.getProfilerAgent = function() /** - * @param {string} url Url frame navigated to. - * @see tools_agent.h - * @private - */ -devtools.ToolsAgent.prototype.frameNavigate_ = function(url) -{ - this.reset(); - // Do not reset Profiles panel. - var profiles = null; - if ("profiles" in WebInspector.panels) { - profiles = WebInspector.panels["profiles"]; - delete WebInspector.panels["profiles"]; - } - WebInspector.reset(); - if (profiles !== null) - WebInspector.panels["profiles"] = profiles; -}; - - -/** * @param {string} message Serialized call to be dispatched on WebInspector. * @private */ devtools.ToolsAgent.prototype.dispatchOnClient_ = function(message) { - var args = JSON.parse(message); + var args = typeof message === "string" ? JSON.parse(message) : message; var methodName = args[0]; var parameters = args.slice(1); WebInspector[methodName].apply(WebInspector, parameters); @@ -151,31 +111,12 @@ devtools.ToolsAgent.prototype.evaluate = function(expr) /** - * Enables / disables resources panel in the ui. - * @param {boolean} enabled New panel status. - */ -WebInspector.setResourcesPanelEnabled = function(enabled) -{ - InspectorBackend._resourceTrackingEnabled = enabled; - WebInspector.panels.resources.reset(); -}; - - -/** * Prints string to the inspector console or shows alert if the console doesn't * exist. * @param {string} text */ function debugPrint(text) { - var console = WebInspector.console; - if (console) { - console.addMessage(new WebInspector.ConsoleMessage( - WebInspector.ConsoleMessage.MessageSource.JS, - WebInspector.ConsoleMessage.MessageType.Log, - WebInspector.ConsoleMessage.MessageLevel.Log, - 1, "chrome://devtools/<internal>", undefined, -1, text)); - } else - alert(text); + WebInspector.log(text); } @@ -188,6 +129,28 @@ devtools.tools = null; var context = {}; // Used by WebCore's inspector routines. +(function() { + WebInspector._paramsObject = {}; + + var queryParams = window.location.search; + if (queryParams) { + var params = queryParams.substring(1).split("&"); + for (var i = 0; i < params.length; ++i) { + var pair = params[i].split("="); + WebInspector._paramsObject[pair[0]] = pair[1]; + } + } + if ("page" in WebInspector._paramsObject) { + WebInspector.socket = new WebSocket("ws://" + window.location.host + "/devtools/page/" + WebInspector._paramsObject.page); + WebInspector.socket.onmessage = function(message) { eval(message.data); } + WebInspector.socket.onerror = function(error) { console.err(error); } + WebInspector.socket.onopen = function() { + WebInspector.socketOpened = true; + if (WebInspector.loadedDone) + WebInspector.doLoadedDone(); + }; + } +})(); /////////////////////////////////////////////////////////////////////////////// // Here and below are overrides to existing WebInspector methods only. // TODO(pfeldman): Patch WebCore and upstream changes. @@ -195,118 +158,36 @@ var oldLoaded = WebInspector.loaded; WebInspector.loaded = function() { devtools.tools = new devtools.ToolsAgent(); - devtools.tools.reset(); Preferences.ignoreWhitespace = false; Preferences.samplingCPUProfiler = true; Preferences.heapProfilerPresent = true; - oldLoaded.call(this); - - InspectorFrontendHost.loaded(); -}; - - -(function() -{ - - /** - * Handles an F3 keydown event to focus the Inspector search box. - * @param {KeyboardEvent} event Event to optionally handle - * @return {boolean} whether the event has been handled - */ - function handleF3Keydown(event) { - if (event.keyIdentifier === "F3" && !event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) { - var searchField = document.getElementById("search"); - searchField.focus(); - searchField.select(); - event.preventDefault(); - return true; - } - return false; - } - - - var oldKeyDown = WebInspector.documentKeyDown; - /** - * This override allows to intercept keydown events we want to handle in a - * custom way. Some nested documents (iframes) delegate keydown handling to - * WebInspector.documentKeyDown (e.g. SourceFrame). - * @param {KeyboardEvent} event - * @override - */ - WebInspector.documentKeyDown = function(event) { - var isHandled = handleF3Keydown(event); - if (!isHandled) { - // Mute refresh action. - if (event.keyIdentifier === "F5") - event.preventDefault(); - else if (event.keyIdentifier === "U+0052" /* "R" */ && (event.ctrlKey || event.metaKey)) - event.preventDefault(); - else - oldKeyDown.call(this, event); - } - }; -})(); - - -/** - * This override is necessary for adding script source asynchronously. - * @override - */ -WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded = function() -{ - if (!this._frameNeedsSetup) + Preferences.debuggerAlwaysEnabled = true; + Preferences.profilerAlwaysEnabled = true; + Preferences.canEditScriptSource = true; + Preferences.appCacheEnabled = false; + + if ("page" in WebInspector._paramsObject) { + WebInspector.loadedDone = true; + if (WebInspector.socketOpened) + WebInspector.doLoadedDone(); return; - - this.attach(); - - if (this.script.source) - this.didResolveScriptSource_(); - else { - var self = this; - devtools.tools.getDebuggerAgent().resolveScriptSource( - this.script.sourceID, - function(source) { - self.script.source = source || WebInspector.UIString("<source is not available>"); - self.didResolveScriptSource_(); - }); } -}; - - -/** - * Performs source frame setup when script source is aready resolved. - */ -WebInspector.ScriptView.prototype.didResolveScriptSource_ = function() -{ - this.sourceFrame.setContent("text/javascript", this.script.source); - this._sourceFrameSetup = true; - delete this._frameNeedsSetup; -}; + WebInspector.doLoadedDone(); +} +WebInspector.doLoadedDone = function() { + oldLoaded.call(this); + InspectorFrontendHost.loaded(); +} -/** - * @param {string} type Type of the the property value("object" or "function"). - * @param {string} className Class name of the property value. - * @constructor - */ -WebInspector.UnresolvedPropertyValue = function(type, className) +devtools.domContentLoaded = function() { - this.type = type; - this.className = className; -}; - - -(function() -{ - var oldShow = WebInspector.ScriptsPanel.prototype.show; - WebInspector.ScriptsPanel.prototype.show = function() - { - devtools.tools.getDebuggerAgent().initUI(); - this.enableToggleButton.visible = false; - oldShow.call(this); - }; -})(); + WebInspector.setAttachedWindow(WebInspector._paramsObject.docked === "true"); + if (WebInspector._paramsObject.toolbar_color && WebInspector._paramsObject.text_color) + WebInspector.setToolbarColors(WebInspector._paramsObject.toolbar_color, WebInspector._paramsObject.text_color); +} +document.addEventListener("DOMContentLoaded", devtools.domContentLoaded, false); (function InterceptProfilesPanelEvents() @@ -334,36 +215,6 @@ WebInspector.UIString = function(string) }; -// There is no clear way of setting frame title yet. So sniffing main resource -// load. -(function OverrideUpdateResource() { - var originalUpdateResource = WebInspector.updateResource; - WebInspector.updateResource = function(identifier, payload) - { - originalUpdateResource.call(this, identifier, payload); - var resource = this.resources[identifier]; - if (resource && resource.mainResource && resource.finished) - document.title = WebInspector.UIString("Developer Tools - %s", resource.url); - }; -})(); - - -// Highlight extension content scripts in the scripts list. -(function () { - var original = WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu; - WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu = function(script) - { - var result = original.apply(this, arguments); - var debuggerAgent = devtools.tools.getDebuggerAgent(); - var type = debuggerAgent.getScriptContextType(script.sourceID); - var option = script.filesSelectOption; - if (type === "injected" && option) - option.addStyleClass("injected"); - return result; - }; -})(); - - /** Pending WebKit upstream by apavlov). Fixes iframe vs drag problem. */ (function() { @@ -392,84 +243,10 @@ WebInspector.UIString = function(string) })(); -(function () { -var orig = InjectedScriptAccess.prototype.getProperties; -InjectedScriptAccess.prototype.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate, callback) -{ - if (objectProxy.isScope) - devtools.tools.getDebuggerAgent().resolveScope(objectProxy.objectId, callback); - else if (objectProxy.isV8Ref) - devtools.tools.getDebuggerAgent().resolveChildren(objectProxy.objectId, callback, false); - else - orig.apply(this, arguments); -}; -})(); - - -(function() -{ -InjectedScriptAccess.prototype.evaluateInCallFrame = function(callFrameId, code, objectGroup, callback) -{ - //TODO(pfeldman): remove once 49084 is rolled. - if (!callback) - callback = objectGroup; - devtools.tools.getDebuggerAgent().evaluateInCallFrame(callFrameId, code, callback); -}; -})(); - - -WebInspector.resourceTrackingWasEnabled = function() -{ - InspectorBackend._resourceTrackingEnabled = true; - this.panels.resources.resourceTrackingWasEnabled(); -}; - -WebInspector.resourceTrackingWasDisabled = function() -{ - InspectorBackend._resourceTrackingEnabled = false; - this.panels.resources.resourceTrackingWasDisabled(); -}; - -(function() -{ -var orig = WebInspector.ConsoleMessage.prototype.setMessageBody; -WebInspector.ConsoleMessage.prototype.setMessageBody = function(args) -{ - for (var i = 0; i < args.length; ++i) { - if (typeof args[i] === "string") - args[i] = WebInspector.ObjectProxy.wrapPrimitiveValue(args[i]); - } - orig.call(this, args); -}; -})(); - - -(function() -{ -var orig = InjectedScriptAccess.prototype.getCompletions; -InjectedScriptAccess.prototype.getCompletions = function(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions) -{ - if (typeof callFrameId === "number") - devtools.tools.getDebuggerAgent().resolveCompletionsOnFrame(expressionString, callFrameId, reportCompletions); - else - return orig.apply(this, arguments); -}; -})(); - -(function() -{ -WebInspector.ElementsPanel.prototype._nodeSearchButtonClicked = function( event) -{ - InspectorBackend.toggleNodeSearch(); - this.nodeSearchButton.toggled = !this.nodeSearchButton.toggled; -}; -})(); - - -// We need to have a place for postponed tasks -// which should be executed when all the messages between agent and frontend -// are processed. +/////////////////////////////////////////// +// Chromium layout test harness support. // +/////////////////////////////////////////// WebInspector.runAfterPendingDispatchesQueue = []; @@ -486,19 +263,44 @@ WebInspector.queuesAreEmpty = function() copy[i].call(this); }; -(function() + +///////////////////////////// +// Chromium theme support. // +///////////////////////////// + +WebInspector.setToolbarColors = function(backgroundColor, color) { -var originalAddToFrame = InspectorFrontendHost.addResourceSourceToFrame; -InspectorFrontendHost.addResourceSourceToFrame = function(identifier, element) + if (!WebInspector._themeStyleElement) { + WebInspector._themeStyleElement = document.createElement("style"); + document.head.appendChild(WebInspector._themeStyleElement); + } + WebInspector._themeStyleElement.textContent = + "#toolbar {\ + background-image: none !important;\ + background-color: " + backgroundColor + " !important;\ + }\ + \ + .toolbar-label {\ + color: " + color + " !important;\ + text-shadow: none;\ + }"; +} + +WebInspector.resetToolbarColors = function() { - var resource = WebInspector.resources[identifier]; - if (!resource) - return; - originalAddToFrame.call(this, identifier, resource.mimeType, element); -}; -})(); + if (WebInspector._themeStyleElement) + WebInspector._themeStyleElement.textContent = ""; + +} + +// TODO(yurys): should be removed when eclipse debugger stops using it. +if (window.RemoteDebuggerAgent) { + RemoteDebuggerAgent.setContextId = function() {}; +} + -WebInspector.pausedScript = function(callFrames) +// Support for pause while renderer is busy (is dispatched on IO thread). +InspectorBackend.pause = function() { - this.panels.scripts.debuggerPaused(callFrames); + RemoteDebuggerCommandExecutor.DebuggerPauseScript(); }; diff --git a/WebKit/chromium/src/js/DevToolsHostStub.js b/WebKit/chromium/src/js/DevToolsHostStub.js index 8b2f46b..52b28bb 100644 --- a/WebKit/chromium/src/js/DevToolsHostStub.js +++ b/WebKit/chromium/src/js/DevToolsHostStub.js @@ -33,277 +33,10 @@ * DevTools frontend to function as a standalone web app. */ -if (!window["RemoteDebuggerAgent"]) { - -/** - * FIXME: change field naming style to use trailing underscore. - * @constructor - */ -RemoteDebuggerAgentStub = function() -{ -}; - - -RemoteDebuggerAgentStub.prototype.getContextId = function() -{ - RemoteDebuggerAgent.setContextId(3); -}; - - -RemoteDebuggerAgentStub.prototype.processDebugCommands = function() -{ -}; - - -/** - * @constructor - */ -RemoteProfilerAgentStub = function() -{ -}; - - -RemoteProfilerAgentStub.prototype.getActiveProfilerModules = function() -{ - ProfilerStubHelper.GetInstance().getActiveProfilerModules(); -}; - - -RemoteProfilerAgentStub.prototype.getLogLines = function(pos) -{ - ProfilerStubHelper.GetInstance().getLogLines(pos); -}; - - -/** - * @constructor - */ -RemoteToolsAgentStub = function() -{ -}; - - -RemoteToolsAgentStub.prototype.dispatchOnInjectedScript = function() -{ -}; - - -RemoteToolsAgentStub.prototype.dispatchOnInspectorController = function() -{ -}; - - -/** - * @constructor - */ -ProfilerStubHelper = function() -{ - this.activeProfilerModules_ = devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; - this.heapProfSample_ = 0; - this.log_ = ''; -}; - - -ProfilerStubHelper.GetInstance = function() -{ - if (!ProfilerStubHelper.instance_) - ProfilerStubHelper.instance_ = new ProfilerStubHelper(); - return ProfilerStubHelper.instance_; -}; - - -ProfilerStubHelper.prototype.StopProfiling = function(modules) -{ - this.activeProfilerModules_ &= ~modules; -}; - - -ProfilerStubHelper.prototype.StartProfiling = function(modules) -{ - var profModules = devtools.ProfilerAgent.ProfilerModules; - if (modules & profModules.PROFILER_MODULE_HEAP_SNAPSHOT) { - if (modules & profModules.PROFILER_MODULE_HEAP_STATS) { - this.log_ += - 'heap-sample-begin,"Heap","allocated",' + - (new Date()).getTime() + '\n' + - 'heap-sample-stats,"Heap","allocated",10000,1000\n'; - this.log_ += - 'heap-sample-item,STRING_TYPE,100,1000\n' + - 'heap-sample-item,CODE_TYPE,10,200\n' + - 'heap-sample-item,MAP_TYPE,20,350\n'; - this.log_ += ProfilerStubHelper.HeapSamples[this.heapProfSample_++]; - this.heapProfSample_ %= ProfilerStubHelper.HeapSamples.length; - this.log_ += 'heap-sample-end,"Heap","allocated"\n'; - } - } else { - if (modules & profModules.PROFILER_MODULE_CPU) - this.log_ += ProfilerStubHelper.ProfilerLogBuffer; - this.activeProfilerModules_ |= modules; - } -}; - - -ProfilerStubHelper.prototype.getActiveProfilerModules = function() -{ - var self = this; - setTimeout(function() { - RemoteProfilerAgent.didGetActiveProfilerModules(self.activeProfilerModules_); - }, 100); -}; - - -ProfilerStubHelper.prototype.getLogLines = function(pos) -{ - var profModules = devtools.ProfilerAgent.ProfilerModules; - var logLines = this.log_.substr(pos); - setTimeout(function() { - RemoteProfilerAgent.didGetLogLines(pos + logLines.length, logLines); - }, 100); -}; - - -ProfilerStubHelper.ProfilerLogBuffer = - 'profiler,begin,1\n' + - 'profiler,resume\n' + - 'code-creation,LazyCompile,0x1000,256,"test1 http://aaa.js:1"\n' + - 'code-creation,LazyCompile,0x2000,256,"test2 http://bbb.js:2"\n' + - 'code-creation,LazyCompile,0x3000,256,"test3 http://ccc.js:3"\n' + - 'tick,0x1010,0x0,3\n' + - 'tick,0x2020,0x0,3,0x1010\n' + - 'tick,0x2020,0x0,3,0x1010\n' + - 'tick,0x3010,0x0,3,0x2020, 0x1010\n' + - 'tick,0x2020,0x0,3,0x1010\n' + - 'tick,0x2030,0x0,3,0x2020, 0x1010\n' + - 'tick,0x2020,0x0,3,0x1010\n' + - 'tick,0x1010,0x0,3\n' + - 'profiler,pause\n'; - - -ProfilerStubHelper.HeapSamples = [ - 'heap-js-cons-item,foo,1,100\n' + - 'heap-js-cons-item,bar,20,2000\n' + - 'heap-js-cons-item,Object,5,100\n' + - 'heap-js-ret-item,foo,bar;3\n' + - 'heap-js-ret-item,bar,foo;5\n' + - 'heap-js-ret-item,Object:0x1234,(roots);1\n', - - 'heap-js-cons-item,foo,2000,200000\n' + - 'heap-js-cons-item,bar,10,1000\n' + - 'heap-js-cons-item,Object,6,120\n' + - 'heap-js-ret-item,foo,bar;7,Object:0x1234;10\n' + - 'heap-js-ret-item,bar,foo;10,Object:0x1234;10\n' + - 'heap-js-ret-item,Object:0x1234,(roots);1\n', - - 'heap-js-cons-item,foo,15,1500\n' + - 'heap-js-cons-item,bar,15,1500\n' + - 'heap-js-cons-item,Object,5,100\n' + - 'heap-js-cons-item,Array,3,1000\n' + - 'heap-js-ret-item,foo,bar;3,Array:0x5678;1\n' + - 'heap-js-ret-item,bar,foo;5,Object:0x1234;8,Object:0x5678;2\n' + - 'heap-js-ret-item,Object:0x1234,(roots);1,Object:0x5678;2\n' + - 'heap-js-ret-item,Object:0x5678,(global property);3,Object:0x1234;5\n' + - 'heap-js-ret-item,Array:0x5678,(global property);3,Array:0x5678;2\n', - - 'heap-js-cons-item,bar,20,2000\n' + - 'heap-js-cons-item,Object,6,120\n' + - 'heap-js-ret-item,bar,foo;5,Object:0x1234;1,Object:0x1235;3\n' + - 'heap-js-ret-item,Object:0x1234,(global property);3\n' + - 'heap-js-ret-item,Object:0x1235,(global property);5\n', - - 'heap-js-cons-item,foo,15,1500\n' + - 'heap-js-cons-item,bar,15,1500\n' + - 'heap-js-cons-item,Array,10,1000\n' + - 'heap-js-ret-item,foo,bar;1,Array:0x5678;1\n' + - 'heap-js-ret-item,bar,foo;5\n' + - 'heap-js-ret-item,Array:0x5678,(roots);3\n', - - 'heap-js-cons-item,bar,20,2000\n' + - 'heap-js-cons-item,baz,15,1500\n' + - 'heap-js-ret-item,bar,baz;3\n' + - 'heap-js-ret-item,baz,bar;3\n' -]; - - -/** - * @constructor - */ -RemoteDebuggerCommandExecutorStub = function() -{ -}; - - -RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand = function(cmd) -{ - if ('{"seq":2,"type":"request","command":"scripts","arguments":{"includeSource":false}}' === cmd) { - var response1 = - '{"seq":5,"request_seq":2,"type":"response","command":"scripts","' + - 'success":true,"body":[{"handle":61,"type":"script","name":"' + - 'http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' + - '"lineCount":1,"sourceStart":"function fib(n) {","sourceLength":300,' + - '"scriptType":2,"compilationType":0,"context":{"ref":60}}],"refs":[{' + - '"handle":60,"type":"context","data":"page,3"}],"running":false}'; - this.sendResponse_(response1); - } else if ('{"seq":3,"type":"request","command":"scripts","arguments":{"ids":[59],"includeSource":true}}' === cmd) { - this.sendResponse_( - '{"seq":8,"request_seq":3,"type":"response","command":"scripts",' + - '"success":true,"body":[{"handle":1,"type":"script","name":' + - '"http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' + - '"lineCount":1,"source":"function fib(n) {return n+1;}",' + - '"sourceLength":244,"scriptType":2,"compilationType":0,"context":{' + - '"ref":0}}],"refs":[{"handle":0,"type":"context","data":"page,3}],"' + - '"running":false}'); - } else if (cmd.indexOf('"command":"profile"') !== -1) { - var cmdObj = JSON.parse(cmd); - if (cmdObj.arguments.command === "resume") - ProfilerStubHelper.GetInstance().StartProfiling(parseInt(cmdObj.arguments.modules)); - else if (cmdObj.arguments.command === "pause") - ProfilerStubHelper.GetInstance().StopProfiling(parseInt(cmdObj.arguments.modules)); - else - debugPrint("Unexpected profile command: " + cmdObj.arguments.command); - } else - debugPrint("Unexpected command: " + cmd); -}; - - -RemoteDebuggerCommandExecutorStub.prototype.DebuggerPauseScript = function() -{ -}; - - -RemoteDebuggerCommandExecutorStub.prototype.sendResponse_ = function(response) -{ - setTimeout(function() { - RemoteDebuggerAgent.debuggerOutput(response); - }, 0); -}; - - -DevToolsHostStub = function() -{ - this.isStub = true; -}; -DevToolsHostStub.prototype.__proto__ = WebInspector.InspectorFrontendHostStub.prototype; - - -DevToolsHostStub.prototype.reset = function() -{ -}; - - -DevToolsHostStub.prototype.setting = function() -{ -}; - - -DevToolsHostStub.prototype.setSetting = function() -{ -}; - - -window["RemoteDebuggerAgent"] = new RemoteDebuggerAgentStub(); -window["RemoteDebuggerCommandExecutor"] = new RemoteDebuggerCommandExecutorStub(); -window["RemoteProfilerAgent"] = new RemoteProfilerAgentStub(); -window["RemoteToolsAgent"] = new RemoteToolsAgentStub(); -InspectorFrontendHost = new DevToolsHostStub(); - +if (!window["RemoteDebuggerCommandExecutor"]) { + window["RemoteDebuggerCommandExecutor"] = {}; + window["RemoteProfilerAgent"] = {}; + window["RemoteToolsAgent"] = { + dispatchOnInspectorController: function() {} + }; } diff --git a/WebKit/chromium/src/js/HeapProfilerPanel.js b/WebKit/chromium/src/js/HeapProfilerPanel.js index abbf580..bcb008f 100644 --- a/WebKit/chromium/src/js/HeapProfilerPanel.js +++ b/WebKit/chromium/src/js/HeapProfilerPanel.js @@ -205,7 +205,7 @@ WebInspector.HeapSnapshotView.prototype = { // Call searchCanceled since it will reset everything we need before doing a new search. this.searchCanceled(); - query = query.trimWhitespace(); + query = query.trim(); if (!query.length) return; @@ -932,12 +932,12 @@ WebInspector.HeapSnapshotProfileType.prototype = { buttonClicked: function() { - InspectorBackend.takeHeapSnapshot(); + devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT); }, get welcomeMessage() { - return WebInspector.UIString("Get a heap snapshot by pressing<br>the %s button on the status bar."); + return WebInspector.UIString("Get a heap snapshot by pressing the %s button on the status bar."); }, createSidebarTreeElementForProfile: function(profile) diff --git a/WebKit/chromium/src/js/Images/segmentChromium.png b/WebKit/chromium/src/js/Images/segmentChromium.png Binary files differindex 607559b..f4248e1 100755 --- a/WebKit/chromium/src/js/Images/segmentChromium.png +++ b/WebKit/chromium/src/js/Images/segmentChromium.png diff --git a/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png b/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png Binary files differindex 9d326ac..7a760c1 100755 --- a/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png +++ b/WebKit/chromium/src/js/Images/statusbarBackgroundChromium.png diff --git a/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png b/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png Binary files differindex 7c7db0a..e3bc944 100755 --- a/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png +++ b/WebKit/chromium/src/js/Images/statusbarBottomBackgroundChromium.png diff --git a/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png b/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png Binary files differindex 0c6635d..136d5a8 100755 --- a/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png +++ b/WebKit/chromium/src/js/Images/statusbarButtonsChromium.png diff --git a/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png b/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png Binary files differindex bf26684..5ff61d9 100755 --- a/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png +++ b/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium.png diff --git a/WebKit/chromium/src/js/InjectDispatch.js b/WebKit/chromium/src/js/InjectDispatch.js index e070c42..cda84e5 100644 --- a/WebKit/chromium/src/js/InjectDispatch.js +++ b/WebKit/chromium/src/js/InjectDispatch.js @@ -49,58 +49,19 @@ InspectorControllerDispatcher.dispatch = function(functionName, json_args) }; /** - * Special controller object for APU related messages. Outgoing messages - * are sent to this object if the ApuAgentDispatcher is enabled. - **/ -var ApuAgentDispatcher = { enabled : false }; - -/** - * Dispatches messages to APU. This filters and transforms - * outgoing messages that are used by APU. - * @param {string} method name of the dispatch method. - **/ -ApuAgentDispatcher.dispatchToApu = function(method, args) -{ - if (method !== "addRecordToTimeline" && method !== "updateResource" && method !== "addResource") - return; - // TODO(knorton): Transform args so they can be used - // by APU. - DevToolsAgentHost.dispatchToApu(JSON.stringify(args)); -}; - -/** * This is called by the InspectorFrontend for serialization. * We serialize the call and send it to the client over the IPC * using dispatchOut bound method. */ function dispatch(method, var_args) { - // Handle all messages with non-primitieve arguments here. var args = Array.prototype.slice.call(arguments); - - if (method === "inspectedWindowCleared" || method === "reset" || method === "setAttachedWindow") { - // Filter out messages we don't need here. - // We do it on the sender side since they may have non-serializable - // parameters. - return; - } - - // Sniff some inspector controller state changes in order to support - // cross-navigation instrumentation. Keep names in sync with - // webdevtoolsagent_impl. - if (method === "timelineProfilerWasStarted") - DevToolsAgentHost.runtimeFeatureStateChanged("timeline-profiler", true); - else if (method === "timelineProfilerWasStopped") - DevToolsAgentHost.runtimeFeatureStateChanged("timeline-profiler", false); - else if (method === "resourceTrackingWasEnabled") - DevToolsAgentHost.runtimeFeatureStateChanged("resource-tracking", true); - else if (method === "resourceTrackingWasDisabled") - DevToolsAgentHost.runtimeFeatureStateChanged("resource-tracking", false); - - if (ApuAgentDispatcher.enabled) { - ApuAgentDispatcher.dispatchToApu(method, args); - return; - } - var call = JSON.stringify(args); - DevToolsAgentHost.dispatch(call); + DevToolsAgentHost.dispatch(call, method); }; + +function close() { + // This method is called when InspectorFrontend closes in layout tests. +} + +function inspectedPageDestroyed() { +} diff --git a/WebKit/chromium/src/js/InspectorControllerImpl.js b/WebKit/chromium/src/js/InspectorControllerImpl.js deleted file mode 100644 index c92a94c..0000000 --- a/WebKit/chromium/src/js/InspectorControllerImpl.js +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 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. - */ - -/** - * @fileoverview DevTools' implementation of the InspectorController API. - */ - -if (!this.devtools) - devtools = {}; - -devtools.InspectorBackendImpl = function() -{ - WebInspector.InspectorBackendStub.call(this); - this.installInspectorControllerDelegate_("clearMessages"); - this.installInspectorControllerDelegate_("copyNode"); - this.installInspectorControllerDelegate_("deleteCookie"); - this.installInspectorControllerDelegate_("didEvaluateForTestInFrontend"); - this.installInspectorControllerDelegate_("disableResourceTracking"); - this.installInspectorControllerDelegate_("disableTimeline"); - this.installInspectorControllerDelegate_("enableResourceTracking"); - this.installInspectorControllerDelegate_("enableTimeline"); - this.installInspectorControllerDelegate_("getChildNodes"); - this.installInspectorControllerDelegate_("getCookies"); - this.installInspectorControllerDelegate_("getDatabaseTableNames"); - this.installInspectorControllerDelegate_("getDOMStorageEntries"); - this.installInspectorControllerDelegate_("getEventListenersForNode"); - this.installInspectorControllerDelegate_("getResourceContent"); - this.installInspectorControllerDelegate_("highlightDOMNode"); - this.installInspectorControllerDelegate_("hideDOMNodeHighlight"); - this.installInspectorControllerDelegate_("releaseWrapperObjectGroup"); - this.installInspectorControllerDelegate_("removeAttribute"); - this.installInspectorControllerDelegate_("removeDOMStorageItem"); - this.installInspectorControllerDelegate_("removeNode"); - this.installInspectorControllerDelegate_("saveFrontendSettings"); - this.installInspectorControllerDelegate_("setAttribute"); - this.installInspectorControllerDelegate_("setDOMStorageItem"); - this.installInspectorControllerDelegate_("setInjectedScriptSource"); - this.installInspectorControllerDelegate_("setTextNodeValue"); - this.installInspectorControllerDelegate_("startTimelineProfiler"); - this.installInspectorControllerDelegate_("stopTimelineProfiler"); - this.installInspectorControllerDelegate_("storeLastActivePanel"); -}; -devtools.InspectorBackendImpl.prototype.__proto__ = WebInspector.InspectorBackendStub.prototype; - - -/** - * {@inheritDoc}. - */ -devtools.InspectorBackendImpl.prototype.toggleNodeSearch = function() -{ - WebInspector.InspectorBackendStub.prototype.toggleNodeSearch.call(this); - this.callInspectorController_.call(this, "toggleNodeSearch"); - if (!this.searchingForNode()) { - // This is called from ElementsPanel treeOutline's focusNodeChanged(). - DevToolsHost.activateWindow(); - } -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.debuggerEnabled = function() -{ - return true; -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.profilerEnabled = function() -{ - return true; -}; - - -devtools.InspectorBackendImpl.prototype.addBreakpoint = function(sourceID, line, condition) -{ - devtools.tools.getDebuggerAgent().addBreakpoint(sourceID, line, condition); -}; - - -devtools.InspectorBackendImpl.prototype.removeBreakpoint = function(sourceID, line) -{ - devtools.tools.getDebuggerAgent().removeBreakpoint(sourceID, line); -}; - -devtools.InspectorBackendImpl.prototype.updateBreakpoint = function(sourceID, line, condition) -{ - devtools.tools.getDebuggerAgent().updateBreakpoint(sourceID, line, condition); -}; - -devtools.InspectorBackendImpl.prototype.pauseInDebugger = function() -{ - devtools.tools.getDebuggerAgent().pauseExecution(); -}; - - -devtools.InspectorBackendImpl.prototype.resumeDebugger = function() -{ - devtools.tools.getDebuggerAgent().resumeExecution(); -}; - - -devtools.InspectorBackendImpl.prototype.stepIntoStatementInDebugger = function() -{ - devtools.tools.getDebuggerAgent().stepIntoStatement(); -}; - - -devtools.InspectorBackendImpl.prototype.stepOutOfFunctionInDebugger = function() -{ - devtools.tools.getDebuggerAgent().stepOutOfFunction(); -}; - - -devtools.InspectorBackendImpl.prototype.stepOverStatementInDebugger = function() -{ - devtools.tools.getDebuggerAgent().stepOverStatement(); -}; - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.setPauseOnExceptionsState = function(state) -{ - this._setPauseOnExceptionsState = state; - // TODO(yurys): support all three states. See http://crbug.com/32877 - var enabled = (state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); - return devtools.tools.getDebuggerAgent().setPauseOnExceptions(enabled); -}; - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.pauseOnExceptionsState = function() -{ - return (this._setPauseOnExceptionsState || WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); -}; - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.pauseOnExceptions = function() -{ - return devtools.tools.getDebuggerAgent().pauseOnExceptions(); -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.setPauseOnExceptions = function(value) -{ - return devtools.tools.getDebuggerAgent().setPauseOnExceptions(value); -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.startProfiling = function() -{ - devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU); -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.stopProfiling = function() -{ - devtools.tools.getProfilerAgent().stopProfiling( devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU); -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.getProfileHeaders = function(callId) -{ - WebInspector.didGetProfileHeaders(callId, []); -}; - - -/** - * Emulate WebKit InspectorController behavior. It stores profiles on renderer side, - * and is able to retrieve them by uid using "getProfile". - */ -devtools.InspectorBackendImpl.prototype.addFullProfile = function(profile) -{ - WebInspector.__fullProfiles = WebInspector.__fullProfiles || {}; - WebInspector.__fullProfiles[profile.uid] = profile; -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.getProfile = function(callId, uid) -{ - if (WebInspector.__fullProfiles && (uid in WebInspector.__fullProfiles)) - WebInspector.didGetProfile(callId, WebInspector.__fullProfiles[uid]); -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.takeHeapSnapshot = function() -{ - devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT - | devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_STATS - | devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_JS_CONSTRUCTORS); -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.dispatchOnInjectedScript = function(callId, injectedScriptId, methodName, argsString, async) -{ - // Encode injectedScriptId into callId - if (typeof injectedScriptId !== "number") - injectedScriptId = 0; - RemoteToolsAgent.dispatchOnInjectedScript(callId, injectedScriptId, methodName, argsString, async); -}; - - -/** - * Installs delegating handler into the inspector controller. - * @param {string} methodName Method to install delegating handler for. - */ -devtools.InspectorBackendImpl.prototype.installInspectorControllerDelegate_ = function(methodName) -{ - this[methodName] = this.callInspectorController_.bind(this, methodName); -}; - - -/** - * Bound function with the installInjectedScriptDelegate_ actual - * implementation. - */ -devtools.InspectorBackendImpl.prototype.callInspectorController_ = function(methodName, var_arg) -{ - var args = Array.prototype.slice.call(arguments, 1); - RemoteToolsAgent.dispatchOnInspectorController(WebInspector.Callback.wrap(function(){}), methodName, JSON.stringify(args)); -}; - - -InspectorBackend = new devtools.InspectorBackendImpl(); diff --git a/WebKit/chromium/src/js/ProfilerAgent.js b/WebKit/chromium/src/js/ProfilerAgent.js index e08c5d2..0b65ace 100644 --- a/WebKit/chromium/src/js/ProfilerAgent.js +++ b/WebKit/chromium/src/js/ProfilerAgent.js @@ -41,18 +41,6 @@ devtools.ProfilerAgent = function() RemoteProfilerAgent.didGetLogLines = this._didGetLogLines.bind(this); /** - * Active profiler modules flags. - * @type {number} - */ - this._activeProfilerModules = devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; - - /** - * Interval for polling profiler state. - * @type {number} - */ - this._getActiveProfilerModulesInterval = null; - - /** * Profiler log position. * @type {number} */ @@ -65,12 +53,6 @@ devtools.ProfilerAgent = function() this._lastRequestedLogPosition = -1; /** - * Whether log contents retrieval must be forced next time. - * @type {boolean} - */ - this._forceGetLogLines = false; - - /** * Profiler processor instance. * @type {devtools.profiler.Processor} */ @@ -92,50 +74,11 @@ devtools.ProfilerAgent.ProfilerModules = { /** - * Sets up callbacks that deal with profiles processing. - */ -devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks = function() -{ - // A temporary icon indicating that the profile is being processed. - var processingIcon = new WebInspector.SidebarTreeElement( - "profile-sidebar-tree-item", - WebInspector.UIString("Processing..."), - '', null, false); - var profilesSidebar = WebInspector.panels.profiles.getProfileType(WebInspector.CPUProfileType.TypeId).treeElement; - - this._profilerProcessor.setCallbacks( - function onProfileProcessingStarted() { - // Set visually empty string. Subtitle hiding is done via styles - // manipulation which doesn't play well with dynamic append / removal. - processingIcon.subtitle = " "; - profilesSidebar.appendChild(processingIcon); - }, - function onProfileProcessingStatus(ticksCount) { - processingIcon.subtitle = WebInspector.UIString("%d ticks processed", ticksCount); - }, - function onProfileProcessingFinished(profile) { - profilesSidebar.removeChild(processingIcon); - profile.typeId = WebInspector.CPUProfileType.TypeId; - InspectorBackend.addFullProfile(profile); - WebInspector.addProfileHeader(profile); - // If no profile is currently shown, show the new one. - var profilesPanel = WebInspector.panels.profiles; - if (!profilesPanel.visibleView) { - profilesPanel.showProfile(profile); - } - } - ); -}; - - -/** * Initializes profiling state. */ devtools.ProfilerAgent.prototype.initializeProfiling = function() { - this.setupProfilerProcessorCallbacks(); - this._forceGetLogLines = true; - this._getActiveProfilerModulesInterval = setInterval(function() { RemoteProfilerAgent.getActiveProfilerModules(); }, 1000); + this._getNextLogLines(false); }; @@ -162,12 +105,8 @@ devtools.ProfilerAgent.prototype._getNextLogLines = function(immediately) */ devtools.ProfilerAgent.prototype.startProfiling = function(modules) { - var cmd = new devtools.DebugCommand("profile", { - "modules": modules, - "command": "resume"}); - devtools.DebuggerAgent.sendCommand_(cmd); - RemoteDebuggerAgent.processDebugCommands(); if (modules & devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) { + InspectorBackend.takeHeapSnapshot(); // Active modules will not change, instead, a snapshot will be logged. this._getNextLogLines(); } @@ -175,34 +114,11 @@ devtools.ProfilerAgent.prototype.startProfiling = function(modules) /** - * Stops profiling. - */ -devtools.ProfilerAgent.prototype.stopProfiling = function(modules) -{ - var cmd = new devtools.DebugCommand("profile", { - "modules": modules, - "command": "pause"}); - devtools.DebuggerAgent.sendCommand_(cmd); - RemoteDebuggerAgent.processDebugCommands(); -}; - - -/** * Handles current profiler status. * @param {number} modules List of active (started) modules. */ devtools.ProfilerAgent.prototype._didGetActiveProfilerModules = function(modules) { - var profModules = devtools.ProfilerAgent.ProfilerModules; - var profModuleNone = profModules.PROFILER_MODULE_NONE; - if (this._forceGetLogLines || (modules !== profModuleNone && this._activeProfilerModules === profModuleNone)) { - this._forceGetLogLines = false; - // Start to query log data. - this._getNextLogLines(true); - } - this._activeProfilerModules = modules; - // Update buttons. - WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU); }; @@ -214,14 +130,11 @@ devtools.ProfilerAgent.prototype._didGetActiveProfilerModules = function(modules devtools.ProfilerAgent.prototype._didGetLogLines = function(pos, log) { this._logPosition = pos; - if (log.length > 0) + if (log.length > 0) { this._profilerProcessor.processLogChunk(log); - else { + this._getNextLogLines(); + } else { // Allow re-reading from the last position. this._lastRequestedLogPosition = this._logPosition - 1; - if (this._activeProfilerModules === devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE) - // No new data and profiling is stopped---suspend log reading. - return; } - this._getNextLogLines(); }; diff --git a/WebKit/chromium/src/js/Tests.js b/WebKit/chromium/src/js/Tests.js index fa0c99f..e2ab3b3 100644 --- a/WebKit/chromium/src/js/Tests.js +++ b/WebKit/chromium/src/js/Tests.js @@ -295,19 +295,19 @@ TestSuite.prototype.testResourceContentLength = function() var resource = WebInspector.resources[identifier]; if (!resource || !resource.url) return; - if (resource.url.search("image.html$") !== -1) { + if (resource.url.search("image.html") !== -1) { var expectedLength = 87; test.assertTrue( - resource.contentLength <= expectedLength, + resource.resourceSize <= expectedLength, "image.html content length is greater thatn expected."); - if (expectedLength === resource.contentLength) + if (expectedLength === resource.resourceSize) html = true; } else if (resource.url.search("image.png") !== -1) { var expectedLength = 257796; test.assertTrue( - resource.contentLength <= expectedLength, + resource.resourceSize <= expectedLength, "image.png content length is greater than expected."); - if (expectedLength === resource.contentLength) + if (expectedLength === resource.resourceSize) png = true; } if (html && png) { @@ -425,39 +425,83 @@ TestSuite.prototype.testProfilerTab = function() { this.showPanel("profiles"); + var panel = WebInspector.panels.profiles; var test = this; - this.addSniffer(WebInspector.panels.profiles, "addProfileHeader", - function(typeOrProfile, profile) { - if (!profile) - profile = typeOrProfile; - var panel = WebInspector.panels.profiles; - panel.showProfile(profile); - var node = panel.visibleView.profileDataGridTree.children[0]; - // Iterate over displayed functions and search for a function - // that is called "fib" or "eternal_fib". If found, it will mean - // that we actually have profiled page's code. - while (node) { - if (node.functionName.indexOf("fib") !== -1) - test.releaseControl(); - node = node.traverseNextNode(true, null, true); - } - test.fail(); - }); - var ticksCount = 0; - var tickRecord = "\nt,"; - this.addSniffer(RemoteProfilerAgent, "didGetLogLines", - function(posIgnored, log) { - var pos = 0; - while ((pos = log.indexOf(tickRecord, pos)) !== -1) { - pos += tickRecord.length; - ticksCount++; + function findDisplayedNode() { + var node = panel.visibleView.profileDataGridTree.children[0]; + if (!node) { + // Profile hadn't been queried yet, re-schedule. + window.setTimeout(findDisplayedNode, 100); + return; + } + + // Iterate over displayed functions and search for a function + // that is called "fib" or "eternal_fib". If found, this will mean + // that we actually have profiled page's code. + while (node) { + if (node.functionName.indexOf("fib") !== -1) + test.releaseControl(); + node = node.traverseNextNode(true, null, true); + } + + test.fail(); + } + + function findVisibleView() { + if (!panel.visibleView) { + setTimeout(findVisibleView, 0); + return; + } + setTimeout(findDisplayedNode, 0); + } + + findVisibleView(); + this.takeControl(); +}; + + +/** + * Tests that heap profiler works. + */ +TestSuite.prototype.testHeapProfiler = function() +{ + this.showPanel("profiles"); + + var panel = WebInspector.panels.profiles; + var test = this; + + function findDisplayedNode() { + var node = panel.visibleView.dataGrid.children[0]; + if (!node) { + // Profile hadn't been queried yet, re-schedule. + window.setTimeout(findDisplayedNode, 100); + return; + } + + // Iterate over displayed functions and find node called "A" + // If found, this will mean that we actually have taken heap snapshot. + while (node) { + if (node.constructorName.indexOf("A") !== -1) { + test.releaseControl(); + return; } - if (ticksCount > 100) - InspectorBackend.stopProfiling(); - }, true); + node = node.traverseNextNode(false, null, true); + } + + test.fail(); + } + + function findVisibleView() { + if (!panel.visibleView) { + setTimeout(findVisibleView, 0); + return; + } + setTimeout(findDisplayedNode, 0); + } - InspectorBackend.startProfiling(); + WebInspector.HeapSnapshotProfileType.prototype.buttonClicked(); + findVisibleView(); this.takeControl(); }; @@ -470,7 +514,7 @@ TestSuite.prototype.testShowScriptsTab = function() this.showPanel("scripts"); var test = this; // There should be at least main page script. - this._waitUntilScriptsAreParsed(["debugger_test_page.html$"], + this._waitUntilScriptsAreParsed(["debugger_test_page.html"], function() { test.releaseControl(); }); @@ -489,31 +533,19 @@ TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function() var test = this; this.assertEquals(WebInspector.panels.elements, WebInspector.currentPanel, "Elements panel should be current one."); - this.addSniffer(devtools.DebuggerAgent.prototype, "reset", waitUntilScriptIsParsed); + this.addSniffer(WebInspector.panels.scripts, "reset", waitUntilScriptIsParsed); // Reload inspected page. It will reset the debugger agent. test.evaluateInConsole_( "window.location.reload(true);", - function(resultText) { - test.assertEquals("undefined", resultText, "Unexpected result of reload()."); - }); + function(resultText) {}); function waitUntilScriptIsParsed() { - var parsed = devtools.tools.getDebuggerAgent().parsedScripts_; - for (var id in parsed) { - var url = parsed[id].getUrl(); - if (url && url.search("debugger_test_page.html$") !== -1) { - checkScriptsPanel(); - return; - } - } - test.addSniffer(devtools.DebuggerAgent.prototype, "addScriptInfo_", waitUntilScriptIsParsed); - } - - function checkScriptsPanel() { test.showPanel("scripts"); - test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html$"]), "Inspected script not found in the scripts list"); - test.releaseControl(); + test._waitUntilScriptsAreParsed(["debugger_test_page.html"], + function() { + test.releaseControl(); + }); } // Wait until all scripts are added to the debugger. @@ -530,7 +562,7 @@ TestSuite.prototype.testContentScriptIsPresent = function() var test = this; test._waitUntilScriptsAreParsed( - ["page_with_content_script.html$", "simple_content_script.js$"], + ["page_with_content_script.html", "simple_content_script.js"], function() { test.releaseControl(); }); @@ -568,7 +600,7 @@ TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() function checkScriptsPanel() { test.assertTrue(!!WebInspector.panels.scripts.visibleView, "No visible script view."); - test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html$"]), "Some scripts are missing."); + test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html"]), "Some scripts are missing."); checkNoDuplicates(); test.releaseControl(); } @@ -584,7 +616,7 @@ TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() } test._waitUntilScriptsAreParsed( - ["debugger_test_page.html$"], + ["debugger_test_page.html"], function() { checkNoDuplicates(); setTimeout(switchToElementsTab, 0); @@ -604,7 +636,7 @@ TestSuite.prototype.testSetBreakpoint = function() var test = this; this.showPanel("scripts"); - var breakpointLine = 12; + var breakpointLine = 16 this._waitUntilScriptsAreParsed(["debugger_test_page.html"], function() { @@ -612,15 +644,25 @@ TestSuite.prototype.testSetBreakpoint = function() "debugger_test_page.html", function(view, url) { view._addBreakpoint(breakpointLine); - // Force v8 execution. - RemoteDebuggerAgent.processDebugCommands(); - test.waitForSetBreakpointResponse_(url, breakpointLine, - function() { - test.releaseControl(); + + test.evaluateInConsole_( + 'setTimeout("calculate()" , 0)', + function(resultText) { + test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); }); }); }); + this._waitForScriptPause( + { + functionsOnStack: ["calculate", ""], + lineNumber: breakpointLine, + lineText: " result = fib(lastVal++);" + }, + function() { + test.releaseControl(); + }); + this.takeControl(); }; @@ -633,21 +675,13 @@ TestSuite.prototype.testPauseOnException = function() this.showPanel("scripts"); var test = this; - // TODO(yurys): remove else branch once the states are supported. - if (WebInspector.ScriptsPanel.PauseOnExceptionsState) { - while (WebInspector.currentPanel.pauseOnExceptionButton.state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions) - WebInspector.currentPanel.pauseOnExceptionButton.element.click(); - } else { - // Make sure pause on exceptions is on. - if (!WebInspector.currentPanel.pauseOnExceptionButton.toggled) - WebInspector.currentPanel.pauseOnExceptionButton.element.click(); - } + InspectorBackend.setPauseOnExceptionsState(WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions); - this._executeCodeWhenScriptsAreParsed("handleClick()", ["pause_on_exception.html$"]); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["pause_on_exception.html"]); this._waitForScriptPause( { - functionsOnStack: ["throwAnException", "handleClick", "(anonymous function)"], + functionsOnStack: ["throwAnException", "handleClick", ""], lineNumber: 6, lineText: " return unknown_var;" }, @@ -729,7 +763,7 @@ TestSuite.prototype.testPauseWhenScriptIsRunning = function() test._waitForScriptPause( { - functionsOnStack: ["handleClick", "(anonymous function)"], + functionsOnStack: ["handleClick", ""], lineNumber: 5, lineText: " while(true) {" }, @@ -818,7 +852,7 @@ TestSuite.prototype.showMainPageScriptSource_ = function(scriptName, callback) */ TestSuite.prototype.evaluateInConsole_ = function(code, callback) { - WebInspector.console.visible = true; + WebInspector.showConsole(); WebInspector.console.prompt.text = code; WebInspector.console.promptElement.dispatchEvent( TestSuite.createKeyEvent("Enter")); @@ -829,29 +863,6 @@ TestSuite.prototype.evaluateInConsole_ = function(code, callback) }; -/* - * Waits for "setbreakpoint" response, checks that corresponding breakpoint - * was successfully set and invokes the callback if it was. - * @param {string} scriptUrl - * @param {number} breakpointLine - * @param {function()} callback - */ -TestSuite.prototype.waitForSetBreakpointResponse_ = function(scriptUrl, breakpointLine, callback) -{ - var test = this; - test.addSniffer( - devtools.DebuggerAgent.prototype, - "handleSetBreakpointResponse_", - function(msg) { - var bps = this.urlToBreakpoints_[scriptUrl]; - test.assertTrue(!!bps, "No breakpoints for line " + breakpointLine); - var line = devtools.DebuggerAgent.webkitToV8LineNumber_(breakpointLine); - test.assertTrue(!!bps[line].getV8Id(), "Breakpoint id was not assigned."); - callback(); - }); -}; - - /** * Tests eval on call frame. */ @@ -862,36 +873,30 @@ TestSuite.prototype.testEvalOnCallFrame = function() var breakpointLine = 16; var test = this; - this.addSniffer(devtools.DebuggerAgent.prototype, "handleScriptsResponse_", - function(msg) { + this._waitUntilScriptsAreParsed(["debugger_test_page.html"], + function() { test.showMainPageScriptSource_( "debugger_test_page.html", function(view, url) { view._addBreakpoint(breakpointLine); - // Force v8 execution. - RemoteDebuggerAgent.processDebugCommands(); - test.waitForSetBreakpointResponse_(url, breakpointLine, setBreakpointCallback); + + // Since breakpoints are ignored in evals' calculate() function is + // execute after zero-timeout so that the breakpoint is hit. + test.evaluateInConsole_( + 'setTimeout("calculate(123)" , 0)', + function(resultText) { + test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); + waitForBreakpointHit(); + }); }); }); - function setBreakpointCallback() { - // Since breakpoints are ignored in evals' calculate() function is - // execute after zero-timeout so that the breakpoint is hit. - test.evaluateInConsole_( - 'setTimeout("calculate(123)" , 0)', - function(resultText) { - test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); - waitForBreakpointHit(); - }); - } - function waitForBreakpointHit() { - test.addSniffer( - devtools.DebuggerAgent.prototype, - "handleBacktraceResponse_", - function(msg) { - test.assertEquals(2, this.callFrames_.length, "Unexpected stack depth on the breakpoint. " + JSON.stringify(msg)); - test.assertEquals("calculate", this.callFrames_[0].functionName, "Unexpected top frame function."); + test.addSniffer(WebInspector, + "pausedScript", + function(callFrames) { + test.assertEquals(2, callFrames.length, "Unexpected stack depth on the breakpoint. " + JSON.stringify(callFrames, null, 4)); + test.assertEquals("calculate", callFrames[0].functionName, "Unexpected top frame function."); // Evaluate "e+1" where "e" is an argument of "calculate" function. test.evaluateInConsole_( "e+1", @@ -913,19 +918,23 @@ TestSuite.prototype.testCompletionOnPause = function() { this.showPanel("scripts"); var test = this; - this._executeCodeWhenScriptsAreParsed("handleClick()", ["completion_on_pause.html$"]); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["completion_on_pause.html"]); this._waitForScriptPause( { - functionsOnStack: ["innerFunction", "handleClick", "(anonymous function)"], + functionsOnStack: ["innerFunction", "handleClick", ""], lineNumber: 9, lineText: " debugger;" }, showConsole); function showConsole() { - test.addSniffer(WebInspector.console, "afterShow", testLocalsCompletion); - WebInspector.showConsole(); + if (WebInspector.currentFocusElement === WebInspector.console.promptElement) + testLocalsCompletion(); + else { + test.addSniffer(WebInspector.console, "afterShow", testLocalsCompletion); + WebInspector.showConsole(); + } } function testLocalsCompletion() { @@ -964,56 +973,7 @@ TestSuite.prototype.testCompletionOnPause = function() */ TestSuite.prototype.testAutoContinueOnSyntaxError = function() { - this.showPanel("scripts"); - var test = this; - - function checkScriptsList() { - var scriptSelect = document.getElementById("scripts-files"); - var options = scriptSelect.options; - // There should be only console API source (see - // InjectedScript._ensureCommandLineAPIInstalled) since the page script - // contains a syntax error. - for (var i = 0 ; i < options.length; i++) { - if (options[i].text.search("script_syntax_error.html$") !== -1) - test.fail("Script with syntax error should not be in the list of parsed scripts."); - } - } - - this.addSniffer(devtools.DebuggerAgent.prototype, "handleScriptsResponse_", - function(msg) { - checkScriptsList(); - - // Reload inspected page. - test.evaluateInConsole_( - "window.location.reload(true);", - function(resultText) { - test.assertEquals("undefined", resultText, "Unexpected result of reload()."); - waitForExceptionEvent(); - }); - }); - - function waitForExceptionEvent() { - var exceptionCount = 0; - test.addSniffer( - devtools.DebuggerAgent.prototype, - "handleExceptionEvent_", - function(msg) { - exceptionCount++; - test.assertEquals(1, exceptionCount, "Too many exceptions."); - test.assertEquals(undefined, msg.getBody().script, "Unexpected exception: " + JSON.stringify(msg)); - test.releaseControl(); - }); - - // Check that the script is not paused on parse error. - test.addSniffer( - WebInspector, - "pausedScript", - function(callFrames) { - test.fail("Script execution should not pause on syntax error."); - }); - } - - this.takeControl(); + // TODO(yurys): provide an implementation that works with ScriptDebugServer. }; @@ -1141,7 +1101,7 @@ TestSuite.prototype._executeCodeWhenScriptsAreParsed = function(code, expectedSc test.evaluateInConsole_( 'setTimeout("' + code + '" , 0)', function(resultText) { - test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); + test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText + ". Code: " + code); }); } @@ -1173,7 +1133,7 @@ TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callb */ TestSuite.prototype._executeFunctionForStepTest = function() { - this._executeCodeWhenScriptsAreParsed("a()", ["debugger_step.html$", "debugger_step.js$"]); + this._executeCodeWhenScriptsAreParsed("a()", ["debugger_step.html", "debugger_step.js"]); }; @@ -1189,7 +1149,7 @@ TestSuite.prototype.testStepOver = function() this._performSteps([ { - functionsOnStack: ["d","a","(anonymous function)"], + functionsOnStack: ["d","a",""], lineNumber: 3, lineText: " debugger;" }, @@ -1197,7 +1157,7 @@ TestSuite.prototype.testStepOver = function() document.getElementById("scripts-step-over").click(); }, { - functionsOnStack: ["d","a","(anonymous function)"], + functionsOnStack: ["d","a",""], lineNumber: 5, lineText: " var y = fact(10);" }, @@ -1205,7 +1165,7 @@ TestSuite.prototype.testStepOver = function() document.getElementById("scripts-step-over").click(); }, { - functionsOnStack: ["d","a","(anonymous function)"], + functionsOnStack: ["d","a",""], lineNumber: 6, lineText: " return y;" }, @@ -1230,7 +1190,7 @@ TestSuite.prototype.testStepOut = function() this._performSteps([ { - functionsOnStack: ["d","a","(anonymous function)"], + functionsOnStack: ["d","a",""], lineNumber: 3, lineText: " debugger;" }, @@ -1238,7 +1198,7 @@ TestSuite.prototype.testStepOut = function() document.getElementById("scripts-step-out").click(); }, { - functionsOnStack: ["a","(anonymous function)"], + functionsOnStack: ["a",""], lineNumber: 8, lineText: " printResult(result);" }, @@ -1263,7 +1223,7 @@ TestSuite.prototype.testStepIn = function() this._performSteps([ { - functionsOnStack: ["d","a","(anonymous function)"], + functionsOnStack: ["d","a",""], lineNumber: 3, lineText: " debugger;" }, @@ -1271,7 +1231,7 @@ TestSuite.prototype.testStepIn = function() document.getElementById("scripts-step-over").click(); }, { - functionsOnStack: ["d","a","(anonymous function)"], + functionsOnStack: ["d","a",""], lineNumber: 5, lineText: " var y = fact(10);" }, @@ -1279,9 +1239,9 @@ TestSuite.prototype.testStepIn = function() document.getElementById("scripts-step-into").click(); }, { - functionsOnStack: ["fact","d","a","(anonymous function)"], - lineNumber: 15, - lineText: " return r;" + functionsOnStack: ["fact","d","a",""], + lineNumber: 10, + lineText: " var r = 1;" }, function() { test.releaseControl(); @@ -1437,11 +1397,11 @@ TestSuite.prototype.testExpandScope = function() this.showPanel("scripts"); var test = this; - this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_closure.html$"]); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_closure.html"]); this._waitForScriptPause( { - functionsOnStack: ["innerFunction", "handleClick", "(anonymous function)"], + functionsOnStack: ["innerFunction", "handleClick", ""], lineNumber: 8, lineText: " debugger;" }, @@ -1464,14 +1424,14 @@ TestSuite.prototype.testExpandScope = function() properties: { x:"2009", innerFunctionLocalVar:"2011", - "this": "global", + "this": "DOMWindow", } }, { title: "Closure", properties: { - n:"TextParam", - makeClosureLocalVar:"local.TextParam", + n: '"TextParam"', + makeClosureLocalVar: '"local.TextParam"', } }, { @@ -1551,11 +1511,11 @@ TestSuite.prototype.testDebugIntrinsicProperties = function() this.showPanel("scripts"); var test = this; - this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_intrinsic_properties.html$"]); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_intrinsic_properties.html"]); this._waitForScriptPause( { - functionsOnStack: ["callDebugger", "handleClick", "(anonymous function)"], + functionsOnStack: ["callDebugger", "handleClick", ""], lineNumber: 29, lineText: " debugger;" }, @@ -1576,44 +1536,32 @@ TestSuite.prototype.testDebugIntrinsicProperties = function() function examineLocalScope() { var scopeExpectations = [ - "a", "Object", [ - "constructor", "function Child()", [ - "constructor", "function Function()", null, - "name", "Child", null, - "prototype", "Object", [ - "childProtoField", 21, null - ] - ], - - "__proto__", "Object", [ - "__proto__", "Object", [ - "__proto__", "Object", [ - "__proto__", "null", null, - "constructor", "function Object()", null, - ], - "constructor", "function Parent()", [ - "name", "Parent", null, - "prototype", "Object", [ - "parentProtoField", 11, null, + "a", "Child", [ + "__proto__", "Child", [ + "__proto__", "Parent", [ + "__proto__", "Object", null, + "constructor", "function Parent(n) {", [ + "name", '"Parent"', null, + "prototype", 'Parent', [ + "parentProtoField", "11", null, ] ], - "parentProtoField", 11, null, + "parentProtoField", "11", null, ], - "constructor", "function Child()", null, - "childProtoField", 21, null, + "constructor", "function Child(n) {", null, + "childProtoField", "21", null, ], - "parentField", 10, null, - "childField", 20, null, + "parentField", "10", null, + "childField", "20", null, ] ]; - checkProperty(localScopeSection.propertiesTreeOutline, "<Local Scope>", scopeExpectations); } var propQueue = []; var index = 0; - var expectedFinalIndex = 8; + var expectedFinalIndex = 5; function expandAndCheckNextProperty() { if (index === propQueue.length) { @@ -1719,7 +1667,7 @@ TestSuite.prototype.testConsoleEval = function() */ TestSuite.prototype.testConsoleLog = function() { - WebInspector.console.visible = true; + WebInspector.showConsole(); var messages = WebInspector.console.messages; var index = 0; @@ -1761,7 +1709,7 @@ TestSuite.prototype.testConsoleLog = function() */ TestSuite.prototype.testEvalGlobal = function() { - WebInspector.console.visible = true; + WebInspector.showConsole(); var inputs = ["foo", "foobar"]; var expectations = ["foo", "fooValue", "foobar", "ReferenceError: foobar is not defined"]; @@ -1794,6 +1742,48 @@ TestSuite.prototype.testEvalGlobal = function() /** + * Tests the message loop re-entrancy. + */ +TestSuite.prototype.testMessageLoopReentrant = function() +{ + var test = this; + this.showPanel("scripts"); + + var breakpointLine = 16; + + WebInspector.showConsole(); + + this._waitUntilScriptsAreParsed(["debugger_test_page.html"], + function() { + test.showMainPageScriptSource_( + "debugger_test_page.html", + function(view, url) { + view._addBreakpoint(breakpointLine); + + test.evaluateInConsole_( + 'setTimeout("calculate()", 0)', + function(resultText) { + test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); + }); + + }); + }); + + // Wait until script is paused. + this.addSniffer( + WebInspector, + "pausedScript", + function(callFrames) { + test.evaluateInConsole_( + 'document.cookie', + test.releaseControl.bind(test)); // This callback will be invoked only if the test succeeds (i.e. no crash). + }); + + this.takeControl(); +}; + + +/** * Tests that Storage panel can be open and that local DOM storage is added * to the panel. */ diff --git a/WebKit/chromium/src/js/devTools.css b/WebKit/chromium/src/js/devTools.css index 1fa935f..dfcaadf 100755 --- a/WebKit/chromium/src/js/devTools.css +++ b/WebKit/chromium/src/js/devTools.css @@ -1,7 +1,3 @@ -#scripts-files option.injected { - color: rgb(70, 134, 240); -} - .data-grid table { line-height: 120%; } @@ -13,16 +9,33 @@ body.attached #toolbar { padding-left: 0; } - /* Chrome theme overrides */ -body.platform-windows #toolbar { - background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(242, 247, 253)), to(rgb(223, 234, 248))); + +body.platform-windows #toolbar, body.platform-windows.inactive #toolbar { + background-image: none; +} + +body.detached.platform-mac-leopard #toolbar { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(175, 175, 175)), to(rgb(151, 151, 151))) !important; } -body.platform-windows.inactive #toolbar { - background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(248, 248, 248)), to(rgb(237, 237, 237))); +body.detached.platform-mac-leopard.inactive #toolbar { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(221, 221, 221)), to(rgb(207, 207, 207))) !important; } +body.detached.platform-mac-snowleopard #toolbar { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(189, 189, 189)), to(rgb(151, 151, 151))) !important; +} + +body.detached.platform-mac-snowleopard.inactive #toolbar { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(215, 215, 215)), to(rgb(207, 207, 207))) !important; +} + +body.platform-linux #scripts-files { + font-size: 11px; + font-weight: normal; + line-height: 12px; +} /* Heap Profiler Styles */ @@ -136,77 +149,75 @@ body.platform-windows.inactive #toolbar { left: 25%; } -body.platform-windows .section > .header { +.section > .header { border: 1px solid rgb(92, 116, 157); background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(105, 133, 180)), to(rgb(92, 116, 157))); } -body.platform-windows .console-group-messages .section > .header { +.console-group-messages .section > .header { padding: 0 8px 0 0; background-image: none; border: none; min-height: 0; } -body.platform-windows #resources-filter { +#resources-filter { background: -webkit-gradient(linear, left top, left bottom, from(rgb(233, 233, 233)), to(rgb(233, 233, 233))); } -body.platform-windows .crumbs .crumb { +.crumbs .crumb { -webkit-border-image: url(Images/segmentChromium.png) 0 12 0 2; + margin-right: -3px; + padding-left: 6px; } -body.platform-windows .crumbs .crumb.end { - -webkit-border-image: url(Images/segmentEndChromium.png) 0 2 0 2; -} - -body.platform-windows .crumbs .crumb.selected { +.crumbs .crumb.selected { -webkit-border-image: url(Images/segmentSelectedChromium.png) 0 12 0 2; color: white; text-shadow: rgba(255, 255, 255, 0.5) 0 0px 0; } -body.platform-windows .crumbs .crumb.selected:hover { +.crumbs .crumb.selected:hover { -webkit-border-image: url(Images/segmentSelectedChromium.png) 0 12 0 2; } -body.platform-windows .crumbs .crumb.selected.end, .crumbs .crumb.selected.end:hover { +.crumbs .crumb.selected.end, .crumbs .crumb.selected.end:hover { -webkit-border-image: url(Images/segmentSelectedEndChromium.png) 0 2 0 2; } -body.platform-windows .crumbs .crumb:hover { +.crumbs .crumb:hover { -webkit-border-image: url(Images/segmentHoverChromium.png) 0 12 0 2; } -body.platform-windows .crumbs .crumb.dimmed:hover { +.crumbs .crumb.dimmed:hover { -webkit-border-image: url(Images/segmentHoverChromium.png) 0 12 0 2; } -body.platform-windows .crumbs .crumb.end:hover { +.crumbs .crumb.end:hover { -webkit-border-image: url(Images/segmentHoverEndChromium.png) 0 2 0 2; } -body.platform-windows body.drawer-visible #main-status-bar { +body.drawer-visible #main-status-bar { background-image: url(Images/statusbarResizerVertical.png), url(Images/statusbarBackgroundChromium.png); } -body.platform-windows .status-bar { +.status-bar { background-image: url(Images/statusbarBackgroundChromium.png); } -body.platform-windows button.status-bar-item { +button.status-bar-item { background-image: url(Images/statusbarButtonsChromium.png); } -body.platform-windows select.status-bar-item:active { +select.status-bar-item:active { -webkit-border-image: url(Images/statusbarMenuButtonSelectedChromium.png) 0 17 0 2; } -body.platform-windows #drawer { +#drawer { background-image: url(Images/statusbarBottomBackgroundChromium.png); } -body.platform-windows select.status-bar-item { +select.status-bar-item { -webkit-border-image: url(Images/statusbarMenuButtonChromium.png) 0 17 0 2; } @@ -218,6 +229,6 @@ body.platform-windows select.status-bar-item { -webkit-box-shadow: 0px 0px 0px rgba(0, 0, 0, 0.0); } -.timeline-category-tree-item input { +.timeline-category-statusbar-item input { vertical-align: middle; } diff --git a/WebKit/chromium/src/linux/WebFontRenderStyle.cpp b/WebKit/chromium/src/linux/WebFontRenderStyle.cpp new file mode 100644 index 0000000..0b864d1 --- /dev/null +++ b/WebKit/chromium/src/linux/WebFontRenderStyle.cpp @@ -0,0 +1,60 @@ +/* + * 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 "WebFontRenderStyle.h" + +#include "FontRenderStyle.h" + +using WebCore::FontRenderStyle; + +namespace WebKit { + +void WebFontRenderStyle::toFontRenderStyle(FontRenderStyle* out) +{ + out->useBitmaps = useBitmaps; + out->useAutoHint = useAutoHint; + out->useHinting = useHinting; + out->hintStyle = hintStyle; + out->useAntiAlias = useAntiAlias; + out->useSubpixel = useSubpixel; +} + +void WebFontRenderStyle::setDefaults() +{ + useBitmaps = 2; + useAutoHint = 2; + useHinting = 2; + hintStyle = 0; + useAntiAlias = 2; + useSubpixel = 2; +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/mac/WebInputEventFactory.mm b/WebKit/chromium/src/mac/WebInputEventFactory.mm index 46b0afe..694155f 100644 --- a/WebKit/chromium/src/mac/WebInputEventFactory.mm +++ b/WebKit/chromium/src/mac/WebInputEventFactory.mm @@ -861,6 +861,29 @@ static inline int modifiersFromEvent(NSEvent* event) { return modifiers; } +static inline void setWebEventLocationFromEventInView(WebMouseEvent* result, + NSEvent* event, + NSView* view) { + NSPoint windowLocal = [event locationInWindow]; + + NSPoint screenLocal = [[view window] convertBaseToScreen:windowLocal]; + result->globalX = screenLocal.x; + // Flip y. + NSScreen* primaryScreen = ([[NSScreen screens] count] > 0) ? + [[NSScreen screens] objectAtIndex:0] : nil; + if (primaryScreen) + result->globalY = [primaryScreen frame].size.height - screenLocal.y; + else + result->globalY = screenLocal.y; + + NSPoint contentLocal = [view convertPoint:windowLocal fromView:nil]; + result->x = contentLocal.x; + result->y = [view frame].size.height - contentLocal.y; // Flip y. + + result->windowX = result->x; + result->windowY = result->y; +} + WebKeyboardEvent WebInputEventFactory::keyboardEvent(NSEvent* event) { WebKeyboardEvent result; @@ -1021,16 +1044,7 @@ WebMouseEvent WebInputEventFactory::mouseEvent(NSEvent* event, NSView* view) ASSERT_NOT_REACHED(); } - NSPoint location = [NSEvent mouseLocation]; // global coordinates - result.globalX = location.x; - result.globalY = [[[view window] screen] frame].size.height - location.y; - - NSPoint windowLocal = [event locationInWindow]; - location = [view convertPoint:windowLocal fromView:nil]; - result.y = [view frame].size.height - location.y; // flip y - result.x = location.x; - result.windowX = result.x; - result.windowY = result.y; + setWebEventLocationFromEventInView(&result, event, view); result.modifiers = modifiersFromEvent(event); @@ -1050,16 +1064,7 @@ WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(NSEvent* event, NSView* result.modifiers = modifiersFromEvent(event); - // Set coordinates by translating event coordinates from screen to client. - NSPoint location = [NSEvent mouseLocation]; // global coordinates - result.globalX = location.x; - result.globalY = location.y; - NSPoint windowLocal = [event locationInWindow]; - location = [view convertPoint:windowLocal fromView:nil]; - result.x = location.x; - result.y = [view frame].size.height - location.y; // flip y - result.windowX = result.x; - result.windowY = result.y; + setWebEventLocationFromEventInView(&result, event, view); // Of Mice and Men // --------------- |
