/extensions/widgetutils/src/nsWidgetUtils.cpp

http://github.com/zpao/v8monkey · C++ · 589 lines · 461 code · 76 blank · 52 comment · 59 complexity · 683ea4bbc8f1f179922bafb268c7c2c3 MD5 · raw file

  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim:set ts=2 sw=2 sts=2 tw=80 et cindent: */
  3. /* ***** BEGIN LICENSE BLOCK *****
  4. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5. *
  6. * The contents of this file are subject to the Mozilla Public License Version
  7. * 1.1 (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. * http://www.mozilla.org/MPL/
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. *
  16. * The Original Code is Mozilla's Element Optimizeing extension.
  17. *
  18. * The Initial Developer of the Original Code is the Mozilla Foundation.
  19. * Portions created by the Initial Developer are Copyright (C) 2006
  20. * the Initial Developer. All Rights Reserved.
  21. *
  22. * Contributor(s):
  23. * Oleg Romashin <romaxa@gmail.com> (original author)
  24. * Brad Lassey <blassey@mozilla.com>
  25. * Ms2ger <ms2ger@gmail.com>
  26. *
  27. * Alternatively, the contents of this file may be used under the terms of
  28. * either the GNU General Public License Version 2 or later (the "GPL"), or
  29. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30. * in which case the provisions of the GPL or the LGPL are applicable instead
  31. * of those above. If you wish to allow use of your version of this file only
  32. * under the terms of either the GPL or the LGPL, and not to allow others to
  33. * use your version of this file under the terms of the MPL, indicate your
  34. * decision by deleting the provisions above and replace them with the notice
  35. * and other provisions required by the GPL or the LGPL. If you do not delete
  36. * the provisions above, a recipient may use your version of this file under
  37. * the terms of any one of the MPL, the GPL or the LGPL.
  38. *
  39. * ***** END LICENSE BLOCK ***** */
  40. #include "nsCURILoader.h"
  41. #include "nsICategoryManager.h"
  42. #include "nsIDOMDocument.h"
  43. #include "nsIDOMHTMLElement.h"
  44. #include "nsIDOMHTMLIFrameElement.h"
  45. #include "nsIDOMNode.h"
  46. #include "nsIDOMNodeList.h"
  47. #include "nsIDOMWindow.h"
  48. #include "nsIDOMWindowCollection.h"
  49. #include "nsIDocument.h"
  50. #include "nsIGenericFactory.h"
  51. #include "nsIObserver.h"
  52. #include "nsIPresShell.h"
  53. #include "nsIStyleSheetService.h"
  54. #include "nsIWebProgress.h"
  55. #include "nsIWebProgressListener.h"
  56. #include "nsIWindowWatcher.h"
  57. #include "nsNetUtil.h"
  58. #include "nsRect.h"
  59. #include "nsStringGlue.h"
  60. #include "nsWeakReference.h"
  61. #include "nsIWebBrowser.h"
  62. #include "nsIObserverService.h"
  63. #include "nsIDOMEventTarget.h"
  64. #include "nsPIDOMWindow.h"
  65. #include "nsIDOMWindow.h"
  66. #include "nsIDOMCompositionListener.h"
  67. #include "nsIDOMTextListener.h"
  68. #include "nsIDOMMouseEvent.h"
  69. #include "nsIDOMNSEvent.h"
  70. #include "nsIView.h"
  71. #include "nsGUIEvent.h"
  72. #include "nsIViewManager.h"
  73. #include "nsIContentPolicy.h"
  74. #include "nsIDocShellTreeItem.h"
  75. #include "nsIContent.h"
  76. #include "nsITimer.h"
  77. const int MIN_INT =((int) (1 << (sizeof(int) * 8 - 1)));
  78. static int g_lastX=MIN_INT;
  79. static int g_lastY=MIN_INT;
  80. static PRInt32 g_panning = 0;
  81. static bool g_is_scrollable = false;
  82. #define EM_MULT 16.
  83. #define NS_FRAME_HAS_RELATIVE_SIZE 0x01000000
  84. #define NS_FRAME_HAS_OPTIMIZEDVIEW 0x02000000
  85. #define BEHAVIOR_ACCEPT nsIPermissionManager::ALLOW_ACTION
  86. #define BEHAVIOR_REJECT nsIPermissionManager::DENY_ACTION
  87. #define BEHAVIOR_NOFOREIGN 3
  88. #define NUMBER_OF_TYPES 13
  89. // TODO auto reload nsWidgetUtils in C.
  90. class nsWidgetUtils : public nsIObserver,
  91. public nsIDOMEventListener,
  92. public nsIContentPolicy,
  93. public nsSupportsWeakReference
  94. {
  95. public:
  96. nsWidgetUtils();
  97. virtual ~nsWidgetUtils();
  98. NS_DECL_ISUPPORTS
  99. NS_DECL_NSIDOMEVENTLISTENER
  100. NS_DECL_NSIOBSERVER
  101. NS_DECL_NSICONTENTPOLICY
  102. private:
  103. nsresult Init(void);
  104. void RemoveWindowListeners(nsIDOMWindow *aDOMWin);
  105. void GetChromeEventHandler(nsIDOMWindow *aDOMWin, nsIDOMEventTarget **aChromeTarget);
  106. void AttachWindowListeners(nsIDOMWindow *aDOMWin);
  107. bool IsXULNode(nsIDOMNode *aNode, PRUint32 *aType = 0);
  108. nsresult GetDOMWindowByNode(nsIDOMNode *aNode, nsIDOMWindow * *aDOMWindow);
  109. nsresult UpdateFromEvent(nsIDOMEvent *aDOMEvent);
  110. nsresult MouseDown(nsIDOMEvent* aDOMEvent);
  111. nsresult MouseUp(nsIDOMEvent* aDOMEvent);
  112. nsresult MouseMove(nsIDOMEvent* aDOMEvent);
  113. static void StopPanningCallback(nsITimer *timer, void *closure);
  114. nsCOMPtr<nsIWidget> mWidget;
  115. nsCOMPtr<nsIViewManager> mViewManager;
  116. nsCOMPtr<nsITimer> mTimer;
  117. };
  118. nsWidgetUtils::nsWidgetUtils()
  119. {
  120. Init();
  121. }
  122. NS_IMETHODIMP
  123. nsWidgetUtils::Init()
  124. {
  125. nsresult rv;
  126. nsCOMPtr<nsIObserverService> obsSvc =
  127. do_GetService("@mozilla.org/observer-service;1");
  128. NS_ENSURE_STATE(obsSvc);
  129. rv = obsSvc->AddObserver(this, "domwindowopened", false);
  130. NS_ENSURE_SUCCESS(rv, rv);
  131. rv = obsSvc->AddObserver(this, "domwindowclosed", false);
  132. NS_ENSURE_SUCCESS(rv, rv);
  133. mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
  134. }
  135. nsresult
  136. nsWidgetUtils::UpdateFromEvent(nsIDOMEvent *aDOMEvent)
  137. {
  138. nsCOMPtr <nsIDOMMouseEvent> mouseEvent;
  139. mouseEvent = do_QueryInterface(aDOMEvent);
  140. if (!mouseEvent)
  141. return NS_OK;
  142. ((nsIDOMMouseEvent*)mouseEvent)->GetScreenX(&g_lastX);
  143. ((nsIDOMMouseEvent*)mouseEvent)->GetScreenY(&g_lastY);
  144. nsCOMPtr<nsIDOMWindow> mWindow;
  145. nsCOMPtr<nsIDOMNode> mNode;
  146. nsCOMPtr<nsIDOMNode> mOrigNode;
  147. PRUint32 type = 0;
  148. bool isXul = false;
  149. {
  150. nsCOMPtr <nsIDOMNSEvent> aEvent = do_QueryInterface(aDOMEvent);
  151. nsCOMPtr<nsIDOMEventTarget> eventOrigTarget;
  152. if (aEvent)
  153. aEvent->GetOriginalTarget(getter_AddRefs(eventOrigTarget));
  154. if (eventOrigTarget)
  155. mOrigNode = do_QueryInterface(eventOrigTarget);
  156. isXul = IsXULNode(mOrigNode, &type);
  157. }
  158. if (isXul)
  159. return NS_ERROR_FAILURE;
  160. nsCOMPtr<nsIDOMEventTarget> eventTarget;
  161. aDOMEvent->GetTarget(getter_AddRefs(eventTarget));
  162. if (eventTarget)
  163. mNode = do_QueryInterface(eventTarget);
  164. if (!mNode)
  165. return NS_OK;
  166. GetDOMWindowByNode(mNode, getter_AddRefs(mWindow));
  167. if (!mWindow)
  168. return NS_OK;
  169. nsCOMPtr<nsIDocument> doc;
  170. nsCOMPtr<nsIDOMDocument> domDoc;
  171. mWindow->GetDocument(getter_AddRefs(domDoc));
  172. doc = do_QueryInterface(domDoc);
  173. if (!doc) return NS_OK;
  174. // the only case where there could be more shells in printpreview
  175. nsIPresShell *shell = doc->GetShell();
  176. NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
  177. mViewManager = shell->GetViewManager();
  178. NS_ENSURE_TRUE(mViewManager, NS_ERROR_FAILURE);
  179. mViewManager->GetRootWidget(getter_AddRefs(mWidget));
  180. NS_ENSURE_TRUE(mWidget, NS_ERROR_FAILURE);
  181. return NS_OK;
  182. }
  183. nsresult
  184. nsWidgetUtils::MouseDown(nsIDOMEvent* aDOMEvent)
  185. {
  186. g_is_scrollable = false;
  187. // Return TRUE from your signal handler to mark the event as consumed.
  188. if (NS_FAILED(UpdateFromEvent(aDOMEvent)))
  189. return NS_OK;
  190. g_is_scrollable = true;
  191. if (g_is_scrollable) {
  192. aDOMEvent->StopPropagation();
  193. aDOMEvent->PreventDefault();
  194. }
  195. return NS_OK;
  196. }
  197. /* static */ void
  198. nsWidgetUtils::StopPanningCallback(nsITimer *timer, void *closure)
  199. {
  200. g_panning = false;
  201. }
  202. nsresult
  203. nsWidgetUtils::MouseUp(nsIDOMEvent* aDOMEvent)
  204. {
  205. nsCOMPtr <nsIDOMMouseEvent> mouseEvent;
  206. mouseEvent = do_QueryInterface(aDOMEvent);
  207. if (!mouseEvent)
  208. return NS_OK;
  209. // Return TRUE from your signal handler to mark the event as consumed.
  210. g_lastX = MIN_INT;
  211. g_lastY = MIN_INT;
  212. g_is_scrollable = false;
  213. if (g_panning) {
  214. aDOMEvent->StopPropagation();
  215. aDOMEvent->PreventDefault();
  216. nsresult rv;
  217. if (mTimer) {
  218. rv = mTimer->InitWithFuncCallback(nsWidgetUtils::StopPanningCallback,
  219. nsnull, 500, nsITimer::TYPE_ONE_SHOT);
  220. if (NS_SUCCEEDED(rv))
  221. return NS_OK;
  222. }
  223. g_panning = false;
  224. }
  225. return NS_OK;
  226. }
  227. nsresult
  228. nsWidgetUtils::MouseMove(nsIDOMEvent* aDOMEvent)
  229. {
  230. if (!g_is_scrollable) return NS_OK;
  231. nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aDOMEvent);
  232. if (!mouseEvent)
  233. return NS_OK;
  234. int x, y;
  235. ((nsIDOMMouseEvent*)mouseEvent)->GetScreenX(&x);
  236. ((nsIDOMMouseEvent*)mouseEvent)->GetScreenY(&y);
  237. int dx = g_lastX - x;
  238. int dy = g_lastY - y;
  239. if(g_lastX == MIN_INT || g_lastY == MIN_INT)
  240. return NS_OK;
  241. nsIView* aView = mViewManager->GetRootView();
  242. if (!aView)
  243. if (NS_FAILED(UpdateFromEvent(aDOMEvent)))
  244. return NS_OK;
  245. nsEventStatus statusX;
  246. nsMouseScrollEvent scrollEventX(true, NS_MOUSE_SCROLL, mWidget);
  247. scrollEventX.delta = dx;
  248. scrollEventX.scrollFlags = nsMouseScrollEvent::kIsHorizontal | nsMouseScrollEvent::kHasPixels;
  249. mViewManager->DispatchEvent(&scrollEventX, aView, &statusX);
  250. if(statusX != nsEventStatus_eIgnore ){
  251. if (dx > 5)
  252. g_panning = true;
  253. g_lastX = x;
  254. }
  255. nsEventStatus statusY;
  256. nsMouseScrollEvent scrollEventY(true, NS_MOUSE_SCROLL, mWidget);
  257. scrollEventY.delta = dy;
  258. scrollEventY.scrollFlags = nsMouseScrollEvent::kIsVertical | nsMouseScrollEvent::kHasPixels;
  259. mViewManager->DispatchEvent(&scrollEventY, aView, &statusY);
  260. if(statusY != nsEventStatus_eIgnore ){
  261. if (dy > 5)
  262. g_panning = true;
  263. g_lastY = y;
  264. }
  265. if (g_panning) {
  266. aDOMEvent->StopPropagation();
  267. aDOMEvent->PreventDefault();
  268. }
  269. return NS_OK;
  270. }
  271. // nsIContentPolicy Implementation
  272. NS_IMETHODIMP
  273. nsWidgetUtils::ShouldLoad(PRUint32 aContentType,
  274. nsIURI *aContentLocation,
  275. nsIURI *aRequestingLocation,
  276. nsISupports *aRequestingContext,
  277. const nsACString &aMimeGuess,
  278. nsISupports *aExtra,
  279. PRInt16 *aDecision)
  280. {
  281. *aDecision = nsIContentPolicy::ACCEPT;
  282. nsresult rv;
  283. if (aContentType != nsIContentPolicy::TYPE_DOCUMENT)
  284. return NS_OK;
  285. // we can't do anything without this
  286. if (!aContentLocation)
  287. return NS_OK;
  288. nsCAutoString scheme;
  289. rv = aContentLocation->GetScheme(scheme);
  290. nsCAutoString lscheme;
  291. ToLowerCase(scheme, lscheme);
  292. if (!lscheme.EqualsLiteral("ftp") &&
  293. !lscheme.EqualsLiteral("http") &&
  294. !lscheme.EqualsLiteral("https"))
  295. return NS_OK;
  296. if (g_panning > 0)
  297. *aDecision = nsIContentPolicy::REJECT_REQUEST;
  298. return NS_OK;
  299. }
  300. NS_IMETHODIMP
  301. nsWidgetUtils::HandleEvent(nsIDOMEvent* aDOMEvent)
  302. {
  303. nsAutoString eventType;
  304. aEvent->GetType(eventType);
  305. if (eventType.EqualsLiteral("mousedown")) {
  306. return MouseDown(aEvent);
  307. }
  308. if (eventType.EqualsLiteral("mouseup")) {
  309. return MouseUp(aEvent);
  310. }
  311. if (eventType.EqualsLiteral("mousemove")) {
  312. return MouseMove(aEvent);
  313. }
  314. return NS_OK;
  315. }
  316. NS_IMETHODIMP
  317. nsWidgetUtils::ShouldProcess(PRUint32 aContentType,
  318. nsIURI *aContentLocation,
  319. nsIURI *aRequestingLocation,
  320. nsISupports *aRequestingContext,
  321. const nsACString &aMimeGuess,
  322. nsISupports *aExtra,
  323. PRInt16 *aDecision)
  324. {
  325. *aDecision = nsIContentPolicy::ACCEPT;
  326. return NS_OK;
  327. }
  328. bool
  329. nsWidgetUtils::IsXULNode(nsIDOMNode *aNode, PRUint32 *aType)
  330. {
  331. bool retval = false;
  332. if (!aNode) return retval;
  333. nsString sorigNode;
  334. aNode->GetNodeName(sorigNode);
  335. if (sorigNode.EqualsLiteral("#document"))
  336. return retval;
  337. retval = StringBeginsWith(sorigNode, NS_LITERAL_STRING("xul:"));
  338. if (!aType) return retval;
  339. if (sorigNode.EqualsLiteral("xul:thumb")
  340. || sorigNode.EqualsLiteral("xul:vbox")
  341. || sorigNode.EqualsLiteral("xul:spacer"))
  342. *aType = false; // Magic
  343. else if (sorigNode.EqualsLiteral("xul:slider"))
  344. *aType = 2; // Magic
  345. else if (sorigNode.EqualsLiteral("xul:scrollbarbutton"))
  346. *aType = 3; // Magic
  347. return retval;
  348. }
  349. nsresult
  350. nsWidgetUtils::GetDOMWindowByNode(nsIDOMNode* aNode, nsIDOMWindow** aDOMWindow)
  351. {
  352. nsCOMPtr<nsIDOMDocument> nodeDoc;
  353. nsresult rv = aNode->GetOwnerDocument(getter_AddRefs(nodeDoc));
  354. NS_ENSURE_SUCCESS(rv, rv);
  355. NS_ENSURE_TRUE(nodeDoc, NS_ERROR_NULL_POINTER);
  356. nsCOMPtr<nsIDOMWindow> window;
  357. rv = nodeDoc->GetDefaultView(getter_AddRefs(window));
  358. NS_ENSURE_SUCCESS(rv, rv);
  359. NS_ENSURE_TRUE(window, NS_ERROR_NULL_POINTER);
  360. window.forget(aDOMWindow);
  361. return rv;
  362. }
  363. void
  364. nsWidgetUtils::GetChromeEventHandler(nsIDOMWindow *aDOMWin,
  365. nsIDOMEventTarget **aChromeTarget)
  366. {
  367. nsCOMPtr<nsPIDOMWindow> privateDOMWindow(do_QueryInterface(aDOMWin));
  368. nsIDOMEventTarget* chromeEventHandler = nsnull;
  369. if (privateDOMWindow) {
  370. chromeEventHandler = privateDOMWindow->GetChromeEventHandler();
  371. }
  372. NS_IF_ADDREF(*aChromeTarget = chromeEventHandler);
  373. }
  374. void
  375. nsWidgetUtils::RemoveWindowListeners(nsIDOMWindow *aDOMWin)
  376. {
  377. nsresult rv;
  378. nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
  379. GetChromeEventHandler(aDOMWin, getter_AddRefs(chromeEventHandler));
  380. if (!chromeEventHandler) {
  381. return;
  382. }
  383. // Use capturing, otherwise the normal find next will get activated when ours should
  384. // Remove DOM Text listener for IME text events
  385. chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("mousedown"),
  386. this, false);
  387. chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("mouseup"),
  388. this, false);
  389. chromeEventHandler->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
  390. this, false);
  391. }
  392. void
  393. nsWidgetUtils::AttachWindowListeners(nsIDOMWindow *aDOMWin)
  394. {
  395. nsresult rv;
  396. nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
  397. GetChromeEventHandler(aDOMWin, getter_AddRefs(chromeEventHandler));
  398. if (!chromeEventHandler) {
  399. return;
  400. }
  401. // Use capturing, otherwise the normal find next will get activated when ours should
  402. // Attach menu listeners, this will help us ignore keystrokes meant for menus
  403. chromeEventHandler->AddEventListener(NS_LITERAL_STRING("mousedown"), this,
  404. false, false);
  405. chromeEventHandler->AddEventListener(NS_LITERAL_STRING("mouseup"), this,
  406. false, false);
  407. chromeEventHandler->AddEventListener(NS_LITERAL_STRING("mousemove"), this,
  408. false, false);
  409. }
  410. nsWidgetUtils::~nsWidgetUtils()
  411. {
  412. }
  413. NS_IMPL_ISUPPORTS4(nsWidgetUtils,
  414. nsIObserver,
  415. nsIDOMEventListener,
  416. nsIContentPolicy,
  417. nsISupportsWeakReference)
  418. NS_IMETHODIMP
  419. nsWidgetUtils::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
  420. {
  421. nsresult rv;
  422. if (!strcmp(aTopic,"domwindowopened"))
  423. {
  424. nsCOMPtr<nsIDOMWindow> chromeWindow = do_QueryInterface(aSubject);
  425. if (chromeWindow)
  426. AttachWindowListeners(chromeWindow);
  427. return NS_OK;
  428. }
  429. if (!strcmp(aTopic,"domwindowclosed"))
  430. {
  431. nsCOMPtr<nsIDOMWindow> chromeWindow = do_QueryInterface(aSubject);
  432. RemoveWindowListeners(chromeWindow);
  433. return NS_OK;
  434. }
  435. return NS_OK;
  436. }
  437. //------------------------------------------------------------------------------
  438. // XPCOM REGISTRATION BELOW
  439. //------------------------------------------------------------------------------
  440. #define WidgetUtils_CID \
  441. { 0x0ced17b6, 0x96ed, 0x4030, \
  442. {0xa1, 0x34, 0x77, 0xcb, 0x66, 0x10, 0xa8, 0xf6} }
  443. #define WidgetUtils_ContractID "@mozilla.org/extensions/widgetutils;1"
  444. static NS_METHOD WidgetUtilsRegistration(nsIComponentManager *aCompMgr,
  445. nsIFile *aPath,
  446. const char *registryLocation,
  447. const char *componentType,
  448. const nsModuleComponentInfo *info)
  449. {
  450. nsresult rv;
  451. nsCOMPtr<nsIServiceManager> servman = do_QueryInterface((nsISupports*)aCompMgr, &rv);
  452. if (NS_FAILED(rv))
  453. return rv;
  454. nsCOMPtr<nsICategoryManager> catman;
  455. servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
  456. NS_GET_IID(nsICategoryManager),
  457. getter_AddRefs(catman));
  458. if (NS_FAILED(rv))
  459. return rv;
  460. char* previous = nsnull;
  461. rv = catman->AddCategoryEntry("app-startup",
  462. "WidgetUtils",
  463. WidgetUtils_ContractID,
  464. true,
  465. true,
  466. &previous);
  467. if (previous)
  468. nsMemory::Free(previous);
  469. rv = catman->AddCategoryEntry("content-policy",
  470. "WidgetUtils",
  471. WidgetUtils_ContractID,
  472. true,
  473. true,
  474. &previous);
  475. if (previous)
  476. nsMemory::Free(previous);
  477. return rv;
  478. }
  479. static NS_METHOD WidgetUtilsUnregistration(nsIComponentManager *aCompMgr,
  480. nsIFile *aPath,
  481. const char *registryLocation,
  482. const nsModuleComponentInfo *info)
  483. {
  484. nsresult rv;
  485. nsCOMPtr<nsIServiceManager> servman = do_QueryInterface((nsISupports*)aCompMgr, &rv);
  486. if (NS_FAILED(rv))
  487. return rv;
  488. nsCOMPtr<nsICategoryManager> catman;
  489. servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
  490. NS_GET_IID(nsICategoryManager),
  491. getter_AddRefs(catman));
  492. if (NS_FAILED(rv))
  493. return rv;
  494. rv = catman->DeleteCategoryEntry("app-startup",
  495. "WidgetUtils",
  496. true);
  497. rv = catman->DeleteCategoryEntry("content-policy",
  498. "WidgetUtils",
  499. true);
  500. return rv;
  501. }
  502. NS_GENERIC_FACTORY_CONSTRUCTOR(nsWidgetUtils)
  503. static const nsModuleComponentInfo components[] =
  504. {
  505. { "nsWidgetUtilsService",
  506. WidgetUtils_CID,
  507. WidgetUtils_ContractID,
  508. nsWidgetUtilsConstructor,
  509. WidgetUtilsRegistration,
  510. WidgetUtilsUnregistration
  511. }
  512. };
  513. NS_IMPL_NSGETMODULE(nsWidgetUtilsModule, components)