Merge autoland to mozilla-central. a=merge

This commit is contained in:
shindli 2018-03-08 02:18:59 +02:00
Родитель 61f1c5bba8 6fc9759b14
Коммит 8969dbf20d
238 изменённых файлов: 1058 добавлений и 7323 удалений

Просмотреть файл

@ -71,8 +71,6 @@ browser/branding/**/firefox-branding.js
# Gzipped test file.
browser/base/content/test/general/gZipOfflineChild.html
browser/base/content/test/urlbar/file_blank_but_not_blank.html
# New tab is likely to be replaced soon.
browser/base/content/newtab/**
# Test files that are really json not js, and don't need to be linted.
browser/components/sessionstore/test/unit/data/sessionstore_valid.js
browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
@ -380,6 +378,7 @@ testing/talos/talos/scripts/jszip.min.js
testing/talos/talos/startup_test/sessionrestore/profile/sessionstore.js
testing/talos/talos/startup_test/sessionrestore/profile-manywindows/sessionstore.js
testing/talos/talos/tests/canvasmark/**
testing/talos/talos/tests/devtools/addon/content/pages/**
testing/talos/talos/tests/dromaeo/**
testing/talos/talos/tests/v8_7/**
testing/talos/talos/tests/kraken/**

1
Cargo.lock сгенерированный
Просмотреть файл

@ -2034,6 +2034,7 @@ dependencies = [
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

Просмотреть файл

@ -1167,7 +1167,6 @@ pref("services.sync.prefs.sync.browser.download.useDownloadDir", true);
pref("services.sync.prefs.sync.browser.formfill.enable", true);
pref("services.sync.prefs.sync.browser.link.open_newwindow", true);
pref("services.sync.prefs.sync.browser.newtabpage.enabled", true);
pref("services.sync.prefs.sync.browser.newtabpage.enhanced", true);
pref("services.sync.prefs.sync.browser.newtabpage.pinned", true);
pref("services.sync.prefs.sync.browser.offline-apps.notify", true);
pref("services.sync.prefs.sync.browser.safebrowsing.phishing.enabled", true);
@ -1258,29 +1257,10 @@ pref("prompts.tab_modal.enabled", true);
// Activates preloading of the new tab url.
pref("browser.newtab.preload", true);
// Remembers if the about:newtab intro has been shown
// NOTE: This preference is unused but was not removed in case
// this information will be valuable in the future.
pref("browser.newtabpage.introShown", false);
// Toggles the content of 'about:newtab'. Shows the grid when enabled.
// Is supposed to toggle something to do with about:newtab . Doesn't seem to do
// anything in activity stream. bug 1443646 covers dealing with this.
pref("browser.newtabpage.enabled", true);
// Toggles the directory tiles content of 'about:newtab'.
pref("browser.newtabpage.enhanced", true, sticky);
// enables Activity Stream inspired layout
pref("browser.newtabpage.compact", false);
// enables showing basic placeholders for missing thumbnails
pref("browser.newtabpage.thumbnailPlaceholder", false);
// number of rows of newtab grid
pref("browser.newtabpage.rows", 3);
// number of columns of newtab grid
pref("browser.newtabpage.columns", 5);
// Activity Stream prefs that control to which page to redirect
pref("browser.newtabpage.activity-stream.prerender", true);
#ifndef RELEASE_OR_BETA

Просмотреть файл

@ -13,9 +13,6 @@ with Files("defaultthemes/**"):
with Files("docs/**"):
BUG_COMPONENT = ("Core", "Security")
with Files("newtab/**"):
BUG_COMPONENT = ("Firefox", "New Tab Page")
with Files("pageinfo/**"):
BUG_COMPONENT = ("Firefox", "Page Info Window")
@ -37,9 +34,6 @@ with Files("test/contextMenu/**"):
with Files("test/forms/**"):
BUG_COMPONENT = ("Core", "Layout: Form Controls")
with Files("test/newtab/**"):
BUG_COMPONENT = ("Firefox", "New Tab Page")
with Files("test/pageinfo/**"):
BUG_COMPONENT = ("Firefox", "Page Info Window")

Просмотреть файл

@ -1,50 +0,0 @@
{
"directory": [
{
"bgColor": "#ffffff",
"directoryId": 10000000,
"imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAIX0lEQVR4nO1afXDbZh1+sxbWsbGvsrLbuBt36766sR3sOEgiuU4kx2vTpFGKm0SKsyyOlI8laUZTulLojQEHx4CyAaNnt72yrivklo1YSpxcW7YVbKXHgCvduCvroDt6o6OtLSWN1MRWX/5I4imyJMu2bPNHnrvfSZbf6P09z+/jfV+3ACxhCUsoAEouNWGlMRLri5GuZwUSe1Ug8bcFEjsjUPgHAoX/UyCxkyKJjQoU/iOhCd8WJSvW/8vpXFFsx7PGeaJsVaytul+g8KMiic+IFA7NTNB/rggk/jeRcu26RGFris3JEqIUtkFsdo2KFK6kI52pCSR2UmirZgY9YFmxeaYg1uyqFSj8lMXI5mofRb3rOwEAJcXmDS72ex8QvO43skjv3MeT2DtRX2150cgLzVUDIonF8xBh64KQ2FWRwncPejyFK4tYq/Nmoa1mPE/pnZ1ILe4TFxpdd+SdvOhxrhabXaeLTVjfsHfzSj5K4V8QKfyjnGs3P2UiCt/v/1LeyAsNlXebkbeRSOZ/Q+JCrBH/Yt7IX+qlbhS96dM+Y+dJLC6S+BWRwmazFizf5AEAQPRtHLEhukqMwo8KTfg2oamy8t+e0uvUczwDwDWxhopHBBLvElrc+wUSm/r/IN9a3ZtrbYqUe9eHTc7PZDLvoAcsi/lq2wQSO1M88k93r7ayjzdI76sxEv/5hdryT+foRknM696q9qMg5AEAQHx83WhWtU5i56PtG1E7fYkO+B4SKNd7AoWLBSEv9G3Asol8zOs+ddFTeWc+fDrXgq2MNmEP5+PdKZB/XR4RvRnWe8tjJ8+1ECsL4mA+EQ+vcCg8gHHuPjjZvc5S6guU6/3/POG5rdi+24IEv+KwEgFQ4QFU/rAKTu90pal5fCY60PlQsf22BefHwfUKD2YVfl6ACIAKfx2UX0QNBYj6arqL7bdtSIQBnYy+2iIAzg49Cid9bm3qv11sn21FggeHUwSILGQCgIljd8Kpreq+4Koqts+2QuGBmBL9FLsFSj+sgAKFnyq2v7ZCDoO7dKOvvc7fS3vcW4rts61I8OBxXdI6/UCJADgVvmGVHfMSAelgfUA6VBeQDqmv2nuzZ3rf6Y2r3SM7DB1RwmCnOsLaiGuenbWD/JwAcqI+IEPCL8H6gAwX7omADIn5z/Wqe0Iz1sgI3edSv6EjcR78OEk4jQiJCNhnlwD1ATlBmDqdCUHzcYRf3mXoSCIMXjdK95SeEAbfslUAk4iaEc1EsLnx0vNmAhw3q3mNAFvtFCBd2i8i4bdWAgYCDBkLwIMJw8antTDos12ARSTNM8JK5Amd8URAPmosQAS8Zdr41N/lIQOS0Z2/pkZe0iWoS35+rIY8rPfLvzcWgAdDljMgAr5tlwCEWgArjUxnnJXSmX8eMnQkPrH8OasCJMJgfyEE0KZxMrJ+i2WgyZq6gHTQ0BGFv+abujs//ab4gV0CqEvAar1n0gQXizj9PUNHEmHgTSFt1At4O3eCH+8D0tW2YUmoMkKvfyQzwC/vMHREegN8Tpe4zjIY55fD14+X9tgiwC8mV2ZrHS/LGOGXRd3y8aeKVee/3GrqjBIGMcMsmL/GJu6AW4+1QZRl/mKHADmipD4gz1jJHCIgw9oXJ+8zfVsi/ImXU7bDquvfI2ugZ7wHoiwDUY6BTrbTWRie+ti0d7rGrHTU5UD45StpX5iILPMZrQTD4Q0QG+2GKMckzcF28AXgaYiv7ZNesdokCb90PO0LP2TBpxQezKpFkPmb4Q/ebFlEHOWYZBY8FtriKwDXFDAHhLvr/bJi9TzQtPeycQNUI3HihkML5M9NfB4+caRTl/jHRsvtb333gTzzTUHDPonNZFkkfjVl7Zfr+MRtiMID+McICqtDvfrE2cWfHRxz2j321K155pxE84HLLWb7BK0odX75TEYTBI43hB1ch0HE554h7GJhKrkn/4wPMjfliXMSO4alcsIvx/UanZE17pcGMppkU2iL2zDt9QSZtwqu66/Okdbb88Qd7PydVFYfkGVthLWHHk1JyOteuHRjxpNh3JNjRtE3EgDlGIiwzLlqrq/MbvKtLwkewi/PalPc8PyQPDdIP8lqQvdw92qEZWbNyBqJgnD0VTTI7H74Je/1uRL/8mDr7VWjfYeJkecgdfC/6c8JavPL0+6fitn3JtdIzxbdqLPqiNMmwtAxR7BzZ+mgL2MnHGzHPQhL/wzlmCsLc64PbYPU4Xd1zwN6WdCwT/p61uQXsH6sL5TS/dOUgY4QCZRlxsuD9EDZsM/x4KDnk5ppSsqGfHehw3QjytHfQVj6HaP+U8F1wZbhMf1Dkerzpr3Sn4Ad/5/Yc2T7TQ6OOW2YBWZimAsVRzlaRoL0DMLRV/WW19SVh05+v5nbAxsPCPpZ4Jclwj95b87kF+BgO+5Bg8yFFHKZZkO68XqimoyvGd0FqUNnU/pA1yvTdbaRXwDCtj2CsszFjFLfSjZoRbEiqEqoqtE+6H2VT5LfvPfydtvJJ0V4jb537QhzxjLRdMSsimIhq5q538DNgSnbfqs0FoHrusUd6j2ScdTNyGZTNovfHa8Z6/fmnbwaTq5r+1wj0ziZrjlmvIKYP3ew9Hvk+NOPFpT8AjxHd6ypGOl607Z+YDUL5s4iChpkdq8b7b22KOTVQIPtGxet3bmQtVA6eKhnyBP6hvnPW8UAwvpq1nIdoeS6bpWY0fK3aMfJTCMc/csqtuf+YvNMi68Mt38WDTJPoSx9DGHpmaxLI8hcqBzpCiDB9ibnM87lxeaVLUrKg+1fRVimby3LPItw9G9Rlj6Bssw/EI4+i3DM+0iQPomy9JiD69hdztI7SoPtTWWvddry7w5LWIIx/gdCuvcjoZqlLQAAAABJRU5ErkJggg==",
"type": "affiliate",
"title": "Google",
"url": "https://www.google.com/"
},
{
"bgColor": "#E62117",
"directoryId": 10000001,
"imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACd0lEQVR4nO3av0tVYRzH8WOIBEVDUUIGCa32FwQ5OrS42NKeRUOTdGmoqUGiLVBqa5UG+7WUREGiEqhTDkVJEA2iYZBkxKvhHumo96o3uM9z0ucNZ7zn834+XO59znm+WZZIJBKJRCKRSGwCx3AWfbiIaxjEPYzgOd7gLWbwIb8WsFjjWrU9q3U+u1C4/0yeOZ47jOROg6jkrn25e3uji27NbzC9A9n/hWnVNbVut/hOTMZ1bSqT6Ky3+A58jOsXhE/o2Lj4FryILBaSF2gpFtAT2ygCPcUCHse2icDTtcW3YSW2TQRW0JahK7ZJRLoy9Ma2iEhvhoHYFhEZyDAU2yIiwxkeBgj6FSDjXxjN8CpA0A1cxucAWY0wkeFdgKBK/pe7H1fxNUDmTpjLMB8gqLJh631A9dF6IUD2Vsxn+BYgaF0BhSIO4WYgh1osZVgOEFSzgEIRh3EL3wO4FFnOAgVtWUChiKO4gx+BvJSqgEIRx3EXP5stVsoCCkWcxH1N3EeUuoBCEafwshlipS8AJzTxW1DaAnAEtzX5B7F0BeAgrmMphFhpClB9M3UFXwI5oQQFYB8u4H0gl3VE3QninOoxVyyWozwL4AxeB8jdjqWgT4M4jUcB8nbKfKj3AUN4gN8BshphLtQbobIyEeqdYFkZzTAc2yIiw+lcQDoZSmeDe/t0ON+gPIltE4Fnxa3pnp8QacFYbKOAjCnOCOUldKhOUO12Nk+JFUroxFRkwWYypd6cYKGEVvTbfZOil2w3KVqjjHZ047xqKRWbZ4XHVed2Z/2d5a0167vYgHC9z6/df9bWs8L9uXO3RmeFE4lEIpFIJPYKfwAcall+TY3q/wAAAABJRU5ErkJggg==",
"type": "affiliate",
"title": "YouTube",
"url": "https://www.youtube.com/"
},
{
"directoryId": 10000002,
"imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACT0lEQVR4nO3bzWsTQRgG8PlPHMVLqRVMoQiFehJyUBAFtRCFHspExaaSoFg8CMGPSg+R3kQhh3osIbOlMVrbGKtrsbYESTbB0gqNVGu1WCkWutnXg+ihQjqxi7Oz8w481533+V32iyGEEEIZ76Rho0SZ4ewOG+D3UMatXSx9nPwqb5ySPZC0dPMzhDJelD6IrDCjQijjtvRBJIWGeY3IHkJ2EED2ALKDALIHkB2lAJoujkIwnoNQwoQL96aha3AKQgkTTtyZhKM383D4+gQEoll/AQRiWbg1XILZ+VWwaw6IrE3bgZbejNoAe8+PwEC6DOsbm0Klt679lxQGCESzMD335Z+KKw+wrzcDpcVvOyqvNMCwubjj8soCnBx44Up5ZQGeFZf1BWi7/BhqjthtzpcAseRsQwVrjgNzS9/hZWUFJq3Pf6U5MqoWQHJ8Qbh8aqoKB688cWVfzwBMvP0kVN6srMCec+7t6xmAmfmvQgCRBzOu7usZgHJ1TQjgyI283gCHrj3VG6C9bwwBEAABEEAtgAPRR9A3VKibpdUfQgD9KWvba529+8pbAMF4TqicW+th/r3eAP0pS2+Anvtv9AY4dvu53gCtMfGfI74DWN+wG5rNdwDl6preAGOFj3oDJMcXvAfQHMlAKGHWTeWD2KPw1aFC3et0NPi9wDPvAq/fif0LDMZzru6LALKLIwACIAACIAACIAACIAACIAACIAACIAACIMD/BvDKwUkZAJRx2zNHZyUBFAntTp+WXV4iQCf5c3yecUsXAMq49bv8Txsl6ZCTabOAAAAAAElFTkSuQmCC",
"title": "Facebook",
"type": "affiliate",
"url": "https://www.facebook.com/"
},
{
"bgColor": "#ffffff",
"directoryId": 10000003,
"imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAA/CAYAAABQHc7KAAAEyUlEQVRoge2abYhVRRjHf7veVqSFhIQwa7E3ojXNpSiNgl0S+tAHKUjohbQohUgqKKwMSXpbsATdqOgFU4zKpAzMioploxI/WFBZmhRlL/S2lbpsudvd24dzjve5c58558ycey9B84MB95x5/vM/d+bMzDNHCAQCgUAgEAgE/rf0AOd6lJmKVrdDfI8SfxawIKNcEscfa8TOzBFrlj6Aimd5XnmAbx01TD5xiL3IiH3Y8zm4DXgaGALGMip/DDwHDACXKQ9wA/AiMJyi8T3wAnCvEr841t9tiR2JY/uB443YC4BHgA3ApyntTxD90FuAlaaBU4EfLIHvKIZtnAT8ZtE5O6fGCiNuFJiTM7YNWKe0PQScmRV8ncX4+zkbT1hq0bkyZ/wyI+5ux/bPM+I/ACbnCSyhv8tloMvBQAnYr+h8mDP+PRHzGXCMQ9sA14j4ceAMl+A70HtvjaMJ22jqy4i70Kh/sWO7AO+K+Jdcg6cCh6k3/gfQ6aBTAr5UdN7OiHtL1H3NxXhMN9Fkl2jM89BgPXrv3eKoc71Fx2ZqvqhTJv+kKRkQGjs94gE4PTZgGt9DNMvmpQR8pehst9R/Q9TZ5OG7EzgkNK720DjKNvTeu9RRZ4miMUH9bnCeuH8EOMXD881C40egw0PjKL3oP8Cbjjq2FWGrUW+HuDfg6XmP0NA2W060GYKy97odtbQVoQzMiu+fL66PACd4+O0VGqPANA+NOm5CHwVPOeqUgH2Kzub4/uvi2gOeXrcU8GdlCtG7ZBr/C5juqHWtojMOXCX+HgaO8/B5YqyV6GjZpjf3oI+C+x11JgF7FZ1/xL/v9PS4WmgMempYsW2MfsdtYwTRsqT9mBXgANGIc6WD2lG60EMjk0fRTS931GkHPrdo3ejpbZHQ2B+30XC6iNZm0/Q3RBOcC7Yc4WRPb0NC43ZPjVxsRDe+yFHHHLJJWevhabaIP0z0ujaNWdQmGUn5yEPrPkVnBPe1+0kRv97DhzPb0UdBr6OObZv9kIOGnJzLRPlL0+lFN+6yPe5BH0kV4E/yD+PlIm6bQ/uF2Um98Qlgbs74V5V4WVbl0GgDvsB/BBbiCnTj2lG5yVyqvX+QaOSYOsNk7y8WiPo+c1Ah2tFPesbJTmFfEfX7qU2BZVmRoSPnkMU+D1EUW5L0WErMHKq9P0o149NeqZ+w7wq7qO77f02p11Qmo6/laWnoVlFvnbh+uaJTAW616Dwo6rjmIw3lLnTjminZ+38DM8Q92yv1HfUnOh3AL/H9I7hnpA1lKrXnb0nRkqSXxf0nFC3bK7XMqCdT6o2NeIiirEE3Lvfks6kesI6hf1m2nTt8TW2uIeeLhub8vsxAT5IOUB2+8qTm2RStlYqOnOV7xLXBRj5EUWxJ0hKic/2k98dJ367azh32Es0Tz4hrTcn5fZE9I8s+ajc6m20CgrUWrdVEK0yFJub8RRhEN56UMjk+TVO7xtuK6yFMS1hIuuk82+SETSk6h3A/hmsJ7egfPypEh555ej/hHOzZYktyfl9keiqLzzc+LUlqWc7vSyfRJ3Rpegw4zUOrj/ofoKU5vy/91Jp+vIDWLkPL/J9h/0mmAT9TXa58vvIkzKe6ydpQ3FogEAgEAoFAIBCI+Rf5q90lTPZHIwAAAABJRU5ErkJggg==",
"title": "Wikipedia",
"type": "affiliate",
"url": "https://www.wikipedia.org/"
},
{
"bgColor": "#400090",
"directoryId": 10000004,
"imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAD3ElEQVR4nO3bS4xecxjH8WmLBVVEx63JBIkEISkhJqURpAsZQioWqpeNSxraYlKpSwiDIRY0aSakqgS9qHRBIhKxYdFFFxWXIGkilYZEUCKj4zLzsfi/LN55zpiZc/lr+/6Ss3nfc57ze77n9r88/y7swxaswgLM7jpMhTlYiNWtnPd1Ga9RfIVtuB+L0J3b/FSFeejDQ9iBvRhrTzYCUKTv8RFewlrcgAtxQsYk5+Ii3IQHsBm78ONkk5oKgIn0Mz7BO3gBA7gHS3EtLsXZre1UnITj2pI5vvV7D85BL67DCvRjEJvwHj7HcBXGqwJwyKoDILeB3OoAyG0gt8oAGMYj0qdnJ17DY3i2vK1CPYmn8Cq2YwgP4rfpBix7BwwE3+aZ2F0ybqQPMSM439NlgpYFMILzAlO9glZXCf2F+cF5LsafZQJX8Q4oujKbK4j9j4aC+EdhT9nAVb0Ebw8MduNABbF/wMlB/LUVxK4MwE84JTC5uoLYK4O48/BrBbEr/Qy+XnCbfloi5h7MCuJurcSxagGMYWFg9qr/SbxQVTeEiq7Ym9OI9UYQ52ipJ1iZ6mgJ3h0Y7zG17usvOC2I01+12ToAHBCMIGHdFGKsCo4/QwJTqerqC2wMEjgGX0zi2KLH6JU6jNYFYBSXBElc/R/HjaE3OO4y1bYs/1WdvcFd4hbilgmOie6cGa1Ytaju7vDSIKHTxc9yUYtvWZ0G6wawH8cGSa0J9r0t2G92K0ZtamJA5PEgsfaOTNHjMlC3uSYADKMnSG6B9GIr6uqehYN1m2tqSGxre4KtJDdhfcF/O5ow1hSAMVweJNmNOcHvlbb3J1KTg6K7MTO62m3Jz1LBQMdk1fSo8IpJALizSUNNA/jWBNPvOFGahG1MOeYFnpgAwHNNm8kB4CDODJI/F380bSbXzNAzAYD1OYzkAjAYABjKYaQDIMdJxQDqnFMsVC4A6wIAgzmMdADkOKkYwKM5jOQCcFcAYCqjxpUpF4Bovu+IB3BfDiO5AIzrFWJlDiO5ACzpABgP4I4cRnIBWBwAWJLDSC4AfR0A4wHcksNILgCLAgB9OYzkAnDFkQ5gDZbj3ta2XCp5bVydYuncBnKrAyC3gdzqAMhtILfqBDCCb6SZ3velatGXsUFa5NC+vdjatrf2/QAfSyUyv9dlsgyAEXyGt/G8VBl+PS7A3PaGTllJCy7n40Zp8GQD3sWXSgCaDIBRqcBxGx7GYmll57hixlySaojPx83SuqW3pLXC0wKwX7oF+3GloILjUJE03X6NtAh8J76LAOzFRtwqKGY63CStX14mLen5+m9Vgqdbrd+9cgAAAABJRU5ErkJggg==",
"title": "Yahoo!",
"type": "affiliate",
"url": "https://www.yahoo.com/"
},
{
"directoryId": 10000005,
"imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAJdklEQVR4nO1ba1QTZwL9iCY8hCDxDUpYOIUDBOVZAlJ5NQXRFlEQ8YGiRaqESlhxeRQ3FAWURRC6FYglqBHTEaI8Eg+CRMRatfKwLNL6oqer1h57XEWYbwJK9sdKixiSmRCCbrnn3D8w351770wy3zd8ADCJSUxiPMHhcPS3bdv2/tq1a9MWL16MODs7t5iamt4zMjLq0dfX76VSqU8sLCzueHt7S+3t7QtjYmLWJyYmzp1o32NGSUmJd0BAQLmRkVEPAEBOhCQS6bm3t7c0MjIyHACgMyEB1AGCILTY2NgUOzu7fwGCoUfj/Pnz/x0XF/fXgoICXW3nIYTs7Owlpqam94CGgo+ktbX1j4mJiY7azIQbMTExu3V0dF6AcQo/RF1dXYggSIj2kuFAfHx8Lhjn4ODVElCxWOygpXjKkZWVxQZaDD9EOp3eXV9fb6yVkKOho6Njgb6+fp8ig9pgfHx8gjZyjgYdX1/fhtHMqSKJRHpOJpNl6o4HAMidnJxatJJUEWpraz3xmBxOExOT30JDQ/+elpZmD14+26uqqubExcVFzJs3T53H5uCJEydMtZN4BKKiovKJmA0KChLu3bt3zmh6Bw4c0F+3bl0BEU0AgLygoCByXAKqgq2tbSdek0FBQTV4dZlM5kW8ugAAOZPJ/IeGIuHH9evXp+no6DzHa7K+vt4Lr3ZiYuIOvLoAALmnp6dQQ7HwIzc31xqvQRsbmy5AYC6fnJzsjlcbACD38/M7p5lUBBEeHp5lbm7+E4lEUnonREdHpxPRLSwsNFWmN5Kurq5XNZNITfj4+EwtLCw0dXFxcebz+UFhYWFbmExm6qZNm/IjIiKyampqDIjonTp1ajp4mwrQNP70BfD5/D9PAcXFxQZcLteOwWCw9u/f/3FwcHC6paVlOfg/K4CUlpbmEB0dvSEkJCTLxsamwtnZuXXmzJmPAACDgEBYRXxjC8jJyfFYtmzZYWNj48dgjCGV8Y0qICsryyQiIiKVTqf/BMYxNHgTC8jPz/+ISqU+AVoKDt6kAnbs2MGeMmXKANByePAmFBAbG5utyJi2OKEFJCcnx+MxqYizZs361d/fvyw9PX0bg8FgZWRk2FZVVc1pampaQERnwgoQi8VLVK0DRpJMJstWrlx5hMPhvMflckmKdN+amSDRdbuenl5fRkaGnyrdt6KAsrKyD4iYpFKpTy9cuPAuHu23ogAmk9lIxGRCQsLneLVLS0tnEdHWegFisXgu0b8ANTc3W+LVT0pKsiSirfUCDh06tJyIQSsrq5tE9PPy8jyI6Gu9gMDAQA5Bg9VE9Hfu3BlFRJ/BYHSMPRUBsNnsfUQMksnkciL6q1ev5hHRNzQ07AHa3D9A9N19QEAA7lfiAAAdOp3eTUQfACBHEMR87MlwgmgBZmZm9wHOK1RUVLSFiPYQd+/eHaOheKrB4XCyiBrk8XguqnTb29vNDAwMeolqAwDkCxcuvKbBiMoREhLyKVGDy5cvr1Cm2d3dPd3Ly+sCUd3h3LNnT7xGg46GoqKiQHUMbt68uZjL5VJG6qWkpPjS6fS76miO4Ivm5maVd9qYUV5ePlPdtb+FhUV3cHBwkbm5efrGjRvz7O3tr2og+O90dHRslUqlUxX5lkq5U7HmJEtUsnTxwG0kEJ7b4Cer32ArlXIVHq8ULBarVpPGNcng4GDP4V6xloxArNq3oq+M9hTlUeSvsfwvPxMuoKGhwWO8N0RRKBSM6Bg6nf4jgiC0zk6Egl3czsYQhxsKQ48g4QIAAMDf3//0eIWn0WiPjh075jx79uyHeMfY2dl1IAgyFwAAZA1rjqE8ihw9rPscrXRp7xO5lckaN6X0t+dt7m/LiYanPI+iPPLgmApoa2t75+W7fY2GX7RoUcvx48fpAAAgEom88NwJLBbr65ycnGlD3gZuli15VhfC6JZy9Ubzj1W6to6pAAAAEAgEDsbGxv/RVHh3d/ezEomEOvwcqamp6crGsNns/NHeLg0HPPOhV98Pf2ynQRHG+ZcFDKpdAAAAFBcX+6qzF3gkly5dqjCIVCrVs7e3v6RozKpVqw6q8idrybCFonfrUB5FDqsWfzv0c1jh2IHyKHIotL0J+lsyY7CqJXmyO4hamw/Ly8vnhIeH51Op1KdEQtNotN9WrFjxpVAodFOmv337dkMmk1k9NI5CoWCZmZk7EQSZouj4bilfT/ZtUjhW4yNCDxv0ozyKHJaZ9Mq+S1sDAACdnQgF8o1RlEeRy5picsDA3dPv9QnMHqI88iAUudYNdJV4q1NEXFyc7q5duzZ4eXmdtLKyukUikV6ZL1Cp1CeOjo6tHh4eRVwudwWfzx/1MzoSXC53alRUVCaLxapjs9kBio55fC3bGPvm0wRUQL/3yjc9n9Yz0HX090zolTSP//2OPIjdEVkDAAB42nmYJjsbWjo0CEMcfoCNkXvR5lh3BAlT2LQqhIWFTZFIJFSJRELdunUrWR0NVXhc/zdj9MxHa6B4qRAemfHasx6rYUnQjn8uGD5G9k3CHpRHkcvqQk+8Joh1lX2AHl9wf+RkAWtYvx9eSvaWSn2Iz5w0jId1O6fJLn8Wila6iVCe/oCiZ3sff8YT7CLnE6BgJQoRhxtoqcmz3l8vK9629+xW6Sx4dnUmLJv55DXxo3MeQ8ThDKxlfS77Pm8F1pxkqegkmsItSZxu75nAhf1NMZFY47ov4MlFzejLz69ClhrB/vObc3uuZM5QpIf9fM4K5VHk/W25sSpP3tdaaArPrBSgJbovlM6m+LQeWO13HqtwO4i1Zn0CRZ5+2Hf7bB5cK8a9P6hbytfDOgqsMJErC7vyWRw87VUERR5X0VJDiGc2h/IocljL+rr3Klfpv9pg9xttsLOrVIcfDtltEQOtcP0CFZg/wGvmjysyvQ8VmP8ChTa3McThBiZya8NEbm3YSUYXFNrcRgXmv8Ay2jOUp0tMd9gdidWHFsiuH2QQCqUOuFwuSXY5ZT1a6dyullkNEiKMLky6NaYTeX2JrRXILqcslIkDk2GFYyP6lSE27oGPzHiKVTiJZdV+qf2dh50mJPRo6Jby9bBLycvRSpcCeNLpe7SEovw7Aw+/MpDBUx5XsNqAbHgp2buzc4KutDp4dHGXEVq3xh02fbwFq2Htg5WuQljlcwFWLOqAJ97p7hOYPewTmD2EQuu76Emn67DauxmtdEawap8ceH5TNFofznxQs5XQBstJTGISk1AX/wUPVWOeSpK50AAAAABJRU5ErkJggg==",
"title": "Amazon",
"type": "affiliate",
"url": "https://www.amazon.com/"
}
]
}

Просмотреть файл

@ -1,126 +0,0 @@
#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);
}, 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;
}
}
};

Просмотреть файл

@ -1,132 +0,0 @@
#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
var gCustomize = {
_nodeIDSuffixes: [
"blank",
"button",
"classic",
"enhanced",
"panel",
"overlay",
"learn"
],
_nodes: {},
init: function() {
for (let idSuffix of this._nodeIDSuffixes) {
this._nodes[idSuffix] = document.getElementById("newtab-customize-" + idSuffix);
}
this._nodes.button.addEventListener("click", e => this.showPanel(e));
this._nodes.blank.addEventListener("click", this);
this._nodes.classic.addEventListener("click", this);
this._nodes.enhanced.addEventListener("click", this);
this._nodes.learn.addEventListener("click", this);
this.updateSelected();
},
hidePanel: function() {
this._nodes.overlay.addEventListener("transitionend", function() {
gCustomize._nodes.overlay.style.display = "none";
}, {once: true});
this._nodes.overlay.style.opacity = 0;
this._nodes.button.removeAttribute("active");
this._nodes.panel.removeAttribute("open");
document.removeEventListener("click", this);
document.removeEventListener("keydown", this);
},
showPanel: function(event) {
if (this._nodes.panel.getAttribute("open") == "true") {
return;
}
let {panel, button, overlay} = this._nodes;
overlay.style.display = "block";
panel.setAttribute("open", "true");
button.setAttribute("active", "true");
setTimeout(() => {
// Wait for display update to take place, then animate.
overlay.style.opacity = 0.8;
}, 0);
document.addEventListener("click", this);
document.addEventListener("keydown", this);
// Stop the event propogation to prevent panel from immediately closing
// via the document click event that we just added.
event.stopPropagation();
},
handleEvent: function(event) {
switch (event.type) {
case "click":
this.onClick(event);
break;
case "keydown":
this.onKeyDown(event);
break;
}
},
onClick: function(event) {
if (event.currentTarget == document) {
if (!this._nodes.panel.contains(event.target)) {
this.hidePanel();
}
}
switch (event.currentTarget.id) {
case "newtab-customize-blank":
sendAsyncMessage("NewTab:Customize", {enabled: false, enhanced: false});
break;
case "newtab-customize-classic":
if (this._nodes.enhanced.getAttribute("selected")){
sendAsyncMessage("NewTab:Customize", {enabled: true, enhanced: true});
} else {
sendAsyncMessage("NewTab:Customize", {enabled: true, enhanced: false});
}
break;
case "newtab-customize-enhanced":
sendAsyncMessage("NewTab:Customize", {enabled: true, enhanced: !gAllPages.enhanced});
break;
case "newtab-customize-learn":
this.showLearn();
break;
}
},
onKeyDown: function(event) {
if (event.keyCode == event.DOM_VK_ESCAPE) {
this.hidePanel();
}
},
showLearn: function() {
window.open(TILES_INTRO_LINK, 'new_window');
this.hidePanel();
},
updateSelected: function() {
let {enabled, enhanced} = gAllPages;
let selected = enabled ? enhanced ? "enhanced" : "classic" : "blank";
["enhanced", "classic", "blank"].forEach(id => {
let node = this._nodes[id];
if (id == selected) {
node.setAttribute("selected", true);
}
else {
node.removeAttribute("selected");
}
});
if (selected == "enhanced") {
// If enhanced is selected, so is classic (since enhanced is a subitem of classic)
this._nodes.classic.setAttribute("selected", true);
}
},
};

Просмотреть файл

@ -1,151 +0,0 @@
#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 singleton implements site dragging functionality.
*/
var gDrag = {
/**
* The site offset to the drag start point.
*/
_offsetX: null,
_offsetY: null,
/**
* The site that is dragged.
*/
_draggedSite: null,
get draggedSite() { return this._draggedSite; },
/**
* The cell width/height at the point the drag started.
*/
_cellWidth: null,
_cellHeight: null,
get cellWidth() { return this._cellWidth; },
get cellHeight() { return this._cellHeight; },
/**
* Start a new drag operation.
* @param aSite The site that's being dragged.
* @param aEvent The 'dragstart' event.
*/
start: function Drag_start(aSite, aEvent) {
this._draggedSite = aSite;
// Mark nodes as being dragged.
let selector = ".newtab-site, .newtab-control, .newtab-thumbnail";
let parentCell = aSite.node.parentNode;
let nodes = parentCell.querySelectorAll(selector);
for (let i = 0; i < nodes.length; i++)
nodes[i].setAttribute("dragged", "true");
parentCell.setAttribute("dragged", "true");
this._setDragData(aSite, aEvent);
// Store the cursor offset.
let node = aSite.node;
let rect = node.getBoundingClientRect();
this._offsetX = aEvent.clientX - rect.left;
this._offsetY = aEvent.clientY - rect.top;
// Store the cell dimensions.
let cellNode = aSite.cell.node;
this._cellWidth = cellNode.offsetWidth;
this._cellHeight = cellNode.offsetHeight;
gTransformation.freezeSitePosition(aSite);
},
/**
* Handles the 'drag' event.
* @param aSite The site that's being dragged.
* @param aEvent The 'drag' event.
*/
drag: function Drag_drag(aSite, aEvent) {
// Get the viewport size.
let {clientWidth, clientHeight} = document.documentElement;
// We'll want a padding of 5px.
let border = 5;
// Enforce minimum constraints to keep the drag image inside the window.
let left = Math.max(scrollX + aEvent.clientX - this._offsetX, border);
let top = Math.max(scrollY + aEvent.clientY - this._offsetY, border);
// Enforce maximum constraints to keep the drag image inside the window.
left = Math.min(left, scrollX + clientWidth - this.cellWidth - border);
top = Math.min(top, scrollY + clientHeight - this.cellHeight - border);
// Update the drag image's position.
gTransformation.setSitePosition(aSite, {left: left, top: top});
},
/**
* Ends the current drag operation.
* @param aSite The site that's being dragged.
* @param aEvent The 'dragend' event.
*/
end: function Drag_end(aSite, aEvent) {
let nodes = gGrid.node.querySelectorAll("[dragged]")
for (let i = 0; i < nodes.length; i++)
nodes[i].removeAttribute("dragged");
// Slide the dragged site back into its cell (may be the old or the new cell).
gTransformation.slideSiteTo(aSite, aSite.cell, {unfreeze: true});
this._draggedSite = null;
},
/**
* Checks whether we're responsible for a given drag event.
* @param aEvent The drag event to check.
* @return Whether we should handle this drag and drop operation.
*/
isValid: function Drag_isValid(aEvent) {
let link = gDragDataHelper.getLinkFromDragEvent(aEvent);
// Check that the drag data is non-empty.
// Can happen when dragging places folders.
if (!link || !link.url) {
return false;
}
// Check that we're not accepting URLs which would inherit the caller's
// principal (such as javascript: or data:).
return gLinkChecker.checkLoadURI(link.url);
},
/**
* Initializes the drag data for the current drag operation.
* @param aSite The site that's being dragged.
* @param aEvent The 'dragstart' event.
*/
_setDragData: function Drag_setDragData(aSite, aEvent) {
let {url, title} = aSite;
let dt = aEvent.dataTransfer;
dt.mozCursor = "default";
dt.effectAllowed = "move";
dt.setData("text/plain", url);
dt.setData("text/uri-list", url);
dt.setData("text/x-moz-url", url + "\n" + title);
dt.setData("text/html", "<a href=\"" + url + "\">" + url + "</a>");
// Create and use an empty drag element. We don't want to use the default
// drag image with its default opacity.
let dragElement = document.createElementNS(HTML_NAMESPACE, "div");
dragElement.classList.add("newtab-drag");
let scrollbox = document.getElementById("newtab-vertical-margin");
scrollbox.appendChild(dragElement);
dt.setDragImage(dragElement, 0, 0);
// After the 'dragstart' event has been processed we can remove the
// temporary drag element from the DOM.
setTimeout(() => scrollbox.removeChild(dragElement), 0);
}
};

Просмотреть файл

@ -1,22 +0,0 @@
#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
var gDragDataHelper = {
get mimeType() {
return "text/x-moz-url";
},
getLinkFromDragEvent: function DragDataHelper_getLinkFromDragEvent(aEvent) {
let dt = aEvent.dataTransfer;
if (!dt || !dt.types.includes(this.mimeType)) {
return null;
}
let data = dt.getData(this.mimeType) || "";
let [url, title] = data.split(/[\r\n]+/);
return {url: url, title: title};
}
};

Просмотреть файл

@ -1,150 +0,0 @@
#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
// A little delay that prevents the grid from being too sensitive when dragging
// sites around.
const DELAY_REARRANGE_MS = 100;
/**
* This singleton implements site dropping functionality.
*/
var gDrop = {
/**
* The last drop target.
*/
_lastDropTarget: null,
/**
* Handles the 'dragenter' event.
* @param aCell The drop target cell.
*/
enter: function Drop_enter(aCell) {
this._delayedRearrange(aCell);
},
/**
* Handles the 'dragexit' event.
* @param aCell The drop target cell.
* @param aEvent The 'dragexit' event.
*/
exit: function Drop_exit(aCell, aEvent) {
if (aEvent.dataTransfer && !aEvent.dataTransfer.mozUserCancelled) {
this._delayedRearrange();
} else {
// The drag operation has been cancelled.
this._cancelDelayedArrange();
this._rearrange();
}
},
/**
* Handles the 'drop' event.
* @param aCell The drop target cell.
* @param aEvent The 'dragexit' event.
*/
drop: function Drop_drop(aCell, aEvent) {
// The cell that is the drop target could contain a pinned site. We need
// to find out where that site has gone and re-pin it there.
if (aCell.containsPinnedSite())
this._repinSitesAfterDrop(aCell);
// Pin the dragged or insert the new site.
this._pinDraggedSite(aCell, aEvent);
this._cancelDelayedArrange();
// Update the grid and move all sites to their new places.
gUpdater.updateGrid();
},
/**
* Re-pins all pinned sites in their (new) positions.
* @param aCell The drop target cell.
*/
_repinSitesAfterDrop: function Drop_repinSitesAfterDrop(aCell) {
let sites = gDropPreview.rearrange(aCell);
// Filter out pinned sites.
let pinnedSites = sites.filter(function (aSite) {
return aSite && aSite.isPinned();
});
// Re-pin all shifted pinned cells.
pinnedSites.forEach(aSite => aSite.pin(sites.indexOf(aSite)));
},
/**
* Pins the dragged site in its new place.
* @param aCell The drop target cell.
* @param aEvent The 'dragexit' event.
*/
_pinDraggedSite: function Drop_pinDraggedSite(aCell, aEvent) {
let index = aCell.index;
let draggedSite = gDrag.draggedSite;
if (draggedSite) {
// Pin the dragged site at its new place.
if (aCell != draggedSite.cell)
draggedSite.pin(index);
} else {
let link = gDragDataHelper.getLinkFromDragEvent(aEvent);
if (link) {
// A new link was dragged onto the grid. Create it by pinning its URL.
gPinnedLinks.pin(link, index);
// Make sure the newly added link is not blocked.
gBlockedLinks.unblock(link);
}
}
},
/**
* Time a rearrange with a little delay.
* @param aCell The drop target cell.
*/
_delayedRearrange: function Drop_delayedRearrange(aCell) {
// The last drop target didn't change so there's no need to re-arrange.
if (this._lastDropTarget == aCell)
return;
let self = this;
function callback() {
self._rearrangeTimeout = null;
self._rearrange(aCell);
}
this._cancelDelayedArrange();
this._rearrangeTimeout = setTimeout(callback, DELAY_REARRANGE_MS);
// Store the last drop target.
this._lastDropTarget = aCell;
},
/**
* Cancels a timed rearrange, if any.
*/
_cancelDelayedArrange: function Drop_cancelDelayedArrange() {
if (this._rearrangeTimeout) {
clearTimeout(this._rearrangeTimeout);
this._rearrangeTimeout = null;
}
},
/**
* Rearrange all sites in the grid depending on the current drop target.
* @param aCell The drop target cell.
*/
_rearrange: function Drop_rearrange(aCell) {
let sites = gGrid.sites;
// We need to rearrange the grid only if there's a current drop target.
if (aCell)
sites = gDropPreview.rearrange(aCell);
gTransformation.rearrangeSites(sites, {unfreeze: !aCell});
}
};

Просмотреть файл

@ -1,222 +0,0 @@
#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 singleton provides the ability to re-arrange the current grid to
* indicate the transformation that results from dropping a cell at a certain
* position.
*/
var gDropPreview = {
/**
* Rearranges the sites currently contained in the grid when a site would be
* dropped onto the given cell.
* @param aCell The drop target cell.
* @return The re-arranged array of sites.
*/
rearrange: function DropPreview_rearrange(aCell) {
let sites = gGrid.sites;
// Insert the dragged site into the current grid.
this._insertDraggedSite(sites, aCell);
// After the new site has been inserted we need to correct the positions
// of all pinned tabs that have been moved around.
this._repositionPinnedSites(sites, aCell);
return sites;
},
/**
* Inserts the currently dragged site into the given array of sites.
* @param aSites The array of sites to insert into.
* @param aCell The drop target cell.
*/
_insertDraggedSite: function DropPreview_insertDraggedSite(aSites, aCell) {
let dropIndex = aCell.index;
let draggedSite = gDrag.draggedSite;
// We're currently dragging a site.
if (draggedSite) {
let dragCell = draggedSite.cell;
let dragIndex = dragCell.index;
// Move the dragged site into its new position.
if (dragIndex != dropIndex) {
aSites.splice(dragIndex, 1);
aSites.splice(dropIndex, 0, draggedSite);
}
// We're handling an external drag item.
} else {
aSites.splice(dropIndex, 0, null);
}
},
/**
* Correct the position of all pinned sites that might have been moved to
* different positions after the dragged site has been inserted.
* @param aSites The array of sites containing the dragged site.
* @param aCell The drop target cell.
*/
_repositionPinnedSites:
function DropPreview_repositionPinnedSites(aSites, aCell) {
// Collect all pinned sites.
let pinnedSites = this._filterPinnedSites(aSites, aCell);
// Correct pinned site positions.
pinnedSites.forEach(function (aSite) {
aSites[aSites.indexOf(aSite)] = aSites[aSite.cell.index];
aSites[aSite.cell.index] = aSite;
}, this);
// There might be a pinned cell that got pushed out of the grid, try to
// sneak it in by removing a lower-priority cell.
if (this._hasOverflowedPinnedSite(aSites, aCell))
this._repositionOverflowedPinnedSite(aSites, aCell);
},
/**
* Filter pinned sites out of the grid that are still on their old positions
* and have not moved.
* @param aSites The array of sites to filter.
* @param aCell The drop target cell.
* @return The filtered array of sites.
*/
_filterPinnedSites: function DropPreview_filterPinnedSites(aSites, aCell) {
let draggedSite = gDrag.draggedSite;
// When dropping on a cell that contains a pinned site make sure that all
// pinned cells surrounding the drop target are moved as well.
let range = this._getPinnedRange(aCell);
return aSites.filter(function (aSite, aIndex) {
// The site must be valid, pinned and not the dragged site.
if (!aSite || aSite == draggedSite || !aSite.isPinned())
return false;
let index = aSite.cell.index;
// If it's not in the 'pinned range' it's a valid pinned site.
return (index > range.end || index < range.start);
});
},
/**
* Determines the range of pinned sites surrounding the drop target cell.
* @param aCell The drop target cell.
* @return The range of pinned cells.
*/
_getPinnedRange: function DropPreview_getPinnedRange(aCell) {
let dropIndex = aCell.index;
let range = {start: dropIndex, end: dropIndex};
// We need a pinned range only when dropping on a pinned site.
if (aCell.containsPinnedSite()) {
let links = gPinnedLinks.links;
// Find all previous siblings of the drop target that are pinned as well.
while (range.start && links[range.start - 1])
range.start--;
let maxEnd = links.length - 1;
// Find all next siblings of the drop target that are pinned as well.
while (range.end < maxEnd && links[range.end + 1])
range.end++;
}
return range;
},
/**
* Checks if the given array of sites contains a pinned site that has
* been pushed out of the grid.
* @param aSites The array of sites to check.
* @param aCell The drop target cell.
* @return Whether there is an overflowed pinned cell.
*/
_hasOverflowedPinnedSite:
function DropPreview_hasOverflowedPinnedSite(aSites, aCell) {
// If the drop target isn't pinned there's no way a pinned site has been
// pushed out of the grid so we can just exit here.
if (!aCell.containsPinnedSite())
return false;
let cells = gGrid.cells;
// No cells have been pushed out of the grid, nothing to do here.
if (aSites.length <= cells.length)
return false;
let overflowedSite = aSites[cells.length];
// Nothing to do if the site that got pushed out of the grid is not pinned.
return (overflowedSite && overflowedSite.isPinned());
},
/**
* We have a overflowed pinned site that we need to re-position so that it's
* visible again. We try to find a lower-priority cell (empty or containing
* an unpinned site) that we can move it to.
* @param aSites The array of sites.
* @param aCell The drop target cell.
*/
_repositionOverflowedPinnedSite:
function DropPreview_repositionOverflowedPinnedSite(aSites, aCell) {
// Try to find a lower-priority cell (empty or containing an unpinned site).
let index = this._indexOfLowerPrioritySite(aSites, aCell);
if (index > -1) {
let cells = gGrid.cells;
let dropIndex = aCell.index;
// Move all pinned cells to their new positions to let the overflowed
// site fit into the grid.
for (let i = index + 1, lastPosition = index; i < aSites.length; i++) {
if (i != dropIndex) {
aSites[lastPosition] = aSites[i];
lastPosition = i;
}
}
// Finally, remove the overflowed site from its previous position.
aSites.splice(cells.length, 1);
}
},
/**
* Finds the index of the last cell that is empty or contains an unpinned
* site. These are considered to be of a lower priority.
* @param aSites The array of sites.
* @param aCell The drop target cell.
* @return The cell's index.
*/
_indexOfLowerPrioritySite:
function DropPreview_indexOfLowerPrioritySite(aSites, aCell) {
let cells = gGrid.cells;
let dropIndex = aCell.index;
// Search (beginning with the last site in the grid) for a site that is
// empty or unpinned (an thus lower-priority) and can be pushed out of the
// grid instead of the pinned site.
for (let i = cells.length - 1; i >= 0; i--) {
// The cell that is our drop target is not a good choice.
if (i == dropIndex)
continue;
let site = aSites[i];
// We can use the cell only if it's empty or the site is un-pinned.
if (!site || !site.isPinned())
return i;
}
return -1;
}
};

Просмотреть файл

@ -1,232 +0,0 @@
#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 singleton provides a custom drop target detection. We need this because
* the default DnD target detection relies on the cursor's position. We want
* to pick a drop target based on the dragged site's position.
*/
var gDropTargetShim = {
/**
* Cache for the position of all cells, cleaned after drag finished.
*/
_cellPositions: null,
/**
* The last drop target that was hovered.
*/
_lastDropTarget: null,
/**
* Initializes the drop target shim.
*/
init: function () {
gGrid.node.addEventListener("dragstart", this, true);
},
/**
* Add all event listeners needed during a drag operation.
*/
_addEventListeners: function () {
gGrid.node.addEventListener("dragend", this);
let docElement = document.documentElement;
docElement.addEventListener("dragover", this);
docElement.addEventListener("dragenter", this);
docElement.addEventListener("drop", this);
},
/**
* Remove all event listeners that were needed during a drag operation.
*/
_removeEventListeners: function () {
gGrid.node.removeEventListener("dragend", this);
let docElement = document.documentElement;
docElement.removeEventListener("dragover", this);
docElement.removeEventListener("dragenter", this);
docElement.removeEventListener("drop", this);
},
/**
* Handles all shim events.
*/
handleEvent: function (aEvent) {
switch (aEvent.type) {
case "dragstart":
this._dragstart(aEvent);
break;
case "dragenter":
aEvent.preventDefault();
break;
case "dragover":
this._dragover(aEvent);
break;
case "drop":
this._drop(aEvent);
break;
case "dragend":
this._dragend(aEvent);
break;
}
},
/**
* Handles the 'dragstart' event.
* @param aEvent The 'dragstart' event.
*/
_dragstart: function (aEvent) {
if (aEvent.target.classList.contains("newtab-link")) {
gGrid.lock();
this._addEventListeners();
}
},
/**
* Handles the 'dragover' event.
* @param aEvent The 'dragover' event.
*/
_dragover: function (aEvent) {
// XXX bug 505521 - Use the dragover event to retrieve the
// current mouse coordinates while dragging.
let sourceNode = aEvent.dataTransfer.mozSourceNode.parentNode;
gDrag.drag(sourceNode._newtabSite, aEvent);
// Find the current drop target, if there's one.
this._updateDropTarget(aEvent);
// If we have a valid drop target,
// let the drag-and-drop service know.
if (this._lastDropTarget) {
aEvent.preventDefault();
}
},
/**
* Handles the 'drop' event.
* @param aEvent The 'drop' event.
*/
_drop: function (aEvent) {
// We're accepting all drops.
aEvent.preventDefault();
// remember that drop event was seen, this explicitly
// assumes that drop event preceeds dragend event
this._dropSeen = true;
// Make sure to determine the current drop target
// in case the dragover event hasn't been fired.
this._updateDropTarget(aEvent);
// A site was successfully dropped.
this._dispatchEvent(aEvent, "drop", this._lastDropTarget);
},
/**
* Handles the 'dragend' event.
* @param aEvent The 'dragend' event.
*/
_dragend: function (aEvent) {
if (this._lastDropTarget) {
if (aEvent.dataTransfer.mozUserCancelled || !this._dropSeen) {
// The drag operation was cancelled or no drop event was generated
this._dispatchEvent(aEvent, "dragexit", this._lastDropTarget);
this._dispatchEvent(aEvent, "dragleave", this._lastDropTarget);
}
// Clean up.
this._lastDropTarget = null;
this._cellPositions = null;
}
this._dropSeen = false;
gGrid.unlock();
this._removeEventListeners();
},
/**
* Tries to find the current drop target and will fire
* appropriate dragenter, dragexit, and dragleave events.
* @param aEvent The current drag event.
*/
_updateDropTarget: function (aEvent) {
// Let's see if we find a drop target.
let target = this._findDropTarget(aEvent);
if (target != this._lastDropTarget) {
if (this._lastDropTarget)
// We left the last drop target.
this._dispatchEvent(aEvent, "dragexit", this._lastDropTarget);
if (target)
// We're now hovering a (new) drop target.
this._dispatchEvent(aEvent, "dragenter", target);
if (this._lastDropTarget)
// We left the last drop target.
this._dispatchEvent(aEvent, "dragleave", this._lastDropTarget);
this._lastDropTarget = target;
}
},
/**
* Determines the current drop target by matching the dragged site's position
* against all cells in the grid.
* @return The currently hovered drop target or null.
*/
_findDropTarget: function () {
// These are the minimum intersection values - we want to use the cell if
// the site is >= 50% hovering its position.
let minWidth = gDrag.cellWidth / 2;
let minHeight = gDrag.cellHeight / 2;
let cellPositions = this._getCellPositions();
let rect = gTransformation.getNodePosition(gDrag.draggedSite.node);
// Compare each cell's position to the dragged site's position.
for (let i = 0; i < cellPositions.length; i++) {
let inter = rect.intersect(cellPositions[i].rect);
// If the intersection is big enough we found a drop target.
if (inter.width >= minWidth && inter.height >= minHeight)
return cellPositions[i].cell;
}
// No drop target found.
return null;
},
/**
* Gets the positions of all cell nodes.
* @return The (cached) cell positions.
*/
_getCellPositions: function DropTargetShim_getCellPositions() {
if (this._cellPositions)
return this._cellPositions;
return this._cellPositions = gGrid.cells.map(function (cell) {
return {cell: cell, rect: gTransformation.getNodePosition(cell.node)};
});
},
/**
* Dispatches a custom DragEvent on the given target node.
* @param aEvent The source event.
* @param aType The event type.
* @param aTarget The target node that receives the event.
*/
_dispatchEvent: function (aEvent, aType, aTarget) {
let node = aTarget.node;
let event = document.createEvent("DragEvent");
// The event should not bubble to prevent recursion.
event.initDragEvent(aType, false, true, window, 0, 0, 0, 0, 0, false, false,
false, false, 0, node, aEvent.dataTransfer);
node.dispatchEvent(event);
}
};

Просмотреть файл

@ -1,295 +0,0 @@
#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
/**
* Define various fixed dimensions
*/
const GRID_BOTTOM_EXTRA = 7; // title's line-height extends 7px past the margin
const GRID_WIDTH_EXTRA = 1; // provide 1px buffer to allow for rounding error
/**
* This singleton represents the grid that contains all sites.
*/
var gGrid = {
/**
* The DOM node of the grid.
*/
_node: null,
_gridDefaultContent: null,
get node() { return this._node; },
/**
* The cached DOM fragment for sites.
*/
_siteFragment: null,
/**
* All cells contained in the grid.
*/
_cells: [],
get cells() { return this._cells; },
/**
* All sites contained in the grid's cells. Sites may be empty.
*/
get sites() { return this.cells.map(cell => cell.site); },
// Tells whether the grid has already been initialized.
get ready() { return !!this._ready; },
// Returns whether the page has finished loading yet.
get isDocumentLoaded() { return document.readyState == "complete"; },
/**
* Initializes the grid.
* @param aSelector The query selector of the grid.
*/
init: function Grid_init() {
this._node = document.getElementById("newtab-grid");
this._gridDefaultContent = this._node.lastChild;
this._createSiteFragment();
gLinks.populateCache(() => {
this._refreshGrid();
this._ready = true;
// If fetching links took longer than loading the page itself then
// we need to resize the grid as that was blocked until now.
// We also want to resize now if the page was already loaded when
// initializing the grid (the user toggled the page).
this._resizeGrid();
addEventListener("resize", this);
});
// Resize the grid as soon as the page loads.
if (!this.isDocumentLoaded) {
addEventListener("load", this);
}
},
/**
* Creates a new site in the grid.
* @param aLink The new site's link.
* @param aCell The cell that will contain the new site.
* @return The newly created site.
*/
createSite: function Grid_createSite(aLink, aCell) {
let node = aCell.node;
node.appendChild(this._siteFragment.cloneNode(true));
return new Site(node.firstElementChild, aLink);
},
/**
* Handles all grid events.
*/
handleEvent: function Grid_handleEvent(aEvent) {
switch (aEvent.type) {
case "load":
case "resize":
this._resizeGrid();
break;
}
},
/**
* Locks the grid to block all pointer events.
*/
lock: function Grid_lock() {
this.node.setAttribute("locked", "true");
},
/**
* Unlocks the grid to allow all pointer events.
*/
unlock: function Grid_unlock() {
this.node.removeAttribute("locked");
},
/**
* Renders and resizes the gird. _resizeGrid() call is needed to ensure
* that scrollbar disappears when the bottom row becomes empty following
* the block action, or tile display is turmed off via cog menu
*/
refresh() {
this._refreshGrid();
this._resizeGrid();
},
/**
* Renders the grid, including cells and sites.
*/
_refreshGrid() {
let cell = document.createElementNS(HTML_NAMESPACE, "div");
cell.classList.add("newtab-cell");
// Creates all the cells up to the maximum
let fragment = document.createDocumentFragment();
for (let i = 0; i < gGridPrefs.gridColumns * gGridPrefs.gridRows; i++) {
fragment.appendChild(cell.cloneNode(true));
}
// Create cells.
let cells = Array.from(fragment.childNodes, (cell) => new Cell(this, cell));
// Fetch links.
let links = gLinks.getLinks();
// Create sites.
let numLinks = Math.min(links.length, cells.length);
let hasHistoryTiles = false;
for (let i = 0; i < numLinks; i++) {
if (links[i]) {
this.createSite(links[i], cells[i]);
if (links[i].type == "history") {
hasHistoryTiles = true;
}
}
}
this._cells = cells;
while (this._gridDefaultContent.nextSibling) {
this._gridDefaultContent.nextSibling.remove();
}
this._node.appendChild(fragment);
document.getElementById("topsites-heading").textContent =
newTabString(hasHistoryTiles ? "userTopSites.heading" : "defaultTopSites.heading");
},
/**
* Calculate the height for a number of rows up to the maximum rows
* @param rows Number of rows defaulting to the max
*/
_computeHeight: function Grid_computeHeight(aRows) {
let {gridRows} = gGridPrefs;
aRows = aRows === undefined ? gridRows : Math.min(gridRows, aRows);
return aRows * this._cellHeight + GRID_BOTTOM_EXTRA;
},
/**
* Creates the DOM fragment that is re-used when creating sites.
*/
_createSiteFragment: function Grid_createSiteFragment() {
let site = document.createElementNS(HTML_NAMESPACE, "div");
site.classList.add("newtab-site");
site.setAttribute("draggable", "true");
let link = document.createElement("a");
link.className = "newtab-link";
site.appendChild(link);
let thumbnailPlaceHolder = document.createElement("span");
thumbnailPlaceHolder.className = "newtab-thumbnail placeholder";
link.appendChild(thumbnailPlaceHolder);
let thumbnail = document.createElement("img");
thumbnail.className = "newtab-thumbnail thumbnail";
link.appendChild(thumbnail);
let enhancedContent = document.createElement("img");
enhancedContent.className = "newtab-thumbnail enhanced-content";
link.appendChild(enhancedContent);
let title = document.createElement("span");
title.className = "newtab-title";
link.appendChild(title);
let pinButton = document.createElement("input");
pinButton.type = "button";
pinButton.title = newTabString("pin");
pinButton.className = "newtab-control newtab-control-pin";
site.appendChild(pinButton);
let removeButton = document.createElement("input");
removeButton.type = "button";
removeButton.title = newTabString("block");
removeButton.className = "newtab-control newtab-control-block";
site.appendChild(removeButton);
this._siteFragment = document.createDocumentFragment();
this._siteFragment.appendChild(site);
},
/**
* Test a tile at a given position for being pinned or history
* @param position Position in sites array
*/
_isHistoricalTile: function Grid_isHistoricalTile(aPos) {
let site = this.sites[aPos];
return site && (site.isPinned() || site.link && site.link.type == "history");
},
/**
* Make sure the correct number of rows and columns are visible
*/
_resizeGrid: function Grid_resizeGrid() {
// If we're somehow called before the page has finished loading,
// let's bail out to avoid caching zero heights and widths.
// We'll be called again when DOMContentLoaded fires.
// Same goes for the grid if that's not ready yet.
if (!this.isDocumentLoaded || !this._ready) {
return;
}
// Save the cell's computed height/width including margin and border
if (this._cellHeight === undefined) {
let refCell = document.querySelector(".newtab-cell");
let style = getComputedStyle(refCell);
this._cellHeight = refCell.offsetHeight +
parseFloat(style.marginTop) + parseFloat(style.marginBottom);
this._cellWidth = refCell.offsetWidth +
parseFloat(style.marginLeft) + parseFloat(style.marginRight);
}
let searchContainer = document.querySelector("#newtab-search-container");
// Save search-container margin height
if (this._searchContainerMargin === undefined) {
let style = getComputedStyle(searchContainer);
this._searchContainerMargin = parseFloat(style.marginBottom) +
parseFloat(style.marginTop);
}
// Find the number of rows we can place into view port
let availHeight = document.documentElement.clientHeight -
searchContainer.offsetHeight - this._searchContainerMargin;
let visibleRows = Math.floor(availHeight / this._cellHeight);
// Find the number of columns that fit into view port
let maxGridWidth = gGridPrefs.gridColumns * this._cellWidth + GRID_WIDTH_EXTRA;
// available width is current grid width, but no greater than maxGridWidth
let availWidth = Math.min(document.querySelector("#newtab-grid").clientWidth,
maxGridWidth);
// finally get the number of columns we can fit into view port
let gridColumns = Math.floor(availWidth / this._cellWidth);
// walk sites backwords until a pinned or history tile is found or visibleRows reached
let tileIndex = Math.min(gGridPrefs.gridRows * gridColumns, this.sites.length) - 1;
while (tileIndex >= visibleRows * gridColumns) {
if (this._isHistoricalTile(tileIndex)) {
break;
}
tileIndex--;
}
// Compute the actual number of grid rows we will display (potentially
// with a scroll bar). tileIndex now points to a historical tile with
// heighest index or to the last index of the visible row, if none found
// Dividing tileIndex by number of tiles in a column gives the rows
let gridRows = Math.floor(tileIndex / gridColumns) + 1;
// we need to set grid width, for otherwise the scrollbar may shrink
// the grid when shown and cause grid layout to be different from
// what being computed above. This, in turn, may cause scrollbar shown
// for directory tiles, and introduce jitter when grid width is aligned
// exactly on the column boundary
this._node.style.width = gridColumns * this._cellWidth + "px";
this._node.style.maxWidth = gGridPrefs.gridColumns * this._cellWidth +
GRID_WIDTH_EXTRA + "px";
this._node.style.height = this._computeHeight() + "px";
this._node.style.maxHeight = this._computeHeight(gridRows) + "px";
}
};

Просмотреть файл

@ -1,512 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html {
width: 100%;
height: 100%;
}
body {
font: message-box;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
background-color: #F9F9FA;
display: -moz-box;
position: relative;
-moz-box-flex: 1;
-moz-user-focus: normal;
-moz-box-orient: vertical;
}
input {
font: message-box;
font-size: 16px;
}
input[type=button] {
cursor: pointer;
}
/* UNDO */
#newtab-undo-container {
transition: opacity 100ms ease-out;
-moz-box-align: center;
-moz-box-pack: center;
position: relative;
left: -50%;
}
#newtab-undo-container[undo-disabled] {
opacity: 0;
pointer-events: none;
}
/* CUSTOMIZE */
#newtab-customize-button {
position: absolute;
top: 10px;
right: 20px;
z-index: 101;
}
#newtab-customize-button:dir(rtl) {
left: 20px;
right: auto;
}
/* MARGINS */
#newtab-vertical-margin {
display: -moz-box;
position: relative;
-moz-box-flex: 1;
-moz-box-orient: vertical;
}
#newtab-margin-undo-container {
display: -moz-box;
left: 50%;
position: absolute;
top: 6px;
z-index: 1;
}
#newtab-margin-undo-container:dir(rtl) {
left: auto;
right: 6px;
}
#newtab-undo-close-button:dir(rtl) {
float:left;
}
#newtab-horizontal-margin {
display: -moz-box;
-moz-box-flex: 1;
}
#newtab-margin-top,
#newtab-margin-bottom {
display: -moz-box;
position: relative;
}
#newtab-margin-top {
-moz-box-flex: 1;
}
#newtab-margin-bottom {
-moz-box-flex: 2;
}
.newtab-side-margin {
min-width: 10px;
-moz-box-flex: 1;
}
/* GRID */
#newtab-grid {
-moz-box-flex: 5;
overflow: hidden;
text-align: center;
transition: 100ms ease-out;
transition-property: opacity;
}
#newtab-grid[page-disabled] {
opacity: 0;
}
#newtab-grid[locked],
#newtab-grid[page-disabled] {
pointer-events: none;
}
body:not(.compact) #topsites-heading {
display: none;
}
/*
* If you change the sizes here, make sure you
* change the preferences:
* toolkit.pageThumbs.minWidth
* toolkit.pageThumbs.minHeight
*/
/* CELLS */
.newtab-cell {
display: -moz-box;
height: 210px;
margin: 20px 10px 35px;
width: 290px;
}
body.compact .newtab-cell {
width: 110px;
height: 110px;
margin: 12px;
}
/* SITES */
.newtab-site {
position: relative;
-moz-box-flex: 1;
transition: 100ms ease-out;
transition-property: top, left, opacity;
}
.newtab-site[frozen] {
position: absolute;
pointer-events: none;
}
.newtab-site[dragged] {
transition-property: none;
z-index: 10;
}
/* LINK + THUMBNAILS */
.newtab-link,
.newtab-thumbnail {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
/* TITLES */
.newtab-title {
overflow: hidden;
position: absolute;
right: 0;
text-align: center;
bottom: 0;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
}
.newtab-title {
left: 0;
padding: 0 4px;
}
/* CONTROLS */
.newtab-control {
position: absolute;
opacity: 0;
transition: opacity 100ms ease-out;
}
.newtab-control:-moz-focusring,
.newtab-cell:not([ignorehover]) > .newtab-site:hover > .newtab-control {
opacity: 1;
}
.newtab-control[dragged] {
opacity: 0 !important;
}
@media (-moz-touch-enabled) {
.newtab-control {
opacity: 1;
}
}
/* DRAG & DROP */
/*
* This is just a temporary drag element used for dataTransfer.setDragImage()
* so that we can use custom drag images and elements. It needs an opacity of
* 0.01 so that the core code detects that it's in fact a visible element.
*/
.newtab-drag {
width: 1px;
height: 1px;
background-color: #fff;
opacity: 0.01;
}
/* SEARCH */
#newtab-search-container {
display: -moz-box;
position: relative;
-moz-box-pack: center;
margin: 55px 0 15px;
}
body.compact #newtab-search-container {
margin-top: 0;
margin-bottom: 80px;
}
#newtab-search-container[page-disabled] {
opacity: 0;
pointer-events: none;
}
#newtab-search-form {
display: -moz-box;
position: relative;
height: 36px;
-moz-box-flex: 1;
max-width: 600px; /* 2 * (290 cell width + 10 cell margin) */
}
#newtab-search-icon {
width: 35px;
height: 35px;
background: url("chrome://browser/skin/search-glass.svg") no-repeat 12px center/16px;
fill: rgba(12, 12, 13, 0.4);
-moz-context-properties: fill;
position: absolute;
offset-inline-start: 0;
}
#newtab-search-text {
-moz-box-flex: 1;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 3px;
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
color: inherit;
padding: 0;
padding-inline-end: 36px;
padding-inline-start: 35px;
width: 100%;
font-size: 15px;
}
#newtab-search-text:active,
#newtab-search-text:focus {
border-color: #0A84FF;
box-shadow: 0 0 0 2px #0A84FF;
}
#newtab-search-submit {
offset-inline-end: 0;
color: transparent;
background: url("chrome://browser/skin/forward.svg") no-repeat center center;
-moz-context-properties: fill;
fill: rgba(12, 12, 13, 0.4);
position: absolute;
border: 0;
border-radius: 0 3px 3px 0;
background-size: 16px 16px;
height: 100%;
width: 36px;
}
#newtab-search-submit:dir(rtl) {
transform: scaleX(-1);
}
#newtab-search-submit:focus, #newtab-search-submit:hover {
background-color: rgba(12, 12, 13, 0.1);
cursor: pointer;
}
#newtab-search-submit:active {
background-color: rgba(12, 12, 13, 0.15);
}
/* CUSTOMIZE */
#newtab-customize-overlay {
opacity: 0;
display: none;
width: 100%;
height: 100%;
background: #F9F9F9;
z-index: 100;
position: fixed;
transition: opacity .07s linear;
}
.newtab-customize-panel-container {
position: absolute;
margin-right: 40px;
right: 0;
}
.newtab-customize-panel-container:dir(rtl) {
right: auto;
left: 0;
}
#newtab-customize-panel {
z-index: 999;
margin-top: 55px;
min-width: 270px;
position: absolute;
top: 100%;
right: -25px;
filter: drop-shadow(0 0 1px rgba(0,0,0,0.4)) drop-shadow(0 3px 4px rgba(0,0,0,0.4));
transition: all 200ms ease-in-out;
transform-origin: top right;
transform: translate(-30px, -20px) scale(0) translate(30px, 20px);
}
#newtab-customize-panel:dir(rtl) {
transform-origin: 40px top 20px;
}
#newtab-customize-panel:dir(rtl),
#newtab-customize-panel-anchor:dir(rtl) {
left: 15px;
right: auto;
}
#newtab-customize-panel[open="true"] {
transform: translate(-30px, -20px) scale(1) translate(30px, 20px);
}
#newtab-customize-panel-anchor {
width: 18px;
height: 18px;
background-color: white;
transform: rotate(45deg);
position: absolute;
top: -6px;
right: 15px;
}
#newtab-customize-title {
color: #7A7A7A;
font-size: 14px;
background-color: #FFFFFF;
line-height: 25px;
padding: 15px;
font-weight: 600;
cursor: default;
border-radius: 5px 5px 0px 0px;
max-width: 300px;
overflow: hidden;
display: table-cell;
border-top: none;
}
#newtab-customize-panel-inner-wrapper {
background-color: #FFFFFF;
border-radius: 6px;
overflow: hidden;
}
#newtab-customize-title > label {
cursor: default;
}
#newtab-customize-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
.newtab-customize-panel-item {
line-height: 25px;
padding: 15px;
padding-inline-start: 40px;
font-size: 14px;
cursor: pointer;
max-width: 300px;
}
.newtab-customize-panel-item:not(:first-child) {
border-top: 1px solid threedshadow;
}
.newtab-customize-panel-subitem > label,
.newtab-customize-panel-item > label,
.newtab-customize-complex-option {
padding: 0;
margin: 0;
cursor: pointer;
}
.newtab-customize-panel-item,
.newtab-customize-complex-option {
display: block;
text-align: start;
background-color: #F9F9F9;
}
.newtab-customize-panel-item[selected]:dir(rtl){
background-position: right 15px center;
}
.newtab-customize-complex-option:hover > .selectable:not([selected]):dir(rtl),
.selectable:not([selected]):hover:dir(rtl) {
background-position: right 15px center;
}
.newtab-customize-panel-item:not([selected]),
.newtab-customize-panel-subitem:not([selected]){
color: #7A7A7A;
}
.newtab-customize-panel-item:not([selected]):hover {
color: #FFFFFF;
background-color: #4A90E2
}
.newtab-customize-complex-option:hover > .selectable:not([selected]),
.selectable:not([selected]):hover {
background: url("chrome://global/skin/menu/shared-menu-check-hover.svg") no-repeat #FFFFFF;
background-size: 16px 16px;
background-position: 15px 15px;
color: #171F26;
}
.newtab-customize-complex-option:hover > .selectable:not([selected]) + .newtab-customize-panel-subitem {
background-color: #FFFFFF;
}
.newtab-customize-panel-item[selected] {
background: url("chrome://global/skin/menu/shared-menu-check-active.svg") no-repeat transparent;
background-size: 16px 16px;
background-position: 15px 15px;
color: black;
font-weight: 600;
}
.newtab-customize-panel-subitem > .checkbox {
width: 18px;
height: 18px;
background-color: #FFFFFF;
border: solid 1px threedshadow;
}
.newtab-customize-panel-subitem[selected] > .checkbox {
background: url("chrome://global/skin/menu/shared-menu-check-black.svg") no-repeat #FFFFFF;
background-size: 9px 9px;
background-position: center;
color: #333333;
}
.newtab-customize-panel-subitem {
font-size: 12px;
padding: 0px 15px 15px 15px;
padding-inline-start: 40px;
display: block;
max-width: 300px;
}
.newtab-customize-panel-subitem > label {
padding: 0px 10px;
line-height: 20px;
vertical-align: middle;
max-width: 225px;
}
.newtab-customize-panel-superitem {
line-height: 20px;
border-bottom: medium none !important;
padding: 15px 15px 10px 15px;
padding-inline-start: 40px;
border-top: 1px solid threedshadow;
}
.contentSearchSuggestionTable {
font: message-box;
font-size: 16px;
border: 0;
transform: translateY(2px);
}

Просмотреть файл

@ -1,67 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/PageThumbs.jsm");
ChromeUtils.import("resource://gre/modules/BackgroundPageThumbs.jsm");
ChromeUtils.import("resource://gre/modules/NewTabUtils.jsm");
ChromeUtils.defineModuleGetter(this, "Rect",
"resource://gre/modules/Geometry.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
var {
links: gLinks,
allPages: gAllPages,
linkChecker: gLinkChecker,
pinnedLinks: gPinnedLinks,
blockedLinks: gBlockedLinks,
gridPrefs: gGridPrefs
} = NewTabUtils;
XPCOMUtils.defineLazyGetter(this, "gStringBundle", function() {
return Services.strings.
createBundle("chrome://browser/locale/newTab.properties");
});
function newTabString(name, args) {
let stringName = "newtab." + name;
if (!args) {
return gStringBundle.GetStringFromName(stringName);
}
return gStringBundle.formatStringFromName(stringName, args, args.length);
}
function inPrivateBrowsingMode() {
return PrivateBrowsingUtils.isContentWindowPrivate(window);
}
const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
const XUL_NAMESPACE = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const TILES_EXPLAIN_LINK = "https://support.mozilla.org/kb/how-do-tiles-work-firefox";
const TILES_INTRO_LINK = "https://www.mozilla.org/firefox/tiles/";
const TILES_PRIVACY_LINK = "https://www.mozilla.org/privacy/";
#include transformations.js
#include page.js
#include grid.js
#include cells.js
#include sites.js
#include drag.js
#include dragDataHelper.js
#include drop.js
#include dropTargetShim.js
#include dropPreview.js
#include updater.js
#include undo.js
#include search.js
#include customize.js
// Everything is loaded. Initialize the New Tab Page.
gPage.init();

Просмотреть файл

@ -1,97 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html [
<!ENTITY % newTabDTD SYSTEM "chrome://browser/locale/newTab.dtd">
%newTabDTD;
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
%browserDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&newtab.pageTitle;</title>
<link rel="stylesheet" type="text/css" media="all" href="chrome://global/skin/" />
<link rel="stylesheet" type="text/css" media="all" href="chrome://browser/content/contentSearchUI.css" />
<link rel="stylesheet" type="text/css" media="all" href="chrome://browser/content/newtab/newTab.css" />
<link rel="stylesheet" type="text/css" media="all" href="chrome://browser/skin/newtab/newTab.css" />
</head>
<body dir="&locale.dir;">
<div id="newtab-customize-overlay"></div>
<div class="newtab-customize-panel-container">
<div id="newtab-customize-panel" orient="vertical">
<div id="newtab-customize-panel-anchor"></div>
<div id="newtab-customize-panel-inner-wrapper">
<div id="newtab-customize-title" class="newtab-customize-panel-item">
<label>&newtab.customize.cog.title2;</label>
</div>
<div class="newtab-customize-complex-option">
<div id="newtab-customize-classic" class="newtab-customize-panel-superitem newtab-customize-panel-item selectable">
<label>&newtab.customize.classic;</label>
</div>
<div id="newtab-customize-enhanced" class="newtab-customize-panel-subitem">
<label class="checkbox"></label>
<label>&newtab.customize.cog.enhanced;</label>
</div>
</div>
<div id="newtab-customize-blank" class="newtab-customize-panel-item selectable">
<label>&newtab.customize.blank2;</label>
</div>
<div id="newtab-customize-learn" class="newtab-customize-panel-item">
<label>&newtab.customize.cog.learn;</label>
</div>
</div>
</div>
</div>
<div id="newtab-vertical-margin">
<div id="newtab-margin-top"/>
<div id="newtab-margin-undo-container">
<div id="newtab-undo-container" undo-disabled="true">
<label id="newtab-undo-label">&newtab.undo.removedLabel;</label>
<button id="newtab-undo-button" tabindex="-1"
class="newtab-undo-button">&newtab.undo.undoButton;</button>
<button id="newtab-undo-restore-button" tabindex="-1"
class="newtab-undo-button">&newtab.undo.restoreButton;</button>
<button id="newtab-undo-close-button" tabindex="-1" title="&newtab.undo.closeTooltip;"/>
</div>
</div>
<div id="newtab-search-container">
<div id="newtab-search-form">
<div id="newtab-search-icon"/>
<input type="text" name="q" value="" id="newtab-search-text"
placeholder="&searchInput.placeholder;"
aria-label="&contentSearchInput.label;" maxlength="256"/>
<input id="newtab-search-submit" type="button"
title="&contentSearchSubmit.tooltip;"/>
</div>
</div>
<div id="newtab-horizontal-margin">
<div class="newtab-side-margin"/>
<div id="newtab-grid">
<h1 id="topsites-heading"/>
</div>
<div class="newtab-side-margin"/>
</div>
<div id="newtab-margin-bottom"/>
</div>
<input id="newtab-customize-button" type="button" dir="&locale.dir;"
value="&#x2699;"
title="&newtab.customize.title;"/>
</body>
<script type="text/javascript" src="chrome://browser/content/contentSearchUI.js"/>
<script type="text/javascript" src="chrome://browser/content/newtab/newTab.js"/>
</html>

Просмотреть файл

@ -1,248 +0,0 @@
#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
// The amount of time we wait while coalescing updates for hidden pages.
const SCHEDULE_UPDATE_TIMEOUT_MS = 1000;
/**
* This singleton represents the whole 'New Tab Page' and takes care of
* initializing all its components.
*/
var gPage = {
/**
* Initializes the page.
*/
init: function Page_init() {
// Add ourselves to the list of pages to receive notifications.
gAllPages.register(this);
// Listen for 'unload' to unregister this page. Save a promise that can be
// passed to others to know when to clean up, e.g., background thumbnails.
this.unloadingPromise = new Promise(resolve => {
addEventListener("unload", () => {
resolve();
this._handleUnloadEvent();
});
});
// XXX bug 991111 - Not all click events are correctly triggered when
// listening from xhtml nodes -- in particular middle clicks on sites, so
// listen from the xul window and filter then delegate
addEventListener("click", this, false);
// Check if the new tab feature is enabled.
let enabled = gAllPages.enabled;
if (enabled)
this._init();
this._updateAttributes(enabled);
// Initialize customize controls.
gCustomize.init();
},
/**
* Listens for notifications specific to this page.
*/
observe: function Page_observe(aSubject, aTopic, aData) {
if (aTopic == "nsPref:changed") {
gCustomize.updateSelected();
let enabled = gAllPages.enabled;
this._updateAttributes(enabled);
// Update thumbnails to the new enhanced setting
if (aData == "browser.newtabpage.enhanced") {
this.update();
}
// Initialize the whole page if we haven't done that, yet.
if (enabled) {
this._init();
} else {
gUndoDialog.hide();
}
} else if (aTopic == "page-thumbnail:create" && gGrid.ready) {
for (let site of gGrid.sites) {
if (site && site.url === aData) {
site.refreshThumbnail();
}
}
}
},
/**
* Updates the page's grid right away for visible pages. If the page is
* currently hidden, i.e. in a background tab or in the preloader, then we
* batch multiple update requests and refresh the grid once after a short
* delay. Accepts a single parameter the specifies the reason for requesting
* a page update. The page may decide to delay or prevent a requested updated
* based on the given reason.
*/
update(reason = "") {
// Update immediately if we're visible.
if (!document.hidden) {
// Ignore updates where reason=links-changed as those signal that the
// provider's set of links changed. We don't want to update visible pages
// in that case, it is ok to wait until the user opens the next tab.
if (reason != "links-changed" && gGrid.ready) {
gGrid.refresh();
}
return;
}
// Bail out if we scheduled before.
if (this._scheduleUpdateTimeout) {
return;
}
this._scheduleUpdateTimeout = requestIdleCallback(() => {
// Refresh if the grid is ready.
if (gGrid.ready) {
gGrid.refresh();
}
this._scheduleUpdateTimeout = null;
}, {timeout: SCHEDULE_UPDATE_TIMEOUT_MS});
},
/**
* Internally initializes the page. This runs only when/if the feature
* is/gets enabled.
*/
_init: function Page_init() {
if (this._initialized)
return;
this._initialized = true;
// Set submit button label for when CSS background are disabled (e.g.
// high contrast mode).
document.getElementById("newtab-search-submit").value =
document.body.getAttribute("dir") == "ltr" ? "\u25B6" : "\u25C0";
if (Services.prefs.getBoolPref("browser.newtabpage.compact")) {
document.body.classList.add("compact");
}
// Initialize search.
gSearch.init();
if (document.hidden) {
addEventListener("visibilitychange", this);
} else {
setTimeout(() => this.onPageFirstVisible());
}
// Initialize and render the grid.
gGrid.init();
// Initialize the drop target shim.
gDropTargetShim.init();
#ifdef XP_MACOSX
// Workaround to prevent a delay on MacOSX due to a slow drop animation.
document.addEventListener("dragover", this);
document.addEventListener("drop", this);
#endif
},
/**
* Updates the 'page-disabled' attributes of the respective DOM nodes.
* @param aValue Whether the New Tab Page is enabled or not.
*/
_updateAttributes: function Page_updateAttributes(aValue) {
// Set the nodes' states.
let nodeSelector = "#newtab-grid, #newtab-search-container";
for (let node of document.querySelectorAll(nodeSelector)) {
if (aValue)
node.removeAttribute("page-disabled");
else
node.setAttribute("page-disabled", "true");
}
// Enables/disables the control and link elements.
let inputSelector = ".newtab-control, .newtab-link";
for (let input of document.querySelectorAll(inputSelector)) {
if (aValue)
input.removeAttribute("tabindex");
else
input.setAttribute("tabindex", "-1");
}
},
/**
* Handles unload event
*/
_handleUnloadEvent: function Page_handleUnloadEvent() {
gAllPages.unregister(this);
},
/**
* Handles all page events.
*/
handleEvent: function Page_handleEvent(aEvent) {
switch (aEvent.type) {
case "load":
this.onPageVisibleAndLoaded();
break;
case "click":
let {button, target} = aEvent;
// Go up ancestors until we find a Site or not
while (target) {
if (target.hasOwnProperty("_newtabSite")) {
target._newtabSite.onClick(aEvent);
break;
}
target = target.parentNode;
}
break;
case "dragover":
if (gDrag.isValid(aEvent) && gDrag.draggedSite)
aEvent.preventDefault();
break;
case "drop":
if (gDrag.isValid(aEvent) && gDrag.draggedSite) {
aEvent.preventDefault();
aEvent.stopPropagation();
}
break;
case "visibilitychange":
// Cancel any delayed updates for hidden pages now that we're visible.
if (this._scheduleUpdateTimeout) {
cancelIdleCallback(this._scheduleUpdateTimeout);
this._scheduleUpdateTimeout = null;
// An update was pending so force an update now.
this.update();
}
setTimeout(() => this.onPageFirstVisible());
removeEventListener("visibilitychange", this);
break;
}
},
onPageFirstVisible: function () {
for (let site of gGrid.sites) {
if (site) {
site.captureIfMissing();
}
}
if (document.readyState == "complete") {
this.onPageVisibleAndLoaded();
} else {
addEventListener("load", this);
}
},
onPageVisibleAndLoaded() {
// Maybe tell the user they can undo an initial automigration
sendAsyncMessage("NewTab:MaybeShowMigrateMessage");
},
};

Просмотреть файл

@ -1,15 +0,0 @@
#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
var gSearch = {
init: function () {
document.getElementById("newtab-search-submit")
.addEventListener("click", e => this._contentSearchController.search(e));
let textbox = document.getElementById("newtab-search-text");
this._contentSearchController =
new ContentSearchUIController(textbox, textbox.parentNode, "newtab", "newtab");
},
};

Просмотреть файл

@ -1,285 +0,0 @@
#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
const THUMBNAIL_PLACEHOLDER_ENABLED =
Services.prefs.getBoolPref("browser.newtabpage.thumbnailPlaceholder");
/**
* This class represents a site that is contained in a cell and can be pinned,
* moved around or deleted.
*/
function Site(aNode, aLink) {
this._node = aNode;
this._node._newtabSite = this;
this._link = aLink;
this._render();
this._addEventHandlers();
}
Site.prototype = {
/**
* The site's DOM node.
*/
get node() { return this._node; },
/**
* The site's link.
*/
get link() { return this._link; },
/**
* The url of the site's link.
*/
get url() { return this.link.url; },
/**
* The title of the site's link.
*/
get title() { return this.link.title || this.link.url; },
/**
* The site's parent cell.
*/
get cell() {
let parentNode = this.node.parentNode;
return parentNode && parentNode._newtabCell;
},
/**
* Pins the site on its current or a given index.
* @param aIndex The pinned index (optional).
*/
pin: function Site_pin(aIndex) {
if (typeof aIndex == "undefined")
aIndex = this.cell.index;
this._updateAttributes(true);
gPinnedLinks.pin(this._link, aIndex);
},
/**
* Unpins the site and calls the given callback when done.
*/
unpin: function Site_unpin() {
if (this.isPinned()) {
this._updateAttributes(false);
gPinnedLinks.unpin(this._link);
gUpdater.updateGrid();
}
},
/**
* Checks whether this site is pinned.
* @return Whether this site is pinned.
*/
isPinned: function Site_isPinned() {
return gPinnedLinks.isPinned(this._link);
},
/**
* Blocks the site (removes it from the grid) and calls the given callback
* when done.
*/
block: function Site_block() {
if (!gBlockedLinks.isBlocked(this._link)) {
gUndoDialog.show(this);
gBlockedLinks.block(this._link);
gUpdater.updateGrid();
}
},
/**
* Gets the DOM node specified by the given query selector.
* @param aSelector The query selector.
* @return The DOM node we found.
*/
_querySelector: function Site_querySelector(aSelector) {
return this.node.querySelector(aSelector);
},
/**
* Updates attributes for all nodes which status depends on this site being
* pinned or unpinned.
* @param aPinned Whether this site is now pinned or unpinned.
*/
_updateAttributes: function (aPinned) {
let control = this._querySelector(".newtab-control-pin");
if (aPinned) {
this.node.setAttribute("pinned", true);
control.setAttribute("title", newTabString("unpin"));
} else {
this.node.removeAttribute("pinned");
control.setAttribute("title", newTabString("pin"));
}
},
_newTabString: function(str, substrArr) {
let regExp = /%[0-9]\$S/g;
let matches;
while ((matches = regExp.exec(str))) {
let match = matches[0];
let index = match.charAt(1); // Get the digit in the regExp.
str = str.replace(match, substrArr[index - 1]);
}
return str;
},
/**
* Renders the site's data (fills the HTML fragment).
*/
_render: function Site_render() {
// setup display variables
let enhanced = gAllPages.enhanced;
let url = this.url;
let title = enhanced && enhanced.title ? enhanced.title :
this.link.type == "history" ? this.link.baseDomain :
this.title;
let tooltip = (this.title == url ? this.title : this.title + "\n" + url);
let link = this._querySelector(".newtab-link");
link.setAttribute("title", tooltip);
link.setAttribute("href", url);
this.node.setAttribute("type", this.link.type);
let titleNode = this._querySelector(".newtab-title");
titleNode.textContent = title;
if (this.link.titleBgColor) {
titleNode.style.backgroundColor = this.link.titleBgColor;
}
if (this.isPinned())
this._updateAttributes(true);
// Capture the page if the thumbnail is missing, which will cause page.js
// to be notified and call our refreshThumbnail() method.
this.captureIfMissing();
// but still display whatever thumbnail might be available now.
this.refreshThumbnail();
},
/**
* Captures the site's thumbnail in the background, but only if there's no
* existing thumbnail and the page allows background captures.
*/
captureIfMissing: function Site_captureIfMissing() {
if (!document.hidden && !this.link.imageURI) {
const {unloadingPromise} = gPage;
BackgroundPageThumbs.captureIfMissing(this.url, {unloadingPromise});
}
},
/**
* Refreshes the thumbnail for the site.
*/
refreshThumbnail: function Site_refreshThumbnail() {
// Only enhance tiles if that feature is turned on
let link = gAllPages.enhanced || this.link;
let thumbnail = this._querySelector(".newtab-thumbnail.thumbnail");
if (link.bgColor) {
thumbnail.style.backgroundColor = link.bgColor;
}
let uri = link.imageURI || PageThumbs.getThumbnailURL(this.url);
thumbnail.src = uri;
if (THUMBNAIL_PLACEHOLDER_ENABLED &&
link.type == "history" &&
link.baseDomain) {
let placeholder = this._querySelector(".newtab-thumbnail.placeholder");
let charCodeSum = 0;
for (let c of link.baseDomain) {
charCodeSum += c.charCodeAt(0);
}
const COLORS = 16;
let hue = Math.round((charCodeSum % COLORS) / COLORS * 360);
placeholder.style.backgroundColor = "hsl(" + hue + ",80%,40%)";
placeholder.textContent = link.baseDomain.substr(0,1).toUpperCase();
}
if (link.enhancedImageURI) {
let enhanced = this._querySelector(".enhanced-content");
enhanced.src = link.enhancedImageURI;
}
},
/**
* Adds event handlers for the site and its buttons.
*/
_addEventHandlers: function Site_addEventHandlers() {
// Register drag-and-drop event handlers.
this._node.addEventListener("dragstart", this);
this._node.addEventListener("dragend", this);
this._node.addEventListener("mouseover", this);
},
/**
* Speculatively opens a connection to the current site.
*/
_speculativeConnect: function Site_speculativeConnect() {
let sc = Services.io.QueryInterface(Ci.nsISpeculativeConnect);
let uri = Services.io.newURI(this.url);
if (!uri.schemeIs("http") && !uri.schemeIs("https")) {
return;
}
try {
// This can throw for certain internal URLs, when they wind up in
// about:newtab. Be sure not to propagate the error.
// We use the URI's codebase principal here to open its speculative
// connection.
let originAttributes = document.docShell.getOriginAttributes();
let principal = Services.scriptSecurityManager
.createCodebasePrincipal(uri, originAttributes);
sc.speculativeConnect2(uri, principal, null);
} catch (e) {}
},
/**
* Handles site click events.
*/
onClick: function Site_onClick(aEvent) {
let pinned = this.isPinned();
let {button, target} = aEvent;
const isLinkClick = target.classList.contains("newtab-link") ||
target.parentElement.classList.contains("newtab-link");
// Handle primary click for pin and block
if (button == 0 && !isLinkClick) {
aEvent.preventDefault();
if (target.classList.contains("newtab-control-block")) {
this.block();
}
else if (pinned && target.classList.contains("newtab-control-pin")) {
this.unpin();
}
else if (!pinned && target.classList.contains("newtab-control-pin")) {
this.pin();
}
}
},
/**
* Handles all site events.
*/
handleEvent: function Site_handleEvent(aEvent) {
switch (aEvent.type) {
case "mouseover":
this._node.removeEventListener("mouseover", this);
this._speculativeConnect();
break;
case "dragstart":
gDrag.start(this, aEvent);
break;
case "dragend":
gDrag.end(this, aEvent);
break;
}
}
};

Просмотреть файл

@ -1,270 +0,0 @@
#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 singleton allows to transform the grid by repositioning a site's node
* in the DOM and by showing or hiding the node. It additionally provides
* convenience methods to work with a site's DOM node.
*/
var gTransformation = {
/**
* Returns the width of the left and top border of a cell. We need to take it
* into account when measuring and comparing site and cell positions.
*/
get _cellBorderWidths() {
let cstyle = window.getComputedStyle(gGrid.cells[0].node);
let widths = {
left: parseInt(cstyle.getPropertyValue("border-left-width")),
top: parseInt(cstyle.getPropertyValue("border-top-width"))
};
// Cache this value, overwrite the getter.
Object.defineProperty(this, "_cellBorderWidths",
{value: widths, enumerable: true});
return widths;
},
/**
* Gets a DOM node's position.
* @param aNode The DOM node.
* @return A Rect instance with the position.
*/
getNodePosition: function Transformation_getNodePosition(aNode) {
let {left, top, width, height} = aNode.getBoundingClientRect();
return new Rect(left + scrollX, top + scrollY, width, height);
},
/**
* Fades a given node from zero to full opacity.
* @param aNode The node to fade.
* @param aCallback The callback to call when finished.
*/
fadeNodeIn: function Transformation_fadeNodeIn(aNode, aCallback) {
this._setNodeOpacity(aNode, 1, function () {
// Clear the style property.
aNode.style.opacity = "";
if (aCallback)
aCallback();
});
},
/**
* Fades a given node from full to zero opacity.
* @param aNode The node to fade.
* @param aCallback The callback to call when finished.
*/
fadeNodeOut: function Transformation_fadeNodeOut(aNode, aCallback) {
this._setNodeOpacity(aNode, 0, aCallback);
},
/**
* Fades a given site from zero to full opacity.
* @param aSite The site to fade.
* @param aCallback The callback to call when finished.
*/
showSite: function Transformation_showSite(aSite, aCallback) {
this.fadeNodeIn(aSite.node, aCallback);
},
/**
* Fades a given site from full to zero opacity.
* @param aSite The site to fade.
* @param aCallback The callback to call when finished.
*/
hideSite: function Transformation_hideSite(aSite, aCallback) {
this.fadeNodeOut(aSite.node, aCallback);
},
/**
* Allows to set a site's position.
* @param aSite The site to re-position.
* @param aPosition The desired position for the given site.
*/
setSitePosition: function Transformation_setSitePosition(aSite, aPosition) {
let style = aSite.node.style;
let {top, left} = aPosition;
style.top = top + "px";
style.left = left + "px";
},
/**
* Freezes a site in its current position by positioning it absolute.
* @param aSite The site to freeze.
*/
freezeSitePosition: function Transformation_freezeSitePosition(aSite) {
if (this._isFrozen(aSite))
return;
let style = aSite.node.style;
let comp = getComputedStyle(aSite.node, null);
style.width = comp.getPropertyValue("width");
style.height = comp.getPropertyValue("height");
aSite.node.setAttribute("frozen", "true");
this.setSitePosition(aSite, this.getNodePosition(aSite.node));
},
/**
* Unfreezes a site by removing its absolute positioning.
* @param aSite The site to unfreeze.
*/
unfreezeSitePosition: function Transformation_unfreezeSitePosition(aSite) {
if (!this._isFrozen(aSite))
return;
let style = aSite.node.style;
style.left = style.top = style.width = style.height = "";
aSite.node.removeAttribute("frozen");
},
/**
* Slides the given site to the target node's position.
* @param aSite The site to move.
* @param aTarget The slide target.
* @param aOptions Set of options (see below).
* unfreeze - unfreeze the site after sliding
* callback - the callback to call when finished
*/
slideSiteTo: function Transformation_slideSiteTo(aSite, aTarget, aOptions) {
let currentPosition = this.getNodePosition(aSite.node);
let targetPosition = this.getNodePosition(aTarget.node)
let callback = aOptions && aOptions.callback;
let self = this;
function finish() {
if (aOptions && aOptions.unfreeze)
self.unfreezeSitePosition(aSite);
if (callback)
callback();
}
// We need to take the width of a cell's border into account.
targetPosition.left += this._cellBorderWidths.left;
targetPosition.top += this._cellBorderWidths.top;
// Nothing to do here if the positions already match.
if (currentPosition.left == targetPosition.left &&
currentPosition.top == targetPosition.top) {
finish();
} else {
this.setSitePosition(aSite, targetPosition);
this._whenTransitionEnded(aSite.node, ["left", "top"], finish);
}
},
/**
* Rearranges a given array of sites and moves them to their new positions or
* fades in/out new/removed sites.
* @param aSites An array of sites to rearrange.
* @param aOptions Set of options (see below).
* unfreeze - unfreeze the site after rearranging
* callback - the callback to call when finished
*/
rearrangeSites: function Transformation_rearrangeSites(aSites, aOptions) {
let batch = [];
let cells = gGrid.cells;
let callback = aOptions && aOptions.callback;
let unfreeze = aOptions && aOptions.unfreeze;
aSites.forEach(function (aSite, aIndex) {
// Do not re-arrange empty cells or the dragged site.
if (!aSite || aSite == gDrag.draggedSite)
return;
batch.push(new Promise(resolve => {
if (!cells[aIndex]) {
// The site disappeared from the grid, hide it.
this.hideSite(aSite, resolve);
} else if (this._getNodeOpacity(aSite.node) != 1) {
// The site disappeared before but is now back, show it.
this.showSite(aSite, resolve);
} else {
// The site's position has changed, move it around.
this._moveSite(aSite, aIndex, {unfreeze: unfreeze, callback: resolve});
}
}));
}, this);
if (callback) {
Promise.all(batch).then(callback);
}
},
/**
* Listens for the 'transitionend' event on a given node and calls the given
* callback.
* @param aNode The node that is transitioned.
* @param aProperties The properties we'll wait to be transitioned.
* @param aCallback The callback to call when finished.
*/
_whenTransitionEnded:
function Transformation_whenTransitionEnded(aNode, aProperties, aCallback) {
let props = new Set(aProperties);
aNode.addEventListener("transitionend", function onEnd(e) {
if (props.has(e.propertyName)) {
aNode.removeEventListener("transitionend", onEnd);
aCallback();
}
});
},
/**
* Gets a given node's opacity value.
* @param aNode The node to get the opacity value from.
* @return The node's opacity value.
*/
_getNodeOpacity: function Transformation_getNodeOpacity(aNode) {
let cstyle = window.getComputedStyle(aNode);
return cstyle.getPropertyValue("opacity");
},
/**
* Sets a given node's opacity.
* @param aNode The node to set the opacity value for.
* @param aOpacity The opacity value to set.
* @param aCallback The callback to call when finished.
*/
_setNodeOpacity:
function Transformation_setNodeOpacity(aNode, aOpacity, aCallback) {
if (this._getNodeOpacity(aNode) == aOpacity) {
if (aCallback)
aCallback();
} else {
if (aCallback) {
this._whenTransitionEnded(aNode, ["opacity"], aCallback);
}
aNode.style.opacity = aOpacity;
}
},
/**
* Moves a site to the cell with the given index.
* @param aSite The site to move.
* @param aIndex The target cell's index.
* @param aOptions Options that are directly passed to slideSiteTo().
*/
_moveSite: function Transformation_moveSite(aSite, aIndex, aOptions) {
this.freezeSitePosition(aSite);
this.slideSiteTo(aSite, gGrid.cells[aIndex], aOptions);
},
/**
* Checks whether a site is currently frozen.
* @param aSite The site to check.
* @return Whether the given site is frozen.
*/
_isFrozen: function Transformation_isFrozen(aSite) {
return aSite.node.hasAttribute("frozen");
}
};

Просмотреть файл

@ -1,116 +0,0 @@
#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
/**
* Dialog allowing to undo the removal of single site or to completely restore
* the grid's original state.
*/
var gUndoDialog = {
/**
* The undo dialog's timeout in miliseconds.
*/
HIDE_TIMEOUT_MS: 15000,
/**
* Contains undo information.
*/
_undoData: null,
/**
* Initializes the undo dialog.
*/
init: function UndoDialog_init() {
this._undoContainer = document.getElementById("newtab-undo-container");
this._undoContainer.addEventListener("click", this);
this._undoButton = document.getElementById("newtab-undo-button");
this._undoCloseButton = document.getElementById("newtab-undo-close-button");
this._undoRestoreButton = document.getElementById("newtab-undo-restore-button");
},
/**
* Shows the undo dialog.
* @param aSite The site that just got removed.
*/
show: function UndoDialog_show(aSite) {
if (this._undoData)
clearTimeout(this._undoData.timeout);
this._undoData = {
index: aSite.cell.index,
wasPinned: aSite.isPinned(),
blockedLink: aSite.link,
timeout: setTimeout(this.hide.bind(this), this.HIDE_TIMEOUT_MS)
};
this._undoContainer.removeAttribute("undo-disabled");
this._undoButton.removeAttribute("tabindex");
this._undoCloseButton.removeAttribute("tabindex");
this._undoRestoreButton.removeAttribute("tabindex");
},
/**
* Hides the undo dialog.
*/
hide: function UndoDialog_hide() {
if (!this._undoData)
return;
clearTimeout(this._undoData.timeout);
this._undoData = null;
this._undoContainer.setAttribute("undo-disabled", "true");
this._undoButton.setAttribute("tabindex", "-1");
this._undoCloseButton.setAttribute("tabindex", "-1");
this._undoRestoreButton.setAttribute("tabindex", "-1");
},
/**
* The undo dialog event handler.
* @param aEvent The event to handle.
*/
handleEvent: function UndoDialog_handleEvent(aEvent) {
switch (aEvent.target.id) {
case "newtab-undo-button":
this._undo();
break;
case "newtab-undo-restore-button":
this._undoAll();
break;
case "newtab-undo-close-button":
this.hide();
break;
}
},
/**
* Undo the last blocked site.
*/
_undo: function UndoDialog_undo() {
if (!this._undoData)
return;
let {index, wasPinned, blockedLink} = this._undoData;
gBlockedLinks.unblock(blockedLink);
if (wasPinned) {
gPinnedLinks.pin(blockedLink, index);
}
gUpdater.updateGrid();
this.hide();
},
/**
* Undo all blocked sites.
*/
_undoAll: function UndoDialog_undoAll() {
NewTabUtils.undoAll(() => {
gUpdater.updateGrid();
this.hide();
});
}
};
gUndoDialog.init();

Просмотреть файл

@ -1,177 +0,0 @@
#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 singleton provides functionality to update the current grid to a new
* set of pinned and blocked sites. It adds, moves and removes sites.
*/
var gUpdater = {
/**
* Updates the current grid according to its pinned and blocked sites.
* This removes old, moves existing and creates new sites to fill gaps.
* @param aCallback The callback to call when finished.
*/
updateGrid: function Updater_updateGrid(aCallback) {
let links = gLinks.getLinks().slice(0, gGrid.cells.length);
// Find all sites that remain in the grid.
let sites = this._findRemainingSites(links);
// Remove sites that are no longer in the grid.
this._removeLegacySites(sites, () => {
// Freeze all site positions so that we can move their DOM nodes around
// without any visual impact.
this._freezeSitePositions(sites);
// Move the sites' DOM nodes to their new position in the DOM. This will
// have no visual effect as all the sites have been frozen and will
// remain in their current position.
this._moveSiteNodes(sites);
// Now it's time to animate the sites actually moving to their new
// positions.
this._rearrangeSites(sites, () => {
// Try to fill empty cells and finish.
this._fillEmptyCells(links, aCallback);
// Update other pages that might be open to keep them synced.
gAllPages.update(gPage);
});
});
},
/**
* Takes an array of links and tries to correlate them to sites contained in
* the current grid. If no corresponding site can be found (i.e. the link is
* new and a site will be created) then just set it to null.
* @param aLinks The array of links to find sites for.
* @return Array of sites mapped to the given links (can contain null values).
*/
_findRemainingSites: function Updater_findRemainingSites(aLinks) {
let map = {};
// Create a map to easily retrieve the site for a given URL.
gGrid.sites.forEach(function (aSite) {
if (aSite)
map[aSite.url] = aSite;
});
// Map each link to its corresponding site, if any.
return aLinks.map(function (aLink) {
return aLink && (aLink.url in map) && map[aLink.url];
});
},
/**
* Freezes the given sites' positions.
* @param aSites The array of sites to freeze.
*/
_freezeSitePositions: function Updater_freezeSitePositions(aSites) {
aSites.forEach(function (aSite) {
if (aSite)
gTransformation.freezeSitePosition(aSite);
});
},
/**
* Moves the given sites' DOM nodes to their new positions.
* @param aSites The array of sites to move.
*/
_moveSiteNodes: function Updater_moveSiteNodes(aSites) {
let cells = gGrid.cells;
// Truncate the given array of sites to not have more sites than cells.
// This can happen when the user drags a bookmark (or any other new kind
// of link) onto the grid.
let sites = aSites.slice(0, cells.length);
sites.forEach(function (aSite, aIndex) {
let cell = cells[aIndex];
let cellSite = cell.site;
// The site's position didn't change.
if (!aSite || cellSite != aSite) {
let cellNode = cell.node;
// Empty the cell if necessary.
if (cellSite)
cellNode.removeChild(cellSite.node);
// Put the new site in place, if any.
if (aSite)
cellNode.appendChild(aSite.node);
}
}, this);
},
/**
* Rearranges the given sites and slides them to their new positions.
* @param aSites The array of sites to re-arrange.
* @param aCallback The callback to call when finished.
*/
_rearrangeSites: function Updater_rearrangeSites(aSites, aCallback) {
let options = {callback: aCallback, unfreeze: true};
gTransformation.rearrangeSites(aSites, options);
},
/**
* Removes all sites from the grid that are not in the given links array or
* exceed the grid.
* @param aSites The array of sites remaining in the grid.
* @param aCallback The callback to call when finished.
*/
_removeLegacySites: function Updater_removeLegacySites(aSites, aCallback) {
let batch = [];
// Delete sites that were removed from the grid.
gGrid.sites.forEach(function (aSite) {
// The site must be valid and not in the current grid.
if (!aSite || aSites.includes(aSite))
return;
batch.push(new Promise(resolve => {
// Fade out the to-be-removed site.
gTransformation.hideSite(aSite, function () {
let node = aSite.node;
// Remove the site from the DOM.
node.remove();
resolve();
});
}));
});
Promise.all(batch).then(aCallback);
},
/**
* Tries to fill empty cells with new links if available.
* @param aLinks The array of links.
* @param aCallback The callback to call when finished.
*/
_fillEmptyCells: function Updater_fillEmptyCells(aLinks, aCallback) {
let {cells, sites} = gGrid;
// Find empty cells and fill them.
Promise.all(sites.map((aSite, aIndex) => {
if (aSite || !aLinks[aIndex])
return null;
return new Promise(resolve => {
// Create the new site and fade it in.
let site = gGrid.createSite(aLinks[aIndex], cells[aIndex]);
// Set the site's initial opacity to zero.
site.node.style.opacity = 0;
// Flush all style changes for the dynamically inserted site to make
// the fade-in transition work.
window.getComputedStyle(site.node).opacity;
gTransformation.showSite(site, resolve);
});
})).then(aCallback).catch(console.exception);
}
};

Просмотреть файл

@ -156,9 +156,6 @@ window._gBrowser = {
this.mCurrentBrowser = this.initialBrowser;
this.mCurrentBrowser.permanentKey = {};
CustomizableUI.addListener(this);
this._updateNewTabVisibility();
Services.obs.addObserver(this, "contextual-identity-updated");
this.mCurrentTab = this.tabContainer.firstChild;
@ -1812,6 +1809,8 @@ window._gBrowser = {
browser.loadURI(BROWSER_NEW_TAB_URL);
browser.docShellIsActive = false;
browser.renderLayers = true;
browser._urlbarFocused = true;
// Make sure the preloaded browser is loaded with desired zoom level
let tabURI = Services.io.newURI(BROWSER_NEW_TAB_URL);
@ -2075,9 +2074,19 @@ window._gBrowser = {
browser.droppedLinkHandler = handleDroppedLink;
// We start our browsers out as inactive, and then maintain
// activeness in the tab switcher.
browser.docShellIsActive = false;
// Most of the time, we start our browser's docShells out as inactive,
// and then maintain activeness in the tab switcher. Preloaded about:newtab's
// are already created with their docShell's as inactive, but then explicitly
// render their layers to ensure that we can switch to them quickly. We avoid
// setting docShellIsActive to false again in this case, since that'd cause
// the layers for the preloaded tab to be dropped, and we'd see a flash
// of empty content instead.
//
// So for all browsers except for the preloaded case, we set the browser
// docShell to inactive.
if (!usingPreloadedContent) {
browser.docShellIsActive = false;
}
// When addTab() is called with an URL that is not "about:blank" we
// set the "nodefaultsrc" attribute that prevents a frameLoader
@ -3899,42 +3908,6 @@ window._gBrowser = {
}
},
_updateNewTabVisibility() {
// Helper functions to help deal with customize mode wrapping some items
let wrap = n => n.parentNode.localName == "toolbarpaletteitem" ? n.parentNode : n;
let unwrap = n => n && n.localName == "toolbarpaletteitem" ? n.firstElementChild : n;
let sib = this.tabContainer;
do {
sib = unwrap(wrap(sib).nextElementSibling);
} while (sib && sib.hidden);
const kAttr = "hasadjacentnewtabbutton";
if (sib && sib.id == "new-tab-button") {
this.tabContainer.setAttribute(kAttr, "true");
} else {
this.tabContainer.removeAttribute(kAttr);
}
},
onWidgetAfterDOMChange(aNode, aNextNode, aContainer) {
if (aContainer.ownerDocument == document &&
aContainer.id == "TabsToolbar") {
this._updateNewTabVisibility();
}
},
onAreaNodeRegistered(aArea, aContainer) {
if (aContainer.ownerDocument == document &&
aArea == "TabsToolbar") {
this._updateNewTabVisibility();
}
},
onAreaReset(aArea, aContainer) {
this.onAreaNodeRegistered(aArea, aContainer);
},
_generateUniquePanelID() {
if (!this._uniquePanelIDCounter) {
this._uniquePanelIDCounter = 0;
@ -3953,8 +3926,6 @@ window._gBrowser = {
destroy() {
Services.obs.removeObserver(this, "contextual-identity-updated");
CustomizableUI.removeListener(this);
for (let tab of this.tabs) {
let browser = tab.linkedBrowser;
if (browser.registeredOpenURI) {

Просмотреть файл

@ -126,12 +126,17 @@
this.observe(null, "nsPref:changed", "privacy.userContext.enabled");
this._setPositionalAttributes();
CustomizableUI.addListener(this);
this._updateNewTabVisibility();
]]>
</constructor>
<destructor>
<![CDATA[
Services.prefs.removeObserver("privacy.userContext", this);
CustomizableUI.removeListener(this);
]]>
</destructor>
@ -908,6 +913,57 @@
]]>
</body>
</method>
<method name="_updateNewTabVisibility">
<body><![CDATA[
// Helper functions to help deal with customize mode wrapping some items
let wrap = n => n.parentNode.localName == "toolbarpaletteitem" ? n.parentNode : n;
let unwrap = n => n && n.localName == "toolbarpaletteitem" ? n.firstElementChild : n;
let sib = this;
do {
sib = unwrap(wrap(sib).nextElementSibling);
} while (sib && sib.hidden);
const kAttr = "hasadjacentnewtabbutton";
if (sib && sib.id == "new-tab-button") {
this.setAttribute(kAttr, "true");
} else {
this.removeAttribute(kAttr);
}
]]></body>
</method>
<method name="onWidgetAfterDOMChange">
<parameter name="aNode"/>
<parameter name="aNextNode"/>
<parameter name="aContainer"/>
<body><![CDATA[
if (aContainer.ownerDocument == document &&
aContainer.id == "TabsToolbar") {
this._updateNewTabVisibility();
}
]]></body>
</method>
<method name="onAreaNodeRegistered">
<parameter name="aArea"/>
<parameter name="aContainer"/>
<body><![CDATA[
if (aContainer.ownerDocument == document &&
aArea == "TabsToolbar") {
this._updateNewTabVisibility();
}
]]></body>
</method>
<method name="onAreaReset">
<parameter name="aArea"/>
<parameter name="aContainer"/>
<body><![CDATA[
this.onAreaNodeRegistered(aArea, aContainer);
]]></body>
</method>
</implementation>
<handlers>

Просмотреть файл

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/browser-test"
]
};

Просмотреть файл

@ -1,52 +0,0 @@
[DEFAULT]
skip-if = true # Bug 1433133 to remove; previously skipped for intermittents, e.g., Bug 1243103, Bug 1243398
support-files =
head.js
[browser_newtab_1188015.js]
[browser_newtab_background_captures.js]
[browser_newtab_block.js]
[browser_newtab_bug721442.js]
[browser_newtab_bug722273.js]
skip-if = (os == "mac" && debug) # temporary skip-if due to increase in intermittent failures on Mac debug - bug 1119906
[browser_newtab_bug723102.js]
[browser_newtab_bug723121.js]
[browser_newtab_bug725996.js]
skip-if = (os == "mac" || os == "win") && debug # bug 1338848
[browser_newtab_bug734043.js]
[browser_newtab_bug735987.js]
[browser_newtab_bug752841.js]
[browser_newtab_bug765628.js]
skip-if = (os == "mac" || os == "win") && debug # bug 1338836
[browser_newtab_bug876313.js]
[browser_newtab_bug991111.js]
[browser_newtab_bug991210.js]
[browser_newtab_bug998387.js]
[browser_newtab_bug1271075.js]
[browser_newtab_disable.js]
[browser_newtab_drag_drop.js]
[browser_newtab_drag_drop_ext.js]
# temporary until determine why more intermittent on VM
subsuite = clipboard
[browser_newtab_drop_preview.js]
[browser_newtab_focus.js]
[browser_newtab_fullscreen_focus.js]
skip-if = os == "mac" # bug 1394963
[browser_newtab_perwindow_private_browsing.js]
[browser_newtab_reflow_load.js]
support-files =
content-reflows.js
[browser_newtab_search.js]
support-files =
searchEngineNoLogo.xml
searchEngineFavicon.xml
searchEngine1xLogo.xml
searchEngine2xLogo.xml
searchEngine1x2xLogo.xml
../general/searchSuggestionEngine.xml
../general/searchSuggestionEngine.sjs
[browser_newtab_undo.js]
# temporary until determine why more intermittent on VM
subsuite = clipboard
[browser_newtab_unpin.js]
[browser_newtab_update.js]

Просмотреть файл

@ -1,26 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
gDirectorySource = "data:application/json," + JSON.stringify({
"directory": [{
url: "http://example1.com/",
enhancedImageURI: "data:image/png;base64,helloWORLD2",
title: "title1",
type: "affiliate",
titleBgColor: "green"
}]
});
add_task(async function() {
await pushPrefs(["browser.newtab.preload", false]);
// Make the page have a directory link
await setLinks([]);
await addNewTabPageTab();
let color = await performOnCell(0, cell => {
return cell.node.querySelector(".newtab-title").style.backgroundColor;
});
is(color, "green", "title bg color is green");
});

Просмотреть файл

@ -1,64 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Verifies that hidden, pre-loaded newtabs don't allow background captures, and
* when unhidden, do allow background captures.
*/
const CAPTURE_PREF = "browser.pagethumbnails.capturing_disabled";
XPCOMUtils.defineLazyServiceGetter(this, "PageThumbsStorageService",
"@mozilla.org/thumbnails/pagethumbs-service;1",
"nsIPageThumbsStorageService");
add_task(async function() {
// Disable captures.
await pushPrefs([CAPTURE_PREF, false]);
// Make sure the thumbnail doesn't exist yet.
let url = "http://example.com/";
let path = PageThumbsStorageService.getFilePathForURL(url);
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(path);
try {
file.remove(false);
} catch (err) {}
// Add a top site.
await setLinks("-1");
// We need a handle to a hidden, pre-loaded newtab so we can verify that it
// doesn't allow background captures. Ensure we have a preloaded browser.
gBrowser._createPreloadBrowser();
// Wait for the preloaded browser to load.
if (gBrowser._preloadedBrowser.contentDocument.readyState != "complete") {
await BrowserTestUtils.waitForEvent(gBrowser._preloadedBrowser, "load", true);
}
// We're now ready to use the preloaded browser.
BrowserOpenTab();
let tab = gBrowser.selectedTab;
let thumbnailCreatedPromise = new Promise(resolve => {
// Showing the preloaded tab should trigger thumbnail capture.
Services.obs.addObserver(function onCreate(subj, topic, data) {
if (data != url)
return;
Services.obs.removeObserver(onCreate, "page-thumbnail:create");
ok(true, "thumbnail created after preloaded tab was shown");
resolve();
}, "page-thumbnail:create");
});
// Enable captures.
await pushPrefs([CAPTURE_PREF, false]);
await thumbnailCreatedPromise;
// Test finished!
gBrowser.removeTab(tab);
file.remove(false);
});

Просмотреть файл

@ -1,65 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/*
* These tests make sure that blocking/removing sites from the grid works
* as expected. Pinned tabs should not be moved. Gaps will be re-filled
* if more sites are available.
*/
add_task(async function() {
// we remove sites and expect the gaps to be filled as long as there still
// are some sites available
await setLinks("0,1,2,3,4,5,6,7,8,9");
setPinnedLinks("");
await addNewTabPageTab();
await customizeNewTabPage("enhanced"); // Toggle enhanced off
await checkGrid("0,1,2,3,4,5,6,7,8");
await blockCell(4);
await checkGrid("0,1,2,3,5,6,7,8,9");
await blockCell(4);
await checkGrid("0,1,2,3,6,7,8,9,");
await blockCell(4);
await checkGrid("0,1,2,3,7,8,9,,");
// we removed a pinned site
await restore();
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",1");
await addNewTabPageTab();
await checkGrid("0,1p,2,3,4,5,6,7,8");
await blockCell(1);
await checkGrid("0,2,3,4,5,6,7,8,");
// we remove the last site on the grid (which is pinned) and expect the gap
// to be re-filled and the new site to be unpinned
await restore();
await setLinks("0,1,2,3,4,5,6,7,8,9");
setPinnedLinks(",,,,,,,,8");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8p");
await blockCell(8);
await checkGrid("0,1,2,3,4,5,6,7,9");
// we remove the first site on the grid with the last one pinned. all cells
// but the last one should shift to the left and a new site fades in
await restore();
await setLinks("0,1,2,3,4,5,6,7,8,9");
setPinnedLinks(",,,,,,,,8");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8p");
await blockCell(0);
await checkGrid("1,2,3,4,5,6,7,9,8p");
});

Просмотреть файл

@ -1,32 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
is(gBrowser.tabs.length, 1, "one tab is open initially");
// Add a few tabs.
let tabs = [];
function addTab(aURL, aReferrer) {
let tab = BrowserTestUtils.addTab(gBrowser, aURL, {referrerURI: aReferrer});
tabs.push(tab);
return BrowserTestUtils.browserLoaded(tab.linkedBrowser);
}
await addTab("http://mochi.test:8888/#0");
await addTab("http://mochi.test:8888/#1");
await addTab("http://mochi.test:8888/#2");
await addTab("http://mochi.test:8888/#3");
// Create a new tab page with a "www.example.com" tile and move it to the 2nd tab position.
await setLinks("-1");
await addNewTabPageTab();
gBrowser.moveTabTo(gBrowser.selectedTab, 1);
// Send a middle-click and confirm that the clicked site opens immediately next to the new tab page.
await BrowserTestUtils.synthesizeMouseAtCenter(".newtab-cell",
{button: 1}, gBrowser.selectedBrowser);
await BrowserTestUtils.browserLoaded(gBrowser.getBrowserAtIndex(2));
is(gBrowser.getBrowserAtIndex(2).currentURI.spec, "http://example.com/",
"Middle click opens site in a new tab immediately to the right.");
});

Просмотреть файл

@ -1,28 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks([
{url: "http://example7.com/", title: ""},
{url: "http://example8.com/", title: "title"},
{url: "http://example9.com/", title: "http://example9.com/"}
]);
await addNewTabPageTab();
await checkGrid("7p,8p,9p,0,1,2,3,4,5");
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
function checkTooltip(aIndex, aExpected, aMessage) {
let cell = content.gGrid.cells[aIndex];
let link = cell.node.querySelector(".newtab-link");
Assert.equal(link.getAttribute("title"), aExpected, aMessage);
}
checkTooltip(0, "http://example7.com/", "1st tooltip is correct");
checkTooltip(1, "title\nhttp://example8.com/", "2nd tooltip is correct");
checkTooltip(2, "http://example9.com/", "3rd tooltip is correct");
});
});

Просмотреть файл

@ -1,48 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const NOW = Date.now() * 1000;
const URL = "http://fake-site.com/";
add_task(async function() {
await Sanitizer.sanitize(["history"]);
await promiseAddFakeVisits();
await addNewTabPageTab();
let cellUrl = await performOnCell(0, cell => { return cell.site.url; });
is(cellUrl, URL, "first site is our fake site");
let updatedPromise = whenPagesUpdated();
await Sanitizer.sanitize(["history"]);
await updatedPromise;
let isGone = await performOnCell(0, cell => { return cell.site == null; });
ok(isGone, "fake site is gone");
});
function promiseAddFakeVisits() {
let visits = [];
for (let i = 59; i > 0; i--) {
visits.push({
visitDate: NOW - i * 60 * 1000000,
transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
});
}
let place = {
uri: makeURI(URL),
title: "fake site",
visits
};
return new Promise((resolve, reject) => {
PlacesUtils.asyncHistory.updatePlaces(place, {
handleError: () => reject(new Error("Couldn't add visit")),
handleResult() {},
handleCompletion() {
NewTabUtils.links.populateCache(function() {
NewTabUtils.allPages.update();
resolve();
}, true);
}
});
});
}

Просмотреть файл

@ -1,24 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
// create a new tab page and hide it.
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
let firstTab = gBrowser.selectedTab;
await addNewTabPageTab();
await BrowserTestUtils.removeTab(firstTab);
ok(NewTabUtils.allPages.enabled, "page is enabled");
NewTabUtils.allPages.enabled = false;
await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
Assert.ok(content.gGrid.node.hasAttribute("page-disabled"), "page is disabled");
});
NewTabUtils.allPages.enabled = true;
});

Просмотреть файл

@ -1,42 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
let grid = content.gGrid;
let cell = grid.cells[0];
let site = cell.site.node;
let link = site.querySelector(".newtab-link");
function checkGridLocked(aLocked, aMessage) {
Assert.equal(grid.node.hasAttribute("locked"), aLocked, aMessage);
}
function sendDragEvent(aEventType, aTarget) {
let dataTransfer = new content.DataTransfer(aEventType, false);
let event = content.document.createEvent("DragEvent");
event.initDragEvent(aEventType, true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
aTarget.dispatchEvent(event);
}
checkGridLocked(false, "grid is unlocked");
sendDragEvent("dragstart", link);
checkGridLocked(true, "grid is now locked");
sendDragEvent("dragend", link);
checkGridLocked(false, "grid isn't locked anymore");
sendDragEvent("dragstart", cell.node);
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
sendDragEvent("dragstart", site);
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
});
});

Просмотреть файл

@ -1,35 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8");
function doDrop(data) {
return ContentTask.spawn(gBrowser.selectedBrowser, { data }, async function(args) {
let dataTransfer = new content.DataTransfer("dragstart", false);
dataTransfer.mozSetDataAt("text/x-moz-url", args.data, 0);
let event = content.document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
let target = content.gGrid.cells[0].node;
target.dispatchEvent(event);
});
}
await doDrop("http://example99.com/\nblank");
is(NewTabUtils.pinnedLinks.links[0].url, "http://example99.com/",
"first cell is pinned and contains the dropped site");
await whenPagesUpdated();
await checkGrid("99p,0,1,2,3,4,5,6,7");
await doDrop("");
is(NewTabUtils.pinnedLinks.links[0].url, "http://example99.com/",
"first cell is still pinned with the site we dropped before");
});

Просмотреть файл

@ -1,34 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8");
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
content.addEventListener("error", function() {
sendAsyncMessage("test:newtab-error", {});
});
});
let receivedError = false;
let mm = gBrowser.selectedBrowser.messageManager;
mm.addMessageListener("test:newtab-error", function onResponse(message) {
mm.removeMessageListener("test:newtab-error", onResponse);
ok(false, "Error event happened");
receivedError = true;
});
let pagesUpdatedPromise = whenPagesUpdated();
for (let i = 0; i < 3; i++) {
await BrowserTestUtils.synthesizeMouseAtCenter(".newtab-control-block", {}, gBrowser.selectedBrowser);
}
await pagesUpdatedPromise;
ok(!receivedError, "we got here without any errors");
});

Просмотреть файл

@ -1,32 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8");
await simulateExternalDrop(1);
await checkGrid("0,99p,1,2,3,4,5,6,7");
await blockCell(1);
await checkGrid("0,1,2,3,4,5,6,7,8");
await simulateExternalDrop(1);
await checkGrid("0,99p,1,2,3,4,5,6,7");
// Simulate a restart and force the next about:newtab
// instance to read its data from the storage again.
NewTabUtils.blockedLinks.resetCache();
// Update all open pages, e.g. preloaded ones.
NewTabUtils.allPages.update();
await addNewTabPageTab();
await checkGrid("0,99p,1,2,3,4,5,6,7");
await blockCell(1);
await checkGrid("0,1,2,3,4,5,6,7,8");
});

Просмотреть файл

@ -1,55 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const PREF_NEWTAB_ROWS = "browser.newtabpage.rows";
const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns";
function getCellsCount() {
return ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
return content.gGrid.cells.length;
});
}
add_task(async function() {
let testValues = [
{row: 0, column: 0},
{row: -1, column: -1},
{row: -1, column: 0},
{row: 0, column: -1},
{row: 2, column: 4},
{row: 2, column: 5},
];
// Expected length of grid
let expectedValues = [1, 1, 1, 1, 8, 10];
// Values before setting new pref values (15 is the default value -> 5 x 3)
let previousValues = [15, 1, 1, 1, 1, 8];
await addNewTabPageTab();
let existingTab = gBrowser.selectedTab;
for (let i = 0; i < expectedValues.length; i++) {
let existingTabGridLength = await getCellsCount();
is(existingTabGridLength, previousValues[i],
"Grid length of existing page before update is correctly.");
await pushPrefs([PREF_NEWTAB_ROWS, testValues[i].row]);
await pushPrefs([PREF_NEWTAB_COLUMNS, testValues[i].column]);
existingTabGridLength = await getCellsCount();
is(existingTabGridLength, expectedValues[i],
"Existing page grid is updated correctly.");
await addNewTabPageTab();
let newTab = gBrowser.selectedTab;
let newTabGridLength = await getCellsCount();
is(newTabGridLength, expectedValues[i],
"New page grid is updated correctly.");
await BrowserTestUtils.removeTab(newTab);
}
gBrowser.removeTab(existingTab);
});

Просмотреть файл

@ -1,32 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8");
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
const BAD_DRAG_DATA = "javascript:alert('h4ck0rz');\nbad stuff";
const GOOD_DRAG_DATA = "http://example99.com/\nsite 99";
function sendDropEvent(aCellIndex, aDragData) {
let dataTransfer = new content.DataTransfer("dragstart", false);
dataTransfer.mozSetDataAt("text/x-moz-url", aDragData, 0);
let event = content.document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
let target = content.gGrid.cells[aCellIndex].node;
target.dispatchEvent(event);
}
sendDropEvent(0, BAD_DRAG_DATA);
sendDropEvent(1, GOOD_DRAG_DATA);
});
await whenPagesUpdated();
await checkGrid("0,99p,1,2,3,4,5,6,7");
});

Просмотреть файл

@ -1,24 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* This test makes sure that the changes made by unpinning
* a site are actually written to NewTabUtils' storage.
*/
add_task(async function() {
// Second cell is pinned with page #99.
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",99");
await addNewTabPageTab();
await checkGrid("0,99p,1,2,3,4,5,6,7");
// Unpin the second cell's site.
await unpinCell(1);
await checkGrid("0,1,2,3,4,5,6,7,8");
// Clear the pinned cache to force NewTabUtils to read the pref again.
NewTabUtils.pinnedLinks.resetCache();
NewTabUtils.allPages.update();
await checkGrid("0,1,2,3,4,5,6,7,8");
});

Просмотреть файл

@ -1,35 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
// set max rows to 1, to avoid scroll events by clicking middle button
await pushPrefs(["browser.newtabpage.rows", 1]);
await setLinks("-1");
await addNewTabPageTab();
// we need a second newtab to honor max rows
await addNewTabPageTab();
await ContentTask.spawn(gBrowser.selectedBrowser, {index: 0}, async function(args) {
let {site} = content.wrappedJSObject.gGrid.cells[args.index];
let origOnClick = site.onClick;
site.onClick = e => {
origOnClick.call(site, e);
sendAsyncMessage("test:clicked-on-cell", {});
};
});
let mm = gBrowser.selectedBrowser.messageManager;
let messagePromise = new Promise(resolve => {
mm.addMessageListener("test:clicked-on-cell", function onResponse(message) {
mm.removeMessageListener("test:clicked-on-cell", onResponse);
resolve();
});
});
// Send a middle-click and make sure it happened
await BrowserTestUtils.synthesizeMouseAtCenter(".newtab-cell",
{button: 1}, gBrowser.selectedBrowser);
await messagePromise;
ok(true, "middle click triggered click listener");
});

Просмотреть файл

@ -1,34 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
// turn off preload to ensure that a newtab page loads
await pushPrefs(["browser.newtab.preload", false]);
// add a test provider that waits for load
let afterLoadProvider = {
getLinks(callback) {
this.callback = callback;
},
addObserver() {},
};
NewTabUtils.links.addProvider(afterLoadProvider);
// wait until about:newtab loads before calling provider callback
await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab");
afterLoadProvider.callback([]);
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
let {_cellHeight, _cellWidth, node} = content.gGrid;
Assert.notEqual(_cellHeight, null, "grid has a computed cell height");
Assert.notEqual(_cellWidth, null, "grid has a computed cell width");
let {height, maxHeight, maxWidth} = node.style;
Assert.notEqual(height, "", "grid has a computed grid height");
Assert.notEqual(maxHeight, "", "grid has a computed grid max-height");
Assert.notEqual(maxWidth, "", "grid has a computed grid max-width");
});
// restore original state
NewTabUtils.links.removeProvider(afterLoadProvider);
});

Просмотреть файл

@ -1,39 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
// set max rows to 1, to avoid scroll events by clicking middle button
await pushPrefs(["browser.newtabpage.rows", 1]);
await setLinks("0");
await addNewTabPageTab();
// we need a second newtab to honor max rows
await addNewTabPageTab();
await ContentTask.spawn(gBrowser.selectedBrowser, {index: 0}, async function(args) {
let {site} = content.wrappedJSObject.gGrid.cells[args.index];
let origOnClick = site.onClick;
site.onClick = e => {
origOnClick.call(site, e);
sendAsyncMessage("test:clicked-on-cell", {});
};
});
let mm = gBrowser.selectedBrowser.messageManager;
let messagePromise = new Promise(resolve => {
mm.addMessageListener("test:clicked-on-cell", function onResponse(message) {
mm.removeMessageListener("test:clicked-on-cell", onResponse);
resolve();
});
});
// Send a middle-click and make sure it happened
await BrowserTestUtils.synthesizeMouseAtCenter(".newtab-control-block",
{button: 1}, gBrowser.selectedBrowser);
await messagePromise;
ok(true, "middle click triggered click listener");
// Make sure the cell didn't actually get blocked
await checkGrid("0");
});

Просмотреть файл

@ -1,48 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* These tests make sure that the 'New Tab Page' feature can be disabled if the
* decides not to use it.
*/
add_task(async function() {
// create a new tab page and hide it.
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
let firstTab = await addNewTabPageTab();
function isGridDisabled(browser = gBrowser.selectedBrowser) {
return ContentTask.spawn(browser, {}, async function() {
return content.gGrid.node.hasAttribute("page-disabled");
});
}
let isDisabled = await isGridDisabled();
ok(!isDisabled, "page is not disabled");
NewTabUtils.allPages.enabled = false;
isDisabled = await isGridDisabled();
ok(isDisabled, "page is disabled");
// create a second new tab page and make sure it's disabled. enable it
// again and check if the former page gets enabled as well.
await addNewTabPageTab();
isDisabled = await isGridDisabled(firstTab.linkedBrowser);
ok(isDisabled, "page is disabled");
// check that no sites have been rendered
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
Assert.equal(content.document.querySelectorAll(".site").length, 0,
"no sites have been rendered");
});
NewTabUtils.allPages.enabled = true;
isDisabled = await isGridDisabled();
ok(!isDisabled, "page is not disabled");
isDisabled = await isGridDisabled(firstTab.linkedBrowser);
ok(!isDisabled, "old page is not disabled");
});

Просмотреть файл

@ -1,95 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* These tests make sure that dragging and dropping sites works as expected.
* Sites contained in the grid need to shift around to indicate the result
* of the drag-and-drop operation. If the grid is full and we're dragging
* a new site into it another one gets pushed out.
*/
add_task(async function() {
requestLongerTimeout(2);
await addNewTabPageTab();
// test a simple drag-and-drop scenario
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8");
await doDragEvent(0, 1);
await checkGrid("1,0p,2,3,4,5,6,7,8");
// drag a cell to its current cell and make sure it's not pinned afterwards
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8");
await doDragEvent(0, 0);
await checkGrid("0,1,2,3,4,5,6,7,8");
// ensure that pinned pages aren't moved if that's not necessary
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",1,2");
await addNewTabPageTab();
await checkGrid("0,1p,2p,3,4,5,6,7,8");
await doDragEvent(0, 3);
await checkGrid("3,1p,2p,0p,4,5,6,7,8");
// pinned sites should always be moved around as blocks. if a pinned site is
// moved around, neighboring pinned are affected as well
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("0,1");
await addNewTabPageTab();
await checkGrid("0p,1p,2,3,4,5,6,7,8");
await doDragEvent(2, 0);
await checkGrid("2p,0p,1p,3,4,5,6,7,8");
// pinned sites should not be pushed out of the grid (unless there are only
// pinned ones left on the grid)
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",,,,,,,7,8");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7p,8p");
await doDragEvent(2, 5);
await checkGrid("0,1,3,4,5,2p,6,7p,8p");
// make sure that pinned sites are re-positioned correctly
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("0,1,2,,,5");
await addNewTabPageTab();
await checkGrid("0p,1p,2p,3,4,5p,6,7,8");
await doDragEvent(0, 4);
await checkGrid("3,1p,2p,4,0p,5p,6,7,8");
});
function doDragEvent(sourceIndex, dropIndex) {
return ContentTask.spawn(gBrowser.selectedBrowser,
{ sourceIndex, dropIndex }, async function(args) {
let dataTransfer = new content.DataTransfer("dragstart", false);
let event = content.document.createEvent("DragEvent");
event.initDragEvent("dragstart", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
let target = content.gGrid.cells[args.sourceIndex].site.node;
target.dispatchEvent(event);
event = content.document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
target = content.gGrid.cells[args.dropIndex].node;
target.dispatchEvent(event);
});
}

Просмотреть файл

@ -1,75 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns";
const PREF_NEWTAB_ROWS = "browser.newtabpage.rows";
/*
* These tests make sure that dragging and dropping sites works as expected.
* Sites contained in the grid need to shift around to indicate the result
* of the drag-and-drop operation. If the grid is full and we're dragging
* a new site into it another one gets pushed out.
* This is a continuation of browser_newtab_drag_drop.js
* to decrease test run time, focusing on external sites.
*/
add_task(async function() {
await addNewTabPageTab();
// drag a new site onto the very first cell
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",,,,,,,7,8");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7p,8p");
await simulateExternalDrop(0);
await checkGrid("99p,0,1,2,3,4,5,7p,8p");
// drag a new site onto the grid and make sure that pinned cells don't get
// pushed out
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",,,,,,,7,8");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7p,8p");
// force the grid to be small enough that a pinned cell could be pushed out
await pushPrefs([PREF_NEWTAB_COLUMNS, 3]);
await pushPrefs([PREF_NEWTAB_ROWS, 3]);
await simulateExternalDrop(5);
await checkGrid("0,1,2,3,4,99p,5,7p,8p");
// drag a new site beneath a pinned cell and make sure the pinned cell is
// not moved
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",,,,,,,,8");
await addNewTabPageTab();
await checkGrid("0,1,2,3,4,5,6,7,8p");
await simulateExternalDrop(5);
await checkGrid("0,1,2,3,4,99p,5,6,8p");
// drag a new site onto a block of pinned sites and make sure they're shifted
// around accordingly
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("0,1,2,,,,,,");
await addNewTabPageTab();
await checkGrid("0p,1p,2p");
await simulateExternalDrop(1);
await checkGrid("0p,99p,1p,2p,3,4,5,6,7");
// force the grid to be small enough that a pinned cell could be pushed out
// and the full list is truncated
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",,,,,,,7,8");
await addNewTabPageTab();
await pushPrefs([PREF_NEWTAB_ROWS, 2]);
await simulateExternalDrop(5);
await checkGrid("0,1,2,3,4,99p");
});

Просмотреть файл

@ -1,41 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* These tests ensure that the drop preview correctly arranges sites when
* dragging them around.
*/
add_task(async function() {
await addNewTabPageTab();
// the first three sites are pinned - make sure they're re-arranged correctly
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("0,1,2,,,5");
await addNewTabPageTab();
await checkGrid("0p,1p,2p,3,4,5p,6,7,8");
let foundSites = await ContentTask.spawn(gWindow.gBrowser.selectedBrowser, {}, async function() {
let cells = content.gGrid.cells;
content.gDrag._draggedSite = cells[0].site;
let sites = content.gDropPreview.rearrange(cells[4]);
content.gDrag._draggedSite = null;
sites = sites.slice(0, 9);
return sites.map(function(aSite) {
if (!aSite)
return "";
let pinned = aSite.isPinned();
if (pinned != aSite.node.hasAttribute("pinned")) {
Assert.ok(false, "invalid state (site.isPinned() != site[pinned])");
}
return aSite.url.replace(/^http:\/\/example(\d+)\.com\/$/, "$1") + (pinned ? "p" : "");
});
});
let expectedSites = "3,1p,2p,4,0p,5p,6,7,8";
is(foundSites, expectedSites, "grid status = " + expectedSites);
});

Просмотреть файл

@ -1,92 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* These tests make sure that focusing the 'New Tab Page' works as expected.
*/
add_task(async function() {
await pushPrefs(["accessibility.tabfocus", 7]);
// When the onboarding component is enabled, it would inject extra tour notification into
// the newtab page so there would be 3 more overlay button, notification close button and action button
let onbardingEnabled = Services.prefs.getBoolPref("browser.onboarding.enabled");
// Focus count in new tab page.
// 30 = 9 * 3 + 3 = 9 sites, each with link, pin and remove buttons; search
// bar; search button; and toggle button. Additionaly there may or may not be
// a scroll bar caused by fix to 1180387, which will eat an extra focus
let FOCUS_COUNT = 30;
// Create a new tab page.
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
if (onbardingEnabled) {
await promiseNoMuteNotificationOnFirstSession();
}
let tab = await addNewTabPageTab();
if (onbardingEnabled) {
FOCUS_COUNT += 3;
await promiseTourNotificationOpened(tab.linkedBrowser);
}
gURLBar.focus();
// Count the focus with the enabled page.
countFocus(FOCUS_COUNT);
// Disable page and count the focus with the disabled page.
NewTabUtils.allPages.enabled = false;
let expectedCount = 4;
if (onbardingEnabled) {
expectedCount += 3;
}
countFocus(expectedCount);
NewTabUtils.allPages.enabled = true;
});
/**
* Focus the urlbar and count how many focus stops to return again to the urlbar.
*/
function countFocus(aExpectedCount) {
let focusCount = 0;
do {
EventUtils.synthesizeKey("KEY_Tab");
if (document.activeElement == gBrowser.selectedBrowser) {
focusCount++;
}
} while (document.activeElement != gURLBar.inputField);
ok(focusCount == aExpectedCount || focusCount == (aExpectedCount + 1),
"Validate focus count in the new tab page.");
}
function promiseNoMuteNotificationOnFirstSession() {
return SpecialPowers.pushPrefEnv({set: [["browser.onboarding.notification.mute-duration-on-first-session-ms", 0]]});
}
/**
* Wait for the onboarding tour notification opens
*/
function promiseTourNotificationOpened(browser) {
return ContentTask.spawn(browser, {}, function() {
let doc = content && content.document;
let notification = doc.querySelector("#onboarding-notification-bar");
if (notification && notification.classList.contains("onboarding-opened")) {
ok(true, "Should open tour notification");
return Promise.resolve();
}
return new Promise(resolve => {
let observer = new content.MutationObserver(mutations => {
mutations.forEach(mutation => {
let bar = Array.from(mutation.addedNodes)
.find(node => node.id == "onboarding-notification-bar");
if (bar && bar.classList.contains("onboarding-opened")) {
observer.disconnect();
ok(true, "Should open tour notification");
resolve();
}
});
});
observer.observe(doc.body, { childList: true });
});
});
}

Просмотреть файл

@ -1,35 +0,0 @@
"use strict";
function isFullscreenSizeMode() {
let sizemode = document.documentElement.getAttribute("sizemode");
return sizemode == "fullscreen";
}
/**
* Checks that the URL bar is correctly focused
* when a new tab is opened while in fullscreen
* mode.
*/
add_task(async function() {
gURLBar.blur();
Assert.ok(!window.fullScreen, "Should not start in fullscreen mode.");
BrowserFullScreen();
await BrowserTestUtils.waitForCondition(() => isFullscreenSizeMode());
registerCleanupFunction(async function() {
// Exit fullscreen if we're still in it.
if (window.fullScreen) {
BrowserFullScreen();
await BrowserTestUtils.waitForCondition(() => !isFullscreenSizeMode());
}
});
Assert.ok(window.fullScreen, "Should be in fullscreen mode now.");
let newTabOpened = BrowserTestUtils.waitForEvent(gBrowser, "TabSwitchDone");
BrowserOpenTab();
await newTabOpened;
Assert.ok(gURLBar.focused, "URL bar should be focused.");
});

Просмотреть файл

@ -1,56 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* These tests ensure that all changes made to the new tab page in private
* browsing mode are discarded after switching back to normal mode again.
* The private browsing mode should start with the current grid shown in normal
* mode.
*/
add_task(async function() {
// prepare the grid
await testOnWindow(undefined);
await setLinks("0,1,2,3,4,5,6,7,8,9");
await addNewTabPageTab();
await pinCell(0);
await checkGrid("0p,1,2,3,4,5,6,7,8");
// open private window
await testOnWindow({private: true});
await addNewTabPageTab();
await checkGrid("0p,1,2,3,4,5,6,7,8");
// modify the grid while we're in pb mode
await blockCell(1);
await checkGrid("0p,2,3,4,5,6,7,8");
await unpinCell(0);
await checkGrid("0,2,3,4,5,6,7,8");
// open normal window
await testOnWindow(undefined);
// check that the grid is the same as before entering pb mode
await addNewTabPageTab();
await checkGrid("0,2,3,4,5,6,7,8");
});
var windowsToClose = [];
async function testOnWindow(options) {
let newWindowPromise = BrowserTestUtils.waitForNewWindow();
var win = OpenBrowserWindow(options);
windowsToClose.push(win);
gWindow = win;
await newWindowPromise;
}
registerCleanupFunction(function() {
gWindow = window;
windowsToClose.forEach(function(win) {
win.close();
});
});

Просмотреть файл

@ -1,38 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable mozilla/no-arbitrary-setTimeout */
"use strict";
const FRAME_SCRIPT = getRootDirectory(gTestPath) + "content-reflows.js";
const ADDITIONAL_WAIT_MS = 2000;
/*
* Ensure that loading about:newtab doesn't cause uninterruptible reflows.
*/
add_task(async function() {
await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
return gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank", {animate: false});
}, false);
let browser = gBrowser.selectedBrowser;
let mm = browser.messageManager;
mm.loadFrameScript(FRAME_SCRIPT, true);
mm.addMessageListener("newtab-reflow", ({data: stack}) => {
ok(false, `unexpected uninterruptible reflow ${stack}`);
});
let browserLoadedPromise = BrowserTestUtils.waitForEvent(browser, "load", true);
browser.loadURI("about:newtab");
await browserLoadedPromise;
// Wait some more to catch sync reflows after the page has loaded.
await new Promise(resolve => {
setTimeout(resolve, ADDITIONAL_WAIT_MS);
});
// Clean up.
gBrowser.removeCurrentTab({animate: false});
ok(true, "Each test requires at least one pass, fail or todo so here is a pass.");
});

Просмотреть файл

@ -1,240 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// See browser/components/search/test/browser_*_behavior.js for tests of actual
// searches.
const ENGINE_NO_LOGO = {
name: "searchEngineNoLogo.xml",
numLogos: 0,
};
const ENGINE_FAVICON = {
name: "searchEngineFavicon.xml",
logoPrefix1x: "data:image/png;base64,AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAATCwAAEwsA",
numLogos: 1,
};
ENGINE_FAVICON.logoPrefix2x = ENGINE_FAVICON.logoPrefix1x;
const ENGINE_1X_LOGO = {
name: "searchEngine1xLogo.xml",
logoPrefix1x: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAIAAABn3KYmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADEw",
numLogos: 1,
};
ENGINE_1X_LOGO.logoPrefix2x = ENGINE_1X_LOGO.logoPrefix1x;
const ENGINE_2X_LOGO = {
name: "searchEngine2xLogo.xml",
logoPrefix2x: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAIAAADJ8nfCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADMU",
numLogos: 1,
};
ENGINE_2X_LOGO.logoPrefix1x = ENGINE_2X_LOGO.logoPrefix2x;
const ENGINE_1X_2X_LOGO = {
name: "searchEngine1x2xLogo.xml",
logoPrefix1x: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAIAAABn3KYmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADIG",
logoPrefix2x: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAIAAADJ8nfCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADMo",
numLogos: 2,
};
const ENGINE_SUGGESTIONS = {
name: "searchSuggestionEngine.xml",
numLogos: 0,
};
// The test has an expected search event queue and a search event listener.
// Search events that are expected to happen are added to the queue, and the
// listener consumes the queue and ensures that each event it receives is at
// the head of the queue.
let gExpectedSearchEventQueue = [];
let gExpectedSearchEventResolver = null;
let gNewEngines = [];
add_task(async function() {
let oldCurrentEngine = Services.search.currentEngine;
await addNewTabPageTab();
// The tab is removed at the end of the test, so there's no need to remove
// this listener at the end of the test.
info("Adding search event listener");
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
const SERVICE_EVENT_NAME = "ContentSearchService";
content.addEventListener(SERVICE_EVENT_NAME, function(event) {
sendAsyncMessage("test:search-event", { eventType: event.detail.type });
});
});
let mm = gBrowser.selectedBrowser.messageManager;
mm.addMessageListener("test:search-event", function(message) {
let eventType = message.data.eventType;
if (!gExpectedSearchEventResolver) {
ok(false, "Got search event " + eventType + " with no promise assigned");
}
let expectedEventType = gExpectedSearchEventQueue.shift();
is(eventType, expectedEventType, "Got expected search event " + expectedEventType);
if (!gExpectedSearchEventQueue.length) {
gExpectedSearchEventResolver();
gExpectedSearchEventResolver = null;
}
});
// Add the engine without any logos and switch to it.
let noLogoEngine = await promiseNewSearchEngine(ENGINE_NO_LOGO);
let searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
Services.search.currentEngine = noLogoEngine;
await searchEventsPromise;
await checkCurrentEngine(ENGINE_NO_LOGO);
// Add the engine with favicon and switch to it.
let faviconEngine = await promiseNewSearchEngine(ENGINE_FAVICON);
searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
Services.search.currentEngine = faviconEngine;
await searchEventsPromise;
await checkCurrentEngine(ENGINE_FAVICON);
// Add the engine with a 1x-DPI logo and switch to it.
let logo1xEngine = await promiseNewSearchEngine(ENGINE_1X_LOGO);
searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
Services.search.currentEngine = logo1xEngine;
await searchEventsPromise;
await checkCurrentEngine(ENGINE_1X_LOGO);
// Add the engine with a 2x-DPI logo and switch to it.
let logo2xEngine = await promiseNewSearchEngine(ENGINE_2X_LOGO);
searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
Services.search.currentEngine = logo2xEngine;
await searchEventsPromise;
await checkCurrentEngine(ENGINE_2X_LOGO);
// Add the engine with 1x- and 2x-DPI logos and switch to it.
let logo1x2xEngine = await promiseNewSearchEngine(ENGINE_1X_2X_LOGO);
searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
Services.search.currentEngine = logo1x2xEngine;
await searchEventsPromise;
await checkCurrentEngine(ENGINE_1X_2X_LOGO);
// Add the engine that provides search suggestions and switch to it.
let suggestionEngine = await promiseNewSearchEngine(ENGINE_SUGGESTIONS);
searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
Services.search.currentEngine = suggestionEngine;
await searchEventsPromise;
await checkCurrentEngine(ENGINE_SUGGESTIONS);
// Type an X in the search input. This is only a smoke test. See
// browser_searchSuggestionUI.js for comprehensive content search suggestion
// UI tests.
let suggestionsOpenPromise = new Promise(resolve => {
mm.addMessageListener("test:newtab-suggestions-open", function onResponse(message) {
mm.removeMessageListener("test:newtab-suggestions-open", onResponse);
resolve();
});
});
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
let table = content.document.getElementById("searchSuggestionTable");
let input = content.document.getElementById("newtab-search-text");
input.focus();
info("Waiting for suggestions table to open");
let observer = new content.MutationObserver(() => {
if (input.getAttribute("aria-expanded") == "true") {
observer.disconnect();
Assert.ok(!table.hidden, "Search suggestion table unhidden");
sendAsyncMessage("test:newtab-suggestions-open", {});
}
});
observer.observe(input, {
attributes: true,
attributeFilter: ["aria-expanded"],
});
});
let suggestionsPromise = promiseSearchEvents(["Suggestions"]);
EventUtils.sendString("x");
// Wait for the search suggestions to become visible and for the Suggestions
// message.
await suggestionsOpenPromise;
await suggestionsPromise;
// Empty the search input, causing the suggestions to be hidden.
EventUtils.synthesizeKey("a", {accelKey: true});
EventUtils.synthesizeKey("KEY_Delete");
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
Assert.ok(content.document.getElementById("searchSuggestionTable").hidden,
"Search suggestion table hidden");
});
// Done. Revert the current engine and remove the new engines.
searchEventsPromise = promiseSearchEvents(["CurrentEngine"]);
Services.search.currentEngine = oldCurrentEngine;
await searchEventsPromise;
let events = Array(gNewEngines.length).fill("CurrentState", 0, gNewEngines.length);
searchEventsPromise = promiseSearchEvents(events);
for (let engine of gNewEngines) {
Services.search.removeEngine(engine);
}
await searchEventsPromise;
});
function promiseSearchEvents(events) {
info("Expecting search events: " + events);
return new Promise(resolve => {
gExpectedSearchEventQueue.push(...events);
gExpectedSearchEventResolver = resolve;
});
}
function promiseNewSearchEngine({name: basename, numLogos}) {
info("Waiting for engine to be added: " + basename);
// Wait for the search events triggered by adding the new engine.
// engine-added engine-loaded
let expectedSearchEvents = ["CurrentState", "CurrentState"];
// engine-changed for each of the logos
for (let i = 0; i < numLogos; i++) {
expectedSearchEvents.push("CurrentState");
}
let eventPromise = promiseSearchEvents(expectedSearchEvents);
// Wait for addEngine().
let addEnginePromise = new Promise((resolve, reject) => {
let url = getRootDirectory(gTestPath) + basename;
Services.search.addEngine(url, null, "", false, {
onSuccess(engine) {
info("Search engine added: " + basename);
gNewEngines.push(engine);
resolve(engine);
},
onError(errCode) {
ok(false, "addEngine failed with error code " + errCode);
reject();
},
});
});
return Promise.all([addEnginePromise, eventPromise]).then(([newEngine, _]) => {
return newEngine;
});
}
async function checkCurrentEngine(engineInfo) {
let engine = Services.search.currentEngine;
ok(engine.name.includes(engineInfo.name),
"Sanity check: current engine: engine.name=" + engine.name +
" basename=" + engineInfo.name);
await ContentTask.spawn(gBrowser.selectedBrowser, { name: engine.name }, async function(args) {
Assert.equal(content.gSearch._contentSearchController.defaultEngine.name,
args.name, "currentEngineName: " + args.name);
});
}

Просмотреть файл

@ -1,47 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* These tests make sure that the undo dialog works as expected.
*/
add_task(async function() {
// remove unpinned sites and undo it
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("5");
await addNewTabPageTab();
await checkGrid("5p,0,1,2,3,4,6,7,8");
await blockCell(4);
await blockCell(4);
await checkGrid("5p,0,1,2,6,7,8");
await undo();
await checkGrid("5p,0,1,2,4,6,7,8");
// now remove a pinned site and undo it
await blockCell(0);
await checkGrid("0,1,2,4,6,7,8");
await undo();
await checkGrid("5p,0,1,2,4,6,7,8");
// remove a site and restore all
await blockCell(1);
await checkGrid("5p,1,2,4,6,7,8");
await undoAll();
await checkGrid("5p,0,1,2,3,4,6,7,8");
});
async function undo() {
let updatedPromise = whenPagesUpdated();
await BrowserTestUtils.synthesizeMouseAtCenter("#newtab-undo-button", {}, gBrowser.selectedBrowser);
await updatedPromise;
}
async function undoAll() {
let updatedPromise = whenPagesUpdated();
await BrowserTestUtils.synthesizeMouseAtCenter("#newtab-undo-restore-button", {}, gBrowser.selectedBrowser);
await updatedPromise;
}

Просмотреть файл

@ -1,56 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* These tests make sure that when a site gets unpinned it is either moved to
* its actual place in the grid or removed in case it's not on the grid anymore.
*/
add_task(async function() {
// we have a pinned link that didn't change its position since it was pinned.
// nothing should happen when we unpin it.
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",1");
await addNewTabPageTab();
await checkGrid("0,1p,2,3,4,5,6,7,8");
await unpinCell(1);
await checkGrid("0,1,2,3,4,5,6,7,8");
// we have a pinned link that is not anymore in the list of the most-visited
// links. this should disappear, the remaining links adjust their positions
// and a new link will appear at the end of the grid.
await setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks(",99");
await addNewTabPageTab();
await checkGrid("0,99p,1,2,3,4,5,6,7");
await unpinCell(1);
await checkGrid("0,1,2,3,4,5,6,7,8");
// we have a pinned link that changed its position since it was pinned. it
// should be moved to its new position after being unpinned.
await setLinks("0,1,2,3,4,5,6,7");
setPinnedLinks(",1,,,,,,,0");
await addNewTabPageTab();
await checkGrid("2,1p,3,4,5,6,7,,0p");
await unpinCell(1);
await checkGrid("1,2,3,4,5,6,7,,0p");
await unpinCell(8);
await checkGrid("0,1,2,3,4,5,6,7,");
// we have pinned link that changed its position since it was pinned. the
// link will disappear from the grid because it's now a much lower priority
await setLinks("0,1,2,3,4,5,6,7,8,9");
setPinnedLinks("9");
await addNewTabPageTab();
await checkGrid("9p,0,1,2,3,4,5,6,7");
await unpinCell(0);
await checkGrid("0,1,2,3,4,5,6,7,8");
});

Просмотреть файл

@ -1,48 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Checks that newtab is updated as its links change.
*/
add_task(async function() {
// First, start with an empty page. setLinks will trigger a hidden page
// update because it calls clearHistory. We need to wait for that update to
// happen so that the next time we wait for a page update below, we catch the
// right update and not the one triggered by setLinks.
let updatedPromise = whenPagesUpdated();
let setLinksPromise = setLinks([]);
await Promise.all([updatedPromise, setLinksPromise]);
// Strategy: Add some visits, open a new page, check the grid, repeat.
await fillHistoryAndWaitForPageUpdate([1]);
await addNewTabPageTab();
await checkGrid("1,,,,,,,,");
await fillHistoryAndWaitForPageUpdate([2]);
await addNewTabPageTab();
await checkGrid("2,1,,,,,,,");
await fillHistoryAndWaitForPageUpdate([1]);
await addNewTabPageTab();
await checkGrid("1,2,,,,,,,");
await fillHistoryAndWaitForPageUpdate([2, 3, 4]);
await addNewTabPageTab();
await checkGrid("2,1,3,4,,,,,");
// Make sure these added links have the right type
let type = await performOnCell(1, cell => { return cell.site.link.type; });
is(type, "history", "added link is history");
});
function fillHistoryAndWaitForPageUpdate(links) {
let updatedPromise = whenPagesUpdated;
let fillHistoryPromise = fillHistory(links.map(link));
return Promise.all([updatedPromise, fillHistoryPromise]);
}
function link(id) {
return { url: "http://example" + id + ".com/", title: "site#" + id };
}

Просмотреть файл

@ -1,26 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env mozilla/frame-script */
(function() {
"use strict";
docShell.addWeakReflowObserver({
reflow() {
// Gather information about the current code path.
let path = (new Error().stack).split("\n").slice(1).join("\n");
if (path) {
sendSyncMessage("newtab-reflow", path);
}
},
reflowInterruptible() {
// We're not interested in interruptible reflows.
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
Ci.nsISupportsWeakReference])
});
})();

Просмотреть файл

@ -1,526 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const PREF_NEWTAB_ENABLED = "browser.newtabpage.enabled";
Services.prefs.setBoolPref(PREF_NEWTAB_ENABLED, true);
// Opens and closes a new tab to clear any existing preloaded ones. This is
// necessary to prevent any left-over activity-stream preloaded new tabs from
// affecting these tests.
BrowserOpenTab();
const initialTab = gBrowser.selectedTab;
gBrowser.removeTab(initialTab);
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
PlacesTestUtils: "resource://testing-common/PlacesTestUtils.jsm",
Sanitizer: "resource:///modules/Sanitizer.jsm",
});
var gWindow = window;
// Default to dummy/empty directory links
var gDirectorySource = 'data:application/json,{"test":1}';
var gOrigDirectorySource;
// The tests assume all 3 rows and all 3 columns of sites are shown, but the
// window may be too small to actually show everything. Resize it if necessary.
var requiredSize = {};
requiredSize.innerHeight =
40 + 32 + // undo container + bottom margin
44 + 32 + // search bar + bottom margin
(3 * (180 + 32)) + // 3 rows * (tile height + title and bottom margin)
100; // breathing room
requiredSize.innerWidth =
(3 * (290 + 20)) + // 3 cols * (tile width + side margins)
100; // breathing room
add_task(async function setupWindowSize() {
let [oldSize, curWidth, curHeight] = await ContentTask.spawn(gBrowser.selectedBrowser, requiredSize, (requiredSizeArg) => {
var oldSizeVar = {};
Object.keys(requiredSizeArg).forEach(prop => {
info([prop, content[prop], requiredSizeArg[prop]]);
if (content[prop] < requiredSizeArg[prop]) {
oldSizeVar[prop] = content[prop];
info("Changing browser " + prop + " from " + oldSizeVar[prop] + " to " +
requiredSizeArg[prop]);
content[prop] = requiredSizeArg[prop];
}
});
return [oldSizeVar, content.outerWidth, content.outerHeight];
});
var screenHeight = {};
var screenWidth = {};
Cc["@mozilla.org/gfx/screenmanager;1"].
getService(Ci.nsIScreenManager).
primaryScreen.
GetAvailRectDisplayPix({}, {}, screenWidth, screenHeight);
screenHeight = screenHeight.value;
screenWidth = screenWidth.value;
if (screenHeight < curHeight) {
info("Warning: Browser outer height is now " +
curHeight + ", which is larger than the " +
"available screen height, " + screenHeight +
". That may cause problems.");
}
if (screenWidth < curWidth) {
info("Warning: Browser outer width is now " +
curWidth + ", which is larger than the " +
"available screen width, " + screenWidth +
". That may cause problems.");
}
registerCleanupFunction(function() {
while (gWindow.gBrowser.tabs.length > 1)
gWindow.gBrowser.removeTab(gWindow.gBrowser.tabs[1]);
ContentTask.spawn(gBrowser.selectedBrowser, oldSize, (oldSizeArg) => {
Object.keys(oldSizeArg).forEach(prop => {
if (oldSizeArg[prop]) {
content[prop] = oldSizeArg[prop];
}
});
});
});
});
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
});
function pushPrefs(...aPrefs) {
return SpecialPowers.pushPrefEnv({"set": aPrefs});
}
add_task(async function setup() {
registerCleanupFunction(function() {
return new Promise(resolve => {
function cleanupAndFinish() {
PlacesUtils.history.clear().then(() => {
whenPagesUpdated().then(resolve);
NewTabUtils.restore();
});
}
let callbacks = NewTabUtils.links._populateCallbacks;
let numCallbacks = callbacks.length;
if (numCallbacks)
callbacks.splice(0, numCallbacks, cleanupAndFinish);
else
cleanupAndFinish();
});
});
await whenPagesUpdated();
});
/** Perform an action on a cell within the newtab page.
* @param aIndex index of cell
* @param aFn function to call in child process or tab.
* @returns result of calling the function.
*/
function performOnCell(aIndex, aFn) {
return ContentTask.spawn(gWindow.gBrowser.selectedBrowser,
{ index: aIndex, fn: aFn.toString() }, async function(args) {
let cell = content.gGrid.cells[args.index];
// eslint-disable-next-line no-eval
return eval(args.fn)(cell);
});
}
/**
* Allows to provide a list of links that is used to construct the grid.
* @param aLinksPattern the pattern (see below)
*
* Example: setLinks("-1,0,1,2,3")
* Result: [{url: "http://example.com/", title: "site#-1"},
* {url: "http://example0.com/", title: "site#0"},
* {url: "http://example1.com/", title: "site#1"},
* {url: "http://example2.com/", title: "site#2"},
* {url: "http://example3.com/", title: "site#3"}]
*/
function setLinks(aLinks) {
return new Promise(resolve => {
let links = aLinks;
if (typeof links == "string") {
links = aLinks.split(/\s*,\s*/).map(function(id) {
return {url: "http://example" + (id != "-1" ? id : "") + ".com/",
title: "site#" + id};
});
}
// Call populateCache() once to make sure that all link fetching that is
// currently in progress has ended. We clear the history, fill it with the
// given entries and call populateCache() now again to make sure the cache
// has the desired contents.
NewTabUtils.links.populateCache(function() {
PlacesUtils.history.clear().then(() => {
fillHistory(links).then(() => {
NewTabUtils.links.populateCache(function() {
NewTabUtils.allPages.update();
resolve();
}, true);
});
});
});
});
}
function fillHistory(aLinks) {
return new Promise(resolve => {
let numLinks = aLinks.length;
if (!numLinks) {
executeSoon(resolve);
return;
}
let transitionLink = Ci.nsINavHistoryService.TRANSITION_LINK;
// Important: To avoid test failures due to clock jitter on Windows XP, call
// Date.now() once here, not each time through the loop.
let now = Date.now() * 1000;
for (let i = 0; i < aLinks.length; i++) {
let link = aLinks[i];
let place = {
uri: makeURI(link.url),
title: link.title,
// Links are secondarily sorted by visit date descending, so decrease the
// visit date as we progress through the array so that links appear in the
// grid in the order they're present in the array.
visits: [{visitDate: now - i, transitionType: transitionLink}]
};
PlacesUtils.asyncHistory.updatePlaces(place, {
handleError: () => ok(false, "couldn't add visit to history"),
handleResult() {},
handleCompletion() {
if (--numLinks == 0) {
resolve();
}
}
});
}
});
}
/**
* Allows to specify the list of pinned links (that have a fixed position in
* the grid.
* @param aLinksPattern the pattern (see below)
*
* Example: setPinnedLinks("3,,1")
* Result: 'http://example3.com/' is pinned in the first cell. 'http://example1.com/' is
* pinned in the third cell.
*/
function setPinnedLinks(aLinks) {
let links = aLinks;
if (typeof links == "string") {
links = aLinks.split(/\s*,\s*/).map(function(id) {
if (id)
return {url: "http://example" + (id != "-1" ? id : "") + ".com/",
title: "site#" + id,
type: "history"};
return undefined;
});
}
Services.prefs.setStringPref("browser.newtabpage.pinned", JSON.stringify(links));
NewTabUtils.pinnedLinks.resetCache();
NewTabUtils.allPages.update();
}
/**
* Restore the grid state.
*/
function restore() {
return new Promise(resolve => {
whenPagesUpdated().then(resolve);
NewTabUtils.restore();
});
}
/**
* Wait until a given condition becomes true.
*/
function waitForCondition(aConditionFn, aMaxTries = 50, aCheckInterval = 100) {
return new Promise((resolve, reject) => {
let tries = 0;
function tryNow() {
tries++;
if (aConditionFn()) {
resolve();
} else if (tries < aMaxTries) {
tryAgain();
} else {
reject("Condition timed out: " + aConditionFn.toSource());
}
}
function tryAgain() {
setTimeout(tryNow, aCheckInterval);
}
tryAgain();
});
}
/**
* Creates a new tab containing 'about:newtab'.
*/
async function addNewTabPageTab() {
let tab = await BrowserTestUtils.openNewForegroundTab(gWindow.gBrowser, "about:newtab", false);
let browser = tab.linkedBrowser;
// Wait for the document to become visible in case it was preloaded.
await waitForCondition(() => !browser.contentDocument.hidden);
await new Promise(resolve => {
if (NewTabUtils.allPages.enabled) {
// Continue when the link cache has been populated.
NewTabUtils.links.populateCache(function() {
whenSearchInitDone().then(resolve);
});
} else {
resolve();
}
});
return tab;
}
/**
* Compares the current grid arrangement with the given pattern.
* @param the pattern (see below)
*
* Example: checkGrid("3p,2,,4p")
* Result: We expect the first cell to contain the pinned site 'http://example3.com/'.
* The second cell contains 'http://example2.com/'. The third cell is empty.
* The fourth cell contains the pinned site 'http://example4.com/'.
*/
async function checkGrid(pattern) {
let length = pattern.split(",").length;
await ContentTask.spawn(gWindow.gBrowser.selectedBrowser,
{ length, pattern }, async function(args) {
let grid = content.wrappedJSObject.gGrid;
let sites = grid.sites.slice(0, args.length);
let foundPattern = sites.map(function(aSite) {
if (!aSite)
return "";
let pinned = aSite.isPinned();
let hasPinnedAttr = aSite.node.hasAttribute("pinned");
if (pinned != hasPinnedAttr)
ok(false, "invalid state (site.isPinned() != site[pinned])");
return aSite.url.replace(/^http:\/\/example(\d+)\.com\/$/, "$1") + (pinned ? "p" : "");
});
Assert.equal(foundPattern, args.pattern, "grid status = " + args.pattern);
});
}
/**
* Blocks a site from the grid.
* @param aIndex The cell index.
*/
function blockCell(aIndex) {
return new Promise(resolve => {
whenPagesUpdated().then(resolve);
performOnCell(aIndex, cell => {
return cell.site.block();
});
});
}
/**
* Pins a site on a given position.
* @param aIndex The cell index.
* @param aPinIndex The index the defines where the site should be pinned.
*/
function pinCell(aIndex) {
performOnCell(aIndex, cell => {
cell.site.pin();
});
}
/**
* Unpins the given cell's site.
* @param aIndex The cell index.
*/
function unpinCell(aIndex) {
return new Promise(resolve => {
whenPagesUpdated().then(resolve);
performOnCell(aIndex, cell => {
cell.site.unpin();
});
});
}
/**
* Simulates a drag and drop operation. Instead of rearranging a site that is
* is already contained in the newtab grid, this is used to simulate dragging
* an external link onto the grid e.g. the text from the URL bar.
* @param aDestIndex The cell index of the drop target.
*/
async function simulateExternalDrop(aDestIndex) {
let pagesUpdatedPromise = whenPagesUpdated();
await ContentTask.spawn(gWindow.gBrowser.selectedBrowser, aDestIndex, async function(dropIndex) {
return new Promise(resolve => {
const url = "data:text/html;charset=utf-8," +
"<a id='link' href='http://example99.com/'>link</a>";
let doc = content.document;
let iframe = doc.createElement("iframe");
function iframeLoaded() {
let dataTransfer = new iframe.contentWindow.DataTransfer("dragstart", false);
dataTransfer.mozSetDataAt("text/x-moz-url", "http://example99.com/", 0);
let event = content.document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
let target = content.gGrid.cells[dropIndex].node;
target.dispatchEvent(event);
iframe.remove();
resolve();
}
iframe.addEventListener("load", function() {
content.setTimeout(iframeLoaded, 0);
}, {once: true});
iframe.setAttribute("src", url);
iframe.style.width = "50px";
iframe.style.height = "50px";
iframe.style.position = "absolute";
iframe.style.zIndex = 50;
// the frame has to be attached to a visible element
let margin = doc.getElementById("newtab-search-container");
margin.appendChild(iframe);
});
});
await pagesUpdatedPromise;
}
/**
* Resumes testing when all pages have been updated.
*/
function whenPagesUpdated() {
return new Promise(resolve => {
let page = {
observe: _ => _,
update() {
NewTabUtils.allPages.unregister(this);
executeSoon(resolve);
}
};
NewTabUtils.allPages.register(page);
registerCleanupFunction(function() {
NewTabUtils.allPages.unregister(page);
});
});
}
/**
* Waits for the response to the page's initial search state request.
*/
function whenSearchInitDone() {
return ContentTask.spawn(gWindow.gBrowser.selectedBrowser, {}, async function() {
return new Promise(resolve => {
if (content.gSearch) {
let searchController = content.gSearch._contentSearchController;
if (searchController.defaultEngine) {
resolve();
return;
}
}
let eventName = "ContentSearchService";
content.addEventListener(eventName, function onEvent(event) {
if (event.detail.type == "State") {
content.removeEventListener(eventName, onEvent);
let resolver = function() {
// Wait for the search controller to receive the event, then resolve.
if (content.gSearch._contentSearchController.defaultEngine) {
resolve();
}
};
content.setTimeout(resolver, 0);
}
});
});
});
}
/**
* Changes the newtab customization option and waits for the panel to open and close
*
* @param {string} aTheme
* Can be any of("blank"|"classic"|"enhanced")
*/
function customizeNewTabPage(aTheme) {
return ContentTask.spawn(gWindow.gBrowser.selectedBrowser, aTheme, async function(contentTheme) {
let document = content.document;
let panel = document.getElementById("newtab-customize-panel");
let customizeButton = document.getElementById("newtab-customize-button");
function panelOpened(opened) {
return new Promise( (resolve) => {
let options = {attributes: true, oldValue: true};
let observer = new content.MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
document.getElementById("newtab-customize-" + contentTheme).click();
observer.disconnect();
if (opened == panel.hasAttribute("open")) {
resolve();
}
});
});
observer.observe(panel, options);
});
}
let opened = panelOpened(true);
customizeButton.click();
await opened;
let closed = panelOpened(false);
customizeButton.click();
await closed;
});
}
/**
* Reports presence of a scrollbar
*/
function hasScrollbar() {
return ContentTask.spawn(gWindow.gBrowser.selectedBrowser, {}, async function() {
let docElement = content.document.documentElement;
return docElement.scrollHeight > docElement.clientHeight;
});
}

Просмотреть файл

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>browser_newtab_search searchEngine1x2xLogo.xml</ShortName>
<Url type="text/html" method="GET" template="http://browser-newtab-search.com/1x2xlogo" rel="searchform"/>
<!-- #00FF00 -->
<Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAIAAABn3KYmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADIGr0+8uwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAL0lEQVRYw+3PAREAAAQEsKd/Z3I4W4NVJtd14uDg4ODg4ODg4ODg4ODg4ODg8Pqw7M0BM+n9I0oAAAAASUVORK5CYII=</Image>
<!-- #00FFFF -->
<Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAIAAADJ8nfCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADMoaoKANQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAYklEQVR42u3RQQ0AAAjEMMC/58MECZ9OwtqVlL4bCzAIAwZhwCAMGIQBgzBgEAYMwoBBGDAIAwZhwCAMGIQBgzBgEAYMwoBBGIQBgzBgEAYMwoBBGDAIAwZhwCAMGIQBg+5ar7sCZiri9VUAAAAASUVORK5CYII=</Image>
</SearchPlugin>

Просмотреть файл

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>browser_newtab_search searchEngine1xLogo.xml</ShortName>
<Url type="text/html" method="GET" template="http://browser-newtab-search.com/1xlogo" rel="searchform"/>
<!-- #FF0000 -->
<Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAIAAABn3KYmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADEwS9h64QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAL0lEQVRYw+3PAREAAAQEsKd/Z3I4W4PV5LyOg4ODg4ODg4ODg4ODg4ODg4PD78MC7cwBM02qquMAAAAASUVORK5CYII=</Image>
</SearchPlugin>

Просмотреть файл

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>browser_newtab_search searchEngine2xLogo.xml</ShortName>
<Url type="text/html" method="GET" template="http://browser-newtab-search.com/2xlogo" rel="searchform"/>
<!-- #0000FF -->
<Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAIAAADJ8nfCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkTADMURe38sgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAYklEQVR42u3RQQ0AAAjEsAP/nsEECZ9OwlrJRN+1BRiEAYMwYBAGDMKAQRgwCAMGYcAgDBiEAYMwYBAGDMKAQRgwCAMGYcAgDMKAQRgwCAMGYcAgDBiEAYMwYBAGDMKAQXctkIQBZ/1YP3YAAAAASUVORK5CYII=</Image>
</SearchPlugin>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>browser_newtab_search searchEngineNoLogo.xml</ShortName>
<Url type="text/html" method="GET" template="http://browser-newtab-search.com/nologo" rel="searchform"/>
</SearchPlugin>

Просмотреть файл

@ -50,9 +50,6 @@ var whitelist = [
// security/manager/pki/resources/content/device_manager.js
{file: "chrome://pippki/content/load_device.xul"},
// Used by setting this url as a pref in about:config
{file: "chrome://browser/content/newtab/alternativeDefaultSites.json"},
// Add-on compat
{file: "chrome://global/content/XPCNativeWrapper.js"},
{file: "chrome://global/locale/brand.dtd"},

Просмотреть файл

@ -96,10 +96,6 @@ browser.jar:
content/browser/defaultthemes/5.preview.jpg (content/defaultthemes/5.preview.jpg)
content/browser/defaultthemes/dark.icon.svg (content/defaultthemes/dark.icon.svg)
content/browser/defaultthemes/light.icon.svg (content/defaultthemes/light.icon.svg)
content/browser/newtab/newTab.xhtml (content/newtab/newTab.xhtml)
* content/browser/newtab/newTab.js (content/newtab/newTab.js)
content/browser/newtab/newTab.css (content/newtab/newTab.css)
content/browser/newtab/alternativeDefaultSites.json (content/newtab/alternativeDefaultSites.json)
* content/browser/pageinfo/pageInfo.xul (content/pageinfo/pageInfo.xul)
content/browser/pageinfo/pageInfo.js (content/pageinfo/pageInfo.js)
content/browser/pageinfo/pageInfo.css (content/pageinfo/pageInfo.css)

Просмотреть файл

@ -30,7 +30,6 @@ BROWSER_CHROME_MANIFESTS += [
'content/test/forms/browser.ini',
'content/test/general/browser.ini',
'content/test/metaTags/browser.ini',
'content/test/newtab/browser.ini',
'content/test/pageinfo/browser.ini',
'content/test/performance/browser.ini',
'content/test/performance/hidpi/browser.ini',

Просмотреть файл

@ -97,10 +97,8 @@ add_task(async function() {
function sendWebSearchKeyCommand() {
if (Services.appinfo.OS === "Darwin")
EventUtils.synthesizeKey("k", {accelKey: true});
else
EventUtils.synthesizeKey("k", {ctrlKey: true});
document.documentElement.focus();
EventUtils.synthesizeKey("k", { accelKey: true });
}
function logActiveElement() {

Просмотреть файл

@ -32,8 +32,8 @@ add_task(async function checkNotificationsDismissed() {
});
let firstTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home", false);
let firstNotification = await getOrWaitForNotification(firstTab.linkedBrowser, "first tab");
let secondTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home", false);
let firstNotification = await getOrWaitForNotification(firstTab.linkedBrowser, "first tab");
let secondNotification = await getOrWaitForNotification(secondTab.linkedBrowser, "second tab");
// Create a listener for the removal in the first tab, and a listener for bookmarks removal,

Просмотреть файл

@ -6,10 +6,6 @@
-moz-binding: url("chrome://browser/content/preferences/handlers.xml#handler");
}
#handlersView > richlistitem[selected="true"] {
-moz-binding: url("chrome://browser/content/preferences/handlers.xml#handler-selected");
}
#containersView > richlistitem {
-moz-binding: url("chrome://browser/content/preferences/handlers.xml#container");
}

Просмотреть файл

@ -17,17 +17,30 @@
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="handler-base" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<binding id="handler" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<implementation>
<property name="type" readonly="true">
<getter>
return this.getAttribute("type");
</getter>
</property>
</implementation>
</binding>
<!-- Overriding listitem -->
<property name="selected" onget="return this.getAttribute('selected') == 'true';">
<setter><![CDATA[
if (val) {
this.setAttribute("selected", "true");
gMainPane.rebuildActionsMenu();
} else {
this.removeAttribute("selected");
}
<binding id="handler" extends="chrome://browser/content/preferences/handlers.xml#handler-base">
document.getAnonymousElementByAttribute(this, "anonid", "selected").setAttribute("hidden", !val);
document.getAnonymousElementByAttribute(this, "anonid", "not-selected").setAttribute("hidden", !!val);
return val;
]]></setter>
</property>
</implementation>
<content>
<xul:hbox flex="1" equalsize="always">
<xul:hbox flex="1" align="center" xbl:inherits="tooltiptext=typeDescription">
@ -35,23 +48,11 @@
xbl:inherits="src=typeIcon" height="16" width="16"/>
<xul:label flex="1" crop="end" xbl:inherits="value=typeDescription"/>
</xul:hbox>
<xul:hbox flex="1" align="center" xbl:inherits="tooltiptext=actionDescription">
<xul:hbox anonid="not-selected" flex="1" align="center" xbl:inherits="tooltiptext=actionDescription">
<xul:image xbl:inherits="src=actionIcon" height="16" width="16" class="actionIcon"/>
<xul:label flex="1" crop="end" xbl:inherits="value=actionDescription"/>
</xul:hbox>
</xul:hbox>
</content>
</binding>
<binding id="handler-selected" extends="chrome://browser/content/preferences/handlers.xml#handler-base">
<content>
<xul:hbox flex="1" equalsize="always">
<xul:hbox flex="1" align="center" xbl:inherits="tooltiptext=typeDescription">
<xul:image src="moz-icon://goat?size=16" class="typeIcon"
xbl:inherits="src=typeIcon" height="16" width="16"/>
<xul:label flex="1" crop="end" xbl:inherits="value=typeDescription"/>
</xul:hbox>
<xul:hbox flex="1">
<xul:hbox hidden="true" anonid="selected" flex="1">
<xul:menulist class="actionsMenu" flex="1" crop="end" selectedIndex="1"
xbl:inherits="tooltiptext=actionDescription"
oncommand="gMainPane.onSelectAction(event.originalTarget)">
@ -60,13 +61,6 @@
</xul:hbox>
</xul:hbox>
</content>
<implementation>
<constructor>
gMainPane.rebuildActionsMenu();
</constructor>
</implementation>
</binding>
<binding id="container">

Просмотреть файл

@ -130,7 +130,7 @@ add_task(async function() {
let dialogFrame = dialogOverlay.querySelector(".dialogFrame");
let frameDoc = dialogFrame.contentDocument;
let updates = frameDoc.querySelectorAll("update");
let updates = frameDoc.querySelectorAll("richlistitem.update");
// Test the update history numbers are correct
is(updates.length, mockUpdateManager.updateCount, "The update count is incorrect.");

Просмотреть файл

@ -84,9 +84,7 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars
}
const canvas = captureToCanvas(selectedPos, captureType);
ui.iframe.showLoader();
const width = selectedPos.right - selectedPos.left;
const height = selectedPos.bottom - selectedPos.top;
const imageData = canvas.getContext("2d").getImageData(0, 0, width, height);
const imageData = canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height);
return callBackground("canvasToDataURL", imageData);
}
@ -180,8 +178,8 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars
}));
};
exports.downloadShot = function(selectedPos, previewDataUrl) {
const shotPromise = previewDataUrl ? Promise.resolve(previewDataUrl) : screenshotPageAsync(selectedPos, "fullPage");
exports.downloadShot = function(selectedPos, previewDataUrl, type) {
const shotPromise = previewDataUrl ? Promise.resolve(previewDataUrl) : screenshotPageAsync(selectedPos, type);
catcher.watchPromise(shotPromise.then(dataUrl => {
let promise = Promise.resolve(dataUrl);
if (!dataUrl) {
@ -214,7 +212,7 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars
};
let copyInProgress = null;
exports.copyShot = function(selectedPos, previewDataUrl) {
exports.copyShot = function(selectedPos, previewDataUrl, type) {
// This is pretty slow. We'll ignore additional user triggered copy events
// while it is in progress.
if (copyInProgress) {
@ -231,7 +229,7 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars
copyInProgress = null;
}
}
const shotPromise = previewDataUrl ? Promise.resolve(previewDataUrl) : screenshotPageAsync(selectedPos, "fullPage");
const shotPromise = previewDataUrl ? Promise.resolve(previewDataUrl) : screenshotPageAsync(selectedPos, type);
catcher.watchPromise(shotPromise.then(dataUrl => {
const blob = blobConverters.dataUrlToBlob(dataUrl);
catcher.watchPromise(callBackground("copyShotToClipboard", blob).then(() => {

Просмотреть файл

@ -99,14 +99,14 @@ this.uicontrol = (function() {
const previewDataUrl = (captureType === "fullPageTruncated") ? null : dataUrl;
// Downloaded shots don't have dimension limits
removeDimensionLimitsOnFullPageShot();
shooter.downloadShot(selectedPos, previewDataUrl);
shooter.downloadShot(selectedPos, previewDataUrl, captureType);
}
function copyShot() {
const previewDataUrl = (captureType === "fullPageTruncated") ? null : dataUrl;
// Copied shots don't have dimension limits
removeDimensionLimitsOnFullPageShot();
shooter.copyShot(selectedPos, previewDataUrl);
shooter.copyShot(selectedPos, previewDataUrl, captureType);
}
/** *********************************************

Просмотреть файл

@ -22,7 +22,6 @@ browser/chrome/browser/content/browser/places/bookmarkProperties2.xul
browser/chrome/browser/skin/classic/browser/addons/addon-install-confirm.svg
browser/chrome/browser/skin/classic/browser/connection-secure.svg
browser/chrome/browser/skin/classic/browser/controlcenter/warning-gray.svg
browser/chrome/browser/skin/classic/browser/newtab/close.png
# devtools reduction is bug 1311178
browser/chrome/devtools/content/dom/content/dom-view.css
browser/chrome/devtools/content/dom/dom.html

Просмотреть файл

@ -1,16 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!-- These strings are used in the about:newtab page -->
<!ENTITY newtab.pageTitle "New Tab">
<!ENTITY newtab.customize.classic "Show your top sites">
<!ENTITY newtab.customize.cog.enhanced "Include suggested sites">
<!ENTITY newtab.customize.cog.title2 "NEW TAB CONTROLS">
<!ENTITY newtab.customize.cog.learn "Learn about New Tab">
<!ENTITY newtab.customize.title "Customize your New Tab page">
<!ENTITY newtab.customize.blank2 "Show blank page">
<!ENTITY newtab.undo.removedLabel "Thumbnail removed.">
<!ENTITY newtab.undo.undoButton "Undo.">
<!ENTITY newtab.undo.restoreButton "Restore All.">
<!ENTITY newtab.undo.closeTooltip "Hide">

Просмотреть файл

@ -1,10 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
newtab.defaultTopSites.heading=Top Sites
newtab.userTopSites.heading=Your Top Sites
newtab.pin=Pin this site at its current position
newtab.unpin=Unpin this site
newtab.block=Remove this site

Просмотреть файл

@ -30,8 +30,6 @@
#ifdef XP_WIN
locale/browser/uiDensity.properties (%chrome/browser/uiDensity.properties)
#endif
locale/browser/newTab.dtd (%chrome/browser/newTab.dtd)
locale/browser/newTab.properties (%chrome/browser/newTab.properties)
locale/browser/pageInfo.dtd (%chrome/browser/pageInfo.dtd)
locale/browser/pageInfo.properties (%chrome/browser/pageInfo.properties)
locale/browser/quitDialog.properties (%chrome/browser/quitDialog.properties)

Просмотреть файл

@ -27,7 +27,6 @@ browser.jar:
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/notification-icons/geo-blocked.svg (notification-icons/geo-blocked.svg)
skin/classic/browser/notification-icons/geo-detailed.svg (notification-icons/geo-detailed.svg)
skin/classic/browser/notification-icons/geo.svg (notification-icons/geo.svg)

Просмотреть файл

@ -1,15 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%include ../../shared/newtab/newTab.inc.css
.newtab-undo-button {
color: rgb(221,72,20);
}
#newtab-undo-close-button {
height: 16px;
width: 16px;
}

Просмотреть файл

@ -30,7 +30,6 @@ browser.jar:
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/setDesktopBackground.css
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png

Просмотреть файл

@ -1,10 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%include ../../shared/newtab/newTab.inc.css
.newtab-undo-button {
color: rgb(20,79,174);
}

Просмотреть файл

@ -77,8 +77,6 @@
skin/classic/browser/notification-icons/midi.svg (../shared/notification-icons/midi.svg)
skin/classic/browser/tracking-protection-16.svg (../shared/identity-block/tracking-protection-16.svg)
skin/classic/browser/newtab/close.png (../shared/newtab/close.png)
skin/classic/browser/newtab/controls.svg (../shared/newtab/controls.svg)
skin/classic/browser/panel-icon-arrow-left.svg (../shared/panel-icon-arrow-left.svg)
skin/classic/browser/panel-icon-arrow-right.svg (../shared/panel-icon-arrow-right.svg)
skin/classic/browser/panel-icon-cancel.svg (../shared/panel-icon-cancel.svg)

Двоичные данные
browser/themes/shared/newtab/close.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 698 B

Просмотреть файл

@ -1,155 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="288px" height="32px" viewBox="0 0 288 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>controls</title>
<desc>Created with Sketch.</desc>
<defs>
<circle id="path-1" cx="14" cy="14" r="14"></circle>
<filter x="-12.5%" y="-8.9%" width="125.0%" height="125.0%" filterUnits="objectBoundingBox" id="filter-2">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.246631567 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<circle id="path-3" cx="14" cy="14" r="14"></circle>
<filter x="-12.5%" y="-8.9%" width="125.0%" height="125.0%" filterUnits="objectBoundingBox" id="filter-4">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.246631567 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<circle id="path-5" cx="14" cy="14" r="14"></circle>
<filter x="-12.5%" y="-8.9%" width="125.0%" height="125.0%" filterUnits="objectBoundingBox" id="filter-6">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.246631567 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<circle id="path-7" cx="14" cy="14" r="14"></circle>
<filter x="-12.5%" y="-8.9%" width="125.0%" height="125.0%" filterUnits="objectBoundingBox" id="filter-8">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.246631567 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<circle id="path-9" cx="14" cy="14" r="14"></circle>
<filter x="-12.5%" y="-8.9%" width="125.0%" height="125.0%" filterUnits="objectBoundingBox" id="filter-10">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.246631567 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<circle id="path-11" cx="14" cy="14" r="14"></circle>
<filter x="-12.5%" y="-8.9%" width="125.0%" height="125.0%" filterUnits="objectBoundingBox" id="filter-12">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.246631567 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="controls" fill-rule="nonzero">
<g transform="translate(2.000000, 2.000000)">
<g id="icon-gear-default" fill-opacity="context-fill-opacity" fill="context-fill">
<g id="glyphShape-gear-link">
<path d="M24.5,12.5 L21.35,12.5 C21.1565841,11.5610207 20.7837667,10.6681942 20.252,9.8705 L22.487,7.6355 C23.0554583,7.04693167 23.0473286,6.11137283 22.4687279,5.53277214 C21.8901272,4.95417144 20.9545683,4.94604169 20.366,5.5145 L18.131,7.7495 C17.3329502,7.21706084 16.4395982,6.8437273 15.5,6.65 L15.5,3.5 C15.5,2.67157288 14.8284271,2 14,2 C13.1715729,2 12.5,2.67157288 12.5,3.5 L12.5,6.65 C11.5610318,6.84345197 10.668212,7.21626662 9.8705,7.748 L7.6355,5.513 C7.04938781,4.92730204 6.09944799,4.92763783 5.51375002,5.51375002 C4.92805204,6.0998622 4.92838782,7.04980202 5.5145,7.6355 L7.7495,9.8705 C7.21720441,10.6680797 6.84387483,11.5609129 6.65,12.5 L3.5,12.5 C2.67157289,12.5 2.00000004,13.1715729 2.00000004,14 C2.00000004,14.8284271 2.67157289,15.5 3.5,15.5 L6.65,15.5 C6.84390489,16.444731 7.21934843,17.3428409 7.7555,18.1445 C7.7345,18.164 7.7075,18.17 7.688,18.1895 L5.513,20.3645 C5.12306512,20.7411117 4.9666811,21.2988168 5.10395427,21.823261 C5.24122743,22.3477051 5.65079487,22.7572726 6.17523901,22.8945457 C6.69968316,23.0318189 7.25738829,22.8754349 7.634,22.4855 L9.809,20.3105 C9.8285,20.291 9.836,20.264 9.854,20.243 C10.6559957,20.7798585 11.5546382,21.1558212 12.5,21.35 L12.5,24.5 C12.5,25.3284271 13.1715729,26 14,26 C14.8284271,26 15.5,25.3284271 15.5,24.5 L15.5,21.35 C16.4389682,21.156548 17.331788,20.7837334 18.1295,20.252 L20.3645,22.487 C20.9530683,23.0554583 21.8886272,23.0473286 22.4672279,22.4687279 C23.0458286,21.8901272 23.0539583,20.9545683 22.4855,20.366 L20.2505,18.131 C20.7829725,17.332968 21.1563088,16.4396093 21.35,15.5 L24.5,15.5 C25.3284271,15.5 26,14.8284271 26,14 C26,13.1715729 25.3284271,12.5 24.5,12.5 Z M9.5,14 C9.5,11.5147186 11.5147186,9.5 14,9.5 C16.4852814,9.5 18.5,11.5147186 18.5,14 C18.5,16.4852814 16.4852814,18.5 14,18.5 C11.5147186,18.5 9.5,16.4852814 9.5,14 Z" id="glyphShape-gear"></path>
</g>
</g>
<g id="icon-gear-default" transform="translate(34.000000, 2.000000)" fill="#0A84FF">
<g id="glyphShape-gear-link">
<path d="M22.5,10.5 L19.35,10.5 C19.1565841,9.56102069 18.7837667,8.66819421 18.252,7.8705 L20.487,5.6355 C21.0554583,5.04693167 21.0473286,4.11137283 20.4687279,3.53277214 C19.8901272,2.95417144 18.9545683,2.94604169 18.366,3.5145 L16.131,5.7495 C15.3329502,5.21706084 14.4395982,4.8437273 13.5,4.65 L13.5,1.5 C13.5,0.671572875 12.8284271,5.07265313e-17 12,0 C11.1715729,-5.07265313e-17 10.5,0.671572875 10.5,1.5 L10.5,4.65 C9.56103183,4.84345197 8.66821204,5.21626662 7.8705,5.748 L5.6355,3.513 C5.04938781,2.92730204 4.09944799,2.92763783 3.51375002,3.51375002 C2.92805204,4.0998622 2.92838782,5.04980202 3.5145,5.6355 L5.7495,7.8705 C5.21720441,8.6680797 4.84387483,9.56091293 4.65,10.5 L1.5,10.5 C0.671572893,10.5 4.47034837e-08,11.1715729 4.47034836e-08,12 C4.47034835e-08,12.8284271 0.671572893,13.5 1.5,13.5 L4.65,13.5 C4.84390489,14.444731 5.21934843,15.3428409 5.7555,16.1445 C5.7345,16.164 5.7075,16.17 5.688,16.1895 L3.513,18.3645 C3.12306512,18.7411117 2.9666811,19.2988168 3.10395427,19.823261 C3.24122743,20.3477051 3.65079487,20.7572726 4.17523901,20.8945457 C4.69968316,21.0318189 5.25738829,20.8754349 5.634,20.4855 L7.809,18.3105 C7.8285,18.291 7.836,18.264 7.854,18.243 C8.65599575,18.7798585 9.55463824,19.1558212 10.5,19.35 L10.5,22.5 C10.5,23.3284271 11.1715729,24 12,24 C12.8284271,24 13.5,23.3284271 13.5,22.5 L13.5,19.35 C14.4389682,19.156548 15.331788,18.7837334 16.1295,18.252 L18.3645,20.487 C18.9530683,21.0554583 19.8886272,21.0473286 20.4672279,20.4687279 C21.0458286,19.8901272 21.0539583,18.9545683 20.4855,18.366 L18.2505,16.131 C18.7829725,15.332968 19.1563088,14.4396093 19.35,13.5 L22.5,13.5 C23.3284271,13.5 24,12.8284271 24,12 C24,11.1715729 23.3284271,10.5 22.5,10.5 Z M7.5,12 C7.5,9.51471863 9.51471863,7.5 12,7.5 C14.4852814,7.5 16.5,9.51471863 16.5,12 C16.5,14.4852814 14.4852814,16.5 12,16.5 C9.51471863,16.5 7.5,14.4852814 7.5,12 Z" id="glyphShape-gear"></path>
</g>
</g>
<g id="icon-pin-default" transform="translate(64.000000, 0.000000)">
<g id="glyphShape-circle-link">
<g id="glyphShape-circle">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use fill-opacity="0.5" fill="#000000" fill-rule="evenodd" xlink:href="#path-1"></use>
</g>
</g>
<g id="glyphShape-circle-link" fill="#FFFFFF">
<circle id="glyphShape-circle" cx="14" cy="14" r="14"></circle>
</g>
<g id="glyphShape-pin-link" transform="translate(2.000000, 2.000000)" fill-opacity="0.8" fill="#0C0C0D" opacity="0.5">
<path d="M21.0602235,18.9392235 L16.1207235,13.9997235 L19.5602235,10.5602235 C20.1457964,9.97447373 20.1457964,9.02497329 19.5602235,8.43922351 C18.3214743,7.19329279 16.6356582,6.49487551 14.8787235,6.49972351 L14.6207235,6.49972351 C12.6212434,6.49889574 11.0005513,4.87820361 10.9997235,2.87872351 L10.9997235,1.99972351 C10.999594,1.39312966 10.6341323,0.846322434 10.0737053,0.614206542 C9.51327843,0.38209065 8.86821489,0.510361636 8.43922351,0.939223509 L0.939223509,8.43922351 C0.510361636,8.86821489 0.38209065,9.51327843 0.614206542,10.0737053 C0.846322434,10.6341323 1.39312966,10.999594 1.99972351,10.9997235 L2.87872351,10.9997235 C4.87820361,11.0005513 6.49889574,12.6212434 6.49972351,14.6207235 L6.49972351,14.8742235 C6.4271772,16.6769781 7.16247236,18.4181482 8.50522351,19.6232235 C9.0991645,20.1487898 9.99959214,20.1211854 10.5602235,19.5602235 L13.9997235,16.1207235 L18.9392235,21.0602235 C19.5277918,21.6286818 20.4633507,21.6205521 21.0419514,21.0419514 C21.6205521,20.4633507 21.6286818,19.5277918 21.0602235,18.9392235 Z M9.69322351,16.1837235 C9.55691479,15.7608895 9.49153122,15.3184099 9.49972351,14.8742235 L9.49972351,14.6207235 C9.50463372,12.8640717 8.80682056,11.17841 7.56172351,9.93922351 C6.89356311,9.26903844 6.08949822,8.7498744 5.20372351,8.41672351 L8.41822351,5.20372351 C8.75009692,6.08898872 9.26828926,6.89262165 9.93772351,7.56022351 C11.1768387,8.80652462 12.8632693,9.50497268 14.6207235,9.49972351 L14.8787235,9.49972351 C15.313005,9.49837795 15.7439466,9.5756222 16.1507235,9.72772351 L9.69322351,16.1837235 Z" id="glyphShape-pin"></path>
</g>
</g>
<g id="icon-pin-hover" transform="translate(96.000000, 0.000000)">
<g id="glyphShape-circle-link">
<g id="glyphShape-circle">
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
<use fill-opacity="0.5" fill="#000000" fill-rule="evenodd" xlink:href="#path-3"></use>
</g>
</g>
<g id="glyphShape-circle-link" fill="#FFFFFF">
<circle id="glyphShape-circle" cx="14" cy="14" r="14"></circle>
</g>
<g id="glyphShape-pin-link" transform="translate(2.000000, 2.000000)" fill="#0A84FF">
<path d="M21.0602235,18.9395 L16.1207235,14 L19.5602235,10.5605 C20.1457964,9.97475022 20.1457964,9.02524978 19.5602235,8.4395 C18.3214743,7.19356928 16.6356582,6.495152 14.8787235,6.5 L14.6207235,6.5 C12.6212434,6.49917223 11.0005513,4.8784801 10.9997235,2.879 L10.9997235,2 C10.999594,1.39340615 10.6341323,0.846598925 10.0737053,0.614483033 C9.51327843,0.382367141 8.86821489,0.510638127 8.43922351,0.9395 L0.939223509,8.4395 C0.510361636,8.86849138 0.38209065,9.51355492 0.614206542,10.0739818 C0.846322434,10.6344087 1.39312966,10.9998705 1.99972351,11 L2.87872351,11 C4.87820361,11.0008278 6.49889574,12.6215199 6.49972351,14.621 L6.49972351,14.8745 C6.4271772,16.6772546 7.16247236,18.4184247 8.50522351,19.6235 C9.0991645,20.1490663 9.99959214,20.1214619 10.5602235,19.5605 L13.9997235,16.121 L18.9392235,21.0605 C19.5277918,21.6289583 20.4633507,21.6208286 21.0419514,21.0422279 C21.6205521,20.4636272 21.6286818,19.5280683 21.0602235,18.9395 Z M9.69322351,16.184 C9.55691479,15.761166 9.49153122,15.3186864 9.49972351,14.8745 L9.49972351,14.621 C9.50463372,12.8643482 8.80682056,11.1786865 7.56172351,9.9395 C6.89356311,9.26931493 6.08949822,8.75015089 5.20372351,8.417 L8.41822351,5.204 C8.75009692,6.08926521 9.26828926,6.89289814 9.93772351,7.5605 C11.1768387,8.80680111 12.8632693,9.50524918 14.6207235,9.5 L14.8787235,9.5 C15.313005,9.49865444 15.7439466,9.57589869 16.1507235,9.728 L9.69322351,16.184 Z" id="glyphShape-pin"></path>
</g>
</g>
<g id="icon-pin-hover-active" transform="translate(128.000000, 0.000000)">
<g id="glyphShape-circle-link">
<g id="glyphShape-circle">
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
<use fill-opacity="0.5" fill="#000000" fill-rule="evenodd" xlink:href="#path-5"></use>
</g>
</g>
<g id="glyphShape-circle-link" fill="#FFFFFF">
<circle id="glyphShape-circle" cx="14" cy="14" r="14"></circle>
</g>
<g id="glyphShape-pin-link" transform="translate(2.000000, 2.000000)" fill-opacity="0.8" fill="#0C0C0D">
<path d="M21.0605,18.9395 L16.121,14 L19.5605,10.5605 C20.1460729,9.97475022 20.1460729,9.02524978 19.5605,8.4395 C18.3217508,7.19356928 16.6359346,6.495152 14.879,6.5 L14.621,6.5 C12.6215199,6.49917223 11.0008278,4.8784801 11,2.879 L11,2 C10.9998705,1.39340615 10.6344087,0.846598925 10.0739818,0.614483033 C9.51355492,0.382367141 8.86849138,0.510638127 8.4395,0.9395 L0.9395,8.4395 C0.510638127,8.86849138 0.382367141,9.51355492 0.614483033,10.0739818 C0.846598925,10.6344087 1.39340615,10.9998705 2,11 L2.879,11 C4.8784801,11.0008278 6.49917223,12.6215199 6.5,14.621 L6.5,14.8745 C6.42745369,16.6772546 7.16274886,18.4184247 8.5055,19.6235 C9.09944099,20.1490663 9.99986863,20.1214619 10.5605,19.5605 L14,16.121 L18.9395,21.0605 C19.5280683,21.6289583 20.4636272,21.6208286 21.0422279,21.0422279 C21.6208286,20.4636272 21.6289583,19.5280683 21.0605,18.9395 Z M9.6935,16.184 C9.55719129,15.761166 9.49180771,15.3186864 9.5,14.8745 L9.5,14.621 C9.50491021,12.8643482 8.80709705,11.1786865 7.562,9.9395 C6.8938396,9.26931493 6.08977471,8.75015089 5.204,8.417 L8.4185,5.204 C8.75037341,6.08926521 9.26856575,6.89289814 9.938,7.5605 C11.1771151,8.80680111 12.8635458,9.50524918 14.621,9.5 L14.879,9.5 C15.3132815,9.49865444 15.7442231,9.57589869 16.151,9.728 L9.6935,16.184 Z" id="glyphShape-pin"></path>
</g>
</g>
<g id="icon-delete-default" transform="translate(160.000000, 0.000000)">
<g id="glyphShape-circle-link">
<g id="glyphShape-circle">
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
<use fill-opacity="0.5" fill="#000000" fill-rule="evenodd" xlink:href="#path-7"></use>
</g>
</g>
<g id="glyphShape-circle-link" fill="#FFFFFF">
<circle id="glyphShape-circle" cx="14" cy="14" r="14"></circle>
</g>
<g id="glyphShape-delete-link" transform="translate(7.000000, 7.000000)" fill-opacity="0.8" fill="#0C0C0D" opacity="0.5">
<path d="M8.74459268,7.15309268 L13.9495927,1.94809268 C14.375733,1.50646618 14.3693071,0.804796097 13.93515,0.37104824 C13.500993,-0.0626996171 12.7993172,-0.0684638996 12.3580927,0.358092679 L7.15309268,5.56159268 L1.94809268,0.358092679 C1.66763681,0.0571129121 1.24525937,-0.0667810937 0.846659316,0.0350143657 C0.448059266,0.136809825 0.136809825,0.448059266 0.0350143657,0.846659316 C-0.0667810937,1.24525937 0.0571129121,1.66763681 0.358092679,1.94809268 L5.56159268,7.15309268 L0.358092679,12.3580927 C0.0571129121,12.6385485 -0.0667810937,13.060926 0.0350143657,13.459526 C0.136809825,13.8581261 0.448059266,14.1693755 0.846659316,14.271171 C1.24525937,14.3729665 1.66763681,14.2490724 1.94809268,13.9480927 L7.15309268,8.74459268 L12.3580927,13.9495927 C12.7997192,14.375733 13.5013893,14.3693071 13.9351371,13.93515 C14.368885,13.500993 14.3746493,12.7993172 13.9480927,12.3580927 L8.74459268,7.15309268 Z" id="glyphShape-delete"></path>
</g>
</g>
<g id="icon-delete-hover" transform="translate(192.000000, 0.000000)">
<g id="glyphShape-circle-link">
<g id="glyphShape-circle">
<use fill="black" fill-opacity="1" filter="url(#filter-10)" xlink:href="#path-9"></use>
<use fill-opacity="0.5" fill="#000000" fill-rule="evenodd" xlink:href="#path-9"></use>
</g>
</g>
<g id="glyphShape-circle-link" fill="#FFFFFF">
<circle id="glyphShape-circle" cx="14" cy="14" r="14"></circle>
</g>
<g id="glyphShape-delete-link" transform="translate(7.000000, 7.000000)" fill="#FF0039">
<path d="M8.74459268,7.15309268 L13.9495927,1.94809268 C14.375733,1.50646618 14.3693071,0.804796097 13.93515,0.37104824 C13.500993,-0.0626996171 12.7993172,-0.0684638996 12.3580927,0.358092679 L7.15309268,5.56159268 L1.94809268,0.358092679 C1.66763681,0.0571129121 1.24525937,-0.0667810937 0.846659316,0.0350143657 C0.448059266,0.136809825 0.136809825,0.448059266 0.0350143657,0.846659316 C-0.0667810937,1.24525937 0.0571129121,1.66763681 0.358092679,1.94809268 L5.56159268,7.15309268 L0.358092679,12.3580927 C0.0571129121,12.6385485 -0.0667810937,13.060926 0.0350143657,13.459526 C0.136809825,13.8581261 0.448059266,14.1693755 0.846659316,14.271171 C1.24525937,14.3729665 1.66763681,14.2490724 1.94809268,13.9480927 L7.15309268,8.74459268 L12.3580927,13.9495927 C12.7997192,14.375733 13.5013893,14.3693071 13.9351371,13.93515 C14.368885,13.500993 14.3746493,12.7993172 13.9480927,12.3580927 L8.74459268,7.15309268 Z" id="glyphShape-delete"></path>
</g>
</g>
<g id="icon-delete-hover-active" transform="translate(224.000000, 0.000000)">
<g id="glyphShape-circle-link">
<g id="glyphShape-circle">
<use fill="black" fill-opacity="1" filter="url(#filter-12)" xlink:href="#path-11"></use>
<use fill-opacity="0.5" fill="#000000" fill-rule="evenodd" xlink:href="#path-11"></use>
</g>
</g>
<g id="glyphShape-circle-link" fill="#FFFFFF">
<circle id="glyphShape-circle" cx="14" cy="14" r="14"></circle>
</g>
<g id="glyphShape-delete-link" transform="translate(7.000000, 7.000000)" fill-opacity="0.8" fill="#0C0C0D">
<path d="M8.74459268,7.15309268 L13.9495927,1.94809268 C14.375733,1.50646618 14.3693071,0.804796097 13.93515,0.37104824 C13.500993,-0.0626996171 12.7993172,-0.0684638996 12.3580927,0.358092679 L7.15309268,5.56159268 L1.94809268,0.358092679 C1.66763681,0.0571129121 1.24525937,-0.0667810937 0.846659316,0.0350143657 C0.448059266,0.136809825 0.136809825,0.448059266 0.0350143657,0.846659316 C-0.0667810937,1.24525937 0.0571129121,1.66763681 0.358092679,1.94809268 L5.56159268,7.15309268 L0.358092679,12.3580927 C0.0571129121,12.6385485 -0.0667810937,13.060926 0.0350143657,13.459526 C0.136809825,13.8581261 0.448059266,14.1693755 0.846659316,14.271171 C1.24525937,14.3729665 1.66763681,14.2490724 1.94809268,13.9480927 L7.15309268,8.74459268 L12.3580927,13.9495927 C12.7997192,14.375733 13.5013893,14.3693071 13.9351371,13.93515 C14.368885,13.500993 14.3746493,12.7993172 13.9480927,12.3580927 L8.74459268,7.15309268 Z" id="glyphShape-delete"></path>
</g>
</g>
<g id="icon-pin-default" transform="translate(258.000000, 2.000000)" fill="#B4B4B4">
<g id="glyphShape-pin-link">
<path d="M21.0602235,18.9392235 L16.1207235,13.9997235 L19.5602235,10.5602235 C20.1457964,9.97447373 20.1457964,9.02497329 19.5602235,8.43922351 C18.3214743,7.19329279 16.6356582,6.49487551 14.8787235,6.49972351 L14.6207235,6.49972351 C12.6212434,6.49889574 11.0005513,4.87820361 10.9997235,2.87872351 L10.9997235,1.99972351 C10.999594,1.39312966 10.6341323,0.846322434 10.0737053,0.614206542 C9.51327843,0.38209065 8.86821489,0.510361636 8.43922351,0.939223509 L0.939223509,8.43922351 C0.510361636,8.86821489 0.38209065,9.51327843 0.614206542,10.0737053 C0.846322434,10.6341323 1.39312966,10.999594 1.99972351,10.9997235 L2.87872351,10.9997235 C4.87820361,11.0005513 6.49889574,12.6212434 6.49972351,14.6207235 L6.49972351,14.8742235 C6.4271772,16.6769781 7.16247236,18.4181482 8.50522351,19.6232235 C9.0991645,20.1487898 9.99959214,20.1211854 10.5602235,19.5602235 L13.9997235,16.1207235 L18.9392235,21.0602235 C19.5277918,21.6286818 20.4633507,21.6205521 21.0419514,21.0419514 C21.6205521,20.4633507 21.6286818,19.5277918 21.0602235,18.9392235 Z M9.69322351,16.1837235 C9.55691479,15.7608895 9.49153122,15.3184099 9.49972351,14.8742235 L9.49972351,14.6207235 C9.50463372,12.8640717 8.80682056,11.17841 7.56172351,9.93922351 C6.89356311,9.26903844 6.08949822,8.7498744 5.20372351,8.41672351 L8.41822351,5.20372351 C8.75009692,6.08898872 9.26828926,6.89262165 9.93772351,7.56022351 C11.1768387,8.80652462 12.8632693,9.50497268 14.6207235,9.49972351 L14.8787235,9.49972351 C15.313005,9.49837795 15.7439466,9.5756222 16.1507235,9.72772351 L9.69322351,16.1837235 Z" id="Shape"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 22 KiB

Просмотреть файл

@ -1,307 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
:root {
-moz-appearance: none;
font-size: 75%;
background-color: transparent;
}
/* UNDO */
#newtab-undo-container {
padding: 4px 3px;
border: 1px solid;
border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
background-color: rgba(255,255,255,.4);
color: #525e69;
}
#newtab-undo-label {
margin-top: 0;
margin-bottom: 0;
}
.newtab-undo-button {
-moz-appearance: none;
cursor: pointer;
padding: 0;
margin: 0 4px;
border: 0;
background: transparent;
text-decoration: none;
min-width: 0;
}
.newtab-undo-button:hover {
text-decoration: underline;
}
.newtab-undo-button:-moz-focusring {
outline: 1px dotted;
}
#newtab-undo-close-button {
-moz-appearance: none;
padding: 0;
border: none;
}
#newtab-undo-close-button {
-moz-appearance: none;
padding: 0;
border: none;
height: 16px;
width: 16px;
float: right;
right: 0;
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/close.png), 0, 16, 16, 0);
background-color: transparent;
}
#newtab-undo-close-button:hover {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/close.png), 0, 32, 16, 16);
}
#newtab-undo-close-button:hover:active {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/close.png), 0, 48, 16, 32);
}
/* CUSTOMIZE */
#newtab-customize-button,
.newtab-customize {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 32, 32, 0);
background-size: 28px;
height: 38px;
width: 38px;
background-repeat: no-repeat;
background-position: center;
background-color: transparent;
border: none;
}
.newtab-customize {
height: 28px;
width: 28px;
}
#newtab-customize-button {
font-size: 28px;
padding: 0;
/* only display the text label when CSS backgrounds are disabled (e.g. in high contrast mode) */
color: transparent;
fill: rgba(12, 12, 12, 0.6);
-moz-context-properties: fill;
}
#newtab-customize-button:-moz-any(:hover, :active, [active]) {
background-color: #EDEDF0;
}
/* GRID */
#topsites-heading {
color: #7A7A7A;
font-size: 1em;
font-weight: normal;
/* Position the heading such that it doesn't affect how many cells we
can fit into the grid. */
position: absolute;
/* The top margin moves the heading away from the grid.
The horizontal margin aligns the heading with the cells. */
margin: -1em 10px 0;
}
/* CELLS */
.newtab-cell {
--cell-corner-radius: 4px;
background-color: rgba(255,255,255,.2);
border-radius: var(--cell-corner-radius);
}
body.compact .newtab-cell {
--cell-corner-radius: 2px;
}
.newtab-cell:empty {
outline: 2px dashed #c1c1c1;
outline-offset: -2px;
-moz-outline-radius: var(--cell-corner-radius);
}
/* SITES */
.newtab-site {
border-radius: var(--cell-corner-radius);
box-shadow: 0 2px 4px #c1c1c1;
text-decoration: none;
}
/* LINKS */
.newtab-link {
border-radius: var(--cell-corner-radius);
overflow: hidden;
}
/***
* If you change the sizes here, change them in newTab.css
* and the preference values:
* toolkit.pageThumbs.minWidth
* toolkit.pageThumbs.minHeight
*/
/* THUMBNAILS */
.newtab-thumbnail {
background-origin: padding-box;
background-clip: padding-box;
background-repeat: no-repeat;
background-size: cover;
height: 180px;
transition: opacity 100ms ease-out;
}
body.compact .newtab-thumbnail {
height: 100%;
border-radius: calc(var(--cell-corner-radius) + 1px);
outline: 1px solid hsla(0,0%,0%,.1);
-moz-outline-radius: var(--cell-corner-radius);
outline-offset: -1px;
}
.newtab-thumbnail.placeholder {
color: white;
font-size: 85px;
line-height: 200%;
}
body.compact .newtab-thumbnail.placeholder {
font-size: 45px;
}
.newtab-cell:not([ignorehover]) .newtab-site:hover .newtab-thumbnail.enhanced-content {
opacity: 0;
}
.newtab-site[type=affiliate] .newtab-thumbnail {
background-position: center center;
}
body.compact .newtab-site[type=affiliate] .newtab-thumbnail {
background-position: center 30%;
}
.newtab-site[type=affiliate] .newtab-thumbnail {
background-size: auto;
}
/* TITLES */
.newtab-title {
background-color: #F9F9FA;
font-size: 14px;
line-height: 30px;
border: 1px solid #fff;
border-radius: 0 0 var(--cell-corner-radius) var(--cell-corner-radius);
color: rgba(12, 12, 13, 0.76);
}
body.compact .newtab-title {
background-color: hsla(0,0%,100%,.85);
font-size: 12px;
line-height: 21px;
border: 1px solid hsla(0,0%,80%,.8);
border-top-color: hsla(0,0%,0%,.1);
background-clip: padding-box;
}
body.compact .newtab-title {
color: black;
}
body:not(.compact) .newtab-site:hover .newtab-title {
color: white;
background-color: #4A4A4F;
border-color: white;
}
body.compact .newtab-site:hover .newtab-title {
color: white;
background-color: hsla(0,0%,20%,.85);
border-color: hsla(0,0%,0%,.8);
border-top-color: white;
}
.newtab-site[pinned] .newtab-title::before {
background-image: -moz-image-rect(url("chrome://browser/skin/newtab/controls.svg"), 0, 298, 28, 256);
background-size: 20px;
content: "";
height: 20px;
left: 0;
position: absolute;
width: 20px;
margin-left: 8px;
margin-top: 6px;
}
.newtab-site[pinned] .newtab-title:dir(rtl)::before {
left: auto;
right: 0;
}
/* CONTROLS */
.newtab-control {
background-color: transparent;
background-size: 26px;
border: none;
height: 26px;
width: 26px;
top: 8px;
}
.newtab-control-pin:dir(ltr),
.newtab-control-block:dir(rtl) {
left: 8px;
}
.newtab-control-block:dir(ltr),
.newtab-control-pin:dir(rtl) {
right: 8px;
}
body.compact .newtab-control {
top: -8px;
}
body.compact .newtab-control-pin:dir(ltr),
body.compact .newtab-control-block:dir(rtl) {
left: -8px;
}
body.compact .newtab-control-block:dir(ltr),
body.compact .newtab-control-pin:dir(rtl) {
right: -8px;
}
.newtab-control-pin,
.newtab-site[pinned] .newtab-control-pin:hover:active {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 96, 32, 64);
}
.newtab-control-pin:hover,
.newtab-site[pinned] .newtab-control-pin:hover {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 160, 32, 128);
}
.newtab-control-pin:hover:active,
.newtab-site[pinned] .newtab-control-pin {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 128, 32, 96);
}
.newtab-control-block {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 192, 32, 160);
}
.newtab-control-block:hover {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 224, 32, 192);
}
.newtab-control-block:hover:active {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 256, 32, 224);
}

Просмотреть файл

@ -28,7 +28,6 @@ browser.jar:
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/notification-icons/geo-blocked.svg (notification-icons/geo-blocked.svg)
skin/classic/browser/notification-icons/geo-detailed.svg (notification-icons/geo-detailed.svg)
skin/classic/browser/notification-icons/geo.svg (notification-icons/geo.svg)

Просмотреть файл

@ -1,14 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%include ../../shared/newtab/newTab.inc.css
.newtab-undo-button {
color: rgb(0,102,204);
}
.newtab-undo-button > .button-box {
padding: 0;
}

Просмотреть файл

@ -1266,7 +1266,10 @@ def pgo_flags(compiler):
use_cflags=['-GL', '-wd4624', '-wd4952'],
# XXX: should be -LTCG:PGOPTIMIZE, but that fails on libxul.
# Probably also a compiler bug, but what can you do?
use_ldflags=['-LTCG:PGUPDATE', cgthreads],
# /d2:-cgsummary prints a summary of what is happening during
# code generation. How long individual functions are optimized,
# which functions are optimized, etc.
use_ldflags=['-LTCG:PGUPDATE', cgthreads, '-d2:-cgsummary'],
)

Просмотреть файл

@ -218,7 +218,7 @@ var DebuggerView = {
});
// Relay events from the VariablesView.
this.Variables.on("fetched", (aEvent, aType) => {
this.Variables.on("fetched", aType => {
switch (aType) {
case "scopes":
window.emit(EVENTS.FETCHED_SCOPES);

Просмотреть файл

@ -215,7 +215,7 @@ VariableBubbleView.prototype = {
getterOrSetterEvalMacro: this._getGetterOrSetterEvalMacro(evalPrefix),
overrideValueEvalMacro: this._getOverrideValueEvalMacro(evalPrefix)
}, {
fetched: (aEvent, aType) => {
fetched: aType => {
if (aType == "properties") {
window.emit(EVENTS.FETCHED_BUBBLE_PROPERTIES);
}

Просмотреть файл

@ -814,7 +814,7 @@ Toolbox.prototype = {
},
_buildOptions: function () {
let selectOptions = (name, event) => {
let selectOptions = event => {
// Flip back to the last used panel if we are already
// on the options panel.
if (this.currentToolId === "options" &&
@ -854,7 +854,7 @@ Toolbox.prototype = {
* if this tool is active.
*/
useKeyWithSplitConsole: function (key, handler, whichTool) {
this.shortcuts.on(key, (name, event) => {
this.shortcuts.on(key, event => {
if (this.currentToolId === whichTool && this.isSplitConsoleFocused()) {
handler();
event.preventDefault();
@ -870,7 +870,7 @@ Toolbox.prototype = {
["forceReload2", true]
].forEach(([id, force]) => {
let key = L10N.getStr("toolbox." + id + ".key");
this.shortcuts.on(key, (name, event) => {
this.shortcuts.on(key, event => {
this.reloadTarget(force);
// Prevent Firefox shortcuts from reloading the page
@ -881,22 +881,22 @@ Toolbox.prototype = {
_addHostListeners: function () {
this.shortcuts.on(L10N.getStr("toolbox.nextTool.key"),
(name, event) => {
event => {
this.selectNextTool();
event.preventDefault();
});
this.shortcuts.on(L10N.getStr("toolbox.previousTool.key"),
(name, event) => {
event => {
this.selectPreviousTool();
event.preventDefault();
});
this.shortcuts.on(L10N.getStr("toolbox.minimize.key"),
(name, event) => {
event => {
this._toggleMinimizeMode();
event.preventDefault();
});
this.shortcuts.on(L10N.getStr("toolbox.toggleHost.key"),
(name, event) => {
event => {
this.switchToPreviousHost();
event.preventDefault();
});
@ -2263,7 +2263,7 @@ Toolbox.prototype = {
/**
* Show 'frames' menu on key down
*/
showFramesMenuOnKeyDown: function (name, event) {
showFramesMenuOnKeyDown: function (event) {
if (event.target.id == "command-button-frames") {
this.showFramesMenu(event);
}

Просмотреть файл

@ -578,7 +578,7 @@ HTMLBreadcrumbs.prototype = {
* @param {DOMEvent} event
* Original event that triggered the shortcut.
*/
handleShortcut: function (name, event) {
handleShortcut: function (event) {
if (!this.selection.isElementNode()) {
return;
}
@ -588,9 +588,13 @@ HTMLBreadcrumbs.prototype = {
this.keyPromise = (this.keyPromise || promise.resolve(null)).then(() => {
let currentnode;
if (name === "Left" && this.currentIndex != 0) {
const isLeft = event.code === "ArrowLeft";
const isRight = event.code === "ArrowRight";
if (isLeft && this.currentIndex != 0) {
currentnode = this.nodeHierarchy[this.currentIndex - 1];
} else if (name === "Right" && this.currentIndex < this.nodeHierarchy.length - 1) {
} else if (isRight && this.currentIndex < this.nodeHierarchy.length - 1) {
currentnode = this.nodeHierarchy[this.currentIndex + 1];
} else {
return null;

Просмотреть файл

@ -184,8 +184,8 @@ function CssComputedView(inspector, document, pageStyle) {
this.shortcuts = new KeyShortcuts({ window: this.styleWindow });
this._onShortcut = this._onShortcut.bind(this);
this.shortcuts.on("CmdOrCtrl+F", this._onShortcut);
this.shortcuts.on("Escape", this._onShortcut);
this.shortcuts.on("CmdOrCtrl+F", event => this._onShortcut("CmdOrCtrl+F", event));
this.shortcuts.on("Escape", event => this._onShortcut("Escape", event));
this.styleDocument.addEventListener("copy", this._onCopy);
this.styleDocument.addEventListener("mousedown", this.focusWindow);
this.element.addEventListener("click", this._onClick);
@ -975,14 +975,14 @@ PropertyView.prototype = {
window: this.tree.styleWindow,
target: this.element
});
this.shortcuts.on("F1", (name, event) => {
this.shortcuts.on("F1", event => {
this.mdnLinkClick(event);
// Prevent opening the options panel
event.preventDefault();
event.stopPropagation();
});
this.shortcuts.on("Return", (name, event) => this.onMatchedToggle(event));
this.shortcuts.on("Space", (name, event) => this.onMatchedToggle(event));
this.shortcuts.on("Return", this.onMatchedToggle);
this.shortcuts.on("Space", this.onMatchedToggle);
let nameContainer = doc.createElementNS(HTML_NS, "span");
nameContainer.className = "computed-property-name-container";

Просмотреть файл

@ -391,7 +391,7 @@ Inspector.prototype = {
window: this.panelDoc.defaultView,
});
let key = INSPECTOR_L10N.getStr("inspector.searchHTML.key");
shortcuts.on(key, (name, event) => {
shortcuts.on(key, event => {
// Prevent overriding same shortcut from the computed/rule views
if (event.target.closest("#sidebar-panel-ruleview") ||
event.target.closest("#sidebar-panel-computedview")) {

Просмотреть файл

@ -690,13 +690,13 @@ MarkupView.prototype = {
"markupView.edit.key",
"markupView.scrollInto.key"].forEach(name => {
let key = INSPECTOR_L10N.getStr(name);
shortcuts.on(key, (_, event) => this._onShortcut(name, event));
shortcuts.on(key, event => this._onShortcut(name, event));
});
// Process generic keys:
["Delete", "Backspace", "Home", "Left", "Right", "Up", "Down", "PageUp",
"PageDown", "Esc", "Enter", "Space"].forEach(key => {
shortcuts.on(key, this._onShortcut);
shortcuts.on(key, event => this._onShortcut(key, event));
});
},

Просмотреть файл

@ -140,10 +140,10 @@ function CssRuleView(inspector, document, store, pageStyle) {
this.shortcuts = new KeyShortcuts({ window: this.styleWindow });
this._onShortcut = this._onShortcut.bind(this);
this.shortcuts.on("Escape", this._onShortcut);
this.shortcuts.on("Return", this._onShortcut);
this.shortcuts.on("Space", this._onShortcut);
this.shortcuts.on("CmdOrCtrl+F", this._onShortcut);
this.shortcuts.on("Escape", event => this._onShortcut("Escape", event));
this.shortcuts.on("Return", event => this._onShortcut("Return", event));
this.shortcuts.on("Space", event => this._onShortcut("Space", event));
this.shortcuts.on("CmdOrCtrl+F", event => this._onShortcut("CmdOrCtrl+F", event));
this.element.addEventListener("copy", this._onCopy);
this.element.addEventListener("contextmenu", this._onContextMenu);
this.addRuleButton.addEventListener("click", this._onAddRule);
@ -156,10 +156,13 @@ function CssRuleView(inspector, document, store, pageStyle) {
this.focusCheckbox.addEventListener("click", this._onTogglePseudoClass);
this._handlePrefChange = this._handlePrefChange.bind(this);
this._handleUAStylePrefChange = this._handleUAStylePrefChange.bind(this);
this._handleDefaultColorUnitPrefChange =
this._handleDefaultColorUnitPrefChange.bind(this);
this._prefObserver = new PrefObserver("devtools.");
this._prefObserver.on(PREF_UA_STYLES, this._handlePrefChange);
this._prefObserver.on(PREF_DEFAULT_COLOR_UNIT, this._handlePrefChange);
this._prefObserver.on(PREF_UA_STYLES, this._handleUAStylePrefChange);
this._prefObserver.on(PREF_DEFAULT_COLOR_UNIT, this._handleDefaultColorUnitPrefChange);
this.showUserAgentStyles = Services.prefs.getBoolPref(PREF_UA_STYLES);
@ -571,11 +574,16 @@ CssRuleView.prototype = {
.length > 0;
},
_handlePrefChange: function (pref) {
if (pref === PREF_UA_STYLES) {
this.showUserAgentStyles = Services.prefs.getBoolPref(pref);
}
_handleUAStylePrefChange: function () {
this.showUserAgentStyles = Services.prefs.getBoolPref(PREF_UA_STYLES);
this._handlePrefChange(PREF_UA_STYLES);
},
_handleDefaultColorUnitPrefChange: function () {
this._handlePrefChange(PREF_DEFAULT_COLOR_UNIT);
},
_handlePrefChange: function (pref) {
// Reselect the currently selected element
let refreshOnPrefs = [PREF_UA_STYLES, PREF_DEFAULT_COLOR_UNIT];
if (refreshOnPrefs.indexOf(pref) > -1) {
@ -693,9 +701,12 @@ CssRuleView.prototype = {
this.clear();
this._dummyElement = null;
this._prefObserver.off(PREF_UA_STYLES, this._handlePrefChange);
this._prefObserver.off(PREF_DEFAULT_COLOR_UNIT, this._handlePrefChange);
// off handlers must have the same reference as their on handlers
this._prefObserver.off(PREF_UA_STYLES, this._handleUAStylePrefChange);
this._prefObserver.off(
PREF_DEFAULT_COLOR_UNIT,
this._handleDefaultColorUnitPrefChange
);
this._prefObserver.destroy();
this._outputParser = null;

Просмотреть файл

@ -33,7 +33,7 @@ add_task(function* () {
// If the mousemove below fails to detect that the button is no longer pressed
// the spectrum will update and emit changed event synchronously after calling
// synthesizeMouse so this handler is executed before the test ends.
spectrum.once("changed", (event, newValue) => {
spectrum.once("changed", newValue => {
is(newValue, value, "Value changed on mousemove without a button pressed.");
});

Просмотреть файл

@ -185,7 +185,7 @@ class StatisticsPanel extends Component {
sorted: true,
});
chart.on("click", (_, { label }) => {
chart.on("click", ({ label }) => {
// Reset FilterButtons and enable one filter exclusively
this.props.closeStatistics();
this.props.enableRequestFilterTypeOnly(label);

Просмотреть файл

@ -51,7 +51,7 @@ add_task(function* () {
let receivedFocusEvent = once(treeRoot, "focus");
mousedown(treeRoot.target.querySelector(".arrow"));
let [, eventItem] = yield receivedExpandEvent;
let [eventItem] = yield receivedExpandEvent;
is(eventItem, treeRoot,
"The 'expand' event target is correct (1).");
@ -102,7 +102,7 @@ add_task(function* () {
receivedFocusEvent = once(treeRoot, "focus", { spreadArgs: true });
mousedown(fooItem.target);
[, eventItem] = yield receivedFocusEvent;
[eventItem] = yield receivedFocusEvent;
is(eventItem, fooItem,
"The 'focus' event target is correct (2).");
is(document.commandDispatcher.focusedElement, fooItem.target,
@ -114,7 +114,7 @@ add_task(function* () {
receivedFocusEvent = once(treeRoot, "focus");
dblclick(barItem.target);
[, eventItem] = yield receivedExpandEvent;
[eventItem] = yield receivedExpandEvent;
is(eventItem, barItem,
"The 'expand' event target is correct (3).");

Просмотреть файл

@ -28,7 +28,7 @@ add_task(function* () {
let D = B.getChild();
let linkEvent = null;
let handler = (_, e) => {
let handler = (e) => {
linkEvent = e;
};

Просмотреть файл

@ -165,9 +165,9 @@ var DetailsSubview = {
/**
* Fired when a preference in `devtools.performance.ui.` is changed.
*/
_onPrefChanged: function (_, prefName) {
_onPrefChanged: function (_, prefName, prefValue) {
if (~this.observedPrefs.indexOf(prefName) && this._onObservedPrefChange) {
this._onObservedPrefChange(_, prefName);
this._onObservedPrefChange(prefName);
}
// All detail views require a recording to be complete, so do not
@ -182,7 +182,7 @@ var DetailsSubview = {
}
if (this._onRerenderPrefChanged) {
this._onRerenderPrefChanged(_, prefName);
this._onRerenderPrefChanged(prefName);
}
if (DetailsView.isViewSelected(this) || this.canUpdateWhileHidden) {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше