Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/sessionstore/nsSessionStoreUtils.cpp
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "nsSessionStoreUtils.h"
6
7
#include "mozilla/dom/Event.h"
8
#include "mozilla/dom/EventListenerBinding.h"
9
#include "mozilla/dom/EventTarget.h"
10
#include "mozilla/dom/ScriptSettings.h"
11
#include "nsPIDOMWindow.h"
12
#include "nsIDocShell.h"
13
14
using namespace mozilla::dom;
15
16
namespace {
17
18
class DynamicFrameEventFilter final : public nsIDOMEventListener
19
{
20
public:
21
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
22
  NS_DECL_CYCLE_COLLECTION_CLASS(DynamicFrameEventFilter)
23
24
  explicit DynamicFrameEventFilter(EventListener* aListener)
25
    : mListener(aListener)
26
0
  { }
27
28
  NS_IMETHODIMP HandleEvent(Event* aEvent) override
29
0
  {
30
0
    if (mListener && TargetInNonDynamicDocShell(aEvent)) {
31
0
      mListener->HandleEvent(*aEvent);
32
0
    }
33
0
34
0
    return NS_OK;
35
0
  }
36
37
private:
38
0
  ~DynamicFrameEventFilter() { }
39
40
  bool TargetInNonDynamicDocShell(Event* aEvent)
41
0
  {
42
0
    EventTarget* target = aEvent->GetTarget();
43
0
    if (!target) {
44
0
      return false;
45
0
    }
46
0
47
0
    nsPIDOMWindowOuter* outer = target->GetOwnerGlobalForBindings();
48
0
    if (!outer) {
49
0
      return false;
50
0
    }
51
0
52
0
    nsIDocShell* docShell = outer->GetDocShell();
53
0
    if (!docShell) {
54
0
      return false;
55
0
    }
56
0
57
0
    bool isDynamic = false;
58
0
    nsresult rv = docShell->GetCreatedDynamically(&isDynamic);
59
0
    return NS_SUCCEEDED(rv) && !isDynamic;
60
0
  }
61
62
  RefPtr<EventListener> mListener;
63
};
64
65
NS_IMPL_CYCLE_COLLECTION(DynamicFrameEventFilter, mListener)
66
67
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DynamicFrameEventFilter)
68
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
69
0
  NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
70
0
NS_INTERFACE_MAP_END
71
72
NS_IMPL_CYCLE_COLLECTING_ADDREF(DynamicFrameEventFilter)
73
NS_IMPL_CYCLE_COLLECTING_RELEASE(DynamicFrameEventFilter)
74
75
} // anonymous namespace
76
77
NS_IMPL_ISUPPORTS(nsSessionStoreUtils, nsISessionStoreUtils)
78
79
NS_IMETHODIMP
80
nsSessionStoreUtils::ForEachNonDynamicChildFrame(mozIDOMWindowProxy* aWindow,
81
                                                 nsISessionStoreUtilsFrameCallback* aCallback)
82
0
{
83
0
  NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
84
0
85
0
  nsCOMPtr<nsPIDOMWindowOuter> outer = nsPIDOMWindowOuter::From(aWindow);
86
0
  NS_ENSURE_TRUE(outer, NS_ERROR_FAILURE);
87
0
88
0
  nsCOMPtr<nsIDocShell> docShell = outer->GetDocShell();
89
0
  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
90
0
91
0
  int32_t length;
92
0
  nsresult rv = docShell->GetChildCount(&length);
93
0
  NS_ENSURE_SUCCESS(rv, rv);
94
0
95
0
  for (int32_t i = 0; i < length; ++i) {
96
0
    nsCOMPtr<nsIDocShellTreeItem> item;
97
0
    docShell->GetChildAt(i, getter_AddRefs(item));
98
0
    NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
99
0
100
0
    nsCOMPtr<nsIDocShell> childDocShell(do_QueryInterface(item));
101
0
    NS_ENSURE_TRUE(childDocShell, NS_ERROR_FAILURE);
102
0
103
0
    bool isDynamic = false;
104
0
    nsresult rv = childDocShell->GetCreatedDynamically(&isDynamic);
105
0
    if (NS_SUCCEEDED(rv) && isDynamic) {
106
0
      continue;
107
0
    }
108
0
109
0
    int32_t childOffset = 0;
110
0
    rv = childDocShell->GetChildOffset(&childOffset);
111
0
    NS_ENSURE_SUCCESS(rv, rv);
112
0
113
0
    aCallback->HandleFrame(item->GetWindow(), childOffset);
114
0
  }
115
0
116
0
  return NS_OK;
117
0
}
118
119
NS_IMETHODIMP
120
nsSessionStoreUtils::AddDynamicFrameFilteredListener(EventTarget* aTarget,
121
                                                     const nsAString& aType,
122
                                                     JS::Handle<JS::Value> aListener,
123
                                                     bool aUseCapture,
124
                                                     JSContext* aCx,
125
                                                     nsISupports** aResult)
126
0
{
127
0
  if (NS_WARN_IF(!aListener.isObject())) {
128
0
    return NS_ERROR_INVALID_ARG;
129
0
  }
130
0
131
0
  NS_ENSURE_TRUE(aTarget, NS_ERROR_NO_INTERFACE);
132
0
133
0
  JS::Rooted<JSObject*> obj(aCx, &aListener.toObject());
134
0
  JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
135
0
  RefPtr<EventListener> listener =
136
0
    new EventListener(aCx, obj, global, GetIncumbentGlobal());
137
0
138
0
  nsCOMPtr<nsIDOMEventListener> filter(new DynamicFrameEventFilter(listener));
139
0
140
0
  nsresult rv = aTarget->AddEventListener(aType, filter, aUseCapture);
141
0
  NS_ENSURE_SUCCESS(rv, rv);
142
0
143
0
  filter.forget(aResult);
144
0
  return NS_OK;
145
0
}
146
147
NS_IMETHODIMP
148
nsSessionStoreUtils::RemoveDynamicFrameFilteredListener(EventTarget* aTarget,
149
                                                        const nsAString& aType,
150
                                                        nsISupports* aListener,
151
                                                        bool aUseCapture)
152
0
{
153
0
  NS_ENSURE_TRUE(aTarget, NS_ERROR_NO_INTERFACE);
154
0
155
0
  nsCOMPtr<nsIDOMEventListener> listener = do_QueryInterface(aListener);
156
0
  NS_ENSURE_TRUE(listener, NS_ERROR_NO_INTERFACE);
157
0
158
0
  aTarget->RemoveEventListener(aType, listener, aUseCapture);
159
0
  return NS_OK;
160
0
}