123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "base/basictypes.h"
- #include "TabChild.h"
- #include "gfxPrefs.h"
- #ifdef ACCESSIBILITY
- #include "mozilla/a11y/DocAccessibleChild.h"
- #endif
- #include "Layers.h"
- #include "ContentChild.h"
- #include "TabParent.h"
- #include "mozilla/Preferences.h"
- #include "mozilla/BrowserElementParent.h"
- #include "mozilla/ClearOnShutdown.h"
- #include "mozilla/EventListenerManager.h"
- #include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
- #include "mozilla/plugins/PluginWidgetChild.h"
- #include "mozilla/IMEStateManager.h"
- #include "mozilla/ipc/URIUtils.h"
- #include "mozilla/layers/APZChild.h"
- #include "mozilla/layers/APZCCallbackHelper.h"
- #include "mozilla/layers/APZCTreeManager.h"
- #include "mozilla/layers/APZEventState.h"
- #include "mozilla/layers/ContentProcessController.h"
- #include "mozilla/layers/CompositorBridgeChild.h"
- #include "mozilla/layers/DoubleTapToZoom.h"
- #include "mozilla/layers/ImageBridgeChild.h"
- #include "mozilla/layers/InputAPZContext.h"
- #include "mozilla/layers/ShadowLayers.h"
- #include "mozilla/layout/RenderFrameChild.h"
- #include "mozilla/layout/RenderFrameParent.h"
- #include "mozilla/LookAndFeel.h"
- #include "mozilla/MouseEvents.h"
- #include "mozilla/Move.h"
- #include "mozilla/ProcessHangMonitor.h"
- #include "mozilla/ScopeExit.h"
- #include "mozilla/Services.h"
- #include "mozilla/StaticPtr.h"
- #include "mozilla/TextEvents.h"
- #include "mozilla/TouchEvents.h"
- #include "mozilla/Unused.h"
- #include "mozIApplication.h"
- #include "nsContentUtils.h"
- #include "nsCSSFrameConstructor.h"
- #include "nsDocShell.h"
- #include "nsEmbedCID.h"
- #include "nsGlobalWindow.h"
- #include <algorithm>
- #include "nsFilePickerProxy.h"
- #include "mozilla/dom/Element.h"
- #include "nsGlobalWindow.h"
- #include "nsIBaseWindow.h"
- #include "nsIBrowserDOMWindow.h"
- #include "nsIDocumentInlines.h"
- #include "nsIDocShellTreeOwner.h"
- #include "nsIDOMChromeWindow.h"
- #include "nsIDOMDocument.h"
- #include "nsIDOMEvent.h"
- #include "nsIDOMWindow.h"
- #include "nsIDOMWindowUtils.h"
- #include "nsFocusManager.h"
- #include "EventStateManager.h"
- #include "nsIDocShell.h"
- #include "nsIFrame.h"
- #include "nsIURI.h"
- #include "nsIURIFixup.h"
- #include "nsCDefaultURIFixup.h"
- #include "nsISupportsPrimitives.h"
- #include "nsIWebBrowser.h"
- #include "nsIWebBrowserFocus.h"
- #include "nsIWebBrowserSetup.h"
- #include "nsIWebProgress.h"
- #include "nsIXULRuntime.h"
- #include "nsPIDOMWindow.h"
- #include "nsPIWindowRoot.h"
- #include "nsLayoutUtils.h"
- #include "nsPrintfCString.h"
- #include "nsThreadUtils.h"
- #include "nsViewManager.h"
- #include "nsWeakReference.h"
- #include "nsWindowWatcher.h"
- #include "PermissionMessageUtils.h"
- #include "PuppetWidget.h"
- #include "StructuredCloneData.h"
- #include "nsViewportInfo.h"
- #include "nsILoadContext.h"
- #include "ipc/nsGUIEventIPC.h"
- #include "mozilla/gfx/Matrix.h"
- #include "UnitTransforms.h"
- #include "ClientLayerManager.h"
- #include "LayersLogging.h"
- #include "nsDOMClassInfoID.h"
- #include "nsColorPickerProxy.h"
- #include "nsContentPermissionHelper.h"
- #include "nsPresShell.h"
- #include "nsIAppsService.h"
- #include "nsNetUtil.h"
- #include "nsIPermissionManager.h"
- #include "nsIURILoader.h"
- #include "nsIScriptError.h"
- #include "mozilla/EventForwards.h"
- #include "nsDeviceContext.h"
- #include "nsSandboxFlags.h"
- #include "FrameLayerBuilder.h"
- #include "nsICommandParams.h"
- #include "nsISHistory.h"
- #include "nsQueryObject.h"
- #include "GroupedSHistory.h"
- #include "nsIHttpChannel.h"
- #include "mozilla/dom/DocGroup.h"
- #ifdef NS_PRINTING
- #include "nsIPrintSession.h"
- #include "nsIPrintSettings.h"
- #include "nsIPrintSettingsService.h"
- #include "nsIWebBrowserPrint.h"
- #endif
- #define BROWSER_ELEMENT_CHILD_SCRIPT \
- NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
- #define TABC_LOG(...)
- // #define TABC_LOG(...) printf_stderr("TABC: " __VA_ARGS__)
- using namespace mozilla;
- using namespace mozilla::dom;
- using namespace mozilla::dom::ipc;
- using namespace mozilla::dom::workers;
- using namespace mozilla::ipc;
- using namespace mozilla::layers;
- using namespace mozilla::layout;
- using namespace mozilla::docshell;
- using namespace mozilla::widget;
- using namespace mozilla::jsipc;
- using mozilla::layers::GeckoContentController;
- NS_IMPL_ISUPPORTS(ContentListener, nsIDOMEventListener)
- NS_IMPL_ISUPPORTS(TabChildSHistoryListener,
- nsISHistoryListener,
- nsIPartialSHistoryListener,
- nsISupportsWeakReference)
- static const CSSSize kDefaultViewportSize(980, 480);
- static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
- typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
- static TabChildMap* sTabChildren;
- TabChildBase::TabChildBase()
- : mTabChildGlobal(nullptr)
- {
- mozilla::HoldJSObjects(this);
- }
- TabChildBase::~TabChildBase()
- {
- mAnonymousGlobalScopes.Clear();
- mozilla::DropJSObjects(this);
- }
- NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildBase)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TabChildBase)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChildGlobal)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnonymousGlobalScopes)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebBrowserChrome)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_END
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TabChildBase)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChildGlobal)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebBrowserChrome)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
- NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(TabChildBase)
- tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
- NS_IMPL_CYCLE_COLLECTION_TRACE_END
- NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TabChildBase)
- NS_INTERFACE_MAP_ENTRY(nsISupports)
- NS_INTERFACE_MAP_END
- NS_IMPL_CYCLE_COLLECTING_ADDREF(TabChildBase)
- NS_IMPL_CYCLE_COLLECTING_RELEASE(TabChildBase)
- already_AddRefed<nsIDocument>
- TabChildBase::GetDocument() const
- {
- nsCOMPtr<nsIDOMDocument> domDoc;
- WebNavigation()->GetDocument(getter_AddRefs(domDoc));
- nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
- return doc.forget();
- }
- already_AddRefed<nsIPresShell>
- TabChildBase::GetPresShell() const
- {
- nsCOMPtr<nsIPresShell> result;
- if (nsCOMPtr<nsIDocument> doc = GetDocument()) {
- result = doc->GetShell();
- }
- return result.forget();
- }
- void
- TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
- const nsAString& aJSONData)
- {
- AutoSafeJSContext cx;
- JS::Rooted<JS::Value> json(cx, JS::NullValue());
- StructuredCloneData data;
- if (JS_ParseJSON(cx,
- static_cast<const char16_t*>(aJSONData.BeginReading()),
- aJSONData.Length(),
- &json)) {
- ErrorResult rv;
- data.Write(cx, json, rv);
- if (NS_WARN_IF(rv.Failed())) {
- rv.SuppressException();
- return;
- }
- }
- nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
- // Let the BrowserElementScrolling helper (if it exists) for this
- // content manipulate the frame state.
- RefPtr<nsFrameMessageManager> mm =
- static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
- mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
- aMessageName, false, &data, nullptr, nullptr, nullptr);
- }
- bool
- TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
- {
- MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
- if (aFrameMetrics.IsRootContent()) {
- if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
- // Guard against stale updates (updates meant for a pres shell which
- // has since been torn down and destroyed).
- if (aFrameMetrics.GetPresShellId() == shell->GetPresShellId()) {
- ProcessUpdateFrame(aFrameMetrics);
- return true;
- }
- }
- } else {
- // aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
- // This requires special handling.
- FrameMetrics newSubFrameMetrics(aFrameMetrics);
- APZCCallbackHelper::UpdateSubFrame(newSubFrameMetrics);
- return true;
- }
- return true;
- }
- void
- TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
- {
- if (!mGlobal || !mTabChildGlobal) {
- return;
- }
- FrameMetrics newMetrics = aFrameMetrics;
- APZCCallbackHelper::UpdateRootFrame(newMetrics);
- }
- NS_IMETHODIMP
- ContentListener::HandleEvent(nsIDOMEvent* aEvent)
- {
- RemoteDOMEvent remoteEvent;
- remoteEvent.mEvent = do_QueryInterface(aEvent);
- NS_ENSURE_STATE(remoteEvent.mEvent);
- mTabChild->SendEvent(remoteEvent);
- return NS_OK;
- }
- class TabChild::DelayedDeleteRunnable final
- : public Runnable
- {
- RefPtr<TabChild> mTabChild;
- public:
- explicit DelayedDeleteRunnable(TabChild* aTabChild)
- : mTabChild(aTabChild)
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aTabChild);
- }
- private:
- ~DelayedDeleteRunnable()
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!mTabChild);
- }
- NS_IMETHOD
- Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(mTabChild);
- // Check in case ActorDestroy was called after RecvDestroy message.
- if (mTabChild->IPCOpen()) {
- Unused << PBrowserChild::Send__delete__(mTabChild);
- }
- mTabChild = nullptr;
- return NS_OK;
- }
- };
- namespace {
- StaticRefPtr<TabChild> sPreallocatedTab;
- std::map<TabId, RefPtr<TabChild>>&
- NestedTabChildMap()
- {
- MOZ_ASSERT(NS_IsMainThread());
- static std::map<TabId, RefPtr<TabChild>> sNestedTabChildMap;
- return sNestedTabChildMap;
- }
- } // namespace
- already_AddRefed<TabChild>
- TabChild::FindTabChild(const TabId& aTabId)
- {
- auto iter = NestedTabChildMap().find(aTabId);
- if (iter == NestedTabChildMap().end()) {
- return nullptr;
- }
- RefPtr<TabChild> tabChild = iter->second;
- return tabChild.forget();
- }
- static void
- PreloadSlowThingsPostFork(void* aUnused)
- {
- nsCOMPtr<nsIObserverService> observerService =
- mozilla::services::GetObserverService();
- observerService->NotifyObservers(nullptr, "preload-postfork", nullptr);
- MOZ_ASSERT(sPreallocatedTab);
- // Initialize initial reflow of the PresShell has to happen after fork
- // because about:blank content viewer is created in the above observer
- // notification.
- nsCOMPtr<nsIDocShell> docShell =
- do_GetInterface(sPreallocatedTab->WebNavigation());
- if (nsIPresShell* presShell = docShell->GetPresShell()) {
- // Initialize and do an initial reflow of the about:blank
- // PresShell to let it preload some things for us.
- presShell->Initialize(0, 0);
- nsIDocument* doc = presShell->GetDocument();
- doc->FlushPendingNotifications(Flush_Layout);
- // ... but after it's done, make sure it doesn't do any more
- // work.
- presShell->MakeZombie();
- }
- }
- static bool sPreloaded = false;
- /*static*/ void
- TabChild::PreloadSlowThings()
- {
- if (sPreloaded) {
- // If we are alredy initialized in Nuwa, don't redo preloading.
- return;
- }
- sPreloaded = true;
- // Pass nullptr to aManager since at this point the TabChild is
- // not connected to any manager. Any attempt to use the TabChild
- // in IPC will crash.
- RefPtr<TabChild> tab(new TabChild(nullptr,
- TabId(0),
- TabContext(), /* chromeFlags */ 0));
- if (!NS_SUCCEEDED(tab->Init()) ||
- !tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
- return;
- }
- // Just load and compile these scripts, but don't run them.
- tab->TryCacheLoadAndCompileScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
- // Load, compile, and run these scripts.
- tab->RecvLoadRemoteScript(
- NS_LITERAL_STRING("chrome://global/content/preload.js"),
- true);
- sPreallocatedTab = tab;
- ClearOnShutdown(&sPreallocatedTab);
- PreloadSlowThingsPostFork(nullptr);
- }
- /*static*/ already_AddRefed<TabChild>
- TabChild::Create(nsIContentChild* aManager,
- const TabId& aTabId,
- const TabContext &aContext,
- uint32_t aChromeFlags)
- {
- if (sPreallocatedTab &&
- sPreallocatedTab->mChromeFlags == aChromeFlags &&
- aContext.IsMozBrowserOrApp()) {
- RefPtr<TabChild> child = sPreallocatedTab.get();
- sPreallocatedTab = nullptr;
- MOZ_ASSERT(!child->mTriedBrowserInit);
- child->mManager = aManager;
- child->SetTabId(aTabId);
- child->SetTabContext(aContext);
- child->NotifyTabContextUpdated(true);
- return child.forget();
- }
- RefPtr<TabChild> iframe = new TabChild(aManager, aTabId,
- aContext, aChromeFlags);
- return NS_SUCCEEDED(iframe->Init()) ? iframe.forget() : nullptr;
- }
- TabChild::TabChild(nsIContentChild* aManager,
- const TabId& aTabId,
- const TabContext& aContext,
- uint32_t aChromeFlags)
- : TabContext(aContext)
- , mRemoteFrame(nullptr)
- , mManager(aManager)
- , mChromeFlags(aChromeFlags)
- , mActiveSuppressDisplayport(0)
- , mLayersId(0)
- , mDidFakeShow(false)
- , mNotified(false)
- , mTriedBrowserInit(false)
- , mOrientation(eScreenOrientation_PortraitPrimary)
- , mIgnoreKeyPressEvent(false)
- , mHasValidInnerSize(false)
- , mDestroyed(false)
- , mUniqueId(aTabId)
- , mDPI(0)
- , mRounding(0)
- , mDefaultScale(0)
- , mIsTransparent(false)
- , mIPCOpen(false)
- , mParentIsActive(false)
- , mDidSetRealShowInfo(false)
- , mDidLoadURLInit(false)
- , mIsFreshProcess(false)
- , mLayerObserverEpoch(0)
- #if defined(XP_WIN) && defined(ACCESSIBILITY)
- , mNativeWindowHandle(0)
- #endif
- {
- // In the general case having the TabParent tell us if APZ is enabled or not
- // doesn't really work because the TabParent itself may not have a reference
- // to the owning widget during initialization. Instead we assume that this
- // TabChild corresponds to a widget type that would have APZ enabled, and just
- // check the other conditions necessary for enabling APZ.
- mAsyncPanZoomEnabled = gfxPlatform::AsyncPanZoomEnabled();
- nsWeakPtr weakPtrThis(do_GetWeakReference(static_cast<nsITabChild*>(this))); // for capture by the lambda
- mSetAllowedTouchBehaviorCallback = [weakPtrThis](uint64_t aInputBlockId,
- const nsTArray<TouchBehaviorFlags>& aFlags)
- {
- if (nsCOMPtr<nsITabChild> tabChild = do_QueryReferent(weakPtrThis)) {
- static_cast<TabChild*>(tabChild.get())->SetAllowedTouchBehavior(aInputBlockId, aFlags);
- }
- };
- // preloaded TabChild should not be added to child map
- if (mUniqueId) {
- MOZ_ASSERT(NestedTabChildMap().find(mUniqueId) == NestedTabChildMap().end());
- NestedTabChildMap()[mUniqueId] = this;
- }
- nsCOMPtr<nsIObserverService> observerService =
- mozilla::services::GetObserverService();
- if (observerService) {
- const nsAttrValue::EnumTable* table =
- AudioChannelService::GetAudioChannelTable();
- nsAutoCString topic;
- for (uint32_t i = 0; table[i].tag; ++i) {
- topic.Assign("audiochannel-activity-");
- topic.Append(table[i].tag);
- observerService->AddObserver(this, topic.get(), false);
- }
- }
- for (uint32_t idx = 0; idx < NUMBER_OF_AUDIO_CHANNELS; idx++) {
- mAudioChannelsActive.AppendElement(false);
- }
- }
- NS_IMETHODIMP
- TabChild::Observe(nsISupports *aSubject,
- const char *aTopic,
- const char16_t *aData)
- {
- if (!strcmp(aTopic, BEFORE_FIRST_PAINT)) {
- if (AsyncPanZoomEnabled()) {
- nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject));
- nsCOMPtr<nsIDocument> doc(GetDocument());
- if (SameCOMIdentity(subject, doc)) {
- nsCOMPtr<nsIPresShell> shell(doc->GetShell());
- if (shell) {
- shell->SetIsFirstPaint(true);
- }
- APZCCallbackHelper::InitializeRootDisplayport(shell);
- }
- }
- }
- const nsAttrValue::EnumTable* table =
- AudioChannelService::GetAudioChannelTable();
- nsAutoCString topic;
- int16_t audioChannel = -1;
- for (uint32_t i = 0; table[i].tag; ++i) {
- topic.Assign("audiochannel-activity-");
- topic.Append(table[i].tag);
- if (topic.Equals(aTopic)) {
- audioChannel = table[i].value;
- break;
- }
- }
- if (audioChannel != -1 && mIPCOpen) {
- // If the subject is not a wrapper, it is sent by the TabParent and we
- // should ignore it.
- nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
- if (!wrapper) {
- return NS_OK;
- }
- // We must have a window in order to compare the windowID contained into the
- // wrapper.
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
- if (!window) {
- return NS_OK;
- }
- uint64_t windowID = 0;
- nsresult rv = wrapper->GetData(&windowID);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- // In theory a tabChild should contain just 1 top window, but let's double
- // check it comparing the windowID.
- if (window->WindowID() != windowID) {
- MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
- ("TabChild, Observe, different windowID, owner ID = %lld, "
- "ID from wrapper = %lld", window->WindowID(), windowID));
- return NS_OK;
- }
- nsAutoString activeStr(aData);
- bool active = activeStr.EqualsLiteral("active");
- if (active != mAudioChannelsActive[audioChannel]) {
- mAudioChannelsActive[audioChannel] = active;
- Unused << SendAudioChannelActivityNotification(audioChannel, active);
- }
- }
- return NS_OK;
- }
- void
- TabChild::ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
- uint64_t aInputBlockId,
- bool aPreventDefault) const
- {
- if (mApzcTreeManager) {
- mApzcTreeManager->ContentReceivedInputBlock(aInputBlockId, aPreventDefault);
- }
- }
- void
- TabChild::SetTargetAPZC(uint64_t aInputBlockId,
- const nsTArray<ScrollableLayerGuid>& aTargets) const
- {
- if (mApzcTreeManager) {
- mApzcTreeManager->SetTargetAPZC(aInputBlockId, aTargets);
- }
- }
- void
- TabChild::SetAllowedTouchBehavior(uint64_t aInputBlockId,
- const nsTArray<TouchBehaviorFlags>& aTargets) const
- {
- if (mApzcTreeManager) {
- mApzcTreeManager->SetAllowedTouchBehavior(aInputBlockId, aTargets);
- }
- }
- bool
- TabChild::DoUpdateZoomConstraints(const uint32_t& aPresShellId,
- const ViewID& aViewId,
- const Maybe<ZoomConstraints>& aConstraints)
- {
- if (sPreallocatedTab == this) {
- // If we're the preallocated tab, bail out because doing IPC will crash.
- // Once we get used for something we'll get another zoom constraints update
- // and all will be well.
- return true;
- }
- if (!mApzcTreeManager) {
- return false;
- }
- ScrollableLayerGuid guid = ScrollableLayerGuid(mLayersId, aPresShellId, aViewId);
- mApzcTreeManager->UpdateZoomConstraints(guid, aConstraints);
- return true;
- }
- nsresult
- TabChild::Init()
- {
- nsCOMPtr<nsIWebBrowser> webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
- if (!webBrowser) {
- NS_ERROR("Couldn't create a nsWebBrowser?");
- return NS_ERROR_FAILURE;
- }
- webBrowser->SetContainerWindow(this);
- webBrowser->SetOriginAttributes(OriginAttributesRef());
- mWebNav = do_QueryInterface(webBrowser);
- NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
- nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(WebNavigation()));
- docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
- nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation());
- if (!baseWindow) {
- NS_ERROR("mWebNav doesn't QI to nsIBaseWindow");
- return NS_ERROR_FAILURE;
- }
- nsCOMPtr<nsIWidget> widget = nsIWidget::CreatePuppetWidget(this);
- mPuppetWidget = static_cast<PuppetWidget*>(widget.get());
- if (!mPuppetWidget) {
- NS_ERROR("couldn't create fake widget");
- return NS_ERROR_FAILURE;
- }
- mPuppetWidget->InfallibleCreate(
- nullptr, 0, // no parents
- LayoutDeviceIntRect(0, 0, 0, 0),
- nullptr // HandleWidgetEvent
- );
- baseWindow->InitWindow(0, mPuppetWidget, 0, 0, 0, 0);
- baseWindow->Create();
- // Set the tab context attributes then pass to docShell
- NotifyTabContextUpdated(false);
- // IPC uses a WebBrowser object for which DNS prefetching is turned off
- // by default. But here we really want it, so enable it explicitly
- nsCOMPtr<nsIWebBrowserSetup> webBrowserSetup =
- do_QueryInterface(baseWindow);
- if (webBrowserSetup) {
- webBrowserSetup->SetProperty(nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH,
- true);
- } else {
- NS_WARNING("baseWindow doesn't QI to nsIWebBrowserSetup, skipping "
- "DNS prefetching enable step.");
- }
- nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
- MOZ_ASSERT(docShell);
- docShell->SetAffectPrivateSessionLifetime(
- mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME);
- nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(WebNavigation());
- MOZ_ASSERT(loadContext);
- loadContext->SetPrivateBrowsing(OriginAttributesRef().mPrivateBrowsingId > 0);
- loadContext->SetRemoteTabs(
- mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW);
- // Few lines before, baseWindow->Create() will end up creating a new
- // window root in nsGlobalWindow::SetDocShell.
- // Then this chrome event handler, will be inherited to inner windows.
- // We want to also set it to the docshell so that inner windows
- // and any code that has access to the docshell
- // can all listen to the same chrome event handler.
- // XXX: ideally, we would set a chrome event handler earlier,
- // and all windows, even the root one, will use the docshell one.
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
- NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
- nsCOMPtr<EventTarget> chromeHandler =
- do_QueryInterface(window->GetChromeEventHandler());
- docShell->SetChromeEventHandler(chromeHandler);
- if (window->GetCurrentInnerWindow()) {
- window->SetKeyboardIndicators(ShowAccelerators(), ShowFocusRings());
- } else {
- // Skip ShouldShowFocusRing check if no inner window is available
- window->SetInitialKeyboardIndicators(ShowAccelerators(), ShowFocusRings());
- }
- // Set prerender flag if necessary.
- if (mIsPrerendered) {
- docShell->SetIsPrerendered();
- }
- nsContentUtils::SetScrollbarsVisibility(window->GetDocShell(),
- !!(mChromeFlags & nsIWebBrowserChrome::CHROME_SCROLLBARS));
- nsWeakPtr weakPtrThis = do_GetWeakReference(static_cast<nsITabChild*>(this)); // for capture by the lambda
- ContentReceivedInputBlockCallback callback(
- [weakPtrThis](const ScrollableLayerGuid& aGuid,
- uint64_t aInputBlockId,
- bool aPreventDefault)
- {
- if (nsCOMPtr<nsITabChild> tabChild = do_QueryReferent(weakPtrThis)) {
- static_cast<TabChild*>(tabChild.get())->ContentReceivedInputBlock(aGuid, aInputBlockId, aPreventDefault);
- }
- });
- mAPZEventState = new APZEventState(mPuppetWidget, Move(callback));
- mIPCOpen = true;
- if (GroupedSHistory::GroupedHistoryEnabled()) {
- // Set session history listener.
- nsCOMPtr<nsISHistory> shistory;
- mWebNav->GetSessionHistory(getter_AddRefs(shistory));
- if (!shistory) {
- return NS_ERROR_FAILURE;
- }
- mHistoryListener = new TabChildSHistoryListener(this);
- nsCOMPtr<nsISHistoryListener> listener(do_QueryObject(mHistoryListener));
- shistory->AddSHistoryListener(listener);
- nsCOMPtr<nsIPartialSHistoryListener> partialListener(do_QueryObject(mHistoryListener));
- shistory->SetPartialSHistoryListener(partialListener);
- }
- return NS_OK;
- }
- void
- TabChild::NotifyTabContextUpdated(bool aIsPreallocated)
- {
- nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
- MOZ_ASSERT(docShell);
- if (!docShell) {
- return;
- }
- UpdateFrameType();
- if (aIsPreallocated) {
- nsDocShell::Cast(docShell)->SetOriginAttributes(OriginAttributesRef());
- }
- }
- void
- TabChild::UpdateFrameType()
- {
- nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
- MOZ_ASSERT(docShell);
- // TODO: Bug 1252794 - remove frameType from nsIDocShell.idl
- docShell->SetFrameType(IsMozBrowserElement() ? nsIDocShell::FRAME_TYPE_BROWSER :
- HasOwnApp() ? nsIDocShell::FRAME_TYPE_APP :
- nsIDocShell::FRAME_TYPE_REGULAR);
- }
- NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild)
- NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
- NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
- NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
- NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
- NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
- NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
- NS_INTERFACE_MAP_ENTRY(nsITabChild)
- NS_INTERFACE_MAP_ENTRY(nsIObserver)
- NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
- NS_INTERFACE_MAP_ENTRY(nsITooltipListener)
- NS_INTERFACE_MAP_END_INHERITING(TabChildBase)
- NS_IMPL_ADDREF_INHERITED(TabChild, TabChildBase);
- NS_IMPL_RELEASE_INHERITED(TabChild, TabChildBase);
- NS_IMETHODIMP
- TabChild::SetStatus(uint32_t aStatusType, const char16_t* aStatus)
- {
- return SetStatusWithContext(aStatusType,
- aStatus ? static_cast<const nsString &>(nsDependentString(aStatus))
- : EmptyString(),
- nullptr);
- }
- NS_IMETHODIMP
- TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser)
- {
- NS_WARNING("TabChild::GetWebBrowser not supported in TabChild");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser)
- {
- NS_WARNING("TabChild::SetWebBrowser not supported in TabChild");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::GetChromeFlags(uint32_t* aChromeFlags)
- {
- *aChromeFlags = mChromeFlags;
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::SetChromeFlags(uint32_t aChromeFlags)
- {
- NS_WARNING("trying to SetChromeFlags from content process?");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::DestroyBrowserWindow()
- {
- NS_WARNING("TabChild::DestroyBrowserWindow not supported in TabChild");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::RemoteSizeShellTo(int32_t aWidth, int32_t aHeight,
- int32_t aShellItemWidth, int32_t aShellItemHeight)
- {
- nsCOMPtr<nsIDocShell> ourDocShell = do_GetInterface(WebNavigation());
- nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(ourDocShell));
- int32_t width, height;
- docShellAsWin->GetSize(&width, &height);
- uint32_t flags = 0;
- if (width == aWidth) {
- flags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CX;
- }
- if (height == aHeight) {
- flags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CY;
- }
- bool sent = SendSizeShellTo(flags, aWidth, aHeight, aShellItemWidth, aShellItemHeight);
- return sent ? NS_OK : NS_ERROR_FAILURE;
- }
- NS_IMETHODIMP
- TabChild::RemoteDropLinks(uint32_t aLinksCount, nsIDroppedLinkItem** aLinks)
- {
- nsTArray<nsString> linksArray;
- nsresult rv = NS_OK;
- for (uint32_t i = 0; i < aLinksCount; i++) {
- nsString tmp;
- rv = aLinks[i]->GetUrl(tmp);
- if (NS_FAILED(rv)) {
- return rv;
- }
- linksArray.AppendElement(tmp);
- rv = aLinks[i]->GetName(tmp);
- if (NS_FAILED(rv)) {
- return rv;
- }
- linksArray.AppendElement(tmp);
- rv = aLinks[i]->GetType(tmp);
- if (NS_FAILED(rv)) {
- return rv;
- }
- linksArray.AppendElement(tmp);
- }
- bool sent = SendDropLinks(linksArray);
- return sent ? NS_OK : NS_ERROR_FAILURE;
- }
- NS_IMETHODIMP
- TabChild::SizeBrowserTo(int32_t aWidth, int32_t aHeight)
- {
- NS_WARNING("TabChild::SizeBrowserTo not supported in TabChild");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::ShowAsModal()
- {
- NS_WARNING("TabChild::ShowAsModal not supported in TabChild");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::IsWindowModal(bool* aRetVal)
- {
- *aRetVal = false;
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::ExitModalEventLoop(nsresult aStatus)
- {
- NS_WARNING("TabChild::ExitModalEventLoop not supported in TabChild");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::SetStatusWithContext(uint32_t aStatusType,
- const nsAString& aStatusText,
- nsISupports* aStatusContext)
- {
- // We can only send the status after the ipc machinery is set up,
- // mRemoteFrame is a good indicator.
- if (mRemoteFrame)
- SendSetStatus(aStatusType, nsString(aStatusText));
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY,
- int32_t aCx, int32_t aCy)
- {
- // The parent is in charge of the dimension changes. If JS code wants to
- // change the dimensions (moveTo, screenX, etc.) we send a message to the
- // parent about the new requested dimension, the parent does the resize/move
- // then send a message to the child to update itself. For APIs like screenX
- // this function is called with the current value for the non-changed values.
- // In a series of calls like window.screenX = 10; window.screenY = 10; for
- // the second call, since screenX is not yet updated we might accidentally
- // reset back screenX to it's old value. To avoid this if a parameter did not
- // change we want the parent to ignore its value.
- int32_t x, y, cx, cy;
- GetDimensions(aFlags, &x, &y, &cx, &cy);
- if (x == aX) {
- aFlags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_X;
- }
- if (y == aY) {
- aFlags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_Y;
- }
- if (cx == aCx) {
- aFlags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CX;
- }
- if (cy == aCy) {
- aFlags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CY;
- }
- Unused << SendSetDimensions(aFlags, aX, aY, aCx, aCy);
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::GetDimensions(uint32_t aFlags, int32_t* aX,
- int32_t* aY, int32_t* aCx, int32_t* aCy)
- {
- ScreenIntRect rect = GetOuterRect();
- if (aX) {
- *aX = rect.x;
- }
- if (aY) {
- *aY = rect.y;
- }
- if (aCx) {
- *aCx = rect.width;
- }
- if (aCy) {
- *aCy = rect.height;
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::SetFocus()
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::GetVisibility(bool* aVisibility)
- {
- *aVisibility = true;
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::SetVisibility(bool aVisibility)
- {
- // should the platform support this? Bug 666365
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::GetTitle(char16_t** aTitle)
- {
- NS_WARNING("TabChild::GetTitle not supported in TabChild");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::SetTitle(const char16_t* aTitle)
- {
- // JavaScript sends the "DOMTitleChanged" event to the parent
- // via the message manager.
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::GetSiteWindow(void** aSiteWindow)
- {
- NS_WARNING("TabChild::GetSiteWindow not supported in TabChild");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::Blur()
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChild::FocusNextElement(bool aForDocumentNavigation)
- {
- SendMoveFocus(true, aForDocumentNavigation);
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::FocusPrevElement(bool aForDocumentNavigation)
- {
- SendMoveFocus(false, aForDocumentNavigation);
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::GetInterface(const nsIID & aIID, void **aSink)
- {
- if (aIID.Equals(NS_GET_IID(nsIWebBrowserChrome3))) {
- NS_IF_ADDREF(((nsISupports *) (*aSink = mWebBrowserChrome)));
- return NS_OK;
- }
- // XXXbz should we restrict the set of interfaces we hand out here?
- // See bug 537429
- return QueryInterface(aIID, aSink);
- }
- NS_IMETHODIMP
- TabChild::ProvideWindow(mozIDOMWindowProxy* aParent,
- uint32_t aChromeFlags,
- bool aCalledFromJS,
- bool aPositionSpecified, bool aSizeSpecified,
- nsIURI* aURI, const nsAString& aName,
- const nsACString& aFeatures, bool aForceNoOpener,
- bool* aWindowIsNew, mozIDOMWindowProxy** aReturn)
- {
- *aReturn = nullptr;
- // If aParent is inside an <iframe mozbrowser> or <iframe mozapp> and this
- // isn't a request to open a modal-type window, we're going to create a new
- // <iframe mozbrowser/mozapp> and return its window here.
- nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
- bool iframeMoz = (docshell && docshell->GetIsInMozBrowserOrApp() &&
- !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
- nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
- nsIWebBrowserChrome::CHROME_OPENAS_CHROME)));
- if (!iframeMoz) {
- int32_t openLocation =
- nsWindowWatcher::GetWindowOpenLocation(nsPIDOMWindowOuter::From(aParent),
- aChromeFlags, aCalledFromJS,
- aPositionSpecified, aSizeSpecified);
- // If it turns out we're opening in the current browser, just hand over the
- // current browser's docshell.
- if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
- nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation());
- *aWindowIsNew = false;
- return browser->GetContentDOMWindow(aReturn);
- }
- }
- // Note that ProvideWindowCommon may return NS_ERROR_ABORT if the
- // open window call was canceled. It's important that we pass this error
- // code back to our caller.
- ContentChild* cc = ContentChild::GetSingleton();
- return cc->ProvideWindowCommon(this,
- aParent,
- iframeMoz,
- aChromeFlags,
- aCalledFromJS,
- aPositionSpecified,
- aSizeSpecified,
- aURI,
- aName,
- aFeatures,
- aForceNoOpener,
- aWindowIsNew,
- aReturn);
- }
- void
- TabChild::DestroyWindow()
- {
- nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation());
- if (baseWindow)
- baseWindow->Destroy();
- // NB: the order of mPuppetWidget->Destroy() and mRemoteFrame->Destroy()
- // is important: we want to kill off remote layers before their
- // frames
- if (mPuppetWidget) {
- mPuppetWidget->Destroy();
- }
- if (mRemoteFrame) {
- mRemoteFrame->Destroy();
- mRemoteFrame = nullptr;
- }
- if (mLayersId != 0) {
- MOZ_ASSERT(sTabChildren);
- sTabChildren->Remove(mLayersId);
- if (!sTabChildren->Count()) {
- delete sTabChildren;
- sTabChildren = nullptr;
- }
- mLayersId = 0;
- }
- }
- void
- TabChild::ActorDestroy(ActorDestroyReason why)
- {
- mIPCOpen = false;
- DestroyWindow();
- if (mTabChildGlobal) {
- // We should have a message manager if the global is alive, but it
- // seems sometimes we don't. Assert in aurora/nightly, but don't
- // crash in release builds.
- MOZ_DIAGNOSTIC_ASSERT(mTabChildGlobal->mMessageManager);
- if (mTabChildGlobal->mMessageManager) {
- // The messageManager relays messages via the TabChild which
- // no longer exists.
- static_cast<nsFrameMessageManager*>
- (mTabChildGlobal->mMessageManager.get())->Disconnect();
- mTabChildGlobal->mMessageManager = nullptr;
- }
- }
- CompositorBridgeChild* compositorChild = static_cast<CompositorBridgeChild*>(CompositorBridgeChild::Get());
- compositorChild->CancelNotifyAfterRemotePaint(this);
- if (GetTabId() != 0) {
- NestedTabChildMap().erase(GetTabId());
- }
- }
- TabChild::~TabChild()
- {
- DestroyWindow();
- nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(WebNavigation());
- if (webBrowser) {
- webBrowser->SetContainerWindow(nullptr);
- }
- if (mHistoryListener) {
- mHistoryListener->ClearTabChild();
- }
- }
- void
- TabChild::SetProcessNameToAppName()
- {
- nsCOMPtr<mozIApplication> app = GetOwnApp();
- if (!app) {
- return;
- }
- nsAutoString appName;
- nsresult rv = app->GetName(appName);
- if (NS_FAILED(rv)) {
- NS_WARNING("Failed to retrieve app name");
- return;
- }
- ContentChild::GetSingleton()->SetProcessName(appName, true);
- }
- bool
- TabChild::RecvLoadURL(const nsCString& aURI,
- const ShowInfo& aInfo)
- {
- if (!mDidLoadURLInit) {
- mDidLoadURLInit = true;
- if (!InitTabChildGlobal()) {
- return false;
- }
- ApplyShowInfo(aInfo);
- SetProcessNameToAppName();
- }
- nsresult rv =
- WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(aURI).get(),
- nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
- nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL,
- nullptr, nullptr, nullptr);
- if (NS_FAILED(rv)) {
- NS_WARNING("WebNavigation()->LoadURI failed. Eating exception, what else can I do?");
- }
- return true;
- }
- void
- TabChild::DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
- const uint64_t& aLayersId,
- PRenderFrameChild* aRenderFrame, const ShowInfo& aShowInfo)
- {
- RecvShow(ScreenIntSize(0, 0), aShowInfo, aTextureFactoryIdentifier,
- aLayersId, aRenderFrame, mParentIsActive, nsSizeMode_Normal);
- mDidFakeShow = true;
- }
- void
- TabChild::ApplyShowInfo(const ShowInfo& aInfo)
- {
- if (mDidSetRealShowInfo) {
- return;
- }
- if (!aInfo.fakeShowInfo()) {
- // Once we've got one ShowInfo from parent, no need to update the values
- // anymore.
- mDidSetRealShowInfo = true;
- }
- nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
- if (docShell) {
- nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);
- if (IsMozBrowserOrApp()) {
- // B2G allows window.name to be set by changing the name attribute on the
- // <iframe mozbrowser> element. window.open calls cause this attribute to
- // be set to the correct value. A normal <xul:browser> element has no such
- // attribute. The data we get here comes from reading the attribute, so we
- // shouldn't trust it for <xul:browser> elements.
- item->SetName(aInfo.name());
- }
- docShell->SetFullscreenAllowed(aInfo.fullscreenAllowed());
- if (aInfo.isPrivate()) {
- nsCOMPtr<nsILoadContext> context = do_GetInterface(docShell);
- // No need to re-set private browsing mode.
- if (!context->UsePrivateBrowsing()) {
- if (docShell->GetHasLoadedNonBlankURI()) {
- nsContentUtils::ReportToConsoleNonLocalized(
- NS_LITERAL_STRING("We should not switch to Private Browsing after loading a document."),
- nsIScriptError::warningFlag,
- NS_LITERAL_CSTRING("mozprivatebrowsing"),
- nullptr);
- } else {
- DocShellOriginAttributes attrs(nsDocShell::Cast(docShell)->GetOriginAttributes());
- attrs.SyncAttributesWithPrivateBrowsing(true);
- nsDocShell::Cast(docShell)->SetOriginAttributes(attrs);
- }
- }
- }
- }
- mDPI = aInfo.dpi();
- mRounding = aInfo.widgetRounding();
- mDefaultScale = aInfo.defaultScale();
- mIsTransparent = aInfo.isTransparent();
- }
- bool
- TabChild::RecvShow(const ScreenIntSize& aSize,
- const ShowInfo& aInfo,
- const TextureFactoryIdentifier& aTextureFactoryIdentifier,
- const uint64_t& aLayersId,
- PRenderFrameChild* aRenderFrame,
- const bool& aParentIsActive,
- const nsSizeMode& aSizeMode)
- {
- MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame));
- mPuppetWidget->SetSizeMode(aSizeMode);
- if (mDidFakeShow) {
- ApplyShowInfo(aInfo);
- RecvParentActivated(aParentIsActive);
- return true;
- }
- nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation());
- if (!baseWindow) {
- NS_ERROR("WebNavigation() doesn't QI to nsIBaseWindow");
- return false;
- }
- if (!InitRenderingState(aTextureFactoryIdentifier, aLayersId, aRenderFrame)) {
- // We can fail to initialize our widget if the <browser
- // remote> has already been destroyed, and we couldn't hook
- // into the parent-process's layer system. That's not a fatal
- // error.
- return true;
- }
- baseWindow->SetVisibility(true);
- bool res = InitTabChildGlobal();
- ApplyShowInfo(aInfo);
- RecvParentActivated(aParentIsActive);
- return res;
- }
- bool
- TabChild::RecvUpdateDimensions(const CSSRect& rect, const CSSSize& size,
- const ScreenOrientationInternal& orientation,
- const LayoutDeviceIntPoint& clientOffset,
- const LayoutDeviceIntPoint& chromeDisp)
- {
- if (!mRemoteFrame) {
- return true;
- }
- mUnscaledOuterRect = rect;
- mClientOffset = clientOffset;
- mChromeDisp = chromeDisp;
- mOrientation = orientation;
- SetUnscaledInnerSize(size);
- if (!mHasValidInnerSize && size.width != 0 && size.height != 0) {
- mHasValidInnerSize = true;
- }
- ScreenIntSize screenSize = GetInnerSize();
- ScreenIntRect screenRect = GetOuterRect();
- // Set the size on the document viewer before we update the widget and
- // trigger a reflow. Otherwise the MobileViewportManager reads the stale
- // size from the content viewer when it computes a new CSS viewport.
- nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation());
- baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height,
- nsIBaseWindow::eRepaint);
- mPuppetWidget->Resize(screenRect.x + clientOffset.x + chromeDisp.x,
- screenRect.y + clientOffset.y + chromeDisp.y,
- screenSize.width, screenSize.height, true);
- return true;
- }
- bool
- TabChild::RecvSizeModeChanged(const nsSizeMode& aSizeMode)
- {
- mPuppetWidget->SetSizeMode(aSizeMode);
- if (!mPuppetWidget->IsVisible()) {
- return true;
- }
- nsCOMPtr<nsIDocument> document(GetDocument());
- nsCOMPtr<nsIPresShell> presShell = document->GetShell();
- if (presShell) {
- nsPresContext* presContext = presShell->GetPresContext();
- if (presContext) {
- presContext->SizeModeChanged(aSizeMode);
- }
- }
- return true;
- }
- bool
- TabChild::UpdateFrame(const FrameMetrics& aFrameMetrics)
- {
- return TabChildBase::UpdateFrameHandler(aFrameMetrics);
- }
- bool
- TabChild::RecvSuppressDisplayport(const bool& aEnabled)
- {
- if (aEnabled) {
- mActiveSuppressDisplayport++;
- } else {
- mActiveSuppressDisplayport--;
- }
- MOZ_ASSERT(mActiveSuppressDisplayport >= 0);
- APZCCallbackHelper::SuppressDisplayport(aEnabled, GetPresShell());
- return true;
- }
- void
- TabChild::HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
- const ScrollableLayerGuid& aGuid)
- {
- TABC_LOG("Handling double tap at %s with %p %p\n",
- Stringify(aPoint).c_str(), mGlobal.get(), mTabChildGlobal.get());
- if (!mGlobal || !mTabChildGlobal) {
- return;
- }
- // Note: there is nothing to do with the modifiers here, as we are not
- // synthesizing any sort of mouse event.
- nsCOMPtr<nsIDocument> document = GetDocument();
- CSSRect zoomToRect = CalculateRectToZoomTo(document, aPoint);
- // The double-tap can be dispatched by any scroll frame (so |aGuid| could be
- // the guid of any scroll frame), but the zoom-to-rect operation must be
- // performed by the root content scroll frame, so query its identifiers
- // for the SendZoomToRect() call rather than using the ones from |aGuid|.
- uint32_t presShellId;
- ViewID viewId;
- if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(
- document->GetDocumentElement(), &presShellId, &viewId) && mApzcTreeManager) {
- ScrollableLayerGuid guid(mLayersId, presShellId, viewId);
- mApzcTreeManager->ZoomToRect(guid, zoomToRect, DEFAULT_BEHAVIOR);
- }
- }
- bool
- TabChild::RecvHandleTap(const GeckoContentController::TapType& aType,
- const LayoutDevicePoint& aPoint,
- const Modifiers& aModifiers,
- const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId)
- {
- nsCOMPtr<nsIPresShell> presShell = GetPresShell();
- if (!presShell) {
- return true;
- }
- if (!presShell->GetPresContext()) {
- return true;
- }
- CSSToLayoutDeviceScale scale(presShell->GetPresContext()->CSSToDevPixelScale());
- CSSPoint point = APZCCallbackHelper::ApplyCallbackTransform(aPoint / scale, aGuid);
- switch (aType) {
- case GeckoContentController::TapType::eSingleTap:
- if (mGlobal && mTabChildGlobal) {
- mAPZEventState->ProcessSingleTap(point, scale, aModifiers, aGuid, 1);
- }
- break;
- case GeckoContentController::TapType::eDoubleTap:
- HandleDoubleTap(point, aModifiers, aGuid);
- break;
- case GeckoContentController::TapType::eSecondTap:
- if (mGlobal && mTabChildGlobal) {
- mAPZEventState->ProcessSingleTap(point, scale, aModifiers, aGuid, 2);
- }
- break;
- case GeckoContentController::TapType::eLongTap:
- if (mGlobal && mTabChildGlobal) {
- mAPZEventState->ProcessLongTap(presShell, point, scale, aModifiers, aGuid,
- aInputBlockId);
- }
- break;
- case GeckoContentController::TapType::eLongTapUp:
- if (mGlobal && mTabChildGlobal) {
- mAPZEventState->ProcessLongTapUp(presShell, point, scale, aModifiers);
- }
- break;
- case GeckoContentController::TapType::eSentinel:
- // Should never happen, but we need to handle this case to make the compiler
- // happy.
- MOZ_ASSERT(false);
- break;
- }
- return true;
- }
- bool
- TabChild::NotifyAPZStateChange(const ViewID& aViewId,
- const layers::GeckoContentController::APZStateChange& aChange,
- const int& aArg)
- {
- mAPZEventState->ProcessAPZStateChange(aViewId, aChange, aArg);
- if (aChange == layers::GeckoContentController::APZStateChange::eTransformEnd) {
- // This is used by tests to determine when the APZ is done doing whatever
- // it's doing. XXX generify this as needed when writing additional tests.
- nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
- observerService->NotifyObservers(nullptr, "APZ:TransformEnd", nullptr);
- }
- return true;
- }
- void
- TabChild::StartScrollbarDrag(const layers::AsyncDragMetrics& aDragMetrics)
- {
- ScrollableLayerGuid guid(mLayersId, aDragMetrics.mPresShellId,
- aDragMetrics.mViewId);
- if (mApzcTreeManager) {
- mApzcTreeManager->StartScrollbarDrag(guid, aDragMetrics);
- }
- }
- void
- TabChild::ZoomToRect(const uint32_t& aPresShellId,
- const FrameMetrics::ViewID& aViewId,
- const CSSRect& aRect,
- const uint32_t& aFlags)
- {
- ScrollableLayerGuid guid(mLayersId, aPresShellId, aViewId);
- if (mApzcTreeManager) {
- mApzcTreeManager->ZoomToRect(guid, aRect, aFlags);
- }
- }
- bool
- TabChild::RecvActivate()
- {
- nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(WebNavigation());
- browser->Activate();
- return true;
- }
- bool TabChild::RecvDeactivate()
- {
- nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(WebNavigation());
- browser->Deactivate();
- return true;
- }
- bool TabChild::RecvParentActivated(const bool& aActivated)
- {
- mParentIsActive = aActivated;
- nsFocusManager* fm = nsFocusManager::GetFocusManager();
- NS_ENSURE_TRUE(fm, true);
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
- fm->ParentActivated(window, aActivated);
- return true;
- }
- bool TabChild::RecvSetKeyboardIndicators(const UIStateChangeType& aShowAccelerators,
- const UIStateChangeType& aShowFocusRings)
- {
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
- NS_ENSURE_TRUE(window, true);
- window->SetKeyboardIndicators(aShowAccelerators, aShowFocusRings);
- return true;
- }
- bool
- TabChild::RecvStopIMEStateManagement()
- {
- IMEStateManager::StopIMEStateManagement();
- return true;
- }
- bool
- TabChild::RecvMenuKeyboardListenerInstalled(const bool& aInstalled)
- {
- IMEStateManager::OnInstalledMenuKeyboardListener(aInstalled);
- return true;
- }
- bool
- TabChild::RecvNotifyAttachGroupedSessionHistory(const uint32_t& aOffset)
- {
- // nsISHistory uses int32_t
- if (NS_WARN_IF(aOffset > INT32_MAX)) {
- return false;
- }
- nsCOMPtr<nsISHistory> shistory;
- mWebNav->GetSessionHistory(getter_AddRefs(shistory));
- NS_ENSURE_TRUE(shistory, false);
- return NS_SUCCEEDED(shistory->OnAttachGroupedSessionHistory(aOffset));
- }
- bool
- TabChild::RecvNotifyPartialSessionHistoryActive(const uint32_t& aGlobalLength,
- const uint32_t& aTargetLocalIndex)
- {
- // nsISHistory uses int32_t
- if (NS_WARN_IF(aGlobalLength > INT32_MAX || aTargetLocalIndex > INT32_MAX)) {
- return false;
- }
- nsCOMPtr<nsISHistory> shistory;
- mWebNav->GetSessionHistory(getter_AddRefs(shistory));
- NS_ENSURE_TRUE(shistory, false);
- return NS_SUCCEEDED(shistory->OnPartialSessionHistoryActive(aGlobalLength,
- aTargetLocalIndex));
- }
- bool
- TabChild::RecvNotifyPartialSessionHistoryDeactive()
- {
- nsCOMPtr<nsISHistory> shistory;
- mWebNav->GetSessionHistory(getter_AddRefs(shistory));
- NS_ENSURE_TRUE(shistory, false);
- return NS_SUCCEEDED(shistory->OnPartialSessionHistoryDeactive());
- }
- bool
- TabChild::RecvMouseEvent(const nsString& aType,
- const float& aX,
- const float& aY,
- const int32_t& aButton,
- const int32_t& aClickCount,
- const int32_t& aModifiers,
- const bool& aIgnoreRootScrollFrame)
- {
- APZCCallbackHelper::DispatchMouseEvent(GetPresShell(), aType, CSSPoint(aX, aY),
- aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame, nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN);
- return true;
- }
- bool
- TabChild::RecvRealMouseMoveEvent(const WidgetMouseEvent& aEvent,
- const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId)
- {
- return RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId);
- }
- bool
- TabChild::RecvSynthMouseMoveEvent(const WidgetMouseEvent& aEvent,
- const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId)
- {
- return RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId);
- }
- bool
- TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
- const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId)
- {
- // Mouse events like eMouseEnterIntoWidget, that are created in the parent
- // process EventStateManager code, have an input block id which they get from
- // the InputAPZContext in the parent process stack. However, they did not
- // actually go through the APZ code and so their mHandledByAPZ flag is false.
- // Since thos events didn't go through APZ, we don't need to send notifications
- // for them.
- if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
- nsCOMPtr<nsIDocument> document(GetDocument());
- APZCCallbackHelper::SendSetTargetAPZCNotification(
- mPuppetWidget, document, aEvent, aGuid, aInputBlockId);
- }
- nsEventStatus unused;
- InputAPZContext context(aGuid, aInputBlockId, unused);
- WidgetMouseEvent localEvent(aEvent);
- localEvent.mWidget = mPuppetWidget;
- APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
- mPuppetWidget->GetDefaultScale());
- APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
- mAPZEventState->ProcessMouseEvent(aEvent, aGuid, aInputBlockId);
- }
- return true;
- }
- bool
- TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
- const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId)
- {
- if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
- nsCOMPtr<nsIDocument> document(GetDocument());
- APZCCallbackHelper::SendSetTargetAPZCNotification(
- mPuppetWidget, document, aEvent, aGuid, aInputBlockId);
- }
- WidgetWheelEvent localEvent(aEvent);
- localEvent.mWidget = mPuppetWidget;
- APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
- mPuppetWidget->GetDefaultScale());
- APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- if (localEvent.mCanTriggerSwipe) {
- SendRespondStartSwipeEvent(aInputBlockId, localEvent.TriggersSwipe());
- }
- if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
- mAPZEventState->ProcessWheelEvent(localEvent, aGuid, aInputBlockId);
- }
- return true;
- }
- bool
- TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
- const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId,
- const nsEventStatus& aApzResponse)
- {
- TABC_LOG("Receiving touch event of type %d\n", aEvent.mMessage);
- WidgetTouchEvent localEvent(aEvent);
- localEvent.mWidget = mPuppetWidget;
- APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
- mPuppetWidget->GetDefaultScale());
- if (localEvent.mMessage == eTouchStart && AsyncPanZoomEnabled()) {
- nsCOMPtr<nsIDocument> document = GetDocument();
- if (gfxPrefs::TouchActionEnabled()) {
- APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(mPuppetWidget,
- document, localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
- }
- APZCCallbackHelper::SendSetTargetAPZCNotification(mPuppetWidget, document,
- localEvent, aGuid, aInputBlockId);
- }
- // Dispatch event to content (potentially a long-running operation)
- nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- if (!AsyncPanZoomEnabled()) {
- // We shouldn't have any e10s platforms that have touch events enabled
- // without APZ.
- MOZ_ASSERT(false);
- return true;
- }
- mAPZEventState->ProcessTouchEvent(localEvent, aGuid, aInputBlockId,
- aApzResponse, status);
- return true;
- }
- bool
- TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
- const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId,
- const nsEventStatus& aApzResponse)
- {
- return RecvRealTouchEvent(aEvent, aGuid, aInputBlockId, aApzResponse);
- }
- bool
- TabChild::RecvRealDragEvent(const WidgetDragEvent& aEvent,
- const uint32_t& aDragAction,
- const uint32_t& aDropEffect)
- {
- WidgetDragEvent localEvent(aEvent);
- localEvent.mWidget = mPuppetWidget;
- nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
- if (dragSession) {
- dragSession->SetDragAction(aDragAction);
- nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
- dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
- if (initialDataTransfer) {
- initialDataTransfer->SetDropEffectInt(aDropEffect);
- }
- }
- if (aEvent.mMessage == eDrop) {
- bool canDrop = true;
- if (!dragSession || NS_FAILED(dragSession->GetCanDrop(&canDrop)) ||
- !canDrop) {
- localEvent.mMessage = eDragExit;
- }
- } else if (aEvent.mMessage == eDragOver) {
- nsCOMPtr<nsIDragService> dragService =
- do_GetService("@mozilla.org/widget/dragservice;1");
- if (dragService) {
- // This will dispatch 'drag' event at the source if the
- // drag transaction started in this process.
- dragService->FireDragEventAtSource(eDrag);
- }
- }
- APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- return true;
- }
- bool
- TabChild::RecvPluginEvent(const WidgetPluginEvent& aEvent)
- {
- WidgetPluginEvent localEvent(aEvent);
- localEvent.mWidget = mPuppetWidget;
- nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- if (status != nsEventStatus_eConsumeNoDefault) {
- // If not consumed, we should call default action
- SendDefaultProcOfPluginEvent(aEvent);
- }
- return true;
- }
- void
- TabChild::RequestNativeKeyBindings(AutoCacheNativeKeyCommands* aAutoCache,
- const WidgetKeyboardEvent* aEvent)
- {
- MaybeNativeKeyBinding maybeBindings;
- if (!SendRequestNativeKeyBindings(*aEvent, &maybeBindings)) {
- return;
- }
- if (maybeBindings.type() == MaybeNativeKeyBinding::TNativeKeyBinding) {
- const NativeKeyBinding& bindings = maybeBindings;
- aAutoCache->Cache(bindings.singleLineCommands(),
- bindings.multiLineCommands(),
- bindings.richTextCommands());
- } else {
- aAutoCache->CacheNoCommands();
- }
- }
- bool
- TabChild::RecvNativeSynthesisResponse(const uint64_t& aObserverId,
- const nsCString& aResponse)
- {
- mozilla::widget::AutoObserverNotifier::NotifySavedObserver(aObserverId, aResponse.get());
- return true;
- }
- bool
- TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event,
- const MaybeNativeKeyBinding& aBindings)
- {
- AutoCacheNativeKeyCommands autoCache(mPuppetWidget);
- if (event.mMessage == eKeyPress) {
- // If content code called preventDefault() on a keydown event, then we don't
- // want to process any following keypress events.
- if (mIgnoreKeyPressEvent) {
- return true;
- }
- if (aBindings.type() == MaybeNativeKeyBinding::TNativeKeyBinding) {
- const NativeKeyBinding& bindings = aBindings;
- autoCache.Cache(bindings.singleLineCommands(),
- bindings.multiLineCommands(),
- bindings.richTextCommands());
- } else {
- autoCache.CacheNoCommands();
- }
- }
- WidgetKeyboardEvent localEvent(event);
- localEvent.mWidget = mPuppetWidget;
- nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- if (event.mMessage == eKeyDown) {
- mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault;
- }
- if (localEvent.mFlags.mIsSuppressedOrDelayed) {
- localEvent.PreventDefault();
- }
- // If a response is desired from the content process, resend the key event.
- // If mAccessKeyForwardedToChild is set, then don't resend the key event yet
- // as RecvHandleAccessKey will do this.
- if (localEvent.mFlags.mWantReplyFromContentProcess) {
- SendReplyKeyEvent(localEvent);
- }
- if (localEvent.mAccessKeyForwardedToChild) {
- SendAccessKeyNotHandled(localEvent);
- }
- if (PresShell::BeforeAfterKeyboardEventEnabled()) {
- SendDispatchAfterKeyboardEvent(localEvent);
- }
- return true;
- }
- bool
- TabChild::RecvKeyEvent(const nsString& aType,
- const int32_t& aKeyCode,
- const int32_t& aCharCode,
- const int32_t& aModifiers,
- const bool& aPreventDefault)
- {
- bool ignored = false;
- nsContentUtils::SendKeyEvent(mPuppetWidget, aType, aKeyCode, aCharCode,
- aModifiers, aPreventDefault, &ignored);
- return true;
- }
- bool
- TabChild::RecvCompositionEvent(const WidgetCompositionEvent& event)
- {
- WidgetCompositionEvent localEvent(event);
- localEvent.mWidget = mPuppetWidget;
- APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- Unused << SendOnEventNeedingAckHandled(event.mMessage);
- return true;
- }
- bool
- TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event)
- {
- WidgetSelectionEvent localEvent(event);
- localEvent.mWidget = mPuppetWidget;
- APZCCallbackHelper::DispatchWidgetEvent(localEvent);
- Unused << SendOnEventNeedingAckHandled(event.mMessage);
- return true;
- }
- bool
- TabChild::RecvPasteTransferable(const IPCDataTransfer& aDataTransfer,
- const bool& aIsPrivateData,
- const IPC::Principal& aRequestingPrincipal)
- {
- nsresult rv;
- nsCOMPtr<nsITransferable> trans =
- do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
- NS_ENSURE_SUCCESS(rv, true);
- trans->Init(nullptr);
- rv = nsContentUtils::IPCTransferableToTransferable(aDataTransfer,
- aIsPrivateData,
- aRequestingPrincipal,
- trans, nullptr, this);
- NS_ENSURE_SUCCESS(rv, true);
- nsCOMPtr<nsIDocShell> ourDocShell = do_GetInterface(WebNavigation());
- if (NS_WARN_IF(!ourDocShell)) {
- return true;
- }
- nsCOMPtr<nsICommandParams> params = do_CreateInstance("@mozilla.org/embedcomp/command-params;1", &rv);
- NS_ENSURE_SUCCESS(rv, true);
- rv = params->SetISupportsValue("transferable", trans);
- NS_ENSURE_SUCCESS(rv, true);
- ourDocShell->DoCommandWithParams("cmd_pasteTransferable", params);
- return true;
- }
- a11y::PDocAccessibleChild*
- TabChild::AllocPDocAccessibleChild(PDocAccessibleChild*, const uint64_t&,
- const uint32_t&, const IAccessibleHolder&)
- {
- MOZ_ASSERT(false, "should never call this!");
- return nullptr;
- }
- bool
- TabChild::DeallocPDocAccessibleChild(a11y::PDocAccessibleChild* aChild)
- {
- #ifdef ACCESSIBILITY
- delete static_cast<mozilla::a11y::DocAccessibleChild*>(aChild);
- #endif
- return true;
- }
- PColorPickerChild*
- TabChild::AllocPColorPickerChild(const nsString&, const nsString&)
- {
- NS_RUNTIMEABORT("unused");
- return nullptr;
- }
- bool
- TabChild::DeallocPColorPickerChild(PColorPickerChild* aColorPicker)
- {
- nsColorPickerProxy* picker = static_cast<nsColorPickerProxy*>(aColorPicker);
- NS_RELEASE(picker);
- return true;
- }
- PFilePickerChild*
- TabChild::AllocPFilePickerChild(const nsString&, const int16_t&)
- {
- NS_RUNTIMEABORT("unused");
- return nullptr;
- }
- bool
- TabChild::DeallocPFilePickerChild(PFilePickerChild* actor)
- {
- nsFilePickerProxy* filePicker = static_cast<nsFilePickerProxy*>(actor);
- NS_RELEASE(filePicker);
- return true;
- }
- auto
- TabChild::AllocPIndexedDBPermissionRequestChild(const Principal& aPrincipal)
- -> PIndexedDBPermissionRequestChild*
- {
- MOZ_CRASH("PIndexedDBPermissionRequestChild actors should always be created "
- "manually!");
- }
- bool
- TabChild::DeallocPIndexedDBPermissionRequestChild(
- PIndexedDBPermissionRequestChild* aActor)
- {
- MOZ_ASSERT(aActor);
- delete aActor;
- return true;
- }
- bool
- TabChild::RecvActivateFrameEvent(const nsString& aType, const bool& capture)
- {
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
- NS_ENSURE_TRUE(window, true);
- nsCOMPtr<EventTarget> chromeHandler =
- do_QueryInterface(window->GetChromeEventHandler());
- NS_ENSURE_TRUE(chromeHandler, true);
- RefPtr<ContentListener> listener = new ContentListener(this);
- chromeHandler->AddEventListener(aType, listener, capture);
- return true;
- }
- bool
- TabChild::RecvLoadRemoteScript(const nsString& aURL, const bool& aRunInGlobalScope)
- {
- if (!mGlobal && !InitTabChildGlobal())
- // This can happen if we're half-destroyed. It's not a fatal
- // error.
- return true;
- LoadScriptInternal(aURL, aRunInGlobalScope);
- return true;
- }
- bool
- TabChild::RecvAsyncMessage(const nsString& aMessage,
- InfallibleTArray<CpowEntry>&& aCpows,
- const IPC::Principal& aPrincipal,
- const ClonedMessageData& aData)
- {
- if (!mTabChildGlobal) {
- return true;
- }
- // We should have a message manager if the global is alive, but it
- // seems sometimes we don't. Assert in aurora/nightly, but don't
- // crash in release builds.
- MOZ_DIAGNOSTIC_ASSERT(mTabChildGlobal->mMessageManager);
- if (!mTabChildGlobal->mMessageManager) {
- return true;
- }
- nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
- StructuredCloneData data;
- UnpackClonedMessageDataForChild(aData, data);
- RefPtr<nsFrameMessageManager> mm =
- static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
- CrossProcessCpowHolder cpows(Manager(), aCpows);
- mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
- aMessage, false, &data, &cpows, aPrincipal, nullptr);
- return true;
- }
- bool
- TabChild::RecvSwappedWithOtherRemoteLoader(const IPCTabContext& aContext)
- {
- nsCOMPtr<nsIDocShell> ourDocShell = do_GetInterface(WebNavigation());
- if (NS_WARN_IF(!ourDocShell)) {
- return true;
- }
- nsCOMPtr<nsPIDOMWindowOuter> ourWindow = ourDocShell->GetWindow();
- if (NS_WARN_IF(!ourWindow)) {
- return true;
- }
- RefPtr<nsDocShell> docShell = static_cast<nsDocShell*>(ourDocShell.get());
- nsCOMPtr<EventTarget> ourEventTarget = ourWindow->GetParentTarget();
- docShell->SetInFrameSwap(true);
- nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, false);
- nsContentUtils::FirePageHideEvent(ourDocShell, ourEventTarget);
- // Owner content type may have changed, so store the possibly updated context
- // and notify others.
- MaybeInvalidTabContext maybeContext(aContext);
- if (!maybeContext.IsValid()) {
- NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
- "the parent process. (%s)",
- maybeContext.GetInvalidReason()).get());
- MOZ_CRASH("Invalid TabContext received from the parent process.");
- }
- if (!UpdateTabContextAfterSwap(maybeContext.GetTabContext())) {
- MOZ_CRASH("Update to TabContext after swap was denied.");
- }
- // Since mIsMozBrowserElement may change in UpdateTabContextAfterSwap, so we
- // call UpdateFrameType here to make sure the frameType on the docshell is
- // correct.
- UpdateFrameType();
- // Ignore previous value of mTriedBrowserInit since owner content has changed.
- mTriedBrowserInit = true;
- // Initialize the child side of the browser element machinery, if appropriate.
- if (IsMozBrowserOrApp()) {
- RecvLoadRemoteScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
- }
- nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, true);
- docShell->SetInFrameSwap(false);
- return true;
- }
- bool
- TabChild::RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
- nsTArray<uint32_t>&& aCharCodes,
- const int32_t& aModifierMask)
- {
- nsCOMPtr<nsIDocument> document(GetDocument());
- nsCOMPtr<nsIPresShell> presShell = document->GetShell();
- if (presShell) {
- nsPresContext* pc = presShell->GetPresContext();
- if (pc) {
- if (!pc->EventStateManager()->
- HandleAccessKey(&(const_cast<WidgetKeyboardEvent&>(aEvent)),
- pc, aCharCodes,
- aModifierMask, true)) {
- // If no accesskey was found, inform the parent so that accesskeys on
- // menus can be handled.
- WidgetKeyboardEvent localEvent(aEvent);
- localEvent.mWidget = mPuppetWidget;
- SendAccessKeyNotHandled(localEvent);
- }
- }
- }
- return true;
- }
- bool
- TabChild::RecvAudioChannelChangeNotification(const uint32_t& aAudioChannel,
- const float& aVolume,
- const bool& aMuted)
- {
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
- if (window) {
- RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
- MOZ_ASSERT(service);
- service->SetAudioChannelVolume(window,
- static_cast<AudioChannel>(aAudioChannel),
- aVolume);
- service->SetAudioChannelMuted(window,
- static_cast<AudioChannel>(aAudioChannel),
- aMuted);
- }
- return true;
- }
- bool
- TabChild::RecvSetUseGlobalHistory(const bool& aUse)
- {
- nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
- MOZ_ASSERT(docShell);
- nsresult rv = docShell->SetUseGlobalHistory(aUse);
- if (NS_FAILED(rv)) {
- NS_WARNING("Failed to set UseGlobalHistory on TabChild docShell");
- }
- return true;
- }
- bool
- TabChild::RecvPrint(const uint64_t& aOuterWindowID, const PrintData& aPrintData)
- {
- #ifdef NS_PRINTING
- nsGlobalWindow* outerWindow =
- nsGlobalWindow::GetOuterWindowWithId(aOuterWindowID);
- if (NS_WARN_IF(!outerWindow)) {
- return true;
- }
- nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint =
- do_GetInterface(outerWindow->AsOuter());
- if (NS_WARN_IF(!webBrowserPrint)) {
- return true;
- }
- nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
- do_GetService("@mozilla.org/gfx/printsettings-service;1");
- if (NS_WARN_IF(!printSettingsSvc)) {
- return true;
- }
- nsCOMPtr<nsIPrintSettings> printSettings;
- nsresult rv =
- printSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return true;
- }
- nsCOMPtr<nsIPrintSession> printSession =
- do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return true;
- }
- printSettings->SetPrintSession(printSession);
- printSettingsSvc->DeserializeToPrintSettings(aPrintData, printSettings);
- rv = webBrowserPrint->Print(printSettings, nullptr);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return true;
- }
- #endif
- return true;
- }
- bool
- TabChild::RecvUpdateNativeWindowHandle(const uintptr_t& aNewHandle)
- {
- #if defined(XP_WIN) && defined(ACCESSIBILITY)
- mNativeWindowHandle = aNewHandle;
- return true;
- #else
- return false;
- #endif
- }
- bool
- TabChild::RecvDestroy()
- {
- MOZ_ASSERT(mDestroyed == false);
- mDestroyed = true;
- nsTArray<PContentPermissionRequestChild*> childArray =
- nsContentPermissionUtils::GetContentPermissionRequestChildById(GetTabId());
- // Need to close undeleted ContentPermissionRequestChilds before tab is closed.
- for (auto& permissionRequestChild : childArray) {
- auto child = static_cast<RemotePermissionRequest*>(permissionRequestChild);
- child->Destroy();
- }
- while (mActiveSuppressDisplayport > 0) {
- APZCCallbackHelper::SuppressDisplayport(false, nullptr);
- mActiveSuppressDisplayport--;
- }
- if (mTabChildGlobal) {
- // Message handlers are called from the event loop, so it better be safe to
- // run script.
- MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
- mTabChildGlobal->DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
- }
- nsCOMPtr<nsIObserverService> observerService =
- mozilla::services::GetObserverService();
- observerService->RemoveObserver(this, BEFORE_FIRST_PAINT);
- const nsAttrValue::EnumTable* table =
- AudioChannelService::GetAudioChannelTable();
- nsAutoCString topic;
- for (uint32_t i = 0; table[i].tag; ++i) {
- topic.Assign("audiochannel-activity-");
- topic.Append(table[i].tag);
- observerService->RemoveObserver(this, topic.get());
- }
- // XXX what other code in ~TabChild() should we be running here?
- DestroyWindow();
- // Bounce through the event loop once to allow any delayed teardown runnables
- // that were just generated to have a chance to run.
- nsCOMPtr<nsIRunnable> deleteRunnable = new DelayedDeleteRunnable(this);
- MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(deleteRunnable));
- return true;
- }
- bool
- TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
- const bool& aPreserveLayers,
- const uint64_t& aLayerObserverEpoch)
- {
- // Since SetDocShellIsActive requests come in from both the hang monitor
- // channel and the PContent channel, we have an ordering problem. This code
- // ensures that we respect the order in which the requests were made and
- // ignore stale requests.
- if (mLayerObserverEpoch >= aLayerObserverEpoch) {
- return true;
- }
- mLayerObserverEpoch = aLayerObserverEpoch;
- MOZ_ASSERT(mPuppetWidget);
- MOZ_ASSERT(mPuppetWidget->GetLayerManager());
- MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() ==
- LayersBackend::LAYERS_CLIENT);
- auto clearForcePaint = MakeScopeExit([&] {
- // We might force a paint, or we might already have painted and this is a
- // no-op. In either case, once we exit this scope, we need to alert the
- // ProcessHangMonitor that we've finished responding to what might have
- // been a request to force paint. This is so that the BackgroundHangMonitor
- // for force painting can be made to wait again.
- if (aIsActive) {
- ProcessHangMonitor::ClearForcePaint();
- }
- });
- // We send the current layer observer epoch to the compositor so that
- // TabParent knows whether a layer update notification corresponds to the
- // latest SetDocShellIsActive request that was made.
- if (ClientLayerManager* clm = mPuppetWidget->GetLayerManager()->AsClientLayerManager()) {
- clm->SetLayerObserverEpoch(aLayerObserverEpoch);
- }
- // docshell is consider prerendered only if not active yet
- mIsPrerendered &= !aIsActive;
- nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
- if (docShell) {
- bool wasActive;
- docShell->GetIsActive(&wasActive);
- if (aIsActive && wasActive) {
- // This request is a no-op. In this case, we still want a MozLayerTreeReady
- // notification to fire in the parent (so that it knows that the child has
- // updated its epoch). ForcePaintNoOp does that.
- if (IPCOpen()) {
- Unused << SendForcePaintNoOp(aLayerObserverEpoch);
- return true;
- }
- }
- docShell->SetIsActive(aIsActive);
- }
- if (aIsActive) {
- MakeVisible();
- // We don't use TabChildBase::GetPresShell() here because that would create
- // a content viewer if one doesn't exist yet. Creating a content viewer can
- // cause JS to run, which we want to avoid. nsIDocShell::GetPresShell
- // returns null if no content viewer exists yet.
- if (nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell()) {
- if (nsIFrame* root = presShell->FrameConstructor()->GetRootFrame()) {
- FrameLayerBuilder::InvalidateAllLayersForFrame(
- nsLayoutUtils::GetDisplayRootFrame(root));
- root->SchedulePaint();
- }
- // If we need to repaint, let's do that right away. No sense waiting until
- // we get back to the event loop again. We suppress the display port so that
- // we only paint what's visible. This ensures that the tab we're switching
- // to paints as quickly as possible.
- APZCCallbackHelper::SuppressDisplayport(true, presShell);
- if (nsContentUtils::IsSafeToRunScript()) {
- WebWidget()->PaintNowIfNeeded();
- } else {
- RefPtr<nsViewManager> vm = presShell->GetViewManager();
- if (nsView* view = vm->GetRootView()) {
- presShell->Paint(view, view->GetBounds(),
- nsIPresShell::PAINT_LAYERS);
- }
- }
- APZCCallbackHelper::SuppressDisplayport(false, presShell);
- }
- } else if (!aPreserveLayers) {
- MakeHidden();
- }
- return true;
- }
- bool
- TabChild::RecvNavigateByKey(const bool& aForward, const bool& aForDocumentNavigation)
- {
- nsIFocusManager* fm = nsFocusManager::GetFocusManager();
- if (fm) {
- nsCOMPtr<nsIDOMElement> result;
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
- // Move to the first or last document.
- uint32_t type = aForward ?
- (aForDocumentNavigation ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FIRSTDOC) :
- static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_ROOT)) :
- (aForDocumentNavigation ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_LASTDOC) :
- static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_LAST));
- fm->MoveFocus(window, nullptr, type,
- nsIFocusManager::FLAG_BYKEY, getter_AddRefs(result));
- // No valid root element was found, so move to the first focusable element.
- if (!result && aForward && !aForDocumentNavigation) {
- fm->MoveFocus(window, nullptr, nsIFocusManager::MOVEFOCUS_FIRST,
- nsIFocusManager::FLAG_BYKEY, getter_AddRefs(result));
- }
- SendRequestFocus(false);
- }
- return true;
- }
- bool
- TabChild::RecvHandledWindowedPluginKeyEvent(
- const NativeEventData& aKeyEventData,
- const bool& aIsConsumed)
- {
- if (NS_WARN_IF(!mPuppetWidget)) {
- return true;
- }
- mPuppetWidget->HandledWindowedPluginKeyEvent(aKeyEventData, aIsConsumed);
- return true;
- }
- PRenderFrameChild*
- TabChild::AllocPRenderFrameChild()
- {
- return new RenderFrameChild();
- }
- bool
- TabChild::DeallocPRenderFrameChild(PRenderFrameChild* aFrame)
- {
- delete aFrame;
- return true;
- }
- bool
- TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
- {
- if (!mGlobal && !mTabChildGlobal) {
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
- NS_ENSURE_TRUE(window, false);
- nsCOMPtr<EventTarget> chromeHandler =
- do_QueryInterface(window->GetChromeEventHandler());
- NS_ENSURE_TRUE(chromeHandler, false);
- RefPtr<TabChildGlobal> scope = new TabChildGlobal(this);
- mTabChildGlobal = scope;
- nsISupports* scopeSupports = NS_ISUPPORTS_CAST(EventTarget*, scope);
- NS_NAMED_LITERAL_CSTRING(globalId, "outOfProcessTabChildGlobal");
- NS_ENSURE_TRUE(InitChildGlobalInternal(scopeSupports, globalId), false);
- scope->Init();
- nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
- NS_ENSURE_TRUE(root, false);
- root->SetParentTarget(scope);
- }
- if (aScriptLoading != DONT_LOAD_SCRIPTS && !mTriedBrowserInit) {
- mTriedBrowserInit = true;
- // Initialize the child side of the browser element machinery,
- // if appropriate.
- if (IsMozBrowserOrApp()) {
- RecvLoadRemoteScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
- }
- }
- return true;
- }
- bool
- TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
- const uint64_t& aLayersId,
- PRenderFrameChild* aRenderFrame)
- {
- mPuppetWidget->InitIMEState();
- RenderFrameChild* remoteFrame = static_cast<RenderFrameChild*>(aRenderFrame);
- if (!remoteFrame) {
- NS_WARNING("failed to construct RenderFrame");
- return false;
- }
- MOZ_ASSERT(aLayersId != 0);
- mTextureFactoryIdentifier = aTextureFactoryIdentifier;
- // Pushing layers transactions directly to a separate
- // compositor context.
- PCompositorBridgeChild* compositorChild = CompositorBridgeChild::Get();
- if (!compositorChild) {
- NS_WARNING("failed to get CompositorBridgeChild instance");
- PRenderFrameChild::Send__delete__(remoteFrame);
- return false;
- }
- ShadowLayerForwarder* lf =
- mPuppetWidget->GetLayerManager(
- nullptr, mTextureFactoryIdentifier.mParentBackend)
- ->AsShadowForwarder();
- // As long as we are creating a ClientLayerManager for the puppet widget,
- // lf must be non-null here.
- MOZ_ASSERT(lf);
- if (lf) {
- nsTArray<LayersBackend> backends;
- backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
- bool success;
- PLayerTransactionChild* shadowManager =
- compositorChild->SendPLayerTransactionConstructor(backends,
- aLayersId, &mTextureFactoryIdentifier, &success);
- if (!success) {
- NS_WARNING("failed to properly allocate layer transaction");
- PRenderFrameChild::Send__delete__(remoteFrame);
- return false;
- }
- if (!shadowManager) {
- NS_WARNING("failed to construct LayersChild");
- // This results in |remoteFrame| being deleted.
- PRenderFrameChild::Send__delete__(remoteFrame);
- return false;
- }
- lf->SetShadowManager(shadowManager);
- lf->IdentifyTextureHost(mTextureFactoryIdentifier);
- ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
- }
- mRemoteFrame = remoteFrame;
- if (aLayersId != 0) {
- if (!sTabChildren) {
- sTabChildren = new TabChildMap;
- }
- MOZ_ASSERT(!sTabChildren->Get(aLayersId));
- sTabChildren->Put(aLayersId, this);
- mLayersId = aLayersId;
- }
- mApzcTreeManager = CompositorBridgeChild::Get()->GetAPZCTreeManager(mLayersId);
- nsCOMPtr<nsIObserverService> observerService =
- mozilla::services::GetObserverService();
- if (observerService) {
- observerService->AddObserver(this,
- BEFORE_FIRST_PAINT,
- false);
- }
- return true;
- }
- void
- TabChild::GetDPI(float* aDPI)
- {
- *aDPI = -1.0;
- if (!mRemoteFrame) {
- return;
- }
- if (mDPI > 0) {
- *aDPI = mDPI;
- return;
- }
- // Fallback to a sync call if needed.
- SendGetDPI(aDPI);
- }
- void
- TabChild::GetDefaultScale(double* aScale)
- {
- *aScale = -1.0;
- if (!mRemoteFrame) {
- return;
- }
- if (mDefaultScale > 0) {
- *aScale = mDefaultScale;
- return;
- }
- // Fallback to a sync call if needed.
- SendGetDefaultScale(aScale);
- }
- void
- TabChild::GetWidgetRounding(int32_t* aRounding)
- {
- *aRounding = 1;
- if (!mRemoteFrame) {
- return;
- }
- if (mRounding > 0) {
- *aRounding = mRounding;
- return;
- }
- // Fallback to a sync call if needed.
- SendGetWidgetRounding(aRounding);
- }
- void
- TabChild::GetMaxTouchPoints(uint32_t* aTouchPoints)
- {
- // Fallback to a sync call.
- SendGetMaxTouchPoints(aTouchPoints);
- }
- void
- TabChild::NotifyPainted()
- {
- if (!mNotified) {
- mRemoteFrame->SendNotifyCompositorTransaction();
- mNotified = true;
- }
- }
- void
- TabChild::MakeVisible()
- {
- if (mPuppetWidget && mPuppetWidget->IsVisible()) {
- return;
- }
- if (mPuppetWidget) {
- mPuppetWidget->Show(true);
- }
- }
- void
- TabChild::MakeHidden()
- {
- if (mPuppetWidget && !mPuppetWidget->IsVisible()) {
- return;
- }
- CompositorBridgeChild* compositor = CompositorBridgeChild::Get();
- // Clear cached resources directly. This avoids one extra IPC
- // round-trip from CompositorBridgeChild to CompositorBridgeParent.
- compositor->RecvClearCachedResources(mLayersId);
- if (mPuppetWidget) {
- mPuppetWidget->Show(false);
- }
- }
- NS_IMETHODIMP
- TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult)
- {
- if (mTabChildGlobal) {
- NS_ADDREF(*aResult = mTabChildGlobal);
- return NS_OK;
- }
- *aResult = nullptr;
- return NS_ERROR_FAILURE;
- }
- NS_IMETHODIMP
- TabChild::GetWebBrowserChrome(nsIWebBrowserChrome3** aWebBrowserChrome)
- {
- NS_IF_ADDREF(*aWebBrowserChrome = mWebBrowserChrome);
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::SetWebBrowserChrome(nsIWebBrowserChrome3* aWebBrowserChrome)
- {
- mWebBrowserChrome = aWebBrowserChrome;
- return NS_OK;
- }
- void
- TabChild::SendRequestFocus(bool aCanFocus)
- {
- PBrowserChild::SendRequestFocus(aCanFocus);
- }
- void
- TabChild::SendGetTabCount(uint32_t* tabCount)
- {
- PBrowserChild::SendGetTabCount(tabCount);
- }
- void
- TabChild::EnableDisableCommands(const nsAString& aAction,
- nsTArray<nsCString>& aEnabledCommands,
- nsTArray<nsCString>& aDisabledCommands)
- {
- PBrowserChild::SendEnableDisableCommands(PromiseFlatString(aAction),
- aEnabledCommands, aDisabledCommands);
- }
- NS_IMETHODIMP
- TabChild::GetTabId(uint64_t* aId)
- {
- *aId = GetTabId();
- return NS_OK;
- }
- void
- TabChild::SetTabId(const TabId& aTabId)
- {
- MOZ_ASSERT(mUniqueId == 0);
- mUniqueId = aTabId;
- NestedTabChildMap()[mUniqueId] = this;
- }
- bool
- TabChild::DoSendBlockingMessage(JSContext* aCx,
- const nsAString& aMessage,
- StructuredCloneData& aData,
- JS::Handle<JSObject *> aCpows,
- nsIPrincipal* aPrincipal,
- nsTArray<StructuredCloneData>* aRetVal,
- bool aIsSync)
- {
- ClonedMessageData data;
- if (!BuildClonedMessageDataForChild(Manager(), aData, data)) {
- return false;
- }
- InfallibleTArray<CpowEntry> cpows;
- if (aCpows && !Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
- return false;
- }
- if (aIsSync) {
- return SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
- Principal(aPrincipal), aRetVal);
- }
- return SendRpcMessage(PromiseFlatString(aMessage), data, cpows,
- Principal(aPrincipal), aRetVal);
- }
- nsresult
- TabChild::DoSendAsyncMessage(JSContext* aCx,
- const nsAString& aMessage,
- StructuredCloneData& aData,
- JS::Handle<JSObject *> aCpows,
- nsIPrincipal* aPrincipal)
- {
- ClonedMessageData data;
- if (!BuildClonedMessageDataForChild(Manager(), aData, data)) {
- return NS_ERROR_DOM_DATA_CLONE_ERR;
- }
- InfallibleTArray<CpowEntry> cpows;
- if (aCpows && !Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
- return NS_ERROR_UNEXPECTED;
- }
- if (!SendAsyncMessage(PromiseFlatString(aMessage), cpows,
- Principal(aPrincipal), data)) {
- return NS_ERROR_UNEXPECTED;
- }
- return NS_OK;
- }
- /* static */ nsTArray<RefPtr<TabChild>>
- TabChild::GetAll()
- {
- nsTArray<RefPtr<TabChild>> list;
- if (!sTabChildren) {
- return list;
- }
- for (auto iter = sTabChildren->Iter(); !iter.Done(); iter.Next()) {
- list.AppendElement(iter.Data());
- }
- return list;
- }
- TabChild*
- TabChild::GetFrom(nsIPresShell* aPresShell)
- {
- nsIDocument* doc = aPresShell->GetDocument();
- if (!doc) {
- return nullptr;
- }
- nsCOMPtr<nsIDocShell> docShell(doc->GetDocShell());
- return GetFrom(docShell);
- }
- TabChild*
- TabChild::GetFrom(uint64_t aLayersId)
- {
- if (!sTabChildren) {
- return nullptr;
- }
- return sTabChildren->Get(aLayersId);
- }
- void
- TabChild::DidComposite(uint64_t aTransactionId,
- const TimeStamp& aCompositeStart,
- const TimeStamp& aCompositeEnd)
- {
- MOZ_ASSERT(mPuppetWidget);
- MOZ_ASSERT(mPuppetWidget->GetLayerManager());
- MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() ==
- LayersBackend::LAYERS_CLIENT);
- RefPtr<ClientLayerManager> manager = mPuppetWidget->GetLayerManager()->AsClientLayerManager();
- manager->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
- }
- void
- TabChild::DidRequestComposite(const TimeStamp& aCompositeReqStart,
- const TimeStamp& aCompositeReqEnd)
- {
- nsCOMPtr<nsIDocShell> docShellComPtr = do_GetInterface(WebNavigation());
- if (!docShellComPtr) {
- return;
- }
- nsDocShell* docShell = static_cast<nsDocShell*>(docShellComPtr.get());
- RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
- if (timelines && timelines->HasConsumer(docShell)) {
- // Since we're assuming that it's impossible for content JS to directly
- // trigger a synchronous paint, we can avoid capturing a stack trace here,
- // which means we won't run into JS engine reentrancy issues like bug
- // 1310014.
- timelines->AddMarkerForDocShell(docShell,
- "CompositeForwardTransaction", aCompositeReqStart,
- MarkerTracingType::START, MarkerStackRequest::NO_STACK);
- timelines->AddMarkerForDocShell(docShell,
- "CompositeForwardTransaction", aCompositeReqEnd,
- MarkerTracingType::END, MarkerStackRequest::NO_STACK);
- }
- }
- void
- TabChild::ClearCachedResources()
- {
- MOZ_ASSERT(mPuppetWidget);
- MOZ_ASSERT(mPuppetWidget->GetLayerManager());
- MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() ==
- LayersBackend::LAYERS_CLIENT);
- ClientLayerManager *manager = mPuppetWidget->GetLayerManager()->AsClientLayerManager();
- manager->ClearCachedResources();
- }
- void
- TabChild::InvalidateLayers()
- {
- MOZ_ASSERT(mPuppetWidget);
- MOZ_ASSERT(mPuppetWidget->GetLayerManager());
- MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() ==
- LayersBackend::LAYERS_CLIENT);
- RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
- FrameLayerBuilder::InvalidateAllLayers(lm);
- }
- void
- TabChild::ReinitRendering()
- {
- MOZ_ASSERT(mLayersId);
- // Before we establish a new PLayerTransaction, we must connect our layer tree
- // id, CompositorBridge, and the widget compositor all together again.
- // Normally this happens in TabParent before TabChild is given rendering
- // information.
- //
- // In this case, we will send a sync message to our TabParent, which in turn
- // will send a sync message to the Compositor of the widget owning this tab.
- // This guarantees the correct association is in place before our
- // PLayerTransaction constructor message arrives on the cross-process
- // compositor bridge.
- SendEnsureLayersConnected();
- RefPtr<CompositorBridgeChild> cb = CompositorBridgeChild::Get();
- bool success;
- nsTArray<LayersBackend> ignored;
- PLayerTransactionChild* shadowManager =
- cb->SendPLayerTransactionConstructor(ignored, LayersId(), &mTextureFactoryIdentifier, &success);
- if (!success) {
- NS_WARNING("failed to re-allocate layer transaction");
- return;
- }
- if (!shadowManager) {
- NS_WARNING("failed to re-construct LayersChild");
- return;
- }
- RefPtr<LayerManager> lm = mPuppetWidget->RecreateLayerManager(shadowManager);
- ShadowLayerForwarder* lf = lm->AsShadowForwarder();
- lf->IdentifyTextureHost(mTextureFactoryIdentifier);
- mApzcTreeManager = CompositorBridgeChild::Get()->GetAPZCTreeManager(mLayersId);
- if (mApzcTreeManager) {
- APZChild* apz = ContentProcessController::Create(mUniqueId);
- CompositorBridgeChild::Get()->SendPAPZConstructor(apz, mLayersId);
- }
- nsCOMPtr<nsIDocument> doc(GetDocument());
- doc->NotifyLayerManagerRecreated();
- }
- void
- TabChild::CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier)
- {
- gfxPlatform::GetPlatform()->CompositorUpdated();
- RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
- ClientLayerManager* clm = lm->AsClientLayerManager();
- MOZ_ASSERT(clm);
- mTextureFactoryIdentifier = aNewIdentifier;
- clm->UpdateTextureFactoryIdentifier(aNewIdentifier);
- FrameLayerBuilder::InvalidateAllLayers(clm);
- }
- NS_IMETHODIMP
- TabChild::OnShowTooltip(int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText,
- const char16_t *aTipDir)
- {
- nsString str(aTipText);
- nsString dir(aTipDir);
- SendShowTooltip(aXCoords, aYCoords, str, dir);
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChild::OnHideTooltip()
- {
- SendHideTooltip();
- return NS_OK;
- }
- bool
- TabChild::RecvRequestNotifyAfterRemotePaint()
- {
- // Get the CompositorBridgeChild instance for this content thread.
- CompositorBridgeChild* compositor = CompositorBridgeChild::Get();
- // Tell the CompositorBridgeChild that, when it gets a RemotePaintIsReady
- // message that it should forward it us so that we can bounce it to our
- // RenderFrameParent.
- compositor->RequestNotifyAfterRemotePaint(this);
- return true;
- }
- bool
- TabChild::RecvUIResolutionChanged(const float& aDpi,
- const int32_t& aRounding,
- const double& aScale)
- {
- ScreenIntSize oldScreenSize = GetInnerSize();
- mDPI = 0;
- mRounding = 0;
- mDefaultScale = 0;
- static_cast<PuppetWidget*>(mPuppetWidget.get())->UpdateBackingScaleCache(aDpi, aRounding, aScale);
- nsCOMPtr<nsIDocument> document(GetDocument());
- nsCOMPtr<nsIPresShell> presShell = document->GetShell();
- if (presShell) {
- RefPtr<nsPresContext> presContext = presShell->GetPresContext();
- if (presContext) {
- presContext->UIResolutionChangedSync();
- }
- }
- ScreenIntSize screenSize = GetInnerSize();
- if (mHasValidInnerSize && oldScreenSize != screenSize) {
- ScreenIntRect screenRect = GetOuterRect();
- mPuppetWidget->Resize(screenRect.x + mClientOffset.x + mChromeDisp.x,
- screenRect.y + mClientOffset.y + mChromeDisp.y,
- screenSize.width, screenSize.height, true);
- nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation());
- baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height,
- nsIBaseWindow::eRepaint);
- }
- return true;
- }
- bool
- TabChild::RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache)
- {
- LookAndFeel::SetIntCache(aLookAndFeelIntCache);
- nsCOMPtr<nsIDocument> document(GetDocument());
- nsCOMPtr<nsIPresShell> presShell = document->GetShell();
- if (presShell) {
- RefPtr<nsPresContext> presContext = presShell->GetPresContext();
- if (presContext) {
- presContext->ThemeChanged();
- }
- }
- return true;
- }
- bool
- TabChild::RecvSetFreshProcess()
- {
- mIsFreshProcess = true;
- return true;
- }
- mozilla::plugins::PPluginWidgetChild*
- TabChild::AllocPPluginWidgetChild()
- {
- return new mozilla::plugins::PluginWidgetChild();
- }
- bool
- TabChild::DeallocPPluginWidgetChild(mozilla::plugins::PPluginWidgetChild* aActor)
- {
- delete aActor;
- return true;
- }
- nsresult
- TabChild::CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut)
- {
- *aOut = nullptr;
- mozilla::plugins::PluginWidgetChild* child =
- static_cast<mozilla::plugins::PluginWidgetChild*>(SendPPluginWidgetConstructor());
- if (!child) {
- NS_ERROR("couldn't create PluginWidgetChild");
- return NS_ERROR_UNEXPECTED;
- }
- nsCOMPtr<nsIWidget> pluginWidget = nsIWidget::CreatePluginProxyWidget(this, child);
- if (!pluginWidget) {
- NS_ERROR("couldn't create PluginWidgetProxy");
- return NS_ERROR_UNEXPECTED;
- }
- nsWidgetInitData initData;
- initData.mWindowType = eWindowType_plugin_ipc_content;
- initData.mUnicode = false;
- initData.clipChildren = true;
- initData.clipSiblings = true;
- nsresult rv = pluginWidget->Create(aParent, nullptr,
- LayoutDeviceIntRect(0, 0, 0, 0),
- &initData);
- if (NS_FAILED(rv)) {
- NS_WARNING("Creating native plugin widget on the chrome side failed.");
- }
- pluginWidget.forget(aOut);
- return rv;
- }
- ScreenIntSize
- TabChild::GetInnerSize()
- {
- LayoutDeviceIntSize innerSize =
- RoundedToInt(mUnscaledInnerSize * mPuppetWidget->GetDefaultScale());
- return ViewAs<ScreenPixel>(innerSize, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
- };
- ScreenIntRect
- TabChild::GetOuterRect()
- {
- LayoutDeviceIntRect outerRect =
- RoundedToInt(mUnscaledOuterRect * mPuppetWidget->GetDefaultScale());
- return ViewAs<ScreenPixel>(outerRect, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
- }
- void
- TabChild::ForcePaint(uint64_t aLayerObserverEpoch)
- {
- if (!IPCOpen()) {
- // Don't bother doing anything now. Better to wait until we receive the
- // message on the PContent channel.
- return;
- }
- nsAutoScriptBlocker scriptBlocker;
- RecvSetDocShellIsActive(true, false, aLayerObserverEpoch);
- }
- /*******************************************************************************
- * nsISHistoryListener
- ******************************************************************************/
- NS_IMETHODIMP
- TabChildSHistoryListener::OnHistoryNewEntry(nsIURI *aNewURI, int32_t aOldIndex)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChildSHistoryListener::OnHistoryGoBack(nsIURI *aBackURI, bool *_retval)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChildSHistoryListener::OnHistoryGoForward(nsIURI *aForwardURI, bool *_retval)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChildSHistoryListener::OnHistoryReload(nsIURI *aReloadURI, uint32_t aReloadFlags, bool *_retval)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChildSHistoryListener::OnHistoryGotoIndex(int32_t aIndex, nsIURI *aGotoURI, bool *_retval)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChildSHistoryListener::OnHistoryPurge(int32_t aNumEntries, bool *_retval)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChildSHistoryListener::OnHistoryReplaceEntry(int32_t aIndex)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- TabChildSHistoryListener::OnLengthChange(int32_t aCount)
- {
- RefPtr<TabChild> tabChild(mTabChild);
- if (!tabChild) {
- return NS_ERROR_FAILURE;
- }
- if (aCount < 0) {
- return NS_ERROR_FAILURE;
- }
- return tabChild->SendNotifySessionHistoryChange(aCount) ?
- NS_OK : NS_ERROR_FAILURE;
- }
- NS_IMETHODIMP
- TabChildSHistoryListener::OnRequestCrossBrowserNavigation(uint32_t aIndex)
- {
- RefPtr<TabChild> tabChild(mTabChild);
- if (!tabChild) {
- return NS_ERROR_FAILURE;
- }
- return tabChild->SendRequestCrossBrowserNavigation(aIndex) ?
- NS_OK : NS_ERROR_FAILURE;
- }
- TabChildGlobal::TabChildGlobal(TabChildBase* aTabChild)
- : mTabChild(aTabChild)
- {
- SetIsNotDOMBinding();
- }
- TabChildGlobal::~TabChildGlobal()
- {
- }
- void
- TabChildGlobal::Init()
- {
- NS_ASSERTION(!mMessageManager, "Re-initializing?!?");
- mMessageManager = new nsFrameMessageManager(mTabChild,
- nullptr,
- MM_CHILD);
- }
- NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildGlobal)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TabChildGlobal,
- DOMEventTargetHelper)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager);
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChild);
- tmp->UnlinkHostObjectURIs();
- NS_IMPL_CYCLE_COLLECTION_UNLINK_END
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TabChildGlobal,
- DOMEventTargetHelper)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChild)
- tmp->TraverseHostObjectURIs(cb);
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
- NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal)
- NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
- NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
- NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
- NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
- NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
- NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
- NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
- NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
- NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
- NS_IMPL_ADDREF_INHERITED(TabChildGlobal, DOMEventTargetHelper)
- NS_IMPL_RELEASE_INHERITED(TabChildGlobal, DOMEventTargetHelper)
- // This method isn't automatically forwarded safely because it's notxpcom, so
- // the IDL binding doesn't know what value to return.
- NS_IMETHODIMP_(bool)
- TabChildGlobal::MarkForCC()
- {
- if (mTabChild) {
- mTabChild->MarkScopesForCC();
- }
- EventListenerManager* elm = GetExistingListenerManager();
- if (elm) {
- elm->MarkForCC();
- }
- return mMessageManager ? mMessageManager->MarkForCC() : false;
- }
- NS_IMETHODIMP
- TabChildGlobal::GetContent(mozIDOMWindowProxy** aContent)
- {
- *aContent = nullptr;
- if (!mTabChild)
- return NS_ERROR_NULL_POINTER;
- nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(mTabChild->WebNavigation());
- window.forget(aContent);
- return NS_OK;
- }
- NS_IMETHODIMP
- TabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
- {
- *aDocShell = nullptr;
- if (!mTabChild)
- return NS_ERROR_NULL_POINTER;
- nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mTabChild->WebNavigation());
- docShell.swap(*aDocShell);
- return NS_OK;
- }
- nsIPrincipal*
- TabChildGlobal::GetPrincipal()
- {
- if (!mTabChild)
- return nullptr;
- return mTabChild->GetPrincipal();
- }
- JSObject*
- TabChildGlobal::GetGlobalJSObject()
- {
- NS_ENSURE_TRUE(mTabChild, nullptr);
- nsCOMPtr<nsIXPConnectJSObjectHolder> ref = mTabChild->GetGlobal();
- NS_ENSURE_TRUE(ref, nullptr);
- return ref->GetJSObject();
- }
|