Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/html/nsBrowserElement.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "nsBrowserElement.h"
8
9
#include "mozilla/Preferences.h"
10
#include "mozilla/Services.h"
11
#include "mozilla/dom/BrowserElementBinding.h"
12
#include "mozilla/dom/DOMRequest.h"
13
#include "mozilla/dom/ScriptSettings.h"
14
#include "mozilla/dom/ToJSValue.h"
15
16
#include "nsComponentManagerUtils.h"
17
#include "nsFrameLoader.h"
18
#include "nsIMozBrowserFrame.h"
19
#include "nsINode.h"
20
#include "nsIPrincipal.h"
21
22
#include "js/Wrapper.h"
23
24
using namespace mozilla::dom;
25
26
namespace mozilla {
27
28
bool
29
nsBrowserElement::IsBrowserElementOrThrow(ErrorResult& aRv)
30
0
{
31
0
  if (mBrowserElementAPI) {
32
0
    return true;
33
0
  }
34
0
  aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
35
0
  return false;
36
0
}
37
38
void
39
nsBrowserElement::InitBrowserElementAPI()
40
0
{
41
0
  RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
42
0
  NS_ENSURE_TRUE_VOID(frameLoader);
43
0
44
0
  if (!frameLoader->OwnerIsMozBrowserFrame()) {
45
0
    return;
46
0
  }
47
0
48
0
  if (!mBrowserElementAPI) {
49
0
    mBrowserElementAPI = do_CreateInstance("@mozilla.org/dom/browser-element-api;1");
50
0
    if (NS_WARN_IF(!mBrowserElementAPI)) {
51
0
      return;
52
0
    }
53
0
  }
54
0
  mBrowserElementAPI->SetFrameLoader(frameLoader);
55
0
}
56
57
void
58
nsBrowserElement::DestroyBrowserElementFrameScripts()
59
0
{
60
0
  if (!mBrowserElementAPI) {
61
0
    return;
62
0
  }
63
0
  mBrowserElementAPI->DestroyFrameScripts();
64
0
}
65
66
void
67
nsBrowserElement::SendMouseEvent(const nsAString& aType,
68
                                 uint32_t aX,
69
                                 uint32_t aY,
70
                                 uint32_t aButton,
71
                                 uint32_t aClickCount,
72
                                 uint32_t aModifiers,
73
                                 ErrorResult& aRv)
74
0
{
75
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
76
0
77
0
  nsresult rv = mBrowserElementAPI->SendMouseEvent(aType,
78
0
                                                   aX,
79
0
                                                   aY,
80
0
                                                   aButton,
81
0
                                                   aClickCount,
82
0
                                                   aModifiers);
83
0
84
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
85
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
86
0
  }
87
0
}
88
89
void
90
nsBrowserElement::SendTouchEvent(const nsAString& aType,
91
                                 const Sequence<uint32_t>& aIdentifiers,
92
                                 const Sequence<int32_t>& aXs,
93
                                 const Sequence<int32_t>& aYs,
94
                                 const Sequence<uint32_t>& aRxs,
95
                                 const Sequence<uint32_t>& aRys,
96
                                 const Sequence<float>& aRotationAngles,
97
                                 const Sequence<float>& aForces,
98
                                 uint32_t aCount,
99
                                 uint32_t aModifiers,
100
                                 ErrorResult& aRv)
101
0
{
102
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
103
0
104
0
  if (aIdentifiers.Length() != aCount ||
105
0
      aXs.Length() != aCount ||
106
0
      aYs.Length() != aCount ||
107
0
      aRxs.Length() != aCount ||
108
0
      aRys.Length() != aCount ||
109
0
      aRotationAngles.Length() != aCount ||
110
0
      aForces.Length() != aCount) {
111
0
    aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
112
0
    return;
113
0
  }
114
0
115
0
  nsresult rv = mBrowserElementAPI->SendTouchEvent(aType,
116
0
                                                   aIdentifiers.Elements(),
117
0
                                                   aXs.Elements(),
118
0
                                                   aYs.Elements(),
119
0
                                                   aRxs.Elements(),
120
0
                                                   aRys.Elements(),
121
0
                                                   aRotationAngles.Elements(),
122
0
                                                   aForces.Elements(),
123
0
                                                   aCount,
124
0
                                                   aModifiers);
125
0
126
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
127
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
128
0
  }
129
0
}
130
131
void
132
nsBrowserElement::GoBack(ErrorResult& aRv)
133
0
{
134
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
135
0
136
0
  nsresult rv = mBrowserElementAPI->GoBack();
137
0
138
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
139
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
140
0
  }
141
0
}
142
143
void
144
nsBrowserElement::GoForward(ErrorResult& aRv)
145
0
{
146
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
147
0
148
0
  nsresult rv = mBrowserElementAPI->GoForward();
149
0
150
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
151
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
152
0
  }
153
0
}
154
155
void
156
nsBrowserElement::Reload(bool aHardReload, ErrorResult& aRv)
157
0
{
158
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
159
0
160
0
  nsresult rv = mBrowserElementAPI->Reload(aHardReload);
161
0
162
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
163
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
164
0
  }
165
0
}
166
167
void
168
nsBrowserElement::Stop(ErrorResult& aRv)
169
0
{
170
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
171
0
172
0
  nsresult rv = mBrowserElementAPI->Stop();
173
0
174
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
175
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
176
0
  }
177
0
}
178
179
already_AddRefed<DOMRequest>
180
nsBrowserElement::Download(const nsAString& aUrl,
181
                           const BrowserElementDownloadOptions& aOptions,
182
                           ErrorResult& aRv)
183
0
{
184
0
  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
185
0
186
0
  RefPtr<DOMRequest> req;
187
0
  nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(mBrowserElementAPI);
188
0
  MOZ_ASSERT(wrappedObj, "Failed to get wrapped JS from XPCOM component.");
189
0
  MOZ_RELEASE_ASSERT(!js::IsWrapper(wrappedObj->GetJSObject()));
190
0
  AutoJSAPI jsapi;
191
0
  if (!jsapi.Init(wrappedObj->GetJSObject())) {
192
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
193
0
    return nullptr;
194
0
  }
195
0
  JSContext* cx = jsapi.cx();
196
0
  JS::Rooted<JS::Value> options(cx);
197
0
  aRv.MightThrowJSException();
198
0
  if (!ToJSValue(cx, aOptions, &options)) {
199
0
    aRv.StealExceptionFromJSContext(cx);
200
0
    return nullptr;
201
0
  }
202
0
  nsresult rv = mBrowserElementAPI->Download(aUrl, options, getter_AddRefs(req));
203
0
204
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
205
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
206
0
    return nullptr;
207
0
  }
208
0
209
0
  return req.forget();
210
0
}
211
212
already_AddRefed<DOMRequest>
213
nsBrowserElement::PurgeHistory(ErrorResult& aRv)
214
0
{
215
0
  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
216
0
217
0
  RefPtr<DOMRequest> req;
218
0
  nsresult rv = mBrowserElementAPI->PurgeHistory(getter_AddRefs(req));
219
0
220
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
221
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
222
0
    return nullptr;
223
0
  }
224
0
225
0
  return req.forget();
226
0
}
227
228
already_AddRefed<DOMRequest>
229
nsBrowserElement::GetScreenshot(uint32_t aWidth,
230
                                uint32_t aHeight,
231
                                const nsAString& aMimeType,
232
                                ErrorResult& aRv)
233
0
{
234
0
  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
235
0
236
0
  RefPtr<DOMRequest> req;
237
0
  nsresult rv = mBrowserElementAPI->GetScreenshot(aWidth, aHeight, aMimeType,
238
0
                                                  getter_AddRefs(req));
239
0
240
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
241
0
    if (rv == NS_ERROR_INVALID_ARG) {
242
0
      aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
243
0
    } else {
244
0
      aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
245
0
    }
246
0
    return nullptr;
247
0
  }
248
0
249
0
  return req.forget();
250
0
}
251
252
void
253
nsBrowserElement::Zoom(float aZoom, ErrorResult& aRv)
254
0
{
255
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
256
0
257
0
  nsresult rv = mBrowserElementAPI->Zoom(aZoom);
258
0
259
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
260
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
261
0
  }
262
0
}
263
264
already_AddRefed<DOMRequest>
265
nsBrowserElement::GetCanGoBack(ErrorResult& aRv)
266
0
{
267
0
  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
268
0
269
0
  RefPtr<DOMRequest> req;
270
0
  nsresult rv = mBrowserElementAPI->GetCanGoBack(getter_AddRefs(req));
271
0
272
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
273
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
274
0
    return nullptr;
275
0
  }
276
0
277
0
  return req.forget();
278
0
}
279
280
already_AddRefed<DOMRequest>
281
nsBrowserElement::GetCanGoForward(ErrorResult& aRv)
282
0
{
283
0
  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
284
0
285
0
  RefPtr<DOMRequest> req;
286
0
  nsresult rv = mBrowserElementAPI->GetCanGoForward(getter_AddRefs(req));
287
0
288
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
289
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
290
0
    return nullptr;
291
0
  }
292
0
293
0
  return req.forget();
294
0
}
295
296
already_AddRefed<DOMRequest>
297
nsBrowserElement::GetContentDimensions(ErrorResult& aRv)
298
0
{
299
0
  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
300
0
301
0
  RefPtr<DOMRequest> req;
302
0
  nsresult rv = mBrowserElementAPI->GetContentDimensions(getter_AddRefs(req));
303
0
304
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
305
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
306
0
    return nullptr;
307
0
  }
308
0
309
0
  return req.forget();
310
0
}
311
312
void
313
nsBrowserElement::FindAll(const nsAString& aSearchString,
314
                          BrowserFindCaseSensitivity aCaseSensitivity,
315
                          ErrorResult& aRv)
316
0
{
317
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
318
0
319
0
  uint32_t caseSensitivity;
320
0
  if (aCaseSensitivity == BrowserFindCaseSensitivity::Case_insensitive) {
321
0
    caseSensitivity = nsIBrowserElementAPI::FIND_CASE_INSENSITIVE;
322
0
  } else {
323
0
    caseSensitivity = nsIBrowserElementAPI::FIND_CASE_SENSITIVE;
324
0
  }
325
0
326
0
  nsresult rv = mBrowserElementAPI->FindAll(aSearchString, caseSensitivity);
327
0
328
0
  if (NS_FAILED(rv)) {
329
0
    aRv.Throw(rv);
330
0
  }
331
0
}
332
333
void
334
nsBrowserElement::FindNext(BrowserFindDirection aDirection,
335
                          ErrorResult& aRv)
336
0
{
337
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
338
0
339
0
  uint32_t direction;
340
0
  if (aDirection == BrowserFindDirection::Backward) {
341
0
    direction = nsIBrowserElementAPI::FIND_BACKWARD;
342
0
  } else {
343
0
    direction = nsIBrowserElementAPI::FIND_FORWARD;
344
0
  }
345
0
346
0
  nsresult rv = mBrowserElementAPI->FindNext(direction);
347
0
348
0
  if (NS_FAILED(rv)) {
349
0
    aRv.Throw(rv);
350
0
  }
351
0
}
352
353
void
354
nsBrowserElement::ClearMatch(ErrorResult& aRv)
355
0
{
356
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
357
0
358
0
  nsresult rv = mBrowserElementAPI->ClearMatch();
359
0
360
0
  if (NS_FAILED(rv)) {
361
0
    aRv.Throw(rv);
362
0
  }
363
0
}
364
365
void
366
nsBrowserElement::AddNextPaintListener(BrowserElementNextPaintEventCallback& aListener,
367
                                       ErrorResult& aRv)
368
0
{
369
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
370
0
371
0
  JS::Rooted<JS::Value> val(RootingCx(),
372
0
                            JS::ObjectOrNullValue(aListener.CallbackOrNull()));
373
0
  nsresult rv = mBrowserElementAPI->AddNextPaintListener(val);
374
0
375
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
376
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
377
0
  }
378
0
}
379
380
void
381
nsBrowserElement::RemoveNextPaintListener(BrowserElementNextPaintEventCallback& aListener,
382
                                          ErrorResult& aRv)
383
0
{
384
0
  NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
385
0
386
0
  JS::Rooted<JS::Value> val(RootingCx(),
387
0
                            JS::ObjectOrNullValue(aListener.CallbackOrNull()));
388
0
  nsresult rv = mBrowserElementAPI->RemoveNextPaintListener(val);
389
0
390
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
391
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
392
0
  }
393
0
}
394
395
already_AddRefed<DOMRequest>
396
nsBrowserElement::ExecuteScript(const nsAString& aScript,
397
                                const BrowserElementExecuteScriptOptions& aOptions,
398
                                ErrorResult& aRv)
399
0
{
400
0
  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
401
0
402
0
  RefPtr<DOMRequest> req;
403
0
  nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(mBrowserElementAPI);
404
0
  MOZ_ASSERT(wrappedObj, "Failed to get wrapped JS from XPCOM component.");
405
0
  MOZ_RELEASE_ASSERT(!js::IsWrapper(wrappedObj->GetJSObject()));
406
0
  AutoJSAPI jsapi;
407
0
  if (!jsapi.Init(wrappedObj->GetJSObject())) {
408
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
409
0
    return nullptr;
410
0
  }
411
0
  JSContext* cx = jsapi.cx();
412
0
  JS::Rooted<JS::Value> options(cx);
413
0
  aRv.MightThrowJSException();
414
0
  if (!ToJSValue(cx, aOptions, &options)) {
415
0
    aRv.StealExceptionFromJSContext(cx);
416
0
    return nullptr;
417
0
  }
418
0
419
0
  nsresult rv = mBrowserElementAPI->ExecuteScript(aScript, options, getter_AddRefs(req));
420
0
421
0
  if (NS_FAILED(rv)) {
422
0
    if (rv == NS_ERROR_INVALID_ARG) {
423
0
      aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
424
0
    } else {
425
0
      aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
426
0
    }
427
0
    return nullptr;
428
0
  }
429
0
430
0
  return req.forget();
431
0
}
432
433
already_AddRefed<DOMRequest>
434
nsBrowserElement::GetWebManifest(ErrorResult& aRv)
435
0
{
436
0
  NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
437
0
438
0
  RefPtr<DOMRequest> req;
439
0
  nsresult rv = mBrowserElementAPI->GetWebManifest(getter_AddRefs(req));
440
0
441
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
442
0
    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
443
0
    return nullptr;
444
0
  }
445
0
446
0
  return req.forget();
447
0
}
448
449
450
451
} // namespace mozilla