Revert the electrolysis-plugins-only branch so that the Electrolysis repository can return to its normal (plugins and tabs) state.
electrolysis-not-just-plugins
Revert the electrolysis-plugins-only branch so that the Electrolysis repository can return to its normal (plugins and tabs) state.
--- a/.hgtags
+++ b/.hgtags
@@ -30,8 +30,16 @@ 8a601ed6bc4c7b3d1e35aa9e81f257512d984bd5
d7d64f68423b68a671f623f123e90057ebc49dac UPDATE_PACKAGING_R7
fb32f6e1859c07846a01b4478a7b1678019e0b45 UPDATE_PACKAGING_R7
f817a4378f32b1ad0a7c4b5a9949586dba816da5 FENNEC_M11
5c1e7c779b6edc8ff912001990edc579f80597f4 FENNEC_B1
fe9cc55b8db7f56f7e68a246acba363743854979 UPDATE_PACKAGING_R8
6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-r15462
6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-latest
376b78fc72230aaf2ca4e279a8f4ef1efd4a1d9f GECKO_1_9_2_BASE
+941ad9d7d079246481f365c3cfbfc75a5bbefc94 last-mozilla-central
+2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
+2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
+65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
+65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
+27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
+27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
+a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
--- a/content/base/public/nsIFrameLoader.idl
+++ b/content/base/public/nsIFrameLoader.idl
@@ -36,18 +36,19 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIDocShell;
interface nsIURI;
+interface nsIFrame;
-[scriptable, uuid(d675c531-6bdc-417c-b176-635060105f07)]
+[scriptable, uuid(8f94788d-ec69-4220-971c-0fd68d47b80f)]
interface nsIFrameLoader : nsISupports
{
/**
* Get the docshell from the frame loader.
*/
readonly attribute nsIDocShell docShell;
/**
@@ -69,16 +70,45 @@ interface nsIFrameLoader : nsISupports
void destroy();
/**
* Find out whether the loader's frame is at too great a depth in
* the frame tree. This can be used to decide what operations may
* or may not be allowed on the loader's docshell.
*/
readonly attribute boolean depthTooGreat;
+
+ /**
+ * Updates the position and size of the subdocument loaded by this frameloader.
+ *
+ * @param aIFrame The nsIFrame for the content node that owns this frameloader
+ */
+ [noscript] void updatePositionAndSize(in nsIFrame aIFrame);
+
+ /**
+ * Activate remote frame.
+ * Throws an exception with non-remote frames.
+ */
+ void activateRemoteFrame();
+
+ /**
+ * @see nsIDOMWindowUtils sendMouseEvent.
+ */
+ void sendCrossProcessMouseEvent(in AString aType,
+ in float aX,
+ in float aY,
+ in long aButton,
+ in long aClickCount,
+ in long aModifiers,
+ [optional] in boolean aIgnoreRootScrollFrame);
+
+ /**
+ * Activate event forwarding from client (remote frame) to parent.
+ */
+ void activateFrameEvent(in AString aType, in boolean capture);
};
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
[scriptable, uuid(8f3b12a0-35ae-4e0d-9152-8e0d7e49d446)]
interface nsIFrameLoaderOwner : nsISupports
{
/**
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -138,26 +138,29 @@ CPPSRCS = \
GQI_SRCS = contentbase.gqi
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1
EXTRA_COMPONENTS = $(srcdir)/nsBadCertHandler.js
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
INCLUDES += \
-I$(srcdir)/../../events/src \
-I$(srcdir)/../../xml/content/src \
-I$(srcdir)/../../../layout/xul/base/src \
-I$(srcdir)/../../xul/content/src \
-I$(srcdir)/../../html/content/src \
-I$(srcdir)/../../base/src \
-I$(srcdir)/../../xbl/src \
-I$(srcdir)/../../../layout/generic \
-I$(srcdir)/../../../layout/style \
-I$(srcdir)/../../../dom/base \
-I$(srcdir)/../../xml/document/src \
-I$(topsrcdir)/xpcom/io \
+ -I$(topsrcdir)/dom/ipc \
$(NULL)
DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -18,16 +18,17 @@
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johnny Stenback <jst@netscape.com> (original author)
* Boris Zbarsky <bzbarsky@mit.edu>
+ * Frederic Plourde <frederic.plourde@polymtl.ca>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -38,16 +39,22 @@
*
* ***** END LICENSE BLOCK ***** */
/*
* Class for managing loading of a subframe (creation of the docshell,
* handling of loads in it, recursion-checking).
*/
+#ifdef MOZ_IPC
+# include "base/basictypes.h"
+#endif
+
+#include "prenv.h"
+
#include "nsIDOMHTMLIFrameElement.h"
#include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMWindow.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
#include "nsIContentViewer.h"
#include "nsIDocument.h"
@@ -72,28 +79,44 @@
#include "nsIFrameFrame.h"
#include "nsDOMError.h"
#include "nsPresShellIterator.h"
#include "nsGUIEvent.h"
#include "nsEventDispatcher.h"
#include "nsISHistory.h"
#include "nsISHistoryInternal.h"
#include "nsIDOMNSHTMLDocument.h"
-#include "nsIView.h"
+#include "nsLayoutUtils.h"
#include "nsIURI.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsGkAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsThreadUtils.h"
#include "nsICSSStyleSheet.h"
#include "nsIContentViewer.h"
+#include "nsIView.h"
+
+#ifdef MOZ_WIDGET_GTK2
+#include "mozcontainer.h"
+
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#endif
+
+#ifdef MOZ_IPC
+#include "ContentProcessParent.h"
+#include "TabParent.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+#endif
class nsAsyncDocShellDestroyer : public nsRunnable
{
public:
nsAsyncDocShellDestroyer(nsIDocShell* aDocShell)
: mDocShell(aDocShell)
{
}
@@ -207,21 +230,44 @@ nsFrameLoader::LoadURI(nsIURI* aURI)
}
return rv;
}
nsresult
nsFrameLoader::ReallyStartLoading()
{
NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInDoc());
+
+ nsresult rv = MaybeCreateDocShell();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+#ifdef MOZ_IPC
+ if (mRemoteFrame) {
+ if (!mChildProcess) {
+ TryNewProcess();
+ }
+
+ if (!mChildProcess) {
+ NS_WARNING("Couldn't create child process for iframe.");
+ return NS_ERROR_FAILURE;
+ }
+
+ // FIXME get error codes from child
+ mChildProcess->LoadURL(mURIToLoad);
+ return NS_OK;
+ }
+#endif
+
+ NS_ASSERTION(mDocShell,
+ "MaybeCreateDocShell succeeded with a null mDocShell");
+
// Just to be safe, recheck uri.
- nsresult rv = CheckURILoad(mURIToLoad);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = EnsureDocShell();
+ rv = CheckURILoad(mURIToLoad);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
mDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
// We'll use our principal, not that of the document loaded inside us. This
// is very important; needed to prevent XSS attacks on documents loaded in
@@ -275,30 +321,48 @@ nsFrameLoader::CheckURILoad(nsIURI* aURI
nsresult rv =
secMan->CheckLoadURIWithPrincipal(principal, aURI,
nsIScriptSecurityManager::STANDARD);
if (NS_FAILED(rv)) {
return rv; // We're not
}
// Bail out if this is an infinite recursion scenario
+ rv = MaybeCreateDocShell();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+#ifdef MOZ_IPC
+ if (mRemoteFrame) {
+ return NS_OK;
+ }
+#endif
return CheckForRecursiveLoad(aURI);
}
NS_IMETHODIMP
nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
{
*aDocShell = nsnull;
// If we have an owner, make sure we have a docshell and return
// that. If not, we're most likely in the middle of being torn down,
// then we just return null.
if (mOwnerContent) {
- nsresult rv = EnsureDocShell();
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = MaybeCreateDocShell();
+ if (NS_FAILED(rv))
+ return rv;
+#ifdef MOZ_IPC
+ if (mRemoteFrame) {
+ NS_WARNING("No docshells for remote frames!");
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+#endif
+ NS_ASSERTION(mDocShell,
+ "MaybeCreateDocShell succeeded, but null mDocShell");
}
*aDocShell = mDocShell;
NS_IF_ADDREF(*aDocShell);
return NS_OK;
}
@@ -475,73 +539,88 @@ AllDescendantsOfType(nsIDocShellTreeItem
bool
nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
PRInt32 scrollbarPrefX, PRInt32 scrollbarPrefY,
nsIFrameFrame* frame)
{
nsContentType contentType;
- nsresult rv = EnsureDocShell();
+ nsresult rv = MaybeCreateDocShell();
if (NS_FAILED(rv)) {
return false;
}
- if (!mDocShell)
- return false;
-
- nsCOMPtr<nsIPresShell> presShell;
- mDocShell->GetPresShell(getter_AddRefs(presShell));
- if (presShell)
- return true;
+#ifdef MOZ_IPC
+ if (mRemoteFrame) {
+ contentType = eContentTypeUI;
+ }
+ else
+#endif
+ {
+ if (!mDocShell)
+ return false;
- mDocShell->SetMarginWidth(marginWidth);
- mDocShell->SetMarginHeight(marginHeight);
+ nsCOMPtr<nsIPresShell> presShell;
+ mDocShell->GetPresShell(getter_AddRefs(presShell));
+ if (presShell)
+ return true;
+
+ mDocShell->SetMarginWidth(marginWidth);
+ mDocShell->SetMarginHeight(marginHeight);
- nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell);
- if (sc) {
- sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
- scrollbarPrefX);
- sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
- scrollbarPrefY);
- }
+ nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell);
+ if (sc) {
+ sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
+ scrollbarPrefX);
+ sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
+ scrollbarPrefY);
+ }
- nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
- NS_ASSERTION(treeItem,
- "Found a nsIDocShell that isn't a nsIDocShellTreeItem.");
+ nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
+ NS_ASSERTION(treeItem,
+ "Found a nsIDocShell that isn't a nsIDocShellTreeItem.");
- PRInt32 itemType;
- treeItem->GetItemType(&itemType);
+ PRInt32 itemType;
+ treeItem->GetItemType(&itemType);
- if (itemType == nsIDocShellTreeItem::typeChrome)
- contentType = eContentTypeUI;
- else {
- nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
- treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
- contentType = sameTypeParent ? eContentTypeContentFrame : eContentTypeContent;
+ if (itemType == nsIDocShellTreeItem::typeChrome)
+ contentType = eContentTypeUI;
+ else {
+ nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
+ treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
+ contentType = sameTypeParent ? eContentTypeContentFrame : eContentTypeContent;
+ }
}
nsIView* view = frame->CreateViewAndWidget(contentType);
if (!view)
return false;
+#ifdef MOZ_IPC
+ if (mRemoteFrame) {
+ return ShowRemoteFrame(frame, view);
+ }
+#endif
+
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell);
NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow.");
baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0, 10, 10);
// This is kinda whacky, this "Create()" call doesn't really
// create anything, one starts to wonder why this was named
// "Create"...
baseWindow->Create();
baseWindow->SetVisibility(PR_TRUE);
// Trigger editor re-initialization if midas is turned on in the
// sub-document. This shouldn't be necessary, but given the way our
// editor works, it is. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=284245
+ nsCOMPtr<nsIPresShell> presShell;
mDocShell->GetPresShell(getter_AddRefs(presShell));
if (presShell) {
nsCOMPtr<nsIDOMNSHTMLDocument> doc =
do_QueryInterface(presShell->GetDocument());
if (doc) {
nsAutoString designMode;
doc->GetDesignMode(designMode);
@@ -551,16 +630,77 @@ nsFrameLoader::Show(PRInt32 marginWidth,
doc->SetDesignMode(NS_LITERAL_STRING("on"));
}
}
}
return true;
}
+#ifdef MOZ_IPC
+bool
+nsFrameLoader::ShowRemoteFrame(nsIFrameFrame* frame, nsIView* view)
+{
+ NS_ASSERTION(mRemoteFrame, "ShowRemote only makes sense on remote frames.");
+
+ TryNewProcess();
+ if (!mChildProcess) {
+ NS_ERROR("Couldn't create child process.");
+ return false;
+ }
+
+ nsIWidget* w = view->GetWidget();
+ if (!w) {
+ NS_ERROR("Our view doesn't have a widget. Totally stuffed!");
+ return false;
+ }
+
+ nsIntSize size = GetSubDocumentSize(frame->GetFrame());
+
+#ifdef XP_WIN
+ HWND parentwin =
+ static_cast<HWND>(w->GetNativeData(NS_NATIVE_WINDOW));
+
+ mChildProcess->SendcreateWidget(parentwin);
+#elif defined(MOZ_WIDGET_GTK2)
+ GdkWindow* parent_win =
+ static_cast<GdkWindow*>(w->GetNativeData(NS_NATIVE_WINDOW));
+
+ gpointer user_data = nsnull;
+ gdk_window_get_user_data(parent_win, &user_data);
+
+ MozContainer* parentMozContainer = MOZ_CONTAINER(user_data);
+ GtkContainer* container = GTK_CONTAINER(parentMozContainer);
+
+ // create the socket for the child and add it to our view's widget
+ mRemoteSocket = gtk_socket_new();
+ gtk_widget_set_parent_window(mRemoteSocket, parent_win);
+ gtk_container_add(container, mRemoteSocket);
+ gtk_widget_realize(mRemoteSocket);
+
+ // set the child window's size and position
+ GtkAllocation alloc = { 0, 0, size.width, size.height };
+ gtk_widget_size_allocate(mRemoteSocket, &alloc);
+
+ gtk_widget_show(mRemoteSocket);
+ GdkNativeWindow id = gtk_socket_get_id(GTK_SOCKET(mRemoteSocket));
+ mChildProcess->SendcreateWidget(id);
+#elif defined(XP_MACOSX)
+# warning IMPLEMENT ME
+
+#else
+#error TODO for this platform
+#endif
+
+ mChildProcess->Move(0, 0, size.width, size.height);
+
+ return true;
+}
+#endif
+
void
nsFrameLoader::Hide()
{
if (!mDocShell)
return;
nsCOMPtr<nsIContentViewer> contentViewer;
mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
@@ -854,30 +994,37 @@ nsFrameLoader::Destroy()
doc = mOwnerContent->GetOwnerDoc();
if (doc) {
doc->SetSubDocumentFor(mOwnerContent, nsnull);
}
mOwnerContent = nsnull;
}
+#ifdef MOZ_IPC
+ if (mChildProcess) {
+ mChildProcess->SetOwnerElement(nsnull);
+ PIFrameEmbeddingParent::Send__delete__(mChildProcess);
+ mChildProcess = nsnull;
+ }
+#endif
// Let the tree owner know we're gone.
if (mIsTopLevelContent) {
nsCOMPtr<nsIDocShellTreeItem> ourItem = do_QueryInterface(mDocShell);
if (ourItem) {
nsCOMPtr<nsIDocShellTreeItem> parentItem;
ourItem->GetParent(getter_AddRefs(parentItem));
nsCOMPtr<nsIDocShellTreeOwner> owner = do_GetInterface(parentItem);
if (owner) {
owner->ContentShellRemoved(ourItem);
}
}
}
-
+
// Let our window know that we are gone
nsCOMPtr<nsPIDOMWindow> win_private(do_GetInterface(mDocShell));
if (win_private) {
win_private->SetFrameElementInternal(nsnull);
}
if ((mNeedsAsyncDestroy || !doc ||
NS_FAILED(doc->FinalizeFrameLoader(this))) && mDocShell) {
@@ -898,24 +1045,74 @@ nsFrameLoader::Destroy()
NS_IMETHODIMP
nsFrameLoader::GetDepthTooGreat(PRBool* aDepthTooGreat)
{
*aDepthTooGreat = mDepthTooGreat;
return NS_OK;
}
+#ifdef MOZ_IPC
+bool
+nsFrameLoader::ShouldUseRemoteProcess()
+{
+ // Check for *disabled* multi-process first: environment, prefs, attribute
+ // Then check for *enabled* multi-process pref: attribute, prefs
+ // Default is not-remote.
+
+ if (PR_GetEnv("MOZ_DISABLE_OOP_TABS")) {
+ return false;
+ }
+
+ PRBool remoteDisabled = nsContentUtils::GetBoolPref("dom.ipc.tabs.disabled",
+ PR_FALSE);
+ if (remoteDisabled) {
+ return false;
+ }
+
+ static nsIAtom* const *const remoteValues[] = {
+ &nsGkAtoms::_false,
+ &nsGkAtoms::_true,
+ nsnull
+ };
+
+ switch (mOwnerContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::Remote,
+ remoteValues, eCaseMatters)) {
+ case 0:
+ return false;
+ case 1:
+ return true;
+ }
+
+ PRBool remoteEnabled = nsContentUtils::GetBoolPref("dom.ipc.tabs.enabled",
+ PR_FALSE);
+ return (bool) remoteEnabled;
+}
+#endif
+
nsresult
-nsFrameLoader::EnsureDocShell()
+nsFrameLoader::MaybeCreateDocShell()
{
if (mDocShell) {
return NS_OK;
}
+#ifdef MOZ_IPC
+ if (mRemoteFrame) {
+ return NS_OK;
+ }
+#endif
NS_ENSURE_STATE(!mDestroyCalled);
+#ifdef MOZ_IPC
+ if (ShouldUseRemoteProcess()) {
+ mRemoteFrame = true;
+ return NS_OK;
+ }
+#endif
+
// Get our parent docshell off the document of mOwnerContent
// XXXbz this is such a total hack.... We really need to have a
// better setup for doing this.
nsIDocument* doc = mOwnerContent->GetOwnerDoc();
if (!doc || !(doc->IsStaticDocument() || mOwnerContent->IsInDoc())) {
return NS_ERROR_UNEXPECTED;
}
@@ -930,16 +1127,17 @@ nsFrameLoader::EnsureDocShell()
// Create the docshell...
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
// Get the frame name and tell the docshell about it.
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
+
nsAutoString frameName;
PRInt32 namespaceID = mOwnerContent->GetNameSpaceID();
if (namespaceID == kNameSpaceID_XHTML && !mOwnerContent->IsInHTMLDocument()) {
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName);
} else {
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName);
// XXX if no NAME then use ID, after a transition period this will be
@@ -1036,19 +1234,30 @@ nsFrameLoader::GetURL(nsString& aURI)
} else {
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, aURI);
}
}
nsresult
nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
{
+ nsresult rv;
+
mDepthTooGreat = PR_FALSE;
- nsresult rv = EnsureDocShell();
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = MaybeCreateDocShell();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+#ifdef MOZ_IPC
+ NS_ASSERTION(!mRemoteFrame,
+ "Shouldn't call CheckForRecursiveLoad on remote frames.");
+#endif
+ if (!mDocShell) {
+ return NS_ERROR_FAILURE;
+ }
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
NS_ASSERTION(treeItem, "docshell must be a treeitem!");
PRInt32 ourType;
rv = treeItem->GetItemType(&ourType);
if (NS_SUCCEEDED(rv) && ourType != nsIDocShellTreeItem::typeContent) {
// No need to do recursion-protection here XXXbz why not?? Do we really
@@ -1124,21 +1333,196 @@ nsFrameLoader::CheckForRecursiveLoad(nsI
nsCOMPtr<nsIDocShellTreeItem> temp;
temp.swap(parentAsItem);
temp->GetSameTypeParent(getter_AddRefs(parentAsItem));
}
return NS_OK;
}
+NS_IMETHODIMP
+nsFrameLoader::UpdatePositionAndSize(nsIFrame *aIFrame)
+{
+#ifdef MOZ_IPC
+ if (mRemoteFrame) {
+ if (mChildProcess) {
+ nsIntSize size = GetSubDocumentSize(aIFrame);
+
+#ifdef MOZ_WIDGET_GTK2
+ if (mRemoteSocket) {
+ GtkAllocation alloc = {0, 0, size.width, size.height };
+ gtk_widget_size_allocate(mRemoteSocket, &alloc);
+ }
+#endif
+
+ mChildProcess->Move(0, 0, size.width, size.height);
+ }
+ return NS_OK;
+ }
+#endif
+ return UpdateBaseWindowPositionAndSize(aIFrame);
+}
+
+nsresult
+nsFrameLoader::UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame)
+{
+ nsCOMPtr<nsIDocShell> docShell;
+ GetDocShell(getter_AddRefs(docShell));
+ nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell));
+
+ // resize the sub document
+ if (baseWindow) {
+ PRInt32 x = 0;
+ PRInt32 y = 0;
+
+ nsWeakFrame weakFrame(aIFrame);
+
+ baseWindow->GetPositionAndSize(&x, &y, nsnull, nsnull);
+
+ if (!weakFrame.IsAlive()) {
+ // GetPositionAndSize() killed us
+ return NS_OK;
+ }
+
+ nsIntSize size = GetSubDocumentSize(aIFrame);
+
+ baseWindow->SetPositionAndSize(x, y, size.width, size.height, PR_FALSE);
+ }
+
+ return NS_OK;
+}
+
+nsIntSize
+nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
+{
+ nsAutoDisableGetUsedXAssertions disableAssert;
+ nsSize docSizeAppUnits;
+ nsPresContext* presContext = aIFrame->PresContext();
+ nsCOMPtr<nsIDOMHTMLFrameElement> frameElem =
+ do_QueryInterface(aIFrame->GetContent());
+ if (frameElem) {
+ docSizeAppUnits = aIFrame->GetSize();
+ } else {
+ docSizeAppUnits = aIFrame->GetContentRect().Size();
+ }
+ return nsIntSize(presContext->AppUnitsToDevPixels(docSizeAppUnits.width),
+ presContext->AppUnitsToDevPixels(docSizeAppUnits.height));
+}
+
+#ifdef MOZ_IPC
+bool
+nsFrameLoader::TryNewProcess()
+{
+ NS_ASSERTION(!mChildProcess, "TryNewProcess called with a process already?");
+
+ nsIDocument* doc = mOwnerContent->GetDocument();
+ if (!doc) {
+ return false;
+ }
+
+ if (doc->GetDisplayDocument()) {
+ // Don't allow subframe loads in external reference documents
+ return false;
+ }
+
+ nsCOMPtr<nsIWebNavigation> parentAsWebNav =
+ do_GetInterface(doc->GetScriptGlobalObject());
+
+ if (!parentAsWebNav) {
+ return false;
+ }
+
+ nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsWebNav));
+
+ PRInt32 parentType;
+ parentAsItem->GetItemType(&parentType);
+
+ if (parentType != nsIDocShellTreeItem::typeChrome) {
+ return false;
+ }
+
+ if (!mOwnerContent->IsXUL()) {
+ return false;
+ }
+
+ nsAutoString value;
+ mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
+
+ if (!value.LowerCaseEqualsLiteral("content") &&
+ !StringBeginsWith(value, NS_LITERAL_STRING("content-"),
+ nsCaseInsensitiveStringComparator())) {
+ return false;
+ }
+
+ mChildProcess = ContentProcessParent::GetSingleton()->CreateTab();
+ if (mChildProcess) {
+ nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
+ mChildProcess->SetOwnerElement(element);
+ }
+ return true;
+}
+#endif
+
+#ifdef MOZ_IPC
+mozilla::dom::PIFrameEmbeddingParent*
+nsFrameLoader::GetChildProcess()
+{
+ return mChildProcess;
+}
+#endif
+
+NS_IMETHODIMP
+nsFrameLoader::ActivateRemoteFrame() {
+#ifdef MOZ_IPC
+ if (mChildProcess) {
+ mChildProcess->Activate();
+ return NS_OK;
+ }
+#endif
+ return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+nsFrameLoader::SendCrossProcessMouseEvent(const nsAString& aType,
+ float aX,
+ float aY,
+ PRInt32 aButton,
+ PRInt32 aClickCount,
+ PRInt32 aModifiers,
+ PRBool aIgnoreRootScrollFrame)
+{
+#ifdef MOZ_IPC
+ if (mChildProcess) {
+ mChildProcess->SendMouseEvent(aType, aX, aY, aButton,
+ aClickCount, aModifiers,
+ aIgnoreRootScrollFrame);
+ return NS_OK;
+ }
+#endif
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsFrameLoader::ActivateFrameEvent(const nsAString& aType,
+ PRBool aCapture)
+{
+#ifdef MOZ_IPC
+ if (mChildProcess) {
+ mChildProcess->SendactivateFrameEvent(nsString(aType), aCapture);
+ return NS_OK;
+ }
+#endif
+ return NS_ERROR_FAILURE;
+}
+
nsresult
nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
{
nsFrameLoader* dest = static_cast<nsFrameLoader*>(aDest);
- dest->EnsureDocShell();
+ dest->MaybeCreateDocShell();
NS_ENSURE_STATE(dest->mDocShell);
nsCOMPtr<nsIDOMDocument> dummy = do_GetInterface(dest->mDocShell);
nsCOMPtr<nsIContentViewer> viewer;
dest->mDocShell->GetContentViewer(getter_AddRefs(viewer));
NS_ENSURE_STATE(viewer);
nsCOMPtr<nsIDocShell> origDocShell;
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -42,32 +42,55 @@
*/
#ifndef nsFrameLoader_h_
#define nsFrameLoader_h_
#include "nsIDocShell.h"
#include "nsStringFwd.h"
#include "nsIFrameLoader.h"
+#include "nsSize.h"
#include "nsIURI.h"
+#include "nsAutoPtr.h"
class nsIContent;
class nsIURI;
class nsIFrameFrame;
+class nsIView;
+
+#ifdef MOZ_IPC
+namespace mozilla {
+ namespace dom {
+ class TabParent;
+ class PIFrameEmbeddingParent;
+ }
+}
+
+#ifdef MOZ_WIDGET_GTK2
+typedef struct _GtkWidget GtkWidget;
+#endif
+#endif
class nsFrameLoader : public nsIFrameLoader
{
protected:
nsFrameLoader(nsIContent *aOwner) :
mOwnerContent(aOwner),
mDepthTooGreat(PR_FALSE),
mIsTopLevelContent(PR_FALSE),
mDestroyCalled(PR_FALSE),
mNeedsAsyncDestroy(PR_FALSE),
mInSwap(PR_FALSE)
+#ifdef MOZ_IPC
+ , mRemoteFrame(false)
+ , mChildProcess(nsnull)
+#ifdef MOZ_WIDGET_GTK2
+ , mRemoteSocket(nsnull)
+#endif
+#endif
{}
public:
~nsFrameLoader() {
mNeedsAsyncDestroy = PR_TRUE;
nsFrameLoader::Destroy();
}
@@ -101,25 +124,64 @@ public:
nsresult CloneForStatic(nsIFrameLoader* aOriginal);
// The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation. A
// frame loader owner needs to call this, and pass in the two references to
// nsRefPtrs for frame loaders that need to be swapped.
nsresult SwapWithOtherLoader(nsFrameLoader* aOther,
nsRefPtr<nsFrameLoader>& aFirstToSwap,
nsRefPtr<nsFrameLoader>& aSecondToSwap);
+
+#ifdef MOZ_IPC
+ mozilla::dom::PIFrameEmbeddingParent* GetChildProcess();
+#endif
+
private:
- NS_HIDDEN_(nsresult) EnsureDocShell();
- NS_HIDDEN_(void) GetURL(nsString& aURL);
+#ifdef MOZ_IPC
+ bool ShouldUseRemoteProcess();
+#endif
+
+ /**
+ * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
+ * initialize mDocShell.
+ */
+ nsresult MaybeCreateDocShell();
+ void GetURL(nsString& aURL);
+
+ // Properly retrieves documentSize of any subdocument type.
+ NS_HIDDEN_(nsIntSize) GetSubDocumentSize(const nsIFrame *aIFrame);
+
+ // Updates the subdocument position and size. This gets called only
+ // when we have our own in-process DocShell.
+ NS_HIDDEN_(nsresult) UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame);
nsresult CheckURILoad(nsIURI* aURI);
+#ifdef MOZ_IPC
+ // True means new process started; nothing else to do
+ bool TryNewProcess();
+
+ // Do the hookup necessary to actually show a remote frame once the view and
+ // widget are available.
+ bool ShowRemoteFrame(nsIFrameFrame* frame, nsIView* view);
+#endif
+
nsCOMPtr<nsIDocShell> mDocShell;
nsCOMPtr<nsIURI> mURIToLoad;
nsIContent *mOwnerContent; // WEAK
PRPackedBool mDepthTooGreat : 1;
PRPackedBool mIsTopLevelContent : 1;
PRPackedBool mDestroyCalled : 1;
PRPackedBool mNeedsAsyncDestroy : 1;
PRPackedBool mInSwap : 1;
+
+#ifdef MOZ_IPC
+ bool mRemoteFrame;
+ // XXX leaking
+ mozilla::dom::TabParent* mChildProcess;
+
+#ifdef MOZ_WIDGET_GTK2
+ GtkWidget* mRemoteSocket;
+#endif
+#endif
};
#endif
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1693,16 +1693,19 @@ GK_ATOM(Taiwanese, "zh-TW")
GK_ATOM(HongKongChinese, "zh-HK")
GK_ATOM(Unicode, "x-unicode")
// Names for editor transactions
GK_ATOM(TypingTxnName, "Typing")
GK_ATOM(IMETxnName, "IME")
GK_ATOM(DeleteTxnName, "Deleting")
+// IPC stuff
+GK_ATOM(Remote, "remote")
+
// Names for system metrics
GK_ATOM(scrollbar_start_backward, "scrollbar-start-backward")
GK_ATOM(scrollbar_start_forward, "scrollbar-start-forward")
GK_ATOM(scrollbar_end_backward, "scrollbar-end-backward")
GK_ATOM(scrollbar_end_forward, "scrollbar-end-forward")
GK_ATOM(scrollbar_thumb_proportional, "scrollbar-thumb-proportional")
GK_ATOM(images_in_menus, "images-in-menus")
GK_ATOM(images_in_buttons, "images-in-buttons")
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -481,16 +481,25 @@ public:
NS_IMETHOD_(nsEvent*) GetInternalNSEvent()
{
return mInner->GetInternalNSEvent();
}
NS_IMETHOD SetTrusted(PRBool aTrusted)
{
return mInner->SetTrusted(aTrusted);
}
+ virtual void Serialize(IPC::Message* aMsg,
+ PRBool aSerializeInterfaceType)
+ {
+ mInner->Serialize(aMsg, aSerializeInterfaceType);
+ }
+ virtual PRBool Deserialize(const IPC::Message* aMsg, void** aIter)
+ {
+ return mInner->Deserialize(aMsg, aIter);
+ }
protected:
// Use nsDOMProgressEvent so that we can forward
// most of the method calls easily.
nsRefPtr<nsDOMProgressEvent> mInner;
PRUint64 mCurProgress;
PRUint64 mMaxProgress;
};
new file mode 100644
--- /dev/null
+++ b/content/canvas/public/DocumentRendererChild.h
@@ -0,0 +1,68 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Electrolysis.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_dom_DocumentRendererChild
+#define mozilla_dom_DocumentRendererChild
+
+#include "mozilla/ipc/PDocumentRendererChild.h"
+#include "nsICanvasRenderingContextInternal.h"
+#include "nsString.h"
+#include "gfxContext.h"
+
+class nsIDOMWindow;
+
+namespace mozilla {
+namespace ipc {
+
+class DocumentRendererChild : public PDocumentRendererChild
+{
+public:
+ DocumentRendererChild();
+ virtual ~DocumentRendererChild();
+
+ bool RenderDocument(nsIDOMWindow *window, const PRInt32& x, const PRInt32& y, const PRInt32& w, const PRInt32& h,
+ const nsString& bgcolor, const PRUint32& flags, const PRBool& flush,
+ PRUint32& _width, PRUint32& _height, nsCString& data);
+
+private:
+
+ DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererChild);
+};
+
+}
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/content/canvas/public/DocumentRendererParent.h
@@ -0,0 +1,73 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Electrolysis.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_dom_DocumentRendererParent
+#define mozilla_dom_DocumentRendererParent
+
+#include "mozilla/ipc/PDocumentRendererParent.h"
+#include "nsICanvasRenderingContextInternal.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "gfxContext.h"
+
+namespace mozilla {
+namespace ipc {
+
+class DocumentRendererParent : public PDocumentRendererParent
+{
+public:
+ DocumentRendererParent();
+ virtual ~DocumentRendererParent();
+
+ void SetCanvasContext(nsICanvasRenderingContextInternal* aCanvas,
+ gfxContext* ctx);
+ void DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight,
+ const nsCString& aData);
+
+ virtual bool Recv__delete__(const PRUint32& w, const PRUint32& h,
+ const nsCString& data);
+
+private:
+ nsCOMPtr<nsICanvasRenderingContextInternal> mCanvas;
+ nsRefPtr<gfxContext> mCanvasContext;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererParent);
+};
+
+}
+}
+
+#endif
--- a/content/canvas/public/Makefile.in
+++ b/content/canvas/public/Makefile.in
@@ -40,19 +40,26 @@ topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = content
XPIDL_MODULE = content_canvas
+EXPORTS_NAMESPACES = mozilla/ipc
+
EXPORTS = \
nsICanvasRenderingContextInternal.h \
nsICanvasElement.h \
WebGLArray.h \
$(NULL)
+EXPORTS_mozilla/ipc = \
+ DocumentRendererChild.h \
+ DocumentRendererParent.h \
+ $(NULL)
+
XPIDLSRCS = \
nsICanvasGLPrivate.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk
--- a/content/canvas/public/nsICanvasRenderingContextInternal.h
+++ b/content/canvas/public/nsICanvasRenderingContextInternal.h
@@ -82,14 +82,17 @@ public:
// return the surface. Otherwise returns an error.
NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0;
// If this context is opaque, the backing store of the canvas should
// be created as opaque; all compositing operators should assume the
// dst alpha is always 1.0. If this is never called, the context
// defaults to false (not opaque).
NS_IMETHOD SetIsOpaque(PRBool isOpaque) = 0;
+
+ // Redraw the dirty rectangle of this canvas.
+ NS_IMETHOD Redraw(const gfxRect &dirty) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,
NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
#endif /* nsICanvasRenderingContextInternal_h___ */
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/DocumentRendererChild.cpp
@@ -0,0 +1,147 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Electrolysis.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "base/basictypes.h"
+
+#include "gfxImageSurface.h"
+#include "gfxPattern.h"
+#include "nsPIDOMWindow.h"
+#include "nsIDOMWindow.h"
+#include "nsIDOMDocument.h"
+#include "nsIDocShellTreeNode.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsIDocument.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsICSSParser.h"
+#include "nsPresContext.h"
+#include "nsCOMPtr.h"
+#include "nsColor.h"
+#include "gfxContext.h"
+#include "gfxImageSurface.h"
+#include "nsLayoutUtils.h"
+
+#include "mozilla/ipc/DocumentRendererChild.h"
+
+using namespace mozilla::ipc;
+
+DocumentRendererChild::DocumentRendererChild()
+{}
+
+DocumentRendererChild::~DocumentRendererChild()
+{}
+
+static void
+FlushLayoutForTree(nsIDOMWindow* aWindow)
+{
+ nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
+ if (!piWin)
+ return;
+
+ // Note that because FlushPendingNotifications flushes parents, this
+ // is O(N^2) in docshell tree depth. However, the docshell tree is
+ // usually pretty shallow.
+
+ nsCOMPtr<nsIDOMDocument> domDoc;
+ aWindow->GetDocument(getter_AddRefs(domDoc));
+ nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+ if (doc) {
+ doc->FlushPendingNotifications(Flush_Layout);
+ }
+
+ nsCOMPtr<nsIDocShellTreeNode> node =
+ do_QueryInterface(piWin->GetDocShell());
+ if (node) {
+ PRInt32 i = 0, i_end;
+ node->GetChildCount(&i_end);
+ for (; i < i_end; ++i) {
+ nsCOMPtr<nsIDocShellTreeItem> item;
+ node->GetChildAt(i, getter_AddRefs(item));
+ nsCOMPtr<nsIDOMWindow> win = do_GetInterface(item);
+ if (win) {
+ FlushLayoutForTree(win);
+ }
+ }
+ }
+}
+
+bool
+DocumentRendererChild::RenderDocument(nsIDOMWindow *window, const PRInt32& x, const PRInt32& y, const PRInt32& w, const PRInt32& h,
+ const nsString& aBGColor, const PRUint32& flags, const PRBool& flush,
+ PRUint32& _width, PRUint32& _height, nsCString& data)
+{
+ if (flush)
+ FlushLayoutForTree(window);
+
+ nsCOMPtr<nsPresContext> presContext;
+ nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
+ if (win) {
+ nsIDocShell* docshell = win->GetDocShell();
+ if (docshell) {
+ docshell->GetPresContext(getter_AddRefs(presContext));
+ }
+ }
+ if (!presContext)
+ return false;
+
+ nscolor bgColor;
+ nsCOMPtr<nsICSSParser> parser = do_CreateInstance("@mozilla.org/content/css-parser;1");
+ nsresult rv = parser->ParseColorString(PromiseFlatString(aBGColor),
+ nsnull, 0, &bgColor);
+ if (NS_FAILED(rv))
+ return false;
+
+ nsIPresShell* presShell = presContext->PresShell();
+
+ nsRect r(x, y, w, h);
+
+ _width = nsPresContext::AppUnitsToIntCSSPixels(w);
+ _height = nsPresContext::AppUnitsToIntCSSPixels(h);
+
+ // Draw directly into the output array.
+ data.SetLength(_width * _height * 4);
+ nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(reinterpret_cast<PRUint8*>(const_cast<char*>(data.get())),
+ gfxIntSize(_width, _height),
+ 4 * _width, gfxASurface::ImageFormatARGB32);
+ nsRefPtr<gfxContext> ctx = new gfxContext(surf);
+
+ PRBool oldDisableValue = nsLayoutUtils::sDisableGetUsedXAssertions;
+ nsLayoutUtils::sDisableGetUsedXAssertions = oldDisableValue || !flush;
+ presShell->RenderDocument(r, flags, bgColor, ctx);
+ nsLayoutUtils::sDisableGetUsedXAssertions = oldDisableValue;
+
+ return true;
+}
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/DocumentRendererParent.cpp
@@ -0,0 +1,85 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Electrolysis.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/ipc/DocumentRendererParent.h"
+#include "gfxImageSurface.h"
+#include "gfxPattern.h"
+
+using namespace mozilla::ipc;
+
+DocumentRendererParent::DocumentRendererParent()
+{}
+
+DocumentRendererParent::~DocumentRendererParent()
+{}
+
+void DocumentRendererParent::SetCanvasContext(nsICanvasRenderingContextInternal* aCanvas,
+ gfxContext* ctx)
+{
+ mCanvas = aCanvas;
+ mCanvasContext = ctx;
+}
+
+void DocumentRendererParent::DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight,
+ const nsCString& aData)
+{
+ if (!mCanvas || !mCanvasContext)
+ return;
+
+ nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(reinterpret_cast<PRUint8*>(const_cast<char*>(aData.Data())),
+ gfxIntSize(aWidth, aHeight),
+ aWidth * 4,
+ gfxASurface::ImageFormatARGB32);
+ nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
+
+ mCanvasContext->NewPath();
+ mCanvasContext->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, aWidth, aHeight), pat);
+ mCanvasContext->Fill();
+
+ // get rid of the pattern surface ref, because aData is very likely to go away shortly
+ mCanvasContext->SetColor(gfxRGBA(1,1,1,1));
+
+ gfxRect damageRect = mCanvasContext->UserToDevice(gfxRect(0, 0, aWidth, aHeight));
+ mCanvas->Redraw(damageRect);
+}
+
+bool
+DocumentRendererParent::Recv__delete__(const PRUint32& w, const PRUint32& h,
+ const nsCString& data)
+{
+ DrawToCanvas(w, h, data);
+ return true;
+}
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -48,16 +48,23 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \
CanvasUtils.cpp \
nsCanvasRenderingContext2D.cpp \
$(NULL)
+ifdef MOZ_IPC
+CPPSRCS += \
+ DocumentRendererParent.cpp \
+ DocumentRendererChild.cpp \
+ $(NULL)
+endif
+
# Canvas 3D Pieces
ifdef MOZ_WEBGL
ifeq (1_1,$(MOZ_X11)_$(NS_OSSO))
WEBGL_PLATFORM = EGL
DEFINES += -DUSE_GLES2
endif
@@ -102,16 +109,17 @@ else
CPPSRCS += WebGLContextNotSupported.cpp
endif
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
INCLUDES += \
-I$(srcdir)/../../../layout/xul/base/src \
-I$(srcdir)/../../../layout/style \
-I$(srcdir)/../../../layout/generic \
-I$(srcdir)/../../base/src \
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -240,16 +240,17 @@ public:
NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, PRInt32 width, PRInt32 height)
{ return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter f);
NS_IMETHOD GetInputStream(const char* aMimeType,
const PRUnichar* aEncoderOptions,
nsIInputStream **aStream);
NS_IMETHOD GetThebesSurface(gfxASurface **surface);
NS_IMETHOD SetIsOpaque(PRBool b) { return NS_OK; };
+ NS_IMETHOD Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; }
protected:
GLES20Wrap *gl;
nsICanvasElement* mCanvasElement;
nsGLPbuffer *mGLPbuffer;
PRInt32 mWidth, mHeight;
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -32,16 +32,22 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+# include "base/basictypes.h"
+#endif
+
+#include "nsIDOMXULElement.h"
+
#ifdef _MSC_VER
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#include "prmem.h"
#include "nsIServiceManager.h"
@@ -98,20 +104,30 @@
#include "gfxImageSurface.h"
#include "gfxPlatform.h"
#include "gfxFont.h"
#include "gfxTextRunCache.h"
#include "gfxBlur.h"
#include "nsFrameManager.h"
+#include "nsFrameLoader.h"
+
#include "nsBidiPresUtils.h"
#include "CanvasUtils.h"
+#ifdef MOZ_IPC
+# include "mozilla/ipc/PDocumentRendererParent.h"
+# include "mozilla/dom/PIFrameEmbeddingParent.h"
+# include "mozilla/ipc/DocumentRendererParent.h"
+// windows.h (included by chromium code) defines this, in its infinite wisdom
+# undef DrawText
+#endif
+
using namespace mozilla;
#ifndef M_PI
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#endif
/* Float validation stuff */
@@ -306,29 +322,29 @@ class nsCanvasRenderingContext2D :
public nsIDOMCanvasRenderingContext2D,
public nsICanvasRenderingContextInternal
{
public:
nsCanvasRenderingContext2D();
virtual ~nsCanvasRenderingContext2D();
nsresult Redraw();
- // this rect is in CSS pixels
- nsresult Redraw(const gfxRect& r);
// nsICanvasRenderingContextInternal
NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, PRInt32 width, PRInt32 height);
NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter);
NS_IMETHOD GetInputStream(const char* aMimeType,
const PRUnichar* aEncoderOptions,
nsIInputStream **aStream);
NS_IMETHOD GetThebesSurface(gfxASurface **surface);
NS_IMETHOD SetIsOpaque(PRBool isOpaque);
+ // this rect is in CSS pixels
+ NS_IMETHOD Redraw(const gfxRect &r);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIDOMCanvasRenderingContext2D interface
NS_DECL_NSIDOMCANVASRENDERINGCONTEXT2D
enum Style {
@@ -843,17 +859,17 @@ nsCanvasRenderingContext2D::Redraw()
if (mIsEntireFrameInvalid)
return NS_OK;
mIsEntireFrameInvalid = PR_TRUE;
return mCanvasElement->InvalidateFrame();
}
-nsresult
+NS_IMETHODIMP
nsCanvasRenderingContext2D::Redraw(const gfxRect& r)
{
if (!mCanvasElement)
return NS_OK;
if (mIsEntireFrameInvalid)
return NS_OK;
@@ -3310,16 +3326,93 @@ nsCanvasRenderingContext2D::DrawWindow(n
// space.
gfxRect damageRect = mThebes->UserToDevice(gfxRect(0, 0, aW, aH));
Redraw(damageRect);
return rv;
}
+NS_IMETHODIMP
+nsCanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* aElem, float aX, float aY,
+ float aW, float aH,
+ const nsAString& aBGColor,
+ PRUint32 flags)
+{
+ NS_ENSURE_ARG(aElem != nsnull);
+
+ // We can't allow web apps to call this until we fix at least the
+ // following potential security issues:
+ // -- rendering cross-domain IFRAMEs and then extracting the results
+ // -- rendering the user's theme and then extracting the results
+ // -- rendering native anonymous content (e.g., file input paths;
+ // scrollbars should be allowed)
+ if (!nsContentUtils::IsCallerTrustedForRead()) {
+ // not permitted to use DrawWindow
+ // XXX ERRMSG we need to report an error to developers here! (bug 329026)
+ return NS_ERROR_DOM_SECURITY_ERR;
+ }
+
+ nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aElem);
+ if (!loaderOwner)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
+ if (!frameloader)
+ return NS_ERROR_FAILURE;
+
+#ifdef MOZ_IPC
+ mozilla::dom::PIFrameEmbeddingParent *child = frameloader->GetChildProcess();
+ if (!child) {
+ nsCOMPtr<nsIDOMWindow> window =
+ do_GetInterface(frameloader->GetExistingDocShell());
+ if (!window)
+ return NS_ERROR_FAILURE;
+
+ return DrawWindow(window, aX, aY, aW, aH, aBGColor, flags);
+ }
+
+ // protect against too-large surfaces that will cause allocation
+ // or overflow issues
+ if (!gfxASurface::CheckSurfaceSize(gfxIntSize(aW, aH), 0xffff))
+ return NS_ERROR_FAILURE;
+
+ PRBool flush =
+ (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH) == 0;
+
+ PRUint32 renderDocFlags = nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+ if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
+ renderDocFlags |= nsIPresShell::RENDER_CARET;
+ }
+ if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
+ renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+ }
+
+ PRInt32 x = nsPresContext::CSSPixelsToAppUnits(aX),
+ y = nsPresContext::CSSPixelsToAppUnits(aY),
+ w = nsPresContext::CSSPixelsToAppUnits(aW),
+ h = nsPresContext::CSSPixelsToAppUnits(aH);
+
+ mozilla::ipc::PDocumentRendererParent *pdocrender =
+ child->SendPDocumentRendererConstructor(x, y, w, h, nsString(aBGColor), renderDocFlags, flush);
+ mozilla::ipc::DocumentRendererParent *docrender = static_cast<mozilla::ipc::DocumentRendererParent *>(pdocrender);
+
+ docrender->SetCanvasContext(this, mThebes);
+
+ return NS_OK;
+#else
+ nsCOMPtr<nsIDOMWindow> window =
+ do_GetInterface(frameloader->GetExistingDocShell());
+ if (!window)
+ return NS_ERROR_FAILURE;
+
+ return DrawWindow(window, aX, aY, aW, aH, aBGColor, flags);
+#endif
+}
+
//
// device pixel getting/setting
//
extern "C" {
#include "jstypes.h"
JS_FRIEND_API(JSBool)
js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count,
JSUint8 *dest);
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -36,36 +36,42 @@
* ***** END LICENSE BLOCK ***** */
#ifndef nsIPrivateDOMEvent_h__
#define nsIPrivateDOMEvent_h__
#include "nsISupports.h"
#define NS_IPRIVATEDOMEVENT_IID \
-{ 0x1da4c501, 0xe87e, 0x49b4, \
- { 0xb0, 0x49, 0xdf, 0x9f, 0xc3, 0x6b, 0x56, 0xd4 } }
+{ 0x26f5f0e9, 0x2960, 0x4405, \
+ { 0xa1, 0x7e, 0xd8, 0x9f, 0xb0, 0xd9, 0x4c, 0x71 } }
class nsIDOMEventTarget;
class nsIDOMEvent;
class nsEvent;
class nsCommandEvent;
class nsPresContext;
class nsInvalidateRequestList;
+namespace IPC {
+class Message;
+}
class nsIPrivateDOMEvent : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATEDOMEVENT_IID)
NS_IMETHOD DuplicatePrivateData() = 0;
NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget) = 0;
NS_IMETHOD_(PRBool) IsDispatchStopped() = 0;
NS_IMETHOD_(nsEvent*) GetInternalNSEvent() = 0;
NS_IMETHOD SetTrusted(PRBool aTrusted) = 0;
+ virtual void Serialize(IPC::Message* aMsg,
+ PRBool aSerializeInterfaceType) = 0;
+ virtual PRBool Deserialize(const IPC::Message* aMsg, void** aIter) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateDOMEvent, NS_IPRIVATEDOMEVENT_IID)
nsresult
NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
nsresult
NS_NewDOMDataContainerEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -81,19 +81,21 @@ CPPSRCS = \
nsDOMSimpleGestureEvent.cpp \
nsDOMEventTargetHelper.cpp \
nsDOMScrollAreaEvent.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
-LOCAL_INCLUDES = \
+LOCAL_INCLUDES += \
-I$(srcdir)/../../base/src \
-I$(srcdir)/../../html/base/src \
-I$(srcdir)/../../xul/content/src \
-I$(srcdir)/../../xml/content/src \
-I$(srcdir)/../../../dom/base \
-I$(srcdir)/../../../layout/generic \
-I$(srcdir)/../../../layout/xul/base/src \
-I$(srcdir)/../../../layout/xul/base/src/tree/src \
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -32,16 +32,20 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+#include "base/basictypes.h"
+#include "IPC/IPCMessageUtils.h"
+#endif
#include "nsCOMPtr.h"
#include "nsDOMEvent.h"
#include "nsEventStateManager.h"
#include "nsIFrame.h"
#include "nsIContent.h"
#include "nsIPresShell.h"
#include "nsIDocument.h"
#include "nsIPrivateCompositionEvent.h"
@@ -1528,16 +1532,71 @@ nsDOMEvent::ReportWrongPropertyAccessWar
NS_IMETHODIMP
nsDOMEvent::GetPreventDefault(PRBool* aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = mEvent && (mEvent->flags & NS_EVENT_FLAG_NO_DEFAULT);
return NS_OK;
}
+void
+nsDOMEvent::Serialize(IPC::Message* aMsg, PRBool aSerializeInterfaceType)
+{
+#ifdef MOZ_IPC
+ if (aSerializeInterfaceType) {
+ IPC::WriteParam(aMsg, NS_LITERAL_STRING("event"));
+ }
+
+ nsString type;
+ GetType(type);
+ IPC::WriteParam(aMsg, type);
+
+ PRBool bubbles = PR_FALSE;
+ GetBubbles(&bubbles);
+ IPC::WriteParam(aMsg, bubbles);
+
+ PRBool cancelable = PR_FALSE;
+ GetCancelable(&cancelable);
+ IPC::WriteParam(aMsg, cancelable);
+
+ PRBool trusted = PR_FALSE;
+ GetIsTrusted(&trusted);
+ IPC::WriteParam(aMsg, trusted);
+
+ // No timestamp serialization for now!
+#endif
+}
+
+PRBool
+nsDOMEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
+{
+#ifdef MOZ_IPC
+ nsString type;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &type), PR_FALSE);
+
+ PRBool bubbles = PR_FALSE;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &bubbles), PR_FALSE);
+
+ PRBool cancelable = PR_FALSE;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &cancelable), PR_FALSE);
+
+ PRBool trusted = PR_FALSE;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &trusted), PR_FALSE);
+
+ nsresult rv = InitEvent(type, bubbles, cancelable);
+ NS_ENSURE_SUCCESS(rv, PR_FALSE);
+ SetTrusted(trusted);
+
+ return PR_TRUE;
+#else
+ return PR_FALSE;
+#endif
+}
+
+
nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsEvent *aEvent)
{
nsDOMEvent* it = new nsDOMEvent(aPresContext, aEvent);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -188,16 +188,19 @@ public:
// nsIPrivateDOMEvent interface
NS_IMETHOD DuplicatePrivateData();
NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget);
NS_IMETHOD_(PRBool) IsDispatchStopped();
NS_IMETHOD_(nsEvent*) GetInternalNSEvent();
NS_IMETHOD SetTrusted(PRBool aTrusted);
+ virtual void Serialize(IPC::Message* aMsg, PRBool aSerializeInterfaceType);
+ virtual PRBool Deserialize(const IPC::Message* aMsg, void** aIter);
+
static PopupControlState GetEventPopupControlState(nsEvent *aEvent);
static void PopupAllowedEventsChanged();
static void Shutdown();
static const char* GetEventName(PRUint32 aEventType);
protected:
--- a/content/events/src/nsDOMNotifyPaintEvent.cpp
+++ b/content/events/src/nsDOMNotifyPaintEvent.cpp
@@ -31,16 +31,20 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+#include "base/basictypes.h"
+#include "IPC/IPCMessageUtils.h"
+#endif
#include "nsDOMNotifyPaintEvent.h"
#include "nsContentUtils.h"
#include "nsClientRect.h"
#include "nsPaintRequest.h"
#include "nsIFrame.h"
nsDOMNotifyPaintEvent::nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
nsEvent* aEvent,
@@ -137,16 +141,60 @@ nsDOMNotifyPaintEvent::GetPaintRequests(
r->SetRequest(mInvalidateRequests[i]);
requests->Append(r);
}
requests.forget(aResult);
return NS_OK;
}
+#ifdef MOZ_IPC
+void
+nsDOMNotifyPaintEvent::Serialize(IPC::Message* aMsg,
+ PRBool aSerializeInterfaceType)
+{
+ if (aSerializeInterfaceType) {
+ IPC::WriteParam(aMsg, NS_LITERAL_STRING("notifypaintevent"));
+ }
+
+ nsDOMEvent::Serialize(aMsg, PR_FALSE);
+
+ PRUint32 length = mInvalidateRequests.Length();
+ IPC::WriteParam(aMsg, length);
+ for (PRUint32 i = 0; i < length; ++i) {
+ IPC::WriteParam(aMsg, mInvalidateRequests[i].mRect.x);
+ IPC::WriteParam(aMsg, mInvalidateRequests[i].mRect.y);
+ IPC::WriteParam(aMsg, mInvalidateRequests[i].mRect.width);
+ IPC::WriteParam(aMsg, mInvalidateRequests[i].mRect.height);
+ IPC::WriteParam(aMsg, mInvalidateRequests[i].mFlags);
+ }
+}
+
+PRBool
+nsDOMNotifyPaintEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
+{
+ NS_ENSURE_TRUE(nsDOMEvent::Deserialize(aMsg, aIter), PR_FALSE);
+
+ PRUint32 length = 0;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &length), PR_FALSE);
+ mInvalidateRequests.SetCapacity(length);
+ for (PRUint32 i = 0; i < length; ++i) {
+ nsInvalidateRequestList::Request req;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mRect.x), PR_FALSE);
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mRect.y), PR_FALSE);
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mRect.width), PR_FALSE);
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mRect.height), PR_FALSE);
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &req.mFlags), PR_FALSE);
+ mInvalidateRequests.AppendElement(req);
+ }
+
+ return PR_TRUE;
+}
+#endif
+
nsresult NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsEvent *aEvent,
PRUint32 aEventType,
nsInvalidateRequestList* aInvalidateRequests)
{
nsDOMNotifyPaintEvent* it =
new nsDOMNotifyPaintEvent(aPresContext, aEvent, aEventType,
--- a/content/events/src/nsDOMNotifyPaintEvent.h
+++ b/content/events/src/nsDOMNotifyPaintEvent.h
@@ -56,15 +56,19 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMNOTIFYPAINTEVENT
// Forward to base class
NS_FORWARD_TO_NSDOMEVENT
+#ifdef MOZ_IPC
+ virtual void Serialize(IPC::Message* aMsg, PRBool aSerializeInterfaceType);
+ virtual PRBool Deserialize(const IPC::Message* aMsg, void** aIter);
+#endif
private:
nsRegion GetRegion();
nsTArray<nsInvalidateRequestList::Request> mInvalidateRequests;
};
#endif // nsDOMNotifyPaintEvent_h_
--- a/content/events/src/nsDOMScrollAreaEvent.cpp
+++ b/content/events/src/nsDOMScrollAreaEvent.cpp
@@ -30,16 +30,20 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+#include "base/basictypes.h"
+#include "IPC/IPCMessageUtils.h"
+#endif
#include "nsDOMScrollAreaEvent.h"
#include "nsGUIEvent.h"
#include "nsClientRect.h"
nsDOMScrollAreaEvent::nsDOMScrollAreaEvent(nsPresContext *aPresContext,
nsScrollAreaEvent *aEvent)
: nsDOMUIEvent(aPresContext, aEvent)
{
@@ -101,16 +105,74 @@ nsDOMScrollAreaEvent::InitScrollAreaEven
nsresult rv = nsDOMUIEvent::InitUIEvent(aEventType, aCanBubble, aCancelable, aView, aDetail);
NS_ENSURE_SUCCESS(rv, rv);
mClientArea.SetRect(aX, aY, aWidth, aHeight);
return NS_OK;
}
+#ifdef MOZ_IPC
+void
+nsDOMScrollAreaEvent::Serialize(IPC::Message* aMsg,
+ PRBool aSerializeInterfaceType)
+{
+ if (aSerializeInterfaceType) {
+ IPC::WriteParam(aMsg, NS_LITERAL_STRING("scrollareaevent"));
+ }
+
+ nsDOMUIEvent::Serialize(aMsg, PR_FALSE);
+
+ NS_ASSERTION(sizeof(PRInt32) == sizeof(float),
+ "PRInt32 and float should be the same size!");
+
+ float x = 0.0f;
+ GetX(&x);
+ IPC::WriteParam(aMsg, reinterpret_cast<PRInt32&>(x));
+
+ float y = 0.0f;
+ GetY(&y);
+ IPC::WriteParam(aMsg, reinterpret_cast<PRInt32&>(y));
+
+ float width = 0.0f;
+ GetWidth(&width);
+ IPC::WriteParam(aMsg, reinterpret_cast<PRInt32&>(width));
+
+ float height = 0.0f;
+ GetHeight(&height);
+ IPC::WriteParam(aMsg, reinterpret_cast<PRInt32&>(height));
+}
+
+PRBool
+nsDOMScrollAreaEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
+{
+ NS_ENSURE_TRUE(nsDOMUIEvent::Deserialize(aMsg, aIter), PR_FALSE);
+
+ PRInt32 x_;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &x_), PR_FALSE);
+ float x = reinterpret_cast<float&>(x_);
+
+ PRInt32 y_;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &y_), PR_FALSE);
+ float y = reinterpret_cast<float&>(y_);
+
+ PRInt32 width_;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &width_), PR_FALSE);
+ float width = reinterpret_cast<float&>(width_);
+
+ PRInt32 height_;
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &height_), PR_FALSE);
+ float height = reinterpret_cast<float&>(height_);
+
+ mClientArea.SetRect(x, y, width, height);
+
+ return PR_TRUE;
+}
+#endif
+
nsresult
NS_NewDOMScrollAreaEvent(nsIDOMEvent **aInstancePtrResult,
nsPresContext *aPresContext,
nsScrollAreaEvent *aEvent)
{
nsDOMScrollAreaEvent *ev = new nsDOMScrollAreaEvent(aPresContext, aEvent);
if (!ev) {
--- a/content/events/src/nsDOMScrollAreaEvent.h
+++ b/content/events/src/nsDOMScrollAreaEvent.h
@@ -53,13 +53,17 @@ public:
virtual ~nsDOMScrollAreaEvent();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMSCROLLAREAEVENT
NS_FORWARD_TO_NSDOMUIEVENT
+#ifdef MOZ_IPC
+ virtual void Serialize(IPC::Message* aMsg, PRBool aSerializeInterfaceType);
+ virtual PRBool Deserialize(const IPC::Message* aMsg, void** aIter);
+#endif
protected:
nsClientRect mClientArea;
};
#endif // nsDOMScrollAreaEvent_h__
--- a/content/events/src/nsDOMUIEvent.cpp
+++ b/content/events/src/nsDOMUIEvent.cpp
@@ -32,16 +32,20 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+#include "base/basictypes.h"
+#include "IPC/IPCMessageUtils.h"
+#endif
#include "nsCOMPtr.h"
#include "nsDOMUIEvent.h"
#include "nsIPresShell.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMNode.h"
#include "nsIContent.h"
#include "nsContentUtils.h"
@@ -389,16 +393,40 @@ nsDOMUIEvent::DuplicatePrivateData()
nsIntPoint screenPoint = GetScreenPoint();
nsresult rv = nsDOMEvent::DuplicatePrivateData();
if (NS_SUCCEEDED(rv)) {
mEvent->refPoint = screenPoint;
}
return rv;
}
+#ifdef MOZ_IPC
+void
+nsDOMUIEvent::Serialize(IPC::Message* aMsg, PRBool aSerializeInterfaceType)
+{
+ if (aSerializeInterfaceType) {
+ IPC::WriteParam(aMsg, NS_LITERAL_STRING("uievent"));
+ }
+
+ nsDOMEvent::Serialize(aMsg, PR_FALSE);
+
+ PRInt32 detail = 0;
+ GetDetail(&detail);
+ IPC::WriteParam(aMsg, detail);
+}
+
+PRBool
+nsDOMUIEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
+{
+ NS_ENSURE_TRUE(nsDOMEvent::Deserialize(aMsg, aIter), PR_FALSE);
+ NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &mDetail), PR_FALSE);
+ return PR_TRUE;
+}
+#endif
+
nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsGUIEvent *aEvent)
{
nsDOMUIEvent* it = new nsDOMUIEvent(aPresContext, aEvent);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
--- a/content/events/src/nsDOMUIEvent.h
+++ b/content/events/src/nsDOMUIEvent.h
@@ -59,17 +59,20 @@ public:
// nsIDOMUIEvent Interface
NS_DECL_NSIDOMUIEVENT
// nsIDOMNSUIEvent Interface
NS_DECL_NSIDOMNSUIEVENT
// nsIPrivateDOMEvent interface
NS_IMETHOD DuplicatePrivateData();
-
+#ifdef MOZ_IPC
+ virtual void Serialize(IPC::Message* aMsg, PRBool aSerializeInterfaceType);
+ virtual PRBool Deserialize(const IPC::Message* aMsg, void** aIter);
+#endif
// nsIPrivateCompositionEvent interface
NS_IMETHOD GetCompositionReply(nsTextEventReply** aReply);
// Forward to nsDOMEvent
NS_FORWARD_TO_NSDOMEVENT
NS_FORWARD_NSIDOMNSEVENT(nsDOMEvent::)
protected:
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -77,14 +77,20 @@ endif
DIRS += \
public/coreEvents \
base \
src \
locales \
plugins \
$(NULL)
+ifdef MOZ_IPC
+DIRS += \
+ ipc \
+ $(NULL)
+endif
+
ifdef ENABLE_TESTS
DIRS += tests
endif
include $(topsrcdir)/config/rules.mk
--- a/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
+++ b/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
@@ -38,16 +38,17 @@
#include "nsISupports.idl"
#include "nsIVariant.idl"
interface nsIDOMWindow;
interface nsIDOMElement;
interface nsIDOMHTMLElement;
interface nsIDOMHTMLImageElement;
interface nsIDOMHTMLCanvasElement;
+interface nsIDOMXULElement;
[scriptable, uuid(bbb20a59-524e-4662-981e-5e142814b20c)]
interface nsIDOMCanvasGradient : nsISupports
{
void addColorStop(in float offset, in DOMString color);
};
[scriptable, uuid(21dea65c-5c08-4eb1-ac82-81fe95be77b8)]
@@ -56,17 +57,17 @@ interface nsIDOMCanvasPattern : nsISuppo
};
[scriptable, uuid(2d01715c-ec7d-424a-ab85-e0fd70c8665c)]
interface nsIDOMTextMetrics : nsISupports
{
readonly attribute float width;
};
-[scriptable, uuid(72635fb6-0c1c-47d7-bf69-49388d5980fc)]
+[scriptable, uuid(408be1b9-4d75-4873-b50b-9b651626e41d)]
interface nsIDOMCanvasRenderingContext2D : nsISupports
{
// back-reference to the canvas element for which
// this context was created
readonly attribute nsIDOMHTMLCanvasElement canvas;
// state
void save();
@@ -217,9 +218,12 @@ interface nsIDOMCanvasRenderingContext2D
* transparency.
*
* This API cannot currently be used by Web content. It is chrome
* only.
*/
void drawWindow(in nsIDOMWindow window, in float x, in float y,
in float w, in float h, in DOMString bgColor,
[optional] in unsigned long flags);
+ void asyncDrawXULElement(in nsIDOMXULElement elem, in float x, in float y,
+ in float w, in float h, in DOMString bgColor,
+ [optional] in unsigned long flags);
};
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ContentProcessChild.cpp
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ContentProcessChild.h"
+#include "TabChild.h"
+
+#include "mozilla/ipc/TestShellChild.h"
+#include "mozilla/net/NeckoChild.h"
+
+#include "nsXULAppAPI.h"
+
+#include "base/message_loop.h"
+#include "base/task.h"
+
+using namespace mozilla::ipc;
+using namespace mozilla::net;
+
+namespace mozilla {
+namespace dom {
+
+ContentProcessChild* ContentProcessChild::sSingleton;
+
+ContentProcessChild::ContentProcessChild()
+ : mQuit(PR_FALSE)
+{
+}
+
+ContentProcessChild::~ContentProcessChild()
+{
+}
+
+bool
+ContentProcessChild::Init(MessageLoop* aIOLoop,
+ base::ProcessHandle aParentHandle,
+ IPC::Channel* aChannel)
+{
+ NS_ASSERTION(!sSingleton, "only one ContentProcessChild per child");
+
+ Open(aChannel, aParentHandle, aIOLoop);
+ sSingleton = this;
+
+ return true;
+}
+
+PIFrameEmbeddingChild*
+ContentProcessChild::AllocPIFrameEmbedding()
+{
+ nsRefPtr<TabChild> iframe = new TabChild();
+ NS_ENSURE_TRUE(iframe && NS_SUCCEEDED(iframe->Init()) &&
+ mIFrames.AppendElement(iframe),
+ nsnull);
+ return iframe.forget().get();
+}
+
+bool
+ContentProcessChild::DeallocPIFrameEmbedding(PIFrameEmbeddingChild* iframe)
+{
+ if (mIFrames.RemoveElement(iframe)) {
+ TabChild* child = static_cast<TabChild*>(iframe);
+ NS_RELEASE(child);
+ }
+ return true;
+}
+
+PTestShellChild*
+ContentProcessChild::AllocPTestShell()
+{
+ PTestShellChild* testshell = new TestShellChild();
+ if (testshell && mTestShells.AppendElement(testshell)) {
+ return testshell;
+ }
+ delete testshell;
+ return nsnull;
+}
+
+bool
+ContentProcessChild::DeallocPTestShell(PTestShellChild* shell)
+{
+ mTestShells.RemoveElement(shell);
+ return true;
+}
+
+PNeckoChild*
+ContentProcessChild::AllocPNecko()
+{
+ return new NeckoChild();
+}
+
+bool
+ContentProcessChild::DeallocPNecko(PNeckoChild* necko)
+{
+ delete necko;
+ return true;
+}
+
+void
+ContentProcessChild::Quit()
+{
+ NS_ASSERTION(mQuit, "Exiting uncleanly!");
+ mIFrames.Clear();
+ mTestShells.Clear();
+}
+
+void
+ContentProcessChild::ActorDestroy(ActorDestroyReason why)
+{
+ if (AbnormalShutdown == why)
+ NS_WARNING("shutting down because of crash!");
+
+ mQuit = PR_TRUE;
+ Quit();
+
+ XRE_ShutdownChildProcess();
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ContentProcessChild.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_dom_ContentProcessChild_h
+#define mozilla_dom_ContentProcessChild_h
+
+#include "mozilla/dom/PContentProcessChild.h"
+
+#include "nsTArray.h"
+#include "nsAutoPtr.h"
+
+namespace mozilla {
+namespace dom {
+
+class ContentProcessChild : public PContentProcessChild
+{
+public:
+ ContentProcessChild();
+ virtual ~ContentProcessChild();
+
+ bool Init(MessageLoop* aIOLoop,
+ base::ProcessHandle aParentHandle,
+ IPC::Channel* aChannel);
+
+ static ContentProcessChild* GetSingleton() {
+ NS_ASSERTION(sSingleton, "not initialized");
+ return sSingleton;
+ }
+
+ virtual PIFrameEmbeddingChild* AllocPIFrameEmbedding();
+ virtual bool DeallocPIFrameEmbedding(PIFrameEmbeddingChild*);
+
+ virtual PTestShellChild* AllocPTestShell();
+ virtual bool DeallocPTestShell(PTestShellChild*);
+
+ virtual PNeckoChild* AllocPNecko();
+ virtual bool DeallocPNecko(PNeckoChild*);
+
+private:
+ NS_OVERRIDE
+ virtual void ActorDestroy(ActorDestroyReason why);
+
+ void Quit();
+
+ static ContentProcessChild* sSingleton;
+
+ nsTArray<PIFrameEmbeddingChild* > mIFrames;
+ nsTArray<nsAutoPtr<PTestShellChild> > mTestShells;
+
+ PRBool mQuit;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ContentProcessChild);
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ContentProcessParent.cpp
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ContentProcessParent.h"
+
+#include "mozilla/ipc/GeckoThread.h"
+
+#include "TabParent.h"
+#include "mozilla/ipc/TestShellParent.h"
+#include "mozilla/net/NeckoParent.h"
+
+#include "nsIObserverService.h"
+
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
+#include "nsServiceManagerUtils.h"
+#include "nsThreadUtils.h"
+
+using namespace mozilla::ipc;
+using namespace mozilla::net;
+using mozilla::MonitorAutoEnter;
+
+namespace {
+PRBool gSingletonDied = PR_FALSE;
+}
+
+namespace mozilla {
+namespace dom {
+
+ContentProcessParent* ContentProcessParent::gSingleton;
+
+ContentProcessParent*
+ContentProcessParent::GetSingleton()
+{
+ if (!gSingleton && !gSingletonDied) {
+ nsRefPtr<ContentProcessParent> parent = new ContentProcessParent();
+ if (parent) {
+ nsCOMPtr<nsIObserverService> obs =
+ do_GetService("@mozilla.org/observer-service;1");
+ if (obs) {
+ if (NS_SUCCEEDED(obs->AddObserver(parent, "xpcom-shutdown",
+ PR_FALSE))) {
+ gSingleton = parent;
+ }
+ }
+ }
+ }
+ return gSingleton;
+}
+
+TabParent*
+ContentProcessParent::CreateTab()
+{
+ return static_cast<TabParent*>(SendPIFrameEmbeddingConstructor());
+}
+
+TestShellParent*
+ContentProcessParent::CreateTestShell()
+{
+ return static_cast<TestShellParent*>(SendPTestShellConstructor());
+}
+
+bool
+ContentProcessParent::DestroyTestShell(TestShellParent* aTestShell)
+{
+ return PTestShellParent::Send__delete__(aTestShell);
+}
+
+ContentProcessParent::ContentProcessParent()
+ : mMonitor("ContentProcessParent::mMonitor")
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content);
+ mSubprocess->AsyncLaunch();
+ Open(mSubprocess->GetChannel(), mSubprocess->GetChildProcessHandle());
+}
+
+ContentProcessParent::~ContentProcessParent()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ NS_ASSERTION(gSingleton == this, "More than one singleton?!");
+ gSingletonDied = PR_TRUE;
+ gSingleton = nsnull;
+}
+
+NS_IMPL_ISUPPORTS1(ContentProcessParent, nsIObserver)
+
+namespace {
+void
+DeleteSubprocess(GeckoChildProcessHost* aSubprocess)
+{
+ delete aSubprocess;
+}
+}
+
+NS_IMETHODIMP
+ContentProcessParent::Observe(nsISupports* aSubject,
+ const char* aTopic,
+ const PRUnichar* aData)
+{
+ if (!strcmp(aTopic, "xpcom-shutdown") && mSubprocess) {
+ Close();
+ XRE_GetIOMessageLoop()->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(DeleteSubprocess, mSubprocess));
+ mSubprocess = nsnull;
+ }
+ return NS_OK;
+}
+
+PIFrameEmbeddingParent*
+ContentProcessParent::AllocPIFrameEmbedding()
+{
+ return new TabParent();
+}
+
+bool
+ContentProcessParent::DeallocPIFrameEmbedding(PIFrameEmbeddingParent* frame)
+{
+ delete frame;
+ return true;
+}
+
+PTestShellParent*
+ContentProcessParent::AllocPTestShell()
+{
+ return new TestShellParent();
+}
+
+bool
+ContentProcessParent::DeallocPTestShell(PTestShellParent* shell)
+{
+ delete shell;
+ return true;
+}
+
+PNeckoParent*
+ContentProcessParent::AllocPNecko()
+{
+ return new NeckoParent();
+}
+
+bool
+ContentProcessParent::DeallocPNecko(PNeckoParent* necko)
+{
+ delete necko;
+ return true;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ContentProcessParent.h
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_dom_ContentProcessParent_h
+#define mozilla_dom_ContentProcessParent_h
+
+#include "base/waitable_event_watcher.h"
+
+#include "mozilla/dom/PContentProcessParent.h"
+#include "mozilla/ipc/GeckoChildProcessHost.h"
+
+#include "nsIObserver.h"
+#include "mozilla/Monitor.h"
+
+namespace mozilla {
+
+namespace ipc {
+class TestShellParent;
+}
+
+namespace dom {
+
+class TabParent;
+
+class ContentProcessParent : public PContentProcessParent,
+ public nsIObserver
+{
+private:
+ typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
+ typedef mozilla::ipc::TestShellParent TestShellParent;
+
+public:
+ static ContentProcessParent* GetSingleton();
+
+#if 0
+ // TODO: implement this somewhere!
+ static ContentProcessParent* FreeSingleton();
+#endif
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ TabParent* CreateTab();
+
+ TestShellParent* CreateTestShell();
+ bool DestroyTestShell(TestShellParent* aTestShell);
+
+private:
+ static ContentProcessParent* gSingleton;
+
+ // Hide the raw constructor methods since we don't want client code
+ // using them.
+ using PContentProcessParent::SendPIFrameEmbeddingConstructor;
+ using PContentProcessParent::SendPTestShellConstructor;
+
+ ContentProcessParent();
+ virtual ~ContentProcessParent();
+
+ virtual PIFrameEmbeddingParent* AllocPIFrameEmbedding();
+ virtual bool DeallocPIFrameEmbedding(PIFrameEmbeddingParent* frame);
+
+ virtual PTestShellParent* AllocPTestShell();
+ virtual bool DeallocPTestShell(PTestShellParent* shell);
+
+ virtual PNeckoParent* AllocPNecko();
+ virtual bool DeallocPNecko(PNeckoParent* necko);
+
+ mozilla::Monitor mMonitor;
+
+ GeckoChildProcessHost* mSubprocess;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ContentProcessThread.cpp
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80 :
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ContentProcessThread.h"
+
+#include "prlink.h"
+
+#include "base/command_line.h"
+#include "base/string_util.h"
+#include "chrome/common/child_process.h"
+#include "chrome/common/chrome_switches.h"
+
+using mozilla::ipc::GeckoThread;
+
+namespace mozilla {
+namespace dom {
+
+ContentProcessThread::ContentProcessThread(ProcessHandle mParentHandle) :
+ GeckoThread(mParentHandle),
+ mContentProcess()
+{
+}
+
+ContentProcessThread::~ContentProcessThread()
+{
+}
+
+void
+ContentProcessThread::Init()
+{
+ GeckoThread::Init();
+
+ // FIXME/cjones: set up channel stuff, etc.
+
+ // FIXME owner_loop() is bad here
+ mContentProcess.Init(owner_loop(), GetParentProcessHandle(), channel());
+}
+
+void
+ContentProcessThread::CleanUp()
+{
+ GeckoThread::CleanUp();
+}
+
+} // namespace tabs
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ContentProcessThread.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80 :
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef dom_tabs_ContentProcessThread_h
+#define dom_tabs_ContentProcessThread_h 1
+
+#include "chrome/common/child_thread.h"
+#include "base/file_path.h"
+
+#include "mozilla/ipc/GeckoThread.h"
+#include "ContentProcessChild.h"
+
+#undef _MOZ_LOG
+#define _MOZ_LOG(s) printf("[ContentProcessThread] %s", s)
+
+namespace mozilla {
+namespace dom {
+
+/**
+ * ContentProcessThread is a singleton on the content process which represents
+ * a background thread where tab instances live.
+ */
+class ContentProcessThread : public mozilla::ipc::GeckoThread
+{
+public:
+ ContentProcessThread(ProcessHandle mParentHandle);
+ ~ContentProcessThread();
+
+private:
+ // Thread implementation:
+ virtual void Init();
+ virtual void CleanUp();
+
+ ContentProcessChild mContentProcess;
+ IPC::Channel* mChannel;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ContentProcessThread);
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // ifndef dom_tabs_ContentProcessThread_h
new file mode 100644
--- /dev/null
+++ b/dom/ipc/Makefile.in
@@ -0,0 +1,77 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Firefox.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = dom
+LIBRARY_NAME = domipc_s
+LIBXUL_LIBRARY = 1
+FORCE_STATIC_LIB = 1
+EXPORT_LIBRARY = 1
+
+EXPORTS = TabMessageUtils.h
+
+EXPORTS_NAMESPACES = mozilla mozilla/dom
+
+EXPORTS_mozilla = \
+ TabTypes.h \
+ $(NULL)
+
+EXPORTS_mozilla/dom = \
+ ContentProcessChild.h \
+ ContentProcessParent.h \
+ ContentProcessThread.h \
+ $(NULL)
+
+CPPSRCS = \
+ ContentProcessThread.cpp \
+ ContentProcessParent.cpp \
+ ContentProcessChild.cpp \
+ TabParent.cpp \
+ TabChild.cpp \
+ TabMessageUtils.cpp \
+ $(NULL)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
new file mode 100644
--- /dev/null
+++ b/dom/ipc/PContentProcess.ipdl
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol "PIFrameEmbedding.ipdl";
+include protocol "PTestShell.ipdl";
+include protocol "PNecko.ipdl";
+
+include "mozilla/TabTypes.h";
+
+namespace mozilla {
+namespace dom {
+
+sync protocol PContentProcess
+{
+ manages PIFrameEmbedding;
+ manages PTestShell;
+ manages PNecko;
+
+child:
+ PIFrameEmbedding();
+
+ PTestShell();
+
+parent:
+ PNecko();
+};
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/dom/ipc/PDocumentRenderer.ipdl
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Fenntrolysis.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol "PIFrameEmbedding.ipdl";
+
+namespace mozilla {
+namespace ipc {
+
+protocol PDocumentRenderer
+{
+ manager PIFrameEmbedding;
+
+parent:
+ __delete__(PRUint32 w, PRUint32 h, nsCString data);
+};
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/ipc/PIFrameEmbedding.ipdl
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol "PContentProcess.ipdl";
+include protocol "PDocumentRenderer.ipdl";
+
+include "mozilla/TabTypes.h";
+include "TabMessageUtils.h";
+
+using MagicWindowHandle;
+using RemoteDOMEvent;
+
+namespace mozilla {
+namespace dom {
+
+async protocol PIFrameEmbedding
+{
+ manager PContentProcess;
+ manages PDocumentRenderer;
+
+child:
+ __delete__();
+
+parent:
+ /**
+ * When child sends this message, parent should move focus to
+ * the next or previous focusable element.
+ */
+ moveFocus(bool forward);
+
+ sendEvent(RemoteDOMEvent aEvent);
+child:
+ createWidget(MagicWindowHandle parentWidget);
+
+ loadURL(nsCString uri);
+
+ move(PRUint32 x,
+ PRUint32 y,
+ PRUint32 width,
+ PRUint32 height);
+
+ /**
+ * Sending an activate message moves focus to the child.
+ */
+ activate();
+
+ /**
+ * @see nsIDOMWindowUtils sendMouseEvent.
+ */
+ sendMouseEvent(nsString aType,
+ PRInt32 aX, //XXX should be float, but ipdl doesn't seem to support that.
+ PRInt32 aY, //XXX - " -
+ PRInt32 aButton,
+ PRInt32 aClickCount,
+ PRInt32 aModifiers,
+ bool aIgnoreRootScrollFrame);
+
+ /**
+ * Activate event forwarding from client to parent.
+ */
+ activateFrameEvent(nsString aType, bool capture);
+
+ PDocumentRenderer(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h, nsString bgcolor, PRUint32 flags, bool flush);
+};
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/dom/ipc/TabChild.cpp
@@ -0,0 +1,416 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "TabChild.h"
+
+#include "nsIWebBrowser.h"
+#include "nsEmbedCID.h"
+#include "nsComponentManagerUtils.h"
+#include "nsIBaseWindow.h"
+#include "nsIDOMWindow.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsThreadUtils.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "mozilla/ipc/DocumentRendererChild.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsPIDOMWindow.h"
+#include "nsIDOMWindowUtils.h"
+#include "nsISupportsImpl.h"
+#include "nsIWebBrowserFocus.h"
+#include "nsIDOMEvent.h"
+#include "nsIPrivateDOMEvent.h"
+
+#ifdef MOZ_WIDGET_GTK2
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#endif
+
+using namespace mozilla::dom;
+
+NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
+
+NS_IMETHODIMP
+ContentListener::HandleEvent(nsIDOMEvent* aEvent)
+{
+ RemoteDOMEvent remoteEvent;
+ remoteEvent.mEvent = do_QueryInterface(aEvent);
+ NS_ENSURE_STATE(remoteEvent.mEvent);
+ mTabChild->SendsendEvent(remoteEvent);
+ return NS_OK;
+}
+
+TabChild::TabChild()
+{
+ printf("creating %d!\n", NS_IsMainThread());
+}
+
+nsresult
+TabChild::Init()
+{
+#ifdef MOZ_WIDGET_GTK2
+ gtk_init(NULL, NULL);
+#endif
+
+ nsCOMPtr<nsIWebBrowser> webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
+ if (!webBrowser) {
+ NS_ERROR("Couldn't create a nsWebBrowser?");
+ return NS_ERROR_FAILURE;
+ }
+
+ webBrowser->SetContainerWindow(this);
+
+ mWebNav = do_QueryInterface(webBrowser);
+ NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
+
+ nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(mWebNav));
+ docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
+ return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS5(TabChild, nsIWebBrowserChrome, nsIWebBrowserChrome2,
+ nsIEmbeddingSiteWindow, nsIEmbeddingSiteWindow2,
+ nsIWebBrowserChromeFocus)
+
+NS_IMETHODIMP
+TabChild::SetStatus(PRUint32 aStatusType, const PRUnichar* aStatus)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::GetChromeFlags(PRUint32* aChromeFlags)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::SetChromeFlags(PRUint32 aChromeFlags)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::DestroyBrowserWindow()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::ShowAsModal()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::IsWindowModal(PRBool* aRetVal)
+{
+ *aRetVal = PR_FALSE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+TabChild::ExitModalEventLoop(nsresult aStatus)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::SetStatusWithContext(PRUint32 aStatusType,
+ const nsAString& aStatusText,
+ nsISupports* aStatusContext)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::SetDimensions(PRUint32 aFlags, PRInt32 aX, PRInt32 aY,
+ PRInt32 aCx, PRInt32 aCy)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::GetDimensions(PRUint32 aFlags, PRInt32* aX,
+ PRInt32* aY, PRInt32* aCx, PRInt32* aCy)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::SetFocus()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::GetVisibility(PRBool* aVisibility)
+{
+ *aVisibility = PR_TRUE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+TabChild::SetVisibility(PRBool aVisibility)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::GetTitle(PRUnichar** aTitle)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::SetTitle(const PRUnichar* aTitle)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::GetSiteWindow(void** aSiteWindow)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::Blur()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+TabChild::FocusNextElement()
+{
+ SendmoveFocus(PR_TRUE);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+TabChild::FocusPrevElement()
+{
+ SendmoveFocus(PR_FALSE);
+ return NS_OK;
+}
+
+bool
+TabChild::RecvcreateWidget(const MagicWindowHandle& parentWidget)
+{
+ nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
+ if (!baseWindow) {
+ NS_ERROR("mWebNav doesn't QI to nsIBaseWindow");
+ return true;
+ }
+
+#ifdef MOZ_WIDGET_GTK2
+ GtkWidget* win = gtk_plug_new((GdkNativeWindow)parentWidget);
+ gtk_widget_show(win);
+#elif defined(XP_WIN)
+ HWND win = parentWidget;
+#elif defined(XP_MACOSX)
+# warning IMPLEMENT ME
+#else
+#error You lose!
+#endif
+
+#if !defined(XP_MACOSX)
+ baseWindow->InitWindow(win, 0, 0, 0, 0, 0);
+ baseWindow->Create();
+ baseWindow->SetVisibility(PR_TRUE);
+#endif
+
+ return true;
+}
+
+bool
+TabChild::destroyWidget()
+{
+ nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
+ if (baseWindow)
+ baseWindow->Destroy();
+
+ return true;
+}
+
+TabChild::~TabChild()
+{
+ destroyWidget();
+ nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(mWebNav);
+ if (webBrowser) {
+ webBrowser->SetContainerWindow(nsnull);
+ }
+}
+
+bool
+TabChild::RecvloadURL(const nsCString& uri)
+{
+ printf("loading %s, %d\n", uri.get(), NS_IsMainThread());
+
+ nsresult rv = mWebNav->LoadURI(NS_ConvertUTF8toUTF16(uri).get(),
+ nsIWebNavigation::LOAD_FLAGS_NONE,
+ NULL, NULL, NULL);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("mWebNav->LoadURI failed. Eating exception, what else can I do?");
+ }
+ return true;
+}
+
+bool
+TabChild::Recvmove(const PRUint32& x,
+ const PRUint32& y,
+ const PRUint32& width,
+ const PRUint32& height)
+{
+ printf("[TabChild] MOVE to (x,y)=(%ud, %ud), (w,h)= (%ud, %ud)\n",
+ x, y, width, height);
+
+ nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mWebNav);
+ baseWin->SetPositionAndSize(x, y, width, height, PR_TRUE);
+ return true;
+}
+
+bool
+TabChild::Recvactivate()
+{
+ nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(mWebNav);
+ browser->Activate();
+ return true;
+}
+
+bool
+TabChild::RecvsendMouseEvent(const nsString& aType,
+ const PRInt32& aX,
+ const PRInt32& aY,
+ const PRInt32& aButton,
+ const PRInt32& aClickCount,
+ const PRInt32& aModifiers,
+ const bool& aIgnoreRootScrollFrame)
+{
+ nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
+ nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window);
+ NS_ENSURE_TRUE(utils, true);
+ utils->SendMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers,
+ aIgnoreRootScrollFrame);
+ return true;
+}
+
+mozilla::ipc::PDocumentRendererChild*
+TabChild::AllocPDocumentRenderer(
+ const PRInt32& x,
+ const PRInt32& y,
+ const PRInt32& w,
+ const PRInt32& h,
+ const nsString& bgcolor,
+ const PRUint32& flags,
+ const bool& flush)
+{
+ return new mozilla::ipc::DocumentRendererChild();
+}
+
+bool
+TabChild::DeallocPDocumentRenderer(PDocumentRendererChild* actor)
+{
+ delete actor;
+ return true;
+}
+
+bool
+TabChild::RecvPDocumentRendererConstructor(
+ mozilla::ipc::PDocumentRendererChild *__a,
+ const PRInt32& aX,
+ const PRInt32& aY,
+ const PRInt32& aW,
+ const PRInt32& aH,
+ const nsString& bgcolor,
+ const PRUint32& flags,
+ const bool& flush)
+{
+ mozilla::ipc::DocumentRendererChild *render =
+ static_cast<mozilla::ipc::DocumentRendererChild *>(__a);
+
+ nsCOMPtr<nsIWebBrowser> browser = do_QueryInterface(mWebNav);
+ if (!browser)
+ return true; // silently ignore
+ nsCOMPtr<nsIDOMWindow> window;
+ if (NS_FAILED(browser->GetContentDOMWindow(getter_AddRefs(window))) ||
+ !window)
+ {
+ return true; // silently ignore
+ }
+
+ PRUint32 width, height;
+ nsCString data;
+ bool ret = render->RenderDocument(window, aX, aY, aW, aH, bgcolor, flags, flush,
+ width, height, data);
+ if (!ret)
+ return true; // silently ignore
+
+ return PDocumentRendererChild::Send__delete__(__a, width, height, data);
+}
+
+bool
+TabChild::RecvactivateFrameEvent(const nsString& aType, const bool& capture)
+{
+ nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
+ NS_ENSURE_TRUE(window, true);
+ nsCOMPtr<nsIDOMEventTarget> chromeHandler =
+ do_QueryInterface(window->GetChromeEventHandler());
+ NS_ENSURE_TRUE(chromeHandler, true);
+ nsRefPtr<ContentListener> listener = new ContentListener(this);
+ NS_ENSURE_TRUE(listener, true);
+ chromeHandler->AddEventListener(aType, listener, capture);
+ return true;
+}
new file mode 100644
--- /dev/null
+++ b/dom/ipc/TabChild.h
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_tabs_TabChild_h
+#define mozilla_tabs_TabChild_h
+
+#include "mozilla/dom/PIFrameEmbeddingChild.h"
+#include "nsIWebNavigation.h"
+#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
+#include "nsIWebBrowserChrome2.h"
+#include "nsIEmbeddingSiteWindow2.h"
+#include "nsIWebBrowserChromeFocus.h"
+#include "nsIDOMEventListener.h"
+#include "nsIDOMEventTarget.h"
+
+namespace mozilla {
+namespace dom {
+
+class TabChild;
+
+class ContentListener : public nsIDOMEventListener
+{
+public:
+ ContentListener(TabChild* aTabChild) : mTabChild(aTabChild) {}
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDOMEVENTLISTENER
+protected:
+ TabChild* mTabChild;
+};
+
+class TabChild : public PIFrameEmbeddingChild,
+ public nsIWebBrowserChrome2,
+ public nsIEmbeddingSiteWindow2,
+ public nsIWebBrowserChromeFocus
+{
+public:
+ TabChild();
+ virtual ~TabChild();
+ bool destroyWidget();
+ nsresult Init();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEBBROWSERCHROME
+ NS_DECL_NSIWEBBROWSERCHROME2
+ NS_DECL_NSIEMBEDDINGSITEWINDOW
+ NS_DECL_NSIEMBEDDINGSITEWINDOW2
+ NS_DECL_NSIWEBBROWSERCHROMEFOCUS
+
+ virtual bool RecvcreateWidget(const MagicWindowHandle& parentWidget);
+ virtual bool RecvloadURL(const nsCString& uri);
+ virtual bool Recvmove(const PRUint32& x,
+ const PRUint32& y,
+ const PRUint32& width,
+ const PRUint32& height);
+ virtual bool Recvactivate();
+ virtual bool RecvsendMouseEvent(const nsString& aType,
+ const PRInt32& aX,
+ const PRInt32& aY,
+ const PRInt32& aButton,
+ const PRInt32& aClickCount,
+ const PRInt32& aModifiers,
+ const bool& aIgnoreRootScrollFrame);
+ virtual bool RecvactivateFrameEvent(const nsString& aType, const bool& capture);
+ virtual mozilla::ipc::PDocumentRendererChild* AllocPDocumentRenderer(
+ const PRInt32& x,
+ const PRInt32& y,
+ const PRInt32& w,
+ const PRInt32& h,
+ const nsString& bgcolor,
+ const PRUint32& flags,
+ const bool& flush);
+ virtual bool DeallocPDocumentRenderer(PDocumentRendererChild* actor);
+ virtual bool RecvPDocumentRendererConstructor(
+ mozilla::ipc::PDocumentRendererChild *__a,
+ const PRInt32& x,
+ const PRInt32& y,
+ const PRInt32& w,
+ const PRInt32& h,
+ const nsString& bgcolor,
+ const PRUint32& flags,
+ const bool& flush);
+
+private:
+ nsCOMPtr<nsIWebNavigation> mWebNav;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TabChild);
+};
+
+}
+}
+
+#endif // mozilla_tabs_TabChild_h
new file mode 100644
--- /dev/null
+++ b/dom/ipc/TabMessageUtils.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Olli Pettay <Olli.Pettay@helsinki.fi>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "TabMessageUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIDOMEvent.h"
+
+#ifdef CreateEvent
+#undef CreateEvent
+#endif
+
+#include "nsEventDispatcher.h"
+
+namespace mozilla {
+namespace dom {
+
+bool
+ReadRemoteEvent(const IPC::Message* aMsg, void** aIter,
+ RemoteDOMEvent* aResult)
+{
+ aResult->mEvent = nsnull;
+ nsString type;
+ NS_ENSURE_TRUE(ReadParam(aMsg, aIter, &type), false);
+
+ nsCOMPtr<nsIDOMEvent> event;
+ nsEventDispatcher::CreateEvent(nsnull, nsnull, type, getter_AddRefs(event));
+ aResult->mEvent = do_QueryInterface(event);
+ NS_ENSURE_TRUE(aResult->mEvent, false);
+
+ return aResult->mEvent->Deserialize(aMsg, aIter);
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/dom/ipc/TabMessageUtils.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Olli Pettay <Olli.Pettay@helsinki.fi>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef TABMESSAGE_UTILS_H
+#define TABMESSAGE_UTILS_H
+
+#include "IPC/IPCMessageUtils.h"
+#include "nsIPrivateDOMEvent.h"
+#include "nsCOMPtr.h"
+
+namespace mozilla {
+namespace dom {
+struct RemoteDOMEvent
+{
+ nsCOMPtr<nsIPrivateDOMEvent> mEvent;
+};
+
+bool ReadRemoteEvent(const IPC::Message* aMsg, void** aIter,
+ mozilla::dom::RemoteDOMEvent* aResult);
+
+}
+}
+
+namespace IPC {
+
+template<>
+struct ParamTraits<mozilla::dom::RemoteDOMEvent>
+{
+ typedef mozilla::dom::RemoteDOMEvent paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ aParam.mEvent->Serialize(aMsg, PR_TRUE);
+ }
+
+ static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+ {
+ return mozilla::dom::ReadRemoteEvent(aMsg, aIter, aResult);
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog)
+ {
+ }
+};
+
+
+}
+
+
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/ipc/TabParent.cpp
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "TabParent.h"
+
+#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/DocumentRendererParent.h"
+
+#include "nsIURI.h"
+#include "nsFocusManager.h"
+#include "nsCOMPtr.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIDOMElement.h"
+#include "nsEventDispatcher.h"
+#include "nsIDOMEventTarget.h"
+#include "nsIDOMEvent.h"
+#include "nsIPrivateDOMEvent.h"
+
+using mozilla::ipc::BrowserProcessSubThread;
+using mozilla::ipc::DocumentRendererParent;
+
+namespace mozilla {
+namespace dom {
+
+TabParent::TabParent()
+{
+}
+
+TabParent::~TabParent()
+{
+}
+
+bool
+TabParent::RecvmoveFocus(const bool& aForward)
+{
+ nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
+ if (fm) {
+ nsCOMPtr<nsIDOMElement> dummy;
+ PRUint32 type = aForward ? nsIFocusManager::MOVEFOCUS_FORWARD
+ : nsIFocusManager::MOVEFOCUS_BACKWARD;
+ fm->MoveFocus(nsnull, mFrameElement, type, nsIFocusManager::FLAG_BYKEY,
+ getter_AddRefs(dummy));
+ }
+ return true;
+}
+
+bool
+TabParent::RecvsendEvent(const RemoteDOMEvent& aEvent)
+{
+ nsCOMPtr<nsIDOMEvent> event = do_QueryInterface(aEvent.mEvent);
+ NS_ENSURE_TRUE(event, true);
+
+ nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mFrameElement);
+ NS_ENSURE_TRUE(target, true);
+
+ PRBool dummy;
+ target->DispatchEvent(event, &dummy);
+ return true;
+}
+
+void
+TabParent::LoadURL(nsIURI* aURI)
+{
+ nsCString spec;
+ aURI->GetSpec(spec);
+
+ SendloadURL(spec);
+}
+
+void
+TabParent::Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height)
+{
+ Sendmove(x, y, width, height);
+}
+
+void
+TabParent::Activate()
+{
+ Sendactivate();
+}
+
+mozilla::ipc::PDocumentRendererParent*
+TabParent::AllocPDocumentRenderer(const PRInt32& x,
+ const PRInt32& y, const PRInt32& w, const PRInt32& h, const nsString& bgcolor,
+ const PRUint32& flags, const bool& flush)
+{
+ return new DocumentRendererParent();
+}
+
+bool
+TabParent::DeallocPDocumentRenderer(PDocumentRendererParent* actor)
+{
+ delete actor;
+ return true;
+}
+
+void
+TabParent::SendMouseEvent(const nsAString& aType, float aX, float aY,
+ PRInt32 aButton, PRInt32 aClickCount,
+ PRInt32 aModifiers, PRBool aIgnoreRootScrollFrame)
+{
+ SendsendMouseEvent(nsString(aType), aX, aY, aButton, aClickCount,
+ aModifiers, aIgnoreRootScrollFrame);
+}
+
+} // namespace tabs
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/ipc/TabParent.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_tabs_TabParent_h
+#define mozilla_tabs_TabParent_h
+
+#include "mozilla/dom/PIFrameEmbeddingParent.h"
+
+#include "mozilla/ipc/GeckoChildProcessHost.h"
+
+class nsIURI;
+class nsIDOMElement;
+
+namespace mozilla {
+namespace dom {
+
+class TabParent : public PIFrameEmbeddingParent
+{
+public:
+ TabParent();
+ virtual ~TabParent();
+ void SetOwnerElement(nsIDOMElement* aElement) { mFrameElement = aElement; }
+
+ virtual bool RecvmoveFocus(const bool& aForward);
+ virtual bool RecvsendEvent(const RemoteDOMEvent& aEvent);
+
+ void LoadURL(nsIURI* aURI);
+ void Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height);
+ void Activate();
+ void SendMouseEvent(const nsAString& aType, float aX, float aY,
+ PRInt32 aButton, PRInt32 aClickCount,
+ PRInt32 aModifiers, PRBool aIgnoreRootScrollFrame);
+
+ virtual mozilla::ipc::PDocumentRendererParent* AllocPDocumentRenderer(
+ const PRInt32& x,
+ const PRInt32& y,
+ const PRInt32& w,
+ const PRInt32& h,
+ const nsString& bgcolor,
+ const PRUint32& flags,
+ const bool& flush);
+ virtual bool DeallocPDocumentRenderer(PDocumentRendererParent* actor);
+protected:
+ nsIDOMElement* mFrameElement;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/ipc/TabTypes.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+
+#ifndef mozilla_tabs_TabTypes_h
+#define mozilla_tabs_TabTypes_h
+
+#include "base/basictypes.h"
+
+#ifdef XP_WIN
+#include <windows.h>
+
+typedef HWND MagicWindowHandle;
+#elif defined(MOZ_WIDGET_GTK2)
+#include <X11/X.h>
+
+typedef XID MagicWindowHandle;
+
+#elif defined(XP_MACOSX)
+# warning This is a placeholder
+typedef long MagicWindowHandle;
+
+#else
+#error Not implemented, stooge
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/ipc/ipdl.mk
@@ -0,0 +1,41 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Content App.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+IPDLSRCS = \
+ PContentProcess.ipdl \
+ PIFrameEmbedding.ipdl \
+ PDocumentRenderer.ipdl \
+ $(NULL)
new file mode 100644
--- /dev/null
+++ b/dom/ipc/jar.mn
@@ -0,0 +1,2 @@
+toolkit.jar:
+ content/global/test-ipc.xul (test.xul)
new file mode 100644
--- /dev/null
+++ b/dom/ipc/test.xul
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ width="800" height="800" orient="vertical">
+ <script>
+
+ function dumpClientRect(r) {
+ dump(r.left + "," + r.top + "," + r.right + "," +
+ r.bottom + "," + r.width + "," + r.height + "\n");
+ }
+
+ function handleMozAfterPaint(e) {
+ return;
+ dump(e.type + "\n")
+ var rects = e.clientRects;
+ var i;
+ dump("\tclientRects:\n");
+ for (i = 0; i < rects.length; ++i) {
+ var r = rects.item(i);
+ dump("\t\t");
+ dumpClientRect(rects.item(i));
+ }
+
+ dump("\tboundingClientRect\n\t\t");
+ dumpClientRect(e.boundingClientRect);
+
+ var paintRequests = e.paintRequests;
+ dump("\tpaintRequests\n");
+ for (i = 0; i < paintRequests.length; ++i) {
+ var pr = paintRequests.item(i);
+ dump("\t\t");
+ dumpClientRect(pr.clientRect);
+ if (pr.reason)
+ dump("\t\t" + pr.reason + "\n");
+ }
+ }
+
+ function handleMozScrolledAreaChanged(e) {
+ return;
+ dump(e.type + "\n");
+ dump("\t" + e.x + "," + e.y + "," + e.width + "," + e.height + "\n");
+ }
+
+ function restart() {
+ var y = document.getElementById('page');
+ var p = y.parentNode;
+ p.removeChild(y);
+ p.appendChild(y);
+
+ var fl = y.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+ fl.activateFrameEvent("MozAfterPaint", true);
+ fl.activateFrameEvent("MozScrolledAreaChanged", true);
+ y.addEventListener("MozAfterPaint", handleMozAfterPaint, true);
+ y.addEventListener("MozScrolledAreaChanged", handleMozScrolledAreaChanged, true);
+ }
+
+ function loadURL(url) {
+ document.getElementById('page').setAttribute('src', url);
+ }
+
+ function randomClick() {
+ // First focus the remote frame, then dispatch click. This way remote frame gets focus before
+ // mouse event.
+ document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
+ .frameLoader.activateRemoteFrame();
+ var frameLoader = document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+ var x = parseInt(Math.random() * 100);
+ var y = parseInt(Math.random() * 100);
+ frameLoader.sendCrossProcessMouseEvent("mousedown", x, y, 0, 1, 0, false);
+ frameLoader.sendCrossProcessMouseEvent("mouseup", x, y, 0, 1, 0, false);
+ }
+
+ function openWindow() {
+ window.open('chrome://global/content/test-ipc.xul', '_blank', 'chrome,resizable,width=800,height=800');
+ }
+
+ function closeWindow() {
+ window.close();
+ }
+ </script>
+
+ <toolbar id="controls">
+ <toolbarbutton label="Back"/>
+ <toolbarbutton label="Forward"/>
+ <textbox onchange="loadURL(this.value)" flex="1" id="URL"/>
+ <toolbarbutton onclick="restart()" label="Recover"/>
+ <toolbarbutton onclick="randomClick()" label="random click"/>
+ <toolbarbutton onclick="openWindow()" label="open new window"/>
+ <toolbarbutton onclick="closeWindow()" label="close this window"/>
+ </toolbar>
+
+ <browser type="content" src="http://www.google.com/" flex="1" id="page" remote="true"
+ onfocus="this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.activateRemoteFrame();"/>
+</window>
--- a/ipc/Makefile.in
+++ b/ipc/Makefile.in
@@ -39,13 +39,13 @@ topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
# NB: chromium/ and glue/ are in tier_xpcom
# tier_gecko:
-DIRS += ipdl
+DIRS += ipdl testshell
TOOL_DIRS = app
include $(topsrcdir)/config/rules.mk
--- a/ipc/ipdl/Makefile.in
+++ b/ipc/ipdl/Makefile.in
@@ -50,17 +50,21 @@ FORCE_STATIC_LIB = 1
LIBXUL_LIBRARY = 1
EXPORT_LIBRARY = 1
##-----------------------------------------------------------------------------
## When you add IPDL files to a source directory, list the directory here.
##
IPDLDIRS = \
dom/plugins \
+ dom/ipc \
+ netwerk/ipc \
+ netwerk/protocol/http/src \
ipc/ipdl/test/cxx \
+ ipc/testshell \
$(NULL)
##-----------------------------------------------------------------------------
ifdef MOZ_IPDL_TESTS
DIRS += test
endif
vpath %.ipdl $(topsrcdir)
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/Makefile.in
@@ -0,0 +1,74 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla IPCShell.
+#
+# The Initial Developer of the Original Code is
+# Ben Turner <bent.mozilla@gmail.com>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = ipcshell
+LIBRARY_NAME = ipcshell_s
+FORCE_STATIC_LIB = 1
+LIBXUL_LIBRARY = 1
+EXPORT_LIBRARY = 1
+
+EXPORTS_NAMESPACES = mozilla/ipc
+
+EXPORTS_mozilla/ipc = \
+ TestShellChild.h \
+ TestShellParent.h \
+ XPCShellEnvironment.h \
+ $(NULL)
+
+CPPSRCS += \
+ TestShellChild.cpp \
+ TestShellParent.cpp \
+ XPCShellEnvironment.cpp \
+ $(NULL)
+
+# For xpcshell error messages and nsDependentJSString
+LOCAL_INCLUDES += \
+ -I$(topsrcdir)/js/src/xpconnect/shell \
+ -I$(topsrcdir)/dom/base \
+ $(NULL)
+
+XPCSHELL_TESTS = tests
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/PTestShell.ipdl
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPCShell.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol "PContentProcess.ipdl";
+include protocol "PTestShellCommand.ipdl";
+
+namespace mozilla {
+namespace ipc {
+
+protocol PTestShell
+{
+ manager PContentProcess;
+
+ manages PTestShellCommand;
+
+child:
+ __delete__();
+
+ ExecuteCommand(nsString aCommand);
+
+ PTestShellCommand(nsString aCommand);
+};
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/PTestShellCommand.ipdl
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPCShell.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol "PTestShell.ipdl";
+
+namespace mozilla {
+namespace ipc {
+
+protocol PTestShellCommand
+{
+ manager PTestShell;
+
+parent:
+ __delete__(nsString aResponse);
+};
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/TestShellChild.cpp
@@ -0,0 +1,87 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPCShell.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "TestShellChild.h"
+
+using mozilla::ipc::TestShellChild;
+using mozilla::ipc::PTestShellCommandChild;
+using mozilla::ipc::XPCShellEnvironment;
+
+TestShellChild::TestShellChild()
+: mXPCShell(XPCShellEnvironment::CreateEnvironment())
+{
+}
+
+bool
+TestShellChild::RecvExecuteCommand(const nsString& aCommand)
+{
+ if (mXPCShell->IsQuitting()) {
+ NS_WARNING("Commands sent after quit command issued!");
+ return false;
+ }
+
+ return mXPCShell->EvaluateString(aCommand);
+}
+
+PTestShellCommandChild*
+TestShellChild::AllocPTestShellCommand(const nsString& aCommand)
+{
+ return new PTestShellCommandChild();
+}
+
+bool
+TestShellChild::DeallocPTestShellCommand(PTestShellCommandChild* aCommand)
+{
+ delete aCommand;
+ return true;
+}
+
+bool
+TestShellChild::RecvPTestShellCommandConstructor(PTestShellCommandChild* aActor,
+ const nsString& aCommand)
+{
+ if (mXPCShell->IsQuitting()) {
+ NS_WARNING("Commands sent after quit command issued!");
+ return false;
+ }
+
+ nsString response;
+ if (!mXPCShell->EvaluateString(aCommand, &response)) {
+ return false;
+ }
+
+ return PTestShellCommandChild::Send__delete__(aActor, response);
+}
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/TestShellChild.h
@@ -0,0 +1,80 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPCShell.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ipc_testshell_TestShellChild_h
+#define ipc_testshell_TestShellChild_h 1
+
+#include "mozilla/ipc/PTestShellChild.h"
+#include "mozilla/ipc/PTestShellCommandChild.h"
+#include "mozilla/ipc/XPCShellEnvironment.h"
+
+#include "nsAutoPtr.h"
+
+namespace mozilla {
+namespace ipc {
+
+class XPCShellEnvironment;
+
+class TestShellChild : public PTestShellChild
+{
+public:
+ TestShellChild();
+
+ bool
+ RecvExecuteCommand(const nsString& aCommand);
+
+ PTestShellCommandChild*
+ AllocPTestShellCommand(const nsString& aCommand);
+
+ bool
+ RecvPTestShellCommandConstructor(PTestShellCommandChild* aActor,
+ const nsString& aCommand);
+
+ bool
+ DeallocPTestShellCommand(PTestShellCommandChild* aCommand);
+
+ void SetXPCShell(XPCShellEnvironment* aXPCShell) {
+ mXPCShell = aXPCShell;
+ }
+
+private:
+ nsAutoPtr<XPCShellEnvironment> mXPCShell;
+};
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+#endif /* ipc_testshell_TestShellChild_h */
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/TestShellParent.cpp
@@ -0,0 +1,110 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPCShell.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "TestShellParent.h"
+
+#include "nsAutoPtr.h"
+
+using mozilla::ipc::TestShellParent;
+using mozilla::ipc::TestShellCommandParent;
+using mozilla::ipc::PTestShellCommandParent;
+
+PTestShellCommandParent*
+TestShellParent::AllocPTestShellCommand(const nsString& aCommand)
+{
+ return new TestShellCommandParent();
+}
+
+bool
+TestShellParent::DeallocPTestShellCommand(PTestShellCommandParent* aActor)
+{
+ delete aActor;
+ return true;
+}
+
+bool
+TestShellParent::CommandDone(TestShellCommandParent* command,
+ const nsString& aResponse)
+{
+ // XXX what should happen if the callback fails?
+ /*JSBool ok = */command->RunCallback(aResponse);
+ command->ReleaseCallback();
+
+ return true;
+}
+
+JSBool
+TestShellCommandParent::SetCallback(JSContext* aCx,
+ jsval aCallback)
+{
+ if (!mCallback.Hold(aCx)) {
+ return JS_FALSE;
+ }
+
+ mCallback = aCallback;
+ mCx = aCx;
+
+ return JS_TRUE;
+}
+
+JSBool
+TestShellCommandParent::RunCallback(const nsString& aResponse)
+{
+ NS_ENSURE_TRUE(mCallback && mCx, JS_FALSE);
+
+ JSAutoRequest ar(mCx);
+
+ JSObject* global = JS_GetGlobalObject(mCx);
+ NS_ENSURE_TRUE(global, JS_FALSE);
+
+ JSString* str = JS_NewUCStringCopyN(mCx, aResponse.get(), aResponse.Length());
+ NS_ENSURE_TRUE(str, JS_FALSE);
+
+ jsval argv[] = { STRING_TO_JSVAL(str) };
+ int argc = NS_ARRAY_LENGTH(argv);
+
+ jsval rval;
+ JSBool ok = JS_CallFunctionValue(mCx, global, mCallback, argc, argv, &rval);
+ NS_ENSURE_TRUE(ok, JS_FALSE);
+
+ return JS_TRUE;
+}
+
+void
+TestShellCommandParent::ReleaseCallback()
+{
+ mCallback.Release();
+}
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/TestShellParent.h
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPCShell.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ipc_testshell_TestShellParent_h
+#define ipc_testshell_TestShellParent_h 1
+
+#include "mozilla/ipc/PTestShellParent.h"
+#include "mozilla/ipc/PTestShellCommandParent.h"
+
+#include "jsapi.h"
+#include "nsAutoJSValHolder.h"
+#include "nsStringGlue.h"
+
+namespace mozilla {
+namespace ipc {
+
+class TestShellCommandParent;
+
+
+class TestShellParent : public PTestShellParent
+{
+public:
+ PTestShellCommandParent*
+ AllocPTestShellCommand(const nsString& aCommand);
+
+ bool
+ DeallocPTestShellCommand(PTestShellCommandParent* aActor);
+
+ bool
+ CommandDone(TestShellCommandParent* aActor, const nsString& aResponse);
+};
+
+
+class TestShellCommandParent : public PTestShellCommandParent
+{
+public:
+ TestShellCommandParent() : mCx(NULL) { }
+
+ JSBool SetCallback(JSContext* aCx,
+ jsval aCallback);
+
+ JSBool RunCallback(const nsString& aResponse);
+
+ void ReleaseCallback();
+
+protected:
+ bool Recv__delete__(const nsString& aResponse) {
+ return static_cast<TestShellParent*>(Manager())->CommandDone(
+ this, aResponse);
+ }
+
+private:
+ JSContext* mCx;
+ nsAutoJSValHolder mCallback;
+};
+
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+#endif /* ipc_testshell_TestShellParent_h */
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -0,0 +1,1258 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPCShell.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "XPCShellEnvironment.h"
+
+#include <stdlib.h>
+#include <errno.h>
+#ifdef HAVE_IO_H
+#include <io.h> /* for isatty() */
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* for isatty() */
+#endif
+
+#include "jsapi.h"
+#include "jscntxt.h"
+#include "jsdbgapi.h"
+#include "jsprf.h"
+
+#include "mozilla/XPCOM.h"
+
+#include "nsIChannel.h"
+#include "nsIClassInfo.h"
+#include "nsIDirectoryService.h"
+#include "nsIJSContextStack.h"
+#include "nsIJSRuntimeService.h"
+#include "nsIPrincipal.h"
+#include "nsIScriptSecurityManager.h"
+#include "nsIURI.h"
+#include "nsIXPConnect.h"
+#include "nsIXPCScriptable.h"
+
+#include "nsJSUtils.h"
+#include "nsThreadUtils.h"
+#include "nsXULAppAPI.h"
+
+#include "TestShellChild.h"
+#include "TestShellParent.h"
+
+#define EXITCODE_RUNTIME_ERROR 3
+#define EXITCODE_FILE_NOT_FOUND 4
+
+using mozilla::ipc::XPCShellEnvironment;
+using mozilla::ipc::TestShellChild;
+using mozilla::ipc::TestShellParent;
+
+namespace {
+
+static const char kDefaultRuntimeScriptFilename[] = "xpcshell.js";
+
+class FullTrustSecMan : public nsIScriptSecurityManager
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIXPCSECURITYMANAGER
+ NS_DECL_NSISCRIPTSECURITYMANAGER
+
+ FullTrustSecMan() { }
+ virtual ~FullTrustSecMan() { }
+
+ void SetSystemPrincipal(nsIPrincipal *aPrincipal) {
+ mSystemPrincipal = aPrincipal;
+ }
+
+private:
+ nsCOMPtr<nsIPrincipal> mSystemPrincipal;
+};
+
+class XPCShellDirProvider : public nsIDirectoryServiceProvider
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDIRECTORYSERVICEPROVIDER
+
+ XPCShellDirProvider() { }
+ ~XPCShellDirProvider() { }
+
+ PRBool SetGREDir(const char *dir);
+ void ClearGREDir() { mGREDir = nsnull; }
+
+private:
+ nsCOMPtr<nsILocalFile> mGREDir;
+};
+
+inline XPCShellEnvironment*
+Environment(JSContext* cx)
+{
+ XPCShellEnvironment* env =
+ static_cast<XPCShellEnvironment*>(JS_GetContextPrivate(cx));
+ NS_ASSERTION(env, "Should never be null!");
+ return env;
+}
+
+static void
+ScriptErrorReporter(JSContext *cx,
+ const char *message,
+ JSErrorReport *report)
+{
+ int i, j, k, n;
+ char *prefix = NULL, *tmp;
+ const char *ctmp;
+ JSStackFrame * fp = nsnull;
+ nsCOMPtr<nsIXPConnect> xpc;
+
+ // Don't report an exception from inner JS frames as the callers may intend
+ // to handle it.
+ while ((fp = JS_FrameIterator(cx, &fp))) {
+ if (!JS_IsNativeFrame(cx, fp)) {
+ return;
+ }
+ }
+
+ // In some cases cx->fp is null here so use XPConnect to tell us about inner
+ // frames.
+ if ((xpc = do_GetService(nsIXPConnect::GetCID()))) {
+ nsAXPCNativeCallContext *cc = nsnull;
+ xpc->GetCurrentNativeCallContext(&cc);
+ if (cc) {
+ nsAXPCNativeCallContext *prev = cc;
+ while (NS_SUCCEEDED(prev->GetPreviousCallContext(&prev)) && prev) {
+ PRUint16 lang;
+ if (NS_SUCCEEDED(prev->GetLanguage(&lang)) &&
+ lang == nsAXPCNativeCallContext::LANG_JS) {
+ return;
+ }
+ }
+ }
+ }
+
+ if (!report) {
+ fprintf(stderr, "%s\n", message);
+ return;
+ }
+
+ /* Conditionally ignore reported warnings. */
+ if (JSREPORT_IS_WARNING(report->flags) &&
+ !Environment(cx)->ShouldReportWarnings()) {
+ return;
+ }
+
+ if (report->filename)
+ prefix = JS_smprintf("%s:", report->filename);
+ if (report->lineno) {
+ tmp = prefix;
+ prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
+ JS_free(cx, tmp);
+ }
+ if (JSREPORT_IS_WARNING(report->flags)) {
+ tmp = prefix;
+ prefix = JS_smprintf("%s%swarning: ",
+ tmp ? tmp : "",
+ JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
+ JS_free(cx, tmp);
+ }
+
+ /* embedded newlines -- argh! */
+ while ((ctmp = strchr(message, '\n')) != 0) {
+ ctmp++;
+ if (prefix) fputs(prefix, stderr);
+ fwrite(message, 1, ctmp - message, stderr);
+ message = ctmp;
+ }
+ /* If there were no filename or lineno, the prefix might be empty */
+ if (prefix)
+ fputs(prefix, stderr);
+ fputs(message, stderr);
+
+ if (!report->linebuf) {
+ fputc('\n', stderr);
+ goto out;
+ }
+
+ fprintf(stderr, ":\n%s%s\n%s", prefix, report->linebuf, prefix);
+ n = report->tokenptr - report->linebuf;
+ for (i = j = 0; i < n; i++) {
+ if (report->linebuf[i] == '\t') {
+ for (k = (j + 8) & ~7; j < k; j++) {
+ fputc('.', stderr);
+ }
+ continue;
+ }
+ fputc('.', stderr);
+ j++;
+ }
+ fputs("^\n", stderr);
+ out:
+ if (!JSREPORT_IS_WARNING(report->flags)) {
+ Environment(cx)->SetExitCode(EXITCODE_RUNTIME_ERROR);
+ }
+ JS_free(cx, prefix);
+}
+
+JSContextCallback gOldContextCallback = NULL;
+
+static JSBool
+ContextCallback(JSContext *cx,
+ uintN contextOp)
+{
+ if (gOldContextCallback && !gOldContextCallback(cx, contextOp))
+ return JS_FALSE;
+
+ if (contextOp == JSCONTEXT_NEW) {
+ JS_SetErrorReporter(cx, ScriptErrorReporter);
+ JS_SetVersion(cx, JSVERSION_LATEST);
+ }
+ return JS_TRUE;
+}
+
+static JSBool
+Print(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ uintN i, n;
+ JSString *str;
+
+ for (i = n = 0; i < argc; i++) {
+ str = JS_ValueToString(cx, argv[i]);
+ if (!str)
+ return JS_FALSE;
+ fprintf(stdout, "%s%s", i ? " " : "", JS_GetStringBytes(str));
+ fflush(stdout);
+ }
+ n++;
+ if (n)
+ fputc('\n', stdout);
+ return JS_TRUE;
+}
+
+static JSBool
+GetLine(char *bufp,
+ FILE *file,
+ const char *prompt)
+{
+ char line[256];
+ fprintf(stdout, prompt);
+ fflush(stdout);
+ if (!fgets(line, sizeof line, file))
+ return JS_FALSE;
+ strcpy(bufp, line);
+ return JS_TRUE;
+}
+
+static JSBool
+Dump(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ JSString *str;
+ if (!argc)
+ return JS_TRUE;
+
+ str = JS_ValueToString(cx, argv[0]);
+ if (!str)
+ return JS_FALSE;
+
+ fputs(JS_GetStringBytes(str), stdout);
+ fflush(stdout);
+ return JS_TRUE;
+}
+
+static JSBool
+Load(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ uintN i;
+ JSString *str;
+ const char *filename;
+ JSScript *script;
+ JSBool ok;
+ jsval result;
+ FILE *file;
+
+ for (i = 0; i < argc; i++) {
+ str = JS_ValueToString(cx, argv[i]);
+ if (!str)
+ return JS_FALSE;
+ argv[i] = STRING_TO_JSVAL(str);
+ filename = JS_GetStringBytes(str);
+ file = fopen(filename, "r");
+ if (!file) {
+ JS_ReportError(cx, "cannot open file '%s' for reading", filename);
+ return JS_FALSE;
+ }
+ script = JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
+ Environment(cx)->GetPrincipal());
+ fclose(file);
+ if (!script)
+ return JS_FALSE;
+
+ ok = !Environment(cx)->ShouldCompileOnly()
+ ? JS_ExecuteScript(cx, obj, script, &result)
+ : JS_TRUE;
+ JS_DestroyScript(cx, script);
+ if (!ok)
+ return JS_FALSE;
+ }
+ return JS_TRUE;
+}
+
+static JSBool
+Version(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ if (argc > 0 && JSVAL_IS_INT(argv[0]))
+ *rval = INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(argv[0]))));
+ else
+ *rval = INT_TO_JSVAL(JS_GetVersion(cx));
+ return JS_TRUE;
+}
+
+static JSBool
+BuildDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ fprintf(stdout, "built on %s at %s\n", __DATE__, __TIME__);
+ return JS_TRUE;
+}
+
+static JSBool
+Quit(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ int exitCode = 0;
+ JS_ConvertArguments(cx, argc, argv, "/ i", &exitCode);
+
+ XPCShellEnvironment* env = Environment(cx);
+ env->SetExitCode(exitCode);
+ env->SetIsQuitting();
+
+ return JS_FALSE;
+}
+
+static JSBool
+DumpXPC(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ int32 depth = 2;
+
+ if (argc > 0) {
+ if (!JS_ValueToInt32(cx, argv[0], &depth))
+ return JS_FALSE;
+ }
+
+ nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
+ if(xpc)
+ xpc->DebugDump((int16)depth);
+ return JS_TRUE;
+}
+
+static JSBool
+GC(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ JSRuntime *rt;
+ uint32 preBytes;
+
+ rt = cx->runtime;
+ preBytes = rt->gcBytes;
+ JS_GC(cx);
+ fprintf(stdout, "before %lu, after %lu, break %08lx\n",
+ (unsigned long)preBytes, (unsigned long)rt->gcBytes,
+#ifdef XP_UNIX
+ (unsigned long)sbrk(0)
+#else
+ 0
+#endif
+ );
+#ifdef JS_GCMETER
+ js_DumpGCStats(rt, stdout);
+#endif
+ return JS_TRUE;
+}
+
+#ifdef DEBUG
+
+static JSBool
+DumpHeap(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ char *fileName = NULL;
+ void* startThing = NULL;
+ uint32 startTraceKind = 0;
+ void *thingToFind = NULL;
+ size_t maxDepth = (size_t)-1;
+ void *thingToIgnore = NULL;
+ jsval *vp;
+ FILE *dumpFile;
+ JSBool ok;
+
+ vp = &argv[0];
+ if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) {
+ JSString *str;
+
+ str = JS_ValueToString(cx, *vp);
+ if (!str)
+ return JS_FALSE;
+ *vp = STRING_TO_JSVAL(str);
+ fileName = JS_GetStringBytes(str);
+ }
+
+ vp = &argv[1];
+ if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) {
+ if (!JSVAL_IS_TRACEABLE(*vp))
+ goto not_traceable_arg;
+ startThing = JSVAL_TO_TRACEABLE(*vp);
+ startTraceKind = JSVAL_TRACE_KIND(*vp);
+ }
+
+ vp = &argv[2];
+ if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) {
+ if (!JSVAL_IS_TRACEABLE(*vp))
+ goto not_traceable_arg;
+ thingToFind = JSVAL_TO_TRACEABLE(*vp);
+ }
+
+ vp = &argv[3];
+ if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) {
+ uint32 depth;
+
+ if (!JS_ValueToECMAUint32(cx, *vp, &depth))
+ return JS_FALSE;
+ maxDepth = depth;
+ }
+
+ vp = &argv[4];
+ if (*vp != JSVAL_NULL && *vp != JSVAL_VOID) {
+ if (!JSVAL_IS_TRACEABLE(*vp))
+ goto not_traceable_arg;
+ thingToIgnore = JSVAL_TO_TRACEABLE(*vp);
+ }
+
+ if (!fileName) {
+ dumpFile = stdout;
+ } else {
+ dumpFile = fopen(fileName, "w");
+ if (!dumpFile) {
+ fprintf(stderr, "dumpHeap: can't open %s: %s\n",
+ fileName, strerror(errno));
+ return JS_FALSE;
+ }
+ }
+
+ ok = JS_DumpHeap(cx, dumpFile, startThing, startTraceKind, thingToFind,
+ maxDepth, thingToIgnore);
+ if (dumpFile != stdout)
+ fclose(dumpFile);
+ return ok;
+
+ not_traceable_arg:
+ fprintf(stderr,
+ "dumpHeap: argument %u is not null or a heap-allocated thing\n",
+ (unsigned)(vp - argv));
+ return JS_FALSE;
+}
+
+#endif /* DEBUG */
+
+static JSBool
+Clear(JSContext *cx,
+ JSObject *obj,
+ uintN argc,
+ jsval *argv,
+ jsval *rval)
+{
+ if (argc > 0 && !JSVAL_IS_PRIMITIVE(argv[0])) {
+ JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0]));
+ } else {
+ JS_ReportError(cx, "'clear' requires an object");
+ return JS_FALSE;
+ }
+ return JS_TRUE;
+}
+
+JSFunctionSpec gGlobalFunctions[] =
+{
+ {"print", Print, 0,0,0},
+ {"load", Load, 1,0,0},
+ {"quit", Quit, 0,0,0},
+ {"version", Version, 1,0,0},
+ {"build", BuildDate, 0,0,0},
+ {"dumpXPC", DumpXPC, 1,0,0},
+ {"dump", Dump, 1,0,0},
+ {"gc", GC, 0,0,0},
+ {"clear", Clear, 1,0,0},
+#ifdef DEBUG
+ {"dumpHeap", DumpHeap, 5,0,0},
+#endif
+#ifdef MOZ_SHARK
+ {"startShark", js_StartShark, 0,0,0},
+ {"stopShark", js_StopShark, 0,0,0},
+ {"connectShark", js_ConnectShark, 0,0,0},
+ {"disconnectShark", js_DisconnectShark, 0,0,0},
+#endif
+#ifdef MOZ_CALLGRIND
+ {"startCallgrind", js_StartCallgrind, 0,0,0},
+ {"stopCallgrind", js_StopCallgrind, 0,0,0},
+ {"dumpCallgrind", js_DumpCallgrind, 1,0,0},
+#endif
+ {nsnull,nsnull,0,0,0}
+};
+
+typedef enum JSShellErrNum
+{
+#define MSG_DEF(name, number, count, exception, format) \
+ name = number,
+#include "jsshell.msg"
+#undef MSG_DEF
+ JSShellErr_Limit
+#undef MSGDEF
+} JSShellErrNum;
+
+JSErrorFormatString gErrorFormatString[JSErr_Limit] =
+{
+#define MSG_DEF(name, number, count, exception, format) \
+ { format, count } ,
+#include "jsshell.msg"
+#undef MSG_DEF
+};
+
+static const JSErrorFormatString *
+GetErrorMessage(void *userRef,
+ const char *locale,
+ const uintN errorNumber)
+{
+ if ((errorNumber > 0) && (errorNumber < JSShellErr_Limit))
+ return &gErrorFormatString[errorNumber];
+
+ return NULL;
+}
+
+static void
+ProcessFile(JSContext *cx,
+ JSObject *obj,
+ const char *filename,
+ FILE *file,
+ JSBool forceTTY)
+{
+ XPCShellEnvironment* env = Environment(cx);
+ XPCShellEnvironment::AutoContextPusher pusher(env);
+
+ JSScript *script;
+ jsval result;
+ int lineno, startline;
+ JSBool ok, hitEOF;
+ char *bufp, buffer[4096];
+ JSString *str;
+
+ if (forceTTY) {
+ file = stdin;
+ }
+ else
+#ifdef HAVE_ISATTY
+ if (!isatty(fileno(file)))
+#endif
+ {
+ /*
+ * It's not interactive - just execute it.
+ *
+ * Support the UNIX #! shell hack; gobble the first line if it starts
+ * with '#'. TODO - this isn't quite compatible with sharp variables,
+ * as a legal js program (using sharp variables) might start with '#'.
+ * But that would require multi-character lookahead.
+ */
+ int ch = fgetc(file);
+ if (ch == '#') {
+ while((ch = fgetc(file)) != EOF) {
+ if(ch == '\n' || ch == '\r')
+ break;
+ }
+ }
+ ungetc(ch, file);
+
+ JSAutoRequest ar(cx);
+
+ JSScript* script =
+ JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
+ env->GetPrincipal());
+ if (script) {
+ if (!env->ShouldCompileOnly())
+ (void)JS_ExecuteScript(cx, obj, script, &result);
+ JS_DestroyScript(cx, script);
+ }
+
+ return;
+ }
+
+ /* It's an interactive filehandle; drop into read-eval-print loop. */
+ lineno = 1;
+ hitEOF = JS_FALSE;
+ do {
+ bufp = buffer;
+ *bufp = '\0';
+
+ JSAutoRequest ar(cx);
+
+ /*
+ * Accumulate lines until we get a 'compilable unit' - one that either
+ * generates an error (before running out of source) or that compiles
+ * cleanly. This should be whenever we get a complete statement that
+ * coincides with the end of a line.
+ */
+ startline = lineno;
+ do {
+ if (!GetLine(bufp, file, startline == lineno ? "js> " : "")) {
+ hitEOF = JS_TRUE;
+ break;
+ }
+ bufp += strlen(bufp);
+ lineno++;
+ } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
+
+ /* Clear any pending exception from previous failed compiles. */
+ JS_ClearPendingException(cx);
+ script =
+ JS_CompileScriptForPrincipals(cx, obj, env->GetPrincipal(), buffer,
+ strlen(buffer), "typein", startline);
+ if (script) {
+ JSErrorReporter older;
+
+ if (!env->ShouldCompileOnly()) {
+ ok = JS_ExecuteScript(cx, obj, script, &result);
+ if (ok && result != JSVAL_VOID) {
+ /* Suppress error reports from JS_ValueToString(). */
+ older = JS_SetErrorReporter(cx, NULL);
+ str = JS_ValueToString(cx, result);
+ JS_SetErrorReporter(cx, older);
+
+ if (str)
+ fprintf(stdout, "%s\n", JS_GetStringBytes(str));
+ else
+ ok = JS_FALSE;
+ }
+ }
+ JS_DestroyScript(cx, script);
+ }
+ } while (!hitEOF && !env->IsQuitting());
+
+ fprintf(stdout, "\n");
+}
+
+} /* anonymous namespace */
+
+NS_INTERFACE_MAP_BEGIN(FullTrustSecMan)
+ NS_INTERFACE_MAP_ENTRY(nsIXPCSecurityManager)
+ NS_INTERFACE_MAP_ENTRY(nsIScriptSecurityManager)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCSecurityManager)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(FullTrustSecMan)
+NS_IMPL_RELEASE(FullTrustSecMan)
+
+NS_IMETHODIMP
+FullTrustSecMan::CanCreateWrapper(JSContext * aJSContext,
+ const nsIID & aIID,
+ nsISupports *aObj,
+ nsIClassInfo *aClassInfo,
+ void * *aPolicy)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CanCreateInstance(JSContext * aJSContext,
+ const nsCID & aCID)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CanGetService(JSContext * aJSContext,
+ const nsCID & aCID)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CanAccess(PRUint32 aAction,
+ nsAXPCNativeCallContext *aCallContext,
+ JSContext * aJSContext,
+ JSObject * aJSObject,
+ nsISupports *aObj,
+ nsIClassInfo *aClassInfo,
+ jsval aName,
+ void * *aPolicy)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckPropertyAccess(JSContext * aJSContext,
+ JSObject * aJSObject,
+ const char *aClassName,
+ jsval aProperty,
+ PRUint32 aAction)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckConnect(JSContext * aJSContext,
+ nsIURI *aTargetURI,
+ const char *aClassName,
+ const char *aProperty)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckLoadURIFromScript(JSContext * cx,
+ nsIURI *uri)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckLoadURIWithPrincipal(nsIPrincipal *aPrincipal,
+ nsIURI *uri,
+ PRUint32 flags)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckLoadURI(nsIURI *from,
+ nsIURI *uri,
+ PRUint32 flags)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckLoadURIStrWithPrincipal(nsIPrincipal *aPrincipal,
+ const nsACString & uri,
+ PRUint32 flags)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckLoadURIStr(const nsACString & from,
+ const nsACString & uri,
+ PRUint32 flags)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckFunctionAccess(JSContext * cx,
+ void * funObj,
+ void * targetObj)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CanExecuteScripts(JSContext * cx,
+ nsIPrincipal *principal,
+ PRBool *_retval)
+{
+ *_retval = PR_TRUE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::GetSubjectPrincipal(nsIPrincipal **_retval)
+{
+ NS_IF_ADDREF(*_retval = mSystemPrincipal);
+ return *_retval ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **_retval)
+{
+ NS_IF_ADDREF(*_retval = mSystemPrincipal);
+ return *_retval ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::GetCertificatePrincipal(const nsACString & aCertFingerprint,
+ const nsACString & aSubjectName,
+ const nsACString & aPrettyName,
+ nsISupports *aCert,
+ nsIURI *aURI,
+ nsIPrincipal **_retval)
+{
+ NS_IF_ADDREF(*_retval = mSystemPrincipal);
+ return *_retval ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::GetCodebasePrincipal(nsIURI *aURI,
+ nsIPrincipal **_retval)
+{
+ NS_IF_ADDREF(*_retval = mSystemPrincipal);
+ return *_retval ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::RequestCapability(nsIPrincipal *principal,
+ const char *capability,
+ PRInt16 *_retval)
+{
+ *_retval = nsIPrincipal::ENABLE_GRANTED;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::IsCapabilityEnabled(const char *capability,
+ PRBool *_retval)
+{
+ *_retval = PR_TRUE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::EnableCapability(const char *capability)
+{
+ return NS_OK;;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::RevertCapability(const char *capability)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::DisableCapability(const char *capability)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::SetCanEnableCapability(const nsACString & certificateFingerprint,
+ const char *capability,
+ PRInt16 canEnable)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::GetObjectPrincipal(JSContext * cx,
+ JSObject * obj,
+ nsIPrincipal **_retval)
+{
+ NS_IF_ADDREF(*_retval = mSystemPrincipal);
+ return *_retval ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::SubjectPrincipalIsSystem(PRBool *_retval)
+{
+ *_retval = PR_TRUE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckSameOrigin(JSContext * aJSContext,
+ nsIURI *aTargetURI)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::CheckSameOriginURI(nsIURI *aSourceURI,
+ nsIURI *aTargetURI,
+ PRBool reportError)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::GetPrincipalFromContext(JSContext * cx,
+ nsIPrincipal **_retval)
+{
+ NS_IF_ADDREF(*_retval = mSystemPrincipal);
+ return *_retval ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::GetChannelPrincipal(nsIChannel *aChannel,
+ nsIPrincipal **_retval)
+{
+ NS_IF_ADDREF(*_retval = mSystemPrincipal);
+ return *_retval ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::IsSystemPrincipal(nsIPrincipal *aPrincipal,
+ PRBool *_retval)
+{
+ *_retval = aPrincipal == mSystemPrincipal;
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(nsIPrincipal *)
+FullTrustSecMan::GetCxSubjectPrincipal(JSContext *cx)
+{
+ return mSystemPrincipal;
+}
+
+NS_IMETHODIMP_(nsIPrincipal *)
+FullTrustSecMan::GetCxSubjectPrincipalAndFrame(JSContext *cx,
+ JSStackFrame **fp)
+{
+ *fp = nsnull;
+ return mSystemPrincipal;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::PushContextPrincipal(JSContext *cx,
+ JSStackFrame *fp,
+ nsIPrincipal *principal)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FullTrustSecMan::PopContextPrincipal(JSContext *cx)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+XPCShellDirProvider::AddRef()
+{
+ return 2;
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+XPCShellDirProvider::Release()
+{
+ return 1;
+}
+
+NS_IMPL_QUERY_INTERFACE1(XPCShellDirProvider, nsIDirectoryServiceProvider)
+
+PRBool
+XPCShellDirProvider::SetGREDir(const char *dir)
+{
+ nsresult rv = XRE_GetFileFromPath(dir, getter_AddRefs(mGREDir));
+ return NS_SUCCEEDED(rv);
+}
+
+NS_IMETHODIMP
+XPCShellDirProvider::GetFile(const char *prop,
+ PRBool *persistent,
+ nsIFile* *result)
+{
+ if (mGREDir && !strcmp(prop, NS_GRE_DIR)) {
+ *persistent = PR_TRUE;
+ NS_ADDREF(*result = mGREDir);
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+XPCShellEnvironment::
+AutoContextPusher::AutoContextPusher(XPCShellEnvironment* aEnv)
+{
+ NS_ASSERTION(aEnv->mCx, "Null context?!");
+
+ if (NS_SUCCEEDED(aEnv->mCxStack->Push(aEnv->mCx))) {
+ mEnv = aEnv;
+ }
+}
+
+XPCShellEnvironment::
+AutoContextPusher::~AutoContextPusher()
+{
+ if (mEnv) {
+ JSContext* cx;
+ mEnv->mCxStack->Pop(&cx);
+ NS_ASSERTION(cx == mEnv->mCx, "Wrong context on the stack!");
+ }
+}
+
+// static
+XPCShellEnvironment*
+XPCShellEnvironment::CreateEnvironment()
+{
+ XPCShellEnvironment* env = new XPCShellEnvironment();
+ if (env && !env->Init()) {
+ delete env;
+ env = nsnull;
+ }
+ return env;
+}
+
+XPCShellEnvironment::XPCShellEnvironment()
+: mCx(NULL),
+ mJSPrincipals(NULL),
+ mExitCode(0),
+ mQuitting(JS_FALSE),
+ mReportWarnings(JS_TRUE),
+ mCompileOnly(JS_FALSE)
+{
+}
+
+XPCShellEnvironment::~XPCShellEnvironment()
+{
+ if (mCx) {
+ JS_BeginRequest(mCx);
+
+ JSObject* global = GetGlobalObject();
+ if (global) {
+ JS_ClearScope(mCx, global);
+ }
+ mGlobalHolder.Release();
+
+ JS_GC(mCx);
+
+ mCxStack = nsnull;
+
+ if (mJSPrincipals) {
+ JSPRINCIPALS_DROP(mCx, mJSPrincipals);
+ }
+
+ JSRuntime* rt = gOldContextCallback ? JS_GetRuntime(mCx) : NULL;
+
+ JS_DestroyContext(mCx);
+
+ if (gOldContextCallback) {
+ NS_ASSERTION(rt, "Should never be null!");
+ JS_SetContextCallback(rt, gOldContextCallback);
+ gOldContextCallback = NULL;
+ }
+ }
+}
+
+bool
+XPCShellEnvironment::Init()
+{
+ nsresult rv;
+
+#ifdef HAVE_SETBUF
+ // unbuffer stdout so that output is in the correct order; note that stderr
+ // is unbuffered by default
+ setbuf(stdout, 0);
+#endif
+
+ nsCOMPtr<nsIJSRuntimeService> rtsvc =
+ do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
+ if (!rtsvc) {
+ NS_ERROR("failed to get nsJSRuntimeService!");
+ return false;
+ }
+
+ JSRuntime *rt;
+ if (NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) {
+ NS_ERROR("failed to get JSRuntime from nsJSRuntimeService!");
+ return false;
+ }
+
+ if (!mGlobalHolder.Hold(rt)) {
+ NS_ERROR("Can't protect global object!");
+ return false;
+ }
+
+ gOldContextCallback = JS_SetContextCallback(rt, ContextCallback);
+
+ JSContext *cx = JS_NewContext(rt, 8192);
+ if (!cx) {
+ NS_ERROR("JS_NewContext failed!");
+
+ JS_SetContextCallback(rt, gOldContextCallback);
+ gOldContextCallback = NULL;
+
+ return false;
+ }
+ mCx = cx;
+
+ JS_SetContextPrivate(cx, this);
+
+ nsCOMPtr<nsIXPConnect> xpc =
+ do_GetService(nsIXPConnect::GetCID());
+ if (!xpc) {
+ NS_ERROR("failed to get nsXPConnect service!");
+ return false;
+ }
+
+ nsRefPtr<FullTrustSecMan> secman(new FullTrustSecMan());
+ xpc->SetSecurityManagerForJSContext(cx, secman, 0xFFFF);
+
+ nsCOMPtr<nsIPrincipal> principal;
+
+ nsCOMPtr<nsIScriptSecurityManager> securityManager =
+ do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+ if (NS_SUCCEEDED(rv) && securityManager) {
+ rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
+ if (NS_FAILED(rv)) {
+ fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n");
+ } else {
+ // fetch the JS principals and stick in a global
+ rv = principal->GetJSPrincipals(cx, &mJSPrincipals);
+ if (NS_FAILED(rv)) {
+ fprintf(stderr, "+++ Failed to obtain JS principals from SystemPrincipal.\n");
+ }
+ secman->SetSystemPrincipal(principal);
+ }
+ } else {
+ fprintf(stderr, "+++ Failed to get ScriptSecurityManager service, running without principals");
+ }
+
+ nsCOMPtr<nsIJSContextStack> cxStack =
+ do_GetService("@mozilla.org/js/xpc/ContextStack;1");
+ if (!cxStack) {
+ NS_ERROR("failed to get the nsThreadJSContextStack service!");
+ return false;
+ }
+ mCxStack = cxStack;
+
+ AutoContextPusher pusher(this);
+
+ nsCOMPtr<nsIXPCScriptable> backstagePass;
+ rv = rtsvc->GetBackstagePass(getter_AddRefs(backstagePass));
+ if (NS_FAILED(rv)) {
+ NS_ERROR("Failed to get backstage pass from rtsvc!");
+ return false;
+ }
+
+ nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
+ rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass,
+ NS_GET_IID(nsISupports),
+ nsIXPConnect::
+ FLAG_SYSTEM_GLOBAL_OBJECT,
+ getter_AddRefs(holder));
+ if (NS_FAILED(rv)) {
+ NS_ERROR("InitClassesWithNewWrappedGlobal failed!");
+ return false;
+ }
+
+ JSObject *globalObj;
+ rv = holder->GetJSObject(&globalObj);
+ if (NS_FAILED(rv)) {
+ NS_ERROR("Failed to get global JSObject!");
+ return false;
+ }
+
+
+ {
+ JSAutoRequest ar(cx);
+
+ if (!JS_DefineFunctions(cx, globalObj, gGlobalFunctions)) {
+ NS_ERROR("JS_DefineFunctions failed!");
+ return false;
+ }
+ }
+
+ mGlobalHolder = globalObj;
+
+ FILE* runtimeScriptFile = fopen(kDefaultRuntimeScriptFilename, "r");
+ if (runtimeScriptFile) {
+ fprintf(stdout, "[loading '%s'...]\n", kDefaultRuntimeScriptFilename);
+ ProcessFile(cx, globalObj, kDefaultRuntimeScriptFilename,
+ runtimeScriptFile, JS_FALSE);
+ fclose(runtimeScriptFile);
+ }
+
+ return true;
+}
+
+bool
+XPCShellEnvironment::EvaluateString(const nsString& aString,
+ nsString* aResult)
+{
+ JSAutoRequest ar(mCx);
+
+ JS_ClearPendingException(mCx);
+
+ JSObject* global = GetGlobalObject();
+
+ JSScript* script =
+ JS_CompileUCScriptForPrincipals(mCx, global, GetPrincipal(),
+ aString.get(), aString.Length(),
+ "typein", 0);
+ if (!script) {
+ return false;
+ }
+
+ if (!ShouldCompileOnly()) {
+ if (aResult) {
+ aResult->Truncate();
+ }
+
+ jsval result;
+ JSBool ok = JS_ExecuteScript(mCx, global, script, &result);
+ if (ok && result != JSVAL_VOID) {
+ JSErrorReporter old = JS_SetErrorReporter(mCx, NULL);
+ JSString* str = JS_ValueToString(mCx, result);
+ JS_SetErrorReporter(mCx, old);
+
+ if (str && aResult) {
+ aResult->Assign(nsDependentJSString(str));
+ }
+ }
+ }
+
+ JS_DestroyScript(mCx, script);
+
+ return true;
+}
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/XPCShellEnvironment.h
@@ -0,0 +1,132 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPCShell.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _IPC_TESTSHELL_XPCSHELLENVIRONMENT_H_
+#define _IPC_TESTSHELL_XPCSHELLENVIRONMENT_H_
+
+#include "base/basictypes.h"
+
+#include <string>
+#include <stdio.h>
+
+#include "nsAutoJSValHolder.h"
+#include "nsCOMPtr.h"
+#include "nsDebug.h"
+#include "nsStringGlue.h"
+
+struct JSContext;
+struct JSObject;
+struct JSPrincipals;
+
+class nsIJSContextStack;
+
+namespace mozilla {
+namespace ipc {
+
+class XPCShellEnvironment
+{
+public:
+ static XPCShellEnvironment* CreateEnvironment();
+ ~XPCShellEnvironment();
+
+ bool EvaluateString(const nsString& aString,
+ nsString* aResult = nsnull);
+
+ JSPrincipals* GetPrincipal() {
+ return mJSPrincipals;
+ }
+
+ JSObject* GetGlobalObject() {
+ return mGlobalHolder.ToJSObject();
+ }
+
+ void SetExitCode(int aExitCode) {
+ mExitCode = aExitCode;
+ }
+ int ExitCode() {
+ return mExitCode;
+ }
+
+ void SetIsQuitting() {
+ mQuitting = JS_TRUE;
+ }
+ JSBool IsQuitting() {
+ return mQuitting;
+ }
+
+ void SetShouldReportWarnings(JSBool aReportWarnings) {
+ mReportWarnings = aReportWarnings;
+ }
+ JSBool ShouldReportWarnings() {
+ return mReportWarnings;
+ }
+
+ void SetShouldCompoleOnly(JSBool aCompileOnly) {
+ mCompileOnly = aCompileOnly;
+ }
+ JSBool ShouldCompileOnly() {
+ return mCompileOnly;
+ }
+
+ class AutoContextPusher
+ {
+ public:
+ AutoContextPusher(XPCShellEnvironment* aEnv);
+ ~AutoContextPusher();
+ private:
+ XPCShellEnvironment* mEnv;
+ };
+
+protected:
+ XPCShellEnvironment();
+ bool Init();
+
+private:
+ JSContext* mCx;
+ nsAutoJSValHolder mGlobalHolder;
+ nsCOMPtr<nsIJSContextStack> mCxStack;
+ JSPrincipals* mJSPrincipals;
+
+ int mExitCode;
+ JSBool mQuitting;
+ JSBool mReportWarnings;
+ JSBool mCompileOnly;
+};
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+#endif /* _IPC_TESTSHELL_XPCSHELLENVIRONMENT_H_ */
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/ipdl.mk
@@ -0,0 +1,4 @@
+IPDLSRCS = \
+ PTestShell.ipdl \
+ PTestShellCommand.ipdl \
+ $(NULL)
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/tests/test_ipcshell.js
@@ -0,0 +1,15 @@
+function callback(result) {
+ do_check_eq(result, Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT);
+ do_test_finished();
+}
+
+function run_test() {
+ do_test_pending();
+
+ do_check_eq(runtime.processType, Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT);
+
+ sendCommand("load('test_ipcshell_child.js');");
+ sendCommand("runtime.processType;", callback);
+}
+load('test_ipcshell_child.js');
+
new file mode 100644
--- /dev/null
+++ b/ipc/testshell/tests/test_ipcshell_child.js
@@ -0,0 +1,9 @@
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
+
+if (typeof(run_test) == "undefined") {
+ run_test = function() {
+ do_check_eq(runtime.processType, Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT);
+ }
}
--- a/js/src/xpconnect/shell/Makefile.in
+++ b/js/src/xpconnect/shell/Makefile.in
@@ -64,16 +64,18 @@ NSDISTMODE = copy
ifdef _MSC_VER
ifdef WINCE
WIN32_EXE_LDFLAGS += -ENTRY:mainWCRTStartup
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre/
endif
endif
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
DEFINES += -DJS_THREADSAFE
ifdef MOZ_SHARK
DEFINES += -DMOZ_SHARK
CFLAGS += -F/System/Library/PrivateFrameworks
LDFLAGS += -F/System/Library/PrivateFrameworks -framework CHUD
--- a/js/src/xpconnect/shell/xpcshell.cpp
+++ b/js/src/xpconnect/shell/xpcshell.cpp
@@ -40,16 +40,21 @@
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* XPConnect JavaScript interactive shell. */
+#ifdef MOZ_IPC
+#include "mozilla/dom/ContentProcessParent.h"
+#include "mozilla/ipc/TestShellParent.h"
+#endif
+
#include <stdio.h>
#include "nsXULAppAPI.h"
#include "nsServiceManagerUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsStringAPI.h"
#include "nsIXPConnect.h"
#include "nsIXPCScriptable.h"
#include "nsIInterfaceInfo.h"
@@ -104,16 +109,21 @@
#endif
#include "nsIJSContextStack.h"
#ifdef MOZ_CRASHREPORTER
#include "nsICrashReporter.h"
#endif
+#ifdef MOZ_IPC
+using mozilla::dom::ContentProcessParent;
+using mozilla::ipc::TestShellParent;
+#endif
+
class XPCShellDirProvider : public nsIDirectoryServiceProvider2
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
XPCShellDirProvider() { }
@@ -645,16 +655,51 @@ Clear(JSContext *cx, JSObject *obj, uint
JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0]));
} else {
JS_ReportError(cx, "'clear' requires an object");
return JS_FALSE;
}
return JS_TRUE;
}
+#ifdef MOZ_IPC
+
+static JSBool
+SendCommand(JSContext* cx,
+ JSObject* obj,
+ uintN argc,
+ jsval* argv,
+ jsval* rval)
+{
+ if (argc == 0) {
+ JS_ReportError(cx, "Function takes at least one argument!");
+ return JS_FALSE;
+ }
+
+ JSString* str = JS_ValueToString(cx, argv[0]);
+ if (!str) {
+ JS_ReportError(cx, "Could not convert argument 1 to string!");
+ return JS_FALSE;
+ }
+
+ if (argc > 1 && JS_TypeOfValue(cx, argv[1]) != JSTYPE_FUNCTION) {
+ JS_ReportError(cx, "Could not convert argument 2 to function!");
+ return JS_FALSE;
+ }
+
+ if (!XRE_SendTestShellCommand(cx, str, argc > 1 ? &argv[1] : nsnull)) {
+ JS_ReportError(cx, "Couldn't send command!");
+ return JS_FALSE;
+ }
+
+ return JS_TRUE;
+}
+
+#endif // MOZ_IPC
+
/*
* JSContext option name to flag map. The option names are in alphabetical
* order for better reporting.
*/
static const struct {
const char *name;
uint32 flag;
} js_options[] = {
@@ -758,16 +803,19 @@ static JSFunctionSpec glob_functions[] =
{"dumpXPC", DumpXPC, 1,0,0},
{"dump", Dump, 1,0,0},
{"gc", GC, 0,0,0},
{"clear", Clear, 1,0,0},
{"options", Options, 0,0,0},
#ifdef DEBUG
{"dumpHeap", DumpHeap, 5,0,0},
#endif
+#ifdef MOZ_IPC
+ {"sendCommand", SendCommand, 1,0,0},
+#endif
#ifdef MOZ_SHARK
{"startShark", js_StartShark, 0,0,0},
{"stopShark", js_StopShark, 0,0,0},
{"connectShark", js_ConnectShark, 0,0,0},
{"disconnectShark", js_DisconnectShark, 0,0,0},
#endif
#ifdef MOZ_CALLGRIND
{"startCallgrind", js_StartCallgrind, 0,0,0},
@@ -1894,16 +1942,21 @@ main(int argc, char **argv)
JSContext *oldcx;
cxstack->Pop(&oldcx);
NS_ASSERTION(oldcx == cx, "JS thread context push/pop mismatch");
cxstack = nsnull;
JS_GC(cx);
JS_DestroyContext(cx);
} // this scopes the nsCOMPtrs
+#ifdef MOZ_IPC
+ if (!XRE_ShutdownTestShell())
+ NS_ERROR("problem shutting down testshell");
+#endif
+
#ifdef MOZ_CRASHREPORTER
// Get the crashreporter service while XPCOM is still active.
// This is a special exception: it will remain usable after NS_ShutdownXPCOM().
nsCOMPtr<nsICrashReporter> crashReporter =
do_GetService("@mozilla.org/toolkit/crash-reporter;1");
#endif
// no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
--- a/layout/generic/nsFrameFrame.cpp
+++ b/layout/generic/nsFrameFrame.cpp
@@ -176,16 +176,17 @@ public:
#ifdef ACCESSIBILITY
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
#endif
// nsIFrameFrame
NS_IMETHOD GetDocShell(nsIDocShell **aDocShell);
NS_IMETHOD BeginSwapDocShells(nsIFrame* aOther);
virtual void EndSwapDocShells(nsIFrame* aOther);
+ virtual nsIFrame* GetFrame() { return this; }
// nsIReflowCallback
virtual PRBool ReflowFinished();
virtual void ReflowCallbackCanceled();
protected:
// Helper method to look up the HTML marginwidth & marginheight attributes
nsIntSize GetMarginAttributes();
@@ -622,62 +623,26 @@ nsSubDocumentFrame::Reflow(nsPresContext
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK;
}
PRBool
nsSubDocumentFrame::ReflowFinished()
{
- nsCOMPtr<nsIDocShell> docShell;
- GetDocShell(getter_AddRefs(docShell));
-
- nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell));
-
- // resize the sub document
- if (baseWindow) {
- PRInt32 x = 0;
- PRInt32 y = 0;
+ if (mFrameLoader) {
+ nsWeakFrame weakFrame(this);
- nsWeakFrame weakFrame(this);
-
- nsPresContext* presContext = PresContext();
- baseWindow->GetPositionAndSize(&x, &y, nsnull, nsnull);
-
- if (!weakFrame.IsAlive()) {
- // GetPositionAndSize() killed us
- return PR_FALSE;
- }
+ mFrameLoader->UpdatePositionAndSize(this);
- // GetPositionAndSize might have resized us. So now is the time to
- // get our size.
- mPostedReflowCallback = PR_FALSE;
-
- nsSize innerSize(GetSize());
- if (IsInline()) {
- nsMargin usedBorderPadding = GetUsedBorderAndPadding();
-
- // Sadly, XUL smacks the frame size without changing the used
- // border and padding, so we can't trust those. Subtracting
- // them might make things negative.
- innerSize.width -= usedBorderPadding.LeftRight();
- innerSize.width = NS_MAX(innerSize.width, 0);
-
- innerSize.height -= usedBorderPadding.TopBottom();
- innerSize.height = NS_MAX(innerSize.height, 0);
- }
-
- PRInt32 cx = presContext->AppUnitsToDevPixels(innerSize.width);
- PRInt32 cy = presContext->AppUnitsToDevPixels(innerSize.height);
- baseWindow->SetPositionAndSize(x, y, cx, cy, PR_FALSE);
- } else {
- // Make sure that we can post a reflow callback in the future.
- mPostedReflowCallback = PR_FALSE;
+ if (weakFrame.IsAlive()) {
+ // Make sure that we can post a reflow callback in the future.
+ mPostedReflowCallback = PR_FALSE;
+ }
}
-
return PR_FALSE;
}
void
nsSubDocumentFrame::ReflowCallbackCanceled()
{
mPostedReflowCallback = PR_FALSE;
}
--- a/layout/generic/nsIFrameFrame.h
+++ b/layout/generic/nsIFrameFrame.h
@@ -60,11 +60,13 @@ public:
*/
NS_IMETHOD BeginSwapDocShells(nsIFrame* aOther) = 0;
virtual void EndSwapDocShells(nsIFrame* aOther) = 0;
/**
* The frameloader informs us what kind of widget to create during Show()
*/
virtual nsIView* CreateViewAndWidget(nsContentType aContentType) = 0;
+
+ virtual nsIFrame* GetFrame() = 0;
};
#endif
--- a/netwerk/Makefile.in
+++ b/netwerk/Makefile.in
@@ -51,16 +51,22 @@ DIRS = \
socket \
mime \
streamconv \
cache \
protocol \
system \
$(NULL)
+ifdef MOZ_IPC
+DIRS += \
+ ipc \
+ $(NULL)
+endif
+
ifdef NECKO_WIFI
DIRS += wifi
endif
DIRS += \
build \
locales \
$(NULL)
--- a/netwerk/build.mk
+++ b/netwerk/build.mk
@@ -40,20 +40,17 @@
ifndef tier_nspr_dirs
include $(topsrcdir)/config/nspr/build.mk
endif
ifndef tier_xpcom_dirs
include $(topsrcdir)/xpcom/build.mk
endif
-TIERS += zlib \
- necko \
- $(NULL)
-
+TIERS += zlib
ifndef MOZ_NATIVE_ZLIB
tier_zlib_dirs += modules/zlib
endif
#
# tier "necko" - the networking library and its dependencies
#
--- a/netwerk/build/Makefile.in
+++ b/netwerk/build/Makefile.in
@@ -58,16 +58,23 @@ SHARED_LIBRARY_LIBS = \
../base/src/$(LIB_PREFIX)neckobase_s.$(LIB_SUFFIX) \
../dns/src/$(LIB_PREFIX)neckodns_s.$(LIB_SUFFIX) \
../socket/base/$(LIB_PREFIX)neckosocket_s.$(LIB_SUFFIX) \
../streamconv/src/$(LIB_PREFIX)nkconv_s.$(LIB_SUFFIX) \
../streamconv/converters/$(LIB_PREFIX)nkcnvts_s.$(LIB_SUFFIX) \
../mime/src/$(LIB_PREFIX)nkmime_s.$(LIB_SUFFIX) \
../cache/src/$(LIB_PREFIX)nkcache_s.$(LIB_SUFFIX) \
../protocol/about/src/$(LIB_PREFIX)nkabout_s.$(LIB_SUFFIX) \
+ $(NULL)
+
+ifdef MOZ_IPC
+SHARED_LIBRARY_LIBS += ../ipc/$(LIB_PREFIX)neckoipc_s.$(LIB_SUFFIX)
+endif
+
+SHARED_LIBRARY_LIBS += \
$(foreach d,$(filter-out about,$(NECKO_PROTOCOLS)), \
../protocol/$(d)/src/$(LIB_PREFIX)nk$(d)_s.$(LIB_SUFFIX)) \
$(NULL)
ifeq ($(OS_ARCH),WINNT)
SHARED_LIBRARY_LIBS += \
../system/win32/$(LIB_PREFIX)neckosystem_s.$(LIB_SUFFIX)
endif
@@ -149,15 +156,17 @@ EXTRA_DSO_LDOPTS += \
$(TK_LIBS) \
$(NULL)
endif
ifeq ($(OS_ARCH),AIX)
EXTRA_DSO_LDOPTS += -lodm -lcfg
endif
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH),WINNT)
OS_LIBS += $(call EXPAND_LIBNAME,ole32 shell32)
endif
DEFINES += -DIMPL_NS_NET
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -32,16 +32,20 @@
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "necko-config.h"
+#ifdef MOZ_IPC
+#include "base/basictypes.h"
+#endif
+
#include "nsCOMPtr.h"
#include "nsIModule.h"
#include "nsIClassInfoImpl.h"
#include "nsIGenericFactory.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsICategoryManager.h"
#include "nsSocketProviderService.h"
--- a/netwerk/dns/src/nsIDNKitInterface.h
+++ b/netwerk/dns/src/nsIDNKitInterface.h
@@ -87,16 +87,17 @@ typedef enum {
typedef struct idn_nameprep *idn_nameprep_t;
/*
* The latest version of nameprep.
*/
#define IDN_NAMEPREP_CURRENT "nameprep-11"
+#undef assert
#define assert(a)
#define TRACE(a)
/* race.c */
idn_result_t race_decode_decompress(const char *from,
PRUint16 *buf,
size_t buflen);
new file mode 100644
--- /dev/null
+++ b/netwerk/ipc/Makefile.in
@@ -0,0 +1,65 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Firefox.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s): Jason Duell
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = necko
+
+LIBRARY_NAME = neckoipc_s
+LIBXUL_LIBRARY = 1
+FORCE_STATIC_LIB = 1
+EXPORT_LIBRARY = 1
+
+EXPORTS_NAMESPACES = mozilla/net
+
+EXPORTS_mozilla/net = \
+ NeckoParent.h \
+ NeckoChild.h \
+ $(NULL)
+
+CPPSRCS = \
+ NeckoChild.cpp \
+ NeckoParent.cpp \
+ $(NULL)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/net/NeckoChild.h"
+#include "mozilla/dom/ContentProcessChild.h"
+#include "mozilla/net/HttpChannelChild.h"
+
+namespace mozilla {
+namespace net {
+
+PNeckoChild *gNeckoChild = nsnull;
+
+// C++ file contents
+NeckoChild::NeckoChild()
+{
+}
+
+NeckoChild::~NeckoChild()
+{
+}
+
+void NeckoChild::InitNeckoChild()
+{
+ if (XRE_GetProcessType() == GeckoProcessType_Content) {
+ mozilla::dom::ContentProcessChild * cpc =
+ mozilla::dom::ContentProcessChild::GetSingleton();
+ NS_ASSERTION(cpc, "Content Protocol is NULL!");
+ gNeckoChild = cpc->SendPNeckoConstructor();
+ NS_ASSERTION(gNeckoChild, "PNecko Protocol init failed!");
+ }
+}
+
+PHttpChannelChild*
+NeckoChild::AllocPHttpChannel()
+{
+ return new HttpChannelChild();
+}
+
+bool
+NeckoChild::DeallocPHttpChannel(PHttpChannelChild* channel)
+{
+ delete channel;
+ return true;
+}
+
+}} // mozilla::net
+
new file mode 100644
--- /dev/null
+++ b/netwerk/ipc/NeckoChild.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_net_NeckoChild_h
+#define mozilla_net_NeckoChild_h
+
+#include "mozilla/net/PNeckoChild.h"
+#include "mozilla/net/HttpChannelChild.h"
+#include "nsXULAppAPI.h"
+
+namespace mozilla {
+namespace net {
+
+// Header file contents
+class NeckoChild :
+ public PNeckoChild
+{
+public:
+ NeckoChild();
+ virtual ~NeckoChild();
+
+ static void InitNeckoChild();
+
+ virtual PHttpChannelChild* AllocPHttpChannel();
+ virtual bool DeallocPHttpChannel(PHttpChannelChild*);
+
+protected:
+};
+
+/**
+ * Reference to the PNecko Child protocol.
+ * Null if this is not a content process.
+ */
+extern PNeckoChild *gNeckoChild;
+
+static inline PRBool
+IsNeckoChild()
+{
+ return XRE_GetProcessType() == GeckoProcessType_Content;
+}
+
+} // namespace net
+} // namespace mozilla
+
+#endif // mozilla_net_NeckoChild_h
new file mode 100644
--- /dev/null
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/net/NeckoParent.h"
+#include "mozilla/net/HttpChannelParent.h"
+
+namespace mozilla {
+namespace net {
+
+// C++ file contents
+NeckoParent::NeckoParent()
+{
+}
+
+NeckoParent::~NeckoParent()
+{
+}
+
+PHttpChannelParent*
+NeckoParent::AllocPHttpChannel()
+{
+ return new HttpChannelParent();
+}
+
+bool
+NeckoParent::DeallocPHttpChannel(PHttpChannelParent* channel)
+{
+ delete channel;
+ return true;
+}
+
+
+}} // mozilla::net
+
new file mode 100644
--- /dev/null
+++ b/netwerk/ipc/NeckoParent.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/net/PNeckoParent.h"
+#include "mozilla/net/HttpChannelChild.h"
+
+#ifndef mozilla_net_NeckoParent_h
+#define mozilla_net_NeckoParent_h
+
+namespace mozilla {
+namespace net {
+
+// Header file contents
+class NeckoParent :
+ public PNeckoParent
+{
+public:
+ NeckoParent();
+ virtual ~NeckoParent();
+
+protected:
+ virtual PHttpChannelParent* AllocPHttpChannel();
+ virtual bool DeallocPHttpChannel(PHttpChannelParent*);
+};
+
+} // namespace net
+} // namespace mozilla
+
+#endif // mozilla_net_NeckoParent_h
new file mode 100644
--- /dev/null
+++ b/netwerk/ipc/PNecko.ipdl
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol "PContentProcess.ipdl";
+include protocol "PHttpChannel.ipdl";
+
+namespace mozilla {
+namespace net {
+
+
+//-------------------------------------------------------------------
+protocol PNecko
+{
+ manager PContentProcess;
+ manages PHttpChannel;
+
+parent:
+ __delete__();
+
+ PHttpChannel();
+};
+
+
+} // namespace net
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/netwerk/ipc/ipdl.mk
@@ -0,0 +1,40 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Firefox.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s): Jason Duell
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+IPDLSRCS = \
+ PNecko.ipdl \
+ $(NULL)
+
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/src/HttpChannelChild.cpp
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/net/HttpChannelChild.h"
+#include "mozilla/dom/ContentProcessChild.h"
+
+namespace mozilla {
+namespace net {
+
+// C++ file contents
+HttpChannelChild::HttpChannelChild()
+{
+}
+
+HttpChannelChild::~HttpChannelChild()
+{
+}
+
+}} // mozilla::net
+
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/src/HttpChannelChild.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_net_HttpChannelChild_h
+#define mozilla_net_HttpChannelChild_h
+
+#include "mozilla/net/PHttpChannelChild.h"
+#include "nsXULAppAPI.h"
+
+namespace mozilla {
+namespace net {
+
+// Header file contents
+class HttpChannelChild :
+ public PHttpChannelChild
+{
+public:
+ HttpChannelChild();
+ virtual ~HttpChannelChild();
+
+protected:
+};
+
+
+} // namespace net
+} // namespace mozilla
+
+#endif // mozilla_net_HttpChannelChild_h
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/src/HttpChannelParent.cpp
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/net/HttpChannelParent.h"
+
+namespace mozilla {
+namespace net {
+
+// C++ file contents
+HttpChannelParent::HttpChannelParent()
+{
+}
+
+HttpChannelParent::~HttpChannelParent()
+{
+}
+
+//-----------------------------------------------------------------------------
+//
+bool HttpChannelParent::RecvasyncOpen(const nsCString& uri)
+{
+ puts("[HttpChannelParent] got asyncOpen msg");
+ return true;
+}
+
+}} // mozilla::net
+
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/src/HttpChannelParent.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_net_HttpChannelParent_h
+#define mozilla_net_HttpChannelParent_h
+
+#include "mozilla/net/PHttpChannelParent.h"
+
+namespace mozilla {
+namespace net {
+
+// Header file contents
+class HttpChannelParent :
+ public PHttpChannelParent
+{
+public:
+ HttpChannelParent();
+ virtual ~HttpChannelParent();
+
+protected:
+ virtual bool RecvasyncOpen(const nsCString& uri);
+};
+
+} // namespace net
+} // namespace mozilla
+
+#endif // mozilla_net_HttpChannelParent_h
--- a/netwerk/protocol/http/src/Makefile.in
+++ b/netwerk/protocol/http/src/Makefile.in
@@ -41,16 +41,24 @@ srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = necko
LIBRARY_NAME = nkhttp_s
LIBXUL_LIBRARY = 1
+ifdef MOZ_IPC
+EXPORTS_NAMESPACES = mozilla/net
+
+EXPORTS_mozilla/net = \
+ HttpChannelParent.h \
+ HttpChannelChild.h \
+ $(NULL)
+endif
CPPSRCS = \
nsHttp.cpp \
nsHttpHeaderArray.cpp \
nsHttpConnectionInfo.cpp \
nsHttpConnection.cpp \
nsHttpConnectionMgr.cpp \
nsHttpRequestHead.cpp \
@@ -63,17 +71,26 @@ CPPSRCS = \
nsHttpNTLMAuth.cpp \
nsHttpTransaction.cpp \
nsHttpHandler.cpp \
nsHttpChannel.cpp \
nsHttpPipeline.cpp \
nsHttpActivityDistributor.cpp \
$(NULL)
+ifdef MOZ_IPC
+CPPSRCS += \
+ HttpChannelParent.cpp \
+ HttpChannelChild.cpp \
+ $(NULL)
+endif
+
LOCAL_INCLUDES=-I$(srcdir)/../../../base/src -I$(topsrcdir)/xpcom/ds
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
DEFINES += -DIMPL_NS_NET
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/src/PHttpChannel.ipdl
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jason Duell <jduell.mcbugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol "PNecko.ipdl";
+
+namespace mozilla {
+namespace net {
+
+
+//-------------------------------------------------------------------
+protocol PHttpChannel
+{
+ manager PNecko;
+
+parent:
+ __delete__();
+
+ asyncOpen(nsCString uri);
+};
+
+
+} // namespace net
+} // namespace mozilla
+
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/src/ipdl.mk
@@ -0,0 +1,40 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Firefox.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s): Jason Duell
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+IPDLSRCS = \
+ PHttpChannel.ipdl \
+ $(NULL)
+
--- a/netwerk/protocol/http/src/nsHttp.h
+++ b/netwerk/protocol/http/src/nsHttp.h
@@ -39,16 +39,20 @@
#ifndef nsHttp_h__
#define nsHttp_h__
#if defined(MOZ_LOGGING)
#define FORCE_PR_LOG
#endif
+#ifdef MOZ_IPC
+#include "mozilla/net/NeckoChild.h"
+#endif
+
#include "plstr.h"
#include "prlog.h"
#include "prtime.h"
#include "nsISupportsUtils.h"
#include "nsPromiseFlatString.h"
#include "nsURLHelper.h"
#include "netCore.h"
@@ -62,16 +66,17 @@
// set NSPR_LOG_FILE=http.log
//
// this enables PR_LOG_ALWAYS level information and places all output in
// the file http.log
//
extern PRLogModuleInfo *gHttpLog;
#endif
+#undef LOG
// http logging
#define LOG1(args) PR_LOG(gHttpLog, 1, args)
#define LOG2(args) PR_LOG(gHttpLog, 2, args)
#define LOG3(args) PR_LOG(gHttpLog, 3, args)
#define LOG4(args) PR_LOG(gHttpLog, 4, args)
#define LOG(args) LOG4(args)
#define LOG1_ENABLED() PR_LOG_TEST(gHttpLog, 1)
--- a/netwerk/protocol/http/src/nsHttpChunkedDecoder.h
+++ b/netwerk/protocol/http/src/nsHttpChunkedDecoder.h
@@ -34,16 +34,17 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsHttpChunkedDecoder_h__
#define nsHttpChunkedDecoder_h__
+#include "nsHttp.h"
#include "nsError.h"
#include "nsString.h"
#include "nsHttpHeaderArray.h"
class nsHttpChunkedDecoder
{
public:
nsHttpChunkedDecoder() : mTrailers(nsnull)
--- a/netwerk/protocol/http/src/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/src/nsHttpHandler.cpp
@@ -89,16 +89,21 @@
#include <Carbon/Carbon.h>
#endif
#if defined(XP_OS2)
#define INCL_DOSMISC
#include <os2.h>
#endif
+//-----------------------------------------------------------------------------
+#ifdef MOZ_IPC
+using namespace mozilla::net;
+#endif
+
#ifdef DEBUG
// defined by the socket transport service while active
extern PRThread *gSocketThread;
#endif
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
@@ -220,16 +225,21 @@ nsHttpHandler::Init()
return rv;
mIOService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
NS_WARNING("unable to continue without io service");
return rv;
}
+#ifdef MOZ_IPC
+ if (IsNeckoChild() && !gNeckoChild)
+ NeckoChild::InitNeckoChild();
+#endif // MOZ_IPC
+
InitUserAgentComponents();
// monitor some preference changes
nsCOMPtr<nsIPrefBranch2> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefBranch) {
prefBranch->AddObserver(HTTP_PREF_PREFIX, this, PR_TRUE);
prefBranch->AddObserver(UA_PREF_PREFIX, this, PR_TRUE);
prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, PR_TRUE);
--- a/netwerk/protocol/http/src/nsHttpHeaderArray.h
+++ b/netwerk/protocol/http/src/nsHttpHeaderArray.h
@@ -34,22 +34,22 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsHttpHeaderArray_h__
#define nsHttpHeaderArray_h__
+#include "nsHttp.h"
#include "nsTArray.h"
#include "nsIHttpChannel.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsCOMPtr.h"
#include "nsString.h"
-#include "nsHttp.h"
class nsHttpHeaderArray
{
public:
nsHttpHeaderArray() {}
~nsHttpHeaderArray() { Clear(); }
const char *PeekHeader(nsHttpAtom header);
--- a/netwerk/protocol/http/src/nsHttpRequestHead.h
+++ b/netwerk/protocol/http/src/nsHttpRequestHead.h
@@ -34,18 +34,18 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsHttpRequestHead_h__
#define nsHttpRequestHead_h__
+#include "nsHttp.h"
#include "nsHttpHeaderArray.h"
-#include "nsHttp.h"
#include "nsString.h"
#include "nsCRT.h"
//-----------------------------------------------------------------------------
// nsHttpRequestHead represents the request line and headers from an HTTP
// request.
//-----------------------------------------------------------------------------
--- a/security/manager/ssl/src/nsSmartCardEvent.cpp
+++ b/security/manager/ssl/src/nsSmartCardEvent.cpp
@@ -123,16 +123,30 @@ NS_IMETHODIMP_(nsEvent*) nsSmartCardEven
}
NS_IMETHODIMP nsSmartCardEvent::SetTrusted(PRBool aResult)
{
NS_ASSERTION(mPrivate, "SmartCardEvent called without Init");
return mPrivate->SetTrusted(aResult);
}
+void
+nsSmartCardEvent::Serialize(IPC::Message* aMsg,
+ PRBool aSerializeInterfaceType)
+{
+ NS_ASSERTION(mPrivate, "SmartCardEvent called without Init");
+ mPrivate->Serialize(aMsg, aSerializeInterfaceType);
+}
+
+PRBool
+nsSmartCardEvent::Deserialize(const IPC::Message* aMsg, void** aIter)
+{
+ NS_ASSERTION(mPrivate, "SmartCardEvent called without Init");
+ return mPrivate->Deserialize(aMsg, aIter);
+}
// IDOMNSEvent maps
NS_IMETHODIMP nsSmartCardEvent::GetOriginalTarget(nsIDOMEventTarget * *aOriginalTarget)
{
NS_ASSERTION(mNSEvent, "SmartCardEvent called without Init");
return mNSEvent->GetOriginalTarget(aOriginalTarget);
}
--- a/security/manager/ssl/src/nsSmartCardEvent.h
+++ b/security/manager/ssl/src/nsSmartCardEvent.h
@@ -61,16 +61,19 @@ public:
NS_DECL_NSIDOMNSEVENT
//NS_DECL_NSIPRIVATEDOMEEVENT
NS_IMETHOD DuplicatePrivateData();
NS_IMETHOD SetTarget(nsIDOMEventTarget *aTarget);
NS_IMETHOD_(nsEvent*) GetInternalNSEvent();
NS_IMETHOD_(PRBool ) IsDispatchStopped();
NS_IMETHOD SetTrusted(PRBool aResult);
+ virtual void Serialize(IPC::Message* aMsg,
+ PRBool aSerializeInterfaceType);
+ virtual PRBool Deserialize(const IPC::Message* aMsg, void** aIter);
NS_DECL_NSIDOMEVENT
protected:
nsCOMPtr<nsIDOMEvent> mInner;
nsCOMPtr<nsIPrivateDOMEvent> mPrivate;
nsCOMPtr<nsIDOMNSEvent> mNSEvent;
nsString mTokenName;
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/fennec-tile-testapp/application.ini
@@ -0,0 +1,11 @@
+[App]
+Vendor=venderr
+Name=tile
+Version=1.0
+BuildID=20060101
+Copyright=Copyright (c) 2006 Mark Finkle
+ID=xulapp@starkravingfinkle.org
+
+[Gecko]
+MinVersion=1.8
+MaxVersion=2.0
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/chrome.manifest
@@ -0,0 +1,1 @@
+content tile file:content/
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/BrowserView.js
@@ -0,0 +1,728 @@
+// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roy Frostig <rfrostig@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let Ci = Components.interfaces;
+
+// --- REMOVE ---
+let noop = function() {};
+let endl = '\n';
+// --------------
+
+function BrowserView(container, visibleRect) {
+ bindAll(this);
+ this.init(container, visibleRect);
+}
+
+/**
+ * A BrowserView maintains state of the viewport (browser, zoom level,
+ * dimensions) and the visible rectangle into the viewport, for every
+ * browser it is given (cf setBrowser()). In updates to the viewport state,
+ * a BrowserView (using its TileManager) renders parts of the page quasi-
+ * intelligently, with guarantees of having rendered and appended all of the
+ * visible browser content (aka the "critical rectangle").
+ *
+ * State is characterized in large part by two rectangles (and an implicit third):
+ * - Viewport: Always rooted at the origin, ie with (left, top) at (0, 0). The
+ * width and height (right and bottom) of this rectangle are that of the
+ * current viewport, which corresponds more or less to the transformed
+ * browser content (scaled by zoom level).
+ * - Visible: Corresponds to the client's viewing rectangle in viewport
+ * coordinates. Has (top, left) corresponding to position, and width & height
+ * corresponding to the clients viewing dimensions. Take note that the top
+ * and left of the visible rect are per-browser state, but that the width
+ * and height persist across setBrowser() calls. This is best explained by
+ * a simple example: user views browser A, pans to position (x0, y0), switches
+ * to browser B, where she finds herself at position (x1, y1), tilts her
+ * device so that visible rectangle's width and height change, and switches
+ * back to browser A. She expects to come back to position (x0, y0), but her
+ * device remains tilted.
+ * - Critical (the implicit one): The critical rectangle is the (possibly null)
+ * intersection of the visible and viewport rectangles. That is, it is that
+ * region of the viewport which is visible to the user. We care about this
+ * because it tells us which region must be rendered as soon as it is dirtied.
+ * The critical rectangle is mostly state that we do not keep in BrowserView
+ * but that our TileManager maintains.
+ *
+ * Example rectangle state configurations:
+ *
+ *
+ * +-------------------------------+
+ * |A |
+ * | |
+ * | |
+ * | |
+ * | +----------------+ |
+ * | |B,C | |
+ * | | | |
+ * | | | |
+ * | | | |
+ * | +----------------+ |
+ * | |
+ * | |
+ * | |
+ * | |
+ * | |
+ * +-------------------------------+
+ *
+ *
+ * A = viewport ; at (0, 0)
+ * B = visible ; at (x, y) where x > 0, y > 0
+ * C = critical ; at (x, y)
+ *
+ *
+ *
+ * +-------------------------------+
+ * |A |
+ * | |
+ * | |
+ * | |
+ * +----+-----------+ |
+ * |B .C | |
+ * | . | |
+ * | . | |
+ * | . | |
+ * +----+-----------+ |
+ * | |
+ * | |
+ * | |
+ * | |
+ * | |
+ * +-------------------------------+
+ *
+ *
+ * A = viewport ; at (0, 0)
+ * B = visible ; at (x, y) where x < 0, y > 0
+ * C = critical ; at (0, y)
+ *
+ *
+ * Maintaining per-browser state is a little bit of a hack involving attaching
+ * an object as the obfuscated dynamic JS property of the browser object, that
+ * hopefully no one but us will touch. See getViewportStateFromBrowser() for
+ * the property name.
+ */
+BrowserView.prototype = (
+function() {
+
+ // -----------------------------------------------------------
+ // Privates
+ //
+
+ const kZoomLevelMin = 0.2;
+ const kZoomLevelMax = 4.0;
+ const kZoomLevelPrecision = 10000;
+
+ function visibleRectToCriticalRect(visibleRect, browserViewportState) {
+ return visibleRect.intersect(browserViewportState.viewportRect);
+ }
+
+ function clampZoomLevel(zl) {
+ let bounded = Math.min(Math.max(kZoomLevelMin, zl), kZoomLevelMax);
+ return Math.round(bounded * kZoomLevelPrecision) / kZoomLevelPrecision;
+ }
+
+ function pageZoomLevel(visibleRect, browserW, browserH) {
+ return clampZoomLevel(visibleRect.width / browserW);
+ }
+
+ function seenBrowser(browser) {
+ return !!(browser.__BrowserView__vps);
+ }
+
+ function initBrowserState(browser, visibleRect) {
+ let [browserW, browserH] = getBrowserDimensions(browser);
+
+ let zoomLevel = pageZoomLevel(visibleRect, browserW, browserH);
+ let viewportRect = (new wsRect(0, 0, browserW, browserH)).scale(zoomLevel, zoomLevel);
+
+ dump('--- initing browser to ---' + endl);
+ browser.__BrowserView__vps = new BrowserView.BrowserViewportState(viewportRect,
+ visibleRect.x,
+ visibleRect.y,
+ zoomLevel);
+ dump(browser.__BrowserView__vps.toString() + endl);
+ dump('--------------------------' + endl);
+ }
+
+ function getViewportStateFromBrowser(browser) {
+ return browser.__BrowserView__vps;
+ }
+
+ function getBrowserDimensions(browser) {
+ return [browser.scrollWidth, browser.scrollHeight];
+ }
+
+ function getContentScrollValues(browser) {
+ let cwu = getBrowserDOMWindowUtils(browser);
+ let scrollX = {};
+ let scrollY = {};
+ cwu.getScrollXY(false, scrollX, scrollY);
+
+ return [scrollX.value, scrollY.value];
+ }
+
+ function getBrowserDOMWindowUtils(browser) {
+ return browser.contentWindow
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ }
+
+ function getNewBatchOperationState() {
+ return {
+ viewportSizeChanged: false,
+ dirtyAll: false
+ };
+ }
+
+ function clampViewportWH(width, height, visibleRect) {
+ let minW = visibleRect.width;
+ let minH = visibleRect.height;
+ return [Math.max(width, minW), Math.max(height, minH)];
+ }
+
+ function initContainer(container, visibleRect) {
+ container.style.width = visibleRect.width + 'px';
+ container.style.height = visibleRect.height + 'px';
+ container.style.overflow = '-moz-hidden-unscrollable';
+ }
+
+ function resizeContainerToViewport(container, viewportRect) {
+ container.style.width = viewportRect.width + 'px';
+ container.style.height = viewportRect.height + 'px';
+ }
+
+ // !!! --- RESIZE HACK BEGIN -----
+ function simulateMozAfterSizeChange(browser, width, height) {
+ let ev = document.createElement("MouseEvents");
+ ev.initEvent("FakeMozAfterSizeChange", false, false, window, 0, width, height);
+ browser.dispatchEvent(ev);
+ }
+ // !!! --- RESIZE HACK END -------
+
+ // --- Change of coordinates functions --- //
+
+
+ // The following returned object becomes BrowserView.prototype
+ return {
+
+ // -----------------------------------------------------------
+ // Public instance methods
+ //
+
+ init: function init(container, visibleRect) {
+ this._batchOps = [];
+ this._container = container;
+ this._browserViewportState = null;
+ this._renderMode = 0;
+ this._tileManager = new TileManager(this._appendTile, this._removeTile, this);
+ this.setVisibleRect(visibleRect);
+
+ // !!! --- RESIZE HACK BEGIN -----
+ // remove this eventually
+ this._resizeHack = {
+ maxSeenW: 0,
+ maxSeenH: 0
+ };
+ // !!! --- RESIZE HACK END -------
+ },
+
+ setVisibleRect: function setVisibleRect(r) {
+ let bvs = this._browserViewportState;
+ let vr = this._visibleRect;
+
+ if (!vr)
+ this._visibleRect = vr = r.clone();
+ else
+ vr.copyFrom(r);
+
+ if (bvs) {
+ bvs.visibleX = vr.left;
+ bvs.visibleY = vr.top;
+
+ // reclamp minimally to the new visible rect
+ //this.setViewportDimensions(bvs.viewportRect.right, bvs.viewportRect.bottom);
+ } else
+ this._viewportChanged(false, false);
+ },
+
+ getVisibleRect: function getVisibleRect() {
+ return this._visibleRect.clone();
+ },
+
+ getVisibleRectX: function getVisibleRectX() { return this._visibleRect.x; },
+ getVisibleRectY: function getVisibleRectY() { return this._visibleRect.y; },
+ getVisibleRectWidth: function getVisibleRectWidth() { return this._visibleRect.width; },
+ getVisibleRectHeight: function getVisibleRectHeight() { return this._visibleRect.height; },
+
+ setViewportDimensions: function setViewportDimensions(width, height, causedByZoom) {
+ let bvs = this._browserViewportState;
+ let vis = this._visibleRect;
+
+ if (!bvs)
+ return;
+
+ //[width, height] = clampViewportWH(width, height, vis);
+ bvs.viewportRect.right = width;
+ bvs.viewportRect.bottom = height;
+
+ // XXX we might not want the user's page to disappear from under them
+ // at this point, which could happen if the container gets resized such
+ // that visible rect becomes entirely outside of viewport rect. might
+ // be wise to define what UX should be in this case, like a move occurs.
+ // then again, we could also argue this is the responsibility of the
+ // caller who would do such a thing...
+
+ this._viewportChanged(true, !!causedByZoom);
+ },
+
+ setZoomLevel: function setZoomLevel(zl) {
+ let bvs = this._browserViewportState;
+
+ if (!bvs)
+ return;
+
+ let newZL = clampZoomLevel(zl);
+
+ if (newZL != bvs.zoomLevel) {
+ let browserW = this.viewportToBrowser(bvs.viewportRect.right);
+ let browserH = this.viewportToBrowser(bvs.viewportRect.bottom);
+ bvs.zoomLevel = newZL; // side-effect: now scale factor in transformations is newZL
+ this.setViewportDimensions(this.browserToViewport(browserW),
+ this.browserToViewport(browserH));
+ }
+ },
+
+ getZoomLevel: function getZoomLevel() {
+ let bvs = this._browserViewportState;
+ if (!bvs)
+ return undefined;
+
+ return bvs.zoomLevel;
+ },
+
+ beginBatchOperation: function beginBatchOperation() {
+ this._batchOps.push(getNewBatchOperationState());
+ this.pauseRendering();
+ },
+
+ commitBatchOperation: function commitBatchOperation() {
+ let bops = this._batchOps;
+
+ if (bops.length == 0)
+ return;
+
+ let opState = bops.pop();
+ this._viewportChanged(opState.viewportSizeChanged, opState.dirtyAll);
+ this.resumeRendering();
+ },
+
+ discardBatchOperation: function discardBatchOperation() {
+ let bops = this._batchOps;
+ bops.pop();
+ this.resumeRendering();
+ },
+
+ discardAllBatchOperations: function discardAllBatchOperations() {
+ let bops = this._batchOps;
+ while (bops.length > 0)
+ this.discardBatchOperation();
+ },
+
+ moveVisibleBy: function moveVisibleBy(dx, dy) {
+ let vr = this._visibleRect;
+ let vs = this._browserViewportState;
+
+ this.onBeforeVisibleMove(dx, dy);
+ this.onAfterVisibleMove(dx, dy);
+ },
+
+ moveVisibleTo: function moveVisibleTo(x, y) {
+ let visibleRect = this._visibleRect;
+ let dx = x - visibleRect.x;
+ let dy = y - visibleRect.y;
+ this.moveBy(dx, dy);
+ },
+
+ /**
+ * Calls to this function need to be one-to-one with calls to
+ * resumeRendering()
+ */
+ pauseRendering: function pauseRendering() {
+ this._renderMode++;
+ },
+
+ /**
+ * Calls to this function need to be one-to-one with calls to
+ * pauseRendering()
+ */
+ resumeRendering: function resumeRendering(renderNow) {
+ if (this._renderMode > 0)
+ this._renderMode--;
+
+ if (renderNow || this._renderMode == 0)
+ this._tileManager.criticalRectPaint();
+ },
+
+ isRendering: function isRendering() {
+ return (this._renderMode == 0);
+ },
+
+ /**
+ * @param dx Guess delta to destination x coordinate
+ * @param dy Guess delta to destination y coordinate
+ */
+ onBeforeVisibleMove: function onBeforeVisibleMove(dx, dy) {
+ let vs = this._browserViewportState;
+ let vr = this._visibleRect;
+
+ let destCR = visibleRectToCriticalRect(vr.clone().translate(dx, dy), vs);
+
+ this._tileManager.beginCriticalMove(destCR);
+ },
+
+ /**
+ * @param dx Actual delta to destination x coordinate
+ * @param dy Actual delta to destination y coordinate
+ */
+ onAfterVisibleMove: function onAfterVisibleMove(dx, dy) {
+ let vs = this._browserViewportState;
+ let vr = this._visibleRect;
+
+ vr.translate(dx, dy);
+ vs.visibleX = vr.left;
+ vs.visibleY = vr.top;
+
+ let cr = visibleRectToCriticalRect(vr, vs);
+
+ this._tileManager.endCriticalMove(cr, this.isRendering());
+ },
+
+ setBrowser: function setBrowser(browser, skipZoom) {
+ let currentBrowser = this._browser;
+
+ let browserChanged = (currentBrowser !== browser);
+
+ if (currentBrowser) {
+ currentBrowser.removeEventListener("MozAfterPaint", this.handleMozAfterPaint, false);
+
+ // !!! --- RESIZE HACK BEGIN -----
+ // change to the real event type and perhaps refactor the handler function name
+ currentBrowser.removeEventListener("FakeMozAfterSizeChange", this.handleMozAfterSizeChange, false);
+ // !!! --- RESIZE HACK END -------
+
+ this.discardAllBatchOperations();
+
+ currentBrowser.setAttribute("type", "content");
+ currentBrowser.docShell.isOffScreenBrowser = false;
+ }
+
+ this._restoreBrowser(browser);
+
+ browser.setAttribute("type", "content-primary");
+
+ this.beginBatchOperation();
+
+ browser.addEventListener("MozAfterPaint", this.handleMozAfterPaint, false);
+
+ // !!! --- RESIZE HACK BEGIN -----
+ // change to the real event type and perhaps refactor the handler function name
+ browser.addEventListener("FakeMozAfterSizeChange", this.handleMozAfterSizeChange, false);
+ // !!! --- RESIZE HACK END -------
+
+ if (!skipZoom) {
+ browser.docShell.isOffScreenBrowser = true;
+ this.zoomToPage();
+ }
+
+ this._viewportChanged(browserChanged, browserChanged);
+
+ this.commitBatchOperation();
+ },
+
+ handleMozAfterPaint: function handleMozAfterPaint(ev) {
+ let browser = this._browser;
+ let tm = this._tileManager;
+ let vs = this._browserViewportState;
+
+ let [scrollX, scrollY] = getContentScrollValues(browser);
+ let clientRects = ev.clientRects;
+
+ // !!! --- RESIZE HACK BEGIN -----
+ // remove this, cf explanation in loop below
+ let hack = this._resizeHack;
+ let hackSizeChanged = false;
+ // !!! --- RESIZE HACK END -------
+
+ let rects = [];
+ // loop backwards to avoid xpconnect penalty for .length
+ for (let i = clientRects.length - 1; i >= 0; --i) {
+ let e = clientRects.item(i);
+ let r = new wsRect(e.left + scrollX,
+ e.top + scrollY,
+ e.width, e.height);
+
+ this.browserToViewportRect(r);
+ r.round();
+
+ if (r.right < 0 || r.bottom < 0)
+ continue;
+
+ // !!! --- RESIZE HACK BEGIN -----
+ // remove this. this is where we make 'lazy' calculations
+ // that hint at a browser size change and fake the size change
+ // event dispach
+ if (r.right > hack.maxW) {
+ hack.maxW = rect.right;
+ hackSizeChanged = true;
+ }
+ if (r.bottom > hack.maxH) {
+ hack.maxH = rect.bottom;
+ hackSizeChanged = true;
+ }
+ // !!! --- RESIZE HACK END -------
+
+ r.restrictTo(vs.viewportRect);
+ rects.push(r);
+ }
+
+ // !!! --- RESIZE HACK BEGIN -----
+ // remove this, cf explanation in loop above
+ if (hackSizeChanged)
+ simulateMozAfterSizeChange(browser, hack.maxW, hack.maxH);
+ // !!! --- RESIZE HACK END -------
+
+ tm.dirtyRects(rects, this.isRendering());
+ },
+
+ handleMozAfterSizeChange: function handleMozAfterPaint(ev) {
+ // !!! --- RESIZE HACK BEGIN -----
+ // get the correct properties off of the event, these are wrong because
+ // we're using a MouseEvent since it has an X and Y prop of some sort and
+ // we piggyback on that.
+ let w = ev.screenX;
+ let h = ev.screenY;
+ // !!! --- RESIZE HACK END -------
+
+ this.setViewportDimensions(w, h);
+ },
+
+ zoomToPage: function zoomToPage() {
+ let browser = this._browser;
+
+ if (!browser)
+ return;
+
+ let [w, h] = getBrowserDimensions(browser);
+ this.setZoomLevel(pageZoomLevel(this._visibleRect, w, h));
+ },
+
+ zoom: function zoom(aDirection) {
+ if (aDirection == 0)
+ return;
+
+ var zoomDelta = 0.05; // 1/20
+ if (aDirection >= 0)
+ zoomDelta *= -1;
+
+ this.zoomLevel = this._zoomLevel + zoomDelta;
+ },
+
+ viewportToBrowser: function viewportToBrowser(x) {
+ let bvs = this._browserViewportState;
+
+ if (!bvs)
+ throw "No browser is set";
+
+ return x / bvs.zoomLevel;
+ },
+
+ browserToViewport: function browserToViewport(x) {
+ let bvs = this._browserViewportState;
+
+ if (!bvs)
+ throw "No browser is set";
+
+ return x * bvs.zoomLevel;
+ },
+
+ viewportToBrowserRect: function viewportToBrowserRect(rect) {
+ let f = this.viewportToBrowser(1.0);
+ return rect.scale(f, f);
+ },
+
+ browserToViewportRect: function browserToViewportRect(rect) {
+ let f = this.browserToViewport(1.0);
+ return rect.scale(f, f);
+ },
+
+ browserToViewportCanvasContext: function browserToViewportCanvasContext(ctx) {
+ let f = this.browserToViewport(1.0);
+ ctx.scale(f, f);
+ },
+
+
+ // -----------------------------------------------------------
+ // Private instance methods
+ //
+
+ _restoreBrowser: function _restoreBrowser(browser) {
+ let vr = this._visibleRect;
+
+ if (!seenBrowser(browser))
+ initBrowserState(browser, vr);
+
+ let bvs = getViewportStateFromBrowser(browser);
+
+ this._contentWindow = browser.contentWindow;
+ this._browser = browser;
+ this._browserViewportState = bvs;
+ vr.left = bvs.visibleX;
+ vr.top = bvs.visibleY;
+ this._tileManager.setBrowser(browser);
+ },
+
+ _viewportChanged: function _viewportChanged(viewportSizeChanged, dirtyAll) {
+ let bops = this._batchOps;
+
+ if (bops.length > 0) {
+ let opState = bops[bops.length - 1];
+
+ if (viewportSizeChanged)
+ opState.viewportSizeChanged = viewportSizeChanged;
+
+ if (dirtyAll)
+ opState.dirtyAll = dirtyAll;
+
+ return;
+ }
+
+ let bvs = this._browserViewportState;
+ let vis = this._visibleRect;
+
+ // !!! --- RESIZE HACK BEGIN -----
+ // We want to uncomment this for perf, but we can't with the hack in place
+ // because the mozAfterPaint gives us rects that we use to create the
+ // fake mozAfterResize event, so we can't just clear things.
+ /*
+ if (dirtyAll) {
+ // We're about to mark the entire viewport dirty, so we can clear any
+ // queued afterPaint events that will cause redundant draws
+ getBrowserDOMWindowUtils(this._browser).clearMozAfterPaintEvents();
+ }
+ */
+ // !!! --- RESIZE HACK END -------
+
+ if (bvs) {
+ resizeContainerToViewport(this._container, bvs.viewportRect);
+
+ this._tileManager.viewportChangeHandler(bvs.viewportRect,
+ visibleRectToCriticalRect(vis, bvs),
+ viewportSizeChanged,
+ dirtyAll);
+ }
+ },
+
+ _appendTile: function _appendTile(tile) {
+ let canvas = tile.getContentImage();
+
+ /*
+ canvas.style.position = "absolute";
+ canvas.style.left = tile.x + "px";
+ canvas.style.top = tile.y + "px";
+ */
+
+ canvas.setAttribute("style", "position: absolute; left: " + tile.boundRect.left + "px; " + "top: " + tile.boundRect.top + "px;");
+
+ this._container.appendChild(canvas);
+
+ //dump('++ ' + tile.toString(true) + endl);
+ },
+
+ _removeTile: function _removeTile(tile) {
+ let canvas = tile.getContentImage();
+
+ this._container.removeChild(canvas);
+
+ //dump('-- ' + tile.toString(true) + endl);
+ }
+
+ };
+
+}
+)();
+
+
+// -----------------------------------------------------------
+// Helper structures
+//
+
+BrowserView.BrowserViewportState = function(viewportRect,
+ visibleX,
+ visibleY,
+ zoomLevel) {
+
+ this.init(viewportRect, visibleX, visibleY, zoomLevel);
+};
+
+BrowserView.BrowserViewportState.prototype = {
+
+ init: function init(viewportRect, visibleX, visibleY, zoomLevel) {
+ this.viewportRect = viewportRect;
+ this.visibleX = visibleX;
+ this.visibleY = visibleY;
+ this.zoomLevel = zoomLevel;
+ },
+
+ clone: function clone() {
+ return new BrowserView.BrowserViewportState(this.viewportRect,
+ this.visibleX,
+ this.visibleY,
+ this.zoomLevel);
+ },
+
+ toString: function toString() {
+ let props = ['\tviewportRect=' + this.viewportRect.toString(),
+ '\tvisibleX=' + this.visibleX,
+ '\tvisibleY=' + this.visibleY,
+ '\tzoomLevel=' + this.zoomLevel];
+
+ return '[BrowserViewportState] {\n' + props.join(',\n') + '\n}';
+ }
+
+};
+
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/FooScript.js
@@ -0,0 +1,359 @@
+let noop = function() {};
+Browser = {
+ updateViewportSize: noop
+ /*************************************************************
+ function
+ let browser = document.getElementById("googlenews");
+ let cdoc = browser.contentDocument;
+
+ // These might not exist yet depending on page load state
+ var body = cdoc.body || {};
+ var html = cdoc.documentElement || {};
+
+ var w = Math.max(body.scrollWidth || 0, html.scrollWidth);
+ var h = Math.max(body.scrollHeight || 0, html.scrollHeight);
+
+ window.tileManager.viewportHandler(new wsRect(0, 0, w, h),
+ window.innerWidth,
+ new wsRect(0, 0, window.innerWidth, window.innerHeight),
+ false);
+ *************************************************************/
+};
+let ws = {
+ beginUpdateBatch: noop,
+ panTo: noop,
+ endUpdateBatch: noop
+};
+let Ci = Components.interfaces;
+let bv = null;
+let endl = "\n";
+
+
+function BrowserView() {
+ this.init();
+ bindAll(this);
+}
+
+BrowserView.prototype = {
+
+ // --- PROPERTIES ---
+ // public:
+ // init()
+ // getViewportInnerBoundsRect(dx, dy)
+ // tileManager
+ // scrollbox
+ //
+ // private:
+ // _scrollbox
+ // _leftbar
+ // _rightbar
+ // _topbar
+ // _browser
+ // _tileManager
+ // _viewportRect
+ // _viewportInnerBoundsRect
+ //
+
+ get tileManager() { return this._tileManager; },
+ get scrollbox() { return this._scrollbox; },
+
+ init: function init() {
+ let scrollbox = document.getElementById("scrollbox")
+ .boxObject
+ .QueryInterface(Components.interfaces.nsIScrollBoxObject);
+ this._scrollbox = scrollbox;
+
+ let leftbar = document.getElementById("left_sidebar");
+ let rightbar = document.getElementById("right_sidebar");
+ let topbar = document.getElementById("top_urlbar");
+ this._leftbar = leftbar;
+ this._rightbar = rightbar;
+ this._topbar = topbar;
+
+ scrollbox.scrollTo(Math.round(leftbar.getBoundingClientRect().right), 0);
+
+ let tileContainer = document.getElementById("tile_container");
+ tileContainer.addEventListener("mousedown", onMouseDown, true);
+ tileContainer.addEventListener("mouseup", onMouseUp, true);
+ tileContainer.addEventListener("mousemove", onMouseMove, true);
+ this._tileContainer = tileContainer;
+
+ let tileManager = new TileManager(this.appendTile, this.removeTile, window.innerWidth);
+ this._tileManager = tileManager;
+
+ let browser = document.getElementById("googlenews");
+ this.setCurrentBrowser(browser, false); // sets this._browser
+
+ let cdoc = browser.contentDocument;
+
+ // These might not exist yet depending on page load state
+ let body = cdoc.body || {};
+ let html = cdoc.documentElement || {};
+
+ let w = Math.max(body.scrollWidth || 0, html.scrollWidth);
+ let h = Math.max(body.scrollHeight || 0, html.scrollHeight);
+
+ let viewportRect = new wsRect(0, 0, w, h);
+ this._viewportRect = viewportRect;
+
+ let viewportInnerBoundsRect = this.getViewportInnerBoundsRect();
+ this._viewportInnerBoundsRect = viewportInnerBoundsRect;
+
+ tileManager.viewportHandler(viewportRect,
+ window.innerWidth,
+ viewportInnerBoundsRect,
+ true);
+ },
+
+ resizeTileContainer: function resizeTileContainer() {
+
+ },
+
+ scrollboxToViewportRect: function scrollboxToViewportRect(rect, clip) {
+ let leftbar = this._leftbar.getBoundingClientRect();
+ let rightbar = this._rightbar.getBoundingClientRect();
+ let topbar = this._topbar.getBoundingClientRect();
+
+ let xtrans = -leftbar.width;
+ let ytrans = -topbar.height;
+ let x = rect.x + xtrans;
+ let y = rect.y + ytrans;
+
+ // XXX we're cheating --- this is not really a clip, but its the only
+ // way this function is used
+ rect.x = (clip) ? Math.max(x, 0) : x;
+ rect.y = (clip) ? Math.max(y, 0) : y;
+
+ return rect;
+ },
+
+ getScrollboxPosition: function getScrollboxPosition() {
+ let x = {};
+ let y = {};
+ this._scrollbox.getPosition(x, y);
+ return [x.value, y.value];
+ },
+
+ getViewportInnerBoundsRect: function getViewportInnerBoundsRect(dx, dy) {
+ if (!dx) dx = 0;
+ if (!dy) dy = 0;
+
+ let w = window.innerWidth;
+ let h = window.innerHeight;
+
+ let leftbar = this._leftbar.getBoundingClientRect();
+ let rightbar = this._rightbar.getBoundingClientRect();
+ let topbar = this._topbar.getBoundingClientRect();
+
+ let leftinner = Math.max(leftbar.right - dx, 0);
+ let rightinner = Math.min(rightbar.left - dx, w);
+ let topinner = Math.max(topbar.bottom - dy, 0);
+
+ let [x, y] = this.getScrollboxPosition();
+
+ return this.scrollboxToViewportRect(new wsRect(x + dx, y + dy, rightinner - leftinner, h - topinner),
+ true);
+ },
+
+ appendTile: function appendTile(tile) {
+ let canvas = tile.contentImage;
+
+ canvas.style.position = "absolute";
+ canvas.style.left = tile.x + "px";
+ canvas.style.top = tile.y + "px";
+
+ let tileContainer = document.getElementById("tile_container");
+ tileContainer.appendChild(canvas);
+
+ dump('++ ' + tile.toString() + endl);
+ },
+
+ removeTile: function removeTile(tile) {
+ let canvas = tile.contentImage;
+
+ let tileContainer = document.getElementById("tile_container");
+ tileContainer.removeChild(canvas);
+
+ dump('-- ' + tile.toString() + endl);
+ },
+
+ scrollBy: function scrollBy(dx, dy) {
+ // TODO
+ this.onBeforeScroll();
+ this.onAfterScroll();
+ },
+
+ // x: current x
+ // y: current y
+ // dx: delta to get to x from current x
+ // dy: delta to get to y from current y
+ onBeforeScroll: function onBeforeScroll(x, y, dx, dy) {
+ this.tileManager.onBeforeScroll(this.getViewportInnerBoundsRect(dx, dy));
+
+ // shouldn't update margin if it doesn't need to be changed
+ let sidebars = document.getElementsByClassName("sidebar");
+ for (let i = 0; i < sidebars.length; i++) {
+ let sidebar = sidebars[i];
+ sidebar.style.margin = (y + dy) + "px 0px 0px 0px";
+ }
+
+ let urlbar = document.getElementById("top_urlbar");
+ urlbar.style.margin = "0px 0px 0px " + (x + dx) + "px";
+ },
+
+ onAfterScroll: function onAfterScroll(x, y, dx, dy) {
+ this.tileManager.onAfterScroll(this.getViewportInnerBoundsRect());
+ },
+
+ setCurrentBrowser: function setCurrentBrowser(browser, skipZoom) {
+ let currentBrowser = this._browser;
+ if (currentBrowser) {
+ // backup state
+ currentBrowser.mZoomLevel = this.zoomLevel;
+ currentBrowser.mPanX = ws._viewingRect.x;
+ currentBrowser.mPanY = ws._viewingRect.y;
+
+ // stop monitor paint events for this browser
+ currentBrowser.removeEventListener("MozAfterPaint", this.handleMozAfterPaint, false);
+ currentBrowser.setAttribute("type", "content");
+ currentBrowser.docShell.isOffScreenBrowser = false;
+ }
+
+ browser.setAttribute("type", "content-primary");
+ if (!skipZoom)
+ browser.docShell.isOffScreenBrowser = true;
+
+ // start monitoring paint events for this browser
+ browser.addEventListener("MozAfterPaint", this.handleMozAfterPaint, false);
+
+ this._browser = browser;
+
+ // endLoading(and startLoading in most cases) calls zoom anyway
+ if (!skipZoom) {
+ this.zoomToPage();
+ }
+
+ if ("mZoomLevel" in browser) {
+ // restore last state
+ ws.beginUpdateBatch();
+ ws.panTo(browser.mPanX, browser.mPanY);
+ this.zoomLevel = browser.mZoomLevel;
+ ws.endUpdateBatch(true);
+
+ // drop the cache
+ delete browser.mZoomLevel;
+ delete browser.mPanX;
+ delete browser.mPanY;
+ }
+
+ this.tileManager.browser = browser;
+ },
+
+ handleMozAfterPaint: function handleMozAfterPaint(ev) {
+ this.tileManager.handleMozAfterPaint(ev);
+ },
+
+ zoomToPage: function zoomToPage() {
+ /********************************************************
+ let needToPanToTop = this._needToPanToTop;
+ // Ensure pages are panned at the top before zooming/painting
+ // combine the initial pan + zoom into a transaction
+ if (needToPanToTop) {
+ ws.beginUpdateBatch();
+ this._needToPanToTop = false;
+ ws.panTo(0, -BrowserUI.toolbarH);
+ }
+ // Adjust the zoomLevel to fit the page contents in our window width
+ let [contentW, ] = this._contentAreaDimensions;
+ let fakeW = this._fakeWidth;
+
+ if (contentW > fakeW)
+ this.zoomLevel = fakeW / contentW;
+
+ if (needToPanToTop)
+ ws.endUpdateBatch();
+ ********************************************************/
+ }
+
+};
+
+
+function onResize(e) {
+ let browser = document.getElementById("googlenews");
+ let cdoc = browser.contentDocument;
+
+ // These might not exist yet depending on page load state
+ var body = cdoc.body || {};
+ var html = cdoc.documentElement || {};
+
+ var w = Math.max(body.scrollWidth || 0, html.scrollWidth);
+ var h = Math.max(body.scrollHeight || 0, html.scrollHeight);
+
+ if (bv)
+ bv.tileManager.viewportHandler(new wsRect(0, 0, w, h),
+ window.innerWidth,
+ bv.getViewportInnerBoundsRect(),
+ true);
+}
+
+function onMouseDown(e) {
+ window._isDragging = true;
+ window._dragStart = {x: e.clientX, y: e.clientY};
+
+ bv.tileManager.startPanning();
+}
+
+function onMouseUp() {
+ window._isDragging = false;
+
+ bv.tileManager.endPanning();
+}
+
+function onMouseMove(e) {
+ if (window._isDragging) {
+ let scrollbox = bv.scrollbox;
+
+ let x = {};
+ let y = {};
+ let w = {};
+ let h = {};
+ scrollbox.getPosition(x, y);
+ scrollbox.getScrolledSize(w, h);
+
+ let dx = window._dragStart.x - e.clientX;
+ let dy = window._dragStart.y - e.clientY;
+
+ // XXX if max(x, 0) > scrollwidth we shouldn't do anything (same for y/height)
+ let newX = Math.max(x.value + dx, 0);
+ let newY = Math.max(y.value + dy, 0);
+
+ if (newX < w.value || newY < h.value) {
+ // clip dx and dy to prevent us from going below 0
+ dx = Math.max(dx, -x.value);
+ dy = Math.max(dy, -y.value);
+
+ bv.onBeforeScroll(x.value, y.value, dx, dy);
+
+ /*dump("==========scroll==========" + endl);
+ dump("delta: " + dx + "," + dy + endl);
+ let xx = {};
+ let yy = {};
+ scrollbox.getPosition(xx, yy);
+ dump(xx.value + "," + yy.value + endl);*/
+
+ scrollbox.scrollBy(dx, dy);
+
+ /*scrollbox.getPosition(xx, yy);
+ dump(xx.value + "," + yy.value + endl);
+ dump("==========================" + endl);*/
+
+ bv.onAfterScroll();
+ }
+ }
+
+ window._dragStart = {x: e.clientX, y: e.clientY};
+}
+
+function onLoad() {
+ bv = new BrowserView();
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/TileManager.js
@@ -0,0 +1,1055 @@
+// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mobile Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roy Frostig <rfrostig@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const kXHTMLNamespaceURI = "http://www.w3.org/1999/xhtml";
+
+// base-2 exponent for width, height of a single tile.
+const kTileExponentWidth = 7;
+const kTileExponentHeight = 7;
+const kTileWidth = Math.pow(2, kTileExponentWidth); // 2^7 = 128
+const kTileHeight = Math.pow(2, kTileExponentHeight); // 2^7 = 128
+const kLazyRoundTimeCap = 500; // millis
+
+
+function bind(f, thisObj) {
+ return function() {
+ return f.apply(thisObj, arguments);
+ };
+}
+
+function bindSome(instance, methodNames) {
+ for each (let methodName in methodNames)
+ if (methodName in instance)
+ instance[methodName] = bind(instance[methodName], instance);
+}
+
+function bindAll(instance) {
+ for (let key in instance)
+ if (instance[key] instanceof Function)
+ instance[key] = bind(instance[key], instance);
+}
+
+
+/**
+ * The Tile Manager!
+ *
+ * @param appendTile The function the tile manager should call in order to
+ * "display" a tile (e.g. append it to the DOM). The argument to this
+ * function is a TileManager.Tile object.
+ * @param removeTile The function the tile manager should call in order to
+ * "undisplay" a tile (e.g. remove it from the DOM). The argument to this
+ * function is a TileManager.Tile object.
+ * @param fakeWidth The width of the widest possible visible rectangle, e.g.
+ * the width of the screen. This is used in setting the zoomLevel.
+ */
+function TileManager(appendTile, removeTile, browserView) {
+ // backref to the BrowserView object that owns us
+ this._browserView = browserView;
+
+ // callbacks to append / remove a tile to / from the parent
+ this._appendTile = appendTile;
+ this._removeTile = removeTile;
+
+ // tile cache holds tile objects and pools them under a given capacity
+ let self = this;
+ this._tileCache = new TileManager.TileCache(function(tile) { self._removeTileSafe(tile); },
+ -1, -1, 110);
+
+ // Rectangle within the viewport that is visible to the user. It is "critical"
+ // in the sense that it must be rendered as soon as it becomes dirty
+ this._criticalRect = null;
+
+ // Current <browser> DOM element, holding the content we wish to render.
+ // This is null when no browser is attached
+ this._browser = null;
+
+ // if we have an outstanding paint timeout, its value is stored here
+ // for cancelling when we end page loads
+ //this._drawTimeout = 0;
+ this._pageLoadResizerTimeout = 0;
+
+ // timeout of the non-visible-tiles-crawler to cache renders from the browser
+ this._idleTileCrawlerTimeout = 0;
+
+ // object that keeps state on our current lazyload crawl
+ this._crawler = null;
+
+ // the max right coordinate we've seen from paint events
+ // while we were loading a page. If we see something that's bigger than
+ // our width, we'll trigger a page zoom.
+ this._pageLoadMaxRight = 0;
+ this._pageLoadMaxBottom = 0;
+
+ // Tells us to pan to top before first draw
+ this._needToPanToTop = false;
+}
+
+TileManager.prototype = {
+
+ setBrowser: function setBrowser(b) { this._browser = b; },
+
+ // This is the callback fired by our client whenever the viewport
+ // changed somehow (or didn't change but someone asked it to update).
+ viewportChangeHandler: function viewportChangeHandler(viewportRect,
+ criticalRect,
+ boundsSizeChanged,
+ dirtyAll) {
+ // !!! --- DEBUG BEGIN -----
+ dump("***vphandler***\n");
+ dump(viewportRect.toString() + "\n");
+ dump(criticalRect.toString() + "\n");
+ dump(boundsSizeChanged + "\n");
+ dump(dirtyAll + "\n***************\n");
+ // !!! --- DEBUG END -------
+
+ let tc = this._tileCache;
+
+ tc.iBound = Math.ceil(viewportRect.right / kTileWidth);
+ tc.jBound = Math.ceil(viewportRect.bottom / kTileHeight);
+
+ if (!criticalRect || !criticalRect.equals(this._criticalRect)) {
+ this.beginCriticalMove(criticalRect);
+ this.endCriticalMove(criticalRect, !boundsSizeChanged);
+ }
+
+ if (boundsSizeChanged) {
+ // TODO fastpath if !dirtyAll
+ this.dirtyRects([viewportRect.clone()], true);
+ }
+ },
+
+ dirtyRects: function dirtyRects(rects, doCriticalRender) {
+ let criticalIsDirty = false;
+ let criticalRect = this._criticalRect;
+
+ for each (let rect in rects) {
+ this._tileCache.forEachIntersectingRect(rect, false, this._dirtyTile, this);
+
+ if (criticalRect && rect.intersects(criticalRect))
+ criticalIsDirty = true;
+ }
+
+ if (criticalIsDirty && doCriticalRender)
+ this.criticalRectPaint();
+ },
+
+ criticalRectPaint: function criticalRectPaint() {
+ let cr = this._criticalRect;
+
+ if (cr) {
+ let [ctrx, ctry] = cr.centerRounded();
+ this.recenterEvictionQueue(ctrx, ctry);
+ this._renderAppendHoldRect(cr);
+ }
+ },
+
+ beginCriticalMove2: function beginCriticalMove(destCriticalRect) {
+ let start = Date.now();
+ function appendNonDirtyTile(tile) {
+ if (!tile.isDirty())
+ this._appendTileSafe(tile);
+ }
+
+ if (destCriticalRect)
+ this._tileCache.forEachIntersectingRect(destCriticalRect, false, appendNonDirtyTile, this);
+ let end = Date.now();
+ dump("start: " + (end-start) + "\n")
+ },
+
+ beginCriticalMove: function beginCriticalMove(destCriticalRect) {
+ /*
+ function appendNonDirtyTile(tile) {
+ if (!tile.isDirty())
+ this._appendTileSafe(tile);
+ }
+ */
+
+ let start = Date.now();
+
+ if (destCriticalRect) {
+
+ let rect = destCriticalRect;
+
+ let create = false;
+
+ // this._tileCache.forEachIntersectingRect(destCriticalRect, false, appendNonDirtyTile, this);
+ let visited = {};
+ let evictGuard = null;
+ if (create) {
+ evictGuard = function evictGuard(tile) {
+ return !visited[tile.toString()];
+ };
+ }
+
+ let starti = rect.left >> kTileExponentWidth;
+ let endi = rect.right >> kTileExponentWidth;
+
+ let startj = rect.top >> kTileExponentHeight;
+ let endj = rect.bottom >> kTileExponentHeight;
+
+ let tile = null;
+ let tc = this._tileCache;
+
+ for (var j = startj; j <= endj; ++j) {
+ for (var i = starti; i <= endi; ++i) {
+
+ // 'this' for getTile needs to be tc
+
+ //tile = this.getTile(i, j, create, evictGuard);
+ //if (!tc.inBounds(i, j)) {
+ if (0 <= i && 0 <= j && i <= tc.iBound && j <= tc.jBound) {
+ //return null;
+ break;
+ }
+
+ tile = null;
+
+ //if (tc._isOccupied(i, j)) {
+ if (!!(tc._tiles[i] && tc._tiles[i][j])) {
+ tile = tc._tiles[i][j];
+ } else if (create) {
+ // NOTE: create is false here
+ tile = tc._createTile(i, j, evictionGuard);
+ if (tile) tile.markDirty();
+ }
+
+ if (tile) {
+ visited[tile.toString()] = true;
+ //fn.call(thisObj, tile);
+ //function appendNonDirtyTile(tile) {
+ //if (!tile.isDirty())
+ if (!tile._dirtyTileCanvas) {
+ //this._appendTileSafe(tile);
+ if (!tile._appended) {
+ let astart = Date.now();
+ this._appendTile(tile);
+ tile._appended = true;
+ let aend = Date.now();
+ dump("append: " + (aend - astart) + "\n");
+ }
+ }
+ //}
+ }
+ }
+ }
+ }
+
+ let end = Date.now();
+ dump("start: " + (end-start) + "\n")
+ },
+
+ endCriticalMove: function endCriticalMove(destCriticalRect, doCriticalPaint) {
+ let start = Date.now();
+
+ let tc = this._tileCache;
+ let cr = this._criticalRect;
+
+ let dcr = destCriticalRect.clone();
+
+ let f = function releaseOldTile(tile) {
+ // release old tile
+ if (!tile.boundRect.intersects(dcr))
+ tc.releaseTile(tile);
+ }
+
+ if (cr)
+ tc.forEachIntersectingRect(cr, false, f, this);
+
+ this._holdRect(destCriticalRect);
+
+ if (cr)
+ cr.copyFrom(destCriticalRect);
+ else
+ this._criticalRect = cr = destCriticalRect;
+
+ let crpstart = Date.now();
+ if (doCriticalPaint)
+ this.criticalRectPaint();
+ dump(" crp: " + (Date.now() - crpstart) + "\n");
+
+ let end = Date.now();
+ dump("end: " + (end - start) + "\n");
+ },
+
+ restartLazyCrawl: function restartLazyCrawl(startRectOrQueue) {
+ if (!startRectOrQueue || startRectOrQueue instanceof Array) {
+ this._crawler = new TileManager.CrawlIterator(this._tileCache);
+
+ if (startRectOrQueue) {
+ let len = startRectOrQueue.length;
+ for (let k = 0; k < len; ++k)
+ this._crawler.enqueue(startRectOrQueue[k].i, startRectOrQueue[k].j);
+ }
+ } else {
+ this._crawler = new TileManager.CrawlIterator(this._tileCache, startRectOrQueue);
+ }
+
+ if (!this._idleTileCrawlerTimeout)
+ this._idleTileCrawlerTimeout = setTimeout(this._idleTileCrawler, 2000, this);
+ },
+
+ stopLazyCrawl: function stopLazyCrawl() {
+ this._idleTileCrawlerTimeout = 0;
+ this._crawler = null;
+
+ let cr = this._criticalRect;
+ if (cr) {
+ let [ctrx, ctry] = cr.centerRounded();
+ this.recenterEvictionQueue(ctrx, ctry);
+ }
+ },
+
+ recenterEvictionQueue: function recenterEvictionQueue(ctrx, ctry) {
+ let ctri = ctrx >> kTileExponentWidth;
+ let ctrj = ctry >> kTileExponentHeight;
+
+ function evictFarTiles(a, b) {
+ let dista = Math.max(Math.abs(a.i - ctri), Math.abs(a.j - ctrj));
+ let distb = Math.max(Math.abs(b.i - ctri), Math.abs(b.j - ctrj));
+ return dista - distb;
+ }
+
+ this._tileCache.sortEvictionQueue(evictFarTiles);
+ },
+
+ _renderTile: function _renderTile(tile) {
+ if (tile.isDirty())
+ tile.render(this._browser, this._browserView);
+ },
+
+ _appendTileSafe: function _appendTileSafe(tile) {
+ if (!tile._appended) {
+ this._appendTile(tile);
+ tile._appended = true;
+ }
+ },
+
+ _removeTileSafe: function _removeTileSafe(tile) {
+ if (tile._appended) {
+ this._removeTile(tile);
+ tile._appended = false;
+ }
+ },
+