Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/browser
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@tomeuvizoso.net>2007-04-17 19:53:34 (GMT)
committer Tomeu Vizoso <tomeu@tomeuvizoso.net>2007-04-17 19:53:34 (GMT)
commitb7030a74dd5208afc75be42c81201cfa72ebbcc9 (patch)
tree9f047f76e653130d2cadf98a9bf6434a1eee57b3 /browser
parent92416d1519c67012e02af17a672edead91f68011 (diff)
Drag images out of mozilla.
Diffstat (limited to 'browser')
-rw-r--r--browser/GeckoBrowserPersist.cpp185
-rw-r--r--browser/GeckoBrowserPersist.h19
-rw-r--r--browser/GeckoDocumentObject.cpp187
-rw-r--r--browser/GeckoDocumentObject.h29
-rw-r--r--browser/GeckoDragDropHooks.cpp185
-rw-r--r--browser/GeckoDragDropHooks.h25
-rw-r--r--browser/Makefile.am9
-rw-r--r--browser/sugar-browser.cpp218
8 files changed, 688 insertions, 169 deletions
diff --git a/browser/GeckoBrowserPersist.cpp b/browser/GeckoBrowserPersist.cpp
new file mode 100644
index 0000000..48de4d1
--- /dev/null
+++ b/browser/GeckoBrowserPersist.cpp
@@ -0,0 +1,185 @@
+#include <stdio.h>
+
+#include <gtkmozembed.h>
+#include <gtkmozembed_internal.h>
+#include <nsIRequest.h>
+#include <nsNetUtil.h>
+#include <nsISeekableStream.h>
+#include <nsIHttpChannel.h>
+#include <nsIUploadChannel.h>
+#include <nsIWebBrowser.h>
+#include <nsISHistory.h>
+#include <nsIHistoryEntry.h>
+#include <nsISHEntry.h>
+#include <nsIInputStream.h>
+#include <nsIWebNavigation.h>
+
+#include <config.h>
+#include "GeckoBrowserPersist.h"
+
+GeckoBrowserPersist::GeckoBrowserPersist(SugarBrowser *browser)
+ : mBrowser(browser)
+{
+}
+
+GeckoBrowserPersist::~GeckoBrowserPersist()
+{
+}
+
+static nsresult
+NewURI(const char *uri, nsIURI **result)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIServiceManager> mgr;
+ NS_GetServiceManager (getter_AddRefs (mgr));
+ NS_ENSURE_TRUE(mgr, FALSE);
+
+ nsCOMPtr<nsIIOService> ioService;
+ rv = mgr->GetServiceByContractID ("@mozilla.org/network/io-service;1",
+ NS_GET_IID (nsIIOService),
+ getter_AddRefs(ioService));
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ nsCString cSpec(uri);
+ return ioService->NewURI (cSpec, nsnull, nsnull, result);
+}
+
+static nsresult
+GetPostData(SugarBrowser *browser, nsIInputStream **postData)
+{
+#ifdef HAVE_NS_WEB_BROWSER
+ nsCOMPtr<nsIWebBrowser> webBrowser;
+ gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(browser),
+ getter_AddRefs(webBrowser));
+ NS_ENSURE_TRUE(webBrowser, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(webBrowser));
+ NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
+
+ PRInt32 sindex;
+
+ nsCOMPtr<nsISHistory> sessionHistory;
+ webNav->GetSessionHistory(getter_AddRefs(sessionHistory));
+ NS_ENSURE_TRUE(sessionHistory, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIHistoryEntry> entry;
+ sessionHistory->GetIndex(&sindex);
+ sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry));
+
+ nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
+ if (shEntry) {
+ shEntry->GetPostData(postData);
+ }
+
+ return NS_OK;
+#endif
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+bool
+GeckoBrowserPersist::SaveURI(const char *uri, const char *filename)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIURI> sourceURI;
+ rv = NewURI(uri, getter_AddRefs(sourceURI));
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ nsCOMPtr<nsILocalFile> destFile = do_CreateInstance("@mozilla.org/file/local;1");
+ NS_ENSURE_TRUE(destFile, FALSE);
+
+ destFile->InitWithNativePath(nsCString(filename));
+
+ nsCOMPtr<nsIInputStream> postData;
+ GetPostData(mBrowser, getter_AddRefs(postData));
+
+ nsCOMPtr<nsIChannel> inputChannel;
+ rv = NS_NewChannel(getter_AddRefs(inputChannel), sourceURI,
+ nsnull, nsnull, nsnull, nsIRequest::LOAD_NORMAL);
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(inputChannel));
+ if (httpChannel) {
+ nsCOMPtr<nsISeekableStream> stream(do_QueryInterface(postData));
+ if (stream)
+ {
+ // Rewind the postdata stream
+ stream->Seek(nsISeekableStream::NS_SEEK_SET, 0);
+ nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
+ NS_ASSERTION(uploadChannel, "http must support nsIUploadChannel");
+ // Attach the postdata to the http channel
+ uploadChannel->SetUploadStream(postData, EmptyCString(), -1);
+ }
+ }
+
+ nsCOMPtr<nsIInputStream> stream;
+ rv = inputChannel->Open(getter_AddRefs(stream));
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ nsCOMPtr<nsIFileOutputStream> fileOutputStream =
+ do_CreateInstance(NS_LOCALFILEOUTPUTSTREAM_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ rv = fileOutputStream->Init(destFile, -1, -1, 0);
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ // Read data from the input and write to the output
+ char buffer[8192];
+ PRUint32 bytesRead;
+ PRUint32 bytesRemaining;
+ PRBool cancel = PR_FALSE;
+ PRBool readError;
+
+ rv = stream->Available(&bytesRemaining);
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ while (!cancel && bytesRemaining)
+ {
+ readError = PR_TRUE;
+ rv = stream->Read(buffer, PR_MIN(sizeof(buffer), bytesRemaining), &bytesRead);
+ if (NS_SUCCEEDED(rv))
+ {
+ readError = PR_FALSE;
+ // Write out the data until something goes wrong, or, it is
+ // all written. We loop because for some errors (e.g., disk
+ // full), we get NS_OK with some bytes written, then an error.
+ // So, we want to write again in that case to get the actual
+ // error code.
+ const char *bufPtr = buffer; // Where to write from.
+ while (NS_SUCCEEDED(rv) && bytesRead)
+ {
+ PRUint32 bytesWritten = 0;
+ rv = fileOutputStream->Write(bufPtr, bytesRead, &bytesWritten);
+ if (NS_SUCCEEDED(rv))
+ {
+ bytesRead -= bytesWritten;
+ bufPtr += bytesWritten;
+ bytesRemaining -= bytesWritten;
+ // Force an error if (for some reason) we get NS_OK but
+ // no bytes written.
+ if (!bytesWritten)
+ {
+ rv = NS_ERROR_FAILURE;
+ cancel = PR_TRUE;
+ }
+ }
+ else
+ {
+ // Disaster - can't write out the bytes - disk full / permission?
+ cancel = PR_TRUE;
+ }
+ }
+ }
+ else
+ {
+ // Disaster - can't read the bytes - broken link / file error?
+ cancel = PR_TRUE;
+ }
+ }
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ stream->Close();
+
+ return TRUE;
+}
diff --git a/browser/GeckoBrowserPersist.h b/browser/GeckoBrowserPersist.h
new file mode 100644
index 0000000..e976789
--- /dev/null
+++ b/browser/GeckoBrowserPersist.h
@@ -0,0 +1,19 @@
+#ifndef __GECKO_BROWSER_PERSIST_H__
+#define __GECKO_BROWSER_PERSIST_H__
+
+#include "sugar-browser.h"
+
+class GeckoBrowserPersist
+{
+public:
+ GeckoBrowserPersist(SugarBrowser *browser);
+ ~GeckoBrowserPersist();
+
+ bool SaveURI(const char *uri, const char *filename);
+private:
+ SugarBrowser *mBrowser;
+protected:
+ /* additional members */
+};
+
+#endif // __GECKO_BROWSER_PERSIST_H__
diff --git a/browser/GeckoDocumentObject.cpp b/browser/GeckoDocumentObject.cpp
new file mode 100644
index 0000000..6f034e1
--- /dev/null
+++ b/browser/GeckoDocumentObject.cpp
@@ -0,0 +1,187 @@
+#include <unistd.h>
+
+#include <glib.h>
+#include <imgICache.h>
+#include <nsComponentManagerUtils.h>
+#include <nsCOMPtr.h>
+#include <nsIDOMHTMLElement.h>
+#include <nsIInterfaceRequestorUtils.h>
+#include <nsIIOService.h>
+#include <nsILocalFile.h>
+#include <nsIMIMEHeaderParam.h>
+#include <nsIProperties.h>
+#include <nsISupportsPrimitives.h>
+#include <nsIURI.h>
+#include <nsIURL.h>
+#include <nsServiceManagerUtils.h>
+#include <nsStringAPI.h>
+
+#include <config.h>
+#include "GeckoDocumentObject.h"
+#include "GeckoBrowserPersist.h"
+
+GeckoDocumentObject::GeckoDocumentObject(SugarBrowser *browser, nsIDOMNode *node)
+ : mBrowser(browser),
+ mNode(node),
+ mImage(NULL)
+{
+}
+
+GeckoDocumentObject::~GeckoDocumentObject()
+{
+}
+
+bool GeckoDocumentObject::IsImage()
+{
+ if(mImage) {
+ return true;
+ }
+
+ nsresult rv;
+
+ PRUint16 type;
+ rv = mNode->GetNodeType(&type);
+ if(NS_FAILED(rv)) return rv;
+
+ nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(mNode);
+ if ((nsIDOMNode::ELEMENT_NODE == type) && element) {
+ nsString uTag;
+ rv = element->GetLocalName(uTag);
+ if(NS_FAILED(rv)) return rv;
+
+ nsCString tag;
+ NS_UTF16ToCString (uTag, NS_CSTRING_ENCODING_UTF8, tag);
+
+ if (g_ascii_strcasecmp (tag.get(), "img") == 0) {
+ nsCOMPtr <nsIDOMHTMLImageElement> imagePtr;
+ imagePtr = do_QueryInterface(mNode, &rv);
+ if(NS_FAILED(rv)) return rv;
+
+ mImage = imagePtr;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static nsresult
+NewURI(const char *uri, nsIURI **result)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIServiceManager> mgr;
+ NS_GetServiceManager (getter_AddRefs (mgr));
+ NS_ENSURE_TRUE(mgr, FALSE);
+
+ nsCOMPtr<nsIIOService> ioService;
+ rv = mgr->GetServiceByContractID ("@mozilla.org/network/io-service;1",
+ NS_GET_IID (nsIIOService),
+ getter_AddRefs(ioService));
+ NS_ENSURE_SUCCESS(rv, FALSE);
+
+ nsCString cSpec(uri);
+ return ioService->NewURI (cSpec, nsnull, nsnull, result);
+}
+
+static nsresult
+FilenameFromContentDisposition(nsCString contentDisposition, nsCString &fileName)
+{
+ nsresult rv;
+ nsCString fallbackCharset;
+
+ nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar =
+ do_GetService("@mozilla.org/network/mime-hdrparam;1");
+ NS_ENSURE_TRUE(mimehdrpar, NS_ERROR_FAILURE);
+
+ nsString aFileName;
+ rv = mimehdrpar->GetParameter (contentDisposition, "filename",
+ fallbackCharset, PR_TRUE, nsnull,
+ aFileName);
+
+ if (NS_FAILED(rv) || !fileName.Length()) {
+ rv = mimehdrpar->GetParameter (contentDisposition, "name",
+ fallbackCharset, PR_TRUE, nsnull,
+ aFileName);
+ }
+
+ if (NS_SUCCEEDED(rv) && fileName.Length()) {
+ NS_UTF16ToCString (aFileName, NS_CSTRING_ENCODING_UTF8, fileName);
+ }
+
+ return NS_OK;
+}
+
+char *
+GeckoDocumentObject::GetImageName()
+{
+ if(!IsImage()) {
+ return NULL;
+ }
+
+ nsresult rv;
+ char *imgURIStr = GetImageURI();
+
+ nsCOMPtr<nsIURI> imageURI;
+ rv = NewURI(imgURIStr, getter_AddRefs(imageURI));
+ NS_ENSURE_SUCCESS(rv, NULL);
+
+ nsCOMPtr<nsIServiceManager> mgr;
+ NS_GetServiceManager (getter_AddRefs (mgr));
+ NS_ENSURE_TRUE(mgr, NULL);
+
+ nsCOMPtr<imgICache> imgCache;
+ rv = mgr->GetServiceByContractID("@mozilla.org/image/cache;1",
+ NS_GET_IID (imgICache),
+ getter_AddRefs(imgCache));
+ NS_ENSURE_SUCCESS(rv, NULL);
+
+ nsCOMPtr<nsIProperties> imgProperties;
+ imgCache->FindEntryProperties(imageURI, getter_AddRefs(imgProperties));
+ if (imgProperties) {
+ nsCOMPtr<nsISupportsCString> dispositionCString;
+ imgProperties->Get("content-disposition",
+ NS_GET_IID(nsISupportsCString),
+ getter_AddRefs(dispositionCString));
+ if (dispositionCString) {
+ nsCString contentDisposition;
+ dispositionCString->GetData(contentDisposition);
+ FilenameFromContentDisposition(contentDisposition, mImageName);
+ }
+ }
+
+ if (!mImageName.Length()) {
+ nsCOMPtr<nsIURL> url(do_QueryInterface(imageURI));
+ if (url) {
+ url->GetFileName(mImageName);
+ }
+ }
+
+ return mImageName.Length() ? g_strdup(mImageName.get()) : NULL;
+}
+
+char *
+GeckoDocumentObject::GetImageURI()
+{
+ if(!IsImage()) {
+ return NULL;
+ }
+
+ if(!mImageURI.Length()) {
+ nsresult rv;
+ nsString img;
+ rv = mImage->GetSrc(img);
+ if (NS_FAILED(rv)) return NULL;
+
+ NS_UTF16ToCString (img, NS_CSTRING_ENCODING_UTF8, mImageURI);
+ }
+ return g_strdup(mImageURI.get());
+}
+
+bool
+GeckoDocumentObject::SaveImage(const char *filename)
+{
+ GeckoBrowserPersist browserPersist(mBrowser);
+ return browserPersist.SaveURI(mImageURI.get(), filename);
+}
diff --git a/browser/GeckoDocumentObject.h b/browser/GeckoDocumentObject.h
new file mode 100644
index 0000000..05328e5
--- /dev/null
+++ b/browser/GeckoDocumentObject.h
@@ -0,0 +1,29 @@
+#ifndef __GECKO_DOCUMENT_OBJECT_H__
+#define __GECKO_DOCUMENT_OBJECT_H__
+
+#include <nsIDOMNode.h>
+#include <nsIDOMHTMLImageElement.h>
+
+#include "sugar-browser.h"
+
+class GeckoDocumentObject
+{
+public:
+ GeckoDocumentObject(SugarBrowser *browser, nsIDOMNode *node);
+ ~GeckoDocumentObject();
+
+ bool IsImage();
+ char *GetImageURI();
+ char *GetImageName();
+ bool SaveImage(const char *filename);
+private:
+ SugarBrowser *mBrowser;
+ nsCOMPtr<nsIDOMNode> mNode;
+ nsCOMPtr<nsIDOMHTMLImageElement> mImage;
+ nsCString mImageURI;
+ nsCString mImageName;
+protected:
+ /* additional members */
+};
+
+#endif // __GECKO_DOCUMENT_OBJECT_H__
diff --git a/browser/GeckoDragDropHooks.cpp b/browser/GeckoDragDropHooks.cpp
new file mode 100644
index 0000000..425ee45
--- /dev/null
+++ b/browser/GeckoDragDropHooks.cpp
@@ -0,0 +1,185 @@
+#include <sys/time.h>
+#include <time.h>
+
+#include <glib.h>
+#include <nsStringAPI.h>
+#include <nsCOMPtr.h>
+#include <nsITransferable.h>
+#include <nsISupportsPrimitives.h>
+#include <nsIDOMEventTarget.h>
+#include <nsComponentManagerUtils.h>
+#include <nsServiceManagerUtils.h>
+#include <nsIInterfaceRequestorUtils.h>
+#include <nsIDOMMouseEvent.h>
+
+#include <config.h>
+#include "GeckoDragDropHooks.h"
+#include "GeckoDocumentObject.h"
+
+#define TEXT_URI_LIST "text/uri-list"
+#define TEXT_X_MOZ_URL "text/x-moz-url"
+#define FILE_LOCALHOST "file://"
+
+//*****************************************************************************
+// UriListDataProvider
+//*****************************************************************************
+
+class UriListDataProvider : public nsIFlavorDataProvider
+{
+public:
+ UriListDataProvider(GeckoDocumentObject *mDocumentObject);
+ virtual ~UriListDataProvider();
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIFLAVORDATAPROVIDER
+private:
+ GeckoDocumentObject *mDocumentObject;
+ nsCString mFilePath;
+};
+
+//*****************************************************************************
+
+NS_IMPL_ISUPPORTS1(UriListDataProvider, nsIFlavorDataProvider)
+
+UriListDataProvider::UriListDataProvider(GeckoDocumentObject *documentObject)
+ : mDocumentObject(documentObject)
+{
+}
+
+UriListDataProvider::~UriListDataProvider()
+{
+ if(mFilePath.Length()) {
+ remove(mFilePath.get());
+ }
+
+ delete mDocumentObject;
+}
+
+NS_IMETHODIMP
+UriListDataProvider::GetFlavorData(nsITransferable *aTransferable,
+ const char *aFlavor, nsISupports **aData,
+ PRUint32 *aDataLen)
+{
+ NS_ENSURE_ARG_POINTER(aData && aDataLen);
+
+ nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
+ char *image_name;
+ timeval timestamp;
+
+ *aData = nsnull;
+ *aDataLen = 0;
+
+ if(g_ascii_strcasecmp(aFlavor, TEXT_URI_LIST) != 0) {
+ return rv;
+ }
+
+ gettimeofday(&timestamp, NULL);
+
+ mFilePath.Append(g_get_tmp_dir());
+ mFilePath.Append("/");
+ mFilePath.AppendInt(timestamp.tv_sec);
+ mFilePath.AppendInt(timestamp.tv_usec);
+
+ image_name = mDocumentObject->GetImageName();
+ mFilePath.Append(image_name);
+ g_free(image_name);
+
+ if(!mDocumentObject->SaveImage(mFilePath.get())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCString localURI(FILE_LOCALHOST);
+ localURI.Append(mFilePath);
+
+ nsString localURI16;
+ NS_CStringToUTF16(localURI, NS_CSTRING_ENCODING_UTF8, localURI16);
+
+ nsCOMPtr<nsISupportsString> localURIData(do_CreateInstance(
+ "@mozilla.org/supports-string;1", &rv));
+ if(NS_FAILED(rv)) return rv;
+
+ rv = localURIData->SetData(localURI16);
+ if(NS_FAILED(rv)) return rv;
+
+ CallQueryInterface(localURIData, aData);
+ *aDataLen = sizeof(nsISupportsString*);
+
+ // FIXME: Why do we need this? Is there a leak in mozilla?
+ this->Release();
+
+ return rv;
+}
+
+//*****************************************************************************
+// GeckoDragDropHooks
+//*****************************************************************************
+
+NS_IMPL_ISUPPORTS1(GeckoDragDropHooks, nsIClipboardDragDropHooks)
+
+GeckoDragDropHooks::GeckoDragDropHooks(SugarBrowser *browser)
+ : mBrowser(browser)
+{
+}
+
+GeckoDragDropHooks::~GeckoDragDropHooks()
+{
+}
+
+NS_IMETHODIMP
+GeckoDragDropHooks::AllowStartDrag(nsIDOMEvent *event, PRBool *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+GeckoDragDropHooks::AllowDrop(nsIDOMEvent *event, nsIDragSession *session,
+ PRBool *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+GeckoDragDropHooks::OnCopyOrDrag(nsIDOMEvent *aEvent, nsITransferable *trans,
+ PRBool *_retval)
+{
+ nsresult rv;
+
+ *_retval = true;
+
+ nsCOMPtr<nsIDOMMouseEvent> mouseEvent;
+ mouseEvent = do_QueryInterface(aEvent, &rv);
+ if(NS_FAILED(rv)) return rv;
+
+ nsCOMPtr<nsIDOMEventTarget> eventTarget;
+ rv = mouseEvent->GetTarget(getter_AddRefs(eventTarget));
+ if(NS_FAILED(rv)) return rv;
+
+ nsCOMPtr<nsIDOMNode> targetNode;
+ targetNode = do_QueryInterface(eventTarget, &rv);
+ if(NS_FAILED(rv)) return rv;
+
+ GeckoDocumentObject *documentObject = new GeckoDocumentObject(mBrowser,
+ targetNode);
+ if(documentObject->IsImage()) {
+ rv = trans->RemoveDataFlavor(TEXT_X_MOZ_URL);
+ if(NS_FAILED(rv)) return rv;
+
+ rv = trans->AddDataFlavor(TEXT_URI_LIST);
+ if(NS_FAILED(rv)) return rv;
+
+ UriListDataProvider *rawPtr = new UriListDataProvider(documentObject);
+ nsCOMPtr<nsISupports> dataProvider(do_QueryInterface(rawPtr, &rv));
+ if(NS_FAILED(rv)) return rv;
+
+ rv = trans->SetTransferData(TEXT_URI_LIST, dataProvider, 0);
+ if(NS_FAILED(rv)) return rv;
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+GeckoDragDropHooks::OnPasteOrDrop(nsIDOMEvent *event, nsITransferable *trans,
+ PRBool *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/browser/GeckoDragDropHooks.h b/browser/GeckoDragDropHooks.h
new file mode 100644
index 0000000..c551c0e
--- /dev/null
+++ b/browser/GeckoDragDropHooks.h
@@ -0,0 +1,25 @@
+#ifndef __GECKO_DRAG_DROP_HOOKS_H__
+#define __GECKO_DRAG_DROP_HOOKS_H__
+
+#include <nsIClipboardDragDropHooks.h>
+
+#include "sugar-browser.h"
+
+class GeckoDragDropHooks : public nsIClipboardDragDropHooks
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICLIPBOARDDRAGDROPHOOKS
+
+ GeckoDragDropHooks(SugarBrowser *browser);
+
+private:
+ ~GeckoDragDropHooks();
+
+ SugarBrowser *mBrowser;
+
+protected:
+ /* additional members */
+};
+
+#endif // __GECKO_DRAG_DROP_HOOKS_H__
diff --git a/browser/Makefile.am b/browser/Makefile.am
index ae013e0..b418583 100644
--- a/browser/Makefile.am
+++ b/browser/Makefile.am
@@ -3,6 +3,7 @@ libsugarbrowser_la_CPPFLAGS = \
$(LIB_CFLAGS) \
$(GECKO_CFLAGS) \
$(NSPR_CFLAGS) \
+ -I$(MOZILLA_INCLUDE_DIR)/commandhandler \
-I$(MOZILLA_INCLUDE_DIR)/dom \
-I$(MOZILLA_INCLUDE_DIR)/docshell \
-I$(MOZILLA_INCLUDE_DIR)/exthandler \
@@ -15,6 +16,8 @@ libsugarbrowser_la_CPPFLAGS = \
-I$(MOZILLA_INCLUDE_DIR)/uriloader \
-I$(MOZILLA_INCLUDE_DIR)/webbrwsr \
-I$(MOZILLA_INCLUDE_DIR)/webbrowserpersist \
+ -I$(MOZILLA_INCLUDE_DIR)/widget \
+ -I$(MOZILLA_INCLUDE_DIR)/xpcom \
-DPLUGIN_DIR=\"$(libdir)/mozilla/plugins\" \
-DSHARE_DIR=\"$(pkgdatadir)\"
@@ -26,8 +29,14 @@ libsugarbrowser_la_LIBADD = \
libsugarbrowser_la_SOURCES = \
$(BUILT_SOURCES) \
+ GeckoBrowserPersist.h \
+ GeckoBrowserPersist.cpp \
GeckoContentHandler.h \
GeckoContentHandler.cpp \
+ GeckoDocumentObject.h \
+ GeckoDocumentObject.cpp \
+ GeckoDragDropHooks.h \
+ GeckoDragDropHooks.cpp \
GeckoDownload.h \
GeckoDownload.cpp \
sugar-address-entry.c \
diff --git a/browser/sugar-browser.cpp b/browser/sugar-browser.cpp
index cd455b6..270631b 100644
--- a/browser/sugar-browser.cpp
+++ b/browser/sugar-browser.cpp
@@ -23,6 +23,9 @@
#include "sugar-marshal.h"
#include "GeckoContentHandler.h"
#include "GeckoDownload.h"
+#include "GeckoDragDropHooks.h"
+#include "GeckoDocumentObject.h"
+#include "GeckoBrowserPersist.h"
#include <gdk/gdkx.h>
#include <gtkmozembed_internal.h>
@@ -56,6 +59,8 @@
#include <nsIHistoryEntry.h>
#include <nsISHEntry.h>
#include <nsIInputStream.h>
+#include <nsICommandManager.h>
+#include <nsIClipboardDragDropHooks.h>
enum {
PROP_0,
@@ -75,6 +80,8 @@ enum {
static guint signals[N_SIGNALS];
+static GObjectClass *parent_class = NULL;
+
static const nsModuleComponentInfo sSugarComponents[] = {
{
"Gecko Content Handler",
@@ -211,25 +218,6 @@ sugar_browser_shutdown(void)
G_DEFINE_TYPE(SugarBrowser, sugar_browser, GTK_TYPE_MOZ_EMBED)
static nsresult
-NewURI(const char *uri, nsIURI **result)
-{
- nsresult rv;
-
- nsCOMPtr<nsIServiceManager> mgr;
- NS_GetServiceManager (getter_AddRefs (mgr));
- NS_ENSURE_TRUE(mgr, FALSE);
-
- nsCOMPtr<nsIIOService> ioService;
- rv = mgr->GetServiceByContractID ("@mozilla.org/network/io-service;1",
- NS_GET_IID (nsIIOService),
- getter_AddRefs(ioService));
- NS_ENSURE_SUCCESS(rv, FALSE);
-
- nsCString cSpec(uri);
- return ioService->NewURI (cSpec, nsnull, nsnull, result);
-}
-
-static nsresult
FilenameFromContentDisposition(nsCString contentDisposition, nsCString &fileName)
{
nsresult rv;
@@ -258,38 +246,6 @@ FilenameFromContentDisposition(nsCString contentDisposition, nsCString &fileName
return NS_OK;
}
-static nsresult
-ImageNameFromCache(nsIURI *imgURI, nsCString &imgName)
-{
- nsresult rv;
-
- nsCOMPtr<nsIServiceManager> mgr;
- NS_GetServiceManager (getter_AddRefs (mgr));
- NS_ENSURE_TRUE(mgr, NS_ERROR_FAILURE);
-
- nsCOMPtr<imgICache> imgCache;
- rv = mgr->GetServiceByContractID("@mozilla.org/image/cache;1",
- NS_GET_IID (imgICache),
- getter_AddRefs(imgCache));
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-
- nsCOMPtr<nsIProperties> imgProperties;
- imgCache->FindEntryProperties(imgURI, getter_AddRefs(imgProperties));
- if (imgProperties) {
- nsCOMPtr<nsISupportsCString> dispositionCString;
- imgProperties->Get("content-disposition",
- NS_GET_IID(nsISupportsCString),
- getter_AddRefs(dispositionCString));
- if (dispositionCString) {
- nsCString contentDisposition;
- dispositionCString->GetData(contentDisposition);
- FilenameFromContentDisposition(contentDisposition, imgName);
- }
- }
-
- return NS_OK;
-}
-
static SugarBrowserMetadata *
sugar_browser_get_document_metadata(SugarBrowser *browser)
{
@@ -382,13 +338,47 @@ sugar_browser_get_property(GObject *object,
}
}
+static void
+sugar_browser_realize(GtkWidget *widget)
+{
+ GTK_WIDGET_CLASS(parent_class)->realize(widget);
+
+#ifdef HAVE_NS_WEB_BROWSER
+ GtkMozEmbed *embed = GTK_MOZ_EMBED(widget);
+ nsCOMPtr<nsIWebBrowser> webBrowser;
+ gtk_moz_embed_get_nsIWebBrowser(embed, getter_AddRefs(webBrowser));
+ NS_ENSURE_TRUE(webBrowser, );
+
+ nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(webBrowser);
+ if (commandManager) {
+ nsresult rv;
+ nsIClipboardDragDropHooks *rawPtr = new GeckoDragDropHooks(
+ SUGAR_BROWSER(widget));
+ nsCOMPtr<nsIClipboardDragDropHooks> geckoDragDropHooks(
+ do_QueryInterface(rawPtr, &rv));
+ NS_ENSURE_SUCCESS(rv, );
+
+ nsCOMPtr<nsIDOMWindow> DOMWindow = do_GetInterface(webBrowser);
+ nsCOMPtr<nsICommandParams> cmdParamsObj = do_CreateInstance(
+ NS_COMMAND_PARAMS_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, );
+ cmdParamsObj->SetISupportsValue("addhook", geckoDragDropHooks);
+ commandManager->DoCommand("cmd_clipboardDragDropHook", cmdParamsObj,
+ DOMWindow);
+ }
+#endif
+}
static void
sugar_browser_class_init(SugarBrowserClass *browser_class)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS(browser_class);
+ GObjectClass *gobject_class = G_OBJECT_CLASS(browser_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(browser_class);
- gobject_class->get_property = sugar_browser_get_property;
+ parent_class = (GObjectClass *) g_type_class_peek_parent(browser_class);
+
+ gobject_class->get_property = sugar_browser_get_property;
+ widget_class->realize = sugar_browser_realize;
signals[MOUSE_CLICK] = g_signal_new ("mouse_click",
SUGAR_TYPE_BROWSER,
@@ -570,29 +560,6 @@ location_cb(GtkMozEmbed *embed)
update_navigation_properties(browser);
}
-static char *
-get_image_name(const char *uri)
-{
- nsresult rv;
-
- nsCString imgName;
-
- nsCOMPtr<nsIURI> imgURI;
- rv = NewURI(uri, getter_AddRefs(imgURI));
- NS_ENSURE_SUCCESS(rv, NULL);
-
- ImageNameFromCache(imgURI, imgName);
-
- if (!imgName.Length()) {
- nsCOMPtr<nsIURL> url(do_QueryInterface(imgURI));
- if (url) {
- url->GetFileName(imgName);
- }
- }
-
- return imgName.Length() ? g_strdup(imgName.get()) : NULL;
-}
-
static gboolean
dom_mouse_click_cb(GtkMozEmbed *embed, nsIDOMMouseEvent *mouseEvent)
{
@@ -610,36 +577,10 @@ dom_mouse_click_cb(GtkMozEmbed *embed, nsIDOMMouseEvent *mouseEvent)
event = sugar_browser_event_new();
- nsresult rv;
-
- PRUint16 type;
- rv = targetNode->GetNodeType(&type);
- if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
-
- nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(targetNode);
- if ((nsIDOMNode::ELEMENT_NODE == type) && element) {
- nsString uTag;
- rv = element->GetLocalName(uTag);
- if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
-
- nsCString tag;
- NS_UTF16ToCString (uTag, NS_CSTRING_ENCODING_UTF8, tag);
-
- if (g_ascii_strcasecmp (tag.get(), "img") == 0) {
- nsString img;
-
- nsCOMPtr <nsIDOMHTMLImageElement> image;
- image = do_QueryInterface(targetNode, &rv);
- if (NS_FAILED(rv) || !image) return NS_ERROR_FAILURE;
-
- rv = image->GetSrc(img);
- if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
-
- nsCString cImg;
- NS_UTF16ToCString (img, NS_CSTRING_ENCODING_UTF8, cImg);
- event->image_uri = g_strdup(cImg.get());
- event->image_name = get_image_name(event->image_uri);
- }
+ GeckoDocumentObject documentObject(browser, targetNode);
+ if(documentObject.IsImage()) {
+ event->image_uri = documentObject.GetImageURI();
+ event->image_name = documentObject.GetImageName();
}
PRUint16 btn = 0;
@@ -712,74 +653,13 @@ sugar_browser_grab_focus(SugarBrowser *browser)
}
}
-
-static nsresult
-GetPostData(SugarBrowser *browser, nsIInputStream **postData)
-{
-#ifdef HAVE_NS_WEB_BROWSER
- nsCOMPtr<nsIWebBrowser> webBrowser;
- gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(browser),
- getter_AddRefs(webBrowser));
- NS_ENSURE_TRUE(webBrowser, NS_ERROR_FAILURE);
-
- nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(webBrowser));
- NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
-
- PRInt32 sindex;
-
- nsCOMPtr<nsISHistory> sessionHistory;
- webNav->GetSessionHistory(getter_AddRefs(sessionHistory));
- NS_ENSURE_TRUE(sessionHistory, NS_ERROR_FAILURE);
-
- nsCOMPtr<nsIHistoryEntry> entry;
- sessionHistory->GetIndex(&sindex);
- sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry));
-
- nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
- if (shEntry) {
- shEntry->GetPostData(postData);
- }
-
- return NS_OK;
-#endif
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
gboolean
sugar_browser_save_uri(SugarBrowser *browser,
const char *uri,
const char *filename)
{
-#ifdef HAVE_NS_WEB_BROWSER
- nsresult rv;
-
- nsCOMPtr<nsIURI> sourceURI;
- rv = NewURI(uri, getter_AddRefs(sourceURI));
- NS_ENSURE_SUCCESS(rv, FALSE);
-
- nsCOMPtr<nsILocalFile> destFile = do_CreateInstance("@mozilla.org/file/local;1");
- NS_ENSURE_TRUE(destFile, FALSE);
-
- destFile->InitWithNativePath(nsCString(filename));
-
- nsCOMPtr<nsIWebBrowser> webBrowser;
- gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(browser),
- getter_AddRefs(webBrowser));
- NS_ENSURE_TRUE(webBrowser, FALSE);
-
- nsCOMPtr<nsIWebBrowserPersist> webPersist = do_QueryInterface (webBrowser);
- NS_ENSURE_TRUE(webPersist, FALSE);
-
- nsCOMPtr<nsIInputStream> postData;
- GetPostData(browser, getter_AddRefs(postData));
-
- rv = webPersist->SaveURI(sourceURI, nsnull, nsnull, postData, nsnull, destFile);
- NS_ENSURE_SUCCESS(rv, FALSE);
-
- return TRUE;
-#else
- return FALSE;
-#endif
+ GeckoBrowserPersist browserPersist(browser);
+ return browserPersist.SaveURI(uri, filename);
}
gboolean