nsGenericHTMLFrameElement.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "nsGenericHTMLFrameElement.h"
  6. #include "mozilla/dom/BrowserElementAudioChannel.h"
  7. #include "mozilla/dom/ContentChild.h"
  8. #include "mozilla/dom/HTMLIFrameElement.h"
  9. #include "mozilla/Preferences.h"
  10. #include "mozilla/ErrorResult.h"
  11. #include "GeckoProfiler.h"
  12. #include "mozIApplication.h"
  13. #include "nsAttrValueInlines.h"
  14. #include "nsContentUtils.h"
  15. #include "nsIAppsService.h"
  16. #include "nsIDocShell.h"
  17. #include "nsIDOMDocument.h"
  18. #include "nsIFrame.h"
  19. #include "nsIInterfaceRequestorUtils.h"
  20. #include "nsIPermissionManager.h"
  21. #include "nsIPresShell.h"
  22. #include "nsIScrollable.h"
  23. #include "nsPresContext.h"
  24. #include "nsServiceManagerUtils.h"
  25. #include "nsSubDocumentFrame.h"
  26. #include "nsXULElement.h"
  27. #include "nsAttrValueOrString.h"
  28. using namespace mozilla;
  29. using namespace mozilla::dom;
  30. NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericHTMLFrameElement)
  31. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFrameElement,
  32. nsGenericHTMLElement)
  33. NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
  34. NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenerWindow)
  35. NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAPI)
  36. NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAudioChannels)
  37. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
  38. NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGenericHTMLFrameElement,
  39. nsGenericHTMLElement)
  40. if (tmp->mFrameLoader) {
  41. tmp->mFrameLoader->Destroy();
  42. }
  43. NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader)
  44. NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenerWindow)
  45. NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserElementAPI)
  46. NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserElementAudioChannels)
  47. NS_IMPL_CYCLE_COLLECTION_UNLINK_END
  48. NS_IMPL_ADDREF_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement)
  49. NS_IMPL_RELEASE_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement)
  50. NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsGenericHTMLFrameElement)
  51. NS_INTERFACE_TABLE_INHERITED(nsGenericHTMLFrameElement,
  52. nsIFrameLoaderOwner,
  53. nsIDOMMozBrowserFrame,
  54. nsIMozBrowserFrame)
  55. NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
  56. NS_IMPL_BOOL_ATTR(nsGenericHTMLFrameElement, Mozbrowser, mozbrowser)
  57. int32_t
  58. nsGenericHTMLFrameElement::TabIndexDefault()
  59. {
  60. return 0;
  61. }
  62. nsGenericHTMLFrameElement::~nsGenericHTMLFrameElement()
  63. {
  64. if (mFrameLoader) {
  65. mFrameLoader->Destroy();
  66. }
  67. }
  68. nsresult
  69. nsGenericHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
  70. {
  71. NS_PRECONDITION(aContentDocument, "Null out param");
  72. nsCOMPtr<nsIDOMDocument> document =
  73. do_QueryInterface(GetContentDocument(*nsContentUtils::SubjectPrincipal()));
  74. document.forget(aContentDocument);
  75. return NS_OK;
  76. }
  77. nsIDocument*
  78. nsGenericHTMLFrameElement::GetContentDocument(nsIPrincipal& aSubjectPrincipal)
  79. {
  80. nsCOMPtr<nsPIDOMWindowOuter> win = GetContentWindow();
  81. if (!win) {
  82. return nullptr;
  83. }
  84. nsIDocument *doc = win->GetDoc();
  85. if (!doc) {
  86. return nullptr;
  87. }
  88. // Return null for cross-origin contentDocument.
  89. if (!aSubjectPrincipal.SubsumesConsideringDomain(doc->NodePrincipal())) {
  90. return nullptr;
  91. }
  92. return doc;
  93. }
  94. already_AddRefed<nsPIDOMWindowOuter>
  95. nsGenericHTMLFrameElement::GetContentWindow()
  96. {
  97. EnsureFrameLoader();
  98. if (!mFrameLoader) {
  99. return nullptr;
  100. }
  101. bool depthTooGreat = false;
  102. mFrameLoader->GetDepthTooGreat(&depthTooGreat);
  103. if (depthTooGreat) {
  104. // Claim to have no contentWindow
  105. return nullptr;
  106. }
  107. nsCOMPtr<nsIDocShell> doc_shell;
  108. mFrameLoader->GetDocShell(getter_AddRefs(doc_shell));
  109. if (!doc_shell) {
  110. return nullptr;
  111. }
  112. nsCOMPtr<nsPIDOMWindowOuter> win = doc_shell->GetWindow();
  113. if (!win) {
  114. return nullptr;
  115. }
  116. NS_ASSERTION(win->IsOuterWindow(),
  117. "Uh, this window should always be an outer window!");
  118. return win.forget();
  119. }
  120. void
  121. nsGenericHTMLFrameElement::EnsureFrameLoader()
  122. {
  123. if (!IsInComposedDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) {
  124. // If frame loader is there, we just keep it around, cached
  125. return;
  126. }
  127. // Strangely enough, this method doesn't actually ensure that the
  128. // frameloader exists. It's more of a best-effort kind of thing.
  129. mFrameLoader = nsFrameLoader::Create(this,
  130. nsPIDOMWindowOuter::From(mOpenerWindow),
  131. mNetworkCreated);
  132. if (mIsPrerendered) {
  133. mFrameLoader->SetIsPrerendered();
  134. }
  135. }
  136. nsresult
  137. nsGenericHTMLFrameElement::CreateRemoteFrameLoader(nsITabParent* aTabParent)
  138. {
  139. MOZ_ASSERT(!mFrameLoader);
  140. EnsureFrameLoader();
  141. NS_ENSURE_STATE(mFrameLoader);
  142. mFrameLoader->SetRemoteBrowser(aTabParent);
  143. if (nsSubDocumentFrame* subdocFrame = do_QueryFrame(GetPrimaryFrame())) {
  144. // The reflow for this element already happened while we were waiting
  145. // for the iframe creation. Therefore the subdoc frame didn't have a
  146. // frameloader when UpdatePositionAndSize was supposed to be called in
  147. // ReflowFinished, and we need to do it properly now.
  148. mFrameLoader->UpdatePositionAndSize(subdocFrame);
  149. }
  150. return NS_OK;
  151. }
  152. NS_IMETHODIMP
  153. nsGenericHTMLFrameElement::GetFrameLoaderXPCOM(nsIFrameLoader **aFrameLoader)
  154. {
  155. NS_IF_ADDREF(*aFrameLoader = mFrameLoader);
  156. return NS_OK;
  157. }
  158. NS_IMETHODIMP_(already_AddRefed<nsFrameLoader>)
  159. nsGenericHTMLFrameElement::GetFrameLoader()
  160. {
  161. RefPtr<nsFrameLoader> loader = mFrameLoader;
  162. return loader.forget();
  163. }
  164. NS_IMETHODIMP
  165. nsGenericHTMLFrameElement::GetParentApplication(mozIApplication** aApplication)
  166. {
  167. if (!aApplication) {
  168. return NS_ERROR_FAILURE;
  169. }
  170. *aApplication = nullptr;
  171. nsIPrincipal *principal = NodePrincipal();
  172. uint32_t appId = principal->GetAppId();
  173. nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
  174. if (NS_WARN_IF(!appsService)) {
  175. return NS_ERROR_FAILURE;
  176. }
  177. nsresult rv = appsService->GetAppByLocalId(appId, aApplication);
  178. if (NS_WARN_IF(NS_FAILED(rv))) {
  179. return rv;
  180. }
  181. return NS_OK;
  182. }
  183. void
  184. nsGenericHTMLFrameElement::PresetOpenerWindow(mozIDOMWindowProxy* aWindow, ErrorResult& aRv)
  185. {
  186. MOZ_ASSERT(!mFrameLoader);
  187. mOpenerWindow = nsPIDOMWindowOuter::From(aWindow);
  188. }
  189. void
  190. nsGenericHTMLFrameElement::InternalSetFrameLoader(nsIFrameLoader* aNewFrameLoader)
  191. {
  192. mFrameLoader = static_cast<nsFrameLoader*>(aNewFrameLoader);
  193. }
  194. void
  195. nsGenericHTMLFrameElement::SwapFrameLoaders(HTMLIFrameElement& aOtherLoaderOwner,
  196. ErrorResult& rv)
  197. {
  198. if (&aOtherLoaderOwner == this) {
  199. // nothing to do
  200. return;
  201. }
  202. aOtherLoaderOwner.SwapFrameLoaders(this, rv);
  203. }
  204. void
  205. nsGenericHTMLFrameElement::SwapFrameLoaders(nsXULElement& aOtherLoaderOwner,
  206. ErrorResult& rv)
  207. {
  208. aOtherLoaderOwner.SwapFrameLoaders(this, rv);
  209. }
  210. void
  211. nsGenericHTMLFrameElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherLoaderOwner,
  212. mozilla::ErrorResult& rv)
  213. {
  214. RefPtr<nsFrameLoader> loader = GetFrameLoader();
  215. RefPtr<nsFrameLoader> otherLoader = aOtherLoaderOwner->GetFrameLoader();
  216. if (!loader || !otherLoader) {
  217. rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
  218. return;
  219. }
  220. rv = loader->SwapWithOtherLoader(otherLoader, this, aOtherLoaderOwner);
  221. }
  222. NS_IMETHODIMP
  223. nsGenericHTMLFrameElement::SetIsPrerendered()
  224. {
  225. MOZ_ASSERT(!mFrameLoader, "Please call SetIsPrerendered before frameLoader is created");
  226. mIsPrerendered = true;
  227. return NS_OK;
  228. }
  229. nsresult
  230. nsGenericHTMLFrameElement::LoadSrc()
  231. {
  232. EnsureFrameLoader();
  233. if (!mFrameLoader) {
  234. return NS_OK;
  235. }
  236. nsresult rv = mFrameLoader->LoadFrame();
  237. #ifdef DEBUG
  238. if (NS_FAILED(rv)) {
  239. NS_WARNING("failed to load URL");
  240. }
  241. #endif
  242. return rv;
  243. }
  244. nsresult
  245. nsGenericHTMLFrameElement::BindToTree(nsIDocument* aDocument,
  246. nsIContent* aParent,
  247. nsIContent* aBindingParent,
  248. bool aCompileEventHandlers)
  249. {
  250. nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
  251. aBindingParent,
  252. aCompileEventHandlers);
  253. NS_ENSURE_SUCCESS(rv, rv);
  254. if (IsInComposedDoc()) {
  255. NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
  256. "Missing a script blocker!");
  257. PROFILER_LABEL("nsGenericHTMLFrameElement", "BindToTree",
  258. js::ProfileEntry::Category::OTHER);
  259. // We're in a document now. Kick off the frame load.
  260. LoadSrc();
  261. }
  262. // We're now in document and scripts may move us, so clear
  263. // the mNetworkCreated flag.
  264. mNetworkCreated = false;
  265. return rv;
  266. }
  267. void
  268. nsGenericHTMLFrameElement::UnbindFromTree(bool aDeep, bool aNullParent)
  269. {
  270. if (mFrameLoader) {
  271. // This iframe is being taken out of the document, destroy the
  272. // iframe's frame loader (doing that will tear down the window in
  273. // this iframe).
  274. // XXXbz we really want to only partially destroy the frame
  275. // loader... we don't want to tear down the docshell. Food for
  276. // later bug.
  277. mFrameLoader->Destroy();
  278. mFrameLoader = nullptr;
  279. }
  280. nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
  281. }
  282. /* static */ int32_t
  283. nsGenericHTMLFrameElement::MapScrollingAttribute(const nsAttrValue* aValue)
  284. {
  285. int32_t mappedValue = nsIScrollable::Scrollbar_Auto;
  286. if (aValue && aValue->Type() == nsAttrValue::eEnum) {
  287. switch (aValue->GetEnumValue()) {
  288. case NS_STYLE_FRAME_OFF:
  289. case NS_STYLE_FRAME_NOSCROLL:
  290. case NS_STYLE_FRAME_NO:
  291. mappedValue = nsIScrollable::Scrollbar_Never;
  292. break;
  293. }
  294. }
  295. return mappedValue;
  296. }
  297. static bool
  298. PrincipalAllowsBrowserFrame(nsIPrincipal* aPrincipal)
  299. {
  300. nsCOMPtr<nsIPermissionManager> permMgr = mozilla::services::GetPermissionManager();
  301. NS_ENSURE_TRUE(permMgr, false);
  302. uint32_t permission = nsIPermissionManager::DENY_ACTION;
  303. nsresult rv = permMgr->TestPermissionFromPrincipal(aPrincipal, "browser", &permission);
  304. NS_ENSURE_SUCCESS(rv, false);
  305. return permission == nsIPermissionManager::ALLOW_ACTION;
  306. }
  307. /* virtual */ nsresult
  308. nsGenericHTMLFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
  309. const nsAttrValue* aValue,
  310. const nsAttrValue* aOldValue, bool aNotify)
  311. {
  312. if (aValue) {
  313. nsAttrValueOrString value(aValue);
  314. AfterMaybeChangeAttr(aNameSpaceID, aName, &value, aNotify);
  315. } else {
  316. AfterMaybeChangeAttr(aNameSpaceID, aName, nullptr, aNotify);
  317. }
  318. if (aNameSpaceID == kNameSpaceID_None) {
  319. if (aName == nsGkAtoms::scrolling) {
  320. if (mFrameLoader) {
  321. nsIDocShell* docshell = mFrameLoader->GetExistingDocShell();
  322. nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(docshell);
  323. if (scrollable) {
  324. int32_t cur;
  325. scrollable->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, &cur);
  326. int32_t val = MapScrollingAttribute(aValue);
  327. if (cur != val) {
  328. scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, val);
  329. scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, val);
  330. RefPtr<nsPresContext> presContext;
  331. docshell->GetPresContext(getter_AddRefs(presContext));
  332. nsIPresShell* shell = presContext ? presContext->GetPresShell() : nullptr;
  333. nsIFrame* rootScroll = shell ? shell->GetRootScrollFrame() : nullptr;
  334. if (rootScroll) {
  335. shell->FrameNeedsReflow(rootScroll, nsIPresShell::eStyleChange,
  336. NS_FRAME_IS_DIRTY);
  337. }
  338. }
  339. }
  340. }
  341. } else if (aName == nsGkAtoms::mozbrowser) {
  342. mReallyIsBrowser = !!aValue && BrowserFramesEnabled() &&
  343. PrincipalAllowsBrowserFrame(NodePrincipal());
  344. }
  345. }
  346. return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
  347. aOldValue, aNotify);
  348. }
  349. nsresult
  350. nsGenericHTMLFrameElement::OnAttrSetButNotChanged(int32_t aNamespaceID,
  351. nsIAtom* aName,
  352. const nsAttrValueOrString& aValue,
  353. bool aNotify)
  354. {
  355. AfterMaybeChangeAttr(aNamespaceID, aName, &aValue, aNotify);
  356. return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
  357. aValue, aNotify);
  358. }
  359. void
  360. nsGenericHTMLFrameElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
  361. nsIAtom* aName,
  362. const nsAttrValueOrString* aValue,
  363. bool aNotify)
  364. {
  365. if (aNamespaceID == kNameSpaceID_None) {
  366. if (aName == nsGkAtoms::src) {
  367. if (aValue && (!IsHTMLElement(nsGkAtoms::iframe) ||
  368. !HasAttr(kNameSpaceID_None, nsGkAtoms::srcdoc))) {
  369. // Don't propagate error here. The attribute was successfully set,
  370. // that's what we should reflect.
  371. LoadSrc();
  372. }
  373. } else if (aName == nsGkAtoms::name) {
  374. // Propagate "name" to the docshell to make browsing context names live,
  375. // per HTML5.
  376. nsIDocShell* docShell = mFrameLoader ? mFrameLoader->GetExistingDocShell()
  377. : nullptr;
  378. if (docShell) {
  379. if (aValue) {
  380. docShell->SetName(aValue->String());
  381. } else {
  382. docShell->SetName(EmptyString());
  383. }
  384. }
  385. }
  386. }
  387. }
  388. void
  389. nsGenericHTMLFrameElement::DestroyContent()
  390. {
  391. if (mFrameLoader) {
  392. mFrameLoader->Destroy();
  393. mFrameLoader = nullptr;
  394. }
  395. nsGenericHTMLElement::DestroyContent();
  396. }
  397. nsresult
  398. nsGenericHTMLFrameElement::CopyInnerTo(Element* aDest)
  399. {
  400. nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest);
  401. NS_ENSURE_SUCCESS(rv, rv);
  402. nsIDocument* doc = aDest->OwnerDoc();
  403. if (doc->IsStaticDocument() && mFrameLoader) {
  404. nsGenericHTMLFrameElement* dest =
  405. static_cast<nsGenericHTMLFrameElement*>(aDest);
  406. nsFrameLoader* fl = nsFrameLoader::Create(dest, nullptr, false);
  407. NS_ENSURE_STATE(fl);
  408. dest->mFrameLoader = fl;
  409. static_cast<nsFrameLoader*>(mFrameLoader.get())->CreateStaticClone(fl);
  410. }
  411. return rv;
  412. }
  413. bool
  414. nsGenericHTMLFrameElement::IsHTMLFocusable(bool aWithMouse,
  415. bool *aIsFocusable,
  416. int32_t *aTabIndex)
  417. {
  418. if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
  419. return true;
  420. }
  421. *aIsFocusable = nsContentUtils::IsSubDocumentTabbable(this);
  422. if (!*aIsFocusable && aTabIndex) {
  423. *aTabIndex = -1;
  424. }
  425. return false;
  426. }
  427. bool
  428. nsGenericHTMLFrameElement::BrowserFramesEnabled()
  429. {
  430. static bool sMozBrowserFramesEnabled = false;
  431. static bool sBoolVarCacheInitialized = false;
  432. if (!sBoolVarCacheInitialized) {
  433. sBoolVarCacheInitialized = true;
  434. Preferences::AddBoolVarCache(&sMozBrowserFramesEnabled,
  435. "dom.mozBrowserFramesEnabled");
  436. }
  437. return sMozBrowserFramesEnabled;
  438. }
  439. /**
  440. * Return true if this frame element really is a mozbrowser or mozapp. (It
  441. * needs to have the right attributes, and its creator must have the right
  442. * permissions.)
  443. */
  444. /* [infallible] */ nsresult
  445. nsGenericHTMLFrameElement::GetReallyIsBrowserOrApp(bool *aOut)
  446. {
  447. *aOut = mReallyIsBrowser;
  448. return NS_OK;
  449. }
  450. /* [infallible] */ NS_IMETHODIMP
  451. nsGenericHTMLFrameElement::GetReallyIsApp(bool *aOut)
  452. {
  453. nsAutoString manifestURL;
  454. GetAppManifestURL(manifestURL);
  455. *aOut = !manifestURL.IsEmpty();
  456. return NS_OK;
  457. }
  458. namespace {
  459. bool NestedEnabled()
  460. {
  461. static bool sMozNestedEnabled = false;
  462. static bool sBoolVarCacheInitialized = false;
  463. if (!sBoolVarCacheInitialized) {
  464. sBoolVarCacheInitialized = true;
  465. Preferences::AddBoolVarCache(&sMozNestedEnabled,
  466. "dom.ipc.tabs.nested.enabled");
  467. }
  468. return sMozNestedEnabled;
  469. }
  470. } // namespace
  471. /* [infallible] */ NS_IMETHODIMP
  472. nsGenericHTMLFrameElement::GetIsolated(bool *aOut)
  473. {
  474. *aOut = true;
  475. if (!nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
  476. return NS_OK;
  477. }
  478. // Isolation is only disabled if the attribute is present
  479. *aOut = !HasAttr(kNameSpaceID_None, nsGkAtoms::noisolation);
  480. return NS_OK;
  481. }
  482. /*
  483. * Get manifest url of app.
  484. */
  485. void nsGenericHTMLFrameElement::GetManifestURL(nsAString& aManifestURL)
  486. {
  487. aManifestURL.Truncate();
  488. nsAutoString manifestURL;
  489. GetAttr(kNameSpaceID_None, nsGkAtoms::mozapp, manifestURL);
  490. if (manifestURL.IsEmpty()) {
  491. return;
  492. }
  493. // Check permission.
  494. nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
  495. NS_ENSURE_TRUE_VOID(permMgr);
  496. nsIPrincipal *principal = NodePrincipal();
  497. const char* aPermissionType = "embed-apps";
  498. uint32_t permission = nsIPermissionManager::DENY_ACTION;
  499. nsresult rv = permMgr->TestPermissionFromPrincipal(principal,
  500. aPermissionType,
  501. &permission);
  502. NS_ENSURE_SUCCESS_VOID(rv);
  503. if (permission != nsIPermissionManager::ALLOW_ACTION) {
  504. return;
  505. }
  506. nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
  507. NS_ENSURE_TRUE_VOID(appsService);
  508. nsCOMPtr<mozIApplication> app;
  509. appsService->GetAppByManifestURL(manifestURL, getter_AddRefs(app));
  510. if (!app) {
  511. return;
  512. }
  513. aManifestURL.Assign(manifestURL);
  514. }
  515. NS_IMETHODIMP
  516. nsGenericHTMLFrameElement::GetAppManifestURL(nsAString& aOut)
  517. {
  518. aOut.Truncate();
  519. // At the moment, you can't be an app without being a browser.
  520. if (!nsIMozBrowserFrame::GetReallyIsBrowserOrApp()) {
  521. return NS_OK;
  522. }
  523. // Only allow content process to embed an app when nested content
  524. // process is enabled.
  525. if (!XRE_IsParentProcess() &&
  526. !(GetBoolAttr(nsGkAtoms::Remote) && NestedEnabled())){
  527. NS_WARNING("Can't embed-apps. Embed-apps is restricted to in-proc apps "
  528. "or content processes with nested pref enabled, see bug 1097479");
  529. return NS_OK;
  530. }
  531. nsAutoString appManifestURL;
  532. GetManifestURL(appManifestURL);
  533. bool isApp = !appManifestURL.IsEmpty();
  534. if (!isApp) {
  535. // No valid case to get manifest
  536. return NS_OK;
  537. }
  538. if (isApp) {
  539. NS_WARNING("Can not simultaneously be mozapp");
  540. return NS_OK;
  541. }
  542. nsAutoString manifestURL;
  543. if (isApp) {
  544. manifestURL.Assign(appManifestURL);
  545. }
  546. aOut.Assign(manifestURL);
  547. return NS_OK;
  548. }
  549. NS_IMETHODIMP
  550. nsGenericHTMLFrameElement::DisallowCreateFrameLoader()
  551. {
  552. MOZ_ASSERT(!mFrameLoader);
  553. MOZ_ASSERT(!mFrameLoaderCreationDisallowed);
  554. mFrameLoaderCreationDisallowed = true;
  555. return NS_OK;
  556. }
  557. NS_IMETHODIMP
  558. nsGenericHTMLFrameElement::AllowCreateFrameLoader()
  559. {
  560. MOZ_ASSERT(!mFrameLoader);
  561. MOZ_ASSERT(mFrameLoaderCreationDisallowed);
  562. mFrameLoaderCreationDisallowed = false;
  563. return NS_OK;
  564. }
  565. NS_IMETHODIMP
  566. nsGenericHTMLFrameElement::InitializeBrowserAPI()
  567. {
  568. MOZ_ASSERT(mFrameLoader);
  569. InitBrowserElementAPI();
  570. return NS_OK;
  571. }
  572. NS_IMETHODIMP
  573. nsGenericHTMLFrameElement::DestroyBrowserFrameScripts()
  574. {
  575. MOZ_ASSERT(mFrameLoader);
  576. DestroyBrowserElementFrameScripts();
  577. return NS_OK;
  578. }