EmbedChromeListener.cpp 6.09 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "EmbedChromeListener.h"

#include "nsServiceManagerUtils.h"
#include "nsIObserverService.h"
#include "mozilla/embedlite/EmbedLog.h"

#include "nsStringGlue.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIDOMWindow.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMEvent.h"
18 19
#include "nsIURI.h"
#include "nsIDOMDocument.h"
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#include "nsPIDOMWindow.h"
#include "nsIEmbedLiteJSON.h"
#include "nsComponentManagerUtils.h"
#include "nsIVariant.h"
#include "nsHashPropertyBag.h"
#include "nsIDOMWindowUtils.h"
#include "nsIDOMHTMLLinkElement.h"
#include "nsIFocusManager.h"
#include "nsIDocShellTreeItem.h"
#include "nsIWebNavigation.h"

EmbedChromeListener::EmbedChromeListener(nsIDOMWindow* aWin)
  :  DOMWindow(aWin)
  ,  mWindowCounter(0)
{
    if (!mService) {
        mService = do_GetService("@mozilla.org/embedlite-app-service;1");
    }
}

EmbedChromeListener::~EmbedChromeListener()
{
}

44
NS_IMPL_ISUPPORTS(EmbedChromeListener, nsIDOMEventListener)
45 46 47 48 49 50 51 52 53 54

nsresult
GetDOMWindowByNode(nsIDOMNode *aNode, nsIDOMWindow **aDOMWindow)
{
    nsresult rv;
    nsCOMPtr<nsIDOMDocument> ctDoc = do_QueryInterface(aNode, &rv);
    NS_ENSURE_SUCCESS(rv , rv);
    nsCOMPtr<nsIDOMWindow> targetWin;
    rv = ctDoc->GetDefaultView(getter_AddRefs(targetWin));
    NS_ENSURE_SUCCESS(rv , rv);
55
    *aDOMWindow = targetWin.forget().take();
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
    return rv;
}

NS_IMETHODIMP
GetTopWindow(nsIDOMWindow* aWin, nsIDOMWindow **aDOMWindow)
{
    nsCOMPtr<nsIDOMWindow> window;
    nsCOMPtr<nsIWebNavigation> navNav(do_GetInterface(aWin));
    nsCOMPtr<nsIDocShellTreeItem> navItem(do_QueryInterface(navNav));
    NS_ENSURE_TRUE(navItem, NS_ERROR_FAILURE);
    nsCOMPtr<nsIDocShellTreeItem> rootItem;
    navItem->GetRootTreeItem(getter_AddRefs(rootItem));
    nsCOMPtr<nsIDOMWindow> rootWin(do_GetInterface(rootItem));
    NS_ENSURE_TRUE(rootWin, NS_ERROR_FAILURE);
    rootWin->GetTop(getter_AddRefs(window));
71
    *aDOMWindow = window.forget().take();
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    return NS_OK;
}


NS_IMETHODIMP
EmbedChromeListener::HandleEvent(nsIDOMEvent* aEvent)
{
    nsresult rv;
    nsString type;
    if (aEvent) {
        aEvent->GetType(type);
    }
    // LOGT("Event:'%s'", NS_ConvertUTF16toUTF8(type).get());

    nsString messageName;
    nsString message;
    // Just simple property bag support still
    nsCOMPtr<nsIEmbedLiteJSON> json = do_GetService("@mozilla.org/embedlite-json;1", &rv);
    if (!json) {
        LOGT("Failed to create json component");
    }
    nsCOMPtr<nsIWritablePropertyBag2> root;
    json->CreateObject(getter_AddRefs(root));

    nsCOMPtr<nsIDOMWindow> docWin = do_GetInterface(DOMWindow);
    nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(DOMWindow);

    uint32_t winid;
    mService->GetIDByWindow(window, &winid);
    NS_ENSURE_TRUE(winid , NS_ERROR_FAILURE);
102
    mService->EnterSecureJSContext();
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window);

    if (type.EqualsLiteral(MOZ_DOMMetaAdded)) {
        messageName.AssignLiteral("chrome:metaadded");
    } else if (type.EqualsLiteral(MOZ_DOMContentLoaded)) {
        nsCOMPtr<nsIDOMDocument> ctDoc;
        window->GetDocument(getter_AddRefs(ctDoc));
        nsString docURI;
        ctDoc->GetDocumentURI(docURI);
        if (!docURI.EqualsLiteral("about:blank")) {
            messageName.AssignLiteral("chrome:contentloaded");
            root->SetPropertyAsAString(NS_LITERAL_STRING("docuri"), docURI);
        }
        // Need send session history from here
    } else if (type.EqualsLiteral(MOZ_DOMLinkAdded)) {
        nsCOMPtr<nsIDOMEventTarget> origTarget;
        aEvent->GetOriginalTarget(getter_AddRefs(origTarget));
        nsCOMPtr<nsIDOMHTMLLinkElement> disabledIface = do_QueryInterface(origTarget);
        nsString href;
        bool disabled = true;
123
        disabledIface->GetMozDisabled(&disabled);
124
        if (!disabledIface || disabled) {
125
            mService->LeaveSecureJSContext();
126 127 128 129 130
            return NS_OK;
        }
        disabledIface->GetHref(href);
        nsCOMPtr<nsIDOMDocument> ctDoc;
        window->GetDocument(getter_AddRefs(ctDoc));
131 132 133 134
        // ignore on frames and other documents
        nsCOMPtr<nsIDOMDocument> ownDoc;
        nsCOMPtr<nsIDOMNode> node = do_QueryInterface(origTarget);
        node->GetOwnerDocument(getter_AddRefs(ownDoc));
135 136
        if (ownDoc != ctDoc) {
          mService->LeaveSecureJSContext();
137
          return NS_OK;
138
        }
139

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
        nsString charset, title, rel, type;
        ctDoc->GetCharacterSet(charset);
        ctDoc->GetTitle(title);
        disabledIface->GetRel(rel);
        disabledIface->GetType(type);
        nsString sizes;
        nsCOMPtr<nsIDOMElement> element = do_QueryInterface(origTarget);
        bool hasSizesAttr = false;
        if (NS_SUCCEEDED(element->HasAttribute(NS_LITERAL_STRING("sizes"), &hasSizesAttr)) && hasSizesAttr) {
            element->GetAttribute(NS_LITERAL_STRING("sizes"), sizes);
        }
        messageName.AssignLiteral("chrome:linkadded");
        root->SetPropertyAsAString(NS_LITERAL_STRING("href"), href);
        root->SetPropertyAsAString(NS_LITERAL_STRING("charset"), charset);
        root->SetPropertyAsAString(NS_LITERAL_STRING("title"), title);
        root->SetPropertyAsAString(NS_LITERAL_STRING("rel"), rel);
        root->SetPropertyAsAString(NS_LITERAL_STRING("sizes"), sizes);
        root->SetPropertyAsAString(NS_LITERAL_STRING("get"), type);
    } else if (type.EqualsLiteral(MOZ_DOMWillOpenModalDialog) ||
               type.EqualsLiteral(MOZ_DOMModalDialogClosed) ||
               type.EqualsLiteral(MOZ_DOMWindowClose)) {
        messageName.AssignLiteral("chrome:winopenclose");
        root->SetPropertyAsAString(NS_LITERAL_STRING("type"), type);
    } else {
164
        mService->LeaveSecureJSContext();
165 166 167 168 169 170
        return NS_OK;
    }

    nsString outStr;
    json->CreateJSON(root, message);
    mService->SendAsyncMessage(winid, messageName.get(), message.get());
171
    mService->LeaveSecureJSContext();
172 173 174

    return NS_OK;
}