Compare commits

...
Author SHA1 Message Date
wolfbeast a731633d7b Revert "Issue #1473 - Add %OS_SLICE% macro to SSUAO to refine OS info"
This reverts commit 3c8bc3da7c.
2020-03-24 21:12:24 +01:00
wolfbeast cd2ffb4b8f Revert "Issue #1482 - Give dynamic SSUAO rules priority over static ones"
This reverts commit a20f208834.
2020-03-24 21:11:53 +01:00
Brian Smith df9ab936f2 Issue #1491 - Part 2: Disable a workaround on macOS 10.14+ for an Apple bug described in Mozilla bug 378645 involving popup windows that was fixed by Apple. 2020-03-22 14:44:22 +01:00
Brian Smith 8c7ca10cfe Issue #1491 - Part 1: Update nsCocoaFeatures for newer versions of MacOS X. 2020-03-22 14:44:09 +01:00
wolfbeast 0a5ad190c3 [devtools] Properly escape method arguments for curl. 2020-03-19 07:55:33 +01:00
wolfbeast 97b0520d7b Revert "Issue #1445 - Clarify the status of extensions in the Add-On manager"
This reverts commit f107de8a90.
2020-03-19 06:36:18 +01:00
wolfbeast b33a151836 Revert "Issue #1446 - Only allow extension add-on types for Firefox compat mode."
This reverts commit e8417acbff.
2020-03-19 06:36:03 +01:00
wolfbeast 32ca14f34b Revert "Issue #1446 - Only match extension add-on types for target applications."
This reverts commit 4889e6dbbd.
2020-03-19 06:35:47 +01:00
wolfbeast 0da8e0b496 Revert "Issue #1445 - Use the detailed string also in the list entries."
This reverts commit ac68f8cf6c.
2020-03-19 06:35:22 +01:00
wolfbeast 473e75d5aa Revert "Issue #1445 - remove redundant nativeIndicator"
This reverts commit 2073a7f1c9.
2020-03-19 06:34:46 +01:00
wolfbeast 28613ba836 Revert "Issue #1445 - Add a link to details on using Firefox extensions in Pale Moon"
This reverts commit c220c30bbb.
2020-03-19 06:34:28 +01:00
wolfbeast 8a5b121489 Revert "Issue #1445 - strings cleanup"
This reverts commit 461a9e86b2.
2020-03-19 06:34:02 +01:00
wolfbeast 9550c68d7a [DOM] Make sure to exit fullscreen mode if popups are opened or focused. 2020-03-18 21:15:10 +01:00
wolfbeast 54f44bb628 [js] Remove pointless MakeMRegExpHoistable optimization.
It's a lot of code with no measurable effect.
2020-03-18 13:31:19 +01:00
wolfbeast 22fc220354 [network] Cherry-pick various sctp lib upstream fixes. 2020-03-18 11:11:13 +01:00
wolfbeast 6d504711a0 Issue #1355 - Make addition of cell border display items depend on
whether they should be drawn.

This reduces the size of display lists for tables by only adding display
list items that are actually going to be visibly drawn, which will help
overall performance of table drawing.
2020-03-16 09:30:31 +01:00
Moonchild 60ea1e85f5 Merge pull request #1484 from JustOff/PR_ssuao_priority
Give dynamic SSUAO rules priority over static ones
2020-03-15 17:34:46 +01:00
JustOff a20f208834 Issue #1482 - Give dynamic SSUAO rules priority over static ones 2020-03-15 13:41:46 +02:00
Moonchild a1f53ada59 Merge pull request #1486 from MoonchildProductions/1485
Fix incorrect grid cell sizing to min/max space.
2020-03-15 00:10:54 +01:00
Matt A. Tobin 157a4abbcc Issue #1477 - Fix finding config.guess on builds not using MOZ_OBJDIR
* So far this seems to only affect Macintosh builds but other unix builds may be affected. Windows doesn't seem to be.
* This maintains consistency with other one-off file invocations and backwards compatibility with older comm setups
2020-03-13 13:00:12 -04:00
wolfbeast b3a4b8361e Issue #1485 - Fix incorrect grid cell sizing to min/max space.
There were actually two separate logical errors in this method:

The first part is that "origSizes.isSome()" is simply a bogus
requirement for applying min/max-sizes here. I'm still keeping
the optimization of not needlessly copying the mSizes array
(as originally intended) since it's a quite common case.

The second bug is that min/max-sizes were only applied under
the "if (fr != 0.0f)" block. This is bogus since the calculated
'fr' value depends on 'aAvailableSize' which might change by
applying min/max-sizes and thus 'fr' could become non-zero in
the second round.
To fix, this patch just moves "applyMinMax" block out one level.
2020-03-13 11:28:54 +01:00
Moonchild 41e5925b42 Merge pull request #1481 from MoonchildProductions/1480
Skip abspos, fixed, float and placeholders for outline.
2020-03-11 23:24:42 +01:00
wolfbeast 8dc520647d Issue #1480 - Skip abspos, fixed, float and placeholders for outline. 2020-03-11 13:01:48 +01:00
Moonchild e8275b9a1e Merge pull request #1479 from JustOff/PR_uau_cleanup
Remove no longer used function and modules from UserAgentUpdates.jsm
2020-03-11 11:49:30 +01:00
JustOff ad7526fe70 Issue #1053 - Remove no longer used function and modules from UserAgentUpdates.jsm 2020-03-11 01:07:33 +02:00
New Tobin Paradigm ccee9ea5b7 Merge pull request #1476 from JustOff/PR_ssuao_os_slice
Add `%OS_SLICE%` macro to SSUAO to refine OS info
2020-03-10 16:58:06 -04:00
wolfbeast fda8403f56 Minor update to UXP coding style guideline. 2020-03-10 12:47:03 +01:00
JustOff 3c8bc3da7c Issue #1473 - Add %OS_SLICE% macro to SSUAO to refine OS info 2020-03-10 13:10:26 +02:00
New Tobin Paradigm be415c44c7 Update README.md 2020-03-09 17:38:25 -04:00
wolfbeast a1e6132772 Issue #1474 - Prevent the cp detection from starting if preffed off.
When setting up connectivity, e.g. with new network detection, the pref
wouldn't be checked (or honored), resulting in spurious startup calls
despite being preffed off. This fixes that.

Resolves #1474
2020-03-07 21:58:27 +01:00
wolfbeast 9815e4bdf0 Update UXP coding style guide JS guide. 2020-03-07 12:30:31 +01:00
wolfbeast d0b2595322 Update UXP coding style guide JS guide. 2020-03-06 23:23:57 +01:00
Matt A. Tobin b14d245a8a Merge branch 'updateutils-work' 2020-03-06 15:05:51 -05:00
wolfbeast 66ab2fa3da Update UXP coding style guide with JS guide. 2020-03-06 11:47:52 +01:00
Matt A. Tobin 4d80ed3d51 Issue #1470 - Part 3: Remove now unused update.locale
This requires changes to package-manifest in all applications
2020-03-05 19:30:38 -05:00
Matt A. Tobin 8baaecd89c Issue #1470 - Part 2: Change calls from UpdateUtils.getUpdateChannel() to UpdateUtils.UpdateChannel in telemetry modules 2020-03-05 19:24:11 -05:00
Matt A. Tobin aaedcc45fb Issue #1470 - Part 1: Refactor UpdateUtils.jsm 2020-03-05 19:22:49 -05:00
New Tobin Paradigm 88da01c294 Remove exposed bug from UpdateUtils.jsm 2020-03-04 13:03:27 -05:00
Matt A. Tobin 65b37410ca Revert "Issue #190 - Part 1: Remove XP_IOS conditional code"
This reverts commit 6a3d5769d0.
2020-02-28 18:00:45 -05:00
Matt A. Tobin 6a3d5769d0 Issue #190 - Part 1: Remove XP_IOS conditional code 2020-02-28 17:58:46 -05:00
Matt A. Tobin 1d86d37828 Issue #1053 - Remove android-only skia-npapi 2020-02-28 17:19:05 -05:00
Matt A. Tobin 9b86872d37 Issue #1053 - Remove android support from nsNSSComponent.cpp 2020-02-28 16:51:00 -05:00
Matt A. Tobin f0abf6273c Issue #251 - Move --disable-dbm to ac configure
Also Tag #1467
2020-02-28 16:21:05 -05:00
Matt A. Tobin 76bacde2ae Remove unused mailnews.mozbuild 2020-02-28 15:11:25 -05:00
Matt A. Tobin 9fceb389c1 Mork is not dependent on dbm and never was. 2020-02-28 15:01:37 -05:00
Matt A. Tobin c30898ce33 Correct typo in mailnews/base/src/moz.build 2020-02-28 15:01:13 -05:00
Matt A. Tobin b118bab81f Issue #1319 - Remove EARLY_BETA_OR_EARLIER condition 2020-02-28 12:05:19 -05:00
wolfbeast ae8eb4d4c4 Issue #1465 - Implement optional catch binding. 2020-02-27 20:09:26 +01:00
wolfbeast 793da7dd62 Revert "Issue #1355 - Better way to create display items for column backgrounds"
This reverts commit 44c47c5038.
2020-02-26 20:51:22 +01:00
wolfbeast 16abf27e65 Revert "Layout\reftests\table-background\reftest.list should have only additions to the end of it."
This reverts commit efdc2af8ab.
2020-02-26 20:51:05 +01:00
wolfbeast cdc2a22c79 [DOM] Add a null check 2020-02-26 16:22:10 +01:00
Matt A. Tobin de35c43f12 Merge branch 'master' of https://github.com/MoonchildProductions/UXP 2020-02-26 09:25:07 -05:00
Matt A. Tobin 11d14ae59f No Issue - Always build marionette until it can be tracked down and killed 2020-02-26 09:24:49 -05:00
Moonchild d585e25e27 Merge pull request #1463 from win7-7/column-backgrounds-pr
Better way to create display items for column backgrounds
2020-02-26 13:53:30 +01:00
Matt A. Tobin 4ff7606b6a Issue #1053 - Remove android preprocessor directive from toolkit/locales/jar.mn 2020-02-25 22:22:41 -05:00
Moonchild cce2bc9677 Merge pull request #1461 from MoonchildProductions/ubbo
Back out unboxed array/object removals
2020-02-26 02:38:18 +01:00
Matt A. Tobin 35c26c6c19 Issue #1053 - Remove android support from toolkit
Note: Does not remove support completely from toolkit/mozapps/installer or from telemetry or AppConstants.jsm
2020-02-25 19:45:39 -05:00
Matt A. Tobin 8f35c37a9e Bug 1339444 - Remove unused resource://gre/modules/sqlite/sqlite_internal.js 2020-02-25 18:24:40 -05:00
win7-7 efdc2af8ab Layout\reftests\table-background\reftest.list should have only additions to the end of it.
Layout\reftests\table-background\reftest.list should have only additions to the end of it. Revert incorrect additions.
2020-02-26 00:36:09 +02:00
Matt A. Tobin 0ddd00f195 Issue #439 - Remove tests from toolkit/ 2020-02-25 15:07:00 -05:00
Matt A. Tobin 20f0905b33 Issue #1053 - Remove android support from db 2020-02-25 12:28:41 -05:00
Matt A. Tobin 8e09aff187 Issue #1053 - Remove android support from docshell 2020-02-25 12:26:18 -05:00
win7-7 44c47c5038 Issue #1355 - Better way to create display items for column backgrounds
Part 1: Remove current table item, as it's never set.

Part 2: Get rid of generic table painting code, and handle each class separately.

Part 4: Hoist outline skipping into col(group) frame code.

Part 5: Skip box-shadow for table column and column groups.

Part 6: Store column and column group backgrounds separately, and then append them before the rest of the table contents.

Part 7: Pass rects in display list coordinates to AppendBackgroundItemsToTop.

Part 8: Create column and column group background display items as part of the cell's BuildDisplayList.

Part 9: Used cached values instead of calling nsDisplayListBuilder::ToReferenceFrame when possible, since it can be expensive when the requested frame isn't the builder's current frame.

Part 10: Make sure we build display items for table parts where only the normal position is visible, since we may need to create background items for ancestors at that position.

Part 11: Create an AutoBuildingDisplayList when we create background items for table columns and column groups, so that we initialize the invalidation state correctly.
2020-02-25 00:17:54 +02:00
wolfbeast ecdeefc4dd Revert #1091 Remove unboxed object code phase 1 + extras.
This should be the last code backout for this. merging this branch
should get us back to the way we were (+ additional code changes for
later changes) as fasr as the unused unboxed code is concerned.
2020-02-23 19:43:47 +01:00
Matt A. Tobin 81089ff094 Issue #1053 - Remove android support from hal 2020-02-23 11:29:12 -05:00
Matt A. Tobin 30e4959bd3 Issue #1053 - Remove android support from image 2020-02-23 11:28:41 -05:00
Matt A. Tobin 33ec695ac0 Issue #1053 - Remove android support from intl/locale/nsLocaleService.cpp
This is the only non-icu file with android code in it. Not going to remove android in icu its self because it remains a 3rd party lib.
2020-02-23 11:18:42 -05:00
Matt A. Tobin e9ee12c988 Follow-up to 4e2e9be6a - Move HeapSnapshot DevTools-only Modules back to DevTools
I am so done with this.

Resolves #316
2020-02-23 10:38:36 -05:00
wolfbeast dd57b9273c Revert #1137 - Remove unboxed arrays
- accounting for removal of watch()/unwatch()
- updated for intermediate code changes.
2020-02-23 14:41:40 +01:00
wolfbeast be16123ddc Revert "Issue #1382 - Remove invalid assertion."
This reverts commit 9c6a8450b3.
2020-02-23 11:33:50 +01:00
Matt A. Tobin e9360fae13 Issue #1053 - Remove android support from memory 2020-02-23 00:26:22 -05:00
Matt A. Tobin 2896724eaf Issue #1053 - Remove android support from mfbt 2020-02-22 23:30:31 -05:00
Matt A. Tobin dada39db23 Issue #1053 - Remove android support from ipc except for ipc/chromium
This does not include android in the imported chromium code as specific research needs done on defines and logic.
2020-02-22 22:44:01 -05:00
Matt A. Tobin 5496e4f391 Issue #1053 - Remove android support from mozglue
Yes, I checked for unsaved files this time...
2020-02-22 21:16:37 -05:00
Matt A. Tobin 13a8e78881 Issue #1053 - Remove android support from netwerk/protocol/http/nsHttpHandler.cpp 2020-02-22 20:48:32 -05:00
Matt A. Tobin bdad2357a1 Issue #1053 - Remove android support from netwerk 2020-02-22 20:10:23 -05:00
Matt A. Tobin 881c1e5f18 Issue #1053 - Remove android support from storage/mozStorageConnection.cpp 2020-02-22 19:31:52 -05:00
Matt A. Tobin ce21c398d7 Issue #1053 - Remove android support from uriloader 2020-02-22 19:22:01 -05:00
Matt A. Tobin c895d35a7a Issue #1053 - Remove android support from xpcom/threads/nsThread.cpp
Forgot to save..
2020-02-22 19:04:51 -05:00
Matt A. Tobin 69ed4e4b4e Issue #1053 - Remove android support from XPCOM 2020-02-22 19:03:00 -05:00
Matt A. Tobin 7c8262e8c3 Remove redundant moz.build from db/ 2020-02-22 17:47:21 -05:00
Matt A. Tobin 4e2e9be6ab Reclassify heapsnapshot and nsJSInspector as not part of devtools
This resolves Issue #316
2020-02-22 17:32:39 -05:00
wolfbeast 5ee844f710 Revert #1142 - Remove unboxed objects
- accounting for removal of watch()/unwatch()
2020-02-22 21:09:32 +01:00
wolfbeast b1cd96989b Revert 1320408 part 15: Make addDataProperty static 2020-02-22 21:07:48 +01:00
wolfbeast a7888b8cf2 Set module default identification properly. 2020-02-21 18:50:28 +01:00
wolfbeast 944cf0dda9 Remove gtest reference to non-existing path of removed component 2020-02-21 12:21:10 +00:00
wolfbeast 623c44226a [gfx] Put Skia-specific CTOR init behind Skia-conditional. 2020-02-21 12:12:47 +00:00
wolfbeast 1e88448ddf Merge branch '316' 2020-02-21 01:20:27 +01:00
wolfbeast 5e21bf1d54 Issue #316 - Make sure MOZ_DEVTOOLS_SERVER is passed down to js. 2020-02-21 01:19:16 +01:00
Matt A. Tobin 04fb9eaa6a Issue #1053 - Remove android support from NPAPI 2020-02-20 12:44:29 -05:00
Matt A. Tobin b36e606158 Issue #1053 - Remove conditional android code from widget/ 2020-02-20 12:12:30 -05:00
Matt A. Tobin 18e74277b3 Issue #1053 - Remove Android Widget Toolkit specific files 2020-02-20 11:22:40 -05:00
Matt A. Tobin 178382e4ce Issue #439 - Remove tests from widget/ 2020-02-20 11:08:15 -05:00
Moonchild 7832dded37 Merge pull request #1458 from MoonchildProductions/316
Fix buildability of builds without devtools-server
2020-02-20 16:50:49 +01:00
wolfbeast d53b11c9dc Issue #316 - Be more gentle with the CC and nursery. 2020-02-20 16:47:04 +01:00
Matt A. Tobin 0e9957c412 Issue #1457 - Unfold sqlite3 from nss 2020-02-20 10:02:49 -05:00
wolfbeast 28f67bddcf Issue #316 - Pre-process Performance.webidl 2020-02-20 13:29:03 +01:00
wolfbeast 59f7a2cdb4 Issue #316 - Make the memory GC performance object conditional (WIP)
This was only added for GCubench and likely interfering with building
without devtools-server.
2020-02-20 12:00:26 +01:00
wolfbeast e3d81b698e Issue #1383 - Remove "Copy raw data to clipboard" button
This resolves #1383
2020-02-20 11:01:30 +01:00
Moonchild 0a8530b916 Merge pull request #1455 from JustOff/issue1445_details_url
Add a link to details on using Firefox extensions in Pale Moon
2020-02-19 21:23:24 +01:00
Matt A. Tobin e6b48cb648 Issue #1454 - Add MOZ_PKG_SPECIAL to UpdateUtils 2020-02-19 15:05:50 -05:00
JustOff c220c30bbb Issue #1445 - Add a link to details on using Firefox extensions in Pale Moon 2020-02-19 19:30:21 +02:00
Moonchild 8dc04fc24b Merge pull request #1452 from JustOff/Issue1445_cleanup
Issue #1445 - strings cleanup
2020-02-19 14:34:44 +01:00
JustOff 461a9e86b2 Issue #1445 - strings cleanup 2020-02-19 14:37:14 +02:00
wolfbeast 2073a7f1c9 Issue #1445 - remove redundant nativeIndicator
This resolves #1445
2020-02-19 11:56:34 +01:00
Matt A. Tobin 66b9ddfd32 Issue #1320 - Stop appending cpu arch to the end of %BUILD_TARGET% on Windows in UpdateUtils.jsm 2020-02-17 12:19:22 -05:00
wolfbeast ac68f8cf6c Issue #1445 - Use the detailed string also in the list entries. 2020-02-17 16:19:57 +01:00
wolfbeast 4889e6dbbd Issue #1446 - Only match extension add-on types for target applications.
This resolves #1446
2020-02-17 16:19:05 +01:00
Moonchild a4ab3fc59d Merge pull request #1447 from win7-7/optimization-4-pr
Speed up nsTableColFrame::GetColIndex
2020-02-17 12:40:36 +01:00
wolfbeast e8417acbff Issue #1446 - Only allow extension add-on types for Firefox compat mode. 2020-02-17 12:33:34 +01:00
win7-7 d4098037a4 Issue #1355 - Make nsTableCellFrame::GetColIndex/GetRowIndex faster
We can devirtualize it, remove some branches.
2020-02-16 16:06:53 +02:00
wolfbeast f107de8a90 Issue #1445 - Clarify the status of extensions in the Add-On manager
This resolves #1445.
2020-02-16 13:10:55 +01:00
wolfbeast d3067ffdda [CSS] Only emit non-GC chrome wrapped XUL box warnings in debug builds. 2020-02-14 19:09:13 +01:00
wolfbeast 4ce361d9ba Issue #1441 - Guard appomni/greomni with UXP_CUSTOM_OMNI env var.
This adds an addition to the environment set up for child processes
(plugin container) so that it may still be able to pass the omni
parameters there as-needed.
2020-02-14 17:06:30 +01:00
wolfbeast 786417cf0f Revert "Issue #1441 - Guard appomni/greomni with UXP_CUSTOM_OMNI env var."
This reverts commit 2bdbca39b2.
2020-02-14 16:31:54 +01:00
Simon Giesecke 16fce4341d [IndexedDB] Ensure that strong references to newly created cursors are
kept until the DOM Binding is created.

This fixes random crashes on websites that use IndexedDB cursors.
See also BZ bug 1599420
2020-02-14 14:39:40 +01:00
Henri Sivonen 3bf1b83591 [Parser] Move setting context to null to the correct location. 2020-02-14 13:24:59 +01:00
wolfbeast 2bdbca39b2 Issue #1441 - Guard appomni/greomni with UXP_CUSTOM_OMNI env var. 2020-02-14 12:35:58 +01:00
sotaro 8ec7618633 [Layers] Clear WrappingTextureSourceYCbCrBasic::mTexture correctly 2020-02-14 10:46:53 +01:00
wolfbeast 0a5784d3ce [Network] Bump http channel default Firefox CompatMode init value. 2020-02-14 10:32:41 +01:00
wolfbeast 7dc9aa0585 Fix a whitespace issue in nsComputedDOMStyle.cpp 2020-02-12 00:01:55 +01:00
wolfbeast a399acd57c [CSS] Add stub for font-variation-settings
This stub is added because websites insist on considering this
very hardware-dependent and O.S.-variable low-level font-control
as a "critical feature" which it isn't as there is 0 guarantee
that font variation settings are supported or honored by any
operating system used by the client.

On top this is a WD status feature that sites shouldn't be using, and
the feature itself is strongly discouraged for use in favor of standard
CSS font manipulation keywords like `font-weight`.
2020-02-11 23:59:53 +01:00
wolfbeast 6184ed7555 [CSP] Allow not having a Port for RessourceURI if the Scheme has no
Default Port
2020-02-11 12:30:45 +01:00
Matt A. Tobin 31d8779a22 Issue #65 - Correct nsHelperAppDlg.js for bad preprocessing conversion 2020-02-09 19:54:01 -05:00
Matt A. Tobin 5007e7c498 Issue #80 - Stop building non-generated dom/binding files as UNIFIED_SOURCES
Also fix deprot
2020-02-08 23:23:20 -05:00
Matt A. Tobin 07fe89e26f Directly assign PrimitiveConversions.h to the generated binding of KeyframeAnimationOptions.
This is a hack to deal UnifiedBindings trying to deal with an incomplete codegen implementation so it was worked around with a hack back in Firefox 30-something. If we have anymore of this non-sense crop up as stuff is added or removed from DOM then extend this conditional.

Least until something better comes along.
2020-02-08 20:33:04 -05:00
Moonchild 4234b3a36b Merge pull request #1393 from win7-7/optimization-3-pr
Do less work for columns not in the desired set in PaintRowGroupBackgroundByColIdx
2020-02-08 15:17:21 +01:00
Moonchild 6c82d043a1 Merge pull request #1394 from MoonchildProductions/appconst-work
The rest of removing AppConstants for Platform
2020-02-07 10:57:04 +01:00
Matt A. Tobin fa52fa60b7 Issue #65 - Don't split in the middle of assignment statements in createProfileWizard.js 2020-02-07 04:55:10 -05:00
Matt A. Tobin b4ac6a7dcb Issue #65 - Correct fallthough case in profileSelection.js 2020-02-07 04:51:00 -05:00
Moonchild a6ef90b183 Merge pull request #1388 from win7-7/devirtualize-pr
Merging this in even without a test performed since the code change looks sane. real-world testing will have to be performed.
2020-02-07 09:52:57 +01:00
Matt A. Tobin 99aa809cb8 Issue #1395 - Part 2: Remove the /rest/ of FlyWeb 2020-02-06 19:49:46 -05:00
Matt A. Tobin 6da9e3c6b9 Issue #1395 - Remove FlyWeb Service 2020-02-06 19:47:29 -05:00
Matt A. Tobin 5483f807c2 Issue #1390 - Get rid of the Presentation API 2020-02-06 16:03:39 -05:00
Matt A. Tobin e80e4595b9 Issue #1390 - Remove secondscreen modules from toolkit 2020-02-06 14:49:41 -05:00
wolfbeast 551c418932 [AM] Remove shared theme leftovers for webextensions 2020-02-06 19:24:50 +01:00
Matt A. Tobin 832d84d2c0 Issue #1392 - Change --enable-eme to MOZ_ARG_ENABLE_BOOL and remove MOZ_EME_MODULES 2020-02-06 13:06:35 -05:00
Matt A. Tobin cf4ad4e969 Issue #65 - Remove AppConstants from toolkit/components/passwordmgr 2020-02-06 10:39:22 -05:00
win7-7 6376eceaeb Merge branch 'master' into optimization-3-pr 2020-02-06 17:17:28 +02:00
win7-7 074f23467b Issue #1355 - Do less work for columns not in the desired set in PaintRowGroupBackgroundByColIdx
Do less work in PaintRowGroupBackgroundByColIdx for cells that are not in our desired set of columns.

crash fix:

Guard against empty column groups when building a display list for a table.
2020-02-06 17:13:55 +02:00
Matt A. Tobin 741abd440e Issue #65 - Remove AppConstants from toolkit/components/alerts 2020-02-06 09:47:45 -05:00
Matt A. Tobin 0749a35be9 Issue #65 - Remove AppConstants from toolkit/components/places 2020-02-06 09:43:27 -05:00
Matt A. Tobin cd87677798 Issue #65 - Remove AppConstants from toolkit/components/apppicker 2020-02-06 09:38:29 -05:00
Matt A. Tobin 0ab5c6474c Issue #65 - Remove AppConstants from toolkit/components/thumbnails 2020-02-06 09:34:25 -05:00
Matt A. Tobin 7a0b23aab8 Issue #65 - Remove AppConstants from toolkit/components/printing 2020-02-06 09:31:03 -05:00
Matt A. Tobin c09eca89e4 Issue #65 - Remove AppConstants from toolkit/components/satchel 2020-02-06 09:11:39 -05:00
Moonchild 04c770c8c8 Update UXP Coding Style.md
Be more explicit about paranthesis spacing
2020-02-06 14:50:58 +01:00
Moonchild bf914e9975 Update UXP Coding Style.md
Minor typo
2020-02-06 14:47:30 +01:00
Matt A. Tobin 180543f6c3 Issue #65 - Remove AppConstants from toolkit/components/jsdownloads 2020-02-06 08:31:14 -05:00
Matt A. Tobin 2e6782afb5 Issue #65 - Remove AppConstants from toolkit/mozapps/downloads 2020-02-06 06:32:11 -05:00
Matt A. Tobin 758618b605 Issue #65 - Remove AppConstants from toolkit/mozapps/extensions 2020-02-06 06:07:37 -05:00
Moonchild 58cfb9acc2 Merge pull request #1389 from MoonchildProductions/EME_conditional
Make building of EME conditional
2020-02-06 11:53:51 +01:00
wolfbeast 4c9689f680 Issue #26 - Part 2c: Remove dependence on gmp/widevine-adapter/* 2020-02-05 22:32:52 +01:00
Matt A. Tobin 43f91872bd Issue #65 - Remove AppConstants from toolkit/mozapps/update 2020-02-05 14:31:58 -05:00
Matt A. Tobin 840ecb5262 Issue #65 - Remove AppConstants from toolkit/profile 2020-02-05 13:52:28 -05:00
win7-7 3a7d5d01cc fix whitespace
fix whitespace.
2020-02-05 16:57:42 +02:00
wolfbeast d44c61bf60 Issue #26 - Part 2b: Stub out GMPDecryptorProxy functions.
If EME isn't built, these functions would have no use and the callback
structures are unavailable. Stubbing these out will still allow the
callers to work unchanged, but in effect simply always return without
dispatching a promised task.
This fixes the dependency issue from part 2a.
2020-02-04 11:48:13 +01:00
wolfbeast 99118e38e1 Issue #26 Part 2a: make more EME code conditional.
- Exclude missed MediaKey functions and CDMProxy code.
- Exclude EME APIs frm being built (webidl change)
- Fix tests in --disable-eme state
2020-02-03 23:42:52 +01:00
wolfbeast a595451104 [Installer] Updated the 7-zip stub binary to make sure it doesn't hang
on older versions of Windows but instead provides a usable error message
2020-02-03 23:23:41 +01:00
win7-7 597a6996f1 Issue #1386 - Devirtualize GetRowSpan/GetColSpan
It's at ~1.5% on the perf log for the Netflix use case, which seems a bit too much.
2020-02-03 20:47:41 +02:00
Moonchild c4e1022f57 Merge pull request #1385 from win7-7/standard-pr
Match standard for colSpan/rowSpan
2020-02-03 18:18:40 +01:00
win7-7 52940bc44c Issue #1384 - Match standard for colSpan/rowSpan
HTML standardizes proper behavior of colSpan and rowSpan:

The main thing is that getting the .rowSpan and .colSpan IDL properties will now return the actual clamped value that we use.
2020-02-03 16:59:23 +02:00
wolfbeast 9c6a8450b3 Issue #1382 - Remove invalid assertion.
There is flexibility in exactly the value the initialized length must
hold, i.e. if an array is completely empty, it is valid for the
initialized length to be any value between zero and the length of the
array, as long as the in-memory values below the initialized length have
been initialized with a hole value.
In the case of 0, the array is packed and the move operation would be a
nop, so simply convert the assert to a condition to save some cycles.
2020-02-03 04:52:44 +01:00
Moonchild bbbfd00f95 Merge pull request #1381 from win7-7/optimization2-pr
Add dirty rect intersection checks so that we don't build unnecessary table part display items
2020-02-02 19:17:12 +01:00
win7-7 e6c346c36f Issue #1355 - Hit testing in large tables has become extremely slow
Add dirty rect intersection checks so that we don't build unnecessary table part display items.
2020-02-02 15:02:47 +02:00
wolfbeast d216db11e7 Revert "Issue #1355 - Hit testing in large tables has become extremely slow"
This reverts commit f7b2f0a665.
2020-02-02 13:37:13 +01:00
Moonchild 0db3f512ea Merge pull request #1380 from win7-7/optimization-2-pr
Add dirty rect intersection checks so that we don't build unnecessary table part display items
2020-02-02 13:21:22 +01:00
New Tobin Paradigm 54e3d74002 Fix preprocessor directive in UserAgentUpdates.jsm 2020-02-02 06:52:04 -05:00
win7-7 f7b2f0a665 Issue #1355 - Hit testing in large tables has become extremely slow
Add dirty rect intersection checks so that we don't build unnecessary table part display items.
2020-02-02 13:50:51 +02:00
wolfbeast dd68cb9b3d Issue #1378 - Follow-up: make sure background items remain table-aligned. 2020-02-02 11:31:07 +01:00
Matt A. Tobin 6a3907dae4 Issue #65 - Remove AppConstants from toolkit/modules
Except for secondscreen
2020-02-02 04:25:47 -05:00
Matt A. Tobin 7d21d02d53 Issue #65 - Remove AppConstants from toolkit/content 2020-02-01 23:45:36 -05:00
Matt A. Tobin a18c27ddde Issue #65 - Remove AppConstants from netwerk/ 2020-02-01 21:59:08 -05:00
Matt A. Tobin f9ddbe3640 Issue #65 - Remove AppConstants from mailnews/ 2020-02-01 21:54:04 -05:00
Matt A. Tobin 406fc463e0 Issue #65 - Remove AppConstants from dom/ 2020-02-01 21:45:08 -05:00
wolfbeast 28208f1d3e Issue #1378 - Align the drawing of table cell backgrounds with the spec. 2020-02-02 02:16:41 +01:00
Matt A. Tobin 6bb671bcdd Issue #1377 - Fix porting typo in mailnews/base/search/content/searchWidgets.xml
MailNews Core being historically comm tended to avoid defining shorthand for Components.interfaces
2020-02-01 20:06:57 -05:00
wolfbeast 33ad27614a Issue #447 - Update HSTS preload list & reduce debug spew
Commented out spewing dump() statements in loops. With the ever growing
HSTS list it takes too much time and is pointless to display.
2020-02-01 01:37:52 +00:00
wolfbeast 229f841295 Issue #1342 - Remove support for system libvpx 2020-01-31 16:54:07 +01:00
wolfbeast d41ba28f52 Issue #1342 - Remove support for system sqlite 2020-01-31 15:40:09 +01:00
wolfbeast 8f89965f50 Issue #1342 - Update old.configure for removed build options 2020-01-31 15:12:09 +01:00
wolfbeast e0103f3d5b Issue #1342 - Remove support for system linbpng 2020-01-31 15:10:26 +01:00
Moonchild 64c8c65cf4 Merge pull request #1376 from win7-7/optimization-1-pr
Speed up the traversal of a table row frame's child cells
2020-01-30 17:54:48 +00:00
wolfbeast 499b287394 Issue #1342 - Remove support for system NSPR/NSS 2020-01-30 18:15:38 +01:00
wolfbeast 00a5321c95 Issue #1342 - Remove support for system ICU 2020-01-29 15:13:55 +01:00
win7-7 fd26b84536 Issue #1355 - Speed up the traversal of a table row frame's child cells
Speed up getting the first cellframe in a row and the next cellframe after the given one
2020-01-29 11:14:34 +02:00
wolfbeast e57998f68b [WebRequest] Remove AddonManagerPermissions leftovers
This was added as part of the WebExtension sec issue CVE-2017-5389.
Since we no longer have this interface, it needed to be removed to
prevent errors in the WebRequest channel callback.
2020-01-29 09:08:00 +01:00
Moonchild ed88b99849 Merge pull request #1357 from athenian200/form-disabled-issue
Forms: Click() isn't executing properly when elements are defined disabled
2020-01-28 23:03:48 +00:00
athenian200 7a697172f3 Issue #1356 - Add tests.
Forgot to include these before.
2020-01-28 00:03:00 -06:00
athenian200 3c4f414db7 Merge branch 'master' of https://github.com/MoonchildProductions/UXP into form-disabled-issue 2020-01-27 22:59:08 -06:00
wolfbeast c4b0715baa Issue #1360 - Enable acceleration by default on all known-good platforms. 2020-01-27 22:06:03 +01:00
wolfbeast 54fbb5c75c Update platform version.
Intended to be bumped to 4.6.x once CE/sDOM is landed completely.
2020-01-27 11:54:06 +01:00
wolfbeast 71416f9b79 Merge branch '1360' 2020-01-27 11:49:31 +01:00
Matt A. Tobin d56573bb9c Force CLOBBER 2020-01-26 18:30:55 -05:00
New Tobin Paradigm 22ed46f7cc Merge pull request #1374 from g4jc/custom_elementsv1
Custom Elements v1
2020-01-26 17:13:16 -05:00
Gaming4JC 3c70b297c7 Bug 1430951 - Avoid element name atomizing to improve performance of LookupCustomElementDefinition
Since we are dealing with the element (nodeInfo->LocalName() and NameAtom() are the same value), we could use nodeInfo->NameAtom() instead.

Tag UXP Issue #1344
2020-01-26 15:50:52 -05:00
Gaming4JC 0cea94242a Bug 1430034 - Fix attributeChangedCallback isn't fired with correct newValue when the attribute value is an empty string;
Tag UXP Issue #1344
2020-01-26 15:50:52 -05:00
Gaming4JC d84323905b Bug 1421544 - Lazy push/pop CustomElementReactionsStack entry;
Tag UXP Issue #1344
2020-01-26 15:50:51 -05:00
Gaming4JC e8f95f974f Bug 1413815 - Convert 'observedAttributes' to a sequence<DOMString>
Tag UXP Issue #1344
2020-01-26 15:50:51 -05:00
Gaming4JC 53319e5df6 Bug 1407669 - Fix custom element creation hides uncatchable exceptions from the constructor.
Tag UXP Issue #1344
2020-01-26 15:50:51 -05:00
Gaming4JC a8bf089e8a Bug 1419305 - Part 2: Keep processing remaining elements in ElementQueue even if some of elements are already unlinked
Tag UXP Issue #1344
2020-01-26 15:50:50 -05:00
Gaming4JC 0405d843be Bug 1419305 - Part 1: Use MicroTask on CustomElements correctly
Tag UXP Issue #1344
2020-01-26 15:50:50 -05:00
Gaming4JC 2077cdb41e Bug 1406922 - Make CycleCollectedJSContext to handle microtasks and make MutationObserver to use them
Tag UXP Issue #1344
2020-01-26 15:50:50 -05:00
Gaming4JC 43a8113072 Bug 1405821 - Move microtask handling to CycleCollectedJSContext
Tag UXP Issue #1344
2020-01-26 15:50:49 -05:00
Gaming4JC 14d115cfe3 Bug 1419643 - Don't need to lookup custom element definition for a non-custom element
Tag UXP Issue #1344
2020-01-26 15:50:49 -05:00
Gaming4JC 8db81508a1 Bug 1415761 - Catch the exception and rethrow it after invoking custom elements reactions;
The spec was unclear on how CEReactions interact with thrown exceptions; see https://github.com/whatwg/html/issues/3217. The spec is now being clarified in https://github.com/whatwg/html/pull/3235.

Tag UXP Issue #1344
2020-01-26 15:50:48 -05:00
Gaming4JC 4083a9abf7 Bug 1396620 - Part 2: Fix compartment mismatch crash when doing old prototype swizzling for custom element
Tag UXP Issue #1344
2020-01-26 15:50:48 -05:00
Gaming4JC f576d8f0fe Bug 1396620 - Part 1: Remove created callback for custom elements
Tag UXP Issue #1344
2020-01-26 15:50:48 -05:00
Gaming4JC 37d09da24e Bug 1400762 - Make dom.webcomponents.enabled pref doesn't control CustomElements feature
Tag UXP Issue #1344
2020-01-26 15:50:47 -05:00
Gaming4JC 7e9efb0f27 Bug 1405335 - Remove custom element attached and detached callbacks validation checks
Tag UXP Issue #1344
2020-01-26 15:50:47 -05:00
Gaming4JC 93313b0ce3 Bug 1406325 - Part 5: Implement try to upgrade.
Tag UXP Issue #1344
2020-01-26 15:50:46 -05:00
Gaming4JC fb657f7a1e Bug 1406325 - Part 4: Use mType for LookupCustomElementDefinition and also removing parts of v0.
Tag UXP Issue #1344
2020-01-26 15:50:46 -05:00
Gaming4JC 72d4c0b8df Bug 1406325 - Part 3: Refactor custom elements clone a node.
Tag UXP Issue #1344
2020-01-26 15:50:46 -05:00
Gaming4JC c199dd22e6 Bug 1406325 - Part 2: Set CustomElementData when cloning a node.
Tag UXP Issue #1344
2020-01-26 15:50:45 -05:00
Gaming4JC e62385604d Bug 1406325 - Part 1: Make sure custom element state is custom before sending callback.
Tag UXP Issue #1344
2020-01-26 15:50:45 -05:00
Gaming4JC a0014ac6e9 Bug 1378079 - Part 3: Complete the steps related to custom elements in "create an element for a token".
With fixup for missing header due to unified builds.

Tag UXP Issue #1344
2020-01-26 15:50:44 -05:00
Gaming4JC dd6749f7dd Regenerate Parser for 483155
Tag UXP Issue #1344
2020-01-26 15:50:44 -05:00
Gaming4JC e2fc7a9d49 Fix Build: We don't have SVG or MathML prefs yet
See Bug 1173199 / 1216893

Tag UXP Issue #1344
2020-01-26 15:50:44 -05:00
Gaming4JC 950275abe6 Fix aAttributes
Fallout from 483155

Tag UXP Issue #1344
2020-01-26 15:50:43 -05:00
Gaming4JC ea35625369 Fix ISINDEX
Since we want to keep this element, it has to be adapted to the parser changes in 483155

Tag UXP Issue #1344
2020-01-26 15:50:43 -05:00
Gaming4JC 0f9746b6e5 Add missing space to ElementName.java self-regeneration code.
Tag UXP Issue #1344
2020-01-26 15:50:43 -05:00
Gaming4JC 97ed13a9f9 Add missing elements from Bug 483155
Tag UXP Issue #1344
2020-01-26 15:50:42 -05:00
Gaming4JC d163c367d9 Bug 483155 - Put content creator function pointers onto nsHtml5ElementName.
This is all the manual work for Bug 483155, minus the added functionality to disable SVG and MathML which can be done at any time and are out of scope.

Tag UXP Issue #1344
2020-01-26 15:50:42 -05:00
Gaming4JC 9bf83c6a78 Bug 483155 - Put Gecko content creator function pointers on ElementName.
Tag UXP Issue #1344
2020-01-26 15:50:41 -05:00
Gaming4JC bec4d0ecdc Bug 1355779 - Skip interned ElementName lookup for Custom Elements (ones with hyphen).
Regen.

Tag UXP Issue #1344
2020-01-26 15:50:41 -05:00
Gaming4JC 1ef7d17528 Bug 1355779 - Skip interned nsHtml5ElementName lookup for Custom Elements (ones with hyphen).
Tag UXP Issue #1344
2020-01-26 15:50:41 -05:00
Gaming4JC 0b6548613a Bug 1378079 - Part 2: Introduce throw-on-dynamic-markup-insertion counter.
Per spec, document objects have a throw-on-dynamic-markup-insertion counter, which is used in conjunction with the create an element for the token algorithm to prevent custom element constructors from being able to use document.open(), document.close(), and document.write() when they are invoked by the parser.

Tag UXP Issue #1344
2020-01-26 15:50:40 -05:00
Gaming4JC 004b231d03 Bug 1378079 - Part 1: Gecko changes for adding attribute 'is' to parser.
Tag UXP Issue #1344
2020-01-26 15:50:40 -05:00
Gaming4JC 4c193edcaf Bug 1378079 - Add attribute 'is' to HTML parser.
Tag UXP Issue #1344
2020-01-26 15:50:39 -05:00
Gaming4JC b7f890e02e Bug 1410790 - Add more assertion in CustomElementData::SetCustomElementDefinition and GetCustomElementDefinition;
This is a follow-up patch for bug 1392970. Since we only set CustomElementDefinition on a custom element which is custom, we could add more assertion to ensure that.

Tag UXP Issue #1344
2020-01-26 15:50:39 -05:00
Gaming4JC fce396323d Bug 1366241 - Change memory layout of element name and attribute name hashes in HTML parser from sorted to level order BST in order to take advantage of cache during lookup.
HTML Regen.

Tag UXP Issue #1344
2020-01-26 15:50:38 -05:00
Gaming4JC a8511d983c Bug 1366241 - Change memory layout of element name and attribute name hashes from sorted to level order BST in order to take advantage of cache during lookup.
Java Regen.

Tag UXP Issue #1344
2020-01-26 15:50:38 -05:00
Gaming4JC e17a17766e Bug 1366241 - Change memory layout of element name and attribute name hashes from sorted to level order BST in order to take advantage of cache during lookup.
Tag UXP Issue #1344
2020-01-26 15:50:38 -05:00
Gaming4JC 76a4af3406 Bug 1358037 - Inline the methods of nsHtml5ElementName and nsHtml5AttributeName.
HTML Regen.

Tag UXP Issue #1344
2020-01-26 15:50:37 -05:00
Gaming4JC 5d4200f56d Bug 1358037 - Inline the methods of nsHtml5ElementName and nsHtml5AttributeName.
Manual changes

Tag UXP Issue #1344
2020-01-26 15:50:37 -05:00
Gaming4JC 41e477e2ce Bug 1358037 - Inline the methods of nsHtml5ElementName and nsHtml5AttributeName.
Tag UXP Issue #1344
2020-01-26 15:50:36 -05:00
Gaming4JC e5557d43d6 Bug 1355479 - Flatten attribute storage in the HTML parser to AutoTArray to avoid malloc.
HTML Regen.

Tag UXP Issue #1344
2020-01-26 15:50:36 -05:00
Gaming4JC 650f6b5eb3 Bug 1355479 - Flatten attribute storage in the HTML parser to AutoTArray to avoid malloc.
- Removes nsHtml5ReleasableAttributeName
- Adds nsHtml5AttributeEntry.h
- Makes nsHtml5HtmlAttributes no longer gentered.

Tag UXP Issue #1344
2020-01-26 15:50:36 -05:00
Gaming4JC 90d19b0a31 Bug 1355479 - Remove isindex on the Java side and allow the C++ side to reduce malloc in attribute handling.
Tag UXP Issue #1344
2020-01-26 15:50:35 -05:00
Gaming4JC f7bb7e81e3 Bug 1355769 - Avoid malloc for nsHtml5ElementName when processing a non-interned element name.
Fix build - Remove no longer used ReleaseableElement

Tag UXP Issue #1344
2020-01-26 15:50:35 -05:00
Gaming4JC 016a21c414 Bug 1355769 - Avoid malloc for nsHtml5ElementName when processing a non-interned element name.
HTML Regen.

Tag UXP Issue #1344
2020-01-26 15:50:34 -05:00
Gaming4JC e387308d9b Bug 1355769 - Avoid malloc for nsHtml5ElementName when processing a non-interned element name.
Tag UXP Issue #1344
2020-01-26 15:50:34 -05:00
Gaming4JC 738190dfde Bug 1355493 - Tweak bufToHash() and reduce the number of pre-interned elements.
HTML Regen.

Tag UXP Issue #1344
2020-01-26 15:50:34 -05:00
Gaming4JC 4503b51a4a Bug 1355493 - Tweak bufToHash() and reduce the number of pre-interned elements.
Java Regen.

Tag UXP Issue #1344
2020-01-26 15:50:33 -05:00
Gaming4JC 56925e1f4a Bug 1355493 - Tweak bufToHash() and reduce the number of pre-interned elements.
Tag UXP Issue #1344
2020-01-26 15:50:33 -05:00
Gaming4JC 72a6fd4d2a Bug 1352082 - Avoid shifting a signed integer left in C++.
Tag UXP Issue #1344
2020-01-26 15:50:32 -05:00
Gaming4JC 5b862aa38c Bug 1352082 - Avoid shifting a signed integer left in C++.
Tag UXP Issue #1344
2020-01-26 15:50:32 -05:00
Gaming4JC 1aa6cdcc1d Bug 1352290 - Add assertion to CustomElementReactionsStack::Enqueue to ensure upgrade reactions aren't scheduled to BackupQueue;
Tag UXP Issue #1344
2020-01-26 15:50:32 -05:00
Gaming4JC 2cbd6d3699 Bug 1407937 - Move mDefinition from CustomElementReacion to CustomElementUpgradeReaction;
Tag UXP Issue #1344
2020-01-26 15:50:31 -05:00
Gaming4JC 4dda3f6039 Bug 1406297 - Fix Document.createElement must report an exception.
Tag UXP Issue #1344
2020-01-26 15:50:31 -05:00
Gaming4JC 6ec385fbdb Bug 1319342 - Clone a node should enqueue an upgrade reaction.
Tag UXP Issue #1344
2020-01-26 15:50:30 -05:00
Gaming4JC 8e6ce5fae7 Bug 1121994 - Implement adopted callback for custom elements.
Tag UXP Issue #1344
2020-01-26 15:50:30 -05:00
Gaming4JC 6bbb9f062b Bug 1334044: Replace detached callback (v0) with disconnected callback (v1).
Tag UXP Issue #1344
2020-01-26 15:50:29 -05:00
Gaming4JC 01dfbc928f Bug 1334043 - Part 3: Update tests for connected callback.
Tag UXP Issue #1344
2020-01-26 15:50:29 -05:00
Gaming4JC 3d4c410091 Bug 1334043 - Part 2: Make nsContentUtils::EnqueueLifecycleCallback static.
We make nsContentUtils::EnqueueLifecycleCallback static so that it can be called without a window object. To achive this, we also make CustomElementReaction not taking a CustomElementRegistry in the constructor, as it can call Upgrade statically.

Tag UXP Issue #1344
2020-01-26 15:50:29 -05:00
Gaming4JC 186782301c Bug 1334043 - Part 1: Replace attached callback (v0) with connected callback (v1).
Tag UXP Issue #1344
2020-01-26 15:50:28 -05:00
Gaming4JC 42331663e6 Bug 1392970 - Part 2: Get CustomElementDefinition from CustomElementData when possible.
Tag UXP Issue #1344
2020-01-26 15:50:28 -05:00
Gaming4JC 8573c572fb Bug 1392970 - Part 1: Make CustomElementDefinition ref-counted and put it in CustomElementData.
Tag UXP Issue #1344
2020-01-26 15:50:27 -05:00
Gaming4JC f50503df9c Bug 1301024 - Part 2: Implement create an element steps.
Tag UXP Issue #1344
2020-01-26 15:50:27 -05:00
Gaming4JC 5840b63cca Bug 1301024 - Part 1: Set CreateElement/CreateElementNS is attribute.
Tag UXP Issue #1344
2020-01-26 15:50:27 -05:00
Gaming4JC 45a4aaf7e0 Bug 1398401 - Add preference check for custom element setup.
Tag UXP Issue #1344
2020-01-26 15:50:26 -05:00
Gaming4JC 49f597e7fb Bug 1332233 - prevent resource leak in CustomElementRegistry::Define.
Tag UXP Issue #1344
2020-01-26 15:50:26 -05:00
Gaming4JC bf004bb63b Bug 1334051 - Part 2: Invoke attributeChangedCallback only if attribute name is in the observed attribute list.
We call attributeChangedCallback in two cases:

1. When any of the attributes in the observed attribute list has changed, appended, removed, or replaced.

2. When upgrading an element, for each attribute in element's attribute list that is in the observed attribute list.

Note: w/ Fixup for not implementing an API Enhancement Bug 1363481.

Tag UXP Issue #1344
2020-01-26 15:50:25 -05:00
Gaming4JC 08fc057471 Bug 1334051 - Part 1: Include namespace in attributeChangedCallback.
Per spec [1], we should include namesapce in attributeChangedCallback argurment list.
[1] https://html.spec.whatwg.org/multipage/custom-elements.html#concept-upgrade-an-element, step 3

Tag UXP Issue #1344
2020-01-26 15:50:25 -05:00
Gaming4JC 704318ea0a Bug 1299363 - Part 5-2: Implement new upgrade steps.
Tag UXP Issue #1344
2020-01-26 15:50:25 -05:00
Gaming4JC bbb717ec12 Bug 1299363 - Part 5-1: Make the constructor created by document.registerElement() also works with construction stack.
So that the old upgrade can also work with new upgrade steps which will be implemented in part 5-2.

Tag UXP Issue #1344
2020-01-26 15:50:24 -05:00
Gaming4JC 515c46e695 Bug 1353647 - Fix the custom elements v0 upgrade inconsistency;
There are two places doing prototype setup in old upgrade,
- If definition comes after JS reflector creation, CustomElementRegistry::Upgrade will do prototype swizzling.
- If definition comes before JS reflector creation, Element::WrapObject will set up the prototype.

The later one does SubsumesConsideringDomain, but the former doesn't not.

This patch is to fix the inconsistency, i.e. the former case should also do SubsumesConsideringDomain.

Tag UXP Issue #1344
2020-01-26 15:50:24 -05:00
Gaming4JC d7e5ad445c Bug 1299363 - Part 4: Hold a pointer of ElementQueue in ReactionsStack instead.
1. It is possible that invoking a reaction triggers pushing a new ElementQueue into ReactionStack (e.g., calling define() in constructor which probably enqueue another upgrade reaction), and the reference of ElementQueue passed to InvokeReactions becomes invalid due to the memmove in nsTArray implementation.

2. And we get another benefit from this is memmove becomes faster.

Tag UXP Issue #1344
2020-01-26 15:50:23 -05:00
Gaming4JC ca596f2823 Bug 1299363 - Part 3: Remove unused argument in UpgradeCandidates.
Tag UXP Issue #1344
2020-01-26 15:50:23 -05:00
Gaming4JC 3d44a0b7f0 Bug 1299363 - Part 2: Allow prototype swizzling in html constructor.
Tag UXP Issue #1344
2020-01-26 15:50:23 -05:00
Gaming4JC 32f1ff0f8d Bug 1299363 - Part 1: Implement construction stack.
Tag UXP Issue #1344
2020-01-26 15:50:22 -05:00
Gaming4JC 53c9b77ed4 Bug 1315885 - Part 4: Implement callback reaction for custom element reactions.
Note: Skipped SyncInvokeReactions since it is removed in CE v1, waste of time.

Tag UXP Issue #1344
2020-01-26 15:50:22 -05:00
Gaming4JC e6733c9278 Bug 1315885 - Part 3: Transfer the ownership of ReactionQueue's entry due to re-enter CustomElementReactionsStack::InvokeReactions.
Tag UXP Issue #1344
2020-01-26 15:50:21 -05:00
Gaming4JC 6ff1c0c52f Bug 1315885 - Part 2: Avoid rethrowing exception in CustomElementCallback::Call.
Tag UXP Issue #1344
2020-01-26 15:50:21 -05:00
Gaming4JC 19f08038f0 Bug 1315885 - Part 1: Add ShadowRoot CEReactions annotation.
Tag UXP Issue #1344
2020-01-26 15:50:20 -05:00
Gaming4JC 4c9eab4d26 Bug 1340027 - Part 5: Add XSLTProcessor CEReactions annotation.
Tag UXP Issue #1344
2020-01-26 15:50:20 -05:00
Gaming4JC 7a1cb50405 Bug 1340027 - Part 4: Add DOM parsing CEReactions annotation.
Tag UXP Issue #1344
2020-01-26 15:50:20 -05:00
Gaming4JC db86d423e5 Bug 1340027 - Part 3: Add CSSStyleDeclaration CEReactions annotation.
Tag UXP Issue #1344
2020-01-26 15:50:19 -05:00
Gaming4JC 3fd2f61949 Bug 1340027 - Part 2: Add HTML CEReactions annotation.
Tag UXP Issue #1344
2020-01-26 15:50:19 -05:00
Gaming4JC 1674f8f750 Bug 1340027 - Part 1: Add DOM CEReactions annotation.
Tag UXP Issue #1344
2020-01-26 15:50:18 -05:00
Gaming4JC cc533eaee5 Bug 1377993 - Make node slots less memory hungry in common cases.
Tag UXP Issue #1344
2020-01-26 15:50:18 -05:00
Gaming4JC 59c26110c1 Bug 1347634 - GetCustomElementData and SetCustomElementData don't need to be virtual;
Tag UXP Issue #1344
2020-01-26 15:50:17 -05:00
Gaming4JC a2c7b5f1d9 Bug 1325279 - Put the reaction queue in CustomElementData structure instead of using a map;
Bug 1347446 makes accessing ElementReactionQueue becomes a bit non-trival (have to get it via DocGroup). Since bug 1359346 already refactors the creation time of CustomElementData, ReactionQueue can also be put into CustomElementData, then we can just get ReactionQueue from Element.

Tag UXP Issue #1344
2020-01-26 15:50:17 -05:00
Gaming4JC 9d51b9d06a Creating customized built-in elements without relevant definitions registered first shouldn't throw NotFoundError;
per spec change: https://github.com/w3c/webcomponents/issues/608

Tag UXP Issue #1344
2020-01-26 15:50:17 -05:00
Gaming4JC e86aac28b8 Bug 1359346 - Implement custom element state;
https://dom.spec.whatwg.org/#concept-element-custom-element-state

Tag UXP Issue #1344
2020-01-26 15:50:16 -05:00
Gaming4JC 88925e150b Bug 1357002 - Part 2: Don't call SetupCustomElement() if the custom element feature is pref-ed off;
Tag UXP Issue #1344
2020-01-26 15:50:16 -05:00
Gaming4JC 9abc9b2b78 Bug 1357002 - Part 1: Cache dom.webcomponents.customelements.enabled preference;
Tag UXP Issue #1344
2020-01-26 15:50:15 -05:00
Gaming4JC 859fbc139a Bug 1341898 - Make nsDocument::IsWebComponentsEnabled use a cached bool pref;
Note: Minus IPC bit.

Tag UXP Issue #1344
2020-01-26 15:50:15 -05:00
Gaming4JC d8109fa9a0 Bug 1309147 - Part 5: Eliminate performance cliff when accessing CEReactions code.
Tag UXP Issue #1344
2020-01-26 15:50:15 -05:00
Gaming4JC e055747038 Bug 1309147 - Part 4: Add CEReactions for CustomElementRegistry.
Tag UXP Issue #1344
2020-01-26 15:50:14 -05:00
Gaming4JC df23f78ad1 Bug 1309147 - Part 3: Implement the support for CEReactions in Codegen.
Tag UXP Issue #1344
2020-01-26 15:50:14 -05:00
Gaming4JC 20799ce18c Bug 1309147 - Part 2: Add the name of 'this' value's JSObject* for codegen to generate CEReaction code.
Tag UXP Issue #1344
2020-01-26 15:50:13 -05:00
Gaming4JC 08d22f03ea Bug 1309147 - Part 1: Implement the support for CEReactions in WebIDL parser.
Tag UXP Issue #1344
2020-01-26 15:50:13 -05:00
Gaming4JC ba8fb9dc58 Bug 1350960 - Release CustomElementReactionsStack in TabGroup thread when DocGroup is going away.
Note: In UXP we use non-Quantum thread checking implementation here.

Tag UXP Issue #1344
2020-01-26 15:50:12 -05:00
Gaming4JC 16cd53bd8d Bug 1351979 - Change CustomElementRegistry::Define code to properly propagate out JS exceptions;
Tag UXP Issue #1344
2020-01-26 15:50:12 -05:00
Gaming4JC 25a33c7123 Bug 1347446 - Move custom element reactions stack to DocGroup.
Tag UXP Issue #1344
2020-01-26 15:50:12 -05:00
Gaming4JC 5cf46e2f87 Bug 1341693 - Don't need to check GetDocShell() when creating CustomElementRegistry;
Tag UXP Issue #1344
2020-01-26 15:50:11 -05:00
Gaming4JC 3a97503b36 Bug 1309184 - Implement upgrade reaction for custom element reactions.
Tag UXP Issue #1344
2020-01-26 15:50:11 -05:00
Gaming4JC bac01e30fd Bug 1274159 - Part 4: Add test cases for HTMLConstructor;
Tag UXP Issue #1344
2020-01-26 15:50:10 -05:00
Gaming4JC 5b814fffd6 Bug 1274159 - Part 3-2: Update web-platform-test expected result;
Tag UXP Issue #1344
2020-01-26 15:50:10 -05:00
Gaming4JC 6ea0acf750 Bug 1274159 - Part 3-1: Add HTMLConstructor to HTMLElement and its subclass;
Tag UXP Issue #1344
2020-01-26 15:50:10 -05:00
Gaming4JC 5222f6e9da Bug 1274159 - Part 2-2: Support HTMLConstructor WebIDL extended attribute for custom elements;
Tag UXP Issue #1344
2020-01-26 15:50:09 -05:00
Gaming4JC 244277a3fa Bug 1274159 - Part 2-1: Include the name of relevant interface in nsHTMLTagList.h;
Tag UXP Issue #1344
2020-01-26 15:50:09 -05:00
Gaming4JC 2d31ebf6b6 Bug 1274159 - Part 1: Support looking up definitions by using constructor as a key;
Tag UXP Issue #1344
2020-01-26 15:50:08 -05:00
Gaming4JC bc8543bf79 Bug 1271549 - Remove details and summary preference.
Tag UXP Issue #1344
2020-01-26 15:50:08 -05:00
Gaming4JC ce285b6f2d Bug 1276438 part 3. Align the .body setter with the spec a bit better.
There are two changes here:

1) We allow setting .body even if the root element is not an <html:html>. This is what the spec says to do, and what we used to do before the changes in bug
366200. No tests for this yet, pending https://github.com/whatwg/html/issues/3403 getting resolved.

2) We use GetBody(), not GetBodyElement(), to look for an existing thing to replace. This matters if there are <frameset>s involved.

Tag UXP Issue #1344
Tag UXP Issue #252
2020-01-26 15:50:07 -05:00
Gaming4JC 32f3f8826f Bug 1276438 part 2. Move the implementation of the .body setter from nsHTMLDocument to nsIDocument.
Tag UXP Issue #1344
Tag UXP Issue #252
2020-01-26 15:50:07 -05:00
Gaming4JC a2b56b295b Bug 1276438 part 1. Move the implementation of the .body getter from nsHTMLDocument to nsIDocument.
Tag UXP Issue #1344
Tag UXP Issue #252
2020-01-26 15:49:16 -05:00
wolfbeast 90773547e7 Issue #1360 - Part 2: Update tests for changed preferences. 2020-01-26 10:28:17 +01:00
wolfbeast 282b791acb Issue #1360 - Part 1: Simplify layers acceleration prefs.
This gets rid of platform-dependent hard-coded defaults, but keeps
build-time blocking if there is no GL provider (in which case layers
acceleration almost certainly won't work because it needs a GL
compositor and would likely crash without)

New prefs are
- layers.acceleration.enabled to enable HWA
- layers.acceleration.force to force it enabled (requires .enabled to be
  set as well)

This is the platform part of this issue. The rest will be front-end work
(Preference UI integration and pref migration)
2020-01-26 09:48:52 +01:00
Moonchild a1cce3b2b0 Merge pull request #1371 from athenian200/ftp-list
Potential hang on bad FTP sequence
2020-01-26 08:26:23 +00:00
athenian200 7d53919c26 Fix whitespace. 2020-01-26 01:51:37 -06:00
athenian200 8bb5db350d Issue #1349 - Stop 2xx FTP responses from causing browser to hang.
LIST and RETR still appear to work as intended on ftp:// URLs after my changes. I wasn't able to test STOR because the browser doesn't appear to support FTP uploads at this time (although our FTP implementation appears perfectly capable of doing an FTP upload.)

If I understood the issue correctly, though, what we're doing is ensuring that we receive a preliminary 100 response from the FTP server for a given action before jumping to the 200 code describing what we do if the action was completed. Even though it makes no logical sense for a server to say an action was completed before it was initiated, someone could write a really annoying FTP server that takes advantage of this fact to crash the browser if they wanted.
2020-01-26 01:40:55 -06:00
wolfbeast a64ac6d702 No issue - Always use jemalloc allocator for storage memory when
MOZ_MEMORY is defined (which is defined by enabling jemalloc in config)
2020-01-23 15:17:51 +01:00
Kai Engert 6d761aa68f Issue #1338 - Follow-up: Also cache the most recent PBKDF1 hash
This rewrites the caching mechanism to apply to both PBKDF1 and PBKDF2
2020-01-23 13:11:09 +01:00
wolfbeast 90c5288fef Issue #1342 - Remove support for system libevent 2020-01-23 13:08:02 +01:00
wolfbeast 3624078103 Issue #1366 - Fix build bustage from erroneously removing 2 function implementations. 2020-01-22 21:42:10 +01:00
wolfbeast 5a6059feef Issue #1354 - Fix another potential crashing scenario in WebGL.
(merge of gl-work branch)
2020-01-22 11:51:19 +01:00
Moonchild 8e33fa9c4b Merge pull request #1367 from g4jc/showmodaldialog
Completely remove showModalDialog
2020-01-22 10:35:12 +00:00
Gaming4JC a9290ef91e Issue #1366 - Completely remove showModalDialog 2020-01-21 21:36:54 -05:00
wolfbeast fabe21d593 Issue #1354 - Fix typo 2020-01-21 21:23:46 +01:00
wolfbeast c6dbf55449 Issue #1354 - Clear the current context when MakeCurrent() fails. 2020-01-20 22:42:14 +01:00
wolfbeast 722161775b Issue #1338 - Bump NSS version
Our NSS version is closer to the currently-released .1, so bump version
to that.
Note: we still have some additional patches to the in-tree version in
place so this isn't a 100% match to the RTM one.
2020-01-20 11:59:36 +01:00
wolfbeast 71d8ada4a9 Merge branch 'master' of https://github.com/MoonchildProductions/UXP 2020-01-19 14:40:01 +01:00
wolfbeast e0baeba546 Issue #1362 - Revert "Implement regular expression lookbehind"
This reverts commit fa473930f4.
2020-01-19 14:39:14 +01:00
wolfbeast b1abb9aebe Issue #1362 - Revert "Update js/src/builtin/TestingFunctions.cpp for
regex lookbehind changes"

This reverts commit e79607a7a6.
2020-01-19 14:36:29 +01:00
Matt A. Tobin 22198ec194 Issue #1358 - Default to SSL/TLS when using the Account Wizard 2020-01-18 14:09:43 -05:00
Matt A. Tobin c137a4045c Issue #1359 - Pointlessly rename greprefs.. again. 2020-01-18 13:17:41 -05:00
wolfbeast 63219a15b1 Minor update to the html5 parser component doc 2020-01-18 13:25:35 +01:00
wolfbeast b87a4551b5 No issue - Fix unsafe http methods on HTTP/2 with TLSv1.3 0RTT. 2020-01-18 13:17:09 +01:00
wolfbeast 82dffb32bd Add component documentation for the HTML5 parser. 2020-01-18 13:01:53 +01:00
wolfbeast a2073c54b4 Revert "No issue - Fix unsafe http methods on HTTP/2 with TLSv1.3 0RTT."
This reverts commit 67d336a6f2.
2020-01-18 02:08:53 +01:00
wolfbeast 67d336a6f2 No issue - Fix unsafe http methods on HTTP/2 with TLSv1.3 0RTT. 2020-01-17 17:11:06 +01:00
athenian200 1f8d508258 Issue #1356 - Restore older syntax.
Some newer Firefox syntax snuck into my last bug. Just to be on the safe side I'm restoring the older syntax here.
2020-01-16 14:15:23 -06:00
athenian200 42e4816771 Issue #1356 - Remove -moz-user-input disabled to improve event handling. 2020-01-16 14:07:04 -06:00
Matt A. Tobin e4c4c20e7e Update readme instructions for how to use the java html5 parser codegen makefile 2020-01-16 07:43:21 -05:00
Matt A. Tobin ed60101550 Merge branch 'html5-parser-work' 2020-01-16 07:32:48 -05:00
Matt A. Tobin 927c386dd8 Regenerate nsHtml5*.cpp files from java htmlparser sources 2020-01-16 07:28:40 -05:00
Matt A. Tobin 635baac21a Update the html5 parser java codegen makefile to clean up snapshot javasrc 2020-01-16 07:22:22 -05:00
Matt A. Tobin c050c611df Update gitignore to no longer track snapshot javasrc for the html5 parser 2020-01-16 07:19:29 -05:00
Matt A. Tobin 9dbbc6c08f Remove obsolete javasrc snapshot 2020-01-16 07:17:55 -05:00
Matt A. Tobin 72779c9dde Update java htmlparser copyright on code to be translated to cpp 2020-01-16 07:16:39 -05:00
Matt A. Tobin e93b373374 Fix an issue with the html5 tokenizer and tree builder (java htmlparser) 2020-01-15 22:07:59 -05:00
wolfbeast fa816e1ec6 No issue - Fix some line endings in WebGLShaderValidator.cpp 2020-01-16 01:41:21 +01:00
wolfbeast 7007ec9e42 Issue #1354 - Don't allow glsl[130,400] unless we have gpu_shader5
- Teach GLContext about gpu_shader5
- Downgrade shader language version if gpu_shader5 support isn't found.
2020-01-16 01:40:30 +01:00
wolfbeast 058105eec0 Issue #1354 - Cherry-pick ANGLE update for broken drivers that support
required indexing but not the extensions.
2020-01-16 01:31:47 +01:00
Matt A. Tobin 3da18fda02 Bug 1562033
Adjust tokenization of U+0000 (java htmlparser)
2020-01-15 18:10:14 -05:00
Matt A. Tobin ee1d953749 Bug 1347737 - Introduce a new non-heap-allocated type for holding nsStringBuffer* in the HTML parser. (java htmlparser) 2020-01-15 16:55:12 -05:00
Matt A. Tobin 984790c6fb Bug 1555523 (java htmlparser version) 2020-01-15 16:18:08 -05:00
Matt A. Tobin 6f27b4eb34 Bug 1322938 - Make the tree builder aware of <dialog>.
Tag #1343 | https://hg.mozilla.org/projects/htmlparser/rev/d9bdf700af247563fec9b07b52ede6bf61edd513
2020-01-15 15:30:54 -05:00
Matt A. Tobin 2ac58ecef8 Update the java codegen makefile for having the two libs in-tree and change a few target names so they aren't obnoxious 2020-01-15 14:59:35 -05:00
Matt A. Tobin 03fb2e2294 Add the java javaparser
https://github.com/javaparser/javaparser/
Invisible tag: javaparser-1.0.6
2020-01-15 14:58:11 -05:00
Matt A. Tobin 6168dbe21f Add java htmlparser sources that match the original 52-level state
https://hg.mozilla.org/projects/htmlparser/
Commit: abe62ab2a9b69ccb3b5d8a231ec1ae11154c571d
2020-01-15 14:56:04 -05:00
Matt A. Tobin 09314667a6 Update gitignore for import of java html5 codegen and parser sources 2020-01-15 14:45:20 -05:00
wolfbeast 82804d2002 Issue #1332 - Enable seeking to next frame by default.
The indicated BZ bug was resolved in Gecko 50, and could have already
been enabled before (since it returns a promise as-required).
With the rest of promise-based media implemented it makes no sense to
keep this disabled on production.
2020-01-14 15:51:26 +01:00
wolfbeast 8d65feff0a No issue - Remove some unused webextension sync preferences. 2020-01-14 15:48:23 +01:00
wolfbeast da7423057d Issue #1319 - Set some obvious prefs for production builds.
This sets some defaults for production builds that should be
self-explanatory.
2020-01-14 15:47:27 +01:00
wolfbeast cbbae72431 Issue #1353 - Disable remote jar: URIs by default.
Considering the one exception this was still enabled for on all versions
of Firefox since 45 until our fork point is no longer applicable.
This resolves #1353
2020-01-14 15:29:08 +01:00
wolfbeast 1392abe1de No issue - Remove unused network.http.bypass-cachelock-threshold pref. 2020-01-14 15:07:15 +01:00
wolfbeast abf6fd8f2a No issue - Don't define gamepad prefs when gamepad support isn't built.
This also sets sane defaults when present. See also #1319.
2020-01-14 14:45:33 +01:00
wolfbeast 0257b657d2 Issue #1319 - Enable promise debugging only in DEBUG builds. 2020-01-14 14:44:13 +01:00
wolfbeast 4a038e2b4b Issue #1319 - Disable MOZ_LOGGING in production builds.
This makes it only enabled in debug builds, instead, where logging
would be most useful.
2020-01-14 13:35:03 +01:00
wolfbeast 6d342dbab9 Issue #1319 - Remove stderr_to_file.
This local-debug function is only useful for Android to work around
issues with logspewing and should never be in production builds anyway.
2020-01-14 13:23:39 +01:00
wolfbeast 217dca872b Fix comments for NSS PBKDF setup (no code change) 2020-01-14 13:14:57 +01:00
Kai Engert 3733205f09 Issue #1338: Follow-up: Cache the most recent PBKDF2 password hash,
to speed up repeated SDR operations.

Landed on NSS-3.48 for Bug 1606992
2020-01-14 13:08:48 +01:00
wolfbeast aa2ac8dded Reinstate the java->c++ source, generator code + documentation.
We've kept the java source up-to-date until its removal, so there should
be very little additional java mangling needed to have it back up to
speed and usable again.

This reverts commit c6446f1126.
2020-01-13 09:32:00 +01:00
wolfbeast 60dc9eaa95 Simplify some alias sets in IonMonkey. 2020-01-11 13:09:17 +01:00
wolfbeast 06dbb7b7dd Prefer file extension as-provided over default extension for mimetype to
look up default applications on Windows
2020-01-11 12:53:56 +01:00
Daiki Ueno f64e760ab0 Issue #1338 - Followup: certdb: propagate trust information if trust
module is loaded afterwards,

Summary: When the builtin trust module is loaded after some temp certs
being created, these temp certs are usually not accompanied by trust
information. This causes a problem in UXP as it loads the module from a
separate thread while accessing the network cache which populates temp
certs.

This change makes it properly roll up the trust information, if a temp
cert doesn't have trust information.
2020-01-10 20:34:53 +01:00
wolfbeast 095a02f259 Update GTK clipboard handling
- Store the clipboard even if it was set in a GTK dialog.
- Fix a GtkTargetList leak.
- Notify GTK that the data is no longer available for
clipboard_get_cb(), so that GTK will no longer advertise nor attempt to
store the data.
2020-01-10 19:40:14 +01:00
wolfbeast 9365776219 Issue #1338 - Un-bust building of NSS after update to 3.48 on Linux. 2020-01-10 18:17:14 +01:00
wolfbeast 0186023f4a Handle missing base64 challenge in NegotiateAuth and NTLMAuth. 2020-01-09 22:35:03 +01:00
Yaron Tausky 51b1cd97aa Make copy of list before iterating over it. 2020-01-09 22:23:13 +01:00
wolfbeast 8198126c39 Be more consistent about decoding IP addresses in PSM. 2020-01-09 21:39:28 +01:00
wolfbeast d429ac8a60 Simplify value setting.
This gets rid of unused boolean return values on setters and a level of
indirection for calls to set values.
2020-01-09 18:26:06 +01:00
Moonchild 29bf28ca34 Merge pull request #1347 from g4jc/html5_dialog
Implement HMTL5 <dialog>
2020-01-09 13:07:56 +00:00
wolfbeast d79cc5fb49 Issue #1348 - Part 3: Set IS_PRIVATE input scope in private browsing.
Microsoft IME on Windows 10 20H1 (build 19025+) supports IME private
mode by input scope. Although previous Windows versions use an
undocumented API for Edge and IE only, the next Windows 10 release will
use a public API for it.
We pre-empt this potential privacy concern by setting the IS_PRIVATE
flag when in PB mode.
2020-01-09 13:22:29 +01:00
wolfbeast 8ae047bbbf Issue #1348 - Part 2: Teach IMEState about Private Browsing mode. 2020-01-09 13:19:56 +01:00
Makoto Kato 1672355a77 Issue #1348 - Part 1: Clean up input scope support for IMM32.
Use AutoTArray to set input scope.
2020-01-09 09:53:16 +01:00
Gaming4JC 52bda2a828 Bug 1379728 part 1. Remove the double-definition of the 'close' event from EventNameList.h.
Tag #1343
2020-01-07 18:33:24 -05:00
Gaming4JC 25e85f99ce Bug 1322938 - Make the HTML tree builder aware of <dialog>.
Original patch by :hsivonen
Tag #1343
2020-01-07 18:33:24 -05:00
Gaming4JC b91b0c37eb Bug 1322938 - Put <dialog> element behind preference.
Tag #1343
2020-01-07 18:33:23 -05:00
Gaming4JC a4011e7246 Bug 1322938 - Update <dialog> element Web Platform Tests expected results.
Tag #1343
2020-01-07 18:33:23 -05:00
Gaming4JC ef2cd8749f Bug 1322938 - Emit close event when HTMLDialogElement.prototype.close() is called.
Tag #1343
2020-01-07 18:33:23 -05:00
Gaming4JC 2e3b937f4e Bug 1322938 - Basic implementation of HTMLDialogElement.
Tag #1343
2020-01-07 18:33:22 -05:00
wolfbeast c032651778 Reject sample rates that are out-of-range for libsoundtouch.
We never reach this with our normal use of this lib but adding the
sanity check just in case. (ported from upstream)
2020-01-07 21:24:58 +01:00
Moonchild c66b70c4da Merge pull request #1346 from JustOff/PR_CSSStyleSheet_legacy
Issue #1345 - Implement non-standard legacy CSSStyleSheet rules
2020-01-07 12:30:21 +00:00
JustOff b4d686d62d Issue #1345 - Implement non-standard legacy CSSStyleSheet rules 2020-01-07 13:05:05 +02:00
Moonchild e30d68b699 Merge pull request #1341 from MoonchildProductions/nss-work
Update NSPR and NSS
2020-01-04 21:06:45 +00:00
wolfbeast b1694ef0a1 Issue #1338 - Part 5: Clobber for NSS update
We usually need this, so just in case.
2020-01-02 21:25:41 +01:00
wolfbeast 24f97a1683 Issue #1338 - Part 4: Initialize NSS with desired run-time values.
This NSS version (and onward) has variables to enable PKDBF rounds for
master password hardening (combating brute-force guessing).
Since we use DBM, we need to explicitly enable iteration counts in DBM
mode, and adjust the rounds used with a lower maximum because the PKDBF
routine for DBM is considerably slower for which the NSS default of
10,000 is debilitatingly high.
The method for this is run-time configuration through environment
variables. We set these prior to NSS initialization from nsAppRunner.cpp
so the NSS lib picks them up and allows us to continue using the DBM
cert/key stores with stored rounds per record.
2020-01-02 21:24:54 +01:00
wolfbeast c097dcf7fa Issue #1338 - Part 3: Update NSS symbols 2020-01-02 21:16:43 +01:00
wolfbeast f4a12fc676 Issue #1338 - Part 2: Update NSS to 3.48-RTM 2020-01-02 21:06:40 +01:00
wolfbeast f7d3013322 Issue #1338 - Part 1: Update NSPR to 4.24 2020-01-02 21:01:38 +01:00
New Tobin Paradigm 26b297510a Merge pull request #1340 from g4jc/mailnews_enhance
OAuth2 updates
2019-12-31 20:17:35 -05:00
Gaming4JC 12eb1554f9 Bug 1599054 - allow callers to ommit sending OAuth2 client_secret parameter. 2019-12-30 20:29:27 -05:00
Gaming4JC fb7de243f8 Bug 1597933 - Use URLSearchParams for setting params for OAuth2 authorization request. 2019-12-30 20:29:26 -05:00
Gaming4JC 8fdd883f7e Bug 1597933 - use fetch + URLSearchParms instead of Http.jsm to request OAuth2 access token. 2019-12-30 20:29:26 -05:00
Gaming4JC fd9d39ac97 Bug 1597933 - don't pass string constants to determine OAuth refresh token or not. 2019-12-30 20:29:26 -05:00
Gaming4JC f532cec976 Bug 1597933 - improve OAuth2 params parsing. 2019-12-30 20:29:25 -05:00
Gaming4JC 3dae851d21 Bug 1597933 - clean up OAuth2 code: remove responseType which is always code.
Response type token is part of the OAuth 2.0 Implicit Flow which is not used in Mail Applications, but also discouraged by the OAuth Working Group: https://developer.okta.com/blog/2019/05/01/is-the-oauth-implicit-flow-dead
2019-12-30 20:29:25 -05:00
Gaming4JC a4ab8fd190 Bug 1453643 - Enable proper retry on oauth2 authenication failure.
This prevents mail applications from  attempting to use an unauthenticated connection to mailbox(s) and avoid unexpected deletion of local mbox files and subsequent re-download of mailbox content over imap.
2019-12-30 20:29:25 -05:00
Gaming4JC 0395a076c8 Bug 1176399 - Multiple requests for master password when GMail OAuth2 is enabled. 2019-12-30 20:29:20 -05:00
Moonchild 357405f635 Merge pull request #1335 from MoonchildProductions/document_open
Align document.open() with the overhauled specification
2019-12-28 10:14:29 +00:00
Moonchild f60bbaf9e4 Merge pull request #1336 from athenian200/html-media-hack
Issue #1332 - Backport promise-based media playback.
2019-12-28 10:05:21 +00:00
athenian200 c3ed7420fd Fix typo. 2019-12-24 06:53:25 -06:00
athenian200 735418fa36 Issue #1332 - Backport promise-based media playback
https://bugzilla.mozilla.org/show_bug.cgi?id=1244768

I happened to find an older version of the promise-based media playback patch in Bugzilla, the one that was originally submitted for review. It had the DocShell changes I already knew how to deal with, and had fewer of the audio wrapper and nsISupports changes that were confusing me in the later patch. I was able to do a better job getting this back into a UXP-appropriate configuration than I could have with the final version.

I'm honestly still a little unsure about some of the minor refactoring done in the patch itself, insisting on already_AddRefed promises and such, but I don't really know how to avoid those completely. Still, I think it's better than it was.
2019-12-23 09:27:09 -06:00
wolfbeast 8b88623463 Issue #1118 - Part 9: Don't allow reuse of unlinked CallbackObjectHolder. 2019-12-23 01:21:32 +01:00
Moonchild 84f4806b46 Merge pull request #1334 from g4jc/bug1333
Don't hang on to pointer from temporary NS_LossyConvertUTF16toASCII.
2019-12-22 23:50:30 +00:00
wolfbeast e0f0b34926 Issue #1118 - Part 8: Remove no-longer-used mDidDocumentOpen and
CheckForOutdatedParent()

This was only used to check for cases when document.open() changed the
global, and elements being inserted into the document needing a new
reflector as a result.

Since document.open() no longer changes the global, this code is no
longer needed.
2019-12-23 00:04:31 +01:00
wolfbeast b1c7cc07c0 Issue #1118 - Part 7: Remove no-longer-used mWillReparent debug code. 2019-12-23 00:00:23 +01:00
wolfbeast f71108680b Issue #1118 - Part 6: Fix various tests that are no longer correct.
The behavior change of document.open() requires these tests to be
changed to account for the new spec behavior.
2019-12-22 23:48:40 +01:00
Gaming4JC 4e6294b248 Bug 1341238 - Don't hang on to pointer from temporary NS_LossyConvertUTF16toASCII.
Resolves #1333
2019-12-22 17:20:23 -05:00
wolfbeast dfa7af70ce Issue #1118 - Part 5: Change the way document.open() works
This changes the work we do for document.open() in the following ways:
- We no longer create a new Window when doing document.open().
  We use the same Window but remove all the event listeners on the
  existing DOM tree and Window before removing the document's existing
  children to provide a clean slate document to use for .write().
- We no longer create a session history entry (previously would be a
  wyciwyg URI). We now replace the current one, effectively losing the
  entry for the original document.
- We now support document.open() on windowless documents.
2019-12-22 19:57:30 +01:00
wolfbeast 54091ecab4 Forward to new tree structure. 2019-12-22 01:26:49 +01:00
wolfbeast 492624a710 Update README 2019-12-21 22:48:48 +01:00
wolfbeast d6baead6c8 Issue #1219 - Align computed DOM styles with mainstream behvior.
This updates our behavior for computed DOM styling to no longer return
null on elements that have no display, but return a 0-length (empty)
style instead and don't throw. For this we stop looking at having a
presentation for the style and just look at the document instead.

This resolves #1219
2019-12-20 23:08:47 +01:00
wolfbeast ce250e9ccf Enable layers acceleration by default on GTK platforms.
"Why is this still `blocked by default for platform`.. Everyone on Linux
forces it on anyway once they are aware of it." -- Tobin

Tag #1319
2019-12-20 17:59:59 +01:00
wolfbeast 368170bdc0 Issue #1316 - Reduce compiler warnings in ICU
This add a few disabled compiler warnings to the compiler flags on MSVC
and specifically filters out the RTTI disabling CL flag to prevent CLI
override warnings.

This resolves #1316
2019-12-19 17:40:52 +01:00
New Tobin Paradigm 3332f584c8 Merge pull request #1330 from MoonchildProductions/DOM-promise-removal
DOM `Promise` removal
2019-12-18 23:07:31 -05:00
wolfbeast c7ae364a88 Issue #1322 - Part 4: Fix WebIDL.py parser for line endings and wrong
IDL name
2019-12-19 03:26:59 +01:00
wolfbeast d461262405 Issue #1322 - Part 3: Remove DOM promise interface gunk
Based on work by Boris Zbarsky
2019-12-19 03:05:45 +01:00
wolfbeast cdea310f17 Issue #1322 - Part 2: Remove --enable-sm-promise buildconfig switch. 2019-12-19 01:36:07 +01:00
wolfbeast fb96b43b5f Issue #1322 - Part 1: Remove the DOM Promise guts.
This removes all the parts guarded by SPIDERMONKEY_PROMISE
2019-12-19 01:35:24 +01:00
wolfbeast 8220776c9b Issue #1328 - Follow-up: Increase font size for changed monospace fonts.
Previously-used `Courier New` was purposefully used at a smaller font
size due to its width. With the font switch this forced downscaling is
no longer needed, although it should still remain somewhat smaller than
variable width for balance (variable width is inherently more compact).
2019-12-18 17:27:22 +01:00
wolfbeast 11ce27f0dd Merge branch 'master' of https://github.com/MoonchildProductions/UXP 2019-12-18 13:38:59 +01:00
Chris Peterson eea149e732 Issue #1328 - Part 3: Add fuzz to reftests and fix misc other tests. 2019-12-18 13:36:53 +01:00
wolfbeast 0f67e7b22c Issue #1328 - Part 2: Change tests that require Courier New explicitly. 2019-12-18 13:22:53 +01:00
wolfbeast 342f942952 Issue #1328 - Part 1: Change default monospace font to Consolas for all
localizations where this would be set to Courier New.
2019-12-18 13:08:39 +01:00
Matt A. Tobin a3e93d08d4 No Issue - Fix indentation and account for system libevent in ipc/chromium/moz.build 2019-12-17 19:06:03 -05:00
Moonchild 07d0bcbf11 Merge pull request #1327 from g4jc/async_iteration
Implement Async Iteration in SpiderMonkey

This resolves #1287
2019-12-17 21:47:18 +00:00
Gaming4JC 6c3e42ac64 Bug 1454285 - Part 2: Disallow using innermostEmitterScope while the value does not match the bytecode environment.
Tag #1287
2019-12-17 06:25:31 -05:00
Gaming4JC c66d255122 Bug 1454285 - Part 1: Specify the current scope when emitting await and .generator.
Tag #1287
2019-12-17 06:25:31 -05:00
Gaming4JC c9bddfca7e Bug 1352312 - Enable Async Iteration.
Tag #1287
2019-12-17 06:25:30 -05:00
Gaming4JC e0eee318c6 Bug 1390082 - Implement AsyncGeneratorQueue with simpler array operations.
Tag #1287

Note: Without ReadableStream implementation
2019-12-17 06:25:30 -05:00
Gaming4JC 4a5ed79c6c Bug 1379525 - Part 2: Properly handle rejection in async-from-sync iteration.
Tag #1287
2019-12-17 06:25:30 -05:00
Gaming4JC 38c1d558af Bug 1379525 - Part 1: Await on the value before yielding or returning inside async generator.
Tag #1287
2019-12-17 06:25:29 -05:00
Gaming4JC dd1cbde156 Bug 1364608 - Stash rval in AsyncIteratorClose.
Tag #1287
2019-12-17 06:25:29 -05:00
Gaming4JC 63eee6325e Bug 1355399 - Switch property retrieval in Async-from-Sync Iterator prototype methods.
Tag #1287
2019-12-17 06:25:29 -05:00
Gaming4JC 55728c964f Bug 1331092 - Part 11: Await on the innerResult.value when innerResult.done is true in yield*.
Tag #1287
2019-12-17 06:25:29 -05:00
Gaming4JC 5bdfdb678d Bug 1331092 - Part 9: Implement for-await-of.
Tag #1287
2019-12-17 06:25:28 -05:00
Gaming4JC 580dfb2afb Bug 1331092 - Part 8: Support JSOP_TOASYNCITER in JIT.
Tag #1287
2019-12-17 06:25:28 -05:00
Gaming4JC ef44324d91 Bug 1331092 - Part 7: Implement Async Generator yield*.
Tag #1287
2019-12-17 06:25:28 -05:00
Gaming4JC bbd1fef784 Bug 1331092 - Part 6: Support JSOP_TOASYNCGEN in JIT.
Tag #1287
2019-12-17 06:25:27 -05:00
Gaming4JC 8e2f6a7599 Bug 1331092 - Part 2: Implement Async Generator except yield*.
Tag #1287
2019-12-17 06:25:27 -05:00
Gaming4JC d5086ac3aa Bug 1331092 - Part 2: Implement Async Generator except yield*.
Tag #1287
2019-12-17 06:25:27 -05:00
Gaming4JC 82f9efff93 Bug 1331092 - Part 1: Add Symbol.asyncIterator.
Tag #1287
2019-12-17 06:25:26 -05:00
Gaming4JC 5e1f00240d Bug 1331092 - Part 0: Define NOMINMAX to avoid compile error from min/max macro on windows.
Tag #1287
2019-12-17 06:25:26 -05:00
Gaming4JC f87b1b8850 Bug 1317389: Change property attributes for generator and async functions to match ES2015/2017.
Tag #1287
2019-12-17 06:25:26 -05:00
Gaming4JC f5fa6cfea7 Bug 1344753 - Update for-of stack depth in ControlFlowGenerator::processWhileOrForInLoop.
Tag #1287
2019-12-17 06:25:25 -05:00
Gaming4JC d0d9a4f43d Bug 1316098 - Optimize out result object allocation for await/return in async function.
Tag #1287
2019-12-17 06:25:25 -05:00
Gaming4JC 79b5eb14bc Bug 1343481 - Part 7: Add BytecodeEmitter::emitDotGenerator and make yield/await nodes unary.
Tag #1287
2019-12-17 06:25:25 -05:00
Gaming4JC cba3f61427 Bug 1343481 - Part 6: Add native functions wrapper for GetInternalError and GetTypeError.
Tag #1287
2019-12-17 06:25:25 -05:00
Gaming4JC 4f88fc8513 Bug 1343481 - Part 5: Rename AsyncFunction-related names in Promise.cpp to explicitly say Async Function.
Tag #1287
2019-12-17 06:25:24 -05:00
Gaming4JC 73c8732000 Bug 1343481 - Part 4: Add Add GeneratorObject.{isAfterYield,isAfterAwait}.
Tag #1287
2019-12-17 06:25:24 -05:00
Gaming4JC 3a3de55aad Bug 1343481 - Part 3: Add JSOP_AWAIT and rename {yieldIndex,yieldOffset} to {yieldAndAwaitIndex,yieldAndAwaitOffset}.
Tag #1287
2019-12-17 06:25:24 -05:00
Gaming4JC f07d5707c7 Bug 1343481 - Part 2: Stop using StarGegerator for async function.
Tag #1287
2019-12-17 06:25:23 -05:00
Gaming4JC 9163aaebb6 Bug 1343481 - Part 1: Remove {JSFunction,JSScript,LazyScript}.isGenerator() method.
Tag #1287
2019-12-17 06:25:23 -05:00
Gaming4JC 1fd726c6b0 Bug 1336705 - Part 2: Add self-hosting intrinsics for resolving/rejecting Promises and adding reactions.
Tag #1287
2019-12-17 06:25:23 -05:00
Gaming4JC cb732e5fdd Bug 336705 - Part 1: Support creating and resolving Promises without resolve/reject functions.
Useful for internally-created Promises that'll only ever be resolved/rejected internally.

Tag #1287
2019-12-17 06:25:22 -05:00
Gaming4JC f589ef8166 Bug 1317376 - Part 2: Detect Promise self-resolution when resolving through the Promise resolving fast path.
Tag #1287
2019-12-17 06:25:22 -05:00
Gaming4JC e23b013adf Bug 1317376 - Part 1: Remove unreachable code and remnants from the self-hosted implementation.
Tag #1287
2019-12-17 06:25:16 -05:00
Matt A. Tobin e2de507e02 Issue #1323 - Move XULRunner back to topsrcdir 2019-12-16 20:09:38 -05:00
Matt A. Tobin 06494f3078 Remove Basilisk from the Unified XUL Platform repository
Development will proceed at https://github.com/MoonchildProductions/Basilisk
2019-12-16 13:57:01 -05:00
wolfbeast e7d4713e07 Update 7z-stub README to reflect the current state of its use. 2019-12-15 01:34:51 +01:00
wolfbeast e6a3515a19 Update metadata in UXP 7z-stub installer 2019-12-15 01:25:32 +01:00
Matt A. Tobin 094e74ff6f Remove Pale Moon 7zstub 2019-12-14 17:31:53 -05:00
Matt A. Tobin 4e34c57467 Remove Pale Moon from the Unified XUL Platform repository
Development will proceed at https://github.com/MoonchildProductions/Pale-Moon
2019-12-14 14:37:24 -05:00
wolfbeast dacb3da00b Issue #1317 - Increase the XML nested depth limit to 2048.
- Converts from macro to static const for the limit.
- Uses a check against the declared type for the counter instead of
  a hard-coded one.

This resolves #1317.
2019-12-12 17:00:08 +01:00
wolfbeast d2a1d638b5 Update default bookmarks toolbar FAQ entry to redirect to forum. 2019-12-12 01:10:24 +01:00
wolfbeast 7758b9a26a New cycle version bump 2019-12-10 15:06:57 +01:00
wolfbeast c1013e9122 Issue #1118 Part 4: Allow UpdateURLAndHistory to work even if there's no
root session history.

This can happen when someone does a document.open() on a document that
has no session history.
2019-08-06 09:58:35 +00:00
wolfbeast 80e4577e3b Issue #1118 Part 3: Add a public RemoveAllListeners method on
EventListenerManager.
2019-08-06 09:57:37 +00:00
wolfbeast f5c848aa9b Issue #1118 Part 2: Allow UpdateURLAndHistory to work even if mOSHE is
null, if we're doing a replace.

We're going to end up hitting this if someone does a document.open()
before mOSHE has been set. We shouldn't need to worry about mLSHE,
because the document.open() will cancel the corresponding load.
2019-08-06 08:41:51 +00:00
wolfbeast 027fbae80a Issue #1118 Part 1: Split out part of nsDocShell::AddState into a
separate method.

This implements the "URL and history update steps" from the HTML spec.
See https://html.spec.whatwg.org/multipage/history.html
2019-07-31 14:18:54 +00:00
8622 changed files with 1802663 additions and 966461 deletions

No files matched your search

+5 -3
View File
@@ -49,9 +49,11 @@ js/src/autom4te.cache
js/src/tests/results-*.html
js/src/tests/results-*.txt
# Java HTML5 parser classes
parser/html/java/htmlparser/
parser/html/java/javaparser/
# Java HTML5 parser codegen artifacts
parser/html/java/htmlparser/bin/
parser/html/java/javaparser/bin/
parser/html/java/*.jar
parser/html/javasrc/
# Ignore the files and directory that Eclipse IDE creates
.project
+2 -1
View File
@@ -22,4 +22,5 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Clobber for NSS Update
Clobber for incremental customElements v1 landing
+11 -7
View File
@@ -6,11 +6,10 @@ with an ESR-52 fork point.
In addition to further development based on the Mozilla upstream code, and
selective cherry-picking of directly-applicable patches, this repository has its
own development and holds the base for a future platform to be used by XUL
own development and holds the base for a maintained platform to be used by XUL
applications.
This repository will contain at least one application to demonstrate and make use
of the platform: The Basilisk web browser, a close twin to Mozilla's Firefox.
For a list of active projects making use of the Unified XUL Platform, checkout http://thereisonlyxul.org/.
## Additional documentation
@@ -20,6 +19,7 @@ using and distributing this code and its binaries.
If you are interested in the development and building side of things, some
information will be available on the [Pale Moon developer wiki](http://developer.palemoon.org).
You are also always welcome to get in touch with our community on the [Pale Moon forum](https://forum.palemoon.org/).
### A note about trademarks and branding
@@ -29,7 +29,11 @@ owners. For more details, please see the notifications in the respective directo
### Foundation and maintainership
This repository has been founded and is maintained by Moonchild (M.C. Straver).
If you fork this repository to perform your own work on it, please consider
offering improvement patches upstream to its origin to mutually improve the
platform and build a future for XUL.
This repository has been founded by Moonchild (M.C. Straver) and is maintained by him
and other community members.
If you fork this repository to perform your own work on it, please consider offering
improvement patches upstream to its origin to mutually improve the platform and build
a future for XUL.
## Looking for Pale Moon and Basilisk?
As of [`Issue #969`](https://github.com/MoonchildProductions/UXP/issues/969), release versions `29.0.0` and `2020.03.04` respectively, they have been split off into their own dedicated repositories located at [`MoonchildProductions/Pale-Moon`](https://github.com/MoonchildProductions/Pale-Moon) and [`MoonchildProductions/Basilisk`](https://github.com/MoonchildProductions/Basilisk).
+21 -27
View File
@@ -175,23 +175,17 @@ HTMLTableCellAccessible::Table() const
uint32_t
HTMLTableCellAccessible::ColIdx() const
{
nsITableCellLayout* cellLayout = GetCellLayout();
NS_ENSURE_TRUE(cellLayout, 0);
int32_t colIdx = 0;
cellLayout->GetColIndex(colIdx);
return colIdx > 0 ? static_cast<uint32_t>(colIdx) : 0;
nsTableCellFrame* cellFrame = GetCellFrame();
NS_ENSURE_TRUE(cellFrame, 0);
return cellFrame->ColIndex();
}
uint32_t
HTMLTableCellAccessible::RowIdx() const
{
nsITableCellLayout* cellLayout = GetCellLayout();
NS_ENSURE_TRUE(cellLayout, 0);
int32_t rowIdx = 0;
cellLayout->GetRowIndex(rowIdx);
return rowIdx > 0 ? static_cast<uint32_t>(rowIdx) : 0;
nsTableCellFrame* cellFrame = GetCellFrame();
NS_ENSURE_TRUE(cellFrame, 0);
return cellFrame->RowIndex();
}
uint32_t
@@ -285,6 +279,12 @@ HTMLTableCellAccessible::GetCellLayout() const
return do_QueryFrame(mContent->GetPrimaryFrame());
}
nsTableCellFrame*
HTMLTableCellAccessible::GetCellFrame() const
{
return do_QueryFrame(mContent->GetPrimaryFrame());
}
nsresult
HTMLTableCellAccessible::GetCellIndexes(int32_t& aRowIdx, int32_t& aColIdx) const
{
@@ -520,11 +520,9 @@ HTMLTableAccessible::SelectedCellCount()
if (!cellFrame || !cellFrame->IsSelected())
continue;
int32_t startRow = -1, startCol = -1;
cellFrame->GetRowIndex(startRow);
cellFrame->GetColIndex(startCol);
if (startRow >= 0 && (uint32_t)startRow == rowIdx &&
startCol >= 0 && (uint32_t)startCol == colIdx)
uint32_t startRow = cellFrame->RowIndex();
uint32_t startCol = cellFrame->ColIndex();
if (startRow == rowIdx && startCol == colIdx)
count++;
}
}
@@ -570,11 +568,9 @@ HTMLTableAccessible::SelectedCells(nsTArray<Accessible*>* aCells)
if (!cellFrame || !cellFrame->IsSelected())
continue;
int32_t startCol = -1, startRow = -1;
cellFrame->GetRowIndex(startRow);
cellFrame->GetColIndex(startCol);
if ((startRow >= 0 && (uint32_t)startRow != rowIdx) ||
(startCol >= 0 && (uint32_t)startCol != colIdx))
uint32_t startRow = cellFrame->RowIndex();
uint32_t startCol = cellFrame->ColIndex();
if (startRow != rowIdx || startCol != colIdx)
continue;
Accessible* cell = mDoc->GetAccessible(cellFrame->GetContent());
@@ -597,11 +593,9 @@ HTMLTableAccessible::SelectedCellIndices(nsTArray<uint32_t>* aCells)
if (!cellFrame || !cellFrame->IsSelected())
continue;
int32_t startRow = -1, startCol = -1;
cellFrame->GetColIndex(startCol);
cellFrame->GetRowIndex(startRow);
if (startRow >= 0 && (uint32_t)startRow == rowIdx &&
startCol >= 0 && (uint32_t)startCol == colIdx)
uint32_t startCol = cellFrame->ColIndex();
uint32_t startRow = cellFrame->RowIndex();
if (startRow == rowIdx && startCol == colIdx)
aCells->AppendElement(CellIndexAt(rowIdx, colIdx));
}
}
+6
View File
@@ -11,6 +11,7 @@
#include "TableCellAccessible.h"
class nsITableCellLayout;
class nsTableCellFrame;
namespace mozilla {
namespace a11y {
@@ -53,6 +54,11 @@ protected:
*/
nsITableCellLayout* GetCellLayout() const;
/**
* Return the table cell frame.
*/
nsTableCellFrame* GetCellFrame() const;
/**
* Return row and column indices of the cell.
*/
@@ -421,7 +421,7 @@
//////////////////////////////////////////////////////////////////////////
// HTML:dialog
todo(isAccessible("dialog"), "dialog element is not accessible");
ok(isAccessible("dialog"), "dialog element is not accessible");
//////////////////////////////////////////////////////////////////////////
// HTML:div
-15
View File
@@ -1,15 +0,0 @@
"use strict";
module.exports = {
"extends": [
"../toolkit/.eslintrc.js"
],
"rules": {
"no-unused-vars": ["error", {
"vars": "local",
"varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
"args": "none",
}]
}
};
-13
View File
@@ -1,13 +0,0 @@
Please see the file ../toolkit/content/license.html for the copyright
licensing conditions attached to this codebase, including copies of the
licenses concerned.
You are not granted rights or licenses to the trademarks of Moonchild
Productions or any other party, including without limitation the
Basilisk name or logo.
The Serpent logo in branding/unofficial is derived from "Sea Serpent"
by Lorc, licensed under the Creative Commons license CC-BY 3.0
For individual licensing restrictions on branding, see the LICENSE
files in the appropriate branding directories.
-13
View File
@@ -1,13 +0,0 @@
# 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 $(topsrcdir)/config/rules.mk
ifdef MAKENSISU
# For Windows build the uninstaller during the application build since the
# uninstaller is included with the application for mar file generation.
libs::
$(MAKE) -C installer/windows uninstaller
endif
-1
View File
@@ -1 +0,0 @@
PURGECACHES_DIRS = $(DIST)/bin/browser
-15
View File
@@ -1,15 +0,0 @@
# vim: set filetype=python:
# 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('/toolkit/toolkit.mozbuild')
if CONFIG['MOZ_EXTENSIONS']:
DIRS += ['/extensions']
DIRS += ['/%s' % CONFIG['MOZ_BRANDING_DIRECTORY']]
# Never add dirs after the browser root because they apparently won't
# get packaged properly on Mac.
DIRS += ['/application/basilisk']
-96
View File
@@ -1,96 +0,0 @@
# 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/.
dist_dest = $(DIST)/$(MOZ_MACBUNDLE_NAME)
# hardcode en-US for the moment
AB_CD = en-US
# Build a binary bootstrapping with XRE_main
ifndef MOZ_WINCONSOLE
ifneq (,$(MOZ_DEBUG)$(MOZ_ASAN))
MOZ_WINCONSOLE = 1
else
MOZ_WINCONSOLE = 0
endif
endif
# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
NSDISTMODE = copy
include $(topsrcdir)/config/config.mk
ifeq ($(OS_ARCH),WINNT)
# Rebuild firefox.exe if the manifest changes - it's included by splash.rc.
# (this dependency should really be just for firefox.exe, not other targets)
# Note the manifest file exists in the tree, so we use the explicit filename
# here.
EXTRA_DEPS += basilisk.exe.manifest
endif
PROGRAMS_DEST = $(DIST)/bin
include $(topsrcdir)/config/rules.mk
ifneq (,$(filter-out WINNT,$(OS_ARCH)))
ifdef COMPILE_ENVIRONMENT
libs::
cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
endif
GARBAGE += $(addprefix $(FINAL_TARGET)/defaults/pref/, basilisk.js)
endif
# channel-prefs.js is handled separate from other prefs due to bug 756325
libs:: $(srcdir)/profile/channel-prefs.js
$(NSINSTALL) -D $(DIST)/bin/defaults/pref
$(call py_action,preprocessor,-Fsubstitution $(PREF_PPFLAGS) $(ACDEFINES) $^ -o $(DIST)/bin/defaults/pref/channel-prefs.js)
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
MAC_APP_NAME = $(MOZ_APP_DISPLAYNAME)
ifdef MOZ_DEBUG
MAC_APP_NAME := $(MAC_APP_NAME)Debug
endif
AB_CD = $(MOZ_UI_LOCALE)
ifeq (zh-TW,$(AB_CD))
LPROJ_ROOT := $(subst -,_,$(AB_CD))
else
LPROJ_ROOT := $(firstword $(subst -, ,$(AB_CD)))
endif
LPROJ := Contents/Resources/$(LPROJ_ROOT).lproj
clean clobber repackage::
$(RM) -r $(dist_dest)
MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/buildid.h)
.PHONY: repackage
tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME)
$(MKDIR) -p '$(dist_dest)/Contents/MacOS'
$(MKDIR) -p '$(dist_dest)/$(LPROJ)'
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents '$(dist_dest)' --exclude English.lproj
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ '$(dist_dest)/$(LPROJ)'
sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' $(srcdir)/macbuild/Contents/Info.plist.in > '$(dist_dest)/Contents/Info.plist'
sed -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > '$(dist_dest)/$(LPROJ)/InfoPlist.strings'
rsync -a --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ '$(dist_dest)/Contents/Resources'
rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ '$(dist_dest)/Contents/MacOS'
$(RM) '$(dist_dest)/Contents/MacOS/$(MOZ_APP_NAME)'
rsync -aL $(DIST)/bin/$(MOZ_APP_NAME) '$(dist_dest)/Contents/MacOS'
cp -RL $(DIST)/branding/firefox.icns '$(dist_dest)/Contents/Resources/firefox.icns'
cp -RL $(DIST)/branding/document.icns '$(dist_dest)/Contents/Resources/document.icns'
ifdef MOZ_UPDATER
$(MKDIR) -p '$(dist_dest)/Contents/Library/LaunchServices'
mv -f '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater' '$(dist_dest)/Contents/Library/LaunchServices'
ln -s ../../../../Library/LaunchServices/org.mozilla.updater '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater'
endif
printf APPLMOZB > '$(dist_dest)/Contents/PkgInfo'
endif
-50
View File
@@ -1,50 +0,0 @@
#if MOZ_APP_STATIC_INI
#ifdef MOZ_BUILD_APP_IS_BROWSER
; This file is not used. If you modify it and want the application to use
; your modifications, move it under the browser/ subdirectory and start with
; the "-app /path/to/browser/application.ini" argument.
#else
; This file is not used. If you modify it and want the application to use
; your modifications, start with the "-app /path/to/application.ini"
; argument.
#endif
#endif
#if 0
; 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/.
#endif
#filter substitution
#include @TOPOBJDIR@/buildid.h
#include @TOPOBJDIR@/source-repo.h
[App]
# Vendor=@MOZ_APP_VENDOR@
Vendor=Moonchild Productions
# Name=@MOZ_APP_BASENAME@
Name=Basilisk
RemotingName=@MOZ_APP_REMOTINGNAME@
#ifdef MOZ_APP_DISPLAYNAME
CodeName=@MOZ_APP_DISPLAYNAME@
#endif
Version=@MOZ_APP_VERSION@
#ifdef MOZ_APP_PROFILE
Profile=@MOZ_APP_PROFILE@
#endif
BuildID=@MOZ_BUILDID@
#ifdef MOZ_SOURCE_REPO
SourceRepository=@MOZ_SOURCE_REPO@
#endif
#ifdef MOZ_SOURCE_STAMP
SourceStamp=@MOZ_SOURCE_STAMP@
#endif
ID=@MOZ_APP_ID@
[Gecko]
MinVersion=@GRE_MILESTONE@
MaxVersion=@GRE_MILESTONE@
[XRE]
#ifdef MOZ_PROFILE_MIGRATOR
EnableProfileMigrator=1
#endif
@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="Basilisk"
type="win32"
/>
<description>Firefox</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
<ms_asmv3:security>
<ms_asmv3:requestedPrivileges>
<ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
</ms_asmv3:requestedPrivileges>
</ms_asmv3:security>
</ms_asmv3:trustInfo>
<ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
<ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
</ms_asmv3:windowsSettings>
</ms_asmv3:application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
</assembly>
File diff suppressed because it is too large. Load diff
@@ -1,229 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>html</string>
<string>htm</string>
<string>shtml</string>
<string>xht</string>
<string>xhtml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>HTML Document</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>HTML</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>svg</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>image/svg+xml</string>
</array>
<key>CFBundleTypeName</key>
<string>SVG document</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>TEXT</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>NSDocumentClass</key>
<string>BrowserDocument</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>text</string>
<string>txt</string>
<string>js</string>
<string>log</string>
<string>css</string>
<string>xul</string>
<string>rdf</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>Text Document</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>TEXT</string>
<string>utxt</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>jpeg</string>
<string>jpg</string>
<string>png</string>
<string>gif</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>fileBookmark.icns</string>
<key>CFBundleTypeName</key>
<string>document.icns</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>GIFf</string>
<string>JPEG</string>
<string>PNGf</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>oga</string>
<string>ogg</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>audio/ogg</string>
</array>
<key>CFBundleTypeName</key>
<string>HTML5 Audio (Ogg)</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>ogv</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>video/ogg</string>
</array>
<key>CFBundleTypeName</key>
<string>HTML5 Video (Ogg)</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>webm</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>video/webm</string>
</array>
<key>CFBundleTypeName</key>
<string>HTML5 Video (WebM)</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>basilisk</string>
<key>CFBundleGetInfoString</key>
<string>%MAC_APP_NAME% %APP_VERSION%</string>
<key>CFBundleIconFile</key>
<string>firefox.icns</string>
<key>CFBundleIdentifier</key>
<string>%MOZ_MACBUNDLE_ID%</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>%MAC_APP_NAME%</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>%APP_VERSION%</string>
<key>CFBundleSignature</key>
<string>MOZB</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLIconFile</key>
<string>document.icns</string>
<key>CFBundleURLName</key>
<string>http URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>http</string>
</array>
</dict>
<dict>
<key>CFBundleURLIconFile</key>
<string>document.icns</string>
<key>CFBundleURLName</key>
<string>https URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>https</string>
</array>
</dict>
<dict>
<key>CFBundleURLName</key>
<string>ftp URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>ftp</string>
</array>
</dict>
<dict>
<key>CFBundleURLName</key>
<string>file URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>file</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>%MAC_BUNDLE_VERSION%</string>
<key>NSAppleScriptEnabled</key>
<true/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string>
<key>LSEnvironment</key>
<dict>
<key>MallocNanoZone</key>
<string>0</string>
</dict>
<key>LSFileQuarantineEnabled</key>
<true/>
<key>LSMinimumSystemVersion</key>
<string>10.7.0</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSPrincipalClass</key>
<string>GeckoNSApplication</string>
<key>SMPrivilegedExecutables</key>
<dict>
<key>org.mozilla.updater</key>
<string>identifier "org.mozilla.updater" and ((anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9]) or (anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "43AQ936H96"))</string>
</dict>
<key>NSDisablePersistence</key>
<true/>
</dict>
</plist>
@@ -1,9 +0,0 @@
/*.app/***
/*.dylib
/certutil
/firefox-bin
/gtest/***
/pk12util
/ssltunnel
/xpcshell
/XUL
@@ -1,5 +0,0 @@
/* 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/. */
CFBundleName = "%MAC_APP_NAME%";
-44
View File
@@ -1,44 +0,0 @@
#!/usr/bin/python
# 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/.
from optparse import OptionParser
import sys
import re
o = OptionParser()
o.add_option("--buildid", dest="buildid")
o.add_option("--version", dest="version")
(options, args) = o.parse_args()
if not options.buildid:
print >>sys.stderr, "--buildid is required"
sys.exit(1)
if not options.version:
print >>sys.stderr, "--version is required"
sys.exit(1)
# We want to build a version number that matches the format allowed for
# CFBundleVersion (nnnnn[.nn[.nn]]). We'll incorporate both the version
# number as well as the date, so that it changes at least daily (for nightly
# builds), but also so that newly-built older versions (e.g. beta build) aren't
# considered "newer" than previously-built newer versions (e.g. a trunk nightly)
define, MOZ_BUILDID, buildid = open(options.buildid, 'r').read().split()
# extract only the major version (i.e. "14" from "14.0b1")
majorVersion = re.match(r'^(\d+)[^\d].*', options.version).group(1)
# last two digits of the year
twodigityear = buildid[2:4]
month = buildid[4:6]
if month[0] == '0':
month = month[1]
day = buildid[6:8]
if day[0] == '0':
day = day[1]
print '%s.%s.%s' % (majorVersion + twodigityear, month, day)
-8
View File
@@ -1,8 +0,0 @@
WIN32_MODULE_COMPANYNAME=Moonchild Productions
WIN32_MODULE_COPYRIGHT=©Basilisk and Mozilla Developers; available under the MPL 2 license.
WIN32_MODULE_PRODUCTVERSION=@MOZ_APP_WINVERSION@
WIN32_MODULE_PRODUCTVERSION_STRING=@MOZ_APP_VERSION@
WIN32_MODULE_TRADEMARKS=Basilisk is a Trademark of Moonchild Productions.
WIN32_MODULE_DESCRIPTION=@MOZ_APP_DISPLAYNAME@
WIN32_MODULE_PRODUCTNAME=@MOZ_APP_DISPLAYNAME@
WIN32_MODULE_NAME=@MOZ_APP_DISPLAYNAME@
-75
View File
@@ -1,75 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DIRS += ['profile/extensions']
GeckoProgram(CONFIG['MOZ_APP_NAME'])
JS_PREFERENCE_PP_FILES += [
'profile/basilisk.js',
]
SOURCES += [
'nsBrowserApp.cpp',
]
FINAL_TARGET_FILES += ['blocklist.xml']
FINAL_TARGET_FILES.defaults.profile += ['profile/prefs.js']
FINAL_TARGET_FILES.defaults += ['permissions']
DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
LOCAL_INCLUDES += [
'!/build',
'/toolkit/xre',
'/xpcom/base',
'/xpcom/build',
]
USE_LIBS += [
'mozglue',
]
if CONFIG['LIBFUZZER']:
USE_LIBS += [ 'fuzzer' ]
if CONFIG['_MSC_VER']:
# Always enter a Windows program through wmain, whether or not we're
# a console application.
WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
if CONFIG['OS_ARCH'] == 'WINNT':
RCINCLUDE = 'splash.rc'
DEFINES['MOZ_PHOENIX'] = True
for cdm in CONFIG['MOZ_EME_MODULES']:
DEFINES['MOZ_%s_EME' % cdm.upper()] = True
# Control the default heap size.
# This is the heap returned by GetProcessHeap().
# As we use the CRT heap, the default size is too large and wastes VM.
#
# The default heap size is 1MB on Win32.
# The heap will grow if need be.
#
# Set it to 256k. See bug 127069.
if CONFIG['OS_ARCH'] == 'WINNT' and not CONFIG['GNU_CC']:
LDFLAGS += ['/HEAP:0x40000']
DISABLE_STL_WRAPPING = True
if CONFIG['MOZ_LINKER']:
OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
if CONFIG['HAVE_CLOCK_MONOTONIC']:
OS_LIBS += CONFIG['REALTIME_LIBS']
if CONFIG['MOZ_GPSD']:
DEFINES['MOZ_GPSD'] = True
for icon in ('firefox', 'document', 'newwindow', 'newtab', 'pbmode'):
DEFINES[icon.upper() + '_ICO'] = '"%s/dist/branding/%s.ico"' % (
TOPOBJDIR, icon)
-393
View File
@@ -1,393 +0,0 @@
/* -*- Mode: C++; tab-width: 2; 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 "nsXULAppAPI.h"
#include "mozilla/AppData.h"
#include "application.ini.h"
#include "nsXPCOMGlue.h"
#if defined(XP_WIN)
#include <windows.h>
#include <stdlib.h>
#elif defined(XP_UNIX)
#include <sys/resource.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "nsStringGlue.h"
#ifdef XP_WIN
#define XRE_WANT_ENVIRON
#define strcasecmp _stricmp
#endif
#include "BinaryPath.h"
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
#include "mozilla/Sprintf.h"
#include "mozilla/Telemetry.h"
#include "mozilla/WindowsDllBlocklist.h"
#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID)
#define MOZ_BROWSER_CAN_BE_CONTENTPROC
#include "../../ipc/contentproc/plugin-container.cpp"
#endif
using namespace mozilla;
#ifdef XP_MACOSX
#define kOSXResourcesFolder "Resources"
#endif
#define kDesktopFolder "browser"
static void Output(const char *fmt, ... )
{
va_list ap;
va_start(ap, fmt);
#ifndef XP_WIN
vfprintf(stderr, fmt, ap);
#else
char msg[2048];
vsnprintf_s(msg, _countof(msg), _TRUNCATE, fmt, ap);
wchar_t wide_msg[2048];
MultiByteToWideChar(CP_UTF8,
0,
msg,
-1,
wide_msg,
_countof(wide_msg));
#if MOZ_WINCONSOLE
fwprintf_s(stderr, wide_msg);
#else
// Linking user32 at load-time interferes with the DLL blocklist (bug 932100).
// This is a rare codepath, so we can load user32 at run-time instead.
HMODULE user32 = LoadLibraryW(L"user32.dll");
if (user32) {
decltype(MessageBoxW)* messageBoxW =
(decltype(MessageBoxW)*) GetProcAddress(user32, "MessageBoxW");
if (messageBoxW) {
messageBoxW(nullptr, wide_msg, L"Basilisk", MB_OK
| MB_ICONERROR
| MB_SETFOREGROUND);
}
FreeLibrary(user32);
}
#endif
#endif
va_end(ap);
}
/**
* Return true if |arg| matches the given argument name.
*/
static bool IsArg(const char* arg, const char* s)
{
if (*arg == '-')
{
if (*++arg == '-')
++arg;
return !strcasecmp(arg, s);
}
#if defined(XP_WIN)
if (*arg == '/')
return !strcasecmp(++arg, s);
#endif
return false;
}
XRE_GetFileFromPathType XRE_GetFileFromPath;
XRE_CreateAppDataType XRE_CreateAppData;
XRE_FreeAppDataType XRE_FreeAppData;
XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
XRE_StartupTimelineRecordType XRE_StartupTimelineRecord;
XRE_mainType XRE_main;
XRE_StopLateWriteChecksType XRE_StopLateWriteChecks;
XRE_XPCShellMainType XRE_XPCShellMain;
XRE_GetProcessTypeType XRE_GetProcessType;
XRE_SetProcessTypeType XRE_SetProcessType;
XRE_InitChildProcessType XRE_InitChildProcess;
XRE_EnableSameExecutableForContentProcType XRE_EnableSameExecutableForContentProc;
#ifdef LIBFUZZER
XRE_LibFuzzerSetMainType XRE_LibFuzzerSetMain;
XRE_LibFuzzerGetFuncsType XRE_LibFuzzerGetFuncs;
#endif
static const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
{ "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
{ "XRE_StartupTimelineRecord", (NSFuncPtr*) &XRE_StartupTimelineRecord },
{ "XRE_main", (NSFuncPtr*) &XRE_main },
{ "XRE_StopLateWriteChecks", (NSFuncPtr*) &XRE_StopLateWriteChecks },
{ "XRE_XPCShellMain", (NSFuncPtr*) &XRE_XPCShellMain },
{ "XRE_GetProcessType", (NSFuncPtr*) &XRE_GetProcessType },
{ "XRE_SetProcessType", (NSFuncPtr*) &XRE_SetProcessType },
{ "XRE_InitChildProcess", (NSFuncPtr*) &XRE_InitChildProcess },
{ "XRE_EnableSameExecutableForContentProc", (NSFuncPtr*) &XRE_EnableSameExecutableForContentProc },
#ifdef LIBFUZZER
{ "XRE_LibFuzzerSetMain", (NSFuncPtr*) &XRE_LibFuzzerSetMain },
{ "XRE_LibFuzzerGetFuncs", (NSFuncPtr*) &XRE_LibFuzzerGetFuncs },
#endif
{ nullptr, nullptr }
};
#ifdef LIBFUZZER
int libfuzzer_main(int argc, char **argv);
/* This wrapper is used by the libFuzzer main to call into libxul */
void libFuzzerGetFuncs(const char* moduleName, LibFuzzerInitFunc* initFunc,
LibFuzzerTestingFunc* testingFunc) {
return XRE_LibFuzzerGetFuncs(moduleName, initFunc, testingFunc);
}
#endif
static int do_main(int argc, char* argv[], char* envp[], nsIFile *xreDirectory)
{
nsCOMPtr<nsIFile> appini;
nsresult rv;
uint32_t mainFlags = 0;
// Allow basilisk.exe to launch XULRunner apps via -app <application.ini>
// Note that -app must be the *first* argument.
const char *appDataFile = getenv("XUL_APP_FILE");
if (appDataFile && *appDataFile) {
rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
if (NS_FAILED(rv)) {
Output("Invalid path found: '%s'", appDataFile);
return 255;
}
}
else if (argc > 1 && IsArg(argv[1], "app")) {
if (argc == 2) {
Output("Incorrect number of arguments passed to -app");
return 255;
}
rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
if (NS_FAILED(rv)) {
Output("application.ini path not recognized: '%s'", argv[2]);
return 255;
}
char appEnv[MAXPATHLEN];
SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]);
if (putenv(strdup(appEnv))) {
Output("Couldn't set %s.\n", appEnv);
return 255;
}
argv[2] = argv[0];
argv += 2;
argc -= 2;
} else if (argc > 1 && IsArg(argv[1], "xpcshell")) {
for (int i = 1; i < argc; i++) {
argv[i] = argv[i + 1];
}
return XRE_XPCShellMain(--argc, argv, envp);
}
if (appini) {
nsXREAppData *appData;
rv = XRE_CreateAppData(appini, &appData);
if (NS_FAILED(rv)) {
Output("Couldn't read application.ini");
return 255;
}
#if defined(HAS_DLL_BLOCKLIST)
// The dll blocklist operates in the exe vs. xullib. Pass a flag to
// xullib so automated tests can check the result once the browser
// is up and running.
appData->flags |=
DllBlocklist_CheckStatus() ? NS_XRE_DLL_BLOCKLIST_ENABLED : 0;
#endif
// xreDirectory already has a refcount from NS_NewLocalFile
appData->xreDirectory = xreDirectory;
int result = XRE_main(argc, argv, appData, mainFlags);
XRE_FreeAppData(appData);
return result;
}
ScopedAppData appData(&sAppData);
nsCOMPtr<nsIFile> exeFile;
rv = mozilla::BinaryPath::GetFile(argv[0], getter_AddRefs(exeFile));
if (NS_FAILED(rv)) {
Output("Couldn't find the application directory.\n");
return 255;
}
nsCOMPtr<nsIFile> greDir;
exeFile->GetParent(getter_AddRefs(greDir));
#ifdef XP_MACOSX
greDir->SetNativeLeafName(NS_LITERAL_CSTRING(kOSXResourcesFolder));
#endif
nsCOMPtr<nsIFile> appSubdir;
greDir->Clone(getter_AddRefs(appSubdir));
appSubdir->Append(NS_LITERAL_STRING(kDesktopFolder));
SetStrongPtr(appData.directory, static_cast<nsIFile*>(appSubdir.get()));
// xreDirectory already has a refcount from NS_NewLocalFile
appData.xreDirectory = xreDirectory;
#if defined(HAS_DLL_BLOCKLIST)
appData.flags |=
DllBlocklist_CheckStatus() ? NS_XRE_DLL_BLOCKLIST_ENABLED : 0;
#endif
#ifdef LIBFUZZER
if (getenv("LIBFUZZER"))
XRE_LibFuzzerSetMain(argc, argv, libfuzzer_main);
#endif
return XRE_main(argc, argv, &appData, mainFlags);
}
static bool
FileExists(const char *path)
{
#ifdef XP_WIN
wchar_t wideDir[MAX_PATH];
MultiByteToWideChar(CP_UTF8, 0, path, -1, wideDir, MAX_PATH);
DWORD fileAttrs = GetFileAttributesW(wideDir);
return fileAttrs != INVALID_FILE_ATTRIBUTES;
#else
return access(path, R_OK) == 0;
#endif
}
static nsresult
InitXPCOMGlue(const char *argv0, nsIFile **xreDirectory)
{
char exePath[MAXPATHLEN];
nsresult rv = mozilla::BinaryPath::Get(argv0, exePath);
if (NS_FAILED(rv)) {
Output("Couldn't find the application directory.\n");
return rv;
}
char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
if (!lastSlash ||
(size_t(lastSlash - exePath) > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
return NS_ERROR_FAILURE;
strcpy(lastSlash + 1, XPCOM_DLL);
if (!FileExists(exePath)) {
Output("Could not find the Mozilla runtime.\n");
return NS_ERROR_FAILURE;
}
// We do this because of data in bug 771745
XPCOMGlueEnablePreload();
rv = XPCOMGlueStartup(exePath);
if (NS_FAILED(rv)) {
Output("Couldn't load XPCOM.\n");
return rv;
}
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
if (NS_FAILED(rv)) {
Output("Couldn't load XRE functions.\n");
return rv;
}
// This will set this thread as the main thread.
NS_LogInit();
if (xreDirectory) {
// chop XPCOM_DLL off exePath
*lastSlash = '\0';
#ifdef XP_MACOSX
lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
strcpy(lastSlash + 1, kOSXResourcesFolder);
#endif
#ifdef XP_WIN
rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
xreDirectory);
#else
rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
xreDirectory);
#endif
}
return rv;
}
int main(int argc, char* argv[], char* envp[])
{
mozilla::TimeStamp start = mozilla::TimeStamp::Now();
#ifdef HAS_DLL_BLOCKLIST
DllBlocklist_Initialize();
#ifdef DEBUG
// In order to be effective against AppInit DLLs, the blocklist must be
// initialized before user32.dll is loaded into the process (bug 932100).
if (GetModuleHandleA("user32.dll")) {
fprintf(stderr, "DLL blocklist was unable to intercept AppInit DLLs.\n");
}
#endif
#endif
#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
// We are launching as a content process, delegate to the appropriate
// main
if (argc > 1 && IsArg(argv[1], "contentproc")) {
nsresult rv = InitXPCOMGlue(argv[0], nullptr);
if (NS_FAILED(rv)) {
return 255;
}
int result = content_process_main(argc, argv);
// InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
NS_LogTerm();
return result;
}
#endif
nsIFile *xreDirectory;
nsresult rv = InitXPCOMGlue(argv[0], &xreDirectory);
if (NS_FAILED(rv)) {
return 255;
}
XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
XRE_EnableSameExecutableForContentProc();
#endif
int result = do_main(argc, argv, envp, xreDirectory);
NS_LogTerm();
#ifdef XP_MACOSX
// Allow writes again. While we would like to catch writes from static
// destructors to allow early exits to use _exit, we know that there is
// at least one such write that we don't control (see bug 826029). For
// now we enable writes again and early exits will have to use exit instead
// of _exit.
XRE_StopLateWriteChecks();
#endif
return result;
}
-17
View File
@@ -1,17 +0,0 @@
# This file has default permissions for the permission manager.
# The file-format is strict:
# * matchtype \t type \t permission \t host
# * "origin" should be used for matchtype, "host" is supported for legacy reasons
# * type is a string that identifies the type of permission (e.g. "cookie")
# * permission is an integer between 1 and 15
# See nsPermissionManager.cpp for more...
# XPInstall
origin install 1 http://addons.basilisk-browser.org
origin install 1 https://addons.basilisk-browser.org
origin install 1 https://addons.mozilla.org
origin install 1 https://testpilot.firefox.com
# Remote troubleshooting
origin remote-troubleshooting 1 https://input.mozilla.org
origin remote-troubleshooting 1 https://support.mozilla.org
File diff suppressed because it is too large. Load diff
@@ -1,5 +0,0 @@
/* 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/. */
pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@");
@@ -1,7 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DIRS += ['{972ce4c6-7e08-4474-a285-3208198ce6fd}']
@@ -1,40 +0,0 @@
<?xml version="1.0"?>
<!-- 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/. -->
#filter substitution
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>{972ce4c6-7e08-4474-a285-3208198ce6fd}</em:id>
<em:version>@MOZ_APP_VERSION@</em:version>
<!-- Target Application this theme can install into,
with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
<em:id>@MOZ_APP_ID@</em:id>
<em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
<em:maxVersion>@MOZ_APP_VERSION@</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Default</em:name>
<em:description>The default theme.</em:description>
<!-- Front End Integration Hooks (used by Theme Manager)-->
<em:creator>Mozilla</em:creator>
<em:contributor>Mozilla Contributors</em:contributor>
<!-- Allow lightweight themes to apply to this theme -->
<em:skinnable>true</em:skinnable>
<em:internalName>classic/1.0</em:internalName>
</Description>
</RDF>
@@ -1,14 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_ID'] = CONFIG['MOZ_APP_ID']
FINAL_TARGET = 'dist/bin/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}'
FINAL_TARGET_PP_FILES += [
'install.rdf.in',
]
@@ -1,7 +0,0 @@
<?xml version="1.0"?> <!-- -*- Mode: SGML -*- -->
<!-- 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/. -->
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"/>
-13
View File
@@ -1,13 +0,0 @@
/* 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/. */
# Mozilla User Preferences
/* Do not edit this file.
*
* If you make changes to this file while the browser is running,
* the changes will be overwritten when the browser exits.
*
* To make a manual change to preferences, you can visit the URL about:config
*/
-21
View File
@@ -1,21 +0,0 @@
/* -*- Mode: C++; tab-width: 2; 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 <windows.h>
#include "nsNativeAppSupportWin.h"
1 24 "basilisk.exe.manifest"
IDI_APPICON ICON FIREFOX_ICO
IDI_DOCUMENT ICON DOCUMENT_ICO
IDI_APPLICATION ICON FIREFOX_ICO
IDI_NEWWINDOW ICON NEWWINDOW_ICO
IDI_NEWTAB ICON NEWTAB_ICO
IDI_PBMODE ICON PBMODE_ICO
STRINGTABLE DISCARDABLE
BEGIN
IDS_STARTMENU_APPNAME, "@MOZ_APP_DISPLAYNAME@"
END
-11
View File
@@ -1,11 +0,0 @@
"use strict";
module.exports = {
"rules": {
"no-unused-vars": ["error", {
"vars": "local",
"varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
"args": "none",
}]
}
};
@@ -1,428 +0,0 @@
/* 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/. */
// Note: this file is included in aboutDialog.xul if MOZ_UPDATER is defined.
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
const PREF_APP_UPDATE_CANCELATIONS_OSX = "app.update.cancelations.osx";
const PREF_APP_UPDATE_ELEVATE_NEVER = "app.update.elevate.never";
var gAppUpdater;
function onUnload(aEvent) {
if (gAppUpdater.isChecking)
gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK);
// Safe to call even when there isn't a download in progress.
gAppUpdater.removeDownloadListener();
gAppUpdater = null;
}
function appUpdater()
{
XPCOMUtils.defineLazyServiceGetter(this, "aus",
"@mozilla.org/updates/update-service;1",
"nsIApplicationUpdateService");
XPCOMUtils.defineLazyServiceGetter(this, "checker",
"@mozilla.org/updates/update-checker;1",
"nsIUpdateChecker");
XPCOMUtils.defineLazyServiceGetter(this, "um",
"@mozilla.org/updates/update-manager;1",
"nsIUpdateManager");
this.updateDeck = document.getElementById("updateDeck");
// Hide the update deck when the update window is already open and it's not
// already applied, to avoid syncing issues between them. Applied updates
// don't have any information to sync between the windows as they both just
// show the "Restart to continue"-type button.
if (Services.wm.getMostRecentWindow("Update:Wizard") &&
!this.isApplied) {
this.updateDeck.hidden = true;
return;
}
this.bundle = Services.strings.
createBundle("chrome://browser/locale/browser.properties");
let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
let manualLink = document.getElementById("manualLink");
manualLink.value = manualURL;
manualLink.href = manualURL;
document.getElementById("failedLink").href = manualURL;
if (this.updateDisabledAndLocked) {
this.selectPanel("adminDisabled");
return;
}
if (this.isPending || this.isApplied) {
this.selectPanel("apply");
return;
}
if (this.aus.isOtherInstanceHandlingUpdates) {
this.selectPanel("otherInstanceHandlingUpdates");
return;
}
if (this.isDownloading) {
this.startDownload();
// selectPanel("downloading") is called from setupDownloadingUI().
return;
}
// Honor the "Never check for updates" option by not only disabling background
// update checks, but also in the About dialog, by presenting a
// "Check for updates" button.
// If updates are found, the user is then asked if he wants to "Update to <version>".
if (!this.updateEnabled ||
Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ELEVATE_NEVER)) {
this.selectPanel("checkForUpdates");
return;
}
// That leaves the options
// "Check for updates, but let me choose whether to install them", and
// "Automatically install updates".
// In both cases, we check for updates without asking.
// In the "let me choose" case, we ask before downloading though, in onCheckComplete.
this.checkForUpdates();
}
appUpdater.prototype =
{
// true when there is an update check in progress.
isChecking: false,
// true when there is an update already staged / ready to be applied.
get isPending() {
if (this.update) {
return this.update.state == "pending" ||
this.update.state == "pending-service" ||
this.update.state == "pending-elevate";
}
return this.um.activeUpdate &&
(this.um.activeUpdate.state == "pending" ||
this.um.activeUpdate.state == "pending-service" ||
this.um.activeUpdate.state == "pending-elevate");
},
// true when there is an update already installed in the background.
get isApplied() {
if (this.update)
return this.update.state == "applied" ||
this.update.state == "applied-service";
return this.um.activeUpdate &&
(this.um.activeUpdate.state == "applied" ||
this.um.activeUpdate.state == "applied-service");
},
// true when there is an update download in progress.
get isDownloading() {
if (this.update)
return this.update.state == "downloading";
return this.um.activeUpdate &&
this.um.activeUpdate.state == "downloading";
},
// true when updating is disabled by an administrator.
get updateDisabledAndLocked() {
return !this.updateEnabled &&
Services.prefs.prefIsLocked("app.update.enabled");
},
// true when updating is enabled.
get updateEnabled() {
try {
return Services.prefs.getBoolPref("app.update.enabled");
}
catch (e) { }
return true; // Firefox default is true
},
// true when updating in background is enabled.
get backgroundUpdateEnabled() {
return this.updateEnabled &&
gAppUpdater.aus.canStageUpdates;
},
// true when updating is automatic.
get updateAuto() {
try {
return Services.prefs.getBoolPref("app.update.auto");
}
catch (e) { }
return true; // Firefox default is true
},
/**
* Sets the panel of the updateDeck.
*
* @param aChildID
* The id of the deck's child to select, e.g. "apply".
*/
selectPanel: function(aChildID) {
let panel = document.getElementById(aChildID);
let button = panel.querySelector("button");
if (button) {
if (aChildID == "downloadAndInstall") {
let updateVersion = gAppUpdater.update.displayVersion;
button.label = this.bundle.formatStringFromName("update.downloadAndInstallButton.label", [updateVersion], 1);
button.accessKey = this.bundle.GetStringFromName("update.downloadAndInstallButton.accesskey");
}
this.updateDeck.selectedPanel = panel;
if (!document.commandDispatcher.focusedElement || // don't steal the focus
document.commandDispatcher.focusedElement.localName == "button") // except from the other buttons
button.focus();
} else {
this.updateDeck.selectedPanel = panel;
}
},
/**
* Check for updates
*/
checkForUpdates: function() {
// Clear prefs that could prevent a user from discovering available updates.
if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CANCELATIONS_OSX)) {
Services.prefs.clearUserPref(PREF_APP_UPDATE_CANCELATIONS_OSX);
}
if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ELEVATE_NEVER)) {
Services.prefs.clearUserPref(PREF_APP_UPDATE_ELEVATE_NEVER);
}
this.selectPanel("checkingForUpdates");
this.isChecking = true;
this.checker.checkForUpdates(this.updateCheckListener, true);
// after checking, onCheckComplete() is called
},
/**
* Handles oncommand for the "Restart to Update" button
* which is presented after the download has been downloaded.
*/
buttonRestartAfterDownload: function() {
if (!this.isPending && !this.isApplied) {
return;
}
gAppUpdater.selectPanel("restarting");
// Notify all windows that an application quit has been requested.
let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
createInstance(Components.interfaces.nsISupportsPRBool);
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
// Something aborted the quit process.
if (cancelQuit.data) {
gAppUpdater.selectPanel("apply");
return;
}
let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
getService(Components.interfaces.nsIAppStartup);
// If already in safe mode restart in safe mode (bug 327119)
if (Services.appinfo.inSafeMode) {
appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit);
return;
}
appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
Components.interfaces.nsIAppStartup.eRestart);
},
/**
* Implements nsIUpdateCheckListener. The methods implemented by
* nsIUpdateCheckListener are in a different scope from nsIIncrementalDownload
* to make it clear which are used by each interface.
*/
updateCheckListener: {
/**
* See nsIUpdateService.idl
*/
onCheckComplete: function(aRequest, aUpdates, aUpdateCount) {
gAppUpdater.isChecking = false;
gAppUpdater.update = gAppUpdater.aus.
selectUpdate(aUpdates, aUpdates.length);
if (!gAppUpdater.update) {
gAppUpdater.selectPanel("noUpdatesFound");
return;
}
if (gAppUpdater.update.unsupported) {
if (gAppUpdater.update.detailsURL) {
let unsupportedLink = document.getElementById("unsupportedLink");
unsupportedLink.href = gAppUpdater.update.detailsURL;
}
gAppUpdater.selectPanel("unsupportedSystem");
return;
}
if (!gAppUpdater.aus.canApplyUpdates) {
gAppUpdater.selectPanel("manualUpdate");
return;
}
if (gAppUpdater.updateAuto) // automatically download and install
gAppUpdater.startDownload();
else // ask
gAppUpdater.selectPanel("downloadAndInstall");
},
/**
* See nsIUpdateService.idl
*/
onError: function(aRequest, aUpdate) {
// Errors in the update check are treated as no updates found. If the
// update check fails repeatedly without a success the user will be
// notified with the normal app update user interface so this is safe.
gAppUpdater.isChecking = false;
gAppUpdater.selectPanel("noUpdatesFound");
},
/**
* See nsISupports.idl
*/
QueryInterface: function(aIID) {
if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
!aIID.equals(Components.interfaces.nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
},
/**
* Starts the download of an update mar.
*/
startDownload: function() {
if (!this.update)
this.update = this.um.activeUpdate;
this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag);
this.update.setProperty("foregroundDownload", "true");
this.aus.pauseDownload();
let state = this.aus.downloadUpdate(this.update, false);
if (state == "failed") {
this.selectPanel("downloadFailed");
return;
}
this.setupDownloadingUI();
},
/**
* Switches to the UI responsible for tracking the download.
*/
setupDownloadingUI: function() {
this.downloadStatus = document.getElementById("downloadStatus");
this.downloadStatus.value =
DownloadUtils.getTransferTotal(0, this.update.selectedPatch.size);
this.selectPanel("downloading");
this.aus.addDownloadListener(this);
},
removeDownloadListener: function() {
if (this.aus) {
this.aus.removeDownloadListener(this);
}
},
/**
* See nsIRequestObserver.idl
*/
onStartRequest: function(aRequest, aContext) {
},
/**
* See nsIRequestObserver.idl
*/
onStopRequest: function(aRequest, aContext, aStatusCode) {
switch (aStatusCode) {
case Components.results.NS_ERROR_UNEXPECTED:
if (this.update.selectedPatch.state == "download-failed" &&
(this.update.isCompleteUpdate || this.update.patchCount != 2)) {
// Verification error of complete patch, informational text is held in
// the update object.
this.removeDownloadListener();
this.selectPanel("downloadFailed");
break;
}
// Verification failed for a partial patch, complete patch is now
// downloading so return early and do NOT remove the download listener!
break;
case Components.results.NS_BINDING_ABORTED:
// Do not remove UI listener since the user may resume downloading again.
break;
case Components.results.NS_OK:
this.removeDownloadListener();
if (this.backgroundUpdateEnabled) {
this.selectPanel("applying");
let self = this;
Services.obs.addObserver(function (aSubject, aTopic, aData) {
// Update the UI when the background updater is finished
let status = aData;
if (status == "applied" || status == "applied-service" ||
status == "pending" || status == "pending-service" ||
status == "pending-elevate") {
// If the update is successfully applied, or if the updater has
// fallen back to non-staged updates, show the "Restart to Update"
// button.
self.selectPanel("apply");
} else if (status == "failed") {
// Background update has failed, let's show the UI responsible for
// prompting the user to update manually.
self.selectPanel("downloadFailed");
} else if (status == "downloading") {
// We've fallen back to downloading the full update because the
// partial update failed to get staged in the background.
// Therefore we need to keep our observer.
self.setupDownloadingUI();
return;
}
Services.obs.removeObserver(arguments.callee, "update-staged");
}, "update-staged", false);
} else {
this.selectPanel("apply");
}
break;
default:
this.removeDownloadListener();
this.selectPanel("downloadFailed");
break;
}
},
/**
* See nsIProgressEventSink.idl
*/
onStatus: function(aRequest, aContext, aStatus, aStatusArg) {
},
/**
* See nsIProgressEventSink.idl
*/
onProgress: function(aRequest, aContext, aProgress, aProgressMax) {
this.downloadStatus.value =
DownloadUtils.getTransferTotal(aProgress, aProgressMax);
},
/**
* See nsISupports.idl
*/
QueryInterface: function(aIID) {
if (!aIID.equals(Components.interfaces.nsIProgressEventSink) &&
!aIID.equals(Components.interfaces.nsIRequestObserver) &&
!aIID.equals(Components.interfaces.nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
@@ -1,97 +0,0 @@
/* 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/. */
#aboutDialog {
width: 620px;
/* Set an explicit line-height to avoid discrepancies in 'auto' spacing
across screens with different device DPI, which may cause font metrics
to round differently. */
line-height: 1.5;
}
#rightBox {
background-image: url("chrome://branding/content/about-wordmark.png");
background-repeat: no-repeat;
/* padding-top creates room for the wordmark */
padding-top: 38px;
margin-top:20px;
}
#rightBox:-moz-locale-dir(rtl) {
background-position: 100% 0;
}
#bottomBox {
padding: 15px 10px 0;
}
#version {
font-weight: bold;
margin-top: 10px;
margin-left: 0;
-moz-user-select: text;
-moz-user-focus: normal;
cursor: text;
}
#version:-moz-locale-dir(rtl) {
direction: ltr;
text-align: right;
margin-left: 5px;
margin-right: 0;
}
#releasenotes {
margin-top: 10px;
}
#distribution,
#distributionId {
display: none;
margin-top: 0;
margin-bottom: 0;
}
.text-blurb {
margin-bottom: 10px;
margin-inline-start: 0;
padding-inline-start: 0;
}
#updateButton,
#updateDeck > hbox > label {
margin-inline-start: 0;
padding-inline-start: 0;
}
.update-throbber {
width: 16px;
min-height: 16px;
margin-inline-end: 3px;
list-style-image: url("chrome://global/skin/icons/loading.png");
}
@media (min-resolution: 1.1dppx) {
.update-throbber {
list-style-image: url("chrome://global/skin/icons/loading@2x.png");
}
}
description > .text-link,
description > .text-link:focus {
margin: 0px;
padding: 0px;
}
.bottom-link,
.bottom-link:focus {
text-align: center;
margin: 0 40px;
}
#currentChannel {
margin: 0;
padding: 0;
font-weight: bold;
}
@@ -1,91 +0,0 @@
/* 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/. */
"use strict";
// Services = object with smart getters for common XPCOM services
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/AppConstants.jsm");
function init(aEvent)
{
if (aEvent.target != document)
return;
try {
var distroId = Services.prefs.getCharPref("distribution.id");
if (distroId) {
var distroVersion = Services.prefs.getCharPref("distribution.version");
var distroIdField = document.getElementById("distributionId");
distroIdField.value = distroId + " - " + distroVersion;
distroIdField.style.display = "block";
try {
// This is in its own try catch due to bug 895473 and bug 900925.
var distroAbout = Services.prefs.getComplexValue("distribution.about",
Components.interfaces.nsISupportsString);
var distroField = document.getElementById("distribution");
distroField.value = distroAbout;
distroField.style.display = "block";
}
catch (ex) {
// Pref is unset
Components.utils.reportError(ex);
}
}
}
catch (e) {
// Pref is unset
}
// Include the build ID
let versionField = document.getElementById("version");
let version = Services.appinfo.version;
let buildID = Services.appinfo.appBuildID;
let year = buildID.slice(0, 4);
let month = buildID.slice(4, 6);
let day = buildID.slice(6, 8);
let hour = buildID.slice(8, 10);
let minute = buildID.slice(10, 12);
if (Services.prefs.getBoolPref("general.useragent.appVersionIsBuildID")) {
versionField.textContent = `${year}.${month}.${day}`;
} else {
versionField.textContent = `v` + version + ` (${year}-${month}-${day})`;
}
// Display warning if this is an "a#" (nightly or aurora) build
if (/a\d+$/.test(version)) {
document.getElementById("experimental").hidden = false;
document.getElementById("communityDesc").hidden = true;
}
// Append "(32-bit)" or "(64-bit)" build architecture to the version number:
let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
let archResource = Services.appinfo.is64Bit
? "aboutDialog.architecture.sixtyFourBit"
: "aboutDialog.architecture.thirtyTwoBit";
let arch = bundle.GetStringFromName(archResource);
versionField.textContent += ` (${arch})`;
// Get Release Notes URL from Preferences
let releaseNotesURL = Services.prefs.getCharPref("app.releaseNotesURL");
document.getElementById("releasenotes").setAttribute("href", releaseNotesURL);
if (AppConstants.MOZ_UPDATER) {
gAppUpdater = new appUpdater();
let channelLabel = document.getElementById("currentChannel");
let currentChannelText = document.getElementById("currentChannelText");
channelLabel.value = UpdateUtils.UpdateChannel;
if (/^release($|\-)/.test(channelLabel.value))
currentChannelText.hidden = true;
}
if (AppConstants.platform == "macosx") {
// it may not be sized at this point, and we need its width to calculate its position
window.sizeToContent();
window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
}
}
@@ -1,157 +0,0 @@
<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
# 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/.
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/aboutDialog.css" type="text/css"?>
<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % aboutDialogDTD SYSTEM "chrome://browser/locale/aboutDialog.dtd" >
%aboutDialogDTD;
]>
#ifdef XP_MACOSX
<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
#endif
<window xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="aboutDialog"
windowtype="Browser:About"
onload="init(event);"
#ifdef MOZ_UPDATER
onunload="onUnload(event);"
#endif
#ifdef XP_MACOSX
inwindowmenu="false"
#else
title="&aboutDialog.title;"
#endif
role="dialog"
aria-describedby="version distribution distributionId communityDesc contributeDesc trademark"
>
<script type="application/javascript" src="chrome://browser/content/aboutDialog.js"/>
#ifdef MOZ_UPDATER
<script type="application/javascript" src="chrome://browser/content/aboutDialog-appUpdater.js"/>
#endif
<vbox id="aboutDialogContainer">
<hbox id="clientBox">
<vbox id="leftBox" flex="1"/>
<vbox id="rightBox" flex="1">
<hbox align="baseline">
#expand <label id="version"></label>
#ifndef NIGHTLY_BUILD
<label id="releasenotes" class="text-link">&releaseNotes.link;</label>
#endif
</hbox>
<label id="distribution" class="text-blurb"/>
<label id="distributionId" class="text-blurb"/>
<vbox id="detailsBox">
<vbox id="updateBox">
#ifdef MOZ_UPDATER
<deck id="updateDeck" orient="vertical">
<hbox id="checkForUpdates" align="center">
<button id="checkForUpdatesButton" align="start"
label="&update.checkForUpdatesButton.label;"
accesskey="&update.checkForUpdatesButton.accesskey;"
oncommand="gAppUpdater.checkForUpdates();"/>
<spacer flex="1"/>
</hbox>
<hbox id="downloadAndInstall" align="center">
<button id="downloadAndInstallButton" align="start"
oncommand="gAppUpdater.startDownload();"/>
<!-- label and accesskey will be filled by JS -->
<spacer flex="1"/>
</hbox>
<hbox id="apply" align="center">
<button id="updateButton" align="start"
label="&update.updateButton.label2;"
accesskey="&update.updateButton.accesskey;"
oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
<spacer flex="1"/>
</hbox>
<hbox id="checkingForUpdates" align="center">
<image class="update-throbber"/><label>&update.checkingForUpdates;</label>
</hbox>
<hbox id="downloading" align="center">
<image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
</hbox>
<hbox id="applying" align="center">
<image class="update-throbber"/><label>&update.applying;</label>
</hbox>
<hbox id="downloadFailed" align="center">
<label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
</hbox>
<hbox id="adminDisabled" align="center">
<label>&update.adminDisabled;</label>
</hbox>
<hbox id="noUpdatesFound" align="center">
<label>&update.noUpdatesFound;</label>
</hbox>
<hbox id="otherInstanceHandlingUpdates" align="center">
<label>&update.otherInstanceHandlingUpdates;</label>
</hbox>
<hbox id="manualUpdate" align="center">
<label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
</hbox>
<hbox id="unsupportedSystem" align="center">
<label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label>
</hbox>
<hbox id="restarting" align="center">
<label>&update.restarting;</label>
</hbox>
</deck>
#endif
</vbox>
#ifdef MOZ_UPDATER
<description class="text-blurb" id="currentChannelText">
&channel.description.start;<label id="currentChannel"/>&channel.description.end;
</description>
#endif
<vbox id="experimental" hidden="true">
<description class="text-blurb" id="warningDesc">
&warningDesc.version;
</description>
</vbox>
#ifdef MC_PRIVATE_BUILD
<description class="text-blurb" id="communityDesc">
This is a private build of Basilisk. If you did not manually build this copy from source yourself, then please download an official version from the <label class="text-link" href="http://www.basilisk-browser.org/">Basilisk website</label>.
</description>
#else
<description class="text-blurb" id="communityDesc">
Basilisk is community software released by <label class="text-link" href="http://www.palemoon.org/">the Pale Moon team</label> and Mozilla developers. Learn <label class="text-link" useoriginprincipal="true" href="about:credits">who contributed</label> to this software.
</description>
<description class="text-blurb" id="contributeDesc">
Want to help? Please consider <label class="text-link" href="https://www.palemoon.org/donations.shtml">donating</label> or get involved with our <label class="text-link" href="https://github.com/MoonchildProductions/UXP">development</label> of the Unified XUL Platform.
</description>
#endif
</vbox>
</vbox>
</hbox>
<vbox id="bottomBox">
<hbox pack="center">
<label class="text-link bottom-link" useoriginprincipal="true" href="about:license">&bottomLinks.license;</label>
<label class="text-link bottom-link" useoriginprincipal="true" href="about:rights">&bottomLinks.rights;</label>
<label class="text-link bottom-link" href="https://www.palemoon.org/privacy.shtml">&bottomLinks.privacy;</label>
</hbox>
<description id="trademark">&trademarkInfo.part1;</description>
</vbox>
</vbox>
<keyset>
<key keycode="VK_ESCAPE" oncommand="window.close();"/>
</keyset>
#ifdef XP_MACOSX
#include browserMountPoints.inc
#endif
</window>
@@ -1,573 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html [
<!ENTITY % htmlDTD
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % netErrorDTD
SYSTEM "chrome://global/locale/netError.dtd">
%netErrorDTD;
<!ENTITY % globalDTD
SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<!-- 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/. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&loadError.label;</title>
<link rel="stylesheet" href="chrome://browser/skin/aboutNetError.css" type="text/css" media="all" />
<!-- If the location of the favicon is changed here, the FAVICON_ERRORPAGE_URL symbol in
toolkit/components/places/src/nsFaviconService.h should be updated. -->
<link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/warning-16.png"/>
<script type="application/javascript"><![CDATA[
// The following parameters are parsed from the error URL:
// e - the error code
// s - custom CSS class to allow alternate styling/favicons
// d - error description
// captive - "true" to indicate we're behind a captive portal.
// Any other value is ignored.
// Note that this file uses document.documentURI to get
// the URL (with the format from above). This is because
// document.location.href gets the current URI off the docshell,
// which is the URL displayed in the location bar, i.e.
// the URI that the user attempted to load.
let searchParams = new URLSearchParams(document.documentURI.split("?")[1]);
// Set to true on init if the error code is nssBadCert.
let gIsCertError;
function getErrorCode()
{
return searchParams.get("e");
}
function getCSSClass()
{
return searchParams.get("s");
}
function getDescription()
{
return searchParams.get("d");
}
function isCaptive() {
return searchParams.get("captive") == "true";
}
function retryThis(buttonEl)
{
// Note: The application may wish to handle switching off "offline mode"
// before this event handler runs, but using a capturing event handler.
// Session history has the URL of the page that failed
// to load, not the one of the error page. So, just call
// reload(), which will also repost POST data correctly.
try {
location.reload();
} catch (e) {
// We probably tried to reload a URI that caused an exception to
// occur; e.g. a nonexistent file.
}
buttonEl.disabled = true;
}
function doOverride(buttonEl) {
var event = new CustomEvent("AboutNetErrorOverride", {bubbles:true});
document.dispatchEvent(event);
retryThis(buttonEl);
}
function toggleDisplay(node) {
const toggle = {
"": "block",
"none": "block",
"block": "none"
};
return (node.style.display = toggle[node.style.display]);
}
function showPrefChangeContainer() {
const panel = document.getElementById("prefChangeContainer");
panel.style.display = "block";
document.getElementById("netErrorButtonContainer").style.display = "none";
document.getElementById("prefResetButton").addEventListener("click", function resetPreferences(e) {
const event = new CustomEvent("AboutNetErrorResetPreferences", {bubbles:true});
document.dispatchEvent(event);
});
addAutofocus("prefResetButton", "beforeend");
}
function setupAdvancedButton(allowOverride) {
// Get the hostname and add it to the panel
var panelId = gIsCertError ? "badCertAdvancedPanel" : "weakCryptoAdvancedPanel";
var panel = document.getElementById(panelId);
for (var span of panel.querySelectorAll("span.hostname")) {
span.textContent = document.location.hostname;
}
if (!gIsCertError) {
panel.replaceChild(document.getElementById("errorLongDesc"),
document.getElementById("advancedLongDesc"));
}
// Register click handler for the weakCryptoAdvancedPanel
document.getElementById("advancedButton")
.addEventListener("click", function togglePanelVisibility() {
toggleDisplay(panel);
if (panel.style.display == "block") {
// send event to trigger telemetry ping
var event = new CustomEvent("AboutNetErrorUIExpanded", {bubbles:true});
document.dispatchEvent(event);
}
});
if (allowOverride) {
document.getElementById("overrideWeakCryptoPanel").style.display = "flex";
var overrideLink = document.getElementById("overrideWeakCrypto");
overrideLink.addEventListener("click", () => doOverride(overrideLink), false);
}
if (!gIsCertError) {
return;
}
if (getCSSClass() == "expertBadCert") {
toggleDisplay(document.getElementById("badCertAdvancedPanel"));
}
disallowCertOverridesIfNeeded();
document.getElementById("badCertTechnicalInfo").textContent = getDescription();
}
function disallowCertOverridesIfNeeded() {
var cssClass = getCSSClass();
// Disallow overrides if this is a Strict-Transport-Security
// host and the cert is bad (STS Spec section 7.3) or if the
// certerror is in a frame (bug 633691).
if (cssClass == "badStsCert" || window != top) {
document.getElementById("exceptionDialogButton").setAttribute("hidden", "true");
}
if (cssClass == "badStsCert") {
document.getElementById("badStsCertExplanation").removeAttribute("hidden");
}
}
function initPage()
{
var err = getErrorCode();
gIsCertError = (err == "nssBadCert");
// Only worry about captive portals if this is a cert error.
let showCaptivePortalUI = isCaptive() && gIsCertError;
if (showCaptivePortalUI) {
err = "captivePortal";
}
// if it's an unknown error or there's no title or description
// defined, get the generic message
var errTitle = document.getElementById("et_" + err);
var errDesc = document.getElementById("ed_" + err);
if (!errTitle || !errDesc)
{
errTitle = document.getElementById("et_generic");
errDesc = document.getElementById("ed_generic");
}
document.querySelector(".title-text").innerHTML = errTitle.innerHTML;
var sd = document.getElementById("errorShortDescText");
if (sd) {
if (gIsCertError) {
sd.innerHTML = errDesc.innerHTML;
}
else {
sd.textContent = getDescription();
}
}
if (showCaptivePortalUI) {
initPageCaptivePortal();
return;
}
if (gIsCertError) {
initPageCertError();
return;
}
addAutofocus("errorTryAgain");
document.body.className = "neterror";
var ld = document.getElementById("errorLongDesc");
if (ld)
{
ld.innerHTML = errDesc.innerHTML;
}
if (err == "sslv3Used") {
document.body.className = "certerror";
}
if (err == "weakCryptoUsed") {
document.body.className = "certerror";
}
// remove undisplayed errors to avoid bug 39098
var errContainer = document.getElementById("errorContainer");
errContainer.parentNode.removeChild(errContainer);
var className = getCSSClass();
if (className && className != "expertBadCert") {
// Associate a CSS class with the root of the page, if one was passed in,
// to allow custom styling.
// Not "expertBadCert" though, don't want to deal with the favicon
document.documentElement.className = className;
// Also, if they specified a CSS class, they must supply their own
// favicon. In order to trigger the browser to repaint though, we
// need to remove/add the link element.
var favicon = document.getElementById("favicon");
var faviconParent = favicon.parentNode;
faviconParent.removeChild(favicon);
favicon.setAttribute("href", "chrome://global/skin/icons/" + className + "_favicon.png");
faviconParent.appendChild(favicon);
}
if (err == "remoteXUL") {
// Remove the "Try again" button for remote XUL errors given that
// it is useless.
document.getElementById("netErrorButtonContainer").style.display = "none";
}
if (err == "cspBlocked") {
// Remove the "Try again" button for CSP violations, since it's
// almost certainly useless. (Bug 553180)
document.getElementById("netErrorButtonContainer").style.display = "none";
}
window.addEventListener("AboutNetErrorOptions", function(evt) {
// Pinning errors are of type nssFailure2
if (getErrorCode() == "nssFailure2" || getErrorCode() == "weakCryptoUsed") {
const hasPrefStyleError = [
"interrupted", // This happens with subresources that are above the max tls
"SSL_ERROR_PROTOCOL_VERSION_ALERT",
"SSL_ERROR_UNSUPPORTED_VERSION",
"SSL_ERROR_NO_CYPHER_OVERLAP",
"SSL_ERROR_NO_CIPHERS_SUPPORTED"
].some((substring) => getDescription().includes(substring));
// If it looks like an error that is user config based
if (getErrorCode() == "nssFailure2" && hasPrefStyleError && options && options.changedCertPrefs) {
showPrefChangeContainer();
}
}
if (getErrorCode() == "weakCryptoUsed" || getErrorCode() == "sslv3Used") {
setupAdvancedButton(getErrorCode() == "weakCryptoUsed");
}
}.bind(this), true, true);
var event = new CustomEvent("AboutNetErrorLoad", {bubbles:true});
document.dispatchEvent(event);
if (err == "inadequateSecurityError") {
// Remove the "Try again" button for HTTP/2 inadequate security as it
// is useless.
document.getElementById("errorTryAgain").style.display = "none";
var container = document.getElementById("errorLongDesc");
for (var span of container.querySelectorAll("span.hostname")) {
span.textContent = document.location.hostname;
}
}
addDomainErrorLink();
}
function initPageCaptivePortal()
{
document.body.className = "captiveportal";
document.title = document.getElementById("captivePortalPageTitle").textContent;
document.getElementById("openPortalLoginPageButton")
.addEventListener("click", () => {
let event = new CustomEvent("AboutNetErrorOpenCaptivePortal", {bubbles:true});
document.dispatchEvent(event);
});
addAutofocus("openPortalLoginPageButton");
setupAdvancedButton(true);
addDomainErrorLink();
// When the portal is freed, an event is generated by the frame script
// that we can pick up and attempt to reload the original page.
window.addEventListener("AboutNetErrorCaptivePortalFreed", () => {
document.location.reload();
});
}
function initPageCertError() {
document.body.className = "certerror";
document.title = document.getElementById("certErrorPageTitle").textContent;
for (let host of document.querySelectorAll(".hostname")) {
host.textContent = document.location.hostname;
}
addAutofocus("returnButton");
setupAdvancedButton(true);
let event = new CustomEvent("AboutNetErrorLoad", {bubbles:true});
document.getElementById("advancedButton").dispatchEvent(event);
addDomainErrorLink();
}
/* Only do autofocus if we're the toplevel frame; otherwise we
don't want to call attention to ourselves! The key part is
that autofocus happens on insertion into the tree, so we
can remove the button, add @autofocus, and reinsert the
button.
*/
function addAutofocus(buttonId, position = "afterbegin") {
if (window.top == window) {
var button = document.getElementById(buttonId);
var parent = button.parentNode;
button.remove();
button.setAttribute("autofocus", "true");
parent.insertAdjacentElement(position, button);
}
}
/* In the case of SSL error pages about domain mismatch, see if
we can hyperlink the user to the correct site. We don't want
to do this generically since it allows MitM attacks to redirect
users to a site under attacker control, but in certain cases
it is safe (and helpful!) to do so. Bug 402210
*/
function addDomainErrorLink() {
// Rather than textContent, we need to treat description as HTML
var sdid = gIsCertError ? "badCertTechnicalInfo" : "errorShortDescText";
var sd = document.getElementById(sdid);
if (sd) {
var desc = getDescription();
// sanitize description text - see bug 441169
// First, find the index of the <a> tag we care about, being
// careful not to use an over-greedy regex.
var re = /<a id="cert_domain_link" title="([^"]+)">/;
var result = re.exec(desc);
if (!result)
return;
// Remove sd's existing children
sd.textContent = "";
// Everything up to the link should be text content.
sd.appendChild(document.createTextNode(desc.slice(0, result.index)));
// Now create the link itself.
var anchorEl = document.createElement("a");
anchorEl.setAttribute("id", "cert_domain_link");
anchorEl.setAttribute("title", result[1]);
anchorEl.appendChild(document.createTextNode(result[1]));
sd.appendChild(anchorEl);
// Finally, append text for anything after the closing </a>.
sd.appendChild(document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length)));
}
// Initialize the cert domain link.
var link = document.getElementById("cert_domain_link");
if (!link)
return;
var okHost = link.getAttribute("title");
var thisHost = document.location.hostname;
var proto = document.location.protocol;
// If okHost is a wildcard domain ("*.example.com") let's
// use "www" instead. "*.example.com" isn't going to
// get anyone anywhere useful. bug 432491
okHost = okHost.replace(/^\*\./, "www.");
/* case #1:
* example.com uses an invalid security certificate.
*
* The certificate is only valid for www.example.com
*
* Make sure to include the "." ahead of thisHost so that
* a MitM attack on paypal.com doesn't hyperlink to "notpaypal.com"
*
* We'd normally just use a RegExp here except that we lack a
* library function to escape them properly (bug 248062), and
* domain names are famous for having '.' characters in them,
* which would allow spurious and possibly hostile matches.
*/
if (okHost.endsWith("." + thisHost))
link.href = proto + okHost;
/* case #2:
* browser.garage.maemo.org uses an invalid security certificate.
*
* The certificate is only valid for garage.maemo.org
*/
if (thisHost.endsWith("." + okHost))
link.href = proto + okHost;
// If we set a link, meaning there's something helpful for
// the user here, expand the section by default
if (link.href && getCSSClass() != "expertBadCert") {
var panelId = gIsCertError ? "badCertAdvancedPanel" : "weakCryptoAdvancedPanel"
toggleDisplay(document.getElementById(panelId));
}
}
]]></script>
</head>
<body dir="&locale.dir;">
<!-- Contains an alternate page title set on page init for cert errors. -->
<div id="certErrorPageTitle" style="display: none;">&certerror.pagetitle1;</div>
<div id="captivePortalPageTitle" style="display: none;">&captivePortal.title;</div>
<!-- ERROR ITEM CONTAINER (removed during loading to avoid bug 39098) -->
<div id="errorContainer">
<div id="errorTitlesContainer">
<h1 id="et_generic">&generic.title;</h1>
<h1 id="et_captivePortal">&captivePortal.title;</h1>
<h1 id="et_dnsNotFound">&dnsNotFound.title;</h1>
<h1 id="et_fileNotFound">&fileNotFound.title;</h1>
<h1 id="et_fileAccessDenied">&fileAccessDenied.title;</h1>
<h1 id="et_malformedURI">&malformedURI.title;</h1>
<h1 id="et_unknownProtocolFound">&unknownProtocolFound.title;</h1>
<h1 id="et_connectionFailure">&connectionFailure.title;</h1>
<h1 id="et_netTimeout">&netTimeout.title;</h1>
<h1 id="et_redirectLoop">&redirectLoop.title;</h1>
<h1 id="et_unknownSocketType">&unknownSocketType.title;</h1>
<h1 id="et_netReset">&netReset.title;</h1>
<h1 id="et_notCached">&notCached.title;</h1>
<h1 id="et_netOffline">&netOffline.title;</h1>
<h1 id="et_netInterrupt">&netInterrupt.title;</h1>
<h1 id="et_deniedPortAccess">&deniedPortAccess.title;</h1>
<h1 id="et_proxyResolveFailure">&proxyResolveFailure.title;</h1>
<h1 id="et_proxyConnectFailure">&proxyConnectFailure.title;</h1>
<h1 id="et_contentEncodingError">&contentEncodingError.title;</h1>
<h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
<h1 id="et_nssFailure2">&nssFailure2.title;</h1>
<h1 id="et_nssBadCert">&certerror.longpagetitle1;</h1>
<h1 id="et_cspBlocked">&cspBlocked.title;</h1>
<h1 id="et_remoteXUL">&remoteXUL.title;</h1>
<h1 id="et_corruptedContentErrorv2">&corruptedContentErrorv2.title;</h1>
<h1 id="et_sslv3Used">&sslv3Used.title;</h1>
<h1 id="et_weakCryptoUsed">&weakCryptoUsed.title;</h1>
<h1 id="et_inadequateSecurityError">&inadequateSecurityError.title;</h1>
</div>
<div id="errorDescriptionsContainer">
<div id="ed_generic">&generic.longDesc;</div>
<div id="ed_captivePortal">&captivePortal.longDesc;</div>
<div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
<div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
<div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
<div id="ed_malformedURI">&malformedURI.longDesc;</div>
<div id="ed_unknownProtocolFound">&unknownProtocolFound.longDesc;</div>
<div id="ed_connectionFailure">&connectionFailure.longDesc;</div>
<div id="ed_netTimeout">&netTimeout.longDesc;</div>
<div id="ed_redirectLoop">&redirectLoop.longDesc;</div>
<div id="ed_unknownSocketType">&unknownSocketType.longDesc;</div>
<div id="ed_netReset">&netReset.longDesc;</div>
<div id="ed_notCached">&notCached.longDesc;</div>
<div id="ed_netOffline">&netOffline.longDesc2;</div>
<div id="ed_netInterrupt">&netInterrupt.longDesc;</div>
<div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>
<div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc;</div>
<div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
<div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
<div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
<div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
<div id="ed_nssBadCert">&certerror.introPara;</div>
<div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
<div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
<div id="ed_corruptedContentErrorv2">&corruptedContentErrorv2.longDesc;</div>
<div id="ed_sslv3Used">&sslv3Used.longDesc2;</div>
<div id="ed_weakCryptoUsed">&weakCryptoUsed.longDesc2;</div>
<div id="ed_inadequateSecurityError">&inadequateSecurityError.longDesc;</div>
</div>
</div>
<!-- PAGE CONTAINER (for styling purposes only) -->
<div id="errorPageContainer" class="container">
<!-- Error Title -->
<div class="title">
<h1 class="title-text"/>
</div>
<!-- LONG CONTENT (the section most likely to require scrolling) -->
<div id="errorLongContent">
<!-- Short Description -->
<div id="errorShortDesc">
<p id="errorShortDescText" />
</div>
<p id="badStsCertExplanation" hidden="true">&certerror.whatShouldIDo.badStsCertExplanation;</p>
<div id="wrongSystemTimePanel" style="display: none;">
&certerror.wrongSystemTime;
</div>
<!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
<div id="errorLongDesc" />
<div id="prefChangeContainer" class="button-container">
<p>&prefReset.longDesc;</p>
<button id="prefResetButton" class="primary" autocomplete="off">&prefReset.label;</button>
</div>
<div id="certErrorAndCaptivePortalButtonContainer" class="button-container">
<button id="returnButton" class="primary" autocomplete="off">&returnToPreviousPage.label;</button>
<button id="openPortalLoginPageButton" class="primary" autocomplete="off">&openPortalLoginPage.label;</button>
<div class="button-spacer"></div>
<button id="advancedButton" autocomplete="off">&advanced.label;</button>
</div>
</div>
<div id="netErrorButtonContainer" class="button-container">
<button id="errorTryAgain" class="primary" autocomplete="off" onclick="retryThis(this);">&retry.label;</button>
</div>
<div id="advancedPanelContainer">
<div id="weakCryptoAdvancedPanel" class="advanced-panel">
<div id="weakCryptoAdvancedDescription">
<p>&weakCryptoAdvanced.longDesc;</p>
</div>
<div id="advancedLongDesc" />
<div id="overrideWeakCryptoPanel">
<a id="overrideWeakCrypto" href="#">&weakCryptoAdvanced.override;</a>
</div>
</div>
<div id="badCertAdvancedPanel" class="advanced-panel">
<p id="badCertTechnicalInfo"/>
<button id="exceptionDialogButton">&securityOverride.exceptionButtonLabel;</button>
</div>
</div>
</div>
<!--
- Note: It is important to run the script this way, instead of using
- an onload handler. This is because error pages are loaded as
- LOAD_BACKGROUND, which means that onload handlers will not be executed.
-->
<script type="application/javascript">
initPage();
</script>
</body>
</html>
@@ -1,11 +0,0 @@
/* 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/. */
html:not(.crashDumpSubmitted) #reportSent,
html:not(.crashDumpAvailable) #reportBox,
.container[multiple="true"] > .offers > #offerHelpMessageSingle,
.container[multiple="false"] > .offers > #offerHelpMessageMultiple,
.container[multiple="false"] > .button-container > #restoreAll {
display: none;
}
@@ -1,309 +0,0 @@
/* 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/. */
var AboutTabCrashed = {
/**
* This can be set to true once this page receives a message from the
* parent saying whether or not a crash report is available.
*/
hasReport: false,
/**
* The messages that we might receive from the parent.
*/
MESSAGES: [
"SetCrashReportAvailable",
"CrashReportSent",
"UpdateCount",
],
/**
* Items for which we will listen for click events.
*/
CLICK_TARGETS: [
"closeTab",
"restoreTab",
"restoreAll",
"sendReport",
],
/**
* Returns information about this crashed tab.
*
* @return (Object) An object with the following properties:
* title (String):
* The title of the page that crashed.
* URL (String):
* The URL of the page that crashed.
*/
get pageData() {
delete this.pageData;
let URL = document.documentURI;
let queryString = URL.replace(/^about:tabcrashed?e=tabcrashed/, "");
let titleMatch = queryString.match(/d=([^&]*)/);
let URLMatch = queryString.match(/u=([^&]*)/);
return this.pageData = {
title: titleMatch && titleMatch[1] ? decodeURIComponent(titleMatch[1]) : "",
URL: URLMatch && URLMatch[1] ? decodeURIComponent(URLMatch[1]) : "",
};
},
init() {
this.MESSAGES.forEach((msg) => addMessageListener(msg, this.receiveMessage.bind(this)));
addEventListener("DOMContentLoaded", this);
document.title = this.pageData.title;
},
receiveMessage(message) {
switch (message.name) {
case "UpdateCount": {
this.setMultiple(message.data.count > 1);
break;
}
case "SetCrashReportAvailable": {
this.onSetCrashReportAvailable(message);
break;
}
case "CrashReportSent": {
this.onCrashReportSent();
break;
}
}
},
handleEvent(event) {
switch (event.type) {
case "DOMContentLoaded": {
this.onDOMContentLoaded();
break;
}
case "click": {
this.onClick(event);
break;
}
case "input": {
this.onInput(event);
break;
}
}
},
onDOMContentLoaded() {
this.CLICK_TARGETS.forEach((targetID) => {
let el = document.getElementById(targetID);
el.addEventListener("click", this);
});
// For setting "emailMe" checkbox automatically on email value change.
document.getElementById("email").addEventListener("input", this);
// Error pages are loaded as LOAD_BACKGROUND, so they don't get load events.
let event = new CustomEvent("AboutTabCrashedLoad", {bubbles:true});
document.dispatchEvent(event);
sendAsyncMessage("Load");
},
onClick(event) {
switch (event.target.id) {
case "closeTab": {
this.sendMessage("closeTab");
break;
}
case "restoreTab": {
this.sendMessage("restoreTab");
break;
}
case "restoreAll": {
this.sendMessage("restoreAll");
break;
}
case "sendReport": {
this.showCrashReportUI(event.target.checked);
break;
}
}
},
onInput(event) {
switch (event.target.id) {
case "email": {
document.getElementById("emailMe").checked = !!event.target.value;
break;
}
}
},
/**
* After this page tells the parent that it has loaded, the parent
* will respond with whether or not a crash report is available. This
* method handles that message.
*
* @param message
* The message from the parent, which should contain a data
* Object property with the following properties:
*
* hasReport (bool):
* Whether or not there is a crash report.
*
* sendReport (bool):
* Whether or not the the user prefers to send the report
* by default.
*
* includeURL (bool):
* Whether or not the user prefers to send the URL of
* the tab that crashed.
*
* emailMe (bool):
* Whether or not to send the email address of the user
* in the report.
*
* email (String):
* The email address of the user (empty if emailMe is false).
*
* requestAutoSubmit (bool):
* Whether or not we should ask the user to automatically
* submit backlogged crash reports.
*
*/
onSetCrashReportAvailable(message) {
let data = message.data;
if (data.hasReport) {
this.hasReport = true;
document.documentElement.classList.add("crashDumpAvailable");
document.getElementById("sendReport").checked = data.sendReport;
document.getElementById("includeURL").checked = data.includeURL;
if (data.requestEmail) {
document.getElementById("requestEmail").hidden = false;
document.getElementById("emailMe").checked = data.emailMe;
if (data.emailMe) {
document.getElementById("email").value = data.email;
}
}
this.showCrashReportUI(data.sendReport);
} else {
this.showCrashReportUI(false);
}
if (data.requestAutoSubmit) {
document.getElementById("requestAutoSubmit").hidden = false;
}
let event = new CustomEvent("AboutTabCrashedReady", {bubbles:true});
document.dispatchEvent(event);
},
/**
* Handler for when the parent reports that the crash report associated
* with this about:tabcrashed page has been sent.
*/
onCrashReportSent() {
document.documentElement.classList.remove("crashDumpAvailable");
document.documentElement.classList.add("crashDumpSubmitted");
},
/**
* Toggles the display of the crash report form.
*
* @param shouldShow (bool)
* True if the crash report form should be shown
*/
showCrashReportUI(shouldShow) {
let options = document.getElementById("options");
options.hidden = !shouldShow;
},
/**
* Toggles whether or not the page is one of several visible pages
* showing the crash reporter. This controls some of the language
* on the page, along with what the "primary" button is.
*
* @param hasMultiple (bool)
* True if there are multiple crash report pages being shown.
*/
setMultiple(hasMultiple) {
let main = document.getElementById("main");
main.setAttribute("multiple", hasMultiple);
let restoreTab = document.getElementById("restoreTab");
// The "Restore All" button has the "primary" class by default, so
// we only need to modify the "Restore Tab" button.
if (hasMultiple) {
restoreTab.classList.remove("primary");
} else {
restoreTab.classList.add("primary");
}
},
/**
* Sends a message to the parent in response to the user choosing
* one of the actions available on the page. This might also send up
* crash report information if the user has chosen to submit a crash
* report.
*
* @param messageName (String)
* The message to send to the parent
*/
sendMessage(messageName) {
let comments = "";
let email = "";
let URL = "";
let sendReport = false;
let emailMe = false;
let includeURL = false;
let autoSubmit = false;
if (this.hasReport) {
sendReport = document.getElementById("sendReport").checked;
if (sendReport) {
comments = document.getElementById("comments").value.trim();
includeURL = document.getElementById("includeURL").checked;
if (includeURL) {
URL = this.pageData.URL.trim();
}
if (!document.getElementById("requestEmail").hidden) {
emailMe = document.getElementById("emailMe").checked;
if (emailMe) {
email = document.getElementById("email").value.trim();
}
}
}
}
let requestAutoSubmit = document.getElementById("requestAutoSubmit");
if (requestAutoSubmit.hidden) {
// The checkbox is hidden if the user has already opted in to sending
// backlogged crash reports.
autoSubmit = true;
} else {
autoSubmit = document.getElementById("autoSubmit").checked;
}
sendAsyncMessage(messageName, {
sendReport,
comments,
email,
emailMe,
includeURL,
URL,
autoSubmit,
hasReport: this.hasReport,
});
},
};
AboutTabCrashed.init();
@@ -1,97 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % globalDTD
SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % tabCrashedDTD
SYSTEM "chrome://browser/locale/aboutTabCrashed.dtd">
%tabCrashedDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" media="all"
href="chrome://global/skin/in-content/info-pages.css"/>
<link rel="stylesheet" type="text/css" media="all"
href="chrome://browser/content/aboutTabCrashed.css"/>
<link rel="stylesheet" type="text/css" media="all"
href="chrome://browser/skin/aboutTabCrashed.css"/>
</head>
<body dir="&locale.dir;">
<div id="main" class="container" multiple="false">
<div class="title">
<h1 class="title-text">&tabCrashed.header2;</h1>
</div>
<div class="offers">
<h2>&tabCrashed.offerHelp;</h2>
<p id="offerHelpMessageSingle">&tabCrashed.single.offerHelpMessage;</p>
<p id="offerHelpMessageMultiple">&tabCrashed.multiple.offerHelpMessage;</p>
</div>
<div id="reportBox">
<h2>&tabCrashed.requestHelp;</h2>
<p>&tabCrashed.requestHelpMessage;</p>
<h2>&tabCrashed.requestReport;</h2>
<div class="checkbox-with-label">
<input type="checkbox" id="sendReport"/>
<label for="sendReport">&tabCrashed.sendReport2;</label>
</div>
<ul id="options">
<li>
<textarea id="comments" placeholder="&tabCrashed.commentPlaceholder2;" rows="4"></textarea>
</li>
<li class="checkbox-with-label">
<input type="checkbox" id="includeURL"/>
<label for="includeURL">&tabCrashed.includeURL2;</label>
</li>
<li id="requestEmail" hidden="true">
<div class="checkbox-with-label">
<input type="checkbox" id="emailMe"/>
<label for="emailMe">&tabCrashed.emailMe;</label>
</div>
<input type="text" id="email" placeholder="&tabCrashed.emailPlaceholder;"/>
</li>
</ul>
<div id="requestAutoSubmit" hidden="true">
<h2>&tabCrashed.requestAutoSubmit2;</h2>
<div class="checkbox-with-label">
<input type="checkbox" id="autoSubmit"/>
<label for="autoSubmit">&tabCrashed.autoSubmit;</label>
</div>
</div>
</div>
<p id="reportSent">&tabCrashed.reportSent;</p>
<div class="button-container">
<button id="closeTab">
&tabCrashed.closeTab;</button>
<button id="restoreTab" class="primary">
&tabCrashed.restoreTab;</button>
<button id="restoreAll" autofocus="true" class="primary">
&tabCrashed.restoreAll;</button>
</div>
</div>
</body>
<script type="text/javascript;version=1.8" src="chrome://browser/content/aboutTabCrashed.js"/>
</html>
@@ -1,15 +0,0 @@
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
#remote-report {
width: 100%;
height: 100%;
border: 0;
display: flex;
}
@@ -1,180 +0,0 @@
/* 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/. */
"use strict";
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const prefs = new Preferences("datareporting.healthreport.");
const PREF_UNIFIED = "toolkit.telemetry.unified";
const PREF_REPORTING_URL = "datareporting.healthreport.about.reportUrl";
var healthReportWrapper = {
init: function () {
let iframe = document.getElementById("remote-report");
iframe.addEventListener("load", healthReportWrapper.initRemotePage, false);
iframe.src = this._getReportURI().spec;
prefs.observe("uploadEnabled", this.updatePrefState, healthReportWrapper);
},
uninit: function () {
prefs.ignore("uploadEnabled", this.updatePrefState, healthReportWrapper);
},
_getReportURI: function () {
let url = Services.urlFormatter.formatURLPref(PREF_REPORTING_URL);
return Services.io.newURI(url, null, null);
},
setDataSubmission: function (enabled) {
MozSelfSupport.healthReportDataSubmissionEnabled = enabled;
this.updatePrefState();
},
updatePrefState: function () {
try {
let prefs = {
enabled: MozSelfSupport.healthReportDataSubmissionEnabled,
};
healthReportWrapper.injectData("prefs", prefs);
}
catch (ex) {
healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PREFS_FAILED);
}
},
sendTelemetryPingList: function () {
console.log("AboutHealthReport: Collecting Telemetry ping list.");
MozSelfSupport.getTelemetryPingList().then((list) => {
console.log("AboutHealthReport: Sending Telemetry ping list.");
this.injectData("telemetry-ping-list", list);
}).catch((ex) => {
console.log("AboutHealthReport: Collecting ping list failed: " + ex);
});
},
sendTelemetryPingData: function (pingId) {
console.log("AboutHealthReport: Collecting Telemetry ping data.");
MozSelfSupport.getTelemetryPing(pingId).then((ping) => {
console.log("AboutHealthReport: Sending Telemetry ping data.");
this.injectData("telemetry-ping-data", {
id: pingId,
pingData: ping,
});
}).catch((ex) => {
console.log("AboutHealthReport: Loading ping data failed: " + ex);
this.injectData("telemetry-ping-data", {
id: pingId,
error: "error-generic",
});
});
},
sendCurrentEnvironment: function () {
console.log("AboutHealthReport: Sending Telemetry environment data.");
MozSelfSupport.getCurrentTelemetryEnvironment().then((environment) => {
this.injectData("telemetry-current-environment-data", environment);
}).catch((ex) => {
console.log("AboutHealthReport: Collecting current environment data failed: " + ex);
});
},
sendCurrentPingData: function () {
console.log("AboutHealthReport: Sending current Telemetry ping data.");
MozSelfSupport.getCurrentTelemetrySubsessionPing().then((ping) => {
this.injectData("telemetry-current-ping-data", ping);
}).catch((ex) => {
console.log("AboutHealthReport: Collecting current ping data failed: " + ex);
});
},
injectData: function (type, content) {
let report = this._getReportURI();
// file URIs can't be used for targetOrigin, so we use "*" for this special case
// in all other cases, pass in the URL to the report so we properly restrict the message dispatch
let reportUrl = report.scheme == "file" ? "*" : report.spec;
let data = {
type: type,
content: content
}
let iframe = document.getElementById("remote-report");
iframe.contentWindow.postMessage(data, reportUrl);
},
handleRemoteCommand: function (evt) {
// Do an origin check to harden against the frame content being loaded from unexpected locations.
let allowedPrincipal = Services.scriptSecurityManager.getCodebasePrincipal(this._getReportURI());
let targetPrincipal = evt.target.nodePrincipal;
if (!allowedPrincipal.equals(targetPrincipal)) {
Cu.reportError(`Origin check failed for message "${evt.detail.command}": ` +
`target origin is "${targetPrincipal.origin}", expected "${allowedPrincipal.origin}"`);
return;
}
switch (evt.detail.command) {
case "DisableDataSubmission":
this.setDataSubmission(false);
break;
case "EnableDataSubmission":
this.setDataSubmission(true);
break;
case "RequestCurrentPrefs":
this.updatePrefState();
break;
case "RequestTelemetryPingList":
this.sendTelemetryPingList();
break;
case "RequestTelemetryPingData":
this.sendTelemetryPingData(evt.detail.id);
break;
case "RequestCurrentEnvironment":
this.sendCurrentEnvironment();
break;
case "RequestCurrentPingData":
this.sendCurrentPingData();
break;
default:
Cu.reportError("Unexpected remote command received: " + evt.detail.command + ". Ignoring command.");
break;
}
},
initRemotePage: function () {
let iframe = document.getElementById("remote-report").contentDocument;
iframe.addEventListener("RemoteHealthReportCommand",
function onCommand(e) { healthReportWrapper.handleRemoteCommand(e); },
false);
healthReportWrapper.updatePrefState();
},
// error handling
ERROR_INIT_FAILED: 1,
ERROR_PAYLOAD_FAILED: 2,
ERROR_PREFS_FAILED: 3,
reportFailure: function (error) {
let details = {
errorType: error,
}
healthReportWrapper.injectData("error", details);
},
handleInitFailure: function () {
healthReportWrapper.reportFailure(healthReportWrapper.ERROR_INIT_FAILED);
},
handlePayloadFailure: function () {
healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PAYLOAD_FAILED);
},
}
window.addEventListener("load", function () { healthReportWrapper.init(); });
window.addEventListener("unload", function () { healthReportWrapper.uninit(); });
@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!ENTITY % securityPrefsDTD SYSTEM "chrome://browser/locale/preferences/security.dtd">
%securityPrefsDTD;
<!ENTITY % aboutHealthReportDTD SYSTEM "chrome://browser/locale/aboutHealthReport.dtd">
%aboutHealthReportDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&abouthealth.pagetitle;</title>
<link rel="icon" type="image/png" id="favicon"
href="chrome://branding/content/icon32.png"/>
<link rel="stylesheet"
href="chrome://browser/content/abouthealthreport/abouthealth.css"
type="text/css" />
<script type="text/javascript;version=1.8"
src="chrome://browser/content/abouthealthreport/abouthealth.js" />
</head>
<body>
<iframe id="remote-report"/>
</body>
</html>
@@ -1,401 +0,0 @@
%if 0
/* 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/. */
%endif
html {
font: message-box;
font-size: 100%;
background-color: hsl(0,0%,95%);
color: #000;
height: 100%;
}
body {
margin: 0;
display: -moz-box;
-moz-box-orient: vertical;
width: 100%;
height: 100%;
}
input,
button {
font-size: inherit;
font-family: inherit;
}
a {
color: -moz-nativehyperlinktext;
text-decoration: none;
}
.spacer {
-moz-box-flex: 1;
}
#topSection {
text-align: center;
}
#brandLogo {
height: 192px;
width: 192px;
margin: 22px auto 31px;
background-image: url("chrome://branding/content/about-logo.png");
background-size: 192px auto;
background-position: center center;
background-repeat: no-repeat;
}
#searchIconAndTextContainer {
width: 470px;
}
#searchIconAndTextContainer {
display: -moz-box;
height: 36px;
position: relative;
}
#searchIcon {
border: 1px transparent;
padding: 0;
margin: 0;
width: 36px;
height: 36px;
background: url("chrome://browser/skin/search-indicator-magnifying-glass.svg") center center no-repeat;
position: absolute;
}
#searchText {
margin-left: 0;
-moz-box-flex: 1;
padding-top: 6px;
padding-bottom: 6px;
padding-inline-start: 34px;
padding-inline-end: 8px;
background: hsla(0,0%,100%,.9) padding-box;
border: 1px solid;
border-radius: 2px 0 0 2px;
border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
box-shadow: 0 1px 0 hsla(210,65%,9%,.02) inset,
0 0 2px hsla(210,65%,9%,.1) inset,
0 1px 0 hsla(0,0%,100%,.2);
color: inherit;
unicode-bidi: plaintext;
}
#searchText:dir(rtl) {
border-radius: 0 2px 2px 0;
}
#searchText[aria-expanded="true"] {
border-radius: 2px 0 0 0;
}
#searchText[aria-expanded="true"]:dir(rtl) {
border-radius: 0 2px 0 0;
}
#searchText[keepfocus],
#searchText:focus,
#searchText[autofocus] {
border-color: hsla(206,100%,60%,.6) hsla(206,76%,52%,.6) hsla(204,100%,40%,.6);
}
#searchSubmit {
margin-inline-start: -1px;
color: transparent;
background: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go") center center no-repeat, linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box;
padding: 0;
border: 1px solid;
border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
border-radius: 0 2px 2px 0;
border-inline-start: 1px solid transparent;
box-shadow: 0 0 2px hsla(0,0%,100%,.5) inset,
0 1px 0 hsla(0,0%,100%,.2);
cursor: pointer;
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
width: 50px;
}
#searchSubmit:dir(rtl) {
border-radius: 2px 0 0 2px;
background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-rtl"), linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1));
}
#searchText:focus + #searchSubmit,
#searchText[keepfocus] + #searchSubmit,
#searchText + #searchSubmit:hover,
#searchText[autofocus] + #searchSubmit {
border-color: #59b5fc #45a3e7 #3294d5;
}
#searchText:focus + #searchSubmit,
#searchText[keepfocus] + #searchSubmit,
#searchText[autofocus] + #searchSubmit {
background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-inverted"), linear-gradient(#4cb1ff, #1793e5);
box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset,
0 0 0 1px hsla(0,0%,100%,.1) inset,
0 1px 0 hsla(210,54%,20%,.03);
}
#searchText:focus + #searchSubmit:dir(rtl),
#searchText[keepfocus] + #searchSubmit:dir(rtl),
#searchText[autofocus] + #searchSubmit:dir(rtl) {
background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-rtl-inverted"), linear-gradient(#4cb1ff, #1793e5);
}
#searchText + #searchSubmit:hover {
background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-inverted"), linear-gradient(#66bdff, #0d9eff);
box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset,
0 0 0 1px hsla(0,0%,100%,.1) inset,
0 1px 0 hsla(210,54%,20%,.03),
0 0 4px hsla(206,100%,20%,.2);
}
#searchText + #searchSubmit:dir(rtl):hover {
background-image: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go-rtl-inverted"), linear-gradient(#66bdff, #0d9eff);
}
#searchText + #searchSubmit:hover:active {
box-shadow: 0 1px 1px hsla(211,79%,6%,.1) inset,
0 0 1px hsla(211,79%,6%,.2) inset;
transition-duration: 0ms;
}
#launcher {
display: -moz-box;
-moz-box-align: center;
-moz-box-pack: center;
width: 100%;
background-color: hsla(0,0%,0%,.03);
border-top: 1px solid hsla(0,0%,0%,.03);
box-shadow: 0 1px 2px hsla(0,0%,0%,.02) inset,
0 -1px 0 hsla(0,0%,100%,.25);
}
#launcher:not([session]),
body[narrow] #launcher[session] {
display: block; /* display separator and restore button on separate lines */
text-align: center;
white-space: nowrap; /* prevent navigational buttons from wrapping */
}
.launchButton {
display: -moz-box;
-moz-box-orient: vertical;
margin: 16px 1px;
padding: 14px 6px;
min-width: 88px;
max-width: 176px;
max-height: 85px;
vertical-align: top;
white-space: normal;
background: transparent padding-box;
border: 1px solid transparent;
border-radius: 2px;
color: #525c66;
font-size: 75%;
cursor: pointer;
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
}
body[narrow] #launcher[session] > .launchButton {
margin: 4px 1px;
}
.launchButton:hover {
background-color: hsla(211,79%,6%,.03);
border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
}
.launchButton:hover:active {
background-image: linear-gradient(hsla(211,79%,6%,.02), hsla(211,79%,6%,.05));
border-color: hsla(210,54%,20%,.2) hsla(210,54%,20%,.23) hsla(210,54%,20%,.25);
box-shadow: 0 1px 1px hsla(211,79%,6%,.05) inset,
0 0 1px hsla(211,79%,6%,.1) inset;
transition-duration: 0ms;
}
.launchButton[hidden],
#launcher:not([session]) > #restorePreviousSessionSeparator,
#launcher:not([session]) > #restorePreviousSession {
display: none;
}
#restorePreviousSessionSeparator {
width: 3px;
height: 116px;
margin: 0 10px;
background-image: linear-gradient(hsla(0,0%,100%,0), hsla(0,0%,100%,.35), hsla(0,0%,100%,0)),
linear-gradient(hsla(211,79%,6%,0), hsla(211,79%,6%,.2), hsla(211,79%,6%,0)),
linear-gradient(hsla(0,0%,100%,0), hsla(0,0%,100%,.35), hsla(0,0%,100%,0));
background-position: left top, center, right bottom;
background-size: 1px auto;
background-repeat: no-repeat;
}
body[narrow] #restorePreviousSessionSeparator {
margin: 0 auto;
width: 512px;
height: 3px;
background-image: linear-gradient(to right, hsla(0,0%,100%,0), hsla(0,0%,100%,.35), hsla(0,0%,100%,0)),
linear-gradient(to right, hsla(211,79%,6%,0), hsla(211,79%,6%,.2), hsla(211,79%,6%,0)),
linear-gradient(to right, hsla(0,0%,100%,0), hsla(0,0%,100%,.35), hsla(0,0%,100%,0));
background-size: auto 1px;
}
#restorePreviousSession {
max-width: none;
font-size: 90%;
}
body[narrow] #restorePreviousSession {
font-size: 80%;
}
.launchButton::before {
display: block;
width: 32px;
height: 32px;
margin: 0 auto 6px;
line-height: 0; /* remove extra vertical space due to non-zero font-size */
}
#downloads::before {
content: url("chrome://browser/content/abouthome/downloads.png");
}
#bookmarks::before {
content: url("chrome://browser/content/abouthome/bookmarks.png");
}
#history::before {
content: url("chrome://browser/content/abouthome/history.png");
}
#addons::before {
content: url("chrome://browser/content/abouthome/addons.png");
}
%ifdef MOZ_SERVICES_SYNC
#sync::before {
content: url("chrome://browser/content/abouthome/sync.png");
}
%endif
#settings::before {
content: url("chrome://browser/content/abouthome/settings.png");
}
#restorePreviousSession::before {
content: url("chrome://browser/content/abouthome/restore-large.png");
height: 48px;
width: 48px;
display: inline-block; /* display on same line as text label */
vertical-align: middle;
margin-bottom: 0;
margin-inline-end: 8px;
}
#restorePreviousSession:dir(rtl)::before {
transform: scaleX(-1);
}
body[narrow] #restorePreviousSession::before {
content: url("chrome://browser/content/abouthome/restore.png");
height: 32px;
width: 32px;
}
#aboutMozilla {
display: block;
position: relative; /* pin wordmark to edge of document, not of viewport */
-moz-box-ordinal-group: 0;
opacity: .5;
transition: opacity 150ms;
}
#aboutMozilla:hover {
opacity: 1;
}
#aboutMozilla::before {
content: url("chrome://browser/content/abouthome/mozilla.png");
display: block;
position: absolute;
top: 12px;
right: 12px;
width: 69px;
height: 19px;
}
/* [HiDPI]
* At resolutions above 1dppx, prefer downscaling the 2x Retina graphics
* rather than upscaling the original-size ones (bug 818940).
*/
@media not all and (max-resolution: 1dppx) {
#brandLogo {
background-image: url("chrome://branding/content/about-logo@2x.png");
}
.launchButton::before,
#aboutMozilla::before {
transform: scale(.5);
transform-origin: 0 0;
}
.launchButton:dir(rtl)::before,
#aboutMozilla:dir(rtl)::before {
transform: scale(.5) translateX(32px);
}
#downloads::before {
content: url("chrome://browser/content/abouthome/downloads@2x.png");
}
#bookmarks::before {
content: url("chrome://browser/content/abouthome/bookmarks@2x.png");
}
#history::before {
content: url("chrome://browser/content/abouthome/history@2x.png");
}
#addons::before {
content: url("chrome://browser/content/abouthome/addons@2x.png");
}
%ifdef MOZ_SERVICES_SYNC
#sync::before {
content: url("chrome://browser/content/abouthome/sync@2x.png");
}
%endif
#settings::before {
content: url("chrome://browser/content/abouthome/settings@2x.png");
}
#restorePreviousSession::before {
content: url("chrome://browser/content/abouthome/restore-large@2x.png");
}
body[narrow] #restorePreviousSession::before {
content: url("chrome://browser/content/abouthome/restore@2x.png");
}
#restorePreviousSession:dir(rtl)::before {
transform: scale(-0.5, 0.5) translateX(24px);
transform-origin: top center;
}
#aboutMozilla::before {
content: url("chrome://browser/content/abouthome/mozilla@2x.png");
}
}
@@ -1,118 +0,0 @@
/* 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/. */
"use strict";
/* import-globals-from ../contentSearchUI.js */
// IndexedDB storage constants.
const DATABASE_NAME = "abouthome";
const DATABASE_VERSION = 1;
const DATABASE_STORAGE = "persistent";
var searchText;
// This global tracks if the page has been set up before, to prevent double inits
var gInitialized = false;
var gObserver = new MutationObserver(function (mutations) {
for (let mutation of mutations) {
// The addition of the restore session button changes our width:
if (mutation.attributeName == "session") {
fitToWidth();
}
}
});
window.addEventListener("pageshow", function () {
// Delay search engine setup, cause browser.js::BrowserOnAboutPageLoad runs
// later and may use asynchronous getters.
window.gObserver.observe(document.documentElement, { attributes: true });
window.gObserver.observe(document.getElementById("launcher"), { attributes: true });
fitToWidth();
setupSearch();
window.addEventListener("resize", fitToWidth);
// Ask chrome to update snippets.
var event = new CustomEvent("AboutHomeLoad", {bubbles:true});
document.dispatchEvent(event);
});
window.addEventListener("pagehide", function() {
window.gObserver.disconnect();
window.removeEventListener("resize", fitToWidth);
});
window.addEventListener("keypress", ev => {
if (ev.defaultPrevented) {
return;
}
// don't focus the search-box on keypress if something other than the
// body or document element has focus - don't want to steal input from other elements
// Make an exception for <a> and <button> elements (and input[type=button|submit])
// which don't usefully take keypresses anyway.
// (except space, which is handled below)
if (document.activeElement && document.activeElement != document.body &&
document.activeElement != document.documentElement &&
!["a", "button"].includes(document.activeElement.localName) &&
!document.activeElement.matches("input:-moz-any([type=button],[type=submit])")) {
return;
}
let modifiers = ev.ctrlKey + ev.altKey + ev.metaKey;
// ignore Ctrl/Cmd/Alt, but not Shift
// also ignore Tab, Insert, PageUp, etc., and Space
if (modifiers != 0 || ev.charCode == 0 || ev.charCode == 32)
return;
searchText.focus();
// need to send the first keypress outside the search-box manually to it
searchText.value += ev.key;
});
function onSearchSubmit(aEvent)
{
gContentSearchController.search(aEvent);
}
var gContentSearchController;
function setupSearch()
{
// Set submit button label for when CSS background are disabled (e.g.
// high contrast mode).
document.getElementById("searchSubmit").value =
document.body.getAttribute("dir") == "ltr" ? "\u25B6" : "\u25C0";
// The "autofocus" attribute doesn't focus the form element
// immediately when the element is first drawn, so the
// attribute is also used for styling when the page first loads.
searchText = document.getElementById("searchText");
searchText.addEventListener("blur", function searchText_onBlur() {
searchText.removeEventListener("blur", searchText_onBlur);
searchText.removeAttribute("autofocus");
});
if (!gContentSearchController) {
gContentSearchController =
new ContentSearchUIController(searchText, searchText.parentNode,
"abouthome", "homepage");
}
}
/**
* Inform the test harness that we're done loading the page.
*/
function loadCompleted()
{
}
function fitToWidth() {
if (document.documentElement.scrollWidth > window.innerWidth) {
document.body.setAttribute("narrow", "true");
} else if (document.body.hasAttribute("narrow")) {
document.body.removeAttribute("narrow");
fitToWidth();
}
}
@@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
%aboutHomeDTD;
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
%browserDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&abouthome.pageTitle;</title>
<link rel="icon" type="image/png" id="favicon"
href="chrome://branding/content/icon32.png"/>
<link rel="stylesheet" type="text/css" media="all"
href="chrome://browser/content/contentSearchUI.css"/>
<link rel="stylesheet" type="text/css" media="all" defer="defer"
href="chrome://browser/content/abouthome/aboutHome.css"/>
<script type="text/javascript;version=1.8"
src="chrome://browser/content/abouthome/aboutHome.js"/>
<script type="text/javascript;version=1.8"
src="chrome://browser/content/contentSearchUI.js"/>
</head>
<body dir="&locale.dir;">
<div class="spacer"/>
<div id="topSection">
<div id="brandLogo"></div>
<div id="searchIconAndTextContainer">
<div id="searchIcon"/>
<input type="text" name="q" value="" id="searchText" maxlength="256"
aria-label="&contentSearchInput.label;" autofocus="autofocus"/>
<input id="searchSubmit" type="button" onclick="onSearchSubmit(event)"
title="&contentSearchSubmit.tooltip;"/>
</div>
</div>
<div class="spacer"/>
<div id="launcher">
<button class="launchButton" id="downloads">&abouthome.downloadsButton.label;</button>
<button class="launchButton" id="bookmarks">&abouthome.bookmarksButton.label;</button>
<button class="launchButton" id="history">&abouthome.historyButton.label;</button>
<button class="launchButton" id="addons">&abouthome.addonsButton.label;</button>
#ifdef MOZ_SERVICES_SYNC
<button class="launchButton" id="sync">&abouthome.syncButton.label;</button>
#endif
#ifdef XP_WIN
<button class="launchButton" id="settings">&abouthome.preferencesButtonWin.label;</button>
#else
<button class="launchButton" id="settings">&abouthome.preferencesButtonUnix.label;</button>
#endif
<div id="restorePreviousSessionSeparator"/>
<button class="launchButton" id="restorePreviousSession">&historyRestoreLastSession.label;</button>
</div>
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 898 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

@@ -1,114 +0,0 @@
<?xml version="1.0"?>
# 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/.
<!DOCTYPE overlay [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!ENTITY % baseMenuOverlayDTD SYSTEM "chrome://browser/locale/baseMenuOverlay.dtd">
%baseMenuOverlayDTD;
]>
<overlay id="baseMenuOverlay"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
#ifdef XP_MACOSX
<!-- nsMenuBarX hides these and uses them to build the Application menu.
When using Carbon widgets for Mac OS X widgets, some of these are not
used as they only apply to Cocoa widget builds. All version of Firefox
through Firefox 2 will use Carbon widgets. -->
<menupopup id="menu_ToolsPopup">
<menuitem id="menu_preferences" label="&preferencesCmdMac.label;" key="key_preferencesCmdMac" oncommand="openPreferences();"/>
<menuitem id="menu_mac_services" label="&servicesMenuMac.label;"/>
<menuitem id="menu_mac_hide_app" label="&hideThisAppCmdMac2.label;" key="key_hideThisAppCmdMac"/>
<menuitem id="menu_mac_hide_others" label="&hideOtherAppsCmdMac.label;" key="key_hideOtherAppsCmdMac"/>
<menuitem id="menu_mac_show_all" label="&showAllAppsCmdMac.label;"/>
</menupopup>
<!-- Mac window menu -->
#include ../../../../toolkit/content/macWindowMenu.inc
#endif
#ifdef XP_WIN
<menu id="helpMenu"
label="&helpMenuWin.label;"
accesskey="&helpMenuWin.accesskey;">
#else
<menu id="helpMenu"
label="&helpMenu.label;"
accesskey="&helpMenu.accesskey;">
#endif
<menupopup id="menu_HelpPopup" onpopupshowing="buildHelpMenu();">
<menuitem id="menu_openHelp"
oncommand="openHelpLink('firefox-help')"
onclick="checkForMiddleClick(this, event);"
label="&productHelp2.label;"
accesskey="&productHelp2.accesskey;"
#ifdef XP_MACOSX
key="key_openHelpMac"/>
#else
/>
#endif
<menuitem id="menu_keyboardShortcuts"
oncommand="openHelpLink('keyboard-shortcuts')"
onclick="checkForMiddleClick(this, event);"
label="&helpKeyboardShortcuts.label;"
accesskey="&helpKeyboardShortcuts.accesskey;"/>
#ifdef MOZ_TELEMETRY_REPORTING
<menuitem id="healthReport"
label="&healthReport2.label;"
accesskey="&healthReport2.accesskey;"
oncommand="openHealthReport()"
onclick="checkForMiddleClick(this, event);"/>
#endif
<menuitem id="troubleShooting"
accesskey="&helpTroubleshootingInfo.accesskey;"
label="&helpTroubleshootingInfo.label;"
oncommand="openTroubleshootingPage()"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="feedbackPage"
accesskey="&helpFeedbackPage.accesskey;"
label="&helpFeedbackPage.label;"
oncommand="openFeedbackPage()"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="helpSafeMode"
accesskey="&helpSafeMode.accesskey;"
label="&helpSafeMode.label;"
stopaccesskey="&helpSafeMode.stop.accesskey;"
stoplabel="&helpSafeMode.stop.label;"
oncommand="safeModeRestart();"/>
<menuseparator id="aboutSeparator"/>
<menuitem id="aboutName"
accesskey="&aboutProduct2.accesskey;"
label="&aboutProduct2.label;"
oncommand="openAboutDialog();"/>
</menupopup>
</menu>
<keyset id="baseMenuKeyset">
#ifdef XP_MACOSX
<key id="key_openHelpMac"
oncommand="openHelpLink('firefox-osxkey');"
key="&helpMac.commandkey;"
modifiers="accel"/>
<!-- These are used to build the Application menu under Cocoa widgets -->
<key id="key_preferencesCmdMac"
key="&preferencesCmdMac.commandkey;"
modifiers="accel"/>
<key id="key_hideThisAppCmdMac"
key="&hideThisAppCmdMac2.commandkey;"
modifiers="accel"/>
<key id="key_hideOtherAppsCmdMac"
key="&hideOtherAppsCmdMac.commandkey;"
modifiers="accel,alt"/>
#endif
</keyset>
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
<stringbundle id="bundle_browser_region" src="chrome://browser-region/locale/region.properties"/>
</stringbundleset>
</overlay>
@@ -1,196 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html [
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % blockedSiteDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
%blockedSiteDTD;
]>
<!-- 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/. -->
<html xmlns="http://www.w3.org/1999/xhtml" class="blacklist">
<head>
<link rel="stylesheet" href="chrome://browser/skin/blockedSite.css" type="text/css" media="all" />
<link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/blacklist_favicon.png"/>
<script type="application/javascript"><![CDATA[
// Error url MUST be formatted like this:
// about:blocked?e=error_code&u=url(&o=1)?
// (o=1 when user overrides are allowed)
// Note that this file uses document.documentURI to get
// the URL (with the format from above). This is because
// document.location.href gets the current URI off the docshell,
// which is the URL displayed in the location bar, i.e.
// the URI that the user attempted to load.
function getErrorCode()
{
var url = document.documentURI;
var error = url.search(/e\=/);
var duffUrl = url.search(/\&u\=/);
return decodeURIComponent(url.slice(error + 2, duffUrl));
}
function getURL()
{
var url = document.documentURI;
var match = url.match(/&u=([^&]+)&/);
// match == null if not found; if so, return an empty string
// instead of what would turn out to be portions of the URI
if (!match)
return "";
url = decodeURIComponent(match[1]);
// If this is a view-source page, then get then real URI of the page
if (url.startsWith("view-source:"))
url = url.slice(12);
return url;
}
/**
* Check whether this warning page should be overridable or whether
* the "ignore warning" button should be hidden.
*/
function getOverride()
{
var url = document.documentURI;
var match = url.match(/&o=1&/);
return !!match;
}
/**
* Attempt to get the hostname via document.location. Fail back
* to getURL so that we always return something meaningful.
*/
function getHostString()
{
try {
return document.location.hostname;
} catch (e) {
return getURL();
}
}
function initPage()
{
var error = "";
switch (getErrorCode()) {
case "malwareBlocked" :
error = "malware";
break;
case "deceptiveBlocked" :
error = "phishing";
break;
case "unwantedBlocked" :
error = "unwanted";
break;
default:
return;
}
var el;
if (error !== "malware") {
el = document.getElementById("errorTitleText_malware");
el.parentNode.removeChild(el);
el = document.getElementById("errorShortDescText_malware");
el.parentNode.removeChild(el);
el = document.getElementById("errorLongDescText_malware");
el.parentNode.removeChild(el);
}
if (error !== "phishing") {
el = document.getElementById("errorTitleText_phishing");
el.parentNode.removeChild(el);
el = document.getElementById("errorShortDescText_phishing");
el.parentNode.removeChild(el);
el = document.getElementById("errorLongDescText_phishing");
el.parentNode.removeChild(el);
}
if (error !== "unwanted") {
el = document.getElementById("errorTitleText_unwanted");
el.parentNode.removeChild(el);
el = document.getElementById("errorShortDescText_unwanted");
el.parentNode.removeChild(el);
el = document.getElementById("errorLongDescText_unwanted");
el.parentNode.removeChild(el);
}
// Set sitename
document.getElementById(error + "_sitename").textContent = getHostString();
document.title = document.getElementById("errorTitleText_" + error)
.innerHTML;
if (!getOverride()) {
var btn = document.getElementById("ignoreWarningButton");
if (btn) {
btn.parentNode.removeChild(btn);
}
}
// Inform the test harness that we're done loading the page
var event = new CustomEvent("AboutBlockedLoaded");
document.dispatchEvent(event);
}
]]></script>
</head>
<body dir="&locale.dir;">
<div id="errorPageContainer" class="container">
<!-- Error Title -->
<div id="errorTitle" class="title">
<h1 class="title-text" id="errorTitleText_phishing">&safeb.blocked.phishingPage.title2;</h1>
<h1 class="title-text" id="errorTitleText_malware">&safeb.blocked.malwarePage.title;</h1>
<h1 class="title-text" id="errorTitleText_unwanted">&safeb.blocked.unwantedPage.title;</h1>
</div>
<div id="errorLongContent">
<!-- Short Description -->
<div id="errorShortDesc">
<p id="errorShortDescText_phishing">&safeb.blocked.phishingPage.shortDesc2;</p>
<p id="errorShortDescText_malware">&safeb.blocked.malwarePage.shortDesc;</p>
<p id="errorShortDescText_unwanted">&safeb.blocked.unwantedPage.shortDesc;</p>
</div>
<!-- Long Description -->
<div id="errorLongDesc">
<p id="errorLongDescText_phishing">&safeb.blocked.phishingPage.longDesc2;</p>
<p id="errorLongDescText_malware">&safeb.blocked.malwarePage.longDesc;</p>
<p id="errorLongDescText_unwanted">&safeb.blocked.unwantedPage.longDesc;</p>
</div>
<!-- Action buttons -->
<div id="buttons" class="button-container">
<!-- Commands handled in browser.js -->
<button id="getMeOutButton" class="primary">&safeb.palm.accept.label;</button>
<div class="button-spacer"></div>
<button id="reportButton">&safeb.palm.reportPage.label;</button>
</div>
</div>
<div id="ignoreWarning">
<button id="ignoreWarningButton">&safeb.palm.decline.label;</button>
</div>
</div>
<!--
- Note: It is important to run the script this way, instead of using
- an onload handler. This is because error pages are loaded as
- LOAD_BACKGROUND, which means that onload handlers will not be executed.
-->
<script type="application/javascript">
initPage();
</script>
</body>
</html>
@@ -1,729 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
// Removes a doorhanger notification if all of the installs it was notifying
// about have ended in some way.
function removeNotificationOnEnd(notification, installs) {
let count = installs.length;
function maybeRemove(install) {
install.removeListener(this);
if (--count == 0) {
// Check that the notification is still showing
let current = PopupNotifications.getNotification(notification.id, notification.browser);
if (current === notification)
notification.remove();
}
}
for (let install of installs) {
install.addListener({
onDownloadCancelled: maybeRemove,
onDownloadFailed: maybeRemove,
onInstallFailed: maybeRemove,
onInstallEnded: maybeRemove
});
}
}
const gXPInstallObserver = {
_findChildShell: function (aDocShell, aSoughtShell)
{
if (aDocShell == aSoughtShell)
return aDocShell;
var node = aDocShell.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
for (var i = 0; i < node.childCount; ++i) {
var docShell = node.getChildAt(i);
docShell = this._findChildShell(docShell, aSoughtShell);
if (docShell == aSoughtShell)
return docShell;
}
return null;
},
_getBrowser: function (aDocShell)
{
for (let browser of gBrowser.browsers) {
if (this._findChildShell(browser.docShell, aDocShell))
return browser;
}
return null;
},
pendingInstalls: new WeakMap(),
showInstallConfirmation: function(browser, installInfo, height = undefined) {
// If the confirmation notification is already open cache the installInfo
// and the new confirmation will be shown later
if (PopupNotifications.getNotification("addon-install-confirmation", browser)) {
let pending = this.pendingInstalls.get(browser);
if (pending) {
pending.push(installInfo);
} else {
this.pendingInstalls.set(browser, [installInfo]);
}
return;
}
let showNextConfirmation = () => {
// Make sure the browser is still alive.
if (gBrowser.browsers.indexOf(browser) == -1)
return;
let pending = this.pendingInstalls.get(browser);
if (pending && pending.length)
this.showInstallConfirmation(browser, pending.shift());
}
// If all installs have already been cancelled in some way then just show
// the next confirmation
if (installInfo.installs.every(i => i.state != AddonManager.STATE_DOWNLOADED)) {
showNextConfirmation();
return;
}
const anchorID = "addons-notification-icon";
// Make notifications persist a minimum of 30 seconds
var options = {
displayURI: installInfo.originatingURI,
timeout: Date.now() + 30000,
};
let cancelInstallation = () => {
if (installInfo) {
for (let install of installInfo.installs) {
// The notification may have been closed because the add-ons got
// cancelled elsewhere, only try to cancel those that are still
// pending install.
if (install.state != AddonManager.STATE_CANCELLED)
install.cancel();
}
}
this.acceptInstallation = null;
showNextConfirmation();
};
let unsigned = installInfo.installs.filter(i => i.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING);
let someUnsigned = unsigned.length > 0 && unsigned.length < installInfo.installs.length;
options.eventCallback = (aEvent) => {
switch (aEvent) {
case "removed":
cancelInstallation();
break;
case "shown":
let addonList = document.getElementById("addon-install-confirmation-content");
while (addonList.firstChild)
addonList.firstChild.remove();
for (let install of installInfo.installs) {
let container = document.createElement("hbox");
let name = document.createElement("label");
name.setAttribute("value", install.addon.name);
name.setAttribute("class", "addon-install-confirmation-name");
container.appendChild(name);
if (someUnsigned && install.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) {
let unsigned = document.createElement("label");
unsigned.setAttribute("value", gNavigatorBundle.getString("addonInstall.unsigned"));
unsigned.setAttribute("class", "addon-install-confirmation-unsigned");
container.appendChild(unsigned);
}
addonList.appendChild(container);
}
this.acceptInstallation = () => {
for (let install of installInfo.installs)
install.install();
installInfo = null;
};
break;
}
};
options.learnMoreURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
let messageString;
let notification = document.getElementById("addon-install-confirmation-notification");
if (unsigned.length == installInfo.installs.length) {
// None of the add-ons are verified
messageString = gNavigatorBundle.getString("addonConfirmInstallUnsigned.message");
notification.setAttribute("warning", "true");
options.learnMoreURL += "unsigned-addons";
}
else if (unsigned.length == 0) {
// All add-ons are verified or don't need to be verified
messageString = gNavigatorBundle.getString("addonConfirmInstall.message");
notification.removeAttribute("warning");
options.learnMoreURL += "find-and-install-add-ons";
}
else {
// Some of the add-ons are unverified, the list of names will indicate
// which
messageString = gNavigatorBundle.getString("addonConfirmInstallSomeUnsigned.message");
notification.setAttribute("warning", "true");
options.learnMoreURL += "unsigned-addons";
}
let brandBundle = document.getElementById("bundle_brand");
let brandShortName = brandBundle.getString("brandShortName");
messageString = PluralForm.get(installInfo.installs.length, messageString);
messageString = messageString.replace("#1", brandShortName);
messageString = messageString.replace("#2", installInfo.installs.length);
let cancelButton = document.getElementById("addon-install-confirmation-cancel");
cancelButton.label = gNavigatorBundle.getString("addonInstall.cancelButton.label");
cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
let acceptButton = document.getElementById("addon-install-confirmation-accept");
acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
if (height) {
let notification = document.getElementById("addon-install-confirmation-notification");
notification.style.minHeight = height + "px";
}
let tab = gBrowser.getTabForBrowser(browser);
if (tab) {
gBrowser.selectedTab = tab;
}
let popup = PopupNotifications.show(browser, "addon-install-confirmation",
messageString, anchorID, null, null,
options);
removeNotificationOnEnd(popup, installInfo.installs);
},
observe: function (aSubject, aTopic, aData)
{
var brandBundle = document.getElementById("bundle_brand");
var installInfo = aSubject.QueryInterface(Components.interfaces.amIWebInstallInfo);
var browser = installInfo.browser;
// Make sure the browser is still alive.
if (!browser || gBrowser.browsers.indexOf(browser) == -1)
return;
const anchorID = "addons-notification-icon";
var messageString, action;
var brandShortName = brandBundle.getString("brandShortName");
var notificationID = aTopic;
// Make notifications persist a minimum of 30 seconds
var options = {
displayURI: installInfo.originatingURI,
timeout: Date.now() + 30000,
};
switch (aTopic) {
case "addon-install-disabled": {
notificationID = "xpinstall-disabled";
if (gPrefService.prefIsLocked("xpinstall.enabled")) {
messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
buttons = [];
}
else {
messageString = gNavigatorBundle.getString("xpinstallDisabledMessage");
action = {
label: gNavigatorBundle.getString("xpinstallDisabledButton"),
accessKey: gNavigatorBundle.getString("xpinstallDisabledButton.accesskey"),
callback: function editPrefs() {
gPrefService.setBoolPref("xpinstall.enabled", true);
}
};
}
PopupNotifications.show(browser, notificationID, messageString, anchorID,
action, null, options);
break; }
case "addon-install-origin-blocked": {
messageString = gNavigatorBundle.getFormattedString("xpinstallPromptMessage",
[brandShortName]);
let popup = PopupNotifications.show(browser, notificationID,
messageString, anchorID,
null, null, options);
removeNotificationOnEnd(popup, installInfo.installs);
break; }
case "addon-install-blocked": {
messageString = gNavigatorBundle.getFormattedString("xpinstallPromptMessage",
[brandShortName]);
action = {
label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
callback: function() {
installInfo.install();
}
};
let popup = PopupNotifications.show(browser, notificationID,
messageString, anchorID,
action, null, options);
removeNotificationOnEnd(popup, installInfo.installs);
break; }
case "addon-install-started": {
let needsDownload = function needsDownload(aInstall) {
return aInstall.state != AddonManager.STATE_DOWNLOADED;
}
// If all installs have already been downloaded then there is no need to
// show the download progress
if (!installInfo.installs.some(needsDownload))
return;
notificationID = "addon-progress";
messageString = gNavigatorBundle.getString("addonDownloadingAndVerifying");
messageString = PluralForm.get(installInfo.installs.length, messageString);
messageString = messageString.replace("#1", installInfo.installs.length);
options.installs = installInfo.installs;
options.contentWindow = browser.contentWindow;
options.sourceURI = browser.currentURI;
options.eventCallback = (aEvent) => {
switch (aEvent) {
case "removed":
options.contentWindow = null;
options.sourceURI = null;
break;
}
};
let notification = PopupNotifications.show(browser, notificationID, messageString,
anchorID, null, null, options);
notification._startTime = Date.now();
let cancelButton = document.getElementById("addon-progress-cancel");
cancelButton.label = gNavigatorBundle.getString("addonInstall.cancelButton.label");
cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
let acceptButton = document.getElementById("addon-progress-accept");
if (Preferences.get("xpinstall.customConfirmationUI", false)) {
acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
} else {
acceptButton.hidden = true;
}
break; }
case "addon-install-failed": {
// TODO This isn't terribly ideal for the multiple failure case
for (let install of installInfo.installs) {
let host;
try {
host = options.displayURI.host;
} catch (e) {
// displayURI might be missing or 'host' might throw for non-nsStandardURL nsIURIs.
}
if (!host)
host = (install.sourceURI instanceof Ci.nsIStandardURL) &&
install.sourceURI.host;
let error = (host || install.error == 0) ? "addonInstallError" : "addonLocalInstallError";
let args;
if (install.error < 0) {
error += install.error;
args = [brandShortName, install.name];
} else if (install.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
error += "Blocklisted";
args = [install.name];
} else {
error += "Incompatible";
args = [brandShortName, Services.appinfo.version, install.name];
}
// Add Learn More link when refusing to install an unsigned add-on
if (install.error == AddonManager.ERROR_SIGNEDSTATE_REQUIRED) {
options.learnMoreURL = Services.urlFormatter.formatURLPref("app.support.baseURL") + "unsigned-addons";
}
messageString = gNavigatorBundle.getFormattedString(error, args);
PopupNotifications.show(browser, notificationID, messageString, anchorID,
action, null, options);
// Can't have multiple notifications with the same ID, so stop here.
break;
}
this._removeProgressNotification(browser);
break; }
case "addon-install-confirmation": {
let showNotification = () => {
let height = undefined;
if (PopupNotifications.isPanelOpen) {
let rect = document.getElementById("addon-progress-notification").getBoundingClientRect();
height = rect.height;
}
this._removeProgressNotification(browser);
this.showInstallConfirmation(browser, installInfo, height);
};
let progressNotification = PopupNotifications.getNotification("addon-progress", browser);
if (progressNotification) {
let downloadDuration = Date.now() - progressNotification._startTime;
let securityDelay = Services.prefs.getIntPref("security.dialog_enable_delay") - downloadDuration;
if (securityDelay > 0) {
setTimeout(() => {
// The download may have been cancelled during the security delay
if (PopupNotifications.getNotification("addon-progress", browser))
showNotification();
}, securityDelay);
break;
}
}
showNotification();
break; }
case "addon-install-complete": {
let needsRestart = installInfo.installs.some(function(i) {
return i.addon.pendingOperations != AddonManager.PENDING_NONE;
});
if (needsRestart) {
notificationID = "addon-install-restart";
messageString = gNavigatorBundle.getString("addonsInstalledNeedsRestart");
action = {
label: gNavigatorBundle.getString("addonInstallRestartButton"),
accessKey: gNavigatorBundle.getString("addonInstallRestartButton.accesskey"),
callback: function() {
BrowserUtils.restartApplication();
}
};
}
else {
messageString = gNavigatorBundle.getString("addonsInstalled");
action = null;
}
messageString = PluralForm.get(installInfo.installs.length, messageString);
messageString = messageString.replace("#1", installInfo.installs[0].name);
messageString = messageString.replace("#2", installInfo.installs.length);
messageString = messageString.replace("#3", brandShortName);
// Remove notificaion on dismissal, since it's possible to cancel the
// install through the addons manager UI, making the "restart" prompt
// irrelevant.
options.removeOnDismissal = true;
PopupNotifications.show(browser, notificationID, messageString, anchorID,
action, null, options);
break; }
}
},
_removeProgressNotification(aBrowser) {
let notification = PopupNotifications.getNotification("addon-progress", aBrowser);
if (notification)
notification.remove();
}
};
var LightWeightThemeWebInstaller = {
init: function () {
let mm = window.messageManager;
mm.addMessageListener("LightWeightThemeWebInstaller:Install", this);
mm.addMessageListener("LightWeightThemeWebInstaller:Preview", this);
mm.addMessageListener("LightWeightThemeWebInstaller:ResetPreview", this);
},
receiveMessage: function (message) {
// ignore requests from background tabs
if (message.target != gBrowser.selectedBrowser) {
return;
}
let data = message.data;
switch (message.name) {
case "LightWeightThemeWebInstaller:Install": {
this._installRequest(data.themeData, data.principal, data.baseURI);
break;
}
case "LightWeightThemeWebInstaller:Preview": {
this._preview(data.themeData, data.principal, data.baseURI);
break;
}
case "LightWeightThemeWebInstaller:ResetPreview": {
this._resetPreview(data && data.principal);
break;
}
}
},
handleEvent: function (event) {
switch (event.type) {
case "TabSelect": {
this._resetPreview();
break;
}
}
},
get _manager () {
let temp = {};
Cu.import("resource://gre/modules/LightweightThemeManager.jsm", temp);
delete this._manager;
return this._manager = temp.LightweightThemeManager;
},
_installRequest(dataString, principal, baseURI) {
// Don't allow installing off null principals.
if (!principal.URI) {
return;
}
let data = this._manager.parseTheme(dataString, baseURI);
if (!data) {
return;
}
// A notification bar with the option to undo is normally shown after a
// theme is installed. But the discovery pane served from the url(s)
// below has its own toggle switch for quick undos, so don't show the
// notification in that case.
let notify = this._shouldShowUndoPrompt(principal);
if (this._isAllowed(principal)) {
this._install(data, notify);
return;
}
let allowButtonText =
gNavigatorBundle.getString("lwthemeInstallRequest.allowButton");
let allowButtonAccesskey =
gNavigatorBundle.getString("lwthemeInstallRequest.allowButton.accesskey");
let message =
gNavigatorBundle.getFormattedString("lwthemeInstallRequest.message",
[principal.URI.host]);
let buttons = [{
label: allowButtonText,
accessKey: allowButtonAccesskey,
callback: function () {
LightWeightThemeWebInstaller._install(data, notify);
}
}];
this._removePreviousNotifications();
let notificationBox = gBrowser.getNotificationBox();
let notificationBar =
notificationBox.appendNotification(message, "lwtheme-install-request", "",
notificationBox.PRIORITY_INFO_MEDIUM,
buttons);
notificationBar.persistence = 1;
},
_install: function (newLWTheme, notify) {
let previousLWTheme = this._manager.currentTheme;
let listener = {
onEnabling: function(aAddon, aRequiresRestart) {
if (!aRequiresRestart) {
return;
}
let messageString = gNavigatorBundle.getFormattedString("lwthemeNeedsRestart.message",
[aAddon.name], 1);
let action = {
label: gNavigatorBundle.getString("lwthemeNeedsRestart.button"),
accessKey: gNavigatorBundle.getString("lwthemeNeedsRestart.accesskey"),
callback: function () {
BrowserUtils.restartApplication();
}
};
let options = {
timeout: Date.now() + 30000
};
PopupNotifications.show(gBrowser.selectedBrowser, "addon-theme-change",
messageString, "addons-notification-icon",
action, null, options);
},
onEnabled: function(aAddon) {
if (notify) {
LightWeightThemeWebInstaller._postInstallNotification(newLWTheme, previousLWTheme);
}
}
};
AddonManager.addAddonListener(listener);
this._manager.currentTheme = newLWTheme;
AddonManager.removeAddonListener(listener);
},
_postInstallNotification: function (newTheme, previousTheme) {
function text(id) {
return gNavigatorBundle.getString("lwthemePostInstallNotification." + id);
}
let buttons = [{
label: text("undoButton"),
accessKey: text("undoButton.accesskey"),
callback: function () {
LightWeightThemeWebInstaller._manager.forgetUsedTheme(newTheme.id);
LightWeightThemeWebInstaller._manager.currentTheme = previousTheme;
}
}, {
label: text("manageButton"),
accessKey: text("manageButton.accesskey"),
callback: function () {
BrowserOpenAddonsMgr("addons://list/theme");
}
}];
this._removePreviousNotifications();
let notificationBox = gBrowser.getNotificationBox();
let notificationBar =
notificationBox.appendNotification(text("message"),
"lwtheme-install-notification", "",
notificationBox.PRIORITY_INFO_MEDIUM,
buttons);
notificationBar.persistence = 1;
notificationBar.timeout = Date.now() + 20000; // 20 seconds
},
_removePreviousNotifications: function () {
let box = gBrowser.getNotificationBox();
["lwtheme-install-request",
"lwtheme-install-notification"].forEach(function (value) {
let notification = box.getNotificationWithValue(value);
if (notification)
box.removeNotification(notification);
});
},
_preview(dataString, principal, baseURI) {
if (!this._isAllowed(principal))
return;
let data = this._manager.parseTheme(dataString, baseURI);
if (!data)
return;
this._resetPreview();
gBrowser.tabContainer.addEventListener("TabSelect", this, false);
this._manager.previewTheme(data);
},
_resetPreview(principal) {
if (!this._isAllowed(principal))
return;
gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
this._manager.resetPreview();
},
_isAllowed(principal) {
if (!principal || !principal.URI || !principal.URI.schemeIs("https")) {
return false;
}
let pm = Services.perms;
return pm.testPermission(principal.URI, "install") == pm.ALLOW_ACTION;
},
_shouldShowUndoPrompt(principal) {
if (!principal || !principal.URI) {
return true;
}
let prePath = principal.URI.prePath;
if (prePath == "https://addons.palemoon.org") {
return false;
}
return true;
}
};
/*
* Listen for Lightweight Theme styling changes and update the browser's theme accordingly.
*/
var LightweightThemeListener = {
_modifiedStyles: [],
init: function () {
XPCOMUtils.defineLazyGetter(this, "styleSheet", function() {
for (let i = document.styleSheets.length - 1; i >= 0; i--) {
let sheet = document.styleSheets[i];
if (sheet.href == "chrome://browser/skin/browser-lightweightTheme.css")
return sheet;
}
return undefined;
});
Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
Services.obs.addObserver(this, "lightweight-theme-optimized", false);
if (document.documentElement.hasAttribute("lwtheme"))
this.updateStyleSheet(document.documentElement.style.backgroundImage);
},
uninit: function () {
Services.obs.removeObserver(this, "lightweight-theme-styling-update");
Services.obs.removeObserver(this, "lightweight-theme-optimized");
},
/**
* Append the headerImage to the background-image property of all rulesets in
* browser-lightweightTheme.css.
*
* @param headerImage - a string containing a CSS image for the lightweight theme header.
*/
updateStyleSheet: function(headerImage) {
if (!this.styleSheet)
return;
this.substituteRules(this.styleSheet.cssRules, headerImage);
},
substituteRules: function(ruleList, headerImage, existingStyleRulesModified = 0) {
let styleRulesModified = 0;
for (let i = 0; i < ruleList.length; i++) {
let rule = ruleList[i];
if (rule instanceof Ci.nsIDOMCSSGroupingRule) {
// Add the number of modified sub-rules to the modified count
styleRulesModified += this.substituteRules(rule.cssRules, headerImage, existingStyleRulesModified + styleRulesModified);
} else if (rule instanceof Ci.nsIDOMCSSStyleRule) {
if (!rule.style.backgroundImage)
continue;
let modifiedIndex = existingStyleRulesModified + styleRulesModified;
if (!this._modifiedStyles[modifiedIndex])
this._modifiedStyles[modifiedIndex] = { backgroundImage: rule.style.backgroundImage };
rule.style.backgroundImage = this._modifiedStyles[modifiedIndex].backgroundImage + ", " + headerImage;
styleRulesModified++;
} else {
Cu.reportError("Unsupported rule encountered");
}
}
return styleRulesModified;
},
// nsIObserver
observe: function (aSubject, aTopic, aData) {
if ((aTopic != "lightweight-theme-styling-update" && aTopic != "lightweight-theme-optimized") ||
!this.styleSheet)
return;
if (aTopic == "lightweight-theme-optimized" && aSubject != window)
return;
let themeData = JSON.parse(aData);
if (!themeData)
return;
this.updateStyleSheet("url(" + themeData.headerURL + ")");
},
};
@@ -1,257 +0,0 @@
/* 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/. */
XPCOMUtils.defineLazyServiceGetter(this, "cps",
"@mozilla.org/network/captive-portal-service;1",
"nsICaptivePortalService");
var CaptivePortalWatcher = {
/**
* This constant is chosen to be large enough for a portal recheck to complete,
* and small enough that the delay in opening a tab isn't too noticeable.
* Please see comments for _delayedCaptivePortalDetected for more details.
*/
PORTAL_RECHECK_DELAY_MS: Preferences.get("captivedetect.portalRecheckDelayMS", 500),
// This is the value used to identify the captive portal notification.
PORTAL_NOTIFICATION_VALUE: "captive-portal-detected",
// This holds a weak reference to the captive portal tab so that we
// don't leak it if the user closes it.
_captivePortalTab: null,
/**
* If a portal is detected when we don't have focus, we first wait for focus
* and then add the tab if, after a recheck, the portal is still active. This
* is set to true while we wait so that in the unlikely event that we receive
* another notification while waiting, we don't do things twice.
*/
_delayedCaptivePortalDetectedInProgress: false,
// In the situation above, this is set to true while we wait for the recheck.
// This flag exists so that tests can appropriately simulate a recheck.
_waitingForRecheck: false,
get _captivePortalNotification() {
let nb = document.getElementById("high-priority-global-notificationbox");
return nb.getNotificationWithValue(this.PORTAL_NOTIFICATION_VALUE);
},
get canonicalURL() {
return Services.prefs.getCharPref("captivedetect.canonicalURL");
},
get _browserBundle() {
delete this._browserBundle;
return this._browserBundle =
Services.strings.createBundle("chrome://browser/locale/browser.properties");
},
init() {
Services.obs.addObserver(this, "captive-portal-login", false);
Services.obs.addObserver(this, "captive-portal-login-abort", false);
Services.obs.addObserver(this, "captive-portal-login-success", false);
if (cps.state == cps.LOCKED_PORTAL) {
// A captive portal has already been detected.
this._captivePortalDetected();
// Automatically open a captive portal tab if there's no other browser window.
let windows = Services.wm.getEnumerator("navigator:browser");
if (windows.getNext() == window && !windows.hasMoreElements()) {
this.ensureCaptivePortalTab();
}
}
cps.recheckCaptivePortal();
},
uninit() {
Services.obs.removeObserver(this, "captive-portal-login");
Services.obs.removeObserver(this, "captive-portal-login-abort");
Services.obs.removeObserver(this, "captive-portal-login-success");
if (this._delayedCaptivePortalDetectedInProgress) {
Services.obs.removeObserver(this, "xul-window-visible");
}
},
observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "captive-portal-login":
this._captivePortalDetected();
break;
case "captive-portal-login-abort":
case "captive-portal-login-success":
this._captivePortalGone();
break;
case "xul-window-visible":
this._delayedCaptivePortalDetected();
break;
}
},
_captivePortalDetected() {
if (this._delayedCaptivePortalDetectedInProgress) {
return;
}
let win = RecentWindow.getMostRecentBrowserWindow();
// If no browser window has focus, open and show the tab when we regain focus.
// This is so that if a different application was focused, when the user
// (re-)focuses a browser window, we open the tab immediately in that window
// so they can log in before continuing to browse.
if (win != Services.ww.activeWindow) {
this._delayedCaptivePortalDetectedInProgress = true;
Services.obs.addObserver(this, "xul-window-visible", false);
}
this._showNotification();
},
/**
* Called after we regain focus if we detect a portal while a browser window
* doesn't have focus. Triggers a portal recheck to reaffirm state, and adds
* the tab if needed after a short delay to allow the recheck to complete.
*/
_delayedCaptivePortalDetected() {
if (!this._delayedCaptivePortalDetectedInProgress) {
return;
}
let win = RecentWindow.getMostRecentBrowserWindow();
if (win != Services.ww.activeWindow) {
// The window that got focused was not a browser window.
return;
}
Services.obs.removeObserver(this, "xul-window-visible");
this._delayedCaptivePortalDetectedInProgress = false;
if (win != window) {
// Some other browser window got focus, we don't have to do anything.
return;
}
// Trigger a portal recheck. The user may have logged into the portal via
// another client, or changed networks.
cps.recheckCaptivePortal();
this._waitingForRecheck = true;
let requestTime = Date.now();
let self = this;
Services.obs.addObserver(function observer() {
let time = Date.now() - requestTime;
Services.obs.removeObserver(observer, "captive-portal-check-complete");
self._waitingForRecheck = false;
if (cps.state != cps.LOCKED_PORTAL) {
// We're free of the portal!
return;
}
if (time <= self.PORTAL_RECHECK_DELAY_MS) {
// The amount of time elapsed since we requested a recheck (i.e. since
// the browser window was focused) was small enough that we can add and
// focus a tab with the login page with no noticeable delay.
self.ensureCaptivePortalTab();
}
}, "captive-portal-check-complete", false);
},
_captivePortalGone() {
if (this._delayedCaptivePortalDetectedInProgress) {
Services.obs.removeObserver(this, "xul-window-visible");
this._delayedCaptivePortalDetectedInProgress = false;
}
this._removeNotification();
},
handleEvent(aEvent) {
if (aEvent.type != "TabSelect" || !this._captivePortalTab || !this._captivePortalNotification) {
return;
}
let tab = this._captivePortalTab.get();
let n = this._captivePortalNotification;
if (!tab || !n) {
return;
}
let doc = tab.ownerDocument;
let button = n.querySelector("button.notification-button");
if (doc.defaultView.gBrowser.selectedTab == tab) {
button.style.visibility = "hidden";
} else {
button.style.visibility = "visible";
}
},
_showNotification() {
let buttons = [
{
label: this._browserBundle.GetStringFromName("captivePortal.showLoginPage"),
callback: () => {
this.ensureCaptivePortalTab();
// Returning true prevents the notification from closing.
return true;
},
isDefault: true,
},
];
let message = this._browserBundle.GetStringFromName("captivePortal.infoMessage2");
let closeHandler = (aEventName) => {
if (aEventName != "removed") {
return;
}
gBrowser.tabContainer.removeEventListener("TabSelect", this);
};
let nb = document.getElementById("high-priority-global-notificationbox");
nb.appendNotification(message, this.PORTAL_NOTIFICATION_VALUE, "",
nb.PRIORITY_INFO_MEDIUM, buttons, closeHandler);
gBrowser.tabContainer.addEventListener("TabSelect", this);
},
_removeNotification() {
let n = this._captivePortalNotification;
if (!n || !n.parentNode) {
return;
}
n.close();
},
ensureCaptivePortalTab() {
let tab;
if (this._captivePortalTab) {
tab = this._captivePortalTab.get();
}
// If the tab is gone or going, we need to open a new one.
if (!tab || tab.closing || !tab.parentNode) {
tab = gBrowser.addTab(this.canonicalURL, { ownerTab: gBrowser.selectedTab });
this._captivePortalTab = Cu.getWeakReference(tab);
}
gBrowser.selectedTab = tab;
let canonicalURI = makeURI(this.canonicalURL);
// When we are no longer captive, close the tab if it's at the canonical URL.
let tabCloser = () => {
Services.obs.removeObserver(tabCloser, "captive-portal-login-abort");
Services.obs.removeObserver(tabCloser, "captive-portal-login-success");
if (!tab || tab.closing || !tab.parentNode || !tab.linkedBrowser ||
!tab.linkedBrowser.currentURI.equalsExceptRef(canonicalURI)) {
return;
}
gBrowser.removeTab(tab);
}
Services.obs.addObserver(tabCloser, "captive-portal-login-abort", false);
Services.obs.addObserver(tabCloser, "captive-portal-login-success", false);
},
};
@@ -1,12 +0,0 @@
# 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/.
<menu id="charsetMenu"
label="&charsetMenu2.label;"
accesskey="&charsetMenu2.accesskey;"
oncommand="BrowserSetForcedCharacterSet(event.target.getAttribute('charset'));"
onpopupshowing="CharsetMenu.build(event.target); UpdateCurrentCharset(this);">
<menupopup>
</menupopup>
</menu>
@@ -1,425 +0,0 @@
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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/.
<menugroup id="context-navigation">
<menuitem id="context-back"
class="menuitem-iconic"
tooltiptext="&backButton.tooltip;"
aria-label="&backCmd.label;"
command="Browser:BackOrBackDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-forward"
class="menuitem-iconic"
tooltiptext="&forwardButton.tooltip;"
aria-label="&forwardCmd.label;"
command="Browser:ForwardOrForwardDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-reload"
class="menuitem-iconic"
tooltiptext="&reloadButton.tooltip;"
aria-label="&reloadCmd.label;"
oncommand="gContextMenu.reload(event);"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-stop"
class="menuitem-iconic"
tooltiptext="&stopButton.tooltip;"
aria-label="&stopCmd.label;"
command="Browser:Stop"/>
<menuitem id="context-bookmarkpage"
class="menuitem-iconic"
observes="bookmarkThisPageBroadcaster"
aria-label="&bookmarkPageCmd2.label;"
oncommand="gContextMenu.bookmarkThisPage();"/>
</menugroup>
<menuseparator id="context-sep-navigation"/>
<menuseparator id="page-menu-separator"/>
<menuitem id="spell-no-suggestions"
disabled="true"
label="&spellNoSuggestions.label;"/>
<menuitem id="spell-add-to-dictionary"
label="&spellAddToDictionary.label;"
accesskey="&spellAddToDictionary.accesskey;"
oncommand="InlineSpellCheckerUI.addToDictionary();"/>
<menuitem id="spell-undo-add-to-dictionary"
label="&spellUndoAddToDictionary.label;"
accesskey="&spellUndoAddToDictionary.accesskey;"
oncommand="InlineSpellCheckerUI.undoAddToDictionary();" />
<menuseparator id="spell-suggestions-separator"/>
<menuitem id="context-openlinkincurrent"
label="&openLinkCmdInCurrent.label;"
accesskey="&openLinkCmdInCurrent.accesskey;"
oncommand="gContextMenu.openLinkInCurrent();"/>
# label is dynamically set.
<menuitem id="context-openlinkintab"
label="&openLinkCmdInTab.label;"
accesskey="&openLinkCmdInTab.accesskey;"
oncommand="gContextMenu.openLinkInTab();"/>
<menuitem id="context-openlink"
label="&openLinkCmd.label;"
accesskey="&openLinkCmd.accesskey;"
oncommand="gContextMenu.openLink();"/>
<menuitem id="context-openlinkprivate"
label="&openLinkInPrivateWindowCmd.label;"
accesskey="&openLinkInPrivateWindowCmd.accesskey;"
oncommand="gContextMenu.openLinkInPrivateWindow();"/>
<menuseparator id="context-sep-open"/>
<menuitem id="context-bookmarklink"
label="&bookmarkThisLinkCmd.label;"
accesskey="&bookmarkThisLinkCmd.accesskey;"
oncommand="gContextMenu.bookmarkLink();"/>
<menuitem id="context-savelink"
label="&saveLinkCmd.label;"
accesskey="&saveLinkCmd.accesskey;"
oncommand="gContextMenu.saveLink();"/>
<menuitem id="context-copyemail"
label="&copyEmailCmd.label;"
accesskey="&copyEmailCmd.accesskey;"
oncommand="gContextMenu.copyEmail();"/>
<menuitem id="context-copylink"
label="&copyLinkCmd.label;"
accesskey="&copyLinkCmd.accesskey;"
oncommand="gContextMenu.copyLink();"/>
<menuseparator id="context-sep-copylink"/>
<menuitem id="context-media-play"
label="&mediaPlay.label;"
accesskey="&mediaPlay.accesskey;"
oncommand="gContextMenu.mediaCommand('play');"/>
<menuitem id="context-media-pause"
label="&mediaPause.label;"
accesskey="&mediaPause.accesskey;"
oncommand="gContextMenu.mediaCommand('pause');"/>
<menuitem id="context-media-mute"
label="&mediaMute.label;"
accesskey="&mediaMute.accesskey;"
oncommand="gContextMenu.mediaCommand('mute');"/>
<menuitem id="context-media-unmute"
label="&mediaUnmute.label;"
accesskey="&mediaUnmute.accesskey;"
oncommand="gContextMenu.mediaCommand('unmute');"/>
<menu id="context-media-playbackrate" label="&mediaPlaybackRate2.label;" accesskey="&mediaPlaybackRate2.accesskey;">
<menupopup>
<menuitem id="context-media-playbackrate-050x"
label="&mediaPlaybackRate050x2.label;"
accesskey="&mediaPlaybackRate050x2.accesskey;"
type="radio"
name="playbackrate"
oncommand="gContextMenu.mediaCommand('playbackRate', 0.5);"/>
<menuitem id="context-media-playbackrate-100x"
label="&mediaPlaybackRate100x2.label;"
accesskey="&mediaPlaybackRate100x2.accesskey;"
type="radio"
name="playbackrate"
checked="true"
oncommand="gContextMenu.mediaCommand('playbackRate', 1.0);"/>
<menuitem id="context-media-playbackrate-125x"
label="&mediaPlaybackRate125x2.label;"
accesskey="&mediaPlaybackRate125x2.accesskey;"
type="radio"
name="playbackrate"
oncommand="gContextMenu.mediaCommand('playbackRate', 1.25);"/>
<menuitem id="context-media-playbackrate-150x"
label="&mediaPlaybackRate150x2.label;"
accesskey="&mediaPlaybackRate150x2.accesskey;"
type="radio"
name="playbackrate"
oncommand="gContextMenu.mediaCommand('playbackRate', 1.5);"/>
<menuitem id="context-media-playbackrate-200x"
label="&mediaPlaybackRate200x2.label;"
accesskey="&mediaPlaybackRate200x2.accesskey;"
type="radio"
name="playbackrate"
oncommand="gContextMenu.mediaCommand('playbackRate', 2.0);"/>
</menupopup>
</menu>
<menuitem id="context-media-loop"
label="&mediaLoop.label;"
accesskey="&mediaLoop.accesskey;"
type="checkbox"
oncommand="gContextMenu.mediaCommand('loop');"/>
<menuitem id="context-media-showcontrols"
label="&mediaShowControls.label;"
accesskey="&mediaShowControls.accesskey;"
oncommand="gContextMenu.mediaCommand('showcontrols');"/>
<menuitem id="context-media-hidecontrols"
label="&mediaHideControls.label;"
accesskey="&mediaHideControls.accesskey;"
oncommand="gContextMenu.mediaCommand('hidecontrols');"/>
<menuitem id="context-video-fullscreen"
accesskey="&videoFullScreen.accesskey;"
label="&videoFullScreen.label;"
oncommand="gContextMenu.mediaCommand('fullscreen');"/>
<menuitem id="context-leave-dom-fullscreen"
accesskey="&leaveDOMFullScreen.accesskey;"
label="&leaveDOMFullScreen.label;"
oncommand="gContextMenu.leaveDOMFullScreen();"/>
<menuseparator id="context-media-sep-commands"/>
<menuitem id="context-reloadimage"
label="&reloadImageCmd.label;"
accesskey="&reloadImageCmd.accesskey;"
oncommand="gContextMenu.reloadImage();"/>
<menuitem id="context-viewimage"
label="&viewImageCmd.label;"
accesskey="&viewImageCmd.accesskey;"
oncommand="gContextMenu.viewMedia(event);"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-viewvideo"
label="&viewVideoCmd.label;"
accesskey="&viewVideoCmd.accesskey;"
oncommand="gContextMenu.viewMedia(event);"
onclick="checkForMiddleClick(this, event);"/>
#ifdef CONTEXT_COPY_IMAGE_CONTENTS
<menuitem id="context-copyimage-contents"
label="&copyImageContentsCmd.label;"
accesskey="&copyImageContentsCmd.accesskey;"
oncommand="goDoCommand('cmd_copyImage');"/>
#endif
<menuitem id="context-copyimage"
label="&copyImageCmd.label;"
accesskey="&copyImageCmd.accesskey;"
oncommand="gContextMenu.copyMediaLocation();"/>
<menuitem id="context-copyvideourl"
label="&copyVideoURLCmd.label;"
accesskey="&copyVideoURLCmd.accesskey;"
oncommand="gContextMenu.copyMediaLocation();"/>
<menuitem id="context-copyaudiourl"
label="&copyAudioURLCmd.label;"
accesskey="&copyAudioURLCmd.accesskey;"
oncommand="gContextMenu.copyMediaLocation();"/>
<menuseparator id="context-sep-copyimage"/>
<menuitem id="context-saveimage"
label="&saveImageCmd.label;"
accesskey="&saveImageCmd.accesskey;"
oncommand="gContextMenu.saveMedia();"/>
<menuitem id="context-sendimage"
label="&emailImageCmd.label;"
accesskey="&emailImageCmd.accesskey;"
oncommand="gContextMenu.sendMedia();"/>
<menuitem id="context-setDesktopBackground"
label="&setDesktopBackgroundCmd.label;"
accesskey="&setDesktopBackgroundCmd.accesskey;"
oncommand="gContextMenu.setDesktopBackground();"/>
<menuitem id="context-viewimageinfo"
label="&viewImageInfoCmd.label;"
accesskey="&viewImageInfoCmd.accesskey;"
oncommand="gContextMenu.viewImageInfo();"/>
<menuitem id="context-viewimagedesc"
label="&viewImageDescCmd.label;"
accesskey="&viewImageDescCmd.accesskey;"
oncommand="gContextMenu.viewImageDesc(event);"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-savevideo"
label="&saveVideoCmd.label;"
accesskey="&saveVideoCmd.accesskey;"
oncommand="gContextMenu.saveMedia();"/>
<menuitem id="context-saveaudio"
label="&saveAudioCmd.label;"
accesskey="&saveAudioCmd.accesskey;"
oncommand="gContextMenu.saveMedia();"/>
<menuitem id="context-video-saveimage"
accesskey="&videoSaveImage.accesskey;"
label="&videoSaveImage.label;"
oncommand="gContextMenu.saveVideoFrameAsImage();"/>
<menuitem id="context-sendvideo"
label="&emailVideoCmd.label;"
accesskey="&emailVideoCmd.accesskey;"
oncommand="gContextMenu.sendMedia();"/>
<menu id="context-castvideo"
label="&castVideoCmd.label;"
accesskey="&castVideoCmd.accesskey;">
<menupopup id="context-castvideo-popup" onpopupshowing="gContextMenu.populateCastVideoMenu(this)"/>
</menu>
<menuitem id="context-sendaudio"
label="&emailAudioCmd.label;"
accesskey="&emailAudioCmd.accesskey;"
oncommand="gContextMenu.sendMedia();"/>
<menuitem id="context-ctp-play"
label="&playPluginCmd.label;"
accesskey="&playPluginCmd.accesskey;"
oncommand="gContextMenu.playPlugin();"/>
<menuitem id="context-ctp-hide"
label="&hidePluginCmd.label;"
accesskey="&hidePluginCmd.accesskey;"
oncommand="gContextMenu.hidePlugin();"/>
<menuseparator id="context-sep-ctp"/>
<menuitem id="context-savepage"
label="&savePageCmd.label;"
accesskey="&savePageCmd.accesskey2;"
oncommand="gContextMenu.savePageAs();"/>
<menuseparator id="context-sep-sendpagetodevice" hidden="true"/>
<menuseparator id="context-sep-viewbgimage"/>
<menuitem id="context-viewbgimage"
label="&viewBGImageCmd.label;"
accesskey="&viewBGImageCmd.accesskey;"
oncommand="gContextMenu.viewBGImage(event);"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-undo"
label="&undoCmd.label;"
accesskey="&undoCmd.accesskey;"
command="cmd_undo"/>
<menuseparator id="context-sep-undo"/>
<menuitem id="context-cut"
label="&cutCmd.label;"
accesskey="&cutCmd.accesskey;"
command="cmd_cut"/>
<menuitem id="context-copy"
label="&copyCmd.label;"
accesskey="&copyCmd.accesskey;"
command="cmd_copy"/>
<menuitem id="context-paste"
label="&pasteCmd.label;"
accesskey="&pasteCmd.accesskey;"
command="cmd_paste"/>
<menuitem id="context-delete"
label="&deleteCmd.label;"
accesskey="&deleteCmd.accesskey;"
command="cmd_delete"/>
<menuseparator id="context-sep-paste"/>
<menuitem id="context-selectall"
label="&selectAllCmd.label;"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAll"/>
<menuseparator id="context-sep-selectall"/>
<menuitem id="context-keywordfield"
label="&keywordfield.label;"
accesskey="&keywordfield.accesskey;"
oncommand="AddKeywordForSearchField();"/>
<menuitem id="context-searchselect"
oncommand="BrowserSearch.loadSearchFromContext(this.searchTerms);"/>
<menuseparator id="context-sep-sendlinktodevice" hidden="true"/>
<menuseparator id="frame-sep"/>
<menu id="frame" label="&thisFrameMenu.label;" accesskey="&thisFrameMenu.accesskey;">
<menupopup>
<menuitem id="context-showonlythisframe"
label="&showOnlyThisFrameCmd.label;"
accesskey="&showOnlyThisFrameCmd.accesskey;"
oncommand="gContextMenu.showOnlyThisFrame();"/>
<menuitem id="context-openframeintab"
label="&openFrameCmdInTab.label;"
accesskey="&openFrameCmdInTab.accesskey;"
oncommand="gContextMenu.openFrameInTab();"/>
<menuitem id="context-openframe"
label="&openFrameCmd.label;"
accesskey="&openFrameCmd.accesskey;"
oncommand="gContextMenu.openFrame();"/>
<menuseparator id="open-frame-sep"/>
<menuitem id="context-reloadframe"
label="&reloadFrameCmd.label;"
accesskey="&reloadFrameCmd.accesskey;"
oncommand="gContextMenu.reloadFrame();"/>
<menuseparator/>
<menuitem id="context-bookmarkframe"
label="&bookmarkThisFrameCmd.label;"
accesskey="&bookmarkThisFrameCmd.accesskey;"
oncommand="gContextMenu.addBookmarkForFrame();"/>
<menuitem id="context-saveframe"
label="&saveFrameCmd.label;"
accesskey="&saveFrameCmd.accesskey;"
oncommand="gContextMenu.saveFrame();"/>
<menuseparator/>
<menuitem id="context-printframe"
label="&printFrameCmd.label;"
accesskey="&printFrameCmd.accesskey;"
oncommand="gContextMenu.printFrame();"/>
<menuseparator/>
<menuitem id="context-viewframesource"
label="&viewFrameSourceCmd.label;"
accesskey="&viewFrameSourceCmd.accesskey;"
oncommand="gContextMenu.viewFrameSource();"
observes="isFrameImage"/>
<menuitem id="context-viewframeinfo"
label="&viewFrameInfoCmd.label;"
accesskey="&viewFrameInfoCmd.accesskey;"
oncommand="gContextMenu.viewFrameInfo();"/>
</menupopup>
</menu>
<menuitem id="context-viewpartialsource-selection"
label="&viewPartialSourceForSelectionCmd.label;"
accesskey="&viewPartialSourceCmd.accesskey;"
oncommand="gContextMenu.viewPartialSource('selection');"
observes="isImage"/>
<menuitem id="context-viewpartialsource-mathml"
label="&viewPartialSourceForMathMLCmd.label;"
accesskey="&viewPartialSourceCmd.accesskey;"
oncommand="gContextMenu.viewPartialSource('mathml');"
observes="isImage"/>
<menuseparator id="context-sep-viewsource"/>
<menuitem id="context-viewsource"
label="&viewPageSourceCmd.label;"
accesskey="&viewPageSourceCmd.accesskey;"
oncommand="BrowserViewSource(gContextMenu.browser);"
observes="canViewSource"/>
<menuitem id="context-viewinfo"
label="&viewPageInfoCmd.label;"
accesskey="&viewPageInfoCmd.accesskey;"
oncommand="gContextMenu.viewInfo();"/>
<menuseparator id="spell-separator"/>
<menuitem id="spell-check-enabled"
label="&spellCheckToggle.label;"
type="checkbox"
accesskey="&spellCheckToggle.accesskey;"
oncommand="InlineSpellCheckerUI.toggleEnabled(window);"/>
<menuitem id="spell-add-dictionaries-main"
label="&spellAddDictionaries.label;"
accesskey="&spellAddDictionaries.accesskey;"
oncommand="gContextMenu.addDictionaries();"/>
<menu id="spell-dictionaries"
label="&spellDictionaries.label;"
accesskey="&spellDictionaries.accesskey;">
<menupopup id="spell-dictionaries-menu">
<menuseparator id="spell-language-separator"/>
<menuitem id="spell-add-dictionaries"
label="&spellAddDictionaries.label;"
accesskey="&spellAddDictionaries.accesskey;"
oncommand="gContextMenu.addDictionaries();"/>
</menupopup>
</menu>
<menuseparator hidden="true" id="context-sep-bidi"/>
<menuitem hidden="true" id="context-bidi-text-direction-toggle"
label="&bidiSwitchTextDirectionItem.label;"
accesskey="&bidiSwitchTextDirectionItem.accesskey;"
command="cmd_switchTextDirection"/>
<menuitem hidden="true" id="context-bidi-page-direction-toggle"
label="&bidiSwitchPageDirectionItem.label;"
accesskey="&bidiSwitchPageDirectionItem.accesskey;"
oncommand="gContextMenu.switchPageDirection();"/>
<menuseparator id="fill-login-separator" hidden="true"/>
<menu id="fill-login"
label="&fillLoginMenu.label;"
label-login="&fillLoginMenu.label;"
label-password="&fillPasswordMenu.label;"
label-username="&fillUsernameMenu.label;"
accesskey="&fillLoginMenu.accesskey;"
accesskey-login="&fillLoginMenu.accesskey;"
accesskey-password="&fillPasswordMenu.accesskey;"
accesskey-username="&fillUsernameMenu.accesskey;"
hidden="true">
<menupopup id="fill-login-popup">
<menuitem id="fill-login-no-logins"
label="&noLoginSuggestions.label;"
disabled="true"
hidden="true"/>
<menuseparator id="saved-logins-separator"/>
<menuitem id="fill-login-saved-passwords"
label="&viewSavedLogins.label;"
oncommand="gContextMenu.openPasswordManager();"/>
</menupopup>
</menu>
#ifdef MOZ_DEVTOOLS
<menuseparator id="inspect-separator" hidden="true"/>
<menuitem id="context-inspect"
hidden="true"
label="&inspectContextMenu.label;"
accesskey="&inspectContextMenu.accesskey;"
oncommand="gContextMenu.inspectNode();"/>
#endif
<menuseparator id="context-media-eme-separator" hidden="true"/>
<menuitem id="context-media-eme-learnmore"
class="menuitem-iconic"
hidden="true"
label="&emeLearnMoreContextMenu.label;"
accesskey="&emeLearnMoreContextMenu.accesskey;"
oncommand="gContextMenu.drmLearnMore(event);"
onclick="checkForMiddleClick(this, event);"/>
@@ -1,587 +0,0 @@
/* 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/. */
/**
* Tab previews utility, produces thumbnails
*/
var tabPreviews = {
init: function tabPreviews_init() {
if (this._selectedTab)
return;
this._selectedTab = gBrowser.selectedTab;
gBrowser.tabContainer.addEventListener("TabSelect", this, false);
gBrowser.tabContainer.addEventListener("SSTabRestored", this, false);
let screenManager = Cc["@mozilla.org/gfx/screenmanager;1"]
.getService(Ci.nsIScreenManager);
let left = {}, top = {}, width = {}, height = {};
screenManager.primaryScreen.GetRectDisplayPix(left, top, width, height);
this.aspectRatio = height.value / width.value;
},
get: function tabPreviews_get(aTab) {
let uri = aTab.linkedBrowser.currentURI.spec;
if (aTab.__thumbnail_lastURI &&
aTab.__thumbnail_lastURI != uri) {
aTab.__thumbnail = null;
aTab.__thumbnail_lastURI = null;
}
if (aTab.__thumbnail)
return aTab.__thumbnail;
if (aTab.getAttribute("pending") == "true") {
let img = new Image;
img.src = PageThumbs.getThumbnailURL(uri);
return img;
}
return this.capture(aTab, !aTab.hasAttribute("busy"));
},
capture: function tabPreviews_capture(aTab, aShouldCache) {
let browser = aTab.linkedBrowser;
let uri = browser.currentURI.spec;
let canvas = PageThumbs.createCanvas(window);
PageThumbs.shouldStoreThumbnail(browser, (aDoStore) => {
if (aDoStore && aShouldCache) {
PageThumbs.captureAndStore(browser, function () {
let img = new Image;
img.src = PageThumbs.getThumbnailURL(uri);
aTab.__thumbnail = img;
aTab.__thumbnail_lastURI = uri;
canvas.getContext("2d").drawImage(img, 0, 0);
});
} else {
PageThumbs.captureToCanvas(browser, canvas, () => {
if (aShouldCache) {
aTab.__thumbnail = canvas;
aTab.__thumbnail_lastURI = uri;
}
});
}
});
return canvas;
},
handleEvent: function tabPreviews_handleEvent(event) {
switch (event.type) {
case "TabSelect":
if (this._selectedTab &&
this._selectedTab.parentNode &&
!this._pendingUpdate) {
// Generate a thumbnail for the tab that was selected.
// The timeout keeps the UI snappy and prevents us from generating thumbnails
// for tabs that will be closed. During that timeout, don't generate other
// thumbnails in case multiple TabSelect events occur fast in succession.
this._pendingUpdate = true;
setTimeout(function (self, aTab) {
self._pendingUpdate = false;
if (aTab.parentNode &&
!aTab.hasAttribute("busy") &&
!aTab.hasAttribute("pending"))
self.capture(aTab, true);
}, 2000, this, this._selectedTab);
}
this._selectedTab = event.target;
break;
case "SSTabRestored":
this.capture(event.target, true);
break;
}
}
};
var tabPreviewPanelHelper = {
opening: function (host) {
host.panel.hidden = false;
var handler = this._generateHandler(host);
host.panel.addEventListener("popupshown", handler, false);
host.panel.addEventListener("popuphiding", handler, false);
host._prevFocus = document.commandDispatcher.focusedElement;
},
_generateHandler: function (host) {
var self = this;
return function (event) {
if (event.target == host.panel) {
host.panel.removeEventListener(event.type, arguments.callee, false);
self["_" + event.type](host);
}
};
},
_popupshown: function (host) {
if ("setupGUI" in host)
host.setupGUI();
},
_popuphiding: function (host) {
if ("suspendGUI" in host)
host.suspendGUI();
if (host._prevFocus) {
Services.focus.setFocus(host._prevFocus, Ci.nsIFocusManager.FLAG_NOSCROLL);
host._prevFocus = null;
} else
gBrowser.selectedBrowser.focus();
if (host.tabToSelect) {
gBrowser.selectedTab = host.tabToSelect;
host.tabToSelect = null;
}
}
};
/**
* Ctrl-Tab panel
*/
var ctrlTab = {
get panel () {
delete this.panel;
return this.panel = document.getElementById("ctrlTab-panel");
},
get showAllButton () {
delete this.showAllButton;
return this.showAllButton = document.getElementById("ctrlTab-showAll");
},
get previews () {
delete this.previews;
return this.previews = this.panel.getElementsByClassName("ctrlTab-preview");
},
get maxTabPreviews () {
delete this.maxTabPreviews;
return this.maxTabPreviews = this.previews.length - 1;
},
get canvasWidth () {
delete this.canvasWidth;
return this.canvasWidth = Math.ceil(screen.availWidth * .85 / this.maxTabPreviews);
},
get canvasHeight () {
delete this.canvasHeight;
return this.canvasHeight = Math.round(this.canvasWidth * tabPreviews.aspectRatio);
},
get keys () {
var keys = {};
["close", "find", "selectAll"].forEach(function (key) {
keys[key] = document.getElementById("key_" + key)
.getAttribute("key")
.toLocaleLowerCase().charCodeAt(0);
});
delete this.keys;
return this.keys = keys;
},
_selectedIndex: 0,
get selected () {
return this._selectedIndex < 0 ?
document.activeElement :
this.previews.item(this._selectedIndex);
},
get isOpen () {
return this.panel.state == "open" || this.panel.state == "showing" || this._timer;
},
get tabCount () {
return this.tabList.length;
},
get tabPreviewCount () {
return Math.min(this.maxTabPreviews, this.tabCount);
},
get tabList () {
return this._recentlyUsedTabs;
},
init: function ctrlTab_init() {
if (!this._recentlyUsedTabs) {
tabPreviews.init();
this._initRecentlyUsedTabs();
this._init(true);
}
},
uninit: function ctrlTab_uninit() {
this._recentlyUsedTabs = null;
this._init(false);
},
prefName: "browser.ctrlTab.previews",
readPref: function ctrlTab_readPref() {
var enable =
gPrefService.getBoolPref(this.prefName) &&
(!gPrefService.prefHasUserValue("browser.ctrlTab.disallowForScreenReaders") ||
!gPrefService.getBoolPref("browser.ctrlTab.disallowForScreenReaders"));
if (enable)
this.init();
else
this.uninit();
},
observe: function (aSubject, aTopic, aPrefName) {
this.readPref();
},
updatePreviews: function ctrlTab_updatePreviews() {
for (let i = 0; i < this.previews.length; i++)
this.updatePreview(this.previews[i], this.tabList[i]);
var showAllLabel = gNavigatorBundle.getString("ctrlTab.listAllTabs.label");
this.showAllButton.label =
PluralForm.get(this.tabCount, showAllLabel).replace("#1", this.tabCount);
this.showAllButton.hidden = !allTabs.canOpen;
},
updatePreview: function ctrlTab_updatePreview(aPreview, aTab) {
if (aPreview == this.showAllButton)
return;
aPreview._tab = aTab;
if (aPreview.firstChild)
aPreview.removeChild(aPreview.firstChild);
if (aTab) {
let canvasWidth = this.canvasWidth;
let canvasHeight = this.canvasHeight;
aPreview.appendChild(tabPreviews.get(aTab));
aPreview.setAttribute("label", aTab.label);
aPreview.setAttribute("tooltiptext", aTab.label);
aPreview.setAttribute("crop", aTab.crop);
aPreview.setAttribute("canvaswidth", canvasWidth);
aPreview.setAttribute("canvasstyle",
"max-width:" + canvasWidth + "px;" +
"min-width:" + canvasWidth + "px;" +
"max-height:" + canvasHeight + "px;" +
"min-height:" + canvasHeight + "px;");
if (aTab.image)
aPreview.setAttribute("image", aTab.image);
else
aPreview.removeAttribute("image");
aPreview.hidden = false;
} else {
aPreview.hidden = true;
aPreview.removeAttribute("label");
aPreview.removeAttribute("tooltiptext");
aPreview.removeAttribute("image");
}
},
advanceFocus: function ctrlTab_advanceFocus(aForward) {
let selectedIndex = Array.indexOf(this.previews, this.selected);
do {
selectedIndex += aForward ? 1 : -1;
if (selectedIndex < 0)
selectedIndex = this.previews.length - 1;
else if (selectedIndex >= this.previews.length)
selectedIndex = 0;
} while (this.previews[selectedIndex].hidden);
if (this._selectedIndex == -1) {
// Focus is already in the panel.
this.previews[selectedIndex].focus();
} else {
this._selectedIndex = selectedIndex;
}
if (this._timer) {
clearTimeout(this._timer);
this._timer = null;
this._openPanel();
}
},
_mouseOverFocus: function ctrlTab_mouseOverFocus(aPreview) {
if (this._trackMouseOver)
aPreview.focus();
},
pick: function ctrlTab_pick(aPreview) {
if (!this.tabCount)
return;
var select = (aPreview || this.selected);
if (select == this.showAllButton)
this.showAllTabs();
else
this.close(select._tab);
},
showAllTabs: function ctrlTab_showAllTabs(aPreview) {
this.close();
document.getElementById("Browser:ShowAllTabs").doCommand();
},
remove: function ctrlTab_remove(aPreview) {
if (aPreview._tab)
gBrowser.removeTab(aPreview._tab);
},
attachTab: function ctrlTab_attachTab(aTab, aPos) {
if (aTab.closing)
return;
if (aPos == 0)
this._recentlyUsedTabs.unshift(aTab);
else if (aPos)
this._recentlyUsedTabs.splice(aPos, 0, aTab);
else
this._recentlyUsedTabs.push(aTab);
},
detachTab: function ctrlTab_detachTab(aTab) {
var i = this._recentlyUsedTabs.indexOf(aTab);
if (i >= 0)
this._recentlyUsedTabs.splice(i, 1);
},
open: function ctrlTab_open() {
if (this.isOpen)
return;
document.addEventListener("keyup", this, true);
this.updatePreviews();
this._selectedIndex = 1;
// Add a slight delay before showing the UI, so that a quick
// "ctrl-tab" keypress just flips back to the MRU tab.
this._timer = setTimeout(function (self) {
self._timer = null;
self._openPanel();
}, 200, this);
},
_openPanel: function ctrlTab_openPanel() {
tabPreviewPanelHelper.opening(this);
this.panel.width = Math.min(screen.availWidth * .99,
this.canvasWidth * 1.25 * this.tabPreviewCount);
var estimateHeight = this.canvasHeight * 1.25 + 75;
this.panel.openPopupAtScreen(screen.availLeft + (screen.availWidth - this.panel.width) / 2,
screen.availTop + (screen.availHeight - estimateHeight) / 2,
false);
},
close: function ctrlTab_close(aTabToSelect) {
if (!this.isOpen)
return;
if (this._timer) {
clearTimeout(this._timer);
this._timer = null;
this.suspendGUI();
if (aTabToSelect)
gBrowser.selectedTab = aTabToSelect;
return;
}
this.tabToSelect = aTabToSelect;
this.panel.hidePopup();
},
setupGUI: function ctrlTab_setupGUI() {
this.selected.focus();
this._selectedIndex = -1;
// Track mouse movement after a brief delay so that the item that happens
// to be under the mouse pointer initially won't be selected unintentionally.
this._trackMouseOver = false;
setTimeout(function (self) {
if (self.isOpen)
self._trackMouseOver = true;
}, 0, this);
},
suspendGUI: function ctrlTab_suspendGUI() {
document.removeEventListener("keyup", this, true);
for (let preview of this.previews) {
this.updatePreview(preview, null);
}
},
onKeyPress: function ctrlTab_onKeyPress(event) {
var isOpen = this.isOpen;
if (isOpen) {
event.preventDefault();
event.stopPropagation();
}
switch (event.keyCode) {
case event.DOM_VK_TAB:
if (event.ctrlKey && !event.altKey && !event.metaKey) {
if (isOpen) {
this.advanceFocus(!event.shiftKey);
} else if (!event.shiftKey) {
event.preventDefault();
event.stopPropagation();
let tabs = gBrowser.visibleTabs;
if (tabs.length > 2) {
this.open();
} else if (tabs.length == 2) {
let index = tabs[0].selected ? 1 : 0;
gBrowser.selectedTab = tabs[index];
}
}
}
break;
default:
if (isOpen && event.ctrlKey) {
if (event.keyCode == event.DOM_VK_DELETE) {
this.remove(this.selected);
break;
}
switch (event.charCode) {
case this.keys.close:
this.remove(this.selected);
break;
case this.keys.find:
case this.keys.selectAll:
this.showAllTabs();
break;
}
}
}
},
removeClosingTabFromUI: function ctrlTab_removeClosingTabFromUI(aTab) {
if (this.tabCount == 2) {
this.close();
return;
}
this.updatePreviews();
if (this.selected.hidden)
this.advanceFocus(false);
if (this.selected == this.showAllButton)
this.advanceFocus(false);
// If the current tab is removed, another tab can steal our focus.
if (aTab.selected && this.panel.state == "open") {
setTimeout(function (selected) {
selected.focus();
}, 0, this.selected);
}
},
handleEvent: function ctrlTab_handleEvent(event) {
switch (event.type) {
case "SSWindowRestored":
this._initRecentlyUsedTabs();
break;
case "TabAttrModified":
// tab attribute modified (e.g. label, crop, busy, image, selected)
for (let i = this.previews.length - 1; i >= 0; i--) {
if (this.previews[i]._tab && this.previews[i]._tab == event.target) {
this.updatePreview(this.previews[i], event.target);
break;
}
}
break;
case "TabSelect":
this.detachTab(event.target);
this.attachTab(event.target, 0);
break;
case "TabOpen":
this.attachTab(event.target, 1);
break;
case "TabClose":
this.detachTab(event.target);
if (this.isOpen)
this.removeClosingTabFromUI(event.target);
break;
case "keypress":
this.onKeyPress(event);
break;
case "keyup":
if (event.keyCode == event.DOM_VK_CONTROL)
this.pick();
break;
case "popupshowing":
if (event.target.id == "menu_viewPopup")
document.getElementById("menu_showAllTabs").hidden = !allTabs.canOpen;
break;
}
},
filterForThumbnailExpiration: function (aCallback) {
// Save a few more thumbnails than we actually display, so that when tabs
// are closed, the previews we add instead still get thumbnails.
const extraThumbnails = 3;
const thumbnailCount = Math.min(this.tabPreviewCount + extraThumbnails,
this.tabCount);
let urls = [];
for (let i = 0; i < thumbnailCount; i++)
urls.push(this.tabList[i].linkedBrowser.currentURI.spec);
aCallback(urls);
},
_initRecentlyUsedTabs: function () {
this._recentlyUsedTabs =
Array.filter(gBrowser.tabs, tab => !tab.closing)
.sort((tab1, tab2) => tab2.lastAccessed - tab1.lastAccessed);
},
_init: function ctrlTab__init(enable) {
var toggleEventListener = enable ? "addEventListener" : "removeEventListener";
window[toggleEventListener]("SSWindowRestored", this, false);
var tabContainer = gBrowser.tabContainer;
tabContainer[toggleEventListener]("TabOpen", this, false);
tabContainer[toggleEventListener]("TabAttrModified", this, false);
tabContainer[toggleEventListener]("TabSelect", this, false);
tabContainer[toggleEventListener]("TabClose", this, false);
document[toggleEventListener]("keypress", this, false);
gBrowser.mTabBox.handleCtrlTab = !enable;
if (enable)
PageThumbs.addExpirationFilter(this);
else
PageThumbs.removeExpirationFilter(this);
// If we're not running, hide the "Show All Tabs" menu item,
// as Shift+Ctrl+Tab will be handled by the tab bar.
document.getElementById("menu_showAllTabs").hidden = !enable;
document.getElementById("menu_viewPopup")[toggleEventListener]("popupshowing", this);
// Also disable the <key> to ensure Shift+Ctrl+Tab never triggers
// Show All Tabs.
var key_showAllTabs = document.getElementById("key_showAllTabs");
if (enable)
key_showAllTabs.removeAttribute("disabled");
else
key_showAllTabs.setAttribute("disabled", "true");
}
};
/**
* All Tabs menu
*/
var allTabs = {
get toolbarButton() {
return document.getElementById("alltabs-button");
},
get canOpen() {
return isElementVisible(this.toolbarButton);
},
open: function allTabs_open() {
if (this.canOpen) {
// Without setTimeout, the menupopup won't stay open when invoking
// "View > Show All Tabs" and the menu bar auto-hides.
setTimeout(() => {
this.toolbarButton.open = true;
}, 0);
}
}
};
@@ -1,100 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
/**
* Customization handler prepares this browser window for entering and exiting
* customization mode by handling customizationstarting and customizationending
* events.
*/
var CustomizationHandler = {
handleEvent: function(aEvent) {
switch (aEvent.type) {
case "customizationstarting":
this._customizationStarting();
break;
case "customizationchange":
this._customizationChange();
break;
case "customizationending":
this._customizationEnding(aEvent.detail);
break;
}
},
isCustomizing: function() {
return document.documentElement.hasAttribute("customizing");
},
_customizationStarting: function() {
// Disable the toolbar context menu items
let menubar = document.getElementById("main-menubar");
for (let childNode of menubar.childNodes)
childNode.setAttribute("disabled", true);
let cmd = document.getElementById("cmd_CustomizeToolbars");
cmd.setAttribute("disabled", "true");
UpdateUrlbarSearchSplitterState();
CombinedStopReload.uninit();
PlacesToolbarHelper.customizeStart();
DownloadsButton.customizeStart();
// The additional padding on the sides of the browser
// can cause the customize tab to get clipped.
let tabContainer = gBrowser.tabContainer;
if (tabContainer.getAttribute("overflow") == "true") {
let tabstrip = tabContainer.mTabstrip;
tabstrip.ensureElementIsVisible(gBrowser.selectedTab, true);
}
},
_customizationChange: function() {
PlacesToolbarHelper.customizeChange();
},
_customizationEnding: function(aDetails) {
// Update global UI elements that may have been added or removed
if (aDetails.changed) {
gURLBar = document.getElementById("urlbar");
gHomeButton.updateTooltip();
XULBrowserWindow.init();
if (AppConstants.platform != "macosx")
updateEditUIVisibility();
// Hacky: update the PopupNotifications' object's reference to the iconBox,
// if it already exists, since it may have changed if the URL bar was
// added/removed.
if (!window.__lookupGetter__("PopupNotifications")) {
PopupNotifications.iconBox =
document.getElementById("notification-popup-box");
}
}
PlacesToolbarHelper.customizeDone();
DownloadsButton.customizeDone();
// The url bar splitter state is dependent on whether stop/reload
// and the location bar are combined, so we need this ordering
CombinedStopReload.init();
UpdateUrlbarSearchSplitterState();
// Update the urlbar
URLBarSetURI();
XULBrowserWindow.asyncUpdateUI();
// Re-enable parts of the UI we disabled during the dialog
let menubar = document.getElementById("main-menubar");
for (let childNode of menubar.childNodes)
childNode.setAttribute("disabled", false);
let cmd = document.getElementById("cmd_CustomizeToolbars");
cmd.removeAttribute("disabled");
gBrowser.selectedBrowser.focus();
}
}
@@ -1,127 +0,0 @@
/* 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/. */
const LOGGER_NAME = "Toolkit.Telemetry";
const LOGGER_PREFIX = "DataNotificationInfoBar::";
/**
* Represents an info bar that shows a data submission notification.
*/
var gDataNotificationInfoBar = {
_OBSERVERS: [
"datareporting:notify-data-policy:request",
"datareporting:notify-data-policy:close",
],
_DATA_REPORTING_NOTIFICATION: "data-reporting",
get _notificationBox() {
delete this._notificationBox;
return this._notificationBox = document.getElementById("global-notificationbox");
},
get _log() {
let Log = Cu.import("resource://gre/modules/Log.jsm", {}).Log;
delete this._log;
return this._log = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, LOGGER_PREFIX);
},
init: function() {
window.addEventListener("unload", () => {
for (let o of this._OBSERVERS) {
Services.obs.removeObserver(this, o);
}
}, false);
for (let o of this._OBSERVERS) {
Services.obs.addObserver(this, o, true);
}
},
_getDataReportingNotification: function (name=this._DATA_REPORTING_NOTIFICATION) {
return this._notificationBox.getNotificationWithValue(name);
},
_displayDataPolicyInfoBar: function (request) {
if (this._getDataReportingNotification()) {
return;
}
let brandBundle = document.getElementById("bundle_brand");
let appName = brandBundle.getString("brandShortName");
let vendorName = brandBundle.getString("vendorShortName");
let message = gNavigatorBundle.getFormattedString(
"dataReportingNotification.message",
[appName, vendorName]);
this._actionTaken = false;
let buttons = [{
label: gNavigatorBundle.getString("dataReportingNotification.button.label"),
accessKey: gNavigatorBundle.getString("dataReportingNotification.button.accessKey"),
popup: null,
callback: () => {
this._actionTaken = true;
window.openAdvancedPreferences("dataChoicesTab");
},
}];
this._log.info("Creating data reporting policy notification.");
this._notificationBox.appendNotification(
message,
this._DATA_REPORTING_NOTIFICATION,
null,
this._notificationBox.PRIORITY_INFO_HIGH,
buttons,
event => {
if (event == "removed") {
Services.obs.notifyObservers(null, "datareporting:notify-data-policy:close", null);
}
}
);
// It is important to defer calling onUserNotifyComplete() until we're
// actually sure the notification was displayed. If we ever called
// onUserNotifyComplete() without showing anything to the user, that
// would be very good for user choice. It may also have legal impact.
request.onUserNotifyComplete();
},
_clearPolicyNotification: function () {
let notification = this._getDataReportingNotification();
if (notification) {
this._log.debug("Closing notification.");
notification.close();
}
},
observe: function(subject, topic, data) {
switch (topic) {
case "datareporting:notify-data-policy:request":
let request = subject.wrappedJSObject.object;
try {
this._displayDataPolicyInfoBar(request);
} catch (ex) {
request.onUserNotifyFailed(ex);
return;
}
break;
case "datareporting:notify-data-policy:close":
// If this observer fires, it means something else took care of
// responding. Therefore, we don't need to do anything. So, we
// act like we took action and clear state.
this._actionTaken = true;
this._clearPolicyNotification();
break;
default:
}
},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIObserver,
Ci.nsISupportsWeakReference,
]),
};
@@ -1,27 +0,0 @@
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
%browserDTD;
<!ENTITY % baseMenuDTD SYSTEM "chrome://browser/locale/baseMenuOverlay.dtd" >
%baseMenuDTD;
<!ENTITY % charsetDTD SYSTEM "chrome://global/locale/charsetMenu.dtd" >
%charsetDTD;
<!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd" >
%textcontextDTD;
<!ENTITY % customizeToolbarDTD SYSTEM "chrome://global/locale/customizeToolbar.dtd">
%customizeToolbarDTD;
<!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
%placesDTD;
#ifdef MOZ_SAFE_BROWSING
<!ENTITY % safebrowsingDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
%safebrowsingDTD;
#endif
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
%aboutHomeDTD;
#ifdef MOZ_SERVICES_SYNC
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
%syncBrandDTD;
#endif
]>
@@ -1,646 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask",
"resource://gre/modules/DeferredTask.jsm");
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
const PREF_SHOW_FIRST_RUN_UI = "browser.feeds.showFirstRunUI";
const PREF_SELECTED_APP = "browser.feeds.handlers.application";
const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
const PREF_SELECTED_ACTION = "browser.feeds.handler";
const PREF_SELECTED_READER = "browser.feeds.handler.default";
const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
const PREF_UPDATE_DELAY = 2000;
const SETTABLE_PREFS = new Set([
PREF_VIDEO_SELECTED_ACTION,
PREF_AUDIO_SELECTED_ACTION,
PREF_SELECTED_ACTION,
PREF_VIDEO_SELECTED_READER,
PREF_AUDIO_SELECTED_READER,
PREF_SELECTED_READER,
PREF_VIDEO_SELECTED_WEB,
PREF_AUDIO_SELECTED_WEB,
PREF_SELECTED_WEB
]);
const EXECUTABLE_PREFS = new Set([
PREF_SELECTED_APP,
PREF_VIDEO_SELECTED_APP,
PREF_AUDIO_SELECTED_APP
]);
const VALID_ACTIONS = new Set(["ask", "reader", "bookmarks"]);
const VALID_READERS = new Set(["web", "client", "default", "bookmarks"]);
XPCOMUtils.defineLazyPreferenceGetter(this, "SHOULD_LOG",
"feeds.log", false);
function LOG(str) {
if (SHOULD_LOG)
dump("*** Feeds: " + str + "\n");
}
function getPrefActionForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_ACTION;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_ACTION;
default:
return PREF_SELECTED_ACTION;
}
}
function getPrefReaderForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_READER;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_READER;
default:
return PREF_SELECTED_READER;
}
}
function getPrefWebForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_WEB;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_WEB;
default:
return PREF_SELECTED_WEB;
}
}
function getPrefAppForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_APP;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_APP;
default:
return PREF_SELECTED_APP;
}
}
/**
* Maps a feed type to a maybe-feed mimetype.
*/
function getMimeTypeForFeedType(aFeedType) {
switch (aFeedType) {
case Ci.nsIFeed.TYPE_VIDEO:
return TYPE_MAYBE_VIDEO_FEED;
case Ci.nsIFeed.TYPE_AUDIO:
return TYPE_MAYBE_AUDIO_FEED;
default:
return TYPE_MAYBE_FEED;
}
}
/**
* The Feed Handler object manages discovery of RSS/ATOM feeds in web pages
* and shows UI when they are discovered.
*/
var FeedHandler = {
_prefChangeCallback: null,
/** Called when the user clicks on the Subscribe to This Page... menu item,
* or when the user clicks the feed button when the page contains multiple
* feeds.
* Builds a menu of unique feeds associated with the page, and if there
* is only one, shows the feed inline in the browser window.
* @param container
* The feed list container (menupopup or subview) to be populated.
* @param isSubview
* Whether we're creating a subview (true) or menu (false/undefined)
* @return true if the menu/subview should be shown, false if there was only
* one feed and the feed should be shown inline in the browser
* window (do not show the menupopup/subview).
*/
buildFeedList(container, isSubview) {
let feeds = gBrowser.selectedBrowser.feeds;
if (!isSubview && feeds == null) {
// XXX hack -- menu opening depends on setting of an "open"
// attribute, and the menu refuses to open if that attribute is
// set (because it thinks it's already open). onpopupshowing gets
// called after the attribute is unset, and it doesn't get unset
// if we return false. so we unset it here; otherwise, the menu
// refuses to work past this point.
container.parentNode.removeAttribute("open");
return false;
}
for (let i = container.childNodes.length - 1; i >= 0; --i) {
let node = container.childNodes[i];
if (isSubview && node.localName == "label")
continue;
container.removeChild(node);
}
if (!feeds || feeds.length <= 1)
return false;
// Build the menu showing the available feed choices for viewing.
let itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
for (let feedInfo of feeds) {
let item = document.createElement(itemNodeType);
let baseTitle = feedInfo.title || feedInfo.href;
item.setAttribute("label", baseTitle);
item.setAttribute("feed", feedInfo.href);
item.setAttribute("tooltiptext", feedInfo.href);
item.setAttribute("crop", "center");
let className = "feed-" + itemNodeType;
if (isSubview) {
className += " subviewbutton";
}
item.setAttribute("class", className);
container.appendChild(item);
}
return true;
},
/**
* Subscribe to a given feed. Called when
* 1. Page has a single feed and user clicks feed icon in location bar
* 2. Page has a single feed and user selects Subscribe menu item
* 3. Page has multiple feeds and user selects from feed icon popup (or subview)
* 4. Page has multiple feeds and user selects from Subscribe submenu
* @param href
* The feed to subscribe to. May be null, in which case the
* event target's feed attribute is examined.
* @param event
* The event this method is handling. Used to decide where
* to open the preview UI. (Optional, unless href is null)
*/
subscribeToFeed(href, event) {
// Just load the feed in the content area to either subscribe or show the
// preview UI
if (!href)
href = event.target.getAttribute("feed");
urlSecurityCheck(href, gBrowser.contentPrincipal,
Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
let feedURI = makeURI(href, document.characterSet);
// Use the feed scheme so X-Moz-Is-Feed will be set
// The value doesn't matter
if (/^https?$/.test(feedURI.scheme))
href = "feed:" + href;
this.loadFeed(href, event);
},
loadFeed(href, event) {
let feeds = gBrowser.selectedBrowser.feeds;
try {
openUILink(href, event, { ignoreAlt: true });
}
finally {
// We might default to a livebookmarks modal dialog,
// so reset that if the user happens to click it again
gBrowser.selectedBrowser.feeds = feeds;
}
},
get _feedMenuitem() {
delete this._feedMenuitem;
return this._feedMenuitem = document.getElementById("singleFeedMenuitemState");
},
get _feedMenupopup() {
delete this._feedMenupopup;
return this._feedMenupopup = document.getElementById("multipleFeedsMenuState");
},
/**
* Update the browser UI to show whether or not feeds are available when
* a page is loaded or the user switches tabs to a page that has feeds.
*/
updateFeeds() {
if (this._updateFeedTimeout)
clearTimeout(this._updateFeedTimeout);
let feeds = gBrowser.selectedBrowser.feeds;
let haveFeeds = feeds && feeds.length > 0;
let feedButton = document.getElementById("feed-button");
if (feedButton) {
if (haveFeeds) {
feedButton.removeAttribute("disabled");
} else {
feedButton.setAttribute("disabled", "true");
}
}
if (!haveFeeds) {
this._feedMenuitem.setAttribute("disabled", "true");
this._feedMenuitem.removeAttribute("hidden");
this._feedMenupopup.setAttribute("hidden", "true");
return;
}
if (feeds.length > 1) {
this._feedMenuitem.setAttribute("hidden", "true");
this._feedMenupopup.removeAttribute("hidden");
} else {
this._feedMenuitem.setAttribute("feed", feeds[0].href);
this._feedMenuitem.removeAttribute("disabled");
this._feedMenuitem.removeAttribute("hidden");
this._feedMenupopup.setAttribute("hidden", "true");
}
},
addFeed(link, browserForLink) {
if (!browserForLink.feeds)
browserForLink.feeds = [];
browserForLink.feeds.push({ href: link.href, title: link.title });
// If this addition was for the current browser, update the UI. For
// background browsers, we'll update on tab switch.
if (browserForLink == gBrowser.selectedBrowser) {
// Batch updates to avoid updating the UI for multiple onLinkAdded events
// fired within 100ms of each other.
if (this._updateFeedTimeout)
clearTimeout(this._updateFeedTimeout);
this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
}
},
/**
* Get the human-readable display name of a file. This could be the
* application name.
* @param file
* A nsIFile to look up the name of
* @return The display name of the application represented by the file.
*/
_getFileDisplayName(file) {
switch (AppConstants.platform) {
case "win":
if (file instanceof Ci.nsILocalFileWin) {
try {
return file.getVersionInfoField("FileDescription");
} catch (e) {}
}
break;
case "macosx":
if (file instanceof Ci.nsILocalFileMac) {
try {
return file.bundleDisplayName;
} catch (e) {}
}
break;
}
return file.leafName;
},
_chooseClientApp(aTitle, aTypeName, aBrowser) {
const prefName = getPrefAppForType(aTypeName);
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window, aTitle, Ci.nsIFilePicker.modeOpen);
fp.appendFilters(Ci.nsIFilePicker.filterApps);
fp.open((aResult) => {
if (aResult == Ci.nsIFilePicker.returnOK) {
let selectedApp = fp.file;
if (selectedApp) {
// XXXben - we need to compare this with the running instance
// executable just don't know how to do that via script
// XXXmano TBD: can probably add this to nsIShellService
let appName = "";
switch (AppConstants.platform) {
case "win":
appName = AppConstants.MOZ_APP_NAME + ".exe";
break;
case "macosx":
appName = AppConstants.MOZ_MACBUNDLE_NAME;
break;
default:
appName = AppConstants.MOZ_APP_NAME + "-bin";
break;
}
if (fp.file.leafName != appName) {
Services.prefs.setComplexValue(prefName, Ci.nsILocalFile, selectedApp);
aBrowser.messageManager.sendAsyncMessage("FeedWriter:SetApplicationLauncherMenuItem",
{ name: this._getFileDisplayName(selectedApp),
type: "SelectedAppMenuItem" });
}
}
}
});
},
executeClientApp(aSpec, aTitle, aSubtitle, aFeedHandler) {
// aFeedHandler is either "default", indicating the system default reader, or a pref-name containing
// an nsILocalFile pointing to the feed handler's executable.
let clientApp = null;
if (aFeedHandler == "default") {
clientApp = Cc["@mozilla.org/browser/shell-service;1"]
.getService(Ci.nsIShellService)
.defaultFeedReader;
} else {
clientApp = Services.prefs.getComplexValue(aFeedHandler, Ci.nsILocalFile);
}
// For the benefit of applications that might know how to deal with more
// URLs than just feeds, send feed: URLs in the following format:
//
// http urls: replace scheme with feed, e.g.
// http://foo.com/index.rdf -> feed://foo.com/index.rdf
// other urls: prepend feed: scheme, e.g.
// https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
let feedURI = NetUtil.newURI(aSpec);
if (feedURI.schemeIs("http")) {
feedURI.scheme = "feed";
aSpec = feedURI.spec;
} else {
aSpec = "feed:" + aSpec;
}
// Retrieving the shell service might fail on some systems, most
// notably systems where GNOME is not installed.
try {
let ss = Cc["@mozilla.org/browser/shell-service;1"]
.getService(Ci.nsIShellService);
ss.openApplicationWithURI(clientApp, aSpec);
} catch (e) {
// If we couldn't use the shell service, fallback to using a
// nsIProcess instance
let p = Cc["@mozilla.org/process/util;1"]
.createInstance(Ci.nsIProcess);
p.init(clientApp);
p.run(false, [aSpec], 1);
}
},
// nsISupports
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
init() {
window.messageManager.addMessageListener("FeedWriter:ChooseClientApp", this);
window.messageManager.addMessageListener("FeedWriter:GetSubscriptionUI", this);
window.messageManager.addMessageListener("FeedWriter:SetFeedPrefsAndSubscribe", this);
window.messageManager.addMessageListener("FeedWriter:ShownFirstRun", this);
Services.ppmm.addMessageListener("FeedConverter:ExecuteClientApp", this);
const prefs = Services.prefs;
prefs.addObserver(PREF_SELECTED_ACTION, this, true);
prefs.addObserver(PREF_SELECTED_READER, this, true);
prefs.addObserver(PREF_SELECTED_WEB, this, true);
prefs.addObserver(PREF_VIDEO_SELECTED_ACTION, this, true);
prefs.addObserver(PREF_VIDEO_SELECTED_READER, this, true);
prefs.addObserver(PREF_VIDEO_SELECTED_WEB, this, true);
prefs.addObserver(PREF_AUDIO_SELECTED_ACTION, this, true);
prefs.addObserver(PREF_AUDIO_SELECTED_READER, this, true);
prefs.addObserver(PREF_AUDIO_SELECTED_WEB, this, true);
},
uninit() {
Services.ppmm.removeMessageListener("FeedConverter:ExecuteClientApp", this);
this._prefChangeCallback = null;
},
// nsIObserver
observe(subject, topic, data) {
if (topic == "nsPref:changed") {
LOG(`Pref changed ${data}`)
if (this._prefChangeCallback) {
this._prefChangeCallback.disarm();
}
// Multiple prefs are set at the same time, debounce to reduce noise
// This can happen in one feed and we want to message all feed pages
this._prefChangeCallback = new DeferredTask(() => {
this._prefChanged(data);
}, PREF_UPDATE_DELAY);
this._prefChangeCallback.arm();
}
},
_prefChanged(prefName) {
// Don't observe for PREF_*SELECTED_APP as user likely just picked one
// That is also handled by SetApplicationLauncherMenuItem call
// Rather than the others which happen on subscription
switch (prefName) {
case PREF_SELECTED_READER:
case PREF_SELECTED_WEB:
case PREF_VIDEO_SELECTED_READER:
case PREF_VIDEO_SELECTED_WEB:
case PREF_AUDIO_SELECTED_READER:
case PREF_AUDIO_SELECTED_WEB:
case PREF_SELECTED_ACTION:
case PREF_VIDEO_SELECTED_ACTION:
case PREF_AUDIO_SELECTED_ACTION:
const response = {
default: this._getReaderForType(Ci.nsIFeed.TYPE_FEED),
[Ci.nsIFeed.TYPE_AUDIO]: this._getReaderForType(Ci.nsIFeed.TYPE_AUDIO),
[Ci.nsIFeed.TYPE_VIDEO]: this._getReaderForType(Ci.nsIFeed.TYPE_VIDEO)
};
Services.mm.broadcastAsyncMessage("FeedWriter:PreferenceUpdated",
response);
break;
}
},
_initSubscriptionUIResponse(feedType) {
const wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
getService(Ci.nsIWebContentConverterService);
const handlersRaw = wccr.getContentHandlers(getMimeTypeForFeedType(feedType));
const handlers = [];
for (let handler of handlersRaw) {
LOG(`Handler found: ${handler}`);
handlers.push({
name: handler.name,
uri: handler.uri
});
}
let showFirstRunUI = true;
// eslint-disable-next-line mozilla/use-default-preference-values
try {
showFirstRunUI = Services.prefs.getBoolPref(PREF_SHOW_FIRST_RUN_UI);
} catch (ex) { }
const response = { handlers, showFirstRunUI };
let selectedClientApp;
const feedTypePref = getPrefAppForType(feedType);
try {
selectedClientApp = Services.prefs.getComplexValue(feedTypePref, Ci.nsILocalFile);
} catch (ex) {
// Just do nothing, then we won't bother populating
}
let defaultClientApp = null;
try {
// This can sometimes not exist
defaultClientApp = Cc["@mozilla.org/browser/shell-service;1"]
.getService(Ci.nsIShellService)
.defaultFeedReader;
} catch (ex) {
// Just do nothing, then we don't bother populating
}
if (selectedClientApp && selectedClientApp.exists()) {
if (defaultClientApp && selectedClientApp.path != defaultClientApp.path) {
// Only set the default menu item if it differs from the selected one
response.defaultMenuItem = this._getFileDisplayName(defaultClientApp);
}
response.selectedMenuItem = this._getFileDisplayName(selectedClientApp);
}
response.reader = this._getReaderForType(feedType);
return response;
},
_setPref(aPrefName, aPrefValue, aIsComplex = false) {
LOG(`FeedWriter._setPref ${aPrefName}`);
// Ensure we have a pref that is settable
if (aPrefName && SETTABLE_PREFS.has(aPrefName)) {
if (aIsComplex) {
const supportsString = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
supportsString.data = aPrefValue;
Services.prefs.setComplexValue(aPrefName, Ci.nsISupportsString, supportsString);
} else {
Services.prefs.setCharPref(aPrefName, aPrefValue);
}
} else {
LOG(`FeedWriter._setPref ${aPrefName} not allowed`);
}
},
_getReaderForType(feedType) {
let prefs = Services.prefs;
let handler = "bookmarks";
let url;
// eslint-disable-next-line mozilla/use-default-preference-values
try {
handler = prefs.getCharPref(getPrefReaderForType(feedType));
} catch (ex) { }
if (handler === "web") {
try {
url = prefs.getComplexValue(getPrefWebForType(feedType), Ci.nsISupportsString).data;
} catch (ex) {
LOG("FeedWriter._setSelectedHandler: invalid or no handler in prefs");
url = null;
}
}
const alwaysUse = this._getAlwaysUseState(feedType);
const action = prefs.getCharPref(getPrefActionForType(feedType));
return { handler, url, alwaysUse, action };
},
_getAlwaysUseState(feedType) {
try {
return Services.prefs.getCharPref(getPrefActionForType(feedType)) != "ask";
} catch (ex) { }
return false;
},
receiveMessage(msg) {
let handler;
switch (msg.name) {
case "FeedWriter:GetSubscriptionUI":
const response = this._initSubscriptionUIResponse(msg.data.feedType);
msg.target.messageManager
.sendAsyncMessage("FeedWriter:GetSubscriptionUIResponse",
response);
break;
case "FeedWriter:ChooseClientApp":
this._chooseClientApp(msg.data.title, msg.data.feedType, msg.target);
break;
case "FeedWriter:ShownFirstRun":
Services.prefs.setBoolPref(PREF_SHOW_FIRST_RUN_UI, false);
break;
case "FeedWriter:SetFeedPrefsAndSubscribe":
const settings = msg.data;
if (!settings.action || !VALID_ACTIONS.has(settings.action)) {
LOG(`Invalid action ${settings.action}`);
return;
}
if (!settings.reader || !VALID_READERS.has(settings.reader)) {
LOG(`Invalid reader ${settings.reader}`);
return;
}
const actionPref = getPrefActionForType(settings.feedType);
this._setPref(actionPref, settings.action);
const readerPref = getPrefReaderForType(settings.feedType);
this._setPref(readerPref, settings.reader);
handler = null;
switch (settings.reader) {
case "web":
// This is a web set URI by content using window.registerContentHandler()
// Lets make sure we know about it before setting it
const webPref = getPrefWebForType(settings.feedType);
let wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
getService(Ci.nsIWebContentConverterService);
// If the user provided an invalid web URL this function won't give us a reference
handler = wccr.getWebContentHandlerByURI(getMimeTypeForFeedType(settings.feedType), settings.uri);
if (handler) {
this._setPref(webPref, settings.uri, true);
if (settings.useAsDefault) {
wccr.setAutoHandler(getMimeTypeForFeedType(settings.feedType), handler);
}
msg.target.messageManager
.sendAsyncMessage("FeedWriter:SetFeedPrefsAndSubscribeResponse",
{ redirect: handler.getHandlerURI(settings.feedLocation) });
} else {
LOG(`No handler found for web ${settings.feedType} ${settings.uri}`);
}
break;
default:
const feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
getService(Ci.nsIFeedResultService);
feedService.addToClientReader(settings.feedLocation,
settings.feedTitle,
settings.feedSubtitle,
settings.feedType,
settings.reader);
}
break;
case "FeedConverter:ExecuteClientApp":
// Always check feedHandler is from a set array of executable prefs
if (EXECUTABLE_PREFS.has(msg.data.feedHandler)) {
this.executeClientApp(msg.data.spec, msg.data.title,
msg.data.subtitle, msg.data.feedHandler);
} else {
LOG(`FeedConverter:ExecuteClientApp - Will not exec ${msg.data.feedHandler}`);
}
break;
}
},
};
@@ -1,667 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
var PointerlockFsWarning = {
_element: null,
_origin: null,
init: function() {
this.Timeout.prototype = {
start: function() {
this.cancel();
this._id = setTimeout(() => this._handle(), this._delay);
},
cancel: function() {
if (this._id) {
clearTimeout(this._id);
this._id = 0;
}
},
_handle: function() {
this._id = 0;
this._func();
},
get delay() {
return this._delay;
}
};
},
/**
* Timeout object for managing timeout request. If it is started when
* the previous call hasn't finished, it would automatically cancelled
* the previous one.
*/
Timeout: function(func, delay) {
this._id = 0;
this._func = func;
this._delay = delay;
},
showPointerLock: function(aOrigin) {
if (!document.fullscreen) {
let timeout = gPrefService.getIntPref("pointer-lock-api.warning.timeout");
this.show(aOrigin, "pointerlock-warning", timeout, 0);
}
},
showFullScreen: function(aOrigin) {
let timeout = gPrefService.getIntPref("full-screen-api.warning.timeout");
let delay = gPrefService.getIntPref("full-screen-api.warning.delay");
this.show(aOrigin, "fullscreen-warning", timeout, delay);
},
// Shows a warning that the site has entered fullscreen or
// pointer lock for a short duration.
show: function(aOrigin, elementId, timeout, delay) {
if (!this._element) {
this._element = document.getElementById(elementId);
// Setup event listeners
this._element.addEventListener("transitionend", this);
window.addEventListener("mousemove", this, true);
// The timeout to hide the warning box after a while.
this._timeoutHide = new this.Timeout(() => {
this._state = "hidden";
}, timeout);
// The timeout to show the warning box when the pointer is at the top
this._timeoutShow = new this.Timeout(() => {
this._state = "ontop";
this._timeoutHide.start();
}, delay);
}
// Set the strings on the warning UI.
if (aOrigin) {
this._origin = aOrigin;
}
let uri = BrowserUtils.makeURI(this._origin);
let host = null;
try {
host = uri.host;
} catch (e) { }
let textElem = this._element.querySelector(".pointerlockfswarning-domain-text");
if (!host) {
textElem.setAttribute("hidden", true);
} else {
textElem.removeAttribute("hidden");
let hostElem = this._element.querySelector(".pointerlockfswarning-domain");
// Document's principal's URI has a host. Display a warning including it.
let utils = {};
Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
hostElem.textContent = utils.DownloadUtils.getURIHost(uri.spec)[0];
}
this._element.dataset.identity =
gIdentityHandler.pointerlockFsWarningClassName;
// User should be allowed to explicitly disable
// the prompt if they really want.
if (this._timeoutHide.delay <= 0) {
return;
}
// Explicitly set the last state to hidden to avoid the warning
// box being hidden immediately because of mousemove.
this._state = "onscreen";
this._lastState = "hidden";
this._timeoutHide.start();
},
close: function() {
if (!this._element) {
return;
}
// Cancel any pending timeout
this._timeoutHide.cancel();
this._timeoutShow.cancel();
// Reset state of the warning box
this._state = "hidden";
this._element.setAttribute("hidden", true);
// Remove all event listeners
this._element.removeEventListener("transitionend", this);
window.removeEventListener("mousemove", this, true);
// Clear fields
this._element = null;
this._timeoutHide = null;
this._timeoutShow = null;
// Ensure focus switches away from the (now hidden) warning box.
// If the user clicked buttons in the warning box, it would have
// been focused, and any key events would be directed at the (now
// hidden) chrome document instead of the target document.
gBrowser.selectedBrowser.focus();
},
// State could be one of "onscreen", "ontop", "hiding", and
// "hidden". Setting the state to "onscreen" and "ontop" takes
// effect immediately, while setting it to "hidden" actually
// turns the state to "hiding" before the transition finishes.
_lastState: null,
_STATES: ["hidden", "ontop", "onscreen"],
get _state() {
for (let state of this._STATES) {
if (this._element.hasAttribute(state)) {
return state;
}
}
return "hiding";
},
set _state(newState) {
let currentState = this._state;
if (currentState == newState) {
return;
}
if (currentState != "hiding") {
this._lastState = currentState;
this._element.removeAttribute(currentState);
}
if (newState != "hidden") {
if (currentState != "hidden") {
this._element.setAttribute(newState, true);
} else {
// When the previous state is hidden, the display was none,
// thus no box was constructed. We need to wait for the new
// display value taking effect first, otherwise, there won't
// be any transition. Since requestAnimationFrame callback is
// generally triggered before any style flush and layout, we
// should wait for the second animation frame.
requestAnimationFrame(() => {
requestAnimationFrame(() => {
if (this._element) {
this._element.setAttribute(newState, true);
}
});
});
}
}
},
handleEvent: function(event) {
switch (event.type) {
case "mousemove": {
let state = this._state;
if (state == "hidden") {
// If the warning box is currently hidden, show it after
// a short delay if the pointer is at the top.
if (event.clientY != 0) {
this._timeoutShow.cancel();
} else if (this._timeoutShow.delay >= 0) {
this._timeoutShow.start();
}
} else {
let elemRect = this._element.getBoundingClientRect();
if (state == "hiding" && this._lastState != "hidden") {
// If we are on the hiding transition, and the pointer
// moved near the box, restore to the previous state.
if (event.clientY <= elemRect.bottom + 50) {
this._state = this._lastState;
this._timeoutHide.start();
}
} else if (state == "ontop" || this._lastState != "hidden") {
// State being "ontop" or the previous state not being
// "hidden" indicates this current warning box is shown
// in response to user's action. Hide it immediately when
// the pointer leaves that area.
if (event.clientY > elemRect.bottom + 50) {
this._state = "hidden";
this._timeoutHide.cancel();
}
}
}
break;
}
case "transitionend": {
if (this._state == "hiding") {
this._element.setAttribute("hidden", true);
}
break;
}
}
}
};
var PointerLock = {
init: function() {
window.messageManager.addMessageListener("PointerLock:Entered", this);
window.messageManager.addMessageListener("PointerLock:Exited", this);
},
receiveMessage: function(aMessage) {
switch (aMessage.name) {
case "PointerLock:Entered": {
PointerlockFsWarning.showPointerLock(aMessage.data.originNoSuffix);
break;
}
case "PointerLock:Exited": {
PointerlockFsWarning.close();
break;
}
}
}
};
var FullScreen = {
_MESSAGES: [
"DOMFullscreen:Request",
"DOMFullscreen:NewOrigin",
"DOMFullscreen:Exit",
"DOMFullscreen:Painted",
],
init: function() {
// called when we go into full screen, even if initiated by a web page script
window.addEventListener("fullscreen", this, true);
window.addEventListener("MozDOMFullscreen:Entered", this,
/* useCapture */ true,
/* wantsUntrusted */ false);
window.addEventListener("MozDOMFullscreen:Exited", this,
/* useCapture */ true,
/* wantsUntrusted */ false);
for (let type of this._MESSAGES) {
window.messageManager.addMessageListener(type, this);
}
if (window.fullScreen)
this.toggle();
},
uninit: function() {
for (let type of this._MESSAGES) {
window.messageManager.removeMessageListener(type, this);
}
this.cleanup();
},
toggle: function () {
var enterFS = window.fullScreen;
// Toggle the View:FullScreen command, which controls elements like the
// fullscreen menuitem, and menubars.
let fullscreenCommand = document.getElementById("View:FullScreen");
if (enterFS) {
fullscreenCommand.setAttribute("checked", enterFS);
} else {
fullscreenCommand.removeAttribute("checked");
}
if (AppConstants.platform == "macosx") {
// Make sure the menu items are adjusted.
document.getElementById("enterFullScreenItem").hidden = enterFS;
document.getElementById("exitFullScreenItem").hidden = !enterFS;
}
if (!this._fullScrToggler) {
this._fullScrToggler = document.getElementById("fullscr-toggler");
this._fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
this._fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
this._fullScrToggler.addEventListener("touchmove", this._expandCallback, {passive: true});
}
if (enterFS) {
gNavToolbox.setAttribute("inFullscreen", true);
document.documentElement.setAttribute("inFullscreen", true);
if (!document.fullscreenElement && this.useLionFullScreen)
document.documentElement.setAttribute("OSXLionFullscreen", true);
} else {
gNavToolbox.removeAttribute("inFullscreen");
document.documentElement.removeAttribute("inFullscreen");
document.documentElement.removeAttribute("OSXLionFullscreen");
}
if (!document.fullscreenElement)
this._updateToolbars(enterFS);
if (enterFS) {
document.addEventListener("keypress", this._keyToggleCallback, false);
document.addEventListener("popupshown", this._setPopupOpen, false);
document.addEventListener("popuphidden", this._setPopupOpen, false);
// If it is not safe to collapse, add the mouse position tracker or
// else it won't be possible to hide the navigation toolbox again
if (gPrefService.getBoolPref("browser.fullscreen.autohide")) {
gBrowser.mPanelContainer.addEventListener("mousemove",
this._collapseCallback, false);
}
// In DOM fullscreen mode, we hide toolbars with CSS
if (!document.fullscreenElement)
this.hideNavToolbox(true);
}
else {
this.showNavToolbox(false);
// This is needed if they use the context menu to quit fullscreen
this._isPopupOpen = false;
this.cleanup();
// In TabsInTitlebar._update(), we cancel the appearance update on
// resize event for exiting fullscreen, since that happens before we
// change the UI here in the "fullscreen" event. Hence we need to
// call it here to ensure the appearance is properly updated. See
// TabsInTitlebar._update() and bug 1173768.
TabsInTitlebar.updateAppearance(true);
}
if (enterFS && !document.fullscreenElement) {
Services.telemetry.getHistogramById("FX_BROWSER_FULLSCREEN_USED")
.add(1);
}
},
exitDomFullScreen : function() {
document.exitFullscreen();
},
handleEvent: function (event) {
switch (event.type) {
case "fullscreen":
this.toggle();
break;
case "MozDOMFullscreen:Entered": {
// The event target is the element which requested the DOM
// fullscreen. If we were entering DOM fullscreen for a remote
// browser, the target would be `gBrowser` and the original
// target would be the browser which was the parameter of
// `remoteFrameFullscreenChanged` call. If the fullscreen
// request was initiated from an in-process browser, we need
// to get its corresponding browser here.
let browser;
if (event.target == gBrowser) {
browser = event.originalTarget;
} else {
let topWin = event.target.ownerGlobal.top;
browser = gBrowser.getBrowserForContentWindow(topWin);
}
this.enterDomFullscreen(browser);
break;
}
case "MozDOMFullscreen:Exited":
this.cleanupDomFullscreen();
break;
}
},
receiveMessage: function(aMessage) {
let browser = aMessage.target;
switch (aMessage.name) {
case "DOMFullscreen:Request": {
this._windowUtils.remoteFrameFullscreenChanged(browser);
break;
}
case "DOMFullscreen:NewOrigin": {
// Don't show the warning if we've already exited fullscreen.
if (document.fullscreen) {
PointerlockFsWarning.showFullScreen(aMessage.data.originNoSuffix);
}
break;
}
case "DOMFullscreen:Exit": {
this._windowUtils.remoteFrameFullscreenReverted();
break;
}
case "DOMFullscreen:Painted": {
Services.obs.notifyObservers(window, "fullscreen-painted", "");
break;
}
}
},
enterDomFullscreen : function(aBrowser) {
if (!document.fullscreenElement) {
return;
}
// If we have a current pointerlock warning shown then hide it
// before transition.
PointerlockFsWarning.close();
// If it is a remote browser, send a message to ask the content
// to enter fullscreen state. We don't need to do so if it is an
// in-process browser, since all related document should have
// entered fullscreen state at this point.
// This should be done before the active tab check below to ensure
// that the content document handles the pending request. Doing so
// before the check is fine since we also check the activeness of
// the requesting document in content-side handling code.
if (this._isRemoteBrowser(aBrowser)) {
aBrowser.messageManager.sendAsyncMessage("DOMFullscreen:Entered");
}
// If we've received a fullscreen notification, we have to ensure that the
// element that's requesting fullscreen belongs to the browser that's currently
// active. If not, we exit fullscreen since the "full-screen document" isn't
// actually visible now.
if (!aBrowser || gBrowser.selectedBrowser != aBrowser ||
// The top-level window has lost focus since the request to enter
// full-screen was made. Cancel full-screen.
Services.focus.activeWindow != window) {
// This function is called synchronously in fullscreen change, so
// we have to avoid calling exitFullscreen synchronously here.
setTimeout(() => document.exitFullscreen(), 0);
return;
}
document.documentElement.setAttribute("inDOMFullscreen", true);
if (gFindBarInitialized) {
gFindBar.close(true);
}
// Exit DOM full-screen mode upon open, close, or change tab.
gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
// Add listener to detect when the fullscreen window is re-focused.
// If a fullscreen window loses focus, we show a warning when the
// fullscreen window is refocused.
window.addEventListener("activate", this);
},
cleanup: function () {
if (!window.fullScreen) {
gBrowser.mPanelContainer.removeEventListener("mousemove",
this._collapseCallback, false);
document.removeEventListener("keypress", this._keyToggleCallback, false);
document.removeEventListener("popupshown", this._setPopupOpen, false);
document.removeEventListener("popuphidden", this._setPopupOpen, false);
}
},
cleanupDomFullscreen: function () {
window.messageManager
.broadcastAsyncMessage("DOMFullscreen:CleanUp");
PointerlockFsWarning.close();
gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
window.removeEventListener("activate", this);
document.documentElement.removeAttribute("inDOMFullscreen");
},
_isRemoteBrowser: function (aBrowser) {
return gMultiProcessBrowser && aBrowser.getAttribute("remote") == "true";
},
get _windowUtils() {
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
},
// Event callbacks
_expandCallback: function()
{
FullScreen.showNavToolbox();
},
_collapseCallback: function()
{
FullScreen.hideNavToolbox();
},
_keyToggleCallback: function(aEvent)
{
// if we can use the keyboard (eg Ctrl+L or Ctrl+E) to open the toolbars, we
// should provide a way to collapse them too.
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
FullScreen.hideNavToolbox();
}
// F6 is another shortcut to the address bar, but its not covered in OpenLocation()
else if (aEvent.keyCode == aEvent.DOM_VK_F6)
FullScreen.showNavToolbox();
},
// Checks whether we are allowed to collapse the chrome
_isPopupOpen: false,
_isChromeCollapsed: false,
_safeToCollapse: function () {
if (!gPrefService.getBoolPref("browser.fullscreen.autohide"))
return false;
// a popup menu is open in chrome: don't collapse chrome
if (this._isPopupOpen)
return false;
// On OS X Lion we don't want to hide toolbars.
if (this.useLionFullScreen)
return false;
// a textbox in chrome is focused (location bar anyone?): don't collapse chrome
if (document.commandDispatcher.focusedElement &&
document.commandDispatcher.focusedElement.ownerDocument == document &&
document.commandDispatcher.focusedElement.localName == "input") {
return false;
}
return true;
},
_setPopupOpen: function(aEvent)
{
// Popups should only veto chrome collapsing if they were opened when the chrome was not collapsed.
// Otherwise, they would not affect chrome and the user would expect the chrome to go away.
// e.g. we wouldn't want the autoscroll icon firing this event, so when the user
// toggles chrome when moving mouse to the top, it doesn't go away again.
if (aEvent.type == "popupshown" && !FullScreen._isChromeCollapsed &&
aEvent.target.localName != "tooltip" && aEvent.target.localName != "window")
FullScreen._isPopupOpen = true;
else if (aEvent.type == "popuphidden" && aEvent.target.localName != "tooltip" &&
aEvent.target.localName != "window") {
FullScreen._isPopupOpen = false;
// Try again to hide toolbar when we close the popup.
FullScreen.hideNavToolbox(true);
}
},
// Autohide helpers for the context menu item
getAutohide: function(aItem)
{
aItem.setAttribute("checked", gPrefService.getBoolPref("browser.fullscreen.autohide"));
},
setAutohide: function()
{
gPrefService.setBoolPref("browser.fullscreen.autohide", !gPrefService.getBoolPref("browser.fullscreen.autohide"));
// Try again to hide toolbar when we change the pref.
FullScreen.hideNavToolbox(true);
},
showNavToolbox: function(trackMouse = true) {
this._fullScrToggler.hidden = true;
gNavToolbox.removeAttribute("fullscreenShouldAnimate");
gNavToolbox.style.marginTop = "";
if (!this._isChromeCollapsed) {
return;
}
// Track whether mouse is near the toolbox
if (trackMouse && !this.useLionFullScreen) {
gBrowser.mPanelContainer.addEventListener("mousemove",
this._collapseCallback, false);
}
this._isChromeCollapsed = false;
},
hideNavToolbox: function (aAnimate = false) {
if (this._isChromeCollapsed || !this._safeToCollapse())
return;
this._fullScrToggler.hidden = false;
if (aAnimate && gPrefService.getBoolPref("browser.fullscreen.animate")) {
gNavToolbox.setAttribute("fullscreenShouldAnimate", true);
// Hide the fullscreen toggler until the transition ends.
let listener = () => {
gNavToolbox.removeEventListener("transitionend", listener, true);
if (this._isChromeCollapsed)
this._fullScrToggler.hidden = false;
};
gNavToolbox.addEventListener("transitionend", listener, true);
this._fullScrToggler.hidden = true;
}
gNavToolbox.style.marginTop =
-gNavToolbox.getBoundingClientRect().height + "px";
this._isChromeCollapsed = true;
gBrowser.mPanelContainer.removeEventListener("mousemove",
this._collapseCallback, false);
},
_updateToolbars: function (aEnterFS) {
for (let el of document.querySelectorAll("toolbar[fullscreentoolbar=true]")) {
if (aEnterFS) {
// Give the main nav bar and the tab bar the fullscreen context menu,
// otherwise remove context menu to prevent breakage
el.setAttribute("saved-context", el.getAttribute("context"));
if (el.id == "nav-bar" || el.id == "TabsToolbar")
el.setAttribute("context", "autohide-context");
else
el.removeAttribute("context");
// Set the inFullscreen attribute to allow specific styling
// in fullscreen mode
el.setAttribute("inFullscreen", true);
} else {
if (el.hasAttribute("saved-context")) {
el.setAttribute("context", el.getAttribute("saved-context"));
el.removeAttribute("saved-context");
}
el.removeAttribute("inFullscreen");
}
}
ToolbarIconColor.inferFromText();
// For Lion fullscreen, all fullscreen controls are hidden, don't
// bother to touch them. If we don't stop here, the following code
// could cause the native fullscreen button be shown unexpectedly.
// See bug 1165570.
if (this.useLionFullScreen) {
return;
}
var fullscreenctls = document.getElementById("window-controls");
var navbar = document.getElementById("nav-bar");
var ctlsOnTabbar = window.toolbar.visible;
if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
fullscreenctls.removeAttribute("flex");
document.getElementById("TabsToolbar").appendChild(fullscreenctls);
}
else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
fullscreenctls.setAttribute("flex", "1");
navbar.appendChild(fullscreenctls);
}
fullscreenctls.hidden = !aEnterFS;
}
};
XPCOMUtils.defineLazyGetter(FullScreen, "useLionFullScreen", function() {
// We'll only use OS X Lion full screen if we're
// * on OS X
// * on Lion or higher (Darwin 11+)
// * have fullscreenbutton="true"
return AppConstants.isPlatformAndVersionAtLeast("macosx", 11) &&
document.documentElement.getAttribute("fullscreenbutton") == "true";
});
@@ -1,526 +0,0 @@
/* 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/. */
/**
* Controls the "full zoom" setting and its site-specific preferences.
*/
var FullZoom = {
// Identifies the setting in the content prefs database.
name: "browser.content.full-zoom",
// browser.zoom.siteSpecific preference cache
_siteSpecificPref: undefined,
// browser.zoom.updateBackgroundTabs preference cache
updateBackgroundTabs: undefined,
// This maps the browser to monotonically increasing integer
// tokens. _browserTokenMap[browser] is increased each time the zoom is
// changed in the browser. See _getBrowserToken and _ignorePendingZoomAccesses.
_browserTokenMap: new WeakMap(),
// Stores initial locations if we receive onLocationChange
// events before we're initialized.
_initialLocations: new WeakMap(),
get siteSpecific() {
return this._siteSpecificPref;
},
// nsISupports
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
Ci.nsIObserver,
Ci.nsIContentPrefObserver,
Ci.nsISupportsWeakReference,
Ci.nsISupports]),
// Initialization & Destruction
init: function FullZoom_init() {
gBrowser.addEventListener("ZoomChangeUsingMouseWheel", this);
// Register ourselves with the service so we know when our pref changes.
this._cps2 = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService2);
this._cps2.addObserverForName(this.name, this);
this._siteSpecificPref =
gPrefService.getBoolPref("browser.zoom.siteSpecific");
this.updateBackgroundTabs =
gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
// Listen for changes to the browser.zoom branch so we can enable/disable
// updating background tabs and per-site saving and restoring of zoom levels.
gPrefService.addObserver("browser.zoom.", this, true);
// If we received onLocationChange events for any of the current browsers
// before we were initialized we want to replay those upon initialization.
for (let browser of gBrowser.browsers) {
if (this._initialLocations.has(browser)) {
this.onLocationChange(...this._initialLocations.get(browser), browser);
}
}
// This should be nulled after initialization.
this._initialLocations = null;
},
destroy: function FullZoom_destroy() {
gPrefService.removeObserver("browser.zoom.", this);
this._cps2.removeObserverForName(this.name, this);
gBrowser.removeEventListener("ZoomChangeUsingMouseWheel", this);
},
// Event Handlers
// nsIDOMEventListener
handleEvent: function FullZoom_handleEvent(event) {
switch (event.type) {
case "ZoomChangeUsingMouseWheel":
let browser = this._getTargetedBrowser(event);
this._ignorePendingZoomAccesses(browser);
this._applyZoomToPref(browser);
break;
}
},
// nsIObserver
observe: function (aSubject, aTopic, aData) {
switch (aTopic) {
case "nsPref:changed":
switch (aData) {
case "browser.zoom.siteSpecific":
this._siteSpecificPref =
gPrefService.getBoolPref("browser.zoom.siteSpecific");
break;
case "browser.zoom.updateBackgroundTabs":
this.updateBackgroundTabs =
gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
break;
}
break;
}
},
// nsIContentPrefObserver
onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue, aIsPrivate) {
this._onContentPrefChanged(aGroup, aValue, aIsPrivate);
},
onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName, aIsPrivate) {
this._onContentPrefChanged(aGroup, undefined, aIsPrivate);
},
/**
* Appropriately updates the zoom level after a content preference has
* changed.
*
* @param aGroup The group of the changed preference.
* @param aValue The new value of the changed preference. Pass undefined to
* indicate the preference's removal.
*/
_onContentPrefChanged: function FullZoom__onContentPrefChanged(aGroup, aValue, aIsPrivate) {
if (this._isNextContentPrefChangeInternal) {
// Ignore changes that FullZoom itself makes. This works because the
// content pref service calls callbacks before notifying observers, and it
// does both in the same turn of the event loop.
delete this._isNextContentPrefChangeInternal;
return;
}
let browser = gBrowser.selectedBrowser;
if (!browser.currentURI)
return;
let ctxt = this._loadContextFromBrowser(browser);
let domain = this._cps2.extractDomain(browser.currentURI.spec);
if (aGroup) {
if (aGroup == domain && ctxt.usePrivateBrowsing == aIsPrivate)
this._applyPrefToZoom(aValue, browser);
return;
}
this._globalValue = aValue === undefined ? aValue :
this._ensureValid(aValue);
// If the current page doesn't have a site-specific preference, then its
// zoom should be set to the new global preference now that the global
// preference has changed.
let hasPref = false;
let token = this._getBrowserToken(browser);
this._cps2.getByDomainAndName(browser.currentURI.spec, this.name, ctxt, {
handleResult: function () { hasPref = true; },
handleCompletion: function () {
if (!hasPref && token.isCurrent)
this._applyPrefToZoom(undefined, browser);
}.bind(this)
});
},
// location change observer
/**
* Called when the location of a tab changes.
* When that happens, we need to update the current zoom level if appropriate.
*
* @param aURI
* A URI object representing the new location.
* @param aIsTabSwitch
* Whether this location change has happened because of a tab switch.
* @param aBrowser
* (optional) browser object displaying the document
*/
onLocationChange: function FullZoom_onLocationChange(aURI, aIsTabSwitch, aBrowser) {
let browser = aBrowser || gBrowser.selectedBrowser;
// If we haven't been initialized yet but receive an onLocationChange
// notification then let's store and replay it upon initialization.
if (this._initialLocations) {
this._initialLocations.set(browser, [aURI, aIsTabSwitch]);
return;
}
// Ignore all pending async zoom accesses in the browser. Pending accesses
// that started before the location change will be prevented from applying
// to the new location.
this._ignorePendingZoomAccesses(browser);
if (!aURI || (aIsTabSwitch && !this.siteSpecific)) {
this._notifyOnLocationChange(browser);
return;
}
// Avoid the cps roundtrip and apply the default/global pref.
if (aURI.spec == "about:blank") {
this._applyPrefToZoom(undefined, browser,
this._notifyOnLocationChange.bind(this, browser));
return;
}
// Media documents should always start at 1, and are not affected by prefs.
if (!aIsTabSwitch && browser.isSyntheticDocument) {
ZoomManager.setZoomForBrowser(browser, 1);
// _ignorePendingZoomAccesses already called above, so no need here.
this._notifyOnLocationChange(browser);
return;
}
// See if the zoom pref is cached.
let ctxt = this._loadContextFromBrowser(browser);
let pref = this._cps2.getCachedByDomainAndName(aURI.spec, this.name, ctxt);
if (pref) {
this._applyPrefToZoom(pref.value, browser,
this._notifyOnLocationChange.bind(this, browser));
return;
}
// It's not cached, so we have to asynchronously fetch it.
let value = undefined;
let token = this._getBrowserToken(browser);
this._cps2.getByDomainAndName(aURI.spec, this.name, ctxt, {
handleResult: function (resultPref) { value = resultPref.value; },
handleCompletion: function () {
if (!token.isCurrent) {
this._notifyOnLocationChange(browser);
return;
}
this._applyPrefToZoom(value, browser,
this._notifyOnLocationChange.bind(this, browser));
}.bind(this)
});
},
// update state of zoom type menu item
updateMenu: function FullZoom_updateMenu() {
var menuItem = document.getElementById("toggle_zoom");
menuItem.setAttribute("checked", !ZoomManager.useFullZoom);
},
// Setting & Pref Manipulation
/**
* Reduces the zoom level of the page in the current browser.
*/
reduce: function FullZoom_reduce() {
ZoomManager.reduce();
let browser = gBrowser.selectedBrowser;
this._ignorePendingZoomAccesses(browser);
this._applyZoomToPref(browser);
},
/**
* Enlarges the zoom level of the page in the current browser.
*/
enlarge: function FullZoom_enlarge() {
ZoomManager.enlarge();
let browser = gBrowser.selectedBrowser;
this._ignorePendingZoomAccesses(browser);
this._applyZoomToPref(browser);
},
/**
* Sets the zoom level for the given browser to the given floating
* point value, where 1 is the default zoom level.
*/
setZoom: function (value, browser = gBrowser.selectedBrowser) {
ZoomManager.setZoomForBrowser(browser, value);
this._ignorePendingZoomAccesses(browser);
this._applyZoomToPref(browser);
},
/**
* Sets the zoom level of the page in the given browser to the global zoom
* level.
*
* @return A promise which resolves when the zoom reset has been applied.
*/
reset: function FullZoom_reset(browser = gBrowser.selectedBrowser) {
let token = this._getBrowserToken(browser);
let result = this._getGlobalValue(browser).then(value => {
if (token.isCurrent) {
ZoomManager.setZoomForBrowser(browser, value === undefined ? 1 : value);
this._ignorePendingZoomAccesses(browser);
Services.obs.notifyObservers(browser, "browser-fullZoom:zoomReset", "");
}
});
this._removePref(browser);
return result;
},
/**
* Set the zoom level for a given browser.
*
* Per nsPresContext::setFullZoom, we can set the zoom to its current value
* without significant impact on performance, as the setting is only applied
* if it differs from the current setting. In fact getting the zoom and then
* checking ourselves if it differs costs more.
*
* And perhaps we should always set the zoom even if it was more expensive,
* since nsDocumentViewer::SetTextZoom claims that child documents can have
* a different text zoom (although it would be unusual), and it implies that
* those child text zooms should get updated when the parent zoom gets set,
* and perhaps the same is true for full zoom
* (although nsDocumentViewer::SetFullZoom doesn't mention it).
*
* So when we apply new zoom values to the browser, we simply set the zoom.
* We don't check first to see if the new value is the same as the current
* one.
*
* @param aValue The zoom level value.
* @param aBrowser The zoom is set in this browser. Required.
* @param aCallback If given, it's asynchronously called when complete.
*/
_applyPrefToZoom: function FullZoom__applyPrefToZoom(aValue, aBrowser, aCallback) {
if (!this.siteSpecific || gInPrintPreviewMode) {
this._executeSoon(aCallback);
return;
}
// The browser is sometimes half-destroyed because this method is called
// by content pref service callbacks, which themselves can be called at any
// time, even after browsers are closed.
if (!aBrowser.parentNode || aBrowser.isSyntheticDocument) {
this._executeSoon(aCallback);
return;
}
if (aValue !== undefined) {
ZoomManager.setZoomForBrowser(aBrowser, this._ensureValid(aValue));
this._ignorePendingZoomAccesses(aBrowser);
this._executeSoon(aCallback);
return;
}
let token = this._getBrowserToken(aBrowser);
this._getGlobalValue(aBrowser).then(value => {
if (token.isCurrent) {
ZoomManager.setZoomForBrowser(aBrowser, value === undefined ? 1 : value);
this._ignorePendingZoomAccesses(aBrowser);
}
this._executeSoon(aCallback);
});
},
/**
* Saves the zoom level of the page in the given browser to the content
* prefs store.
*
* @param browser The zoom of this browser will be saved. Required.
*/
_applyZoomToPref: function FullZoom__applyZoomToPref(browser) {
Services.obs.notifyObservers(browser, "browser-fullZoom:zoomChange", "");
if (!this.siteSpecific ||
gInPrintPreviewMode ||
browser.isSyntheticDocument)
return;
this._cps2.set(browser.currentURI.spec, this.name,
ZoomManager.getZoomForBrowser(browser),
this._loadContextFromBrowser(browser), {
handleCompletion: function () {
this._isNextContentPrefChangeInternal = true;
}.bind(this),
});
},
/**
* Removes from the content prefs store the zoom level of the given browser.
*
* @param browser The zoom of this browser will be removed. Required.
*/
_removePref: function FullZoom__removePref(browser) {
Services.obs.notifyObservers(browser, "browser-fullZoom:zoomReset", "");
if (browser.isSyntheticDocument)
return;
let ctxt = this._loadContextFromBrowser(browser);
this._cps2.removeByDomainAndName(browser.currentURI.spec, this.name, ctxt, {
handleCompletion: function () {
this._isNextContentPrefChangeInternal = true;
}.bind(this),
});
},
// Utilities
/**
* Returns the zoom change token of the given browser. Asynchronous
* operations that access the given browser's zoom should use this method to
* capture the token before starting and use token.isCurrent to determine if
* it's safe to access the zoom when done. If token.isCurrent is false, then
* after the async operation started, either the browser's zoom was changed or
* the browser was destroyed, and depending on what the operation is doing, it
* may no longer be safe to set and get its zoom.
*
* @param browser The token of this browser will be returned.
* @return An object with an "isCurrent" getter.
*/
_getBrowserToken: function FullZoom__getBrowserToken(browser) {
let map = this._browserTokenMap;
if (!map.has(browser))
map.set(browser, 0);
return {
token: map.get(browser),
get isCurrent() {
// At this point, the browser may have been destructed and unbound but
// its outer ID not removed from the map because outer-window-destroyed
// hasn't been received yet. In that case, the browser is unusable, it
// has no properties, so return false. Check for this case by getting a
// property, say, docShell.
return map.get(browser) === this.token && browser.parentNode;
},
};
},
/**
* Returns the browser that the supplied zoom event is associated with.
* @param event The ZoomChangeUsingMouseWheel event.
* @return The associated browser element, if one exists, otherwise null.
*/
_getTargetedBrowser: function FullZoom__getTargetedBrowser(event) {
let target = event.originalTarget;
// With remote content browsers, the event's target is the browser
// we're looking for.
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
if (target instanceof window.XULElement &&
target.localName == "browser" &&
target.namespaceURI == XUL_NS)
return target;
// With in-process content browsers, the event's target is the content
// document.
if (target.nodeType == Node.DOCUMENT_NODE)
return gBrowser.getBrowserForDocument(target);
throw new Error("Unexpected ZoomChangeUsingMouseWheel event source");
},
/**
* Increments the zoom change token for the given browser so that pending
* async operations know that it may be unsafe to access they zoom when they
* finish.
*
* @param browser Pending accesses in this browser will be ignored.
*/
_ignorePendingZoomAccesses: function FullZoom__ignorePendingZoomAccesses(browser) {
let map = this._browserTokenMap;
map.set(browser, (map.get(browser) || 0) + 1);
},
_ensureValid: function FullZoom__ensureValid(aValue) {
// Note that undefined is a valid value for aValue that indicates a known-
// not-to-exist value.
if (isNaN(aValue))
return 1;
if (aValue < ZoomManager.MIN)
return ZoomManager.MIN;
if (aValue > ZoomManager.MAX)
return ZoomManager.MAX;
return aValue;
},
/**
* Gets the global browser.content.full-zoom content preference.
*
* @param browser The browser pertaining to the zoom.
* @returns Promise<prefValue>
* Resolves to the preference value when done.
*/
_getGlobalValue: function FullZoom__getGlobalValue(browser) {
// * !("_globalValue" in this) => global value not yet cached.
// * this._globalValue === undefined => global value known not to exist.
// * Otherwise, this._globalValue is a number, the global value.
return new Promise(resolve => {
if ("_globalValue" in this) {
resolve(this._globalValue);
return;
}
let value = undefined;
this._cps2.getGlobal(this.name, this._loadContextFromBrowser(browser), {
handleResult: function (pref) { value = pref.value; },
handleCompletion: (reason) => {
this._globalValue = this._ensureValid(value);
resolve(this._globalValue);
}
});
});
},
/**
* Gets the load context from the given Browser.
*
* @param Browser The Browser whose load context will be returned.
* @return The nsILoadContext of the given Browser.
*/
_loadContextFromBrowser: function FullZoom__loadContextFromBrowser(browser) {
return browser.loadContext;
},
/**
* Asynchronously broadcasts "browser-fullZoom:location-change" so that
* listeners can be notified when the zoom levels on those pages change.
* The notification is always asynchronous so that observers are guaranteed a
* consistent behavior.
*/
_notifyOnLocationChange: function FullZoom__notifyOnLocationChange(browser) {
this._executeSoon(function () {
Services.obs.notifyObservers(browser, "browser-fullZoom:location-change", "");
});
},
_executeSoon: function FullZoom__executeSoon(callback) {
if (!callback)
return;
Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
},
};
File diff suppressed because it is too large. Load diff
@@ -1,338 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
var gEMEHandler = {
get uiEnabled() {
#ifdef MOZ_EME
let emeUIEnabled = Services.prefs.getBoolPref("browser.eme.ui.enabled");
// Force-disable on WinXP:
if (navigator.platform.toLowerCase().startsWith("win")) {
emeUIEnabled = emeUIEnabled && parseFloat(Services.sysinfo.get("version")) >= 6;
}
return emeUIEnabled;
#else
return false;
#endif
},
ensureEMEEnabled: function(browser, keySystem) {
Services.prefs.setBoolPref("media.eme.enabled", true);
if (keySystem) {
if (keySystem == "com.widevine.alpha" &&
Services.prefs.getPrefType("media.gmp-widevinecdm.enabled") &&
!Services.prefs.getBoolPref("media.gmp-widevinecdm.enabled")) {
Services.prefs.setBoolPref("media.gmp-widevinecdm.enabled", true);
}
}
browser.reload();
},
isKeySystemVisible: function(keySystem) {
if (!keySystem) {
return false;
}
if (keySystem == "com.widevine.alpha" &&
Services.prefs.getPrefType("media.gmp-widevinecdm.visible")) {
return Services.prefs.getBoolPref("media.gmp-widevinecdm.visible");
}
return true;
},
getEMEDisabledFragment: function(msgId) {
let mainMessage = gNavigatorBundle.getString("emeNotifications.drmContentDisabled.message");
let [prefix, suffix] = mainMessage.split(/%(?:\$\d)?S/).map(s => document.createTextNode(s));
let text = gNavigatorBundle.getString("emeNotifications.drmContentDisabled.learnMoreLabel");
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
let link = document.createElement("label");
link.className = "text-link";
link.setAttribute("href", baseURL + "drm-content");
link.textContent = text;
let fragment = document.createDocumentFragment();
[prefix, link, suffix].forEach(n => fragment.appendChild(n));
return fragment;
},
getMessageWithBrandName: function(notificationId) {
let msgId = "emeNotifications." + notificationId + ".message";
return gNavigatorBundle.getFormattedString(msgId, [this._brandShortName]);
},
receiveMessage: function({target: browser, data: data}) {
let parsedData;
try {
parsedData = JSON.parse(data);
} catch (ex) {
Cu.reportError("Malformed EME video message with data: " + data);
return;
}
let {status: status, keySystem: keySystem} = parsedData;
// Don't need to show if disabled or keysystem not visible.
if (!this.uiEnabled || !this.isKeySystemVisible(keySystem)) {
return;
}
let notificationId;
let buttonCallback;
// Notification message can be either a string or a DOM fragment.
let notificationMessage;
switch (status) {
case "available":
case "cdm-created":
// Only show the chain icon for proprietary CDMs. Clearkey is not one.
if (keySystem != "org.w3.clearkey") {
this.showPopupNotificationForSuccess(browser, keySystem);
}
// ... and bail!
return;
case "api-disabled":
case "cdm-disabled":
notificationId = "drmContentDisabled";
buttonCallback = gEMEHandler.ensureEMEEnabled.bind(gEMEHandler, browser, keySystem)
notificationMessage = this.getEMEDisabledFragment();
break;
case "cdm-insufficient-version":
notificationId = "drmContentCDMInsufficientVersion";
notificationMessage = this.getMessageWithBrandName(notificationId);
break;
case "cdm-not-installed":
notificationId = "drmContentCDMInstalling";
notificationMessage = this.getMessageWithBrandName(notificationId);
break;
case "cdm-not-supported":
// Not to pop up user-level notification because they cannot do anything
// about it.
return;
default:
Cu.reportError(new Error("Unknown message ('" + status + "') dealing with EME key request: " + data));
return;
}
// Now actually create the notification
let box = gBrowser.getNotificationBox(browser);
if (box.getNotificationWithValue(notificationId)) {
return;
}
let buttons = [];
if (buttonCallback) {
let msgPrefix = "emeNotifications." + notificationId + ".";
let btnLabelId = msgPrefix + "button.label";
let btnAccessKeyId = msgPrefix + "button.accesskey";
buttons.push({
label: gNavigatorBundle.getString(btnLabelId),
accessKey: gNavigatorBundle.getString(btnAccessKeyId),
callback: buttonCallback
});
}
let iconURL = "chrome://browser/skin/drm-icon.svg#chains-black";
box.appendNotification(notificationMessage, notificationId, iconURL,
box.PRIORITY_WARNING_MEDIUM, buttons);
},
showPopupNotificationForSuccess: function(browser, keySystem) {
// We're playing EME content! Remove any "we can't play because..." messages.
var box = gBrowser.getNotificationBox(browser);
["drmContentDisabled",
"drmContentCDMInstalling"
].forEach(function (value) {
var notification = box.getNotificationWithValue(value);
if (notification)
box.removeNotification(notification);
});
// Don't bother creating it if it's already there:
if (PopupNotifications.getNotification("drmContentPlaying", browser)) {
return;
}
let msgPrefix = "emeNotifications.drmContentPlaying.";
let msgId = msgPrefix + "message2";
let btnLabelId = msgPrefix + "button.label";
let btnAccessKeyId = msgPrefix + "button.accesskey";
let message = gNavigatorBundle.getFormattedString(msgId, [this._brandShortName]);
let anchorId = "eme-notification-icon";
let firstPlayPref = "browser.eme.ui.firstContentShown";
if (!Services.prefs.getPrefType(firstPlayPref) ||
!Services.prefs.getBoolPref(firstPlayPref)) {
document.getElementById(anchorId).setAttribute("firstplay", "true");
Services.prefs.setBoolPref(firstPlayPref, true);
} else {
document.getElementById(anchorId).removeAttribute("firstplay");
}
let mainAction = {
label: gNavigatorBundle.getString(btnLabelId),
accessKey: gNavigatorBundle.getString(btnAccessKeyId),
callback: function() { openPreferences("paneContent"); },
dismiss: true
};
let options = {
dismissed: true,
eventCallback: aTopic => aTopic == "swapping",
learnMoreURL: Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content",
};
PopupNotifications.show(browser, "drmContentPlaying", message, anchorId, mainAction, null, options);
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener])
};
XPCOMUtils.defineLazyGetter(gEMEHandler, "_brandShortName", function() {
return document.getElementById("bundle_brand").getString("brandShortName");
});
const TELEMETRY_DDSTAT_SHOWN = 0;
const TELEMETRY_DDSTAT_SHOWN_FIRST = 1;
const TELEMETRY_DDSTAT_CLICKED = 2;
const TELEMETRY_DDSTAT_CLICKED_FIRST = 3;
const TELEMETRY_DDSTAT_SOLVED = 4;
let gDecoderDoctorHandler = {
getLabelForNotificationBox(type) {
if (type == "platform-decoder-not-found") {
if (AppConstants.platform == "win") {
return gNavigatorBundle.getString("decoder.noHWAcceleration.message");
}
if (AppConstants.platform == "linux") {
return gNavigatorBundle.getString("decoder.noCodecsLinux.message");
}
}
if (type == "cannot-initialize-pulseaudio") {
return gNavigatorBundle.getString("decoder.noPulseAudio.message");
}
if (type == "unsupported-libavcodec" &&
AppConstants.platform == "linux") {
return gNavigatorBundle.getString("decoder.unsupportedLibavcodec.message");
}
return "";
},
getSumoForLearnHowButton(type) {
if (AppConstants.platform == "win") {
return "fix-video-audio-problems-firefox-windows";
}
if (type == "cannot-initialize-pulseaudio") {
return "fix-common-audio-and-video-issues";
}
return "";
},
receiveMessage({target: browser, data: data}) {
let box = gBrowser.getNotificationBox(browser);
let notificationId = "decoder-doctor-notification";
if (box.getNotificationWithValue(notificationId)) {
return;
}
let parsedData;
try {
parsedData = JSON.parse(data);
} catch (ex) {
Cu.reportError("Malformed Decoder Doctor message with data: " + data);
return;
}
// parsedData (the result of parsing the incoming 'data' json string)
// contains analysis information from Decoder Doctor:
// - 'type' is the type of issue, it determines which text to show in the
// infobar.
// - 'decoderDoctorReportId' is the Decoder Doctor issue identifier, to be
// used here as key for the telemetry (counting infobar displays,
// "Learn how" buttons clicks, and resolutions) and for the prefs used
// to store at-issue formats.
// - 'formats' contains a comma-separated list of formats (or key systems)
// that suffer the issue. These are kept in a pref, which the backend
// uses to later find when an issue is resolved.
// - 'isSolved' is true when the notification actually indicates the
// resolution of that issue, to be reported as telemetry.
let {type, isSolved, decoderDoctorReportId, formats} = parsedData;
type = type.toLowerCase();
// Error out early on invalid ReportId
if (!(/^\w+$/mi).test(decoderDoctorReportId)) {
return
}
let title = gDecoderDoctorHandler.getLabelForNotificationBox(type);
if (!title) {
return;
}
// We keep the list of formats in prefs for the sake of the decoder itself,
// which reads it to determine when issues get solved for these formats.
// (Writing prefs from e10s content is now allowed.)
let formatsPref = "media.decoder-doctor." + decoderDoctorReportId + ".formats";
let buttonClickedPref = "media.decoder-doctor." + decoderDoctorReportId + ".button-clicked";
let histogram =
Services.telemetry.getKeyedHistogramById("DECODER_DOCTOR_INFOBAR_STATS");
let formatsInPref = Services.prefs.getPrefType(formatsPref) &&
Services.prefs.getCharPref(formatsPref);
if (!isSolved) {
if (!formats) {
Cu.reportError("Malformed Decoder Doctor unsolved message with no formats");
return;
}
if (!formatsInPref) {
Services.prefs.setCharPref(formatsPref, formats);
histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SHOWN_FIRST);
} else {
// Split existing formats into an array of strings.
let existing = formatsInPref.split(",").map(String.trim);
// Keep given formats that were not already recorded.
let newbies = formats.split(",").map(String.trim)
.filter(x => !existing.includes(x));
// And rewrite pref with the added new formats (if any).
if (newbies.length) {
Services.prefs.setCharPref(formatsPref,
existing.concat(newbies).join(", "));
}
}
histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SHOWN);
let buttons = [];
let sumo = gDecoderDoctorHandler.getSumoForLearnHowButton(type);
if (sumo) {
buttons.push({
label: gNavigatorBundle.getString("decoder.noCodecs.button"),
accessKey: gNavigatorBundle.getString("decoder.noCodecs.accesskey"),
callback() {
let clickedInPref = Services.prefs.getPrefType(buttonClickedPref) &&
Services.prefs.getBoolPref(buttonClickedPref);
if (!clickedInPref) {
Services.prefs.setBoolPref(buttonClickedPref, true);
histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_CLICKED_FIRST);
}
histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_CLICKED);
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
openUILinkIn(baseURL + sumo, "tab");
}
});
}
box.appendNotification(
title,
notificationId,
"", // This uses the info icon as specified below.
box.PRIORITY_INFO_LOW,
buttons
);
} else if (formatsInPref) {
// Issue is solved, and prefs haven't been cleared yet, meaning it's the
// first time we get this resolution -> Clear prefs and report telemetry.
Services.prefs.clearUserPref(formatsPref);
Services.prefs.clearUserPref(buttonClickedPref);
histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SOLVED);
}
},
}
window.getGroupMessageManager("browsers").addMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
window.getGroupMessageManager("browsers").addMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
window.addEventListener("unload", function() {
window.getGroupMessageManager("browsers").removeMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
window.getGroupMessageManager("browsers").removeMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
}, false);
@@ -1,508 +0,0 @@
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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/.
<menubar id="main-menubar"
onpopupshowing="if (event.target.parentNode.parentNode == this &amp;&amp;
!('@mozilla.org/widget/nativemenuservice;1' in Cc))
this.setAttribute('openedwithkey',
event.target.parentNode.openedWithKey);"
style="border:0px;padding:0px;margin:0px;-moz-appearance:none">
<menu id="file-menu" label="&fileMenu.label;"
accesskey="&fileMenu.accesskey;">
<menupopup id="menu_FilePopup">
<menuitem id="menu_newNavigatorTab"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"
accesskey="&tabCmd.accesskey;"/>
<menuitem id="menu_newNavigator"
label="&newNavigatorCmd.label;"
accesskey="&newNavigatorCmd.accesskey;"
key="key_newNavigator"
command="cmd_newNavigator"/>
<menuitem id="menu_newPrivateWindow"
label="&newPrivateWindow.label;"
accesskey="&newPrivateWindow.accesskey;"
command="Tools:PrivateBrowsing"
key="key_privatebrowsing"/>
#ifdef MAC_NON_BROWSER_WINDOW
<menuitem id="menu_openLocation"
label="&openLocationCmd.label;"
command="Browser:OpenLocation"
key="focusURLBar"/>
#endif
<menuitem id="menu_openFile"
label="&openFileCmd.label;"
command="Browser:OpenFile"
key="openFileKb"
accesskey="&openFileCmd.accesskey;"/>
<menuitem id="menu_close"
class="show-only-for-keyboard"
label="&closeCmd.label;"
key="key_close"
accesskey="&closeCmd.accesskey;"
command="cmd_close"/>
<menuitem id="menu_closeWindow"
class="show-only-for-keyboard"
hidden="true"
command="cmd_closeWindow"
key="key_closeWindow"
label="&closeWindow.label;"
accesskey="&closeWindow.accesskey;"/>
<menuseparator/>
<menuitem id="menu_savePage"
label="&savePageCmd.label;"
accesskey="&savePageCmd.accesskey;"
key="key_savePage"
command="Browser:SavePage"/>
<menuitem id="menu_sendLink"
label="&emailPageCmd.label;"
accesskey="&emailPageCmd.accesskey;"
command="Browser:SendLink"/>
<menuseparator/>
#if !defined(MOZ_WIDGET_GTK)
<menuitem id="menu_printSetup"
label="&printSetupCmd.label;"
accesskey="&printSetupCmd.accesskey;"
command="cmd_pageSetup"/>
#endif
#ifndef XP_MACOSX
<menuitem id="menu_printPreview"
label="&printPreviewCmd.label;"
accesskey="&printPreviewCmd.accesskey;"
command="cmd_printPreview"/>
#endif
<menuitem id="menu_print"
label="&printCmd.label;"
accesskey="&printCmd.accesskey;"
key="printKb"
command="cmd_print"/>
<menuseparator/>
<menuitem id="goOfflineMenuitem"
label="&goOfflineCmd.label;"
accesskey="&goOfflineCmd.accesskey;"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
<menuitem id="menu_FileQuitItem"
#ifdef XP_WIN
label="&quitApplicationCmdWin2.label;"
accesskey="&quitApplicationCmdWin2.accesskey;"
#else
#ifdef XP_MACOSX
label="&quitApplicationCmdMac2.label;"
#else
label="&quitApplicationCmd.label;"
accesskey="&quitApplicationCmd.accesskey;"
#endif
#ifdef XP_UNIX
key="key_quitApplication"
#endif
#endif
command="cmd_quitApplication"/>
</menupopup>
</menu>
<menu id="edit-menu" label="&editMenu.label;"
accesskey="&editMenu.accesskey;">
<menupopup id="menu_EditPopup"
onpopupshowing="updateEditUIVisibility()"
onpopuphidden="updateEditUIVisibility()">
<menuitem id="menu_undo"
label="&undoCmd.label;"
key="key_undo"
accesskey="&undoCmd.accesskey;"
command="cmd_undo"/>
<menuitem id="menu_redo"
label="&redoCmd.label;"
key="key_redo"
accesskey="&redoCmd.accesskey;"
command="cmd_redo"/>
<menuseparator/>
<menuitem id="menu_cut"
label="&cutCmd.label;"
key="key_cut"
accesskey="&cutCmd.accesskey;"
command="cmd_cut"/>
<menuitem id="menu_copy"
label="&copyCmd.label;"
key="key_copy"
accesskey="&copyCmd.accesskey;"
command="cmd_copy"/>
<menuitem id="menu_paste"
label="&pasteCmd.label;"
key="key_paste"
accesskey="&pasteCmd.accesskey;"
command="cmd_paste"/>
<menuitem id="menu_delete"
label="&deleteCmd.label;"
key="key_delete"
accesskey="&deleteCmd.accesskey;"
command="cmd_delete"/>
<menuseparator/>
<menuitem id="menu_selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAll"/>
<menuseparator/>
<menuitem id="menu_find"
label="&findOnCmd.label;"
accesskey="&findOnCmd.accesskey;"
key="key_find"
command="cmd_find"/>
<menuitem id="menu_findAgain"
class="show-only-for-keyboard"
label="&findAgainCmd.label;"
accesskey="&findAgainCmd.accesskey;"
key="key_findAgain"
command="cmd_findAgain"/>
<menuseparator hidden="true" id="textfieldDirection-separator"/>
<menuitem id="textfieldDirection-swap"
command="cmd_switchTextDirection"
key="key_switchTextDirection"
label="&bidiSwitchTextDirectionItem.label;"
accesskey="&bidiSwitchTextDirectionItem.accesskey;"
hidden="true"/>
</menupopup>
</menu>
<menu id="view-menu" label="&viewMenu.label;"
accesskey="&viewMenu.accesskey;">
<menupopup id="menu_viewPopup"
onpopupshowing="updateCharacterEncodingMenuState();">
<menu id="viewToolbarsMenu"
label="&viewToolbarsMenu.label;"
accesskey="&viewToolbarsMenu.accesskey;">
<menupopup onpopupshowing="onViewToolbarsPopupShowing(event);">
<menuseparator/>
<menuitem id="menu_customizeToolbars"
label="&viewCustomizeToolbar.label;"
accesskey="&viewCustomizeToolbar.accesskey;"
command="cmd_CustomizeToolbars"/>
</menupopup>
</menu>
<menu id="viewSidebarMenuMenu"
label="&viewSidebarMenu.label;"
accesskey="&viewSidebarMenu.accesskey;">
<menupopup id="viewSidebarMenu">
<menuitem id="menu_bookmarksSidebar"
key="viewBookmarksSidebarKb"
observes="viewBookmarksSidebar"/>
<menuitem id="menu_historySidebar"
key="key_gotoHistory"
observes="viewHistorySidebar"
label="&historyButton.label;"/>
</menupopup>
</menu>
<menuseparator/>
<menu id="viewFullZoomMenu" label="&fullZoom.label;"
accesskey="&fullZoom.accesskey;"
onpopupshowing="FullZoom.updateMenu();">
<menupopup>
<menuitem id="menu_zoomEnlarge"
key="key_fullZoomEnlarge"
label="&fullZoomEnlargeCmd.label;"
accesskey="&fullZoomEnlargeCmd.accesskey;"
command="cmd_fullZoomEnlarge"/>
<menuitem id="menu_zoomReduce"
key="key_fullZoomReduce"
label="&fullZoomReduceCmd.label;"
accesskey="&fullZoomReduceCmd.accesskey;"
command="cmd_fullZoomReduce"/>
<menuseparator/>
<menuitem id="menu_zoomReset"
key="key_fullZoomReset"
label="&fullZoomResetCmd.label;"
accesskey="&fullZoomResetCmd.accesskey;"
command="cmd_fullZoomReset"/>
<menuseparator/>
<menuitem id="toggle_zoom"
label="&fullZoomToggleCmd.label;"
accesskey="&fullZoomToggleCmd.accesskey;"
type="checkbox"
command="cmd_fullZoomToggle"
checked="false"/>
</menupopup>
</menu>
<menu id="pageStyleMenu" label="&pageStyleMenu.label;"
accesskey="&pageStyleMenu.accesskey;" observes="isImage">
<menupopup onpopupshowing="gPageStyleMenu.fillPopup(this);">
<menuitem id="menu_pageStyleNoStyle"
label="&pageStyleNoStyle.label;"
accesskey="&pageStyleNoStyle.accesskey;"
oncommand="gPageStyleMenu.disableStyle();"
type="radio"/>
<menuitem id="menu_pageStylePersistentOnly"
label="&pageStylePersistentOnly.label;"
accesskey="&pageStylePersistentOnly.accesskey;"
oncommand="gPageStyleMenu.switchStyleSheet('');"
type="radio"
checked="true"/>
<menuseparator/>
</menupopup>
</menu>
#include browser-charsetmenu.inc
<menuseparator/>
#ifdef XP_MACOSX
<menuitem id="enterFullScreenItem"
accesskey="&enterFullScreenCmd.accesskey;"
label="&enterFullScreenCmd.label;"
key="key_fullScreen">
<observes element="View:FullScreen" attribute="oncommand"/>
<observes element="View:FullScreen" attribute="disabled"/>
</menuitem>
<menuitem id="exitFullScreenItem"
accesskey="&exitFullScreenCmd.accesskey;"
label="&exitFullScreenCmd.label;"
key="key_fullScreen"
hidden="true">
<observes element="View:FullScreen" attribute="oncommand"/>
<observes element="View:FullScreen" attribute="disabled"/>
</menuitem>
#else
<menuitem id="fullScreenItem"
accesskey="&fullScreenCmd.accesskey;"
label="&fullScreenCmd.label;"
key="key_fullScreen"
type="checkbox"
observes="View:FullScreen"/>
#endif
<menuitem id="menu_readerModeItem"
observes="View:ReaderView"
hidden="true"/>
<menuitem id="menu_showAllTabs"
hidden="true"
accesskey="&showAllTabsCmd.accesskey;"
label="&showAllTabsCmd.label;"
command="Browser:ShowAllTabs"
key="key_showAllTabs"/>
<menuseparator hidden="true" id="documentDirection-separator"/>
<menuitem id="documentDirection-swap"
hidden="true"
label="&bidiSwitchPageDirectionItem.label;"
accesskey="&bidiSwitchPageDirectionItem.accesskey;"
oncommand="gBrowser.selectedBrowser
.messageManager
.sendAsyncMessage('SwitchDocumentDirection');"/>
</menupopup>
</menu>
<menu id="history-menu"
label="&historyMenu.label;"
accesskey="&historyMenu.accesskey;">
<menupopup id="goPopup"
#ifndef XP_MACOSX
placespopup="true"
#endif
oncommand="this.parentNode._placesView._onCommand(event);"
onclick="checkForMiddleClick(this, event);"
onpopupshowing="if (!this.parentNode._placesView)
new HistoryMenu(event);"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="menu_showAllHistory"
label="&showAllHistoryCmd2.label;"
#ifndef XP_MACOSX
key="showAllHistoryKb"
#endif
command="Browser:ShowAllHistory"/>
<menuitem id="sanitizeItem"
label="&clearRecentHistory.label;"
key="key_sanitize"
command="Tools:Sanitize"/>
<menuseparator id="sanitizeSeparator"/>
#ifdef MOZ_SERVICES_SYNC
<menuitem id="sync-tabs-menuitem"
class="syncTabsMenuItem"
label="&syncTabsMenu2.label;"
oncommand="BrowserOpenSyncTabs();"
disabled="true"/>
#endif
<menuitem id="historyRestoreLastSession"
label="&historyRestoreLastSession.label;"
command="Browser:RestoreLastSession"/>
<menu id="historyUndoMenu"
class="recentlyClosedTabsMenu"
label="&historyUndoMenu.label;"
disabled="true">
<menupopup id="historyUndoPopup"
#ifndef XP_MACOSX
placespopup="true"
#endif
onpopupshowing="document.getElementById('history-menu')._placesView.populateUndoSubmenu();"/>
</menu>
<menu id="historyUndoWindowMenu"
class="recentlyClosedWindowsMenu"
label="&historyUndoWindowMenu.label;"
disabled="true">
<menupopup id="historyUndoWindowPopup"
#ifndef XP_MACOSX
placespopup="true"
#endif
onpopupshowing="document.getElementById('history-menu')._placesView.populateUndoWindowSubmenu();"/>
</menu>
<menuseparator id="startHistorySeparator"
class="hide-if-empty-places-result"/>
</menupopup>
</menu>
<menu id="bookmarksMenu"
label="&bookmarksMenu.label;"
accesskey="&bookmarksMenu.accesskey;"
ondragenter="PlacesMenuDNDHandler.onDragEnter(event);"
ondragover="PlacesMenuDNDHandler.onDragOver(event);"
ondrop="PlacesMenuDNDHandler.onDrop(event);">
<menupopup id="bookmarksMenuPopup"
#ifndef XP_MACOSX
placespopup="true"
#endif
context="placesContext"
openInTabs="children"
oncommand="BookmarksEventHandler.onCommand(event, this.parentNode._placesView);"
onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
onpopupshowing="BookmarkingUI.onMainMenuPopupShowing(event);
if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
tooltip="bhTooltip" popupsinherittooltip="true">
<menuitem id="bookmarksShowAll"
label="&showAllBookmarks2.label;"
command="Browser:ShowAllBookmarks"
key="manBookmarkKb"/>
<menuseparator id="organizeBookmarksSeparator"/>
<menuitem id="menu_bookmarkThisPage"
command="Browser:AddBookmarkAs"
observes="bookmarkThisPageBroadcaster"
key="addBookmarkAsKb"/>
<menuitem id="subscribeToPageMenuitem"
#ifndef XP_MACOSX
class="menuitem-iconic"
#endif
label="&subscribeToPageMenuitem.label;"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"
observes="singleFeedMenuitemState"/>
<menu id="subscribeToPageMenupopup"
#ifndef XP_MACOSX
class="menu-iconic"
#endif
label="&subscribeToPageMenupopup.label;"
observes="multipleFeedsMenuState">
<menupopup id="subscribeToPageSubmenuMenupopup"
onpopupshowing="return FeedHandler.buildFeedList(event.target);"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"/>
</menu>
<menuitem id="menu_bookmarkAllTabs"
label="&addCurPagesCmd.label;"
class="show-only-for-keyboard"
command="Browser:BookmarkAllTabs"
key="bookmarkAllTabsKb"/>
<menuseparator/>
<menuitem label="&recentBookmarks.label;"
id="menu_recentBookmarks"
disabled="true"/>
<menuseparator id="bookmarksToolbarSeparator"/>
<menu id="bookmarksToolbarFolderMenu"
class="menu-iconic bookmark-item"
label="&personalbarCmd.label;"
container="true">
<menupopup id="bookmarksToolbarFolderPopup"
#ifndef XP_MACOSX
placespopup="true"
#endif
context="placesContext"
onpopupshowing="if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
</menu>
<menu id="menu_unsortedBookmarks"
class="menu-iconic bookmark-item"
label="&otherBookmarksCmd.label;"
container="true">
<menupopup id="otherBookmarksFolderPopup"
#ifndef XP_MACOSX
placespopup="true"
#endif
context="placesContext"
onpopupshowing="if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=UNFILED_BOOKMARKS');"/>
</menu>
<menuseparator id="bookmarksMenuItemsSeparator"/>
<!-- Bookmarks menu items -->
</menupopup>
</menu>
<menu id="tools-menu"
label="&toolsMenu.label;"
accesskey="&toolsMenu.accesskey;"
onpopupshowing="mirrorShow(this)">
<menupopup id="menu_ToolsPopup"
#ifdef MOZ_SERVICES_SYNC
onpopupshowing="gSyncUI.updateUI();"
#endif
>
<menuitem id="menu_openDownloads"
label="&downloads.label;"
accesskey="&downloads.accesskey;"
key="key_openDownloads"
command="Tools:Downloads"/>
<menuitem id="menu_openAddons"
label="&addons.label;"
accesskey="&addons.accesskey;"
key="key_openAddons"
command="Tools:Addons"/>
#ifdef MOZ_SERVICES_SYNC
<!-- only one of sync-setup or sync-menu will be showing at once -->
<menuitem id="sync-setup"
label="&syncSetup.label;"
accesskey="&syncSetup.accesskey;"
observes="sync-setup-state"
oncommand="gSyncUI.openSetup()"/>
<menuitem id="sync-syncnowitem"
label="&syncSyncNowItem.label;"
accesskey="&syncSyncNowItem.accesskey;"
observes="sync-syncnow-state"
oncommand="gSyncUI.doSync(event);"/>
#endif
<menuseparator id="devToolsSeparator"/>
<menu id="webDeveloperMenu"
label="&webDeveloperMenu.label;"
accesskey="&webDeveloperMenu.accesskey;">
<menupopup id="menuWebDeveloperPopup">
<menuitem id="menu_pageSource"
observes="devtoolsMenuBroadcaster_PageSource"
accesskey="&pageSourceCmd.accesskey;"/>
<menuitem id="javascriptConsole"
observes="devtoolsMenuBroadcaster_ErrorConsole"
accesskey="&errorConsoleCmd.accesskey;"/>
</menupopup>
</menu>
<menuitem id="menu_pageInfo"
accesskey="&pageInfoCmd.accesskey;"
label="&pageInfoCmd.label;"
#ifndef XP_WIN
key="key_viewInfo"
#endif
command="View:PageInfo"/>
<menu id="menu_mirrorTabCmd"
hidden="true"
accesskey="&mirrorTabCmd.accesskey;"
label="&mirrorTabCmd.label;">
<menupopup id="menu_mirrorTab-popup"
onpopupshowing="populateMirrorTabMenu(this)"/>
</menu>
<menuseparator id="prefSep"/>
<menuitem id="menu_preferences"
label="&preferencesCmd2.label;"
accesskey="&preferencesCmd2.accesskey;"
oncommand="openPreferences();"/>
</menupopup>
</menu>
#ifdef XP_MACOSX
<menu id="windowMenu" />
#endif
<menu id="helpMenu" />
</menubar>
File diff suppressed because it is too large. Load diff
@@ -1,516 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
var gPluginHandler = {
PREF_SESSION_PERSIST_MINUTES: "plugin.sessionPermissionNow.intervalInMinutes",
PREF_PERSISTENT_DAYS: "plugin.persistentPermissionAlways.intervalInDays",
MESSAGES: [
"PluginContent:ShowClickToPlayNotification",
"PluginContent:RemoveNotification",
"PluginContent:UpdateHiddenPluginUI",
"PluginContent:HideNotificationBar",
"PluginContent:InstallSinglePlugin",
"PluginContent:ShowPluginCrashedNotification",
"PluginContent:SubmitReport",
"PluginContent:LinkClickCallback",
],
init: function () {
const mm = window.messageManager;
for (let msg of this.MESSAGES) {
mm.addMessageListener(msg, this);
}
window.addEventListener("unload", this);
},
uninit: function () {
const mm = window.messageManager;
for (let msg of this.MESSAGES) {
mm.removeMessageListener(msg, this);
}
window.removeEventListener("unload", this);
},
handleEvent: function (event) {
if (event.type == "unload") {
this.uninit();
}
},
receiveMessage: function (msg) {
switch (msg.name) {
case "PluginContent:ShowClickToPlayNotification":
this.showClickToPlayNotification(msg.target, msg.data.plugins, msg.data.showNow,
msg.principal, msg.data.location);
break;
case "PluginContent:RemoveNotification":
this.removeNotification(msg.target, msg.data.name);
break;
case "PluginContent:UpdateHiddenPluginUI":
this.updateHiddenPluginUI(msg.target, msg.data.haveInsecure, msg.data.actions,
msg.principal, msg.data.location);
break;
case "PluginContent:HideNotificationBar":
this.hideNotificationBar(msg.target, msg.data.name);
break;
case "PluginContent:InstallSinglePlugin":
this.installSinglePlugin(msg.data.pluginInfo);
break;
case "PluginContent:ShowPluginCrashedNotification":
this.showPluginCrashedNotification(msg.target, msg.data.messageString,
msg.data.pluginID);
break;
case "PluginContent:SubmitReport":
// Nothing to do here
break;
case "PluginContent:LinkClickCallback":
switch (msg.data.name) {
case "managePlugins":
case "openHelpPage":
case "openPluginUpdatePage":
this[msg.data.name].call(this, msg.data.pluginTag);
break;
}
break;
default:
Cu.reportError("gPluginHandler did not expect to handle message " + msg.name);
break;
}
},
// Callback for user clicking on a disabled plugin
managePlugins: function () {
BrowserOpenAddonsMgr("addons://list/plugin");
},
// Callback for user clicking on the link in a click-to-play plugin
// (where the plugin has an update)
openPluginUpdatePage: function(pluginTag) {
let url = Services.blocklist.getPluginInfoURL(pluginTag);
if (!url) {
url = Services.blocklist.getPluginBlocklistURL(pluginTag);
}
openUILinkIn(url, "tab");
},
submitReport: function submitReport(runID, keyVals, submitURLOptIn) {
/*** STUB ***/
return;
},
// Callback for user clicking a "reload page" link
reloadPage: function (browser) {
browser.reload();
},
// Callback for user clicking the help icon
openHelpPage: function () {
openHelpLink("plugin-crashed", false);
},
_clickToPlayNotificationEventCallback: function PH_ctpEventCallback(event) {
if (event == "showing") {
Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_SHOWN")
.add(!this.options.primaryPlugin);
// Histograms always start at 0, even though our data starts at 1
let histogramCount = this.options.pluginData.size - 1;
if (histogramCount > 4) {
histogramCount = 4;
}
Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_PLUGIN_COUNT")
.add(histogramCount);
}
else if (event == "dismissed") {
// Once the popup is dismissed, clicking the icon should show the full
// list again
this.options.primaryPlugin = null;
}
},
/**
* Called from the plugin doorhanger to set the new permissions for a plugin
* and activate plugins if necessary.
* aNewState should be either "allownow" "allowalways" or "block"
*/
_updatePluginPermission: function (aNotification, aPluginInfo, aNewState) {
let permission;
let expireType;
let expireTime;
let histogram =
Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_USER_ACTION");
// Update the permission manager.
// Also update the current state of pluginInfo.fallbackType so that
// subsequent opening of the notification shows the current state.
switch (aNewState) {
case "allownow":
permission = Ci.nsIPermissionManager.ALLOW_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_SESSION;
expireTime = Date.now() + Services.prefs.getIntPref(this.PREF_SESSION_PERSIST_MINUTES) * 60 * 1000;
histogram.add(0);
aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE;
break;
case "allowalways":
permission = Ci.nsIPermissionManager.ALLOW_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_TIME;
expireTime = Date.now() +
Services.prefs.getIntPref(this.PREF_PERSISTENT_DAYS) * 24 * 60 * 60 * 1000;
histogram.add(1);
aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE;
break;
case "block":
permission = Ci.nsIPermissionManager.PROMPT_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_NEVER;
expireTime = 0;
histogram.add(2);
switch (aPluginInfo.blocklistState) {
case Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE:
aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE;
break;
case Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE:
aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
break;
default:
aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY;
}
break;
// In case a plugin has already been allowed in another tab, the "continue allowing" button
// shouldn't change any permissions but should run the plugin-enablement code below.
case "continue":
aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE;
break;
default:
Cu.reportError(Error("Unexpected plugin state: " + aNewState));
return;
}
let browser = aNotification.browser;
if (aNewState != "continue") {
let principal = aNotification.options.principal;
Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString,
permission, expireType, expireTime);
aPluginInfo.pluginPermissionType = expireType;
}
browser.messageManager.sendAsyncMessage("BrowserPlugins:ActivatePlugins", {
pluginInfo: aPluginInfo,
newState: aNewState,
});
},
showClickToPlayNotification: function (browser, plugins, showNow,
principal, location) {
// It is possible that we've received a message from the frame script to show
// a click to play notification for a principal that no longer matches the one
// that the browser's content now has assigned (ie, the browser has browsed away
// after the message was sent, but before the message was received). In that case,
// we should just ignore the message.
if (!principal.equals(browser.contentPrincipal)) {
return;
}
// Data URIs, when linked to from some page, inherit the principal of that
// page. That means that we also need to compare the actual locations to
// ensure we aren't getting a message from a Data URI that we're no longer
// looking at.
let receivedURI = BrowserUtils.makeURI(location);
if (!browser.documentURI.equalsExceptRef(receivedURI)) {
return;
}
let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
// If this is a new notification, create a pluginData map, otherwise append
let pluginData;
if (notification) {
pluginData = notification.options.pluginData;
} else {
pluginData = new Map();
}
for (var pluginInfo of plugins) {
if (pluginData.has(pluginInfo.permissionString)) {
continue;
}
// If a block contains an infoURL, we should always prefer that to the default
// URL that we construct in-product, even for other blocklist types.
let url = Services.blocklist.getPluginInfoURL(pluginInfo.pluginTag);
if (pluginInfo.blocklistState != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
if (!url) {
url = Services.blocklist.getPluginBlocklistURL(pluginInfo.pluginTag);
}
}
else {
url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "clicktoplay";
}
pluginInfo.detailsLink = url;
pluginData.set(pluginInfo.permissionString, pluginInfo);
}
let primaryPluginPermission = null;
if (showNow) {
primaryPluginPermission = plugins[0].permissionString;
}
if (notification) {
// Don't modify the notification UI while it's on the screen, that would be
// jumpy and might allow clickjacking.
if (showNow) {
notification.options.primaryPlugin = primaryPluginPermission;
notification.reshow();
browser.messageManager.sendAsyncMessage("BrowserPlugins:NotificationShown");
}
return;
}
let options = {
dismissed: !showNow,
eventCallback: this._clickToPlayNotificationEventCallback,
primaryPlugin: primaryPluginPermission,
pluginData: pluginData,
principal: principal,
};
PopupNotifications.show(browser, "click-to-play-plugins",
"", "plugins-notification-icon",
null, null, options);
browser.messageManager.sendAsyncMessage("BrowserPlugins:NotificationShown");
},
removeNotification: function (browser, name) {
let notification = PopupNotifications.getNotification(name, browser);
if (notification)
PopupNotifications.remove(notification);
},
hideNotificationBar: function (browser, name) {
let notificationBox = gBrowser.getNotificationBox(browser);
let notification = notificationBox.getNotificationWithValue(name);
if (notification)
notificationBox.removeNotification(notification, true);
},
updateHiddenPluginUI: function (browser, haveInsecure, actions,
principal, location) {
let origin = principal.originNoSuffix;
// It is possible that we've received a message from the frame script to show
// the hidden plugin notification for a principal that no longer matches the one
// that the browser's content now has assigned (ie, the browser has browsed away
// after the message was sent, but before the message was received). In that case,
// we should just ignore the message.
if (!principal.equals(browser.contentPrincipal)) {
return;
}
// Data URIs, when linked to from some page, inherit the principal of that
// page. That means that we also need to compare the actual locations to
// ensure we aren't getting a message from a Data URI that we're no longer
// looking at.
let receivedURI = BrowserUtils.makeURI(location);
if (!browser.documentURI.equalsExceptRef(receivedURI)) {
return;
}
// Set up the icon
document.getElementById("plugins-notification-icon").classList.
toggle("plugin-blocked", haveInsecure);
// Now configure the notification bar
let notificationBox = gBrowser.getNotificationBox(browser);
function hideNotification() {
let n = notificationBox.getNotificationWithValue("plugin-hidden");
if (n) {
notificationBox.removeNotification(n, true);
}
}
// There are three different cases when showing an infobar:
// 1. A single type of plugin is hidden on the page. Show the UI for that
// plugin.
// 2a. Multiple types of plugins are hidden on the page. Show the multi-UI
// with the vulnerable styling.
// 2b. Multiple types of plugins are hidden on the page, but none are
// vulnerable. Show the nonvulnerable multi-UI.
function showNotification() {
let n = notificationBox.getNotificationWithValue("plugin-hidden");
if (n) {
// If something is already shown, just keep it
return;
}
Services.telemetry.getHistogramById("PLUGINS_INFOBAR_SHOWN").
add(true);
let message;
// Icons set directly cannot be manipulated using moz-image-region, so
// we use CSS classes instead.
let brand = document.getElementById("bundle_brand").getString("brandShortName");
if (actions.length == 1) {
let pluginInfo = actions[0];
let pluginName = pluginInfo.pluginName;
switch (pluginInfo.fallbackType) {
case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY:
message = gNavigatorBundle.getFormattedString(
"pluginActivateNew.message",
[pluginName, origin]);
break;
case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE:
message = gNavigatorBundle.getFormattedString(
"pluginActivateOutdated.message",
[pluginName, origin, brand]);
break;
case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE:
message = gNavigatorBundle.getFormattedString(
"pluginActivateVulnerable.message",
[pluginName, origin, brand]);
}
} else {
// Multi-plugin
message = gNavigatorBundle.getFormattedString(
"pluginActivateMultiple.message", [origin]);
}
let buttons = [
{
label: gNavigatorBundle.getString("pluginContinueBlocking.label"),
accessKey: gNavigatorBundle.getString("pluginContinueBlocking.accesskey"),
callback: function() {
Services.telemetry.getHistogramById("PLUGINS_INFOBAR_BLOCK").
add(true);
Services.perms.addFromPrincipal(principal,
"plugin-hidden-notification",
Services.perms.DENY_ACTION);
}
},
{
label: gNavigatorBundle.getString("pluginActivateTrigger.label"),
accessKey: gNavigatorBundle.getString("pluginActivateTrigger.accesskey"),
callback: function() {
Services.telemetry.getHistogramById("PLUGINS_INFOBAR_ALLOW").
add(true);
let curNotification =
PopupNotifications.getNotification("click-to-play-plugins",
browser);
if (curNotification) {
curNotification.reshow();
}
}
}
];
n = notificationBox.
appendNotification(message, "plugin-hidden", null,
notificationBox.PRIORITY_INFO_HIGH, buttons);
if (haveInsecure) {
n.classList.add('pluginVulnerable');
}
}
if (actions.length == 0) {
hideNotification();
} else {
let notificationPermission = Services.perms.testPermissionFromPrincipal(
principal, "plugin-hidden-notification");
if (notificationPermission == Ci.nsIPermissionManager.DENY_ACTION) {
hideNotification();
} else {
showNotification();
}
}
},
contextMenuCommand: function (browser, plugin, command) {
browser.messageManager.sendAsyncMessage("BrowserPlugins:ContextMenuCommand",
{ command: command }, { plugin: plugin });
},
// Crashed-plugin observer. Notified once per plugin crash, before events
// are dispatched to individual plugin instances.
NPAPIPluginCrashed : function(subject, topic, data) {
let propertyBag = subject;
if (!(propertyBag instanceof Ci.nsIPropertyBag2) ||
!(propertyBag instanceof Ci.nsIWritablePropertyBag2) ||
!propertyBag.hasKey("runID") ||
!propertyBag.hasKey("pluginName")) {
Cu.reportError("A NPAPI plugin crashed, but the properties of this plugin " +
"cannot be read.");
return;
}
let runID = propertyBag.getPropertyAsUint32("runID");
let uglyPluginName = propertyBag.getPropertyAsAString("pluginName");
let pluginName = BrowserUtils.makeNicePluginName(uglyPluginName);
let pluginDumpID = propertyBag.getPropertyAsAString("pluginDumpID");
// If we don't have a minidumpID, we can't (or didn't) submit anything.
// This can happen if the plugin is killed from the task manager.
let state = "noSubmit";
let mm = window.getGroupMessageManager("browsers");
mm.broadcastAsyncMessage("BrowserPlugins:NPAPIPluginProcessCrashed",
{ pluginName, runID, state });
},
/**
* Shows a plugin-crashed notification bar for a browser that has had an
* invisiable NPAPI plugin crash, or a GMP plugin crash.
*
* @param browser
* The browser to show the notification for.
* @param messageString
* The string to put in the notification bar
* @param pluginID
* The unique-per-process identifier for the NPAPI plugin or GMP.
* For a GMP, this is the pluginID. For NPAPI plugins (where "pluginID"
* means something different), this is the runID.
*/
showPluginCrashedNotification: function (browser, messageString, pluginID) {
// If there's already an existing notification bar, don't do anything.
let notificationBox = gBrowser.getNotificationBox(browser);
let notification = notificationBox.getNotificationWithValue("plugin-crashed");
if (notification) {
return;
}
// Configure the notification bar
let priority = notificationBox.PRIORITY_WARNING_MEDIUM;
let iconURL = "chrome://mozapps/skin/plugins/notifyPluginCrashed.png";
let reloadLabel = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.label");
let reloadKey = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.accesskey");
let buttons = [{
label: reloadLabel,
accessKey: reloadKey,
popup: null,
callback: function() { browser.reload(); },
}];
notification = notificationBox.appendNotification(messageString, "plugin-crashed",
iconURL, priority, buttons);
// Add the "learn more" link.
let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let link = notification.ownerDocument.createElementNS(XULNS, "label");
link.className = "text-link";
link.setAttribute("value", gNavigatorBundle.getString("crashedpluginsMessage.learnMore"));
let crashurl = formatURL("app.support.baseURL", true);
crashurl += "plugin-crashed-notificationbar";
link.href = crashurl;
let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
description.appendChild(link);
},
};
gPluginHandler.init();
@@ -1,84 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
/**
* If the user has opted into blocking refresh and redirect attempts by
* default, this handles showing the notification to the user which
* gives them the option to let the refresh or redirect proceed.
*/
var RefreshBlocker = {
init() {
gBrowser.addEventListener("RefreshBlocked", this);
},
uninit() {
gBrowser.removeEventListener("RefreshBlocked", this);
},
handleEvent: function(event) {
if (event.type == "RefreshBlocked") {
this.block(event.originalTarget, event.detail);
}
},
/**
* Shows the blocked refresh / redirect notification for some browser.
*
* @param browser (<xul:browser>)
* The browser that had the refresh blocked. This will be the browser
* for which we'll show the notification on.
* @param data (object)
* An object with the following properties:
*
* URI (string)
* The URI that a page is attempting to refresh or redirect to.
*
* delay (int)
* The delay (in milliseconds) before the page was going to reload
* or redirect.
*
* sameURI (bool)
* true if we're refreshing the page. false if we're redirecting.
*
* outerWindowID (int)
* The outerWindowID of the frame that requested the refresh or
* redirect.
*/
block(browser, data) {
let brandBundle = document.getElementById("bundle_brand");
let brandShortName = brandBundle.getString("brandShortName");
let message =
gNavigatorBundle.getFormattedString(data.sameURI ? "refreshBlocked.refreshLabel"
: "refreshBlocked.redirectLabel",
[brandShortName]);
let notificationBox = gBrowser.getNotificationBox(browser);
let notification = notificationBox.getNotificationWithValue("refresh-blocked");
if (notification) {
notification.label = message;
} else {
let refreshButtonText =
gNavigatorBundle.getString("refreshBlocked.goButton");
let refreshButtonAccesskey =
gNavigatorBundle.getString("refreshBlocked.goButton.accesskey");
let buttons = [{
label: refreshButtonText,
accessKey: refreshButtonAccesskey,
callback: function (notification, button) {
if (browser.messageManager) {
browser.messageManager.sendAsyncMessage("RefreshBlocker:Refresh", data);
}
}
}];
notificationBox.appendNotification(message, "refresh-blocked",
"chrome://browser/skin/Info.png",
notificationBox.PRIORITY_INFO_MEDIUM,
buttons);
}
}
};
@@ -1,48 +0,0 @@
/* 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/. */
var gSafeBrowsing = {
setReportPhishingMenu: function() {
// In order to detect whether or not we're at the phishing warning
// page, we have to check the documentURI instead of the currentURI.
// This is because when the DocShell loads an error page, the
// currentURI stays at the original target, while the documentURI
// will point to the internal error page we loaded instead.
var docURI = gBrowser.selectedBrowser.documentURI;
var isPhishingPage =
docURI && docURI.spec.startsWith("about:blocked?e=deceptiveBlocked");
// Show/hide the appropriate menu item.
document.getElementById("menu_HelpPopup_reportPhishingtoolmenu")
.hidden = isPhishingPage;
document.getElementById("menu_HelpPopup_reportPhishingErrortoolmenu")
.hidden = !isPhishingPage;
var broadcasterId = isPhishingPage
? "reportPhishingErrorBroadcaster"
: "reportPhishingBroadcaster";
var broadcaster = document.getElementById(broadcasterId);
if (!broadcaster)
return;
// Now look at the currentURI to learn which page we were trying
// to browse to.
let uri = gBrowser.currentURI;
if (uri && (uri.schemeIs("http") || uri.schemeIs("https")))
broadcaster.removeAttribute("disabled");
else
broadcaster.setAttribute("disabled", true);
},
/**
* Used to report a phishing page or a false positive
* @param name String One of "Phish", "Error", "Malware" or "MalwareError"
* @return String the report phishing URL.
*/
getReportURL: function(name) {
return SafeBrowsing.getReportURL(name, gBrowser.currentURI);
}
}
@@ -1,376 +0,0 @@
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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/.
#ifdef XP_UNIX
#ifndef XP_MACOSX
#define XP_GNOME 1
#endif
#endif
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
<stringbundle id="bundle_shell" src="chrome://browser/locale/shellservice.properties"/>
<stringbundle id="bundle_preferences" src="chrome://browser/locale/preferences/preferences.properties"/>
</stringbundleset>
<commandset id="mainCommandSet">
<command id="cmd_newNavigator" oncommand="OpenBrowserWindow()" reserved="true"/>
<command id="cmd_handleBackspace" oncommand="BrowserHandleBackspace();" />
<command id="cmd_handleShiftBackspace" oncommand="BrowserHandleShiftBackspace();" />
<command id="cmd_newNavigatorTab" oncommand="BrowserOpenTab(event);" reserved="true"/>
<command id="cmd_newNavigatorTabNoEvent" oncommand="BrowserOpenTab();" reserved="true"/>
<command id="Browser:OpenFile" oncommand="BrowserOpenFileWindow();"/>
<command id="Browser:SavePage" oncommand="saveBrowser(gBrowser.selectedBrowser);"/>
<command id="Browser:SendLink"
oncommand="MailIntegration.sendLinkForBrowser(gBrowser.selectedBrowser);"/>
<command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
<command id="cmd_print" oncommand="PrintUtils.printWindow(window.gBrowser.selectedBrowser.outerWindowID, window.gBrowser.selectedBrowser);"/>
<command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
<command id="cmd_close" oncommand="BrowserCloseTabOrWindow()" reserved="true"/>
<command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()" reserved="true"/>
<command id="cmd_toggleMute" oncommand="gBrowser.selectedTab.toggleMuteAudio()"/>
<command id="cmd_CustomizeToolbars" oncommand="BrowserCustomizeToolbar()"/>
<command id="cmd_quitApplication" oncommand="goQuitApplication()" reserved="true"/>
<commandset id="editMenuCommands"/>
<command id="View:PageSource" oncommand="BrowserViewSource(window.gBrowser.selectedBrowser);" observes="canViewSource"/>
<command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
<command id="View:FullScreen" oncommand="BrowserFullScreen();"/>
<command id="View:ReaderView" oncommand="ReaderParent.toggleReaderMode(event);"/>
<command id="cmd_find"
oncommand="gFindBar.onFindCommand();"
observes="isImage"/>
<command id="cmd_findAgain"
oncommand="gFindBar.onFindAgainCommand(false);"
observes="isImage"/>
<command id="cmd_findPrevious"
oncommand="gFindBar.onFindAgainCommand(true);"
observes="isImage"/>
#ifdef XP_MACOSX
<command id="cmd_findSelection" oncommand="gFindBar.onFindSelectionCommand();"/>
#endif
<!-- work-around bug 392512 -->
<command id="Browser:AddBookmarkAs"
oncommand="PlacesCommandHook.bookmarkCurrentPage(true, PlacesUtils.bookmarksMenuFolderId);"/>
<!-- The command disabled state must be manually updated through
PlacesCommandHook.updateBookmarkAllTabsCommand() -->
<command id="Browser:BookmarkAllTabs"
oncommand="PlacesCommandHook.bookmarkCurrentPages();"/>
<command id="Browser:Home" oncommand="BrowserHome();"/>
<command id="Browser:Back" oncommand="BrowserBack();" disabled="true"/>
<command id="Browser:BackOrBackDuplicate" oncommand="BrowserBack(event);" disabled="true">
<observes element="Browser:Back" attribute="disabled"/>
</command>
<command id="Browser:Forward" oncommand="BrowserForward();" disabled="true"/>
<command id="Browser:ForwardOrForwardDuplicate" oncommand="BrowserForward(event);" disabled="true">
<observes element="Browser:Forward" attribute="disabled"/>
</command>
<command id="Browser:Stop" oncommand="BrowserStop();" disabled="true"/>
<command id="Browser:Reload" oncommand="if (event.shiftKey) BrowserReloadSkipCache(); else BrowserReload()" disabled="true"/>
<command id="Browser:ReloadOrDuplicate" oncommand="BrowserReloadOrDuplicate(event)" disabled="true">
<observes element="Browser:Reload" attribute="disabled"/>
</command>
<command id="Browser:ReloadSkipCache" oncommand="BrowserReloadSkipCache()" disabled="true">
<observes element="Browser:Reload" attribute="disabled"/>
</command>
<command id="Browser:NextTab" oncommand="gBrowser.tabContainer.advanceSelectedTab(1, true);" reserved="true"/>
<command id="Browser:PrevTab" oncommand="gBrowser.tabContainer.advanceSelectedTab(-1, true);" reserved="true"/>
<command id="Browser:ShowAllTabs" oncommand="allTabs.open();"/>
<command id="cmd_fullZoomReduce" oncommand="FullZoom.reduce()"/>
<command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
<command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>
<command id="cmd_fullZoomToggle" oncommand="ZoomManager.toggleZoom();"/>
<command id="cmd_gestureRotateLeft" oncommand="gGestureSupport.rotate(event.sourceEvent)"/>
<command id="cmd_gestureRotateRight" oncommand="gGestureSupport.rotate(event.sourceEvent)"/>
<command id="cmd_gestureRotateEnd" oncommand="gGestureSupport.rotateEnd()"/>
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/>
<command id="Browser:NewUserContextTab" oncommand="openNewUserContextTab(event.sourceEvent);" reserved="true"/>
<command id="Browser:OpenAboutContainers" oncommand="openPreferences('paneContainers');"/>
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
<command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()"/>
<command id="Tools:Sanitize"
oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
<command id="Tools:PrivateBrowsing"
oncommand="OpenBrowserWindow({private: true});" reserved="true"/>
<command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
<command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
</commandset>
<commandset id="placesCommands">
<command id="Browser:ShowAllBookmarks"
oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"/>
<command id="Browser:ShowAllHistory"
oncommand="PlacesCommandHook.showPlacesOrganizer('History');"/>
</commandset>
<broadcasterset id="mainBroadcasterSet">
<broadcaster id="viewBookmarksSidebar" autoCheck="false" label="&bookmarksButton.label;"
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
oncommand="SidebarUI.toggle('viewBookmarksSidebar');"/>
<!-- for both places and non-places, the sidebar lives at
chrome://browser/content/history/history-panel.xul so there are no
problems when switching between versions -->
<broadcaster id="viewHistorySidebar" autoCheck="false" sidebartitle="&historyButton.label;"
type="checkbox" group="sidebar"
sidebarurl="chrome://browser/content/history/history-panel.xul"
oncommand="SidebarUI.toggle('viewHistorySidebar');"/>
<broadcaster id="viewWebPanelsSidebar" autoCheck="false"
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/web-panels.xul"
oncommand="SidebarUI.toggle('viewWebPanelsSidebar');"/>
<broadcaster id="bookmarkThisPageBroadcaster"
label="&bookmarkThisPageCmd.label;"
bookmarklabel="&bookmarkThisPageCmd.label;"
editlabel="&editThisBookmarkCmd.label;"/>
<!-- popup blocking menu items -->
<broadcaster id="blockedPopupAllowSite"
accesskey="&allowPopups.accesskey;"
oncommand="gPopupBlockerObserver.toggleAllowPopupsForSite(event);"/>
<broadcaster id="blockedPopupEditSettings"
#ifdef XP_WIN
label="&editPopupSettings.label;"
#else
label="&editPopupSettingsUnix.label;"
#endif
accesskey="&editPopupSettings.accesskey;"
oncommand="gPopupBlockerObserver.editPopupSettings();"/>
<broadcaster id="blockedPopupDontShowMessage"
accesskey="&dontShowMessage.accesskey;"
type="checkbox"
oncommand="gPopupBlockerObserver.dontShowMessage();"/>
<broadcaster id="blockedPopupsSeparator"/>
<broadcaster id="isImage"/>
<broadcaster id="canViewSource"/>
<broadcaster id="isFrameImage"/>
<broadcaster id="singleFeedMenuitemState" disabled="true"/>
<broadcaster id="multipleFeedsMenuState" hidden="true"/>
<!-- Sync broadcasters -->
<!-- A broadcaster of a number of attributes suitable for "sync now" UI -
A 'syncstatus' attribute is set while actively syncing, and the label
attribute which changes from "sync now" to "syncing" etc. -->
#ifdef MOZ_SERVICES_SYNC
<broadcaster id="sync-status"/>
<!-- broadcasters of the "hidden" attribute to reflect setup state for
menus -->
<broadcaster id="sync-setup-state"/>
<broadcaster id="sync-syncnow-state" hidden="true"/>
#endif
<broadcaster id="workOfflineMenuitemState"/>
<broadcaster id="devtoolsMenuBroadcaster_ErrorConsole"
label="&errorConsoleCmd.label;"
command="Tools:ErrorConsole"/>
<broadcaster id="devtoolsMenuBroadcaster_PageSource"
label="&pageSourceCmd.label;"
key="key_viewSource"
command="View:PageSource">
<observes element="canViewSource" attribute="disabled"/>
</broadcaster>
</broadcasterset>
<keyset id="mainKeyset">
<key id="key_newNavigator"
key="&newNavigatorCmd.key;"
command="cmd_newNavigator"
modifiers="accel"/>
<key id="key_newNavigatorTab" key="&tabCmd.commandkey;" modifiers="accel" command="cmd_newNavigatorTabNoEvent"/>
<key id="focusURLBar" key="&openCmd.commandkey;" command="Browser:OpenLocation"
modifiers="accel"/>
#ifndef XP_MACOSX
<key id="focusURLBar2" key="&urlbar.accesskey;" command="Browser:OpenLocation"
modifiers="alt"/>
#endif
#
# Search Command Key Logic works like this:
#
# Unix: Ctrl+K (cross platform binding)
# Ctrl+J (in case of emacs Ctrl-K conflict)
# Mac: Cmd+K (cross platform binding)
# Cmd+Opt+F (platform convention)
# Win: Ctrl+K (cross platform binding)
# Ctrl+E (IE compat)
#
# We support Ctrl+K on all platforms now and advertise it in the menu since it is
# our standard - it is a "safe" choice since it is near no harmful keys like "W" as
# "E" is. People mourning the loss of Ctrl+K for emacs compat can switch their GTK
# system setting to use emacs emulation, and we should respect it. Focus-Search-Box
# is a fundamental keybinding and we are maintaining a XP binding so that it is easy
# for people to switch to Linux.
#
<key id="key_search" key="&searchFocus.commandkey;" command="Tools:Search" modifiers="accel"/>
#ifdef XP_MACOSX
<key id="key_search2" key="&findOnCmd.commandkey;" command="Tools:Search" modifiers="accel,alt"/>
#endif
#ifdef XP_WIN
<key id="key_search2" key="&searchFocus.commandkey2;" command="Tools:Search" modifiers="accel"/>
#endif
#ifdef XP_GNOME
<key id="key_search2" key="&searchFocusUnix.commandkey;" command="Tools:Search" modifiers="accel"/>
<key id="key_openDownloads" key="&downloadsUnix.commandkey;" command="Tools:Downloads" modifiers="accel,shift"/>
#else
<key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/>
#endif
<key id="key_openAddons" key="&addons.commandkey;" command="Tools:Addons" modifiers="accel,shift"/>
<key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/>
<key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/>
<key id="printKb" key="&printCmd.commandkey;" command="cmd_print" modifiers="accel"/>
<key id="key_close" key="&closeCmd.key;" command="cmd_close" modifiers="accel"/>
<key id="key_closeWindow" key="&closeCmd.key;" command="cmd_closeWindow" modifiers="accel,shift"/>
<key id="key_toggleMute" key="&toggleMuteCmd.key;" command="cmd_toggleMute" modifiers="control"/>
<key id="key_undo"
key="&undoCmd.key;"
modifiers="accel"/>
#ifdef XP_UNIX
<key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"/>
#else
<key id="key_redo" key="&redoCmd.key;" modifiers="accel"/>
#endif
<key id="key_cut"
key="&cutCmd.key;"
modifiers="accel"/>
<key id="key_copy"
key="&copyCmd.key;"
modifiers="accel"/>
<key id="key_paste"
key="&pasteCmd.key;"
modifiers="accel"/>
<key id="key_delete" keycode="VK_DELETE" command="cmd_delete"/>
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
<key keycode="VK_BACK" command="cmd_handleBackspace"/>
<key keycode="VK_BACK" command="cmd_handleShiftBackspace" modifiers="shift"/>
#ifndef XP_MACOSX
<key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="alt"/>
<key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="alt"/>
#else
<key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="accel" />
<key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="accel" />
#endif
#ifdef XP_UNIX
<key id="goBackKb2" key="&goBackCmd.commandKey;" command="Browser:Back" modifiers="accel"/>
<key id="goForwardKb2" key="&goForwardCmd.commandKey;" command="Browser:Forward" modifiers="accel"/>
#endif
<key id="goHome" keycode="VK_HOME" command="Browser:Home" modifiers="alt"/>
<key keycode="VK_F5" command="Browser:Reload"/>
#ifndef XP_MACOSX
<key id="showAllHistoryKb" key="&showAllHistoryCmd.commandkey;" command="Browser:ShowAllHistory" modifiers="accel,shift"/>
<key keycode="VK_F5" command="Browser:ReloadSkipCache" modifiers="accel"/>
<key id="key_fullScreen" keycode="VK_F11" command="View:FullScreen"/>
#else
<key id="key_fullScreen" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,control"/>
<key id="key_fullScreen_old" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,shift"/>
<key keycode="VK_F11" command="View:FullScreen"/>
#endif
<key id="key_toggleReaderMode" key="&toggleReaderMode.key;" command="View:ReaderView" modifiers="accel,alt" disabled="true"/>
<key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/>
<key key="&reloadCmd.commandkey;" command="Browser:ReloadSkipCache" modifiers="accel,shift"/>
<key id="key_viewSource" key="&pageSourceCmd.commandkey;" command="View:PageSource" modifiers="accel"/>
#ifndef XP_WIN
<key id="key_viewInfo" key="&pageInfoCmd.commandkey;" command="View:PageInfo" modifiers="accel"/>
#endif
<key id="key_find" key="&findOnCmd.commandkey;" command="cmd_find" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.commandkey;" command="cmd_findAgain" modifiers="accel"/>
<key id="key_findPrevious" key="&findAgainCmd.commandkey;" command="cmd_findPrevious" modifiers="accel,shift"/>
#ifdef XP_MACOSX
<key id="key_findSelection" key="&findSelectionCmd.commandkey;" command="cmd_findSelection" modifiers="accel"/>
#endif
<key keycode="&findAgainCmd.commandkey2;" command="cmd_findAgain"/>
<key keycode="&findAgainCmd.commandkey2;" command="cmd_findPrevious" modifiers="shift"/>
<key id="addBookmarkAsKb" key="&bookmarkThisPageCmd.commandkey;" command="Browser:AddBookmarkAs" modifiers="accel"/>
# Accel+Shift+A-F are reserved on GTK
#ifndef MOZ_WIDGET_GTK
<key id="bookmarkAllTabsKb" key="&bookmarkThisPageCmd.commandkey;" oncommand="PlacesCommandHook.bookmarkCurrentPages();" modifiers="accel,shift"/>
<key id="manBookmarkKb" key="&bookmarksCmd.commandkey;" command="Browser:ShowAllBookmarks" modifiers="accel,shift"/>
#else
<key id="manBookmarkKb" key="&bookmarksGtkCmd.commandkey;" command="Browser:ShowAllBookmarks" modifiers="accel,shift"/>
#endif
<key id="viewBookmarksSidebarKb" key="&bookmarksCmd.commandkey;" command="viewBookmarksSidebar" modifiers="accel"/>
#ifdef XP_WIN
# Cmd+I is conventially mapped to Info on MacOS X, thus it should not be
# overridden for other purposes there.
<key id="viewBookmarksSidebarWinKb" key="&bookmarksWinCmd.commandkey;" command="viewBookmarksSidebar" modifiers="accel"/>
#endif
<key id="key_stop" keycode="VK_ESCAPE" command="Browser:Stop"/>
#ifdef XP_MACOSX
<key id="key_stop_mac" modifiers="accel" key="&stopCmd.macCommandKey;" command="Browser:Stop"/>
#endif
<key id="key_gotoHistory"
key="&historySidebarCmd.commandKey;"
#ifdef XP_MACOSX
modifiers="accel,shift"
#else
modifiers="accel"
#endif
command="viewHistorySidebar"/>
<key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce" modifiers="accel"/>
<key key="&fullZoomReduceCmd.commandkey2;" command="cmd_fullZoomReduce" modifiers="accel"/>
<key id="key_fullZoomEnlarge" key="&fullZoomEnlargeCmd.commandkey;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
<key key="&fullZoomEnlargeCmd.commandkey2;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
<key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
<key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/>
<key key="&fullZoomResetCmd.commandkey2;" command="cmd_fullZoomReset" modifiers="accel"/>
<key id="key_showAllTabs" command="Browser:ShowAllTabs" keycode="VK_TAB" modifiers="control,shift"/>
<key id="key_switchTextDirection" key="&bidiSwitchTextDirectionItem.commandkey;" command="cmd_switchTextDirection" modifiers="accel,shift" />
<key id="key_privatebrowsing" command="Tools:PrivateBrowsing" key="&privateBrowsingCmd.commandkey;" modifiers="accel,shift"/>
<key id="key_sanitize" command="Tools:Sanitize" keycode="VK_DELETE" modifiers="accel,shift"/>
#ifdef XP_MACOSX
<key id="key_sanitize_mac" command="Tools:Sanitize" keycode="VK_BACK" modifiers="accel,shift"/>
<key id="key_quitApplication" key="&quitApplicationCmdUnix.key;" modifiers="accel" reserved="true"/>
#elifdef XP_UNIX
<key id="key_quitApplication" key="&quitApplicationCmdUnix.key;" command="cmd_quitApplication" modifiers="accel"/>
#endif
#ifdef FULL_BROWSER_WINDOW
<key id="key_undoCloseTab" command="History:UndoCloseTab" key="&tabCmd.commandkey;" modifiers="accel,shift"/>
#endif
<key id="key_undoCloseWindow" command="History:UndoCloseWindow" key="&newNavigatorCmd.key;" modifiers="accel,shift"/>
#ifdef XP_GNOME
#define NUM_SELECT_TAB_MODIFIER alt
#else
#define NUM_SELECT_TAB_MODIFIER accel
#endif
#expand <key id="key_selectTab1" oncommand="gBrowser.selectTabAtIndex(0, event);" key="1" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectTab2" oncommand="gBrowser.selectTabAtIndex(1, event);" key="2" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectTab3" oncommand="gBrowser.selectTabAtIndex(2, event);" key="3" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectTab4" oncommand="gBrowser.selectTabAtIndex(3, event);" key="4" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectTab5" oncommand="gBrowser.selectTabAtIndex(4, event);" key="5" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectTab6" oncommand="gBrowser.selectTabAtIndex(5, event);" key="6" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectTab7" oncommand="gBrowser.selectTabAtIndex(6, event);" key="7" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectTab8" oncommand="gBrowser.selectTabAtIndex(7, event);" key="8" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectLastTab" oncommand="gBrowser.selectTabAtIndex(-1, event);" key="9" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
</keyset>
# Used by baseMenuOverlay
#ifdef XP_MACOSX
<commandset id="baseMenuCommandSet" />
#endif
<keyset id="baseMenuKeyset" />
@@ -1,331 +0,0 @@
/* 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/. */
/**
* SidebarUI controls showing and hiding the browser sidebar.
*
* @note
* Some of these methods take a commandID argument - we expect to find a
* xul:broadcaster element with the specified ID.
* The following attributes on that element may be used and/or modified:
* - id (required) the string to match commandID. The convention
* is to use this naming scheme: 'view<sidebar-name>Sidebar'.
* - sidebarurl (required) specifies the URL to load in this sidebar.
* - sidebartitle or label (in that order) specify the title to
* display on the sidebar.
* - checked indicates whether the sidebar is currently displayed.
* Note that toggleSidebar updates this attribute when
* it changes the sidebar's visibility.
* - group this attribute must be set to "sidebar".
*/
var SidebarUI = {
browser: null,
_box: null,
_title: null,
_splitter: null,
init() {
this._box = document.getElementById("sidebar-box");
this.browser = document.getElementById("sidebar");
this._title = document.getElementById("sidebar-title");
this._splitter = document.getElementById("sidebar-splitter");
if (!this.adoptFromWindow(window.opener)) {
let commandID = this._box.getAttribute("sidebarcommand");
if (commandID) {
let command = document.getElementById(commandID);
if (command) {
this._delayedLoad = true;
this._box.hidden = false;
this._splitter.hidden = false;
command.setAttribute("checked", "true");
} else {
// Remove the |sidebarcommand| attribute, because the element it
// refers to no longer exists, so we should assume this sidebar
// panel has been uninstalled. (249883)
this._box.removeAttribute("sidebarcommand");
}
}
}
},
uninit() {
let enumerator = Services.wm.getEnumerator(null);
enumerator.getNext();
if (!enumerator.hasMoreElements()) {
document.persist("sidebar-box", "sidebarcommand");
document.persist("sidebar-box", "width");
document.persist("sidebar-box", "src");
document.persist("sidebar-title", "value");
}
},
/**
* Try and adopt the status of the sidebar from another window.
* @param {Window} sourceWindow - Window to use as a source for sidebar status.
* @return true if we adopted the state, or false if the caller should
* initialize the state itself.
*/
adoptFromWindow(sourceWindow) {
// No source window, or it being closed, or not chrome, or in a different
// private-browsing context means we can't adopt.
if (!sourceWindow || sourceWindow.closed ||
!sourceWindow.document.documentURIObject.schemeIs("chrome") ||
PrivateBrowsingUtils.isWindowPrivate(window) != PrivateBrowsingUtils.isWindowPrivate(sourceWindow)) {
return false;
}
// If the opener had a sidebar, open the same sidebar in our window.
// The opener can be the hidden window too, if we're coming from the state
// where no windows are open, and the hidden window has no sidebar box.
let sourceUI = sourceWindow.SidebarUI;
if (!sourceUI || !sourceUI._box) {
// no source UI or no _box means we also can't adopt the state.
return false;
}
if (sourceUI._box.hidden) {
// just hidden means we have adopted the hidden state.
return true;
}
let commandID = sourceUI._box.getAttribute("sidebarcommand");
let commandElem = document.getElementById(commandID);
// dynamically generated sidebars will fail this check, but we still
// consider it adopted.
if (!commandElem) {
return true;
}
this._title.setAttribute("value",
sourceUI._title.getAttribute("value"));
this._box.setAttribute("width", sourceUI._box.boxObject.width);
this._box.setAttribute("sidebarcommand", commandID);
// Note: we're setting 'src' on this._box, which is a <vbox>, not on
// the <browser id="sidebar">. This lets us delay the actual load until
// delayedStartup().
this._box.setAttribute("src", sourceUI.browser.getAttribute("src"));
this._delayedLoad = true;
this._box.hidden = false;
this._splitter.hidden = false;
commandElem.setAttribute("checked", "true");
return true;
},
/**
* If loading a sidebar was delayed on startup, start the load now.
*/
startDelayedLoad() {
if (!this._delayedLoad) {
return;
}
this.browser.setAttribute("src", this._box.getAttribute("src"));
},
/**
* Fire a "SidebarFocused" event on the sidebar's |window| to give the sidebar
* a chance to adjust focus as needed. An additional event is needed, because
* we don't want to focus the sidebar when it's opened on startup or in a new
* window, only when the user opens the sidebar.
*/
_fireFocusedEvent() {
let event = new CustomEvent("SidebarFocused", {bubbles: true});
this.browser.contentWindow.dispatchEvent(event);
// Run the original function for backwards compatibility.
fireSidebarFocusedEvent();
},
/**
* True if the sidebar is currently open.
*/
get isOpen() {
return !this._box.hidden;
},
/**
* The ID of the current sidebar (ie, the ID of the broadcaster being used).
* This can be set even if the sidebar is hidden.
*/
get currentID() {
return this._box.getAttribute("sidebarcommand");
},
get title() {
return this._title.value;
},
set title(value) {
this._title.value = value;
},
/**
* Toggle the visibility of the sidebar. If the sidebar is hidden or is open
* with a different commandID, then the sidebar will be opened using the
* specified commandID. Otherwise the sidebar will be hidden.
*
* @param {string} commandID ID of the xul:broadcaster element to use.
* @return {Promise}
*/
toggle(commandID = this.currentID) {
if (this.isOpen && commandID == this.currentID) {
this.hide();
return Promise.resolve();
}
return this.show(commandID);
},
/**
* Show the sidebar, using the parameters from the specified broadcaster.
* @see SidebarUI note.
*
* @param {string} commandID ID of the xul:broadcaster element to use.
*/
show(commandID) {
return new Promise((resolve, reject) => {
let sidebarBroadcaster = document.getElementById(commandID);
if (!sidebarBroadcaster || sidebarBroadcaster.localName != "broadcaster") {
reject(new Error("Invalid sidebar broadcaster specified: " + commandID));
return;
}
let broadcasters = document.getElementsByAttribute("group", "sidebar");
for (let broadcaster of broadcasters) {
// skip elements that observe sidebar broadcasters and random
// other elements
if (broadcaster.localName != "broadcaster") {
continue;
}
if (broadcaster != sidebarBroadcaster) {
broadcaster.removeAttribute("checked");
} else {
sidebarBroadcaster.setAttribute("checked", "true");
}
}
this._box.hidden = false;
this._splitter.hidden = false;
this._box.setAttribute("sidebarcommand", sidebarBroadcaster.id);
let title = sidebarBroadcaster.getAttribute("sidebartitle");
if (!title) {
title = sidebarBroadcaster.getAttribute("label");
}
this._title.value = title;
let url = sidebarBroadcaster.getAttribute("sidebarurl");
this.browser.setAttribute("src", url); // kick off async load
// We set this attribute here in addition to setting it on the <browser>
// element itself, because the code in SidebarUI.uninit() persists this
// attribute, not the "src" of the <browser id="sidebar">. The reason it
// does that is that we want to delay sidebar load a bit when a browser
// window opens. See delayedStartup() and SidebarUI.startDelayedLoad().
this._box.setAttribute("src", url);
if (this.browser.contentDocument.location.href != url) {
let onLoad = event => {
this.browser.removeEventListener("load", onLoad, true);
// We're handling the 'load' event before it bubbles up to the usual
// (non-capturing) event handlers. Let it bubble up before firing the
// SidebarFocused event.
setTimeout(() => this._fireFocusedEvent(), 0);
// Run the original function for backwards compatibility.
sidebarOnLoad(event);
resolve();
};
this.browser.addEventListener("load", onLoad, true);
} else {
// Older code handled this case, so we do it too.
this._fireFocusedEvent();
resolve();
}
let selBrowser = gBrowser.selectedBrowser;
selBrowser.messageManager.sendAsyncMessage("Sidebar:VisibilityChange",
{commandID: commandID, isOpen: true}
);
});
},
/**
* Hide the sidebar.
*/
hide() {
if (!this.isOpen) {
return;
}
let commandID = this._box.getAttribute("sidebarcommand");
let sidebarBroadcaster = document.getElementById(commandID);
if (sidebarBroadcaster.getAttribute("checked") != "true") {
return;
}
// Replace the document currently displayed in the sidebar with about:blank
// so that we can free memory by unloading the page. We need to explicitly
// create a new content viewer because the old one doesn't get destroyed
// until about:blank has loaded (which does not happen as long as the
// element is hidden).
this.browser.setAttribute("src", "about:blank");
this.browser.docShell.createAboutBlankContentViewer(null);
sidebarBroadcaster.removeAttribute("checked");
this._box.setAttribute("sidebarcommand", "");
this._title.value = "";
this._box.hidden = true;
this._splitter.hidden = true;
let selBrowser = gBrowser.selectedBrowser;
selBrowser.focus();
selBrowser.messageManager.sendAsyncMessage("Sidebar:VisibilityChange",
{commandID: commandID, isOpen: false}
);
},
};
/**
* This exists for backards compatibility - it will be called once a sidebar is
* ready, following any request to show it.
*
* @deprecated
*/
function fireSidebarFocusedEvent() {}
/**
* This exists for backards compatibility - it gets called when a sidebar has
* been loaded.
*
* @deprecated
*/
function sidebarOnLoad(event) {}
/**
* This exists for backards compatibility, and is equivilent to
* SidebarUI.toggle() without the forceOpen param. With forceOpen set to true,
* it is equalivent to SidebarUI.show().
*
* @deprecated
*/
function toggleSidebar(commandID, forceOpen = false) {
Deprecated.warning("toggleSidebar() is deprecated, please use SidebarUI.toggle() or SidebarUI.show() instead",
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Sidebar");
if (forceOpen) {
SidebarUI.show(commandID);
} else {
SidebarUI.toggle(commandID);
}
}
@@ -1,471 +0,0 @@
# 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/.
// gSyncUI handles updating the tools menu
var gSyncUI = {
_obs: ["weave:service:sync:start",
"weave:service:sync:delayed",
"weave:service:quota:remaining",
"weave:service:setup-complete",
"weave:service:login:start",
"weave:service:login:finish",
"weave:service:logout:finish",
"weave:service:start-over",
"weave:ui:login:error",
"weave:ui:sync:error",
"weave:ui:sync:finish",
"weave:ui:clear-error",
],
_unloaded: false,
init: function SUI_init() {
// Proceed to set up the UI if Sync has already started up.
// Otherwise we'll do it when Sync is firing up.
let xps = Components.classes["@mozilla.org/weave/service;1"]
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
if (xps.ready) {
this.initUI();
return;
}
Services.obs.addObserver(this, "weave:service:ready", true);
// Remove the observer if the window is closed before the observer
// was triggered.
window.addEventListener("unload", function onUnload() {
gSyncUI._unloaded = true;
window.removeEventListener("unload", onUnload, false);
Services.obs.removeObserver(gSyncUI, "weave:service:ready");
if (Weave.Status.ready) {
gSyncUI._obs.forEach(function(topic) {
Services.obs.removeObserver(gSyncUI, topic);
});
}
}, false);
},
initUI: function SUI_initUI() {
// If this is a browser window?
if (gBrowser) {
this._obs.push("weave:notification:added");
}
this._obs.forEach(function(topic) {
Services.obs.addObserver(this, topic, true);
}, this);
if (gBrowser && Weave.Notifications.notifications.length) {
this.initNotifications();
}
this.updateUI();
},
initNotifications: function SUI_initNotifications() {
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let notificationbox = document.createElementNS(XULNS, "notificationbox");
notificationbox.id = "sync-notifications";
notificationbox.setAttribute("flex", "1");
let bottombox = document.getElementById("browser-bottombox");
bottombox.insertBefore(notificationbox, bottombox.firstChild);
// Force a style flush to ensure that our binding is attached.
notificationbox.clientTop;
// notificationbox will listen to observers from now on.
Services.obs.removeObserver(this, "weave:notification:added");
},
_wasDelayed: false,
_needsSetup: function SUI__needsSetup() {
let firstSync = Services.prefs.getCharPref("services.sync.firstSync", "");
return Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
firstSync == "notReady";
},
updateUI: function SUI_updateUI() {
let needsSetup = this._needsSetup();
document.getElementById("sync-setup-state").hidden = !needsSetup;
document.getElementById("sync-syncnow-state").hidden = needsSetup;
if (!gBrowser) {
return;
}
let button = document.getElementById("sync-button");
if (!button) {
return;
}
button.removeAttribute("status");
this._updateLastSyncTime();
if (needsSetup) {
button.removeAttribute("tooltiptext");
button.setAttribute("label", this._stringBundle.GetStringFromName("setupsync.label"));
} else {
button.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label"));
}
},
// Functions called by observers
onActivityStart: function SUI_onActivityStart() {
if (!gBrowser)
return;
let button = document.getElementById("sync-button");
if (!button)
return;
button.setAttribute("status", "active");
button.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label"));
},
onSyncDelay: function SUI_onSyncDelay() {
// basically, we want to just inform users that stuff is going to take a while
let title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
let description = this._stringBundle.GetStringFromName("error.sync.no_node_found");
let buttons = [new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
function() { gSyncUI.openServerStatus(); return true; }
)];
let notification = new Weave.Notification(
title, description, null, Weave.Notifications.PRIORITY_INFO, buttons);
Weave.Notifications.replaceTitle(notification);
this._wasDelayed = true;
},
onLoginFinish: function SUI_onLoginFinish() {
// Clear out any login failure notifications
let title = this._stringBundle.GetStringFromName("error.login.title");
this.clearError(title);
},
onSetupComplete: function SUI_onSetupComplete() {
this.onLoginFinish();
},
onLoginError: function SUI_onLoginError() {
// if login fails, any other notifications are essentially moot
Weave.Notifications.removeAll();
// if we haven't set up the client, don't show errors
if (this._needsSetup()) {
this.updateUI();
return;
}
let title = this._stringBundle.GetStringFromName("error.login.title");
let description;
if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
// Convert to days
let lastSync =
Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
description =
this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
} else {
let reason = Weave.Utils.getErrorString(Weave.Status.login);
description =
this._stringBundle.formatStringFromName("error.sync.description", [reason], 1);
}
let buttons = [];
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.login.prefs.label"),
this._stringBundle.GetStringFromName("error.login.prefs.accesskey"),
function() { gSyncUI.openPrefs(); return true; }
));
let notification = new Weave.Notification(title, description, null,
Weave.Notifications.PRIORITY_WARNING, buttons);
Weave.Notifications.replaceTitle(notification);
this.updateUI();
},
onLogout: function SUI_onLogout() {
this.updateUI();
},
onStartOver: function SUI_onStartOver() {
this.clearError();
},
onQuotaNotice: function onQuotaNotice(subject, data) {
let title = this._stringBundle.GetStringFromName("warning.sync.quota.label");
let description = this._stringBundle.GetStringFromName("warning.sync.quota.description");
let buttons = [];
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"),
this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"),
function() { gSyncUI.openQuotaDialog(); return true; }
));
let notification = new Weave.Notification(
title, description, null, Weave.Notifications.PRIORITY_WARNING, buttons);
Weave.Notifications.replaceTitle(notification);
},
openServerStatus: function () {
let statusURL = Services.prefs.getCharPref("services.sync.statusURL");
window.openUILinkIn(statusURL, "tab");
},
// Commands
doSync: function SUI_doSync() {
setTimeout(function() Weave.Service.errorHandler.syncAndReportErrors(), 0);
},
handleToolbarButton: function SUI_handleStatusbarButton() {
if (this._needsSetup())
this.openSetup();
else
this.doSync();
},
//XXXzpao should be part of syncCommon.js - which we might want to make a module...
// To be fixed in a followup (bug 583366)
/**
* Invoke the Sync setup wizard.
*
* @param wizardType
* Indicates type of wizard to launch:
* null -- regular set up wizard
* "pair" -- pair a device first
* "reset" -- reset sync
*/
openSetup: function SUI_openSetup(wizardType) {
let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
win.focus();
else {
window.openDialog("chrome://browser/content/sync/setup.xul",
"weaveSetup", "centerscreen,chrome,resizable=no",
wizardType);
}
},
openAddDevice: function () {
if (!Weave.Utils.ensureMPUnlocked())
return;
let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
if (win)
win.focus();
else
window.openDialog("chrome://browser/content/sync/addDevice.xul",
"syncAddDevice", "centerscreen,chrome,resizable=no");
},
openQuotaDialog: function SUI_openQuotaDialog() {
let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
if (win)
win.focus();
else
Services.ww.activeWindow.openDialog(
"chrome://browser/content/sync/quota.xul", "",
"centerscreen,chrome,dialog,modal");
},
openPrefs: function SUI_openPrefs() {
openPreferences("paneSync");
},
// Helpers
_updateLastSyncTime: function SUI__updateLastSyncTime() {
if (!gBrowser)
return;
let syncButton = document.getElementById("sync-button");
if (!syncButton)
return;
let lastSync = Services.prefs.getCharPref("services.sync.lastSync", "");
if (!lastSync || this._needsSetup()) {
syncButton.removeAttribute("tooltiptext");
return;
}
// Show the day-of-week and time (HH:MM) of last sync
let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
let lastSyncLabel =
this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1);
syncButton.setAttribute("tooltiptext", lastSyncLabel);
},
clearError: function SUI_clearError(errorString) {
Weave.Notifications.removeAll(errorString);
this.updateUI();
},
onSyncFinish: function SUI_onSyncFinish() {
let title = this._stringBundle.GetStringFromName("error.sync.title");
// Clear out sync failures on a successful sync
this.clearError(title);
if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
this.clearError(title);
this._wasDelayed = false;
}
},
onSyncError: function SUI_onSyncError() {
let title = this._stringBundle.GetStringFromName("error.sync.title");
if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) {
this.onLoginError();
return;
}
let description;
if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
// Convert to days
let lastSync =
Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
description =
this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
} else {
let error = Weave.Utils.getErrorString(Weave.Status.sync);
description =
this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
}
let priority = Weave.Notifications.PRIORITY_WARNING;
let buttons = [];
// Check if the client is outdated in some way
let outdated = Weave.Status.sync == Weave.VERSION_OUT_OF_DATE;
for (let [engine, reason] in Iterator(Weave.Status.engines))
outdated = outdated || reason == Weave.VERSION_OUT_OF_DATE;
if (outdated) {
description = this._stringBundle.GetStringFromName(
"error.sync.needUpdate.description");
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.needUpdate.label"),
this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"),
function() {
window.openUILinkIn(Services.prefs.getCharPref("services.sync.outdated.url"), "tab");
return true;
}
));
}
else if (Weave.Status.sync == Weave.OVER_QUOTA) {
description = this._stringBundle.GetStringFromName(
"error.sync.quota.description");
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName(
"error.sync.viewQuotaButton.label"),
this._stringBundle.GetStringFromName(
"error.sync.viewQuotaButton.accesskey"),
function() { gSyncUI.openQuotaDialog(); return true; } )
);
}
else if (Weave.Status.enforceBackoff) {
priority = Weave.Notifications.PRIORITY_INFO;
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
function() { gSyncUI.openServerStatus(); return true; }
));
}
else {
priority = Weave.Notifications.PRIORITY_INFO;
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"),
this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"),
function() { gSyncUI.doSync(); return true; }
));
}
let notification =
new Weave.Notification(title, description, null, priority, buttons);
Weave.Notifications.replaceTitle(notification);
if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
Weave.Notifications.removeAll(title);
this._wasDelayed = false;
}
this.updateUI();
},
observe: function SUI_observe(subject, topic, data) {
if (this._unloaded) {
Cu.reportError("SyncUI observer called after unload: " + topic);
return;
}
switch (topic) {
case "weave:service:sync:start":
this.onActivityStart();
break;
case "weave:ui:sync:finish":
this.onSyncFinish();
break;
case "weave:ui:sync:error":
this.onSyncError();
break;
case "weave:service:sync:delayed":
this.onSyncDelay();
break;
case "weave:service:quota:remaining":
this.onQuotaNotice();
break;
case "weave:service:setup-complete":
this.onSetupComplete();
break;
case "weave:service:login:start":
this.onActivityStart();
break;
case "weave:service:login:finish":
this.onLoginFinish();
break;
case "weave:ui:login:error":
this.onLoginError();
break;
case "weave:service:logout:finish":
this.onLogout();
break;
case "weave:service:start-over":
this.onStartOver();
break;
case "weave:service:ready":
this.initUI();
break;
case "weave:notification:added":
this.initNotifications();
break;
case "weave:ui:clear-error":
this.clearError();
break;
}
},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIObserver,
Ci.nsISupportsWeakReference
])
};
XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() {
//XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
// but for now just make it work
return Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle("chrome://weave/locale/services/sync.properties");
});
@@ -1,37 +0,0 @@
<?xml version="1.0"?>
# -*- Mode: HTML -*-
# 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/.
<bindings id="tabPreviews"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="ctrlTab-preview" extends="chrome://global/content/bindings/button.xml#button-base">
<content pack="center">
<xul:stack>
<xul:vbox class="ctrlTab-preview-inner" align="center" pack="center"
xbl:inherits="width=canvaswidth">
<xul:hbox class="tabPreview-canvas" xbl:inherits="style=canvasstyle">
<children/>
</xul:hbox>
<xul:label xbl:inherits="value=label,crop" class="plain"/>
</xul:vbox>
<xul:hbox class="ctrlTab-favicon-container" xbl:inherits="hidden=noicon">
<xul:image class="ctrlTab-favicon" xbl:inherits="src=image"/>
</xul:hbox>
</xul:stack>
</content>
<handlers>
<handler event="mouseover" action="ctrlTab._mouseOverFocus(this);"/>
<handler event="command" action="ctrlTab.pick(this);"/>
<handler event="click" button="1" action="ctrlTab.remove(this);"/>
#ifdef XP_MACOSX
# Control+click is a right click on OS X
<handler event="click" button="2" action="ctrlTab.pick(this);"/>
#endif
</handlers>
</binding>
</bindings>
@@ -1,17 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
// This file is used as a stub object for platforms which
// don't have CAN_DRAW_IN_TITLEBAR defined.
var TabsInTitlebar = {
init: function () {},
uninit: function () {},
allowedBy: function (condition, allow) {},
updateAppearance: function updateAppearance(aForce) {},
get enabled() {
return document.documentElement.getAttribute("tabsintitlebar") == "true";
},
};
@@ -1,307 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
// Note: the file browser-tabsintitlebar-stub.js is used instead of
// this one on platforms which don't have CAN_DRAW_IN_TITLEBAR defined.
var TabsInTitlebar = {
init: function () {
if (this._initialized) {
return;
}
this._readPref();
Services.prefs.addObserver(this._prefName, this, false);
// We need to update the appearance of the titlebar when the menu changes
// from the active to the inactive state. We can't, however, rely on
// DOMMenuBarInactive, because the menu fires this event and then removes
// the inactive attribute after an event-loop spin.
//
// Because updating the appearance involves sampling the heights and margins
// of various elements, it's important that the layout be more or less
// settled before updating the titlebar. So instead of listening to
// DOMMenuBarActive and DOMMenuBarInactive, we use a MutationObserver to
// watch the "invalid" attribute directly.
let menu = document.getElementById("toolbar-menubar");
this._menuObserver = new MutationObserver(this._onMenuMutate);
this._menuObserver.observe(menu, {attributes: true});
this.onAreaReset = function(aArea) {
if (aArea == CustomizableUI.AREA_TABSTRIP || aArea == CustomizableUI.AREA_MENUBAR)
this._update(true);
};
this.onWidgetAdded = this.onWidgetRemoved = function(aWidgetId, aArea) {
if (aArea == CustomizableUI.AREA_TABSTRIP || aArea == CustomizableUI.AREA_MENUBAR)
this._update(true);
};
CustomizableUI.addListener(this);
addEventListener("resolutionchange", this, false);
this._initialized = true;
if (this._updateOnInit) {
// We don't need to call this with 'true', even if original calls
// (before init()) did, because this will be the first call and so
// we will update anyway.
this._update();
}
},
allowedBy: function (condition, allow) {
if (allow) {
if (condition in this._disallowed) {
delete this._disallowed[condition];
this._update(true);
}
} else if (!(condition in this._disallowed)) {
this._disallowed[condition] = null;
this._update(true);
}
},
updateAppearance: function updateAppearance(aForce) {
this._update(aForce);
},
get enabled() {
return document.documentElement.getAttribute("tabsintitlebar") == "true";
},
observe: function (subject, topic, data) {
if (topic == "nsPref:changed")
this._readPref();
},
handleEvent: function (aEvent) {
if (aEvent.type == "resolutionchange" && aEvent.target == window) {
this._update(true);
}
},
_onMenuMutate: function (aMutations) {
for (let mutation of aMutations) {
if (mutation.attributeName == "inactive" ||
mutation.attributeName == "autohide") {
TabsInTitlebar._update(true);
return;
}
}
},
_initialized: false,
_updateOnInit: false,
_disallowed: {},
_prefName: "browser.tabs.drawInTitlebar",
_lastSizeMode: null,
_readPref: function () {
this.allowedBy("pref",
Services.prefs.getBoolPref(this._prefName));
},
_update: function (aForce=false) {
let $ = id => document.getElementById(id);
let rect = ele => ele.getBoundingClientRect();
let verticalMargins = cstyle => parseFloat(cstyle.marginBottom) + parseFloat(cstyle.marginTop);
if (window.fullScreen)
return;
// In some edgecases it is possible for this to fire before we've initialized.
// Don't run now, but don't forget to run it when we do initialize.
if (!this._initialized) {
this._updateOnInit = true;
return;
}
if (!aForce) {
// _update is called on resize events, because the window is not ready
// after sizemode events. However, we only care about the event when the
// sizemode is different from the last time we updated the appearance of
// the tabs in the titlebar.
let sizemode = document.documentElement.getAttribute("sizemode");
if (this._lastSizeMode == sizemode) {
return;
}
let oldSizeMode = this._lastSizeMode;
this._lastSizeMode = sizemode;
// Don't update right now if we are leaving fullscreen, since the UI is
// still changing in the consequent "fullscreen" event. Code there will
// call this function again when everything is ready.
// See browser-fullScreen.js: FullScreen.toggle and bug 1173768.
if (oldSizeMode == "fullscreen") {
return;
}
}
let allowed = (Object.keys(this._disallowed)).length == 0;
let titlebar = $("titlebar");
let titlebarContent = $("titlebar-content");
let menubar = $("toolbar-menubar");
if (allowed) {
// We set the tabsintitlebar attribute first so that our CSS for
// tabsintitlebar manifests before we do our measurements.
document.documentElement.setAttribute("tabsintitlebar", "true");
updateTitlebarDisplay();
// Try to avoid reflows in this code by calculating dimensions first and
// then later set the properties affecting layout together in a batch.
// Get the full height of the tabs toolbar:
let tabsToolbar = $("TabsToolbar");
let tabsStyles = window.getComputedStyle(tabsToolbar);
let fullTabsHeight = rect(tabsToolbar).height + verticalMargins(tabsStyles);
// Buttons first:
let captionButtonsBoxWidth = rect($("titlebar-buttonbox-container")).width;
let secondaryButtonsWidth, menuHeight, fullMenuHeight, menuStyles;
if (AppConstants.platform == "macosx") {
secondaryButtonsWidth = rect($("titlebar-secondary-buttonbox")).width;
// No need to look up the menubar stuff on OS X:
menuHeight = 0;
fullMenuHeight = 0;
} else {
// Otherwise, get the height and margins separately for the menubar
menuHeight = rect(menubar).height;
menuStyles = window.getComputedStyle(menubar);
fullMenuHeight = verticalMargins(menuStyles) + menuHeight;
}
// And get the height of what's in the titlebar:
let titlebarContentHeight = rect(titlebarContent).height;
// Begin setting CSS properties which will cause a reflow
// If the menubar is around (menuHeight is non-zero), try to adjust
// its full height (i.e. including margins) to match the titlebar,
// by changing the menubar's bottom padding
if (menuHeight) {
// Calculate the difference between the titlebar's height and that of the menubar
let menuTitlebarDelta = titlebarContentHeight - fullMenuHeight;
let paddingBottom;
// The titlebar is bigger:
if (menuTitlebarDelta > 0) {
fullMenuHeight += menuTitlebarDelta;
// If there is already padding on the menubar, we need to add that
// to the difference so the total padding is correct:
if ((paddingBottom = menuStyles.paddingBottom)) {
menuTitlebarDelta += parseFloat(paddingBottom);
}
menubar.style.paddingBottom = menuTitlebarDelta + "px";
// The menubar is bigger, but has bottom padding we can remove:
} else if (menuTitlebarDelta < 0 && (paddingBottom = menuStyles.paddingBottom)) {
let existingPadding = parseFloat(paddingBottom);
// menuTitlebarDelta is negative; work out what's left, but don't set negative padding:
let desiredPadding = Math.max(0, existingPadding + menuTitlebarDelta);
menubar.style.paddingBottom = desiredPadding + "px";
// We've changed the menu height now:
fullMenuHeight += desiredPadding - existingPadding;
}
}
// Next, we calculate how much we need to stretch the titlebar down to
// go all the way to the bottom of the tab strip, if necessary.
let tabAndMenuHeight = fullTabsHeight + fullMenuHeight;
if (tabAndMenuHeight > titlebarContentHeight) {
// We need to increase the titlebar content's outer height (ie including margins)
// to match the tab and menu height:
let extraMargin = tabAndMenuHeight - titlebarContentHeight;
if (AppConstants.platform != "macosx") {
titlebarContent.style.marginBottom = extraMargin + "px";
}
titlebarContentHeight += extraMargin;
} else {
titlebarContent.style.removeProperty("margin-bottom");
}
// Then add a negative margin to the titlebar, so that the following elements
// will overlap it by the lesser of the titlebar height or the tabstrip+menu.
let minTitlebarOrTabsHeight = Math.min(titlebarContentHeight, tabAndMenuHeight);
titlebar.style.marginBottom = "-" + minTitlebarOrTabsHeight + "px";
// Finally, size the placeholders:
if (AppConstants.platform == "macosx") {
this._sizePlaceholder("fullscreen-button", secondaryButtonsWidth);
}
this._sizePlaceholder("caption-buttons", captionButtonsBoxWidth);
} else {
document.documentElement.removeAttribute("tabsintitlebar");
updateTitlebarDisplay();
if (AppConstants.platform == "macosx") {
let secondaryButtonsWidth = rect($("titlebar-secondary-buttonbox")).width;
this._sizePlaceholder("fullscreen-button", secondaryButtonsWidth);
}
// Reset the margins and padding that might have been modified:
titlebarContent.style.marginTop = "";
titlebarContent.style.marginBottom = "";
titlebar.style.marginBottom = "";
menubar.style.paddingBottom = "";
}
ToolbarIconColor.inferFromText();
if (CustomizationHandler.isCustomizing()) {
gCustomizeMode.updateLWTStyling();
}
},
_sizePlaceholder: function (type, width) {
Array.forEach(document.querySelectorAll(".titlebar-placeholder[type='"+ type +"']"),
function (node) { node.width = width; });
},
uninit: function () {
this._initialized = false;
removeEventListener("resolutionchange", this);
Services.prefs.removeObserver(this._prefName, this);
this._menuObserver.disconnect();
CustomizableUI.removeListener(this);
}
};
function updateTitlebarDisplay() {
if (AppConstants.platform == "macosx") {
// OS X and the other platforms differ enough to necessitate this kind of
// special-casing. Like the other platforms where we CAN_DRAW_IN_TITLEBAR,
// we draw in the OS X titlebar when putting the tabs up there. However, OS X
// also draws in the titlebar when a lightweight theme is applied, regardless
// of whether or not the tabs are drawn in the titlebar.
if (TabsInTitlebar.enabled) {
document.documentElement.setAttribute("chromemargin-nonlwtheme", "0,-1,-1,-1");
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
document.documentElement.removeAttribute("drawtitle");
} else {
// We set chromemargin-nonlwtheme to "" instead of removing it as a way of
// making sure that LightweightThemeConsumer doesn't take it upon itself to
// detect this value again if and when we do a lwtheme state change.
document.documentElement.setAttribute("chromemargin-nonlwtheme", "");
let isCustomizing = document.documentElement.hasAttribute("customizing");
let hasLWTheme = document.documentElement.hasAttribute("lwtheme");
let isPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
if ((!hasLWTheme || isCustomizing) && !isPrivate) {
document.documentElement.removeAttribute("chromemargin");
}
document.documentElement.setAttribute("drawtitle", "true");
}
} else if (TabsInTitlebar.enabled) {
// not OS X
document.documentElement.setAttribute("chromemargin", "0,2,2,2");
} else {
document.documentElement.removeAttribute("chromemargin");
}
}
function onTitlebarMaxClick() {
if (window.windowState == window.STATE_MAXIMIZED)
window.restore();
else
window.maximize();
}
@@ -1,142 +0,0 @@
/* 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/. */
/**
* Keeps thumbnails of open web pages up-to-date.
*/
var gBrowserThumbnails = {
/**
* Pref that controls whether we can store SSL content on disk
*/
PREF_DISK_CACHE_SSL: "browser.cache.disk_cache_ssl",
_captureDelayMS: 1000,
/**
* Used to keep track of disk_cache_ssl preference
*/
_sslDiskCacheEnabled: null,
/**
* Map of capture() timeouts assigned to their browsers.
*/
_timeouts: null,
/**
* List of tab events we want to listen for.
*/
_tabEvents: ["TabClose", "TabSelect"],
init: function Thumbnails_init() {
PageThumbs.addExpirationFilter(this);
gBrowser.addTabsProgressListener(this);
Services.prefs.addObserver(this.PREF_DISK_CACHE_SSL, this, false);
this._sslDiskCacheEnabled =
Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
this._tabEvents.forEach(function (aEvent) {
gBrowser.tabContainer.addEventListener(aEvent, this, false);
}, this);
this._timeouts = new WeakMap();
},
uninit: function Thumbnails_uninit() {
PageThumbs.removeExpirationFilter(this);
gBrowser.removeTabsProgressListener(this);
Services.prefs.removeObserver(this.PREF_DISK_CACHE_SSL, this);
this._tabEvents.forEach(function (aEvent) {
gBrowser.tabContainer.removeEventListener(aEvent, this, false);
}, this);
},
handleEvent: function Thumbnails_handleEvent(aEvent) {
switch (aEvent.type) {
case "scroll":
let browser = aEvent.currentTarget;
if (this._timeouts.has(browser))
this._delayedCapture(browser);
break;
case "TabSelect":
this._delayedCapture(aEvent.target.linkedBrowser);
break;
case "TabClose": {
this._clearTimeout(aEvent.target.linkedBrowser);
break;
}
}
},
observe: function Thumbnails_observe() {
this._sslDiskCacheEnabled =
Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
},
filterForThumbnailExpiration:
function Thumbnails_filterForThumbnailExpiration(aCallback) {
aCallback(this._topSiteURLs);
},
/**
* State change progress listener for all tabs.
*/
onStateChange: function Thumbnails_onStateChange(aBrowser, aWebProgress,
aRequest, aStateFlags, aStatus) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)
this._delayedCapture(aBrowser);
},
_capture: function Thumbnails_capture(aBrowser) {
// Only capture about:newtab top sites.
if (this._topSiteURLs.indexOf(aBrowser.currentURI.spec) == -1)
return;
this._shouldCapture(aBrowser, function (aResult) {
if (aResult) {
PageThumbs.captureAndStoreIfStale(aBrowser);
}
});
},
_delayedCapture: function Thumbnails_delayedCapture(aBrowser) {
if (this._timeouts.has(aBrowser))
clearTimeout(this._timeouts.get(aBrowser));
else
aBrowser.addEventListener("scroll", this, true);
let timeout = setTimeout(function () {
this._clearTimeout(aBrowser);
this._capture(aBrowser);
}.bind(this), this._captureDelayMS);
this._timeouts.set(aBrowser, timeout);
},
_shouldCapture: function Thumbnails_shouldCapture(aBrowser, aCallback) {
// Capture only if it's the currently selected tab.
if (aBrowser != gBrowser.selectedBrowser) {
aCallback(false);
return;
}
PageThumbs.shouldStoreThumbnail(aBrowser, aCallback);
},
get _topSiteURLs() {
return NewTabUtils.links.getLinks().reduce((urls, link) => {
if (link)
urls.push(link.url);
return urls;
}, []);
},
_clearTimeout: function Thumbnails_clearTimeout(aBrowser) {
if (this._timeouts.has(aBrowser)) {
aBrowser.removeEventListener("scroll", this, false);
clearTimeout(this._timeouts.get(aBrowser));
this._timeouts.delete(aBrowser);
}
}
};
@@ -1,177 +0,0 @@
/* 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/. */
var TrackingProtection = {
// If the user ignores the doorhanger, we stop showing it after some time.
PREF_ENABLED_GLOBALLY: "privacy.trackingprotection.enabled",
PREF_ENABLED_IN_PRIVATE_WINDOWS: "privacy.trackingprotection.pbmode.enabled",
enabledGlobally: false,
enabledInPrivateWindows: false,
container: null,
content: null,
icon: null,
activeTooltipText: null,
disabledTooltipText: null,
init() {
let $ = selector => document.querySelector(selector);
this.container = $("#tracking-protection-container");
this.content = $("#tracking-protection-content");
this.icon = $("#tracking-protection-icon");
this.updateEnabled();
Services.prefs.addObserver(this.PREF_ENABLED_GLOBALLY, this, false);
Services.prefs.addObserver(this.PREF_ENABLED_IN_PRIVATE_WINDOWS, this, false);
this.activeTooltipText =
gNavigatorBundle.getString("trackingProtection.icon.activeTooltip");
this.disabledTooltipText =
gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip");
this.enabledHistogramAdd(this.enabledGlobally);
this.disabledPBMHistogramAdd(!this.enabledInPrivateWindows);
},
uninit() {
Services.prefs.removeObserver(this.PREF_ENABLED_GLOBALLY, this);
Services.prefs.removeObserver(this.PREF_ENABLED_IN_PRIVATE_WINDOWS, this);
},
observe() {
this.updateEnabled();
},
get enabled() {
return this.enabledGlobally ||
(this.enabledInPrivateWindows &&
PrivateBrowsingUtils.isWindowPrivate(window));
},
updateEnabled() {
this.enabledGlobally =
Services.prefs.getBoolPref(this.PREF_ENABLED_GLOBALLY);
this.enabledInPrivateWindows =
Services.prefs.getBoolPref(this.PREF_ENABLED_IN_PRIVATE_WINDOWS);
this.container.hidden = !this.enabled;
},
enabledHistogramAdd(value) {
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
return;
}
Services.telemetry.getHistogramById("TRACKING_PROTECTION_ENABLED").add(value);
},
disabledPBMHistogramAdd(value) {
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
return;
}
Services.telemetry.getHistogramById("TRACKING_PROTECTION_PBM_DISABLED").add(value);
},
eventsHistogramAdd(value) {
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
return;
}
Services.telemetry.getHistogramById("TRACKING_PROTECTION_EVENTS").add(value);
},
shieldHistogramAdd(value) {
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
return;
}
Services.telemetry.getHistogramById("TRACKING_PROTECTION_SHIELD").add(value);
},
onSecurityChange(state, isSimulated) {
if (!this.enabled) {
return;
}
// Only animate the shield if the event was not fired directly from
// the tabbrowser (due to a browser change).
if (isSimulated) {
this.icon.removeAttribute("animate");
} else {
this.icon.setAttribute("animate", "true");
}
let isBlocking = state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
let isAllowing = state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
if (isBlocking) {
this.icon.setAttribute("tooltiptext", this.activeTooltipText);
this.icon.setAttribute("state", "blocked-tracking-content");
this.content.setAttribute("state", "blocked-tracking-content");
this.shieldHistogramAdd(2);
} else if (isAllowing) {
this.icon.setAttribute("tooltiptext", this.disabledTooltipText);
this.icon.setAttribute("state", "loaded-tracking-content");
this.content.setAttribute("state", "loaded-tracking-content");
this.shieldHistogramAdd(1);
} else {
this.icon.removeAttribute("tooltiptext");
this.icon.removeAttribute("state");
this.content.removeAttribute("state");
// We didn't show the shield
this.shieldHistogramAdd(0);
}
// Telemetry for state change.
this.eventsHistogramAdd(0);
},
disableForCurrentPage() {
// Convert document URI into the format used by
// nsChannelClassifier::ShouldEnableTrackingProtection.
// Any scheme turned into https is correct.
let normalizedUrl = Services.io.newURI(
"https://" + gBrowser.selectedBrowser.currentURI.hostPort,
null, null);
// Add the current host in the 'trackingprotection' consumer of
// the permission manager using a normalized URI. This effectively
// places this host on the tracking protection allowlist.
if (PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser)) {
PrivateBrowsingUtils.addToTrackingAllowlist(normalizedUrl);
} else {
Services.perms.add(normalizedUrl,
"trackingprotection", Services.perms.ALLOW_ACTION);
}
// Telemetry for disable protection.
this.eventsHistogramAdd(1);
// Hide the control center.
document.getElementById("identity-popup").hidePopup();
BrowserReload();
},
enableForCurrentPage() {
// Remove the current host from the 'trackingprotection' consumer
// of the permission manager. This effectively removes this host
// from the tracking protection allowlist.
let normalizedUrl = Services.io.newURI(
"https://" + gBrowser.selectedBrowser.currentURI.hostPort,
null, null);
if (PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser)) {
PrivateBrowsingUtils.removeFromTrackingAllowlist(normalizedUrl);
} else {
Services.perms.remove(normalizedUrl, "trackingprotection");
}
// Telemetry for enable protection.
this.eventsHistogramAdd(2);
// Hide the control center.
document.getElementById("identity-popup").hidePopup();
BrowserReload();
},
};
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,12 +0,0 @@
<stringbundleset id="stringbundleset"/>
<commandset id="mainCommandSet"/>
<commandset id="baseMenuCommandSet"/>
<commandset id="placesCommands"/>
<broadcasterset id="mainBroadcasterSet"/>
<keyset id="mainKeyset"/>
<keyset id="baseMenuKeyset"/>
<menubar id="main-menubar"/>
Loaded 100 of 8622 files, more files were not shown because too many files have changed in this diff. Show more