Add Pale Moon
@@ -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/
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
repo: 8ba995b74e18334ab3707f27e9eb8f4e37ba3d29
|
||||
node: a7c8e85285e290fdb1325edfb37e905a3779f3cd
|
||||
branch: default
|
||||
tag: FIREFOX_52_6_0esr_BUILD2
|
||||
tag: FIREFOX_52_6_0esr_RELEASE
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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/
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
PURGECACHES_DIRS = $(DIST)/bin/browser
|
||||
@@ -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']
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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']
|
||||
@@ -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#"/>
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -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>
|
||||
|
After Width: | Height: | Size: 9.6 KiB |
|
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>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 898 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
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="©Button.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="©Cmd.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="©EmailCmd.label;"
|
||||
accesskey="©EmailCmd.accesskey;"
|
||||
oncommand="gContextMenu.copyEmail();"/>
|
||||
<menuitem id="context-copylink"
|
||||
label="©LinkCmd.label;"
|
||||
accesskey="©LinkCmd.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="©ImageContentsCmd.label;"
|
||||
accesskey="©ImageContentsCmd.accesskey;"
|
||||
oncommand="goDoCommand('cmd_copyImage');"/>
|
||||
#endif
|
||||
<menuitem id="context-copyimage"
|
||||
label="©ImageCmd.label;"
|
||||
accesskey="©ImageCmd.accesskey;"
|
||||
oncommand="gContextMenu.copyMediaLocation();"/>
|
||||
<menuitem id="context-copyvideourl"
|
||||
label="©VideoURLCmd.label;"
|
||||
accesskey="©VideoURLCmd.accesskey;"
|
||||
oncommand="gContextMenu.copyMediaLocation();"/>
|
||||
<menuitem id="context-copyaudiourl"
|
||||
label="©AudioURLCmd.label;"
|
||||
accesskey="©AudioURLCmd.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="©Cmd.label;"
|
||||
accesskey="©Cmd.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);
|
||||
},
|
||||
};
|
||||
@@ -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 &&
|
||||
!('@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="©Cmd.label;"
|
||||
key="key_copy"
|
||||
accesskey="©Cmd.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>
|
||||
@@ -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="©Cmd.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");
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||