Add Pale Moon

This commit is contained in:
NTD
2018-02-02 03:35:06 -05:00
committed by Roy Tam
parent dcd9973243
commit fe8028fa2e
1173 changed files with 143053 additions and 934 deletions
+5 -2
View File
@@ -10,6 +10,8 @@ ID
.DS_Store*
*.pdb
*.egg-info
*.orig
*.rej
# Vim swap files.
.*.sw[a-z]
@@ -33,6 +35,7 @@ security/manager/.nss.checkout
# Build directories
/obj*/
/build-*/
# Build directories for js shell
_DBG.OBJ/
@@ -90,8 +93,8 @@ testing/web-platform/sync/
mobile/android/gradle/.gradle
# XCode project cruft
embedding/ios/GeckoEmbed/GeckoEmbed.xcodeproj/project.xcworkspace/xcuserdata
embedding/ios/GeckoEmbed/GeckoEmbed.xcodeproj/xcuserdata
embedding/ios/GoannaEmbed/GoannaEmbed.xcodeproj/project.xcworkspace/xcuserdata
embedding/ios/GoannaEmbed/GoannaEmbed.xcodeproj/xcuserdata
# Ignore mozharness execution files
testing/mozharness/.tox/
-5
View File
@@ -1,5 +0,0 @@
repo: 8ba995b74e18334ab3707f27e9eb8f4e37ba3d29
node: a7c8e85285e290fdb1325edfb37e905a3779f3cd
branch: default
tag: FIREFOX_52_6_0esr_BUILD2
tag: FIREFOX_52_6_0esr_RELEASE
-134
View File
@@ -1,134 +0,0 @@
# .hgignore - List of filenames hg should ignore
# Filenames that should be ignored wherever they appear
~$
\.py(c|o)$
(?i)(^|/)TAGS$
(^|/)ID$
(^|/)\.DS_Store$
\.pdb
\.egg-info
# Vim swap files.
^\.sw.$
.[^/]*\.sw.$
# Emacs directory variable files.
\.dir-locals\.el
# User files that may appear at the root
^\.mozconfig
^mozconfig*
^configure$
^old-configure$
^config\.cache$
^config\.log$
^\.clang_complete
^\.?machrc$
# Empty marker file that's generated when we check out NSS
^security/manager/\.nss\.checkout$
# Build directories
^obj
# Build directories for js shell
_DBG\.OBJ/
_OPT\.OBJ/
^js/src/.*-obj/
# SpiderMonkey configury
^js/src/configure$
^js/src/old-configure$
^js/src/autom4te.cache$
# SpiderMonkey test result logs
^js/src/tests/results-.*\.(html|txt)$
^js/src/devtools/rootAnalysis/t/out
# Java HTML5 parser classes
^parser/html/java/(html|java)parser/
# SVN directories
\.svn/
# Ignore the files and directory that Eclipse IDE creates
\.project$
\.cproject$
\.settings/
# Ignore the files and directory that JetBrains IDEs create.
\.idea/
\.iml$
# Gradle cache.
^.gradle/
# Local Gradle configuration properties.
^local.properties$
# Python stuff installed at build time.
^python/psutil/.*\.so
^python/psutil/.*\.pyd
^python/psutil/build/
# Git repositories
.git/
# Ignore chrome.manifest files from the devtools loader
^devtools/client/chrome.manifest$
^devtools/shared/chrome.manifest$
# Ignore node_modules directories in devtools
^devtools/.*/node_modules/
# git checkout of libstagefright
^media/libstagefright/android$
# Tag files generated by GNU Global
GTAGS
GRTAGS
GSYMS
GPATH
# Git clone directory for updating web-platform-tests
^testing/web-platform/sync/
# Android Gradle artifacts.
^mobile/android/gradle/.gradle
# XCode project cruft
^embedding/ios/GeckoEmbed/GeckoEmbed.xcodeproj/project.xcworkspace/xcuserdata
^embedding/ios/GeckoEmbed/GeckoEmbed.xcodeproj/xcuserdata
# Ignore mozharness execution files
^testing/mozharness/.tox/
^testing/mozharness/build/
^testing/mozharness/logs/
^testing/mozharness/.coverage
^testing/mozharness/nosetests.xml
# Ignore tox generated dir
.tox/
# Ignore node_modules
^tools/lint/eslint/node_modules/
# Ignore talos virtualenv and tp5n files.
# The tp5n set is supposed to be decompressed at
# testing/talos/talos/page_load_test/tp5n in order to run tests like tps
# locally. Similarly, running talos requires a Python package virtual
# environment. Both the virtual environment and tp5n files end up littering
# the status command, so we ignore them.
^testing/talos/.Python
^testing/talos/bin/
^testing/talos/include/
^testing/talos/lib/
^testing/talos/talos/tests/tp5n.zip
^testing/talos/talos/tests/tp5n
^testing/talos/talos/tests/devtools/damp.manifest.develop
# Ignore files created when running a reftest.
^lextab.py$
# tup database
^\.tup
-489
View File
@@ -1,489 +0,0 @@
df7a3c8ffeeaba229067efee5a20e21dae0dd877 MOZILLA_1_9_a4_BASE
4209e16b58411750ac73f761023e46b76b793e2c MOZILLA_1_9_a6_BASE
66a5c7bce7ee86a820d3c0d54fa07cb719be751c MOZILLA_1_9_a7_BASE
caeba7562e495a9f604984df0b48b6f99bec3e2e FENNEC_M4
9d9941eacb14827fdab4716710042fdde84eb60d FIREFOX_3_1a1_RELEASE
9d9941eacb14827fdab4716710042fdde84eb60d FIREFOX_3_1a1_BUILD1
c1d7e318a27574c995631fec166ad42672475702 FIREFOX_3_1a1_BUILD2
c1d7e318a27574c995631fec166ad42672475702 FIREFOX_3_1a1_RELEASE
afc4ee509d9ca3bb4031015c3c22963dcb4b7e7f FIREFOX_3_1a1_RELEASE
afc4ee509d9ca3bb4031015c3c22963dcb4b7e7f FIREFOX_3_1a1_BUILD2
f197b51bbc29a30860e750ee87fd0a047a024f2e FIREFOX_3_1a2_BUILD1
f197b51bbc29a30860e750ee87fd0a047a024f2e FIREFOX_3_1a2_RELEASE
269af1ed75649989575d41f53a12048015c6d50e FENNEC_M8
920a4326d1087b174c2fa2b9a8358e12c697022c SEAMONKEY_2_0a1_BUILD1
920a4326d1087b174c2fa2b9a8358e12c697022c SEAMONKEY_2_0a1_RELEASE
f197b51bbc29a30860e750ee87fd0a047a024f2e UPDATE_PACKAGING_R5
f197b51bbc29a30860e750ee87fd0a047a024f2e -m
f197b51bbc29a30860e750ee87fd0a047a024f2e Adding UPDATE_PACKAGING_R5 tag in order to make patcher work.
15cb5d25db054d2d0b56869a2f6351388bfcddcd THUNDERBIRD_3_0a3_RELEASE
15cb5d25db054d2d0b56869a2f6351388bfcddcd THUNDERBIRD_3_0a3_BUILD1
0000000000000000000000000000000000000000 -m
0000000000000000000000000000000000000000 Adding UPDATE_PACKAGING_R5 tag in order to make patcher work.
f197b51bbc29a30860e750ee87fd0a047a024f2e UPDATE_PACKAGING_R6
d7d64f68423b68a671f623f123e90057ebc49dac UPDATE_PACKAGING_R6
0000000000000000000000000000000000000000 THUNDERBIRD_3_0a3_BUILD1
0000000000000000000000000000000000000000 THUNDERBIRD_3_0a3_RELEASE
0cd41f5990807fb6ab52cb59ba3c8e8247281045 GECKO_1_9_1_BASE
8df5a90281cd4d75835e4b7696da200555eed15f GECKO_1_9_1_BASE
8a601ed6bc4c7b3d1e35aa9e81f257512d984bd5 FENNEC_A2
d7d64f68423b68a671f623f123e90057ebc49dac UPDATE_PACKAGING_R7
fb32f6e1859c07846a01b4478a7b1678019e0b45 UPDATE_PACKAGING_R7
f817a4378f32b1ad0a7c4b5a9949586dba816da5 FENNEC_M11
5c1e7c779b6edc8ff912001990edc579f80597f4 FENNEC_B1
fe9cc55b8db7f56f7e68a246acba363743854979 UPDATE_PACKAGING_R8
6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-r15462
6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-latest
376b78fc72230aaf2ca4e279a8f4ef1efd4a1d9f GECKO_1_9_2_BASE
941ad9d7d079246481f365c3cfbfc75a5bbefc94 last-mozilla-central
2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
925595f3c08634cc42e33158ea6858bb55623ef7 last-mozilla-central
dba2abb7db57078c5a4810884834d3056a5d56c2 last-mozilla-central
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R9
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R10
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R11
0327e126ea245112c0aa7283fee154e084866fb5 bsmedberg-static-xpcom-registration-base
0327e126ea245112c0aa7283fee154e084866fb5 bsmedberg-static-xpcom-registration-base
2f83edbbeef0de7dd901411d270da61106c8afae bsmedberg-static-xpcom-registration-base
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R12
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R13
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R11_1_MU
e56ecd8b3a68c158025207c5fd081d043e28f5ce GECKO_2_0_BASE
e273946b74c8d631ed86bd74ba9afe0e67b12378 GECKO_2_1_BASE
b70744835d94e54eec97b8fd186c96da5708a506 PRE_MOBILE_MERGE
b70744835d94e54eec97b8fd186c96da5708a506 PRE_MOBILE_MERGE_20110406
a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE
a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE_20110406
a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
9eae975b3d6fb7748fe5a3c0113d449b1c7cc0b2 AURORA_BASE_20110524
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R14
5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816
c0983049bcaa9551e5f276d5a77ce154c151e0b0 AURORA_BASE_20110927
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R15
54bfd8bf682e295ffd7f22fa921ca343957b6c1c AURORA_BASE_20111108
a8506ab2c65480cf2f85f54e203ea746522c62bb AURORA_BASE_20111220
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R16
bbc7014db2de49e2301680d2a86be8a53108a88a AURORA_BASE_20120131
bbc7014db2de49e2301680d2a86be8a53108a88a AURORA_BASE_20120131
0000000000000000000000000000000000000000 AURORA_BASE_20120131
0000000000000000000000000000000000000000 AURORA_BASE_20120131
bbc7014db2de49e2301680d2a86be8a53108a88a AURORA_BASE_20120131
b6627f28b7ec17e1b46a594df0f780d3a40847e4 FIREFOX_AURORA_13_BASE
357da346ceb705d196a46574804c7c4ec44ac186 FIREFOX_AURORA_14_BASE
26dcd1b1a20893ad99341c61c6b1239ff1523858 FIREFOX_AURORA_15_BASE
0accd12a8e7e217836ea3f1ee7c411913fc75d8e FIREFOX_AURORA_16_BASE
0000000000000000000000000000000000000000 FIREFOX_AURORA_16_BASE
9697eadafa13b4e9233b39aaeecfeac79503cb54 FIREFOX_AURORA_16_BASE
9697eadafa13b4e9233b39aaeecfeac79503cb54 FIREFOX_AURORA_16_BASE
6fdf9985acfe6f939da584b2559464ab22264fe7 FIREFOX_AURORA_16_BASE
fd72dbbd692012224145be1bf13df1d7675fd277 FIREFOX_AURORA_17_BASE
2704e441363fe2a48e992dfac694482dfd82664a FIREFOX_AURORA_18_BASE
cf8750abee06cde395c659f8ecd8ae019d7512e3 FIREFOX_AURORA_19_BASE
5bb309998e7050c9ee80b0147de1e473f008e221 FIREFOX_AURORA_20_BASE
cc37417e2c284aed960f98ffa479de4ccdd5c7c3 FIREFOX_AURORA_21_BASE
1c070ab0f9db59f13423b9c1db60419f7a9098f9 FIREFOX_AURORA_22_BASE
d7ce9089999719d5186595d160f25123a4e63e39 FIREFOX_AURORA_23_BASE
8d3810543edccf4fbe458178b88dd4a6e420b010 FIREFOX_AURORA_24_BASE
ad0ae007aa9e03cd74e9005cd6652e544139b3b5 FIREFOX_AURORA_25_BASE
2520866d58740851d862c7c59246a4e3f8b4a176 FIREFOX_AURORA_26_BASE
05025f4889a0bf4dc99ce0c244c750adc002f015 FIREFOX_AURORA_27_BASE
ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE-m
ba2cc1eda988a1614d8986ae145d28e1268409b9 Tagging for mozilla-central version bumps CLOSED TREE DONTBUILD
ba2cc1eda988a1614d8986ae145d28e1268409b9 Tagging for mozilla-central version bumps CLOSED TREE DONTBUILD
0000000000000000000000000000000000000000 Tagging for mozilla-central version bumps CLOSED TREE DONTBUILD
ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE-m
0000000000000000000000000000000000000000 FIREFOX_AURORA_29_BASE-m
ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
07f5580d8a54e8311fa7641c907065a88de19e08 FIREFOX_AURORA_29_END
3776f72f1967a7068879501eb7c08920032785b8 B2G_1_4_20140317_MERGEDAY
aa70a6ce178a6839cd9e55761c4ac31d43ee7bd9 FIREFOX_BETA_29_END
ba4a8f81efdcf000414f192342ccbd14c9626c36 RELEASE_BASE_20140602
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
83c9853e136451474dfa6d1aaa60a7fca7d2d83a FIREFOX_AURORA_30_BASE
cfde3603b0206e119abea76fdd6e134b634348f1 FIREFOX_AURORA_31_BASE
ab25447610b532eb4c32524a7dbc56a21eeaabb8 FIREFOX_BETA_30_BASE
ab25447610b532eb4c32524a7dbc56a21eeaabb8 FIREFOX_AURORA_30_END
6c18811bcd1b319801fd97aeb09c41b963863968 FIREFOX_BETA_30_END
1772e55568e420f8c7fbf7b9434157e9f419c8f1 FIREFOX_RELEASE_31_BASE
40b1b0712d7b53219a0404e78eec4e6a2796423e FIREFOX_RELEASE_30_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
16f3cac5e8fe471e12f76d6a94a477b14e78df7c FIREFOX_AURORA_32_BASE
f11b164d75442617c4f046177d2ab913ed03a318 FIREFOX_BETA_31_BASE
f11b164d75442617c4f046177d2ab913ed03a318 FIREFOX_AURORA_31_END
dc2fd26b301375f15c935f00fe6283d3e3bc1efc B2G_2_0_20140609_MERGEDAY
d69cd84b6824e018e0906cab0464e11e97a9bdca FIREFOX_BETA_32_BASE
d69cd84b6824e018e0906cab0464e11e97a9bdca FIREFOX_BETA_32_BASE
0000000000000000000000000000000000000000 FIREFOX_BETA_32_BASE
0000000000000000000000000000000000000000 FIREFOX_BETA_32_BASE
ac396ad5a32d60ae5b7eebe5416fdd46e9e12be1 FIREFOX_BETA_32_BASE
6befadcaa68524d24960d8342e00503e4edc1869 FIREFOX_BETA_31_END
92ad4cfa9435fbe136c61071041812f90bc8d89e FIREFOX_RELEASE_32_BASE
cd52a7f8954809fd893196dc857f81b0cb61717c FIREFOX_RELEASE_31_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
dc23164ba2a289a8b22902e30990c77d9677c214 FIREFOX_AURORA_33_BASE
a104ddcd4cdbf950f1755dfaf5a278d53570655f FIREFOX_AURORA_32_END
114b010b6bf1a0efee03f003e54ed6fa00909972 FIREFOX_BETA_33_BASE
ebd0ee3e97dc2756d979261b29f173638fe6aeb6 FIREFOX_BETA_32_END
e8360a0c7d7483491e064c7cd445a94004af0a83 FIREFOX_RELEASE_33_BASE
4641475ee1f3ec3e723e932e0f4f3f3fa7c55a5c FIREFOX_RELEASE_32_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
c360f3d1c00d73b0c1fb0a2c0da525cb55e58b83 FIREFOX_AURORA_34_BASE
9f1aad8e807cc283aafbc14caa3d4775e8d0535c FIREFOX_AURORA_33_END
5b8210dcf52a795646bf0c8a32082a2ed7c4f537 B2G_2_1_20140902_MERGEDAY
e85828ce78a80e2ccda98972d69d5f750335c4ab FIREFOX_BETA_34_BASE
8574e35b517785acc905327f4994e96576218fa8 FIREFOX_BETA_33_END
e247a7f7c43842941bdb4207ca1b9d8881798997 FIREFOX_RELEASE_34_BASE
a47b1b720b67b018a9cb106178de53a363641392 FIREFOX_RELEASE_33_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
cec1a116c4f9a3e887d52e9a26e8bbec200fe162 FIREFOX_AURORA_35_BASE
2608561c091ae83cc85e38740feffa5bfc6b5ed4 FIREFOX_AURORA_34_END
390a34a40ea4e7f4d24b3ed83778e0f408411fcc FIREFOX_BETA_35_BASE
a3cc435fd3c315e5dfe9329d03d5943bb893cced FIREFOX_BETA_34_END
fb06fa0600ab95db48212a237c79b650cac213c5 FIREFOX_RELEASE_35_BASE
f4217563f1568c478c1ddf1647098946e51bc7f8 FIREFOX_RELEASE_34_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
ca89fe55717059e4e43040d16d260765ffa9dca7 FIREFOX_AURORA_36_BASE
6047f510fb73c7dbe9866066fb01ddda3c170c9c FIREFOX_AURORA_37_BASE
ca89fe55717059e4e43040d16d260765ffa9dca7 FIREFOX_AURORA_36_BASE
0000000000000000000000000000000000000000 FIREFOX_AURORA_36_BASE
6047f510fb73c7dbe9866066fb01ddda3c170c9c FIREFOX_AURORA_37_BASE
0000000000000000000000000000000000000000 FIREFOX_AURORA_37_BASE
0000000000000000000000000000000000000000 FIREFOX_AURORA_36_BASE
b297a6727acfd21e757ddd38cd61894812666265 FIREFOX_AURORA_36_BASE
0cf828669d5a0911b6f2b83d501eeef5bdf9905e FIREFOX_AURORA_35_END
75177371cb85baaa9d623f56d849a5c21d18040f FIREFOX_BETA_36_BASE
137baee3dda45c6a3b38be74f5709c24f7c7701a FIREFOX_BETA_35_END
948a2c2e31d4b7eaa282ddeb327708605e3cc7fa FIREFOX_RELEASE_36_BASE
d57ff45ca4fd7ccf1cb924030abf6c7d108eaab0 FIREFOX_RELEASE_35_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
0000000000000000000000000000000000000000 FIREFOX_AURORA_37_BASE
2c951493eef5b50b8085ef78ffe0d7902ff3d593 FIREFOX_AURORA_37_BASE
1bc9beda018a42bdd5f63fc9fc46facf0c6f37ec FIREFOX_AURORA_36_END
030fa1665346dfa94d1f72a1c7830644664ecf08 FIREFOX_BETA_37_BASE
7d4016a05dd32bf2d726975ba9175bb13fc9ea97 FIREFOX_BETA_36_END
196c6575593d6e8997402fb458bf8ed2f954fa4a FIREFOX_RELEASE_37_BASE
58fe203296af528cc711dc314e4769a902e3852f FIREFOX_RELEASE_36_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
98086da94ccdc88f6de86774ce3d1fa258dc7c44 FIREFOX_AURORA_38_BASE
d55b99e8010728b0c802e75e967d2a853122dd30 FIREFOX_AURORA_37_END
8bc9656cad94db48cd44f3947f1b3b1d8c57768a FIREFOX_BETA_38_BASE
b41c57eefd69242fc9664a3e5c2dcaa46840051c FIREFOX_BETA_37_END
fc98815acf5f041c6269fd256a68af8a92ba222a FIREFOX_RELEASE_38_BASE
b95583c8e7e7a7ce629b4d4551747e818367d0a0 FIREFOX_RELEASE_37_END
f33925facceefe32f6347faed2d805551d82e60b FIREFOX_RELEASE_38_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
1b6bf6612c0f4d4fee81d18bf18016e692f874e1 FIREFOX_AURORA_39_BASE
d92bf011e305a4a4ad6bb98192a53b86bd64b813 FIREFOX_AURORA_38_END
5e851d50fb9b8d5a28e4fcd4731dd0f17e8fb4b9 FIREFOX_BETA_39_BASE
85229fbaf01713caa9ad26c7d3afec271494113c FIREFOX_BETA_38_END
5fecfbec2e3c934d4646a739bea60d3c93a35f9e FIREFOX_RELEASE_39_BASE
f33925facceefe32f6347faed2d805551d82e60b FIREFOX_RELEASE_38_END
971ab60e21d340e0407d2b9eb82fca67a4a9f1cb FIREFOX_RELEASE_38_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
66a95a483d2c77dfc387019336d18093acd6aac2 FIREFOX_AURORA_40_BASE
eead3ccdf2d11feefc12907467cebbe07aa91ea9 FIREFOX_AURORA_39_END
d77cf39268848f8a7e9b38082348b6cd4d1f3b5e FIREFOX_BETA_40_BASE
0b0822cabbb95d8509852f90c0b7df5da0a4cabc FIREFOX_BETA_39_END
34e00eb800c52e33059d37f6e41fb255b4bae6b8 FIREFOX_RELEASE_40_BASE
ec21f96665f7d3fdd5d7944c90373938390096d7 FIREFOX_RELEASE_39_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
312c68b16549de9cea1557f461d5d234bd5e0a7d FIREFOX_AURORA_41_BASE
9d83ab013ab61c7f6e987bf0e7cbab1a1aed1ca8 FIREFOX_AURORA_40_END
a019592053c4d93fbbafab8d0bd709529e3746de FIREFOX_BETA_41_BASE
f147014ff61a12480d377c8bde1f90891772540f FIREFOX_BETA_40_END
6c0329aacb73ab0510c6f1026ef066dfaed9139c FIREFOX_RELEASE_41_BASE
9c898cde2175e9e98b916d996ed286a9dff0c853 FIREFOX_RELEASE_40_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
7a19194812eb767bee7cdf8fc36ba9a383c1bead FIREFOX_AURORA_42_BASE
d561dc208e61b2f2b4e82ab61710e14f56da4ddb FIREFOX_AURORA_41_END
61bbc30704aa104e9929c719c0fd7957f96f00ea FIREFOX_BETA_42_BASE
a5bf9cf6777519663e8e1db553727e59d3ad5681 FIREFOX_BETA_41_END
3f2ff85b2f16c1fd161dc5ba77a5f3f2c52fd127 FIREFOX_RELEASE_42_BASE
dc3a2ec52077a5cea772cdb267380f7debc3080b FIREFOX_RELEASE_41_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
fcef8ded82219c89298b4e376cfbdfba79a1d35a FIREFOX_AURORA_43_BASE
b0e20ff87b175424edec414215b325918ccb4792 FIREFOX_AURORA_42_END
41fdefd640f368bccdeafe6446d42c0a5ad22797 FIREFOX_BETA_43_BASE
0ec8472a93ac0c7ef0e98ebb91ac780bde12d5a5 FIREFOX_BETA_42_END
38ffeba26f3e420312e04cb3afb408f4c66a6f2e FIREFOX_RELEASE_43_BASE
56320bc06404b926b475051ba643950bd78cf221 FIREFOX_RELEASE_42_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
67a788db9f07822cfef52351bbbe3745dff8bd7f FIREFOX_AURORA_44_BASE
9d3bc275a924a84ab5f34df58c566af0f87479d0 FIREFOX_AURORA_43_END
b717b80eec62a7ba9b8842487f157b68c1419edd FIREFOX_BETA_44_BASE
366dd290472633b06f0942d7737c34e942e0916a FIREFOX_BETA_43_END
ef3cfadfccb97588653ae06eefdac28ec447c1f6 FIREFOX_RELEASE_44_BASE
af39a90c443c2fda798c2797e196eeb5a8b5cedd FIREFOX_RELEASE_43_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
99137d6d4061f408ae0869122649d8bdf489cc30 FIREFOX_AURORA_45_BASE
4fbd53613240c431522521b953d5a62692909e65 FIREFOX_AURORA_44_END
3bfa5bc61b626761d487b45c170b115259f69d6b FIREFOX_BETA_45_BASE
6a7547e4a0f0e213bb8487c773e16543cbea8c73 FIREFOX_BETA_44_END
3a9789adadcd0de9ee31b16a89a11985822c6a11 FENNEC_45_0b1_RELEASE
6c0fd1f666e70f2b11f7083f9e7bf4c844a3716a FENNEC_45_0b1_RELEASE
3a9789adadcd0de9ee31b16a89a11985822c6a11 FENNEC_45_0b1_BUILD1
6c0fd1f666e70f2b11f7083f9e7bf4c844a3716a FENNEC_45_0b1_BUILD1
5e1da6523e97d7f8b01004bbe33118ac784b40ea FIREFOX_45_0b1_RELEASE
6c0fd1f666e70f2b11f7083f9e7bf4c844a3716a FIREFOX_45_0b1_RELEASE
5e1da6523e97d7f8b01004bbe33118ac784b40ea FIREFOX_45_0b1_BUILD1
6c0fd1f666e70f2b11f7083f9e7bf4c844a3716a FIREFOX_45_0b1_BUILD1
bbe048ab30ad3321a6505697703e5fee20e91343 FIREFOX_RELEASE_45_BASE
5fe8de3ca9bbf8bc18259c3490aca55c97e31979 FIREFOX_RELEASE_44_END
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
67c66c2878aed17ae3096d7db483ddbb2293c503 FIREFOX_AURORA_46_BASE
d82221ba4219e4ac04ecfe2a5301703411e176fa FIREFOX_AURORA_45_END
89effb961712d4a5f84e90bcdd4e421ed6645eea FIREFOX_BETA_46_BASE
78fe98c670fcc9a1548ac655ae9a488d940fd9c8 FIREFOX_BETA_45_END
fb3494d06dfb73e26df72ca7a4bc4ef5ebf8795c FIREFOX_46_0b1_RELEASE
5904e3eb711dd263a6d2deb63b14e0c44e577054 FIREFOX_46_0b2_BUILD3
5904e3eb711dd263a6d2deb63b14e0c44e577054 FIREFOX_46_0b2_RELEASE
2f6f69a19150e03ad68062f2ac92342afb1ef787 FIREFOX_46_0b4_BUILD2
2f6f69a19150e03ad68062f2ac92342afb1ef787 FIREFOX_46_0b4_RELEASE
53d6e6648f97402a740687a82a297c66f5396548 FIREFOX_46_0b5_BUILD2
53d6e6648f97402a740687a82a297c66f5396548 FIREFOX_46_0b5_RELEASE
97b81104ac035d6a8f6ed59a1aad63fcc23e73c8 FIREFOX_46_0b6_BUILD1
97b81104ac035d6a8f6ed59a1aad63fcc23e73c8 FIREFOX_46_0b6_RELEASE
191f5eb4cbd72590277296cdb90d355adb347d45 FIREFOX_46_0b7_BUILD2
191f5eb4cbd72590277296cdb90d355adb347d45 FIREFOX_46_0b7_RELEASE
0334bcac4033f4f163476677165acd406e08fed8 FIREFOX_46_0b8_BUILD1
0334bcac4033f4f163476677165acd406e08fed8 FIREFOX_46_0b8_RELEASE
b007110e90053e58946b59765605bfca766c30d1 FIREFOX_46_0b9_BUILD1
b007110e90053e58946b59765605bfca766c30d1 FIREFOX_46_0b9_RELEASE
9ea83990839bd513869018e57bcbedb3454b63bb FIREFOX_46_0b10_BUILD1
9ea83990839bd513869018e57bcbedb3454b63bb FIREFOX_46_0b10_RELEASE
6c4646c7a6d6506e744c92a8170310191904c98e FIREFOX_RELEASE_46_BASE
64b6b8afb34bf8a4416b1d167b48177d0e30bde9 FIREFOX_RELEASE_45_END
078baf501b55eaa47f3b189fda4dd28dae1fa257 FIREFOX_46_0_BUILD5
078baf501b55eaa47f3b189fda4dd28dae1fa257 FIREFOX_46_0_RELEASE
0b8492c110bec959b94e3d54d5bd5ca7f7f97f6c FIREFOX_46_0_1_BUILD1
0b8492c110bec959b94e3d54d5bd5ca7f7f97f6c FIREFOX_46_0_1_RELEASE
076bf6a0ac85ec6a4f3ee7c3efe653964d92b9f2 FIREFOX_46_0b11_BUILD1
076bf6a0ac85ec6a4f3ee7c3efe653964d92b9f2 FIREFOX_46_0b11_RELEASE
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
68d3781deda0d4d58ec9877862830db89669b3a5 FIREFOX_AURORA_47_BASE
43d92f7052e7bab870c9b994d4b0a0f42d26b7a7 FIREFOX_AURORA_46_END
8551b253f4061db31e4be7829c2f70c2610caf42 FIREFOX_BETA_47_BASE
a2290938ee6cf794896a9347980bcb00ebb24c68 FIREFOX_BETA_46_END
5bbf2e7c2fc6ff9010b1948e2f11477f48ee36e2 FIREFOX_47_0b1_BUILD2
5bbf2e7c2fc6ff9010b1948e2f11477f48ee36e2 FIREFOX_47_0b1_RELEASE
6f82d30fe05e1412e744cb76af86f0c9ffe509d4 FIREFOX_47_0b2_BUILD1
6f82d30fe05e1412e744cb76af86f0c9ffe509d4 FIREFOX_47_0b2_RELEASE
609000bcc11211d7c27ceea36fa2d2262fa0523f FIREFOX_47_0b3_BUILD1
609000bcc11211d7c27ceea36fa2d2262fa0523f FIREFOX_47_0b3_RELEASE
2991f214d4f4d8a3c5cfd95e6223f0660006767d FIREFOX_47_0b4_BUILD1
2991f214d4f4d8a3c5cfd95e6223f0660006767d FIREFOX_47_0b4_RELEASE
93a53170dedffdff45bf9eb8dac6e5ef7a13c4ba FIREFOX_47_0b5_BUILD1
93a53170dedffdff45bf9eb8dac6e5ef7a13c4ba FIREFOX_47_0b5_RELEASE
7d1f3450acc47025876964c1eca854ae027934f3 FIREFOX_47_0b6_BUILD1
7d1f3450acc47025876964c1eca854ae027934f3 FIREFOX_47_0b6_RELEASE
0723a0212f5e0b30d7532d4e35eba7759fb54507 FIREFOX_47_0b7_BUILD1
0723a0212f5e0b30d7532d4e35eba7759fb54507 FIREFOX_47_0b7_RELEASE
cb27eacbe04abc5f91a0379c23617715aab432ec FIREFOX_47_0b8_BUILD1
cb27eacbe04abc5f91a0379c23617715aab432ec FIREFOX_47_0b8_RELEASE
2ee4473c729acb2ba7dc723e7affe79ce14bff85 FIREFOX_47_0b9_BUILD1
2ee4473c729acb2ba7dc723e7affe79ce14bff85 FIREFOX_47_0b9_RELEASE
cf6ec12bd62001b93387ffb184a8841644255b5e FIREFOX_RELEASE_47_BASE
32d716995e14ae1e8eb128fde0881b121b7b53d0 FIREFOX_RELEASE_46_END
b0310cb90fd0158abd0e92850a47768649ba3d77 FIREFOX_47_0_BUILD3
b0310cb90fd0158abd0e92850a47768649ba3d77 FIREFOX_47_0_RELEASE
7f5abf95991bda0bc2b8e0d774a8866b726b312b FIREFOX_47_0_1_BUILD1
7f5abf95991bda0bc2b8e0d774a8866b726b312b FIREFOX_47_0_1_RELEASE
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
1c6385ae1fe7e37d8f23f958ce14582f07af729e FIREFOX_AURORA_48_BASE
037f67a2d6c87e32f60b2753f19e4bed69cb60b3 FIREFOX_AURORA_47_END
961e7105e527f5b44e2b3cb6e24f6da33756f6ab FIREFOX_BETA_48_BASE
a86835580095325bf5c85483fad952f5c99d973e FIREFOX_BETA_47_END
55124c7343021091a61fdddac9f22628ca09642a FIREFOX_48_0b1_BUILD2
55124c7343021091a61fdddac9f22628ca09642a FIREFOX_48_0b1_RELEASE
9798772706750302d87a689cbbf056ae04244f80 FIREFOX_48_0b2_BUILD2
9798772706750302d87a689cbbf056ae04244f80 FIREFOX_48_0b2_RELEASE
13b02b96281e550c3cdbdf4eaed034aa1edefd69 FIREFOX_48_0b3_BUILD1
13b02b96281e550c3cdbdf4eaed034aa1edefd69 FIREFOX_48_0b3_RELEASE
676a32cdd41fd372f4c6df3a4954939f73a6ef02 FIREFOX_48_0b4_BUILD1
676a32cdd41fd372f4c6df3a4954939f73a6ef02 FIREFOX_48_0b4_RELEASE
dd7af1fa4ece1cb3158d08c80dfcbf1c6ca830fb FIREFOX_48_0b5_BUILD1
dd7af1fa4ece1cb3158d08c80dfcbf1c6ca830fb FIREFOX_48_0b5_RELEASE
d142c49033c015f67272562b37dbe2912cfc7f14 FIREFOX_48_0b6_BUILD1
d142c49033c015f67272562b37dbe2912cfc7f14 FIREFOX_48_0b6_RELEASE
9d734024ed35d74449601cc04917b327e0973c0d FIREFOX_48_0b7_BUILD1
9d734024ed35d74449601cc04917b327e0973c0d FIREFOX_48_0b7_RELEASE
d2ab9c39bd1059d74acb3d9ac87dbfbba913427b FIREFOX_48_0b9_BUILD1
d2ab9c39bd1059d74acb3d9ac87dbfbba913427b FIREFOX_48_0b9_RELEASE
05853bb06a8739b77c2937f418cdf4e1610d0d9f FIREFOX_48_0b10_BUILD1
05853bb06a8739b77c2937f418cdf4e1610d0d9f FIREFOX_48_0b10_RELEASE
f3d7abb885c267a7657e3b8ea06c18f76eb69641 FIREFOX_RELEASE_48_BASE
2366ae84e268c386a292185bddb0e4a24c2e1d07 FIREFOX_RELEASE_47_END
c1de04f39fa956cfce83f6065b0e709369215ed5 FIREFOX_48_0_BUILD2
c1de04f39fa956cfce83f6065b0e709369215ed5 FIREFOX_48_0_RELEASE
f36f7ace6f487e06f315f343d560b205fa8bd736 FIREFOX_48_0_1_BUILD3
f36f7ace6f487e06f315f343d560b205fa8bd736 FIREFOX_48_0_1_RELEASE
d4af0671004007e58d316b3e49679b66879c205a FIREFOX_48_0_2_BUILD1
d4af0671004007e58d316b3e49679b66879c205a FIREFOX_48_0_2_RELEASE
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
a8fe75f38163d0af067fea60e951a844fb328db9 FIREFOX_AURORA_48_END
d2f65d99fd51e5ee2f34d892115cc5d6c39a8ea9 FIREFOX_BETA_49_BASE
958cee08361af9ed370be06695973bcda3d3aa46 FIREFOX_BETA_48_END
c14631e328bbbd3aabaf06b51597060b55938ba8 FIREFOX_49_0b1_BUILD3
c14631e328bbbd3aabaf06b51597060b55938ba8 FIREFOX_49_0b1_RELEASE
b1bdd0f3482ae07d38a2ec5fbf190a2c4f2310ee FIREFOX_49_0b2_BUILD1
b1bdd0f3482ae07d38a2ec5fbf190a2c4f2310ee FIREFOX_49_0b2_RELEASE
36af692196a1c92cc935cf6569e03fdf5dc5e426 FIREFOX_49_0b3_BUILD1
36af692196a1c92cc935cf6569e03fdf5dc5e426 FIREFOX_49_0b3_RELEASE
ab7b68014a1e20c423aa9b50ca76fd8edccb272c FIREFOX_49_0b4_BUILD1
ab7b68014a1e20c423aa9b50ca76fd8edccb272c FIREFOX_49_0b4_RELEASE
91505c2a68fb868bcab1e3dc03ffc2e89bf71cac FIREFOX_49_0b5_BUILD1
91505c2a68fb868bcab1e3dc03ffc2e89bf71cac FIREFOX_49_0b5_RELEASE
e6d6eb0ce3c42b4ebca91b1b1b64b716b2acb9fd FIREFOX_49_0b6_BUILD1
e6d6eb0ce3c42b4ebca91b1b1b64b716b2acb9fd FIREFOX_49_0b6_RELEASE
b44c72b85a800d9c6e719579d480bb2c3a87a753 FIREFOX_49_0b7_BUILD1
b44c72b85a800d9c6e719579d480bb2c3a87a753 FIREFOX_49_0b7_RELEASE
68d24e6f784c7e375cf6c84c5c92496464d4f7e0 FIREFOX_49_0b8_BUILD1
68d24e6f784c7e375cf6c84c5c92496464d4f7e0 FIREFOX_49_0b8_RELEASE
e3cc699ccef2abb7075c39e7b9a081718eb9c159 FIREFOX_49_0b9_BUILD1
e3cc699ccef2abb7075c39e7b9a081718eb9c159 FIREFOX_49_0b9_RELEASE
77a60bbacb97c2f36815b2c395958a354aa581c9 FIREFOX_49_0b10_BUILD1
77a60bbacb97c2f36815b2c395958a354aa581c9 FIREFOX_49_0b10_RELEASE
5d1f8216843a6374f3bd2bd74ab2532da67d74ee FIREFOX_RELEASE_49_BASE
31ca1b4c28a9f64e49d59ed01d08469a9af41951 FIREFOX_RELEASE_48_END
416dc3163a1f27b8783ed14660d1b373e830df2f FIREFOX_49_0_BUILD4
416dc3163a1f27b8783ed14660d1b373e830df2f FIREFOX_49_0_RELEASE
2d931a5eaf8aeee925eca2aea42582a1fb9793c8 FIREFOX_49_0_1_BUILD3
2d931a5eaf8aeee925eca2aea42582a1fb9793c8 FIREFOX_49_0_1_RELEASE
7356baae8e736a6c9444bdd21562df806a39766b FIREFOX_49_0_2_BUILD2
7356baae8e736a6c9444bdd21562df806a39766b FIREFOX_49_0_2_RELEASE
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
d98f20c25feeac4dd7ebbd1c022957df1ef58af4 FIREFOX_AURORA_49_BASE
465d150bc8be5bbf9f02a8607d4552b6a5e1697c FIREFOX_AURORA_50_BASE
fa80a27f26dfc653d23392c71f562b1827d82174 FIREFOX_AURORA_49_END
c174d0c3195371011b3bf8044512c06c26f5c741 FIREFOX_BETA_50_BASE
ddeb7907bc1e854738b164bab5ff71c3dcf1d786 FIREFOX_BETA_49_END
91faf7ec36cd18a8ebdc0e2edac966e5bbb15da2 FIREFOX_50_0b1_BUILD2
91faf7ec36cd18a8ebdc0e2edac966e5bbb15da2 FIREFOX_50_0b1_RELEASE
865939f4946d80fa532aaa168515a2fe69f9a774 FIREFOX_50_0b2_BUILD1
865939f4946d80fa532aaa168515a2fe69f9a774 FIREFOX_50_0b2_RELEASE
6a7c1c8db5548d077c7fa36bce41af629ba52bd8 FIREFOX_50_0b3_BUILD1
6a7c1c8db5548d077c7fa36bce41af629ba52bd8 FIREFOX_50_0b3_RELEASE
f4b45ea3c0c836e5a457c8009bff423447e54803 FIREFOX_50_0b4_BUILD1
f4b45ea3c0c836e5a457c8009bff423447e54803 FIREFOX_50_0b4_RELEASE
49776d31766dd130969f9ec4ea3354a43e8e6d9d FIREFOX_50_0b5_BUILD1
49776d31766dd130969f9ec4ea3354a43e8e6d9d FIREFOX_50_0b5_RELEASE
70abfe99097824fd510544b188f24c588fd6d5a0 FIREFOX_50_0b6_BUILD1
70abfe99097824fd510544b188f24c588fd6d5a0 FIREFOX_50_0b6_RELEASE
6efc0964ec62bc4abfdc4cb1dc7cc461c3238634 FIREFOX_50_0b7_BUILD1
6efc0964ec62bc4abfdc4cb1dc7cc461c3238634 FIREFOX_50_0b7_RELEASE
b7adb2f10487f6f886e047670ba720a248edcb44 FIREFOX_50_0b8_BUILD1
b7adb2f10487f6f886e047670ba720a248edcb44 FIREFOX_50_0b8_RELEASE
2bb6dc758711c00d84246d74b57e5aa6cae4b447 FIREFOX_50_0b9_BUILD1
2bb6dc758711c00d84246d74b57e5aa6cae4b447 FIREFOX_50_0b9_RELEASE
38cfded1705240c5d20baff4aef99bdd0a13bcec FIREFOX_50_0b10_BUILD1
38cfded1705240c5d20baff4aef99bdd0a13bcec FIREFOX_50_0b10_RELEASE
829a3f99f2606759305e3db204185242566a4ca6 FIREFOX_50_0b11_BUILD1
829a3f99f2606759305e3db204185242566a4ca6 FIREFOX_50_0b11_RELEASE
d7598ee90bc6085d430b2e9e75c13358ef00a5f4 FIREFOX_RELEASE_50_BASE
dd6c8d2be972cbf8729c01292639b8a03ce94728 FIREFOX_RELEASE_49_END
dc617d65c9f0cdbbe4351cc1e5c288b05f25f8f7 FIREFOX_50_0_BUILD2
dc617d65c9f0cdbbe4351cc1e5c288b05f25f8f7 FIREFOX_50_0_RELEASE
8612c3320053b796678921f8f23358e3e9df997e FIREFOX_50_1_0_BUILD2
8612c3320053b796678921f8f23358e3e9df997e FIREFOX_50_1_0_RELEASE
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
fc69febcbf6c0dcc4b3dfc7a346d8d348798a65f FIREFOX_AURORA_51_BASE
3fdfaaed6e0fad2d81fc28e49903ff6f0a43b12e FIREFOX_AURORA_50_END
2d9b6132e7d75327e063a15d8e5e279077adf987 FIREFOX_BETA_51_BASE
24b8f08f77565f859898b45f62d2132ccc64c6d8 FIREFOX_BETA_50_END
749a8d32b74eae516b9427f28aad4ec1c11e0a54 FIREFOX_51_0b1_BUILD2
749a8d32b74eae516b9427f28aad4ec1c11e0a54 FIREFOX_51_0b1_RELEASE
6296ed3dbefd133bba324230ec4f5a07d37041e1 FIREFOX_51_0b2_BUILD1
6296ed3dbefd133bba324230ec4f5a07d37041e1 FIREFOX_51_0b2_RELEASE
f37e99ebc6e0c682003b52573f415e5fd78d425a FIREFOX_51_0b3_BUILD1
f37e99ebc6e0c682003b52573f415e5fd78d425a FIREFOX_51_0b3_RELEASE
1b954c82dd04faf1926804d89c0d130dc6b9ab93 FIREFOX_51_0b4_BUILD1
1b954c82dd04faf1926804d89c0d130dc6b9ab93 FIREFOX_51_0b4_RELEASE
9afe68360fa82c16b760b448b2156230a90caf11 FIREFOX_51_0b5_BUILD1
9afe68360fa82c16b760b448b2156230a90caf11 FIREFOX_51_0b5_RELEASE
2dec3c6c7c90e2e27093b8a3512c1b32a8263a8f FIREFOX_51_0b6_BUILD1
2dec3c6c7c90e2e27093b8a3512c1b32a8263a8f FIREFOX_51_0b6_RELEASE
829fcc7f60f04dffff4d29b007ef8015a1cd2c99 FIREFOX_51_0b7_BUILD1
829fcc7f60f04dffff4d29b007ef8015a1cd2c99 FIREFOX_51_0b7_RELEASE
ae5275b8c53ba76cb98576e4e2a3031b0d659ba3 FIREFOX_51_0b8_BUILD1
ae5275b8c53ba76cb98576e4e2a3031b0d659ba3 FIREFOX_51_0b8_RELEASE
6e4843d1510be426212d31fec03ad4f2d70b1977 FIREFOX_51_0b9_BUILD1
6e4843d1510be426212d31fec03ad4f2d70b1977 FIREFOX_51_0b9_RELEASE
4fbf5d14ce92bd45e0c7881dad20a66896402683 FIREFOX_51_0b10_BUILD1
4fbf5d14ce92bd45e0c7881dad20a66896402683 FIREFOX_51_0b10_RELEASE
0a17d39220700e742bf37a960967480b2f8159f1 FIREFOX_51_0b11_BUILD1
0a17d39220700e742bf37a960967480b2f8159f1 FIREFOX_51_0b11_RELEASE
9ddd4fee07842e72ba49f1583ec5f596f6e60e72 FIREFOX_51_0b12_BUILD1
9ddd4fee07842e72ba49f1583ec5f596f6e60e72 FIREFOX_51_0b12_RELEASE
ce55e4d276031458f0730d481acff05d7c797038 FIREFOX_51_0b13_BUILD1
ce55e4d276031458f0730d481acff05d7c797038 FIREFOX_51_0b13_RELEASE
09142d07fd735e375fc1ae46886a52d6aef43b60 FIREFOX_51_0b14_BUILD1
09142d07fd735e375fc1ae46886a52d6aef43b60 FIREFOX_51_0b14_RELEASE
15467610e733e3549ea86cdf940b0fccd87eff89 FIREFOX_RELEASE_51_BASE
b1e53b9be6d4834f5b3a58c132dfc5f5c73d2bcd FIREFOX_RELEASE_50_END
ea82b5e20cbbd103f8fa65f0df0386ee4135cc47 FIREFOX_51_0_BUILD2
ea82b5e20cbbd103f8fa65f0df0386ee4135cc47 FIREFOX_51_0_RELEASE
327e081221b064b05a302d7877c6e4be2949a617 FIREFOX_51_0_1_BUILD3
327e081221b064b05a302d7877c6e4be2949a617 FIREFOX_51_0_1_RELEASE
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
1196bf3032e1bce1fb07a01fd9082a767426c5fb FIREFOX_AURORA_52_BASE
3223a6411d8c8b9ec8bcbc607c990bf099ade099 FIREFOX_AURORA_51_END
24a81d93e07cc96300f8e1f5c69034dd4743bd63 FIREFOX_BETA_52_BASE
8e692dd4176cba81ce020b29ae8b352dc1db724a FIREFOX_BETA_51_END
78ae21055d9f303be257abe155ba9dee466c0651 FIREFOX_52_0b1_BUILD2
78ae21055d9f303be257abe155ba9dee466c0651 FIREFOX_52_0b1_RELEASE
0f339c1e154f75c484fe2fac507a9a225990d212 FIREFOX_52_0b2_BUILD1
0f339c1e154f75c484fe2fac507a9a225990d212 FIREFOX_52_0b2_RELEASE
d171c36d484800b1bb00db1612460a7120dd2fdf FIREFOX_52_0b3_BUILD1
d171c36d484800b1bb00db1612460a7120dd2fdf FIREFOX_52_0b3_RELEASE
501a3fa83897af9598adfd6f794b5d5ea82fe237 FIREFOX_52_0b4_BUILD1
501a3fa83897af9598adfd6f794b5d5ea82fe237 FIREFOX_52_0b4_RELEASE
49b3ad9f467d48194dab8121f82e4c938b70b484 FIREFOX_52_0b5_BUILD1
49b3ad9f467d48194dab8121f82e4c938b70b484 FIREFOX_52_0b5_RELEASE
7b8aa893944b94d35e47314e52e0abff576c5ce2 FIREFOX_52_0b6_BUILD1
7b8aa893944b94d35e47314e52e0abff576c5ce2 FIREFOX_52_0b6_RELEASE
820bc5bd3120853d611af1056f4a2b35528bb927 FIREFOX_52_0b7_BUILD1
820bc5bd3120853d611af1056f4a2b35528bb927 FIREFOX_52_0b7_RELEASE
3b31bcb88fe341172e93cc8b1143e617c0988694 FIREFOX_52_0b8_BUILD1
3b31bcb88fe341172e93cc8b1143e617c0988694 FIREFOX_52_0b8_RELEASE
61519976b35f2947eeaabefcad83186b7e004167 FIREFOX_52_0b9_BUILD2
61519976b35f2947eeaabefcad83186b7e004167 FIREFOX_52_0b9_RELEASE
4bd2e5d2ac0d0b15b4446fca5647bfa821b52d46 FIREFOX_RELEASE_52_BASE
1f0fc9316e65cd171b03d4382b4c0f7443a258dc FIREFOX_RELEASE_51_END
2183f7cb4f886e5f0b619dcff101bee72210ef38 FIREFOX_ESR_52_BASE
15d9d940341f02ef6dcad96899d284619d3d48db FIREFOX_52_0esr_BUILD4
15d9d940341f02ef6dcad96899d284619d3d48db FIREFOX_52_0esr_RELEASE
3462b933db3cac9b994b32dfc6350f3d549bf2de FIREFOX_52_0_1esr_BUILD2
3462b933db3cac9b994b32dfc6350f3d549bf2de FIREFOX_52_0_1esr_RELEASE
afa66bcf9203e691f164e5e8a9cc8fad783ccddc FIREFOX_52_0_2esr_BUILD1
afa66bcf9203e691f164e5e8a9cc8fad783ccddc FIREFOX_52_0_2esr_RELEASE
3ea0e075203185d7f2d42f439455e97735bd1b20 FIREFOX_52_1_0esr_BUILD3
3ea0e075203185d7f2d42f439455e97735bd1b20 FIREFOX_52_1_0esr_RELEASE
120111e65bc4e9b99da97e9d046765de95fbac8c FIREFOX_52_1_1esr_BUILD1
120111e65bc4e9b99da97e9d046765de95fbac8c FIREFOX_52_1_1esr_RELEASE
0dc7c28f20648d597b11b60e90be9a15687656aa FIREFOX_52_1_2esr_BUILD1
0dc7c28f20648d597b11b60e90be9a15687656aa FIREFOX_52_1_2esr_RELEASE
f68e0d98a22a4712a3710998081fd0ea5cd00ccb FIREFOX_52_2_0esr_BUILD1
f68e0d98a22a4712a3710998081fd0ea5cd00ccb FIREFOX_52_2_0esr_RELEASE
512efd480dac58acf9eebd5f25a76b32917ab56d FIREFOX_52_2_1esr_BUILD2
512efd480dac58acf9eebd5f25a76b32917ab56d FIREFOX_52_2_1esr_RELEASE
20a1a6ad46d5a4ec83d9800614fc288bf79e14a8 FIREFOX_52_3_0esr_BUILD2
20a1a6ad46d5a4ec83d9800614fc288bf79e14a8 FIREFOX_52_3_0esr_RELEASE
285cde3988335103bd8d60cc09d6fa36db3c4d78 FIREFOX_52_4_0esr_BUILD2
285cde3988335103bd8d60cc09d6fa36db3c4d78 FIREFOX_52_4_0esr_RELEASE
e4fec62e5347a77a9a313d6019a2b372e8011a74 FIREFOX_52_4_1esr_BUILD1
e4fec62e5347a77a9a313d6019a2b372e8011a74 FIREFOX_52_4_1esr_RELEASE
cf34a0574e585fab44fbec1718aca5375790cd97 FIREFOX_52_5_0esr_BUILD2
cf34a0574e585fab44fbec1718aca5375790cd97 FIREFOX_52_5_0esr_RELEASE
b0a57c57b5ef0150e8afc3219bceadb1d6f1584e FIREFOX_52_5_2esr_BUILD2
b0a57c57b5ef0150e8afc3219bceadb1d6f1584e FIREFOX_52_5_2esr_RELEASE
+371 -7
View File
@@ -1,9 +1,373 @@
Please see the file toolkit/content/license.html for the copyright licensing
conditions attached to this codebase, including copies of the licenses
concerned.
Mozilla Public License Version 2.0
==================================
You are not granted rights or licenses to the trademarks of the
Mozilla Foundation or any party, including without limitation the
Firefox name or logo.
1. Definitions
--------------
For more information, see: http://www.mozilla.org/foundation/licensing.html
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
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 it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
-27
View File
@@ -1,27 +0,0 @@
An explanation of the Mozilla Source Code Directory Structure and links to
project pages with documentation can be found at:
https://developer.mozilla.org/en/Mozilla_Source_Code_Directory_Structure
For information on how to build Mozilla from the source code, see:
http://developer.mozilla.org/en/docs/Build_Documentation
To have your bug fix / feature added to Mozilla, you should create a patch and
submit it to Bugzilla (https://bugzilla.mozilla.org). Instructions are at:
http://developer.mozilla.org/en/docs/Creating_a_patch
http://developer.mozilla.org/en/docs/Getting_your_patch_in_the_tree
If you have a question about developing Mozilla, and can't find the solution
on http://developer.mozilla.org, you can try asking your question in a
mozilla.* Usenet group, or on IRC at irc.mozilla.org. [The Mozilla news groups
are accessible on Google Groups, or news.mozilla.org with a NNTP reader.]
You can download nightly development builds from the Mozilla FTP server.
Keep in mind that nightly builds, which are used by Mozilla developers for
testing, may be buggy. Firefox nightlies, for example, can be found at:
https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/
- or -
http://nightly.mozilla.org/
-15
View File
@@ -1,15 +0,0 @@
syntax: glob
local.json
python-lib/cuddlefish/app-extension/components/jetpack.xpt
testdocs.tgz
jetpack-sdk-docs.tgz
.test_tmp
jetpack-sdk-docs
node_modules
# These should really be in a global .hgignore, but such a thing
# seems ridiculously confusing to set up, so we'll include some
# common intermediate files here.
*.pyc
*~
*.DS_Store
-64
View File
@@ -1,64 +0,0 @@
39c45211aa250d43f6e54b776a60ef07a7a4cbb6 jep-31-examples
0120642297b217680e75e68c4005a93b16466001 0.1rc1
1fd7993ff2cec39c5948a1b2535b78c2d4c65858 0.1rc2
530e51d02922ad05fd43e8cf113618068216b0cf 0.1
ed11a9e3ae23aefd56ac88042b9816887d10a04f 0.2rc1
f70ab8998abdce809bda93408435f83648909cdd 0.2rc2
f70ab8998abdce809bda93408435f83648909cdd 0.2
436968c6ec833d9c18a15426be26595a44b79283 0.3rc1
a3b091d29607f0bcecf77fe27801ba901142f1c9 0.3
06031b56312ad7f1880a9620b4d26ce253a23b23 0.3rc2
a3b091d29607f0bcecf77fe27801ba901142f1c9 0.3
4b08c8a8c1eef71ac3aa54e004b68e87049ca56b 0.3
6884e54fd6a1cfa9ec63910c46d2cbf51495b584 0.3rc3
4b08c8a8c1eef71ac3aa54e004b68e87049ca56b 0.3
cd70b7140ec20689255f1248512a1e5b9cf90a32 0.3
d9d733666ca8738e9665ba816d5d12f41fc0d216 0.4rc1
8d2871fc10df16740273f53ef05815310da4b210 0.4
201e60065b1aef23259a71756f93207cffa2abd5 0.4rc2
8d2871fc10df16740273f53ef05815310da4b210 0.4
c0e5bbdcafad4572a5de22e533543bf3330a869e 0.4
201e60065b1aef23259a71756f93207cffa2abd5 0.4rc2
a8dceaefd6f3376b7bc1619cccd854591b76ecc0 0.4rc2
c0e5bbdcafad4572a5de22e533543bf3330a869e 0.4
dfa3bdfedb12d743b5e0ac19d0ecf116b567a0b3 0.4
b519a0848585e2a665a14aac2fb6f15c0a839e6c 0.4rc3
dfa3bdfedb12d743b5e0ac19d0ecf116b567a0b3 0.4
05acdf4987c28d8cc1d5a12d87e71b1445fdd6b7 0.4
04b5afe48d1cee819d9f0af72ed16556a075b67d 0.5rc1
1968150561097bcfeeb28a75801ef881d2fcbbf5 0.5
3236e68e6f2e36353e47f01a9b8acfce56686263 0.5rc2
1968150561097bcfeeb28a75801ef881d2fcbbf5 0.5
0097da78aa23be8b7a5a811c4be0e3e35395af43 0.5
be7016807a69c910ac31ff068a6c2bde0a25c9d4 0.5rc3
0097da78aa23be8b7a5a811c4be0e3e35395af43 0.5
83e97107e4a381b898c780b32e30e48b0e4d37f3 0.5
182a405aa393dbd412e671e8516d2decd8e8d80c 0.6rc1
96799a3d96abfdb1408f9b8e30479668f1feed70 0.6
c5f6cdfa36b2ad33d8017e6844992de0b0a6c0e0 0.6rc2
96799a3d96abfdb1408f9b8e30479668f1feed70 0.6
65c393fbc6af7db79a4a2e903d06b17e90d254bf 0.6
3e747e3e307a4e853d468b03357f96b2172bad37 0.7rc1
b0e97e12eb9115f08127cc447d459f871c5046ed 0.7
37288479d249168668abd60a907620fa7f593128 0.7rc2
b0e97e12eb9115f08127cc447d459f871c5046ed 0.7
db0eabc310619d00ce47372ecaafba7d2539b601 0.7
37288479d249168668abd60a907620fa7f593128 0.7rc2
b90bedb83525d8f32ebb4d3833e8d91efa991b6d 0.7rc2
db0eabc310619d00ce47372ecaafba7d2539b601 0.7
e6ea2e5c5274cbbb0278dc976844dbf51818a95e 0.7
b90bedb83525d8f32ebb4d3833e8d91efa991b6d 0.7rc2
9b978d823509de5d52ca222b9907f72591c68c5a 0.7rc2
e6ea2e5c5274cbbb0278dc976844dbf51818a95e 0.7
cd71e1e77c93adf169b9f38184b1f95d423876ba 0.7
67e3fd285fa955898a2641226c86725365d68b95 0.8rc1
b2f9405db6d74c21601ca9c250887411c837396a 0.8
67e3fd285fa955898a2641226c86725365d68b95 0.8rc1
56e8179ff5b467959ddf33978558d7eb5346ee53 0.8rc1
b2f9405db6d74c21601ca9c250887411c837396a 0.8
51a22a186b1c7d8e7292a5ec9670752dad223ca1 0.8
d150cca77cfef60dee2f2fe7c892fd7fc5ce83c4 0.9rc1
1e106beb57f65fabc32682f277de51a8101c919b 0.9
173d56fa8cc1c5622eae70f1ae88ef789de4722b 0.9rc2
1e106beb57f65fabc32682f277de51a8101c919b 0.9
cde12eefd178d7a0ee7d5e9ae77f3089bcbdc6ec 0.9
+7
View File
@@ -0,0 +1,7 @@
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 the
Mozilla Foundation, Moonchild Productions or any party, including without
limitation the Pale Moon name or logo.
+13
View File
@@ -0,0 +1,13 @@
# 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
@@ -0,0 +1 @@
PURGECACHES_DIRS = $(DIST)/bin/browser
+17
View File
@@ -0,0 +1,17 @@
# 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/.
if not CONFIG['LIBXUL_SDK']:
include('/toolkit/toolkit.mozbuild')
if CONFIG['MOZ_EXTENSIONS']:
DIRS += ['/extensions']
DIRS += ['/%s' % CONFIG['MOZ_BRANDING_DIRECTORY']]
# Never add tier dirs after browser because they apparently won't get
# packaged properly on Mac.
DIRS += ['/browser']
+116
View File
@@ -0,0 +1,116 @@
# 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
DEFINES += \
-DAB_CD=$(AB_CD) \
-DAPP_VERSION="$(MOZ_APP_VERSION)" \
-DFIREFOX_ICO=\"$(DIST)/branding/firefox.ico\" \
-DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\" \
-DNEWWINDOW_ICO=\"$(DIST)/branding/newwindow.ico\" \
-DNEWTAB_ICO=\"$(DIST)/branding/newtab.ico\" \
-DPBMODE_ICO=\"$(DIST)/branding/pbmode.ico\" \
$(NULL)
# Build a binary bootstrapping with XRE_main
ifndef MOZ_WINCONSOLE
ifdef MOZ_DEBUG
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)
EXTRA_DEPS += $(PROGRAM).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/, palemoon.js)
endif
ifdef MOZ_WIDGET_GTK
libs::
$(INSTALL) $(IFLAGS1) $(DIST)/branding/mozicon128.png $(FINAL_TARGET)/icons
$(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png $(FINAL_TARGET)/chrome/icons/default
$(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png $(FINAL_TARGET)/chrome/icons/default
$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png $(FINAL_TARGET)/chrome/icons/default
endif
ifndef LIBXUL_SDK
# 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)
endif
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)
AB := $(firstword $(subst -, ,$(AB_CD)))
clean clobber repackage::
$(RM) -r $(dist_dest)
MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/config/buildid)
.PHONY: repackage
tools repackage:: $(PROGRAM)
$(MKDIR) -p $(dist_dest)/Contents/MacOS
$(MKDIR) -p $(dist_dest)/Contents/Resources/$(AB).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)/Contents/Resources/$(AB).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)/Contents/Resources/$(AB).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/$(PROGRAM)
rsync -aL $(PROGRAM) $(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
printf APPLMOZB > $(dist_dest)/Contents/PkgInfo
endif
ifdef LIBXUL_SDK #{
ifndef SKIP_COPY_XULRUNNER #{
libs::
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
rsync -a --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(dist_dest)/Contents/Frameworks
else
$(NSINSTALL) -D $(DIST)/bin/xulrunner
(cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
endif #} cocoa
endif #} SKIP_COPY_XULRUNNER
endif #} LIBXUL_SDK
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
_CodeSignature/CodeResources
@@ -0,0 +1,222 @@
<?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>palemoon</string>
<key>CFBundleGetInfoString</key>
<string>%MAC_APP_NAME% %APP_VERSION%</string>
<key>CFBundleIconFile</key>
<string>firefox</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>LSMinimumSystemVersion</key>
<string>10.6</string>
<key>LSMinimumSystemVersionByArchitecture</key>
<dict>
<key>i386</key>
<string>10.6.0</string>
<key>x86_64</key>
<string>10.6.0</string>
</dict>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSPrincipalClass</key>
<string>GoannaNSApplication</string>
</dict>
</plist>
@@ -0,0 +1,10 @@
/*.app/***
/*.dylib
/certutil
/firefox-bin
/gtest/***
/pk12util
/ssltunnel
/xpcshell
/XUL
@@ -0,0 +1,5 @@
/* 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%";
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>rules</key>
<dict>
<key>^Info.plist$</key>
<true/>
<key>^PkgInfo$</key>
<true/>
<key>^MacOS/</key>
<true/>
<key>^Resources/</key>
<true/>
<key>^MacOS/distribution/.*</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^MacOS/override.ini</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^MacOS/updates/.*</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^MacOS/active-update.xml$</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^MacOS/defaults/.*</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^MacOS/removed-files$</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^MacOS/updates.xml$</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^Updated.app/.*</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^updating/.*</key><dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
</dict>
</dict>
</plist>
+44
View File
@@ -0,0 +1,44 @@
#!/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)
buildid = open(options.buildid, 'r').read()
# 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
@@ -0,0 +1,8 @@
WIN32_MODULE_COMPANYNAME=Moonchild Productions
WIN32_MODULE_COPYRIGHT=©Pale Moon, Firefox and Mozilla Developers, available under the MPL 2.0.
WIN32_MODULE_PRODUCTVERSION=@MOZ_APP_WINVERSION@
WIN32_MODULE_PRODUCTVERSION_STRING=@MOZ_APP_VERSION@
WIN32_MODULE_TRADEMARKS=The Pale Moon logo and project names are the property of Moonchild Productions.
WIN32_MODULE_DESCRIPTION=Pale Moon web browser
WIN32_MODULE_PRODUCTNAME=Pale Moon
WIN32_MODULE_NAME=Pale Moon
+91
View File
@@ -0,0 +1,91 @@
# -*- Mode: python; c-basic-offset: 4; 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']
if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_ASAN']:
GoannaProgram(CONFIG['MOZ_APP_NAME'])
else:
GoannaProgram(CONFIG['MOZ_APP_NAME'], msvcrt='static')
JS_PREFERENCE_FILES += [
'profile/palemoon.js',
]
if CONFIG['LIBXUL_SDK']:
PREF_JS_EXPORTS += [
'profile/channel-prefs.js',
]
SOURCES += [
'nsBrowserApp.cpp',
]
FINAL_TARGET_FILES += ['blocklist.xml']
FINAL_TARGET_FILES.defaults.profile += ['profile/prefs.js']
DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
for var in ('MOZILLA_OFFICIAL', 'LIBXUL_SDK'):
if CONFIG[var]:
DEFINES[var] = True
DEFINES['XPCOM_GLUE'] = True
GENERATED_INCLUDES += [
'/build',
]
LOCAL_INCLUDES += [
'/toolkit/xre',
'/xpcom/base',
'/xpcom/build',
]
DELAYLOAD_DLLS += [
'mozglue.dll',
]
USE_STATIC_LIBS = True
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
# 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']
if CONFIG['OS_ARCH'] == 'WINNT':
USE_LIBS += [
'mozglue',
'xpcomglue_staticruntime',
]
else:
USE_LIBS += [
'xpcomglue',
]
DISABLE_STL_WRAPPING = True
if CONFIG['MOZ_LINKER']:
OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
if CONFIG['HAVE_CLOCK_MONOTONIC']:
OS_LIBS += CONFIG['REALTIME_LIBS']
+452
View File
@@ -0,0 +1,452 @@
/* -*- 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)
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#include <windows.h>
#include <winbase.h>
#include <VersionHelpers.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>
#elif defined(XP_UNIX)
#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
#endif
#ifdef XP_MACOSX
#include <mach/mach_time.h>
#include "MacQuirks.h"
#endif
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "nsStringGlue.h"
// Easy access to a five second startup delay used to get
// a debugger attached in the metro environment.
// #define DEBUG_delay_start_metro
#ifdef XP_WIN
// we want a wmain entry point
#include "nsWindowsWMain.cpp"
#define snprintf _snprintf
#define strcasecmp _stricmp
#endif
#include "BinaryPath.h"
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
#include "mozilla/StartupTimeline.h"
using namespace mozilla;
#ifdef XP_MACOSX
#define kOSXResourcesFolder "Resources"
#endif
#define kDesktopFolder "browser"
#define kMetroFolder "metro"
#define kMetroAppIniFilename "metroapp.ini"
#ifdef XP_WIN
#define kMetroTestFile "tests.ini"
const char* kMetroConsoleIdParam = "testconsoleid=";
#endif
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
MessageBoxW(nullptr,
wide_msg,
L"Pale Moon",
MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
#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;
}
#ifdef XP_WIN
/*
* AttachToTestHarness - Windows helper for when we are running
* in the immersive environment. Firefox is launched by Windows in
* response to a request by metrotestharness, which is launched by
* runtests.py. As such stdout in fx doesn't point to the right
* stream. This helper touches up stdout such that test output gets
* routed to a named pipe metrotestharness creates and dumps to its
* stdout.
*/
static void AttachToTestHarness()
{
// attach to the metrotestharness named logging pipe
HANDLE winOut = CreateFileA("\\\\.\\pipe\\metrotestharness",
GENERIC_WRITE,
FILE_SHARE_WRITE, 0,
OPEN_EXISTING, 0, 0);
if (winOut == INVALID_HANDLE_VALUE) {
OutputDebugStringW(L"Could not create named logging pipe.\n");
return;
}
// Set the c runtime handle
int stdOut = _open_osfhandle((intptr_t)winOut, _O_APPEND);
if (stdOut == -1) {
OutputDebugStringW(L"Could not open c-runtime handle.\n");
return;
}
FILE *fp = _fdopen(stdOut, "a");
*stdout = *fp;
}
#endif
XRE_GetFileFromPathType XRE_GetFileFromPath;
XRE_CreateAppDataType XRE_CreateAppData;
XRE_FreeAppDataType XRE_FreeAppData;
#ifdef XRE_HAS_DLL_BLOCKLIST
XRE_SetupDllBlocklistType XRE_SetupDllBlocklist;
#endif
XRE_StartupTimelineRecordType XRE_StartupTimelineRecord;
XRE_mainType XRE_main;
XRE_StopLateWriteChecksType XRE_StopLateWriteChecks;
static const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
#ifdef XRE_HAS_DLL_BLOCKLIST
{ "XRE_SetupDllBlocklist", (NSFuncPtr*) &XRE_SetupDllBlocklist },
#endif
{ "XRE_StartupTimelineRecord", (NSFuncPtr*) &XRE_StartupTimelineRecord },
{ "XRE_main", (NSFuncPtr*) &XRE_main },
{ "XRE_StopLateWriteChecks", (NSFuncPtr*) &XRE_StopLateWriteChecks },
{ nullptr, nullptr }
};
static int do_main(int argc, char* argv[], nsIFile *xreDirectory)
{
nsCOMPtr<nsIFile> appini;
nsresult rv;
uint32_t mainFlags = 0;
#ifdef XP_WIN
if (!IsWindowsVistaOrGreater()) {
Output("Couldn't load valid PE image.\n");
return 255;
}
#endif
// Allow palemoon.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];
snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]);
if (putenv(appEnv)) {
Output("Couldn't set %s.\n", appEnv);
return 255;
}
argv[2] = argv[0];
argv += 2;
argc -= 2;
}
if (appini) {
nsXREAppData *appData;
rv = XRE_CreateAppData(appini, &appData);
if (NS_FAILED(rv)) {
Output("Couldn't read application.ini");
return 255;
}
// xreDirectory already has a refcount from NS_NewLocalFile
appData->xreDirectory = xreDirectory;
int result = XRE_main(argc, argv, appData, mainFlags);
XRE_FreeAppData(appData);
return result;
}
// Desktop browser launch
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
nsCOMPtr<nsIFile> parent;
greDir->GetParent(getter_AddRefs(parent));
greDir = parent.forget();
greDir->AppendNative(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;
return XRE_main(argc, argv, &appData, mainFlags);
}
/**
* Local TimeStamp::Now()-compatible implementation used to record timestamps
* which will be passed to XRE_StartupTimelineRecord().
*/
static uint64_t
TimeStamp_Now()
{
#ifdef XP_WIN
LARGE_INTEGER freq;
::QueryPerformanceFrequency(&freq);
return GetTickCount64() * freq.QuadPart;
#elif defined(XP_MACOSX)
return mach_absolute_time();
#elif defined(HAVE_CLOCK_MONOTONIC)
struct timespec ts;
int rv = clock_gettime(CLOCK_MONOTONIC, &ts);
if (rv != 0) {
return 0;
}
uint64_t baseNs = (uint64_t)ts.tv_sec * 1000000000;
return baseNs + (uint64_t)ts.tv_nsec;
#endif
}
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
}
#ifdef LIBXUL_SDK
# define XPCOM_PATH "xulrunner" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL
#else
# define XPCOM_PATH XPCOM_DLL
#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_PATH) - 1))
return NS_ERROR_FAILURE;
strcpy(lastSlash + 1, XPCOM_PATH);
lastSlash += sizeof(XPCOM_PATH) - sizeof(XPCOM_DLL);
if (!FileExists(exePath)) {
#if defined(LIBXUL_SDK) && defined(XP_MACOSX)
// Check for <bundle>/Contents/Frameworks/XUL.framework/libxpcom.dylib
bool greFound = false;
CFBundleRef appBundle = CFBundleGetMainBundle();
if (!appBundle)
return NS_ERROR_FAILURE;
CFURLRef fwurl = CFBundleCopyPrivateFrameworksURL(appBundle);
CFURLRef absfwurl = nullptr;
if (fwurl) {
absfwurl = CFURLCopyAbsoluteURL(fwurl);
CFRelease(fwurl);
}
if (absfwurl) {
CFURLRef xulurl =
CFURLCreateCopyAppendingPathComponent(nullptr, absfwurl,
CFSTR("XUL.framework"),
true);
if (xulurl) {
CFURLRef xpcomurl =
CFURLCreateCopyAppendingPathComponent(nullptr, xulurl,
CFSTR("libxpcom.dylib"),
false);
if (xpcomurl) {
if (CFURLGetFileSystemRepresentation(xpcomurl, true,
(UInt8*) exePath,
sizeof(exePath)) &&
access(tbuffer, R_OK | X_OK) == 0) {
if (realpath(tbuffer, exePath)) {
greFound = true;
}
}
CFRelease(xpcomurl);
}
CFRelease(xulurl);
}
CFRelease(absfwurl);
}
}
if (!greFound) {
#endif
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;
}
NS_LogInit();
// 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[])
{
#ifdef DEBUG_delay_start_metro
Sleep(5000);
#endif
uint64_t start = TimeStamp_Now();
#ifdef XP_MACOSX
TriggerQuirks();
#endif
int gotCounters;
#if defined(XP_UNIX)
struct rusage initialRUsage;
gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
#elif defined(XP_WIN)
IO_COUNTERS ioCounters;
gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
#endif
nsIFile *xreDirectory;
nsresult rv = InitXPCOMGlue(argv[0], &xreDirectory);
if (NS_FAILED(rv)) {
return 255;
}
XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
#ifdef XRE_HAS_DLL_BLOCKLIST
XRE_SetupDllBlocklist();
#endif
int result = do_main(argc, argv, 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;
}
@@ -0,0 +1,48 @@
<?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="Pale Moon"
type="win32"
/>
<description>Pale Moon</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</dpiAware>
</ms_asmv3:windowsSettings>
</ms_asmv3:application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>
@@ -0,0 +1,6 @@
#filter substitution
/* 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@");
@@ -0,0 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; 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}']
@@ -0,0 +1,10 @@
#
# 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/.
FILES := \
install.rdf.in \
$(NULL)
FILES_PATH = $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
PP_TARGETS := FILES
@@ -0,0 +1,40 @@
<?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>Moonchild Productions</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>
@@ -0,0 +1,8 @@
# -*- Mode: python; c-basic-offset: 4; 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']
@@ -0,0 +1,7 @@
<?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#"/>
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
/* 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
@@ -0,0 +1,21 @@
/* -*- 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 "palemoon.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
@@ -0,0 +1,70 @@
/* 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/. */
#PMaboutDialog {
width: 620px;
}
#PMrightBox {
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;
}
#PMrightBox:-moz-locale-dir(rtl) {
background-position: 100% 0;
}
#PMbottomBox {
padding: 15px 10px 0;
}
#PMversion {
margin-top: 10px;
-moz-margin-start: 0;
-moz-user-select: text;
-moz-user-focus: normal;
cursor: text;
}
#distribution,
#distributionId {
font-weight: bold;
display: none;
margin-top: 0;
margin-bottom: 0;
}
.text-blurb {
margin-bottom: 10px;
-moz-margin-start: 0;
-moz-padding-start: 0;
}
#updateButton,
#updateDeck > hbox > label {
-moz-margin-start: 0;
-moz-padding-start: 0;
}
.update-throbber {
width: 16px;
min-height: 16px;
-moz-margin-end: 3px;
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
.text-link,
.text-link:focus {
margin: 0px;
padding: 0px;
}
.bottom-link,
.bottom-link:focus {
text-align: center;
margin: 0 40px;
}
@@ -0,0 +1,590 @@
# 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/.
// Services = object with smart getters for common XPCOM services
Components.utils.import("resource://gre/modules/Services.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 if this is an "a#" or "b#" build
let version = Services.appinfo.version;
if (/[ab]\d+$/.test(version)) {
let buildID = Services.appinfo.appBuildID;
let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + "-" + buildID.slice(6,8);
document.getElementById("PMversion").textContent += " (" + buildDate + ")";
}
#ifdef MOZ_UPDATER
gAppUpdater = new appUpdater();
#endif
#ifdef XP_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);
#endif
// get release notes URL from prefs
var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
.getService(Components.interfaces.nsIURLFormatter);
var releaseNotesURL = formatter.formatURLPref("app.releaseNotesURL");
if (releaseNotesURL != "about:blank") {
var relnotes = document.getElementById("releaseNotesURL");
relnotes.setAttribute("href", releaseNotesURL);
}
}
#ifdef MOZ_UPDATER
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
Components.utils.import("resource://gre/modules/AddonManager.jsm");
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()
{
this.updateDeck = document.getElementById("updateDeck");
// Hide the update deck when there is already an update window open to avoid
// syncing issues between them.
if (Services.wm.getMostRecentWindow("Update:Wizard")) {
this.updateDeck.hidden = true;
return;
}
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.bundle = Services.strings.
createBundle("chrome://browser/locale/browser.properties");
this.updateBtn = document.getElementById("updateButton");
// The button label value must be set so its height is correct.
this.setupUpdateButton("update.checkInsideButton");
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.setupUpdateButton("update.restart." +
(this.isMajor ? "upgradeButton" : "updateButton"));
return;
}
if (this.aus.isOtherInstanceHandlingUpdates) {
this.selectPanel("otherInstanceHandlingUpdates");
return;
}
if (this.isDownloading) {
this.startDownload();
return;
}
if (this.updateEnabled && this.updateAuto) {
this.selectPanel("checkingForUpdates");
this.isChecking = true;
this.checker.checkForUpdates(this.updateCheckListener, true);
return;
}
}
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";
}
return this.um.activeUpdate &&
(this.um.activeUpdate.state == "pending" ||
this.um.activeUpdate.state == "pending-service");
},
// 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 the update type is major.
get isMajor() {
if (this.update)
return this.update.type == "major";
return this.um.activeUpdate.type == "major";
},
// 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 deck's selected panel.
*
* @param aChildID
* The id of the deck's child to select.
*/
selectPanel: function(aChildID) {
this.updateDeck.selectedPanel = document.getElementById(aChildID);
this.updateBtn.disabled = (aChildID != "updateButtonBox");
},
/**
* Sets the update button's label and accesskey.
*
* @param aKeyPrefix
* The prefix for the properties file entry to use for setting the
* label and accesskey.
*/
setupUpdateButton: function(aKeyPrefix) {
this.updateBtn.label = this.bundle.GetStringFromName(aKeyPrefix + ".label");
this.updateBtn.accessKey = this.bundle.GetStringFromName(aKeyPrefix + ".accesskey");
if (!document.commandDispatcher.focusedElement ||
document.commandDispatcher.focusedElement == this.updateBtn)
this.updateBtn.focus();
},
/**
* Handles oncommand for the update button.
*/
buttonOnCommand: function() {
if (this.isPending || this.isApplied) {
// 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)
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);
return;
}
const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
// Firefox no longer displays a license for updates and the licenseURL check
// is just in case a distibution does.
if (this.update) {
var ary = null;
ary = Components.classes["@mozilla.org/supports-array;1"].
createInstance(Components.interfaces.nsISupportsArray);
ary.AppendElement(this.update);
var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary);
window.close();
return;
}
this.selectPanel("checkingForUpdates");
this.isChecking = true;
this.checker.checkForUpdates(this.updateCheckListener, true);
},
/**
* 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;
}
gAppUpdater.selectPanel("updateButtonBox");
gAppUpdater.setupUpdateButton("update.openUpdateUI." +
(this.isMajor ? "upgradeButton"
: "applyButton"));
},
/**
* 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;
}
},
/**
* Checks the compatibility of add-ons for the application update.
*/
checkAddonCompatibility: function() {
var self = this;
AddonManager.getAllAddons(function(aAddons) {
self.addons = [];
self.addonsCheckedCount = 0;
aAddons.forEach(function(aAddon) {
// Protect against code that overrides the add-ons manager and doesn't
// implement the isCompatibleWith or the findUpdates method.
if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) {
let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
"or the findUpdates method!";
if (aAddon.id)
errMsg += " Add-on ID: " + aAddon.id;
Components.utils.reportError(errMsg);
return;
}
// If an add-on isn't appDisabled and isn't userDisabled then it is
// either active now or the user expects it to be active after the
// restart. If that is the case and the add-on is not installed by the
// application and is not compatible with the new application version
// then the user should be warned that the add-on will become
// incompatible. If an addon's type equals plugin it is skipped since
// checking plugins compatibility information isn't supported and
// getting the scope property of a plugin breaks in some environments
// (see bug 566787).
try {
if (aAddon.type != "plugin" && aAddon.isCompatible &&
!aAddon.appDisabled && !aAddon.userDisabled &&
aAddon.scope != AddonManager.SCOPE_APPLICATION &&
!aAddon.isCompatibleWith(self.update.appVersion,
self.update.platformVersion))
self.addons.push(aAddon);
}
catch (e) {
Components.utils.reportError(e);
}
});
self.addonsTotalCount = self.addons.length;
if (self.addonsTotalCount == 0) {
self.startDownload();
return;
}
self.checkAddonsForUpdates();
});
},
/**
* Checks if there are updates for add-ons that are incompatible with the
* application update.
*/
checkAddonsForUpdates: function() {
this.addons.forEach(function(aAddon) {
aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED,
this.update.appVersion,
this.update.platformVersion);
}, this);
},
/**
* See XPIProvider.jsm
*/
onCompatibilityUpdateAvailable: function(aAddon) {
for (var i = 0; i < this.addons.length; ++i) {
if (this.addons[i].id == aAddon.id) {
this.addons.splice(i, 1);
break;
}
}
},
/**
* See XPIProvider.jsm
*/
onUpdateAvailable: function(aAddon, aInstall) {
if (!Services.blocklist.isAddonBlocklisted(aAddon.id, aInstall.version,
this.update.appVersion,
this.update.platformVersion)) {
// Compatibility or new version updates mean the same thing here.
this.onCompatibilityUpdateAvailable(aAddon);
}
},
/**
* See XPIProvider.jsm
*/
onUpdateFinished: function(aAddon) {
++this.addonsCheckedCount;
if (this.addonsCheckedCount < this.addonsTotalCount)
return;
if (this.addons.length == 0) {
// Compatibility updates or new version updates were found for all add-ons
this.startDownload();
return;
}
this.selectPanel("updateButtonBox");
this.setupUpdateButton("update.openUpdateUI." +
(this.isMajor ? "upgradeButton" : "applyButton"));
},
/**
* 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 update = this.um.activeUpdate;
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") {
// 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("updateButtonBox");
self.setupUpdateButton("update.restart." +
(self.isMajor ? "upgradeButton" : "updateButton"));
} 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("updateButtonBox");
this.setupUpdateButton("update.restart." +
(this.isMajor ? "upgradeButton" : "updateButton"));
}
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;
}
};
#endif
@@ -0,0 +1,120 @@
<?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="PMaboutDialog"
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"/>
<vbox id="aboutPMDialogContainer">
<hbox id="PMclientBox">
<vbox id="PMleftBox" flex="1"/>
<vbox id="PMrightBox" flex="1">
#ifdef HAVE_64BIT_BUILD
#expand <label id="PMversion">Version: __MOZ_APP_VERSION__ (64-bit)</label>
#else
#expand <label id="PMversion">Version: __MOZ_APP_VERSION__ (32-bit)</label>
#endif
<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="updateButtonBox" align="center">
<button id="updateButton" align="start"
oncommand="gAppUpdater.buttonOnCommand();"/>
<spacer flex="1"/>
</hbox>
<hbox id="checkingForUpdates" align="center">
<image class="update-throbber"/><label>&update.checkingForUpdates;</label>
</hbox>
<hbox id="checkingAddonCompat" align="center">
<image class="update-throbber"/><label>&update.checkingAddonCompat;</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="manualUpdate" align="center">
<label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
</hbox>
</deck>
#endif
</vbox>
<description class="text-pmcreds">
Pale Moon is released by <label class="text-link" href="http://www.moonchildproductions.info">Moonchild Productions</label>.
</description>
<description class="text-pmcreds">
Special thanks to all our supporters and donors for making this browser possible!
</description>
<description class="text-blurb">
If you wish to contribute, please consider helping out by providing support to other users on the <label class="text-link" href="https://forum.palemoon.org/">Pale Moon forum</label>
or getting involved in our development by tackling some of the issues found in our GitHub issue tracker.
</description>
</vbox>
</vbox>
</hbox>
<vbox id="PMbottomBox">
<hbox pack="center">
<label class="text-link bottom-link" href="about:license">Licensing information</label>
<label class="text-link bottom-link" href="about:rights">End-user rights</label>
<label class="text-link bottom-link" id="releaseNotesURL">Release notes</label>
</hbox>
<description id="PMtrademark">&trademarkInfo.part1;</description>
</vbox>
</vbox>
<keyset>
<key keycode="VK_ESCAPE" oncommand="window.close();"/>
</keyset>
#ifdef XP_MACOSX
#include browserMountPoints.inc
#endif
</window>
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -0,0 +1,108 @@
<?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 % netErrorDTD
SYSTEM "chrome://global/locale/netError.dtd">
%netErrorDTD;
<!ENTITY % globalDTD
SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
<!ENTITY % aboutrobotsDTD
SYSTEM "chrome://browser/locale/aboutRobots.dtd">
%aboutrobotsDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&robots.pagetitle;</title>
<link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
<link rel="icon" type="image/png" id="favicon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACGFjVEwAAAASAAAAAJNtBPIAAAAaZmNUTAAAAAAAAAAQAAAAEAAAAAAAAAAALuAD6AABhIDeugAAALhJREFUOI2Nk8sNxCAMRDlGohauXFOMpfTiAlxICqAELltHLqlgctg1InzMRhpFAc%2BLGWTnmoeZYamt78zXdZmaQtQMADlnU0OIAlbmJUBEcO4bRKQY2rUXIPmAGnDuG%2FBx3%2FfvOPVaDUg%2BoAPUf1PArIMCSD5glMEsUGaG%2BkyAFWIBaCsKuA%2BHGCNijLgP133XgOEtaPFMy2vUolEGJoCIzBmoRUR9%2B7rxj16DZaW%2FmgtmxnJ8V3oAnApQwNS5zpcAAAAaZmNUTAAAAAEAAAAQAAAAEAAAAAAAAAAAAB4D6AIB52fclgAAACpmZEFUAAAAAjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9WF%2Bu8QAAABpmY1RMAAAAAwAAABAAAAAQAAAAAAAAAAAAHgPoAgEK8Q9%2FAAAAFmZkQVQAAAAEOI1jYBgFo2AUjAIIAAAEEAAB0xIn4wAAABpmY1RMAAAABQAAABAAAAAQAAAAAAAAAAAAHgPoAgHnO30FAAAAQGZkQVQAAAAGOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVfozYcAAAABpmY1RMAAAABwAAABAAAAAQAAAAAAAAAAAAHgPoAgEKra7sAAAAFmZkQVQAAAAIOI1jYBgFo2AUjAIIAAAEEAABM9s3hAAAABpmY1RMAAAACQAAABAAAAAQAAAAAAAAAAAAHgPoAgHn3p%2BwAAAAKmZkQVQAAAAKOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F1BhPl6AAAAGmZjVEwAAAALAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQpITFkAAAAWZmRBVAAAAAw4jWNgGAWjYBSMAggAAAQQAAHaszpmAAAAGmZjVEwAAAANAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeeCPiMAAABAZmRBVAAAAA44jWNgGJ5gpxrDf2LEcIL%2FpzAVYxPDavP%2FUwz%2FpW79%2F%2F%2F%2FFMP%2FnWoQjC5GOxcgu4QYsVEwCmAAAOE0KxUmBL0KAAAAGmZjVEwAAAAPAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQoU7coAAAAWZmRBVAAAABA4jWNgGAWjYBSMAggAAAQQAAEpOBELAAAAGmZjVEwAAAARAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeYVWtoAAAAqZmRBVAAAABI4jWNgGAVYQXNz839ixHBq3qnG8B9ZAzYx2rlgFIwCcgAA8psX%2FWvpAecAAAAaZmNUTAAAABMAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC4OJMwAAABZmZEFUAAAAFDiNY2AYBaNgFIwCCAAABBAAAcBQHOkAAAAaZmNUTAAAABUAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5kn7SQAAAEBmZEFUAAAAFjiNY2AYnmCnGsN%2FYsRwgv%2BnMBVjE8Nq8%2F9TDP%2Blbv3%2F%2F%2F8Uw%2F%2BdahCMLkY7FyC7hBixUTAKYAAA4TQrFc%2BcEoQAAAAaZmNUTAAAABcAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC98ooAAAABZmZEFUAAAAGDiNY2AYBaNgFIwCCAAABBAAASCZDI4AAAAaZmNUTAAAABkAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5qwZ%2FAAAACpmZEFUAAAAGjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9cjJWbAAAABpmY1RMAAAAGwAAABAAAAAQAAAAAAAAAAAAHgPoAgELOsoVAAAAFmZkQVQAAAAcOI1jYBgFo2AUjAIIAAAEEAAByfEBbAAAABpmY1RMAAAAHQAAABAAAAAQAAAAAAAAAAAAHgPoAgHm8LhvAAAAQGZkQVQAAAAeOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVlxR3%2FgAAABpmY1RMAAAAHwAAABAAAAAQAAAAAAAAAAAAHgPoAgELZmuGAAAAFmZkQVQAAAAgOI1jYBgFo2AUjAIIAAAEEAABHP5cFQAAABpmY1RMAAAAIQAAABAAAAAQAAAAAAAAAAAAHgPoAgHlgtAOAAAAKmZkQVQAAAAiOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F0%2FMvDdAAAAAElFTkSuQmCC"/>
<script type="application/javascript"><![CDATA[
var buttonClicked = false;
function robotButton()
{
var button = document.getElementById('errorTryAgain');
if (buttonClicked) {
button.style.visibility = "hidden";
} else {
var newLabel = button.getAttribute("label2");
button.textContent = newLabel;
buttonClicked = true;
}
}
]]></script>
<style type="text/css"><![CDATA[
#errorPageContainer {
background-image: none;
}
#errorPageContainer:before {
content: url('chrome://browser/content/aboutRobots-icon.png');
position: absolute;
}
body[dir=rtl] #icon,
body[dir=rtl] #errorPageContainer:before {
transform: scaleX(-1);
}
]]></style>
</head>
<body dir="&locale.dir;">
<!-- PAGE CONTAINER (for styling purposes only) -->
<div id="errorPageContainer">
<!-- Error Title -->
<div id="errorTitle">
<h1 id="errorTitleText">&robots.errorTitleText;</h1>
</div>
<!-- LONG CONTENT (the section most likely to require scrolling) -->
<div id="errorLongContent">
<!-- Short Description -->
<div id="errorShortDesc">
<p id="errorShortDescText">&robots.errorShortDescText;</p>
</div>
<!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
<div id="errorLongDesc">
<ul>
<li>&robots.errorLongDesc1;</li>
<li>&robots.errorLongDesc2;</li>
<li>&robots.errorLongDesc3;</li>
<li>&robots.errorLongDesc4;</li>
</ul>
</div>
<!-- Short Description -->
<div id="errorTrailerDesc">
<p id="errorTrailerDescText">&robots.errorTrailerDescText;</p>
</div>
</div>
<!-- Button -->
<button id="errorTryAgain"
label2="&robots.dontpress;"
onclick="robotButton();">&retry.label;</button>
<img src="chrome://browser/content/aboutRobots-widget-left.png"
style="position: absolute; bottom: -12px; left: -10px;"/>
<img src="chrome://browser/content/aboutRobots-widget-left.png"
style="position: absolute; bottom: -12px; right: -10px; transform: scaleX(-1);"/>
</div>
</body>
</html>
@@ -0,0 +1,339 @@
%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%,90%);
color: #000;
height: 100%;
}
body {
margin: 0;
display: -moz-box;
-moz-box-orient: vertical;
width: 100%;
height: 100%;
background-image: url(chrome://browser/content/abouthome/noise.png),
linear-gradient(hsla(0,0%,100%,.7), hsla(0,0%,100%,.4));
}
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;
}
#searchForm {
width: 470px;
}
#searchForm {
display: -moz-box;
}
#searchLogoContainer {
display: -moz-box;
-moz-box-align: center;
padding-top: 2px;
-moz-padding-end: 8px;
}
#searchLogoContainer[hidden] {
display: none;
}
#searchEngineLogo {
display: inline-block;
height: 28px;
width: 70px;
min-width: 70px;
}
#searchText {
-moz-box-flex: 1;
padding: 6px 8px;
background: hsla(0,0%,100%,.9) padding-box;
border: 1px solid;
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);
border-radius: 2.5px 0 0 2.5px;
}
#searchText:-moz-dir(rtl) {
border-radius: 0 2.5px 2.5px 0;
}
#searchText:focus,
#searchText[autofocus] {
border-color: hsla(206,100%,60%,.6) hsla(206,76%,52%,.6) hsla(204,100%,40%,.6);
}
#searchSubmit {
-moz-margin-start: -1px;
background: linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box;
padding: 0 9px;
border: 1px solid;
border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
-moz-border-start: 1px solid transparent;
border-radius: 0 2.5px 2.5px 0;
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;
}
#searchSubmit:-moz-dir(rtl) {
border-radius: 2.5px 0 0 2.5px;
}
#searchText:focus + #searchSubmit,
#searchText + #searchSubmit:hover,
#searchText[autofocus] + #searchSubmit {
border-color: #59b5fc #45a3e7 #3294d5;
color: white;
}
#searchText:focus + #searchSubmit,
#searchText[autofocus] + #searchSubmit {
background-image: 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 + #searchSubmit:hover {
background-image: 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: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: 2.5px;
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");
}
#sync::before {
content: url("chrome://browser/content/abouthome/sync.png");
}
#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;
-moz-margin-end: 8px;
}
#restorePreviousSession:-moz-dir(rtl)::before {
transform: scaleX(-1);
}
body[narrow] #restorePreviousSession::before {
content: url("chrome://browser/content/abouthome/restore.png");
height: 32px;
width: 32px;
}
/* [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 {
transform: scale(.5);
transform-origin: 0 0;
}
#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");
}
#sync::before {
content: url("chrome://browser/content/abouthome/sync@2x.png");
}
#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");
}
}
@@ -0,0 +1,354 @@
/* 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 SEARCH_ENGINES = {
"Google": {
// This is the "2x" image designed for OS X retina resolution, Windows at 192dpi, etc.;
// it will be scaled down as necessary on lower-dpi displays.
image: "data:image/png;base64," +
"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"
},
"DuckDuckGo": {
image: "data:image/png;base64," +
"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"
}
};
// This global tracks if the page has been set up before, to prevent double inits
let gInitialized = false;
let gObserver = new MutationObserver(function (mutations) {
for (let mutation of mutations) {
if (mutation.attributeName == "searchEngineURL") {
setupSearchEngine();
if (!gInitialized) {
gInitialized = true;
}
return;
}
}
});
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 });
fitToWidth();
window.addEventListener("resize", fitToWidth);
});
window.addEventListener("pagehide", function() {
window.gObserver.disconnect();
window.removeEventListener("resize", fitToWidth);
});
function onSearchSubmit(aEvent)
{
let searchTerms = document.getElementById("searchText").value;
let searchURL = document.documentElement.getAttribute("searchEngineURL");
if (searchURL && searchTerms.length > 0) {
// Send an event that a search was performed. This was originally
// added so Firefox Health Report could record that a search from
// about:home had occurred.
let engineName = document.documentElement.getAttribute("searchEngineName");
let event = new CustomEvent("AboutHomeSearchEvent", {detail: engineName});
document.dispatchEvent(event);
const SEARCH_TOKEN = "_searchTerms_";
let searchPostData = document.documentElement.getAttribute("searchEnginePostData");
if (searchPostData) {
// Check if a post form already exists. If so, remove it.
const POST_FORM_NAME = "searchFormPost";
let form = document.forms[POST_FORM_NAME];
if (form) {
form.parentNode.removeChild(form);
}
// Create a new post form.
form = document.body.appendChild(document.createElement("form"));
form.setAttribute("name", POST_FORM_NAME);
// Set the URL to submit the form to.
form.setAttribute("action", searchURL.replace(SEARCH_TOKEN, searchTerms));
form.setAttribute("method", "post");
// Create new <input type=hidden> elements for search param.
searchPostData = searchPostData.split("&");
for (let postVar of searchPostData) {
let [name, value] = postVar.split("=");
if (value == SEARCH_TOKEN) {
value = searchTerms;
}
let input = document.createElement("input");
input.setAttribute("type", "hidden");
input.setAttribute("name", name);
input.setAttribute("value", value);
form.appendChild(input);
}
// Submit the form.
form.submit();
} else {
searchURL = searchURL.replace(SEARCH_TOKEN, encodeURIComponent(searchTerms));
window.location.href = searchURL;
}
}
aEvent.preventDefault();
}
function setupSearchEngine()
{
// 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.
let searchText = document.getElementById("searchText");
searchText.addEventListener("blur", function searchText_onBlur() {
searchText.removeEventListener("blur", searchText_onBlur);
searchText.removeAttribute("autofocus");
});
let searchEngineName = document.documentElement.getAttribute("searchEngineName");
let searchEngineInfo = SEARCH_ENGINES[searchEngineName];
let logoElt = document.getElementById("searchEngineLogo");
// Add search engine logo.
if (searchEngineInfo && searchEngineInfo.image) {
logoElt.parentNode.hidden = false;
logoElt.src = searchEngineInfo.image;
logoElt.alt = searchEngineName;
searchText.placeholder = "";
}
else {
logoElt.parentNode.hidden = true;
searchText.placeholder = searchEngineName;
}
}
function fitToWidth() {
if (window.scrollMaxX) {
document.body.setAttribute("narrow", "true");
} else if (document.body.hasAttribute("narrow")) {
document.body.removeAttribute("narrow");
fitToWidth();
}
}
@@ -0,0 +1,60 @@
<?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/abouthome/aboutHome.css"/>
<script type="text/javascript;version=1.8"
src="chrome://browser/content/abouthome/aboutHome.js"/>
</head>
<body dir="&locale.dir;">
<div class="spacer"/>
<div id="topSection">
<div id="brandLogo"></div>
<div id="searchContainer">
<form name="searchForm" id="searchForm" onsubmit="onSearchSubmit(event)">
<div id="searchLogoContainer"><img id="searchEngineLogo"/></div>
<input type="text" name="q" value="" id="searchText" maxlength="256"
autofocus="autofocus"/>
<input id="searchSubmit" type="submit" value="&abouthome.searchEngineButton.label;"/>
</form>
</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>
<button class="launchButton" id="sync">&abouthome.syncButton.label;</button>
<button class="launchButton" id="settings">&abouthome.settingsButton.label;</button>
<div id="restorePreviousSessionSeparator"/>
<button class="launchButton" id="restorePreviousSession">&historyRestoreLastSession.label;</button>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

@@ -0,0 +1,60 @@
/* 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/. */
/* Auto-recovery module.
* This module aims to catch fatal browser initialization errors and either
* automatically correct likely causes from them, or automatically restarting
* the browser in safe mode. This is hooked into the browser's "onload"
* event because it can be assumed that at that point, everything must
* have been properly initialized already.
*/
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
// Services = object with smart getters for common XPCOM services
Cu.import("resource://gre/modules/Services.jsm");
var browser_autoRecovery =
{
onLoad: function() {
var nsIAS = Ci.nsIAppStartup; // Application startup interface
if (typeof gBrowser === "undefined") {
// gBrowser should always be defined at this point, but if it is not, then most likely
// it is due to an incompatible or outdated language pack being installed and selected.
// In this case, we reset "general.useragent.locale" to try to recover browser startup.
if (Services.prefs.prefHasUserValue("general.useragent.locale")) {
// Restart automatically in en-US.
Services.prefs.clearUserPref("general.useragent.locale");
Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).quit(nsIAS.eRestart | nsIAS.eAttemptQuit);
} else if (!Services.appinfo.inSafeMode) {
// gBrowser isn't defined, and we're not using a custom locale. Most likely
// a user-installed add-on causes issues here, so we restart in Safe Mode.
let RISM = Services.prompt.confirm(null, "Error",
"The Browser didn't start properly!\n"+
"This is usually caused by an add-on or misconfiguration.\n\n"+
"Restart in Safe Mode?");
if (RISM) {
Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).restartInSafeMode(nsIAS.eRestart | nsIAS.eAttemptQuit);
} else {
// Force quit application
Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).quit(nsIAS.eForceQuit);
}
}
// Something else caused this issue and we're already in Safe Mode, so we return
// without doing anything else, and let normal error handling take place.
return;
} // gBrowser undefined
// Other checks than gBrowser undefined can go here!
// Remove our listener, since we don't want this to fire on every load.
window.removeEventListener("load", browser_autoRecovery.onLoad, false);
}
};
window.addEventListener("load", browser_autoRecovery.onLoad, false);
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<overlay
id="autorecovery"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://browser/content/autorecovery.js"/>
<!-- This is an empty overlay to allow separation of the script into its
own context (needed for locale issues preventing browser start) -->
</overlay>
@@ -0,0 +1,100 @@
<?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="&hideThisAppCmdMac.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="&productHelp.label;"
accesskey="&productHelp.accesskey;"
#ifdef XP_MACOSX
key="key_openHelpMac"/>
#else
/>
#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;"
oncommand="restart(true);"/>
<menuseparator id="aboutSeparator"/>
<menuitem id="aboutName"
accesskey="&aboutProduct.accesskey;"
label="&aboutProduct.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="&hideThisAppCmdMac.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>
@@ -0,0 +1,193 @@
<?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://global/skin/netError.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
// 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;
}
/**
* 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()
{
// Handoff to the appropriate initializer, based on error code
switch (getErrorCode()) {
case "malwareBlocked" :
initPage_malware();
break;
case "phishingBlocked" :
initPage_phishing();
break;
}
}
/**
* Initialize custom strings and functionality for blocked malware case
*/
function initPage_malware()
{
// Remove phishing strings
var 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);
// Set sitename
document.getElementById("malware_sitename").textContent = getHostString();
document.title = document.getElementById("errorTitleText_malware")
.innerHTML;
}
/**
* Initialize custom strings and functionality for blocked phishing case
*/
function initPage_phishing()
{
// Remove malware strings
var 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);
// Set sitename
document.getElementById("phishing_sitename").textContent = getHostString();
document.title = document.getElementById("errorTitleText_phishing")
.innerHTML;
}
]]></script>
<style type="text/css">
/* Style warning button to look like a small text link in the
bottom right. This is preferable to just using a text link
since there is already a mechanism in browser.js for trapping
oncommand events from unprivileged chrome pages (BrowserOnCommand).*/
#ignoreWarningButton {
-moz-appearance: none;
background: transparent;
border: none;
color: white; /* Hard coded because netError.css forces this page's background to dark red */
text-decoration: underline;
margin: 0;
padding: 0;
position: relative;
top: 23px;
left: 20px;
font-size: smaller;
}
#ignoreWarning {
text-align: right;
}
</style>
</head>
<body dir="&locale.dir;">
<div id="errorPageContainer">
<!-- Error Title -->
<div id="errorTitle">
<h1 id="errorTitleText_phishing">&safeb.blocked.phishingPage.title;</h1>
<h1 id="errorTitleText_malware">&safeb.blocked.malwarePage.title;</h1>
</div>
<div id="errorLongContent">
<!-- Short Description -->
<div id="errorShortDesc">
<p id="errorShortDescText_phishing">&safeb.blocked.phishingPage.shortDesc;</p>
<p id="errorShortDescText_malware">&safeb.blocked.malwarePage.shortDesc;</p>
</div>
<!-- Long Description -->
<div id="errorLongDesc">
<p id="errorLongDescText_phishing">&safeb.blocked.phishingPage.longDesc;</p>
<p id="errorLongDescText_malware">&safeb.blocked.malwarePage.longDesc;</p>
</div>
<!-- Action buttons -->
<div id="buttons">
<!-- Commands handled in browser.js -->
<button id="getMeOutButton">&safeb.palm.accept.label;</button>
<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>
@@ -0,0 +1,536 @@
# -*- Mode: javascript; 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/.
// 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;
},
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 = {
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("xpinstallPromptWarningOrigin",
[brandShortName]);
let popup = PopupNotifications.show(browser, notificationID,
messageString, anchorID,
null, null, options);
removeNotificationOnEnd(popup, installInfo.installs);
break; }
case "addon-install-blocked":
let originatingHost;
try {
originatingHost = installInfo.originatingURI.host;
} catch (ex) {
// Need to deal with missing originatingURI and with about:/data: URIs more gracefully,
// see bug 1063418 - but for now, bail:
return;
}
messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
[brandShortName, originatingHost]);
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":
var 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("addonDownloading");
messageString = PluralForm.get(installInfo.installs.length, messageString);
options.installs = installInfo.installs;
options.contentWindow = browser.contentWindow;
options.sourceURI = browser.currentURI;
options.eventCallback = function(aEvent) {
if (aEvent != "removed")
return;
options.contentWindow = null;
options.sourceURI = null;
};
PopupNotifications.show(browser, notificationID, messageString, anchorID,
null, null, options);
break;
case "addon-install-failed":
// TODO This isn't terribly ideal for the multiple failure case
for (let install of installInfo.installs) {
let host = (installInfo.originatingURI instanceof Ci.nsIStandardURL) &&
installInfo.originatingURI.host;
if (!host)
host = (install.sourceURI instanceof Ci.nsIStandardURL) &&
install.sourceURI.host;
let error = (host || install.error == 0) ? "addonError" : "addonLocalError";
if (install.error != 0)
error += install.error;
else if (install.addon.jetsdk)
error += "JetSDK";
else if (install.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
error += "Blocklisted";
else
error += "Incompatible";
messageString = gNavigatorBundle.getString(error);
messageString = messageString.replace("#1", install.name);
if (host)
messageString = messageString.replace("#2", host);
messageString = messageString.replace("#3", brandShortName);
messageString = messageString.replace("#4", Services.appinfo.version);
PopupNotifications.show(browser, notificationID, messageString, anchorID,
action, null, options);
}
break;
case "addon-install-complete":
var needsRestart = installInfo.installs.some(function(i) {
return i.addon.pendingOperations != AddonManager.PENDING_NONE;
});
if (needsRestart) {
messageString = gNavigatorBundle.getString("addonsInstalledNeedsRestart");
action = {
label: gNavigatorBundle.getString("addonInstallRestartButton"),
accessKey: gNavigatorBundle.getString("addonInstallRestartButton.accesskey"),
callback: function() {
Application.restart();
}
};
}
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;
}
}
};
/*
* When addons are installed/uninstalled, check and see if the number of items
* on the add-on bar changed:
* - If an add-on was installed, incrementing the count, show the bar.
* - If an add-on was uninstalled, and no more items are left, hide the bar.
*/
let AddonsMgrListener = {
get addonBar() document.getElementById("addon-bar"),
get statusBar() document.getElementById("status-bar"),
getAddonBarItemCount: function() {
// Take into account the contents of the status bar shim for the count.
var itemCount = this.statusBar.childNodes.length;
var defaultOrNoninteractive = this.addonBar.getAttribute("defaultset")
.split(",")
.concat(["separator", "spacer", "spring"]);
for (let item of this.addonBar.currentSet.split(",")) {
if (defaultOrNoninteractive.indexOf(item) == -1)
itemCount++;
}
return itemCount;
},
onInstalling: function(aAddon) {
this.lastAddonBarCount = this.getAddonBarItemCount();
},
onInstalled: function(aAddon) {
if (this.getAddonBarItemCount() > this.lastAddonBarCount)
setToolbarVisibility(this.addonBar, true);
},
onUninstalling: function(aAddon) {
this.lastAddonBarCount = this.getAddonBarItemCount();
},
onUninstalled: function(aAddon) {
if (this.getAddonBarItemCount() == 0)
setToolbarVisibility(this.addonBar, false);
},
onEnabling: function(aAddon) this.onInstalling(),
onEnabled: function(aAddon) this.onInstalled(),
onDisabling: function(aAddon) this.onUninstalling(),
onDisabled: function(aAddon) this.onUninstalled(),
};
var LightWeightThemeWebInstaller = {
handleEvent: function (event) {
switch (event.type) {
case "InstallBrowserTheme":
case "PreviewBrowserTheme":
case "ResetBrowserThemePreview":
// ignore requests from background tabs
if (event.target.ownerDocument.defaultView.top != content)
return;
}
switch (event.type) {
case "InstallBrowserTheme":
this._installRequest(event);
break;
case "PreviewBrowserTheme":
this._preview(event);
break;
case "ResetBrowserThemePreview":
this._resetPreview(event);
break;
case "pagehide":
case "TabSelect":
this._resetPreview();
break;
}
},
get _manager () {
var temp = {};
Cu.import("resource://gre/modules/LightweightThemeManager.jsm", temp);
delete this._manager;
return this._manager = temp.LightweightThemeManager;
},
_installRequest: function (event) {
var node = event.target;
var data = this._getThemeFromNode(node);
if (!data)
return;
if (this._isAllowed(node)) {
this._install(data);
return;
}
var allowButtonText =
gNavigatorBundle.getString("lwthemeInstallRequest.allowButton");
var allowButtonAccesskey =
gNavigatorBundle.getString("lwthemeInstallRequest.allowButton.accesskey");
var message =
gNavigatorBundle.getFormattedString("lwthemeInstallRequest.message",
[node.ownerDocument.location.host]);
var buttons = [{
label: allowButtonText,
accessKey: allowButtonAccesskey,
callback: function () {
LightWeightThemeWebInstaller._install(data);
}
}];
this._removePreviousNotifications();
var notificationBox = gBrowser.getNotificationBox();
var notificationBar =
notificationBox.appendNotification(message, "lwtheme-install-request", "",
notificationBox.PRIORITY_INFO_MEDIUM,
buttons);
notificationBar.persistence = 1;
},
_install: function (newLWTheme) {
var previousLWTheme = this._manager.currentTheme;
var 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 () {
Application.restart();
}
};
let options = {
timeout: Date.now() + 30000
};
PopupNotifications.show(gBrowser.selectedBrowser, "addon-theme-change",
messageString, "addons-notification-icon",
action, null, options);
},
onEnabled: function(aAddon) {
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);
}
var 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();
var notificationBox = gBrowser.getNotificationBox();
var 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 () {
var box = gBrowser.getNotificationBox();
["lwtheme-install-request",
"lwtheme-install-notification"].forEach(function (value) {
var notification = box.getNotificationWithValue(value);
if (notification)
box.removeNotification(notification);
});
},
_previewWindow: null,
_preview: function (event) {
if (!this._isAllowed(event.target))
return;
var data = this._getThemeFromNode(event.target);
if (!data)
return;
this._resetPreview();
this._previewWindow = event.target.ownerDocument.defaultView;
this._previewWindow.addEventListener("pagehide", this, true);
gBrowser.tabContainer.addEventListener("TabSelect", this, false);
this._manager.previewTheme(data);
},
_resetPreview: function (event) {
if (!this._previewWindow ||
event && !this._isAllowed(event.target))
return;
this._previewWindow.removeEventListener("pagehide", this, true);
this._previewWindow = null;
gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
this._manager.resetPreview();
},
_isAllowed: function (node) {
var pm = Services.perms;
var uri = node.ownerDocument.documentURIObject;
return pm.testPermission(uri, "install") == pm.ALLOW_ACTION;
},
_getThemeFromNode: function (node) {
return this._manager.parseTheme(node.getAttribute("data-browsertheme"),
node.baseURI);
}
}
/*
* Listen for Lightweight Theme styling changes and update the browser's theme accordingly.
*/
let 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;
}
});
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 + ")");
},
};
@@ -0,0 +1,394 @@
# -*- 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/.
<menupopup id="appmenu-popup"
onpopupshowing="if (event.target == this) {
updateEditUIVisibility();
#ifdef MOZ_SERVICES_SYNC
gSyncUI.updateUI();
#endif
return;
}
updateCharacterEncodingMenuState();
if (event.target.parentNode.parentNode.parentNode.parentNode == this)
this._currentPopup = event.target;">
<hbox>
<vbox id="appmenuPrimaryPane">
<menuitem id="appmenu_newTab_popup"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"/>
<menuitem id="appmenu_newNavigator"
label="&newNavigatorCmd.label;"
command="cmd_newNavigator"
key="key_newNavigator"/>
<menuitem id="appmenu_newPrivateWindow"
class="menuitem-iconic menuitem-iconic-tooltip"
label="&newPrivateWindow.label;"
command="Tools:PrivateBrowsing"
key="key_privatebrowsing"/>
<menuitem label="&goOfflineCmd.label;"
id="appmenu_offlineModeRecovery"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
<menuseparator class="appmenu-menuseparator"/>
<hbox>
<menuitem id="appmenu-edit-label"
label="&appMenuEdit.label;"
disabled="true"/>
<toolbarbutton id="appmenu-cut"
class="appmenu-edit-button"
command="cmd_cut"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&cutButton.tooltip;"/>
<toolbarbutton id="appmenu-copy"
class="appmenu-edit-button"
command="cmd_copy"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&copyButton.tooltip;"/>
<toolbarbutton id="appmenu-paste"
class="appmenu-edit-button"
command="cmd_paste"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&pasteButton.tooltip;"/>
<spacer flex="1"/>
<menu id="appmenu-editmenu">
<menupopup id="appmenu-editmenu-menupopup">
<menuitem id="appmenu-editmenu-cut"
class="menuitem-iconic"
label="&cutCmd.label;"
key="key_cut"
command="cmd_cut"/>
<menuitem id="appmenu-editmenu-copy"
class="menuitem-iconic"
label="&copyCmd.label;"
key="key_copy"
command="cmd_copy"/>
<menuitem id="appmenu-editmenu-paste"
class="menuitem-iconic"
label="&pasteCmd.label;"
key="key_paste"
command="cmd_paste"/>
<menuseparator/>
<menuitem id="appmenu-editmenu-undo"
label="&undoCmd.label;"
key="key_undo"
command="cmd_undo"/>
<menuitem id="appmenu-editmenu-redo"
label="&redoCmd.label;"
key="key_redo"
command="cmd_redo"/>
<menuseparator/>
<menuitem id="appmenu-editmenu-selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
command="cmd_selectAll"/>
<menuseparator/>
<menuitem id="appmenu-editmenu-delete"
label="&deleteCmd.label;"
key="key_delete"
command="cmd_delete"/>
</menupopup>
</menu>
</hbox>
<menuitem id="appmenu_find"
class="menuitem-tooltip"
label="&appMenuFind.label;"
command="cmd_find"
key="key_find"/>
<menuseparator class="appmenu-menuseparator"/>
<menuitem id="appmenu_openFile"
label="&openFileCmd.label;"
command="Browser:OpenFile"
key="openFileKb"/>
<menuitem id="appmenu_savePage"
class="menuitem-tooltip"
label="&savePageCmd.label;"
command="Browser:SavePage"
key="key_savePage"/>
<menuitem id="appmenu_sendLink"
label="&emailPageCmd.label;"
command="Browser:SendLink"/>
<splitmenu id="appmenu_print"
iconic="true"
label="&printCmd.label;"
command="cmd_print">
<menupopup>
<menuitem id="appmenu_print_popup"
class="menuitem-iconic"
label="&printCmd.label;"
command="cmd_print"
key="printKb"/>
<menuitem id="appmenu_printPreview"
label="&printPreviewCmd.label;"
command="cmd_printPreview"/>
<menuitem id="appmenu_printSetup"
label="&printSetupCmd.label;"
command="cmd_pageSetup"/>
</menupopup>
</splitmenu>
<menuseparator class="appmenu-menuseparator"/>
<splitmenu id="appmenu_webDeveloper"
command="Tools:DevToolbox"
label="&appMenuWebDeveloper.label;">
<menupopup id="appmenu_webDeveloper_popup">
#ifdef MOZ_DEVTOOLS
<menuitem id="appmenu_devToolbox"
observes="devtoolsMenuBroadcaster_DevToolbox"/>
<menuseparator id="appmenu_devtools_separator"/>
<menuitem id="appmenu_devToolbar"
observes="devtoolsMenuBroadcaster_DevToolbar"/>
<menuitem id="appmenu_chromeDebugger"
observes="devtoolsMenuBroadcaster_ChromeDebugger"/>
<menuitem id="appmenu_browserConsole"
observes="devtoolsMenuBroadcaster_BrowserConsole"/>
<menuitem id="appmenu_responsiveUI"
observes="devtoolsMenuBroadcaster_ResponsiveUI"/>
<menuitem id="appmenu_eyedropper"
observes="devtoolsMenuBroadcaster_Eyedropper"/>
<menuitem id="appmenu_scratchpad"
observes="devtoolsMenuBroadcaster_Scratchpad"/>
#endif
<menuitem id="appmenu_pageSource"
observes="devtoolsMenuBroadcaster_PageSource"/>
<menuitem id="appmenu_errorConsole"
observes="devtoolsMenuBroadcaster_ErrorConsole"/>
#ifdef MOZ_DEVTOOLS
<menuitem id="appmenu_devtools_connect"
observes="devtoolsMenuBroadcaster_connect"/>
#endif
<menuseparator id="appmenu_devToolsEndSeparator"/>
<menuitem id="appmenu_getMoreDevtools"
observes="devtoolsMenuBroadcaster_GetMoreTools"/>
<menuseparator/>
#define ID_PREFIX appmenu_developer_
#define OMIT_ACCESSKEYS
#include browser-charsetmenu.inc
#undef ID_PREFIX
#undef OMIT_ACCESSKEYS
<menuitem label="&goOfflineCmd.label;"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
</menupopup>
</splitmenu>
<menuseparator class="appmenu-menuseparator"/>
#define ID_PREFIX appmenu_
#define OMIT_ACCESSKEYS
#include browser-charsetmenu.inc
#undef ID_PREFIX
#undef OMIT_ACCESSKEYS
<menuitem id="appmenu_fullScreen"
class="menuitem-tooltip"
label="&fullScreenCmd.label;"
type="checkbox"
observes="View:FullScreen"
key="key_fullScreen"/>
<menuitem id="appmenu_restart"
class="menuitem-iconic"
label="&appMenuRestart.label;"
command="cmd_restartApplication"/>
<menuitem id="appmenu-quit"
class="menuitem-iconic"
#ifdef XP_WIN
label="&quitApplicationCmdWin.label;"
#else
label="&quitApplicationCmd.label;"
#endif
command="cmd_quitApplication"/>
</vbox>
<vbox id="appmenuSecondaryPane">
<splitmenu id="appmenu_bookmarks"
iconic="true"
label="&bookmarksMenu.label;"
command="Browser:ShowAllBookmarks">
<menupopup id="appmenu_bookmarksPopup"
placespopup="true"
context="placesContext"
openInTabs="children"
oncommand="BookmarksEventHandler.onCommand(event, this.parentNode._placesView);"
onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
onpopupshowing="BookmarkingUI.onPopupShowing(event);
if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="appmenu_showAllBookmarks"
class="menuitem-iconic"
label="&organizeBookmarks.label;"
command="Browser:ShowAllBookmarks"
context=""
key="manBookmarkKb"/>
<menuseparator/>
<menuitem id="appmenu_bookmarkThisPage"
class="menuitem-iconic"
label="&bookmarkThisPageCmd.label;"
command="Browser:AddBookmarkAs"
key="addBookmarkAsKb"/>
<menuitem id="appmenu_subscribeToPage"
class="menuitem-iconic"
label="&subscribeToPageMenuitem.label;"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"
observes="singleFeedMenuitemState"/>
<menu id="appmenu_subscribeToPageMenu"
class="menu-iconic"
label="&subscribeToPageMenupopup.label;"
observes="multipleFeedsMenuState">
<menupopup id="appmenu_subscribeToPageMenupopup"
onpopupshowing="return FeedHandler.buildFeedList(event.target);"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"/>
</menu>
<menuseparator/>
<menu id="appmenu_bookmarksToolbar"
placesanonid="toolbar-autohide"
class="menu-iconic bookmark-item"
label="&personalbarCmd.label;"
container="true">
<menupopup id="appmenu_bookmarksToolbarPopup"
placespopup="true"
context="placesContext"
onpopupshowing="if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
</menu>
<menuseparator/>
<!-- Bookmarks menu items -->
<menuseparator builder="end"
class="hide-if-empty-places-result"/>
<menuitem id="appmenu_unsortedBookmarks"
class="menuitem-iconic"
label="&appMenuUnsorted.label;"
oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"/>
</menupopup>
</splitmenu>
<splitmenu id="appmenu_history"
iconic="true"
label="&historyMenu.label;"
command="Browser:ShowAllHistory">
<menupopup id="appmenu_historyMenupopup"
placespopup="true"
context="placesContext"
oncommand="this.parentNode._placesView._onCommand(event);"
onclick="checkForMiddleClick(this, event);"
onpopupshowing="if (!this.parentNode._placesView)
new HistoryMenu(event);"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="appmenu_showAllHistory"
class="menuitem-iconic"
label="&showAllHistoryCmd2.label;"
command="Browser:ShowAllHistory"
key="showAllHistoryKb"/>
<menuseparator/>
<menuitem id="appmenu_sanitizeHistory"
class="menuitem-iconic"
label="&clearRecentHistory.label;"
key="key_sanitize"
command="Tools:Sanitize"/>
<menuseparator class="hide-if-empty-places-result"/>
#ifdef MOZ_SERVICES_SYNC
<menuitem id="appmenu_sync-tabs"
class="syncTabsMenuItem"
label="&syncTabsMenu2.label;"
oncommand="BrowserOpenSyncTabs();"
disabled="true"/>
#endif
<menuitem id="appmenu_restoreLastSession"
label="&historyRestoreLastSession.label;"
command="Browser:RestoreLastSession"/>
<menu id="appmenu_recentlyClosedTabsMenu"
class="recentlyClosedTabsMenu"
label="&historyUndoMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedTabsMenupopup"
onpopupshowing="document.getElementById('appmenu_history')._placesView.populateUndoSubmenu();"/>
</menu>
<menu id="appmenu_recentlyClosedWindowsMenu"
class="recentlyClosedWindowsMenu"
label="&historyUndoWindowMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedWindowsMenupopup"
onpopupshowing="document.getElementById('appmenu_history')._placesView.populateUndoWindowSubmenu();"/>
</menu>
<menuseparator/>
</menupopup>
</splitmenu>
<menuitem id="appmenu_downloads"
class="menuitem-tooltip"
label="&downloads.label;"
command="Tools:Downloads"
key="key_openDownloads"/>
<spacer id="appmenuSecondaryPane-spacer"/>
<menuitem id="appmenu_addons"
class="menuitem-iconic menuitem-iconic-tooltip"
label="&addons.label;"
command="Tools:Addons"
key="key_openAddons"/>
<menuitem id="appmenu_permissions"
class="menuitem-iconic"
label="&permissions.label;"
command="Tools:Permissions"
key="key_openPermissions"/>
#ifdef MOZ_SERVICES_SYNC
<!-- only one of sync-setup or sync-syncnow will be showing at once -->
<menuitem id="sync-setup-appmenu"
label="&syncSetup.label;"
observes="sync-setup-state"
oncommand="gSyncUI.openSetup()"/>
<menuitem id="sync-syncnowitem-appmenu"
label="&syncSyncNowItem.label;"
observes="sync-syncnow-state"
oncommand="gSyncUI.doSync(event);"/>
#endif
<splitmenu id="appmenu_customize"
label="&preferencesCmd2.label;"
oncommand="openPreferences();">
<menupopup id="appmenu_customizeMenu"
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
<menuitem id="appmenu_preferences"
label="&preferencesCmd2.label;"
oncommand="openPreferences();"/>
<menuseparator/>
<menuseparator id="appmenu_toggleToolbarsSeparator"/>
<menuitem id="appmenu_toggleTabsOnTop"
label="&viewTabsOnTop.label;"
type="checkbox"
command="cmd_ToggleTabsOnTop"/>
<menuitem id="appmenu_toolbarLayout"
label="&appMenuToolbarLayout.label;"
command="cmd_CustomizeToolbars"/>
</menupopup>
</splitmenu>
<splitmenu id="appmenu_help"
label="&helpMenu.label;"
oncommand="openHelpLink('firefox-help')">
<menupopup id="appmenu_helpMenupopup">
<menuitem id="appmenu_openHelp"
label="&helpMenu.label;"
oncommand="openHelpLink('firefox-help')"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="appmenu_troubleshootingInfo"
label="&helpTroubleshootingInfo.label;"
oncommand="openTroubleshootingPage()"
onclick="checkForMiddleClick(this,event);"/>
<menuitem id="appmenu_feedbackPage"
label="&helpFeedbackPage.label;"
oncommand="openFeedbackPage()"
onclick="checkForMiddleClick(this, event);"/>
<menuseparator/>
<menuitem id="appmenu_safeMode"
label="&appMenuSafeMode.label;"
oncommand="restart(true);"/>
<menuseparator/>
<menuitem id="appmenu_about"
label="&aboutProduct.label;"
oncommand="openAboutDialog();"/>
</menupopup>
</splitmenu>
</vbox>
</hbox>
</menupopup>
@@ -0,0 +1,62 @@
# 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
#expand <menu id="__ID_PREFIX__charsetMenu"
label="&charsetMenu.label;"
#ifndef OMIT_ACCESSKEYS
accesskey="&charsetMenu.accesskey;"
#endif
oncommand="MultiplexHandler(event)"
#ifdef OMIT_ACCESSKEYS
#expand onpopupshowing="CharsetMenu.build(event, '__ID_PREFIX__');"
#else
#expand onpopupshowing="CharsetMenu.build(event, '__ID_PREFIX__', true);"
#endif
onpopupshown="UpdateMenus(event);">
<menupopup>
<menu label="&charsetMenuAutodet.label;"
#ifndef OMIT_ACCESSKEYS
accesskey="&charsetMenuAutodet.accesskey;"
#endif
>
<menupopup>
<menuitem type="radio"
name="detectorGroup"
#expand id="__ID_PREFIX__chardet.off"
label="&charsetMenuAutodet.off.label;"
#ifndef OMIT_ACCESSKEYS
accesskey="&charsetMenuAutodet.off.accesskey;"
#endif
/>
<menuitem type="radio"
name="detectorGroup"
#expand id="__ID_PREFIX__chardet.ja_parallel_state_machine"
label="&charsetMenuAutodet.ja.label;"
#ifndef OMIT_ACCESSKEYS
accesskey="&charsetMenuAutodet.ja.accesskey;"
#endif
/>
<menuitem type="radio"
name="detectorGroup"
#expand id="__ID_PREFIX__chardet.ruprob"
label="&charsetMenuAutodet.ru.label;"
#ifndef OMIT_ACCESSKEYS
accesskey="&charsetMenuAutodet.ru.accesskey;"
#endif
/>
<menuitem type="radio"
name="detectorGroup"
#expand id="__ID_PREFIX__chardet.ukprob"
label="&charsetMenuAutodet.uk.label;"
#ifndef OMIT_ACCESSKEYS
accesskey="&charsetMenuAutodet.uk.accesskey;"
#endif
/>
</menupopup>
</menu>
<menuseparator/>
</menupopup>
</menu>
@@ -0,0 +1,379 @@
# -*- 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/.
<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-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();"/>
<menuitem id="context-openlinkincurrent"
label="&openLinkCmdInCurrent.label;"
accesskey="&openLinkCmdInCurrent.accesskey;"
oncommand="gContextMenu.openLinkInCurrent();"/>
<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-sendlink"
label="&sendLinkCmd.label;"
accesskey="&sendLinkCmd.accesskey;"
oncommand="gContextMenu.sendLink();"/>
<menuitem id="context-copyemail"
label="&copyEmailCmd.label;"
accesskey="&copyEmailCmd.accesskey;"
oncommand="gContextMenu.copyEmail();"/>
<menuitem id="context-copylink"
label="&copyLinkCmd.label;"
accesskey="&copyLinkCmd.accesskey;"
oncommand="goDoCommand('cmd_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="&mediaPlaybackRate.label;" accesskey="&mediaPlaybackRate.accesskey;">
<menupopup>
<menuitem id="context-media-playbackrate-050x"
label="&mediaPlaybackRate050x.label;"
accesskey="&mediaPlaybackRate050x.accesskey;"
type="radio"
name="playbackrate"
oncommand="gContextMenu.mediaCommand('playbackRate', 0.5);"/>
<menuitem id="context-media-playbackrate-100x"
label="&mediaPlaybackRate100x.label;"
accesskey="&mediaPlaybackRate100x.accesskey;"
type="radio"
name="playbackrate"
checked="true"
oncommand="gContextMenu.mediaCommand('playbackRate', 1.0);"/>
<menuitem id="context-media-playbackrate-150x"
label="&mediaPlaybackRate150x.label;"
accesskey="&mediaPlaybackRate150x.accesskey;"
type="radio"
name="playbackrate"
oncommand="gContextMenu.mediaCommand('playbackRate', 1.5);"/>
<menuitem id="context-media-playbackrate-200x"
label="&mediaPlaybackRate200x.label;"
accesskey="&mediaPlaybackRate200x.accesskey;"
type="radio"
name="playbackrate"
oncommand="gContextMenu.mediaCommand('playbackRate', 2.0);"/>
</menupopup>
</menu>
<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-showstats"
accesskey="&videoShowStats.accesskey;"
label="&videoShowStats.label;"
oncommand="gContextMenu.mediaCommand('showstats');"/>
<menuitem id="context-video-hidestats"
accesskey="&videoHideStats.accesskey;"
label="&videoHideStats.label;"
oncommand="gContextMenu.mediaCommand('hidestats');"/>
<menuitem id="context-video-fullscreen"
accesskey="&videoFullScreen.accesskey;"
label="&videoFullScreen.label;"
oncommand="gContextMenu.fullScreenVideo();"/>
<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-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();"/>
<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-back"
label="&backCmd.label;"
accesskey="&backCmd.accesskey;"
command="Browser:BackOrBackDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-forward"
label="&forwardCmd.label;"
accesskey="&forwardCmd.accesskey;"
command="Browser:ForwardOrForwardDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-reload"
label="&reloadCmd.label;"
accesskey="&reloadCmd.accesskey;"
oncommand="gContextMenu.reload(event);"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-stop"
label="&stopCmd.label;"
accesskey="&stopCmd.accesskey;"
command="Browser:Stop"/>
<menuseparator id="context-sep-stop"/>
<menuitem id="context-bookmarkpage"
label="&bookmarkPageCmd2.label;"
accesskey="&bookmarkPageCmd2.accesskey;"
oncommand="gContextMenu.bookmarkThisPage();"/>
<menuitem id="context-savepage"
label="&savePageCmd.label;"
accesskey="&savePageCmd.accesskey2;"
oncommand="gContextMenu.savePageAs();"/>
<menuitem id="context-sendpage"
label="&sendPageCmd.label;"
accesskey="&sendPageCmd.accesskey;"
oncommand="gContextMenu.sendPage();"/>
<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="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="BrowserViewSourceOfDocument(gContextMenu.browser.contentDocument);"
observes="isImage"/>
<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();"/>
<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();"/>
#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
@@ -0,0 +1,19 @@
<!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://browser/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;
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
%aboutHomeDTD;
]>
@@ -0,0 +1,224 @@
# -*- Mode: javascript; 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/.
/**
* The Feed Handler object manages discovery of RSS/ATOM feeds in web pages
* and shows UI when they are discovered.
*/
var FeedHandler = {
/* Pale Moon: Address Bar: Feeds
* The click handler for the Feed icon in the location bar. Opens the
* subscription page if user is not given a choice of feeds.
* (Otherwise the list of available feeds will be presented to the
* user in a popup menu.)
*/
onFeedButtonPMClick: function(event) {
event.stopPropagation();
if (event.target.hasAttribute("feed") &&
event.eventPhase == Event.AT_TARGET &&
(event.button == 0 || event.button == 1)) {
this.subscribeToFeed(null, event);
}
},
/**
* The click handler for the Feed icon in the toolbar. Opens the
* subscription page if user is not given a choice of feeds.
* (Otherwise the list of available feeds will be presented to the
* user in a popup menu.)
*/
onFeedButtonClick: function(event) {
event.stopPropagation();
let feeds = gBrowser.selectedBrowser.feeds || [];
// If there are multiple feeds, the menu will open, so no need to do
// anything. If there are no feeds, nothing to do either.
if (feeds.length != 1)
return;
if (event.eventPhase == Event.AT_TARGET &&
(event.button == 0 || event.button == 1)) {
this.subscribeToFeed(feeds[0].href, event);
}
},
/** Called when the user clicks on the Subscribe to This Page... menu item.
* 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 menuPopup
* The feed list menupopup to be populated.
* @returns true if the menu 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).
*/
buildFeedList: function(menuPopup) {
var feeds = gBrowser.selectedBrowser.feeds;
if (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.
menuPopup.parentNode.removeAttribute("open");
return false;
}
while (menuPopup.firstChild)
menuPopup.removeChild(menuPopup.firstChild);
if (feeds.length == 1) {
var feedButtonPM = document.getElementById("ub-feed-button");
if (feedButtonPM)
feedButtonPM.setAttribute("feed", feeds[0].href);
return false;
}
if (feeds.length <= 1)
return false;
// Build the menu showing the available feed choices for viewing.
for (let feedInfo of feeds) {
var menuItem = document.createElement("menuitem");
var baseTitle = feedInfo.title || feedInfo.href;
var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
menuItem.setAttribute("class", "feed-menuitem");
menuItem.setAttribute("label", labelStr);
menuItem.setAttribute("feed", feedInfo.href);
menuItem.setAttribute("tooltiptext", feedInfo.href);
menuItem.setAttribute("crop", "center");
menuPopup.appendChild(menuItem);
}
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
* 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: function(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);
var 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: function(href, event) {
var 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: function() {
if (this._updateFeedTimeout)
clearTimeout(this._updateFeedTimeout);
var feeds = gBrowser.selectedBrowser.feeds;
var haveFeeds = feeds && feeds.length > 0;
var feedButtonPM = document.getElementById("ub-feed-button");
var feedButton = document.getElementById("feed-button");
if (feedButton)
feedButton.disabled = !haveFeeds;
if (feedButtonPM) {
if (!haveFeeds) {
feedButtonPM.collapsed = true;
feedButtonPM.removeAttribute("feed");
} else {
feedButtonPM.collapsed = !gPrefService.getBoolPref("browser.urlbar.rss");
}
}
if (!haveFeeds) {
this._feedMenuitem.setAttribute("disabled", "true");
this._feedMenuitem.removeAttribute("hidden");
this._feedMenupopup.setAttribute("hidden", "true");
return;
}
if (feeds.length > 1) {
if (feedButtonPM)
feedButtonPM.removeAttribute("feed");
this._feedMenuitem.setAttribute("hidden", "true");
this._feedMenupopup.removeAttribute("hidden");
} else {
if (feedButtonPM)
feedButtonPM.setAttribute("feed", feeds[0].href);
this._feedMenuitem.setAttribute("feed", feeds[0].href);
this._feedMenuitem.removeAttribute("disabled");
this._feedMenuitem.removeAttribute("hidden");
this._feedMenupopup.setAttribute("hidden", "true");
}
},
addFeed: function(link, targetDoc) {
// find which tab this is for, and set the attribute on the browser
var browserForLink = gBrowser.getBrowserForDocument(targetDoc);
if (!browserForLink) {
// ignore feeds loaded in subframes (see bug 305472)
return;
}
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) {
var feedButtonPM = document.getElementById("ub-feed-button");
if (feedButtonPM)
feedButtonPM.collapsed = !gPrefService.getBoolPref("browser.urlbar.rss");
// 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);
}
}
};
@@ -0,0 +1,607 @@
# -*- Mode: javascript; 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/.
var FullScreen = {
_XULNS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
get _fullScrToggler() {
delete this._fullScrToggler;
return this._fullScrToggler = document.getElementById("fullscr-toggler");
},
toggle: function (event) {
var enterFS = window.fullScreen;
// We get the fullscreen event _before_ the window transitions into or out of FS mode.
if (event && event.type == "fullscreen")
enterFS = !enterFS;
// Toggle the View:FullScreen command, which controls elements like the
// fullscreen menuitem, menubars, and the appmenu.
let fullscreenCommand = document.getElementById("View:FullScreen");
if (enterFS) {
fullscreenCommand.setAttribute("checked", enterFS);
} else {
fullscreenCommand.removeAttribute("checked");
}
#ifdef XP_MACOSX
// Make sure the menu items are adjusted.
document.getElementById("enterFullScreenItem").hidden = enterFS;
document.getElementById("exitFullScreenItem").hidden = !enterFS;
#endif
// On OS X Lion we don't want to hide toolbars when entering fullscreen, unless
// we're entering DOM fullscreen, in which case we should hide the toolbars.
// If we're leaving fullscreen, then we'll go through the exit code below to
// make sure toolbars are made visible in the case of DOM fullscreen.
if (enterFS && this.useLionFullScreen) {
if (document.mozFullScreen) {
this.showXULChrome("toolbar", false);
}
else {
gNavToolbox.setAttribute("inFullscreen", true);
document.documentElement.setAttribute("inFullscreen", true);
}
return;
}
// show/hide menubars, toolbars (except the full screen toolbar)
this.showXULChrome("toolbar", !enterFS);
if (enterFS) {
// Add a tiny toolbar to receive mouseover and dragenter events, and provide affordance.
// This will help simulate the "collapse" metaphor while also requiring less code and
// events than raw listening of mouse coords. We don't add the toolbar in DOM full-screen
// mode, only browser full-screen mode.
if (!document.mozFullScreen) {
this._fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
this._fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
}
if (gPrefService.getBoolPref("browser.fullscreen.autohide"))
gBrowser.mPanelContainer.addEventListener("mousemove",
this._collapseCallback, false);
document.addEventListener("keypress", this._keyToggleCallback, false);
document.addEventListener("popupshown", this._setPopupOpen, false);
document.addEventListener("popuphidden", this._setPopupOpen, false);
// We don't animate the toolbar collapse if in DOM full-screen mode,
// as the size of the content area would still be changing after the
// mozfullscreenchange event fired, which could confuse content script.
this._shouldAnimate = !document.mozFullScreen;
this.mouseoverToggle(false);
// Autohide prefs
gPrefService.addObserver("browser.fullscreen", this, false);
}
else {
// The user may quit fullscreen during an animation
this._cancelAnimation();
gNavToolbox.style.marginTop = "";
if (this._isChromeCollapsed)
this.mouseoverToggle(true);
// This is needed if they use the context menu to quit fullscreen
this._isPopupOpen = false;
document.documentElement.removeAttribute("inDOMFullscreen");
this.cleanup();
}
},
exitDomFullScreen : function() {
document.mozCancelFullScreen();
},
handleEvent: function (event) {
switch (event.type) {
case "activate":
if (document.mozFullScreen) {
this.showWarning(this.fullscreenDoc);
}
break;
case "transitionend":
if (event.propertyName == "opacity")
this.cancelWarning();
break;
}
},
enterDomFullscreen : function(event) {
if (!document.mozFullScreen)
return;
// However, if we receive a "MozEnteredDomFullScreen" event for a document
// which is not a subdocument of a currently active (ie. visible) browser
// or iframe, we know that we've switched to a different frame since the
// request to enter full-screen was made, so we should exit full-screen
// since the "full-screen document" isn't acutally visible.
if (!event.target.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell).isActive) {
document.mozCancelFullScreen();
return;
}
let focusManager = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
if (focusManager.activeWindow != window) {
// The top-level window has lost focus since the request to enter
// full-screen was made. Cancel full-screen.
document.mozCancelFullScreen();
return;
}
document.documentElement.setAttribute("inDOMFullscreen", true);
if (gFindBarInitialized)
gFindBar.close();
this.showWarning(event.target);
// 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.
if (!this.useLionFullScreen) {
window.addEventListener("activate", this);
}
// Cancel any "hide the toolbar" animation which is in progress, and make
// the toolbar hide immediately.
this._cancelAnimation();
this.mouseoverToggle(false);
// Remove listeners on the full-screen toggler, so that mouseover
// the top of the screen will not cause the toolbar to re-appear.
this._fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
this._fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
},
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);
gPrefService.removeObserver("browser.fullscreen", this);
this._fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
this._fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
this.cancelWarning();
gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
if (!this.useLionFullScreen)
window.removeEventListener("activate", this);
this.fullscreenDoc = null;
}
},
observe: function(aSubject, aTopic, aData)
{
if (aData == "browser.fullscreen.autohide") {
if (gPrefService.getBoolPref("browser.fullscreen.autohide")) {
gBrowser.mPanelContainer.addEventListener("mousemove",
this._collapseCallback, false);
}
else {
gBrowser.mPanelContainer.removeEventListener("mousemove",
this._collapseCallback, false);
}
}
},
// Event callbacks
_expandCallback: function()
{
FullScreen.mouseoverToggle(true);
},
_collapseCallback: function()
{
FullScreen.mouseoverToggle(false);
},
_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._shouldAnimate = false;
FullScreen.mouseoverToggle(false, true);
}
// F6 is another shortcut to the address bar, but its not covered in OpenLocation()
else if (aEvent.keyCode == aEvent.DOM_VK_F6)
FullScreen.mouseoverToggle(true);
},
// Checks whether we are allowed to collapse the chrome
_isPopupOpen: false,
_isChromeCollapsed: false,
_safeToCollapse: function(forceHide)
{
if (!gPrefService.getBoolPref("browser.fullscreen.autohide"))
return false;
// a popup menu is open in chrome: don't collapse chrome
if (!forceHide && this._isPopupOpen)
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") {
if (forceHide)
// hidden textboxes that still have focus are bad bad bad
document.commandDispatcher.focusedElement.blur();
else
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;
},
// 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"));
},
// Animate the toolbars disappearing
_shouldAnimate: true,
_isAnimating: false,
_animationTimeout: 0,
_animationHandle: 0,
_animateUp: function() {
// check again, the user may have done something before the animation was due to start
if (!window.fullScreen || !this._safeToCollapse(false)) {
this._isAnimating = false;
this._shouldAnimate = true;
return;
}
this._animateStartTime = window.mozAnimationStartTime;
if (!this._animationHandle)
this._animationHandle = window.mozRequestAnimationFrame(this);
},
sample: function (timeStamp) {
const duration = 1500;
const timePassed = timeStamp - this._animateStartTime;
const pos = timePassed >= duration ? 1 :
1 - Math.pow(1 - timePassed / duration, 4);
if (pos >= 1) {
// We've animated enough
this._cancelAnimation();
gNavToolbox.style.marginTop = "";
this.mouseoverToggle(false);
return;
}
gNavToolbox.style.marginTop = (gNavToolbox.boxObject.height * pos * -1) + "px";
this._animationHandle = window.mozRequestAnimationFrame(this);
},
_cancelAnimation: function() {
window.mozCancelAnimationFrame(this._animationHandle);
this._animationHandle = 0;
clearTimeout(this._animationTimeout);
this._isAnimating = false;
this._shouldAnimate = false;
},
cancelWarning: function(event) {
if (!this.warningBox)
return;
this.warningBox.removeEventListener("transitionend", this);
if (this.warningFadeOutTimeout) {
clearTimeout(this.warningFadeOutTimeout);
this.warningFadeOutTimeout = null;
}
// Ensure focus switches away from the (now hidden) warning box. If the user
// clicked buttons in the fullscreen key authorization UI, 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();
this.warningBox.setAttribute("hidden", true);
this.warningBox.removeAttribute("fade-warning-out");
this.warningBox.removeAttribute("obscure-browser");
this.warningBox = null;
},
setFullscreenAllowed: function(isApproved) {
// The "remember decision" checkbox is hidden when showing for documents that
// the permission manager can't handle (documents with URIs without a host).
// We simply require those to be approved every time instead.
let rememberCheckbox = document.getElementById("full-screen-remember-decision");
let uri = this.fullscreenDoc.nodePrincipal.URI;
if (!rememberCheckbox.hidden) {
if (rememberCheckbox.checked)
Services.perms.add(uri,
"fullscreen",
isApproved ? Services.perms.ALLOW_ACTION : Services.perms.DENY_ACTION,
Services.perms.EXPIRE_NEVER);
else if (isApproved) {
// The user has only temporarily approved fullscren for this fullscreen
// session only. Add the permission (so Goanna knows to approve any further
// fullscreen requests for this host in this fullscreen session) but add
// a listener to revoke the permission when the chrome document exits
// fullscreen.
Services.perms.add(uri,
"fullscreen",
Services.perms.ALLOW_ACTION,
Services.perms.EXPIRE_SESSION);
let host = uri.host;
var onFullscreenchange = function onFullscreenchange(event) {
if (event.target == document && document.mozFullScreenElement == null) {
// The chrome document has left fullscreen. Remove the temporary permission grant.
Services.perms.remove(host, "fullscreen");
document.removeEventListener("mozfullscreenchange", onFullscreenchange);
}
}
document.addEventListener("mozfullscreenchange", onFullscreenchange);
}
}
if (this.warningBox)
this.warningBox.setAttribute("fade-warning-out", "true");
// If the document has been granted fullscreen, notify Goanna so it can resume
// any pending pointer lock requests, otherwise exit fullscreen; the user denied
// the fullscreen request.
if (isApproved)
Services.obs.notifyObservers(this.fullscreenDoc, "fullscreen-approved", "");
else
document.mozCancelFullScreen();
},
warningBox: null,
warningFadeOutTimeout: null,
fullscreenDoc: null,
// Shows the fullscreen approval UI, or if the domain has already been approved
// for fullscreen, shows a warning that the site has entered fullscreen for a short
// duration.
showWarning: function(targetDoc) {
if (!document.mozFullScreen ||
!gPrefService.getBoolPref("full-screen-api.approval-required"))
return;
// Set the strings on the fullscreen approval UI.
this.fullscreenDoc = targetDoc;
let uri = this.fullscreenDoc.nodePrincipal.URI;
let host = null;
try {
host = uri.host;
} catch (e) { }
let hostLabel = document.getElementById("full-screen-domain-text");
let rememberCheckbox = document.getElementById("full-screen-remember-decision");
let isApproved = false;
if (host) {
// Document's principal's URI has a host. Display a warning including the hostname and
// show UI to enable the user to permanently grant this host permission to enter fullscreen.
let utils = {};
Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
let displayHost = utils.DownloadUtils.getURIHost(uri.spec)[0];
let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
hostLabel.textContent = bundle.formatStringFromName("fullscreen.entered", [displayHost], 1);
hostLabel.removeAttribute("hidden");
rememberCheckbox.label = bundle.formatStringFromName("fullscreen.rememberDecision", [displayHost], 1);
rememberCheckbox.checked = false;
rememberCheckbox.removeAttribute("hidden");
// Note we only allow documents whose principal's URI has a host to
// store permission grants.
isApproved = Services.perms.testPermission(uri, "fullscreen") == Services.perms.ALLOW_ACTION;
} else {
hostLabel.setAttribute("hidden", "true");
rememberCheckbox.setAttribute("hidden", "true");
}
// Note: the warning box can be non-null if the warning box from the previous request
// wasn't hidden before another request was made.
if (!this.warningBox) {
this.warningBox = document.getElementById("full-screen-warning-container");
// Add a listener to clean up state after the warning is hidden.
this.warningBox.addEventListener("transitionend", this);
this.warningBox.removeAttribute("hidden");
} else {
if (this.warningFadeOutTimeout) {
clearTimeout(this.warningFadeOutTimeout);
this.warningFadeOutTimeout = null;
}
this.warningBox.removeAttribute("fade-warning-out");
}
// If fullscreen mode has not yet been approved for the fullscreen
// document's domain, show the approval UI and don't auto fade out the
// fullscreen warning box. Otherwise, we're just notifying of entry into
// fullscreen mode. Note if the resource's host is null, we must be
// showing a local file or a local data URI, and we require explicit
// approval every time.
let authUI = document.getElementById("full-screen-approval-pane");
if (isApproved) {
authUI.setAttribute("hidden", "true");
this.warningBox.removeAttribute("obscure-browser");
} else {
// Partially obscure the <browser> element underneath the approval UI.
this.warningBox.setAttribute("obscure-browser", "true");
authUI.removeAttribute("hidden");
}
// If we're not showing the fullscreen approval UI, we're just notifying the user
// of the transition, so set a timeout to fade the warning out after a few moments.
if (isApproved)
this.warningFadeOutTimeout =
setTimeout(
function() {
if (this.warningBox)
this.warningBox.setAttribute("fade-warning-out", "true");
}.bind(this),
3000);
},
mouseoverToggle: function(aShow, forceHide)
{
// Don't do anything if:
// a) we're already in the state we want,
// b) we're animating and will become collapsed soon, or
// c) we can't collapse because it would be undesirable right now
if (aShow != this._isChromeCollapsed || (!aShow && this._isAnimating) ||
(!aShow && !this._safeToCollapse(forceHide)))
return;
// browser.fullscreen.animateUp
// 0 - never animate up
// 1 - animate only for first collapse after entering fullscreen (default for perf's sake)
// 2 - animate every time it collapses
if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 0)
this._shouldAnimate = false;
if (!aShow && this._shouldAnimate) {
this._isAnimating = true;
this._shouldAnimate = false;
this._animationTimeout = setTimeout(this._animateUp.bind(this), 800);
return;
}
// The chrome is collapsed so don't spam needless mousemove events
if (aShow) {
gBrowser.mPanelContainer.addEventListener("mousemove",
this._collapseCallback, false);
}
else {
gBrowser.mPanelContainer.removeEventListener("mousemove",
this._collapseCallback, false);
}
// Hiding/collapsing the toolbox interferes with the tab bar's scrollbox,
// so we just move it off-screen instead. See bug 430687.
gNavToolbox.style.marginTop =
aShow ? "" : -gNavToolbox.getBoundingClientRect().height + "px";
this._fullScrToggler.collapsed = aShow;
this._isChromeCollapsed = !aShow;
if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
this._shouldAnimate = true;
},
showXULChrome: function(aTag, aShow)
{
var els = document.getElementsByTagNameNS(this._XULNS, aTag);
for (let el of els) {
// XXX don't interfere with previously collapsed toolbars
if (el.getAttribute("fullscreentoolbar") == "true") {
if (!aShow) {
var toolbarMode = el.getAttribute("mode");
if (toolbarMode != "text") {
el.setAttribute("saved-mode", toolbarMode);
el.setAttribute("saved-iconsize", el.getAttribute("iconsize"));
el.setAttribute("mode", "icons");
el.setAttribute("iconsize", "small");
}
// 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 {
var restoreAttr = function restoreAttr(attrName) {
var savedAttr = "saved-" + attrName;
if (el.hasAttribute(savedAttr)) {
el.setAttribute(attrName, el.getAttribute(savedAttr));
el.removeAttribute(savedAttr);
}
}
restoreAttr("mode");
restoreAttr("iconsize");
restoreAttr("context");
el.removeAttribute("inFullscreen");
}
} else {
// use moz-collapsed so it doesn't persist hidden/collapsed,
// so that new windows don't have missing toolbars
if (aShow)
el.removeAttribute("moz-collapsed");
else
el.setAttribute("moz-collapsed", "true");
}
}
if (aShow) {
gNavToolbox.removeAttribute("inFullscreen");
document.documentElement.removeAttribute("inFullscreen");
} else {
gNavToolbox.setAttribute("inFullscreen", true);
document.documentElement.setAttribute("inFullscreen", true);
}
// In tabs-on-top mode, move window controls to the tab bar,
// and in tabs-on-bottom mode, move them back to the navigation toolbar.
// When there is a chance the tab bar may be collapsed, put window
// controls on nav bar.
var fullscreenctls = document.getElementById("window-controls");
var navbar = document.getElementById("nav-bar");
var ctlsOnTabbar = window.toolbar.visible &&
(navbar.collapsed || (TabsOnTop.enabled &&
!gPrefService.getBoolPref("browser.tabs.autoHide")));
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 = aShow;
ToolbarIconColor.inferFromText();
}
};
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"
#ifdef XP_MACOSX
return parseFloat(Services.sysinfo.getProperty("version")) >= 11 &&
document.documentElement.getAttribute("fullscreenbutton") == "true";
#else
return false;
#endif
});
@@ -0,0 +1,550 @@
/*
#ifdef 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
*/
// One of the possible values for the mousewheel.* preferences.
// From nsEventStateManager.cpp.
const MOUSE_SCROLL_ZOOM = 3;
/**
* 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() {
// Listen for scrollwheel events so we can save scrollwheel-based changes.
window.addEventListener("DOMMouseScroll", this, false);
// 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.clear();
this._initialLocations = null;
},
destroy: function FullZoom_destroy() {
gPrefService.removeObserver("browser.zoom.", this);
this._cps2.removeObserverForName(this.name, this);
window.removeEventListener("DOMMouseScroll", this, false);
},
//**************************************************************************//
// Event Handlers
// nsIDOMEventListener
handleEvent: function FullZoom_handleEvent(event) {
switch (event.type) {
case "DOMMouseScroll":
this._handleMouseScrolled(event);
break;
}
},
_handleMouseScrolled: function FullZoom__handleMouseScrolled(event) {
// Construct the "mousewheel action" pref key corresponding to this event.
// Based on nsEventStateManager::WheelPrefs::GetBasePrefName().
var pref = "mousewheel.";
var pressedModifierCount = event.shiftKey + event.ctrlKey + event.altKey +
event.metaKey + event.getModifierState("OS");
if (pressedModifierCount != 1) {
pref += "default.";
} else if (event.shiftKey) {
pref += "with_shift.";
} else if (event.ctrlKey) {
pref += "with_control.";
} else if (event.altKey) {
pref += "with_alt.";
} else if (event.metaKey) {
pref += "with_meta.";
} else {
pref += "with_win.";
}
pref += "action";
// Don't do anything if this isn't a "zoom" scroll event.
var isZoomEvent = false;
try {
isZoomEvent = (gPrefService.getIntPref(pref) == MOUSE_SCROLL_ZOOM);
} catch (e) {}
if (!isZoomEvent)
return;
// XXX Lazily cache all the possible action prefs so we don't have to get
// them anew from the pref service for every scroll event? We'd have to
// make sure to observe them so we can update the cache when they change.
// We have to call _applyZoomToPref in a timeout because we handle the
// event before the event state manager has a chance to apply the zoom
// during nsEventStateManager::PostHandleEvent.
let browser = gBrowser.selectedBrowser;
let token = this._getBrowserToken(browser);
window.setTimeout(function () {
if (token.isCurrent)
this._applyZoomToPref(browser);
}.bind(this), 0);
},
// 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) {
this._onContentPrefChanged(aGroup, aValue);
},
onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName) {
this._onContentPrefChanged(aGroup, undefined);
},
/**
* 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) {
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 domain = this._cps2.extractDomain(browser.currentURI.spec);
if (aGroup) {
if (aGroup == domain)
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 ctxt = this._loadContextFromBrowser(browser);
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();
return;
}
// Avoid the cps roundtrip and apply the default/global pref.
if (aURI.spec == "about:blank") {
this._applyPrefToZoom(undefined, browser,
this._notifyOnLocationChange.bind(this));
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();
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));
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();
return;
}
this._applyPrefToZoom(value, browser,
this._notifyOnLocationChange.bind(this));
}.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 of the page in the current browser to the global zoom
* level.
*/
reset: function FullZoom_reset() {
let browser = gBrowser.selectedBrowser;
let token = this._getBrowserToken(browser);
this._getGlobalValue(browser, function (value) {
if (token.isCurrent) {
ZoomManager.setZoomForBrowser(browser, value === undefined ? 1 : value);
this._ignorePendingZoomAccesses(browser);
}
});
this._removePref(browser);
},
/**
* 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, function (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) {
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) {
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;
},
};
},
/**
* 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.
*
* WARNING: callback may be called synchronously or asynchronously. The
* reason is that it's usually desirable to avoid turns of the event loop
* where possible, since they can lead to visible, jarring jumps in zoom
* level. It's not always possible to avoid them, though. As a convenience,
* then, this method takes a callback and returns nothing.
*
* @param browser The content browser pertaining to the zoom.
* @param callback Synchronously or asynchronously called when done. It's
* bound to this object (FullZoom) and called as:
* callback(prefValue)
*/
_getGlobalValue: function FullZoom__getGlobalValue(browser, callback) {
// * !("_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.
if ("_globalValue" in this) {
callback.call(this, this._globalValue, true);
return;
}
let value = undefined;
this._cps2.getGlobal(this.name, this._loadContextFromBrowser(browser), {
handleResult: function (pref) value = pref.value,
handleCompletion: function (reason) {
this._globalValue = this._ensureValid(value);
callback.call(this, this._globalValue);
}.bind(this)
});
},
/**
* Gets the load context from the given content 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 a "browser-fullZoom:locationChange" notification
* so that tests can select tabs, load pages, etc. and 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() {
this._executeSoon(function () {
Services.obs.notifyObservers(null, "browser-fullZoom:locationChange", "");
});
},
_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
@@ -0,0 +1,595 @@
# -*- 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"/>
<menuitem id="menu_openLocation"
class="show-only-for-keyboard"
label="&openLocationCmd.label;"
command="Browser:OpenLocation"
key="focusURLBar"
accesskey="&openLocationCmd.accesskey;"/>
<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/>
<menuitem id="menu_printSetup"
label="&printSetupCmd.label;"
accesskey="&printSetupCmd.accesskey;"
command="cmd_pageSetup"/>
#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_restart"
label="&appMenuRestart.label;"
accesskey="&appMenuRestart.accesskey;"
command="cmd_restartApplication"/>
<menuitem id="menu_FileQuitItem"
#ifdef XP_WIN
label="&quitApplicationCmdWin.label;"
accesskey="&quitApplicationCmdWin.accesskey;"
#else
#ifdef XP_MACOSX
label="&quitApplicationCmdMac.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_tabsOnTop"
command="cmd_ToggleTabsOnTop"
type="checkbox"
label="&viewTabsOnTop.label;"
accesskey="&viewTabsOnTop.accesskey;"/>
<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"
label="&bookmarksButton.label;"/>
<menuitem id="menu_historySidebar"
key="key_gotoHistory"
observes="viewHistorySidebar"
label="&historyButton.label;"/>
</menupopup>
</menu>
<menuseparator/>
<menuitem id="menu_stop"
class="show-only-for-keyboard"
label="&stopCmd.label;"
accesskey="&stopCmd.accesskey;"
command="Browser:Stop"
#ifdef XP_MACOSX
key="key_stop_mac"/>
#else
key="key_stop"/>
#endif
<menuitem id="menu_reload"
class="show-only-for-keyboard"
label="&reloadCmd.label;"
accesskey="&reloadCmd.accesskey;"
key="key_reload"
command="Browser:ReloadOrDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuseparator class="show-only-for-keyboard"/>
<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_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="SwitchDocumentDirection(window.content)"/>
</menupopup>
</menu>
<menu id="history-menu"
label="&historyMenu.label;"
accesskey="&historyMenu.accesskey;">
<menupopup id="goPopup"
#ifndef XP_MACOSX
placespopup="true"
#endif
context="placesContext"
oncommand="this.parentNode._placesView._onCommand(event);"
onclick="checkForMiddleClick(this, event);"
onpopupshowing="if (!this.parentNode._placesView)
new HistoryMenu(event);"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="historyMenuBack"
class="show-only-for-keyboard"
label="&backCmd.label;"
#ifdef XP_MACOSX
key="goBackKb2"
#else
key="goBackKb"
#endif
command="Browser:BackOrBackDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="historyMenuForward"
class="show-only-for-keyboard"
label="&forwardCmd.label;"
#ifdef XP_MACOSX
key="goForwardKb2"
#else
key="goForwardKb"
#endif
command="Browser:ForwardOrForwardDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="historyMenuHome"
class="show-only-for-keyboard"
label="&historyHomeCmd.label;"
oncommand="BrowserGoHome(event);"
onclick="checkForMiddleClick(this, event);"
key="goHome"/>
<menuseparator id="historyMenuHomeSeparator"
class="show-only-for-keyboard"/>
<menuitem id="menu_showAllHistory"
label="&showAllHistoryCmd2.label;"
#ifndef XP_MACOSX
class="menuitem-iconic"
key="showAllHistoryKb"
#endif
command="Browser:ShowAllHistory"/>
<menuitem id="sanitizeItem"
#ifndef XP_MACOSX
class="menuitem-iconic"
#endif
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="PlacesCommandHook.updateBookmarkAllTabsCommand();
if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
tooltip="bhTooltip" popupsinherittooltip="true">
<menuitem id="bookmarksShowAll"
#ifndef XP_MACOSX
class="menuitem-iconic"
#endif
label="&organizeBookmarks.label;"
command="Browser:ShowAllBookmarks"
key="manBookmarkKb"/>
<menuseparator id="organizeBookmarksSeparator"/>
<menuitem id="menu_bookmarkThisPage"
#ifndef XP_MACOSX
class="menuitem-iconic"
#endif
label="&bookmarkThisPageCmd.label;"
command="Browser:AddBookmarkAs"
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 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>
<menuseparator id="bookmarksMenuItemsSeparator"/>
<!-- Bookmarks menu items -->
<menuseparator builder="end"
class="hide-if-empty-places-result"/>
<menuitem id="menu_unsortedBookmarks"
#ifndef XP_MACOSX
class="menuitem-iconic"
#endif
label="&unsortedBookmarksCmd.label;"
oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"/>
</menupopup>
</menu>
<menu id="tools-menu"
label="&toolsMenu.label;"
accesskey="&toolsMenu.accesskey;">
<menupopup id="menu_ToolsPopup"
#ifdef MOZ_SERVICES_SYNC
onpopupshowing="gSyncUI.updateUI();"
#endif
>
<menuitem id="menu_search"
class="show-only-for-keyboard"
label="&search.label;"
accesskey="&search.accesskey;"
key="key_search"
command="Tools:Search"/>
<menuseparator id="browserToolsSeparator"
class="show-only-for-keyboard"/>
<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"/>
<menuitem id="menu_openPermissions"
label="&permissions.label;"
command="Tools:Permissions"
accesskey="&permissions.accesskey;"/>
#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">
#ifdef MOZ_DEVTOOLS
<menuitem id="menu_devToolbox"
observes="devtoolsMenuBroadcaster_DevToolbox"
accesskey="&devToolboxMenuItem.accesskey;"/>
<menuseparator id="menu_devtools_separator"/>
<menuitem id="menu_devToolbar"
observes="devtoolsMenuBroadcaster_DevToolbar"
accesskey="&devToolbarMenu.accesskey;"/>
<menuitem id="menu_chromeDebugger"
observes="devtoolsMenuBroadcaster_ChromeDebugger"/>
<menuitem id="menu_browserConsole"
observes="devtoolsMenuBroadcaster_BrowserConsole"
accesskey="&browserConsoleCmd.accesskey;"/>
<menuitem id="menu_responsiveUI"
observes="devtoolsMenuBroadcaster_ResponsiveUI"
accesskey="&responsiveDesignTool.accesskey;"/>
<menuitem id="menu_eyedropper"
observes="devtoolsMenuBroadcaster_Eyedropper"
accesskey="&eyedropper.accesskey;"/>
<menuitem id="menu_scratchpad"
observes="devtoolsMenuBroadcaster_Scratchpad"
accesskey="&scratchpad.accesskey;"/>
#endif
<menuitem id="menu_pageSource"
observes="devtoolsMenuBroadcaster_PageSource"
accesskey="&pageSourceCmd.accesskey;"/>
<menuitem id="javascriptConsole"
observes="devtoolsMenuBroadcaster_ErrorConsole"
accesskey="&errorConsoleCmd.accesskey;"/>
#ifdef MOZ_DEVTOOLS
<menuitem id="menu_devtools_connect"
observes="devtoolsMenuBroadcaster_connect"/>
#endif
<menuseparator id="devToolsEndSeparator"/>
<menuitem id="getMoreDevtools"
observes="devtoolsMenuBroadcaster_GetMoreTools"
accesskey="&getMoreDevtoolsCmd.accesskey;"/>
</menupopup>
</menu>
<menuitem id="menu_pageInfo"
accesskey="&pageInfoCmd.accesskey;"
label="&pageInfoCmd.label;"
#ifndef XP_WIN
key="key_viewInfo"
#endif
command="View:PageInfo"/>
<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>
@@ -0,0 +1,362 @@
// 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/.
//
// Based on original code by alice0775 https://github.com/alice0775
"use strict";
var browserMenuDragging = {
//-- config --
STAY_OPEN_ONDRAGEXIT: false,
DEBUG: false,
//-- config --
menupopup: ['bookmarksMenuPopup',
'PlacesToolbar',
'BMB_bookmarksPopup',
'appmenu_bookmarksPopup',
'BookmarksMenuToolButtonPopup',
'UnsortedBookmarksFolderToolButtonPopup',
'bookmarksMenuPopup-context'],
timer:[],
count:[],
init: function(){
window.removeEventListener('load', this, false);
window.addEventListener('unload', this, false);
this.addPrefListener(this.PrefListener);
window.addEventListener('aftercustomization', this, false);
this.initPref();
this.delayedStartup();
},
uninit: function(){
window.removeEventListener('unload', this, false);
this.removePrefListener(this.PrefListener);
window.removeEventListener('aftercustomization', this, false);
for (var i = 0; i < this.menupopup.length; i++){
var menupopup = document.getElementById(this.menupopup[i]);
if (menupopup){
menupopup.removeEventListener('popupshowing', this, false);
menupopup.removeEventListener('popuphiding', this, false);
}
}
},
initPref: function(){
this.STAY_OPEN_ONDRAGEXIT =
this.getPref('browser.menu.dragging.stayOpen',
'bool', false);
this.DEBUG =
this.getPref('browser.menu.dragging.debug',
'bool', false);
},
//delayed startup
delayedStartup: function(){
//wait until construction of bookmarksBarContent is completed.
for (var i = 0; i < this.menupopup.length; i++){
this.count[i] = 0;
this.timer[i] = setInterval(function(self, i){
if(++self.count[i] > 50 || document.getElementById(self.menupopup[i])){
clearInterval(self.timer[i]);
var menupopup = document.getElementById(self.menupopup[i]);
if (menupopup) {
menupopup.addEventListener('popupshowing', self, false);
menupopup.addEventListener('popuphiding', self, false);
}
}
}, 250, this, i);
}
},
handleEvent: function(event){
switch (event.type) {
case 'popupshowing':
this.popupshowing(event);
break;
case 'popuphiding':
this.popuphiding(event);
break;
case 'aftercustomization':
setTimeout(function(self){self.delayedStartup(self);}, 0, this);
break;
case 'load':
this.init();
break;
case 'unload':
this.uninit();
break;
}
},
popuphiding: function(event) {
var menupopup = event.originalTarget;
menupopup.parentNode.parentNode.openNode = null;
if (menupopup.parentNode.localName == 'toolbarbutton') {
// Fix for Bug 225434 - dragging bookmark from personal toolbar and releasing
// (on same bookmark or elsewhere) or clicking on bookmark menu then cancelling
// leaves button depressed/sunken when hovered
menupopup.parentNode.parentNode._openedMenuButton = null;
if (!PlacesControllerDragHelper.getSession())
// Clear the dragover attribute if present, if we are dragging into a
// folder in the hierachy of current opened popup we don't clear
// this attribute on clearOverFolder. See Notify for closeTimer.
if (menupopup.parentNode.hasAttribute('dragover'))
menupopup.parentNode.removeAttribute('dragover');
}
},
popupshowing: function(event) {
var menupopup = event.originalTarget;
browserMenuDragging.debug("popupshowing ===============\n" + menupopup.parentNode.getAttribute('label'));
var parentPopup = menupopup.parentNode.parentNode;
if (!!parentPopup.openNode){
try {
parentPopup.openNode.hidePopup();
} catch(e){}
}
parentPopup.openNode = menupopup;
menupopup.onDragStart = function (event) {
// Bug 555474 - While bookmark is dragged, the tooltip should not appear
browserMenuDragging.hideTooltip();
}
menupopup.onDragOver = function (event) {
// Bug 555474 - While bookmark is dragged, the tooltip should not appear
browserMenuDragging.hideTooltip();
var target = event.originalTarget;
while (target) {
if (/menupopup/.test(target.localName))
break;
target = target.parentNode;
}
if (this != target)
return;
event.stopPropagation();
browserMenuDragging.debug("onDragOver " + "\n" + this.parentNode.getAttribute('label'));
PlacesControllerDragHelper.currentDropTarget = event.target;
let dt = event.dataTransfer;
let dropPoint = this._getDropPoint(event);
if (!dropPoint || !dropPoint.ip ||
!PlacesControllerDragHelper.canDrop(dropPoint.ip, dt)) {
this._indicatorBar.hidden = true;
event.stopPropagation();
return;
}
// Mark this popup as being dragged over.
this.setAttribute('dragover', 'true');
if (dropPoint.folderElt) {
// We are dragging over a folder.
// _overFolder should take the care of opening it on a timer.
if (this._overFolder.elt &&
this._overFolder.elt != dropPoint.folderElt) {
}
if (!this._overFolder.elt) {
this._overFolder.elt = dropPoint.folderElt;
// Create the timer to open this folder.
this._overFolder.openTimer = this._overFolder
.setTimer(this._overFolder.hoverTime);
}
}
else {
// We are not dragging over a folder.
}
// Autoscroll the popup strip if we drag over the scroll buttons.
let anonid = event.originalTarget.getAttribute('anonid');
let scrollDir = anonid == 'scrollbutton-up' ? -1 :
anonid == 'scrollbutton-down' ? 1 : 0;
if (scrollDir != 0) {
this._scrollBox.scrollByIndex(scrollDir, false);
}
// Check if we should hide the drop indicator for this target.
if (dropPoint.folderElt || this._hideDropIndicator(event)) {
this._indicatorBar.hidden = true;
event.preventDefault();
event.stopPropagation();
return;
}
// We should display the drop indicator relative to the arrowscrollbox.
let sbo = this._scrollBox.scrollBoxObject;
let newMarginTop = 0;
if (scrollDir == 0) {
let elt = this.firstChild;
while (elt && event.screenY > elt.boxObject.screenY +
elt.boxObject.height / 2)
elt = elt.nextSibling;
newMarginTop = elt ? elt.boxObject.screenY - sbo.screenY :
sbo.height;
}
else if (scrollDir == 1)
newMarginTop = sbo.height;
// Set the new marginTop based on arrowscrollbox.
newMarginTop += sbo.y - this._scrollBox.boxObject.y;
this._indicatorBar.firstChild.style.marginTop = newMarginTop + 'px';
this._indicatorBar.hidden = false;
event.preventDefault();
event.stopPropagation();
}
menupopup.onDragExit = function (event) {
var target = event.originalTarget;
while (target) {
if (/menupopup/.test(target.localName))
break;
target = target.parentNode;
}
if (this != target)
return;
event.stopPropagation();
browserMenuDragging.debug("onDragExit " + browserMenuDragging.STAY_OPEN_ONDRAGEXIT);
PlacesControllerDragHelper.currentDropTarget = null;
this.removeAttribute('dragover');
// If we have not moved to a valid new target clear the drop indicator
// this happens when moving out of the popup.
target = event.relatedTarget;
if (!target)
this._indicatorBar.hidden = true;
// Close any folder being hovered over
if (this._overFolder.elt) {
this._overFolder.closeTimer = this._overFolder
.setTimer(this._overFolder.hoverTime);
}
// The auto-opened attribute is set when this folder was automatically
// opened after the user dragged over it. If this attribute is set,
// auto-close the folder on drag exit.
// We should also try to close this popup if the drag has started
// from here, the timer will check if we are dragging over a child.
if (this.hasAttribute('autoopened') ||
!browserMenuDragging.STAY_OPEN_ONDRAGEXIT &&
this.hasAttribute('dragstart')) {
this._overFolder.closeMenuTimer = this._overFolder
.setTimer(this._overFolder.hoverTime);
}
event.stopPropagation();
}
menupopup.addEventListener('dragstart', menupopup.onDragStart, true);
menupopup.addEventListener('dragover', menupopup.onDragOver, true);
menupopup.addEventListener('dragleave', menupopup.onDragExit, true);
},
hideTooltip: function() {
['bhTooltip', 'btTooltip2'].forEach(function(id) {
var tooltip = document.getElementById(id);
if (tooltip)
tooltip.hidePopup();
});
},
get getVer(){
const Cc = Components.classes;
const Ci = Components.interfaces;
var info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
var ver = parseInt(info.version.substr(0,3) * 10,10) / 10;
return ver;
},
debug: function(aMsg){
if (!browserMenuDragging.DEBUG)
return;
Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService)
.logStringMessage(aMsg);
},
getPref: function(aPrefString, aPrefType, aDefault){
var xpPref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
try{
switch (aPrefType){
case 'complex':
return xpPref.getComplexValue(aPrefString, Components.interfaces.nsILocalFile); break;
case 'str':
return xpPref.getCharPref(aPrefString).toString(); break;
case 'int':
return xpPref.getIntPref(aPrefString); break;
case 'bool':
default:
return xpPref.getBoolPref(aPrefString); break;
}
}catch(e){
}
return aDefault;
},
setPref: function(aPrefString, aPrefType, aValue){
var xpPref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
try{
switch (aPrefType){
case 'complex':
return xpPref.setComplexValue(aPrefString, Components.interfaces.nsILocalFile, aValue); break;
case 'str':
return xpPref.setCharPref(aPrefString, aValue); break;
case 'int':
aValue = parseInt(aValue);
return xpPref.setIntPref(aPrefString, aValue); break;
case 'bool':
default:
return xpPref.setBoolPref(aPrefString, aValue); break;
}
}catch(e){
}
return null;
},
addPrefListener: function(aObserver) {
try {
var pbi = Components.classes["@mozilla.org/preferences;1"].
getService(Components.interfaces.nsIPrefBranch2);
pbi.addObserver(aObserver.domain, aObserver, false);
} catch(e) {}
},
removePrefListener: function(aObserver) {
try {
var pbi = Components.classes["@mozilla.org/preferences;1"].
getService(Components.interfaces.nsIPrefBranch2);
pbi.removeObserver(aObserver.domain, aObserver);
} catch(e) {}
},
PrefListener:{
domain : 'browser.menu.dragging.stayOpen',
observe : function(aSubject, aTopic, aPrefstring) {
if (aTopic == 'nsPref:changed') {
browserMenuDragging.initPref();
}
}
}
}
window.addEventListener('load', browserMenuDragging, false);
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<overlay id="menuDraggingOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<window id="main-window">
<script type="application/x-javascript" src="chrome://browser/content/browser-menudragging.js" />
</window>
</overlay>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,797 @@
# -*- Mode: javascript; 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/.
const kPrefSessionPersistMinutes = "plugin.sessionPermissionNow.intervalInMinutes";
const kPrefPersistentDays = "plugin.persistentPermissionAlways.intervalInDays";
var gPluginHandler = {
PLUGIN_SCRIPTED_STATE_NONE: 0,
PLUGIN_SCRIPTED_STATE_FIRED: 1,
PLUGIN_SCRIPTED_STATE_DONE: 2,
getPluginUI: function (plugin, anonid) {
return plugin.ownerDocument.
getAnonymousElementByAttribute(plugin, "anonid", anonid);
},
_getPluginInfo: function (pluginElement) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
pluginElement.QueryInterface(Ci.nsIObjectLoadingContent);
let tagMimetype;
let pluginName = gNavigatorBundle.getString("pluginInfo.unknownPlugin");
let pluginTag = null;
let permissionString = null;
let fallbackType = null;
let blocklistState = null;
if (pluginElement instanceof HTMLAppletElement) {
tagMimetype = "application/x-java-vm";
} else {
tagMimetype = pluginElement.actualType;
if (tagMimetype == "") {
tagMimetype = pluginElement.type;
}
}
if (gPluginHandler.isKnownPlugin(pluginElement)) {
pluginTag = pluginHost.getPluginTagForType(pluginElement.actualType);
pluginName = gPluginHandler.makeNicePluginName(pluginTag.name);
permissionString = pluginHost.getPermissionStringForType(pluginElement.actualType);
fallbackType = pluginElement.defaultFallbackType;
blocklistState = pluginHost.getBlocklistStateForType(pluginElement.actualType);
// Make state-softblocked == state-notblocked for our purposes,
// they have the same UI. STATE_OUTDATED should not exist for plugin
// items, but let's alias it anyway, just in case.
if (blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED ||
blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
blocklistState = Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
}
}
return { mimetype: tagMimetype,
pluginName: pluginName,
pluginTag: pluginTag,
permissionString: permissionString,
fallbackType: fallbackType,
blocklistState: blocklistState,
};
},
// Map the plugin's name to a filtered version more suitable for user UI.
makeNicePluginName : function (aName) {
if (aName == "Shockwave Flash")
return "Adobe Flash";
// Clean up the plugin name by stripping off any trailing version numbers
// or "plugin". EG, "Foo Bar Plugin 1.23_02" --> "Foo Bar"
// Do this by first stripping the numbers, etc. off the end, and then
// removing "Plugin" (and then trimming to get rid of any whitespace).
// (Otherwise, something like "Java(TM) Plug-in 1.7.0_07" gets mangled)
let newName = aName.replace(/[\s\d\.\-\_\(\)]+$/, "").replace(/\bplug-?in\b/i, "").trim();
return newName;
},
isTooSmall : function (plugin, overlay) {
// Is the <object>'s size too small to hold what we want to show?
let pluginRect = plugin.getBoundingClientRect();
// XXX bug 446693. The text-shadow on the submitted-report text at
// the bottom causes scrollHeight to be larger than it should be.
// Clamp width/height to properly show CTP overlay on different
// zoom levels when embedded in iframes (rounding bug). (Bug 972237)
let overflows = (overlay.scrollWidth > Math.ceil(pluginRect.width)) ||
(overlay.scrollHeight - 5 > Math.ceil(pluginRect.height));
return overflows;
},
addLinkClickCallback: function (linkNode, callbackName /*callbackArgs...*/) {
// XXX just doing (callback)(arg) was giving a same-origin error. bug?
let self = this;
let callbackArgs = Array.prototype.slice.call(arguments).slice(2);
linkNode.addEventListener("click",
function(evt) {
if (!evt.isTrusted)
return;
evt.preventDefault();
if (callbackArgs.length == 0)
callbackArgs = [ evt ];
(self[callbackName]).apply(self, callbackArgs);
},
true);
linkNode.addEventListener("keydown",
function(evt) {
if (!evt.isTrusted)
return;
if (evt.keyCode == evt.DOM_VK_RETURN) {
evt.preventDefault();
if (callbackArgs.length == 0)
callbackArgs = [ evt ];
evt.preventDefault();
(self[callbackName]).apply(self, callbackArgs);
}
},
true);
},
// Helper to get the binding handler type from a plugin object
_getBindingType : function(plugin) {
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
return null;
switch (plugin.pluginFallbackType) {
case Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED:
return "PluginNotFound";
case Ci.nsIObjectLoadingContent.PLUGIN_DISABLED:
return "PluginDisabled";
case Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED:
return "PluginBlocklisted";
case Ci.nsIObjectLoadingContent.PLUGIN_OUTDATED:
return "PluginOutdated";
case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY:
return "PluginClickToPlay";
case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE:
return "PluginVulnerableUpdatable";
case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE:
return "PluginVulnerableNoUpdate";
case Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW:
return "PluginPlayPreview";
default:
// Not all states map to a handler
return null;
}
},
handleEvent : function(event) {
let plugin;
let doc;
let eventType = event.type;
if (eventType === "PluginRemoved") {
doc = event.target;
}
else {
plugin = event.target;
doc = plugin.ownerDocument;
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
return;
}
if (eventType == "PluginBindingAttached") {
// The plugin binding fires this event when it is created.
// As an untrusted event, ensure that this object actually has a binding
// and make sure we don't handle it twice
let overlay = this.getPluginUI(plugin, "main");
if (!overlay || overlay._bindingHandled) {
return;
}
overlay._bindingHandled = true;
// Lookup the handler for this binding
eventType = this._getBindingType(plugin);
if (!eventType) {
// Not all bindings have handlers
return;
}
}
let shouldShowNotification = false;
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
if (!browser)
return;
switch (eventType) {
case "PluginCrashed":
this.pluginInstanceCrashed(plugin, event);
break;
case "PluginNotFound":
/* No action (plugin finder obsolete) */
break;
case "PluginBlocklisted":
case "PluginOutdated":
shouldShowNotification = true;
break;
case "PluginVulnerableUpdatable":
let updateLink = this.getPluginUI(plugin, "checkForUpdatesLink");
this.addLinkClickCallback(updateLink, "openPluginUpdatePage");
/* FALLTHRU */
case "PluginVulnerableNoUpdate":
case "PluginClickToPlay":
this._handleClickToPlayEvent(plugin);
let overlay = this.getPluginUI(plugin, "main");
let pluginName = this._getPluginInfo(plugin).pluginName;
let messageString = gNavigatorBundle.getFormattedString("PluginClickToActivate", [pluginName]);
let overlayText = this.getPluginUI(plugin, "clickToPlay");
overlayText.textContent = messageString;
if (eventType == "PluginVulnerableUpdatable" ||
eventType == "PluginVulnerableNoUpdate") {
let vulnerabilityString = gNavigatorBundle.getString(eventType);
let vulnerabilityText = this.getPluginUI(plugin, "vulnerabilityStatus");
vulnerabilityText.textContent = vulnerabilityString;
}
shouldShowNotification = true;
break;
case "PluginPlayPreview":
this._handlePlayPreviewEvent(plugin);
break;
case "PluginDisabled":
let manageLink = this.getPluginUI(plugin, "managePluginsLink");
this.addLinkClickCallback(manageLink, "managePlugins");
shouldShowNotification = true;
break;
case "PluginInstantiated":
//Pale Moon: don't show the indicator when plugins are enabled/allowed
if (gPrefService.getBoolPref("plugins.always_show_indicator")) {
shouldShowNotification = true;
}
break;
case "PluginRemoved":
shouldShowNotification = true;
break;
}
// Show the in-content UI if it's not too big. The crashed plugin handler already did this.
if (eventType != "PluginCrashed" && eventType != "PluginRemoved") {
let overlay = this.getPluginUI(plugin, "main");
if (overlay != null) {
if (!this.isTooSmall(plugin, overlay)) {
overlay.style.visibility = "visible";
}
plugin.addEventListener("overflow", function(event) {
overlay.style.visibility = "hidden";
});
plugin.addEventListener("underflow", function(event) {
// this is triggered if only one dimension underflows,
// the other dimension might still overflow
if (!gPluginHandler.isTooSmall(plugin, overlay)) {
overlay.style.visibility = "visible";
}
});
}
}
// Only show the notification after we've done the isTooSmall check, so
// that the notification can decide whether to show the "alert" icon
if (shouldShowNotification) {
this._showClickToPlayNotification(browser);
}
},
isKnownPlugin: function PH_isKnownPlugin(objLoadingContent) {
return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) ==
Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
},
canActivatePlugin: function PH_canActivatePlugin(objLoadingContent) {
// if this isn't a known plugin, we can't activate it
// (this also guards pluginHost.getPermissionStringForType against
// unexpected input)
if (!gPluginHandler.isKnownPlugin(objLoadingContent))
return false;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
let principal = objLoadingContent.ownerDocument.defaultView.top.document.nodePrincipal;
let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
let isFallbackTypeValid =
objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
if (objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) {
// checking if play preview is subject to CTP rules
let playPreviewInfo = pluginHost.getPlayPreviewInfo(objLoadingContent.actualType);
isFallbackTypeValid = !playPreviewInfo.ignoreCTP;
}
return !objLoadingContent.activated &&
pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
isFallbackTypeValid;
},
hideClickToPlayOverlay: function(aPlugin) {
let overlay = this.getPluginUI(aPlugin, "main");
if (overlay)
overlay.style.visibility = "hidden";
},
stopPlayPreview: function PH_stopPlayPreview(aPlugin, aPlayPlugin) {
let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (objLoadingContent.activated)
return;
if (aPlayPlugin)
objLoadingContent.playPlugin();
else
objLoadingContent.cancelPlayPreview();
},
// Callback for user clicking on a disabled plugin
managePlugins: function (aEvent) {
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 (aEvent) {
openURL(Services.urlFormatter.formatURLPref("plugins.update.url"));
},
// 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);
},
// Event listener for click-to-play plugins.
_handleClickToPlayEvent: function PH_handleClickToPlayEvent(aPlugin) {
let doc = aPlugin.ownerDocument;
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
// guard against giving pluginHost.getPermissionStringForType a type
// not associated with any known plugin
if (!gPluginHandler.isKnownPlugin(objLoadingContent))
return;
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
let principal = doc.defaultView.top.document.nodePrincipal;
let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
let overlay = this.getPluginUI(aPlugin, "main");
if (pluginPermission == Ci.nsIPermissionManager.DENY_ACTION) {
if (overlay)
overlay.style.visibility = "hidden";
return;
}
if (overlay) {
overlay.addEventListener("click", gPluginHandler._overlayClickListener, true);
let closeIcon = gPluginHandler.getPluginUI(aPlugin, "closeIcon");
closeIcon.addEventListener("click", function(aEvent) {
if (aEvent.button == 0 && aEvent.isTrusted)
gPluginHandler.hideClickToPlayOverlay(aPlugin);
}, true);
}
},
_overlayClickListener: {
handleEvent: function PH_handleOverlayClick(aEvent) {
let plugin = document.getBindingParent(aEvent.target);
let contentWindow = plugin.ownerDocument.defaultView.top;
// gBrowser.getBrowserForDocument does not exist in the case where we
// drag-and-dropped a tab from a window containing only that tab. In
// that case, the window gets destroyed.
let browser = gBrowser.getBrowserForDocument ?
gBrowser.getBrowserForDocument(contentWindow.document) :
null;
// If browser is null here, we've been drag-and-dropped from another
// window, and this is the wrong click handler.
if (!browser) {
aEvent.target.removeEventListener("click", gPluginHandler._overlayClickListener, true);
return;
}
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
// Have to check that the target is not the link to update the plugin
if (!(aEvent.originalTarget instanceof HTMLAnchorElement) &&
(aEvent.originalTarget.getAttribute('anonid') != 'closeIcon') &&
aEvent.button == 0 && aEvent.isTrusted) {
gPluginHandler._showClickToPlayNotification(browser, plugin);
aEvent.stopPropagation();
aEvent.preventDefault();
}
}
},
_handlePlayPreviewEvent: function PH_handlePlayPreviewEvent(aPlugin) {
let doc = aPlugin.ownerDocument;
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let pluginInfo = this._getPluginInfo(aPlugin);
let playPreviewInfo = pluginHost.getPlayPreviewInfo(pluginInfo.mimetype);
let previewContent = this.getPluginUI(aPlugin, "previewPluginContent");
let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
if (!iframe) {
// lazy initialization of the iframe
iframe = doc.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
iframe.className = "previewPluginContentFrame";
previewContent.appendChild(iframe);
// Force a style flush, so that we ensure our binding is attached.
aPlugin.clientTop;
}
iframe.src = playPreviewInfo.redirectURL;
// MozPlayPlugin event can be dispatched from the extension chrome
// code to replace the preview content with the native plugin
previewContent.addEventListener("MozPlayPlugin", function playPluginHandler(aEvent) {
if (!aEvent.isTrusted)
return;
previewContent.removeEventListener("MozPlayPlugin", playPluginHandler, true);
let playPlugin = !aEvent.detail;
gPluginHandler.stopPlayPreview(aPlugin, playPlugin);
// cleaning up: removes overlay iframe from the DOM
let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
if (iframe)
previewContent.removeChild(iframe);
}, true);
if (!playPreviewInfo.ignoreCTP) {
gPluginHandler._showClickToPlayNotification(browser);
}
},
reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
let browser = gBrowser.selectedBrowser;
let contentWindow = browser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let doc = contentWindow.document;
let plugins = cwu.plugins;
for (let plugin of plugins) {
let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
if (overlay)
overlay.removeEventListener("click", gPluginHandler._overlayClickListener, true);
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent))
gPluginHandler._handleClickToPlayEvent(plugin);
}
gPluginHandler._showClickToPlayNotification(browser);
},
_clickToPlayNotificationEventCallback: function PH_ctpEventCallback(event) {
if (event == "showing") {
gPluginHandler._makeCenterActions(this);
}
else if (event == "dismissed") {
// Once the popup is dismissed, clicking the icon should show the full
// list again
this.options.primaryPlugin = null;
}
},
// Match the behaviour of nsPermissionManager
_getHostFromPrincipal: function PH_getHostFromPrincipal(principal) {
if (!principal.URI || principal.URI.schemeIs("moz-nullprincipal")) {
return "(null)";
}
try {
if (principal.URI.host)
return principal.URI.host;
} catch (e) {}
return principal.origin;
},
_makeCenterActions: function PH_makeCenterActions(notification) {
let contentWindow = notification.browser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let principal = contentWindow.document.nodePrincipal;
// This matches the behavior of nsPermssionManager, used for display purposes only
let principalHost = this._getHostFromPrincipal(principal);
let centerActions = [];
let pluginsFound = new Set();
for (let plugin of cwu.plugins) {
plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (plugin.getContentTypeForMIMEType(plugin.actualType) != Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
continue;
}
let pluginInfo = this._getPluginInfo(plugin);
if (pluginInfo.permissionString === null) {
Components.utils.reportError("No permission string for active plugin.");
continue;
}
if (pluginsFound.has(pluginInfo.permissionString)) {
continue;
}
pluginsFound.add(pluginInfo.permissionString);
// Add the per-site permissions and details URLs to pluginInfo here
// because they are more expensive to compute and so we avoid it in
// the tighter loop above.
let permissionObj = Services.perms.
getPermissionObject(principal, pluginInfo.permissionString, false);
if (permissionObj) {
pluginInfo.pluginPermissionHost = permissionObj.host;
pluginInfo.pluginPermissionType = permissionObj.expireType;
}
else {
pluginInfo.pluginPermissionHost = principalHost;
pluginInfo.pluginPermissionType = undefined;
}
let url;
// TODO: allow the blocklist to specify a better link, bug 873093
if (pluginInfo.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
url = Services.urlFormatter.formatURLPref("plugins.update.url");
}
else if (pluginInfo.blocklistState != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
url = Services.blocklist.getPluginBlocklistURL(pluginInfo.pluginTag);
}
pluginInfo.detailsLink = url;
centerActions.push(pluginInfo);
}
centerActions.sort(function(a, b) {
return a.pluginName.localeCompare(b.pluginName);
});
notification.options.centerActions = centerActions;
},
/**
* 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 PH_setPermissionForPlugins(aNotification, aPluginInfo, aNewState) {
let permission;
let expireType;
let expireTime;
switch (aNewState) {
case "allownow":
permission = Ci.nsIPermissionManager.ALLOW_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_SESSION;
expireTime = Date.now() + Services.prefs.getIntPref(kPrefSessionPersistMinutes) * 60 * 1000;
break;
case "allowalways":
permission = Ci.nsIPermissionManager.ALLOW_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_TIME;
expireTime = Date.now() +
Services.prefs.getIntPref(kPrefPersistentDays) * 24 * 60 * 60 * 1000;
break;
case "block":
permission = Ci.nsIPermissionManager.PROMPT_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_NEVER;
expireTime = 0;
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":
break;
default:
Cu.reportError(Error("Unexpected plugin state: " + aNewState));
return;
}
let browser = aNotification.browser;
let contentWindow = browser.contentWindow;
if (aNewState != "continue") {
let principal = contentWindow.document.nodePrincipal;
Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString,
permission, expireType, expireTime);
if (aNewState == "block") {
return;
}
}
// Manually activate the plugins that would have been automatically
// activated.
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let plugins = cwu.plugins;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
for (let plugin of plugins) {
plugin.QueryInterface(Ci.nsIObjectLoadingContent);
// canActivatePlugin will return false if this isn't a known plugin type,
// so the pluginHost.getPermissionStringForType call is protected
if (gPluginHandler.canActivatePlugin(plugin) &&
aPluginInfo.permissionString == pluginHost.getPermissionStringForType(plugin.actualType)) {
plugin.playPlugin();
}
}
},
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPrimaryPlugin) {
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
let contentWindow = aBrowser.contentWindow;
let contentDoc = aBrowser.contentDocument;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// Pale Moon: cwu.plugins may contain non-plugin <object>s, filter them out
let plugins = cwu.plugins.filter(function(plugin) {
return (plugin.getContentTypeForMIMEType(plugin.actualType) ==
Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
});
if (plugins.length == 0) {
if (notification) {
PopupNotifications.remove(notification);
}
return;
}
let icon = 'plugins-notification-icon';
for (let plugin of plugins) {
let fallbackType = plugin.pluginFallbackType;
if (fallbackType == plugin.PLUGIN_VULNERABLE_UPDATABLE ||
fallbackType == plugin.PLUGIN_VULNERABLE_NO_UPDATE ||
fallbackType == plugin.PLUGIN_BLOCKLISTED) {
icon = 'blocked-plugins-notification-icon';
break;
}
if (fallbackType == plugin.PLUGIN_CLICK_TO_PLAY) {
let overlay = contentDoc.getAnonymousElementByAttribute(plugin, "anonid", "main");
if (!overlay || overlay.style.visibility == 'hidden') {
icon = 'alert-plugins-notification-icon';
}
}
}
let dismissed = notification ? notification.dismissed : true;
if (aPrimaryPlugin)
dismissed = false;
let primaryPluginPermission = null;
if (aPrimaryPlugin) {
primaryPluginPermission = this._getPluginInfo(aPrimaryPlugin).permissionString;
}
let options = {
dismissed: dismissed,
eventCallback: this._clickToPlayNotificationEventCallback,
primaryPlugin: primaryPluginPermission
};
PopupNotifications.show(aBrowser, "click-to-play-plugins",
"", icon,
null, null, options);
},
// Crashed-plugin observer. Notified once per plugin crash, before events
// are dispatched to individual plugin instances.
pluginCrashed : function(subject, topic, data) {
let propertyBag = subject;
if (!(propertyBag instanceof Ci.nsIPropertyBag2) ||
!(propertyBag instanceof Ci.nsIWritablePropertyBag2))
return;
},
// Crashed-plugin event listener. Called for every instance of a
// plugin in content.
pluginInstanceCrashed: function (plugin, aEvent) {
// Ensure the plugin and event are of the right type.
if (!(aEvent instanceof Ci.nsIDOMDataContainerEvent))
return;
let submittedReport = aEvent.getData("submittedCrashReport");
let doPrompt = true; // XXX followup for .getData("doPrompt");
let submitReports = true; // XXX followup for .getData("submitReports");
let pluginName = aEvent.getData("pluginName");
let pluginDumpID = aEvent.getData("pluginDumpID");
let browserDumpID = aEvent.getData("browserDumpID");
// Remap the plugin name to a more user-presentable form.
pluginName = this.makeNicePluginName(pluginName);
let messageString = gNavigatorBundle.getFormattedString("crashedpluginsMessage.title", [pluginName]);
//
// Configure the crashed-plugin placeholder.
//
// Force a layout flush so the binding is attached.
plugin.clientTop;
let doc = plugin.ownerDocument;
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let statusDiv = doc.getAnonymousElementByAttribute(plugin, "class", "submitStatus");
let crashText = doc.getAnonymousElementByAttribute(plugin, "class", "msgCrashedText");
crashText.textContent = messageString;
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
let link = doc.getAnonymousElementByAttribute(plugin, "class", "reloadLink");
this.addLinkClickCallback(link, "reloadPage", browser);
let notificationBox = gBrowser.getNotificationBox(browser);
let isShowing = true;
// Is the <object>'s size too small to hold what we want to show?
if (this.isTooSmall(plugin, overlay)) {
// First try hiding the crash report submission UI.
statusDiv.removeAttribute("status");
if (this.isTooSmall(plugin, overlay)) {
// Hide the overlay's contents. Use visibility style, so that it doesn't
// collapse down to 0x0.
overlay.style.visibility = "hidden";
isShowing = false;
}
}
if (isShowing) {
// If a previous plugin on the page was too small and resulted in adding a
// notification bar, then remove it because this plugin instance it big
// enough to serve as in-content notification.
hideNotificationBar();
doc.mozNoPluginCrashedNotification = true;
} else {
// If another plugin on the page was large enough to show our UI, we don't
// want to show a notification bar.
if (!doc.mozNoPluginCrashedNotification)
showNotificationBar(pluginDumpID, browserDumpID);
}
function hideNotificationBar() {
let notification = notificationBox.getNotificationWithValue("plugin-crashed");
if (notification)
notificationBox.removeNotification(notification, true);
}
function showNotificationBar(pluginDumpID, browserDumpID) {
// If there's already an existing notification bar, don't do anything.
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 submitLabel = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.label");
let submitKey = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.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);
// Remove the notfication when the page is reloaded.
doc.defaultView.top.addEventListener("unload", function() {
notificationBox.removeNotification(notification);
}, false);
}
}
};
@@ -0,0 +1,436 @@
# -*- 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()"/>
<command id="cmd_handleBackspace" oncommand="BrowserHandleBackspace();" />
<command id="cmd_handleShiftBackspace" oncommand="BrowserHandleShiftBackspace();" />
<command id="cmd_newNavigatorTab" oncommand="BrowserOpenTab();"/>
<command id="Browser:OpenFile" oncommand="BrowserOpenFileWindow();"/>
<command id="Browser:SavePage" oncommand="saveDocument(window.content.document);"/>
<command id="Browser:SendLink"
oncommand="MailIntegration.sendLinkForWindow(window.content);"/>
<command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
<command id="cmd_print" oncommand="PrintUtils.print();"/>
<command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
<command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/>
<command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
<command id="cmd_ToggleTabsOnTop" oncommand="TabsOnTop.toggle()"/>
<command id="cmd_CustomizeToolbars" oncommand="BrowserCustomizeToolbar()"/>
<command id="cmd_restartApplication" oncommand="restart(false);"/>
<command id="cmd_quitApplication" oncommand="goQuitApplication()"/>
<commandset id="editMenuCommands"/>
<command id="View:PageSource" oncommand="BrowserViewSourceOfDocument(content.document);" observes="isImage"/>
<command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
<command id="View:FullScreen" oncommand="BrowserFullScreen();"/>
<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"/>
<!-- 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);"/>
<command id="Browser:PrevTab" oncommand="gBrowser.tabContainer.advanceSelectedTab(-1, true);"/>
<command id="Browser:ShowAllTabs" oncommand="allTabs.open();"/>
<command id="Browser:FocusNextFrame" oncommand="focusNextFrame(event);"/>
<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="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
#ifdef MOZ_DEVTOOLS
<command id="Tools:DevToolbox" oncommand="gDevToolsBrowser.toggleToolboxCommand(gBrowser);"/>
<command id="Tools:DevToolbar" oncommand="DeveloperToolbar.toggle();" disabled="true" hidden="true"/>
<command id="Tools:DevToolbarFocus" oncommand="DeveloperToolbar.focusToggle();" disabled="true"/>
<command id="Tools:DevAppMgr" oncommand="gDevToolsBrowser.openAppManager(gBrowser);" disabled="true" hidden="true"/>
<command id="Tools:WebIDE" oncommand="gDevToolsBrowser.openWebIDE();" disabled="true" hidden="true"/>
<command id="Tools:ChromeDebugger" oncommand="BrowserToolboxProcess.init();" disabled="true" hidden="true"/>
<command id="Tools:BrowserConsole" oncommand="HUDService.openBrowserConsoleOrFocus();"/>
<command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true" hidden="true"/>
<command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();" disabled="true" hidden="true"/>
<command id="Tools:Eyedropper" oncommand="openEyedropper();"/>
#endif
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
<command id="Tools:Permissions" oncommand="BrowserOpenPermissionsMgr();"/>
<command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()" disabled="true" hidden="true"/>
#ifdef MOZ_DEVTOOLS
<command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)" disabled="true" hidden="true"/>
#endif
<command id="Tools:Sanitize"
oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
<command id="Tools:PrivateBrowsing"
oncommand="OpenBrowserWindow({private: true});"/>
<command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
<command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
<command id="Browser:ToggleAddonBar" oncommand="toggleAddonBar();"/>
</commandset>
<commandset id="placesCommands">
<command id="Browser:ShowAllBookmarks"
oncommand="PlacesCommandHook.showPlacesOrganizer('AllBookmarks');"/>
<command id="Browser:ShowAllHistory"
oncommand="PlacesCommandHook.showPlacesOrganizer('History');"/>
</commandset>
<broadcasterset id="mainBroadcasterSet">
<broadcaster id="viewBookmarksSidebar" autoCheck="false" sidebartitle="&bookmarksButton.label;"
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
oncommand="toggleSidebar('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="toggleSidebar('viewHistorySidebar');"/>
<broadcaster id="viewWebPanelsSidebar" autoCheck="false"
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/web-panels.xul"
oncommand="toggleSidebar('viewWebPanelsSidebar');"/>
<!-- 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="isFrameImage"/>
<broadcaster id="singleFeedMenuitemState" disabled="true"/>
<broadcaster id="multipleFeedsMenuState" hidden="true"/>
#ifdef MOZ_SERVICES_SYNC
<broadcaster id="sync-setup-state"/>
<broadcaster id="sync-syncnow-state"/>
#endif
<broadcaster id="workOfflineMenuitemState"/>
#ifdef MOZ_DEVTOOLS
<!-- DevTools broadcasters -->
<broadcaster id="devtoolsMenuBroadcaster_DevToolbox"
label="&devToolboxMenuItem.label;"
type="checkbox" autocheck="false"
command="Tools:DevToolbox"
key="key_devToolbox"/>
<broadcaster id="devtoolsMenuBroadcaster_DevToolbar"
label="&devToolbarMenu.label;"
type="checkbox" autocheck="false"
command="Tools:DevToolbar"
key="key_devToolbar"/>
<broadcaster id="devtoolsMenuBroadcaster_DevAppMgr"
label="&devAppMgrMenu.label;"
command="Tools:DevAppMgr"/>
<broadcaster id="devtoolsMenuBroadcaster_webide"
label="&webide.label;"
command="Tools:WebIDE"
key="key_webide"/>
<broadcaster id="devtoolsMenuBroadcaster_ChromeDebugger"
label="&chromeDebuggerMenu.label;"
command="Tools:ChromeDebugger"/>
<broadcaster id="devtoolsMenuBroadcaster_BrowserConsole"
label="&browserConsoleCmd.label;"
key="key_browserConsole"
command="Tools:BrowserConsole"/>
<broadcaster id="devtoolsMenuBroadcaster_Scratchpad"
label="&scratchpad.label;"
command="Tools:Scratchpad"
key="key_scratchpad"/>
<broadcaster id="devtoolsMenuBroadcaster_ResponsiveUI"
label="&responsiveDesignTool.label;"
type="checkbox" autocheck="false"
command="Tools:ResponsiveUI"
key="key_responsiveUI"/>
<broadcaster id="devtoolsMenuBroadcaster_Eyedropper"
label="&eyedropper.label;"
type="checkbox" autocheck="false"
command="Tools:Eyedropper"/>
#endif
<broadcaster id="devtoolsMenuBroadcaster_PageSource"
label="&pageSourceCmd.label;"
key="key_viewSource"
command="View:PageSource"/>
<broadcaster id="devtoolsMenuBroadcaster_ErrorConsole"
label="&errorConsoleCmd.label;"
command="Tools:ErrorConsole"/>
<broadcaster id="devtoolsMenuBroadcaster_GetMoreTools"
label="&getMoreDevtoolsCmd.label;"
oncommand="openUILinkIn(gPrefService.getCharPref('browser.getdevtools.url'), 'tab');"/>
#ifdef MOZ_DEVTOOLS
<broadcaster id="devtoolsMenuBroadcaster_connect"
label="&devtoolsConnect.label;"
command="Tools:DevToolsConnect"/>
#endif
</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_newNavigatorTab"/>
<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"/>
#ifdef MOZ_DEVTOOLS
<key id="key_browserConsole" key="&browserConsoleCmd.commandkey;" command="Tools:BrowserConsole" modifiers="accel,shift"/>
<key id="key_devToolbox" keycode="VK_F12" keytext="F12" command="Tools:DevToolbox"/>
<key id="key_devToolbar" keycode="&devToolbar.keycode;" modifiers="shift"
keytext="&devToolbar.keytext;" command="Tools:DevToolbarFocus"/>
<key id="key_responsiveUI" key="&responsiveDesignTool.commandkey;" command="Tools:ResponsiveUI"
#ifdef XP_MACOSX
modifiers="accel,alt"
#else
modifiers="accel,shift"
#endif
/>
<key id="key_scratchpad" keycode="&scratchpad.keycode;" modifiers="shift"
keytext="&scratchpad.keytext;" command="Tools:Scratchpad"/>
#endif
<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_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 keycode="VK_F6" command="Browser:FocusNextFrame"/>
<key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/>
<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 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"/>
<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
# Navigation cancel keys: Esc performs a cancel on loading (i.e.: stop button equivalent)
# Shift-Esc (and similar Shift-modified stop on Mac) performs a "superstop": this halts all
# networking requests, XHR, animated gifs, etc.
<key id="key_stop" keycode="VK_ESCAPE" command="Browser:Stop"/>
<key id="key_stop_all" keycode="VK_ESCAPE" modifiers="shift" oncommand="BrowserStop();"/>
#ifdef XP_MACOSX
<key id="key_stop_mac" modifiers="accel" key="&stopCmd.macCommandKey;" command="Browser:Stop"/>
<key id="key_stop_all_mac" modifiers="accel,shift" key="&stopCmd.macCommandKey;" oncommand="BrowserStop();"/>
#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"/>
#endif
#ifdef 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__"/>
<key id="key_toggleAddonBar" command="Browser:ToggleAddonBar" key="&toggleAddonBarCmd.key;" modifiers="accel"/>
</keyset>
# Used by baseMenuOverlay
#ifdef XP_MACOSX
<commandset id="baseMenuCommandSet" />
#endif
<keyset id="baseMenuKeyset" />
@@ -0,0 +1,470 @@
# 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
let 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 = "";
try {
firstSync = Services.prefs.getCharPref("services.sync.firstSync");
} catch (e) { }
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");
},
// Functions called by observers
onActivityStart: function SUI_onActivityStart() {
if (!gBrowser)
return;
let button = document.getElementById("sync-button");
if (!button)
return;
button.setAttribute("status", "active");
},
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;
try {
lastSync = Services.prefs.getCharPref("services.sync.lastSync");
}
catch (e) { };
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");
});
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,75 @@
<?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>
<binding id="allTabs-preview" extends="chrome://global/content/bindings/button.xml#button-base">
<content pack="center" align="center">
<xul:stack>
<xul:vbox class="allTabs-preview-inner" align="center" pack="center">
<xul:hbox class="tabPreview-canvas" xbl:inherits="style=canvasstyle">
<children/>
</xul:hbox>
<xul:label flex="1" xbl:inherits="value=label,crop" class="allTabs-preview-label plain"/>
</xul:vbox>
<xul:hbox class="allTabs-favicon-container">
<xul:image class="allTabs-favicon" xbl:inherits="src=image"/>
</xul:hbox>
</xul:stack>
</content>
<handlers>
<handler event="command" action="allTabs.pick(this);"/>
<handler event="click" button="1" action="gBrowser.removeTab(this._tab);"/>
<handler event="dragstart"><![CDATA[
event.dataTransfer.mozSetDataAt("application/x-moz-node", this._tab, 0);
]]></handler>
<handler event="dragover"><![CDATA[
let tab = event.dataTransfer.mozGetDataAt("application/x-moz-node", 0);
if (tab && tab.parentNode == gBrowser.tabContainer)
event.preventDefault();
]]></handler>
<handler event="drop"><![CDATA[
let tab = event.dataTransfer.mozGetDataAt("application/x-moz-node", 0);
if (tab && tab.parentNode == gBrowser.tabContainer) {
let newIndex = Array.indexOf(gBrowser.tabs, this._tab);
gBrowser.moveTabTo(tab, newIndex);
}
]]></handler>
</handlers>
</binding>
</bindings>
@@ -0,0 +1,198 @@
#ifdef 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
/**
* Keeps thumbnails of open web pages up-to-date.
*/
let 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() {
// Bug 863512 - Make page thumbnails work in electrolysis
if (gMultiProcessBrowser)
return;
try {
if (Services.prefs.getBoolPref("browser.pagethumbnails.capturing_disabled"))
return;
} catch (e) {}
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() {
// Bug 863512 - Make page thumbnails work in electrolysis
if (gMultiProcessBrowser)
return;
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([browser.currentURI.spec for (browser of gBrowser.browsers)]);
},
/**
* 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) {
if (this._shouldCapture(aBrowser))
PageThumbs.captureAndStore(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) {
// Capture only if it's the currently selected tab.
if (aBrowser != gBrowser.selectedBrowser)
return false;
// Don't capture in per-window private browsing mode.
if (PrivateBrowsingUtils.isWindowPrivate(window))
return false;
let doc = aBrowser.contentDocument;
// FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as
// that currently regresses Talos SVG tests.
if (doc instanceof SVGDocument || doc instanceof XMLDocument)
return false;
// There's no point in taking screenshot of loading pages.
if (aBrowser.docShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
return false;
// Don't take screenshots of about: pages.
if (aBrowser.currentURI.schemeIs("about"))
return false;
let channel = aBrowser.docShell.currentDocumentChannel;
// No valid document channel. We shouldn't take a screenshot.
if (!channel)
return false;
// Don't take screenshots of internally redirecting about: pages.
// This includes error pages.
let uri = channel.originalURI;
if (uri.schemeIs("about"))
return false;
let httpChannel;
try {
httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
} catch (e) { /* Not an HTTP channel. */ }
if (httpChannel) {
// Continue only if we have a 2xx status code.
try {
if (Math.floor(httpChannel.responseStatus / 100) != 2)
return false;
} catch (e) {
// Can't get response information from the httpChannel
// because mResponseHead is not available.
return false;
}
// Cache-Control: no-store.
if (httpChannel.isNoStoreResponse())
return false;
// Don't capture HTTPS pages unless the user explicitly enabled it.
if (uri.schemeIs("https") && !this._sslDiskCacheEnabled)
return false;
}
return true;
},
_clearTimeout: function Thumbnails_clearTimeout(aBrowser) {
if (this._timeouts.has(aBrowser)) {
aBrowser.removeEventListener("scroll", this, false);
clearTimeout(this._timeouts.get(aBrowser));
this._timeouts.delete(aBrowser);
}
}
};
@@ -0,0 +1,204 @@
/* 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/. */
#main-window::after {
content: attr(title);
line-height: 50px;
max-height: 50px;
overflow: -moz-hidden-unscrollable;
pointer-events: none;
position: fixed;
word-wrap: break-word;
-moz-hyphens: auto;
color: CaptionText;
font-weight: bold;
text-align: left;
}
#main-window:-moz-window-inactive::after {
color: InactiveCaptionText;
}
/* Win10 doesn't respond to inactive caption, so dim it instead */
@media (-moz-os-version: windows-win10) {
#main-window:-moz-window-inactive::after {
opacity: 0.5;
}
}
/* Hide in fullscreen/TiT mode */
#main-window[inFullscreen="true"]::after,
#main-window[sizemode="maximized"][tabsintitlebar="true"]::after,
#main-window:not([chromemargin])::after {
opacity: 0 !important;
}
#main-window::after {
padding: 0 132px; /* AppMenu button/wincontrols width offset */
left: 0;
right: 0;
}
#main-window[privatebrowsingmode=temporary]::after {
padding: 0px 132px 0px 152px; /* AppMenu button width offset for PB mode */
}
#main-window[sizemode="normal"]::after {
left: -12px;
right: -12px;
}
/* Lightweight Themes */
#main-window:-moz-lwtheme::after {
color: inherit;
text-shadow: inherit;
}
/* Windows Classic theme */
@media all and (-moz-windows-classic) {
#main-window::after {
top: -13px;
text-shadow: none !important;
background-position: 2px 18px;
}
}
/* Windows Aero (Vista, non-glass 7/8) */
@media all and (-moz-windows-theme: aero) {
#main-window::after {
top: -11px;
font-weight: normal;
text-shadow: none;
background-position: 2px 17px;
}
#main-window[sizemode="maximized"]::after {
top: -7px;
}
}
/* Windows Aero Glass */
@media (-moz-windows-glass) {
#main-window::after {
top: -13px;
color: black;
text-shadow: rgba(255,255,255,.6) 7px -1px 12px,
rgba(255,255,255,.6) 6px -1px 13px,
rgba(255,255,255,.9) 5px -1px 14px,
rgba(255,255,255,.6) -7px -1px 12px,
rgba(255,255,255,.6) -6px -1px 13px,
rgba(255,255,255,.9) -5px -1px 14px;
z-index: -99999;
background-position: 2px 18px;
font-weight: bold;
}
#main-window[sizemode="maximized"]::after {
top: -7px;
}
#main-window:-moz-window-inactive::after {
opacity: .9;
color: black;
text-shadow: rgba(255,255,255,.7) 7px -1px 12px,
rgba(255,255,255,.5) 6px -1px 13px,
rgba(255,255,255,.5) 5px -1px 14px,
rgba(255,255,255,.7) -7px -1px 12px,
rgba(255,255,255,.5) -6px -1px 13px,
rgba(255,255,255,.5) -5px -1px 14px;
}
}
/* Generic other themes */
@media all and (-moz-windows-theme: generic) {
#main-window::after {
font-family: trebuchet MS;
font-size: 13px;
text-shadow: 1px 1px rgba(0, 0, 0, .2);
top: -9px;
background-position: 2px 16px;
}
#main-window:-moz-window-inactive::after {
text-shadow: none;
}
}
/* Compositor style for Win 8/10 */
@media all and (-moz-windows-compositor) {
@media not all and (-moz-windows-glass) {
#main-window::after {
background-position: 4px 17px;
top: -13px;
}
@media (-moz-os-version: windows-win8) {
#main-window::after {
font-size: 15px;
text-align: center;
}
#main-window[darkwindowframe="true"]:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
/* Dark window frame/accent color on Win 8 */
color: white;
}
}
@media (-moz-os-version: windows-win10) {
#main-window::after {
text-align: left;
}
@media (-moz-windows-accent-color-applies: 0) {
#main-window:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
/* Default Windows 10 styling is white - apply black text styling */
color: black;
}
}
@media (-moz-windows-accent-color-applies) {
#main-window:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
/* Accent color is applied - use the associated text styling */
color: -moz-win-accentcolortext;
}
}
}
#main-window[sizemode="maximized"]::after {
top: -5px;
}
}
}
/* Hide for small windows */
@media not all and (min-width: 320px) {
#main-window::after {
opacity: 0 !important;
}
}
@@ -0,0 +1,55 @@
# -*- Mode: javascript; 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/.
let WebrtcIndicator = {
init: function () {
let temp = {};
Cu.import("resource:///modules/webrtcUI.jsm", temp);
this.UIModule = temp.webrtcUI;
this.updateButton();
},
get button() {
delete this.button;
return this.button = document.getElementById("webrtc-status-button");
},
updateButton: function () {
this.button.hidden = !this.UIModule.showGlobalIndicator;
},
fillPopup: function (aPopup) {
this._menuitemData = new WeakMap;
for (let streamData of this.UIModule.activeStreams) {
let menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", streamData.uri);
menuitem.setAttribute("tooltiptext", streamData.uri);
this._menuitemData.set(menuitem, streamData);
aPopup.appendChild(menuitem);
}
},
clearPopup: function (aPopup) {
while (aPopup.lastChild)
aPopup.removeChild(aPopup.lastChild);
},
menuCommand: function (aMenuitem) {
let streamData = this._menuitemData.get(aMenuitem);
if (!streamData)
return;
let browserWindow = streamData.browser.ownerDocument.defaultView;
if (streamData.tab) {
browserWindow.gBrowser.selectedTab = streamData.tab;
} else {
streamData.browser.focus();
}
browserWindow.focus();
}
}
@@ -0,0 +1,693 @@
/* 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/. */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
searchbar {
-moz-binding: url("chrome://browser/content/search/search.xml#searchbar");
}
browser[remote="true"] {
-moz-binding: url("chrome://global/content/bindings/remote-browser.xml#remote-browser");
}
tabbrowser {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
}
.tabbrowser-tabs {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
}
#tabbrowser-tabs:not([overflow="true"]) ~ #alltabs-button,
#tabbrowser-tabs:not([overflow="true"]) + #new-tab-button,
#tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
#TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
#TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
visibility: collapse;
}
#alltabs-button { /* Pale Moon: Always show this button! (less jumpy UI) */
visibility: visible !important;
}
#tabbrowser-tabs:not([overflow="true"])[using-closing-tabs-spacer] ~ #alltabs-button {
visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
}
.tabbrowser-tab {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
}
.tabbrowser-tab:not([pinned]) {
-moz-box-flex: 100;
max-width: 250px;
min-width: 100px;
width: 0;
transition: min-width 175ms ease-out,
max-width 200ms ease-out,
opacity 80ms ease-out 20ms /* hide the tab for the first 20ms of the max-width transition */;
}
.tabbrowser-tab:not([pinned]):not([fadein]) {
max-width: 0.1px;
min-width: 0.1px;
opacity: 0 !important;
transition: min-width 175ms ease-out,
max-width 200ms ease-out,
opacity 80ms ease-out 180ms /* hide the tab for the last 20ms of the max-width transition */;
}
.tab-throbber:not([fadein]):not([pinned]),
.tab-label:not([fadein]):not([pinned]),
.tab-icon-image:not([fadein]):not([pinned]),
.tab-close-button:not([fadein]):not([pinned]) {
display: none;
}
.tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
position: fixed !important;
display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
}
.tabbrowser-tabs[movingtab] > .tabbrowser-tab[selected] {
position: relative;
z-index: 2;
pointer-events: none; /* avoid blocking dragover events on scroll buttons */
}
.tabbrowser-tabs[movingtab] > .tabbrowser-tab[fadein]:not([selected]) {
transition: transform 200ms ease-out;
}
#alltabs-popup {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
}
toolbar[printpreview="true"] {
-moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
}
#toolbar-menubar {
-moz-box-ordinal-group: 5;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
-moz-box-ordinal-group: 50;
}
#TabsToolbar {
-moz-box-ordinal-group: 100;
}
#TabsToolbar[tabsontop="true"] {
-moz-box-ordinal-group: 10;
}
%ifdef CAN_DRAW_IN_TITLEBAR
#main-window[inFullscreen] > #titlebar,
#main-window[inFullscreen] .titlebar-placeholder,
#main-window:not([tabsintitlebar]) .titlebar-placeholder {
display: none;
}
#titlebar {
-moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
}
#titlebar-spacer {
pointer-events: none;
}
#main-window[tabsintitlebar] #appmenu-button-container,
#main-window[tabsintitlebar] #titlebar-buttonbox {
position: relative;
}
%endif
#main-window[inDOMFullscreen] #sidebar-box,
#main-window[inDOMFullscreen] #sidebar-splitter {
visibility: collapse;
}
.bookmarks-toolbar-customize,
#wrapper-personal-bookmarks > #personal-bookmarks > #PlacesToolbar > hbox > #PlacesToolbarItems {
display: none;
}
#wrapper-personal-bookmarks[place="toolbar"] > #personal-bookmarks > #PlacesToolbar > .bookmarks-toolbar-customize {
display: -moz-box;
}
#main-window[disablechrome] #navigator-toolbox[tabsontop="true"] > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
visibility: collapse;
}
#wrapper-urlbar-container #urlbar-container > #urlbar > toolbarbutton,
#urlbar-container:not([combined]) > #urlbar > toolbarbutton,
#urlbar-container[combined] + #reload-button + #stop-button,
#urlbar-container[combined] + #reload-button,
toolbar:not([mode="icons"]) > #urlbar-container > #urlbar > toolbarbutton,
toolbar[mode="icons"] > #urlbar-container > #urlbar > #urlbar-reload-button:not([displaystop]) + #urlbar-stop-button,
toolbar[mode="icons"] > #urlbar-container > #urlbar > #urlbar-reload-button[displaystop],
toolbar[mode="icons"] > #reload-button:not([displaystop]) + #stop-button,
toolbar[mode="icons"] > #reload-button[displaystop] {
visibility: collapse;
}
#feed-button > .toolbarbutton-menu-dropmarker {
display: none;
}
#feed-menu > .feed-menuitem:-moz-locale-dir(rtl) {
direction: rtl;
}
#main-window:-moz-lwtheme {
background-repeat: no-repeat;
background-position: top right;
}
%ifdef XP_MACOSX
#main-window[inFullscreen="true"] {
padding-top: 0; /* override drawintitlebar="true" */
}
%endif
#browser-bottombox[lwthemefooter="true"] {
background-repeat: no-repeat;
background-position: bottom left;
}
splitmenu {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#splitmenu");
}
.splitmenu-menuitem {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem");
list-style-image: inherit;
-moz-image-region: inherit;
}
.splitmenu-menuitem[iconic="true"] {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
.splitmenu-menu > .menu-text,
:-moz-any(.splitmenu-menu, .splitmenu-menuitem) > .menu-accel-container,
#appmenu-editmenu > .menu-text,
#appmenu-editmenu > .menu-accel-container {
display: none;
}
.menuitem-tooltip {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-tooltip");
}
.menuitem-iconic-tooltip,
.menuitem-tooltip[type="checkbox"],
.menuitem-tooltip[type="radio"] {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-iconic-tooltip");
}
%ifdef MENUBAR_CAN_AUTOHIDE
%ifndef CAN_DRAW_IN_TITLEBAR
#appmenu-toolbar-button > .toolbarbutton-text {
display: -moz-box;
}
%endif
#appmenu_offlineModeRecovery:not([checked=true]) {
display: none;
}
%endif
/* Hide menu elements intended for keyboard access support */
#main-menubar[openedwithkey=false] .show-only-for-keyboard {
display: none;
}
/* ::::: location bar ::::: */
#urlbar {
-moz-binding: url(chrome://browser/content/urlbarBindings.xml#urlbar);
}
.ac-url-text:-moz-locale-dir(rtl),
.ac-title:-moz-locale-dir(rtl) > description {
direction: ltr !important;
}
/* For results that are actions, their description text is shown instead of
the URL - this needs to follow the locale's direction, unlike URLs. */
panel:not([noactions]) > richlistbox > richlistitem[type~="action"]:-moz-locale-dir(rtl) > .ac-url-box {
direction: rtl;
}
panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-url > .ac-action-text,
panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-action-icon {
visibility: collapse;
}
panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-url > .ac-url-text {
visibility: visible;
}
#urlbar:not([actiontype]) > #urlbar-display-box {
display: none;
}
#wrapper-urlbar-container > #urlbar-container > #urlbar {
-moz-user-input: disabled;
cursor: -moz-grab;
}
#PopupAutoComplete {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup");
}
#PopupAutoCompleteRichResult {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
}
/* Pale Moon: Address bar: Feeds */
#ub-feed-button > .button-box > .box-inherit > .button-text,
#ub-feed-button > .button-box > .button-menu-dropmarker {
display: none;
}
#ub-feed-menu > .feed-menuitem:-moz-locale-dir(rtl) {
direction: rtl;
}
#urlbar-container[combined] > #urlbar > #urlbar-icons > #go-button,
#urlbar[pageproxystate="invalid"] > #urlbar-icons > .urlbar-icon:not(#go-button),
#urlbar[pageproxystate="valid"] > #urlbar-icons > #go-button,
#urlbar[pageproxystate="invalid"][focused="true"] > #urlbar-go-button ~ toolbarbutton,
#urlbar[pageproxystate="valid"] > #urlbar-go-button,
#urlbar:not([focused="true"]) > #urlbar-go-button {
visibility: collapse;
}
#urlbar[pageproxystate="invalid"] > #identity-box > #identity-icon-labels {
visibility: collapse;
}
#urlbar[pageproxystate="invalid"] > #identity-box {
pointer-events: none;
}
#identity-icon-labels {
max-width: 18em;
}
#identity-icon-country-label {
direction: ltr;
}
#identity-box.verifiedIdentity > #identity-icon-labels > #identity-icon-label {
-moz-margin-end: 0.25em !important;
}
#wrapper-search-container > #search-container > #searchbar > .searchbar-textbox > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input {
visibility: hidden;
}
/* ::::: Unified Back-/Forward Button ::::: */
#back-button > .toolbarbutton-menu-dropmarker,
#forward-button > .toolbarbutton-menu-dropmarker {
display: none;
}
.unified-nav-current {
font-weight: bold;
}
toolbarbutton.bookmark-item {
max-width: 13em;
}
%ifdef MENUBAR_CAN_AUTOHIDE
#toolbar-menubar:not([autohide="true"]) ~ toolbar > #bookmarks-menu-button,
#toolbar-menubar:not([autohide="true"]) > #bookmarks-menu-button,
#toolbar-menubar:not([autohide="true"]) ~ toolbar > #history-menu-button,
#toolbar-menubar:not([autohide="true"]) > #history-menu-button {
display: none;
}
%endif
#editBMPanel_tagsSelector {
/* override default listbox width from xul.css */
width: auto;
}
menupopup[emptyplacesresult="true"] > .hide-if-empty-places-result {
display: none;
}
menuitem.spell-suggestion {
font-weight: bold;
}
#sidebar-header > .tabs-closebutton {
-moz-user-focus: normal;
}
/* apply Fitts' law to the notification bar's close button */
window[sizemode="maximized"] #content .notification-inner {
border-right: 0px !important;
}
/* Hide extension toolbars that neglected to set the proper class */
window[chromehidden~="location"][chromehidden~="toolbar"] toolbar:not(.chromeclass-menubar),
window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(#nav-bar):not(#TabsToolbar):not(#print-preview-toolbar):not(.chromeclass-menubar) {
display: none;
}
#navigator-toolbox ,
#status-bar ,
#mainPopupSet {
min-width: 1px;
}
%ifdef MOZ_SERVICES_SYNC
/* Sync notification UI */
#sync-notifications {
-moz-binding: url("chrome://browser/content/sync/notification.xml#notificationbox");
overflow-y: visible !important;
}
#sync-notifications notification {
-moz-binding: url("chrome://browser/content/sync/notification.xml#notification");
}
%endif
/* History Swipe Animation */
#historySwipeAnimationContainer {
overflow: hidden;
}
#historySwipeAnimationPreviousPage,
#historySwipeAnimationCurrentPage,
#historySwipeAnimationNextPage {
background: none top left no-repeat white;
}
#historySwipeAnimationPreviousPage {
background-image: -moz-element(#historySwipeAnimationPreviousPageSnapshot);
}
#historySwipeAnimationCurrentPage {
background-image: -moz-element(#historySwipeAnimationCurrentPageSnapshot);
}
#historySwipeAnimationNextPage {
background-image: -moz-element(#historySwipeAnimationNextPageSnapshot);
}
/* Identity UI */
#identity-popup-content-box.unknownIdentity > #identity-popup-connectedToLabel ,
#identity-popup-content-box.unknownIdentity > #identity-popup-runByLabel ,
#identity-popup-content-box.unknownIdentity > #identity-popup-content-host ,
#identity-popup-content-box.unknownIdentity > #identity-popup-content-owner ,
#identity-popup-content-box.verifiedIdentity > #identity-popup-connectedToLabel2 ,
#identity-popup-content-box.verifiedDomain > #identity-popup-connectedToLabel2 {
display: none;
}
/* Full Screen UI */
#fullscr-toggler {
height: 1px;
background: black;
}
#full-screen-warning-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2147483647 !important;
}
#full-screen-warning-container[fade-warning-out] {
transition-property: opacity !important;
transition-duration: 500ms !important;
opacity: 0.0;
}
/* When the modal fullscreen approval UI is showing, don't allow interaction
with the page, but when we're just showing the warning upon entering
fullscreen on an already approved page, do allow interaction with the page.
*/
#full-screen-warning-container:not([obscure-browser]) {
pointer-events: none;
}
#full-screen-warning-message {
/* We must specify a max-width, otherwise word-wrap:break-word doesn't
work in descendant <description> and <label> elements. Bug 630864. */
max-width: 800px;
}
#full-screen-domain-text,
#full-screen-remember-decision > .checkbox-label-box > .checkbox-label {
word-wrap: break-word;
/* We must specify a min-width, otherwise word-wrap:break-word doesn't work. Bug 630864. */
min-width: 1px;
}
#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-icon {
display: -moz-box;
}
#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text {
display: none;
}
/* ::::: Keyboard UI Panel ::::: */
.KUI-panel-closebutton {
-moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
}
:-moz-any(.ctrlTab-preview, .allTabs-preview) > html|img,
:-moz-any(.ctrlTab-preview, .allTabs-preview) > html|canvas {
min-width: inherit;
max-width: inherit;
min-height: inherit;
max-height: inherit;
}
.ctrlTab-favicon-container,
.allTabs-favicon-container {
-moz-box-align: start;
%ifdef XP_MACOSX
-moz-box-pack: end;
%else
-moz-box-pack: start;
%endif
}
.ctrlTab-favicon,
.allTabs-favicon {
width: 16px;
height: 16px;
}
/* ::::: Ctrl-Tab Panel ::::: */
.ctrlTab-preview {
-moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#ctrlTab-preview");
}
/* ::::: All Tabs Panel ::::: */
.allTabs-preview {
-moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#allTabs-preview");
}
#allTabs-tab-close-button {
-moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
margin: 0;
}
/* notification anchors should only be visible when their associated
notifications are */
.notification-anchor-icon {
-moz-user-focus: normal;
}
.notification-anchor-icon:not([showing]) {
display: none;
}
/* This was added with the identity toolkit, does it have any other purpose? */
#notification-popup .text-link.custom-link {
-moz-binding: url("chrome://global/content/bindings/text.xml#text-label");
text-decoration: none;
}
#invalid-form-popup > description {
max-width: 280px;
}
.form-validation-anchor {
/* should occupy space but not be visible */
opacity: 0;
visibility: hidden;
pointer-events: none;
}
#addon-progress-notification {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#addon-progress-notification");
}
#click-to-play-plugins-notification {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#click-to-play-plugins-notification");
}
.plugin-popupnotification-centeritem {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#plugin-popupnotification-center-item");
}
/* override hidden="true" for the status bar compatibility shim
in case it was persisted for the real status bar */
#status-bar {
display: -moz-box;
}
/* Remove the resizer from the statusbar compatibility shim */
#status-bar[hideresizer] > .statusbar-resizerpanel {
display: none;
}
browser[tabmodalPromptShowing] {
-moz-user-focus: none !important;
}
/* Status panel */
statuspanel {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#statuspanel");
position: fixed;
margin-top: -3em;
left: 0;
max-width: calc(100% - 5px);
pointer-events: none;
}
statuspanel:-moz-locale-dir(ltr)[mirror],
statuspanel:-moz-locale-dir(rtl):not([mirror]) {
left: auto;
right: 0;
}
statuspanel[sizelimit] {
max-width: 50%;
}
statuspanel[type=status] {
min-width: 23em;
}
@media all and (max-width: 800px) {
statuspanel[type=status] {
min-width: 33%;
}
}
statuspanel[type=overLink] {
transition: opacity 120ms ease-out;
direction: ltr;
}
statuspanel[inactive] {
transition: none;
opacity: 0;
}
statuspanel[inactive][previoustype=overLink] {
transition: opacity 200ms ease-out;
}
.statuspanel-inner {
height: 3em;
width: 100%;
-moz-box-align: end;
}
.panel-inner-arrowcontentfooter[footertype="promobox"] {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#promobox");
}
/* highlighter */
%include highlighter.css
/* gcli */
html|*#gcli-tooltip-frame,
html|*#gcli-output-frame,
#gcli-output,
#gcli-tooltip {
overflow-x: hidden;
}
.gclitoolbar-input-node,
.gclitoolbar-complete-node {
direction: ltr;
}
#developer-toolbar-toolbox-button[error-count] > .toolbarbutton-icon {
display: none;
}
#developer-toolbar-toolbox-button[error-count]:before {
content: attr(error-count);
display: -moz-box;
-moz-box-pack: center;
}
/* Responsive Mode */
.browserContainer[responsivemode] {
overflow: auto;
}
.devtools-responsiveui-toolbar:-moz-locale-dir(rtl) {
-moz-box-pack: end;
}
.browserStack[responsivemode] {
transition-duration: 200ms;
transition-timing-function: linear;
}
.browserStack[responsivemode] {
transition-property: min-width, max-width, min-height, max-height;
}
.browserStack[responsivemode][notransition] {
transition: none;
}
.toolbarbutton-badge[badge]:not([badge=""])::after {
content: attr(badge);
}
toolbarbutton[type="badged"] {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#toolbarbutton-badged");
}
/* Strict icon size for PMkit 'ui/button' */
toolbarbutton[pmkit-button="true"] > .toolbarbutton-badge-container > .toolbarbutton-icon {
width: 16px;
height: 16px;
}
/* Remove white bar at the bottom of the screen when watching HTML5 video in fullscreen */
#main-window[inFullscreen] #global-notificationbox,
#main-window[inFullscreen] #high-priority-global-notificationbox {
visibility: collapse;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,12 @@
<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"/>
@@ -0,0 +1,64 @@
/* -*- Mode: javascript; 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/. */
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
"resource://gre/modules/BrowserUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerContent",
"resource://gre/modules/LoginManagerContent.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "InsecurePasswordUtils",
"resource://gre/modules/InsecurePasswordUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FormSubmitObserver",
"resource:///modules/FormSubmitObserver.jsm");
// Bug 671101 - directly using webNavigation in this context
// causes docshells to leak
this.__defineGetter__("webNavigation", function () {
return docShell.QueryInterface(Ci.nsIWebNavigation);
});
addMessageListener("WebNavigation:LoadURI", function (message) {
let flags = message.json.flags || webNavigation.LOAD_FLAGS_NONE;
webNavigation.loadURI(message.json.uri, flags, null, null, null);
});
// TabChildGlobal
var global = this;
// Load the form validation popup handler
var formSubmitObserver = new FormSubmitObserver(content, this);
addMessageListener("Browser:HideSessionRestoreButton", function (message) {
// Hide session restore button on about:home
let doc = content.document;
let container;
if (doc.documentURI.toLowerCase() == "about:home" &&
(container = doc.getElementById("sessionRestoreContainer"))){
container.hidden = true;
}
});
addEventListener("DOMFormHasPassword", function(event) {
InsecurePasswordUtils.checkForInsecurePasswords(event.target);
LoginManagerContent.onFormPassword(event);
});
addEventListener("DOMAutoComplete", function(event) {
LoginManagerContent.onUsernameInput(event);
});
addEventListener("blur", function(event) {
LoginManagerContent.onUsernameInput(event);
});
// Lazily load the finder code
addMessageListener("Finder:Initialize", function () {
let {RemoteFinderListener} = Cu.import("resource://gre/modules/RemoteFinder.jsm", {});
new RemoteFinderListener(global);
});
@@ -0,0 +1,32 @@
<?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/.
<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
<overlay id="downloadManagerOverlay"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<window id="downloadManager">
#include browserMountPoints.inc
<script type="application/javascript"><![CDATA[
window.addEventListener("load", function(event) {
// Bug 405696: Map Edit -> Find command to the download manager's command
var findMenuItem = document.getElementById("menu_find");
findMenuItem.setAttribute("command", "cmd_findDownload");
findMenuItem.setAttribute("key", "key_findDownload");
// Bug 429614: Map Edit -> Select All command to download manager's command
let selectAllMenuItem = document.getElementById("menu_selectAll");
selectAllMenuItem.setAttribute("command", "cmd_selectAllDownloads");
selectAllMenuItem.setAttribute("key", "key_selectAllDownloads");
}, false);
]]></script>
</window>
</overlay>
@@ -0,0 +1,13 @@
# -*- 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/.
<script type="application/javascript" src="chrome://global/content/printUtils.js"/>
<script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/>
<script type="application/javascript" src="chrome://browser/content/places/browserPlacesViews.js"/>
<script type="application/javascript" src="chrome://browser/content/browser.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/downloads.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/indicator.js"/>
<script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/>
<script type="application/javascript" src="chrome://global/content/viewSourceUtils.js"/>
@@ -0,0 +1,19 @@
<?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/.
#ifdef XP_MACOSX
<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
<window id="main-window"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
#include browserMountPoints.inc
</window>
#endif
@@ -0,0 +1,105 @@
/* 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/. */
.highlighter-container {
pointer-events: none;
}
.highlighter-controls {
position: absolute;
top: 0;
left: 0;
}
.highlighter-outline-container {
overflow: hidden;
position: relative;
}
.highlighter-outline {
position: absolute;
}
.highlighter-outline[hidden] {
opacity: 0;
pointer-events: none;
display: -moz-box;
}
.highlighter-outline:not([disable-transitions]) {
transition-property: opacity, top, left, width, height;
transition-duration: 0.1s;
transition-timing-function: linear;
}
/*
* Node Infobar
*/
.highlighter-nodeinfobar-container {
position: absolute;
max-width: 95%;
}
.highlighter-nodeinfobar-container[hidden] {
opacity: 0;
pointer-events: none;
display: -moz-box;
}
.highlighter-nodeinfobar-container:not([disable-transitions]),
.highlighter-nodeinfobar-container[disable-transitions][force-transitions] {
transition-property: transform, opacity, top, left;
transition-duration: 0.1s;
transition-timing-function: linear;
}
.highlighter-nodeinfobar-text {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
direction: ltr;
}
.highlighter-nodeinfobar-button > .toolbarbutton-text {
display: none;
}
.highlighter-nodeinfobar-container:not([locked]):not(:hover) > .highlighter-nodeinfobar > .highlighter-nodeinfobar-button {
visibility: hidden;
}
.highlighter-nodeinfobar-container[locked] > .highlighter-nodeinfobar,
.highlighter-nodeinfobar-container:not([locked]):hover > .highlighter-nodeinfobar {
pointer-events: auto;
}
html|*.highlighter-nodeinfobar-id,
html|*.highlighter-nodeinfobar-classes,
html|*.highlighter-nodeinfobar-pseudo-classes,
html|*.highlighter-nodeinfobar-tagname {
-moz-user-select: text;
-moz-user-focus: normal;
cursor: text;
}
.highlighter-nodeinfobar-arrow {
display: none;
}
.highlighter-nodeinfobar-container[position="top"]:not([hide-arrow]) > .highlighter-nodeinfobar-arrow-bottom {
display: block;
}
.highlighter-nodeinfobar-container[position="bottom"]:not([hide-arrow]) > .highlighter-nodeinfobar-arrow-top {
display: block;
}
.highlighter-nodeinfobar-container[disabled] {
visibility: hidden;
}
html|*.highlighter-nodeinfobar-tagname {
text-transform: lowercase;
}
@@ -0,0 +1,18 @@
<?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/.
<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
<overlay id="jsConsoleOverlay"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<window id="JSConsoleWindow">
#include browserMountPoints.inc
</window>
</overlay>
@@ -0,0 +1,64 @@
<?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/places/places.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<?xul-overlay href="chrome://browser/content/baseMenuOverlay.xul"?>
<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
# All DTD information is stored in a separate file so that it can be shared by
# hiddenWindow.xul.
#include browser-doctype.inc
<overlay id="hidden-overlay"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
# All JS files which are not content (only) dependent that browser.xul
# wishes to include *must* go into the global-scripts.inc file
# so that they can be shared by this overlay.
#include global-scripts.inc
<script type="application/javascript">
function OpenBrowserWindowFromDockMenu(options) {
let win = OpenBrowserWindow(options);
win.addEventListener("load", function listener() {
win.removeEventListener("load", listener);
let dockSupport = Cc["@mozilla.org/widget/macdocksupport;1"]
.getService(Ci.nsIMacDockSupport);
dockSupport.activateApplication(true);
});
return win;
}
addEventListener("load", function() { gBrowserInit.nonBrowserWindowStartup() }, false);
addEventListener("unload", function() { gBrowserInit.nonBrowserWindowShutdown() }, false);
</script>
# All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the
# browser-sets.inc file for sharing with hiddenWindow.xul.
#include browser-sets.inc
# The entire main menubar is placed into browser-menubar.inc, so that it can be shared by
# hiddenWindow.xul.
#include browser-menubar.inc
<!-- Dock menu -->
<popupset>
<menupopup id="menu_mac_dockmenu">
<!-- The command cannot be cmd_newNavigator because we need to activate
the application. -->
<menuitem label="&newNavigatorCmd.label;" oncommand="OpenBrowserWindowFromDockMenu();"
id="macDockMenuNewWindow" />
<menuitem label="&newPrivateWindow.label;" oncommand="OpenBrowserWindowFromDockMenu({private: true});" />
</menupopup>
</popupset>
</overlay>
@@ -0,0 +1,126 @@
#ifdef 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
/**
* This class manages a cell's DOM node (not the actually cell content, a site).
* It's mostly read-only, i.e. all manipulation of both position and content
* aren't handled here.
*/
function Cell(aGrid, aNode) {
this._grid = aGrid;
this._node = aNode;
this._node._newtabCell = this;
// Register drag-and-drop event handlers.
["dragenter", "dragover", "dragexit", "drop"].forEach(function (aType) {
this._node.addEventListener(aType, this, false);
}, this);
}
Cell.prototype = {
/**
* The grid.
*/
_grid: null,
/**
* The cell's DOM node.
*/
get node() { return this._node; },
/**
* The cell's offset in the grid.
*/
get index() {
let index = this._grid.cells.indexOf(this);
// Cache this value, overwrite the getter.
Object.defineProperty(this, "index", {value: index, enumerable: true});
return index;
},
/**
* The previous cell in the grid.
*/
get previousSibling() {
let prev = this.node.previousElementSibling;
prev = prev && prev._newtabCell;
// Cache this value, overwrite the getter.
Object.defineProperty(this, "previousSibling", {value: prev, enumerable: true});
return prev;
},
/**
* The next cell in the grid.
*/
get nextSibling() {
let next = this.node.nextElementSibling;
next = next && next._newtabCell;
// Cache this value, overwrite the getter.
Object.defineProperty(this, "nextSibling", {value: next, enumerable: true});
return next;
},
/**
* The site contained in the cell, if any.
*/
get site() {
let firstChild = this.node.firstElementChild;
return firstChild && firstChild._newtabSite;
},
/**
* Checks whether the cell contains a pinned site.
* @return Whether the cell contains a pinned site.
*/
containsPinnedSite: function Cell_containsPinnedSite() {
let site = this.site;
return site && site.isPinned();
},
/**
* Checks whether the cell contains a site (is empty).
* @return Whether the cell is empty.
*/
isEmpty: function Cell_isEmpty() {
return !this.site;
},
/**
* Handles all cell events.
*/
handleEvent: function Cell_handleEvent(aEvent) {
// We're not responding to external drag/drop events
// when our parent window is in private browsing mode.
if (inPrivateBrowsingMode() && !gDrag.draggedSite)
return;
if (aEvent.type != "dragexit" && !gDrag.isValid(aEvent))
return;
switch (aEvent.type) {
case "dragenter":
aEvent.preventDefault();
gDrop.enter(this, aEvent);
break;
case "dragover":
aEvent.preventDefault();
break;
case "dragexit":
gDrop.exit(this, aEvent);
break;
case "drop":
aEvent.preventDefault();
gDrop.drop(this, aEvent);
break;
}
}
};

Some files were not shown because too many files have changed in this diff Show More